summaryrefslogtreecommitdiffstats
path: root/src/vnet/policer
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/policer')
-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,