Skip to content

Commit e7afb95

Browse files
committed
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/[email protected]/ v2: https://lore.kernel.org/[email protected]/ v1: https://lore.kernel.org/[email protected]/ RFC: https://lore.kernel.org/[email protected]/ ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents ba7a0f4 + 536b97a commit e7afb95

File tree

6 files changed

+177
-120
lines changed

6 files changed

+177
-120
lines changed

Documentation/netlink/specs/tc.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ definitions:
4141
- in-hw
4242
- not-in-nw
4343
- verbose
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
4454
-
4555
name: tc-stats
4656
type: struct
@@ -2536,10 +2546,14 @@ attribute-sets:
25362546
name: key-flags
25372547
type: u32
25382548
byte-order: big-endian
2549+
enum: tc-flower-key-ctrl-flags
2550+
enum-as-flags: true
25392551
-
25402552
name: key-flags-mask
25412553
type: u32
25422554
byte-order: big-endian
2555+
enum: tc-flower-key-ctrl-flags
2556+
enum-as-flags: true
25432557
-
25442558
name: key-icmpv4-code
25452559
type: u8
@@ -2749,6 +2763,18 @@ attribute-sets:
27492763
name: key-spi-mask
27502764
type: u32
27512765
byte-order: big-endian
2766+
-
2767+
name: key-enc-flags
2768+
type: u32
2769+
byte-order: big-endian
2770+
enum: tc-flower-key-ctrl-flags
2771+
enum-as-flags: true
2772+
-
2773+
name: key-enc-flags-mask
2774+
type: u32
2775+
byte-order: big-endian
2776+
enum: tc-flower-key-ctrl-flags
2777+
enum-as-flags: true
27522778
-
27532779
name: tc-flower-key-enc-opts-attrs
27542780
attributes:

include/net/flow_dissector.h

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/siphash.h>
88
#include <linux/string.h>
99
#include <uapi/linux/if_ether.h>
10+
#include <uapi/linux/pkt_cls.h>
1011

1112
struct bpf_prog;
1213
struct net;
@@ -16,17 +17,29 @@ struct sk_buff;
1617
* struct flow_dissector_key_control:
1718
* @thoff: Transport header offset
1819
* @addr_type: Type of key. One of FLOW_DISSECTOR_KEY_*
19-
* @flags: Key flags. Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAGENCAPSULATION)
20+
* @flags: Key flags.
21+
* Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAG|ENCAPSULATION|F_*)
2022
*/
2123
struct flow_dissector_key_control {
2224
u16 thoff;
2325
u16 addr_type;
2426
u32 flags;
2527
};
2628

27-
#define FLOW_DIS_IS_FRAGMENT BIT(0)
28-
#define FLOW_DIS_FIRST_FRAG BIT(1)
29-
#define FLOW_DIS_ENCAPSULATION BIT(2)
29+
/* The control flags are kept in sync with TCA_FLOWER_KEY_FLAGS_*, as those
30+
* flags are exposed to userspace in some error paths, ie. unsupported flags.
31+
*/
32+
enum flow_dissector_ctrl_flags {
33+
FLOW_DIS_IS_FRAGMENT = TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT,
34+
FLOW_DIS_FIRST_FRAG = TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST,
35+
FLOW_DIS_F_TUNNEL_CSUM = TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM,
36+
FLOW_DIS_F_TUNNEL_DONT_FRAGMENT = TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT,
37+
FLOW_DIS_F_TUNNEL_OAM = TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM,
38+
FLOW_DIS_F_TUNNEL_CRIT_OPT = TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT,
39+
40+
/* These flags are internal to the kernel */
41+
FLOW_DIS_ENCAPSULATION = (TCA_FLOWER_KEY_FLAGS_MAX << 1),
42+
};
3043

3144
enum flow_dissect_ret {
3245
FLOW_DISSECT_RET_OUT_GOOD,
@@ -329,14 +342,6 @@ struct flow_dissector_key_cfm {
329342
#define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
330343
#define FLOW_DIS_CFM_MDL_MAX 7
331344

332-
/**
333-
* struct flow_dissector_key_enc_flags: tunnel metadata control flags
334-
* @flags: tunnel control flags
335-
*/
336-
struct flow_dissector_key_enc_flags {
337-
u32 flags;
338-
};
339-
340345
enum flow_dissector_key_id {
341346
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
342347
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
@@ -371,7 +376,6 @@ enum flow_dissector_key_id {
371376
FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
372377
FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
373378
FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */
374-
FLOW_DISSECTOR_KEY_ENC_FLAGS, /* struct flow_dissector_key_enc_flags */
375379

376380
FLOW_DISSECTOR_KEY_MAX,
377381
};

include/net/ip_tunnels.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -247,18 +247,6 @@ static inline bool ip_tunnel_is_options_present(const unsigned long *flags)
247247
return ip_tunnel_flags_intersect(flags, present);
248248
}
249249

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-
262250
static inline bool ip_tunnel_flags_is_be16_compat(const unsigned long *flags)
263251
{
264252
IP_TUNNEL_DECLARE_FLAGS(supp) = { };

include/uapi/linux/pkt_cls.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -554,8 +554,8 @@ enum {
554554
TCA_FLOWER_KEY_SPI, /* be32 */
555555
TCA_FLOWER_KEY_SPI_MASK, /* be32 */
556556

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 */
559559

560560
__TCA_FLOWER_MAX,
561561
};
@@ -677,8 +677,15 @@ enum {
677677
enum {
678678
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
679679
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,
680685
};
681686

687+
#define TCA_FLOWER_KEY_FLAGS_MAX (__TCA_FLOWER_KEY_FLAGS_MAX - 1)
688+
682689
enum {
683690
TCA_FLOWER_KEY_CFM_OPT_UNSPEC,
684691
TCA_FLOWER_KEY_CFM_MD_LEVEL,

net/core/flow_dissector.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,10 @@ void skb_flow_dissect_meta(const struct sk_buff *skb,
299299
EXPORT_SYMBOL(skb_flow_dissect_meta);
300300

301301
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)
305306
{
306307
struct flow_dissector_key_control *ctrl;
307308

@@ -312,6 +313,7 @@ skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
312313
FLOW_DISSECTOR_KEY_ENC_CONTROL,
313314
target_container);
314315
ctrl->addr_type = type;
316+
ctrl->flags = ctrl_flags;
315317
}
316318

317319
void
@@ -367,6 +369,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
367369
{
368370
struct ip_tunnel_info *info;
369371
struct ip_tunnel_key *key;
372+
u32 ctrl_flags = 0;
370373

371374
/* A quick check to see if there might be something to do. */
372375
if (!dissector_uses_key(flow_dissector,
@@ -382,9 +385,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
382385
!dissector_uses_key(flow_dissector,
383386
FLOW_DISSECTOR_KEY_ENC_IP) &&
384387
!dissector_uses_key(flow_dissector,
385-
FLOW_DISSECTOR_KEY_ENC_OPTS) &&
386-
!dissector_uses_key(flow_dissector,
387-
FLOW_DISSECTOR_KEY_ENC_FLAGS))
388+
FLOW_DISSECTOR_KEY_ENC_OPTS))
388389
return;
389390

390391
info = skb_tunnel_info(skb);
@@ -393,11 +394,20 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
393394

394395
key = &info->key;
395396

397+
if (test_bit(IP_TUNNEL_CSUM_BIT, key->tun_flags))
398+
ctrl_flags |= FLOW_DIS_F_TUNNEL_CSUM;
399+
if (test_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, key->tun_flags))
400+
ctrl_flags |= FLOW_DIS_F_TUNNEL_DONT_FRAGMENT;
401+
if (test_bit(IP_TUNNEL_OAM_BIT, key->tun_flags))
402+
ctrl_flags |= FLOW_DIS_F_TUNNEL_OAM;
403+
if (test_bit(IP_TUNNEL_CRIT_OPT_BIT, key->tun_flags))
404+
ctrl_flags |= FLOW_DIS_F_TUNNEL_CRIT_OPT;
405+
396406
switch (ip_tunnel_info_af(info)) {
397407
case AF_INET:
398-
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
399-
flow_dissector,
400-
target_container);
408+
skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
409+
ctrl_flags, flow_dissector,
410+
target_container);
401411
if (dissector_uses_key(flow_dissector,
402412
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
403413
struct flow_dissector_key_ipv4_addrs *ipv4;
@@ -410,9 +420,9 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
410420
}
411421
break;
412422
case AF_INET6:
413-
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
414-
flow_dissector,
415-
target_container);
423+
skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
424+
ctrl_flags, flow_dissector,
425+
target_container);
416426
if (dissector_uses_key(flow_dissector,
417427
FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
418428
struct flow_dissector_key_ipv6_addrs *ipv6;
@@ -424,6 +434,10 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
424434
ipv6->dst = key->u.ipv6.dst;
425435
}
426436
break;
437+
default:
438+
skb_flow_dissect_set_enc_control(0, ctrl_flags, flow_dissector,
439+
target_container);
440+
break;
427441
}
428442

429443
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
@@ -477,18 +491,6 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
477491
IP_TUNNEL_GENEVE_OPT_BIT);
478492
enc_opt->dst_opt_type = val < __IP_TUNNEL_FLAG_NUM ? val : 0;
479493
}
480-
481-
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_FLAGS)) {
482-
struct flow_dissector_key_enc_flags *enc_flags;
483-
IP_TUNNEL_DECLARE_FLAGS(flags) = {};
484-
485-
enc_flags = skb_flow_dissector_target(flow_dissector,
486-
FLOW_DISSECTOR_KEY_ENC_FLAGS,
487-
target_container);
488-
ip_tunnel_set_encflags_present(flags);
489-
ip_tunnel_flags_and(flags, flags, info->key.tun_flags);
490-
enc_flags->flags = bitmap_read(flags, IP_TUNNEL_CSUM_BIT, 32);
491-
}
492494
}
493495
EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
494496

0 commit comments

Comments
 (0)