|
@@ -25,7 +25,8 @@ MODULE_LICENSE("GPL");
|
|
|
static inline bool match_ip(const struct sk_buff *skb,
|
|
|
const struct ipt_ecn_info *einfo)
|
|
|
{
|
|
|
- return (ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect;
|
|
|
+ return ((ip_hdr(skb)->tos & IPT_ECN_IP_MASK) == einfo->ip_ect) ^
|
|
|
+ !!(einfo->invert & IPT_ECN_OP_MATCH_IP);
|
|
|
}
|
|
|
|
|
|
static inline bool match_tcp(const struct sk_buff *skb,
|
|
@@ -76,8 +77,6 @@ static bool ecn_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
|
|
return false;
|
|
|
|
|
|
if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
|
|
|
- if (ip_hdr(skb)->protocol != IPPROTO_TCP)
|
|
|
- return false;
|
|
|
if (!match_tcp(skb, info, &par->hotdrop))
|
|
|
return false;
|
|
|
}
|
|
@@ -97,7 +96,7 @@ static int ecn_mt_check(const struct xt_mtchk_param *par)
|
|
|
return -EINVAL;
|
|
|
|
|
|
if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR) &&
|
|
|
- ip->proto != IPPROTO_TCP) {
|
|
|
+ (ip->proto != IPPROTO_TCP || ip->invflags & IPT_INV_PROTO)) {
|
|
|
pr_info("cannot match TCP bits in rule for non-tcp packets\n");
|
|
|
return -EINVAL;
|
|
|
}
|