aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vnet/policer/node_funcs.c70
-rw-r--r--src/vnet/policer/policer.api17
-rw-r--r--src/vnet/policer/policer.c44
-rw-r--r--src/vnet/policer/policer.h7
-rw-r--r--src/vnet/policer/policer_api.c26
5 files changed, 140 insertions, 24 deletions
diff --git a/src/vnet/policer/node_funcs.c b/src/vnet/policer/node_funcs.c
index 21b9393a222..5fa0c8563be 100644
--- a/src/vnet/policer/node_funcs.c
+++ b/src/vnet/policer/node_funcs.c
@@ -68,7 +68,7 @@ static char *vnet_policer_error_strings[] = {
static inline uword
vnet_policer_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame)
+ vlib_frame_t *frame, vlib_dir_t dir)
{
u32 n_left_from, *from, *to_next;
vnet_policer_next_t next_index;
@@ -120,11 +120,11 @@ vnet_policer_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
b0 = vlib_get_buffer (vm, bi0);
b1 = vlib_get_buffer (vm, bi1);
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[dir];
+ sw_if_index1 = vnet_buffer (b1)->sw_if_index[dir];
- pi0 = pm->policer_index_by_sw_if_index[sw_if_index0];
- pi1 = pm->policer_index_by_sw_if_index[sw_if_index1];
+ pi0 = pm->policer_index_by_sw_if_index[dir][sw_if_index0];
+ pi1 = pm->policer_index_by_sw_if_index[dir][sw_if_index1];
act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods,
POLICE_CONFORM /* no chaining */, true);
@@ -206,9 +206,8 @@ vnet_policer_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
b0 = vlib_get_buffer (vm, bi0);
- sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
-
- pi0 = pm->policer_index_by_sw_if_index[sw_if_index0];
+ sw_if_index0 = vnet_buffer (b0)->sw_if_index[dir];
+ pi0 = pm->policer_index_by_sw_if_index[dir][sw_if_index0];
act0 = vnet_policer_police (vm, b0, pi0, time_in_policer_periods,
POLICE_CONFORM /* no chaining */, true);
@@ -256,7 +255,7 @@ vnet_policer_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
VLIB_NODE_FN (policer_input_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return vnet_policer_inline (vm, node, frame);
+ return vnet_policer_inline (vm, node, frame, VLIB_RX);
}
VLIB_REGISTER_NODE (policer_input_node) = {
@@ -279,12 +278,43 @@ VNET_FEATURE_INIT (policer_input_node, static) = {
.runs_before = VNET_FEATURES ("ethernet-input"),
};
+VLIB_NODE_FN (policer_output_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return vnet_policer_inline (vm, node, frame, VLIB_TX);
+}
+
+VLIB_REGISTER_NODE (policer_output_node) = {
+ .name = "policer-output",
+ .vector_size = sizeof (u32),
+ .format_trace = format_policer_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(vnet_policer_error_strings),
+ .error_strings = vnet_policer_error_strings,
+ .n_next_nodes = VNET_POLICER_N_NEXT,
+ .next_nodes = {
+ [VNET_POLICER_NEXT_DROP] = "error-drop",
+ [VNET_POLICER_NEXT_HANDOFF] = "policer-output-handoff",
+ },
+};
+
+VNET_FEATURE_INIT (policer_output_node, static) = {
+ .arc_name = "ip4-output",
+ .node_name = "policer-output",
+};
+
+VNET_FEATURE_INIT (policer6_output_node, static) = {
+ .arc_name = "ip6-output",
+ .node_name = "policer-output",
+};
+
static char *policer_input_handoff_error_strings[] = { "congestion drop" };
VLIB_NODE_FN (policer_input_handoff_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return policer_handoff (vm, node, frame, vnet_policer_main.fq_index, ~0);
+ return policer_handoff (vm, node, frame, vnet_policer_main.fq_index[VLIB_RX],
+ ~0);
}
VLIB_REGISTER_NODE (policer_input_handoff_node) = {
@@ -301,6 +331,26 @@ VLIB_REGISTER_NODE (policer_input_handoff_node) = {
},
};
+VLIB_NODE_FN (policer_output_handoff_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return policer_handoff (vm, node, frame, vnet_policer_main.fq_index[VLIB_TX],
+ ~0);
+}
+
+VLIB_REGISTER_NODE (policer_output_handoff_node) = {
+ .name = "policer-output-handoff",
+ .vector_size = sizeof (u32),
+ .format_trace = format_policer_handoff_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(policer_input_handoff_error_strings),
+ .error_strings = policer_input_handoff_error_strings,
+
+ .n_next_nodes = 1,
+ .next_nodes = {
+ [0] = "error-drop",
+ },
+};
typedef struct
{
u32 sw_if_index;
diff --git a/src/vnet/policer/policer.api b/src/vnet/policer/policer.api
index a664ab0be76..f4bf9384f10 100644
--- a/src/vnet/policer/policer.api
+++ b/src/vnet/policer/policer.api
@@ -52,6 +52,23 @@ autoreply define policer_input
bool apply;
};
+/** \brief policer output: Apply policer as an output feature.
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param name - policer name
+ @param sw_if_index - interface to apply the policer
+ @param apply - Apply/remove
+*/
+autoreply define policer_output
+{
+ u32 client_index;
+ u32 context;
+
+ string name[64];
+ vl_api_interface_index_t sw_if_index;
+ bool apply;
+};
+
/** \brief Add/del policer
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
diff --git a/src/vnet/policer/policer.c b/src/vnet/policer/policer.c
index 9eb56414561..0513563e1ec 100644
--- a/src/vnet/policer/policer.c
+++ b/src/vnet/policer/policer.c
@@ -166,7 +166,7 @@ policer_bind_worker (u8 *name, u32 worker, bool bind)
}
int
-policer_input (u8 *name, u32 sw_if_index, bool apply)
+policer_input (u8 *name, u32 sw_if_index, vlib_dir_t dir, bool apply)
{
vnet_policer_main_t *pm = &vnet_policer_main;
policer_t *policer;
@@ -184,16 +184,26 @@ policer_input (u8 *name, u32 sw_if_index, bool apply)
if (apply)
{
- vec_validate (pm->policer_index_by_sw_if_index, sw_if_index);
- pm->policer_index_by_sw_if_index[sw_if_index] = policer_index;
+ vec_validate (pm->policer_index_by_sw_if_index[dir], sw_if_index);
+ pm->policer_index_by_sw_if_index[dir][sw_if_index] = policer_index;
}
else
{
- pm->policer_index_by_sw_if_index[sw_if_index] = ~0;
+ pm->policer_index_by_sw_if_index[dir][sw_if_index] = ~0;
}
- vnet_feature_enable_disable ("device-input", "policer-input", sw_if_index,
- apply, 0, 0);
+ if (dir == VLIB_RX)
+ {
+ vnet_feature_enable_disable ("device-input", "policer-input",
+ sw_if_index, apply, 0, 0);
+ }
+ else
+ {
+ vnet_feature_enable_disable ("ip4-output", "policer-output", sw_if_index,
+ apply, 0, 0);
+ vnet_feature_enable_disable ("ip6-output", "policer-output", sw_if_index,
+ apply, 0, 0);
+ }
return 0;
}
@@ -637,6 +647,7 @@ policer_input_command_fn (vlib_main_t *vm, unformat_input_t *input,
u8 apply, *name = 0;
u32 sw_if_index;
int rv;
+ vlib_dir_t dir = cmd->function_arg;
apply = 1;
sw_if_index = ~0;
@@ -669,7 +680,7 @@ policer_input_command_fn (vlib_main_t *vm, unformat_input_t *input,
}
else
{
- rv = policer_input (name, sw_if_index, apply);
+ rv = policer_input (name, sw_if_index, dir, apply);
if (rv)
error = clib_error_return (0, "failed: `%d'", rv);
@@ -681,33 +692,43 @@ done:
return error;
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (configure_policer_command, static) = {
.path = "configure policer",
.short_help = "configure policer name <name> <params> ",
.function = policer_add_command_fn,
};
+
VLIB_CLI_COMMAND (policer_add_command, static) = {
.path = "policer add",
.short_help = "policer name <name> <params> ",
.function = policer_add_command_fn,
};
+
VLIB_CLI_COMMAND (policer_del_command, static) = {
.path = "policer del",
.short_help = "policer del name <name> ",
.function = policer_del_command_fn,
};
+
VLIB_CLI_COMMAND (policer_bind_command, static) = {
.path = "policer bind",
.short_help = "policer bind [unbind] name <name> <worker>",
.function = policer_bind_command_fn,
};
+
VLIB_CLI_COMMAND (policer_input_command, static) = {
.path = "policer input",
.short_help = "policer input [unapply] name <name> <interfac>",
.function = policer_input_command_fn,
+ .function_arg = VLIB_RX,
+};
+
+VLIB_CLI_COMMAND (policer_output_command, static) = {
+ .path = "policer output",
+ .short_help = "policer output [unapply] name <name> <interfac>",
+ .function = policer_input_command_fn,
+ .function_arg = VLIB_TX,
};
-/* *INDENT-ON* */
static clib_error_t *
show_policer_command_fn (vlib_main_t * vm,
@@ -792,7 +813,10 @@ policer_init (vlib_main_t * vm)
pm->vlib_main = vm;
pm->vnet_main = vnet_get_main ();
pm->log_class = vlib_log_register_class ("policer", 0);
- pm->fq_index = vlib_frame_queue_main_init (policer_input_node.index, 0);
+ pm->fq_index[VLIB_RX] =
+ vlib_frame_queue_main_init (policer_input_node.index, 0);
+ pm->fq_index[VLIB_TX] =
+ vlib_frame_queue_main_init (policer_output_node.index, 0);
pm->policer_config_by_name = hash_create_string (0, sizeof (uword));
pm->policer_index_by_name = hash_create_string (0, sizeof (uword));
diff --git a/src/vnet/policer/policer.h b/src/vnet/policer/policer.h
index 2687064bf0d..f5b6c0d3b31 100644
--- a/src/vnet/policer/policer.h
+++ b/src/vnet/policer/policer.h
@@ -39,7 +39,7 @@ typedef struct
uword *policer_index_by_name;
/* Policer by sw_if_index vector */
- u32 *policer_index_by_sw_if_index;
+ u32 *policer_index_by_sw_if_index[VLIB_N_RX_TX];
/* convenience */
vlib_main_t *vlib_main;
@@ -48,7 +48,7 @@ typedef struct
vlib_log_class_t log_class;
/* frame queue for thread handoff */
- u32 fq_index;
+ u32 fq_index[VLIB_N_RX_TX];
u16 msg_id_base;
} vnet_policer_main_t;
@@ -58,6 +58,7 @@ extern vnet_policer_main_t vnet_policer_main;
extern vlib_combined_counter_main_t policer_counters[];
extern vlib_node_registration_t policer_input_node;
+extern vlib_node_registration_t policer_output_node;
typedef enum
{
@@ -71,7 +72,7 @@ clib_error_t *policer_add_del (vlib_main_t *vm, u8 *name,
qos_pol_cfg_params_st *cfg, u32 *policer_index,
u8 is_add);
int policer_bind_worker (u8 *name, u32 worker, bool bind);
-int policer_input (u8 *name, u32 sw_if_index, bool apply);
+int policer_input (u8 *name, u32 sw_if_index, vlib_dir_t dir, bool apply);
#endif /* __included_policer_h__ */
diff --git a/src/vnet/policer/policer_api.c b/src/vnet/policer/policer_api.c
index 8c958e79676..4f9baa09feb 100644
--- a/src/vnet/policer/policer_api.c
+++ b/src/vnet/policer/policer_api.c
@@ -120,7 +120,7 @@ vl_api_policer_input_t_handler (vl_api_policer_input_t *mp)
sw_if_index = ntohl (mp->sw_if_index);
apply = mp->apply;
- rv = policer_input (name, sw_if_index, apply);
+ rv = policer_input (name, sw_if_index, VLIB_RX, apply);
vec_free (name);
BAD_SW_IF_INDEX_LABEL;
@@ -128,6 +128,30 @@ vl_api_policer_input_t_handler (vl_api_policer_input_t *mp)
}
static void
+vl_api_policer_output_t_handler (vl_api_policer_input_t *mp)
+{
+ vl_api_policer_bind_reply_t *rmp;
+ u8 *name;
+ u32 sw_if_index;
+ u8 apply;
+ int rv;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ name = format (0, "%s", mp->name);
+ vec_terminate_c_string (name);
+
+ sw_if_index = ntohl (mp->sw_if_index);
+ apply = mp->apply;
+
+ rv = policer_input (name, sw_if_index, VLIB_TX, apply);
+ vec_free (name);
+
+ BAD_SW_IF_INDEX_LABEL;
+ REPLY_MACRO (VL_API_POLICER_OUTPUT_REPLY);
+}
+
+static void
send_policer_details (u8 *name, qos_pol_cfg_params_st *config,
policer_t *templ, vl_api_registration_t *reg,
u32 context)