From b412048cae497643a794c1d2c6ce1deb65ef38e7 Mon Sep 17 00:00:00 2001 From: Hongjun Ni Date: Thu, 28 Jul 2016 20:11:33 +0800 Subject: Add NSH-Proxy feature within NSH_SFC PatchSet 6: spit nsh_input to three node instances PatchSet 5: refactor NSH-Proxy PatchSet 4: Fix some issues PatchSet 3: get parameters from VPP via metadata PatchSet 2: Add FIXME Change-Id: I97448af867eb71554b8629f8da57a2ed6c6a3b8a Signed-off-by: Hongjun Ni --- nsh-plugin/nsh/nsh.c | 368 +++++++++++++++++++++++++++++++++++++++------- nsh-plugin/nsh/nsh.h | 50 +++++-- nsh-plugin/nsh/nsh_test.c | 6 +- 3 files changed, 356 insertions(+), 68 deletions(-) diff --git a/nsh-plugin/nsh/nsh.c b/nsh-plugin/nsh/nsh.c index 12c8d6b..c26c228 100644 --- a/nsh-plugin/nsh/nsh.c +++ b/nsh-plugin/nsh/nsh.c @@ -174,16 +174,26 @@ u8 * format_nsh_map (u8 * s, va_list * args) switch (map->next_node) { - case NSH_INPUT_NEXT_ENCAP_GRE: + case NSH_NODE_NEXT_ENCAP_GRE: { s = format (s, "encapped by GRE intf: %d", map->sw_if_index); break; } - case NSH_INPUT_NEXT_ENCAP_VXLANGPE: + case NSH_NODE_NEXT_ENCAP_VXLANGPE: { s = format (s, "encapped by VXLAN GPE intf: %d", map->sw_if_index); break; } + case NSH_NODE_NEXT_ENCAP_VXLAN4: + { + s = format (s, "encapped by VXLAN4 intf: %d", map->sw_if_index); + break; + } + case NSH_NODE_NEXT_ENCAP_VXLAN6: + { + s = format (s, "encapped by VXLAN6 intf: %d", map->sw_if_index); + break; + } default: s = format (s, "only GRE and VXLANGPE support in this rev"); } @@ -225,7 +235,7 @@ u8 * format_nsh_header_with_length (u8 * s, va_list * args) return s; } -u8 * format_nsh_input_map_trace (u8 * s, va_list * args) +u8 * format_nsh_node_map_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 *); @@ -300,6 +310,67 @@ int nsh_add_del_map (nsh_add_del_map_args_t *a, u32 * map_indexp) return 0; } +/** + * Action function to add or del an nsh-proxy-session. + * Shared by both CLI and binary API + **/ + +int nsh_add_del_proxy_session (nsh_add_del_map_args_t *a) +{ + nsh_main_t * nm = &nsh_main; + nsh_proxy_session_t *proxy = 0; + nsh_proxy_session_by_key_t key, *key_copy; + uword * entry; + hash_pair_t *hp; + u32 nsp = 0, nsi = 0; + + memset (&key, 0, sizeof (key)); + key.transport_type = a->map.next_node; + key.transport_index = a->map.sw_if_index; + + entry = hash_get_mem (nm->nsh_proxy_session_by_key, &key); + + if (a->is_add) + { + /* adding an entry, must not already exist */ + if (entry) + return -1; //TODO API_ERROR_INVALID_VALUE; + + pool_get_aligned (nm->nsh_proxy_sessions, proxy, CLIB_CACHE_LINE_BYTES); + memset (proxy, 0, sizeof (*proxy)); + + /* Nsi needs to minus 1 within NSH-Proxy */ + nsp = (a->map.nsp_nsi>>NSH_NSP_SHIFT) & NSH_NSP_MASK; + nsi = a->map.nsp_nsi & NSH_NSI_MASK; + if (nsi == 0 ) + return -1; + + nsi = nsi -1; + proxy->nsp_nsi = (nsp<< NSH_NSP_SHIFT) | nsi; + + key_copy = clib_mem_alloc (sizeof (*key_copy)); + clib_memcpy (key_copy, &key, sizeof (*key_copy)); + + hash_set_mem (nm->nsh_proxy_session_by_key, key_copy, + proxy - nm->nsh_proxy_sessions); + } + else + { + if (!entry) + return -2 ; //TODO API_ERROR_NO_SUCH_ENTRY; + + proxy = pool_elt_at_index (nm->nsh_proxy_sessions, entry[0]); + hp = hash_get_pair (nm->nsh_proxy_session_by_key, &key); + key_copy = (void *)(hp->key); + hash_unset_mem (nm->nsh_proxy_session_by_key, &key); + clib_mem_free (key_copy); + + pool_put (nm->nsh_proxy_sessions, proxy); + } + + return 0; +} + /** * CLI command for NSH map */ @@ -358,11 +429,15 @@ nsh_add_del_map_command_fn (vlib_main_t * vm, &nsh_action)) nsh_action_set = 1; else if (unformat (line_input, "encap-gre-intf %d", &sw_if_index)) - next_node = NSH_INPUT_NEXT_ENCAP_GRE; + next_node = NSH_NODE_NEXT_ENCAP_GRE; else if (unformat (line_input, "encap-vxlan-gpe-intf %d", &sw_if_index)) - next_node = NSH_INPUT_NEXT_ENCAP_VXLANGPE; + next_node = NSH_NODE_NEXT_ENCAP_VXLANGPE; + else if (unformat (line_input, "encap-vxlan4-intf %d", &sw_if_index)) + next_node = NSH_NODE_NEXT_ENCAP_VXLAN4; + else if (unformat (line_input, "encap-vxlan6-intf %d", &sw_if_index)) + next_node = NSH_NODE_NEXT_ENCAP_VXLAN6; else if (unformat (line_input, "encap-none")) - next_node = NSH_INPUT_NEXT_DROP; // Once moved to NSHSFC see nsh.h:foreach_nsh_input_next to handle this case + next_node = NSH_NODE_NEXT_DROP; // Once moved to NSHSFC see nsh.h:foreach_nsh_input_next to handle this case else return clib_error_return (0, "parse error: '%U'", format_unformat_error, line_input); @@ -392,8 +467,7 @@ nsh_add_del_map_command_fn (vlib_main_t * vm, a->map.sw_if_index = sw_if_index; a->map.next_node = next_node; - - rv = nsh_add_del_map (a, &map_index); + rv = nsh_add_del_map(a, &map_index); switch(rv) { @@ -409,6 +483,28 @@ nsh_add_del_map_command_fn (vlib_main_t * vm, return clib_error_return (0, "nsh_add_del_map returned %d", rv); } + + if((a->map.next_node == NSH_NODE_NEXT_ENCAP_VXLAN4) + | (a->map.next_node == NSH_NODE_NEXT_ENCAP_VXLAN6)) + { + rv = nsh_add_del_proxy_session(a); + + switch(rv) + { + case 0: + break; + case -1: //TODO API_ERROR_INVALID_VALUE: + return clib_error_return (0, "nsh-proxy-session already exists. Remove it first."); + + case -2: // TODO API_ERROR_NO_SUCH_ENTRY: + return clib_error_return (0, "nsh-proxy-session does not exist."); + + default: + return clib_error_return + (0, "nsh_add_del_proxy_session() returned %d", rv); + } + } + return 0; } @@ -835,7 +931,8 @@ nsh_plugin_api_hookup (vlib_main_t *vm) static uword nsh_input_map (vlib_main_t * vm, vlib_node_runtime_t * node, - vlib_frame_t * from_frame) + vlib_frame_t * from_frame, + u32 node_type) { u32 n_left_from, next_index, *from, *to_next; nsh_main_t * nm = &nsh_main; @@ -855,7 +952,7 @@ nsh_input_map (vlib_main_t * vm, { u32 bi0, bi1; vlib_buffer_t * b0, *b1; - u32 next0 = NSH_INPUT_NEXT_DROP, next1 = NSH_INPUT_NEXT_DROP; + u32 next0 = NSH_NODE_NEXT_DROP, next1 = NSH_NODE_NEXT_DROP; uword * entry0, *entry1; nsh_header_t * hdr0 = 0, *hdr1 = 0; u32 header_len0 = 0, header_len1 = 0; @@ -864,6 +961,9 @@ nsh_input_map (vlib_main_t * vm, nsh_map_t * map0 = 0, *map1 = 0; nsh_header_t *encap_hdr0 = 0, *encap_hdr1 = 0; u32 encap_hdr_len0 = 0, encap_hdr_len1 = 0; + nsh_proxy_session_by_key_t key0, key1; + uword *p0, *p1; + nsh_proxy_session_t *proxy0, *proxy1; /* Prefetch next iteration. */ { @@ -893,19 +993,71 @@ nsh_input_map (vlib_main_t * vm, b0 = vlib_get_buffer(vm, bi0); hdr0 = vlib_buffer_get_current(b0); - header_len0 = hdr0->length * 4; - nsp_nsi0 = clib_net_to_host_u32(hdr0->nsp_nsi); + if(node_type == NSH_INPUT_TYPE) + { + nsp_nsi0 = clib_net_to_host_u32(hdr0->nsp_nsi); + header_len0 = hdr0->length * 4; + } + else + { + memset (&key0, 0, sizeof(key0)); + key0.transport_type = NSH_NODE_NEXT_ENCAP_VXLAN4; + key0.transport_index = vnet_buffer(b0)->sw_if_index[VLIB_RX]; + + p0 = hash_get_mem(nm->nsh_proxy_session_by_key, &key0); + if (PREDICT_FALSE(p0 == 0)) + { + error0 = NSH_NODE_ERROR_NO_PROXY; + goto trace0; + } + + proxy0 = pool_elt_at_index(nm->nsh_proxy_sessions, p0[0]); + if (PREDICT_FALSE(proxy0 == 0)) + { + error0 = NSH_NODE_ERROR_NO_PROXY; + goto trace0; + } + nsp_nsi0 = proxy0->nsp_nsi; + } + + entry0 = hash_get_mem(nm->nsh_mapping_by_key, &nsp_nsi0); b1 = vlib_get_buffer(vm, bi1); - hdr1 = vlib_buffer_get_current(b1); - header_len1 = hdr1->length * 4; - nsp_nsi1 = clib_net_to_host_u32(hdr1->nsp_nsi); + hdr1 = vlib_buffer_get_current(b1); + if(node_type == NSH_INPUT_TYPE) + { + nsp_nsi1 = clib_net_to_host_u32(hdr1->nsp_nsi); + header_len1 = hdr1->length * 4; + } + else + { + memset (&key1, 0, sizeof(key1)); + key1.transport_type = NSH_NODE_NEXT_ENCAP_VXLAN4; + key1.transport_index = vnet_buffer(b1)->sw_if_index[VLIB_RX]; + + p1 = hash_get_mem(nm->nsh_proxy_session_by_key, &key1); + if (PREDICT_FALSE(p1 == 0)) + { + error1 = NSH_NODE_ERROR_NO_PROXY; + goto trace1; + } + + proxy1 = pool_elt_at_index(nm->nsh_proxy_sessions, p1[0]); + if (PREDICT_FALSE(proxy1 == 0)) + { + error1 = NSH_NODE_ERROR_NO_PROXY; + goto trace1; + } + nsp_nsi1 = proxy1->nsp_nsi; + } + + entry1 = hash_get_mem(nm->nsh_mapping_by_key, &nsp_nsi1); /* Process packet 0 */ entry0 = hash_get_mem(nm->nsh_mapping_by_key, &nsp_nsi0); if (PREDICT_FALSE(entry0 == 0)) { - error0 = NSH_INPUT_ERROR_NO_MAPPING; + error0 = NSH_NODE_ERROR_NO_MAPPING; goto trace0; } @@ -913,7 +1065,7 @@ nsh_input_map (vlib_main_t * vm, map0 = pool_elt_at_index(nm->nsh_mappings, entry0[0]); if (PREDICT_FALSE(map0 == 0)) { - error0 = NSH_INPUT_ERROR_NO_MAPPING; + error0 = NSH_NODE_ERROR_NO_MAPPING; goto trace0; } @@ -931,33 +1083,33 @@ nsh_input_map (vlib_main_t * vm, entry0 = hash_get_mem(nm->nsh_entry_by_key, &map0->mapped_nsp_nsi); if (PREDICT_FALSE(entry0 == 0)) { - error0 = NSH_INPUT_ERROR_NO_ENTRY; + error0 = NSH_NODE_ERROR_NO_ENTRY; goto trace0; } encap_hdr0 = pool_elt_at_index(nm->nsh_entries, entry0[0]); encap_hdr_len0 = encap_hdr0->length * 4; - if(PREDICT_TRUE(map0->nsh_action == NSH_ACTION_SWAP)) - { + if(PREDICT_TRUE(map0->nsh_action == NSH_ACTION_SWAP)) + { /* Pop old NSH header */ - vlib_buffer_advance(b0, (word)header_len0); + vlib_buffer_advance(b0, (word)header_len0); - /* Push new NSH header */ - vlib_buffer_advance(b0, -(word)encap_hdr_len0); - hdr0 = vlib_buffer_get_current(b0); - clib_memcpy(hdr0, encap_hdr0, (word)encap_hdr_len0); + /* Push new NSH header */ + vlib_buffer_advance(b0, -(word)encap_hdr_len0); + hdr0 = vlib_buffer_get_current(b0); + clib_memcpy(hdr0, encap_hdr0, (word)encap_hdr_len0); - goto trace0; - } + goto trace0; + } - if(PREDICT_FALSE(map0->nsh_action == NSH_ACTION_PUSH)) - { - /* Push new NSH header */ - vlib_buffer_advance(b0, -(word)encap_hdr_len0); - hdr0 = vlib_buffer_get_current(b0); - clib_memcpy(hdr0, encap_hdr0, (word)encap_hdr_len0); - } + if(PREDICT_TRUE(map0->nsh_action == NSH_ACTION_PUSH)) + { + /* Push new NSH header */ + vlib_buffer_advance(b0, -(word)encap_hdr_len0); + hdr0 = vlib_buffer_get_current(b0); + clib_memcpy(hdr0, encap_hdr0, (word)encap_hdr_len0); + } trace0: b0->error = error0 ? node->errors[error0] : 0; @@ -971,7 +1123,7 @@ nsh_input_map (vlib_main_t * vm, entry1 = hash_get_mem(nm->nsh_mapping_by_key, &nsp_nsi1); if (PREDICT_FALSE(entry1 == 0)) { - error1 = NSH_INPUT_ERROR_NO_MAPPING; + error1 = NSH_NODE_ERROR_NO_MAPPING; goto trace1; } @@ -979,7 +1131,7 @@ nsh_input_map (vlib_main_t * vm, map1 = pool_elt_at_index(nm->nsh_mappings, entry1[0]); if (PREDICT_FALSE(map1 == 0)) { - error1 = NSH_INPUT_ERROR_NO_MAPPING; + error1 = NSH_NODE_ERROR_NO_MAPPING; goto trace1; } @@ -989,7 +1141,7 @@ nsh_input_map (vlib_main_t * vm, if(PREDICT_FALSE(map1->nsh_action == NSH_ACTION_POP)) { - /* Pop NSH header */ + /* Pop NSH header */ vlib_buffer_advance(b1, (word)header_len1); goto trace1; } @@ -997,7 +1149,7 @@ nsh_input_map (vlib_main_t * vm, entry1 = hash_get_mem(nm->nsh_entry_by_key, &map1->mapped_nsp_nsi); if (PREDICT_FALSE(entry1 == 0)) { - error1 = NSH_INPUT_ERROR_NO_ENTRY; + error1 = NSH_NODE_ERROR_NO_ENTRY; goto trace1; } @@ -1042,7 +1194,7 @@ nsh_input_map (vlib_main_t * vm, { u32 bi0; vlib_buffer_t * b0; - u32 next0 = NSH_INPUT_NEXT_DROP; + u32 next0 = NSH_NODE_NEXT_DROP; uword * entry0; nsh_header_t * hdr0 = 0; u32 header_len0 = 0; @@ -1051,6 +1203,9 @@ nsh_input_map (vlib_main_t * vm, nsh_map_t * map0 = 0; nsh_header_t * encap_hdr0 = 0; u32 encap_hdr_len0 = 0; + nsh_proxy_session_by_key_t key0; + uword *p0; + nsh_proxy_session_t *proxy0 = 0; bi0 = from[0]; to_next[0] = bi0; @@ -1062,13 +1217,39 @@ nsh_input_map (vlib_main_t * vm, b0 = vlib_get_buffer(vm, bi0); hdr0 = vlib_buffer_get_current(b0); - header_len0 = hdr0->length * 4; - nsp_nsi0 = clib_net_to_host_u32(hdr0->nsp_nsi); + + if(node_type == NSH_INPUT_TYPE) + { + nsp_nsi0 = clib_net_to_host_u32(hdr0->nsp_nsi); + header_len0 = hdr0->length * 4; + } + else + { + memset (&key0, 0, sizeof(key0)); + key0.transport_type = NSH_NODE_NEXT_ENCAP_VXLAN4; + key0.transport_index = vnet_buffer(b0)->sw_if_index[VLIB_RX]; + + p0 = hash_get_mem(nm->nsh_proxy_session_by_key, &key0); + if (PREDICT_FALSE(p0 == 0)) + { + error0 = NSH_NODE_ERROR_NO_PROXY; + goto trace00; + } + + proxy0 = pool_elt_at_index(nm->nsh_proxy_sessions, p0[0]); + if (PREDICT_FALSE(proxy0 == 0)) + { + error0 = NSH_NODE_ERROR_NO_PROXY; + goto trace00; + } + nsp_nsi0 = proxy0->nsp_nsi; + } + entry0 = hash_get_mem(nm->nsh_mapping_by_key, &nsp_nsi0); if (PREDICT_FALSE(entry0 == 0)) { - error0 = NSH_INPUT_ERROR_NO_MAPPING; + error0 = NSH_NODE_ERROR_NO_MAPPING; goto trace00; } @@ -1077,7 +1258,7 @@ nsh_input_map (vlib_main_t * vm, if (PREDICT_FALSE(map0 == 0)) { - error0 = NSH_INPUT_ERROR_NO_MAPPING; + error0 = NSH_NODE_ERROR_NO_MAPPING; goto trace00; } @@ -1087,16 +1268,15 @@ nsh_input_map (vlib_main_t * vm, if(PREDICT_FALSE(map0->nsh_action == NSH_ACTION_POP)) { - /* Pop NSH header */ + /* Pop NSH header */ vlib_buffer_advance(b0, (word)header_len0); goto trace00; } entry0 = hash_get_mem(nm->nsh_entry_by_key, &map0->mapped_nsp_nsi); - if (PREDICT_FALSE(entry0 == 0)) { - error0 = NSH_INPUT_ERROR_NO_ENTRY; + error0 = NSH_NODE_ERROR_NO_ENTRY; goto trace00; } @@ -1124,7 +1304,7 @@ nsh_input_map (vlib_main_t * vm, clib_memcpy(hdr0, encap_hdr0, (word)encap_hdr_len0); } - trace00: b0->error = error0 ? node->errors[error0] : 0; + trace00: b0->error = error0 ? node->errors[error0] : 0; if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { @@ -1143,33 +1323,94 @@ nsh_input_map (vlib_main_t * vm, return from_frame->n_vectors; } +/** + * @brief Graph processing dispatch function for NSH Input + * + * @node nsh_input + * @param *vm + * @param *node + * @param *from_frame + * + * @return from_frame->n_vectors + * + */ +static uword +nsh_input (vlib_main_t * vm, vlib_node_runtime_t * node, + vlib_frame_t * from_frame) +{ + return nsh_input_map (vm, node, from_frame, NSH_INPUT_TYPE); +} -static char * nsh_input_error_strings[] = { +/** + * @brief Graph processing dispatch function for NSH-Proxy + * + * @node nsh_proxy + * @param *vm + * @param *node + * @param *from_frame + * + * @return from_frame->n_vectors + * + */ +static uword +nsh_proxy (vlib_main_t * vm, vlib_node_runtime_t * node, + vlib_frame_t * from_frame) +{ + return nsh_input_map (vm, node, from_frame, NSH_PROXY_TYPE); +} + +static char * nsh_node_error_strings[] = { #define _(sym,string) string, - foreach_nsh_input_error + foreach_nsh_node_error #undef _ }; +/* register nsh-input node */ VLIB_REGISTER_NODE (nsh_input_node) = { - .function = nsh_input_map, + .function = nsh_input, .name = "nsh-input", .vector_size = sizeof (u32), - .format_trace = format_nsh_input_map_trace, + .format_trace = format_nsh_node_map_trace, + .format_buffer = format_nsh_header_with_length, + .type = VLIB_NODE_TYPE_INTERNAL, + + .n_errors = ARRAY_LEN(nsh_node_error_strings), + .error_strings = nsh_node_error_strings, + + .n_next_nodes = NSH_NODE_N_NEXT, + + .next_nodes = { +#define _(s,n) [NSH_NODE_NEXT_##s] = n, + foreach_nsh_node_next +#undef _ + }, +}; + +VLIB_NODE_FUNCTION_MULTIARCH (nsh_input_node, nsh_input); + +/* register nsh-proxy node */ +VLIB_REGISTER_NODE (nsh_proxy_node) = { + .function = nsh_proxy, + .name = "nsh-proxy", + .vector_size = sizeof (u32), + .format_trace = format_nsh_node_map_trace, .format_buffer = format_nsh_header_with_length, .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = ARRAY_LEN(nsh_input_error_strings), - .error_strings = nsh_input_error_strings, + .n_errors = ARRAY_LEN(nsh_node_error_strings), + .error_strings = nsh_node_error_strings, - .n_next_nodes = NSH_INPUT_N_NEXT, + .n_next_nodes = NSH_NODE_N_NEXT, .next_nodes = { -#define _(s,n) [NSH_INPUT_NEXT_##s] = n, - foreach_nsh_input_next +#define _(s,n) [NSH_NODE_NEXT_##s] = n, + foreach_nsh_node_next #undef _ }, }; +VLIB_NODE_FUNCTION_MULTIARCH (nsh_proxy_node, nsh_proxy); + clib_error_t *nsh_init (vlib_main_t *vm) { nsh_main_t *nm = &nsh_main; @@ -1193,6 +1434,9 @@ clib_error_t *nsh_init (vlib_main_t *vm) nm->nsh_entry_by_key = hash_create_mem (0, sizeof(u32), sizeof (uword)); + nm->nsh_proxy_session_by_key + = hash_create_mem (0, sizeof(nsh_proxy_session_by_key_t), sizeof (uword)); + name = format (0, "nsh_%08x%c", api_version, 0); /* Set up the API */ @@ -1206,14 +1450,26 @@ clib_error_t *nsh_init (vlib_main_t *vm) ASSERT(vxlan4_gpe_input_node); //alagalah - validate we don't really need to use the node value vlib_node_add_next (vm, vxlan4_gpe_input_node->index, nsh_input_node.index); + vlib_node_add_next (vm, vxlan4_gpe_input_node->index, nsh_proxy_node.index); vxlan6_gpe_input_node = vlib_get_node_by_name (vm, (u8 *)"vxlan6-gpe-input"); ASSERT(vxlan6_gpe_input_node); vlib_node_add_next (vm, vxlan6_gpe_input_node->index, nsh_input_node.index); + vlib_node_add_next (vm, vxlan6_gpe_input_node->index, nsh_proxy_node.index); gre_input_node = vlib_get_node_by_name (vm, (u8 *)"gre-input"); ASSERT(gre_input_node); vlib_node_add_next (vm, gre_input_node->index, nsh_input_node.index); + vlib_node_add_next (vm, gre_input_node->index, nsh_proxy_node.index); + + /* Add NSH-Proxy support */ + vxlan4_input_node = vlib_get_node_by_name (vm, (u8 *)"vxlan4-input"); + ASSERT(vxlan4_input_node); + vlib_node_add_next (vm, vxlan4_input_node->index, nsh_proxy_node.index); + + vxlan6_input_node = vlib_get_node_by_name (vm, (u8 *)"vxlan6-input"); + ASSERT(vxlan6_input_node); + vlib_node_add_next (vm, vxlan6_input_node->index, nsh_proxy_node.index); vec_free(name); diff --git a/nsh-plugin/nsh/nsh.h b/nsh-plugin/nsh/nsh.h index 539a45d..781245b 100644 --- a/nsh-plugin/nsh/nsh.h +++ b/nsh-plugin/nsh/nsh.h @@ -43,6 +43,21 @@ typedef struct { } nsh_map_t; +typedef struct { + + u32 transport_type; /* 1:vxlan; */ + + u32 transport_index; /* transport's sw_if_index */ + +} nsh_proxy_session_by_key_t; + +typedef struct { + + /* 24bit NSP 8bit NSI */ + u32 nsp_nsi; + +} nsh_proxy_session_t; + typedef struct { nsh_map_t map; u8 is_add; @@ -70,6 +85,12 @@ typedef struct { uword * nsh_mapping_by_key; uword * nsh_mapping_by_mapped_key; // for use in NSHSFC + /* vector of nsh_proxy */ + nsh_proxy_session_t *nsh_proxy_sessions; + + /* hash lookup nsh_proxy by key */ + uword * nsh_proxy_session_by_key; + /* convenience */ vlib_main_t * vlib_main; vnet_main_t * vnet_main; @@ -77,6 +98,9 @@ typedef struct { nsh_main_t nsh_main; +vlib_node_t * vxlan4_input_node = 0; +vlib_node_t * vxlan6_input_node = 0; + u8 * format_nsh_input_map_trace (u8 * s, va_list * args); u8 * format_nsh_header_with_length (u8 * s, va_list * args); @@ -100,24 +124,27 @@ _(c3) \ _(c4) /* Statistics (not really errors) */ -#define foreach_nsh_input_error \ +#define foreach_nsh_node_error \ _(MAPPED, "NSH header found and mapped") \ _(NO_MAPPING, "no mapping for nsh key") \ _(NO_ENTRY, "no entry for nsh key") \ +_(NO_PROXY, "no proxy for transport key") \ _(INVALID_NEXT_PROTOCOL, "invalid next protocol") \ typedef enum { -#define _(sym,str) NSH_INPUT_ERROR_##sym, - foreach_nsh_input_error +#define _(sym,str) NSH_NODE_ERROR_##sym, + foreach_nsh_node_error #undef _ - NSH_INPUT_N_ERROR, + NSH_NODE_N_ERROR, } nsh_input_error_t; -#define foreach_nsh_input_next \ +#define foreach_nsh_node_next \ _(DROP, "error-drop") \ _(ENCAP_GRE, "gre-input" ) \ _(ENCAP_VXLANGPE, "vxlan-gpe-encap" ) \ + _(ENCAP_VXLAN4, "vxlan4-encap" ) \ + _(ENCAP_VXLAN6, "vxlan6-encap" ) \ /* /\* TODO once moved to Project:NSH_SFC *\/ */ /* _(ENCAP_ETHERNET, "*** TX TO ETHERNET ***") \ */ /* _(DECAP_ETHERNET_LOOKUP, "ethernet-input" ) \ */ @@ -125,11 +152,11 @@ typedef enum { /* _(DECAP_IP6_INPUT, "ip6-input" ) \ */ typedef enum { -#define _(s,n) NSH_INPUT_NEXT_##s, - foreach_nsh_input_next +#define _(s,n) NSH_NODE_NEXT_##s, + foreach_nsh_node_next #undef _ - NSH_INPUT_N_NEXT, -} nsh_input_next_t; + NSH_NODE_N_NEXT, +} nsh_node_next_t; typedef enum { NSH_ACTION_SWAP, @@ -137,4 +164,9 @@ typedef enum { NSH_ACTION_POP }; +typedef enum { + NSH_INPUT_TYPE, + NSH_PROXY_TYPE +}; + #endif /* included_nsh_h */ diff --git a/nsh-plugin/nsh/nsh_test.c b/nsh-plugin/nsh/nsh_test.c index c5d30ef..a7b7957 100644 --- a/nsh-plugin/nsh/nsh_test.c +++ b/nsh-plugin/nsh/nsh_test.c @@ -276,11 +276,11 @@ static int api_nsh_add_del_map (vat_main_t * vam) else if (unformat (line_input, "mapped-nsi %d", &mapped_nsi)) mapped_nsi_set = 1; else if (unformat (line_input, "encap-gre-intf %d", &sw_if_index)) - next_node = NSH_INPUT_NEXT_ENCAP_GRE; + next_node = NSH_NODE_NEXT_ENCAP_GRE; else if (unformat (line_input, "encap-vxlan-gpe-intf %d", &sw_if_index)) - next_node = NSH_INPUT_NEXT_ENCAP_VXLANGPE; + next_node = NSH_NODE_NEXT_ENCAP_VXLANGPE; else if (unformat (line_input, "encap-none")) - next_node = NSH_INPUT_NEXT_DROP; // Once moved to NSHSFC see nsh.h:foreach_nsh_input_next to handle this case + next_node = NSH_NODE_NEXT_DROP; // Once moved to NSHSFC see nsh.h:foreach_nsh_input_next to handle this case else return -99; //TODO clib_error_return (0, "parse error: '%U'", } -- cgit 1.2.3-korg