diff mbox series

[ovs-dev] dpif-netdev: Provide orig_in_port in metadata for tunneled packets

Message ID 20210205180413.43337-1-sriharsha.basavapatna@broadcom.com
State Superseded
Headers show
Series [ovs-dev] dpif-netdev: Provide orig_in_port in metadata for tunneled packets | expand

Commit Message

Sriharsha Basavapatna Feb. 5, 2021, 6:04 p.m. UTC
When an encapsulated packet is recirculated through a TUNNEL_POP
action, the metadata gets reinitialized and the originating physical
port information is lost. When this flow gets processed by the vport
and it needs to be offloaded, we can't figure out the physical port
through which the tunneled packet was received.

Add a new member to the metadata: 'orig_in_port'. This is passed to
the next stage during recirculation and the offload layer should use
this to offload the flow to the right uplink port.

Signed-off-by: Sriharsha Basavapatna <sriharsha.basavapatna@broadcom.com>
---
 lib/dpif-netdev.c         | 28 ++++++++++++++++++++++------
 lib/netdev-offload-dpdk.c |  9 +++++++++
 lib/netdev-offload.h      |  1 +
 lib/packets.h             |  1 +
 4 files changed, 33 insertions(+), 6 deletions(-)

Comments

0-day Robot Feb. 5, 2021, 9:03 p.m. UTC | #1
Bleep bloop.  Greetings Sriharsha Basavapatna, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


git-am:
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch
Patch failed at 0001 dpif-netdev: Provide orig_in_port in metadata for tunneled packets
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".


Please check this out.  If you feel there has been an error, please email aconole@redhat.com

Thanks,
0-day Robot
diff mbox series

Patch

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 7c82a7a27..c65e1d39c 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -430,6 +430,7 @@  struct dp_flow_offload_item {
     struct match match;
     struct nlattr *actions;
     size_t actions_len;
+    odp_port_t orig_in_port;    /* Originating in_port for tnl flows */
 
     struct ovs_list node;
 };
@@ -2695,11 +2696,13 @@  dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload)
         }
     }
     info.flow_mark = mark;
+    info.orig_in_port = offload->orig_in_port;
 
     port = netdev_ports_get(in_port, dpif_type_str);
     if (!port) {
         goto err_free;
     }
+
     /* Taking a global 'port_mutex' to fulfill thread safety restrictions for
      * the netdev-offload-dpdk module. */
     ovs_mutex_lock(&pmd->dp->port_mutex);
@@ -2797,7 +2800,8 @@  queue_netdev_flow_del(struct dp_netdev_pmd_thread *pmd,
 static void
 queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd,
                       struct dp_netdev_flow *flow, struct match *match,
-                      const struct nlattr *actions, size_t actions_len)
+                      const struct nlattr *actions, size_t actions_len,
+                      odp_port_t orig_in_port)
 {
     struct dp_flow_offload_item *offload;
     int op;
@@ -2823,6 +2827,7 @@  queue_netdev_flow_put(struct dp_netdev_pmd_thread *pmd,
     offload->actions = xmalloc(actions_len);
     memcpy(offload->actions, actions, actions_len);
     offload->actions_len = actions_len;
+    offload->orig_in_port = orig_in_port;
 
     dp_netdev_append_flow_offload(offload);
 }
@@ -3624,7 +3629,8 @@  dp_netdev_get_mega_ufid(const struct match *match, ovs_u128 *mega_ufid)
 static struct dp_netdev_flow *
 dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd,
                    struct match *match, const ovs_u128 *ufid,
-                   const struct nlattr *actions, size_t actions_len)
+                   const struct nlattr *actions, size_t actions_len,
+                   odp_port_t orig_in_port)
     OVS_REQUIRES(pmd->flow_mutex)
 {
     struct ds extra_info = DS_EMPTY_INITIALIZER;
@@ -3690,7 +3696,8 @@  dp_netdev_flow_add(struct dp_netdev_pmd_thread *pmd,
     cmap_insert(&pmd->flow_table, CONST_CAST(struct cmap_node *, &flow->node),
                 dp_netdev_flow_hash(&flow->ufid));
 
-    queue_netdev_flow_put(pmd, flow, match, actions, actions_len);
+    queue_netdev_flow_put(pmd, flow, match, actions, actions_len,
+                          orig_in_port);
 
     if (OVS_UNLIKELY(!VLOG_DROP_DBG((&upcall_rl)))) {
         struct ds ds = DS_EMPTY_INITIALIZER;
@@ -3761,7 +3768,7 @@  flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd,
     if (!netdev_flow) {
         if (put->flags & DPIF_FP_CREATE) {
             dp_netdev_flow_add(pmd, match, ufid, put->actions,
-                               put->actions_len);
+                               put->actions_len, ODPP_NONE);
         } else {
             error = ENOENT;
         }
@@ -3777,7 +3784,7 @@  flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd,
             ovsrcu_set(&netdev_flow->actions, new_actions);
 
             queue_netdev_flow_put(pmd, netdev_flow, match,
-                                  put->actions, put->actions_len);
+                                  put->actions, put->actions_len, ODPP_NONE);
 
             if (stats) {
                 get_dpif_flow_status(pmd->dp, netdev_flow, stats, NULL);
@@ -7100,6 +7107,7 @@  dfc_processing(struct dp_netdev_pmd_thread *pmd,
 
         if (!md_is_valid) {
             pkt_metadata_init(&packet->md, port_no);
+            packet->md.orig_in_port = port_no;
         }
 
         if (*recirc_depth_get() == 0) {
@@ -7129,6 +7137,8 @@  dfc_processing(struct dp_netdev_pmd_thread *pmd,
                         continue;
                     }
                 }
+            } else {
+                packet->md.orig_in_port = port_no;
             }
         }
 
@@ -7204,6 +7214,7 @@  handle_packet_upcall(struct dp_netdev_pmd_thread *pmd,
     ovs_u128 ufid;
     int error;
     uint64_t cycles = cycles_counter_update(&pmd->perf_stats);
+    odp_port_t orig_in_port = packet->md.orig_in_port;
 
     match.tun_md.valid = false;
     miniflow_expand(&key->mf, &match.flow);
@@ -7253,7 +7264,7 @@  handle_packet_upcall(struct dp_netdev_pmd_thread *pmd,
         if (OVS_LIKELY(!netdev_flow)) {
             netdev_flow = dp_netdev_flow_add(pmd, &match, &ufid,
                                              add_actions->data,
-                                             add_actions->size);
+                                             add_actions->size, orig_in_port);
         }
         ovs_mutex_unlock(&pmd->flow_mutex);
         uint32_t hash = dp_netdev_flow_hash(&netdev_flow->ufid);
@@ -7771,6 +7782,9 @@  dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
 
                 dp_packet_batch_apply_cutlen(packets_);
 
+                /* Metadata gets reset in pop_header(), save orig_in_port */
+                odp_port_t orig_in_port =
+                        packets_->packets[0]->md.orig_in_port;
                 packet_count = dp_packet_batch_size(packets_);
                 netdev_pop_header(p->port->netdev, packets_);
                 packets_dropped =
@@ -7785,6 +7799,8 @@  dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
 
                 struct dp_packet *packet;
                 DP_PACKET_BATCH_FOR_EACH (i, packet, packets_) {
+                    /* Restore orig_in_port in metadata */
+                    packet->md.orig_in_port = orig_in_port;
                     packet->md.in_port.odp_port = portno;
                 }
 
diff --git a/lib/netdev-offload-dpdk.c b/lib/netdev-offload-dpdk.c
index 6cfdea8fc..bbdc561fd 100644
--- a/lib/netdev-offload-dpdk.c
+++ b/lib/netdev-offload-dpdk.c
@@ -63,6 +63,7 @@  struct rte_flow_data {
     bool actions_offloaded;
     struct dpif_flow_stats stats;
     struct ovs_list indirect;
+    odp_port_t orig_in_port;
 };
 
 static uint32_t
@@ -1935,6 +1936,10 @@  netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match,
     if (rte_flow_data && rte_flow_data->rte_flow) {
         old_stats = rte_flow_data->stats;
         modification = true;
+        if (netdev_vport_is_vport_class(netdev->netdev_class)) {
+            /* Retrieve orig_in_port saved earlier */
+            info->orig_in_port = rte_flow_data->orig_in_port;
+        }
         ret = netdev_offload_dpdk_flow_destroy(rte_flow_data);
         if (ret < 0) {
             return ret;
@@ -1949,6 +1954,10 @@  netdev_offload_dpdk_flow_put(struct netdev *netdev, struct match *match,
     if (modification) {
         rte_flow_data->stats = old_stats;
     }
+    if (netdev_vport_is_vport_class(netdev->netdev_class)) {
+        /*  Save orig_in_port; need this if the flow gets modified later */
+        rte_flow_data->orig_in_port = info->orig_in_port;
+    }
     if (stats) {
         *stats = rte_flow_data->stats;
     }
diff --git a/lib/netdev-offload.h b/lib/netdev-offload.h
index b063c43a3..eb4bc733f 100644
--- a/lib/netdev-offload.h
+++ b/lib/netdev-offload.h
@@ -76,6 +76,7 @@  struct offload_info {
 
     bool tc_modify_flow_deleted; /* Indicate the tc modify flow put success
                                   * to delete the original flow. */
+    odp_port_t orig_in_port;     /* Originating in_port for tnl flows */
 };
 
 int netdev_flow_flush(struct netdev *);
diff --git a/lib/packets.h b/lib/packets.h
index 481bc22fa..dad843cdc 100644
--- a/lib/packets.h
+++ b/lib/packets.h
@@ -115,6 +115,7 @@  PADDED_MEMBERS_CACHELINE_MARKER(CACHE_LINE_SIZE, cacheline0,
     uint32_t ct_mark;           /* Connection mark. */
     ovs_u128 ct_label;          /* Connection label. */
     union flow_in_port in_port; /* Input port. */
+    odp_port_t orig_in_port;	/* Originating in_port for tunneled packets */
     struct conn *conn;          /* Cached conntrack connection. */
     bool reply;                 /* True if reply direction. */
     bool icmp_related;          /* True if ICMP related. */