diff mbox series

[ovs-dev,19/62] netdev-offload-dpdk: add vxlan decap action offloading mechanism

Message ID 20201228092520.11807-20-taoyunxiang@cmss.chinamobile.com
State Not Applicable
Headers show
Series DPDK Offload API to test | expand

Commit Message

Tao YunXiang Dec. 28, 2020, 9:24 a.m. UTC
From: Liuchang <liuchang@cmss.chinamobile.com>

Code Source From: Self Code
Description:

    add vxlan decap action offloading mechanism

Jira:  #[Optional]
市场项目编号(名称):[Optional]
---
 lib/dpif-netdev.c         |  1 -
 lib/netdev-offload-dpdk.c | 51 +++++++++++++++++++++++++++++++++++++++++++++--
 lib/netdev-offload.h      |  1 +
 3 files changed, 50 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index ce6ba27..74ceadc 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -2399,7 +2399,6 @@  static int
 dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload)
 {
     struct dp_netdev_pmd_thread *pmd = offload->pmd;
-    const struct dpif_class *dpif_class = pmd->dp->class;
     struct dp_netdev_flow *flow = offload->flow;
     odp_port_t in_port = flow->flow.in_port.odp_port;
     const char *dpif_type_str = dpif_normalize_type(pmd->dp->class->type);
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 970eada..96a295f 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -419,6 +419,8 @@  dump_flow_action(struct ds *s, const struct rte_flow_action *actions)
         while (items && items->type != RTE_FLOW_ITEM_TYPE_END) {
             dump_flow_pattern(s, items++);
         }
+    } else if (actions->type == RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) {
+        ds_put_format(s, "vxlan-decap: nop\n");
     } else if (actions->type == RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN) {
         const struct rte_flow_action_of_push_vlan *vlan_tci = actions->conf;
          
@@ -627,8 +629,40 @@  free_flow_actions(struct flow_actions *actions)
 }
 
 static int
+parse_vxlan_match(struct flow_patterns *patterns,
+                  const struct match *match)
+{
+    struct rte_flow_item_vxlan *vx_spec, *vx_mask;
+
+    if (is_all_zeros(&match->wc.masks.tunnel, sizeof match->wc.masks.tunnel)) {
+        return 0;
+    }
+
+    /* no need to tranmit layer2/layer3/layer4 as 
+     * for outer key fpga only support vni */
+    /* 
+    ret = parse_tnl_ip_match(patterns, match, IPPROTO_UDP); 
+    parse_tnl_udp_match(patterns, match);
+     */
+
+    /* VXLAN */
+    vx_spec = xzalloc(sizeof *vx_spec);
+    vx_mask = xzalloc(sizeof *vx_mask);
+
+    put_unaligned_be32((ovs_be32 *)vx_spec->vni,
+                       htonl(ntohll(match->flow.tunnel.tun_id) << 8));
+    put_unaligned_be32((ovs_be32 *)vx_mask->vni,
+                       htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8));
+
+    add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask);
+    return 0;
+}
+
+static int
 parse_flow_match(struct flow_patterns *patterns,
-                 const struct match *match)
+                 const struct match *match,
+                 struct netdev *netdev,
+                 struct offload_info *info)
 {
     uint8_t *next_proto_mask = NULL;
     uint8_t proto = 0;
@@ -643,6 +677,15 @@  parse_flow_match(struct flow_patterns *patterns,
     consumed_masks->recirc_id = 0;
     consumed_masks->packet_type = 0;
 
+    if (!strcmp(netdev_get_type(netdev), "vxlan")) {
+        parse_vxlan_match(patterns, match);
+        memset(&consumed_masks->tunnel, 0, sizeof consumed_masks->tunnel);
+        info->vxlan_decap = true;
+    } else if (netdev_vport_is_vport_class(netdev->netdev_class)) {
+        VLOG_DBG("in port (%s) not supported", netdev->name);
+        return -1;
+    }
+
     /* Eth */
     if (!eth_addr_is_zero(match->wc.masks.dl_src) ||
         !eth_addr_is_zero(match->wc.masks.dl_dst)) {
@@ -1289,6 +1332,10 @@  parse_flow_actions(struct netdev *netdev,
         }
     }
 
+    if (info->vxlan_decap) {
+        add_flow_action(actions, RTE_FLOW_ACTION_TYPE_VXLAN_DECAP, NULL);
+        info->vxlan_decap = false;
+    }
     if (nl_actions_len == 0) {
         VLOG_DBG_RL(&rl, "No actions provided");
         return -1;
@@ -1335,7 +1382,7 @@  netdev_offload_dpdk_add_flow(struct netdev *netdev,
     struct rte_flow *flow;
     int ret = 0;
 
-    ret = parse_flow_match(&patterns, match);
+    ret = parse_flow_match(&patterns, match, netdev, info);
     if (ret) {
         goto out;
     }
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index cadbde1..8264e32 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -77,6 +77,7 @@  struct offload_info {
     bool tc_modify_flow_deleted; /* Indicate the tc modify flow put success
                                   * to delete the original flow. */
     bool valid_ucast;            /* flag to judge multicast && broadcast */
+    bool vxlan_decap;            /* flag to turn on vxlan decap */
 };
 
 int netdev_flow_flush(struct netdev *);