Posted for review and checkup. ===Patch begins=== Convert ipt_TOS to xt_TOS, with the following extras: * IPv6 support (will use the priority field) * can set network precedence Signed-off-by: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx> --- include/linux/netfilter/Kbuild | 1 include/linux/netfilter/xt_TOS.h | 13 ++ include/linux/netfilter_ipv4/Kbuild | 1 net/ipv4/netfilter/Kconfig | 10 -- net/ipv4/netfilter/Makefile | 1 net/ipv4/netfilter/ipt_TOS.c | 82 ------------------ net/netfilter/Kconfig | 8 + net/netfilter/Makefile | 1 net/netfilter/xt_TOS.c | 160 ++++++++++++++++++++++++++++++++++++ 9 files changed, 183 insertions(+), 94 deletions(-) Index: net-2.6.25/include/linux/netfilter/Kbuild =================================================================== --- net-2.6.25.orig/include/linux/netfilter/Kbuild +++ net-2.6.25/include/linux/netfilter/Kbuild @@ -12,6 +12,7 @@ header-y += xt_NFLOG.h header-y += xt_NFQUEUE.h header-y += xt_SECMARK.h header-y += xt_TCPMSS.h +header-y += xt_TOS.h header-y += xt_comment.h header-y += xt_connbytes.h header-y += xt_connmark.h Index: net-2.6.25/include/linux/netfilter/xt_TOS.h =================================================================== --- /dev/null +++ net-2.6.25/include/linux/netfilter/xt_TOS.h @@ -0,0 +1,13 @@ +#ifndef _XT_TOS_TARGET_H +#define _XT_TOS_TARGET_H + +#ifndef IPTOS_NORMALSVC +# define IPTOS_NORMALSVC 0 +#endif + +struct xt_tos_target_info { + u_int8_t tos_value; + u_int8_t tos_mask; +}; + +#endif /* _XT_TOS_TARGET_H */ Index: net-2.6.25/include/linux/netfilter_ipv4/Kbuild =================================================================== --- net-2.6.25.orig/include/linux/netfilter_ipv4/Kbuild +++ net-2.6.25/include/linux/netfilter_ipv4/Kbuild @@ -9,7 +9,6 @@ header-y += ipt_NFQUEUE.h header-y += ipt_REJECT.h header-y += ipt_SAME.h header-y += ipt_TCPMSS.h -header-y += ipt_TOS.h header-y += ipt_TTL.h header-y += ipt_ULOG.h header-y += ipt_addrtype.h Index: net-2.6.25/net/ipv4/netfilter/Kconfig =================================================================== --- net-2.6.25.orig/net/ipv4/netfilter/Kconfig +++ net-2.6.25/net/ipv4/netfilter/Kconfig @@ -302,16 +302,6 @@ config IP_NF_MANGLE To compile it as a module, choose M here. If unsure, say N. -config IP_NF_TARGET_TOS - tristate "TOS target support" - depends on IP_NF_MANGLE - help - This option adds a `TOS' target, which allows you to create rules in - the `mangle' table which alter the Type Of Service field of an IP - packet prior to routing. - - To compile it as a module, choose M here. If unsure, say N. - config IP_NF_TARGET_ECN tristate "ECN target support" depends on IP_NF_MANGLE Index: net-2.6.25/net/ipv4/netfilter/Makefile =================================================================== --- net-2.6.25.orig/net/ipv4/netfilter/Makefile +++ net-2.6.25/net/ipv4/netfilter/Makefile @@ -58,7 +58,6 @@ obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_SAME.o -obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o Index: net-2.6.25/net/ipv4/netfilter/ipt_TOS.c =================================================================== --- net-2.6.25.orig/net/ipv4/netfilter/ipt_TOS.c +++ /dev/null @@ -1,82 +0,0 @@ -/* This is a module which is used for setting the TOS field of a packet. */ - -/* (C) 1999-2001 Paul `Rusty' Russell - * (C) 2002-2004 Netfilter Core Team <coreteam@xxxxxxxxxxxxx> - * - * 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. - */ - -#include <linux/module.h> -#include <linux/skbuff.h> -#include <linux/ip.h> -#include <net/checksum.h> - -#include <linux/netfilter/x_tables.h> -#include <linux/netfilter_ipv4/ipt_TOS.h> - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Netfilter Core Team <coreteam@xxxxxxxxxxxxx>"); -MODULE_DESCRIPTION("iptables TOS mangling module"); - -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 ipt_tos_target_info *tosinfo = targinfo; - struct iphdr *iph = ip_hdr(skb); - - if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { - __u8 oldtos; - if (!skb_make_writable(skb, sizeof(struct iphdr))) - return NF_DROP; - iph = ip_hdr(skb); - oldtos = iph->tos; - iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; - nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos)); - } - return XT_CONTINUE; -} - -static bool -tos_tg_check(const char *tablename, const void *e_void, - const struct xt_target *target, void *targinfo, - unsigned int hook_mask) -{ - const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos; - - if (tos != IPTOS_LOWDELAY - && tos != IPTOS_THROUGHPUT - && tos != IPTOS_RELIABILITY - && tos != IPTOS_MINCOST - && tos != IPTOS_NORMALSVC) { - printk(KERN_WARNING "TOS: bad tos value %#x\n", tos); - return false; - } - return true; -} - -static struct xt_target tos_tg_reg __read_mostly = { - .name = "TOS", - .family = AF_INET, - .target = tos_tg, - .targetsize = sizeof(struct ipt_tos_target_info), - .table = "mangle", - .checkentry = tos_tg_check, - .me = THIS_MODULE, -}; - -static int __init tos_tg_init(void) -{ - return xt_register_target(&tos_tg_reg); -} - -static void __exit tos_tg_exit(void) -{ - xt_unregister_target(&tos_tg_reg); -} - -module_init(tos_tg_init); -module_exit(tos_tg_exit); Index: net-2.6.25/net/netfilter/Kconfig =================================================================== --- net-2.6.25.orig/net/netfilter/Kconfig +++ net-2.6.25/net/netfilter/Kconfig @@ -411,6 +411,14 @@ config NETFILTER_XT_TARGET_TCPMSS To compile it as a module, choose M here. If unsure, say N. +config NETFILTER_XT_TARGET_TOS + tristate '"TOS" target support' + depends on NETFILTER_XTABLES + ---help--- + This option adds a "TOS" target, which allows you to create rules in + the "mangle" table to alter the Type Of Service field of an IPv4 + packet or the Traffic Class field of an IPv6 packet prior to routing. + config NETFILTER_XT_MATCH_COMMENT tristate '"comment" match support' depends on NETFILTER_XTABLES Index: net-2.6.25/net/netfilter/Makefile =================================================================== --- net-2.6.25.orig/net/netfilter/Makefile +++ net-2.6.25/net/netfilter/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o +obj-$(CONFIG_NETFILTER_XT_TARGET_TOS) += xt_TOS.o obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o # matches Index: net-2.6.25/net/netfilter/xt_TOS.c =================================================================== --- /dev/null +++ net-2.6.25/net/netfilter/xt_TOS.c @@ -0,0 +1,160 @@ +/* This is a module which is used for setting the TOS field of a packet. */ + +/* (C) 1999-2001 Paul `Rusty' Russell + * (C) 2002-2004 Netfilter Core Team <coreteam@xxxxxxxxxxxxx> + * © 2007 CC Computer Consultants GmbH <jengelh@xxxxxxxxxxxxxxx> + * + * 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. + */ + +#include <linux/module.h> +#include <linux/skbuff.h> +#include <linux/ip.h> +#include <linux/ipv6.h> +#include <net/checksum.h> +#include <linux/netfilter/x_tables.h> +#include <linux/netfilter/xt_TOS.h> +#include <linux/netfilter_ipv4/ipt_TOS.h> + +static unsigned int +tos_tg4_v0(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 ipt_tos_target_info *info = targinfo; + struct iphdr *iph = ip_hdr(skb); + u_int8_t old_tos; + + if ((iph->tos & IPTOS_TOS_MASK) == info->tos) + return XT_CONTINUE; + + if (!skb_make_writable(skb, sizeof(struct iphdr))) + return NF_DROP; + + iph = ip_hdr(skb); + old_tos = iph->tos; + iph->tos = (iph->tos & IPTOS_PREC_MASK) | info->tos; + nf_csum_replace2(&iph->check, htons(old_tos), htons(iph->tos)); + return XT_CONTINUE; +} + +static unsigned int +tos_tg4(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 old_tos; + + if (!skb_make_writable(skb, sizeof(struct iphdr))) + return NF_DROP; + + iph = ip_hdr(skb); + old_tos = iph->tos; + iph->tos &= info->tos_mask; + iph->tos ^= info->tos_value; + nf_csum_replace2(&iph->check, htons(old_tos), htons(iph->tos)); + 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); + + if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) + return NF_DROP; + + iph = ipv6_hdr(skb); + iph->priority &= info->tos_mask; + iph->priority ^= info->tos_value; + return XT_CONTINUE; +} + +static bool +tos_tg4_check_v0(const char *tablename, const void *e_void, + const struct xt_target *target, void *targinfo, + unsigned int hook_mask) +{ + const struct ipt_tos_target_info *info = targinfo; + + if ((info->tos & ~IPTOS_TOS_MASK) != 0) { + printk(KERN_WARNING KBUILD_MODNAME + ": Bad TOS value %#x\n", info->tos); + return false; + } + + return true; +} + +static bool +tos_tg6_check(const char *tablename, const void *e_void, + const struct xt_target *target, void *targinfo, + unsigned int hook_mask) +{ + const struct xt_tos_target_info *info = targinfo; + + if (info->tos_mask > 0xF || info->tos_value > 0xF) { + printk(KERN_WARNING KBUILD_MODNAME + ": Traffic Class field may only take values 0-15\n"); + return false; + } + + return true; +} + +static struct xt_target tos_tg_reg[] __read_mostly = { + { + .name = "TOS", + .revision = 0, + .family = AF_INET, + .target = tos_tg4_v0, + .targetsize = sizeof(struct ipt_tos_target_info), + .table = "mangle", + .checkentry = tos_tg4_check_v0, + .me = THIS_MODULE, + }, + { + .name = "TOS", + .revision = 1, + .family = AF_INET, + .target = tos_tg4, + .targetsize = sizeof(struct xt_tos_target_info), + .table = "mangle", + .me = THIS_MODULE, + }, + { + .name = "TOS", + .revision = 1, + .family = AF_INET6, + .target = tos_tg6, + .targetsize = sizeof(struct xt_tos_target_info), + .checkentry = tos_tg6_check, + .table = "mangle", + .me = THIS_MODULE, + }, +}; + +static int __init tos_tg_init(void) +{ + return xt_register_targets(tos_tg_reg, ARRAY_SIZE(tos_tg_reg)); +} + +static void __exit tos_tg_exit(void) +{ + xt_unregister_targets(tos_tg_reg, ARRAY_SIZE(tos_tg_reg)); +} + +module_init(tos_tg_init); +module_exit(tos_tg_exit); +MODULE_AUTHOR("Netfilter Core Team <coreteam@xxxxxxxxxxxxx>"); +MODULE_DESCRIPTION("netfilter \"TOS\" target module"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("ipt_TOS"); +MODULE_ALIAS("ip6t_TOS"); - To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html