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:
- in-hw
- not-in-nw
- verbose
-
name: tc-flower-key-ctrl-flags
type: flags
entries:
- frag
- firstfrag
- tuncsum
- tundf
- tunoam
- tuncrit
-
name: tc-stats
type: struct
......@@ -2536,10 +2546,14 @@ attribute-sets:
name: key-flags
type: u32
byte-order: big-endian
enum: tc-flower-key-ctrl-flags
enum-as-flags: true
-
name: key-flags-mask
type: u32
byte-order: big-endian
enum: tc-flower-key-ctrl-flags
enum-as-flags: true
-
name: key-icmpv4-code
type: u8
......@@ -2749,6 +2763,18 @@ attribute-sets:
name: key-spi-mask
type: u32
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
attributes:
......
......@@ -7,6 +7,7 @@
#include <linux/siphash.h>
#include <linux/string.h>
#include <uapi/linux/if_ether.h>
#include <uapi/linux/pkt_cls.h>
struct bpf_prog;
struct net;
......@@ -16,7 +17,8 @@ struct sk_buff;
* struct flow_dissector_key_control:
* @thoff: Transport header offset
* @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 {
u16 thoff;
......@@ -24,9 +26,20 @@ struct flow_dissector_key_control {
u32 flags;
};
#define FLOW_DIS_IS_FRAGMENT BIT(0)
#define FLOW_DIS_FIRST_FRAG BIT(1)
#define FLOW_DIS_ENCAPSULATION BIT(2)
/* The control flags are kept in sync with TCA_FLOWER_KEY_FLAGS_*, as those
* flags are exposed to userspace in some error paths, ie. unsupported flags.
*/
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 {
FLOW_DISSECT_RET_OUT_GOOD,
......@@ -329,14 +342,6 @@ struct flow_dissector_key_cfm {
#define FLOW_DIS_CFM_MDL_MASK GENMASK(7, 5)
#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 {
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
......@@ -371,7 +376,6 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */
FLOW_DISSECTOR_KEY_ENC_FLAGS, /* struct flow_dissector_key_enc_flags */
FLOW_DISSECTOR_KEY_MAX,
};
......
......@@ -247,18 +247,6 @@ static inline bool ip_tunnel_is_options_present(const unsigned long *flags)
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)
{
IP_TUNNEL_DECLARE_FLAGS(supp) = { };
......
......@@ -554,8 +554,8 @@ enum {
TCA_FLOWER_KEY_SPI, /* be32 */
TCA_FLOWER_KEY_SPI_MASK, /* be32 */
TCA_FLOWER_KEY_ENC_FLAGS, /* u32 */
TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* u32 */
TCA_FLOWER_KEY_ENC_FLAGS, /* be32 */
TCA_FLOWER_KEY_ENC_FLAGS_MASK, /* be32 */
__TCA_FLOWER_MAX,
};
......@@ -677,8 +677,15 @@ enum {
enum {
TCA_FLOWER_KEY_FLAGS_IS_FRAGMENT = (1 << 0),
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 {
TCA_FLOWER_KEY_CFM_OPT_UNSPEC,
TCA_FLOWER_KEY_CFM_MD_LEVEL,
......
......@@ -299,7 +299,8 @@ void skb_flow_dissect_meta(const struct sk_buff *skb,
EXPORT_SYMBOL(skb_flow_dissect_meta);
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,
u32 ctrl_flags,
struct flow_dissector *flow_dissector,
void *target_container)
{
......@@ -312,6 +313,7 @@ skb_flow_dissect_set_enc_addr_type(enum flow_dissector_key_id type,
FLOW_DISSECTOR_KEY_ENC_CONTROL,
target_container);
ctrl->addr_type = type;
ctrl->flags = ctrl_flags;
}
void
......@@ -367,6 +369,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
{
struct ip_tunnel_info *info;
struct ip_tunnel_key *key;
u32 ctrl_flags = 0;
/* A quick check to see if there might be something to do. */
if (!dissector_uses_key(flow_dissector,
......@@ -382,9 +385,7 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IP) &&
!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_OPTS) &&
!dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_FLAGS))
FLOW_DISSECTOR_KEY_ENC_OPTS))
return;
info = skb_tunnel_info(skb);
......@@ -393,10 +394,19 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
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)) {
case AF_INET:
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
flow_dissector,
skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV4_ADDRS,
ctrl_flags, flow_dissector,
target_container);
if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS)) {
......@@ -410,8 +420,8 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
}
break;
case AF_INET6:
skb_flow_dissect_set_enc_addr_type(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
flow_dissector,
skb_flow_dissect_set_enc_control(FLOW_DISSECTOR_KEY_IPV6_ADDRS,
ctrl_flags, flow_dissector,
target_container);
if (dissector_uses_key(flow_dissector,
FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS)) {
......@@ -424,6 +434,10 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
ipv6->dst = key->u.ipv6.dst;
}
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)) {
......@@ -477,18 +491,6 @@ skb_flow_dissect_tunnel_info(const struct sk_buff *skb,
IP_TUNNEL_GENEVE_OPT_BIT);
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);
......
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