diff mbox series

[ovs-dev,v17,6/8] ofproto: Introduce API to process sFlow offload packet

Message ID 20211021080103.657675-7-cmi@nvidia.com
State Changes Requested
Headers show
Series Add offload support for sFlow | expand

Checks

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

Commit Message

Chris Mi Oct. 21, 2021, 8:01 a.m. UTC
Process sFlow offload packet in handler thread if handler id is 0.

Signed-off-by: Chris Mi <cmi@nvidia.com>
Reviewed-by: Eli Britstein <elibr@nvidia.com>
Acked-by: Eelco Chaudron <echaudro@redhat.com>
---
 ofproto/ofproto-dpif-upcall.c | 73 +++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
diff mbox series

Patch

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 1c9c720f0..c2c7d3b73 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -22,6 +22,7 @@ 
 #include "connmgr.h"
 #include "coverage.h"
 #include "cmap.h"
+#include "lib/dpif-offload-provider.h"
 #include "lib/dpif-provider.h"
 #include "dpif.h"
 #include "openvswitch/dynamic-string.h"
@@ -779,6 +780,74 @@  udpif_get_n_flows(struct udpif *udpif)
     return flow_count;
 }
 
+static void
+process_offload_sflow(struct udpif *udpif, struct dpif_offload_sflow *sflow)
+{
+    const struct dpif_sflow_attr *attr = sflow->attr;
+    const struct user_action_cookie *cookie;
+    struct dpif_sflow *dpif_sflow;
+    struct ofproto_dpif *ofproto;
+    struct upcall upcall;
+    struct flow flow;
+
+    if (!attr) {
+        VLOG_WARN_RL(&rl, "sFlow upcall is missing its attribute");
+        return;
+    }
+
+    cookie = nl_attr_get(attr->userdata);
+    if (!cookie) {
+        VLOG_WARN_RL(&rl, "sFlow user action cookie is missing");
+        return;
+    }
+    if (nl_attr_get_size(attr->userdata) < sizeof(struct user_action_cookie)) {
+        VLOG_WARN_RL(&rl, "sFlow user action cookie is corrupted");
+        return;
+    }
+    ofproto = ofproto_dpif_lookup_by_uuid(&cookie->ofproto_uuid);
+    if (!ofproto) {
+        VLOG_WARN_RL(&rl, "sFlow upcall can't find ofproto dpif for UUID "
+                     UUID_FMT, UUID_ARGS(&cookie->ofproto_uuid));
+        return;
+    }
+    dpif_sflow = ofproto->sflow;
+    if (!dpif_sflow) {
+        VLOG_WARN_RL(&rl, "sFlow upcall is missing dpif information");
+        return;
+    }
+
+    memset(&flow, 0, sizeof flow);
+    if (attr->tunnel) {
+        memcpy(&flow.tunnel, attr->tunnel, sizeof flow.tunnel);
+    }
+    flow.in_port.odp_port = netdev_ifindex_to_odp_port(sflow->iifindex);
+    memset(&upcall, 0, sizeof upcall);
+    upcall.flow = &flow;
+    upcall.cookie = *cookie;
+    upcall.packet = &sflow->packet;
+    upcall.sflow = dpif_sflow;
+    upcall.ufid = &attr->ufid;
+    upcall.type = SFLOW_UPCALL;
+    process_upcall(udpif, &upcall, NULL, NULL);
+}
+
+static void
+recv_offload_sflow(struct udpif *udpif)
+{
+    size_t n_sflow = 0;
+
+    while (n_sflow < UPCALL_MAX_BATCH) {
+        struct dpif_offload_sflow sflow;
+
+        if (dpif_offload_sflow_recv(udpif->dpif, &sflow)) {
+            break;
+        }
+        process_offload_sflow(udpif, &sflow);
+        n_sflow++;
+    }
+    dpif_offload_sflow_recv_wait(udpif->dpif);
+}
+
 /* The upcall handler thread tries to read a batch of UPCALL_MAX_BATCH
  * upcalls from dpif, processes the batch and installs corresponding flows
  * in dpif. */
@@ -795,6 +864,10 @@  udpif_upcall_handler(void *arg)
             dpif_recv_wait(udpif->dpif, handler->handler_id);
             latch_wait(&udpif->exit_latch);
         }
+        /* Only handler id 0 thread process sFlow offload packet. */
+        if (handler->handler_id == 0) {
+            recv_offload_sflow(udpif);
+        }
         poll_block();
     }