aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/vnet/ip/reass/ip6_full_reass.c88
1 files changed, 75 insertions, 13 deletions
diff --git a/src/vnet/ip/reass/ip6_full_reass.c b/src/vnet/ip/reass/ip6_full_reass.c
index ff877ca7567..77d9b377851 100644
--- a/src/vnet/ip/reass/ip6_full_reass.c
+++ b/src/vnet/ip/reass/ip6_full_reass.c
@@ -165,6 +165,7 @@ typedef struct
u32 fq_index;
u32 fq_local_index;
u32 fq_feature_index;
+ u32 fq_custom_index;
// reference count for enabling/disabling feature - per interface
u32 *feature_use_refcount_per_intf;
@@ -190,6 +191,13 @@ typedef enum
typedef enum
{
+ NORMAL,
+ FEATURE,
+ CUSTOM
+} ip6_full_reass_node_type_t;
+
+typedef enum
+{
RANGE_NEW,
RANGE_OVERLAP,
ICMP_ERROR_RT_EXCEEDED,
@@ -1402,6 +1410,30 @@ VNET_FEATURE_INIT (ip6_full_reassembly_feature, static) = {
.runs_after = 0,
};
+VLIB_NODE_FN (ip6_full_reass_node_custom)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return ip6_full_reassembly_inline (vm, node, frame, false /* is_feature */,
+ true /* is_custom_app */,
+ false /* is_local */);
+}
+
+VLIB_REGISTER_NODE (ip6_full_reass_node_custom) = {
+ .name = "ip6-full-reassembly-custom",
+ .vector_size = sizeof (u32),
+ .format_trace = format_ip6_full_reass_trace,
+ .n_errors = ARRAY_LEN (ip6_full_reassembly_error_strings),
+ .error_strings = ip6_full_reassembly_error_strings,
+ .n_next_nodes = IP6_FULL_REASSEMBLY_N_NEXT,
+ .next_nodes =
+ {
+ [IP6_FULL_REASSEMBLY_NEXT_INPUT] = "ip6-input",
+ [IP6_FULL_REASSEMBLY_NEXT_DROP] = "ip6-drop",
+ [IP6_FULL_REASSEMBLY_NEXT_ICMP_ERROR] = "ip6-icmp-error",
+ [IP6_FULL_REASSEMBLY_NEXT_HANDOFF] = "ip6-full-reass-custom-hoff",
+ },
+};
+
#ifndef CLIB_MARCH_VARIANT
static u32
ip6_full_reass_get_nbuckets ()
@@ -1554,6 +1586,8 @@ ip6_full_reass_init_function (vlib_main_t * vm)
vlib_frame_queue_main_init (ip6_local_full_reass_node.index, 0);
rm->fq_feature_index =
vlib_frame_queue_main_init (ip6_full_reass_node_feature.index, 0);
+ rm->fq_custom_index =
+ vlib_frame_queue_main_init (ip6_full_reass_node_custom.index, 0);
rm->feature_use_refcount_per_intf = NULL;
return error;
@@ -1827,7 +1861,8 @@ format_ip6_full_reassembly_handoff_trace (u8 * s, va_list * args)
always_inline uword
ip6_full_reassembly_handoff_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame, bool is_feature,
+ vlib_frame_t *frame,
+ ip6_full_reass_node_type_t type,
bool is_local)
{
ip6_full_reass_main_t *rm = &ip6_full_reass_main;
@@ -1844,12 +1879,9 @@ ip6_full_reassembly_handoff_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
b = bufs;
ti = thread_indices;
- if (is_feature)
- {
- fq_index = rm->fq_feature_index;
- }
- else
+ switch (type)
{
+ case NORMAL:
if (is_local)
{
fq_index = rm->fq_local_index;
@@ -1858,8 +1890,17 @@ ip6_full_reassembly_handoff_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
{
fq_index = rm->fq_index;
}
+ break;
+ case FEATURE:
+ fq_index = rm->fq_feature_index;
+ break;
+ case CUSTOM:
+ fq_index = rm->fq_custom_index;
+ break;
+ default:
+ clib_warning ("Unexpected `type' (%d)!", type);
+ ASSERT (0);
}
-
while (n_left_from > 0)
{
ti[0] = vnet_buffer (b[0])->ip.reass.owner_thread_index;
@@ -1891,8 +1932,8 @@ VLIB_NODE_FN (ip6_full_reassembly_handoff_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
{
- return ip6_full_reassembly_handoff_inline (
- vm, node, frame, false /* is_feature */, false /* is_local */);
+ return ip6_full_reassembly_handoff_inline (vm, node, frame, NORMAL,
+ false /* is_local */);
}
VLIB_REGISTER_NODE (ip6_full_reassembly_handoff_node) = {
@@ -1912,8 +1953,8 @@ VLIB_REGISTER_NODE (ip6_full_reassembly_handoff_node) = {
VLIB_NODE_FN (ip6_local_full_reassembly_handoff_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return ip6_full_reassembly_handoff_inline (
- vm, node, frame, false /* is_feature */, true /* is_feature */);
+ return ip6_full_reassembly_handoff_inline (vm, node, frame, NORMAL,
+ true /* is_feature */);
}
VLIB_REGISTER_NODE (ip6_local_full_reassembly_handoff_node) = {
@@ -1933,8 +1974,8 @@ VLIB_REGISTER_NODE (ip6_local_full_reassembly_handoff_node) = {
VLIB_NODE_FN (ip6_full_reassembly_feature_handoff_node) (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * frame)
{
- return ip6_full_reassembly_handoff_inline (
- vm, node, frame, true /* is_feature */, false /* is_local */);
+ return ip6_full_reassembly_handoff_inline (vm, node, frame, FEATURE,
+ false /* is_local */);
}
VLIB_REGISTER_NODE (ip6_full_reassembly_feature_handoff_node) = {
@@ -1951,6 +1992,27 @@ VLIB_REGISTER_NODE (ip6_full_reassembly_feature_handoff_node) = {
},
};
+VLIB_NODE_FN (ip6_full_reassembly_custom_handoff_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return ip6_full_reassembly_handoff_inline (vm, node, frame, CUSTOM,
+ false /* is_local */);
+}
+
+VLIB_REGISTER_NODE (ip6_full_reassembly_custom_handoff_node) = {
+ .name = "ip6-full-reass-custom-hoff",
+ .vector_size = sizeof (u32),
+ .n_errors = ARRAY_LEN(ip6_full_reassembly_handoff_error_strings),
+ .error_strings = ip6_full_reassembly_handoff_error_strings,
+ .format_trace = format_ip6_full_reassembly_handoff_trace,
+
+ .n_next_nodes = 1,
+
+ .next_nodes = {
+ [0] = "error-drop",
+ },
+};
+
#ifndef CLIB_MARCH_VARIANT
int
ip6_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable)