netfilter: xtables: move ipt_ecn to xt_ecn
authorJan Engelhardt <jengelh@medozas.de>
Thu, 9 Jun 2011 19:03:07 +0000 (21:03 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Tue, 27 Dec 2011 19:31:31 +0000 (20:31 +0100)
Prepare the ECN match for augmentation by an IPv6 counterpart. Since
no symbol dependencies to ipv6.ko are added, having a single ecn match
module is the more so welcome.

Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter/Kbuild
include/linux/netfilter/xt_ecn.h [new file with mode: 0644]
include/linux/netfilter_ipv4/ipt_ecn.h
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/ipt_ecn.c [deleted file]
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/xt_ecn.c [new file with mode: 0644]

index e630a2ed4f1861c9f044803e7242053a4613b9ff..e144f54185c019a01d2210791e54f1feb12b1586 100644 (file)
@@ -43,6 +43,7 @@ header-y += xt_cpu.h
 header-y += xt_dccp.h
 header-y += xt_devgroup.h
 header-y += xt_dscp.h
+header-y += xt_ecn.h
 header-y += xt_esp.h
 header-y += xt_hashlimit.h
 header-y += xt_helper.h
diff --git a/include/linux/netfilter/xt_ecn.h b/include/linux/netfilter/xt_ecn.h
new file mode 100644 (file)
index 0000000..065c1a5
--- /dev/null
@@ -0,0 +1,35 @@
+/* iptables module for matching the ECN header in IPv4 and TCP header
+ *
+ * (C) 2002 Harald Welte <laforge@gnumonks.org>
+ *
+ * This software is distributed under GNU GPL v2, 1991
+ * 
+ * ipt_ecn.h,v 1.4 2002/08/05 19:39:00 laforge Exp
+*/
+#ifndef _XT_ECN_H
+#define _XT_ECN_H
+
+#include <linux/types.h>
+#include <linux/netfilter/xt_dscp.h>
+
+#define IPT_ECN_IP_MASK        (~XT_DSCP_MASK)
+
+#define IPT_ECN_OP_MATCH_IP    0x01
+#define IPT_ECN_OP_MATCH_ECE   0x10
+#define IPT_ECN_OP_MATCH_CWR   0x20
+
+#define IPT_ECN_OP_MATCH_MASK  0xce
+
+/* match info */
+struct ipt_ecn_info {
+       __u8 operation;
+       __u8 invert;
+       __u8 ip_ect;
+       union {
+               struct {
+                       __u8 ect;
+               } tcp;
+       } proto;
+};
+
+#endif /* _XT_ECN_H */
index eabf95fb7d3e030c17a2f078ce8621e67d54b38a..b1124ec76190ad9b94c41d5eb60111c6e722e4fa 100644 (file)
@@ -1,35 +1,6 @@
-/* iptables module for matching the ECN header in IPv4 and TCP header
- *
- * (C) 2002 Harald Welte <laforge@gnumonks.org>
- *
- * This software is distributed under GNU GPL v2, 1991
- * 
- * ipt_ecn.h,v 1.4 2002/08/05 19:39:00 laforge Exp
-*/
 #ifndef _IPT_ECN_H
 #define _IPT_ECN_H
 
-#include <linux/types.h>
-#include <linux/netfilter/xt_dscp.h>
-
-#define IPT_ECN_IP_MASK        (~XT_DSCP_MASK)
-
-#define IPT_ECN_OP_MATCH_IP    0x01
-#define IPT_ECN_OP_MATCH_ECE   0x10
-#define IPT_ECN_OP_MATCH_CWR   0x20
-
-#define IPT_ECN_OP_MATCH_MASK  0xce
-
-/* match info */
-struct ipt_ecn_info {
-       __u8 operation;
-       __u8 invert;
-       __u8 ip_ect;
-       union {
-               struct {
-                       __u8 ect;
-               } tcp;
-       } proto;
-};
+#include <linux/netfilter/xt_ecn.h>
 
 #endif /* _IPT_ECN_H */
index 7e1f5cdaf11eeed433ee0355be385ac74a5dd03c..53b9c79c8025e82193f6301d8fee4aef6b4a4dbd 100644 (file)
@@ -76,11 +76,11 @@ config IP_NF_MATCH_AH
 config IP_NF_MATCH_ECN
        tristate '"ecn" match support'
        depends on NETFILTER_ADVANCED
-       help
-         This option adds a `ECN' match, which allows you to match against
-         the IPv4 and TCP header ECN fields.
-
-         To compile it as a module, choose M here.  If unsure, say N.
+       select NETFILTER_XT_MATCH_ECN
+       ---help---
+       This is a backwards-compat option for the user's convenience
+       (e.g. when running oldconfig). It selects
+       CONFIG_NETFILTER_XT_MATCH_ECN.
 
 config IP_NF_MATCH_RPFILTER
        tristate '"rpfilter" reverse path filter match support'
index 123dd88cea537d8f66f96ac69b77870c776802eb..213a462b739bbd937ed511485db824aa94e7d26c 100644 (file)
@@ -49,7 +49,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
 
 # matches
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
-obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
 obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ipt_rpfilter.o
 
 # targets
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
deleted file mode 100644 (file)
index 2b57e52..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* IP tables module for matching the value of the IPv4 and TCP ECN bits
- *
- * (C) 2002 by Harald Welte <laforge@gnumonks.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <net/ip.h>
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/tcp.h>
-
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-#include <linux/netfilter_ipv4/ipt_ecn.h>
-
-MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
-MODULE_DESCRIPTION("Xtables: Explicit Congestion Notification (ECN) flag match for IPv4");
-MODULE_LICENSE("GPL");
-
-static inline bool match_ip(const struct sk_buff *skb,
-                           const struct ipt_ecn_info *einfo)
-{
-       return ((ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect) ^
-              !!(einfo->invert & IPT_ECN_OP_MATCH_IP);
-}
-
-static inline bool match_tcp(const struct sk_buff *skb,
-                            const struct ipt_ecn_info *einfo,
-                            bool *hotdrop)
-{
-       struct tcphdr _tcph;
-       const struct tcphdr *th;
-
-       /* In practice, TCP match does this, so can't fail.  But let's
-        * be good citizens.
-        */
-       th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
-       if (th == NULL) {
-               *hotdrop = false;
-               return false;
-       }
-
-       if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
-               if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
-                       if (th->ece == 1)
-                               return false;
-               } else {
-                       if (th->ece == 0)
-                               return false;
-               }
-       }
-
-       if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
-               if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
-                       if (th->cwr == 1)
-                               return false;
-               } else {
-                       if (th->cwr == 0)
-                               return false;
-               }
-       }
-
-       return true;
-}
-
-static bool ecn_mt(const struct sk_buff *skb, struct xt_action_param *par)
-{
-       const struct ipt_ecn_info *info = par->matchinfo;
-
-       if (info->operation & IPT_ECN_OP_MATCH_IP)
-               if (!match_ip(skb, info))
-                       return false;
-
-       if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
-               if (!match_tcp(skb, info, &par->hotdrop))
-                       return false;
-       }
-
-       return true;
-}
-
-static int ecn_mt_check(const struct xt_mtchk_param *par)
-{
-       const struct ipt_ecn_info *info = par->matchinfo;
-       const struct ipt_ip *ip = par->entryinfo;
-
-       if (info->operation & IPT_ECN_OP_MATCH_MASK)
-               return -EINVAL;
-
-       if (info->invert & IPT_ECN_OP_MATCH_MASK)
-               return -EINVAL;
-
-       if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) &&
-           (ip->proto != IPPROTO_TCP || ip->invflags & IPT_INV_PROTO)) {
-               pr_info("cannot match TCP bits in rule for non-tcp packets\n");
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static struct xt_match ecn_mt_reg __read_mostly = {
-       .name           = "ecn",
-       .family         = NFPROTO_IPV4,
-       .match          = ecn_mt,
-       .matchsize      = sizeof(struct ipt_ecn_info),
-       .checkentry     = ecn_mt_check,
-       .me             = THIS_MODULE,
-};
-
-static int __init ecn_mt_init(void)
-{
-       return xt_register_match(&ecn_mt_reg);
-}
-
-static void __exit ecn_mt_exit(void)
-{
-       xt_unregister_match(&ecn_mt_reg);
-}
-
-module_init(ecn_mt_init);
-module_exit(ecn_mt_exit);
index bac93ba607780e9ec4267315b24b2685183fd783..20388a97df66346c8af1b805bdcd38b645b11df2 100644 (file)
@@ -778,6 +778,15 @@ config NETFILTER_XT_MATCH_DSCP
 
          To compile it as a module, choose M here.  If unsure, say N.
 
+config NETFILTER_XT_MATCH_ECN
+       tristate '"ecn" match support'
+       depends on NETFILTER_ADVANCED
+       ---help---
+       This option adds an "ECN" match, which allows you to match against
+       the IPv4 and TCP header ECN fields.
+
+       To compile it as a module, choose M here. If unsure, say N.
+
 config NETFILTER_XT_MATCH_ESP
        tristate '"esp" match support'
        depends on NETFILTER_ADVANCED
index b2eee4df8168be0f5cf8e636eb4c8f9519db43db..40f4c3d636c583d0deb95fa1af959e967c635c87 100644 (file)
@@ -81,6 +81,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CPU) += xt_cpu.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DEVGROUP) += xt_devgroup.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_ECN) += xt_ecn.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o
diff --git a/net/netfilter/xt_ecn.c b/net/netfilter/xt_ecn.c
new file mode 100644 (file)
index 0000000..2c198f5
--- /dev/null
@@ -0,0 +1,128 @@
+/* IP tables module for matching the value of the IPv4 and TCP ECN bits
+ *
+ * (C) 2002 by Harald Welte <laforge@gnumonks.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <net/ip.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/tcp.h>
+
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_ecn.h>
+
+MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
+MODULE_DESCRIPTION("Xtables: Explicit Congestion Notification (ECN) flag match for IPv4");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("ipt_ecn");
+
+static inline bool match_ip(const struct sk_buff *skb,
+                           const struct ipt_ecn_info *einfo)
+{
+       return ((ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect) ^
+              !!(einfo->invert & IPT_ECN_OP_MATCH_IP);
+}
+
+static inline bool match_tcp(const struct sk_buff *skb,
+                            const struct ipt_ecn_info *einfo,
+                            bool *hotdrop)
+{
+       struct tcphdr _tcph;
+       const struct tcphdr *th;
+
+       /* In practice, TCP match does this, so can't fail.  But let's
+        * be good citizens.
+        */
+       th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph);
+       if (th == NULL) {
+               *hotdrop = false;
+               return false;
+       }
+
+       if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
+               if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
+                       if (th->ece == 1)
+                               return false;
+               } else {
+                       if (th->ece == 0)
+                               return false;
+               }
+       }
+
+       if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
+               if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
+                       if (th->cwr == 1)
+                               return false;
+               } else {
+                       if (th->cwr == 0)
+                               return false;
+               }
+       }
+
+       return true;
+}
+
+static bool ecn_mt(const struct sk_buff *skb, struct xt_action_param *par)
+{
+       const struct ipt_ecn_info *info = par->matchinfo;
+
+       if (info->operation & IPT_ECN_OP_MATCH_IP)
+               if (!match_ip(skb, info))
+                       return false;
+
+       if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
+               if (!match_tcp(skb, info, &par->hotdrop))
+                       return false;
+       }
+
+       return true;
+}
+
+static int ecn_mt_check(const struct xt_mtchk_param *par)
+{
+       const struct ipt_ecn_info *info = par->matchinfo;
+       const struct ipt_ip *ip = par->entryinfo;
+
+       if (info->operation & IPT_ECN_OP_MATCH_MASK)
+               return -EINVAL;
+
+       if (info->invert & IPT_ECN_OP_MATCH_MASK)
+               return -EINVAL;
+
+       if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) &&
+           (ip->proto != IPPROTO_TCP || ip->invflags & IPT_INV_PROTO)) {
+               pr_info("cannot match TCP bits in rule for non-tcp packets\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct xt_match ecn_mt_reg __read_mostly = {
+       .name           = "ecn",
+       .family         = NFPROTO_IPV4,
+       .match          = ecn_mt,
+       .matchsize      = sizeof(struct ipt_ecn_info),
+       .checkentry     = ecn_mt_check,
+       .me             = THIS_MODULE,
+};
+
+static int __init ecn_mt_init(void)
+{
+       return xt_register_match(&ecn_mt_reg);
+}
+
+static void __exit ecn_mt_exit(void)
+{
+       xt_unregister_match(&ecn_mt_reg);
+}
+
+module_init(ecn_mt_init);
+module_exit(ecn_mt_exit);