diff mbox series

[ovs-dev,v5,04/12] ofproto: Add upcall callback to process sFlow packet

Message ID 20201029112340.14167-5-cmi@nvidia.com
State Superseded
Headers show
Series Add offload support for sFlow | expand

Commit Message

Chris Mi Oct. 29, 2020, 11:23 a.m. UTC
When offloading sample action, dpif provider may receive packets for
sFlow in a seperate channel. That means the sFlow packets will not be
processed by usual upcall. Add an upcall callback, so the dpif thread
polling the channel can call it to process the sFlow packet.

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

Patch

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index e022fde27..4b7a0292e 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -409,6 +409,7 @@  static int udpif_flow_unprogram(struct udpif *udpif, struct udpif_key *ukey,
 
 static upcall_callback upcall_cb;
 static dp_purge_callback dp_purge_cb;
+static sflow_upcall_callback sflow_upcall_cb;
 
 static atomic_bool enable_megaflows = ATOMIC_VAR_INIT(true);
 static atomic_bool enable_ufid = ATOMIC_VAR_INIT(true);
@@ -463,6 +464,7 @@  udpif_create(struct dpif_backer *backer, struct dpif *dpif)
 
     dpif_register_upcall_cb(dpif, upcall_cb, udpif);
     dpif_register_dp_purge_cb(dpif, dp_purge_cb, udpif);
+    dpif_register_sflow_upcall_cb(dpif, sflow_upcall_cb);
 
     return udpif;
 }
@@ -1345,6 +1347,46 @@  out:
     return error;
 }
 
+int
+sflow_upcall_cb(struct dpif_upcall_sflow *dupcall)
+{
+    const struct dpif_sflow_attr *sflow_attr = dupcall->sflow_attr;
+    struct user_action_cookie *cookie;
+    struct ofproto_dpif *ofproto;
+    struct dpif_sflow *sflow;
+    uint32_t iifindex;
+    struct flow flow;
+
+    if (!sflow_attr) {
+        VLOG_WARN_RL(&rl, "%s: sflow_attr is NULL", __func__);
+        return EINVAL;
+    }
+
+    cookie = sflow_attr->userdata;
+    ofproto = ofproto_dpif_lookup_by_uuid(&cookie->ofproto_uuid);
+    if (!ofproto) {
+        VLOG_WARN_RL(&rl, "%s: could not find ofproto", __func__);
+        return ENODEV;
+    }
+
+    sflow = ofproto->sflow;
+    if (!sflow) {
+        VLOG_WARN_RL(&rl, "%s: could not find sflow", __func__);
+        return ENODEV;
+    }
+
+    memset(&flow, 0, sizeof flow);
+    if (sflow_attr->tunnel) {
+        memcpy(&flow.tunnel, sflow_attr->tunnel, sizeof flow.tunnel);
+    }
+    iifindex = dupcall->iifindex;
+    dpif_sflow_received(sflow, &dupcall->packet, &flow,
+                        netdev_ifindex_to_odp_port(iifindex),
+                        cookie, NULL);
+
+    return 0;
+}
+
 static size_t
 dpif_get_actions(struct udpif *udpif, struct upcall *upcall,
                  const struct nlattr **actions)