commit 97958cdb209a6babc88fdeb10893597dcb8856d5 Author: Kyeong Yoo Date: Mon Jul 27 23:46:05 2015 +1200 [NETFILTER]: support multiple DSCP value match by "-m dscp --dscp-multi" Current "dscp" match supports one DSCP value in a rule. This patch enhances "dscp" match with multiple values: -m dscp --dscp-multi value,value,... As there are 64 values possible in DSCP field (6 bits), list of values are stored in a 64-bit bitmap. Reviewed-by: Luuk Paulussen Reviewed-by: Chris Packham diff --git a/include/uapi/linux/netfilter/xt_dscp.h b/include/uapi/linux/netfilter/xt_dscp.h index 15f8932..bea99fa 100644 --- a/include/uapi/linux/netfilter/xt_dscp.h +++ b/include/uapi/linux/netfilter/xt_dscp.h @@ -16,10 +16,17 @@ #define XT_DSCP_SHIFT 2 #define XT_DSCP_MAX 0x3f /* 00111111 */ +#define dscp_set_bit(bmap, idx) \ + (bmap[(idx) >> 5] |= 1U << (idx & 31)) +#define dscp_test_bit(bmap, idx) \ + (((1U << (idx & 31)) & bmap[(idx) >> 5]) != 0) + /* match info */ struct xt_dscp_info { __u8 dscp; __u8 invert; + __u8 multi; + __u32 dscp_bitmap[(XT_DSCP_MAX >> 5) + 1]; }; struct xt_tos_match_info { diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c index 64670fc..f127f04 100644 --- a/net/netfilter/xt_dscp.c +++ b/net/netfilter/xt_dscp.c @@ -30,6 +30,8 @@ dscp_mt(const struct sk_buff *skb, struct xt_action_param *par) const struct xt_dscp_info *info = par->matchinfo; u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; + if (info->multi) + return (dscp_test_bit(info->dscp_bitmap, dscp) != 0) ^ !!info->invert; return (dscp == info->dscp) ^ !!info->invert; } @@ -39,6 +41,8 @@ dscp_mt6(const struct sk_buff *skb, struct xt_action_param *par) const struct xt_dscp_info *info = par->matchinfo; u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; + if (info->multi) + return (dscp_test_bit(info->dscp_bitmap, dscp) != 0) ^ !!info->invert; return (dscp == info->dscp) ^ !!info->invert; }