diff options
Diffstat (limited to 'hicn-plugin/src')
48 files changed, 2122 insertions, 3363 deletions
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt index 68c583e0b..6852b95bb 100644 --- a/hicn-plugin/src/CMakeLists.txt +++ b/hicn-plugin/src/CMakeLists.txt @@ -66,11 +66,13 @@ set(HICN_PLUGIN_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/mgmt.c ${CMAKE_CURRENT_SOURCE_DIR}/pcs.c ${CMAKE_CURRENT_SOURCE_DIR}/route.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_ctx.c ${CMAKE_CURRENT_SOURCE_DIR}/strategy_dpo_manager.c - ${CMAKE_CURRENT_SOURCE_DIR}/strategy.c + ${CMAKE_CURRENT_SOURCE_DIR}/strategy_node.c ${CMAKE_CURRENT_SOURCE_DIR}/interest_pcslookup_node.c ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitpit_node.c ${CMAKE_CURRENT_SOURCE_DIR}/interest_hitcs_node.c + ${CMAKE_CURRENT_SOURCE_DIR}/data_input_node.c ${CMAKE_CURRENT_SOURCE_DIR}/data_pcslookup_node.c ${CMAKE_CURRENT_SOURCE_DIR}/data_fwd_node.c ${CMAKE_CURRENT_SOURCE_DIR}/data_push_node.c @@ -92,7 +94,6 @@ set(HICN_PLUGIN_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod_node.c ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_app_cli.c - ${CMAKE_CURRENT_SOURCE_DIR}/punt.c ${CMAKE_CURRENT_SOURCE_DIR}/pg.c ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_mw.c ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw.c @@ -140,7 +141,6 @@ set(HICN_PLUGIN_HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/address_mgr.h ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_cons.h ${CMAKE_CURRENT_SOURCE_DIR}/faces/app/face_prod.h - ${CMAKE_CURRENT_SOURCE_DIR}/punt.h ${CMAKE_CURRENT_SOURCE_DIR}/pg.h ${CMAKE_CURRENT_SOURCE_DIR}/strategies/dpo_mw.h ${CMAKE_CURRENT_SOURCE_DIR}/strategies/strategy_mw.h @@ -298,4 +298,4 @@ set(HICNPLUGIN_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/vpp_plugins ${VPP_INCLUDE_DIRS} CACHE INTERNAL "" FORCE) -set(HICNPLUGIN_LIBRARIES ${VPP_LIBRARIES} CACHE INTERNAL "" FORCE)
\ No newline at end of file +set(HICNPLUGIN_LIBRARIES ${VPP_LIBRARIES} CACHE INTERNAL "" FORCE) diff --git a/hicn-plugin/src/cli.c b/hicn-plugin/src/cli.c index fd1c68169..15ea90c96 100644 --- a/hicn-plugin/src/cli.c +++ b/hicn-plugin/src/cli.c @@ -33,12 +33,8 @@ #include "error.h" #include "faces/face.h" #include "route.h" -#include "punt.h" #include "hicn_api.h" -extern ip_version_t ipv4; -extern ip_version_t ipv6; - static vl_api_hicn_api_node_params_set_t node_ctl_params = { .pit_max_size = -1, .pit_max_lifetime_sec = -1.0f, @@ -53,26 +49,6 @@ typedef enum } interface_type_t; /* - * Supporting function that return if the interface is IP or ethernet - */ -static interface_type_t -hicn_cli_is_ip_interface (vlib_main_t * vm, - vnet_main_t * vnm, u32 sw_if_index) -{ - - vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, sw_if_index); - - vnet_device_class_t *dev_class = - vnet_get_device_class (vnm, hi->dev_class_index); - if (!strcmp (dev_class->name, "Loopback")) - { - return IP; - } - return ETHERNET; - -} - -/* * cli handler for 'control start' */ static clib_error_t * @@ -84,7 +60,8 @@ hicn_cli_node_ctl_start_set_command_fn (vlib_main_t * vm, ret = hicn_infra_plugin_enable_disable (1 /* enable */ , node_ctl_params.pit_max_size, - node_ctl_params.pit_max_lifetime_sec, + node_ctl_params. + pit_max_lifetime_sec, node_ctl_params.cs_max_size, node_ctl_params.cs_reserved_app); @@ -127,7 +104,8 @@ hicn_cli_node_ctl_stop_set_command_fn (vlib_main_t * vm, } ret = hicn_infra_plugin_enable_disable (0 /* !enable */ , node_ctl_params.pit_max_size, - node_ctl_params.pit_max_lifetime_sec, + node_ctl_params. + pit_max_lifetime_sec, node_ctl_params.cs_max_size, node_ctl_params.cs_reserved_app); @@ -460,11 +438,12 @@ hicn_cli_fib_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input, } } - fib_prefix_from_ip46_addr(&address, &prefix); - prefix.fp_len=plen; + fib_prefix_from_ip46_addr (&address, &prefix); + prefix.fp_len = plen; /* Check parse */ if (addpfx <= 1 - && ((ip46_address_is_zero (&prefix.fp_addr)) || faceid == HICN_FACE_NULL)) + && ((ip46_address_is_zero (&prefix.fp_addr)) + || faceid == HICN_FACE_NULL)) { cl_err = clib_error_return (0, "Please specify prefix and a valid faceid..."); @@ -524,154 +503,6 @@ done: return (cl_err); } -static clib_error_t * -hicn_cli_punting_command_fn (vlib_main_t * vm, unformat_input_t * main_input, - vlib_cli_command_t * cmd) -{ - hicn_mgmt_punting_op_e punting_op = HICN_MGMT_PUNTING_OP_NONE; - unsigned int subnet_mask = 0; - ip46_address_t address; - u32 sw_if_index = ~0; - int ret = 0; - vnet_main_t *vnm = NULL; - u8 type = HICN_PUNT_IP_TYPE; - u32 src_port = HICN_PUNT_INVALID_PORT, dst_port = HICN_PUNT_INVALID_PORT; - vnm = vnet_get_main (); - u8 sport = 0; - u8 dport = 0; - fib_prefix_t prefix; - - unformat_input_t _line_input, *line_input = &_line_input; - if (!unformat_user (main_input, unformat_line_input, line_input)) - { - return (0); - } - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "add")) - { - punting_op = HICN_MGMT_PUNTING_OP_CREATE; - } - else if (unformat (line_input, "delete")) - { - punting_op = HICN_MGMT_PUNTING_OP_DELETE; - } - else if (unformat (line_input, "intfc %U", - unformat_vnet_sw_interface, vnm, &sw_if_index)) - {; - } - else if (unformat - (line_input, "prefix %U/%d", unformat_ip46_address, - &address, IP46_TYPE_ANY, &subnet_mask)) - {; - } - else if (unformat (line_input, "type ip")) - { - type = HICN_PUNT_IP_TYPE; - } - else if (unformat (line_input, "type")) - { - if (unformat (line_input, "udp4")) - { - type = HICN_PUNT_UDP4_TYPE; - } - else if (unformat (line_input, "udp6")) - { - type = HICN_PUNT_UDP6_TYPE; - } - - if (unformat (line_input, "src_port %u", &src_port)) - { - sport = 1; - } - if (unformat (line_input, "dst_port %u", &dst_port)) - { - dport = 1; - } - } - else - { - return (clib_error_return (0, "invalid option")); - } - } - - fib_prefix_from_ip46_addr(&address, &prefix); - prefix.fp_len = subnet_mask; - if (punting_op == HICN_MGMT_PUNTING_OP_CREATE - && (ip46_address_is_zero (&prefix.fp_addr) || sw_if_index == ~0)) - { - return (clib_error_return - (0, "Please specify valid prefix and interface")); - } - else if ((punting_op == HICN_MGMT_PUNTING_OP_DELETE) && - ip46_address_is_zero (&prefix.fp_addr)) - { - return (clib_error_return - (0, "Please specify valid prefix and optionally an interface")); - } - else if (punting_op == HICN_MGMT_PUNTING_OP_NONE) - { - return (clib_error_return - (0, "Please specify valid operation, add or delete")); - } - switch (punting_op) - { - case HICN_MGMT_PUNTING_OP_CREATE: - { - if (type == HICN_PUNT_UDP4_TYPE || type == HICN_PUNT_UDP6_TYPE) - { - if (sport != 0 || dport != 0) - ret = - hicn_punt_interest_data_for_udp (vm, &prefix, - sw_if_index, type, - clib_host_to_net_u16 - (src_port), - clib_host_to_net_u16 - (dst_port), NO_L2); - else - return (clib_error_return - (0, - "Please specify valid source and destination udp port")); - } - else - { - ret = - hicn_punt_interest_data_for_ip (vm, &prefix, sw_if_index, type, NO_L2); - } - } - break; - case HICN_MGMT_PUNTING_OP_DELETE: - { - if (sw_if_index != ~0) - { - ip46_address_is_ip4 (&prefix.fp_addr) ? - hicn_punt_enable_disable_vnet_ip4_table_on_intf (vm, - sw_if_index, - 0) : - hicn_punt_enable_disable_vnet_ip6_table_on_intf (vm, - sw_if_index, - 0); - } - else if (!(ip46_address_is_zero (&prefix.fp_addr))) - { - ret = ip46_address_is_ip4 (&prefix.fp_addr) ? - hicn_punt_remove_ip4_address (vm, &prefix, 1, - sw_if_index, - 0, NO_L2) : - hicn_punt_remove_ip6_address (vm, &prefix, 1, sw_if_index, 0, - NO_L2); - } - } - break; - default: - break; - } - - return (ret == HICN_ERROR_NONE) ? 0 : clib_error_return (0, - get_error_string - (ret)); -} - /* * cli handler for 'pgen' */ @@ -680,19 +511,16 @@ hicn_cli_pgen_client_set_command_fn (vlib_main_t * vm, unformat_input_t * main_input, vlib_cli_command_t * cmd) { - hicn_main_t *sm = &hicn_main; hicnpg_main_t *hpgm = &hicnpg_main; ip46_address_t src_addr; - fib_prefix_t prefix; + fib_prefix_t *prefix = malloc (sizeof (fib_prefix_t)); vnet_main_t *vnm = vnet_get_main (); u32 sw_if_index = ~0; u16 lifetime = 4000; int rv = VNET_API_ERROR_UNIMPLEMENTED; u32 max_seq = ~0; u32 n_flows = ~0; - u16 mask = 0; u32 n_ifaces = 1; - u32 hicn_underneath = ~0; /* Get a line of input. */ unformat_input_t _line_input, *line_input = &_line_input; @@ -700,13 +528,6 @@ hicn_cli_pgen_client_set_command_fn (vlib_main_t * vm, { while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "fwd")) - { - if (unformat (line_input, "ip")) - hicn_underneath = 0; - else if (unformat (line_input, "hicn")) - hicn_underneath = 1; - } if (unformat (line_input, "intfc %U", unformat_vnet_sw_interface, vnm, &sw_if_index)) @@ -723,8 +544,8 @@ hicn_cli_pgen_client_set_command_fn (vlib_main_t * vm, ; } else if (unformat (line_input, "name %U/%d", - unformat_ip46_address, &prefix.fp_addr, IP46_TYPE_ANY, - &prefix.fp_len)) + unformat_ip46_address, &prefix->fp_addr, + IP46_TYPE_ANY, &prefix->fp_len)) { ; } @@ -750,72 +571,49 @@ hicn_cli_pgen_client_set_command_fn (vlib_main_t * vm, } } hpgm->interest_lifetime = lifetime; - mask = prefix.fp_len; if (sw_if_index == ~0) { return (clib_error_return (0, "Packet generator interface missing")); } - if (hicn_underneath == ~0) - { - return (clib_error_return - (0, "Choose the underlying forwarder type ip|hicn")); - } - else if (hicn_underneath && !sm->is_enabled) + + //Remove bits that are out of the subnet + if (ip46_address_is_ip4 (&prefix->fp_addr)) { - return (clib_error_return (0, "hICN not enabled in VPP")); + ip4_address_t mask; + ip4_preflen_to_mask (prefix->fp_len, &mask); + prefix->fp_addr.ip4.as_u32 = prefix->fp_addr.ip4.as_u32 & mask.as_u32; + prefix->fp_proto = FIB_PROTOCOL_IP4; } - else if (!hicn_underneath && sm->is_enabled) + else { - return (clib_error_return (0, "hICN enabled in VPP")); + ip6_address_t mask; + ip6_preflen_to_mask (prefix->fp_len, &mask); + prefix->fp_addr.ip6.as_u64[0] = + prefix->fp_addr.ip6.as_u64[0] & mask.as_u64[0]; + prefix->fp_addr.ip6.as_u64[1] = + prefix->fp_addr.ip6.as_u64[1] & mask.as_u64[1]; + prefix->fp_proto = FIB_PROTOCOL_IP6; } - int skip = 1; - int base_offset = ETH_L2; - u8 use_current_data = HICN_CLASSIFY_NO_CURRENT_DATA_FLAG; - - if (hicn_cli_is_ip_interface (vm, vnm, sw_if_index) == IP) - { - skip = 0; - base_offset = NO_L2; - use_current_data = HICN_CLASSIFY_CURRENT_DATA_FLAG; - } /* - * Register punting on src address generated by pg and data punting - * on the name + * Enable the feature to divert data packet to the hicnpg-data node to count + * how many data packets have been received. + * Diver all the packets from the packet-generator to the hicn-pg-interest node + * to generate valid interests. */ - if (ip46_address_is_ip4 (&src_addr) && ip46_address_is_ip4 (&prefix.fp_addr)) + if (ip46_address_is_ip4 (&src_addr) + && ip46_address_is_ip4 (&prefix->fp_addr)) { - prefix.fp_proto = FIB_PROTOCOL_IP4; - /* Add data node to the vpp graph */ - u32 next_hit_node = vlib_node_add_next (vm, - hicn_punt_glb. - hicn_node_info.ip4_inacl_node_index, - hicn_pg_data_node.index); + prefix->fp_proto = FIB_PROTOCOL_IP4; + + vnet_feature_enable_disable ("ip4-unicast", "hicnpg-data", + sw_if_index, 1, 0, 0); /* Add pgen_client node to the vpp graph */ vlib_node_add_next (vm, pg_input_node.index, hicn_pg_interest_node.index); - /* Create the punting table if it does not exist */ - hicn_punt_add_vnettbl (&ipv4, &ipv4_src, mask, ~0, sw_if_index, - base_offset, use_current_data); - hicn_punt_add_vnettbl (&ipv4, &ipv4_dst, mask, - hicn_punt_glb.ip4_vnet_tbl_idx[sw_if_index][skip] - [HICN_PUNT_SRC][mask], sw_if_index, base_offset, - use_current_data); - - /* Add a session to the table */ - hicn_punt_add_vnetssn (&ipv4, &ipv4_src, - &prefix, - next_hit_node, sw_if_index, base_offset); - - hicn_punt_add_vnetssn (&ipv4, &ipv4_src, - &prefix, - next_hit_node, sw_if_index, base_offset); - - hicn_punt_enable_disable_vnet_ip4_table_on_intf (vm, sw_if_index, - OP_ENABLE); pg_node_t *pn; pn = pg_get_node (hicn_pg_interest_node.index); @@ -823,39 +621,17 @@ hicn_cli_pgen_client_set_command_fn (vlib_main_t * vm, } else if (!ip46_address_is_ip4 (&src_addr) - && !ip46_address_is_ip4 (&prefix.fp_addr)) + && !ip46_address_is_ip4 (&prefix->fp_addr)) { - prefix.fp_proto = FIB_PROTOCOL_IP6; - /* Add node to the vpp graph */ - u32 next_hit_node = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip6_inacl_node_index, - hicn_pg_data_node.index); + prefix->fp_proto = FIB_PROTOCOL_IP6; + + vnet_feature_enable_disable ("ip6-unicast", "hicnpg-data", + sw_if_index, 1, 0, 0); /* Add pgen_client node to the vpp graph */ vlib_node_add_next (vm, pg_input_node.index, hicn_pg_interest_node.index); - /* Create the punting table if it does not exist */ - hicn_punt_add_vnettbl (&ipv6, &ipv6_src, mask, ~0, sw_if_index, - base_offset, use_current_data); - hicn_punt_add_vnettbl (&ipv6, &ipv6_dst, mask, - hicn_punt_glb.ip6_vnet_tbl_idx[sw_if_index][skip] - [HICN_PUNT_SRC][mask], sw_if_index, base_offset, - use_current_data); - - /* Add a session to the table */ - hicn_punt_add_vnetssn (&ipv6, &ipv6_src, - &prefix, - next_hit_node, sw_if_index, base_offset); - - hicn_punt_add_vnetssn (&ipv6, &ipv6_src, - &prefix, - next_hit_node, sw_if_index, base_offset); - - hicn_punt_enable_disable_vnet_ip6_table_on_intf (vm, sw_if_index, - OP_ENABLE); - pg_node_t *pn; pn = pg_get_node (hicn_pg_interest_node.index); pn->unformat_edit = unformat_pg_ip6_header; @@ -869,11 +645,11 @@ hicn_cli_pgen_client_set_command_fn (vlib_main_t * vm, hpgm->pgen_clt_src_addr = src_addr; - hpgm->pgen_clt_hicn_name = prefix.fp_addr; + hpgm->pgen_clt_hicn_name = prefix; hpgm->max_seq_number = max_seq; hpgm->n_flows = n_flows; hpgm->n_ifaces = n_ifaces; - hpgm->hicn_underneath = hicn_underneath; + hpgm->sw_if = sw_if_index; vlib_cli_output (vm, "ifaces %d", hpgm->n_ifaces); rv = 0; @@ -904,13 +680,10 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t * vm, clib_error_t *cl_err; int rv = HICN_ERROR_NONE; hicnpg_server_main_t *pg_main = &hicnpg_server_main; - hicn_main_t *sm = &hicn_main; - fib_prefix_t prefix; - u32 subnet_mask; - int payload_size = 0; + int payload_size = 1440; u32 sw_if_index = ~0; vnet_main_t *vnm = vnet_get_main (); - u32 hicn_underneath = ~0; + fib_prefix_t *prefix = calloc (1, sizeof (fib_prefix_t)); /* Get a line of input. */ unformat_input_t _line_input, *line_input = &_line_input; @@ -919,16 +692,9 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t * vm, /* Parse the arguments */ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "fwd")) - { - if (unformat (line_input, "ip")) - hicn_underneath = 0; - else if (unformat (line_input, "hicn")) - hicn_underneath = 1; - } if (unformat (line_input, "name %U/%d", - unformat_ip46_address, &prefix.fp_addr, IP46_TYPE_ANY, - &prefix.fp_len)) + unformat_ip46_address, &prefix->fp_addr, + IP46_TYPE_ANY, &prefix->fp_len)) {; } else if (unformat (line_input, "size %d", &payload_size)) @@ -955,99 +721,50 @@ hicn_cli_pgen_server_set_command_fn (vlib_main_t * vm, } } } - prefix.fp_proto = ip46_address_is_ip4(&prefix.fp_addr) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; - subnet_mask = prefix.fp_len; + /* Attach our packet-gen node for ip4 udp local traffic */ - if (payload_size == 0 || sw_if_index == ~0) + if ((prefix->fp_addr.ip6.as_u64[0] == (u64) 0 + && prefix->fp_addr.ip6.as_u64[1] == 0) || payload_size == 0 + || sw_if_index == ~0) { return clib_error_return (0, - "Error: must supply local port, payload size and incoming interface"); + "Error: must supply local port, payload size and incoming hICN prefix"); } - if (hicn_underneath == ~0) - { - return (clib_error_return - (0, "Choose the underlying forwarder type ip|hicn")); - } - else if (hicn_underneath && !sm->is_enabled) + + //Remove bits that are out of the subnet + if (ip46_address_is_ip4 (&prefix->fp_addr)) { - return (clib_error_return (0, "hICN not enabled in VPP")); + ip4_address_t mask; + ip4_preflen_to_mask (prefix->fp_len, &mask); + prefix->fp_addr.ip4.as_u32 = prefix->fp_addr.ip4.as_u32 & mask.as_u32; + prefix->fp_proto = FIB_PROTOCOL_IP4; } - else if (!hicn_underneath && sm->is_enabled) + else { - return (clib_error_return (0, "hICN enabled in VPP")); + ip6_address_t mask; + ip6_preflen_to_mask (prefix->fp_len, &mask); + prefix->fp_addr.ip6.as_u64[0] = + prefix->fp_addr.ip6.as_u64[0] & mask.as_u64[0]; + prefix->fp_addr.ip6.as_u64[1] = + prefix->fp_addr.ip6.as_u64[1] & mask.as_u64[1]; + prefix->fp_proto = FIB_PROTOCOL_IP6; } - pg_main->hicn_underneath = hicn_underneath; /* Allocate the buffer with the actual content payload TLV */ vlib_buffer_alloc (vm, &pg_main->pgen_svr_buffer_idx, 1); vlib_buffer_t *rb = NULL; rb = vlib_get_buffer (vm, pg_main->pgen_svr_buffer_idx); + pg_main->pgen_srv_hicn_name = prefix; + /* Initialize the buffer data with zeros */ memset (rb->data, 0, payload_size); rb->current_length = payload_size; - int skip = 2; - int base_offset = ETH_L2; - u8 use_current_data = HICN_CLASSIFY_NO_CURRENT_DATA_FLAG; - - if (hicn_cli_is_ip_interface (vm, vnm, sw_if_index) == IP) - { - skip = 1; - base_offset = NO_L2; - use_current_data = HICN_CLASSIFY_CURRENT_DATA_FLAG; - } - if (ip46_address_is_ip4 (&prefix.fp_addr)) - { - /* Add node to the vpp graph */ - u32 next_hit_node = vlib_node_add_next (vm, - hicn_punt_glb. - hicn_node_info.ip4_inacl_node_index, - hicn_pg_server_node.index); - - /* Create the punting table if it does not exist */ - hicn_punt_add_vnettbl (&ipv4, &ipv4_src, subnet_mask, ~0, sw_if_index, - base_offset, use_current_data); - hicn_punt_add_vnettbl (&ipv4, &ipv4_dst, subnet_mask, - hicn_punt_glb.ip4_vnet_tbl_idx[sw_if_index][skip] - [HICN_PUNT_SRC][subnet_mask - 1], sw_if_index, - base_offset, use_current_data); - - - /* Add a session to the table */ - hicn_punt_add_vnetssn (&ipv4, &ipv4_dst, - &prefix, next_hit_node, sw_if_index, - base_offset); - - hicn_punt_enable_disable_vnet_ip4_table_on_intf (vm, sw_if_index, - OP_ENABLE); - - } - else - { - /* Add node to the vpp graph */ - u32 next_hit_node = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip6_inacl_node_index, - hicn_pg_server_node.index); - - /* Create the punting table if it does not exist */ - hicn_punt_add_vnettbl (&ipv6, &ipv6_src, subnet_mask, ~0, sw_if_index, - base_offset, use_current_data); - hicn_punt_add_vnettbl (&ipv6, &ipv6_dst, subnet_mask, - hicn_punt_glb.ip6_vnet_tbl_idx[sw_if_index][skip] - [HICN_PUNT_SRC][subnet_mask - 1], sw_if_index, - base_offset, use_current_data); - - - /* Add a session to the table */ - hicn_punt_add_vnetssn (&ipv6, &ipv6_dst, - &prefix, next_hit_node, sw_if_index, - base_offset); - - hicn_punt_enable_disable_vnet_ip6_table_on_intf (vm, sw_if_index, - OP_ENABLE); - } + vnet_feature_enable_disable ("ip4-unicast", "hicnpg-server", + sw_if_index, 1, 0, 0); + vnet_feature_enable_disable ("ip6-unicast", "hicnpg-server", + sw_if_index, 1, 0, 0); switch (rv) { @@ -1119,19 +836,11 @@ VLIB_CLI_COMMAND(hicn_cli_show_command, static)= .function = hicn_cli_show_command_fn, }; -/* cli declaration for 'punting' */ -VLIB_CLI_COMMAND(hicn_cli_punting_command, static)= -{ - .path = "hicn punting", - .short_help = "hicn punting {add|delete} prefix <prefix> intfc <sw_if> {type ip | type <udp4|udp6> src_port <port> dst_port <port>}", - .function = hicn_cli_punting_command_fn, -}; - /* cli declaration for 'hicn pgen client' */ VLIB_CLI_COMMAND(hicn_cli_pgen_client_set_command, static)= { .path = "hicn pgen client", - .short_help = "hicn pgen client fwd <ip|hicn> src <src_addr> n_ifaces <n_ifaces> name <prefix> lifetime <interest-lifetime> intfc <data in-interface> max_seq <max sequence number> n_flows <number of flows>", + .short_help = "hicn pgen client src <src_addr> name <prefix> { n_ifaces <n_ifaces> lifetime <interest-lifetime> intfc <data in-interface> max_seq <max sequence number> n_flows <number of flows>}", .long_help = "Run hicn in packet-gen client mode\n", .function = hicn_cli_pgen_client_set_command_fn, }; @@ -1140,7 +849,7 @@ VLIB_CLI_COMMAND(hicn_cli_pgen_client_set_command, static)= VLIB_CLI_COMMAND(hicn_cli_pgen_server_set_command, static)= { .path = "hicn pgen server", - .short_help = "hicn pgen server fwd <ip|hicn> name <prefix> intfc <interest in-interface> size <payload_size>", + .short_help = "hicn pgen server name <prefix> intfc <interest in-interface> size <payload_size>", .long_help = "Run hicn in packet-gen server mode\n", .function = hicn_cli_pgen_server_set_command_fn, }; diff --git a/hicn-plugin/src/data_input_node.c b/hicn-plugin/src/data_input_node.c new file mode 100644 index 000000000..b8c19757c --- /dev/null +++ b/hicn-plugin/src/data_input_node.c @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2020 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. + */ + +#include <vnet/vnet.h> +#include <vnet/ip/ip.h> +#include <vnet/fib/ip6_fib.h> +#include <vnet/fib/fib_table.h> /* for FIB table and entry creation */ +#include <vnet/fib/fib_entry.h> /* for FIB table and entry creation */ +#include <vnet/fib/ip4_fib.h> +#include <vnet/dpo/load_balance.h> + +#include "mgmt.h" +#include "strategy_dpo_manager.h" + +static __clib_unused char *hicn_data_input_error_strings[] = { +#define _(sym, string) string, + foreach_hicnfwd_error +#undef _ +}; + +typedef struct +{ + u32 next_index; + u32 sw_if_index; +} hicn_data_input_t; + +typedef enum +{ + HICN_DATA_INPUT_IP6_NEXT_FACE, + HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL, + HICN_DATA_INPUT_IP6_N_NEXT, +} hicn_data_input_ip6_next_t; + +typedef enum +{ + HICN_DATA_INPUT_IP4_NEXT_FACE, + HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL, + HICN_DATA_INPUT_IP4_N_NEXT, +} hicn_data_input_ip4_next_t; + +typedef struct +{ + u32 next_index; + u32 sw_if_index; + u8 isv6; +} hicn_data_input_trace_t; + +vlib_node_registration_t hicn_data_input_ip6_node; +vlib_node_registration_t hicn_data_input_ip4_node; + +static __clib_unused u8 * +format_hicn_data_input_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 *); + hicn_data_input_trace_t *t = va_arg (*args, hicn_data_input_trace_t *); + u32 indent = format_get_indent (s); + u8 isv6 = (u8) va_arg (*args, int); + + s = + format (s, "%U hicn_data_input%s: sw_if_index %d next-index %d", + format_white_space, indent, isv6 ? "_ip6" : "_ip4", + t->sw_if_index, t->next_index); + return s; +} + +static uword +hicn_data_input_ip6_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * frame) +{ + ip6_main_t *im = &ip6_main; + vlib_combined_counter_main_t *cm = &load_balance_main.lbm_to_counters; + u32 n_left_from, n_left_to_next, *from, *to_next; + ip_lookup_next_t next; + u32 thread_index = vm->thread_index; + + from = vlib_frame_vector_args (frame); + n_left_from = frame->n_vectors; + next = node->cached_next_index; + + while (n_left_from > 0) + { + vlib_get_next_frame (vm, node, next, to_next, n_left_to_next); + + while (n_left_from >= 4 && n_left_to_next >= 2) + { + vlib_buffer_t *p0, *p1; + u32 pi0, pi1, lbi0, lbi1, wrong_next; + ip_lookup_next_t next0, next1; + ip6_header_t *ip0, *ip1; + ip6_address_t *src_addr0, *src_addr1; + const dpo_id_t *dpo0, *dpo1; + const load_balance_t *lb0, *lb1; + + /* Prefetch next iteration. */ + { + vlib_buffer_t *p2, *p3; + + p2 = vlib_get_buffer (vm, from[2]); + p3 = vlib_get_buffer (vm, from[3]); + + vlib_prefetch_buffer_header (p2, LOAD); + vlib_prefetch_buffer_header (p3, LOAD); + CLIB_PREFETCH (p2->data, sizeof (ip0[0]), LOAD); + CLIB_PREFETCH (p3->data, sizeof (ip0[0]), LOAD); + } + + pi0 = to_next[0] = from[0]; + pi1 = to_next[1] = from[1]; + + p0 = vlib_get_buffer (vm, pi0); + p1 = vlib_get_buffer (vm, pi1); + + ip0 = vlib_buffer_get_current (p0); + ip1 = vlib_buffer_get_current (p1); + + src_addr0 = &ip0->src_address; + src_addr1 = &ip1->src_address; + + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p1); + + lbi0 = ip6_fib_table_fwding_lookup (vnet_buffer (p0)->ip.fib_index, + src_addr0); + lbi1 = ip6_fib_table_fwding_lookup (vnet_buffer (p1)->ip.fib_index, + src_addr1); + + lb0 = load_balance_get (lbi0); + lb1 = load_balance_get (lbi1); + ASSERT (lb0->lb_n_buckets > 0); + ASSERT (lb1->lb_n_buckets > 0); + ASSERT (is_pow2 (lb0->lb_n_buckets)); + ASSERT (is_pow2 (lb1->lb_n_buckets)); + + vnet_buffer (p0)->ip.flow_hash = vnet_buffer (p1)->ip.flow_hash = 0; + + //No vpp loadbalancing. Missing header file to exploit it + dpo0 = load_balance_get_bucket_i (lb0, 0); + dpo1 = load_balance_get_bucket_i (lb1, 0); + + if (dpo_is_hicn (dpo0)) + next0 = HICN_DATA_INPUT_IP6_NEXT_FACE; + else + next0 = HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; + + if (dpo_is_hicn (dpo1)) + next1 = HICN_DATA_INPUT_IP6_NEXT_FACE; + else + next1 = HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (p0->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, p0, sizeof (*t)); + t->sw_if_index = vnet_buffer (p0)->sw_if_index[VLIB_RX]; + t->next_index = next0; + t->isv6 = 1; + } + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (p1->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, p1, sizeof (*t)); + t->sw_if_index = vnet_buffer (p1)->sw_if_index[VLIB_RX]; + t->next_index = next1; + t->isv6 = 1; + } + + + vlib_increment_combined_counter + (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); + vlib_increment_combined_counter + (cm, thread_index, lbi1, 1, vlib_buffer_length_in_chain (vm, p1)); + + from += 2; + to_next += 2; + n_left_to_next -= 2; + n_left_from -= 2; + + wrong_next = (next0 != next) + 2 * (next1 != next); + if (PREDICT_FALSE (wrong_next != 0)) + { + switch (wrong_next) + { + case 1: + /* A B A */ + to_next[-2] = pi1; + to_next -= 1; + n_left_to_next += 1; + vlib_set_next_frame_buffer (vm, node, next0, pi0); + break; + + case 2: + /* A A B */ + to_next -= 1; + n_left_to_next += 1; + vlib_set_next_frame_buffer (vm, node, next1, pi1); + break; + + case 3: + /* A B C */ + to_next -= 2; + n_left_to_next += 2; + vlib_set_next_frame_buffer (vm, node, next0, pi0); + vlib_set_next_frame_buffer (vm, node, next1, pi1); + if (next0 == next1) + { + /* A B B */ + vlib_put_next_frame (vm, node, next, n_left_to_next); + next = next1; + vlib_get_next_frame (vm, node, next, to_next, + n_left_to_next); + } + } + } + } + + while (n_left_from > 0 && n_left_to_next > 0) + { + vlib_buffer_t *p0; + ip6_header_t *ip0; + u32 pi0, lbi0; + ip_lookup_next_t next0; + load_balance_t *lb0; + ip6_address_t *src_addr0; + const dpo_id_t *dpo0; + + pi0 = from[0]; + to_next[0] = pi0; + + p0 = vlib_get_buffer (vm, pi0); + ip0 = vlib_buffer_get_current (p0); + src_addr0 = &ip0->src_address; + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, p0); + lbi0 = ip6_fib_table_fwding_lookup (vnet_buffer (p0)->ip.fib_index, + src_addr0); + + lb0 = load_balance_get (lbi0); + ASSERT (lb0->lb_n_buckets > 0); + ASSERT (is_pow2 (lb0->lb_n_buckets)); + + //No vpp loadbalancing. Missing header file to exploit it + dpo0 = load_balance_get_bucket_i (lb0, 0); + + if (dpo_is_hicn (dpo0)) + next0 = HICN_DATA_INPUT_IP6_NEXT_FACE; + else + next0 = HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL; + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (p0->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, p0, sizeof (*t)); + t->sw_if_index = vnet_buffer (p0)->sw_if_index[VLIB_RX]; + t->next_index = next0; + t->isv6 = 1; + } + + vlib_increment_combined_counter + (cm, thread_index, lbi0, 1, vlib_buffer_length_in_chain (vm, p0)); + + from += 1; + to_next += 1; + n_left_to_next -= 1; + n_left_from -= 1; + + if (PREDICT_FALSE (next0 != next)) + { + n_left_to_next += 1; + vlib_put_next_frame (vm, node, next, n_left_to_next); + next = next0; + vlib_get_next_frame (vm, node, next, to_next, n_left_to_next); + to_next[0] = pi0; + to_next += 1; + n_left_to_next -= 1; + } + } + + vlib_put_next_frame (vm, node, next, n_left_to_next); + } + + return frame->n_vectors; +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE(hicn_data_input_ip6) = + { + .function = hicn_data_input_ip6_fn, + .name = "hicn-data-input-ip6", + .vector_size = sizeof(u32), + .format_trace = format_hicn_data_input_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .n_errors = ARRAY_LEN(hicn_data_input_error_strings), + .error_strings = hicn_data_input_error_strings, + .n_next_nodes = HICN_DATA_INPUT_IP6_N_NEXT, + .next_nodes = + { + [HICN_DATA_INPUT_IP6_NEXT_FACE] = "hicn-face-ip6-input", + [HICN_DATA_INPUT_IP6_NEXT_IP6_LOCAL] = "ip6-local-end-of-arc" + }, + }; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +VNET_FEATURE_INIT(hicn_data_input_ip6_arc, static)= + { + .arc_name = "ip6-local", + .node_name = "hicn-data-input-ip6", + .runs_before = VNET_FEATURES("ip6-local-end-of-arc"), + }; +/* *INDENT-ON* */ + + + +always_inline uword +hicn_data_input_ip4_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * frame) +{ + ip4_main_t *im = &ip4_main; + vlib_combined_counter_main_t *cm = &load_balance_main.lbm_to_counters; + u32 n_left, *from; + u32 thread_index = vm->thread_index; + vlib_buffer_t *bufs[VLIB_FRAME_SIZE]; + vlib_buffer_t **b = bufs; + u16 nexts[VLIB_FRAME_SIZE], *next; + + from = vlib_frame_vector_args (frame); + n_left = frame->n_vectors; + next = nexts; + vlib_get_buffers (vm, from, bufs, n_left); + +#if (CLIB_N_PREFETCHES >= 8) + while (n_left >= 4) + { + ip4_header_t *ip0, *ip1, *ip2, *ip3; + const load_balance_t *lb0, *lb1, *lb2, *lb3; + ip4_fib_mtrie_t *mtrie0, *mtrie1, *mtrie2, *mtrie3; + ip4_fib_mtrie_leaf_t leaf0, leaf1, leaf2, leaf3; + ip4_address_t *src_addr0, *src_addr1, *src_addr2, *src_addr3; + u32 lb_index0, lb_index1, lb_index2, lb_index3; + const dpo_id_t *dpo0, *dpo1, *dpo2, *dpo3; + + /* Prefetch next iteration. */ + if (n_left >= 8) + { + vlib_prefetch_buffer_header (b[4], LOAD); + vlib_prefetch_buffer_header (b[5], LOAD); + vlib_prefetch_buffer_header (b[6], LOAD); + vlib_prefetch_buffer_header (b[7], LOAD); + + CLIB_PREFETCH (b[4]->data, sizeof (ip0[0]), LOAD); + CLIB_PREFETCH (b[5]->data, sizeof (ip0[0]), LOAD); + CLIB_PREFETCH (b[6]->data, sizeof (ip0[0]), LOAD); + CLIB_PREFETCH (b[7]->data, sizeof (ip0[0]), LOAD); + } + + ip0 = vlib_buffer_get_current (b[0]); + ip1 = vlib_buffer_get_current (b[1]); + ip2 = vlib_buffer_get_current (b[2]); + ip3 = vlib_buffer_get_current (b[3]); + + src_addr0 = &ip0->src_address; + src_addr1 = &ip1->src_address; + src_addr2 = &ip2->src_address; + src_addr3 = &ip3->src_address; + + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[0]); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[1]); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[2]); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[3]); + + mtrie0 = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie; + mtrie1 = &ip4_fib_get (vnet_buffer (b[1])->ip.fib_index)->mtrie; + mtrie2 = &ip4_fib_get (vnet_buffer (b[2])->ip.fib_index)->mtrie; + mtrie3 = &ip4_fib_get (vnet_buffer (b[3])->ip.fib_index)->mtrie; + + leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, src_addr0); + leaf1 = ip4_fib_mtrie_lookup_step_one (mtrie1, src_addr1); + leaf2 = ip4_fib_mtrie_lookup_step_one (mtrie2, src_addr2); + leaf3 = ip4_fib_mtrie_lookup_step_one (mtrie3, src_addr3); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 2); + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 2); + leaf2 = ip4_fib_mtrie_lookup_step (mtrie2, leaf2, src_addr2, 2); + leaf3 = ip4_fib_mtrie_lookup_step (mtrie3, leaf3, src_addr3, 2); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 3); + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 3); + leaf2 = ip4_fib_mtrie_lookup_step (mtrie2, leaf2, src_addr2, 3); + leaf3 = ip4_fib_mtrie_lookup_step (mtrie3, leaf3, src_addr3, 3); + + lb_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); + lb_index1 = ip4_fib_mtrie_leaf_get_adj_index (leaf1); + lb_index2 = ip4_fib_mtrie_leaf_get_adj_index (leaf2); + lb_index3 = ip4_fib_mtrie_leaf_get_adj_index (leaf3); + + ASSERT (lb_index0 && lb_index1 && lb_index2 && lb_index3); + lb0 = load_balance_get (lb_index0); + lb1 = load_balance_get (lb_index1); + lb2 = load_balance_get (lb_index2); + lb3 = load_balance_get (lb_index3); + + ASSERT (lb0->lb_n_buckets > 0); + ASSERT (is_pow2 (lb0->lb_n_buckets)); + ASSERT (lb1->lb_n_buckets > 0); + ASSERT (is_pow2 (lb1->lb_n_buckets)); + ASSERT (lb2->lb_n_buckets > 0); + ASSERT (is_pow2 (lb2->lb_n_buckets)); + ASSERT (lb3->lb_n_buckets > 0); + ASSERT (is_pow2 (lb3->lb_n_buckets)); + + dpo0 = load_balance_get_bucket_i (lb0, 0); + dpo1 = load_balance_get_bucket_i (lb1, 0); + dpo2 = load_balance_get_bucket_i (lb2, 0); + dpo3 = load_balance_get_bucket_i (lb3, 0); + + if (dpo_is_hicn (dpo0)) + next[0] = HICN_DATA_INPUT_IP4_NEXT_FACE; + else + next[0] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + + if (dpo_is_hicn (dpo1)) + next[1] = HICN_DATA_INPUT_IP4_NEXT_FACE; + else + next[1] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + + if (dpo_is_hicn (dpo2)) + next[2] = HICN_DATA_INPUT_IP4_NEXT_FACE; + else + next[2] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + + if (dpo_is_hicn (dpo3)) + next[3] = HICN_DATA_INPUT_IP4_NEXT_FACE; + else + next[3] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (b[0]->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, b[0], sizeof (*t)); + t->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_RX]; + t->next_index = next[0]; + t->isv6 = 0; + } + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (b[1]->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, b[1], sizeof (*t)); + t->sw_if_index = vnet_buffer (b[1])->sw_if_index[VLIB_RX]; + t->next_index = next[1]; + t->isv6 = 0; + } + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (b[2]->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, b[2], sizeof (*t)); + t->sw_if_index = vnet_buffer (b[2])->sw_if_index[VLIB_RX]; + t->next_index = next[0]; + t->isv6 = 0; + } + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (b[3]->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, b[3], sizeof (*t)); + t->sw_if_index = vnet_buffer (b[3])->sw_if_index[VLIB_RX]; + t->next_index = next[3]; + t->isv6 = 0; + } + + vlib_increment_combined_counter + (cm, thread_index, lb_index0, 1, + vlib_buffer_length_in_chain (vm, b[0])); + vlib_increment_combined_counter + (cm, thread_index, lb_index1, 1, + vlib_buffer_length_in_chain (vm, b[1])); + vlib_increment_combined_counter + (cm, thread_index, lb_index2, 1, + vlib_buffer_length_in_chain (vm, b[2])); + vlib_increment_combined_counter + (cm, thread_index, lb_index3, 1, + vlib_buffer_length_in_chain (vm, b[3])); + + b += 4; + next += 4; + n_left -= 4; + } +#elif (CLIB_N_PREFETCHES >= 4) + while (n_left >= 4) + { + ip4_header_t *ip0, *ip1; + const load_balance_t *lb0, *lb1; + ip4_fib_mtrie_t *mtrie0, *mtrie1; + ip4_fib_mtrie_leaf_t leaf0, leaf1; + ip4_address_t *src_addr0, *src_addr1; + u32 lb_index0, lb_index1; + flow_hash_config_t flow_hash_config0, flow_hash_config1; + u32 hash_c0, hash_c1; + const dpo_id_t *dpo0, *dpo1; + + /* Prefetch next iteration. */ + { + vlib_prefetch_buffer_header (b[2], LOAD); + vlib_prefetch_buffer_header (b[3], LOAD); + + CLIB_PREFETCH (b[2]->data, sizeof (ip0[0]), LOAD); + CLIB_PREFETCH (b[3]->data, sizeof (ip0[0]), LOAD); + } + + ip0 = vlib_buffer_get_current (b[0]); + ip1 = vlib_buffer_get_current (b[1]); + + src_addr0 = &ip0->src_address; + src_addr1 = &ip1->src_address; + + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[0]); + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[1]); + + mtrie0 = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie; + mtrie1 = &ip4_fib_get (vnet_buffer (b[1])->ip.fib_index)->mtrie; + + leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, src_addr0); + leaf1 = ip4_fib_mtrie_lookup_step_one (mtrie1, src_addr1); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 2); + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 2); + + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 3); + leaf1 = ip4_fib_mtrie_lookup_step (mtrie1, leaf1, src_addr1, 3); + + lb_index0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); + lb_index1 = ip4_fib_mtrie_leaf_get_adj_index (leaf1); + + ASSERT (lb_index0 && lb_index1); + lb0 = load_balance_get (lb_index0); + lb1 = load_balance_get (lb_index1); + + ASSERT (lb0->lb_n_buckets > 0); + ASSERT (is_pow2 (lb0->lb_n_buckets)); + ASSERT (lb1->lb_n_buckets > 0); + ASSERT (is_pow2 (lb1->lb_n_buckets)); + + dpo0 = load_balance_get_bucket_i (lb0, 0); + dpo1 = load_balance_get_bucket_i (lb1, 0); + + if (dpo_is_hicn (dpo0)) + next[0] = HICN_DATA_INPUT_IP4_NEXT_FACE; + else + next[0] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + + if (dpo_is_hicn (dpo1)) + next[1] = HICN_DATA_INPUT_IP4_NEXT_FACE; + else + next[1] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (b0->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, b0, sizeof (*t)); + t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; + t->next_index = next[0]; + t->isv6 = 0; + } + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (b1->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, b1, sizeof (*t)); + t->sw_if_index = vnet_buffer (b1)->sw_if_index[VLIB_RX]; + t->next_index = next[1]; + t->isv6 = 0; + } + + + vlib_increment_combined_counter + (cm, thread_index, lb_index0, 1, + vlib_buffer_length_in_chain (vm, b[0])); + vlib_increment_combined_counter + (cm, thread_index, lb_index1, 1, + vlib_buffer_length_in_chain (vm, b[1])); + + b += 2; + next += 2; + n_left -= 2; + } +#endif + while (n_left > 0) + { + ip4_header_t *ip0; + const load_balance_t *lb0; + ip4_fib_mtrie_t *mtrie0; + ip4_fib_mtrie_leaf_t leaf0; + ip4_address_t *src_addr0; + u32 lbi0; + const dpo_id_t *dpo0; + + ip0 = vlib_buffer_get_current (b[0]); + src_addr0 = &ip0->src_address; + ip_lookup_set_buffer_fib_index (im->fib_index_by_sw_if_index, b[0]); + + mtrie0 = &ip4_fib_get (vnet_buffer (b[0])->ip.fib_index)->mtrie; + leaf0 = ip4_fib_mtrie_lookup_step_one (mtrie0, src_addr0); + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 2); + leaf0 = ip4_fib_mtrie_lookup_step (mtrie0, leaf0, src_addr0, 3); + lbi0 = ip4_fib_mtrie_leaf_get_adj_index (leaf0); + + ASSERT (lbi0); + lb0 = load_balance_get (lbi0); + + ASSERT (lb0->lb_n_buckets > 0); + ASSERT (is_pow2 (lb0->lb_n_buckets)); + + dpo0 = load_balance_get_bucket_i (lb0, 0); + + if (dpo_is_hicn (dpo0)) + next[0] = HICN_DATA_INPUT_IP4_NEXT_FACE; + else + next[0] = HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL; + + if (PREDICT_FALSE (node->flags & VLIB_NODE_FLAG_TRACE) && + (b[0]->flags & VLIB_BUFFER_IS_TRACED)) + { + hicn_data_input_trace_t *t = + vlib_add_trace (vm, node, b[0], sizeof (*t)); + t->sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_RX]; + t->next_index = next[0]; + t->isv6 = 0; + } + + vlib_increment_combined_counter (cm, thread_index, lbi0, 1, + vlib_buffer_length_in_chain (vm, + b[0])); + + b += 1; + next += 1; + n_left -= 1; + } + + vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors); + + if (node->flags & VLIB_NODE_FLAG_TRACE) + ip4_forward_next_trace (vm, node, frame, VLIB_TX); + + return frame->n_vectors; +} + +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE(hicn_data_input_ip4) = + { + .function = hicn_data_input_ip4_fn, + .name = "hicn-data-input-ip4", + .vector_size = sizeof(u32), + .format_trace = format_hicn_data_input_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .n_errors = ARRAY_LEN(hicn_data_input_error_strings), + .error_strings = hicn_data_input_error_strings, + .n_next_nodes = HICN_DATA_INPUT_IP4_N_NEXT, + .next_nodes = + { + [HICN_DATA_INPUT_IP4_NEXT_FACE] = "hicn-face-ip4-input", + [HICN_DATA_INPUT_IP4_NEXT_IP4_LOCAL] = "ip4-local-end-of-arc" + }, + }; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +VNET_FEATURE_INIT(hicn_data_input_ip4_arc, static)= + { + .arc_name = "ip4-local", + .node_name = "hicn-data-input-ip4", + .runs_before = VNET_FEATURES("ip4-local-end-of-arc"), + }; +/* *INDENT-ON* */ diff --git a/hicn-plugin/src/data_pcslookup_node.c b/hicn-plugin/src/data_pcslookup_node.c index 1ae36202f..cbea07871 100644 --- a/hicn-plugin/src/data_pcslookup_node.c +++ b/hicn-plugin/src/data_pcslookup_node.c @@ -73,7 +73,7 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, hicn_name_t name; hicn_header_t *hicn0 = NULL; u32 node_id0 = 0; - u8 dpo_ctx_id0 = 0; + index_t dpo_ctx_id0 = 0; int ret0; u8 vft_id0; u8 is_cs0; @@ -117,7 +117,9 @@ hicn_data_pcslookup_node_fn (vlib_main_t * vm, int res = hicn_hashtb_lookup_node (rt->pitcs->pcs_table, nameptr, namelen, name_hash, - 1 /*is_data. Do not take lock if hit CS */ , + 1 + /*is_data. Do not take lock if hit CS */ + , &node_id0, &dpo_ctx_id0, &vft_id0, &is_cs0, &hash_entry_id, &bucket_id, &bucket_is_overflown); diff --git a/hicn-plugin/src/data_push_node.c b/hicn-plugin/src/data_push_node.c index 21ebae16f..fc19362f9 100644 --- a/hicn-plugin/src/data_push_node.c +++ b/hicn-plugin/src/data_push_node.c @@ -99,7 +99,7 @@ hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt, hicn_header_t *hicn0 = vlib_buffer_get_current (b0); hicn_buffer_t *hicnb0 = hicn_get_buffer (b0); u32 node_id0 = 0; - u8 dpo_ctx_id0 = ~0; + index_t dpo_ctx_id0 = ~0; u8 vft_id0 = default_dpo.hicn_dpo_get_type (); u8 is_cs0 = 1; u8 hash_entry_id = 0; diff --git a/hicn-plugin/src/error.h b/hicn-plugin/src/error.h index 14cec0a3f..2124e63c5 100644 --- a/hicn-plugin/src/error.h +++ b/hicn-plugin/src/error.h @@ -58,25 +58,18 @@ _(ROUTE_NOT_UPDATED, -165, "Unable to update route") \ _(ROUTE_ALREADY_EXISTS, -166, "Route already in FIB") \ _(CLI_INVAL, -167, "Invalid input") \ - _(PUNT_INVAL, -168, "Invalid prefix or subnet or interface") \ - _(PUNT_TBL_NOT_FOUND, -169, "Vnet table not found") \ - _(PUNT_TBL_EXIST, -170, "Vnet table already created") \ - _(PUNT_SSN_NOT_FOUND, -171, "Vnet session not found") \ - _(PUNT_SSN_EXIST, -172, "Vnet session already created") \ - _(PUNT_SKIP_NOT_SUPPORTED, -173, "Skip size not supported. Skip must be <= 1") \ - _(PUNT_NOMEM, -174, "Unable to allocate skip_mask") \ - _(IPS_ADDR_TYPE_NONUNIFORM, -175, "Src and dst addr have different ip types") \ - _(FACE_TYPE_EXISTS, -176, "Face type already registered") \ - _(NO_BUFFERS, -177, "No vlib_buffer available for packet cloning.") \ - _(NOT_IMPLEMENTED, -178, "Function not yet implemented") \ - _(IFACE_IP_ADJ_NOT_FOUND, -179, "IP adjacency on incomplete face not available") \ - _(APPFACE_ALREADY_ENABLED, -180, "Application face already enabled on interface") \ - _(APPFACE_FEATURE, -181, "Error while enabling app face feature") \ - _(APPFACE_NOT_FOUND, -182, "Application face not found") \ - _(APPFACE_PROD_PREFIX_NULL, -183, "Prefix must not be null for producer face") \ - _(STRATEGY_NH_NOT_FOUND, -184, "Next hop not found") \ - _(MW_STRATEGY_SET, -185, "Error while setting weight for next hop") \ - _(STRATEGY_NOT_FOUND, -186, "Strategy not found") + _(IPS_ADDR_TYPE_NONUNIFORM, -168, "Src and dst addr have different ip types") \ + _(FACE_TYPE_EXISTS, -169, "Face type already registered") \ + _(NO_BUFFERS, -170, "No vlib_buffer available for packet cloning.") \ + _(NOT_IMPLEMENTED, -171, "Function not yet implemented") \ + _(IFACE_IP_ADJ_NOT_FOUND, -172, "IP adjacency on incomplete face not available") \ + _(APPFACE_ALREADY_ENABLED, -173, "Application face already enabled on interface") \ + _(APPFACE_FEATURE, -174, "Error while enabling app face feature") \ + _(APPFACE_NOT_FOUND, -175, "Application face not found") \ + _(APPFACE_PROD_PREFIX_NULL, -176, "Prefix must not be null for producer face") \ + _(STRATEGY_NH_NOT_FOUND, -177, "Next hop not found") \ + _(MW_STRATEGY_SET, -178, "Error while setting weight for next hop") \ + _(STRATEGY_NOT_FOUND, -179, "Strategy not found") typedef enum diff --git a/hicn-plugin/src/faces/app/face_cons.c b/hicn-plugin/src/faces/app/face_cons.c index f258da787..e51201c21 100644 --- a/hicn-plugin/src/faces/app/face_cons.c +++ b/hicn-plugin/src/faces/app/face_cons.c @@ -73,10 +73,7 @@ hicn_face_cons_add (ip4_address_t * nh_addr4, ip6_address_t * nh_addr6, face = hicn_dpoi_get_from_idx (*faceid2); face->shared.flags |= HICN_FACE_FLAGS_APPFACE_CONS; - return vnet_feature_enable_disable ("ip6-unicast", - "hicn-iface-ip6-input", swif, 1, 0, - 0) == - 0 ? HICN_ERROR_NONE : HICN_ERROR_APPFACE_FEATURE; + return HICN_ERROR_NONE; } int @@ -89,13 +86,7 @@ hicn_face_cons_del (hicn_face_id_t face_id) if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_CONS) { - int ret = hicn_face_ip_del (face_id); - - return ret == - HICN_ERROR_NONE - ? (vnet_feature_enable_disable - ("ip6-unicast", "hicn-iface-ip6-input", face->shared.sw_if, 0, - 0, 0) == 0 ? HICN_ERROR_NONE : HICN_ERROR_APPFACE_FEATURE) : ret; + return hicn_face_ip_del (face_id); } else { @@ -114,15 +105,6 @@ format_hicn_face_cons (u8 * s, va_list * args) return s; } -/* *INDENT-OFF* */ -VNET_FEATURE_INIT(hicn_cons_app, static)= -{ - .arc_name = "ip6-unicast", - .node_name = "hicn-iface-ip6-input", - .runs_before = VNET_FEATURES("ip6-inacl"), -}; -/* *INDENT-ON* */ - /* * fd.io coding-style-patch-verification: ON * diff --git a/hicn-plugin/src/faces/app/face_prod.c b/hicn-plugin/src/faces/app/face_prod.c index c183d6589..ae59719ce 100644 --- a/hicn-plugin/src/faces/app/face_prod.c +++ b/hicn-plugin/src/faces/app/face_prod.c @@ -271,6 +271,24 @@ hicn_face_prod_add (fib_prefix_t * prefix, u32 sw_if, u32 * cs_reserved, if (ret == HICN_ERROR_NONE && hicn_face_prod_set_lru_max (*faceid, cs_reserved) == HICN_ERROR_NONE) { + if (ip46_address_is_ip4(&(prefix->fp_addr))) + { + ip4_address_t mask; + ip4_preflen_to_mask (prefix->fp_len, &mask); + prefix->fp_addr.ip4.as_u32 = prefix->fp_addr.ip4.as_u32 & mask.as_u32; + prefix->fp_proto = FIB_PROTOCOL_IP4; + } + else + { + ip6_address_t mask; + ip6_preflen_to_mask (prefix->fp_len, &mask); + prefix->fp_addr.ip6.as_u64[0] = + prefix->fp_addr.ip6.as_u64[0] & mask.as_u64[0]; + prefix->fp_addr.ip6.as_u64[1] = + prefix->fp_addr.ip6.as_u64[1] & mask.as_u64[1]; + prefix->fp_proto = FIB_PROTOCOL_IP6; + } + hicn_app_state_create (sw_if, prefix); ret = hicn_route_add (faceid, 1, prefix); } diff --git a/hicn-plugin/src/faces/face.c b/hicn-plugin/src/faces/face.c index fa9d0d203..f2dcdd151 100644 --- a/hicn-plugin/src/faces/face.c +++ b/hicn-plugin/src/faces/face.c @@ -42,7 +42,7 @@ const char *HICN_FACE_CTRX_STRING[] = { u8 * face_show (u8 * s, int face_id, u32 indent) { - s = format (s, "Faces:\n", indent); + s = format (s, "%U Faces:\n", format_white_space, indent); indent += 4; int i; vec_foreach_index (i, face_dpo_vec) @@ -97,7 +97,7 @@ format_hicn_face_all (u8 * s, int n, ...) va_start (ap, n); u32 indent = va_arg (ap, u32); - s = format (s, "Faces: %d\n", indent); + s = format (s, "%U Faces:\n", format_white_space, indent); hicn_face_t *face; diff --git a/hicn-plugin/src/faces/ip/face_ip.c b/hicn-plugin/src/faces/ip/face_ip.c index f4ae5429d..a2fe069ed 100644 --- a/hicn-plugin/src/faces/ip/face_ip.c +++ b/hicn-plugin/src/faces/ip/face_ip.c @@ -41,22 +41,12 @@ hicn_face_ip_init (vlib_main_t * vm) /* Default Strategy has index 0 and it always exists */ strategy_face_ip4_vlib_edge = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft - (default_dpo. - hicn_dpo_get_type ())-> - get_strategy_node_index - (), - hicn_face_ip4_output_node. - index); + hicn_strategy_node.index, + hicn_face_ip4_output_node.index); strategy_face_ip6_vlib_edge = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft - (default_dpo. - hicn_dpo_get_type ())-> - get_strategy_node_index - (), - hicn_face_ip6_output_node. - index); + hicn_strategy_node.index, + hicn_face_ip6_output_node.index); /* * Create and edge between al the other strategy nodes and the * ip_encap nodes. @@ -64,12 +54,10 @@ hicn_face_ip_init (vlib_main_t * vm) for (int i = 1; i < strategy_nodes_n; i++) { u32 temp_index4 = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft_from_id - (i)->get_strategy_node_index (), + hicn_strategy_node.index, hicn_face_ip4_output_node.index); u32 temp_index6 = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft_from_id - (i)->get_strategy_node_index (), + hicn_strategy_node.index, hicn_face_ip6_output_node.index); ASSERT (temp_index4 == strategy_face_ip4_vlib_edge); ASSERT (temp_index6 == strategy_face_ip6_vlib_edge); @@ -104,66 +92,74 @@ hicn_face_ip_del (hicn_face_id_t face_id) { hicn_face_ip4_get_key (&(face_ip->local_addr.ip4), face->shared.sw_if, &key); - hicn_face_ip_input_faces_t * in_faces_vec = hicn_face_ip4_get_vec(&(face_ip->local_addr.ip4), face->shared.sw_if, - &hicn_face_ip_local_hashtb); + hicn_face_ip_input_faces_t *in_faces_vec = + hicn_face_ip4_get_vec (&(face_ip->local_addr.ip4), face->shared.sw_if, + &hicn_face_ip_local_hashtb); if (in_faces_vec != NULL) - { - hicn_face_ip_vec_t * vec = pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id); - u32 index_face = vec_search(*vec, face_id); - vec_del1(*vec, index_face); - - if (vec_len(*vec) == 0) - { - pool_put_index(hicn_vec_pool, in_faces_vec->vec_id); - mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key); - vec_free(*vec); - } - else - { - /* Check if the face we are deleting is the preferred one. */ - /* If so, repleace with another. */ - if (in_faces_vec->face_id == face_id) - { - in_faces_vec->face_id = (*vec)[0]; - } - } - hicn_face_ip4_get_key (&(face_ip->remote_addr.ip4), face->shared.sw_if, - &key); - mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key2); - } + { + hicn_face_ip_vec_t *vec = + pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id); + u32 index_face = vec_search (*vec, face_id); + vec_del1 (*vec, index_face); + + if (vec_len (*vec) == 0) + { + pool_put_index (hicn_vec_pool, in_faces_vec->vec_id); + mhash_unset (&hicn_face_ip_local_hashtb, &key, + (uword *) & old_key); + vec_free (*vec); + } + else + { + /* Check if the face we are deleting is the preferred one. */ + /* If so, repleace with another. */ + if (in_faces_vec->face_id == face_id) + { + in_faces_vec->face_id = (*vec)[0]; + } + } + hicn_face_ip4_get_key (&(face_ip->remote_addr.ip4), + face->shared.sw_if, &key); + mhash_unset (&hicn_face_ip_remote_hashtb, &key, + (uword *) & old_key2); + } } else { hicn_face_ip6_get_key (&(face_ip->local_addr.ip6), face->shared.sw_if, &key); - hicn_face_ip_input_faces_t * in_faces_vec = hicn_face_ip6_get_vec(&(face_ip->local_addr.ip6), face->shared.sw_if, - &hicn_face_ip_local_hashtb); + hicn_face_ip_input_faces_t *in_faces_vec = + hicn_face_ip6_get_vec (&(face_ip->local_addr.ip6), face->shared.sw_if, + &hicn_face_ip_local_hashtb); if (in_faces_vec != NULL) - { - hicn_face_ip_vec_t * vec = pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id); - u32 index_face = vec_search(*vec, face_id); - vec_del1(*vec, index_face); - - if (vec_len(*vec) == 0) - { - pool_put(hicn_vec_pool, vec); - mhash_unset (&hicn_face_ip_local_hashtb, &key, (uword *) & old_key); - vec_free(*vec); - } - else - { - /* Check if the face we are deleting is the preferred one. */ - /* If so, repleace with another. */ - if (in_faces_vec->face_id == face_id) - { - in_faces_vec->face_id = (*vec)[0]; - } - } - hicn_face_ip6_get_key (&(face_ip->remote_addr.ip6), face->shared.sw_if, - &key); - mhash_unset (&hicn_face_ip_remote_hashtb, &key, (uword *) & old_key); - } + { + hicn_face_ip_vec_t *vec = + pool_elt_at_index (hicn_vec_pool, in_faces_vec->vec_id); + u32 index_face = vec_search (*vec, face_id); + vec_del1 (*vec, index_face); + + if (vec_len (*vec) == 0) + { + pool_put (hicn_vec_pool, vec); + mhash_unset (&hicn_face_ip_local_hashtb, &key, + (uword *) & old_key); + vec_free (*vec); + } + else + { + /* Check if the face we are deleting is the preferred one. */ + /* If so, repleace with another. */ + if (in_faces_vec->face_id == face_id) + { + in_faces_vec->face_id = (*vec)[0]; + } + } + hicn_face_ip6_get_key (&(face_ip->remote_addr.ip6), + face->shared.sw_if, &key); + mhash_unset (&hicn_face_ip_remote_hashtb, &key, + (uword *) & old_key); + } } return hicn_face_del (face_id); } @@ -171,17 +167,18 @@ hicn_face_ip_del (hicn_face_id_t face_id) /** * @brief Helper for handling midchain adjacencies */ -void face_midchain_fixup_t (vlib_main_t * vm, - const struct ip_adjacency_t_ * adj, - vlib_buffer_t * b0, - const void *data) { +void +face_midchain_fixup_t (vlib_main_t * vm, + const struct ip_adjacency_t_ *adj, + vlib_buffer_t * b0, const void *data) +{ vnet_buffer (b0)->sw_if_index[VLIB_TX] = 0; }; /** * @brief Build a rewrite string for the face. */ -static u8* +static u8 * face_build_rewrite_i (void) { /* @@ -192,51 +189,56 @@ face_build_rewrite_i (void) */ u8 *rewrite = NULL; - vec_validate(rewrite, 0); - vec_reset_length(rewrite); + vec_validate (rewrite, 0); + vec_reset_length (rewrite); return (rewrite); } always_inline int hicn_face_ip_find_adj (const ip46_address_t * remote_addr, - int sw_if, adj_index_t * adj) + int sw_if, adj_index_t * adj) { fib_prefix_t fib_pfx; fib_node_index_t fib_entry_index; fib_prefix_from_ip46_addr (remote_addr, &fib_pfx); - fib_pfx.fp_len = ip46_address_is_ip4(remote_addr)? 32 : 128; - vnet_link_t link_type = ip46_address_is_ip4(&fib_pfx.fp_addr)? VNET_LINK_IP4 : VNET_LINK_IP6; - *adj = adj_nbr_find(fib_pfx.fp_proto, link_type, &fib_pfx.fp_addr, sw_if); + fib_pfx.fp_len = ip46_address_is_ip4 (remote_addr) ? 32 : 128; + vnet_link_t link_type = + ip46_address_is_ip4 (&fib_pfx.fp_addr) ? VNET_LINK_IP4 : VNET_LINK_IP6; + *adj = adj_nbr_find (fib_pfx.fp_proto, link_type, &fib_pfx.fp_addr, sw_if); if (*adj == ADJ_INDEX_INVALID) { u32 fib_index = fib_table_find_or_create_and_lock (fib_pfx.fp_proto, - HICN_FIB_TABLE, - FIB_SOURCE_PRIORITY_HI); + HICN_FIB_TABLE, + FIB_SOURCE_PRIORITY_HI); fib_entry_index = fib_table_lookup (fib_index, &fib_pfx); if (fib_entry_index == (FIB_NODE_INDEX_INVALID)) - return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; + return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; *adj = fib_entry_get_adj (fib_entry_index); - ip_adjacency_t * temp = NULL; + ip_adjacency_t *temp = NULL; if (*adj != ~0) - temp = adj_get(*adj); + temp = adj_get (*adj); if (temp == NULL || temp->lookup_next_index <= IP_LOOKUP_NEXT_MIDCHAIN) - { - if(sw_if != ~0) - *adj = adj_nbr_add_or_lock(fib_pfx.fp_proto, link_type, remote_addr, sw_if); - else - return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; - } + { + if (sw_if != ~0) + *adj = + adj_nbr_add_or_lock (fib_pfx.fp_proto, link_type, remote_addr, + sw_if); + else + return HICN_ERROR_FACE_IP_ADJ_NOT_FOUND; + } else - { - adj_nbr_midchain_update_rewrite(*adj, &face_midchain_fixup_t, NULL, ADJ_FLAG_NONE, face_build_rewrite_i()); - adj_midchain_delegate_stack(*adj, fib_index, &fib_pfx); - } + { + adj_nbr_midchain_update_rewrite (*adj, &face_midchain_fixup_t, NULL, + ADJ_FLAG_NONE, + face_build_rewrite_i ()); + adj_midchain_delegate_stack (*adj, fib_index, &fib_pfx); + } } return HICN_ERROR_NONE; @@ -249,8 +251,7 @@ hicn_face_ip_find_adj (const ip46_address_t * remote_addr, int hicn_face_ip_add (const ip46_address_t * local_addr, const ip46_address_t * remote_addr, - int sw_if, hicn_face_id_t * pfaceid, - u8 is_app_prod) + int sw_if, hicn_face_id_t * pfaceid, u8 is_app_prod) { dpo_proto_t dpo_proto; @@ -280,78 +281,83 @@ hicn_face_ip_add (const ip46_address_t * local_addr, } if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE)) - return HICN_ERROR_FACE_ALREADY_CREATED; + return HICN_ERROR_FACE_ALREADY_CREATED; hicn_face_ip_key_t key; hicn_face_ip4_get_key (&(local_addr->ip4), sw_if, &key); - hicn_face_ip_input_faces_t * in_faces = + hicn_face_ip_input_faces_t *in_faces = hicn_face_ip4_get_vec (&(local_addr->ip4), sw_if, - &hicn_face_ip_local_hashtb); + &hicn_face_ip_local_hashtb); if (in_faces == NULL) - { - adj_index_t adj; - int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj); - if (ret != HICN_ERROR_NONE) - return ret; - - hicn_face_ip_input_faces_t in_faces_temp; - hicn_face_ip_vec_t *vec; - pool_get(hicn_vec_pool, vec); - *vec = vec_new(hicn_face_ip_vec_t, 0); - u32 index = vec - hicn_vec_pool; - in_faces_temp.vec_id = index; - vec_add1(*vec, *pfaceid); - - hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; - clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t)); - clib_memcpy (&ip_face->remote_addr, remote_addr, - sizeof (ip4_address_t)); - face->shared.sw_if = sw_if; - face->shared.flags = flags; - face->shared.adj = adj; - - dpo_proto = DPO_PROTO_IP4; - - in_faces_temp.face_id = *pfaceid; - - mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) &in_faces_temp, 0); - } + { + adj_index_t adj; + int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj); + if (ret != HICN_ERROR_NONE) + return ret; + + hicn_face_ip_input_faces_t in_faces_temp; + hicn_face_ip_vec_t *vec; + pool_get (hicn_vec_pool, vec); + *vec = vec_new (hicn_face_ip_vec_t, 0); + u32 index = vec - hicn_vec_pool; + in_faces_temp.vec_id = index; + vec_add1 (*vec, *pfaceid); + + hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; + clib_memcpy (&ip_face->local_addr, local_addr, + sizeof (ip4_address_t)); + clib_memcpy (&ip_face->remote_addr, remote_addr, + sizeof (ip4_address_t)); + face->shared.sw_if = sw_if; + face->shared.flags = flags; + face->shared.adj = adj; + + dpo_proto = DPO_PROTO_IP4; + + in_faces_temp.face_id = *pfaceid; + + mhash_set_mem (&hicn_face_ip_local_hashtb, &key, + (uword *) & in_faces_temp, 0); + } else - { - hicn_face_ip_vec_t * vec = pool_elt_at_index(hicn_vec_pool, in_faces->vec_id); - - /* */ - if (vec_search(*vec, *pfaceid) != ~0) - return HICN_ERROR_FACE_ALREADY_CREATED; - - adj_index_t adj; - int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj); - if (ret != HICN_ERROR_NONE) - return ret; - - vec_add1(*vec, *pfaceid); - - hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; - clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip4_address_t)); - clib_memcpy (&ip_face->remote_addr, remote_addr, - sizeof (ip4_address_t)); - face->shared.sw_if = sw_if; - face->shared.flags = flags; - face->shared.adj = adj; - - dpo_proto = DPO_PROTO_IP4; - - mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, 0); - - /* If the face is an application producer face, we set it as the preferred incoming face. */ - /* This is required to handle the CS separation, and the push api in a lightway*/ - if (is_app_prod) - { - in_faces->face_id = *pfaceid; - } - } + { + hicn_face_ip_vec_t *vec = + pool_elt_at_index (hicn_vec_pool, in_faces->vec_id); + + /* */ + if (vec_search (*vec, *pfaceid) != ~0) + return HICN_ERROR_FACE_ALREADY_CREATED; + + adj_index_t adj; + int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj); + if (ret != HICN_ERROR_NONE) + return ret; + + vec_add1 (*vec, *pfaceid); + + hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; + clib_memcpy (&ip_face->local_addr, local_addr, + sizeof (ip4_address_t)); + clib_memcpy (&ip_face->remote_addr, remote_addr, + sizeof (ip4_address_t)); + face->shared.sw_if = sw_if; + face->shared.flags = flags; + face->shared.adj = adj; + + dpo_proto = DPO_PROTO_IP4; + + mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, + 0); + + /* If the face is an application producer face, we set it as the preferred incoming face. */ + /* This is required to handle the CS separation, and the push api in a lightway */ + if (is_app_prod) + { + in_faces->face_id = *pfaceid; + } + } } else { @@ -371,83 +377,87 @@ hicn_face_ip_add (const ip46_address_t * local_addr, } if (!(face->shared.flags & HICN_FACE_FLAGS_IFACE)) - return HICN_ERROR_FACE_ALREADY_CREATED; + return HICN_ERROR_FACE_ALREADY_CREATED; hicn_face_ip_key_t key; hicn_face_ip6_get_key (&(local_addr->ip6), sw_if, &key); - hicn_face_ip_input_faces_t * in_faces = + hicn_face_ip_input_faces_t *in_faces = hicn_face_ip6_get_vec (&(local_addr->ip6), sw_if, - &hicn_face_ip_local_hashtb); + &hicn_face_ip_local_hashtb); if (in_faces == NULL) - { - adj_index_t adj; - int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj); - if (ret != HICN_ERROR_NONE) - return ret; - - hicn_face_ip_input_faces_t in_faces_temp; - hicn_face_ip_vec_t *vec; - pool_get(hicn_vec_pool, vec); - vec_alloc(*vec, 1); - u32 index = vec - hicn_vec_pool; - in_faces_temp.vec_id = index; - vec_add1(*vec, *pfaceid); - - hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; - clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t)); - clib_memcpy (&ip_face->remote_addr, remote_addr, - sizeof (ip6_address_t)); - face->shared.sw_if = sw_if; - face->shared.flags = flags; - face->shared.adj = adj; - - dpo_proto = DPO_PROTO_IP6; - - in_faces_temp.face_id = *pfaceid; - - mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) &in_faces_temp, 0); - } + { + adj_index_t adj; + int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj); + if (ret != HICN_ERROR_NONE) + return ret; + + hicn_face_ip_input_faces_t in_faces_temp; + hicn_face_ip_vec_t *vec; + pool_get (hicn_vec_pool, vec); + vec_alloc (*vec, 1); + u32 index = vec - hicn_vec_pool; + in_faces_temp.vec_id = index; + vec_add1 (*vec, *pfaceid); + + hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; + clib_memcpy (&ip_face->local_addr, local_addr, + sizeof (ip6_address_t)); + clib_memcpy (&ip_face->remote_addr, remote_addr, + sizeof (ip6_address_t)); + face->shared.sw_if = sw_if; + face->shared.flags = flags; + face->shared.adj = adj; + + dpo_proto = DPO_PROTO_IP6; + + in_faces_temp.face_id = *pfaceid; + + mhash_set_mem (&hicn_face_ip_local_hashtb, &key, + (uword *) & in_faces_temp, 0); + } else - { - hicn_face_ip_vec_t *vec = pool_elt_at_index(hicn_vec_pool, in_faces->vec_id); - - /* */ - if (vec_search(*vec, *pfaceid) != ~0) - return HICN_ERROR_FACE_ALREADY_CREATED; - - adj_index_t adj; - int ret = hicn_face_ip_find_adj(remote_addr, sw_if, &adj); - if (ret != HICN_ERROR_NONE) - return ret; - - vec_add1(*vec, *pfaceid); - - hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; - clib_memcpy (&ip_face->local_addr, local_addr, sizeof (ip6_address_t)); - clib_memcpy (&ip_face->remote_addr, remote_addr, - sizeof (ip6_address_t)); - face->shared.sw_if = sw_if; - face->shared.flags = flags; - face->shared.adj = adj; - - dpo_proto = DPO_PROTO_IP6; - - mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, 0); - - /* If the face is an application producer face, we set it as the preferred incoming face. */ - /* This is required to handle the CS separation, and the push api in a lightway*/ - if (is_app_prod) - { - in_faces->face_id = *pfaceid; - } - } + { + hicn_face_ip_vec_t *vec = + pool_elt_at_index (hicn_vec_pool, in_faces->vec_id); + + /* */ + if (vec_search (*vec, *pfaceid) != ~0) + return HICN_ERROR_FACE_ALREADY_CREATED; + + adj_index_t adj; + int ret = hicn_face_ip_find_adj (remote_addr, sw_if, &adj); + if (ret != HICN_ERROR_NONE) + return ret; + + vec_add1 (*vec, *pfaceid); + + hicn_face_ip_t *ip_face = (hicn_face_ip_t *) face->data; + clib_memcpy (&ip_face->local_addr, local_addr, + sizeof (ip6_address_t)); + clib_memcpy (&ip_face->remote_addr, remote_addr, + sizeof (ip6_address_t)); + face->shared.sw_if = sw_if; + face->shared.flags = flags; + face->shared.adj = adj; + + dpo_proto = DPO_PROTO_IP6; + + mhash_set_mem (&hicn_face_ip_local_hashtb, &key, (uword *) in_faces, + 0); + + /* If the face is an application producer face, we set it as the preferred incoming face. */ + /* This is required to handle the CS separation, and the push api in a lightway */ + if (is_app_prod) + { + in_faces->face_id = *pfaceid; + } + } } retx_t *retx = vlib_process_signal_event_data (vlib_get_main (), - hicn_mapme_eventmgr_process_node. - index, + hicn_mapme_eventmgr_process_node.index, HICN_MAPME_EVENT_FACE_ADD, 1, sizeof (retx_t)); diff --git a/hicn-plugin/src/faces/udp/face_udp.c b/hicn-plugin/src/faces/udp/face_udp.c index e2fa3227b..e610cbd14 100644 --- a/hicn-plugin/src/faces/udp/face_udp.c +++ b/hicn-plugin/src/faces/udp/face_udp.c @@ -80,16 +80,11 @@ hicn_face_udp_init (vlib_main_t * vm) /* Default Strategy has index 0 and it always exists */ strategy_face_udp4_vlib_edge = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft - (default_dpo.hicn_dpo_get_type - ())->get_strategy_node_index - (), - hicn_face_udp4_output_node.index); + hicn_strategy_node.index, + hicn_face_udp4_output_node. + index); strategy_face_udp6_vlib_edge = - vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft - (default_dpo.hicn_dpo_get_type - ())->get_strategy_node_index (), + vlib_node_add_next (vm, hicn_strategy_node.index, hicn_face_udp6_output_node.index); /* @@ -99,12 +94,10 @@ hicn_face_udp_init (vlib_main_t * vm) for (int i = 1; i < strategy_nodes_n; i++) { u32 temp_index4 = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft_from_id - (i)->get_strategy_node_index (), + hicn_strategy_node.index, hicn_face_udp4_output_node.index); u32 temp_index6 = vlib_node_add_next (vm, - hicn_dpo_get_strategy_vft_from_id - (i)->get_strategy_node_index (), + hicn_strategy_node.index, hicn_face_udp6_output_node.index); ASSERT (temp_index4 == strategy_face_udp4_vlib_edge); ASSERT (temp_index6 == strategy_face_udp6_vlib_edge); @@ -269,7 +262,8 @@ hicn_face_udp_add (const ip46_address_t * local_addr, } retx_t *retx = vlib_process_signal_event_data (vlib_get_main (), - hicn_mapme_eventmgr_process_node.index, + hicn_mapme_eventmgr_process_node. + index, HICN_MAPME_EVENT_FACE_ADD, 1, sizeof (retx_t)); /* *INDENT-OFF* */ diff --git a/hicn-plugin/src/hashtb.c b/hicn-plugin/src/hashtb.c index 5d41b7aa9..6deddbd84 100644 --- a/hicn-plugin/src/hashtb.c +++ b/hicn-plugin/src/hashtb.c @@ -270,7 +270,7 @@ hicn_hashtb_free (hicn_hashtb_h * ph) int hicn_hashtb_lookup_node (hicn_hashtb_h h, const u8 * key, u32 keylen, u64 hashval, u8 is_data, - u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, + u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow) { @@ -295,7 +295,7 @@ int hicn_hashtb_lookup_node_ex (hicn_hashtb_h h, const u8 * key, u32 keylen, u64 hashval, u8 is_data, int include_deleted_p, u32 * node_id, - u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, + index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow) { @@ -423,7 +423,7 @@ int hicn_hashtb_insert (hicn_hashtb_h h, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hash, u32 * node_id, - u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, + index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow) { @@ -485,8 +485,8 @@ loop_buckets: * If we are doing lookup for a data, do not take a * lock in case of a hit with a CS entry */ - if (!(*is_cs)) - bucket->hb_entries[i].locks++; + if (!(*is_cs)) + bucket->hb_entries[i].locks++; *bucket_is_overflow = is_overflow; ret = HICN_ERROR_HASHTB_EXIST; goto done; diff --git a/hicn-plugin/src/hashtb.h b/hicn-plugin/src/hashtb.h index b74e972b2..756f247b7 100644 --- a/hicn-plugin/src/hashtb.h +++ b/hicn-plugin/src/hashtb.h @@ -189,6 +189,9 @@ typedef struct __attribute__ ((packed)) hicn_hash_entry_s */ u32 locks; + /* Index of dpo (4B) */ + index_t dpo_ctx_id; + /* A few flags, including 'this points to a chain of buckets' */ u8 he_flags; @@ -198,10 +201,10 @@ typedef struct __attribute__ ((packed)) hicn_hash_entry_s */ u8 vft_id; - /* Index of dpo */ - u8 dpo_ctx_id; +} hicn_hash_entry_t; //size 22B + +STATIC_ASSERT (sizeof (index_t) <= 4, "sizeof index_t is greater than 4B"); -} hicn_hash_entry_t; #define HICN_HASH_ENTRY_FLAGS_DEFAULT 0x00 @@ -231,13 +234,13 @@ typedef struct __attribute__ ((packed)) hicn_hash_entry_s * Overflow bucket ratio as a fraction of the fixed/configured count; a pool * of hash buckets used if a row in the fixed table overflows. */ -#define HICN_HASHTB_BUCKET_ENTRIES 6 +#define HICN_HASHTB_BUCKET_ENTRIES 5 typedef struct __attribute__ ((packed)) { hicn_hash_entry_t hb_entries[HICN_HASHTB_BUCKET_ENTRIES]; u64 align1; - u32 align2; + u64 align2; u16 align3; } hicn_hash_bucket_t; @@ -400,7 +403,7 @@ int hicn_hashtb_insert (hicn_hashtb_h h, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hash, u32 * node_id, - u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, + index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow); @@ -414,7 +417,7 @@ hicn_hashtb_insert (hicn_hashtb_h h, hicn_hash_node_t * node, int hicn_hashtb_lookup_node (hicn_hashtb_h h, const u8 * key, u32 keylen, u64 hashval, u8 is_data, - u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, + u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow); @@ -432,7 +435,7 @@ int hicn_hashtb_lookup_node_ex (hicn_hashtb_h h, const u8 * key, u32 keylen, u64 hashval, u8 is_data, int include_deleted_p, u32 * node_id, - u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, + index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow); diff --git a/hicn-plugin/src/hicn.api b/hicn-plugin/src/hicn.api index b226dfe4d..01e4da213 100644 --- a/hicn-plugin/src/hicn.api +++ b/hicn-plugin/src/hicn.api @@ -22,12 +22,6 @@ enum hicn_face_type UDP_FACE, }; -enum hicn_punt_type -{ - IP_PUNT = 0, - UDP_PUNT, -}; - typedef hicn_face_ip { /* IP local address */ @@ -76,39 +70,6 @@ typedef hicn_face_union vl_api_hicn_face_udp_t udp; }; -typedef hicn_punting_ip -{ - /* Prefix to match */ - vl_api_prefix_t prefix; - - /* Interface id */ - u32 swif; -}; - -typedef hicn_punting_udp -{ - /* Prefix to match */ - vl_api_prefix_t prefix; - - /* Source port to match */ - u16 sport; - - /* Destination port to match */ - u16 dport; - - /* Ip version (4 or 6) of the tunnel */ - vl_api_address_family_t ip_version; - - /* Interface id */ - u32 swif; -}; - -typedef hicn_punting_union -{ - vl_api_hicn_punting_ip_t ip; - vl_api_hicn_punting_udp_t udp; -}; - define hicn_api_node_params_set { /* Client identifier, set from api_main.my_client_index */ @@ -663,54 +624,6 @@ define hicn_api_strategy_get_reply i32 retval; }; -define hicn_api_punting_add -{ - /* Client identifier, set from api_main.my_client_index */ - u32 client_index; - - /* Arbitrary context, so client can match reply to request */ - u32 context; - - /* Type of punting rule */ - vl_api_hicn_punt_type_t type; - - /* Prefix to match */ - vl_api_hicn_punting_union_t rule; -}; - -define hicn_api_punting_add_reply -{ - /* From the request */ - u32 context; - - /* Return value, zero means all OK */ - i32 retval; -}; - -define hicn_api_punting_del -{ - /* Client identifier, set from api_main.my_client_index */ - u32 client_index; - - /* Arbitrary context, so client can match reply to request */ - u32 context; - - /* Type of punting rule */ - vl_api_hicn_punt_type_t type; - - /* Prefix to match */ - vl_api_hicn_punting_union_t rule; -}; - -define hicn_api_punting_del_reply -{ - /* From the request */ - u32 context; - - /* Return value, zero means all OK */ - i32 retval; -}; - define hicn_api_register_prod_app { /* Client identifier, set from api_main.my_client_index */ diff --git a/hicn-plugin/src/hicn.c b/hicn-plugin/src/hicn.c index b4a26ec8f..7c2776869 100644 --- a/hicn-plugin/src/hicn.c +++ b/hicn-plugin/src/hicn.c @@ -22,7 +22,6 @@ #include "infra.h" #include "strategy_dpo_manager.h" #include "mgmt.h" -#include "punt.h" #include "error.h" #include "faces/app/address_mgr.h" #include "face_db.h" @@ -216,9 +215,9 @@ hicn_configure (vlib_main_t * vm, unformat_input_t * input) else if (unformat (input, "cs-reserved-app %u", &cs_reserved)) ; else - break; + break; // clib_error_return (0, -// "hICN parameter unknown"); +// "hICN parameter unknown"); } unformat_free (input); @@ -248,9 +247,6 @@ hicn_init (vlib_main_t * vm) error = hicn_api_plugin_hookup (vm); - /* Init the hash table */ - hicn_punt_init (vm); - /* Init the dpo module */ hicn_dpos_init (); @@ -259,8 +255,8 @@ hicn_init (vlib_main_t * vm) hicn_face_module_init (vm); - /* Init the route module*/ - hicn_route_init(); + /* Init the route module */ + hicn_route_init (); return error; } diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c index 4601ae316..7a6babeb2 100644 --- a/hicn-plugin/src/hicn_api.c +++ b/hicn-plugin/src/hicn_api.c @@ -35,7 +35,6 @@ #include "strategy.h" #include "pg.h" #include "error.h" -#include "punt.h" #include "faces/app/face_prod.h" #include "faces/app/face_cons.h" #include "route.h" @@ -314,7 +313,7 @@ vl_api_hicn_api_face_add_t_handler (vl_api_hicn_api_face_add_t * mp) hicn_main_t *sm = &hicn_main; hicn_face_id_t face_id; - vl_api_hicn_face_type_t face_type = clib_net_to_host_u32(mp->type); + vl_api_hicn_face_type_t face_type = clib_net_to_host_u32 (mp->type); switch (face_type) { @@ -436,12 +435,12 @@ send_faces_details (vl_api_registration_t * reg, if (face->shared.face_type == hicn_face_ip_type) { - mp->type = clib_host_to_net_u32(IP_FACE); + mp->type = clib_host_to_net_u32 (IP_FACE); send_face_ip_details (face, &(mp->face.ip)); } else if (face->shared.face_type == hicn_face_udp_type) { - mp->type = clib_host_to_net_u32(UDP_FACE); + mp->type = clib_host_to_net_u32 (UDP_FACE); send_face_udp_details (face, &(mp->face.udp)); } @@ -651,7 +650,6 @@ static void vl_api_hicn_api_route_get_t_handler fib_prefix_t prefix; ip_prefix_decode (&mp->prefix, &prefix); const dpo_id_t *hicn_dpo_id; - const hicn_dpo_vft_t *hicn_dpo_vft; hicn_dpo_ctx_t *hicn_dpo_ctx; u32 fib_index; @@ -662,8 +660,7 @@ static void vl_api_hicn_api_route_get_t_handler { if (rv == HICN_ERROR_NONE) { - hicn_dpo_vft = hicn_dpo_get_vft(hicn_dpo_id->dpoi_type); - hicn_dpo_ctx = hicn_dpo_vft->hicn_dpo_get_ctx(hicn_dpo_id->dpoi_index); + hicn_dpo_ctx = hicn_strategy_dpo_ctx_get(hicn_dpo_id->dpoi_index); for (int i = 0; hicn_dpo_ctx != NULL && i < hicn_dpo_ctx->entry_count; i++) { if (dpo_id_is_valid(&hicn_dpo_ctx->next_hops[i])) @@ -687,11 +684,10 @@ send_route_details (vl_api_registration_t * reg, mp->_vl_msg_id = htons (VL_API_HICN_API_ROUTES_DETAILS + hm->msg_id_base); mp->context = context; - ip_prefix_encode(pfx, &mp->prefix); + ip_prefix_encode (pfx, &mp->prefix); mp->nfaces = 0; const dpo_id_t *hicn_dpo_id; - const hicn_dpo_vft_t *hicn_dpo_vft; hicn_dpo_ctx_t *hicn_dpo_ctx; u32 fib_index; @@ -699,9 +695,9 @@ send_route_details (vl_api_registration_t * reg, if (rv == HICN_ERROR_NONE) { - hicn_dpo_vft = hicn_dpo_get_vft (hicn_dpo_id->dpoi_type); - hicn_dpo_ctx = hicn_dpo_vft->hicn_dpo_get_ctx (hicn_dpo_id->dpoi_index); - for (int i = 0; hicn_dpo_ctx != NULL && i < hicn_dpo_ctx->entry_count; i++) + hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index); + for (int i = 0; hicn_dpo_ctx != NULL && i < hicn_dpo_ctx->entry_count; + i++) { if (dpo_id_is_valid (&hicn_dpo_ctx->next_hops[i])) { @@ -757,8 +753,7 @@ vl_api_hicn_api_route_dump_walk (fib_node_index_t fei, void *arg) } static void - vl_api_hicn_api_routes_dump_t_handler - (vl_api_hicn_api_routes_dump_t * mp) +vl_api_hicn_api_routes_dump_t_handler (vl_api_hicn_api_routes_dump_t * mp) { vl_api_registration_t *reg; fib_table_t *fib_table; @@ -841,81 +836,13 @@ static void vl_api_hicn_api_strategy_get_t_handler { if (rv == HICN_ERROR_NONE) { - const hicn_dpo_vft_t * hicn_dpo_vft = - hicn_dpo_get_vft (strategy_id); - hicn_dpo_vft->format_hicn_dpo (rmp->description, 0);} + const hicn_strategy_vft_t * hicn_strategy_vft = + hicn_dpo_get_strategy_vft (strategy_id); + hicn_strategy_vft->hicn_format_strategy (rmp->description, 0);} })); /* *INDENT-ON* */ } -/****** PUNTING *******/ - -static hicn_error_t -add_ip_punting (vl_api_hicn_punting_ip_t * mp) -{ - vlib_main_t *vm = vlib_get_main (); - fib_prefix_t prefix; - ip_prefix_decode (&mp->prefix, &prefix); - u32 swif = clib_net_to_host_u32 (mp->swif); - - return hicn_punt_interest_data_for_ip (vm, &prefix, swif, HICN_PUNT_IP_TYPE, - NO_L2); -} - -static hicn_error_t -add_udp_punting (vl_api_hicn_punting_udp_t * mp) -{ - vlib_main_t *vm = vlib_get_main (); - fib_prefix_t prefix; - ip_prefix_decode (&mp->prefix, &prefix); - u32 swif = clib_net_to_host_u32 (mp->swif); - u16 sport = clib_net_to_host_u16 (mp->sport); - u16 dport = clib_net_to_host_u16 (mp->sport); - u8 type = - mp->ip_version == ADDRESS_IP6 ? HICN_PUNT_UDP6_TYPE : HICN_PUNT_UDP4_TYPE; - - return hicn_punt_interest_data_for_udp (vm, &prefix, swif, type, sport, - dport, NO_L2); -} - -static void vl_api_hicn_api_punting_add_t_handler - (vl_api_hicn_api_punting_add_t * mp) -{ - vl_api_hicn_api_punting_add_reply_t *rmp; - int rv = HICN_ERROR_NONE; - - hicn_main_t *sm = &hicn_main; - - if (mp->type == IP_PUNT) - { - rv = add_ip_punting (&(mp->rule.ip)); - } - else if (mp->type == UDP_PUNT) - { - rv = add_udp_punting (&(mp->rule.udp)); - } - else - { - rv = HICN_ERROR_PUNT_INVAL; - } - - - REPLY_MACRO (VL_API_HICN_API_PUNTING_ADD_REPLY /* , rmp, mp, rv */ ); -} - -static void vl_api_hicn_api_punting_del_t_handler - (vl_api_hicn_api_punting_del_t * mp) -{ - vl_api_hicn_api_punting_del_reply_t *rmp; - int rv = HICN_ERROR_NONE; - - hicn_main_t *sm = &hicn_main; - - rv = HICN_ERROR_NONE; - - REPLY_MACRO (VL_API_HICN_API_ROUTE_DEL_REPLY /* , rmp, mp, rv */ ); -} - /************* APP FACE ****************/ static void vl_api_hicn_api_register_prod_app_t_handler diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c index 3e93300d7..08a579914 100644 --- a/hicn-plugin/src/hicn_api_test.c +++ b/hicn-plugin/src/hicn_api_test.c @@ -226,9 +226,7 @@ _(hicn_api_face_ip_del_reply) \ _(hicn_api_face_del_reply) \ _(hicn_api_route_nhops_add_reply) \ _(hicn_api_route_del_reply) \ -_(hicn_api_route_nhop_del_reply) \ -_(hicn_api_punting_add_reply) \ -_(hicn_api_punting_del_reply) +_(hicn_api_route_nhop_del_reply) #define _(n) \ static void vl_api_##n##_t_handler \ @@ -270,7 +268,6 @@ _(HICN_API_ROUTE_DEL_REPLY, hicn_api_route_del_reply) \ _(HICN_API_ROUTE_NHOP_DEL_REPLY, hicn_api_route_nhop_del_reply) \ _(HICN_API_STRATEGIES_GET_REPLY, hicn_api_strategies_get_reply) \ _(HICN_API_STRATEGY_GET_REPLY, hicn_api_strategy_get_reply) \ -_(HICN_API_PUNTING_ADD_REPLY, hicn_api_punting_add_reply) \ _(HICN_API_REGISTER_PROD_APP_REPLY, hicn_api_register_prod_app_reply) \ _(HICN_API_FACE_PROD_DEL_REPLY, hicn_api_face_prod_del_reply) \ _(HICN_API_REGISTER_CONS_APP_REPLY, hicn_api_register_cons_app_reply) \ @@ -488,7 +485,7 @@ api_hicn_api_face_ip_add (vat_main_t * vam) } /* Construct the API message */ M (HICN_API_FACE_ADD, mp); - mp->type = clib_host_to_net_u32(IP_FACE); + mp->type = clib_host_to_net_u32 (IP_FACE); ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.ip.local_addr); ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.ip.remote_addr); mp->face.ip.swif = clib_host_to_net_u32 (sw_if); @@ -565,7 +562,7 @@ api_hicn_api_face_udp_add (vat_main_t * vam) } /* Construct the API message */ M (HICN_API_FACE_ADD, mp); - mp->type = clib_host_to_net_u32(UDP_FACE); + mp->type = clib_host_to_net_u32 (UDP_FACE); ip_address_encode (&local_addr, IP46_TYPE_ANY, &mp->face.udp.local_addr); ip_address_encode (&remote_addr, IP46_TYPE_ANY, &mp->face.udp.remote_addr); mp->face.udp.lport = clib_host_to_net_u16 (sport); @@ -591,8 +588,7 @@ api_hicn_api_face_add (vat_main_t * vam) /* Parse args required to build the message */ while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { - if (unformat - (input, "type %d", &type)); + if (unformat (input, "type %d", &type)); else { break; @@ -602,9 +598,9 @@ api_hicn_api_face_add (vat_main_t * vam) vam->input = input; if (type == IP_FACE) - ret = api_hicn_api_face_ip_add(vam); + ret = api_hicn_api_face_ip_add (vam); else if (type == UDP_FACE) - ret = api_hicn_api_face_udp_add(vam); + ret = api_hicn_api_face_udp_add (vam); return ret; } @@ -1419,175 +1415,6 @@ static void } static int -api_hicn_api_ip_punting_add (vat_main_t * vam) -{ - unformat_input_t *input = vam->input; - vl_api_hicn_api_punting_add_t *mp; - fib_prefix_t prefix; - u32 swif = ~0; - int ret; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "prefix %U/%d", unformat_ip46_address, - &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len)) - {; - } - else if (unformat (input, "intfc %d", &swif)) - {; - } - else - { - break; - } - } - - /* Check parse */ - if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0)) - || (prefix.fp_len == 0)) - { - clib_warning ("Please specify prefix..."); - return 1; - } - - if (swif == ~0) - { - clib_warning ("Please specify interface..."); - return 1; - } - /* Construct the API message */ - M (HICN_API_PUNTING_ADD, mp); - mp->type = IP_PUNT; - if (!ip46_address_is_ip4 (&(prefix.fp_addr))) - { - prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); - } - ip_prefix_encode (&prefix, &mp->rule.ip.prefix); - - mp->rule.ip.swif = clib_host_to_net_u32 (swif); - - /* send it... */ - S (mp); - - /* Wait for a reply... */ - W (ret); - - return ret; -} - -static int -api_hicn_api_udp_punting_add (vat_main_t * vam) -{ - unformat_input_t *input = vam->input; - vl_api_hicn_api_punting_add_t *mp; - fib_prefix_t prefix; - u32 swif = ~0; - u16 sport = 0; - u16 dport = 0; - vl_api_address_family_t ip_version = ~0; - int ret; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "prefix %U/%d", unformat_ip46_address, - &prefix.fp_addr, IP46_TYPE_ANY, &prefix.fp_len)) - {; - } - else if (unformat (input, "sport %u", &sport)); - else if (unformat (input, "dport %u", &dport)); - else if (unformat (input, "ip4")) - { - ip_version = ADDRESS_IP4; - } - else if (unformat (input, "ip6")) - { - ip_version = ADDRESS_IP6; - } - else if (unformat (input, "intfc %d", &swif)) - {; - } - else - { - break; - } - } - - /* Check parse */ - if (((prefix.fp_addr.as_u64[0] == 0) && (prefix.fp_addr.as_u64[1] == 0)) - || (prefix.fp_len == 0)) - { - clib_warning ("Please specify prefix..."); - return 1; - } - - if (swif == ~0) - { - clib_warning ("Please specify interface..."); - return 1; - } - if (ip_version == ~0) - { - clib_warning ("Please specify ip version of the udp tunnel..."); - return 1; - } - /* Construct the API message */ - M (HICN_API_PUNTING_ADD, mp); - mp->type = UDP_PUNT; - if (!ip46_address_is_ip4 (&(prefix.fp_addr))) - { - prefix.fp_proto = fib_proto_from_ip46 (IP46_TYPE_IP6); - } - ip_prefix_encode (&prefix, &mp->rule.ip.prefix); - - mp->rule.udp.ip_version = ip_version; - - mp->rule.udp.swif = clib_host_to_net_u32 (swif); - mp->rule.udp.sport = clib_host_to_net_u16 (sport); - mp->rule.udp.sport = clib_host_to_net_u16 (dport); - - /* send it... */ - S (mp); - - /* Wait for a reply... */ - W (ret); - - return ret; -} - -static int -api_hicn_api_punting_add (vat_main_t * vam) -{ - unformat_input_t *input = vam->input; - u32 type = ~0; - int ret = 0; - - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "type %d", &type)) - {; - } - else - { - break; - } - } - - vam->input = input; - if (type == IP_PUNT) - ret = api_hicn_api_ip_punting_add (vam); - else if (type == UDP_PUNT) - ret = api_hicn_api_udp_punting_add (vam); - - return ret; -} - -static int -api_hicn_api_punting_del (vat_main_t * vam) -{ - return 0; -} - -static int api_hicn_api_register_prod_app (vat_main_t * vam) { unformat_input_t *input = vam->input; diff --git a/hicn-plugin/src/interest_hitcs.h b/hicn-plugin/src/interest_hitcs.h index 3588d4e08..c69564452 100644 --- a/hicn-plugin/src/interest_hitcs.h +++ b/hicn-plugin/src/interest_hitcs.h @@ -40,10 +40,10 @@ typedef struct typedef enum { - HICN_INTEREST_HITCS_NEXT_V4_LOOKUP, - HICN_INTEREST_HITCS_NEXT_V6_LOOKUP, + HICN_INTEREST_HITCS_NEXT_STRATEGY, HICN_INTEREST_HITCS_NEXT_PUSH, HICN_INTEREST_HITCS_NEXT_ERROR_DROP, + HICN_INTEREST_HITCS_NEXT_EMPTY, HICN_INTEREST_HITCS_N_NEXT, } hicn_interest_hitcs_next_t; diff --git a/hicn-plugin/src/interest_hitcs_node.c b/hicn-plugin/src/interest_hitcs_node.c index 14f512897..d10f15afa 100644 --- a/hicn-plugin/src/interest_hitcs_node.c +++ b/hicn-plugin/src/interest_hitcs_node.c @@ -172,9 +172,7 @@ hicn_interest_hitcs_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, dpo_vft0, &hicn_dpo_id0); stats.cs_expired_count++; /* Forward interest to the strategy node */ - next0 = - isv6 ? HICN_INTEREST_HITCS_NEXT_V6_LOOKUP : - HICN_INTEREST_HITCS_NEXT_V4_LOOKUP; + next0 = HICN_INTEREST_HITCS_NEXT_STRATEGY; } else { @@ -278,10 +276,10 @@ VLIB_REGISTER_NODE(hicn_interest_hitcs_node) = /* edit / add dispositions here */ .next_nodes = { - [HICN_INTEREST_HITCS_NEXT_V4_LOOKUP] = "ip4-lookup", - [HICN_INTEREST_HITCS_NEXT_V6_LOOKUP] = "ip6-lookup", + [HICN_INTEREST_HITCS_NEXT_STRATEGY] = "hicn-strategy", [HICN_INTEREST_HITCS_NEXT_PUSH] = "hicn-data-push", [HICN_INTEREST_HITCS_NEXT_ERROR_DROP] = "error-drop", + [HICN_INTEREST_HITCS_NEXT_EMPTY] = "ip6-lookup" }, }; /* *INDENT-ON* */ diff --git a/hicn-plugin/src/interest_hitpit.h b/hicn-plugin/src/interest_hitpit.h index 28427d342..fc4cfc3ea 100644 --- a/hicn-plugin/src/interest_hitpit.h +++ b/hicn-plugin/src/interest_hitpit.h @@ -41,8 +41,7 @@ typedef struct typedef enum { HICN_INTEREST_HITPIT_NEXT_INTEREST_HITCS, - HICN_INTEREST_HITPIT_NEXT_IP4_LOOKUP, - HICN_INTEREST_HITPIT_NEXT_IP6_LOOKUP, + HICN_INTEREST_HITPIT_NEXT_STRATEGY, HICN_INTEREST_HITPIT_NEXT_ERROR_DROP, HICN_INTEREST_HITPIT_N_NEXT, } hicn_interest_hitpit_next_t; diff --git a/hicn-plugin/src/interest_hitpit_node.c b/hicn-plugin/src/interest_hitpit_node.c index d5eeb20dd..a346dcc7e 100644 --- a/hicn-plugin/src/interest_hitpit_node.c +++ b/hicn-plugin/src/interest_hitpit_node.c @@ -150,9 +150,7 @@ hicn_interest_hitpit_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, hicn_pcs_delete (rt->pitcs, &pitp, &node0, vm, hash_entry0, dpo_vft0, &hicn_dpo_id0); stats.pit_expired_count++; - next0 = - isv6 ? HICN_INTEREST_HITPIT_NEXT_IP6_LOOKUP : - HICN_INTEREST_HITPIT_NEXT_IP4_LOOKUP; + next0 = HICN_INTEREST_HITPIT_NEXT_STRATEGY; } else { @@ -294,8 +292,7 @@ VLIB_REGISTER_NODE(hicn_interest_hitpit_node) = .next_nodes = { [HICN_INTEREST_HITPIT_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs", - [HICN_INTEREST_HITPIT_NEXT_IP4_LOOKUP] = "ip4-lookup", - [HICN_INTEREST_HITPIT_NEXT_IP6_LOOKUP] = "ip6-lookup", + [HICN_INTEREST_HITPIT_NEXT_STRATEGY] = "hicn-strategy", [HICN_INTEREST_HITPIT_NEXT_ERROR_DROP] = "error-drop", }, }; diff --git a/hicn-plugin/src/interest_pcslookup.h b/hicn-plugin/src/interest_pcslookup.h index e27673a9e..5a5a6a7a8 100644 --- a/hicn-plugin/src/interest_pcslookup.h +++ b/hicn-plugin/src/interest_pcslookup.h @@ -40,8 +40,7 @@ typedef struct typedef enum { - HICN_INTEREST_PCSLOOKUP_NEXT_V4_LOOKUP, - HICN_INTEREST_PCSLOOKUP_NEXT_V6_LOOKUP, + HICN_INTEREST_PCSLOOKUP_NEXT_STRATEGY, HICN_INTEREST_PCSLOOKUP_NEXT_INTEREST_HITPIT, HICN_INTEREST_PCSLOOKUP_NEXT_INTEREST_HITCS, HICN_INTEREST_PCSLOOKUP_NEXT_ERROR_DROP, diff --git a/hicn-plugin/src/interest_pcslookup_node.c b/hicn-plugin/src/interest_pcslookup_node.c index 40d62510b..6ac2aa3a0 100644 --- a/hicn-plugin/src/interest_pcslookup_node.c +++ b/hicn-plugin/src/interest_pcslookup_node.c @@ -85,7 +85,7 @@ hicn_interest_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, hicn_name_t name; hicn_header_t *hicn0; u32 node_id0 = 0; - u8 dpo_ctx_id0 = 0; + index_t dpo_ctx_id0 = 0; u8 vft_id0 = 0; u8 is_cs0 = 0; u8 hash_entry_id = 0; @@ -113,9 +113,7 @@ hicn_interest_pcslookup_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, if (PREDICT_TRUE (ret == HICN_ERROR_NONE)) { - next0 = - isv6 ? HICN_INTEREST_PCSLOOKUP_NEXT_V6_LOOKUP : - HICN_INTEREST_PCSLOOKUP_NEXT_V4_LOOKUP; + next0 = HICN_INTEREST_PCSLOOKUP_NEXT_STRATEGY; } nameptr = (u8 *) (&name); stats.pkts_processed++; @@ -224,8 +222,7 @@ VLIB_REGISTER_NODE(hicn_interest_pcslookup_node) = .n_next_nodes = HICN_INTEREST_PCSLOOKUP_N_NEXT, .next_nodes = { - [HICN_INTEREST_PCSLOOKUP_NEXT_V4_LOOKUP] = "ip4-lookup", - [HICN_INTEREST_PCSLOOKUP_NEXT_V6_LOOKUP] = "ip6-lookup", + [HICN_INTEREST_PCSLOOKUP_NEXT_STRATEGY] = "hicn-strategy", [HICN_INTEREST_PCSLOOKUP_NEXT_INTEREST_HITPIT] = "hicn-interest-hitpit", [HICN_INTEREST_PCSLOOKUP_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs", [HICN_INTEREST_PCSLOOKUP_NEXT_ERROR_DROP] = "error-drop", diff --git a/hicn-plugin/src/mapme_ack_node.c b/hicn-plugin/src/mapme_ack_node.c index ebb12a124..557fb0ad7 100644 --- a/hicn-plugin/src/mapme_ack_node.c +++ b/hicn-plugin/src/mapme_ack_node.c @@ -79,9 +79,8 @@ hicn_mapme_process_ack (vlib_main_t * vm, vlib_buffer_t * b, /* We are only expecting ACKs for hICN DPOs */ ASSERT (dpo_is_hicn (dpo)); - const hicn_dpo_vft_t *dpo_vft = hicn_dpo_get_vft (dpo->dpoi_type); hicn_mapme_tfib_t *tfib = - TFIB (dpo_vft->hicn_dpo_get_ctx (dpo->dpoi_index)); + TFIB (hicn_strategy_dpo_ctx_get (dpo->dpoi_index)); if (tfib == NULL) { @@ -107,11 +106,12 @@ hicn_mapme_process_ack (vlib_main_t * vm, vlib_buffer_t * b, * Is the ingress face in TFIB ? if so, remove it, otherwise it might be a * duplicate */ - retx_t *retx = - vlib_process_signal_event_data (vm, - hicn_mapme_eventmgr_process_node.index, - HICN_MAPME_EVENT_FACE_PH_DEL, 1, - sizeof (retx_t)); + retx_t *retx = vlib_process_signal_event_data (vm, + hicn_mapme_eventmgr_process_node. + index, + HICN_MAPME_EVENT_FACE_PH_DEL, + 1, + sizeof (retx_t)); *retx = (retx_t) { .prefix = prefix,.dpo = *dpo}; diff --git a/hicn-plugin/src/mapme_ctrl_node.c b/hicn-plugin/src/mapme_ctrl_node.c index cef3d0944..ed25a31b0 100644 --- a/hicn-plugin/src/mapme_ctrl_node.c +++ b/hicn-plugin/src/mapme_ctrl_node.c @@ -27,6 +27,7 @@ #include "parser.h" #include "infra.h" #include "strategy_dpo_manager.h" +#include "strategy_dpo_ctx.h" #include "error.h" #include "state.h" @@ -93,7 +94,7 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b, /* if (params.seq == INVALID_SEQ) */ /* { */ /* vlib_log_warn (mapme_main.log_class, */ - /* "Invalid sequence number found in IU"); */ + /* "Invalid sequence number found in IU"); */ /* return true; */ /* } */ @@ -129,9 +130,8 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b, #endif /* Process the hICN DPO */ - const hicn_dpo_vft_t *dpo_vft = hicn_dpo_get_vft (dpo->dpoi_type); hicn_mapme_tfib_t *tfib = - TFIB (dpo_vft->hicn_dpo_get_ctx (dpo->dpoi_index)); + TFIB (hicn_strategy_dpo_ctx_get (dpo->dpoi_index)); if (tfib == NULL) { @@ -163,7 +163,9 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b, tfib->entry_count = 0; break; } - DEBUG ("Adding nexthop to the tfib, dpo index in_face %d, dpo index tfib %d", in_face->dpoi_index, tfib->next_hops[pos].dpoi_index); + DEBUG + ("Adding nexthop to the tfib, dpo index in_face %d, dpo index tfib %d", + in_face->dpoi_index, tfib->next_hops[pos].dpoi_index); hicn_mapme_tfib_add (tfib, &tfib->next_hops[pos]); } @@ -173,7 +175,8 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b, /* We transmit both the prefix and the full dpo (type will be needed to pick the right transmit node */ retx_t *retx = vlib_process_signal_event_data (vm, - hicn_mapme_eventmgr_process_node.index, + hicn_mapme_eventmgr_process_node. + index, HICN_MAPME_EVENT_FACE_NH_SET, 1, sizeof (retx_t)); @@ -195,7 +198,8 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b, /* Multipath, multihoming, multiple producers or duplicate interest */ retx_t *retx = vlib_process_signal_event_data (vm, - hicn_mapme_eventmgr_process_node.index, + hicn_mapme_eventmgr_process_node. + index, HICN_MAPME_EVENT_FACE_NH_ADD, 1, sizeof (retx_t)); @@ -212,7 +216,8 @@ hicn_mapme_process_ctrl (vlib_main_t * vm, vlib_buffer_t * b, hicn_mapme_tfib_add (tfib, in_face); retx_t *retx = vlib_process_signal_event_data (vm, - hicn_mapme_eventmgr_process_node.index, + hicn_mapme_eventmgr_process_node. + index, HICN_MAPME_EVENT_FACE_PH_ADD, 1, sizeof (retx_t)); @@ -277,7 +282,7 @@ hicn_mapme_ctrl_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, preprocess_in_face (hb->type, &hb->face_dpo_id, &in_face); hicn_mapme_process_ctrl (vm, b0, &in_face); - vnet_buffer (b0)->ip.adj_index[VLIB_TX] = in_face.dpoi_index; + vnet_buffer (b0)->ip.adj_index[VLIB_TX] = in_face.dpoi_index; vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, bi0, next0); diff --git a/hicn-plugin/src/mapme_eventmgr.c b/hicn-plugin/src/mapme_eventmgr.c index ef73f9550..5a9e7967e 100644 --- a/hicn-plugin/src/mapme_eventmgr.c +++ b/hicn-plugin/src/mapme_eventmgr.c @@ -261,12 +261,11 @@ hicn_mapme_send_message (vlib_main_t * vm, const hicn_prefix_t * prefix, vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) node_name); u32 node_index = node->index; - u8 *buffer = - get_packet_buffer (vm, node_index, face->dpoi_index, - (ip46_address_t *) prefix, - (params->protocol == - IPPROTO_IPV6) ? HICN_TYPE_IPV6_ICMP : - HICN_TYPE_IPV4_ICMP); + u8 *buffer = get_packet_buffer (vm, node_index, face->dpoi_index, + (ip46_address_t *) prefix, + (params->protocol == + IPPROTO_IPV6) ? HICN_TYPE_IPV6_ICMP : + HICN_TYPE_IPV4_ICMP); n = hicn_mapme_create_packet (buffer, prefix, params); if (n <= 0) { @@ -281,8 +280,7 @@ static_always_inline void hicn_mapme_send_updates (vlib_main_t * vm, hicn_prefix_t * prefix, dpo_id_t dpo, bool send_all) { - const hicn_dpo_vft_t *dpo_vft = hicn_dpo_get_vft (dpo.dpoi_type); - hicn_mapme_tfib_t *tfib = TFIB (dpo_vft->hicn_dpo_get_ctx (dpo.dpoi_index)); + hicn_mapme_tfib_t *tfib = TFIB (hicn_strategy_dpo_ctx_get (dpo.dpoi_index)); if (!tfib) { DEBUG ("NULL TFIB entry id=%d", dpo.dpoi_index); @@ -323,7 +321,7 @@ hicn_mapme_eventmgr_process (vlib_main_t * vm, u8 idle = 0; retx_t retx_array[NUM_RETX_SLOT][NUM_RETX_ENTRIES]; - memset(retx_array, 0, NUM_RETX_SLOT*NUM_RETX_ENTRIES); + memset (retx_array, 0, NUM_RETX_SLOT * NUM_RETX_ENTRIES); u8 retx_len[NUM_RETX_SLOT] = { 0 }; u8 cur = 0; /* current slot */ @@ -500,10 +498,8 @@ hicn_mapme_eventmgr_process (vlib_main_t * vm, if (retx->dpo.dpoi_index == ~0) /* deleted entry */ continue; - const hicn_dpo_vft_t *dpo_vft = - hicn_dpo_get_vft (retx->dpo.dpoi_type); hicn_mapme_tfib_t *tfib = - TFIB (dpo_vft->hicn_dpo_get_ctx (retx->dpo.dpoi_index)); + TFIB (hicn_strategy_dpo_ctx_get (retx->dpo.dpoi_index)); if (!tfib) { DEBUG ("NULL TFIB entry for dpoi_index=%d", @@ -517,16 +513,16 @@ hicn_mapme_eventmgr_process (vlib_main_t * vm, // If we exceed the numver of retransmittion it means that all tfib entries have seens at least HICN_PARAM_RTX_MAX of retransmission if (retx->rtx_count < HICN_PARAM_RTX_MAX) { - /* - * We did some retransmissions, so let's reschedule a check in the - * next slot - */ + /* + * We did some retransmissions, so let's reschedule a check in the + * next slot + */ NXT[NXTLEN++] = CUR[pos]; idle = 0; } else { - hicn_mapme_tfib_clear(tfib); + hicn_mapme_tfib_clear (tfib); } } diff --git a/hicn-plugin/src/mgmt.h b/hicn-plugin/src/mgmt.h index 08b1de089..326922a01 100644 --- a/hicn-plugin/src/mgmt.h +++ b/hicn-plugin/src/mgmt.h @@ -45,16 +45,6 @@ typedef enum HICN_MGMT_FACE_OP_HELLO, } hicn_mgmt_face_op_e; - -typedef enum -{ - HICN_MGMT_PUNTING_OP_NONE = 0, - HICN_MGMT_PUNTING_OP_CREATE, - HICN_MGMT_PUNTING_OP_DELETE, - HICN_MGMT_PUNTING_OP_ENABLE, - HICN_MGMT_PUNTING_OP_DISABLE -} hicn_mgmt_punting_op_e; - typedef enum { HICN_MGMT_MAPME_OP_NONE = 0, diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h index d9c48954e..fc63bd0a6 100644 --- a/hicn-plugin/src/pcs.h +++ b/hicn-plugin/src/pcs.h @@ -174,7 +174,8 @@ hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs, always_inline void hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, - hicn_pcs_entry_t * old_entry, hicn_pcs_entry_t * entry, hicn_hash_node_t * node); + hicn_pcs_entry_t * old_entry, hicn_pcs_entry_t * entry, + hicn_hash_node_t * node); always_inline void hicn_pcs_cs_delete (vlib_main_t * vm, hicn_pit_cs_t * pitcs, @@ -186,24 +187,24 @@ always_inline int hicn_pcs_cs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hashval, - u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, - u8 * hash_entry_id, u32 * bucket_id, + u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id, + u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow); always_inline int hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hashval, - u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, + u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow, dpo_id_t * inface); always_inline int hicn_pcs_pit_insert (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, - u64 hashval, u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, - u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, - u8 * bucket_is_overflow); + u64 hashval, u32 * node_id, index_t * dpo_ctx_id, + u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, + u32 * bucket_id, u8 * bucket_is_overflow); always_inline void hicn_pcs_pit_delete (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t ** pcs_entryp, @@ -215,8 +216,9 @@ always_inline int hicn_pcs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hashval, u32 * node_id, - u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, - u32 * bucket_id, u8 * bucket_is_overflow); + index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, + u8 * hash_entry_id, u32 * bucket_id, + u8 * bucket_is_overflow); always_inline void hicn_pcs_delete (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t ** pcs_entryp, @@ -365,7 +367,7 @@ hicn_pcs_delete_internal (hicn_pit_cs_t * pitcs, else { pitcs->pcs_pit_dealloc++; - dpo_vft->hicn_dpo_unlock_dpo_ctx (hicn_dpo_id); + hicn_strategy_dpo_ctx_unlock (hicn_dpo_id); /* Flush faces */ hicn_faces_flush (&(pcs->u.pit.faces)); @@ -391,7 +393,7 @@ hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs, * hash entry. */ pitcs->pcs_pit_count--; - dpo_vft->hicn_dpo_unlock_dpo_ctx (hicn_dpo_id); + hicn_strategy_dpo_ctx_unlock (hicn_dpo_id); /* Flush faces */ hicn_faces_flush (&(pcs_entry->u.pit.faces)); @@ -448,7 +450,8 @@ hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs, always_inline void hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, - hicn_pcs_entry_t * old_entry, hicn_pcs_entry_t * entry, hicn_hash_node_t * node) + hicn_pcs_entry_t * old_entry, hicn_pcs_entry_t * entry, + hicn_hash_node_t * node) { hicn_cs_policy_t *policy_state; hicn_cs_policy_vft_t *policy_vft; @@ -468,48 +471,48 @@ hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, } } - if (dpo_cmp(&entry->u.cs.cs_rxface, &old_entry->u.cs.cs_rxface) !=0) + if (dpo_cmp (&entry->u.cs.cs_rxface, &old_entry->u.cs.cs_rxface) != 0) { /* Dequeue content from the old queue */ - policy_vft->hicn_cs_dequeue(pitcs, node, old_entry, policy_state); + policy_vft->hicn_cs_dequeue (pitcs, node, old_entry, policy_state); - dpo_copy(&old_entry->u.cs.cs_rxface, &entry->u.cs.cs_rxface); + dpo_copy (&old_entry->u.cs.cs_rxface, &entry->u.cs.cs_rxface); face_dpo = (dpo_id_t *) & (old_entry->u.cs.cs_rxface); policy_state = &pitcs->policy_state; policy_vft = &pitcs->policy_vft; if (face_dpo->dpoi_type == hicn_face_ip_type) - { - hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index); - if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) - { - hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data; - policy_state = &prod_face->policy; - policy_vft = &prod_face->policy_vft; - } - } + { + hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index); + if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) + { + hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data; + policy_state = &prod_face->policy; + policy_vft = &prod_face->policy_vft; + } + } policy_vft->hicn_cs_insert (pitcs, node, old_entry, policy_state); if (policy_state->count > policy_state->max) - { - hicn_hash_node_t *node; - hicn_pcs_entry_t *pcs_entry; - hicn_hash_entry_t *hash_entry; - policy_vft->hicn_cs_delete_get (pitcs, policy_state, - &node, &pcs_entry, &hash_entry); - - /* - * We don't have to decrease the lock (therefore we cannot - * use hicn_pcs_cs_delete function) - */ - policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state); - - hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm); - - /* Update the global CS counter */ - pitcs->pcs_cs_count--; - } + { + hicn_hash_node_t *node; + hicn_pcs_entry_t *pcs_entry; + hicn_hash_entry_t *hash_entry; + policy_vft->hicn_cs_delete_get (pitcs, policy_state, + &node, &pcs_entry, &hash_entry); + + /* + * We don't have to decrease the lock (therefore we cannot + * use hicn_pcs_cs_delete function) + */ + policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state); + + hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm); + + /* Update the global CS counter */ + pitcs->pcs_cs_count--; + } } else /* Update the CS LRU, moving this item to the head */ @@ -565,8 +568,8 @@ always_inline int hicn_pcs_cs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hashval, - u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, - u8 * hash_entry_id, u32 * bucket_id, + u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id, + u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow) { ASSERT (entry == hicn_hashtb_node_data (node)); @@ -611,16 +614,16 @@ hicn_pcs_cs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs, policy_vft->hicn_cs_delete_get (pitcs, policy_state, &node, &pcs_entry, &hash_entry); - /* - * We don't have to decrease the lock (therefore we cannot - * use hicn_pcs_cs_delete function) - */ - policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state); + /* + * We don't have to decrease the lock (therefore we cannot + * use hicn_pcs_cs_delete function) + */ + policy_vft->hicn_cs_dequeue (pitcs, node, pcs_entry, policy_state); - hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm); + hicn_cs_delete_trimmed (pitcs, &pcs_entry, hash_entry, &node, vm); - /* Update the global CS counter */ - pitcs->pcs_cs_count--; + /* Update the global CS counter */ + pitcs->pcs_cs_count--; } } return ret; @@ -634,7 +637,7 @@ always_inline int hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hashval, - u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, + u32 * node_id, index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow, dpo_id_t * inface) { @@ -677,9 +680,9 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, always_inline int hicn_pcs_pit_insert (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, - u64 hashval, u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, - u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, - u8 * bucket_is_overflow) + u64 hashval, u32 * node_id, index_t * dpo_ctx_id, + u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, + u32 * bucket_id, u8 * bucket_is_overflow) { ASSERT (entry == hicn_hashtb_node_data (node)); @@ -724,8 +727,8 @@ always_inline int hicn_pcs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, hicn_hash_node_t * node, hicn_hash_entry_t ** hash_entry, u64 hashval, u32 * node_id, - u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, - u32 * bucket_id, u8 * bucket_is_overflow) + index_t * dpo_ctx_id, u8 * vft_id, u8 * is_cs, + u8 * hash_entry_id, u32 * bucket_id, u8 * bucket_is_overflow) { int ret; diff --git a/hicn-plugin/src/pg.c b/hicn-plugin/src/pg.c index 8181d865e..9938e85ba 100644 --- a/hicn-plugin/src/pg.c +++ b/hicn-plugin/src/pg.c @@ -57,8 +57,6 @@ typedef enum { HICNPG_INTEREST_NEXT_V4_LOOKUP, HICNPG_INTEREST_NEXT_V6_LOOKUP, - HICNPG_INTEREST_NEXT_IFACE_IP4_INPUT, - HICNPG_INTEREST_NEXT_IFACE_IP6_INPUT, HICNPG_INTEREST_NEXT_DROP, HICNPG_N_NEXT, } hicnpg_interest_next_t; @@ -79,12 +77,11 @@ hicnpg_main_t hicnpg_main = { .interest_lifetime = 4, .n_flows = (u32) 0, .n_ifaces = (u32) 1, - .hicn_underneath = 0 + .sw_if = (u32) 0 }; hicnpg_server_main_t hicnpg_server_main = { .node_index = 0, - .hicn_underneath = 0 }; /* packet trace format function */ @@ -193,6 +190,8 @@ hicnpg_client_interest_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; + vnet_buffer (b0)->sw_if_index[VLIB_RX] = hpgm->sw_if; + vnet_buffer (b1)->sw_if_index[VLIB_RX] = hpgm->sw_if; /* Check icn packets, locate names */ if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0, &isv6_0) @@ -225,7 +224,6 @@ hicnpg_client_interest_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP : HICNPG_INTEREST_NEXT_V4_LOOKUP; - next0 += 2 * hpgm->hicn_underneath; } if (hicn_interest_parse_pkt (b1, &name1, &namelen1, &hicn1, &isv6_1) == HICN_ERROR_NONE) @@ -257,7 +255,6 @@ hicnpg_client_interest_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, next1 = isv6_1 ? HICNPG_INTEREST_NEXT_V6_LOOKUP : HICNPG_INTEREST_NEXT_V4_LOOKUP; - next1 += 2 * hpgm->hicn_underneath; } /* Send pkt to next node */ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0; @@ -320,6 +317,7 @@ hicnpg_client_interest_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, b0 = vlib_get_buffer (vm, bi0); sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; + vnet_buffer (b0)->sw_if_index[VLIB_RX] = hpgm->sw_if; /* Check icn packets, locate names */ if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0, &isv6_0) @@ -353,7 +351,6 @@ hicnpg_client_interest_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, next0 = isv6_0 ? HICNPG_INTEREST_NEXT_V6_LOOKUP : HICNPG_INTEREST_NEXT_V4_LOOKUP; - next0 += 2 * hpgm->hicn_underneath; } /* Send pkt to ip lookup */ vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0; @@ -407,7 +404,7 @@ hicn_rewrite_interestv4 (vlib_main_t * vm, vlib_buffer_t * b0, u32 seq_number, .ip4 = hicnpg_main.pgen_clt_src_addr.ip4, }; hicn_name_t dst_name = { - .ip4.prefix_as_ip4 = hicnpg_main.pgen_clt_hicn_name.ip4, + .ip4.prefix_as_ip4 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip4, .ip4.suffix = seq_number, }; @@ -453,7 +450,7 @@ hicn_rewrite_interestv6 (vlib_main_t * vm, vlib_buffer_t * b0, u32 seq_number, .ip6 = hicnpg_main.pgen_clt_src_addr.ip6, }; hicn_name_t dst_name = { - .ip6.prefix_as_ip6 = hicnpg_main.pgen_clt_hicn_name.ip6, + .ip6.prefix_as_ip6 = hicnpg_main.pgen_clt_hicn_name->fp_addr.ip6, .ip6.suffix = seq_number, }; src_addr.ip6.as_u32[3] += clib_host_to_net_u32 (iface); @@ -559,8 +556,6 @@ VLIB_REGISTER_NODE(hicn_pg_interest_node) ={ { [HICNPG_INTEREST_NEXT_V4_LOOKUP] = "ip4-lookup", [HICNPG_INTEREST_NEXT_V6_LOOKUP] = "ip6-lookup", - [HICNPG_INTEREST_NEXT_IFACE_IP4_INPUT] = "hicn-iface-ip4-input", - [HICNPG_INTEREST_NEXT_IFACE_IP6_INPUT] = "hicn-iface-ip6-input", [HICNPG_INTEREST_NEXT_DROP] = "error-drop" }, }; @@ -573,6 +568,8 @@ VLIB_REGISTER_NODE(hicn_pg_interest_node) ={ typedef enum { HICNPG_DATA_NEXT_DROP, + HICNPG_DATA_NEXT_LOOKUP4, + HICNPG_DATA_NEXT_LOOKUP6, HICNPG_DATA_N_NEXT, } hicnpg_data_next_t; @@ -600,6 +597,93 @@ format_hicnpg_data_trace (u8 * s, va_list * args) } +static_always_inline int +match_ip4_name (u32 * name, fib_prefix_t * prefix) +{ + u32 xor = 0; + + xor = *name & prefix->fp_addr.ip4.data_u32; + + return xor == prefix->fp_addr.ip4.data_u32; +} + +static_always_inline int +match_ip6_name (u8 * name, fib_prefix_t * prefix) +{ + union + { + u32x4 as_u32x4; + u64 as_u64[2]; + u32 as_u32[4]; + } xor_sum __attribute__ ((aligned (sizeof (u32x4)))); + + xor_sum.as_u64[0] = ((u64 *) name)[0] & prefix->fp_addr.ip6.as_u64[0]; + xor_sum.as_u64[1] = ((u64 *) name)[1] & prefix->fp_addr.ip6.as_u64[1]; + + return (xor_sum.as_u64[0] == prefix->fp_addr.ip6.as_u64[0]) && + (xor_sum.as_u64[1] == prefix->fp_addr.ip6.as_u64[1]); +} + + +/* + * Return 0,1,2. + * 0 matches + * 1 does not match and the prefix is ip4 + * 2 does not match and the prefix is ip6 + */ +static_always_inline u32 +match_data (vlib_buffer_t * b, fib_prefix_t * prefix) +{ + u8 *ptr = vlib_buffer_get_current (b); + u8 v = *ptr & 0xf0; + u32 next = 0; + + if (PREDICT_TRUE (v == 0x40 && ip46_address_is_ip4 (&prefix->fp_addr))) + { + if (!match_ip4_name ((u32 *) & (ptr[12]), prefix)) + next = 1; + } + else + if (PREDICT_TRUE (v == 0x60 && !ip46_address_is_ip4 (&prefix->fp_addr))) + { + if (!match_ip6_name (&(ptr[8]), prefix)) + next = 2; + } + + return next; +} + +/* + * Return 0,1,2. + * 0 matches + * 1 does not match and the prefix is ip4 + * 2 does not match and the prefix is ip6 + */ +static_always_inline u32 +match_interest (vlib_buffer_t * b, fib_prefix_t * prefix) +{ + u8 *ptr = vlib_buffer_get_current (b); + u8 v = *ptr & 0xf0; + u32 next = 0; + + if (PREDICT_TRUE (v == 0x40 && ip46_address_is_ip4 (&prefix->fp_addr))) + { + if (!match_ip4_name ((u32 *) & (ptr[16]), prefix)) + next = 1; + } + else + if (PREDICT_TRUE (v == 0x60 && !ip46_address_is_ip4 (&prefix->fp_addr))) + { + if (!match_ip6_name (&(ptr[24]), prefix)) + next = 2; + } + + return next; +} + + + + /* * Node function for the icn packet-generator client. The goal here is to * manipulate/tweak a stream of packets that have been injected by the vpp @@ -617,6 +701,7 @@ hicnpg_client_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_buffer_t *b0, *b1; u8 pkt_type0 = 0, pkt_type1 = 0; u16 msg_type0 = 1, msg_type1 = 1; + hicnpg_main_t *hpgm = &hicnpg_main; from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -664,8 +749,33 @@ hicnpg_client_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; - /* Increment a counter */ - content_msgs_received += 2; + next0 = + HICNPG_DATA_NEXT_DROP + match_data (b0, hpgm->pgen_clt_hicn_name); + next1 = + HICNPG_DATA_NEXT_DROP + match_data (b1, hpgm->pgen_clt_hicn_name); + + if (PREDICT_FALSE (vnet_get_feature_count + (vnet_buffer (b0)->feature_arc_index, + vnet_buffer (b0)->sw_if_index[VLIB_RX]) > 1)) + vnet_feature_next (&next0, b0); + + if (PREDICT_FALSE (vnet_get_feature_count + (vnet_buffer (b1)->feature_arc_index, + vnet_buffer (b1)->sw_if_index[VLIB_RX]) > 1)) + vnet_feature_next (&next1, b1); + + + if (next0 == HICNPG_DATA_NEXT_DROP) + { + /* Increment a counter */ + content_msgs_received++; + } + + if (next1 == HICNPG_DATA_NEXT_DROP) + { + /* Increment a counter */ + content_msgs_received++; + } if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE))) { @@ -688,6 +798,10 @@ hicnpg_client_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, t->next_index = next1; } } + + vlib_validate_buffer_enqueue_x2 (vm, node, next_index, + to_next, n_left_to_next, + bi0, bi1, next0, next1); pkts_processed += 2; } @@ -708,8 +822,19 @@ hicnpg_client_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; - /* Increment a counter */ - content_msgs_received++; + next0 = + HICNPG_DATA_NEXT_DROP + match_data (b0, hpgm->pgen_clt_hicn_name); + + if (PREDICT_FALSE (vnet_get_feature_count + (vnet_buffer (b0)->feature_arc_index, + vnet_buffer (b0)->sw_if_index[VLIB_RX]) > 1)) + vnet_feature_next (&next0, b0); + + if (next0 == HICNPG_DATA_NEXT_DROP) + { + /* Increment a counter */ + content_msgs_received++; + } if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && (b0->flags & VLIB_BUFFER_IS_TRACED))) @@ -721,6 +846,10 @@ hicnpg_client_data_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, t->sw_if_index = sw_if_index0; t->next_index = next0; } + + vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, + n_left_to_next, bi0, next0); + pkts_processed++; } vlib_put_next_frame (vm, node, next_index, n_left_to_next); @@ -747,11 +876,33 @@ VLIB_REGISTER_NODE(hicn_pg_data_node) = .n_next_nodes = HICNPG_DATA_N_NEXT, .next_nodes = { - [HICNPG_DATA_NEXT_DROP] = "error-drop" + [HICNPG_DATA_NEXT_DROP] = "error-drop", + [HICNPG_DATA_NEXT_LOOKUP4] = "ip4-lookup", + [HICNPG_DATA_NEXT_LOOKUP6] = "ip6-lookup", }, }; /* *INDENT-ON* */ +/* *INDENT-OFF* */ +VNET_FEATURE_INIT(hicn_data_input_ip4_arc, static)= + { + .arc_name = "ip4-unicast", + .node_name = "hicnpg-data", + .runs_before = VNET_FEATURES("ip4-inacl"), + }; +/* *INDENT-ON* */ + + +/* *INDENT-OFF* */ +VNET_FEATURE_INIT(hicn_data_input_ip6_arc, static)= + { + .arc_name = "ip6-unicast", + .node_name = "hicnpg-data", + .runs_before = VNET_FEATURES("ip6-inacl"), + }; +/* *INDENT-ON* */ + + /* * End of packet-generator client node */ @@ -790,8 +941,6 @@ typedef enum { HICNPG_SERVER_NEXT_V4_LOOKUP, HICNPG_SERVER_NEXT_V6_LOOKUP, - HICNPG_SERVER_NEXT_FACE_IP4_INPUT, - HICNPG_SERVER_NEXT_FACE_IP6_INPUT, HICNPG_SERVER_NEXT_DROP, HICNPG_SERVER_N_NEXT, } icnpg_server_next_t; @@ -892,8 +1041,19 @@ hicnpg_node_server_fn (vlib_main_t * vm, sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX]; - if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0, &isv6_0) - == HICN_ERROR_NONE) + vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0; + vnet_buffer (b1)->sw_if_index[VLIB_TX] = ~0; + + u32 match0 = match_interest (b0, hpgsm->pgen_srv_hicn_name); + u32 match1 = match_interest (b1, hpgsm->pgen_srv_hicn_name); + + if (match0) + { + next0 = match0 - 1; + } + else + if (hicn_interest_parse_pkt + (b0, &name0, &namelen0, &hicn0, &isv6_0) == HICN_ERROR_NONE) { /* this node grabs only interests */ vlib_buffer_t *rb = NULL; @@ -906,11 +1066,15 @@ hicnpg_node_server_fn (vlib_main_t * vm, next0 = isv6_0 ? HICNPG_SERVER_NEXT_V6_LOOKUP : HICNPG_SERVER_NEXT_V4_LOOKUP; - /* if hicn_underneath ,the following will results as next0 = HICNPG_SERVER_NEXT_DATA_LOOKUP */ - next0 += 2 * hpgsm->hicn_underneath; } - if (hicn_interest_parse_pkt (b1, &name1, &namelen1, &hicn1, &isv6_1) - == HICN_ERROR_NONE) + + if (match1) + { + next1 = match1 - 1; + } + else + if (hicn_interest_parse_pkt + (b1, &name1, &namelen1, &hicn1, &isv6_1) == HICN_ERROR_NONE) { /* this node grabs only interests */ vlib_buffer_t *rb = NULL; @@ -923,8 +1087,6 @@ hicnpg_node_server_fn (vlib_main_t * vm, next1 = isv6_1 ? HICNPG_SERVER_NEXT_V6_LOOKUP : HICNPG_SERVER_NEXT_V4_LOOKUP; - /* if hicn_underneath ,the following will results as next0 = HICNPG_SERVER_NEXT_DATA_LOOKUP */ - next1 += 2 * hpgsm->hicn_underneath; } pkts_processed += 2; @@ -983,10 +1145,17 @@ hicnpg_node_server_fn (vlib_main_t * vm, b0 = vlib_get_buffer (vm, bi0); sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX]; + vnet_buffer (b0)->sw_if_index[VLIB_TX] = ~0; + u32 match0 = match_interest (b0, hpgsm->pgen_srv_hicn_name); - if (hicn_interest_parse_pkt (b0, &name0, &namelen0, &hicn0, &isv6_0) - == HICN_ERROR_NONE) + if (match0) + { + next0 = match0 - 1; + } + else + if (hicn_interest_parse_pkt + (b0, &name0, &namelen0, &hicn0, &isv6_0) == HICN_ERROR_NONE) { /* this node grabs only interests */ vlib_buffer_t *rb = NULL; @@ -999,8 +1168,6 @@ hicnpg_node_server_fn (vlib_main_t * vm, next0 = isv6_0 ? HICNPG_SERVER_NEXT_V6_LOOKUP : HICNPG_SERVER_NEXT_V4_LOOKUP; - /* if hicn_underneath ,the following will results as next0 = HICNPG_SERVER_NEXT_DATA_LOOKUP */ - next0 += 2 * hpgsm->hicn_underneath; } if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && (b0->flags & VLIB_BUFFER_IS_TRACED))) @@ -1122,16 +1289,32 @@ VLIB_REGISTER_NODE(hicn_pg_server_node) = .n_next_nodes = HICNPG_SERVER_N_NEXT, /* edit / add dispositions here */ .next_nodes = - { + { [HICNPG_SERVER_NEXT_V4_LOOKUP] = "ip4-lookup", [HICNPG_SERVER_NEXT_V6_LOOKUP] = "ip6-lookup", - [HICNPG_SERVER_NEXT_FACE_IP4_INPUT] = "hicn-face-ip4-input", - [HICNPG_SERVER_NEXT_FACE_IP6_INPUT] = "hicn-face-ip6-input", [HICNPG_SERVER_NEXT_DROP] = "error-drop", }, }; /* *INDENT-ON* */ +/* *INDENT-OFF* */ +VNET_FEATURE_INIT(hicn_pg_server_ip6, static)= + { + .arc_name = "ip6-unicast", + .node_name = "hicnpg-server", + .runs_before = VNET_FEATURES("ip6-inacl"), + }; +/* *INDENT-ON* */ + +/* *INDENT-OFF* */ +VNET_FEATURE_INIT(hicn_pg_server_ip4, static)= + { + .arc_name = "ip4-unicast", + .node_name = "hicnpg-server", + .runs_before = VNET_FEATURES("ip4-inacl"), + }; +/* *INDENT-ON* */ + /* * End of packet-generator server node */ diff --git a/hicn-plugin/src/pg.h b/hicn-plugin/src/pg.h index 083afb6b3..9ec3eeabc 100644 --- a/hicn-plugin/src/pg.h +++ b/hicn-plugin/src/pg.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -16,35 +16,80 @@ #ifndef __HICN_PG_H__ #define __HICN_PG_H__ -/* Subnet-mask for punting data in the client node */ -#define SUBNET_MASK4 32 -#define SUBNET_MASK6 128 +/** + * @File Packet generator for hICN + * + * The packet generator is made of two entities, a client and a server. + * The client issues interests at high speed and the server satisfy each + * interest it receives with the corresponding data. + * The packet generator is made of three nodes: + * - hicnpg-interest that receives packets from a packet generator interface + * and manipulate them to generate interests based on the given configuration. + * This node runs at the client side. + * - hicnpg-data that receives data packets at the client side and counts them. + * This is useful for statistics. The "show err" command will give the number + * of interest issued and data received at the client side + * - hicnpg-server that recevies and interest and replies with the corresponding + * data. The data is generated from the interest switching the src and destination + * address in the packet and appending a payload to the packet. + * + * + * These three nodes are inserted in the vlib graph in the following manner: + * - hicnpg-interest is added as a possible next node of the pg-input node. The packet + * generator stream then specifies it as next node. + * - hicnpg-data is added as next hop of the ip4/6-unicast node exploiting the corresponding + * feature and it runs before the ip4/6-inacl node. In this way, every packet that is + * received through an interface on which this feature is enabled is sent to this node. + * - hicnpg-server is added as next hop of the ip4/6-unicast using the corresponding + * feature and it runs before the ip4/6-inacl node. In this way, every packet that is + * received through an interface on which this feature is enabled is sent to this node. + * + * An example of how to use the pg for hicn is available in the documentation. + */ + +/** + * @brief hICN packet generator main for the pg client nodes + * + * It stores the configuration and make it availables to the pg client nodes. + */ typedef struct hicnpg_main_s { - u32 index; - u32 index_ifaces; - u32 max_seq_number; - u32 n_flows; - u32 n_ifaces; - u32 hicn_underneath; - ip46_address_t pgen_clt_src_addr; - ip46_address_t pgen_clt_hicn_name; - u16 interest_lifetime; + u32 index; //used to compute the sequence number + fib_prefix_t *pgen_clt_hicn_name; //hICN name to put in the destiantion addess of an interest + u32 index_ifaces; /* used to mimic interests coming from different consumer */ + u32 n_ifaces; /* The source address will change from interest to interest */ + /* index_ifaces is used to keep a global reference to the iface used */ + /* and it is incremented when we want to change "consumer" */ + /* n_ifaces identifies how many consumers to simulate */ + u32 max_seq_number; //Use to limit the max sequence number + u32 n_flows; //Use to simulate multiple flows (a flow always have the same hICN name) + ip46_address_t pgen_clt_src_addr; //Source addess base to use in the interest + + u16 interest_lifetime; // Interest lifetime + u32 sw_if; //Interface where to send interest and receives data } hicnpg_main_t; extern hicnpg_main_t hicnpg_main; +/** + * @brief hICN packet generator main for the pg server node + * + * It stores the configuration and make it availables to the pg server node. + */ typedef struct hicnpg_server_main_s { u32 node_index; - u32 hicn_underneath; /* Arbitrary content */ u32 pgen_svr_buffer_idx; + fib_prefix_t *pgen_srv_hicn_name; } hicnpg_server_main_t; extern hicnpg_server_main_t hicnpg_server_main; +extern vlib_node_registration_t hicn_pg_interest_node; +extern vlib_node_registration_t hicn_pg_data_node; + #endif // __HICN_PG_H__ /* diff --git a/hicn-plugin/src/punt.c b/hicn-plugin/src/punt.c deleted file mode 100644 index d62cf992d..000000000 --- a/hicn-plugin/src/punt.c +++ /dev/null @@ -1,1200 +0,0 @@ -/* - * Copyright (c) 2017-2019 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. - */ - -#include <stdarg.h> -#include <stddef.h> // offsetof() -#include <inttypes.h> -#include <vlib/vlib.h> -#include <vppinfra/error.h> -#include <vnet/ip/format.h> -#include <vnet/classify/in_out_acl.h> -#include <vlibapi/api.h> -#include <vlibmemory/api.h> -#include <vnet/ip/ip4_packet.h> -#include <vnet/ip/ip6_packet.h> -#include <vnet/ethernet/packet.h> -#include <vnet/fib/fib_types.h> -#include <vlib/global_funcs.h> - -#include "hicn.h" -#include "infra.h" -#include "parser.h" -#include "mgmt.h" -#include "punt.h" -#include "error.h" -#include "route.h" - -/* Those are not static as they are used for pgen in hicn_cli.c */ -ip_version_t ipv4 = { - .tbl = (u32 *) hicn_punt_glb.ip4_vnet_tbl_idx, - .addr_len_bits = IPV4_ADDR_LEN_BITS, - .protocol_field = &ipv4_protocol, - .version_field = &ipv4_version, - .ip_version = 0x40, -}; - -ip_version_t ipv6 = { - .tbl = (u32 *) hicn_punt_glb.ip6_vnet_tbl_idx, - .addr_len_bits = IPV6_ADDR_LEN_BITS, - .protocol_field = &ipv6_protocol, - .version_field = &ipv6_version, - .ip_version = 0x60, -}; - -ip_version_t udp4_src_ipv4 = { - .tbl = (u32 *) hicn_punt_glb.udp44_vnet_tbl_idx, - .addr_len_bits = IPV4_ADDR_LEN_BITS, - .protocol_field = &udp4_protocol, - .udp_sport = &udp4_sport, - .ip_version = 0x40, -}; - -ip_version_t udp4_src_ipv6 = { - .tbl = (u32 *) hicn_punt_glb.udp46_vnet_tbl_idx, - .addr_len_bits = IPV6_ADDR_LEN_BITS, - .protocol_field = &udp4_protocol, - .udp_sport = &udp4_sport, - .ip_version = 0x40, -}; - -ip_version_t udp4_dst_ipv4 = { - .tbl = (u32 *) hicn_punt_glb.udp44_vnet_tbl_idx, - .addr_len_bits = IPV4_ADDR_LEN_BITS, - .protocol_field = &udp4_protocol, - .udp_dport = &udp4_dport, - .ip_version = 0x40, -}; - -ip_version_t udp4_dst_ipv6 = { - .tbl = (u32 *) hicn_punt_glb.udp46_vnet_tbl_idx, - .addr_len_bits = IPV6_ADDR_LEN_BITS, - .protocol_field = &udp4_protocol, - .udp_dport = &udp4_dport, - .ip_version = 0x40, -}; - -ip_version_t udp6_src_ipv4 = { - .tbl = (u32 *) hicn_punt_glb.udp64_vnet_tbl_idx, - .addr_len_bits = IPV4_ADDR_LEN_BITS, - .protocol_field = &udp6_protocol, - .udp_sport = &udp6_sport, - .ip_version = 0x60, -}; - -ip_version_t udp6_src_ipv6 = { - .tbl = (u32 *) hicn_punt_glb.udp66_vnet_tbl_idx, - .addr_len_bits = IPV6_ADDR_LEN_BITS, - .protocol_field = &udp6_protocol, - .udp_sport = &udp6_sport, - .ip_version = 0x60, -}; - -ip_version_t udp6_dst_ipv4 = { - .tbl = (u32 *) hicn_punt_glb.udp64_vnet_tbl_idx, - .addr_len_bits = IPV4_ADDR_LEN_BITS, - .protocol_field = &udp6_protocol, - .udp_dport = &udp6_dport, - .ip_version = 0x60, -}; - -ip_version_t udp6_dst_ipv6 = { - .tbl = (u32 *) hicn_punt_glb.udp66_vnet_tbl_idx, - .addr_len_bits = IPV6_ADDR_LEN_BITS, - .protocol_field = &udp6_protocol, - .udp_dport = &udp6_dport, - .ip_version = 0x60, -}; - -ip_version_t ipv44 = { - .tbl = (u32 *) hicn_punt_glb.udp44_vnet_tbl_idx, - .addr_len_bits = IPV4_ADDR_LEN_BITS, - .protocol_field = &udp4_protocol, - .udp_sport = &udp4_sport, - .udp_dport = &udp4_dport, - .ip_version = 0x40, -}; - -ip_version_t ipv64 = { - .tbl = (u32 *) hicn_punt_glb.udp64_vnet_tbl_idx, - .addr_len_bits = IPV4_ADDR_LEN_BITS, - .protocol_field = &udp6_protocol, - .udp_sport = &udp6_sport, - .udp_dport = &udp6_dport, - .ip_version = 0x60, -}; - -ip_version_t ipv46 = { - .tbl = (u32 *) hicn_punt_glb.udp46_vnet_tbl_idx, - .addr_len_bits = IPV6_ADDR_LEN_BITS, - .protocol_field = &udp4_protocol, - .udp_sport = &udp4_sport, - .udp_dport = &udp4_dport, - .ip_version = 0x40, -}; - -ip_version_t ipv66 = { - .tbl = (u32 *) hicn_punt_glb.udp66_vnet_tbl_idx, - .addr_len_bits = IPV6_ADDR_LEN_BITS, - .protocol_field = &udp6_protocol, - .udp_sport = &udp6_sport, - .udp_dport = &udp6_dport, - .ip_version = 0x60, -}; - -#define _(NAME, BASE, LAYER, FIELD, PUNT_ID) \ - field_t NAME = { \ - .offset = BASE + offsetof(LAYER, FIELD), \ - .len = STRUCT_SIZE_OF(LAYER, FIELD), \ - .punt_id = PUNT_ID, \ - }; -foreach_field -#undef _ -/* - * In the latest version, we let faces direct the traffic towards Interest - * processing, or MAP-Me nodes. Punting should only make sure that the ICMP - * packets are also sent to the face node. We added the following defines to - * determine the next node to send punted packets. Ideally we might remove - * protocol number check from punting rule. - */ -#define NEXT_MAPME_CTRL4 hicn_punt_glb.next_hit_interest_ipv4 -#define NEXT_MAPME_ACK4 hicn_punt_glb.next_hit_data_ipv4 -#define NEXT_MAPME_CTRL6 hicn_punt_glb.next_hit_interest_ipv6 -#define NEXT_MAPME_ACK6 hicn_punt_glb.next_hit_data_ipv6 -/* Maximum number of vector allowed in match. Value hardcoded in vnet_classify_hash_packet_inline in vnet_classify.h */ -#define MAX_MATCH_SIZE 5 -/** - * HICN global Punt Info - * - * - * - */ - hicn_punt_glb_t hicn_punt_glb; - -/** - * We use the function build_bit_array to populate an initially empty buffer - * with masks/values for the parts of the packet to match. The function also - * returns the correct skip and match values to pass to vnet_classify_*, which - * are the number of vectors to skip/match during classification (they should be - * multiples of vector size = CLASSIFIER_VECTOR_SIZE). - * - * offsets: - * 0 14 offsetof(IP_HDR, SRC) - * | | / - * +----------+----+-------+-------+----+-... - * | ETH | IP . src . dst . | - * +----------+----+-------+-------+----+-... - * | | | - * |<- skip=1 ->|<--- match=2/3 --->| - * - * - */ - -/** - * The following section defines a couple of protocol fields that we will use - * for creating the buffer. We retrieve the offset and length on those fields - * based on the (portable) header struct aliases defined in libhicn. - * - * In the foreach_field macro, the punt_id field is used as convenience as we - * will have to create different classifier tables based on whether we punt - * interests (on dst) or data (on src). It is undefined (NA) otherwise. - */ - -#define NA 0 - - -/** - * @brief Create a bitmask from mask length. - * @param mask [in] mask length (in bits) - * @param buffer [out] output buffer - * @param len [out] output buffer length - */ -static void -build_ip_address_mask (u8 mask, u8 * buffer, u32 len) -{ - u32 hi_bytes = mask / 8; - u32 hi_bits = mask % 8; - u8 byte_mask = 0xff; - - /* - * memset buffer with 0xff in case of IPV6 16 bytes will be used for - * match - */ - memset (buffer, 0, len); - //might not be needed if buffer is already 0 'ed XXX - memset (buffer, 0xff, hi_bytes); - if (hi_bits != 0) - { - for (int i = 0; i < (8 - hi_bits); i++) - byte_mask = byte_mask << 1; - buffer[hi_bytes] = byte_mask; - } -} - -#define CEIL_DIV(x, y) (1 + ((x - 1) / y)) - -/** - * @brief Create a bit array from field/value list - * @param buffer [out] output buffer - * @param len [out] output buffer length - * @param skip [out] number of CLASSIFIER_VECTOR to skip - * @param match [out] number of CLASSIFIER_VECTOR to match - * @param ... [in] list of [field_t *, value] * used to populate buffer - */ -static int -build_bit_array (u8 * buffer, u32 len, u32 base_offset, u32 * skip, - u32 * match, va_list vl) -{ - u8 min = len, max = 0; - field_t *field; - u8 *value; - int pos; - int count = 0; - - /* Clear buffer */ - memset (buffer, 0, len); - - for (;;) - { - count++; - field = va_arg (vl, field_t *); - if (!field) - break; - - /* Check that the field belongs to the reserved buffer */ - if (field->offset + field->len > len) - goto ERR_PUNT; - - /* - * Copy the value of the field inside the buffer at the - * correct offset - */ - pos = base_offset + field->offset; - value = va_arg (vl, u8 *); - memcpy (buffer + pos, value, field->len); - if (min > pos) - min = pos; - if (max < pos + field->len) - max = pos + field->len; - } - - /* We can skip multiples of the vector match */ - *skip = min / CLASSIFIER_VECTOR_SIZE; - *match = CEIL_DIV (max, CLASSIFIER_VECTOR_SIZE) - *skip; - - if (*match > MAX_MATCH_SIZE) - *match = MAX_MATCH_SIZE; - - return HICN_ERROR_NONE; - -ERR_PUNT: - *skip = 0; - *match = 0; - return HICN_ERROR_PUNT_INVAL; -} - -void -update_table4_index (u32 intfc, u32 table_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - - if (hicn_punt_glb.head_ip4[intfc] == ~0) - hicn_punt_glb.head_ip4[intfc] = table_index; - - /* Update the table in tail to poin to this */ - if (hicn_punt_glb.tail_ip4[intfc] != ~0) - { - vnet_classify_table_t *t = - pool_elt_at_index (cm->tables, hicn_punt_glb.tail_ip4[intfc]); - t->next_table_index = table_index; - } - hicn_punt_glb.tail_ip4[intfc] = table_index; -} - -void -update_table6_index (u32 intfc, u32 table_index) -{ - vnet_classify_main_t *cm = &vnet_classify_main; - - if (hicn_punt_glb.head_ip6[intfc] == ~0) - hicn_punt_glb.head_ip6[intfc] = table_index; - - /* Update the table in tail to poin to this */ - if (hicn_punt_glb.tail_ip6[intfc] != ~0) - { - vnet_classify_table_t *t = - pool_elt_at_index (cm->tables, hicn_punt_glb.tail_ip6[intfc]); - t->next_table_index = table_index; - } - hicn_punt_glb.tail_ip6[intfc] = table_index; -} - -/** - * @brief Add or remove a vnet table matching the list of fields/values passed - * as parameters. - * - * @param punt_id Storage identifier (HICN_PUNT_SRC | HICN_PUNT_DST) - * @param mask Subnet mask to match in the table - * @param next_tbl_index next table to match in case of miss - * @param intfc Interface identifier - * @param is_add 1 if the table must be created, 0 if removed - * @param ... list of (field_t, value) to be matched - * - * @result Returns: - * HICN_ERROR_TBL_EXIST if is_add == 1 and a table for the same mask - * already exists, - * HICN_ERROR_TBL_NOT_FOUND if is_add == 0 and there is no table for the - * given mask, - * HICN_ERROR_NONE if no * error occurred. - */ -int -_hicn_punt_add_del_vnettbl (ip_version_t * ip, u8 punt_id, u8 mask, - u32 next_tbl_index, u32 intfc, int base_offset, - int is_add, u8 use_current_data, ...) -{ - u8 buffer[PUNT_BUFFER_SIZE]; /* must be dimensioned - * large enough */ - int rt; - va_list vl; - u32 *table_index; - u32 new_table_index; - u32 skip, match; - - - /* Build the buffer right from the start to determine the skip size */ - va_start (vl, use_current_data); - build_bit_array (buffer, sizeof (buffer), base_offset, &skip, &match, vl); - va_end (vl); - - ASSERT (skip < 4); - //Hardcoded limit in following array - - table_index = TABLE_ELT_P (ip, intfc, skip, punt_id, mask); - - if (is_add && *table_index != HICNP_PUNY_INVALID_TBL) - return HICN_ERROR_PUNT_TBL_EXIST; - if (!is_add && *table_index == HICNP_PUNY_INVALID_TBL) - return HICN_ERROR_PUNT_TBL_NOT_FOUND; - - new_table_index = ~0; - rt = vnet_classify_add_del_table (&vnet_classify_main, - buffer + skip * CLASSIFIER_VECTOR_SIZE, - HICN_CLASSIFY_NBUCKETS, - HICN_CLASSIFY_TABLE_MEMORY_SIZE, skip, - match, HICN_CLASSIFY_NO_NEXT_TABLE, - HICN_CLASSIFY_MISS_NEXT_INDEX, - &new_table_index, - use_current_data, - HICN_CLASSIFY_CURRENT_DATA_OFFSET, is_add, - HICN_CLASSIFY_DON_T_DEL_CHAIN); - - if (rt != 0) - return HICN_ERROR_PUNT_INVAL; - - *table_index = new_table_index; - if (ip->ip_version == 0x40) - update_table4_index (intfc, new_table_index); - else - update_table6_index (intfc, new_table_index); - return HICN_ERROR_NONE; -} - -/** - * @brief Add or remove a vnet table matching the ip_version and field (src/dst) - */ -int -hicn_punt_add_del_vnettbl (ip_version_t * ip, field_t * field, u8 mask, - u32 next_tbl_index, u32 intfc, u8 base_offset, - u8 use_current_data, int is_add) -{ - u8 ip_mask[IPV6_ADDR_LEN]; - build_ip_address_mask (mask, ip_mask, sizeof (ip_mask)); - - return _hicn_punt_add_del_vnettbl (ip, field->punt_id, mask, next_tbl_index, - intfc, base_offset, is_add, - use_current_data, field, ip_mask, NULL); -} - - -/** - * @brief Add or remove a vnet table for udp tunnels matching the ip_version and field (src/dst) - * - */ -int -hicn_punt_add_del_vnettbl_udp (ip_version_t * outer, ip_version_t * inner, - field_t * field, u8 mask, u32 next_tbl_index, - u32 intfc, u8 base_offset, u8 use_current_data, - int is_add) -{ - u8 udp_mask[inner->addr_len_bits]; - build_ip_address_mask (mask, udp_mask, sizeof (udp_mask)); - u16 port_value = 0xffff; - u8 protocol_value = 0xff; - - if (outer->udp_sport == NULL) { - return _hicn_punt_add_del_vnettbl (outer, field->punt_id, mask, - next_tbl_index, intfc, base_offset, - is_add, - use_current_data, - outer->protocol_field, &protocol_value, - outer->udp_dport, &port_value, field, - udp_mask, NULL); - } else if (outer->udp_dport == NULL) { - return _hicn_punt_add_del_vnettbl (outer, field->punt_id, mask, - next_tbl_index, intfc, base_offset, - is_add, - use_current_data, - outer->protocol_field, &protocol_value, - outer->udp_sport, &port_value, field, - udp_mask, NULL); - } else { - return _hicn_punt_add_del_vnettbl (outer, field->punt_id, mask, - next_tbl_index, intfc, base_offset, - is_add, - use_current_data, - outer->protocol_field, &protocol_value, - outer->udp_sport, &port_value, - outer->udp_dport, &port_value, field, - udp_mask, NULL); - } -} - -#define hicn_punt_add_vnettbl_udp(outer, inner, field, mask, next_tbl_index, intfc, base_offset, use_current_data) \ - (hicn_punt_add_del_vnettbl_udp(outer, inner, field, mask, next_tbl_index, intfc, base_offset, use_current_data, OP_ADD)) - -#define hicn_punt_del_vnettbl_udp(outer, inner, field, mask, next_tbl_index, intfc, base_offset, use_current_data) \ - (hicn_punt_add_del_vnettbl_udp(outer, inner, field, mask, next_tbl_index, intfc, base_offset, use_current_data, OP_DEL)) - -/** - * @brief Add or remove a vnet session matching the list of fields/values passed - * as parameters. - * - * @param punt_id Storage identifier (HICN_PUNT_SRC | HICN_PUNT_DST) - * @param v4_address IPv4 address to match in the session // XXX v4/v6 - * @param mask Subnet mask to match in the session - * @param next_hit_index vlib arch id pointing to the next node - * @param intfc Interface identifier - * @param is_add 1 if the session must be create, 0 if removed - * @param ... list of (field_t, value) to be matched - * - * @result Returns: - * HICN_ERROR_TBL_NOT_FOUND there is no table for the given mask, - * HICN_ERROR_PUNT_SSN_NOT_FOUND if is_add == 0 and there is no session for - * the given address, - * HICN_ERROR_NONE if no error * occurred. - */ -int -_hicn_punt_add_del_vnetssn (ip_version_t * ip, u8 punt_id, u8 mask, - u32 next_hit_index, u32 intfc, int base_offset, - int is_add, ...) -{ - u8 buffer[PUNT_BUFFER_SIZE]; /* must be dimensioned - * large enough */ - int rt; - va_list vl; - u32 table_index; - u32 skip, match; - - /* Build the buffer right from the start to determine the skip size */ - va_start (vl, is_add); - build_bit_array (buffer, sizeof (buffer), base_offset, &skip, &match, vl); - va_end (vl); - - ASSERT (skip < 4); - //Hardcoded limit in following array - - table_index = TABLE_ELT (ip, intfc, skip, punt_id, mask); - - if (table_index == HICNP_PUNY_INVALID_TBL) - return HICN_ERROR_PUNT_TBL_NOT_FOUND; - - rt = vnet_classify_add_del_session (&vnet_classify_main, table_index, buffer, //+skip * CLASSIFIER_VECTOR_SIZE, - next_hit_index, - HICN_CLASSIFY_OPAQUE_INDEX, - HICN_CLASSIFY_ADVANCE, - HICN_CLASSIFY_ACTION, - HICN_CLASSIFY_METADATA, is_add); - - if (rt == VNET_API_ERROR_NO_SUCH_ENTRY) - rt = HICN_ERROR_PUNT_SSN_NOT_FOUND; - - return rt; -} - -/** - * @brief Add or remove a vnet session matching the ip6 src address - * - * See hicn_punt_add_del_vnetssn for details about parameters. - */ -int -hicn_punt_add_del_vnetssn (ip_version_t * ip, field_t * field, - fib_prefix_t * prefix, - u32 next_hit_index, u32 intfc, u8 base_offset, - int is_add) -{ - return _hicn_punt_add_del_vnetssn (ip, field->punt_id, prefix->fp_len, next_hit_index, - intfc, base_offset, is_add, field, - ip46_address_is_ip4 (&prefix->fp_addr) ? - prefix->fp_addr.ip4.as_u8 : - prefix->fp_addr.ip6.as_u8, NULL); -} - - - -/** - * @brief Add or remove a vnet session for udp tunnels matching the ip6 src address - * - * See hicn_punt_add_del_vnetssn for details about parameters. - */ -int -hicn_punt_add_del_vnetssn_udp (ip_version_t * outer, ip_version_t * inner, - field_t * field, fib_prefix_t * prefix, - u32 next_hit_index, u32 intfc, - u8 base_offset, u8 protocol, u16 sport, - u16 dport, int is_add) -{ - if(sport == HICN_PUNT_INVALID_PORT) - { - return _hicn_punt_add_del_vnetssn (outer, field->punt_id, prefix->fp_len, - next_hit_index, intfc, base_offset, - is_add, outer->protocol_field, &protocol, - outer->udp_dport, &dport, field, - prefix->fp_addr.as_u8, NULL); - } - else if(dport == HICN_PUNT_INVALID_PORT) - { - return _hicn_punt_add_del_vnetssn (outer, field->punt_id, prefix->fp_len, - next_hit_index, intfc, base_offset, - is_add, outer->protocol_field, &protocol, - outer->udp_sport, &sport, field, - prefix->fp_addr.as_u8, NULL); - } - else - { - return _hicn_punt_add_del_vnetssn (outer, field->punt_id, prefix->fp_len, - next_hit_index, intfc, base_offset, - is_add, outer->protocol_field, &protocol, - outer->udp_sport, &sport, - outer->udp_dport, &dport, field, - prefix->fp_addr.as_u8, NULL); - } -} - -#define hicn_punt_add_vnetssn_udp(outer, inner, field, prefix, index, intfc, offset, protocol, sport, dport) \ - (hicn_punt_add_del_vnetssn_udp(outer, inner, field, prefix, index, intfc, offset, protocol, sport, dport, OP_ADD)) - -#define hicn_punt_del_vnetssn_udp(outer, inner, field, prefix, index, intfc, offset, protocol, sport, dport) \ - (hicn_punt_add_del_vnetssn_udp(outer, inner, field, prefix, index, intfc, offset, protocol, sport, dport, OP_DEL)) - -/* - * Enable the table on a given interface considering the table type - */ -void -hicn_punt_enable_disable_vnet_ip4_table_on_intf (vlib_main_t * vm, - u32 sw_if_index, - int is_enable) -{ - if (hicn_punt_glb.head_ip4[sw_if_index] != HICNP_PUNY_INVALID_TBL) - (void) vnet_set_input_acl_intfc (vm, sw_if_index, - hicn_punt_glb.head_ip4[sw_if_index], - 0xFFFFFFFF, 0xFFFFFFFF, is_enable); - return; -} - -/* - * Enable the table on a given interface considering the table type - * - * XXX replace skip by base_offset XXX are we sure we always have ETH_L2, and - * not base_offset ??? - */ -int -hicn_punt_remove_ip4_address (vlib_main_t * vm, fib_prefix_t * prefix, - int skip, u32 sw_if_index, - int is_enable, u8 with_l2) -{ - - vnet_classify_main_t *cm = &vnet_classify_main; - vnet_classify_table_t *vnet_table = NULL; - u8 mask = prefix->fp_len; - u32 table_index = ~0; - - u32 base_offset = (with_l2 ? ETH_L2 : NO_L2); - - hicn_punt_del_vnetssn (&ipv4, &ipv4_src, prefix, - hicn_punt_glb.next_hit_data_ipv4, sw_if_index, - ETH_L2); - hicn_punt_del_vnetssn (&ipv4, &ipv4_dst, prefix, - hicn_punt_glb.next_hit_interest_ipv4, sw_if_index, - ETH_L2); - - table_index = - hicn_punt_glb.ip4_vnet_tbl_idx[sw_if_index][skip][HICN_PUNT_DST][mask]; - vnet_table = pool_elt_at_index (cm->tables, table_index); - if (vnet_table->active_elements == 0) - { - hicn_punt_del_vnettbl (&ipv4, &ipv4_dst, mask, - hicn_punt_glb.ip4_vnet_tbl_idx[sw_if_index][skip] - [HICN_PUNT_SRC][mask], sw_if_index, base_offset); - } - table_index = - hicn_punt_glb.ip4_vnet_tbl_idx[sw_if_index][skip][HICN_PUNT_SRC][mask]; - vnet_table = pool_elt_at_index (cm->tables, table_index); - if (vnet_table->active_elements == 0) - { - hicn_punt_del_vnettbl (&ipv4, &ipv4_src, mask, ~0, sw_if_index, - base_offset); - } - return HICN_ERROR_NONE; -} - -int -hicn_punt_remove_ip6_address (vlib_main_t * vm, fib_prefix_t * prefix, - int skip, u32 sw_if_index, - int is_enable, u8 with_l2) -{ - - vnet_classify_main_t *cm = &vnet_classify_main; - vnet_classify_table_t *vnet_table = NULL; - u8 mask = prefix->fp_len; - u32 table_index = ~0; - - u32 base_offset = (with_l2 ? ETH_L2 : NO_L2); - - hicn_punt_del_vnetssn (&ipv6, &ipv6_src, prefix, - hicn_punt_glb.next_hit_data_ipv6, sw_if_index, - ETH_L2); - hicn_punt_del_vnetssn (&ipv6, &ipv6_dst, prefix, - hicn_punt_glb.next_hit_interest_ipv6, sw_if_index, - ETH_L2); - - table_index = - hicn_punt_glb.ip6_vnet_tbl_idx[sw_if_index][skip][HICN_PUNT_DST][mask]; - vnet_table = pool_elt_at_index (cm->tables, table_index); - if (vnet_table->active_elements == 0) - { - hicn_punt_del_vnettbl (&ipv6, &ipv6_dst, mask, - hicn_punt_glb.ip6_vnet_tbl_idx[sw_if_index][skip] - [HICN_PUNT_SRC][mask], sw_if_index, base_offset); - } - table_index = - hicn_punt_glb.ip6_vnet_tbl_idx[sw_if_index][skip][HICN_PUNT_SRC][mask]; - vnet_table = pool_elt_at_index (cm->tables, table_index); - if (vnet_table->active_elements == 0) - { - hicn_punt_del_vnettbl (&ipv6, &ipv6_src, mask, ~0, sw_if_index, - base_offset); - } - return HICN_ERROR_NONE; -} - -/* - * Enable the table on a given interface considering the table type - */ -void -hicn_punt_enable_disable_vnet_ip6_table_on_intf (vlib_main_t * vm, - u32 sw_if_index, - int is_enable) -{ - if (hicn_punt_glb.head_ip6[sw_if_index] != HICNP_PUNY_INVALID_TBL) - (void) vnet_set_input_acl_intfc (vm, sw_if_index, - 0xFFFFFFFF, - hicn_punt_glb.head_ip6[sw_if_index], - 0xFFFFFFFF, is_enable); - return; -} - -/* - * HICN PUNT vlibd node addtion - */ -void -hicn_punt_vlib_node_add (vlib_main_t * vm) -{ - u32 hit_next_index = 0xFFFFFFFF; - vlib_node_t *node; - - /* to remove the warning */ - hit_next_index = hit_next_index; - - //Accquire the node indexes - - /* ip face */ - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-ip4-input"); - hicn_punt_glb.hicn_node_info.hicn_face_ip4_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-ip6-input"); - hicn_punt_glb.hicn_node_info.hicn_face_ip6_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-ip4-output"); - hicn_punt_glb.hicn_node_info.hicn_face_ip4_output_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-ip6-output"); - hicn_punt_glb.hicn_node_info.hicn_face_ip6_output_index = node->index; - - /* ip iface */ - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-ip4-input"); - hicn_punt_glb.hicn_node_info.hicn_iface_ip4_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-ip6-input"); - hicn_punt_glb.hicn_node_info.hicn_iface_ip6_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-ip4-output"); - hicn_punt_glb.hicn_node_info.hicn_iface_ip4_output_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-ip6-output"); - hicn_punt_glb.hicn_node_info.hicn_iface_ip4_output_index = node->index; - - /* udp face */ - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-udp4-input"); - hicn_punt_glb.hicn_node_info.hicn_face_udp4_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-udp6-input"); - hicn_punt_glb.hicn_node_info.hicn_face_udp6_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-udp4-output"); - hicn_punt_glb.hicn_node_info.hicn_face_udp4_output_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-face-udp6-output"); - hicn_punt_glb.hicn_node_info.hicn_face_udp6_output_index = node->index; - - /* udp iface */ - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-udp4-input"); - hicn_punt_glb.hicn_node_info.hicn_iface_udp4_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-udp6-input"); - hicn_punt_glb.hicn_node_info.hicn_iface_udp6_input_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-udp4-output"); - hicn_punt_glb.hicn_node_info.hicn_iface_udp4_output_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "hicn-iface-udp6-output"); - hicn_punt_glb.hicn_node_info.hicn_iface_udp6_output_index = node->index; - - node = vlib_get_node_by_name (vm, (u8 *) "ip4-inacl"); - hicn_punt_glb.hicn_node_info.ip4_inacl_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "ip6-inacl"); - hicn_punt_glb.hicn_node_info.ip6_inacl_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "ip4-lookup"); - hicn_punt_glb.hicn_node_info.ip4_lookup_node_index = node->index; - node = vlib_get_node_by_name (vm, (u8 *) "ip6-lookup"); - hicn_punt_glb.hicn_node_info.ip6_lookup_node_index = node->index; - - - hicn_punt_glb.next_hit_data_ipv4 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip4_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_face_ip4_input_index); - - hicn_punt_glb.next_hit_interest_ipv4 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip4_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_iface_ip4_input_index); - - hicn_punt_glb.next_hit_data_ipv6 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip6_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_face_ip6_input_index); - - hicn_punt_glb.next_hit_interest_ipv6 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip6_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_iface_ip6_input_index); - - hicn_punt_glb.next_hit_data_udp4 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip4_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_face_udp4_input_index); - - hicn_punt_glb.next_hit_interest_udp4 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip4_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_iface_udp4_input_index); - - hicn_punt_glb.next_hit_data_udp6 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip6_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_face_udp6_input_index); - - hicn_punt_glb.next_hit_interest_udp6 = vlib_node_add_next (vm, - hicn_punt_glb.hicn_node_info. - ip6_inacl_node_index, - hicn_punt_glb.hicn_node_info. - hicn_iface_udp6_input_index); - - return; -} - -/* - * HICN PUNT INIT - */ -void -hicn_punt_init (vlib_main_t * vm) -{ - u32 table_index = ~0; - //Create vnet classify tables and store the table indexes - memset (hicn_punt_glb.ip4_vnet_tbl_idx, table_index, - sizeof (u32) * 4 * 2 * HICN_PUNT_IP4_MASK * HICN_MAX_INTFC); - memset (hicn_punt_glb.ip6_vnet_tbl_idx, table_index, - sizeof (u32) * 4 * 2 * HICN_PUNT_IP6_MASK * HICN_MAX_INTFC); - - memset (hicn_punt_glb.udp44_vnet_tbl_idx, table_index, - sizeof (u32) * 4 * 2 * HICN_PUNT_IP4_MASK * HICN_MAX_INTFC); - memset (hicn_punt_glb.udp46_vnet_tbl_idx, table_index, - sizeof (u32) * 4 * 2 * HICN_PUNT_IP6_MASK * HICN_MAX_INTFC); - memset (hicn_punt_glb.udp64_vnet_tbl_idx, table_index, - sizeof (u32) * 4 * 2 * HICN_PUNT_IP4_MASK * HICN_MAX_INTFC); - memset (hicn_punt_glb.udp66_vnet_tbl_idx, table_index, - sizeof (u32) * 4 * 2 * HICN_PUNT_IP6_MASK * HICN_MAX_INTFC); - //Register hicn nodes after vnet table creation - hicn_punt_vlib_node_add (vm); - memset (hicn_punt_glb.head_ip4, ~0, sizeof (u32) * HICN_MAX_INTFC); - memset (hicn_punt_glb.tail_ip4, ~0, sizeof (u32) * HICN_MAX_INTFC); - memset (hicn_punt_glb.head_ip6, ~0, sizeof (u32) * HICN_MAX_INTFC); - memset (hicn_punt_glb.tail_ip6, ~0, sizeof (u32) * HICN_MAX_INTFC); - return; -} - -u32 -hicn_punt_interest_data_for_udp (vlib_main_t * vm, - fib_prefix_t * prefix, - u32 swif, u8 punt_type, u16 sport, u16 dport, - u8 with_l2) -{ - int skip = 1; - u32 table_index; - // If we want l2 then we punt from data (and not current) - u8 use_current_data = - with_l2 ? HICN_CLASSIFY_NO_CURRENT_DATA_FLAG : - HICN_CLASSIFY_CURRENT_DATA_FLAG; - u8 base_offset = with_l2 ? ETH_L2 : NO_L2; - u16 mask = prefix->fp_len; - vnet_main_t *vnm = vnet_get_main (); - - if (punt_type != HICN_PUNT_IP_TYPE && punt_type != HICN_PUNT_UDP4_TYPE - && punt_type != HICN_PUNT_UDP6_TYPE) - return HICN_ERROR_PUNT_INVAL; - - if ((sport == HICN_PUNT_INVALID_PORT && dport == HICN_PUNT_INVALID_PORT) || !vnet_sw_interface_is_valid (vnm, swif)) - return HICN_ERROR_PUNT_INVAL; - - if (ip46_address_is_ip4 (&prefix->fp_addr)) - { - if (mask > IPV4_ADDR_LEN_BITS) - return HICN_ERROR_PUNT_INVAL; - - if (punt_type == HICN_PUNT_UDP4_TYPE) - { - //If we consider ethernet we can skip 32 bytes, otherwise only 16 - skip = 1 + with_l2; - /* Create Vnet table for a given mask */ - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_dst_ipv4, &ipv4, &udp44_src, mask, ~0, - swif, base_offset, use_current_data); - else if (dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_src_ipv4, &ipv4, &udp44_src, mask, ~0, - swif, base_offset, use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv44, &ipv4, &udp44_src, mask, ~0, - swif, base_offset, use_current_data); - - table_index = - hicn_punt_glb.udp44_vnet_tbl_idx[swif][skip][HICN_PUNT_SRC][mask]; - - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_dst_ipv4, &ipv4, &udp44_dst, mask, - table_index, swif, base_offset, - use_current_data); - else if (dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_src_ipv4, &ipv4, &udp44_dst, mask, - table_index, swif, base_offset, - use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv44, &ipv4, &udp44_dst, mask, - table_index, swif, base_offset, - use_current_data); - /* - * Add a session for the specified ip address and - * subnet mask - */ - hicn_punt_add_vnetssn_udp (&ipv44, &ipv4, &udp44_src, - prefix, - hicn_punt_glb.next_hit_data_udp4, - swif, base_offset, IPPROTO_UDP, sport, - dport); - - hicn_punt_add_vnetssn_udp (&ipv44, &ipv4, &udp44_dst, - prefix, - hicn_punt_glb.next_hit_interest_udp4, - swif, base_offset, IPPROTO_UDP, sport, - dport); - - hicn_punt_enable_disable_vnet_ip4_table_on_intf (vm, swif, - OP_ENABLE); - } - else //PUNTING is UDP6 - { - //If we consider ethernet we can skip 48 bytes, otherwise only 32 - skip = 2 + with_l2; - /* Create Vnet table for a given mask */ - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_dst_ipv4, &ipv6, &udp64_src, mask, ~0, - swif, base_offset, use_current_data); - else if(dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_src_ipv4, &ipv6, &udp64_src, mask, ~0, - swif, base_offset, use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv64, &ipv6, &udp64_src, mask, ~0, - swif, base_offset, use_current_data); - - table_index = - hicn_punt_glb.udp64_vnet_tbl_idx[swif][skip][HICN_PUNT_SRC][mask]; - - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_dst_ipv4, &ipv6, &udp64_dst, mask, - table_index, swif, base_offset, - use_current_data); - else if (dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_src_ipv4, &ipv6, &udp64_dst, mask, - table_index, swif, base_offset, - use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv64, &ipv6, &udp64_dst, mask, - table_index, swif, base_offset, - use_current_data); - - /* - * Add a session for the specified ip address and - * subnet mask - */ - hicn_punt_add_vnetssn_udp (&ipv64, &ipv4, &udp64_src, - prefix, - hicn_punt_glb.next_hit_data_udp6, - swif, base_offset, IPPROTO_UDP, sport, - dport); - - hicn_punt_add_vnetssn_udp (&ipv64, &ipv4, &udp64_dst, - prefix, - hicn_punt_glb.next_hit_interest_udp6, - swif, base_offset, IPPROTO_UDP, sport, - dport); - - hicn_punt_enable_disable_vnet_ip6_table_on_intf (vm, swif, - OP_ENABLE); - } - } - else - { - if (punt_type == HICN_PUNT_UDP4_TYPE) - { - //If we consider ethernet we can skip 32 bytes, otherwise only 16 - skip = 1 + with_l2; - /* Create Vnet table for a given mask */ - if (mask > 96) - return HICN_ERROR_PUNT_INVAL; - - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_dst_ipv6, &ipv4, &udp46_src, mask, ~0, - swif, base_offset, use_current_data); - else if (dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_src_ipv6, &ipv4, &udp46_src, mask, ~0, - swif, base_offset, use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv46, &ipv4, &udp46_src, mask, ~0, - swif, base_offset, use_current_data); - - table_index = - hicn_punt_glb.udp46_vnet_tbl_idx[swif][skip][HICN_PUNT_SRC][mask]; - - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_dst_ipv6, &ipv4, &udp46_dst, mask, - table_index, swif, base_offset, - use_current_data); - else if (dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp4_src_ipv6, &ipv4, &udp46_dst, mask, - table_index, swif, base_offset, - use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv46, &ipv4, &udp46_dst, mask, - table_index, swif, base_offset, - use_current_data); - - /* - * Add a session for the specified ip address and - * subnet mask - */ - hicn_punt_add_vnetssn_udp (&ipv46, &ipv4, &udp46_src, - prefix, - hicn_punt_glb.next_hit_data_udp4, - swif, base_offset, IPPROTO_UDP, sport, - dport); - hicn_punt_add_vnetssn_udp (&ipv46, &ipv4, &udp46_dst, prefix, - hicn_punt_glb.next_hit_interest_udp4, - swif, base_offset, IPPROTO_UDP, sport, - dport); - - hicn_punt_enable_disable_vnet_ip4_table_on_intf (vm, swif, - OP_ENABLE); - } - else - { - if (mask > 122) - return HICN_ERROR_PUNT_INVAL; - - //If we consider ethernet we can skip 48 bytes, otherwise only 32 - skip = 2 + with_l2; - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_dst_ipv6, &ipv6, &udp66_src, mask, ~0, - swif, base_offset, use_current_data); - else if (dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_src_ipv6, &ipv6, &udp66_src, mask, ~0, - swif, base_offset, use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv66, &ipv6, &udp66_src, mask, ~0, - swif, base_offset, use_current_data); - - table_index = - hicn_punt_glb.udp66_vnet_tbl_idx[swif][skip][HICN_PUNT_SRC][mask]; - if(sport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_dst_ipv6, &ipv6, &udp66_dst, mask, - table_index, swif, base_offset, - use_current_data); - else if (dport == HICN_PUNT_INVALID_PORT) - hicn_punt_add_vnettbl_udp (&udp6_src_ipv6, &ipv6, &udp66_dst, mask, - table_index, swif, base_offset, - use_current_data); - else - hicn_punt_add_vnettbl_udp (&ipv66, &ipv6, &udp66_dst, mask, - table_index, swif, base_offset, - use_current_data); - - /* - * Add a session for the specified ip address and - * subnet mask - */ - hicn_punt_add_vnetssn_udp (&ipv66, &ipv6, &udp66_src, - prefix, - hicn_punt_glb.next_hit_data_udp6, - swif, base_offset, IPPROTO_UDP, sport, - dport); - hicn_punt_add_vnetssn_udp (&ipv66, &ipv6, &udp66_dst, prefix, - hicn_punt_glb.next_hit_interest_udp6, - swif, base_offset, IPPROTO_UDP, sport, - dport); - - hicn_punt_enable_disable_vnet_ip6_table_on_intf (vm, swif, - OP_ENABLE); - } - - } - return HICN_ERROR_NONE; -} - - - -u32 -hicn_punt_interest_data_for_ip (vlib_main_t * vm, - fib_prefix_t * prefix, - u32 swif, u8 punt_type, u8 with_l2) -{ - int skip = 1; - u32 table_index; - // If we want l2 then we punt from data (and not current) - u8 use_current_data = - with_l2 ? HICN_CLASSIFY_NO_CURRENT_DATA_FLAG : - HICN_CLASSIFY_CURRENT_DATA_FLAG; - u8 base_offset = with_l2 ? ETH_L2 : NO_L2; - u16 mask = prefix->fp_len; - vnet_main_t *vnm = vnet_get_main (); - - if ((punt_type != HICN_PUNT_IP_TYPE && punt_type != HICN_PUNT_UDP4_TYPE - && punt_type != HICN_PUNT_UDP6_TYPE) || !vnet_sw_interface_is_valid (vnm, swif)) - return HICN_ERROR_PUNT_INVAL; - - if (ip46_address_is_ip4 (&prefix->fp_addr)) - { - if (mask > IPV4_ADDR_LEN_BITS) - return HICN_ERROR_PUNT_INVAL; - - if (punt_type == HICN_PUNT_IP_TYPE) - { - /* Create Vnet table for a given mask */ - hicn_punt_add_vnettbl (&ipv4, &ipv4_src, mask, ~0, swif, - base_offset, use_current_data); - - table_index = - hicn_punt_glb.ip4_vnet_tbl_idx[swif][skip][HICN_PUNT_SRC][mask]; - - hicn_punt_add_vnettbl (&ipv4, &ipv4_dst, mask, table_index, swif, - base_offset, use_current_data); - - /* - * Add a session for the specified ip address and - * subnet mask - */ - hicn_punt_add_vnetssn (&ipv4, &ipv4_src, - prefix, - hicn_punt_glb.next_hit_data_ipv4, swif, - base_offset); - hicn_punt_add_vnetssn (&ipv4, &ipv4_dst, - prefix, - hicn_punt_glb.next_hit_interest_ipv4, swif, - base_offset); - - hicn_punt_enable_disable_vnet_ip4_table_on_intf (vm, swif, - OP_ENABLE); - } - else - { - return HICN_ERROR_PUNT_INVAL; - } - } - else - { - if (punt_type == HICN_PUNT_IP_TYPE) - { - if (mask > IPV6_ADDR_LEN_BITS) - return HICN_ERROR_PUNT_INVAL; - - /* Create Vnet table for a given mask */ - hicn_punt_add_vnettbl (&ipv6, &ipv6_src, mask, ~0, swif, - base_offset, use_current_data); - - table_index = - hicn_punt_glb.ip6_vnet_tbl_idx[swif][skip][HICN_PUNT_SRC][mask]; - - hicn_punt_add_vnettbl (&ipv6, &ipv6_dst, mask, table_index, swif, - base_offset, use_current_data); - - /* - * Add a session for the specified ip address and - * subnet mask - */ - hicn_punt_add_vnetssn (&ipv6, &ipv6_src, prefix, - hicn_punt_glb.next_hit_data_ipv6, swif, - base_offset); - hicn_punt_add_vnetssn (&ipv6, &ipv6_dst, prefix, - hicn_punt_glb.next_hit_interest_ipv6, - swif, base_offset); - - hicn_punt_enable_disable_vnet_ip6_table_on_intf (vm, swif, - OP_ENABLE); - } - else - { - return HICN_ERROR_PUNT_INVAL; - } - - } - return HICN_ERROR_NONE; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: eval: (c-set-style "gnu") End: - */ diff --git a/hicn-plugin/src/punt.h b/hicn-plugin/src/punt.h deleted file mode 100644 index 0e821ccb7..000000000 --- a/hicn-plugin/src/punt.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (c) 2017-2019 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 __HICN_PUNT_H__ -#define __HICN_PUNT_H__ - -#include <vppinfra/error.h> -#include <vnet/fib/fib_types.h> -#include "hicn.h" -#include <vnet/classify/vnet_classify.h> - -#define HICN_CLASSIFY_TABLE_MEMORY_SIZE (2*1024*1024) // 2MB allocated for the classification table -#define HICN_PUNTING_BUFFER_SIZE_32 (32) -#define HICN_PUNTING_BUFFER_SIZE_48 (48) -#define HICN_PUNTING_BUFFER_SIZE_64 (64) -#define HICN_PUNTING_BUFFER_SIZE_80 (80) -#define HICN_PUNTING_BUFFER_SIZE_128 (128) - -/* Limits */ - -#define HICN_PUNT_IP4 0 -#define HICN_PUNT_IP6 1 - -#define HICN_MAX_INTFC 256 - -/* We also consider mask = 0 to match everything */ -#define HICN_PUNT_IP4_MASK 33 -#define HICN_PUNT_IP6_MASK 129 - -#define HICN_PUNT_IP_TYPE 0 -#define HICN_PUNT_UDP4_TYPE 1 -#define HICN_PUNT_UDP6_TYPE 2 - -#define HICN_PUNT_INVALID_PORT 0 -/* - * u32 ip4_vnet_tbl_idx[HICN_MAX_INTFC][2][3][HICN_PUNT_IP4_MASK]; - * //[skip][src][mask],[skip][dst][mask] u32 - * ip6_vnet_tbl_idx[HICN_MAX_INTFC][2][3][HICN_PUNT_IP6_MASK]; - * //[skip][src][mask],[skip][dst][mask] - */ -#define PUNT_MASK(ip) (ip->addr_len_bits + 1) -#define TABLE_ELT_P(ip, i, j, k, l) (ip->tbl + (4 * 2 * PUNT_MASK(ip)) * i + (2 * PUNT_MASK(ip)) * j + k * PUNT_MASK(ip) + l) -#define TABLE_ELT(ip, i, j, k, l) (*(TABLE_ELT_P(ip, i, j, k, l))) - -#define NO_L2 0 -#define ETH_L2 sizeof(ethernet_header_t) - -#define IPPROTO_MASK 0xFF - -/* Index to access vnet table index */ -#define HICN_PUNT_SRC 0 -#define HICN_PUNT_DST 1 - -#define HICN_PUNT_OK 0 -#define HICN_PUNT_ERR 1 - -#define HICNP_PUNY_INVALID_TBL ~0 - -/* Number of bytes before the next header/protocol field in ip6/4 */ -#define BYTES_TO_PROTOCOL_IP4 9 -#define BYTES_TO_NEXT_HEADER_IP6 6 - -#define PUNT_BUFFER_SIZE 100 /* B */ -#define CLASSIFIER_VECTOR_SIZE 16 /* B */ - -#define OP_DEL 0 -#define OP_ADD 1 -#define OP_DISABLE 0 -#define OP_ENABLE 1 - -/* vnet_classify_add_del_table */ -#define HICN_CLASSIFY_NO_NEXT_TABLE 0xFFFFFFFF -#define HICN_CLASSIFY_MISS_NEXT_INDEX 16 -#define HICN_CLASSIFY_CURRENT_DATA_FLAG CLASSIFY_FLAG_USE_CURR_DATA -#define HICN_CLASSIFY_NO_CURRENT_DATA_FLAG 0 -#define HICN_CLASSIFY_CURRENT_DATA_OFFSET 0 -#define HICN_CLASSIFY_DON_T_DEL_CHAIN 0 - -/* vnet_classify_add_del_session */ -#define HICN_CLASSIFY_OPAQUE_INDEX 0xFFFFFFFF -#define HICN_CLASSIFY_ADVANCE 0 -#define HICN_CLASSIFY_ACTION 0 -#define HICN_CLASSIFY_METADATA 0 - -/* This should be equal to the number of rules we expect in each table */ -#define HICN_CLASSIFY_NBUCKETS 3 - - -/* HICN punt node index */ -typedef struct _hicn_node_info_s -{ - u32 hicn_face_ip4_input_index; - u32 hicn_face_ip6_input_index; - u32 hicn_iface_ip4_input_index; - u32 hicn_iface_ip6_input_index; - u32 hicn_face_ip4_output_index; - u32 hicn_face_ip6_output_index; - u32 hicn_iface_ip4_output_index; - u32 hicn_iface_ip6_output_index; - u32 hicn_face_udp4_input_index; - u32 hicn_face_udp6_input_index; - u32 hicn_iface_udp4_input_index; - u32 hicn_iface_udp6_input_index; - u32 hicn_face_udp4_output_index; - u32 hicn_face_udp6_output_index; - u32 hicn_iface_udp4_output_index; - u32 hicn_iface_udp6_output_index; - u32 ip4_inacl_node_index; - u32 ip6_inacl_node_index; - u32 ip4_lookup_node_index; - u32 ip6_lookup_node_index; -} hicn_node_info_t; - -/* - * HICN global PUNT info - */ -typedef struct _hicn_punt_glb_s -{ - hicn_node_info_t hicn_node_info; - - /* - * The following nodes are used to create the vlib node graph, and - * point classified packets to the right node. - */ - u32 next_hit_interest_ipv4; - //node - graph index to forward packets to our hicn nodes - u32 next_hit_data_ipv4; - u32 next_hit_interest_ipv6; - //node - graph index to forward packets to our hicn nodes - u32 next_hit_data_ipv6; - u32 next_hit_interest_udp4; - //node - graph index to forward packets to our hicn nodes - u32 next_hit_data_udp4; - u32 next_hit_interest_udp6; - //node - graph index to forward packets to our hicn nodes - u32 next_hit_data_udp6; - - /* - * One table is created : - per interface : so that we can have - * different punted prefixes per interface, and thus decrease the - * amount of matched rules per packet. An interface will be - * consistently receiving packets with or without the ethernet - * header, and thus the offsets should always be correct. - per skip - * (assuming it is for the base offset (ethernet or not), in which - * case the interface should be sufficient. - per prefix length to - * allow for sorting later. - per src / dst (?) - * - * Note that there is no test on the packet type (v4 or v6), as they - * follow distinct paths in the vpp graph and will thus be dispatched - * to distinct classifiers. This is also why we duplicate the state - * for both IPv4 and IPv6 in this implementation. - * - * Tables are chained per interface in the order they are added. Each - * table consists in a set of rules (named sessions). - * - * / interface --> table i [.next_table_index=j] --> table j [.nti=~0] - * -- drop \ | | +-- on match, - * send to node m +-- [...] to node n - * - * For debugging purposes, you can use the following commands: - * - * vppctl show inacl type ip4 vppctl show inacl type ip6 - * - * vppctl show classify tables [verbose] - * - * TODO: - allow tables to be removed - sort tables with decreasing - * prefix length to allow for LPM. - directly access the linked list - * through vpp APIs and remove global variables. They are not - * sufficient anyways for removal. - */ - - /** - * Given the current implementation, the following multidimensional array - * stores the table indexes uniquerly identified by the 4-tuple (interface, - * skip, src/dst, mask). - * - * For flexibility, some macros and functions will be defined in the .c to - * manipulate this array. - */ - u32 ip4_vnet_tbl_idx[HICN_MAX_INTFC][4][2][HICN_PUNT_IP4_MASK]; - //[skip][src][mask],[skip][dst][mask] - u32 ip6_vnet_tbl_idx[HICN_MAX_INTFC][4][2][HICN_PUNT_IP6_MASK]; - //[skip][src][mask],[skip][dst][mask] - u32 udp44_vnet_tbl_idx[HICN_MAX_INTFC][4][2][HICN_PUNT_IP4_MASK]; - //[skip][src][mask],[skip][dst][mask] - u32 udp46_vnet_tbl_idx[HICN_MAX_INTFC][4][2][HICN_PUNT_IP6_MASK]; - //[skip][src][mask],[skip][dst][mask] - u32 udp64_vnet_tbl_idx[HICN_MAX_INTFC][4][2][HICN_PUNT_IP4_MASK]; - //[skip][src][mask],[skip][dst][mask] - u32 udp66_vnet_tbl_idx[HICN_MAX_INTFC][4][2][HICN_PUNT_IP6_MASK]; - //[skip][src][mask],[skip][dst][mask] - - /* - * The first and last tables associated to each interface (both for - * v4 and v6) are stored. They are respectively used to : - start - * classification on the correct table depending on the input - * interface: the assumption is that different interfaces with punt - * different prefixes, which should decreate the number of potential - * rules to match for each incoming packet. see. - * vnet_set_input_acl_intfc() - maintain the chaining between tables - * so that upon addition, the newly created table can be chained to - * the previous last one. - */ - u32 head_ip4[HICN_MAX_INTFC]; - u32 tail_ip4[HICN_MAX_INTFC]; - u32 head_ip6[HICN_MAX_INTFC]; - u32 tail_ip6[HICN_MAX_INTFC]; - -} hicn_punt_glb_t; - -extern hicn_punt_glb_t hicn_punt_glb; - - - -/* XXX The two following structs might be opaque */ - -#define NA 0 - -typedef struct -{ - u32 offset; - u32 len; /* bytes */ - u32 punt_id; /* see explanation in hicn_punt.c */ -} field_t; - -/* Format: _(name, base, layer, field, punt_id) */ -#define foreach_field \ - _(ipv6_src, 0, _ipv6_header_t, saddr, HICN_PUNT_SRC) \ - _(ipv6_dst, 0, _ipv6_header_t, daddr, HICN_PUNT_DST) \ - _(ipv6_protocol, 0, _ipv6_header_t, nxt, NA) \ - _(ipv4_src, 0, _ipv4_header_t, saddr, HICN_PUNT_SRC) \ - _(ipv4_dst, 0, _ipv4_header_t, daddr, HICN_PUNT_DST) \ - _(ipv4_protocol, 0, _ipv4_header_t, protocol, NA) \ - \ - _(ipv4_version, 0, _ipv4_header_t, version_ihl, NA) \ - _(ipv6_version, 0, _ipv6_header_t, vfc, NA) \ - _(udp4_sport, IPV4_HDRLEN, _udp_header_t, src_port, NA) \ - _(udp4_dport, IPV4_HDRLEN, _udp_header_t, dst_port, NA) \ - _(udp6_sport, IPV6_HDRLEN, _udp_header_t, src_port, NA) \ - _(udp6_dport, IPV6_HDRLEN, _udp_header_t, dst_port, NA) \ - _(udp6_protocol, 0, _ipv6_header_t, nxt, NA) \ - _(udp4_protocol, 0, _ipv4_header_t, protocol, NA) \ - _(udp46_src, IPV4_HDRLEN + UDP_HDRLEN, _ipv6_header_t, saddr, HICN_PUNT_SRC) \ - _(udp46_dst, IPV4_HDRLEN + UDP_HDRLEN, _ipv6_header_t, daddr, HICN_PUNT_DST) \ - _(udp44_src, IPV4_HDRLEN + UDP_HDRLEN, _ipv4_header_t, saddr, HICN_PUNT_SRC) \ - _(udp44_dst, IPV4_HDRLEN + UDP_HDRLEN, _ipv4_header_t, daddr, HICN_PUNT_DST) \ - _(udp66_src, IPV6_HDRLEN + UDP_HDRLEN, _ipv6_header_t, saddr, HICN_PUNT_SRC) \ - _(udp66_dst, IPV6_HDRLEN + UDP_HDRLEN, _ipv6_header_t, daddr, HICN_PUNT_DST) \ - _(udp64_src, IPV6_HDRLEN + UDP_HDRLEN, _ipv6_header_t, saddr, HICN_PUNT_SRC) \ - _(udp64_dst, IPV6_HDRLEN + UDP_HDRLEN, _ipv6_header_t, daddr, HICN_PUNT_DST) \ - - -#define _(NAME, BASE, LAYER, FIELD, PUNT_ID) \ - extern field_t NAME; -foreach_field -#undef _ - typedef struct -{ - u32 *tbl; - u8 addr_len_bits; - field_t *protocol_field; - field_t *version_field; - field_t *udp_sport; - field_t *udp_dport; - u8 ip_version; -} ip_version_t; - -extern ip_version_t ipv4; -extern ip_version_t ipv6; - - -/* ------------------------- */ - -/** - * @brief Punt table APIs - * - * Those APIs are called when the first punting table is created for a given - * interface, so as to point to the start of the chain. - */ -void -hicn_punt_enable_disable_vnet_ip4_table_on_intf (vlib_main_t * vm, - u32 sw_if_index, - int is_enable); -void -hicn_punt_enable_disable_vnet_ip6_table_on_intf (vlib_main_t * vm, - u32 sw_if_index, - int is_enable); -u32 hicn_punt_interest_data_for_udp (vlib_main_t * vm, - fib_prefix_t * prefix, - u32 swif, u8 punt_type, u16 sport, - u16 dport, u8 with_l2); -u32 hicn_punt_interest_data_for_ip (vlib_main_t * vm, - fib_prefix_t * prefix, - u32 swif, u8 type, u8 with_l2); -int hicn_punt_remove_ip6_address (vlib_main_t * vm, fib_prefix_t * prefix, - int skip, u32 swif, int is_enable, - u8 with_l2); -int hicn_punt_remove_ip4_address (vlib_main_t * vm, fib_prefix_t * prefix, - int skip, u32 swif, int is_enable, - u8 with_l2); -void hicn_punt_init (vlib_main_t * vm); - -int -hicn_punt_add_del_vnettbl (ip_version_t * ip, field_t * field, u8 mask, u32 - next_tbl_index, u32 intfc, u8 base_offset, - u8 use_current_data, int is_add); - -#define hicn_punt_add_vnettbl(ip, field, mask, next_tbl_index, intfc, base_offset, use_current_data) \ - (hicn_punt_add_del_vnettbl(ip, field, mask, next_tbl_index, intfc, base_offset, use_current_data, OP_ADD)) - -#define hicn_punt_del_vnettbl(ip, field, mask, next_tbl_index, intfc, base_offset) \ - (hicn_punt_add_del_vnettbl(ip, field, mask, next_tbl_index, intfc, base_offset, HICN_CLASSIFY_NO_CURRENT_DATA_FLAG, OP_DEL)) - -int -hicn_punt_add_del_vnetssn (ip_version_t * ip, field_t * field, - fib_prefix_t * prefix, - u32 next_hit_index, u32 intfc, u8 base_offset, - int is_add); - -#define hicn_punt_add_vnetssn(ip, field, addr, index, intfc, offset) \ - (hicn_punt_add_del_vnetssn(ip, field, addr, index, intfc, offset, OP_ADD)) - -#define hicn_punt_del_vnetssn(ip, field, addr, index, intfc, offset) \ - (hicn_punt_add_del_vnetssn(ip, field, addr, index, intfc, offset, OP_DEL)) - -#endif /* // __HICN_PUNT_H__ */ - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: eval: (c-set-style "gnu") End: - */ diff --git a/hicn-plugin/src/route.c b/hicn-plugin/src/route.c index 85ad9f729..c208dd4c1 100644 --- a/hicn-plugin/src/route.c +++ b/hicn-plugin/src/route.c @@ -138,6 +138,17 @@ hicn_route_add_nhops (hicn_face_id_t * face_id, u32 len, { u32 vft_id = hicn_dpo_get_vft_id (hicn_dpo_id); dpo_vft = hicn_dpo_get_vft (vft_id); + + hicn_face_t *face = + hicn_dpoi_get_from_idx (faces_dpo_tmp[i].dpoi_index); + //Disable feature on the interface + if (prefix->fp_proto == FIB_PROTOCOL_IP4) + vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4", + face->shared.sw_if, 1, 0, 0); + else if (prefix->fp_proto == FIB_PROTOCOL_IP6) + vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6", + face->shared.sw_if, 1, 0, 0); + ret = dpo_vft->hicn_dpo_add_update_nh (&faces_dpo_tmp[i], hicn_dpo_id->dpoi_index); } @@ -195,16 +206,20 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len, for (int i = 0; i < n_face_dpo; i++) { clib_memcpy (&nhops[i], &face_dpo_tmp[i], sizeof (dpo_id_t)); + hicn_face_t *face = + hicn_dpoi_get_from_idx (face_dpo_tmp[i].dpoi_index); + //Disable feature on the interface + if (prefix->fp_proto == FIB_PROTOCOL_IP4) + vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4", + face->shared.sw_if, 1, 0, 0); + else if (prefix->fp_proto == FIB_PROTOCOL_IP6) + vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6", + face->shared.sw_if, 1, 0, 0); } - ret = - default_dpo.hicn_dpo_create (prefix->fp_proto, nhops, n_face_dpo, - &dpo_idx); + default_dpo.hicn_dpo_create (prefix->fp_proto, nhops, n_face_dpo, + &dpo_idx); - if (ret) - { - return ret; - } /* the value we got when we registered */ /* * This should be taken from the name?!? the index of the @@ -225,7 +240,8 @@ hicn_route_add (hicn_face_id_t * face_id, u32 len, fib_table_entry_special_dpo_add (fib_index, prefix, hicn_fib_src, - FIB_ENTRY_FLAG_EXCLUSIVE, + (FIB_ENTRY_FLAG_EXCLUSIVE | + FIB_ENTRY_FLAG_LOOSE_URPF_EXEMPT), &dpo); /* We added a route, therefore add one lock to the table */ @@ -291,11 +307,21 @@ hicn_route_del_nhop (fib_prefix_t * prefix, hicn_face_id_t face_id) { vft_id = hicn_dpo_get_vft_id (hicn_dpo_id); dpo_vft = hicn_dpo_get_vft (vft_id); - ret = dpo_vft->hicn_dpo_del_nh (face_id, hicn_dpo_id->dpoi_index, - prefix); + + hicn_face_t *face = hicn_dpoi_get_from_idx (face_id); + //Disable feature on the interface + if (prefix->fp_proto == FIB_PROTOCOL_IP4) + vnet_feature_enable_disable ("ip4-local", "hicn-data-input-ip4", + face->shared.sw_if, 0, 0, 0); + else if (prefix->fp_proto == FIB_PROTOCOL_IP6) + vnet_feature_enable_disable ("ip6-local", "hicn-data-input-ip6", + face->shared.sw_if, 0, 0, 0); + + ret = dpo_vft->hicn_dpo_del_nh (face_id, hicn_dpo_id->dpoi_index); hicn_dpo_ctx_t *dpo_ctx = - dpo_vft->hicn_dpo_get_ctx (hicn_dpo_id->dpoi_index); + hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index); + if (ret == HICN_ERROR_NONE && !dpo_ctx->entry_count) ret = hicn_route_del (prefix); @@ -311,21 +337,15 @@ hicn_route_set_strategy (fib_prefix_t * prefix, u8 strategy_id) dpo_id_t new_dpo_id = DPO_INVALID; int ret; hicn_dpo_ctx_t *old_hicn_dpo_ctx; - const hicn_dpo_vft_t *old_dpo_vft; const hicn_dpo_vft_t *new_dpo_vft; index_t new_hicn_dpo_idx; u32 fib_index; - u32 old_vft_id; - ret = hicn_route_get_dpo (prefix, &hicn_dpo_id, &fib_index); if (ret == HICN_ERROR_NONE) { - old_vft_id = hicn_dpo_get_vft_id (hicn_dpo_id); - old_dpo_vft = hicn_dpo_get_vft (old_vft_id); - old_hicn_dpo_ctx = - old_dpo_vft->hicn_dpo_get_ctx (hicn_dpo_id->dpoi_index); + old_hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index); new_dpo_vft = hicn_dpo_get_vft_from_id (strategy_id); diff --git a/hicn-plugin/src/strategies/dpo_mw.c b/hicn-plugin/src/strategies/dpo_mw.c index 3317d31e0..eebb572c4 100644 --- a/hicn-plugin/src/strategies/dpo_mw.c +++ b/hicn-plugin/src/strategies/dpo_mw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -13,27 +13,10 @@ * limitations under the License. */ -#include "../strategy_dpo_ctx.h" #include "dpo_mw.h" #include "strategy_mw.h" #include "../strategy_dpo_manager.h" - -hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx_pool; - -const static char *const hicn_ip6_nodes[] = { - "hicn-mw-strategy", // this is the name you give your node in VLIB_REGISTER_NODE - NULL, -}; - -const static char *const hicn_ip4_nodes[] = { - "hicn-mw-strategy", // this is the name you give your node in VLIB_REGISTER_NODE - NULL, -}; - -const static char *const *const hicn_nodes_mw[DPO_PROTO_NUM] = { - [DPO_PROTO_IP6] = hicn_ip6_nodes, - [DPO_PROTO_IP4] = hicn_ip4_nodes, -}; +#include "../strategy_dpo_ctx.h" /** * @brief DPO type value for the mw_strategy @@ -41,16 +24,13 @@ const static char *const *const hicn_nodes_mw[DPO_PROTO_NUM] = { static dpo_type_t hicn_dpo_type_mw; static const hicn_dpo_vft_t hicn_dpo_mw_vft = { - .hicn_dpo_get_ctx = &hicn_strategy_mw_ctx_get, .hicn_dpo_is_type = &hicn_dpo_is_type_strategy_mw, .hicn_dpo_get_type = &hicn_dpo_strategy_mw_get_type, .hicn_dpo_module_init = &hicn_dpo_strategy_mw_module_init, .hicn_dpo_create = &hicn_strategy_mw_ctx_create, .hicn_dpo_add_update_nh = &hicn_strategy_mw_ctx_add_nh, .hicn_dpo_del_nh = &hicn_strategy_mw_ctx_del_nh, - .hicn_dpo_lock_dpo_ctx = &hicn_strategy_mw_ctx_lock, - .hicn_dpo_unlock_dpo_ctx = hicn_strategy_mw_ctx_unlock, - .format_hicn_dpo = &format_hicn_dpo_strategy_mw + .hicn_dpo_format = &hicn_strategy_mw_format_ctx }; int @@ -62,28 +42,15 @@ hicn_dpo_is_type_strategy_mw (const dpo_id_t * dpo) void hicn_dpo_strategy_mw_module_init (void) { - pool_validate_index (hicn_strategy_mw_ctx_pool, 0); /* * Register our type of dpo */ hicn_dpo_type_mw = - hicn_dpo_register_new_type (hicn_nodes_mw, &hicn_dpo_mw_vft, + hicn_dpo_register_new_type (hicn_nodes_strategy, &hicn_dpo_mw_vft, hicn_mw_strategy_get_vft (), &dpo_strategy_mw_ctx_vft); } -u8 * -format_hicn_dpo_strategy_mw (u8 * s, va_list * ap) -{ - - u32 indent = va_arg (*ap, u32); - s = - format (s, - "Static Weights: weights are updated by the control plane, next hop is the one with the maximum weight.\n", - indent); - return (s); -} - dpo_type_t hicn_dpo_strategy_mw_get_type (void) { @@ -92,33 +59,14 @@ hicn_dpo_strategy_mw_get_type (void) ////////////////////////////////////////////////////////////////////////////////////////////////// -void -hicn_strategy_mw_ctx_lock (dpo_id_t * dpo) -{ - hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = - (hicn_strategy_mw_ctx_t *) hicn_strategy_mw_ctx_get (dpo->dpoi_index); - - if (hicn_strategy_mw_ctx != NULL) - { - hicn_strategy_mw_ctx->default_ctx.locks++; - } -} -void -hicn_strategy_mw_ctx_unlock (dpo_id_t * dpo) +u8 * +hicn_strategy_mw_format_ctx (u8 * s, int n, ...) { - hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = - (hicn_strategy_mw_ctx_t *) hicn_strategy_mw_ctx_get (dpo->dpoi_index); - - if (hicn_strategy_mw_ctx != NULL) - { - hicn_strategy_mw_ctx->default_ctx.locks--; - - if (0 == hicn_strategy_mw_ctx->default_ctx.locks) - { - pool_put (hicn_strategy_mw_ctx_pool, hicn_strategy_mw_ctx); - } - } + va_list args; + va_start (args, n); + s = format_hicn_strategy_mw_ctx (s, &args); + return s; } u8 * @@ -126,24 +74,30 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap) { int i = 0; index_t index = va_arg (*ap, index_t); - hicn_strategy_mw_ctx_t *dpo = NULL; + hicn_dpo_ctx_t *dpo_ctx = NULL; + hicn_strategy_mw_ctx_t *mw_dpo_ctx = NULL; dpo_id_t *next_hop = NULL; hicn_face_vft_t *face_vft = NULL; u32 indent = va_arg (*ap, u32);; - dpo = (hicn_strategy_mw_ctx_t *) hicn_strategy_mw_ctx_get (index); + dpo_ctx = hicn_strategy_dpo_ctx_get (index); + if (dpo_ctx == NULL) + return s; + + mw_dpo_ctx = (hicn_strategy_mw_ctx_t *) dpo_ctx->data; s = format (s, "hicn-mw"); - for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && dpo != NULL; i++) + for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++) { u8 *buf = NULL; - if (i < dpo->default_ctx.entry_count) - buf = format(NULL, "FIB"); - else if (i >= HICN_PARAM_FIB_ENTRY_NHOPS_MAX - dpo->default_ctx.tfib_entry_count) - buf = format(NULL, "TFIB"); + if (i < dpo_ctx->entry_count) + buf = format (NULL, "FIB"); + else if (i >= + HICN_PARAM_FIB_ENTRY_NHOPS_MAX - dpo_ctx->tfib_entry_count) + buf = format (NULL, "TFIB"); else continue; - next_hop = &dpo->default_ctx.next_hops[i]; + next_hop = &dpo_ctx->next_hops[i]; face_vft = hicn_face_get_vft (next_hop->dpoi_type); if (face_vft != NULL) { @@ -151,7 +105,7 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap) s = format (s, "%U ", face_vft->format_face, next_hop->dpoi_index, indent); - s = format (s, "weight %u", dpo->weight[i]); + s = format (s, "weight %u", mw_dpo_ctx->weight[i]); s = format (s, " %s", buf); } } @@ -159,124 +113,49 @@ format_hicn_strategy_mw_ctx (u8 * s, va_list * ap) return (s); } -static index_t -hicn_strategy_mw_ctx_get_index (hicn_strategy_mw_ctx_t * cd) -{ - return (cd - hicn_strategy_mw_ctx_pool); -} - -int +void hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop, int nh_len, index_t * dpo_idx) { hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx; - int ret = HICN_ERROR_NONE, i; + hicn_dpo_ctx_t *hicn_strategy_ctx; /* Allocate a hicn_dpo_ctx on the vpp pool and initialize it */ - pool_get (hicn_strategy_mw_ctx_pool, hicn_strategy_mw_ctx); + hicn_strategy_ctx = hicn_strategy_dpo_ctx_alloc (); + hicn_strategy_mw_ctx = (hicn_strategy_mw_ctx_t *) hicn_strategy_ctx->data; - *dpo_idx = hicn_strategy_mw_ctx_get_index (hicn_strategy_mw_ctx); + *dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx); - init_dpo_ctx (&(hicn_strategy_mw_ctx->default_ctx)); - - for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && i < nh_len; i++) - { - clib_memcpy (&hicn_strategy_mw_ctx->default_ctx.next_hops[i], - &next_hop[i], sizeof (dpo_id_t)); - hicn_strategy_mw_ctx->default_ctx.entry_count++; - } + init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_mw); memset (hicn_strategy_mw_ctx->weight, 0, HICN_PARAM_FIB_ENTRY_NHOPS_MAX); - - return ret; -} - -hicn_dpo_ctx_t * -hicn_strategy_mw_ctx_get (index_t index) -{ - hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = NULL; - if (!pool_is_free_index (hicn_strategy_mw_ctx_pool, index)) - { - hicn_strategy_mw_ctx = - (pool_elt_at_index (hicn_strategy_mw_ctx_pool, index)); - } - - return (hicn_dpo_ctx_t *)hicn_strategy_mw_ctx; } int hicn_strategy_mw_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx) { - hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = - (hicn_strategy_mw_ctx_t *) hicn_strategy_mw_ctx_get (dpo_idx); + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + u8 pos = 0; - if (hicn_strategy_mw_ctx == NULL) + if (hicn_strategy_dpo_ctx == NULL) { return HICN_ERROR_STRATEGY_NOT_FOUND; } - int empty = hicn_strategy_mw_ctx->default_ctx.entry_count; - - /* Iterate through the list of faces to add new faces */ - for (int i = 0; i < hicn_strategy_mw_ctx->default_ctx.entry_count; i++) - { - if (!memcmp - (nh, &hicn_strategy_mw_ctx->default_ctx.next_hops[i], - sizeof (dpo_id_t))) - { - /* If face is marked as deleted, ignore it */ - hicn_face_t *face = - hicn_dpoi_get_from_idx (hicn_strategy_mw_ctx-> - default_ctx.next_hops[i].dpoi_index); - if (face->shared.flags & HICN_FACE_FLAGS_DELETED) - { - continue; - } - return HICN_ERROR_DPO_CTX_NHOPS_EXISTS; - } - } - - /* Get an empty place */ - if (empty > HICN_PARAM_FIB_ENTRY_NHOPS_MAX) - { - return HICN_ERROR_DPO_CTX_NHOPS_NS; - } - - clib_memcpy (&hicn_strategy_mw_ctx->default_ctx.next_hops[empty], nh, - sizeof (dpo_id_t)); - hicn_strategy_mw_ctx->default_ctx.entry_count++; + hicn_strategy_dpo_ctx_add_nh (nh, hicn_strategy_dpo_ctx, &pos); + hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = + (hicn_strategy_mw_ctx_t *) & hicn_strategy_dpo_ctx->data; + hicn_strategy_mw_ctx->weight[pos] = DEFAULT_WEIGHT; return HICN_ERROR_NONE; } int -hicn_strategy_mw_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, - fib_prefix_t * fib_pfx) +hicn_strategy_mw_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx) { - hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = - (hicn_strategy_mw_ctx_t *) hicn_strategy_mw_ctx_get (dpo_idx); - int ret = HICN_ERROR_DPO_CTX_NOT_FOUND; - dpo_id_t invalid = NEXT_HOP_INVALID; - - if (hicn_strategy_mw_ctx == NULL) - return HICN_ERROR_STRATEGY_NOT_FOUND; - - for (int i = 0; i < hicn_strategy_mw_ctx->default_ctx.entry_count; i++) - { - if (hicn_strategy_mw_ctx->default_ctx.next_hops[i].dpoi_index == - face_id) - { - hicn_face_unlock (&hicn_strategy_mw_ctx->default_ctx. - next_hops[i]); - hicn_strategy_mw_ctx->default_ctx.entry_count--; - hicn_strategy_mw_ctx->default_ctx.next_hops[i] = hicn_strategy_mw_ctx->default_ctx.next_hops[hicn_strategy_mw_ctx->default_ctx.entry_count]; - hicn_strategy_mw_ctx->default_ctx.next_hops[hicn_strategy_mw_ctx->default_ctx.entry_count] = invalid; - ret = HICN_ERROR_NONE; - break; - } - } - - return ret; + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + //No need to flush the weights, they are initialized when a dpo_ctx is created; + return hicn_strategy_dpo_ctx_del_nh (face_id, hicn_strategy_dpo_ctx); } /* diff --git a/hicn-plugin/src/strategies/dpo_mw.h b/hicn-plugin/src/strategies/dpo_mw.h index a8c0a3b43..ccc8d044f 100644 --- a/hicn-plugin/src/strategies/dpo_mw.h +++ b/hicn-plugin/src/strategies/dpo_mw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -19,28 +19,14 @@ #include <vnet/dpo/dpo.h> #include "../strategy_dpo_ctx.h" +#define DEFAULT_WEIGHT 0 + typedef struct hicn_strategy_mw_ctx_s { - hicn_dpo_ctx_t default_ctx; - u8 weight[HICN_PARAM_FIB_ENTRY_NHOPS_MAX]; } hicn_strategy_mw_ctx_t; /** - * @brief Lock the mw ctx - * - * @param dpo Identifier of the dpo of the mw ctx - */ -void hicn_strategy_mw_ctx_lock (dpo_id_t * dpo); - -/** - * @brief Unlock the mw ctx - * - * @param dpo Identifier of the dpo of the mw ctx - */ -void hicn_strategy_mw_ctx_unlock (dpo_id_t * dpo); - -/** * @brief Format the dpo ctx for a human-readable string * * @param s String to which to append the formatted dpo ctx @@ -51,8 +37,8 @@ void hicn_strategy_mw_ctx_unlock (dpo_id_t * dpo); u8 *format_hicn_strategy_mw_ctx (u8 * s, va_list * ap); const static dpo_vft_t dpo_strategy_mw_ctx_vft = { - .dv_lock = hicn_strategy_mw_ctx_lock, - .dv_unlock = hicn_strategy_mw_ctx_unlock, + .dv_lock = hicn_strategy_dpo_ctx_lock, + .dv_unlock = hicn_strategy_dpo_ctx_unlock, .dv_format = format_hicn_strategy_mw_ctx, }; @@ -73,7 +59,7 @@ hicn_dpo_ctx_t *hicn_strategy_mw_ctx_get (index_t index); * @param dpo_idx index_t that will hold the index of the created dpo ctx * @return HICN_ERROR_NONE if the creation was fine, otherwise EINVAL */ -int +void hicn_strategy_mw_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop, int nh_len, index_t * dpo_idx); @@ -100,9 +86,7 @@ int hicn_strategy_mw_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx); * @return HICN_ERROR_NONE if the update or insert was fine, * otherwise HICN_ERROR_DPO_CTS_NOT_FOUND */ -int -hicn_strategy_mw_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, - fib_prefix_t * fib_pfx); +int hicn_strategy_mw_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx); /** * @brief Prefetch a dpo @@ -111,14 +95,40 @@ hicn_strategy_mw_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, */ void hicn_strategy_mw_ctx_prefetch (index_t dpo_idx); +/** + * @brief Return true if the dpo is of type strategy mw + * + * @param dpo Dpo to check the type + */ int hicn_dpo_is_type_strategy_mw (const dpo_id_t * dpo); +/** + * @brief Initialize the Maximum Weight strategy + */ void hicn_dpo_strategy_mw_module_init (void); +/** + * @brief Return the dpo type for the Maximum Weight strategy + */ dpo_type_t hicn_dpo_strategy_mw_get_type (void); +/** + * @brief Format the dpo ctx for the strategy Maximum Weight + * + * @param s String to append the formatted dpo ctx + * @param ap List of arguments to format + */ u8 *format_hicn_dpo_strategy_mw (u8 * s, va_list * ap); +/** + * @brief Format the dpo ctx for the strategy Maximum Weight. To + * call from other functions + * + * @param s String to append the formatted dpo ctx + * @param ... List of arguments to format + */ +u8 *hicn_strategy_mw_format_ctx (u8 * s, int n, ...); + #endif // __HICN_DPO_MW_H__ diff --git a/hicn-plugin/src/strategies/dpo_rr.c b/hicn-plugin/src/strategies/dpo_rr.c index dfdc83ff4..a67b06acb 100644 --- a/hicn-plugin/src/strategies/dpo_rr.c +++ b/hicn-plugin/src/strategies/dpo_rr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -13,27 +13,10 @@ * limitations under the License. */ -#include "../strategy_dpo_ctx.h" #include "dpo_rr.h" #include "strategy_rr.h" #include "../strategy_dpo_manager.h" - -hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx_pool; - -const static char *const hicn_ip6_nodes[] = { - "hicn-rr-strategy", // this is the name you give your node in VLIB_REGISTER_NODE - NULL, -}; - -const static char *const hicn_ip4_nodes[] = { - "hicn-rr-strategy", // this is the name you give your node in VLIB_REGISTER_NODE - NULL, -}; - -const static char *const *const hicn_nodes_rr[DPO_PROTO_NUM] = { - [DPO_PROTO_IP6] = hicn_ip6_nodes, - [DPO_PROTO_IP4] = hicn_ip4_nodes, -}; +#include "../strategy_dpo_ctx.h" /** * @brief DPO type value for the rr_strategy @@ -41,16 +24,13 @@ const static char *const *const hicn_nodes_rr[DPO_PROTO_NUM] = { static dpo_type_t hicn_dpo_type_rr; static const hicn_dpo_vft_t hicn_dpo_rr_vft = { - .hicn_dpo_get_ctx = &hicn_strategy_rr_ctx_get, .hicn_dpo_is_type = &hicn_dpo_is_type_strategy_rr, .hicn_dpo_get_type = &hicn_dpo_strategy_rr_get_type, .hicn_dpo_module_init = &hicn_dpo_strategy_rr_module_init, .hicn_dpo_create = &hicn_strategy_rr_ctx_create, .hicn_dpo_add_update_nh = &hicn_strategy_rr_ctx_add_nh, .hicn_dpo_del_nh = &hicn_strategy_rr_ctx_del_nh, - .hicn_dpo_lock_dpo_ctx = &hicn_strategy_rr_ctx_lock, - .hicn_dpo_unlock_dpo_ctx = hicn_strategy_rr_ctx_unlock, - .format_hicn_dpo = &format_hicn_dpo_strategy_rr + .hicn_dpo_format = &hicn_strategy_rr_format_ctx }; int @@ -62,28 +42,15 @@ hicn_dpo_is_type_strategy_rr (const dpo_id_t * dpo) void hicn_dpo_strategy_rr_module_init (void) { - pool_validate_index (hicn_strategy_rr_ctx_pool, 0); /* * Register our type of dpo */ hicn_dpo_type_rr = - hicn_dpo_register_new_type (hicn_nodes_rr, &hicn_dpo_rr_vft, + hicn_dpo_register_new_type (hicn_nodes_strategy, &hicn_dpo_rr_vft, hicn_rr_strategy_get_vft (), &dpo_strategy_rr_ctx_vft); } -u8 * -format_hicn_dpo_strategy_rr (u8 * s, va_list * ap) -{ - - u32 indent = va_arg (*ap, u32); - s = - format (s, - "Round Robin: next hop is chosen ciclying between all the available next hops, one after the other.\n", - indent); - return (s); -} - dpo_type_t hicn_dpo_strategy_rr_get_type (void) { @@ -92,32 +59,14 @@ hicn_dpo_strategy_rr_get_type (void) ////////////////////////////////////////////////////////////////////////////////////////////////// -void -hicn_strategy_rr_ctx_lock (dpo_id_t * dpo) -{ - hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx = - (hicn_strategy_rr_ctx_t *) hicn_strategy_rr_ctx_get (dpo->dpoi_index); - - if (hicn_strategy_rr_ctx != NULL) - { - hicn_strategy_rr_ctx->default_ctx.locks++; - } -} -void -hicn_strategy_rr_ctx_unlock (dpo_id_t * dpo) +u8 * +hicn_strategy_rr_format_ctx (u8 * s, int n, ...) { - hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx = - (hicn_strategy_rr_ctx_t *) hicn_strategy_rr_ctx_get (dpo->dpoi_index); - if (hicn_strategy_rr_ctx != NULL) - { - hicn_strategy_rr_ctx->default_ctx.locks--; - - if (0 == hicn_strategy_rr_ctx->default_ctx.locks) - { - pool_put (hicn_strategy_rr_ctx_pool, hicn_strategy_rr_ctx); - } - } + va_list args; + va_start (args, n); + s = format_hicn_strategy_rr_ctx (s, &args); + return s; } u8 * @@ -125,28 +74,34 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap) { int i = 0; index_t index = va_arg (*ap, index_t); - hicn_strategy_rr_ctx_t *dpo = NULL; + hicn_dpo_ctx_t *dpo_ctx = NULL; + hicn_strategy_rr_ctx_t *rr_dpo_ctx = NULL; dpo_id_t *next_hop = NULL; hicn_face_vft_t *face_vft = NULL; - u32 indent = va_arg (*ap, u32);; + u32 indent = va_arg (*ap, u32); - dpo = (hicn_strategy_rr_ctx_t *) hicn_strategy_rr_ctx_get (index); + dpo_ctx = hicn_strategy_dpo_ctx_get (index); + if (dpo_ctx == NULL) + return s; + + rr_dpo_ctx = (hicn_strategy_rr_ctx_t *) dpo_ctx->data; s = format (s, "hicn-rr, next hop Face %d", - dpo->default_ctx.next_hops[dpo->current_nhop].dpoi_index); + dpo_ctx->next_hops[rr_dpo_ctx->current_nhop].dpoi_index); - for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && dpo != NULL; i++) + for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++) { u8 *buf = NULL; - if (i < dpo->default_ctx.entry_count) - buf = format(NULL, "FIB"); - else if (i >= HICN_PARAM_FIB_ENTRY_NHOPS_MAX - dpo->default_ctx.tfib_entry_count) - buf = format(NULL, "TFIB"); + if (i < dpo_ctx->entry_count) + buf = format (NULL, "FIB"); + else if (i >= + HICN_PARAM_FIB_ENTRY_NHOPS_MAX - dpo_ctx->tfib_entry_count) + buf = format (NULL, "TFIB"); else continue; - next_hop = &dpo->default_ctx.next_hops[i]; + next_hop = &dpo_ctx->next_hops[i]; face_vft = hicn_face_get_vft (next_hop->dpoi_type); if (face_vft != NULL) { @@ -154,132 +109,53 @@ format_hicn_strategy_rr_ctx (u8 * s, va_list * ap) s = format (s, "%U ", face_vft->format_face, next_hop->dpoi_index, indent); - s = format (s, " %s", buf); + s = format (s, " %s", buf); } } return (s); } -static index_t -hicn_strategy_rr_ctx_get_index (hicn_strategy_rr_ctx_t * cd) -{ - return (cd - hicn_strategy_rr_ctx_pool); -} - -int +void hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop, int nh_len, index_t * dpo_idx) { hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx; - int ret = HICN_ERROR_NONE, i; + hicn_dpo_ctx_t *hicn_strategy_ctx; /* Allocate a hicn_dpo_ctx on the vpp pool and initialize it */ - pool_get (hicn_strategy_rr_ctx_pool, hicn_strategy_rr_ctx); + hicn_strategy_ctx = hicn_strategy_dpo_ctx_alloc (); + hicn_strategy_rr_ctx = (hicn_strategy_rr_ctx_t *) hicn_strategy_ctx->data; - *dpo_idx = hicn_strategy_rr_ctx_get_index (hicn_strategy_rr_ctx); + *dpo_idx = hicn_strategy_dpo_ctx_get_index (hicn_strategy_ctx); - init_dpo_ctx (&(hicn_strategy_rr_ctx->default_ctx)); - - for (i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && i < nh_len; i++) - { - clib_memcpy (&hicn_strategy_rr_ctx->default_ctx.next_hops[i], - &next_hop[i], sizeof (dpo_id_t)); - hicn_strategy_rr_ctx->default_ctx.entry_count++; - } + init_dpo_ctx (hicn_strategy_ctx, next_hop, nh_len, hicn_dpo_type_rr); hicn_strategy_rr_ctx->current_nhop = 0; - - return ret; -} - -hicn_dpo_ctx_t * -hicn_strategy_rr_ctx_get (index_t index) -{ - hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx = NULL; - if (!pool_is_free_index (hicn_strategy_rr_ctx_pool, index)) - { - hicn_strategy_rr_ctx = - (pool_elt_at_index (hicn_strategy_rr_ctx_pool, index)); - } - return (hicn_dpo_ctx_t *)hicn_strategy_rr_ctx; } int hicn_strategy_rr_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx) { - hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx = - (hicn_strategy_rr_ctx_t *) hicn_strategy_rr_ctx_get (dpo_idx); + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + u8 pos = 0; - if (hicn_strategy_rr_ctx == NULL) + if (hicn_strategy_dpo_ctx == NULL) { return HICN_ERROR_STRATEGY_NOT_FOUND; } - int empty = hicn_strategy_rr_ctx->default_ctx.entry_count; - - /* Iterate through the list of faces to add new faces */ - for (int i = 0; i < hicn_strategy_rr_ctx->default_ctx.entry_count; i++) - { - if (!memcmp - (nh, &hicn_strategy_rr_ctx->default_ctx.next_hops[i], - sizeof (dpo_id_t))) - { - /* If face is marked as deleted, ignore it */ - hicn_face_t *face = - hicn_dpoi_get_from_idx (hicn_strategy_rr_ctx->default_ctx. - next_hops[i].dpoi_index); - if (face->shared.flags & HICN_FACE_FLAGS_DELETED) - { - continue; - } - return HICN_ERROR_DPO_CTX_NHOPS_EXISTS; - } - } - - /* Get an empty place */ - if (empty > HICN_PARAM_FIB_ENTRY_NHOPS_MAX) - { - return HICN_ERROR_DPO_CTX_NHOPS_NS; - } - - clib_memcpy (&hicn_strategy_rr_ctx->default_ctx.next_hops[empty], nh, - sizeof (dpo_id_t)); - hicn_strategy_rr_ctx->default_ctx.entry_count++; - + hicn_strategy_dpo_ctx_add_nh (nh, hicn_strategy_dpo_ctx, &pos); + //nothing else to initialize in this strategy return HICN_ERROR_NONE; } int -hicn_strategy_rr_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, - fib_prefix_t * fib_pfx) +hicn_strategy_rr_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx) { - hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx = - (hicn_strategy_rr_ctx_t *) hicn_strategy_rr_ctx_get (dpo_idx); - int ret = HICN_ERROR_DPO_CTX_NOT_FOUND; - dpo_id_t invalid = NEXT_HOP_INVALID; - - if (hicn_strategy_rr_ctx == NULL) - { - return HICN_ERROR_STRATEGY_NOT_FOUND; - } - - for (int i = 0; i < hicn_strategy_rr_ctx->default_ctx.entry_count; i++) - { - if (hicn_strategy_rr_ctx->default_ctx.next_hops[i].dpoi_index == - face_id) - { - hicn_face_unlock (&hicn_strategy_rr_ctx-> - default_ctx.next_hops[i]); - hicn_strategy_rr_ctx->default_ctx.entry_count--; - hicn_strategy_rr_ctx->default_ctx.next_hops[i] = hicn_strategy_rr_ctx->default_ctx.next_hops[hicn_strategy_rr_ctx->default_ctx.entry_count]; - hicn_strategy_rr_ctx->default_ctx.next_hops[hicn_strategy_rr_ctx->default_ctx.entry_count] = invalid; - ret = HICN_ERROR_NONE; - break; - } - } - - return ret; + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + //No need to change the current_nhop. It will be updated at the next selection. + return hicn_strategy_dpo_ctx_del_nh (face_id, hicn_strategy_dpo_ctx); } /* diff --git a/hicn-plugin/src/strategies/dpo_rr.h b/hicn-plugin/src/strategies/dpo_rr.h index a12183653..8afd0dabc 100644 --- a/hicn-plugin/src/strategies/dpo_rr.h +++ b/hicn-plugin/src/strategies/dpo_rr.h @@ -25,26 +25,10 @@ typedef struct hicn_strategy_rr_ctx_s { - hicn_dpo_ctx_t default_ctx; - u8 current_nhop; } hicn_strategy_rr_ctx_t; /** - * @brief Lock the round robin ctx - * - * @param dpo Identifier of the dpo of the rr ctx - */ -void hicn_strategy_rr_ctx_lock (dpo_id_t * dpo); - -/** - * @brief Unlock the round robin ctx - * - * @param dpo Identifier of the dpo of the rr ctx - */ -void hicn_strategy_rr_ctx_unlock (dpo_id_t * dpo); - -/** * @brief Format the dpo ctx for a human-readable string * * @param s String to which to append the formatted dpo ctx @@ -55,8 +39,8 @@ void hicn_strategy_rr_ctx_unlock (dpo_id_t * dpo); u8 *format_hicn_strategy_rr_ctx (u8 * s, va_list * ap); const static dpo_vft_t dpo_strategy_rr_ctx_vft = { - .dv_lock = hicn_strategy_rr_ctx_lock, - .dv_unlock = hicn_strategy_rr_ctx_unlock, + .dv_lock = hicn_strategy_dpo_ctx_lock, + .dv_unlock = hicn_strategy_dpo_ctx_unlock, .dv_format = format_hicn_strategy_rr_ctx, }; @@ -77,7 +61,7 @@ hicn_dpo_ctx_t *hicn_strategy_rr_ctx_get (index_t index); * @param dpo_idx index_t that will hold the index of the created dpo ctx * @return HICN_ERROR_NONE if the creation was fine, otherwise EINVAL */ -int +void hicn_strategy_rr_ctx_create (dpo_proto_t proto, const dpo_id_t * next_hop, int nh_len, index_t * dpo_idx); @@ -104,9 +88,7 @@ int hicn_strategy_rr_ctx_add_nh (const dpo_id_t * nh, index_t dpo_idx); * @return HICN_ERROR_NONE if the update or insert was fine, * otherwise HICN_ERROR_DPO_CTS_NOT_FOUND */ -int -hicn_strategy_rr_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, - fib_prefix_t * fib_pfx); +int hicn_strategy_rr_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx); /** * @brief Prefetch a dpo @@ -115,14 +97,40 @@ hicn_strategy_rr_ctx_del_nh (hicn_face_id_t face_id, index_t dpo_idx, */ void hicn_strategy_rr_ctx_prefetch (index_t dpo_idx); +/** + * @brief Return true if the dpo is of type strategy rr + * + * @param dpo Dpo to check the type + */ int hicn_dpo_is_type_strategy_rr (const dpo_id_t * dpo); +/** + * @brief Initialize the Round Robin strategy + */ void hicn_dpo_strategy_rr_module_init (void); +/** + * @brief Return the dpo type for the Round Robin strategy + */ dpo_type_t hicn_dpo_strategy_rr_get_type (void); +/** + * @brief Format the dpo ctx for the strategy Round Robin + * + * @param s String to append the formatted dpo ctx + * @param ap List of arguments to format + */ u8 *format_hicn_dpo_strategy_rr (u8 * s, va_list * ap); +/** + * @brief Format the dpo ctx for the strategy Round Robin. To + * call from other functions + * + * @param s String to append the formatted dpo ctx + * @param ... List of arguments to format + */ +u8 *hicn_strategy_rr_format_ctx (u8 * s, int n, ...); + #endif // __HICN_DPO_RR_H__ diff --git a/hicn-plugin/src/strategies/strategy_mw.c b/hicn-plugin/src/strategies/strategy_mw.c index 40e062bd8..2422d4fed 100644 --- a/hicn-plugin/src/strategies/strategy_mw.c +++ b/hicn-plugin/src/strategies/strategy_mw.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -12,16 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include <vlib/vlib.h> -#include <vnet/vnet.h> - +#include "dpo_mw.h" #include "../strategy.h" #include "../strategy_dpo_ctx.h" -#include "dpo_mw.h" #include "../faces/face.h" -#include "../route.h" -#include "../pcs.h" +#include "../hashtb.h" #include "../strategy_dpo_manager.h" /* Simple strategy that chooses the next hop with the maximum weight */ @@ -32,20 +27,17 @@ void hicn_on_interest_timeout_mw (index_t dpo_idx); u32 hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface); u32 get_strategy_node_index_mw (void); +u8 *hicn_strategy_format_trace_mw (u8 * s, hicn_strategy_trace_t * t); +u8 *hicn_strategy_format_mw (u8 * s, va_list * ap); + static hicn_strategy_vft_t hicn_strategy_mw_vft = { .hicn_receive_data = &hicn_receive_data_mw, .hicn_add_interest = &hicn_add_interest_mw, .hicn_on_interest_timeout = &hicn_on_interest_timeout_mw, .hicn_select_next_hop = &hicn_select_next_hop_mw, - .get_strategy_node_index = get_strategy_node_index_mw -}; - -/* Stats string values */ -static char *hicn_strategy_error_strings[] = { -#define _(sym, string) string, - foreach_hicnfwd_error -#undef _ + .hicn_format_strategy_trace = hicn_strategy_format_trace_mw, + .hicn_format_strategy = &hicn_strategy_format_mw }; /* @@ -57,29 +49,22 @@ hicn_mw_strategy_get_vft (void) return &hicn_strategy_mw_vft; } -/* Registration struct for a graph node */ -vlib_node_registration_t hicn_mw_strategy_node; - -u32 -get_strategy_node_index_mw (void) -{ - return hicn_mw_strategy_node.index; -} - /* DPO should be give in input as it containes all the information to calculate the next hops*/ u32 hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface) { - hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = - (hicn_strategy_mw_ctx_t *) hicn_strategy_mw_ctx_get (dpo_idx); + hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); - if(hicn_strategy_mw_ctx == NULL) + if (dpo_ctx == NULL) return HICN_ERROR_STRATEGY_NOT_FOUND; + hicn_strategy_mw_ctx_t *hicn_strategy_mw_ctx = + (hicn_strategy_mw_ctx_t *) dpo_ctx->data; + u8 next_hop_index = 0; - for (int i = 0; i < hicn_strategy_mw_ctx->default_ctx.entry_count; i++) + for (int i = 0; i < dpo_ctx->entry_count; i++) { - if (dpo_id_is_valid (&hicn_strategy_mw_ctx->default_ctx.next_hops[i])) + if (dpo_id_is_valid (&dpo_ctx->next_hops[i])) { if (hicn_strategy_mw_ctx->weight[next_hop_index] < hicn_strategy_mw_ctx->weight[i]) @@ -89,33 +74,21 @@ hicn_select_next_hop_mw (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface) } } - if (!dpo_id_is_valid - (&hicn_strategy_mw_ctx->default_ctx.next_hops[next_hop_index])) + if (!dpo_id_is_valid (&dpo_ctx->next_hops[next_hop_index])) return HICN_ERROR_STRATEGY_NH_NOT_FOUND; - *outface = - (dpo_id_t *) & hicn_strategy_mw_ctx->default_ctx. - next_hops[next_hop_index]; + *outface = (dpo_id_t *) & dpo_ctx->next_hops[next_hop_index]; return HICN_ERROR_NONE; } -uword -hicn_mw_strategy_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - return hicn_forward_interest_fn (vm, node, frame, &hicn_strategy_mw_vft, - hicn_dpo_strategy_mw_get_type (), - &hicn_mw_strategy_node); -} - void hicn_add_interest_mw (index_t dpo_ctx_idx, hicn_hash_entry_t * hash_entry) { hash_entry->dpo_ctx_id = dpo_ctx_idx; dpo_id_t hicn_dpo_id = { hicn_dpo_strategy_mw_get_type (), 0, 0, dpo_ctx_idx }; - hicn_strategy_mw_ctx_lock (&hicn_dpo_id); + hicn_strategy_dpo_ctx_lock (&hicn_dpo_id); hash_entry->vft_id = hicn_dpo_get_vft_id (&hicn_dpo_id); } @@ -132,41 +105,25 @@ hicn_receive_data_mw (index_t dpo_idx, int nh_idx) /* packet trace format function */ -static u8 * -hicn_strategy_format_trace_mw (u8 * s, va_list * args) +u8 * +hicn_strategy_format_trace_mw (u8 * s, hicn_strategy_trace_t * t) { - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - hicn_strategy_trace_t *t = va_arg (*args, hicn_strategy_trace_t *); - s = format (s, "Strategy_mw: pkt: %d, sw_if_index %d, next index %d", (int) t->pkt_type, t->sw_if_index, t->next_index); return (s); } -/* - * Node registration for the forwarder node - */ -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (hicn_mw_strategy_node) = +u8 * +hicn_strategy_format_mw (u8 * s, va_list * ap) { - .name = "hicn-mw-strategy", - .function = hicn_mw_strategy_node_fn, - .vector_size = sizeof (u32), - .runtime_data_bytes = sizeof (int) + sizeof(hicn_pit_cs_t *), - .format_trace = hicn_strategy_format_trace_mw, - .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = ARRAY_LEN (hicn_strategy_error_strings), - .error_strings = hicn_strategy_error_strings, - .n_next_nodes = HICN_STRATEGY_N_NEXT, - .next_nodes = { - [HICN_STRATEGY_NEXT_INTEREST_HITPIT] = "hicn-interest-hitpit", - [HICN_STRATEGY_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs", - [HICN_STRATEGY_NEXT_ERROR_DROP] = "error-drop", - [HICN_STRATEGY_NEXT_EMPTY] = "ip4-lookup", - }, -}; -/* *INDENT-ON* */ + + u32 indent = va_arg (*ap, u32); + s = + format (s, + "Static Weights: weights are updated by the control plane, next hop is the one with the maximum weight.\n", + indent); + return (s); +} /* * fd.io coding-style-patch-verification: ON diff --git a/hicn-plugin/src/strategies/strategy_mw.h b/hicn-plugin/src/strategies/strategy_mw.h index 10b08c05f..f64f1fdc7 100644 --- a/hicn-plugin/src/strategies/strategy_mw.h +++ b/hicn-plugin/src/strategies/strategy_mw.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -18,6 +18,9 @@ #include "../strategy.h" +/** + * @brief Return the vft for the Maximum Weight strategy + */ hicn_strategy_vft_t *hicn_mw_strategy_get_vft (void); #endif // __HICN_STRATEGY_MW_H__ diff --git a/hicn-plugin/src/strategies/strategy_mw_cli.c b/hicn-plugin/src/strategies/strategy_mw_cli.c index 50d4d21f0..701f96fa7 100644 --- a/hicn-plugin/src/strategies/strategy_mw_cli.c +++ b/hicn-plugin/src/strategies/strategy_mw_cli.c @@ -38,8 +38,6 @@ hicn_mw_strategy_cli_set_weight_command_fn (vlib_main_t * vm, u32 weight = HICN_PARAM_FIB_ENTRY_NHOP_WGHT_DFLT; hicn_dpo_ctx_t *hicn_dpo_ctx; const dpo_id_t *hicn_dpo_id; - u32 vft_id; - const hicn_dpo_vft_t *dpo_vft; /* Get a line of input. */ unformat_input_t _line_input, *line_input = &_line_input; @@ -79,14 +77,14 @@ hicn_mw_strategy_cli_set_weight_command_fn (vlib_main_t * vm, goto done; } - prefix.fp_proto = ip46_address_is_ip4(&prefix.fp_addr) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; + prefix.fp_proto = + ip46_address_is_ip4 (&prefix. + fp_addr) ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6; ret = hicn_route_get_dpo (&prefix, &hicn_dpo_id, &fib_index); if (ret == HICN_ERROR_NONE) { - vft_id = hicn_dpo_get_vft_id (hicn_dpo_id); - dpo_vft = hicn_dpo_get_vft (vft_id); - hicn_dpo_ctx = dpo_vft->hicn_dpo_get_ctx (hicn_dpo_id->dpoi_index); + hicn_dpo_ctx = hicn_strategy_dpo_ctx_get (hicn_dpo_id->dpoi_index); if (hicn_dpo_ctx == NULL || hicn_dpo_id->dpoi_type != hicn_dpo_strategy_mw_get_type ()) diff --git a/hicn-plugin/src/strategies/strategy_rr.c b/hicn-plugin/src/strategies/strategy_rr.c index 53b9b688f..cdcca7f2a 100644 --- a/hicn-plugin/src/strategies/strategy_rr.c +++ b/hicn-plugin/src/strategies/strategy_rr.c @@ -13,15 +13,11 @@ * limitations under the License. */ -#include <vlib/vlib.h> -#include <vnet/vnet.h> - +#include "dpo_rr.h" #include "../strategy.h" #include "../strategy_dpo_ctx.h" -#include "dpo_rr.h" #include "../faces/face.h" -#include "../route.h" -#include "../pcs.h" +#include "../hashtb.h" #include "../strategy_dpo_manager.h" /* Simple strategy that chooses the next hop with the maximum weight */ @@ -31,21 +27,17 @@ void hicn_add_interest_rr (index_t dpo_idx, hicn_hash_entry_t * pit_entry); void hicn_on_interest_timeout_rr (index_t dpo_idx); u32 hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface); -u32 get_strategy_node_index_rr (void); +u8 *hicn_strategy_format_trace_rr (u8 * s, hicn_strategy_trace_t * t); +u8 *hicn_strategy_format_rr (u8 * s, va_list * ap); + static hicn_strategy_vft_t hicn_strategy_rr_vft = { .hicn_receive_data = &hicn_receive_data_rr, .hicn_add_interest = &hicn_add_interest_rr, .hicn_on_interest_timeout = &hicn_on_interest_timeout_rr, .hicn_select_next_hop = &hicn_select_next_hop_rr, - .get_strategy_node_index = get_strategy_node_index_rr -}; - -/* Stats string values */ -static char *hicn_strategy_error_strings[] = { -#define _(sym, string) string, - foreach_hicnfwd_error -#undef _ + .hicn_format_strategy_trace = &hicn_strategy_format_trace_rr, + .hicn_format_strategy = &hicn_strategy_format_rr }; /* @@ -57,64 +49,48 @@ hicn_rr_strategy_get_vft (void) return &hicn_strategy_rr_vft; } -/* Registration struct for a graph node */ -vlib_node_registration_t hicn_rr_strategy_node; - -u32 -get_strategy_node_index_rr (void) -{ - return hicn_rr_strategy_node.index; -} - /* DPO should be give in input as it containes all the information to calculate the next hops*/ u32 hicn_select_next_hop_rr (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface) { + hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo_idx); + + if (dpo_ctx == NULL) + return HICN_ERROR_STRATEGY_NOT_FOUND; + hicn_strategy_rr_ctx_t *hicn_strategy_rr_ctx = - (hicn_strategy_rr_ctx_t *) hicn_strategy_rr_ctx_get (dpo_idx); + (hicn_strategy_rr_ctx_t *) dpo_ctx->data; if (dpo_id_is_valid - (&hicn_strategy_rr_ctx->default_ctx. - next_hops[hicn_strategy_rr_ctx->current_nhop])) + (&dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop])) { *outface = - (dpo_id_t *) & hicn_strategy_rr_ctx->default_ctx. - next_hops[hicn_strategy_rr_ctx->current_nhop]; + (dpo_id_t *) & dpo_ctx->next_hops[hicn_strategy_rr_ctx->current_nhop]; } else return HICN_ERROR_STRATEGY_NH_NOT_FOUND; hicn_strategy_rr_ctx->current_nhop = - (hicn_strategy_rr_ctx->current_nhop + - 1) % hicn_strategy_rr_ctx->default_ctx.entry_count; + (hicn_strategy_rr_ctx->current_nhop + 1) % dpo_ctx->entry_count; return HICN_ERROR_NONE; } -uword -hicn_rr_strategy_node_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * frame) -{ - return hicn_forward_interest_fn (vm, node, frame, &hicn_strategy_rr_vft, - hicn_dpo_strategy_rr_get_type (), - &hicn_rr_strategy_node); -} - void hicn_add_interest_rr (index_t dpo_ctx_idx, hicn_hash_entry_t * hash_entry) { hash_entry->dpo_ctx_id = dpo_ctx_idx; dpo_id_t hicn_dpo_id = { hicn_dpo_strategy_rr_get_type (), 0, 0, dpo_ctx_idx }; - hicn_strategy_rr_ctx_lock (&hicn_dpo_id); + hicn_strategy_dpo_ctx_lock (&hicn_dpo_id); hash_entry->vft_id = hicn_dpo_get_vft_id (&hicn_dpo_id); } void hicn_on_interest_timeout_rr (index_t dpo_idx) { - /* Nothign to do in the rr strategy when we receive an interest */ + /* Nothing to do in the rr strategy when we receive an interest */ } void @@ -124,41 +100,25 @@ hicn_receive_data_rr (index_t dpo_idx, int nh_idx) /* packet trace format function */ -static u8 * -hicn_strategy_format_trace_rr (u8 * s, va_list * args) +u8 * +hicn_strategy_format_trace_rr (u8 * s, hicn_strategy_trace_t * t) { - CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); - CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - hicn_strategy_trace_t *t = va_arg (*args, hicn_strategy_trace_t *); - s = format (s, "Strategy_rr: pkt: %d, sw_if_index %d, next index %d", (int) t->pkt_type, t->sw_if_index, t->next_index); return (s); } -/* - * Node registration for the forwarder node - */ -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (hicn_rr_strategy_node) = +u8 * +hicn_strategy_format_rr (u8 * s, va_list * ap) { - .name = "hicn-rr-strategy", - .function = hicn_rr_strategy_node_fn, - .vector_size = sizeof (u32), - .runtime_data_bytes = sizeof (int) + sizeof(hicn_pit_cs_t *), - .format_trace = hicn_strategy_format_trace_rr, - .type = VLIB_NODE_TYPE_INTERNAL, - .n_errors = ARRAY_LEN (hicn_strategy_error_strings), - .error_strings = hicn_strategy_error_strings, - .n_next_nodes = HICN_STRATEGY_N_NEXT, - .next_nodes = { - [HICN_STRATEGY_NEXT_INTEREST_HITPIT] = "hicn-interest-hitpit", - [HICN_STRATEGY_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs", - [HICN_STRATEGY_NEXT_ERROR_DROP] = "error-drop", - [HICN_STRATEGY_NEXT_EMPTY] = "ip4-lookup", - }, -}; -/* *INDENT-ON* */ + + u32 indent = va_arg (*ap, u32); + s = + format (s, + "Round Robin: next hop is chosen ciclying between all the available next hops, one after the other.\n", + indent); + return (s); +} /* * fd.io coding-style-patch-verification: ON diff --git a/hicn-plugin/src/strategies/strategy_rr.h b/hicn-plugin/src/strategies/strategy_rr.h index 84149c36f..3936845fe 100644 --- a/hicn-plugin/src/strategies/strategy_rr.h +++ b/hicn-plugin/src/strategies/strategy_rr.h @@ -18,6 +18,9 @@ #include "../strategy.h" +/** + * @brief Return the vft for the Round Robin strategy + */ hicn_strategy_vft_t *hicn_rr_strategy_get_vft (void); #endif // __HICN_STRATEGY_RR_H__ diff --git a/hicn-plugin/src/strategy.h b/hicn-plugin/src/strategy.h index 19eee72c5..c18ae4eea 100644 --- a/hicn-plugin/src/strategy.h +++ b/hicn-plugin/src/strategy.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -24,10 +24,13 @@ /** * @File * - * A strategy is defined as a vpp node and a set of function that will be called - * during the packet processing. Having one vpp node per strategy allows to - * easily process multiple interests in the same node (x2 or x4) and call the - * same function for choosing the next hop. + * A strategy is defined as a dpo and a set of function (vft) that will be called + * during the packet processing. A strategy is associated to an entry in the fib by + * assigning the corresponding dpo to the fib entry. The dpo points to a hICN dpo + * context (ctx) which contains the information needed by the strategy to compute + * the next hop. Each strategy hash its own dpo type, which means that the dpo_type + * uniquely identify a strategy and its vft. The strategy node will use the dpo_type + * to retrieve the corresponding vft. * Here we provide: * - a template for the callbacks to implement in order to create a new strategy * (hicn_fwd_strategy_t) @@ -36,6 +39,15 @@ * interest and calling hicn_select_next_hop) */ +/* Trace context struct */ +typedef struct +{ + u32 next_index; + u32 sw_if_index; + u8 pkt_type; + dpo_type_t dpo_type; +} hicn_strategy_trace_t; + typedef struct hicn_strategy_vft_s { void (*hicn_receive_data) (index_t dpo_idx, int nh_idx); @@ -43,39 +55,21 @@ typedef struct hicn_strategy_vft_s void (*hicn_add_interest) (index_t dpo_idx, hicn_hash_entry_t * pit_entry); u32 (*hicn_select_next_hop) (index_t dpo_idx, int *nh_idx, dpo_id_t ** outface); - u32 (*get_strategy_node_index) (void); - /**< Return the vlib node index implementing the strategy */ + u8 *(*hicn_format_strategy_trace) (u8 *, hicn_strategy_trace_t *); + u8 *(*hicn_format_strategy) (u8 * s, va_list * ap); + /**< Format an hICN dpo*/ } hicn_strategy_vft_t; -hicn_face_vft_t *hicn_strategy_get_face_vft (u16 index); - -/* Strategy node API */ -/* Basic interest processing function. To be called in all the strategy nodes */ -uword -hicn_forward_interest_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, - hicn_strategy_vft_t * strategy, - dpo_type_t dpo_type, - vlib_node_registration_t * hicn_strategy_node); - -/* Trace context struct */ -typedef struct -{ - u32 next_index; - u32 sw_if_index; - u8 pkt_type; -} hicn_strategy_trace_t; - typedef enum { HICN_STRATEGY_NEXT_INTEREST_HITPIT, HICN_STRATEGY_NEXT_INTEREST_HITCS, HICN_STRATEGY_NEXT_ERROR_DROP, - HICN_STRATEGY_NEXT_EMPTY, HICN_STRATEGY_N_NEXT, } hicn_strategy_next_t; +extern vlib_node_registration_t hicn_strategy_node; + #endif /* //__HICN_STRATEGY__ */ /* diff --git a/hicn-plugin/src/strategy_dpo_ctx.c b/hicn-plugin/src/strategy_dpo_ctx.c new file mode 100644 index 000000000..6ec1407fb --- /dev/null +++ b/hicn-plugin/src/strategy_dpo_ctx.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2020 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. + */ + +#include "strategy_dpo_ctx.h" +#include "strategy_dpo_manager.h" + +hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_pool; + +void +hicn_strategy_init_dpo_ctx_pool () +{ + pool_init_fixed (hicn_strategy_dpo_ctx_pool, 256); + +} + +void +hicn_strategy_dpo_ctx_lock (dpo_id_t * dpo) +{ + hicn_dpo_ctx_t *dpo_ctx = hicn_strategy_dpo_ctx_get (dpo->dpoi_index); + + if (dpo_ctx != NULL) + { + dpo_ctx->locks++; + } +} + +void +hicn_strategy_dpo_ctx_unlock (dpo_id_t * dpo) +{ + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = + (hicn_dpo_ctx_t *) hicn_strategy_dpo_ctx_get (dpo->dpoi_index); + + if (hicn_strategy_dpo_ctx != NULL) + { + hicn_strategy_dpo_ctx->locks--; + + if (0 == hicn_strategy_dpo_ctx->locks) + { + pool_put (hicn_strategy_dpo_ctx_pool, hicn_strategy_dpo_ctx); + } + } +} + +u8 * +hicn_strategy_dpo_format_ctx (u8 * s, va_list * ap) +{ + index_t index = va_arg (*ap, index_t); + hicn_dpo_ctx_t *dpo = NULL; + u32 indent = va_arg (*ap, u32); + + dpo = (hicn_dpo_ctx_t *) hicn_strategy_dpo_ctx_get (index); + + const hicn_dpo_vft_t *dpo_vft = hicn_dpo_get_vft (dpo->dpo_type); + + s = dpo_vft->hicn_dpo_format (s, 2, index, indent); + + return (s); +} + +index_t +hicn_strategy_dpo_ctx_get_index (hicn_dpo_ctx_t * cd) +{ + return (cd - hicn_strategy_dpo_ctx_pool); +} + +hicn_dpo_ctx_t * +hicn_strategy_dpo_ctx_get (index_t index) +{ + hicn_dpo_ctx_t *hicn_strategy_dpo_ctx = NULL; + if (!pool_is_free_index (hicn_strategy_dpo_ctx_pool, index)) + { + hicn_strategy_dpo_ctx = + (pool_elt_at_index (hicn_strategy_dpo_ctx_pool, index)); + } + + return hicn_strategy_dpo_ctx; +} + +hicn_dpo_ctx_t * +hicn_strategy_dpo_ctx_alloc () +{ + hicn_dpo_ctx_t *dpo_ctx; + pool_get (hicn_strategy_dpo_ctx_pool, dpo_ctx); + return dpo_ctx; +} + +int +hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx, + u8 * pos) +{ + + int empty = dpo_ctx->entry_count; + + /* Iterate through the list of faces to find if the face is already a next hop */ + for (int i = 0; i < dpo_ctx->entry_count; i++) + { + if (!memcmp (nh, &dpo_ctx->next_hops[i], sizeof (dpo_id_t))) + { + /* If face is marked as deleted, ignore it */ + hicn_face_t *face = + hicn_dpoi_get_from_idx (dpo_ctx->next_hops[i].dpoi_index); + if (face->shared.flags & HICN_FACE_FLAGS_DELETED) + { + continue; + } + return HICN_ERROR_DPO_CTX_NHOPS_EXISTS; + } + } + + /* Get an empty place */ + if (empty > HICN_PARAM_FIB_ENTRY_NHOPS_MAX) + { + return HICN_ERROR_DPO_CTX_NHOPS_NS; + } + + clib_memcpy (&dpo_ctx->next_hops[empty], nh, sizeof (dpo_id_t)); + dpo_ctx->entry_count++; + *pos = empty; + + return HICN_ERROR_NONE; +} + +int +hicn_strategy_dpo_ctx_del_nh (hicn_face_id_t face_id, + hicn_dpo_ctx_t * dpo_ctx) +{ + int ret = HICN_ERROR_DPO_CTX_NOT_FOUND; + dpo_id_t invalid = NEXT_HOP_INVALID; + + for (int i = 0; i < dpo_ctx->entry_count; i++) + { + if (dpo_ctx->next_hops[i].dpoi_index == face_id) + { + hicn_face_unlock (&dpo_ctx->next_hops[i]); + dpo_ctx->entry_count--; + dpo_ctx->next_hops[i] = dpo_ctx->next_hops[dpo_ctx->entry_count]; + dpo_ctx->next_hops[dpo_ctx->entry_count] = invalid; + ret = HICN_ERROR_NONE; + break; + } + } + + return ret; + +} + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: eval: (c-set-style "gnu") End: + */ diff --git a/hicn-plugin/src/strategy_dpo_ctx.h b/hicn-plugin/src/strategy_dpo_ctx.h index 00b11412b..737071766 100644 --- a/hicn-plugin/src/strategy_dpo_ctx.h +++ b/hicn-plugin/src/strategy_dpo_ctx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 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: @@ -22,15 +22,21 @@ #include "params.h" #include "faces/face.h" +//FIB table for hicn. 0 is the default one used by ip #define HICN_FIB_TABLE 0 -#define DATA_LEN 8 - #define NEXT_HOP_INVALID DPO_INVALID #define INIT_SEQ 0 -/* - * An hicn dpo is a list of next hops (face + weight). + +/** + * @brief Definition of the general hICN DPO ctx (shared among all the strategies). + * + * An hICN DPO ctx contains the list of next hops, auxiliaries fields to maintain the dpo, map-me + * specifics (tfib_entry_count and seq), the dpo_type and 64B to let each strategy to store additional + * information. Each next hop is a dpo_id_t that refers to an hICN face. The dpo_type is used to + * identify the strategy and to retrieve the vft corresponding to the strategy (see strategy.h) + * and to the dpo ctx (see strategy_dpo_manager.h) */ typedef struct __attribute__ ((packed)) hicn_dpo_ctx_s { @@ -48,39 +54,121 @@ typedef struct __attribute__ ((packed)) hicn_dpo_ctx_s /* 46B + 2B = 48B */ u16 padding; /* To align to 8B */ -#ifdef HICN_MAPME_NOTIFICATIONS - /* (8B) last acked update for IU/IN heuristic on producer */ - f64 last_iu_ack; -#endif - /* (4B) last sequence number */ + /* 48 + 4B = 52; last sequence number */ seq_t seq; + /* 48 + 1B = 53; last sequence number */ + dpo_type_t dpo_type; + + CLIB_CACHE_LINE_ALIGN_MARK (cacheline1); + u8 data[CLIB_CACHE_LINE_BYTES]; + } hicn_dpo_ctx_t; +extern hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_pool; + +/** + * @brief Initialize the hICN dpo ctx + * + * @param dpo_ctx Pointer to the hICN dpo ctx to initialize + * @param next_hop List of netx hops to store in the dpo ctx + * @param nh_len Number of elements in the list of next hops + * @param dpo_type Type of dpo. It identifies the strategy. + */ always_inline void -init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx) +init_dpo_ctx (hicn_dpo_ctx_t * dpo_ctx, const dpo_id_t * next_hop, + int nh_len, dpo_type_t dpo_type) { dpo_id_t invalid = NEXT_HOP_INVALID; - for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++) - { - dpo_ctx->next_hops[i] = invalid; - } - dpo_ctx->entry_count = 0; dpo_ctx->locks = 0; dpo_ctx->tfib_entry_count = 0; -#ifdef HICN_MAPME_NOTIFICATIONS - last_iu_ack = 0; -#endif - dpo_ctx->seq = INIT_SEQ; + dpo_ctx->dpo_type = dpo_type; + + for (int i = 0; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX && i < nh_len; i++) + { + clib_memcpy (&dpo_ctx->next_hops[i], &next_hop[i], sizeof (dpo_id_t)); + dpo_ctx->entry_count++; + } + + + for (int i = nh_len; i < HICN_PARAM_FIB_ENTRY_NHOPS_MAX; i++) + { + dpo_ctx->next_hops[i] = invalid; + } + } -STATIC_ASSERT (sizeof (hicn_dpo_ctx_t) <= CLIB_CACHE_LINE_BYTES, - "sizeof hicn_dpo_ctx_t is greater than 64B"); +/** + * @brief Initialize the pool containing the hICN dpo ctx + * + */ +void hicn_strategy_init_dpo_ctx_pool (void); + +/** + * @brief Allocate a new hICN dpo ctx from the pool + */ +hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_alloc (); + +/** + * @brief Retrieve an existing hICN dpo ctx from the pool + */ +hicn_dpo_ctx_t *hicn_strategy_dpo_ctx_get (index_t index); + +/** + * @brief Retrieve the index of the hICN dpo ctx + */ +index_t hicn_strategy_dpo_ctx_get_index (hicn_dpo_ctx_t * cd); + +/** + * @brief Lock the dpo of a strategy ctx + * + * @param dpo Identifier of the dpo of the strategy ctx + */ +void hicn_strategy_dpo_ctx_lock (dpo_id_t * dpo); + +/** + * @brief Unlock the dpo of a strategy ctx + * + * @param dpo Identifier of the dpo of the strategy ctx + */ +void hicn_strategy_dpo_ctx_unlock (dpo_id_t * dpo); + +/** + * @brief Add or update a next hop in the dpo ctx. + * + * This function is meant to be used in the control plane and not in the data plane, + * as it is not optimized for the latter. + * + * @param nh Next hop to insert in the dpo ctx + * @param dpo_ctx Dpo ctx to update with the new or updated next hop + * @param pos Return the position of the nh that has been added + * @return HICN_ERROR_NONE if the update or insert was fine, + * otherwise HICN_ERROR_DPO_CTX_NOT_FOUND + */ +int +hicn_strategy_dpo_ctx_add_nh (const dpo_id_t * nh, hicn_dpo_ctx_t * dpo_ctx, + u8 * pos); + +/** + * @brief Delete a next hop in the dpo ctx. + * + * @param face_id Face identifier of the next hop + * @param dpo_ctx Dpo ctx to update by removing the face + * @return HICN_ERROR_NONE if the update or insert was fine, + * otherwise HICN_ERROR_DPO_CTS_NOT_FOUND + */ +int +hicn_strategy_dpo_ctx_del_nh (hicn_face_id_t face_id, + hicn_dpo_ctx_t * dpo_ctx); + + +STATIC_ASSERT (sizeof (hicn_dpo_ctx_t) <= 2 * CLIB_CACHE_LINE_BYTES, + "sizeof hicn_dpo_ctx_t is greater than 128B"); #endif /* // __HICN_STRATEGY_DPO_CTX_H__ */ diff --git a/hicn-plugin/src/strategy_dpo_manager.c b/hicn-plugin/src/strategy_dpo_manager.c index 470d8d185..f8d41a372 100644 --- a/hicn-plugin/src/strategy_dpo_manager.c +++ b/hicn-plugin/src/strategy_dpo_manager.c @@ -16,6 +16,7 @@ #include <vnet/dpo/dpo.h> #include "strategy_dpo_manager.h" +#include "strategy_dpo_ctx.h" #include "strategies/dpo_mw.h" #include "strategies/dpo_rr.h" #include "strategy.h" @@ -94,19 +95,17 @@ hicn_dpo_get_strategy_vft_from_id (u8 vfts_id) void hicn_dpos_init (void) { + hicn_strategy_init_dpo_ctx_pool (); hicn_dpo_strategy_mw_module_init (); hicn_dpo_strategy_rr_module_init (); - default_dpo.hicn_dpo_get_ctx = &hicn_strategy_mw_ctx_get; default_dpo.hicn_dpo_is_type = &hicn_dpo_is_type_strategy_mw; default_dpo.hicn_dpo_get_type = &hicn_dpo_strategy_mw_get_type; default_dpo.hicn_dpo_module_init = &hicn_dpo_strategy_mw_module_init; default_dpo.hicn_dpo_create = &hicn_strategy_mw_ctx_create; default_dpo.hicn_dpo_add_update_nh = &hicn_strategy_mw_ctx_add_nh; default_dpo.hicn_dpo_del_nh = &hicn_strategy_mw_ctx_del_nh; - default_dpo.hicn_dpo_lock_dpo_ctx = &hicn_strategy_mw_ctx_lock; - default_dpo.hicn_dpo_unlock_dpo_ctx = hicn_strategy_mw_ctx_unlock; - default_dpo.format_hicn_dpo = &format_hicn_strategy_mw_ctx; + default_dpo.hicn_dpo_format = &hicn_strategy_mw_format_ctx; } u8 * @@ -117,13 +116,13 @@ format_hicn_strategy_list (u8 * s, int n, ...) u32 indent = va_arg (ap, u32); va_end (ap); - s = format (s, "Strategies:\n", indent); + s = format (s, "%U Strategies:\n", format_white_space, indent); indent += 4; int i; vec_foreach_index (i, strategies_id) { - s = format (s, "(%d) ", i, indent); - s = hicn_dpo_vfts[strategies_id[i]]->format_hicn_dpo (s, &ap); + s = format (s, "%U (%d) ", format_white_space, indent, i); + s = hicn_strategy_vfts[strategies_id[i]]->hicn_format_strategy (s, &ap); } return (s); diff --git a/hicn-plugin/src/strategy_dpo_manager.h b/hicn-plugin/src/strategy_dpo_manager.h index 686c2f8c8..63fcb930b 100644 --- a/hicn-plugin/src/strategy_dpo_manager.h +++ b/hicn-plugin/src/strategy_dpo_manager.h @@ -29,21 +29,16 @@ */ typedef struct hicn_dpo_vft_s { - hicn_dpo_ctx_t *(*hicn_dpo_get_ctx) (index_t dpo_idx); /**< Retrieve the dpo ctx*/ int (*hicn_dpo_is_type) (const dpo_id_t * dpo); /**< Check if the type of the hICN DPO is the expected */ dpo_type_t (*hicn_dpo_get_type) (void); /**< Return the type of the hICN dpo */ void (*hicn_dpo_module_init) (void); /**< Initialize the hICN dpo */ - int (*hicn_dpo_create) (dpo_proto_t proto, const dpo_id_t * nh, int nh_len, index_t * dpo_idx); /**< Create the context of the hICN dpo */ + void (*hicn_dpo_create) (dpo_proto_t proto, const dpo_id_t * nh, int nh_len, index_t * dpo_idx); /**< Create the context of the hICN dpo */ int (*hicn_dpo_add_update_nh) (const dpo_id_t * nh, index_t dpo_idx); /**< Add a next hop to the hICN dpo context */ - int (*hicn_dpo_del_nh) (hicn_face_id_t face_id, index_t dpo_idx, - fib_prefix_t * fib_pfx); - /**< Add a next hop to the hICN dpo context */ - void (*hicn_dpo_lock_dpo_ctx) (dpo_id_t * dpo); - void (*hicn_dpo_unlock_dpo_ctx) (dpo_id_t * dpo); - u8 *(*format_hicn_dpo) (u8 * s, va_list * ap); + int (*hicn_dpo_del_nh) (hicn_face_id_t face_id, index_t dpo_idx); + u8 *(*hicn_dpo_format) (u8 * s, int, ...); /**< Format an hICN dpo*/ } hicn_dpo_vft_t; @@ -53,6 +48,21 @@ typedef struct hicn_dpo_vft_s */ extern hicn_dpo_vft_t default_dpo; +const static char *const hicn_ip6_nodes[] = { + "hicn-iface-ip6-input", // this is the name you give your node in VLIB_REGISTER_NODE + NULL, +}; + +const static char *const hicn_ip4_nodes[] = { + "hicn-iface-ip4-input", // this is the name you give your node in VLIB_REGISTER_NODE + NULL, +}; + +const static char *const *const hicn_nodes_strategy[DPO_PROTO_NUM] = { + [DPO_PROTO_IP6] = hicn_ip6_nodes, + [DPO_PROTO_IP4] = hicn_ip4_nodes, +}; + /** * @brief Register a new hICN dpo to the manager. * diff --git a/hicn-plugin/src/strategy.c b/hicn-plugin/src/strategy_node.c index 15c0dc720..27d1e2a03 100644 --- a/hicn-plugin/src/strategy.c +++ b/hicn-plugin/src/strategy_node.c @@ -25,6 +25,10 @@ #include "mgmt.h" #include "pcs.h" #include "state.h" +#include "strategies/strategy_mw.h" + +/* Registration struct for a graph node */ +vlib_node_registration_t hicn_strategy_node; /* * Node context data (to be used in all the strategy nodes); we think this is @@ -36,11 +40,32 @@ typedef struct hicn_strategy_runtime_s hicn_pit_cs_t *pitcs; } hicn_strategy_runtime_t; +/* Stats string values */ +static char *hicn_strategy_error_strings[] = { +#define _(sym, string) string, + foreach_hicnfwd_error +#undef _ +}; + +/* packet trace format function */ +u8 * +hicn_strategy_format_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 *); + hicn_strategy_trace_t *t = va_arg (*args, hicn_strategy_trace_t *); + + const hicn_strategy_vft_t *vft = hicn_dpo_get_strategy_vft (t->dpo_type); + + return vft->hicn_format_strategy_trace (s, t); +} + + always_inline int hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0, u32 * next, f64 tnow, u8 * nameptr, u16 namelen, dpo_id_t * outface, int nh_idx, - index_t hicn_dpo_idx, hicn_strategy_vft_t * strategy, + index_t dpo_ctx_id0, const hicn_strategy_vft_t * strategy, dpo_type_t dpo_type, u8 isv6, vl_api_hicn_api_node_stats_get_reply_t * stats) { @@ -51,7 +76,6 @@ hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0, hicn_main_t *sm = &hicn_main; hicn_buffer_t *hicnb0 = hicn_get_buffer (b0); u32 node_id0 = 0; - u8 dpo_ctx_id0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX]; u8 vft_id0 = dpo_type; u8 is_cs0 = 0; u8 hash_entry_id = 0; @@ -142,24 +166,20 @@ hicn_new_interest (hicn_strategy_runtime_t * rt, vlib_buffer_t * b0, * ipv6/tcp */ uword -hicn_forward_interest_fn (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame, - hicn_strategy_vft_t * strategy, - dpo_type_t dpo_type, - vlib_node_registration_t * hicn_strategy_node) +hicn_strategy_fn (vlib_main_t * vm, + vlib_node_runtime_t * node, vlib_frame_t * frame) { u32 n_left_from, *from, *to_next, n_left_to_next; hicn_strategy_next_t next_index; - hicn_strategy_runtime_t *rt; + hicn_strategy_runtime_t *rt = NULL; vl_api_hicn_api_node_stats_get_reply_t stats = { 0 }; f64 tnow; from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; next_index = (hicn_strategy_next_t) node->cached_next_index; - rt = vlib_node_get_runtime_data (vm, hicn_strategy_node->index); + rt = vlib_node_get_runtime_data (vm, hicn_strategy_node.index); rt->pitcs = &hicn_main.pitcs; /* Capture time in vpp terms */ tnow = vlib_time_now (vm); @@ -202,6 +222,12 @@ hicn_forward_interest_fn (vlib_main_t * vm, b0 = vlib_get_buffer (vm, bi0); next0 = HICN_STRATEGY_NEXT_ERROR_DROP; + hicn_dpo_ctx_t *dpo_ctx = + hicn_strategy_dpo_ctx_get (vnet_buffer (b0)->ip. + adj_index[VLIB_TX]); + const hicn_strategy_vft_t *strategy = + hicn_dpo_get_strategy_vft (dpo_ctx->dpo_type); + ret = hicn_interest_parse_pkt (b0, &name, &namelen, &hicn0, &isv6); stats.pkts_processed++; /* Select next hop */ @@ -212,8 +238,9 @@ hicn_forward_interest_fn (vlib_main_t * vm, */ if (PREDICT_TRUE (ret == HICN_ERROR_NONE && HICN_IS_NAMEHASH_CACHED (b0) - && strategy->hicn_select_next_hop (vnet_buffer (b0)->ip. - adj_index[VLIB_TX], &nh_idx, + && strategy->hicn_select_next_hop (vnet_buffer (b0)-> + ip.adj_index[VLIB_TX], + &nh_idx, &outface) == HICN_ERROR_NONE)) { @@ -226,7 +253,7 @@ hicn_forward_interest_fn (vlib_main_t * vm, hicn_new_interest (rt, b0, &next0, tnow, nameptr, namelen, outface, nh_idx, vnet_buffer (b0)->ip.adj_index[VLIB_TX], - strategy, dpo_type, isv6, &stats); + strategy, dpo_ctx->dpo_type, isv6, &stats); } /* Maybe trace */ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) && @@ -237,6 +264,7 @@ hicn_forward_interest_fn (vlib_main_t * vm, t->pkt_type = HICN_PKT_TYPE_CONTENT; t->sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX]; t->next_index = next0; + t->dpo_type = dpo_ctx->dpo_type; } /* * Verify speculative enqueue, maybe switch current @@ -254,9 +282,9 @@ hicn_forward_interest_fn (vlib_main_t * vm, vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_node_increment_counter (vm, hicn_strategy_node->index, + vlib_node_increment_counter (vm, hicn_strategy_node.index, HICNFWD_ERROR_PROCESSED, stats.pkts_processed); - vlib_node_increment_counter (vm, hicn_strategy_node->index, + vlib_node_increment_counter (vm, hicn_strategy_node.index, HICNFWD_ERROR_INTERESTS, stats.pkts_interest_count); @@ -264,6 +292,30 @@ hicn_forward_interest_fn (vlib_main_t * vm, } /* + * Node registration for the forwarder node + */ +/* *INDENT-OFF* */ +VLIB_REGISTER_NODE (hicn_strategy_node) = + { + .name = "hicn-strategy", + .function = hicn_strategy_fn, + .vector_size = sizeof (u32), + .runtime_data_bytes = sizeof (int) + sizeof(hicn_pit_cs_t *), + .format_trace = hicn_strategy_format_trace, + .type = VLIB_NODE_TYPE_INTERNAL, + .n_errors = ARRAY_LEN (hicn_strategy_error_strings), + .error_strings = hicn_strategy_error_strings, + .n_next_nodes = HICN_STRATEGY_N_NEXT, + .next_nodes = + { + [HICN_STRATEGY_NEXT_INTEREST_HITPIT] = "hicn-interest-hitpit", + [HICN_STRATEGY_NEXT_INTEREST_HITCS] = "hicn-interest-hitcs", + [HICN_STRATEGY_NEXT_ERROR_DROP] = "error-drop", + }, + }; + + +/* * fd.io coding-style-patch-verification: ON * * Local Variables: eval: (c-set-style "gnu") End: |