@@ -1422,6 +1422,26 @@ static int fl_set_key_ct(struct nlattr **tb,
return 0;
}
+#define FL_KEY_MEMBER_OFFSET(member) offsetof(struct fl_flow_key, member)
+#define FL_KEY_MEMBER_SIZE(member) sizeof_field(struct fl_flow_key, member)
+
+#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 { \
+ keys[cnt].key_id = id; \
+ keys[cnt].offset = FL_KEY_MEMBER_OFFSET(member); \
+ cnt++; \
+ } while (0)
+
+#define FL_KEY_SET_IF_MASKED(mask, keys, cnt, id, member) \
+ do { \
+ if (FL_KEY_IS_MASKED(mask, member)) \
+ FL_KEY_SET(keys, cnt, id, member); \
+ } while (0)
+
static int fl_set_key(struct net *net, struct nlattr **tb,
struct fl_flow_key *key, struct fl_flow_key *mask,
struct netlink_ext_ack *extack)
@@ -1484,23 +1504,27 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
}
if (tb[TCA_FLOWER_KEY_IPV4_SRC] || tb[TCA_FLOWER_KEY_IPV4_DST]) {
- key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
- mask->control.addr_type = ~0;
fl_set_key_val(tb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC,
&mask->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC_MASK,
sizeof(key->ipv4.src));
fl_set_key_val(tb, &key->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST,
&mask->ipv4.dst, TCA_FLOWER_KEY_IPV4_DST_MASK,
sizeof(key->ipv4.dst));
+ if (FL_KEY_IS_MASKED(mask, ipv4)) {
+ key->control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+ mask->control.addr_type = ~0;
+ }
} else if (tb[TCA_FLOWER_KEY_IPV6_SRC] || tb[TCA_FLOWER_KEY_IPV6_DST]) {
- key->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
- mask->control.addr_type = ~0;
fl_set_key_val(tb, &key->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC,
&mask->ipv6.src, TCA_FLOWER_KEY_IPV6_SRC_MASK,
sizeof(key->ipv6.src));
fl_set_key_val(tb, &key->ipv6.dst, TCA_FLOWER_KEY_IPV6_DST,
&mask->ipv6.dst, TCA_FLOWER_KEY_IPV6_DST_MASK,
sizeof(key->ipv6.dst));
+ if (FL_KEY_IS_MASKED(mask, ipv6)) {
+ key->control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+ mask->control.addr_type = ~0;
+ }
}
if (key->basic.ip_proto == IPPROTO_TCP) {
@@ -1581,8 +1605,6 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
if (tb[TCA_FLOWER_KEY_ENC_IPV4_SRC] ||
tb[TCA_FLOWER_KEY_ENC_IPV4_DST]) {
- key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV4_ADDRS;
- mask->enc_control.addr_type = ~0;
fl_set_key_val(tb, &key->enc_ipv4.src,
TCA_FLOWER_KEY_ENC_IPV4_SRC,
&mask->enc_ipv4.src,
@@ -1593,12 +1615,15 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
&mask->enc_ipv4.dst,
TCA_FLOWER_KEY_ENC_IPV4_DST_MASK,
sizeof(key->enc_ipv4.dst));
+ if (FL_KEY_IS_MASKED(mask, enc_ipv4)) {
+ key->enc_control.addr_type =
+ FLOW_DISSECTOR_KEY_IPV4_ADDRS;
+ mask->enc_control.addr_type = ~0;
+ }
}
if (tb[TCA_FLOWER_KEY_ENC_IPV6_SRC] ||
tb[TCA_FLOWER_KEY_ENC_IPV6_DST]) {
- key->enc_control.addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
- mask->enc_control.addr_type = ~0;
fl_set_key_val(tb, &key->enc_ipv6.src,
TCA_FLOWER_KEY_ENC_IPV6_SRC,
&mask->enc_ipv6.src,
@@ -1609,6 +1634,11 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
&mask->enc_ipv6.dst,
TCA_FLOWER_KEY_ENC_IPV6_DST_MASK,
sizeof(key->enc_ipv6.dst));
+ if (FL_KEY_IS_MASKED(mask, enc_ipv6)) {
+ key->enc_control.addr_type =
+ FLOW_DISSECTOR_KEY_IPV6_ADDRS;
+ mask->enc_control.addr_type = ~0;
+ }
}
fl_set_key_val(tb, &key->enc_key_id.keyid, TCA_FLOWER_KEY_ENC_KEY_ID,
@@ -1667,26 +1697,6 @@ static int fl_init_mask_hashtable(struct fl_flow_mask *mask)
return rhashtable_init(&mask->ht, &mask->filter_ht_params);
}
-#define FL_KEY_MEMBER_OFFSET(member) offsetof(struct fl_flow_key, member)
-#define FL_KEY_MEMBER_SIZE(member) sizeof_field(struct fl_flow_key, member)
-
-#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 { \
- keys[cnt].key_id = id; \
- keys[cnt].offset = FL_KEY_MEMBER_OFFSET(member); \
- cnt++; \
- } while(0);
-
-#define FL_KEY_SET_IF_MASKED(mask, keys, cnt, id, member) \
- do { \
- if (FL_KEY_IS_MASKED(mask, member)) \
- FL_KEY_SET(keys, cnt, id, member); \
- } while(0);
-
static void fl_init_dissector(struct flow_dissector *dissector,
struct fl_flow_key *mask)
{