[ovs-dev] [PATCH 6/8] ofproto: Add psample receive handler
Chris Mi
cmi at nvidia.com
Mon Sep 14 10:05:31 UTC 2020
Create a dedicated thread to poll psample netlink socket, receive
sampled packet, parse it to sFlow format and send it to sFlow
monitoring host.
Signed-off-by: Chris Mi <cmi at nvidia.com>
Reviewed-by: Eli Britstein <elibr at nvidia.com>
---
ofproto/ofproto-dpif-upcall.c | 78 +++++++++++++++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 72a5b4d73..ac904a50e 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -133,6 +133,8 @@ struct udpif {
struct revalidator *revalidators; /* Flow revalidators. */
size_t n_revalidators;
+ struct handler phandler; /* psample handler */
+
struct latch exit_latch; /* Tells child threads to exit. */
/* Revalidation. */
@@ -339,6 +341,7 @@ static void udpif_start_threads(struct udpif *, size_t n_handlers,
static void udpif_pause_revalidators(struct udpif *);
static void udpif_resume_revalidators(struct udpif *);
static void *udpif_upcall_handler(void *);
+static void *udpif_psample_handler(void *);
static void *udpif_revalidator(void *);
static unsigned long udpif_get_n_flows(struct udpif *);
static void revalidate(struct revalidator *);
@@ -530,6 +533,9 @@ udpif_stop_threads(struct udpif *udpif, bool delete_flows)
for (i = 0; i < udpif->n_revalidators; i++) {
xpthread_join(udpif->revalidators[i].thread, NULL);
}
+ if (dpif_psample_enabled(udpif->dpif)) {
+ xpthread_join(udpif->phandler.thread, NULL);
+ }
dpif_disable_upcall(udpif->dpif);
ovsrcu_quiesce_end();
@@ -594,6 +600,14 @@ udpif_start_threads(struct udpif *udpif, size_t n_handlers_,
revalidator->thread = ovs_thread_create(
"revalidator", udpif_revalidator, revalidator);
}
+
+ if (dpif_psample_enabled(udpif->dpif)) {
+ struct handler *phandler = &udpif->phandler;
+
+ phandler->udpif = udpif;
+ phandler->thread = ovs_thread_create(
+ "psample_handler", udpif_psample_handler, phandler);
+ }
ovsrcu_quiesce_end();
}
}
@@ -857,6 +871,70 @@ free_dupcall:
return n_upcalls;
}
+static int
+recv_psample(struct handler *handler)
+{
+ struct dpif *dpif = handler->udpif->dpif;
+ const struct dpif_sflow_attr *sflow_attr;
+ struct dpif_upcall_psample dupcall;
+ int ret;
+
+ memset(&dupcall, 0, sizeof dupcall);
+ ret = dpif_psample_poll(dpif, &dupcall);
+ if (ret) {
+ VLOG_WARN_RL(&rl, "dpif_psample_poll err: %d", ret);
+ return ret;
+ }
+
+ sflow_attr = dupcall.sflow_attr;
+ if (sflow_attr) {
+ struct user_action_cookie *cookie;
+ struct ofproto_dpif *ofproto;
+ struct dpif_sflow *sflow;
+ uint32_t iifindex;
+ struct flow flow;
+
+ cookie = sflow_attr->userdata;
+ ofproto = ofproto_dpif_lookup_by_uuid(&cookie->ofproto_uuid);
+ if (!ofproto) {
+ VLOG_WARN_RL(&rl, "upcall could not find ofproto");
+ return ENODEV;
+ }
+ sflow = ofproto->sflow;
+ if (!sflow) {
+ VLOG_WARN_RL(&rl, "upcall could not find sflow");
+ 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 void *
+udpif_psample_handler(void *arg)
+{
+ struct handler *handler = arg;
+ struct udpif *udpif = handler->udpif;
+
+ while (!latch_is_set(&handler->udpif->exit_latch)) {
+ recv_psample(handler);
+ dpif_psample_poll_wait(udpif->dpif);
+ latch_wait(&udpif->exit_latch);
+ poll_block();
+ }
+
+ return NULL;
+}
+
static void
udpif_run_flow_rebalance(struct udpif *udpif)
{
--
2.21.1
More information about the dev
mailing list