Process sFlow offload packet in handler thread if handler id is 0. Signed-off-by: Chris Mi <c...@nvidia.com> Reviewed-by: Eli Britstein <el...@nvidia.com> Acked-by: Eelco Chaudron <echau...@redhat.com> --- ofproto/ofproto-dpif-upcall.c | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+)
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(); } -- 2.30.2 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev