diff options
author | Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> | 2006-08-22 03:29:37 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 17:55:21 -0400 |
commit | 9ba1627617d396135a4d679542a3623d5819e628 (patch) | |
tree | 4a0a72bca0e4a6ad91ae89b572ac58a074ba4eab | |
parent | 131852176c1f5b4350b4af811d1836db387d0c61 (diff) |
[NETFILTER]: x_tables: replace IPv4 dscp match by address family independent version
This replaces IPv4 dscp match by address family independent version.
This also
- utilizes dsfield.h to get the DS field in IPv4/IPv6 header, and
- checks for the DSCP value from user space.
- fixes Kconfig help text.
Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netfilter/xt_dscp.h | 23 | ||||
-rw-r--r-- | include/linux/netfilter_ipv4/ipt_dscp.h | 14 | ||||
-rw-r--r-- | net/ipv4/netfilter/Kconfig | 11 | ||||
-rw-r--r-- | net/ipv4/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_dscp.c | 54 | ||||
-rw-r--r-- | net/netfilter/Kconfig | 11 | ||||
-rw-r--r-- | net/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/netfilter/xt_dscp.c | 113 |
8 files changed, 154 insertions, 74 deletions
diff --git a/include/linux/netfilter/xt_dscp.h b/include/linux/netfilter/xt_dscp.h new file mode 100644 index 000000000000..1da61e6acaf7 --- /dev/null +++ b/include/linux/netfilter/xt_dscp.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* x_tables module for matching the IPv4/IPv6 DSCP field | ||
2 | * | ||
3 | * (C) 2002 Harald Welte <laforge@gnumonks.org> | ||
4 | * This software is distributed under GNU GPL v2, 1991 | ||
5 | * | ||
6 | * See RFC2474 for a description of the DSCP field within the IP Header. | ||
7 | * | ||
8 | * xt_dscp.h,v 1.3 2002/08/05 19:00:21 laforge Exp | ||
9 | */ | ||
10 | #ifndef _XT_DSCP_H | ||
11 | #define _XT_DSCP_H | ||
12 | |||
13 | #define XT_DSCP_MASK 0xfc /* 11111100 */ | ||
14 | #define XT_DSCP_SHIFT 2 | ||
15 | #define XT_DSCP_MAX 0x3f /* 00111111 */ | ||
16 | |||
17 | /* match info */ | ||
18 | struct xt_dscp_info { | ||
19 | u_int8_t dscp; | ||
20 | u_int8_t invert; | ||
21 | }; | ||
22 | |||
23 | #endif /* _XT_DSCP_H */ | ||
diff --git a/include/linux/netfilter_ipv4/ipt_dscp.h b/include/linux/netfilter_ipv4/ipt_dscp.h index 2fa6dfe92894..4b82ca912b0e 100644 --- a/include/linux/netfilter_ipv4/ipt_dscp.h +++ b/include/linux/netfilter_ipv4/ipt_dscp.h | |||
@@ -10,14 +10,12 @@ | |||
10 | #ifndef _IPT_DSCP_H | 10 | #ifndef _IPT_DSCP_H |
11 | #define _IPT_DSCP_H | 11 | #define _IPT_DSCP_H |
12 | 12 | ||
13 | #define IPT_DSCP_MASK 0xfc /* 11111100 */ | 13 | #include <linux/netfilter/xt_dscp.h> |
14 | #define IPT_DSCP_SHIFT 2 | ||
15 | #define IPT_DSCP_MAX 0x3f /* 00111111 */ | ||
16 | 14 | ||
17 | /* match info */ | 15 | #define IPT_DSCP_MASK XT_DSCP_MASK |
18 | struct ipt_dscp_info { | 16 | #define IPT_DSCP_SHIFT XT_DSCP_SHIFT |
19 | u_int8_t dscp; | 17 | #define IPT_DSCP_MAX XT_DSCP_MAX |
20 | u_int8_t invert; | 18 | |
21 | }; | 19 | #define ipt_dscp_info xt_dscp_info |
22 | 20 | ||
23 | #endif /* _IPT_DSCP_H */ | 21 | #endif /* _IPT_DSCP_H */ |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index ef0b5aac5838..d88d71d1ce0d 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -278,17 +278,6 @@ config IP_NF_MATCH_ECN | |||
278 | 278 | ||
279 | To compile it as a module, choose M here. If unsure, say N. | 279 | To compile it as a module, choose M here. If unsure, say N. |
280 | 280 | ||
281 | config IP_NF_MATCH_DSCP | ||
282 | tristate "DSCP match support" | ||
283 | depends on IP_NF_IPTABLES | ||
284 | help | ||
285 | This option adds a `DSCP' match, which allows you to match against | ||
286 | the IPv4 header DSCP field (DSCP codepoint). | ||
287 | |||
288 | The DSCP codepoint can have any value between 0x0 and 0x4f. | ||
289 | |||
290 | To compile it as a module, choose M here. If unsure, say N. | ||
291 | |||
292 | config IP_NF_MATCH_AH | 281 | config IP_NF_MATCH_AH |
293 | tristate "AH match support" | 282 | tristate "AH match support" |
294 | depends on IP_NF_IPTABLES | 283 | depends on IP_NF_IPTABLES |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 3ded4a3af59c..b946b0f3ea9d 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
@@ -59,7 +59,6 @@ obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o | |||
59 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o | 59 | obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o |
60 | obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o | 60 | obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o |
61 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o | 61 | obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o |
62 | obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o | ||
63 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o | 62 | obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o |
64 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o | 63 | obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o |
65 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o | 64 | obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o |
diff --git a/net/ipv4/netfilter/ipt_dscp.c b/net/ipv4/netfilter/ipt_dscp.c deleted file mode 100644 index 47177591aeb6..000000000000 --- a/net/ipv4/netfilter/ipt_dscp.c +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* IP tables module for matching the value of the IPv4 DSCP field | ||
2 | * | ||
3 | * ipt_dscp.c,v 1.3 2002/08/05 19:00:21 laforge Exp | ||
4 | * | ||
5 | * (C) 2002 by Harald Welte <laforge@netfilter.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | |||
15 | #include <linux/netfilter_ipv4/ipt_dscp.h> | ||
16 | #include <linux/netfilter_ipv4/ip_tables.h> | ||
17 | |||
18 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
19 | MODULE_DESCRIPTION("iptables DSCP matching module"); | ||
20 | MODULE_LICENSE("GPL"); | ||
21 | |||
22 | static int match(const struct sk_buff *skb, | ||
23 | const struct net_device *in, const struct net_device *out, | ||
24 | const struct xt_match *match, const void *matchinfo, | ||
25 | int offset, unsigned int protoff, int *hotdrop) | ||
26 | { | ||
27 | const struct ipt_dscp_info *info = matchinfo; | ||
28 | const struct iphdr *iph = skb->nh.iph; | ||
29 | |||
30 | u_int8_t sh_dscp = ((info->dscp << IPT_DSCP_SHIFT) & IPT_DSCP_MASK); | ||
31 | |||
32 | return ((iph->tos&IPT_DSCP_MASK) == sh_dscp) ^ info->invert; | ||
33 | } | ||
34 | |||
35 | static struct ipt_match dscp_match = { | ||
36 | .name = "dscp", | ||
37 | .match = match, | ||
38 | .matchsize = sizeof(struct ipt_dscp_info), | ||
39 | .me = THIS_MODULE, | ||
40 | }; | ||
41 | |||
42 | static int __init ipt_dscp_init(void) | ||
43 | { | ||
44 | return ipt_register_match(&dscp_match); | ||
45 | } | ||
46 | |||
47 | static void __exit ipt_dscp_fini(void) | ||
48 | { | ||
49 | ipt_unregister_match(&dscp_match); | ||
50 | |||
51 | } | ||
52 | |||
53 | module_init(ipt_dscp_init); | ||
54 | module_exit(ipt_dscp_fini); | ||
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index a9894ddfd72a..f781405f5d65 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -263,6 +263,17 @@ config NETFILTER_XT_MATCH_DCCP | |||
263 | If you want to compile it as a module, say M here and read | 263 | If you want to compile it as a module, say M here and read |
264 | <file:Documentation/modules.txt>. If unsure, say `N'. | 264 | <file:Documentation/modules.txt>. If unsure, say `N'. |
265 | 265 | ||
266 | config NETFILTER_XT_MATCH_DSCP | ||
267 | tristate '"DSCP" match support' | ||
268 | depends on NETFILTER_XTABLES | ||
269 | help | ||
270 | This option adds a `DSCP' match, which allows you to match against | ||
271 | the IPv4/IPv6 header DSCP field (differentiated services codepoint). | ||
272 | |||
273 | The DSCP field can have any value between 0x0 and 0x3f inclusive. | ||
274 | |||
275 | To compile it as a module, choose M here. If unsure, say N. | ||
276 | |||
266 | config NETFILTER_XT_MATCH_ESP | 277 | config NETFILTER_XT_MATCH_ESP |
267 | tristate '"ESP" match support' | 278 | tristate '"ESP" match support' |
268 | depends on NETFILTER_XTABLES | 279 | depends on NETFILTER_XTABLES |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 6fa4b7580458..0b8a70c1df46 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_CONNBYTES) += xt_connbytes.o | |||
37 | obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o | 37 | obj-$(CONFIG_NETFILTER_XT_MATCH_CONNMARK) += xt_connmark.o |
38 | obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o | 38 | obj-$(CONFIG_NETFILTER_XT_MATCH_CONNTRACK) += xt_conntrack.o |
39 | obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o | 39 | obj-$(CONFIG_NETFILTER_XT_MATCH_DCCP) += xt_dccp.o |
40 | obj-$(CONFIG_NETFILTER_XT_MATCH_DSCP) += xt_dscp.o | ||
40 | obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o | 41 | obj-$(CONFIG_NETFILTER_XT_MATCH_ESP) += xt_esp.o |
41 | obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o | 42 | obj-$(CONFIG_NETFILTER_XT_MATCH_HELPER) += xt_helper.o |
42 | obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o | 43 | obj-$(CONFIG_NETFILTER_XT_MATCH_LENGTH) += xt_length.o |
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c new file mode 100644 index 000000000000..82e250d1f007 --- /dev/null +++ b/net/netfilter/xt_dscp.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* IP tables module for matching the value of the IPv4/IPv6 DSCP field | ||
2 | * | ||
3 | * xt_dscp.c,v 1.3 2002/08/05 19:00:21 laforge Exp | ||
4 | * | ||
5 | * (C) 2002 by Harald Welte <laforge@netfilter.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | #include <linux/ip.h> | ||
15 | #include <linux/ipv6.h> | ||
16 | #include <net/dsfield.h> | ||
17 | |||
18 | #include <linux/netfilter/xt_dscp.h> | ||
19 | #include <linux/netfilter/x_tables.h> | ||
20 | |||
21 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | ||
22 | MODULE_DESCRIPTION("x_tables DSCP matching module"); | ||
23 | MODULE_LICENSE("GPL"); | ||
24 | MODULE_ALIAS("ipt_dscp"); | ||
25 | MODULE_ALIAS("ip6t_dscp"); | ||
26 | |||
27 | static int match(const struct sk_buff *skb, | ||
28 | const struct net_device *in, | ||
29 | const struct net_device *out, | ||
30 | const struct xt_match *match, | ||
31 | const void *matchinfo, | ||
32 | int offset, | ||
33 | unsigned int protoff, | ||
34 | int *hotdrop) | ||
35 | { | ||
36 | const struct xt_dscp_info *info = matchinfo; | ||
37 | u_int8_t dscp = ipv4_get_dsfield(skb->nh.iph) >> XT_DSCP_SHIFT; | ||
38 | |||
39 | return (dscp == info->dscp) ^ !!info->invert; | ||
40 | } | ||
41 | |||
42 | static int match6(const struct sk_buff *skb, | ||
43 | const struct net_device *in, | ||
44 | const struct net_device *out, | ||
45 | const struct xt_match *match, | ||
46 | const void *matchinfo, | ||
47 | int offset, | ||
48 | unsigned int protoff, | ||
49 | int *hotdrop) | ||
50 | { | ||
51 | const struct xt_dscp_info *info = matchinfo; | ||
52 | u_int8_t dscp = ipv6_get_dsfield(skb->nh.ipv6h) >> XT_DSCP_SHIFT; | ||
53 | |||
54 | return (dscp == info->dscp) ^ !!info->invert; | ||
55 | } | ||
56 | |||
57 | static int checkentry(const char *tablename, | ||
58 | const void *info, | ||
59 | const struct xt_match *match, | ||
60 | void *matchinfo, | ||
61 | unsigned int matchsize, | ||
62 | unsigned int hook_mask) | ||
63 | { | ||
64 | const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; | ||
65 | |||
66 | if (dscp > XT_DSCP_MAX) { | ||
67 | printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | return 1; | ||
72 | } | ||
73 | |||
74 | static struct xt_match dscp_match = { | ||
75 | .name = "dscp", | ||
76 | .match = match, | ||
77 | .checkentry = checkentry, | ||
78 | .matchsize = sizeof(struct xt_dscp_info), | ||
79 | .family = AF_INET, | ||
80 | .me = THIS_MODULE, | ||
81 | }; | ||
82 | |||
83 | static struct xt_match dscp6_match = { | ||
84 | .name = "dscp", | ||
85 | .match = match6, | ||
86 | .checkentry = checkentry, | ||
87 | .matchsize = sizeof(struct xt_dscp_info), | ||
88 | .family = AF_INET6, | ||
89 | .me = THIS_MODULE, | ||
90 | }; | ||
91 | |||
92 | static int __init xt_dscp_match_init(void) | ||
93 | { | ||
94 | int ret; | ||
95 | ret = xt_register_match(&dscp_match); | ||
96 | if (ret) | ||
97 | return ret; | ||
98 | |||
99 | ret = xt_register_match(&dscp6_match); | ||
100 | if (ret) | ||
101 | xt_unregister_match(&dscp_match); | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | static void __exit xt_dscp_match_fini(void) | ||
107 | { | ||
108 | xt_unregister_match(&dscp_match); | ||
109 | xt_unregister_match(&dscp6_match); | ||
110 | } | ||
111 | |||
112 | module_init(xt_dscp_match_init); | ||
113 | module_exit(xt_dscp_match_fini); | ||