Browse Source

[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>
Jan Engelhardt 17 years ago
parent
commit
5c350e5a38
3 changed files with 69 additions and 1 deletions
  1. 5 0
      include/linux/netfilter/xt_DSCP.h
  2. 1 1
      net/netfilter/Kconfig
  3. 63 0
      net/netfilter/xt_DSCP.c

+ 5 - 0
include/linux/netfilter/xt_DSCP.h

@@ -17,4 +17,9 @@ struct xt_DSCP_info {
 	u_int8_t dscp;
 	u_int8_t dscp;
 };
 };
 
 
+struct xt_tos_target_info {
+	u_int8_t tos_value;
+	u_int8_t tos_mask;
+};
+
 #endif /* _XT_DSCP_TARGET_H */
 #endif /* _XT_DSCP_TARGET_H */

+ 1 - 1
net/netfilter/Kconfig

@@ -304,7 +304,7 @@ config NETFILTER_XT_TARGET_DSCP
 
 
 	  It also adds the "TOS" target, which allows you to create rules in
 	  It also adds the "TOS" target, which allows you to create rules in
 	  the "mangle" table which alter the Type Of Service field of an IPv4
 	  the "mangle" table which alter the Type Of Service field of an IPv4
-	  packet prior to routing.
+	  or the Priority field of an IPv6 packet, prior to routing.
 
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 

+ 63 - 0
net/netfilter/xt_DSCP.c

@@ -26,6 +26,7 @@ MODULE_LICENSE("GPL");
 MODULE_ALIAS("ipt_DSCP");
 MODULE_ALIAS("ipt_DSCP");
 MODULE_ALIAS("ip6t_DSCP");
 MODULE_ALIAS("ip6t_DSCP");
 MODULE_ALIAS("ipt_TOS");
 MODULE_ALIAS("ipt_TOS");
+MODULE_ALIAS("ip6t_TOS");
 
 
 static unsigned int
 static unsigned int
 dscp_tg(struct sk_buff *skb, const struct net_device *in,
 dscp_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,
 	return true;
 	return true;
 }
 }
 
 
+static unsigned int
+tos_tg(struct sk_buff *skb, const struct net_device *in,
+       const struct net_device *out, unsigned int hooknum,
+       const struct xt_target *target, const void *targinfo)
+{
+	const struct xt_tos_target_info *info = targinfo;
+	struct iphdr *iph = ip_hdr(skb);
+	u_int8_t orig, nv;
+
+	orig = ipv4_get_dsfield(iph);
+	nv   = (orig & info->tos_mask) ^ info->tos_value;
+
+	if (orig != nv) {
+		if (!skb_make_writable(skb, sizeof(struct iphdr)))
+			return NF_DROP;
+		iph = ip_hdr(skb);
+		ipv4_change_dsfield(iph, ~0, nv);
+	}
+
+	return XT_CONTINUE;
+}
+
+static unsigned int
+tos_tg6(struct sk_buff *skb, const struct net_device *in,
+        const struct net_device *out, unsigned int hooknum,
+        const struct xt_target *target, const void *targinfo)
+{
+	const struct xt_tos_target_info *info = targinfo;
+	struct ipv6hdr *iph = ipv6_hdr(skb);
+	u_int8_t orig, nv;
+
+	orig = ipv6_get_dsfield(iph);
+	nv   = (orig & info->tos_mask) ^ info->tos_value;
+
+	if (orig != nv) {
+		if (!skb_make_writable(skb, sizeof(struct iphdr)))
+			return NF_DROP;
+		iph = ipv6_hdr(skb);
+		ipv6_change_dsfield(iph, ~0, nv);
+	}
+
+	return XT_CONTINUE;
+}
+
 static struct xt_target dscp_tg_reg[] __read_mostly = {
 static struct xt_target dscp_tg_reg[] __read_mostly = {
 	{
 	{
 		.name		= "DSCP",
 		.name		= "DSCP",
@@ -146,6 +191,24 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
 		.checkentry	= tos_tg_check_v0,
 		.checkentry	= tos_tg_check_v0,
 		.me		= THIS_MODULE,
 		.me		= THIS_MODULE,
 	},
 	},
+	{
+		.name		= "TOS",
+		.revision	= 1,
+		.family		= AF_INET,
+		.table		= "mangle",
+		.target		= tos_tg,
+		.targetsize	= sizeof(struct xt_tos_target_info),
+		.me		= THIS_MODULE,
+	},
+	{
+		.name		= "TOS",
+		.revision	= 1,
+		.family		= AF_INET6,
+		.table		= "mangle",
+		.target		= tos_tg6,
+		.targetsize	= sizeof(struct xt_tos_target_info),
+		.me		= THIS_MODULE,
+	},
 };
 };
 
 
 static int __init dscp_tg_init(void)
 static int __init dscp_tg_init(void)