X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fnetfilter%2Fxt_dscp.c;h=0280d3a8c16172bc924f53b233c4527fe6b1e7b0;hb=8fea97ec1772bbf553d89187340ef624d548e115;hp=c9c6518907a220c5cb31ca7760b3b05e94a8252e;hpb=1d93a9cbad608f6398ba6c5b588c504ccd35a2ca;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c index c9c6518..0280d3a 100644 --- a/net/netfilter/xt_dscp.c +++ b/net/netfilter/xt_dscp.c @@ -13,89 +13,103 @@ #include #include -#include #include +#include MODULE_AUTHOR("Harald Welte "); -MODULE_DESCRIPTION("x_tables DSCP matching module"); +MODULE_DESCRIPTION("Xtables: DSCP/TOS field match"); MODULE_LICENSE("GPL"); MODULE_ALIAS("ipt_dscp"); MODULE_ALIAS("ip6t_dscp"); +MODULE_ALIAS("ipt_tos"); +MODULE_ALIAS("ip6t_tos"); -static bool match(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) +static bool +dscp_mt(const struct sk_buff *skb, const struct xt_match_param *par) { - const struct xt_dscp_info *info = matchinfo; + const struct xt_dscp_info *info = par->matchinfo; u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; return (dscp == info->dscp) ^ !!info->invert; } -static bool match6(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) +static bool +dscp_mt6(const struct sk_buff *skb, const struct xt_match_param *par) { - const struct xt_dscp_info *info = matchinfo; + const struct xt_dscp_info *info = par->matchinfo; u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; return (dscp == info->dscp) ^ !!info->invert; } -static int checkentry(const char *tablename, - const void *info, - const struct xt_match *match, - void *matchinfo, - unsigned int hook_mask) +static bool dscp_mt_check(const struct xt_mtchk_param *par) { - const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; + const struct xt_dscp_info *info = par->matchinfo; - if (dscp > XT_DSCP_MAX) { - printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); - return 0; + if (info->dscp > XT_DSCP_MAX) { + printk(KERN_ERR "xt_dscp: dscp %x out of range\n", info->dscp); + return false; } - return 1; + return true; +} + +static bool tos_mt(const struct sk_buff *skb, const struct xt_match_param *par) +{ + const struct xt_tos_match_info *info = par->matchinfo; + + if (par->match->family == NFPROTO_IPV4) + 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 xt_dscp_match[] = { +static struct xt_match dscp_mt_reg[] __read_mostly = { { .name = "dscp", - .family = AF_INET, - .checkentry = checkentry, - .match = match, + .family = NFPROTO_IPV4, + .checkentry = dscp_mt_check, + .match = dscp_mt, .matchsize = sizeof(struct xt_dscp_info), .me = THIS_MODULE, }, { .name = "dscp", - .family = AF_INET6, - .checkentry = checkentry, - .match = match6, + .family = NFPROTO_IPV6, + .checkentry = dscp_mt_check, + .match = dscp_mt6, .matchsize = sizeof(struct xt_dscp_info), .me = THIS_MODULE, }, + { + .name = "tos", + .revision = 1, + .family = NFPROTO_IPV4, + .match = tos_mt, + .matchsize = sizeof(struct xt_tos_match_info), + .me = THIS_MODULE, + }, + { + .name = "tos", + .revision = 1, + .family = NFPROTO_IPV6, + .match = tos_mt, + .matchsize = sizeof(struct xt_tos_match_info), + .me = THIS_MODULE, + }, }; -static int __init xt_dscp_match_init(void) +static int __init dscp_mt_init(void) { - return xt_register_matches(xt_dscp_match, ARRAY_SIZE(xt_dscp_match)); + return xt_register_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); } -static void __exit xt_dscp_match_fini(void) +static void __exit dscp_mt_exit(void) { - xt_unregister_matches(xt_dscp_match, ARRAY_SIZE(xt_dscp_match)); + xt_unregister_matches(dscp_mt_reg, ARRAY_SIZE(dscp_mt_reg)); } -module_init(xt_dscp_match_init); -module_exit(xt_dscp_match_fini); +module_init(dscp_mt_init); +module_exit(dscp_mt_exit);