summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Russell <brian@graphiant.com>2021-01-19 16:50:56 +0000
committerNeale Ranns <neale@graphiant.com>2021-01-28 10:26:35 +0000
commit97de8a2d2faad42ff6c36807ec1e21bf9a0d9c91 (patch)
tree0d29bf8de5d9a6489a8cd485ba25bed0a51152f5
parentbaebb22c877d98c891d4d7a20ae23dc07f918edd (diff)
policer: add policer handoff
Add thread handoff for packets being policed. Note that the handoff currently requires the policer index to be passed in. This is suitable for use in the ip[46] punt paths where each policer node will only ever use a single policer. For the more general case, this will be expanded in future to use a policer index stored in packet metadata. Type: improvement Signed-off-by: Brian Russell <brian@graphiant.com> Change-Id: I85a0ecbcfb025f8844e763224cd3de1561249aca
-rw-r--r--src/vnet/policer/police_inlines.h67
-rw-r--r--src/vnet/policer/policer.c14
2 files changed, 81 insertions, 0 deletions
diff --git a/src/vnet/policer/police_inlines.h b/src/vnet/policer/police_inlines.h
index 64386e6f1bf..afcc7724cef 100644
--- a/src/vnet/policer/police_inlines.h
+++ b/src/vnet/policer/police_inlines.h
@@ -78,6 +78,73 @@ vnet_policer_police (vlib_main_t * vm,
return act;
}
+typedef enum
+{
+ POLICER_HANDOFF_ERROR_CONGESTION_DROP,
+} policer_handoff_error_t;
+
+typedef struct policer_handoff_trace_t_
+{
+ u32 policer_index;
+ u32 current_worker_index;
+ u32 next_worker_index;
+} policer_handoff_trace_t;
+
+extern u8 *format_policer_handoff_trace (u8 *s, va_list *args);
+
+/* Do worker handoff based on the policer's thread_index */
+static_always_inline uword
+policer_handoff (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame, u32 fq_index, u32 policer_index)
+{
+ vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
+ u16 thread_indices[VLIB_FRAME_SIZE], *ti;
+ u32 n_enq, n_left_from, *from;
+ vnet_policer_main_t *pm;
+ policer_read_response_type_st *policer;
+ u32 this_thread, policer_thread;
+
+ pm = &vnet_policer_main;
+ policer = &pm->policers[policer_index];
+ policer_thread = policer->thread_index;
+
+ this_thread = vm->thread_index;
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+ vlib_get_buffers (vm, from, bufs, n_left_from);
+
+ b = bufs;
+ ti = thread_indices;
+
+ while (n_left_from > 0)
+ {
+ ti[0] = policer_thread;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ b[0]->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ policer_handoff_trace_t *t =
+ vlib_add_trace (vm, node, b[0], sizeof (*t));
+ t->current_worker_index = this_thread;
+ t->next_worker_index = policer_thread;
+ t->policer_index = policer_index;
+ }
+
+ n_left_from--;
+ ti++;
+ b++;
+ }
+
+ n_enq = vlib_buffer_enqueue_to_thread (vm, fq_index, from, thread_indices,
+ frame->n_vectors, 1);
+
+ if (n_enq < frame->n_vectors)
+ vlib_node_increment_counter (vm, node->node_index,
+ POLICER_HANDOFF_ERROR_CONGESTION_DROP,
+ frame->n_vectors - n_enq);
+
+ return n_enq;
+}
#endif // __POLICE_INLINES_H__
/*
diff --git a/src/vnet/policer/policer.c b/src/vnet/policer/policer.c
index 7ad87a6ebdf..80fa1e6f68d 100644
--- a/src/vnet/policer/policer.c
+++ b/src/vnet/policer/policer.c
@@ -14,10 +14,24 @@
*/
#include <stdint.h>
#include <vnet/policer/policer.h>
+#include <vnet/policer/police_inlines.h>
#include <vnet/classify/vnet_classify.h>
vnet_policer_main_t vnet_policer_main;
+u8 *
+format_policer_handoff_trace (u8 *s, va_list *args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ policer_handoff_trace_t *t = va_arg (*args, policer_handoff_trace_t *);
+
+ s = format (s, "policer %d, handoff thread %d to %d", t->policer_index,
+ t->current_worker_index, t->next_worker_index);
+
+ return s;
+}
+
clib_error_t *
policer_add_del (vlib_main_t * vm,
u8 * name,