#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/policer/policer.h>
+#include <vnet/policer/police_inlines.h>
#include <vnet/ip/ip.h>
#include <vnet/classify/policer_classify.h>
#include <vnet/classify/vnet_classify.h>
+#include <vnet/l2/feat_bitmap.h>
+#include <vnet/l2/l2_input.h>
-#define IP4_NON_DSCP_BITS 0x03
-#define IP4_DSCP_SHIFT 2
-#define IP6_NON_DSCP_BITS 0xf03fffff
-#define IP6_DSCP_SHIFT 22
/* Dispatch functions meant to be instantiated elsewhere */
#undef _
};
-static_always_inline void
-vnet_policer_mark (vlib_buffer_t * b, u8 dscp)
-{
- ethernet_header_t *eh;
- ip4_header_t *ip4h;
- ip6_header_t *ip6h;
- u16 type;
-
- eh = (ethernet_header_t *) b->data;
- type = clib_net_to_host_u16 (eh->type);
-
- if (PREDICT_TRUE (type == ETHERNET_TYPE_IP4))
- {
- ip4h = (ip4_header_t *) & (b->data[sizeof (ethernet_header_t)]);;
- ip4h->tos &= IP4_NON_DSCP_BITS;
- ip4h->tos |= dscp << IP4_DSCP_SHIFT;
- ip4h->checksum = ip4_header_checksum (ip4h);
- }
- else
- {
- if (PREDICT_TRUE (type == ETHERNET_TYPE_IP6))
- {
- ip6h = (ip6_header_t *) & (b->data[sizeof (ethernet_header_t)]);
- ip6h->ip_version_traffic_class_and_flow_label &=
- clib_host_to_net_u32 (IP6_NON_DSCP_BITS);
- ip6h->ip_version_traffic_class_and_flow_label |=
- clib_host_to_net_u32 (dscp << IP6_DSCP_SHIFT);
- }
- }
-}
-
-static_always_inline
- u8 vnet_policer_police (vlib_main_t * vm,
- vlib_buffer_t * b,
- u32 policer_index,
- u64 time_in_policer_periods,
- policer_result_e packet_color)
-{
- u8 act;
- u32 len;
- u32 col;
- policer_read_response_type_st *pol;
- vnet_policer_main_t *pm = &vnet_policer_main;
-
- len = vlib_buffer_length_in_chain (vm, b);
- pol = &pm->policers[policer_index];
- col = vnet_police_packet (pol, len, packet_color, time_in_policer_periods);
- act = pol->action[col];
- if (PREDICT_TRUE (act == SSE2_QOS_ACTION_MARK_AND_TRANSMIT))
- vnet_policer_mark (b, pol->mark_dscp[col]);
-
- return act;
-}
-
static inline uword
vnet_policer_inline (vlib_main_t * vm,
vlib_node_runtime_t * node,
return frame->n_vectors;
}
-uword
-vnet_policer_by_sw_if_index (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
+VLIB_NODE_FN (policer_by_sw_if_index_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
return vnet_policer_inline (vm, node, frame,
VNET_POLICER_INDEX_BY_SW_IF_INDEX);
}
+#ifndef CLIB_MARCH_VARIANT
uword
vnet_policer_by_opaque (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * frame)
vnet_policer_node_funcs_reference (void)
{
}
+#endif /* CLIB_MARCH_VARIANT */
#define TEST_CODE 1
#ifdef TEST_CODE
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (policer_by_sw_if_index_node, static) = {
- .function = vnet_policer_by_sw_if_index,
+VLIB_REGISTER_NODE (policer_by_sw_if_index_node) = {
.name = "policer-by-sw-if-index",
.vector_size = sizeof (u32),
.format_trace = format_policer_trace,
[VNET_POLICER_NEXT_DROP] = "error-drop",
},
};
-
-VLIB_NODE_FUNCTION_MULTIARCH (policer_by_sw_if_index_node,
- vnet_policer_by_sw_if_index);
/* *INDENT-ON* */
+#ifndef CLIB_MARCH_VARIANT
int
test_policer_add_del (u32 rx_sw_if_index, u8 * config_name, int is_add)
{
int rx_set = 0;
int is_add = 1;
int is_show = 0;
+ clib_error_t *error = NULL;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
}
if (rx_set == 0)
- return clib_error_return (0, "interface not set");
+ {
+ error = clib_error_return (0, "interface not set");
+ goto done;
+ }
if (is_show)
{
policer = pool_elt_at_index (pm->policers, pi);
vlib_cli_output (vm, "%U", format_policer_instance, policer);
- return 0;
+ goto done;
}
if (is_add && config_name == 0)
{
- return clib_error_return (0, "policer config name required");
+ error = clib_error_return (0, "policer config name required");
+ goto done;
}
rv = test_policer_add_del (rx_sw_if_index, config_name, is_add);
break;
default:
- return clib_error_return
+ error = clib_error_return
(0, "WARNING: vnet_vnet_policer_add_del returned %d", rv);
+ goto done;
}
- return 0;
+done:
+ unformat_free (line_input);
+
+ return error;
}
/* *INDENT-OFF* */
.function = test_policer_command_fn,
};
/* *INDENT-ON* */
+#endif /* CLIB_MARCH_VARIANT */
#endif /* TEST_CODE */
#define foreach_policer_classify_error \
_(MISS, "Policer classify misses") \
_(HIT, "Policer classify hits") \
-_(CHAIN_HIT, "Polcier classify hits after chain walk") \
+_(CHAIN_HIT, "Policer classify hits after chain walk") \
_(DROP, "Policer classify action drop")
typedef enum
u32 hits = 0;
u32 misses = 0;
u32 chain_hits = 0;
- u32 drop = 0;
u32 n_next_nodes;
u64 time_in_policer_periods;
if (tid == POLICER_CLASSIFY_TABLE_L2)
{
- /* Feature bitmap update */
- vnet_buffer (b0)->l2.feature_bitmap &=
- ~L2INPUT_FEAT_POLICER_CLAS;
- /* Determine the next node */
- next0 =
- feat_bitmap_get_next_node_index (pcm->feat_next_node_index,
- vnet_buffer (b0)->
- l2.feature_bitmap);
+ /* Feature bitmap update and determine the next node */
+ next0 = vnet_l2_feature_next (b0, pcm->feat_next_node_index,
+ L2INPUT_FEAT_POLICER_CLAS);
}
else
vnet_get_config_data (pcm->vnet_config_main[tid],
{
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
b0->error = node->errors[POLICER_CLASSIFY_ERROR_DROP];
- drop++;
}
hits++;
}
next0 = POLICER_CLASSIFY_NEXT_INDEX_DROP;
b0->error =
node->errors[POLICER_CLASSIFY_ERROR_DROP];
- drop++;
}
hits++;
chain_hits++;
POLICER_CLASSIFY_ERROR_HIT, hits);
vlib_node_increment_counter (vm, node->node_index,
POLICER_CLASSIFY_ERROR_CHAIN_HIT, chain_hits);
- vlib_node_increment_counter (vm, node->node_index,
- POLICER_CLASSIFY_ERROR_DROP, drop);
return frame->n_vectors;
}
-static uword
-ip4_policer_classify (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
+VLIB_NODE_FN (ip4_policer_classify_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
return policer_classify_inline (vm, node, frame,
POLICER_CLASSIFY_TABLE_IP4);
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip4_policer_classify_node) = {
- .function = ip4_policer_classify,
.name = "ip4-policer-classify",
.vector_size = sizeof (u32),
.format_trace = format_policer_classify_trace,
[POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop",
},
};
-
-VLIB_NODE_FUNCTION_MULTIARCH (ip4_policer_classify_node, ip4_policer_classify);
/* *INDENT-ON* */
-static uword
-ip6_policer_classify (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
+VLIB_NODE_FN (ip6_policer_classify_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
return policer_classify_inline (vm, node, frame,
POLICER_CLASSIFY_TABLE_IP6);
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_policer_classify_node) = {
- .function = ip6_policer_classify,
.name = "ip6-policer-classify",
.vector_size = sizeof (u32),
.format_trace = format_policer_classify_trace,
[POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop",
},
};
-
-VLIB_NODE_FUNCTION_MULTIARCH (ip6_policer_classify_node, ip6_policer_classify);
/* *INDENT-ON* */
-static uword
-l2_policer_classify (vlib_main_t * vm,
- vlib_node_runtime_t * node, vlib_frame_t * frame)
+VLIB_NODE_FN (l2_policer_classify_node) (vlib_main_t * vm,
+ vlib_node_runtime_t * node,
+ vlib_frame_t * frame)
{
return policer_classify_inline (vm, node, frame, POLICER_CLASSIFY_TABLE_L2);
}
-VLIB_REGISTER_NODE (l2_policer_classify_node) =
-{
- .function = l2_policer_classify,.name = "l2-policer-classify",.vector_size =
- sizeof (u32),.format_trace = format_policer_classify_trace,.n_errors =
- ARRAY_LEN (policer_classify_error_strings),.error_strings =
- policer_classify_error_strings,.n_next_nodes =
- POLICER_CLASSIFY_NEXT_INDEX_N_NEXT,.next_nodes =
- {
- [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop",}
-,};
-
-VLIB_NODE_FUNCTION_MULTIARCH (l2_policer_classify_node, l2_policer_classify);
-
+/* *INDENT-OFF* */
+VLIB_REGISTER_NODE (l2_policer_classify_node) = {
+ .name = "l2-policer-classify",
+ .vector_size = sizeof (u32),
+ .format_trace = format_policer_classify_trace,
+ .n_errors = ARRAY_LEN (policer_classify_error_strings),
+ .error_strings = policer_classify_error_strings,
+ .n_next_nodes = POLICER_CLASSIFY_NEXT_INDEX_N_NEXT,
+ .next_nodes = {
+ [POLICER_CLASSIFY_NEXT_INDEX_DROP] = "error-drop",
+ },
+};
+/* *INDENT-ON* */
+#ifndef CLIB_MARCH_VARIANT
static clib_error_t *
policer_classify_init (vlib_main_t * vm)
{
}
VLIB_INIT_FUNCTION (policer_classify_init);
+#endif /* CLIB_MARCH_VARIANT */
/*
* fd.io coding-style-patch-verification: ON