diff mbox series

[ovs-dev,v6,8/9] netdev-tc-offloads: Probe for allowing vxlan gbp support

Message ID 20230627104814.2028633-9-roid@nvidia.com
State Accepted
Commit 7f04588d78fe0a571f5107b0d5aeda832383f284
Headers show
Series Add vxlan gbp offload with TC | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test fail github build: failed
ovsrobot/intel-ovs-compilation success test: success

Commit Message

Roi Dayan June 27, 2023, 10:48 a.m. UTC
From: Gavin Li <gavinl@nvidia.com>

Kernels that do not support vxlan gbp would treat the rule that has vxlan
gbp encap action or vxlan gbp id match differently, either reject it or
just skip the action/match and continue processing the knowing ones.

To solve the issue, probe and disallow inserting rules with vxlan gbp
action/match if kernel does not support it.

Signed-off-by: Gavin Li <gavinl@nvidia.com>
Reviewed-by: Roi Dayan <roid@nvidia.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Acked-by: Eelco Chaudron <echaudro@redhat.com>
---
 lib/netdev-offload-tc.c | 64 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 61 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index c43eacd4d94f..b846a63c222f 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -52,6 +52,7 @@  static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid);
 static bool multi_mask_per_prio = false;
 static bool block_support = false;
 static uint16_t ct_state_support;
+static bool vxlan_gbp_support = false;
 
 struct netlink_field {
     int offset;
@@ -668,14 +669,17 @@  static void parse_tc_flower_geneve_opts(struct tc_action *action,
     nl_msg_end_nested(buf, geneve_off);
 }
 
-static void
+static int
 parse_tc_flower_vxlan_tun_opts(struct tc_action *action, struct ofpbuf *buf)
 {
     size_t gbp_off;
     uint32_t gbp_raw;
 
     if (!action->encap.gbp.id_present) {
-        return;
+        return 0;
+    }
+    if (!vxlan_gbp_support) {
+        return -EOPNOTSUPP;
     }
 
     gbp_off = nl_msg_start_nested(buf, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
@@ -683,6 +687,7 @@  parse_tc_flower_vxlan_tun_opts(struct tc_action *action, struct ofpbuf *buf)
                                  action->encap.gbp.id);
     nl_msg_put_u32(buf, OVS_VXLAN_EXT_GBP, gbp_raw);
     nl_msg_end_nested(buf, gbp_off);
+    return 0;
 }
 
 static void
@@ -845,6 +850,7 @@  parse_tc_flower_to_actions__(struct tc_flower *flower, struct ofpbuf *buf,
             size_t set_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SET);
             size_t tunnel_offset =
                 nl_msg_start_nested(buf, OVS_KEY_ATTR_TUNNEL);
+            int ret;
 
             if (action->encap.id_present) {
                 nl_msg_put_be64(buf, OVS_TUNNEL_KEY_ATTR_ID, action->encap.id);
@@ -880,7 +886,10 @@  parse_tc_flower_to_actions__(struct tc_flower *flower, struct ofpbuf *buf,
             if (!action->encap.no_csum) {
                 nl_msg_put_flag(buf, OVS_TUNNEL_KEY_ATTR_CSUM);
             }
-            parse_tc_flower_vxlan_tun_opts(action, buf);
+            ret = parse_tc_flower_vxlan_tun_opts(action, buf);
+            if (ret) {
+                return ret;
+            }
             parse_tc_flower_geneve_opts(action, buf);
             nl_msg_end_nested(buf, tunnel_offset);
             nl_msg_end_nested(buf, set_offset);
@@ -1632,6 +1641,9 @@  parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
         }
         break;
         case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: {
+            if (!vxlan_gbp_support) {
+                return EOPNOTSUPP;
+            }
             if (odp_vxlan_tun_opts_from_attr(tun_attr,
                                              &action->encap.gbp.id,
                                              &action->encap.gbp.flags,
@@ -2787,6 +2799,51 @@  probe_tc_block_support(int ifindex)
     }
 }
 
+static void
+probe_vxlan_gbp_support(int ifindex)
+{
+    struct tc_flower flower;
+    struct tcf_id id;
+    int block_id = 0;
+    int prio = 1;
+    int error;
+
+    error = tc_add_del_qdisc(ifindex, true, block_id, TC_INGRESS);
+    if (error) {
+        return;
+    }
+
+    memset(&flower, 0, sizeof flower);
+
+    flower.tc_policy = TC_POLICY_SKIP_HW;
+    flower.key.eth_type = htons(ETH_P_IP);
+    flower.mask.eth_type = OVS_BE16_MAX;
+    flower.tunnel = true;
+    flower.mask.tunnel.id = OVS_BE64_MAX;
+    flower.mask.tunnel.ipv4.ipv4_src = OVS_BE32_MAX;
+    flower.mask.tunnel.ipv4.ipv4_dst = OVS_BE32_MAX;
+    flower.mask.tunnel.tp_dst = OVS_BE16_MAX;
+    flower.mask.tunnel.gbp.id = OVS_BE16_MAX;
+    flower.key.tunnel.ipv4.ipv4_src = htonl(0x01010101);
+    flower.key.tunnel.ipv4.ipv4_dst = htonl(0x01010102);
+    flower.key.tunnel.tp_dst = htons(46354);
+    flower.key.tunnel.gbp.id = htons(512);
+
+    id = tc_make_tcf_id(ifindex, block_id, prio, TC_INGRESS);
+    error = tc_replace_flower(&id, &flower);
+    if (error) {
+        goto out;
+    }
+
+    tc_del_flower_filter(&id);
+
+    vxlan_gbp_support = true;
+    VLOG_INFO("probe tc: vxlan gbp is supported.");
+
+out:
+    tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS);
+}
+
 static int
 tc_get_policer_action_ids(struct hmap *map)
 {
@@ -2914,6 +2971,7 @@  netdev_tc_init_flow_api(struct netdev *netdev)
 
         probe_multi_mask_per_prio(ifindex);
         probe_ct_state_support(ifindex);
+        probe_vxlan_gbp_support(ifindex);
 
         ovs_mutex_lock(&meter_police_ids_mutex);
         meter_police_ids = id_pool_create(METER_POLICE_IDS_BASE,