diff options
Diffstat (limited to 'hicn-plugin')
-rw-r--r-- | hicn-plugin/src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | hicn-plugin/src/cli.c | 160 | ||||
-rw-r--r-- | hicn-plugin/src/error.h | 31 | ||||
-rw-r--r-- | hicn-plugin/src/hicn.api | 87 | ||||
-rw-r--r-- | hicn-plugin/src/hicn.c | 12 | ||||
-rw-r--r-- | hicn-plugin/src/hicn_api.c | 81 | ||||
-rw-r--r-- | hicn-plugin/src/hicn_api_test.c | 185 | ||||
-rw-r--r-- | hicn-plugin/src/mgmt.h | 10 | ||||
-rw-r--r-- | hicn-plugin/src/pg.h | 67 | ||||
-rw-r--r-- | hicn-plugin/src/punt.c | 1200 | ||||
-rw-r--r-- | hicn-plugin/src/punt.h | 344 |
11 files changed, 83 insertions, 2096 deletions
diff --git a/hicn-plugin/src/CMakeLists.txt b/hicn-plugin/src/CMakeLists.txt index 87328e7c1..6852b95bb 100644 --- a/hicn-plugin/src/CMakeLists.txt +++ b/hicn-plugin/src/CMakeLists.txt @@ -94,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 @@ -142,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 diff --git a/hicn-plugin/src/cli.c b/hicn-plugin/src/cli.c index 920d206f8..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, @@ -507,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' */ @@ -988,14 +836,6 @@ 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)= { 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/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 5bdab4408..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" @@ -704,8 +703,8 @@ send_route_details (vl_api_registration_t * reg, { mp->faceids[i] = clib_host_to_net_u32 (((dpo_id_t *) & - hicn_dpo_ctx->next_hops[i])-> - dpoi_index); + hicn_dpo_ctx-> + next_hops[i])->dpoi_index); mp->nfaces++; } } @@ -754,7 +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; @@ -775,8 +774,7 @@ static void fib_table_walk (fib_table->ft_index, FIB_PROTOCOL_IP4, vl_api_hicn_api_route_dump_walk, - &ctx); - } + &ctx);} )); pool_foreach (fib_table, im6->fibs, ( @@ -784,8 +782,7 @@ static void fib_table_walk (fib_table->ft_index, FIB_PROTOCOL_IP6, vl_api_hicn_api_route_dump_walk, - &ctx); - } + &ctx);} )); vec_foreach (lfeip, ctx.feis) @@ -846,74 +843,6 @@ static void vl_api_hicn_api_strategy_get_t_handler /* *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/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/pg.h b/hicn-plugin/src/pg.h index 35f570880..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,22 +16,67 @@ #ifndef __HICN_PG_H__ #define __HICN_PG_H__ + +/** + * @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; - fib_prefix_t *pgen_clt_hicn_name; - u32 index_ifaces; - u32 n_ifaces; - u32 max_seq_number; - u32 n_flows; - ip46_address_t pgen_clt_src_addr; - - u16 interest_lifetime; - u32 sw_if; + 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; 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: - */ |