diff mbox series

[ovs-dev,23/62] When vxlan decap vport should be changed to uplink port to call rte_flow_create

Message ID 20201228092520.11807-24-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: Rongyin <rongyin@cmss.chinamobile.com>

Code Source From: Self Code
Description:

    When vxlan decap vport should be changed to uplink port to call rte_flow_create

Jira:  #[Optional]
市场项目编号(名称):[Optional]
---
 lib/netdev-dpdk.c         | 21 +++++++++++
 lib/netdev-dpdk.h         |  3 ++
 lib/netdev-offload-dpdk.c | 91 ++++++++++++++++++++++++++++++-----------------
 lib/netdev-offload.h      |  2 --
 4 files changed, 82 insertions(+), 35 deletions(-)
diff mbox series

Patch

diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c
index 22f7044..cd3d156 100644
--- a/lib/netdev-dpdk.c
+++ b/lib/netdev-dpdk.c
@@ -5328,6 +5328,25 @@  out:
 }
 
 bool
+netdev_dpdk_is_uplink_port(struct netdev *netdev)
+{
+    struct netdev_dpdk *dev;
+    bool ret = false;
+
+    if (!is_dpdk_class(netdev->netdev_class)) {
+        goto out;
+    }
+
+    dev = netdev_dpdk_cast(netdev);
+    ovs_mutex_lock(&dev->mutex);
+    /*ret = dev->is_uplink_port;*/
+    ret = (dev->type == DPDK_DEV_ETH);
+    ovs_mutex_unlock(&dev->mutex);
+out:
+    return ret;
+}
+
+bool
 netdev_dpdk_flow_api_supported(struct netdev *netdev)
 {
     struct netdev_dpdk *dev;
@@ -5378,8 +5397,10 @@  netdev_dpdk_rte_flow_create(struct netdev *netdev,
     struct rte_flow *flow;
     struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
 
+    VLOG_DBG("TIMO DBG: in netdev_dpdk_rte_flow_create");
     ovs_mutex_lock(&dev->mutex);
     flow = rte_flow_create(dev->port_id, attr, items, actions, error);
+    VLOG_DBG("TIMO DBG: after rte_flow_create");
     ovs_mutex_unlock(&dev->mutex);
     return flow;
 }
diff --git a/lib/netdev-dpdk.h b/lib/netdev-dpdk.h
index 848346c..811992c 100644
--- a/lib/netdev-dpdk.h
+++ b/lib/netdev-dpdk.h
@@ -56,6 +56,9 @@  netdev_dpdk_rte_flow_query_count(struct netdev *netdev,
 int
 netdev_dpdk_get_port_id(struct netdev *netdev);
 
+bool
+netdev_dpdk_is_uplink_port(struct netdev *netdev);
+
 #else
 
 static inline void
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index ea1eb2e..445ca22 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -142,6 +142,7 @@  struct flow_actions {
     struct rte_flow_action *actions;
     int cnt;
     int current_max;
+    bool valid_ucast; /* flag to judge multicast && broadcast */
 };
 
 static void
@@ -516,6 +517,7 @@  netdev_offload_dpdk_flow_create(struct netdev *netdev,
     struct rte_flow *flow;
     struct ds s;
 
+    VLOG_DBG("TIMO DBG: in netdev_offload_dpdk_flow_create %s",netdev->name);
     flow = netdev_dpdk_rte_flow_create(netdev, attr, items, actions, error);
     /* work around: for dump_flow even if rte_flow create fail */
     if (!VLOG_DROP_DBG(&rl)) {
@@ -580,6 +582,11 @@  add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type,
 {
     int cnt = actions->cnt;
 
+    if ( (actions->valid_ucast == true) && 
+         (type == RTE_FLOW_ACTION_TYPE_PORT_ID) ) {
+        VLOG_DBG_RL(&rl, "Unsupported multicast output action");
+        return ;
+    }
     if (cnt == 0) {
         actions->current_max = 8;
         actions->actions = xcalloc(actions->current_max,
@@ -593,6 +600,8 @@  add_flow_action(struct flow_actions *actions, enum rte_flow_action_type type,
     actions->actions[cnt].type = type;
     actions->actions[cnt].conf = conf;
     actions->cnt++;
+    actions->valid_ucast = (type == RTE_FLOW_ACTION_TYPE_PORT_ID)? 
+                            true : actions->valid_ucast;
 }
 
 static void
@@ -626,16 +635,17 @@  free_flow_actions(struct flow_actions *actions)
     free(actions->actions);
     actions->actions = NULL;
     actions->cnt = 0;
+    actions->valid_ucast = false;
 }
 
-static void
+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 ;
+        return -1;
     }
     VLOG_DBG("TIMO:in parse_vxlan_match");
 
@@ -656,32 +666,29 @@  parse_vxlan_match(struct flow_patterns *patterns,
                        htonl(ntohll(match->wc.masks.tunnel.tun_id) << 8));
 
     add_flow_pattern(patterns, RTE_FLOW_ITEM_TYPE_VXLAN, vx_spec, vx_mask);
-    return ;
+    return 0;
 }
 
 static int
 parse_flow_match(struct flow_patterns *patterns,
-                 const struct match *match,
+                 struct match *match,
                  struct netdev *netdev,
                  struct offload_info *info)
 {
     uint8_t *next_proto_mask = NULL;
     uint8_t proto = 0;
-    struct match consumed_match;
     struct flow *consumed_masks;
 
-    memcpy(&consumed_match, match, sizeof consumed_match);
 
-    consumed_masks = &(consumed_match.wc.masks);
+    consumed_masks = &match->wc.masks;
     /* Not attemp to offload in_port/recirc_id ?  */
     memset(&consumed_masks->in_port, 0, sizeof consumed_masks->in_port);
     consumed_masks->recirc_id = 0;
     consumed_masks->packet_type = 0;
 
-    if (!strcmp(netdev_get_type(netdev), "vxlan")) {
-        parse_vxlan_match(patterns, match);
+    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;
@@ -946,14 +953,16 @@  netdev_offload_dpdk_mark_rss(struct flow_patterns *patterns,
         .ingress = 1,
         .egress = 0
     };
-    struct rte_flow_error error;
     struct rte_flow *flow;
+    /* work around : not do mark rss action
+    struct rte_flow_error error;
 
     add_flow_mark_rss_actions(&actions, flow_mark, netdev);
 
     flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items,
                                            actions.actions, &error);
 
+    */
     free_flow_actions(&actions);
     return flow;
 }
@@ -973,6 +982,7 @@  add_port_id_action(struct flow_actions *actions,
     struct rte_flow_action_port_id *port_id;
     int outdev_id;
 
+    VLOG_DBG("TIMO DBG: in add_port_id_action");
     outdev_id = netdev_dpdk_get_port_id(outdev);
     if (outdev_id < 0) {
         return -1;
@@ -993,6 +1003,7 @@  add_output_action(struct netdev *netdev,
     odp_port_t port;
     int ret = 0;
 
+    VLOG_DBG("TIMO DBG: in add_output_action");
     port = nl_attr_get_odp_port(nla);
     outdev = netdev_ports_get(port, info->dpif_type_str);
     if (outdev == NULL) {
@@ -1221,6 +1232,13 @@  err:
     return -1;
 }
 
+static void
+add_vxlan_decap_action(struct flow_actions *actions)
+{
+    VLOG_DBG("TIMO DBG: in add_vxlan_decap_action");
+    add_flow_action(actions, RTE_FLOW_ACTION_TYPE_VXLAN_DECAP, NULL);
+}
+
 static int
 parse_clone_actions(struct netdev *netdev,
                     struct flow_actions *actions,
@@ -1248,13 +1266,6 @@  parse_clone_actions(struct netdev *netdev,
             if (add_output_action(netdev, actions, ca, info)) {
                 return -1;
             }
-            /*
-            } else if (info->valid_ucast) {
-                VLOG_DBG_RL(&rl, "Unsupported multicast output action");
-                return -1;
-                info->valid_ucast = true;
-            }
-             */
         } else if (clone_type == OVS_ACTION_ATTR_PUSH_VLAN) {
             const struct ovs_action_push_vlan *vlan = nl_attr_get(ca);
             struct rte_flow_action_of_push_vlan *vlan_tci;
@@ -1288,6 +1299,9 @@  parse_flow_actions(struct netdev *netdev,
     uint8_t i = 0;
     
 
+    if (nl_actions_len != 0 && !strcmp(netdev_get_type(netdev), "vxlan")) {
+        add_vxlan_decap_action(actions);
+    }
     add_count_action(actions);
     NL_ATTR_FOR_EACH_UNSAFE (nla, left, nl_actions, nl_actions_len) {
 
@@ -1295,12 +1309,6 @@  parse_flow_actions(struct netdev *netdev,
         if (nl_attr_type(nla) == OVS_ACTION_ATTR_OUTPUT) {
             if (add_output_action(netdev, actions, nla, info)) {
                 return -1;
-            /*
-            } else if (info->valid_ucast) {
-                VLOG_DBG_RL(&rl, "Unsupported multicast output action");
-                return -1;
-                info->valid_ucast = true;
-             */
             }
         } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_DROP) {
             add_flow_action(actions, RTE_FLOW_ACTION_TYPE_DROP, NULL);
@@ -1338,10 +1346,6 @@  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;
@@ -1359,17 +1363,38 @@  netdev_offload_dpdk_actions(struct netdev *netdev,
                             struct offload_info *info)
 {
     const struct rte_flow_attr flow_attr = { .ingress = 1, .transfer = 1 };
-    struct flow_actions actions = { .actions = NULL, .cnt = 0 };
+    struct flow_actions actions = { .actions = NULL, .cnt = 0, 
+                                    .valid_ucast = false };
     struct rte_flow *flow = NULL;
     struct rte_flow_error error;
-    int ret;
+    int ret,i;
 
     ret = parse_flow_actions(netdev, &actions, nl_actions, actions_len, info);
     if (ret) {
+        VLOG_DBG("TIMO DBG: after parse_flow_actions, ret is -1");
         goto out;
     }
-    flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items,
-                                           actions.actions, &error);
+    if (netdev_vport_is_vport_class(netdev->netdev_class)) {
+        struct netdev_flow_dump **netdev_dumps;
+        int num_ports = 0;
+
+        netdev_dumps = netdev_ports_flow_dump_create(netdev->dpif_type,
+                                                     &num_ports);
+        for (i = 0; i < num_ports; i++) {
+            if (!netdev_dpdk_is_uplink_port(netdev_dumps[i]->netdev)) {
+                continue;
+            }
+            VLOG_DBG("TIMO DBG: in netdev_offload_dpdk_flow_create, netdev dpdk");
+            flow = netdev_offload_dpdk_flow_create(netdev_dumps[i]->netdev,
+                                               &flow_attr, patterns->items,
+                                               actions.actions, &error);
+            break;
+        }
+
+    } else {
+        flow = netdev_offload_dpdk_flow_create(netdev, &flow_attr, patterns->items,
+                                               actions.actions, &error);
+    }
 out:
     free_flow_actions(&actions);
     return flow;
@@ -1377,7 +1402,7 @@  out:
 
 static int
 netdev_offload_dpdk_add_flow(struct netdev *netdev,
-                             const struct match *match,
+                             struct match *match,
                              struct nlattr *nl_actions,
                              size_t actions_len,
                              const ovs_u128 *ufid,
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index a4b8d5f..f15f86f 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -76,8 +76,6 @@  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 */
     const char *dpif_type_str;   /* dpif type string. */
 };