Commit e7afb958 authored by Jakub Kicinski's avatar Jakub Kicinski

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.netSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents ba7a0f44 536b97ac
...@@ -41,6 +41,16 @@ definitions: ...@@ -41,6 +41,16 @@ definitions:
- in-hw - in-hw
- not-in-nw - not-in-nw
- verbose - verbose
-
name: tc-flower-key-ctrl-flags
type: flags
entries:
- frag
- firstfrag
- tuncsum
- tundf
- tunoam
- tuncrit
- -
name: tc-stats name: tc-stats
type: struct type: struct
...@@ -2536,10 +2546,14 @@ attribute-sets: ...@@ -2536,10 +2546,14 @@ attribute-sets:
name: key-flags name: key-flags
type: u32 type: u32
byte-order: big-endian byte-order: big-endian
enum: tc-flower-key-ctrl-flags
enum-as-flags: true
- -
name: key-flags-mask name: key-flags-mask
type: u32 type: u32
byte-order: big-endian byte-order: big-endian
enum: tc-flower-key-ctrl-flags
enum-as-flags: true
- -
name: key-icmpv4-code name: key-icmpv4-code
type: u8 type: u8
...@@ -2749,6 +2763,18 @@ attribute-sets: ...@@ -2749,6 +2763,18 @@ attribute-sets:
name: key-spi-mask name: key-spi-mask
type: u32 type: u32
byte-order: big-endian byte-order: big-endian
-
name: key-enc-flags
type: u32
byte-order: big-endian
enum: tc-flower-key-ctrl-flags
enum-as-flags: true
-
name: key-enc-flags-mask
type: u32
byte-order: big-endian
enum: tc-flower-key-ctrl-flags
enum-as-flags: true
- -
name: tc-flower-key-enc-opts-attrs name: tc-flower-key-enc-opts-attrs
attributes: attributes:
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <linux/siphash.h> #include <linux/siphash.h>
#include <linux/string.h> #include <linux/string.h>
#include <uapi/linux/if_ether.h> #include <uapi/linux/if_ether.h>
#include <uapi/linux/pkt_cls.h>
struct bpf_prog; struct bpf_prog;
struct net; struct net;
...@@ -16,7 +17,8 @@ struct sk_buff; ...@@ -16,7 +17,8 @@ struct sk_buff;
* struct flow_dissector_key_control: * struct flow_dissector_key_control:
* @thoff: Transport header offset * @thoff: Transport header offset
* @addr_type: Type of key. One of FLOW_DISSECTOR_KEY_* * @addr_type: Type of key. One of FLOW_DISSECTOR_KEY_*
* @flags: Key flags. Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAGENCAPSULATION) * @flags: Key flags.
* Any of FLOW_DIS_(IS_FRAGMENT|FIRST_FRAG|ENCAPSULATION|F_*)
*/ */
struct flow_dissector_key_control { struct flow_dissector_key_control {
u16 thoff; u16 thoff;
...@@ -24,9 +26,20 @@ struct flow_dissector_key_control { ...@@ -24,9 +26,20 @@ struct flow_dissector_key_control {
u32 flags; u32 flags;
}; };
#define FLOW_DIS_IS_FRAGMENT BIT(0) /* The control flags are kept in sync with TCA_FLOWER_KEY_FLAGS_*, as those
#define FLOW_DIS_FIRST_FRAG BIT(1) * flags are exposed to userspace in some error paths, ie. unsupported flags.
#define FLOW_DIS_ENCAPSULATION BIT(2) */
enum flow_dissector_ctrl_flags {
FLOW_DIS_IS_FRAGMENT = TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT,
FLOW_DIS_FIRST_FRAG = TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST,
FLOW_DIS_F_TUNNEL_CSUM = TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM,
FLOW_DIS_F_TUNNEL_DONT_FRAGMENT = TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT,
FLOW_DIS_F_TUNNEL_OAM = TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM,
FLOW_DIS_F_TUNNEL_CRIT_OPT = TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT,
/* These flags are internal to the kernel */
FLOW_DIS_ENCAPSULATION = (TCA_FLOWER_KEY_FLAGS_MAX << 1),
};
enum flow_dissect_ret { enum flow_dissect_ret {
FLOW_DISSECT_RET_OUT_GOOD, FLOW_DISSECT_RET_OUT_GOOD,
...@@ -329,14 +342,6 @@ struct flow_dissector_key_cfm { ...@@ -329,14 +342,6 @@ struct flow_dissector_key_cfm {
#define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5) #define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
#define FLOW_DIS_CFM_MDL_MAX 7 #define FLOW_DIS_CFM_MDL_MAX 7
/**
* struct flow_dissector_key_enc_flags: tunnel metadata control flags
* @flags: tunnel control flags
*/
struct flow_dissector_key_enc_flags {
u32 flags;
};
enum flow_dissector_key_id { enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */ FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */ FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
...@@ -371,7 +376,6 @@ enum flow_dissector_key_id { ...@@ -371,7 +376,6 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */ FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */ FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */ FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */
FLOW_DISSECTOR_KEY_ENC_FLAGS, /* struct flow_dissector_key_enc_flags */
FLOW_DISSECTOR_KEY_MAX, FLOW_DISSECTOR_KEY_MAX,
}; };
......
...@@ -247,18 +247,6 @@ static inline bool ip_tunnel_is_options_present(const unsigned long *flags) ...@@ -247,18 +247,6 @@ static inline bool ip_tunnel_is_options_present(const unsigned long *flags)
return ip_tunnel_flags_intersect(flags, present); return ip_tunnel_flags_intersect(flags, present);
} }
static inline void ip_tunnel_set_encflags_present(unsigned long *flags)
{
IP_TUNNEL_DECLARE_FLAGS(present) = { };
__set_bit(IP_TUNNEL_CSUM_BIT, present);
__set_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, present);
__set_bit(IP_TUNNEL_OAM_BIT, present);
__set_bit(IP_TUNNEL_CRIT_OPT_BIT, present);
ip_tunnel_flags_or(flags, flags, present);
}
static inline bool ip_tunnel_flags_is_be16_compat(const unsigned long *flags) static inline bool ip_tunnel_flags_is_be16_compat(const unsigned long *flags)
{ {
IP_TUNNEL_DECLARE_FLAGS(supp) = { }; IP_TUNNEL_DECLARE_FLAGS(supp) = { };
......
...@@ -554,8 +554,8 @@ enum { ...@@ -554,8 +554,8 @@ enum {
TCA_FLOWER_KEY_SPI, /* be32 */ TCA_FLOWER_KEY_SPI, /* be32 */
TCA_FLOWER_KEY_SPI_MASK, /* be32 */ TCA_FLOWER_KEY_SPI_MASK, /* be32 */
TCA_FLOWER_KEY_ENC_FLAGS, /* u32 */ TCA_FLOWER_KEY_ENC_FLAGS, /* be32 */
TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* u32 */ TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* be32 */
__TCA_FLOWER_MAX, __TCA_FLOWER_MAX,
}; };
...@@ -677,8 +677,15 @@ enum { ...@@ -677,8 +677,15 @@ enum {
enum { enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0), TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1), TCA_FLOWER_KEY_FLAGS_FRAG_IS_FIRST = (1 << 1),
TCA_FLOWER_KEY_FLAGS_TUNNEL_CSUM = (1 << 2),
TCA_FLOWER_KEY_FLAGS_TUNNEL_DONT_FRAGMENT = (1 << 3),
TCA_FLOWER_KEY_FLAGS_TUNNEL_OAM = (1 << 4),
TCA_FLOWER_KEY_FLAGS_TUNNEL_CRIT_OPT = (1 << 5),
__TCA_FLOWER_KEY_FLAGS_MAX,
}; };
#define TCA_FLOWER_KEY_FLAGS_MAX (__TCA_FLOWER_KEY_FLAGS_MAX - 1)
enum { enum {
TCA_FLOWER_KEY_CFM_OPT_UNSPEC, TCA_FLOWER_KEY_CFM_OPT_UNSPEC,
TCA_FLOWER_KEY_CFM_MD_LEVEL, TCA_FLOWER_KEY_CFM_MD_LEVEL,
......
...@@ -299,9 +299,10 @@ void skb_flow_dissect_meta(const struct sk_buff *skb, ...@@ -299,9 +299,10 @@ void skb_flow_dissect_meta(const struct sk_buff *skb,
EXPORT_SYMBOL(skb_flow_dissect_meta); EXPORT_SYMBOL(skb_flow_dissect_meta);
static void static void
skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type, skb_flow_dissect_set_enc_control(enum flow_dissector_key_id type,
struct flow_dissector *flow_dissector, u32 ctrl_flags,
void *target_container) struct flow_dissector *flow_dissector,
void *target_container)
{ {
struct flow_dissector_key_control *ctrl; struct flow_dissector_key_control *ctrl;
...@@ -312,6 +313,7 @@ skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type, ...@@ -312,6 +313,7 @@ skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
FLOW_DISSECTOR_KEY_ENC_CONTROL, FLOW_DISSECTOR_KEY_ENC_CONTROL,
target_container); target_container);
ctrl->addr_type = type; ctrl->addr_type = type;
ctrl->flags = ctrl_flags;
} }
void void
...@@ -367,6 +369,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, ...@@ -367,6 +369,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
{ {
struct ip_tunnel_info *info; struct ip_tunnel_info *info;
struct ip_tunnel_key *key; struct ip_tunnel_key *key;
u32 ctrl_flags = 0;
/* A quick check to see if there might be something to do. */ /* A quick check to see if there might be something to do. */
if (!dissector_uses_key(flow_dissector, if (!dissector_uses_key(flow_dissector,
...@@ -382,9 +385,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, ...@@ -382,9 +385,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
!dissector_uses_key(flow_dissector, !dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IP) && FLOW_DISSECTOR_KEY_ENC_IP) &&
!dissector_uses_key(flow_dissector, !dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_OPTS) && FLOW_DISSECTOR_KEY_ENC_OPTS))
!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_FLAGS))
return; return;
info = skb_tunnel_info(skb); info = skb_tunnel_info(skb);
...@@ -393,11 +394,20 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, ...@@ -393,11 +394,20 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
key = &info->key; key = &info->key;
if (test_bit(IP_TUNNEL_CSUM_BIT, key->tun_flags))
ctrl_flags |= FLOW_DIS_F_TUNNEL_CSUM;
if (test_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, key->tun_flags))
ctrl_flags |= FLOW_DIS_F_TUNNEL_DONT_FRAGMENT;
if (test_bit(IP_TUNNEL_OAM_BIT, key->tun_flags))
ctrl_flags |= FLOW_DIS_F_TUNNEL_OAM;
if (test_bit(IP_TUNNEL_CRIT_OPT_BIT, key->tun_flags))
ctrl_flags |= FLOW_DIS_F_TUNNEL_CRIT_OPT;
switch (ip_tunnel_info_af(info)) { switch (ip_tunnel_info_af(info)) {
case AF_INET: case AF_INET:
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS, skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
flow_dissector, ctrl_flags, flow_dissector,
target_container); target_container);
if (dissector_uses_key(flow_dissector, if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) { FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
struct flow_dissector_key_ipv4_addrs *ipv4; struct flow_dissector_key_ipv4_addrs *ipv4;
...@@ -410,9 +420,9 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, ...@@ -410,9 +420,9 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
} }
break; break;
case AF_INET6: case AF_INET6:
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS, skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
flow_dissector, ctrl_flags, flow_dissector,
target_container); target_container);
if (dissector_uses_key(flow_dissector, if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) { FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
struct flow_dissector_key_ipv6_addrs *ipv6; struct flow_dissector_key_ipv6_addrs *ipv6;
...@@ -424,6 +434,10 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, ...@@ -424,6 +434,10 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
ipv6->dst = key->u.ipv6.dst; ipv6->dst = key->u.ipv6.dst;
} }
break; break;
default:
skb_flow_dissect_set_enc_control(0, ctrl_flags, flow_dissector,
target_container);
break;
} }
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) { 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, ...@@ -477,18 +491,6 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
IP_TUNNEL_GENEVE_OPT_BIT); IP_TUNNEL_GENEVE_OPT_BIT);
enc_opt->dst_opt_type = val < __IP_TUNNEL_FLAG_NUM ? val : 0; enc_opt->dst_opt_type = val < __IP_TUNNEL_FLAG_NUM ? val : 0;
} }
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_ENC_FLAGS)) {
struct flow_dissector_key_enc_flags *enc_flags;
IP_TUNNEL_DECLARE_FLAGS(flags) = {};
enc_flags = skb_flow_dissector_target(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_FLAGS,
target_container);
ip_tunnel_set_encflags_present(flags);
ip_tunnel_flags_and(flags, flags, info->key.tun_flags);
enc_flags->flags = bitmap_read(flags, IP_TUNNEL_CSUM_BIT, 32);
}
} }
EXPORT_SYMBOL(skb_flow_dissect_tunnel_info); EXPORT_SYMBOL(skb_flow_dissect_tunnel_info);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment