diff options
author | Jan Engelhardt <jengelh@computergmbh.de> | 2007-12-04 23:38:30 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 14:56:00 -0800 |
commit | f1095ab51d4297d4a84b64a65c71054183a73486 (patch) | |
tree | 50b3d4fe6d4a23cf5072fd3a92cf935d1545ba57 | |
parent | c9fd49680954714473d6cbd2546d6ff120f96840 (diff) |
[NETFILTER]: IPv6 capable xt_tos v1 match
Extends the xt_dscp match by xt_tos v1 to add support for selectively
matching 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.h | 6 | ||||
-rw-r--r-- | net/netfilter/xt_dscp.c | 32 |
2 files changed, 38 insertions, 0 deletions
diff --git a/include/linux/netfilter/xt_dscp.h b/include/linux/netfilter/xt_dscp.h index 1da61e6acaf..f49bc1a648d 100644 --- a/include/linux/netfilter/xt_dscp.h +++ b/include/linux/netfilter/xt_dscp.h @@ -20,4 +20,10 @@ struct xt_dscp_info { u_int8_t invert; }; +struct xt_tos_match_info { + u_int8_t tos_mask; + u_int8_t tos_value; + u_int8_t invert; +}; + #endif /* _XT_DSCP_H */ diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c index 75b0df990d4..834e4372031 100644 --- a/net/netfilter/xt_dscp.c +++ b/net/netfilter/xt_dscp.c @@ -23,6 +23,7 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("ipt_dscp"); MODULE_ALIAS("ip6t_dscp"); MODULE_ALIAS("ipt_tos"); +MODULE_ALIAS("ip6t_tos"); static bool dscp_mt(const struct sk_buff *skb, const struct net_device *in, @@ -72,6 +73,21 @@ static bool tos_mt_v0(const struct sk_buff *skb, const struct net_device *in, return (ip_hdr(skb)->tos == info->tos) ^ info->invert; } +static bool tos_mt(const struct sk_buff *skb, const struct net_device *in, + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, unsigned int protoff, + bool *hotdrop) +{ + const struct xt_tos_match_info *info = matchinfo; + + if (match->family == AF_INET) + return ((ip_hdr(skb)->tos & info->tos_mask) == + info->tos_value) ^ !!info->invert; + else + return ((ipv6_get_dsfield(ipv6_hdr(skb)) & info->tos_mask) == + info->tos_value) ^ !!info->invert; +} + static struct xt_match dscp_mt_reg[] __read_mostly = { { .name = "dscp", @@ -97,6 +113,22 @@ static struct xt_match dscp_mt_reg[] __read_mostly = { .matchsize = sizeof(struct ipt_tos_info), .me = THIS_MODULE, }, + { + .name = "tos", + .revision = 1, + .family = AF_INET, + .match = tos_mt, + .matchsize = sizeof(struct xt_tos_match_info), + .me = THIS_MODULE, + }, + { + .name = "tos", + .revision = 1, + .family = AF_INET6, + .match = tos_mt, + .matchsize = sizeof(struct xt_tos_match_info), + .me = THIS_MODULE, + }, }; static int __init dscp_mt_init(void) |