diff options
author | Klement Sekera <ksekera@cisco.com> | 2021-12-14 18:25:11 +0000 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2022-01-31 15:07:58 +0000 |
commit | 01c1fa41f04fbc584165806d3f785cfbbd62cedc (patch) | |
tree | feda9d118e6555ebd5b15b03da49f5b3fa13e1fe /src/vnet/ip | |
parent | cf1e8c1eeab1dc07d69210f410a086d7ae4eae90 (diff) |
ip: reassembly - add a way to disable for forus
Add API to disable full reassembly of "forus" packets. Mark packets
passing through ip[4|6]-local nodes with a new buffer flag and check for
that flag in reassembly.
Enable IP6 "forus" full reassembly by default to be consistent with
existing IP4 setting.
Type: improvement
Change-Id: I7067792fcd4304182654237968e4c4d9293c6143
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Diffstat (limited to 'src/vnet/ip')
-rw-r--r-- | src/vnet/ip/ip.api | 24 | ||||
-rw-r--r-- | src/vnet/ip/ip4_forward.c | 3 | ||||
-rw-r--r-- | src/vnet/ip/ip4_input.c | 1 | ||||
-rw-r--r-- | src/vnet/ip/ip4_input.h | 1 | ||||
-rw-r--r-- | src/vnet/ip/ip6_forward.c | 2 | ||||
-rw-r--r-- | src/vnet/ip/ip_api.c | 24 | ||||
-rw-r--r-- | src/vnet/ip/ip_test.c | 18 | ||||
-rw-r--r-- | src/vnet/ip/reass/ip4_full_reass.c | 122 | ||||
-rw-r--r-- | src/vnet/ip/reass/ip4_full_reass.h | 3 | ||||
-rw-r--r-- | src/vnet/ip/reass/ip6_full_reass.c | 139 | ||||
-rw-r--r-- | src/vnet/ip/reass/ip6_full_reass.h | 2 |
11 files changed, 305 insertions, 34 deletions
diff --git a/src/vnet/ip/ip.api b/src/vnet/ip/ip.api index ca1e2008e4f..cd180981773 100644 --- a/src/vnet/ip/ip.api +++ b/src/vnet/ip/ip.api @@ -836,6 +836,30 @@ autoreply define ip_reassembly_enable_disable vl_api_ip_reass_type_t type; }; +/** enable/disable full reassembly of packets aimed at our addresses */ +autoreply define ip_local_reass_enable_disable +{ + u32 client_index; + u32 context; + bool enable_ip4; + bool enable_ip6; +}; + +/** get status of local reassembly */ +define ip_local_reass_get +{ + u32 client_index; + u32 context; +}; + +define ip_local_reass_get_reply +{ + u32 context; + i32 retval; + bool ip4_is_enabled; + bool ip6_is_enabled; +}; + /** @brief Set a Path MTU value. i.e. a MTU value for a given neighbour. The neighbour can be described as attached (w/ interface and next-hop) diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index de8e8e8538f..4d0638209e5 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -61,6 +61,7 @@ #include <vnet/ip/ip4_forward.h> #include <vnet/interface_output.h> #include <vnet/classify/vnet_classify.h> +#include <vnet/ip/reass/ip4_full_reass.h> /** @brief IPv4 lookup node. @node ip4-lookup @@ -1880,7 +1881,7 @@ VLIB_REGISTER_NODE (ip4_local_node) = [IP_LOCAL_NEXT_PUNT] = "ip4-punt", [IP_LOCAL_NEXT_UDP_LOOKUP] = "ip4-udp-lookup", [IP_LOCAL_NEXT_ICMP] = "ip4-icmp-input", - [IP_LOCAL_NEXT_REASSEMBLY] = "ip4-full-reassembly", + [IP_LOCAL_NEXT_REASSEMBLY] = "ip4-local-full-reassembly", }, }; diff --git a/src/vnet/ip/ip4_input.c b/src/vnet/ip/ip4_input.c index 3b3edf9fca7..0e8d22e188b 100644 --- a/src/vnet/ip/ip4_input.c +++ b/src/vnet/ip/ip4_input.c @@ -399,7 +399,6 @@ VLIB_REGISTER_NODE (ip4_input_node) = { [IP4_INPUT_NEXT_LOOKUP] = "ip4-lookup", [IP4_INPUT_NEXT_LOOKUP_MULTICAST] = "ip4-mfib-forward-lookup", [IP4_INPUT_NEXT_ICMP_ERROR] = "ip4-icmp-error", - [IP4_INPUT_NEXT_REASSEMBLY] = "ip4-full-reassembly", }, .format_buffer = format_ip4_header, diff --git a/src/vnet/ip/ip4_input.h b/src/vnet/ip/ip4_input.h index 53948d60266..57aef0bf77a 100644 --- a/src/vnet/ip/ip4_input.h +++ b/src/vnet/ip/ip4_input.h @@ -52,7 +52,6 @@ typedef enum IP4_INPUT_NEXT_LOOKUP, IP4_INPUT_NEXT_LOOKUP_MULTICAST, IP4_INPUT_NEXT_ICMP_ERROR, - IP4_INPUT_NEXT_REASSEMBLY, IP4_INPUT_N_NEXT, } ip4_input_next_t; diff --git a/src/vnet/ip/ip6_forward.c b/src/vnet/ip/ip6_forward.c index ce165e0e2e4..b876b6f2a78 100644 --- a/src/vnet/ip/ip6_forward.c +++ b/src/vnet/ip/ip6_forward.c @@ -1677,7 +1677,7 @@ VLIB_REGISTER_NODE (ip6_local_node) = [IP_LOCAL_NEXT_PUNT] = "ip6-punt", [IP_LOCAL_NEXT_UDP_LOOKUP] = "ip6-udp-lookup", [IP_LOCAL_NEXT_ICMP] = "ip6-icmp-input", - [IP_LOCAL_NEXT_REASSEMBLY] = "ip6-full-reassembly", + [IP_LOCAL_NEXT_REASSEMBLY] = "ip6-local-full-reassembly", }, }; diff --git a/src/vnet/ip/ip_api.c b/src/vnet/ip/ip_api.c index b1b7ff3a7ae..3ff3a6ce5e0 100644 --- a/src/vnet/ip/ip_api.c +++ b/src/vnet/ip/ip_api.c @@ -1875,6 +1875,30 @@ void REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY); } +void +vl_api_ip_local_reass_enable_disable_t_handler ( + vl_api_ip_local_reass_enable_disable_t *mp) +{ + vl_api_ip_local_reass_enable_disable_reply_t *rmp; + int rv = 0; + + ip4_local_full_reass_enable_disable (mp->enable_ip4); + ip6_local_full_reass_enable_disable (mp->enable_ip6); + + REPLY_MACRO (VL_API_IP_LOCAL_REASS_ENABLE_DISABLE_REPLY); +} + +void +vl_api_ip_local_reass_get_t_handler (vl_api_ip_local_reass_get_t *mp) +{ + vl_api_ip_local_reass_get_reply_t *rmp; + int rv = 0; + REPLY_MACRO2 (VL_API_IP_LOCAL_REASS_GET, { + rmp->ip4_is_enabled = ip4_local_full_reass_enabled (); + rmp->ip6_is_enabled = ip6_local_full_reass_enabled (); + }); +} + static walk_rc_t send_ip_punt_redirect_details (u32 rx_sw_if_index, const ip_punt_redirect_rx_t * ipr, void *arg) diff --git a/src/vnet/ip/ip_test.c b/src/vnet/ip/ip_test.c index f87b47f8912..7c994868d87 100644 --- a/src/vnet/ip/ip_test.c +++ b/src/vnet/ip/ip_test.c @@ -1014,6 +1014,24 @@ api_ip_reassembly_enable_disable (vat_main_t *vat) return -1; } +static int +api_ip_local_reass_enable_disable (vat_main_t *vat) +{ + return -1; +} + +static int +api_ip_local_reass_get (vat_main_t *vat) +{ + return -1; +} + +static void +vl_api_ip_local_reass_get_reply_t_handler ( + vl_api_ip_local_reass_get_reply_t *mp) +{ +} + static void vl_api_ip_reassembly_get_reply_t_handler (vl_api_ip_reassembly_get_reply_t *mp) { diff --git a/src/vnet/ip/reass/ip4_full_reass.c b/src/vnet/ip/reass/ip4_full_reass.c index 79f4673a7f5..220117278c0 100644 --- a/src/vnet/ip/reass/ip4_full_reass.c +++ b/src/vnet/ip/reass/ip4_full_reass.c @@ -183,11 +183,15 @@ typedef struct /** Worker handoff */ 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; + + // whether local fragmented packets are reassembled or not + int is_local_reass_enabled; } ip4_full_reass_main_t; extern ip4_full_reass_main_t ip4_full_reass_main; @@ -219,6 +223,7 @@ typedef enum RANGE_OVERLAP, FINALIZE, HANDOFF, + PASSTHROUGH, } ip4_full_reass_trace_operation_e; typedef struct @@ -329,6 +334,9 @@ format_ip4_full_reass_trace (u8 * s, va_list * args) format (s, "handoff from thread #%u to thread #%u", t->thread_id, t->thread_id_to); break; + case PASSTHROUGH: + s = format (s, "passthrough - not a fragment"); + break; } return s; } @@ -1090,8 +1098,9 @@ ip4_full_reass_update (vlib_main_t * vm, vlib_node_runtime_t * node, } always_inline uword -ip4_full_reass_inline (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * frame, ip4_full_reass_node_type_t type) +ip4_full_reass_inline (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, ip4_full_reass_node_type_t type, + bool is_local) { u32 *from = vlib_frame_vector_args (frame); u32 n_left_from, n_left_to_next, *to_next, next_index; @@ -1127,8 +1136,17 @@ ip4_full_reass_inline (vlib_main_t * vm, vlib_node_runtime_t * node, { next0 = vnet_buffer (b0)->ip.reass.next_index; } + ip4_full_reass_add_trace (vm, node, NULL, bi0, PASSTHROUGH, 0, + ~0); + goto packet_enqueue; + } + + if (is_local && !rm->is_local_reass_enabled) + { + next0 = IP4_FULL_REASS_NEXT_DROP; goto packet_enqueue; } + const u32 fragment_first = ip4_get_fragment_offset_bytes (ip0); const u32 fragment_length = clib_net_to_host_u16 (ip0->length) - ip4_header_bytes (ip0); @@ -1269,7 +1287,7 @@ VLIB_NODE_FN (ip4_full_reass_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_full_reass_inline (vm, node, frame, NORMAL); + return ip4_full_reass_inline (vm, node, frame, NORMAL, false /* is_local */); } VLIB_REGISTER_NODE (ip4_full_reass_node) = { @@ -1288,11 +1306,34 @@ VLIB_REGISTER_NODE (ip4_full_reass_node) = { }, }; +VLIB_NODE_FN (ip4_local_full_reass_node) +(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) +{ + return ip4_full_reass_inline (vm, node, frame, NORMAL, true /* is_local */); +} + +VLIB_REGISTER_NODE (ip4_local_full_reass_node) = { + .name = "ip4-local-full-reassembly", + .vector_size = sizeof (u32), + .format_trace = format_ip4_full_reass_trace, + .n_errors = ARRAY_LEN (ip4_full_reass_error_strings), + .error_strings = ip4_full_reass_error_strings, + .n_next_nodes = IP4_FULL_REASS_N_NEXT, + .next_nodes = + { + [IP4_FULL_REASS_NEXT_INPUT] = "ip4-input", + [IP4_FULL_REASS_NEXT_DROP] = "ip4-drop", + [IP4_FULL_REASS_NEXT_HANDOFF] = "ip4-local-full-reassembly-handoff", + + }, +}; + VLIB_NODE_FN (ip4_full_reass_node_feature) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_full_reass_inline (vm, node, frame, FEATURE); + return ip4_full_reass_inline (vm, node, frame, FEATURE, + false /* is_local */); } VLIB_REGISTER_NODE (ip4_full_reass_node_feature) = { @@ -1322,7 +1363,7 @@ VLIB_NODE_FN (ip4_full_reass_node_custom) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_full_reass_inline (vm, node, frame, CUSTOM); + return ip4_full_reass_inline (vm, node, frame, CUSTOM, false /* is_local */); } VLIB_REGISTER_NODE (ip4_full_reass_node_custom) = { @@ -1495,12 +1536,16 @@ ip4_full_reass_init_function (vlib_main_t * vm) rm->ip4_drop_idx = node->index; rm->fq_index = vlib_frame_queue_main_init (ip4_full_reass_node.index, 0); + rm->fq_local_index = + vlib_frame_queue_main_init (ip4_local_full_reass_node.index, 0); rm->fq_feature_index = vlib_frame_queue_main_init (ip4_full_reass_node_feature.index, 0); rm->fq_custom_index = vlib_frame_queue_main_init (ip4_full_reass_node_custom.index, 0); rm->feature_use_refcount_per_intf = NULL; + rm->is_local_reass_enabled = 1; + return error; } @@ -1745,10 +1790,10 @@ format_ip4_full_reass_handoff_trace (u8 * s, va_list * args) } always_inline uword -ip4_full_reass_handoff_node_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, - ip4_full_reass_node_type_t type) +ip4_full_reass_handoff_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, + ip4_full_reass_node_type_t type, + bool is_local) { ip4_full_reass_main_t *rm = &ip4_full_reass_main; @@ -1767,7 +1812,14 @@ ip4_full_reass_handoff_node_inline (vlib_main_t * vm, switch (type) { case NORMAL: - fq_index = rm->fq_index; + if (is_local) + { + fq_index = rm->fq_local_index; + } + else + { + fq_index = rm->fq_index; + } break; case FEATURE: fq_index = rm->fq_feature_index; @@ -1777,7 +1829,6 @@ ip4_full_reass_handoff_node_inline (vlib_main_t * vm, break; default: clib_warning ("Unexpected `type' (%d)!", type); - ASSERT (0); } while (n_left_from > 0) @@ -1811,7 +1862,8 @@ VLIB_NODE_FN (ip4_full_reass_handoff_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_full_reass_handoff_node_inline (vm, node, frame, NORMAL); + return ip4_full_reass_handoff_node_inline (vm, node, frame, NORMAL, + false /* is_local */); } @@ -1829,13 +1881,34 @@ VLIB_REGISTER_NODE (ip4_full_reass_handoff_node) = { }, }; +VLIB_NODE_FN (ip4_local_full_reass_handoff_node) +(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) +{ + return ip4_full_reass_handoff_node_inline (vm, node, frame, NORMAL, + true /* is_local */); +} + +VLIB_REGISTER_NODE (ip4_local_full_reass_handoff_node) = { + .name = "ip4-local-full-reassembly-handoff", + .vector_size = sizeof (u32), + .n_errors = ARRAY_LEN(ip4_full_reass_handoff_error_strings), + .error_strings = ip4_full_reass_handoff_error_strings, + .format_trace = format_ip4_full_reass_handoff_trace, + + .n_next_nodes = 1, + + .next_nodes = { + [0] = "error-drop", + }, +}; VLIB_NODE_FN (ip4_full_reass_feature_handoff_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip4_full_reass_handoff_node_inline (vm, node, frame, FEATURE); + return ip4_full_reass_handoff_node_inline (vm, node, frame, FEATURE, + false /* is_local */); } @@ -1858,7 +1931,8 @@ VLIB_NODE_FN (ip4_full_reass_custom_handoff_node) (vlib_main_t * vm, node, vlib_frame_t * frame) { - return ip4_full_reass_handoff_node_inline (vm, node, frame, CUSTOM); + return ip4_full_reass_handoff_node_inline (vm, node, frame, CUSTOM, + false /* is_local */); } @@ -1903,6 +1977,26 @@ ip4_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable) } return -1; } + +void +ip4_local_full_reass_enable_disable (int enable) +{ + if (enable) + { + ip4_full_reass_main.is_local_reass_enabled = 1; + } + else + { + ip4_full_reass_main.is_local_reass_enabled = 0; + } +} + +int +ip4_local_full_reass_enabled () +{ + return ip4_full_reass_main.is_local_reass_enabled; +} + #endif /* diff --git a/src/vnet/ip/reass/ip4_full_reass.h b/src/vnet/ip/reass/ip4_full_reass.h index 000c80c5906..5df8107ca48 100644 --- a/src/vnet/ip/reass/ip4_full_reass.h +++ b/src/vnet/ip/reass/ip4_full_reass.h @@ -47,6 +47,9 @@ int ip4_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable); uword ip4_full_reass_custom_register_next_node (uword node_index); + +void ip4_local_full_reass_enable_disable (int enable); +int ip4_local_full_reass_enabled (); #endif /* __included_ip4_full_reass_h__ */ /* diff --git a/src/vnet/ip/reass/ip6_full_reass.c b/src/vnet/ip/reass/ip6_full_reass.c index 12cacfc2f33..1bcb6bd0f20 100644 --- a/src/vnet/ip/reass/ip6_full_reass.c +++ b/src/vnet/ip/reass/ip6_full_reass.c @@ -164,10 +164,14 @@ typedef struct /** Worker handoff */ u32 fq_index; + u32 fq_local_index; u32 fq_feature_index; // reference count for enabling/disabling feature - per interface u32 *feature_use_refcount_per_intf; + + // whether local fragmented packets are reassembled or not + int is_local_reass_enabled; } ip6_full_reass_main_t; extern ip6_full_reass_main_t ip6_full_reass_main; @@ -194,6 +198,7 @@ typedef enum ICMP_ERROR_FL_NOT_MULT_8, FINALIZE, HANDOFF, + PASSTHROUGH, } ip6_full_reass_trace_operation_e; typedef struct @@ -306,6 +311,9 @@ format_ip6_full_reass_trace (u8 * s, va_list * args) format (s, "handoff from thread #%u to thread #%u", t->thread_id, t->thread_id_to); break; + case PASSTHROUGH: + s = format (s, "passthrough - not a fragment"); + break; } return s; } @@ -1084,10 +1092,9 @@ ip6_full_reass_verify_packet_size_lt_64k (vlib_main_t * vm, } always_inline uword -ip6_full_reassembly_inline (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, bool is_feature, - bool is_custom_app) +ip6_full_reassembly_inline (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, bool is_feature, + bool is_custom_app, bool is_local) { u32 *from = vlib_frame_vector_args (frame); u32 n_left_from, n_left_to_next, *to_next, next_index; @@ -1122,6 +1129,13 @@ ip6_full_reassembly_inline (vlib_main_t * vm, { // this is a mangled packet - no fragmentation next0 = IP6_FULL_REASSEMBLY_NEXT_DROP; + ip6_full_reass_add_trace (vm, node, NULL, bi0, NULL, PASSTHROUGH, + ~0); + goto skip_reass; + } + if (is_local && !rm->is_local_reass_enabled) + { + next0 = IP6_FULL_REASSEMBLY_NEXT_DROP; goto skip_reass; } frag_hdr = @@ -1303,8 +1317,9 @@ VLIB_NODE_FN (ip6_full_reass_node) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip6_full_reassembly_inline (vm, node, frame, false /* is_feature */ , - false /* is_custom_app */ ); + return ip6_full_reassembly_inline (vm, node, frame, false /* is_feature */, + false /* is_custom_app */, + false /* is_local */); } VLIB_REGISTER_NODE (ip6_full_reass_node) = { @@ -1323,12 +1338,37 @@ VLIB_REGISTER_NODE (ip6_full_reass_node) = { }, }; +VLIB_NODE_FN (ip6_local_full_reass_node) +(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame) +{ + return ip6_full_reassembly_inline (vm, node, frame, false /* is_feature */, + false /* is_custom_app */, + true /* is_local */); +} + +VLIB_REGISTER_NODE (ip6_local_full_reass_node) = { + .name = "ip6-local-full-reassembly", + .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-local-full-reassembly-handoff", + }, +}; + VLIB_NODE_FN (ip6_full_reass_node_feature) (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) { - return ip6_full_reassembly_inline (vm, node, frame, true /* is_feature */ , - false /* is_custom_app */ ); + return ip6_full_reassembly_inline (vm, node, frame, true /* is_feature */, + false /* is_custom_app */, + false /* is_local */); } VLIB_REGISTER_NODE (ip6_full_reass_node_feature) = { @@ -1500,9 +1540,12 @@ ip6_full_reass_init_function (vlib_main_t * vm) if ((error = vlib_call_init_function (vm, ip_main_init))) return error; ip6_register_protocol (IP_PROTOCOL_IPV6_FRAGMENTATION, - ip6_full_reass_node.index); + ip6_local_full_reass_node.index); + rm->is_local_reass_enabled = 1; rm->fq_index = vlib_frame_queue_main_init (ip6_full_reass_node.index, 0); + rm->fq_local_index = + 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); @@ -1777,9 +1820,9 @@ 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) +ip6_full_reassembly_handoff_inline (vlib_main_t *vm, vlib_node_runtime_t *node, + vlib_frame_t *frame, bool is_feature, + bool is_local) { ip6_full_reass_main_t *rm = &ip6_full_reass_main; @@ -1795,7 +1838,21 @@ ip6_full_reassembly_handoff_inline (vlib_main_t * vm, b = bufs; ti = thread_indices; - fq_index = (is_feature) ? rm->fq_feature_index : rm->fq_index; + if (is_feature) + { + fq_index = rm->fq_feature_index; + } + else + { + if (is_local) + { + fq_index = rm->fq_local_index; + } + else + { + fq_index = rm->fq_index; + } + } while (n_left_from > 0) { @@ -1828,8 +1885,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 */ ); + return ip6_full_reassembly_handoff_inline ( + vm, node, frame, false /* is_feature */, false /* is_local */); } VLIB_REGISTER_NODE (ip6_full_reassembly_handoff_node) = { @@ -1846,11 +1903,32 @@ 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 */); +} + +VLIB_REGISTER_NODE (ip6_local_full_reassembly_handoff_node) = { + .name = "ip6-local-full-reassembly-handoff", + .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", + }, +}; 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 */ ); + return ip6_full_reassembly_handoff_inline ( + vm, node, frame, true /* is_feature */, false /* is_local */); } @@ -1895,6 +1973,35 @@ ip6_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable) } return -1; } + +void +ip6_local_full_reass_enable_disable (int enable) +{ + if (enable) + { + if (!ip6_full_reass_main.is_local_reass_enabled) + { + ip6_full_reass_main.is_local_reass_enabled = 1; + ip6_register_protocol (IP_PROTOCOL_IPV6_FRAGMENTATION, + ip6_local_full_reass_node.index); + } + } + else + { + if (ip6_full_reass_main.is_local_reass_enabled) + { + ip6_full_reass_main.is_local_reass_enabled = 0; + ip6_unregister_protocol (IP_PROTOCOL_IPV6_FRAGMENTATION); + } + } +} + +int +ip6_local_full_reass_enabled () +{ + return ip6_full_reass_main.is_local_reass_enabled; +} + #endif /* diff --git a/src/vnet/ip/reass/ip6_full_reass.h b/src/vnet/ip/reass/ip6_full_reass.h index 546075b04b4..f66cb67d796 100644 --- a/src/vnet/ip/reass/ip6_full_reass.h +++ b/src/vnet/ip/reass/ip6_full_reass.h @@ -46,6 +46,8 @@ vnet_api_error_t ip6_full_reass_enable_disable (u32 sw_if_index, int ip6_full_reass_enable_disable_with_refcnt (u32 sw_if_index, int is_enable); +void ip6_local_full_reass_enable_disable (int enable); +int ip6_local_full_reass_enabled (); #endif /* __included_ip6_full_reass_h */ /* |