Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'flower-rework-tca_flower_key_enc_flags-usage'

Asbjørn Sloth Tønnesen says:

====================
flower: rework TCA_FLOWER_KEY_ENC_FLAGS usage

This series reworks the recently added TCA_FLOWER_KEY_ENC_FLAGS
attribute, to be more like TCA_FLOWER_KEY_FLAGS, and use the unused
u32 flags field in FLOW_DISSECTOR_KEY_ENC_CONTROL, instead of adding
a new flags field as FLOW_DISSECTOR_KEY_ENC_FLAGS.

I have defined the new FLOW_DIS_F_* and TCA_FLOWER_KEY_FLAGS_*
flags to co-exist with the existing flags, so the meaning
of the flags field in struct flow_dissector_key_control is not
depending on the context it is used in. If we run out of bits
then we can always split them up later, if we really want to.
Future flags might also be valid in both contexts.

iproute2 RFC v2 patch:
https://lore.kernel.org/560bcd549ca8ab24b1ad5abe352580a621f6d426.1720790774.git.dcaratti@redhat.com/

v3: https://lore.kernel.org/20240709163825.1210046-1-ast@fiberby.net/
v2: https://lore.kernel.org/20240705133348.728901-1-ast@fiberby.net/
v1: https://lore.kernel.org/20240703104600.455125-1-ast@fiberby.net/
RFC: https://lore.kernel.org/20240611235355.177667-1-ast@fiberby.net/
====================

Link: https://patch.msgid.link/20240713021911.1631517-1-ast@fiberby.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+177 -120
+26
Documentation/netlink/specs/tc.yaml
··· 42 42 - not-in-nw 43 43 - verbose 44 44 - 45 + name: tc-flower-key-ctrl-flags 46 + type: flags 47 + entries: 48 + - frag 49 + - firstfrag 50 + - tuncsum 51 + - tundf 52 + - tunoam 53 + - tuncrit 54 + - 45 55 name: tc-stats 46 56 type: struct 47 57 members: ··· 2546 2536 name: key-flags 2547 2537 type: u32 2548 2538 byte-order: big-endian 2539 + enum: tc-flower-key-ctrl-flags 2540 + enum-as-flags: true 2549 2541 - 2550 2542 name: key-flags-mask 2551 2543 type: u32 2552 2544 byte-order: big-endian 2545 + enum: tc-flower-key-ctrl-flags 2546 + enum-as-flags: true 2553 2547 - 2554 2548 name: key-icmpv4-code 2555 2549 type: u8 ··· 2763 2749 name: key-spi-mask 2764 2750 type: u32 2765 2751 byte-order: big-endian 2752 + - 2753 + name: key-enc-flags 2754 + type: u32 2755 + byte-order: big-endian 2756 + enum: tc-flower-key-ctrl-flags 2757 + enum-as-flags: true 2758 + - 2759 + name: key-enc-flags-mask 2760 + type: u32 2761 + byte-order: big-endian 2762 + enum: tc-flower-key-ctrl-flags 2763 + enum-as-flags: true 2766 2764 - 2767 2765 name: tc-flower-key-enc-opts-attrs 2768 2766 attributes:
+17 -13
include/net/flow_dissector.h
··· 7 7 #include <linux/siphash.h> 8 8 #include <linux/string.h> 9 9 #include <uapi/linux/if_ether.h> 10 + #include <uapi/linux/pkt_cls.h> 10 11 11 12 struct bpf_prog; 12 13 struct net; ··· 17 16 * struct flow_dissector_key_control: 18 17 * @thoff: Transport header offset 19 18 * @addr_type: Type of key. One of FLOW_DISSECTOR_KEY_* 20 - * @flags: Key flags. Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAGENCAPSULATION) 19 + * @flags: Key flags. 20 + * Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAG|ENCAPSULATION|F_*) 21 21 */ 22 22 struct flow_dissector_key_control { 23 23 u16 thoff; ··· 26 24 u32 flags; 27 25 }; 28 26 29 - #define FLOW_DIS_IS_FRAGMENT BIT(0) 30 - #define FLOW_DIS_FIRST_FRAG BIT(1) 31 - #define FLOW_DIS_ENCAPSULATION BIT(2) 27 + /* The control flags are kept in sync with TCA_FLOWER_KEY_FLAGS_*, as those 28 + * flags are exposed to userspace in some error paths, ie. unsupported flags. 29 + */ 30 + enum flow_dissector_ctrl_flags { 31 + FLOW_DIS_IS_FRAGMENT = TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT, 32 + FLOW_DIS_FIRST_FRAG = TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, 33 + FLOW_DIS_F_TUNNEL_CSUM = TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM, 34 + FLOW_DIS_F_TUNNEL_DONT_FRAGMENT = TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT, 35 + FLOW_DIS_F_TUNNEL_OAM = TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM, 36 + FLOW_DIS_F_TUNNEL_CRIT_OPT = TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT, 37 + 38 + /* These flags are internal to the kernel */ 39 + FLOW_DIS_ENCAPSULATION = (TCA_FLOWER_KEY_FLAGS_MAX << 1), 40 + }; 32 41 33 42 enum flow_dissect_ret { 34 43 FLOW_DISSECT_RET_OUT_GOOD, ··· 342 329 #define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5) 343 330 #define FLOW_DIS_CFM_MDL_MAX 7 344 331 345 - /** 346 - * struct flow_dissector_key_enc_flags: tunnel metadata control flags 347 - * @flags: tunnel control flags 348 - */ 349 - struct flow_dissector_key_enc_flags { 350 - u32 flags; 351 - }; 352 - 353 332 enum flow_dissector_key_id { 354 333 FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */ 355 334 FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */ ··· 376 371 FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */ 377 372 FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */ 378 373 FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */ 379 - FLOW_DISSECTOR_KEY_ENC_FLAGS, /* struct flow_dissector_key_enc_flags */ 380 374 381 375 FLOW_DISSECTOR_KEY_MAX, 382 376 };
-12
include/net/ip_tunnels.h
··· 247 247 return ip_tunnel_flags_intersect(flags, present); 248 248 } 249 249 250 - static inline void ip_tunnel_set_encflags_present(unsigned long *flags) 251 - { 252 - IP_TUNNEL_DECLARE_FLAGS(present) = { }; 253 - 254 - __set_bit(IP_TUNNEL_CSUM_BIT, present); 255 - __set_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, present); 256 - __set_bit(IP_TUNNEL_OAM_BIT, present); 257 - __set_bit(IP_TUNNEL_CRIT_OPT_BIT, present); 258 - 259 - ip_tunnel_flags_or(flags, flags, present); 260 - } 261 - 262 250 static inline bool ip_tunnel_flags_is_be16_compat(const unsigned long *flags) 263 251 { 264 252 IP_TUNNEL_DECLARE_FLAGS(supp) = { };
+9 -2
include/uapi/linux/pkt_cls.h
··· 554 554 TCA_FLOWER_KEY_SPI, /* be32 */ 555 555 TCA_FLOWER_KEY_SPI_MASK, /* be32 */ 556 556 557 - TCA_FLOWER_KEY_ENC_FLAGS, /* u32 */ 558 - TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* u32 */ 557 + TCA_FLOWER_KEY_ENC_FLAGS, /* be32 */ 558 + TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* be32 */ 559 559 560 560 __TCA_FLOWER_MAX, 561 561 }; ··· 677 677 enum { 678 678 TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), 679 679 TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), 680 + TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM = (1 << 2), 681 + TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT = (1 << 3), 682 + TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM = (1 << 4), 683 + TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT = (1 << 5), 684 + __TCA_FLOWER_KEY_FLAGS_MAX, 680 685 }; 686 + 687 + #define TCA_FLOWER_KEY_FLAGS_MAX (__TCA_FLOWER_KEY_FLAGS_MAX - 1) 681 688 682 689 enum { 683 690 TCA_FLOWER_KEY_CFM_OPT_UNSPEC,
+26 -24
net/core/flow_dissector.c
··· 299 299 EXPORT_SYMBOL(skb_flow_dissect_meta); 300 300 301 301 static void 302 - skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type, 303 - struct flow_dissector *flow_dissector, 304 - void *target_container) 302 + skb_flow_dissect_set_enc_control(enum flow_dissector_key_id type, 303 + u32 ctrl_flags, 304 + struct flow_dissector *flow_dissector, 305 + void *target_container) 305 306 { 306 307 struct flow_dissector_key_control *ctrl; 307 308 ··· 313 312 FLOW_DISSECTOR_KEY_ENC_CONTROL, 314 313 target_container); 315 314 ctrl->addr_type = type; 315 + ctrl->flags = ctrl_flags; 316 316 } 317 317 318 318 void ··· 369 367 { 370 368 struct ip_tunnel_info *info; 371 369 struct ip_tunnel_key *key; 370 + u32 ctrl_flags = 0; 372 371 373 372 /* A quick check to see if there might be something to do. */ 374 373 if (!dissector_uses_key(flow_dissector, ··· 385 382 !dissector_uses_key(flow_dissector, 386 383 FLOW_DISSECTOR_KEY_ENC_IP) && 387 384 !dissector_uses_key(flow_dissector, 388 - FLOW_DISSECTOR_KEY_ENC_OPTS) && 389 - !dissector_uses_key(flow_dissector, 390 - FLOW_DISSECTOR_KEY_ENC_FLAGS)) 385 + FLOW_DISSECTOR_KEY_ENC_OPTS)) 391 386 return; 392 387 393 388 info = skb_tunnel_info(skb); ··· 394 393 395 394 key = &info->key; 396 395 396 + if (test_bit(IP_TUNNEL_CSUM_BIT, key->tun_flags)) 397 + ctrl_flags |= FLOW_DIS_F_TUNNEL_CSUM; 398 + if (test_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, key->tun_flags)) 399 + ctrl_flags |= FLOW_DIS_F_TUNNEL_DONT_FRAGMENT; 400 + if (test_bit(IP_TUNNEL_OAM_BIT, key->tun_flags)) 401 + ctrl_flags |= FLOW_DIS_F_TUNNEL_OAM; 402 + if (test_bit(IP_TUNNEL_CRIT_OPT_BIT, key->tun_flags)) 403 + ctrl_flags |= FLOW_DIS_F_TUNNEL_CRIT_OPT; 404 + 397 405 switch (ip_tunnel_info_af(info)) { 398 406 case AF_INET: 399 - skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS, 400 - flow_dissector, 401 - target_container); 407 + skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV4_ADDRS, 408 + ctrl_flags, flow_dissector, 409 + target_container); 402 410 if (dissector_uses_key(flow_dissector, 403 411 FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) { 404 412 struct flow_dissector_key_ipv4_addrs *ipv4; ··· 420 410 } 421 411 break; 422 412 case AF_INET6: 423 - skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS, 424 - flow_dissector, 425 - target_container); 413 + skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV6_ADDRS, 414 + ctrl_flags, flow_dissector, 415 + target_container); 426 416 if (dissector_uses_key(flow_dissector, 427 417 FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) { 428 418 struct flow_dissector_key_ipv6_addrs *ipv6; ··· 433 423 ipv6->src = key->u.ipv6.src; 434 424 ipv6->dst = key->u.ipv6.dst; 435 425 } 426 + break; 427 + default: 428 + skb_flow_dissect_set_enc_control(0, ctrl_flags, flow_dissector, 429 + target_container); 436 430 break; 437 431 } 438 432 ··· 490 476 val = find_next_bit(flags, __IP_TUNNEL_FLAG_NUM, 491 477 IP_TUNNEL_GENEVE_OPT_BIT); 492 478 enc_opt->dst_opt_type = val < __IP_TUNNEL_FLAG_NUM ? val : 0; 493 - } 494 - 495 - if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_FLAGS)) { 496 - struct flow_dissector_key_enc_flags *enc_flags; 497 - IP_TUNNEL_DECLARE_FLAGS(flags) = {}; 498 - 499 - enc_flags = skb_flow_dissector_target(flow_dissector, 500 - FLOW_DISSECTOR_KEY_ENC_FLAGS, 501 - target_container); 502 - ip_tunnel_set_encflags_present(flags); 503 - ip_tunnel_flags_and(flags, flags, info->key.tun_flags); 504 - enc_flags->flags = bitmap_read(flags, IP_TUNNEL_CSUM_BIT, 32); 505 479 } 506 480 } 507 481 EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
+99 -69
net/sched/cls_flower.c
··· 41 41 #define TCA_FLOWER_KEY_CT_FLAGS_MASK \ 42 42 (TCA_FLOWER_KEY_CT_FLAGS_MAX - 1) 43 43 44 - #define TUNNEL_FLAGS_PRESENT (\ 45 - _BITUL(IP_TUNNEL_CSUM_BIT) | \ 46 - _BITUL(IP_TUNNEL_DONT_FRAGMENT_BIT) | \ 47 - _BITUL(IP_TUNNEL_OAM_BIT) | \ 48 - _BITUL(IP_TUNNEL_CRIT_OPT_BIT)) 44 + #define TCA_FLOWER_KEY_FLAGS_POLICY_MASK \ 45 + (TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT | \ 46 + TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST) 47 + 48 + #define TCA_FLOWER_KEY_ENC_FLAGS_POLICY_MASK \ 49 + (TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM | \ 50 + TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT | \ 51 + TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM | \ 52 + TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT) 49 53 50 54 struct fl_flow_key { 51 55 struct flow_dissector_key_meta meta; ··· 85 81 struct flow_dissector_key_l2tpv3 l2tpv3; 86 82 struct flow_dissector_key_ipsec ipsec; 87 83 struct flow_dissector_key_cfm cfm; 88 - struct flow_dissector_key_enc_flags enc_flags; 89 84 } __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */ 90 85 91 86 struct fl_flow_mask_range { ··· 679 676 [TCA_FLOWER_KEY_ENC_UDP_SRC_PORT_MASK] = { .type = NLA_U16 }, 680 677 [TCA_FLOWER_KEY_ENC_UDP_DST_PORT] = { .type = NLA_U16 }, 681 678 [TCA_FLOWER_KEY_ENC_UDP_DST_PORT_MASK] = { .type = NLA_U16 }, 682 - [TCA_FLOWER_KEY_FLAGS] = { .type = NLA_U32 }, 683 - [TCA_FLOWER_KEY_FLAGS_MASK] = { .type = NLA_U32 }, 679 + [TCA_FLOWER_KEY_FLAGS] = NLA_POLICY_MASK(NLA_BE32, 680 + TCA_FLOWER_KEY_FLAGS_POLICY_MASK), 681 + [TCA_FLOWER_KEY_FLAGS_MASK] = NLA_POLICY_MASK(NLA_BE32, 682 + TCA_FLOWER_KEY_FLAGS_POLICY_MASK), 684 683 [TCA_FLOWER_KEY_ICMPV4_TYPE] = { .type = NLA_U8 }, 685 684 [TCA_FLOWER_KEY_ICMPV4_TYPE_MASK] = { .type = NLA_U8 }, 686 685 [TCA_FLOWER_KEY_ICMPV4_CODE] = { .type = NLA_U8 }, ··· 744 739 [TCA_FLOWER_KEY_SPI_MASK] = { .type = NLA_U32 }, 745 740 [TCA_FLOWER_L2_MISS] = NLA_POLICY_MAX(NLA_U8, 1), 746 741 [TCA_FLOWER_KEY_CFM] = { .type = NLA_NESTED }, 747 - [TCA_FLOWER_KEY_ENC_FLAGS] = NLA_POLICY_MASK(NLA_U32, 748 - TUNNEL_FLAGS_PRESENT), 749 - [TCA_FLOWER_KEY_ENC_FLAGS_MASK] = NLA_POLICY_MASK(NLA_U32, 750 - TUNNEL_FLAGS_PRESENT), 742 + [TCA_FLOWER_KEY_ENC_FLAGS] = NLA_POLICY_MASK(NLA_BE32, 743 + TCA_FLOWER_KEY_ENC_FLAGS_POLICY_MASK), 744 + [TCA_FLOWER_KEY_ENC_FLAGS_MASK] = NLA_POLICY_MASK(NLA_BE32, 745 + TCA_FLOWER_KEY_ENC_FLAGS_POLICY_MASK), 751 746 }; 752 747 753 748 static const struct nla_policy ··· 1171 1166 } 1172 1167 } 1173 1168 1174 - static int fl_set_key_flags(struct nlattr **tb, u32 *flags_key, 1175 - u32 *flags_mask, struct netlink_ext_ack *extack) 1169 + static int fl_set_key_flags(struct nlattr *tca_opts, struct nlattr **tb, 1170 + bool encap, u32 *flags_key, u32 *flags_mask, 1171 + struct netlink_ext_ack *extack) 1176 1172 { 1173 + int fl_key, fl_mask; 1177 1174 u32 key, mask; 1178 1175 1176 + if (encap) { 1177 + fl_key = TCA_FLOWER_KEY_ENC_FLAGS; 1178 + fl_mask = TCA_FLOWER_KEY_ENC_FLAGS_MASK; 1179 + } else { 1180 + fl_key = TCA_FLOWER_KEY_FLAGS; 1181 + fl_mask = TCA_FLOWER_KEY_FLAGS_MASK; 1182 + } 1183 + 1179 1184 /* mask is mandatory for flags */ 1180 - if (!tb[TCA_FLOWER_KEY_FLAGS_MASK]) { 1185 + if (NL_REQ_ATTR_CHECK(extack, tca_opts, tb, fl_mask)) { 1181 1186 NL_SET_ERR_MSG(extack, "Missing flags mask"); 1182 1187 return -EINVAL; 1183 1188 } 1184 1189 1185 - key = be32_to_cpu(nla_get_be32(tb[TCA_FLOWER_KEY_FLAGS])); 1186 - mask = be32_to_cpu(nla_get_be32(tb[TCA_FLOWER_KEY_FLAGS_MASK])); 1190 + key = be32_to_cpu(nla_get_be32(tb[fl_key])); 1191 + mask = be32_to_cpu(nla_get_be32(tb[fl_mask])); 1187 1192 1188 1193 *flags_key = 0; 1189 1194 *flags_mask = 0; ··· 1203 1188 fl_set_key_flag(key, mask, flags_key, flags_mask, 1204 1189 TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, 1205 1190 FLOW_DIS_FIRST_FRAG); 1191 + 1192 + fl_set_key_flag(key, mask, flags_key, flags_mask, 1193 + TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM, 1194 + FLOW_DIS_F_TUNNEL_CSUM); 1195 + 1196 + fl_set_key_flag(key, mask, flags_key, flags_mask, 1197 + TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT, 1198 + FLOW_DIS_F_TUNNEL_DONT_FRAGMENT); 1199 + 1200 + fl_set_key_flag(key, mask, flags_key, flags_mask, 1201 + TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM, FLOW_DIS_F_TUNNEL_OAM); 1202 + 1203 + fl_set_key_flag(key, mask, flags_key, flags_mask, 1204 + TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT, 1205 + FLOW_DIS_F_TUNNEL_CRIT_OPT); 1206 1206 1207 1207 return 0; 1208 1208 } ··· 1866 1836 return 0; 1867 1837 } 1868 1838 1869 - static int fl_set_key_enc_flags(struct nlattr **tb, u32 *flags_key, 1870 - u32 *flags_mask, struct netlink_ext_ack *extack) 1871 - { 1872 - /* mask is mandatory for flags */ 1873 - if (NL_REQ_ATTR_CHECK(extack, NULL, tb, TCA_FLOWER_KEY_ENC_FLAGS_MASK)) { 1874 - NL_SET_ERR_MSG(extack, "missing enc_flags mask"); 1875 - return -EINVAL; 1876 - } 1877 - 1878 - *flags_key = nla_get_u32(tb[TCA_FLOWER_KEY_ENC_FLAGS]); 1879 - *flags_mask = nla_get_u32(tb[TCA_FLOWER_KEY_ENC_FLAGS_MASK]); 1880 - 1881 - return 0; 1882 - } 1883 - 1884 - static int fl_set_key(struct net *net, struct nlattr **tb, 1885 - struct fl_flow_key *key, struct fl_flow_key *mask, 1886 - struct netlink_ext_ack *extack) 1839 + static int fl_set_key(struct net *net, struct nlattr *tca_opts, 1840 + struct nlattr **tb, struct fl_flow_key *key, 1841 + struct fl_flow_key *mask, struct netlink_ext_ack *extack) 1887 1842 { 1888 1843 __be16 ethertype; 1889 1844 int ret = 0; ··· 2101 2086 return ret; 2102 2087 2103 2088 if (tb[TCA_FLOWER_KEY_FLAGS]) { 2104 - ret = fl_set_key_flags(tb, &key->control.flags, 2089 + ret = fl_set_key_flags(tca_opts, tb, false, 2090 + &key->control.flags, 2105 2091 &mask->control.flags, extack); 2106 2092 if (ret) 2107 2093 return ret; 2108 2094 } 2109 2095 2110 2096 if (tb[TCA_FLOWER_KEY_ENC_FLAGS]) 2111 - ret = fl_set_key_enc_flags(tb, &key->enc_flags.flags, 2112 - &mask->enc_flags.flags, extack); 2097 + ret = fl_set_key_flags(tca_opts, tb, true, 2098 + &key->enc_control.flags, 2099 + &mask->enc_control.flags, extack); 2113 2100 2114 2101 return ret; 2115 2102 } ··· 2202 2185 FL_KEY_SET_IF_MASKED(mask, keys, cnt, 2203 2186 FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, enc_ipv6); 2204 2187 if (FL_KEY_IS_MASKED(mask, enc_ipv4) || 2205 - FL_KEY_IS_MASKED(mask, enc_ipv6)) 2188 + FL_KEY_IS_MASKED(mask, enc_ipv6) || 2189 + FL_KEY_IS_MASKED(mask, enc_control)) 2206 2190 FL_KEY_SET(keys, cnt, FLOW_DISSECTOR_KEY_ENC_CONTROL, 2207 2191 enc_control); 2208 2192 FL_KEY_SET_IF_MASKED(mask, keys, cnt, ··· 2226 2208 FLOW_DISSECTOR_KEY_IPSEC, ipsec); 2227 2209 FL_KEY_SET_IF_MASKED(mask, keys, cnt, 2228 2210 FLOW_DISSECTOR_KEY_CFM, cfm); 2229 - FL_KEY_SET_IF_MASKED(mask, keys, cnt, 2230 - FLOW_DISSECTOR_KEY_ENC_FLAGS, enc_flags); 2231 2211 2232 2212 skb_flow_dissector_init(dissector, keys, cnt); 2233 2213 } ··· 2361 2345 { 2362 2346 struct cls_fl_head *head = fl_head_dereference(tp); 2363 2347 bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL); 2348 + struct nlattr *tca_opts = tca[TCA_OPTIONS]; 2364 2349 struct cls_fl_filter *fold = *arg; 2365 2350 bool bound_to_filter = false; 2366 2351 struct cls_fl_filter *fnew; ··· 2370 2353 bool in_ht; 2371 2354 int err; 2372 2355 2373 - if (!tca[TCA_OPTIONS]) { 2356 + if (!tca_opts) { 2374 2357 err = -EINVAL; 2375 2358 goto errout_fold; 2376 2359 } ··· 2388 2371 } 2389 2372 2390 2373 err = nla_parse_nested_deprecated(tb, TCA_FLOWER_MAX, 2391 - tca[TCA_OPTIONS], fl_policy, NULL); 2374 + tca_opts, fl_policy, NULL); 2392 2375 if (err < 0) 2393 2376 goto errout_tb; 2394 2377 ··· 2464 2447 bound_to_filter = true; 2465 2448 } 2466 2449 2467 - err = fl_set_key(net, tb, &fnew->key, &mask->key, extack); 2450 + err = fl_set_key(net, tca_opts, tb, &fnew->key, &mask->key, extack); 2468 2451 if (err) 2469 2452 goto unbind_filter; 2470 2453 ··· 2804 2787 struct nlattr **tca, 2805 2788 struct netlink_ext_ack *extack) 2806 2789 { 2790 + struct nlattr *tca_opts = tca[TCA_OPTIONS]; 2807 2791 struct fl_flow_tmplt *tmplt; 2808 2792 struct nlattr **tb; 2809 2793 int err; 2810 2794 2811 - if (!tca[TCA_OPTIONS]) 2795 + if (!tca_opts) 2812 2796 return ERR_PTR(-EINVAL); 2813 2797 2814 2798 tb = kcalloc(TCA_FLOWER_MAX + 1, sizeof(struct nlattr *), GFP_KERNEL); 2815 2799 if (!tb) 2816 2800 return ERR_PTR(-ENOBUFS); 2817 2801 err = nla_parse_nested_deprecated(tb, TCA_FLOWER_MAX, 2818 - tca[TCA_OPTIONS], fl_policy, NULL); 2802 + tca_opts, fl_policy, NULL); 2819 2803 if (err) 2820 2804 goto errout_tb; 2821 2805 ··· 2826 2808 goto errout_tb; 2827 2809 } 2828 2810 tmplt->chain = chain; 2829 - err = fl_set_key(net, tb, &tmplt->dummy_key, &tmplt->mask, extack); 2811 + err = fl_set_key(net, tca_opts, tb, &tmplt->dummy_key, 2812 + &tmplt->mask, extack); 2830 2813 if (err) 2831 2814 goto errout_tmplt; 2832 2815 ··· 3103 3084 } 3104 3085 } 3105 3086 3106 - static int fl_dump_key_flags(struct sk_buff *skb, u32 flags_key, u32 flags_mask) 3087 + static int fl_dump_key_flags(struct sk_buff *skb, bool encap, 3088 + u32 flags_key, u32 flags_mask) 3107 3089 { 3108 - u32 key, mask; 3090 + int fl_key, fl_mask; 3109 3091 __be32 _key, _mask; 3092 + u32 key, mask; 3110 3093 int err; 3094 + 3095 + if (encap) { 3096 + fl_key = TCA_FLOWER_KEY_ENC_FLAGS; 3097 + fl_mask = TCA_FLOWER_KEY_ENC_FLAGS_MASK; 3098 + } else { 3099 + fl_key = TCA_FLOWER_KEY_FLAGS; 3100 + fl_mask = TCA_FLOWER_KEY_FLAGS_MASK; 3101 + } 3111 3102 3112 3103 if (!memchr_inv(&flags_mask, 0, sizeof(flags_mask))) 3113 3104 return 0; ··· 3131 3102 TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST, 3132 3103 FLOW_DIS_FIRST_FRAG); 3133 3104 3105 + fl_get_key_flag(flags_key, flags_mask, &key, &mask, 3106 + TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM, 3107 + FLOW_DIS_F_TUNNEL_CSUM); 3108 + 3109 + fl_get_key_flag(flags_key, flags_mask, &key, &mask, 3110 + TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT, 3111 + FLOW_DIS_F_TUNNEL_DONT_FRAGMENT); 3112 + 3113 + fl_get_key_flag(flags_key, flags_mask, &key, &mask, 3114 + TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM, FLOW_DIS_F_TUNNEL_OAM); 3115 + 3116 + fl_get_key_flag(flags_key, flags_mask, &key, &mask, 3117 + TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT, 3118 + FLOW_DIS_F_TUNNEL_CRIT_OPT); 3119 + 3134 3120 _key = cpu_to_be32(key); 3135 3121 _mask = cpu_to_be32(mask); 3136 3122 3137 - err = nla_put(skb, TCA_FLOWER_KEY_FLAGS, 4, &_key); 3123 + err = nla_put(skb, fl_key, 4, &_key); 3138 3124 if (err) 3139 3125 return err; 3140 3126 3141 - return nla_put(skb, TCA_FLOWER_KEY_FLAGS_MASK, 4, &_mask); 3127 + return nla_put(skb, fl_mask, 4, &_mask); 3142 3128 } 3143 3129 3144 3130 static int fl_dump_key_geneve_opt(struct sk_buff *skb, ··· 3368 3324 err_cfm_opts: 3369 3325 nla_nest_cancel(skb, opts); 3370 3326 return err; 3371 - } 3372 - 3373 - static int fl_dump_key_enc_flags(struct sk_buff *skb, 3374 - struct flow_dissector_key_enc_flags *key, 3375 - struct flow_dissector_key_enc_flags *mask) 3376 - { 3377 - if (!memchr_inv(mask, 0, sizeof(*mask))) 3378 - return 0; 3379 - 3380 - if (nla_put_u32(skb, TCA_FLOWER_KEY_ENC_FLAGS, key->flags)) 3381 - return -EMSGSIZE; 3382 - 3383 - if (nla_put_u32(skb, TCA_FLOWER_KEY_ENC_FLAGS_MASK, mask->flags)) 3384 - return -EMSGSIZE; 3385 - 3386 - return 0; 3387 3327 } 3388 3328 3389 3329 static int fl_dump_key_options(struct sk_buff *skb, int enc_opt_type, ··· 3660 3632 if (fl_dump_key_ct(skb, &key->ct, &mask->ct)) 3661 3633 goto nla_put_failure; 3662 3634 3663 - if (fl_dump_key_flags(skb, key->control.flags, mask->control.flags)) 3635 + if (fl_dump_key_flags(skb, false, key->control.flags, 3636 + mask->control.flags)) 3664 3637 goto nla_put_failure; 3665 3638 3666 3639 if (fl_dump_key_val(skb, &key->hash.hash, TCA_FLOWER_KEY_HASH, ··· 3672 3643 if (fl_dump_key_cfm(skb, &key->cfm, &mask->cfm)) 3673 3644 goto nla_put_failure; 3674 3645 3675 - if (fl_dump_key_enc_flags(skb, &key->enc_flags, &mask->enc_flags)) 3646 + if (fl_dump_key_flags(skb, true, key->enc_control.flags, 3647 + mask->enc_control.flags)) 3676 3648 goto nla_put_failure; 3677 3649 3678 3650 return 0;