Skip to content

Commit

Permalink
net_sched: flower: Avoid dissection of unmasked keys
Browse files Browse the repository at this point in the history
The current flower implementation checks the mask range and set all the
keys included in that range as "used_keys", even if a specific key in
the range has a zero mask.

This behavior can cause a false positive return value of
dissector_uses_key function and unnecessary dissection in
__skb_flow_dissect.

This patch checks explicitly the mask of each key and "used_keys" will
be set accordingly.

Fixes: 77b9900 ('tc: introduce Flower classifier')
Signed-off-by: Hadar Hen Zion <hadarh@mellanox.com>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hadar Hen Zion authored and David S. Miller committed Aug 19, 2016
1 parent f6a6692 commit 339ba87
Showing 1 changed file with 13 additions and 15 deletions.
28 changes: 13 additions & 15 deletions net/sched/cls_flower.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,10 @@ static int fl_init_hashtable(struct cls_fl_head *head,

#define FL_KEY_MEMBER_OFFSET(member) offsetof(struct fl_flow_key, member)
#define FL_KEY_MEMBER_SIZE(member) (sizeof(((struct fl_flow_key *) 0)->member))
#define FL_KEY_MEMBER_END_OFFSET(member) \
(FL_KEY_MEMBER_OFFSET(member) + FL_KEY_MEMBER_SIZE(member))

#define FL_KEY_IN_RANGE(mask, member) \
(FL_KEY_MEMBER_OFFSET(member) <= (mask)->range.end && \
FL_KEY_MEMBER_END_OFFSET(member) >= (mask)->range.start)
#define FL_KEY_IS_MASKED(mask, member) \
memchr_inv(((char *)mask) + FL_KEY_MEMBER_OFFSET(member), \
0, FL_KEY_MEMBER_SIZE(member)) \

#define FL_KEY_SET(keys, cnt, id, member) \
do { \
Expand All @@ -418,9 +416,9 @@ static int fl_init_hashtable(struct cls_fl_head *head,
cnt++; \
} while(0);

#define FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt, id, member) \
#define FL_KEY_SET_IF_MASKED(mask, keys, cnt, id, member) \
do { \
if (FL_KEY_IN_RANGE(mask, member)) \
if (FL_KEY_IS_MASKED(mask, member)) \
FL_KEY_SET(keys, cnt, id, member); \
} while(0);

Expand All @@ -432,14 +430,14 @@ static void fl_init_dissector(struct cls_fl_head *head,

FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_CONTROL, control);
FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_BASIC, basic);
FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
FLOW_DISSECTOR_KEY_ETH_ADDRS, eth);
FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4);
FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6);
FL_KEY_SET_IF_IN_RANGE(mask, keys, cnt,
FLOW_DISSECTOR_KEY_PORTS, tp);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_ETH_ADDRS, eth);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_IPV4_ADDRS, ipv4);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_IPV6_ADDRS, ipv6);
FL_KEY_SET_IF_MASKED(&mask->key, keys, cnt,
FLOW_DISSECTOR_KEY_PORTS, tp);

skb_flow_dissector_init(&head->dissector, keys, cnt);
}
Expand Down

0 comments on commit 339ba87

Please sign in to comment.