aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@computergmbh.de>2007-12-05 02:39:09 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:56:00 -0500
commit5c350e5a380333c64da8580fa134a2fd8e71fea4 (patch)
tree1d9ff30ad36946af539816fec2761165e7bb4aaf
parentf1095ab51d4297d4a84b64a65c71054183a73486 (diff)
[NETFILTER]: IPv6 capable xt_TOS v1 target
Extends the xt_DSCP target by xt_TOS v1 to add support for selectively setting and flipping any bit in the IPv4 TOS and IPv6 Priority fields. (ipt_TOS and xt_DSCP only accepted a limited range of possible values.) Signed-off-by: Jan Engelhardt <jengelh@computergmbh.de> 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.h5
-rw-r--r--net/netfilter/Kconfig2
-rw-r--r--net/netfilter/xt_DSCP.c63
3 files changed, 69 insertions, 1 deletions
diff --git a/include/linux/netfilter/xt_DSCP.h b/include/linux/netfilter/xt_DSCP.h
index 3c7c963997bd..14da1968e2c6 100644
--- a/include/linux/netfilter/xt_DSCP.h
+++ b/include/linux/netfilter/xt_DSCP.h
@@ -17,4 +17,9 @@ struct xt_DSCP_info {
17 u_int8_t dscp; 17 u_int8_t dscp;
18}; 18};
19 19
20struct xt_tos_target_info {
21 u_int8_t tos_value;
22 u_int8_t tos_mask;
23};
24
20#endif /* _XT_DSCP_TARGET_H */ 25#endif /* _XT_DSCP_TARGET_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 9c82d4cc86bf..7bde6315999a 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -304,7 +304,7 @@ config NETFILTER_XT_TARGET_DSCP
304 304
305 It also adds the "TOS" target, which allows you to create rules in 305 It also adds the "TOS" target, which allows you to create rules in
306 the "mangle" table which alter the Type Of Service field of an IPv4 306 the "mangle" table which alter the Type Of Service field of an IPv4
307 packet prior to routing. 307 or the Priority field of an IPv6 packet, prior to routing.
308 308
309 To compile it as a module, choose M here. If unsure, say N. 309 To compile it as a module, choose M here. If unsure, say N.
310 310
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 40a4f1d71916..fd7500ecadfd 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -26,6 +26,7 @@ MODULE_LICENSE("GPL");
26MODULE_ALIAS("ipt_DSCP"); 26MODULE_ALIAS("ipt_DSCP");
27MODULE_ALIAS("ip6t_DSCP"); 27MODULE_ALIAS("ip6t_DSCP");
28MODULE_ALIAS("ipt_TOS"); 28MODULE_ALIAS("ipt_TOS");
29MODULE_ALIAS("ip6t_TOS");
29 30
30static unsigned int 31static unsigned int
31dscp_tg(struct sk_buff *skb, const struct net_device *in, 32dscp_tg(struct sk_buff *skb, const struct net_device *in,
@@ -117,6 +118,50 @@ tos_tg_check_v0(const char *tablename, const void *e_void,
117 return true; 118 return true;
118} 119}
119 120
121static unsigned int
122tos_tg(struct sk_buff *skb, const struct net_device *in,
123 const struct net_device *out, unsigned int hooknum,
124 const struct xt_target *target, const void *targinfo)
125{
126 const struct xt_tos_target_info *info = targinfo;
127 struct iphdr *iph = ip_hdr(skb);
128 u_int8_t orig, nv;
129
130 orig = ipv4_get_dsfield(iph);
131 nv = (orig & info->tos_mask) ^ info->tos_value;
132
133 if (orig != nv) {
134 if (!skb_make_writable(skb, sizeof(struct iphdr)))
135 return NF_DROP;
136 iph = ip_hdr(skb);
137 ipv4_change_dsfield(iph, ~0, nv);
138 }
139
140 return XT_CONTINUE;
141}
142
143static unsigned int
144tos_tg6(struct sk_buff *skb, const struct net_device *in,
145 const struct net_device *out, unsigned int hooknum,
146 const struct xt_target *target, const void *targinfo)
147{
148 const struct xt_tos_target_info *info = targinfo;
149 struct ipv6hdr *iph = ipv6_hdr(skb);
150 u_int8_t orig, nv;
151
152 orig = ipv6_get_dsfield(iph);
153 nv = (orig & info->tos_mask) ^ info->tos_value;
154
155 if (orig != nv) {
156 if (!skb_make_writable(skb, sizeof(struct iphdr)))
157 return NF_DROP;
158 iph = ipv6_hdr(skb);
159 ipv6_change_dsfield(iph, ~0, nv);
160 }
161
162 return XT_CONTINUE;
163}
164
120static struct xt_target dscp_tg_reg[] __read_mostly = { 165static struct xt_target dscp_tg_reg[] __read_mostly = {
121 { 166 {
122 .name = "DSCP", 167 .name = "DSCP",
@@ -146,6 +191,24 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
146 .checkentry = tos_tg_check_v0, 191 .checkentry = tos_tg_check_v0,
147 .me = THIS_MODULE, 192 .me = THIS_MODULE,
148 }, 193 },
194 {
195 .name = "TOS",
196 .revision = 1,
197 .family = AF_INET,
198 .table = "mangle",
199 .target = tos_tg,
200 .targetsize = sizeof(struct xt_tos_target_info),
201 .me = THIS_MODULE,
202 },
203 {
204 .name = "TOS",
205 .revision = 1,
206 .family = AF_INET6,
207 .table = "mangle",
208 .target = tos_tg6,
209 .targetsize = sizeof(struct xt_tos_target_info),
210 .me = THIS_MODULE,
211 },
149}; 212};
150 213
151static int __init dscp_tg_init(void) 214static int __init dscp_tg_init(void)