From d313f9e6f7c6d50aac189668a67bf13b86dd791c Mon Sep 17 00:00:00 2001 From: Hongjun Ni Date: Mon, 27 Aug 2018 20:27:43 +0800 Subject: Port NSH plugin to VPP Please refer to https://wiki.fd.io/view/NSH_SFC Change-Id: Iba7e33e4dbb064c1527aaddbe8dce4b6b63a627a Signed-off-by: Hongjun Ni Signed-off-by: Keith Burns (alagalah) --- src/plugins/nsh/nsh.h | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 271 insertions(+) create mode 100644 src/plugins/nsh/nsh.h (limited to 'src/plugins/nsh/nsh.h') diff --git a/src/plugins/nsh/nsh.h b/src/plugins/nsh/nsh.h new file mode 100644 index 00000000000..1b14567078b --- /dev/null +++ b/src/plugins/nsh/nsh.h @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef included_nsh_h +#define included_nsh_h + +#include +#include +#include + +typedef struct { + u16 class; + u8 type; + u8 pad; +} nsh_option_map_by_key_t; + +typedef struct { + u32 option_id; +} nsh_option_map_t; + +#define MAX_METADATA_LEN 62 +/** Note: + * rewrite and rewrite_size used to support varied nsh header + */ +typedef struct { + /* Required for pool_get_aligned */ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); + + nsh_base_header_t nsh_base; + union { + nsh_md1_data_t md1_data; + nsh_md2_data_t md2_data; + } md; + u8 tlvs_len; /* configured md2 metadata's length, unit: byte */ + u8 * tlvs_data; /* configured md2 metadata, network order */ + + /** Rewrite string. network order + * contains base header and metadata */ + u8 * rewrite; + u8 rewrite_size; /* unit: byte */ +} nsh_entry_t; + +typedef struct { + u8 is_add; + nsh_entry_t nsh_entry; +} nsh_add_del_entry_args_t; + +typedef struct { + /* Required for pool_get_aligned */ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); + + /** Key for nsh_header_t entry: 24bit NSP 8bit NSI */ + u32 nsp_nsi; + /** Key for nsh_header_t entry to map to. : 24bit NSP 8bit NSI + * This may be ~0 if next action is to decap to NSH next protocol + * Note the following heuristic: + * if nsp_nsi == mapped_nsp_nsi then use-case is like SFC SFF + * if nsp_nsi != mapped_nsp_nsi then use-case is like SFC SF + * Note: these are heuristics. Rules about NSI decrement are out of scope + */ + u32 mapped_nsp_nsi; + /* NSH Header action: swap, push and pop */ + u32 nsh_action; + + /** vnet intfc hw_if_index */ + u32 nsh_hw_if; + /* vnet intfc sw_if_index */ + u32 nsh_sw_if; + + /* encap if index */ + u32 sw_if_index; + u32 rx_sw_if_index; + u32 next_node; + u32 adj_index; +} nsh_map_t; + +typedef struct { + u8 is_add; + nsh_map_t map; +} nsh_add_del_map_args_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; + +#define MAX_MD2_OPTIONS 256 + +typedef struct { + /* API message ID base */ + u16 msg_id_base; + + /* vector of nsh_header entry instances */ + nsh_entry_t *nsh_entries; + + /* hash lookup nsh header by key: {u32: nsp_nsi} */ + uword * nsh_entry_by_key; + + /* vector of nsh_mappings */ + nsh_map_t *nsh_mappings; + + /* hash lookup nsh mapping by key: {u32: nsp_nsi} */ + 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; + + /** Free vlib hw_if_indices */ + u32 * free_nsh_tunnel_hw_if_indices; + /** Mapping from sw_if_index to tunnel index */ + u32 * tunnel_index_by_sw_if_index; + + /* vector of nsh_option_map */ + nsh_option_map_t * nsh_option_mappings; + /* hash lookup nsh_option_map by key */ + uword * nsh_option_map_by_key; + + /* Array of function pointers to process MD-Type 2 handling routines */ + /* + * For API or CLI configuration and construct the rewrite buffer, invokes add_options() function. + * In the encap node, i.e. when performing PUSH nsh header, invokes options() function. + * In the swap node, i.e. when performing SWAP nsh header, invokes swap_options() function. + * In the decap node, i.e. when performing POP nsh header, invokes pop_options() function. + */ + u8 options_size[MAX_MD2_OPTIONS]; /* sum of header and metadata */ + int (*add_options[MAX_MD2_OPTIONS]) (u8 * opt, + u8 * opt_size); + int (*options[MAX_MD2_OPTIONS]) (vlib_buffer_t * b, + nsh_tlv_header_t * opt); + int (*swap_options[MAX_MD2_OPTIONS]) (vlib_buffer_t * b, + nsh_tlv_header_t * old_opt, + nsh_tlv_header_t * new_opt); + int (*pop_options[MAX_MD2_OPTIONS]) (vlib_buffer_t * b, + nsh_tlv_header_t * opt); + u8 *(*trace[MAX_MD2_OPTIONS]) (u8 * s, nsh_tlv_header_t * opt); + uword decap_v4_next_override; + + /* Feature arc indices */ + u8 input_feature_arc_index; + u8 output_feature_arc_index; + + /* convenience */ + vlib_main_t * vlib_main; + vnet_main_t * vnet_main; +} nsh_main_t; + +nsh_main_t nsh_main; + +extern vlib_node_registration_t nsh_aware_vnf_proxy_node; +extern vlib_node_registration_t nsh_eth_output_node; + +typedef struct { + u8 trace_data[256]; +} nsh_input_trace_t; + +u8 * format_nsh_input_map_trace (u8 * s, va_list * args); +u8 * format_nsh_header_with_length (u8 * s, va_list * args); + +/* Helper macros used in nsh.c and nsh_test.c */ +#define foreach_copy_nsh_base_hdr_field \ +_(ver_o_c) \ +_(length) \ +_(md_type) \ +_(next_protocol) \ +_(nsp_nsi) + +/* Statistics (not really errors) */ +#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") \ +_(INVALID_OPTIONS, "invalid md2 options") \ +_(INVALID_TTL, "ttl equals zero") \ + +typedef enum { +#define _(sym,str) NSH_NODE_ERROR_##sym, + foreach_nsh_node_error +#undef _ + NSH_NODE_N_ERROR, + +} nsh_input_error_t; + +#define foreach_nsh_node_next \ + _(DROP, "error-drop") \ + _(ENCAP_GRE4, "gre4-input" ) \ + _(ENCAP_GRE6, "gre6-input" ) \ + _(ENCAP_VXLANGPE, "vxlan-gpe-encap" ) \ + _(ENCAP_VXLAN4, "vxlan4-encap" ) \ + _(ENCAP_VXLAN6, "vxlan6-encap" ) \ + _(DECAP_ETH_INPUT, "ethernet-input" ) \ + _(ENCAP_LISP_GPE, "interface-output" ) \ + _(ENCAP_ETHERNET, "nsh-eth-output") \ +/* _(DECAP_IP4_INPUT, "ip4-input") \ */ +/* _(DECAP_IP6_INPUT, "ip6-input" ) \ */ + +typedef enum { +#define _(s,n) NSH_NODE_NEXT_##s, + foreach_nsh_node_next +#undef _ + NSH_NODE_N_NEXT, +} nsh_node_next_t; + +typedef enum { + NSH_ACTION_SWAP, + NSH_ACTION_PUSH, + NSH_ACTION_POP, +} nsh_action_type; + +typedef enum { + NSH_INPUT_TYPE, + NSH_PROXY_TYPE, + NSH_CLASSIFIER_TYPE, + NSH_AWARE_VNF_PROXY_TYPE, +} nsh_entity_type; + +#define VNET_SW_INTERFACE_FLAG_ADMIN_DOWN 0 + +/* md2 class and type definition */ +#define NSH_MD2_IOAM_CLASS 0x9 +#define NSH_MD2_IOAM_OPTION_TYPE_TRACE 0x3B +#define NSH_MD2_IOAM_OPTION_TYPE_PROOF_OF_TRANSIT 0x3C + +#define NSH_MD2_IOAM_TRACE_DUMMY_LEN 0x8 + +#define MAX_NSH_HEADER_LEN 256 +#define MAX_NSH_OPTION_LEN 128 + +int +nsh_md2_register_option (u16 class, + u8 type, + u8 option_size, + int add_options (u8 * opt, + u8 * opt_size), + int options(vlib_buffer_t * b, + nsh_tlv_header_t * opt), + int swap_options (vlib_buffer_t * b, + nsh_tlv_header_t * old_opt, + nsh_tlv_header_t * new_opt), + int pop_options (vlib_buffer_t * b, + nsh_tlv_header_t * opt), + u8 * trace (u8 * s, + nsh_tlv_header_t * opt)); + +typedef struct _nsh_main_dummy +{ + u8 output_feature_arc_index; +} nsh_main_dummy_t; + +#endif /* included_nsh_h */ -- cgit 1.2.3-korg