]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
flow_dissector: add support for tunnel control flags
authorDavide Caratti <dcaratti@redhat.com>
Thu, 30 May 2024 17:08:34 +0000 (19:08 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 4 Jun 2024 09:16:38 +0000 (11:16 +0200)
Dissect [no]csum, [no]dontfrag, [no]oam, [no]crit flags from skb metadata.
This is a prerequisite for matching these control flags using TC flower.

Suggested-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/net/flow_dissector.h
include/net/ip_tunnels.h
net/core/flow_dissector.c

index 9ab376d1a6771a53a4f602262340e57a67847fb2..99626475c3f4aac3132fd3552e30f56bbf1b5052 100644 (file)
@@ -329,6 +329,14 @@ 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 */
@@ -363,6 +371,7 @@ 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,
 };
index 9a6a08ec77139c9bfb1bf70d393fc45bfad8b3e0..5a530d4fb02c68591377f8751520ef4541cb66ae 100644 (file)
@@ -247,6 +247,18 @@ 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) = { };
index f82e9a7d3b379b328c81c5af23be884a05cabaea..59fe46077b3ca311e59a786932e6cda1e9b65446 100644 (file)
@@ -382,7 +382,9 @@ 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))
+                               FLOW_DISSECTOR_KEY_ENC_OPTS) &&
+           !dissector_uses_key(flow_dissector,
+                               FLOW_DISSECTOR_KEY_ENC_FLAGS))
                return;
 
        info = skb_tunnel_info(skb);
@@ -475,6 +477,18 @@ 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);