Convert ipt_TOS to xt_TOS, adding support for IPv6. Signed-off-by: Jan Engelhardt <jengelh@xxxxxxxxxxxxxxx> --- include/linux/netfilter/xt_TOS.h | 12 +++ net/netfilter/Kconfig | 8 ++ net/netfilter/Makefile | 1 net/netfilter/xt_TOS.c | 130 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 151 insertions(+) Index: gitone/include/linux/netfilter/xt_TOS.h =================================================================== --- /dev/null +++ gitone/include/linux/netfilter/xt_TOS.h @@ -0,0 +1,12 @@ +#ifndef _XT_TOS_TARGET_H +#define _XT_TOS_TARGET_H + +#ifndef IPTOS_NORMALSVC +# define IPTOS_NORMALSVC 0 +#endif + +struct xt_TOS_info { + u_int8_t tos_value, tos_mask; +}; + +#endif /* _XT_TOS_TARGET_H */ Index: gitone/net/netfilter/Kconfig =================================================================== --- gitone.orig/net/netfilter/Kconfig +++ gitone/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: gitone/net/netfilter/Makefile =================================================================== --- gitone.orig/net/netfilter/Makefile +++ gitone/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: gitone/net/netfilter/xt_TOS.c =================================================================== --- /dev/null +++ gitone/net/netfilter/xt_TOS.c @@ -0,0 +1,130 @@ +/* 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> + +static unsigned int +xt_TOS_target4(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_info *info = targinfo; + struct iphdr *iph = ip_hdr(skb); + u_int8_t old_tos; + + if ((iph->tos & IPTOS_TOS_MASK) == info->tos_value) + 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) | + ((iph->tos & info->tos_mask) ^ info->tos_value); + nf_csum_replace2(&iph->check, htons(old_tos), htons(iph->tos)); + return XT_CONTINUE; +} + +static unsigned int +xt_TOS_target6(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_info *info = targinfo; + struct ipv6hdr *iph = ipv6_hdr(skb); + + if (iph->priority == info->tos_value) + return XT_CONTINUE; + + 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 +xt_TOS_check(const char *tablename, const void *e_void, + const struct xt_target *target, void *targinfo, + unsigned int hook_mask) +{ + const struct xt_TOS_info *info = targinfo; + + if (target->family == AF_INET6 && info->tos_value > 0xF) { + printk(KERN_WARNING KBUILD_MODNAME + ": Traffic Class field may only take values 0-15\n"); + return false; + } + + if (target->family == AF_INET) { + if ((info->tos_value & ~IPTOS_TOS_MASK) != 0) { + printk(KERN_WARNING KBUILD_MODNAME + ": Bad TOS value %#x\n", info->tos_value); + return false; + } + if ((info->tos_mask & ~IPTOS_TOS_MASK) != 0) { + printk(KERN_WARNING KBUILD_MODNAME + ": Bad mask for TOS operation: %#x\n", + info->tos_mask); + return false; + } + } + + return true; +} + +static struct xt_target xt_TOS_reg[] __read_mostly = { + { + .name = "TOS", + .family = AF_INET, + .target = xt_TOS_target4, + .targetsize = sizeof(struct xt_TOS_info), + .table = "mangle", + .checkentry = xt_TOS_check, + .me = THIS_MODULE, + }, + { + .name = "TOS", + .family = AF_INET6, + .target = xt_TOS_target6, + .targetsize = sizeof(struct xt_TOS_info), + .table = "mangle", + .checkentry = xt_TOS_check, + .me = THIS_MODULE, + }, +}; + +static int __init xt_TOS_init(void) +{ + return xt_register_targets(xt_TOS_reg, ARRAY_SIZE(xt_TOS_reg)); +} + +static void __exit xt_TOS_exit(void) +{ + xt_unregister_targets(xt_TOS_reg, ARRAY_SIZE(xt_TOS_reg)); +} + +module_init(xt_TOS_init); +module_exit(xt_TOS_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