diff options
-rw-r--r-- | hicn-plugin/src/hicn.api | 67 | ||||
-rw-r--r-- | hicn-plugin/src/hicn_api.c | 40 | ||||
-rw-r--r-- | hicn-plugin/src/hicn_api_test.c | 212 | ||||
-rw-r--r-- | hicn-plugin/src/punt.c | 40 | ||||
-rw-r--r-- | hicn-plugin/src/punt.h | 2 |
5 files changed, 335 insertions, 26 deletions
diff --git a/hicn-plugin/src/hicn.api b/hicn-plugin/src/hicn.api index 9a194b97f..2f33c901b 100644 --- a/hicn-plugin/src/hicn.api +++ b/hicn-plugin/src/hicn.api @@ -16,12 +16,20 @@ option version = "5.1.0"; import "vnet/ip/ip_types.api"; -enum face_type : u8 { +enum face_type : u8 +{ IP_FACE = 0, UDP_FACE, }; -typedef hicn_face_ip { +enum punt_type : u8 +{ + IP_PUNT = 0, + UDP_PUNT, +}; + +typedef hicn_face_ip +{ /* IP local address */ vl_api_address_t local_addr; @@ -38,7 +46,8 @@ typedef hicn_face_ip { u8 if_name[30]; }; -typedef hicn_face_udp { +typedef hicn_face_udp +{ /* IP local address */ vl_api_address_t local_addr; @@ -61,11 +70,45 @@ typedef hicn_face_udp { u8 if_name[30]; }; -typedef hicn_face_union { +typedef hicn_face_union +{ vl_api_hicn_face_ip_t ip; 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 */ @@ -628,11 +671,11 @@ define hicn_api_punting_add /* Arbitrary context, so client can match reply to request */ u32 context; - /* Prefix to match */ - vl_api_prefix_t prefix; + /* Type of punting rule */ + vl_api_punt_type_t type; - /* Interface id */ - u32 swif; + /* Prefix to match */ + vl_api_hicn_punting_union_t rule; }; define hicn_api_punting_add_reply @@ -652,11 +695,11 @@ define hicn_api_punting_del /* Arbitrary context, so client can match reply to request */ u32 context; - /* Prefix to match */ - vl_api_prefix_t prefix; + /* Type of punting rule */ + vl_api_punt_type_t type; - /* Interface id */ - u32 swif; + /* Prefix to match */ + vl_api_hicn_punting_union_t rule; }; define hicn_api_punting_del_reply diff --git a/hicn-plugin/src/hicn_api.c b/hicn-plugin/src/hicn_api.c index b1e6bccb9..1cb14fe1b 100644 --- a/hicn-plugin/src/hicn_api.c +++ b/hicn-plugin/src/hicn_api.c @@ -890,20 +890,50 @@ static void vl_api_hicn_api_strategy_get_t_handler /****** 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; - vlib_main_t *vm = vlib_get_main (); hicn_main_t *sm = &hicn_main; - fib_prefix_t prefix; - ip_prefix_decode (&mp->prefix, &prefix); - u32 swif = clib_net_to_host_u32 (mp->swif); + 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; + } - rv = hicn_punt_interest_data_for_ip (vm, &prefix, swif, 0, NO_L2); REPLY_MACRO (VL_API_HICN_API_PUNTING_ADD_REPLY /* , rmp, mp, rv */ ); } diff --git a/hicn-plugin/src/hicn_api_test.c b/hicn-plugin/src/hicn_api_test.c index fa0e075f8..1dc8158d4 100644 --- a/hicn-plugin/src/hicn_api_test.c +++ b/hicn-plugin/src/hicn_api_test.c @@ -173,6 +173,65 @@ ip_address_encode (const ip46_address_t * in, ip46_type_t type, ip_address_union_encode (in, out->af, &out->un); } +fib_protocol_t +fib_proto_from_ip46 (ip46_type_t iproto) +{ + switch (iproto) + { + case IP46_TYPE_IP4: + return FIB_PROTOCOL_IP4; + case IP46_TYPE_IP6: + return FIB_PROTOCOL_IP6; + case IP46_TYPE_ANY: + ASSERT(0); + return FIB_PROTOCOL_IP4; + } + + ASSERT(0); + return FIB_PROTOCOL_IP4; +} + +ip46_type_t +fib_proto_to_ip46 (fib_protocol_t fproto) +{ + switch (fproto) + { + case FIB_PROTOCOL_IP4: + return (IP46_TYPE_IP4); + case FIB_PROTOCOL_IP6: + return (IP46_TYPE_IP6); + case FIB_PROTOCOL_MPLS: + return (IP46_TYPE_ANY); + } + ASSERT(0); + return (IP46_TYPE_ANY); +} + +void +ip_prefix_decode (const vl_api_prefix_t * in, fib_prefix_t * out) +{ + switch (clib_net_to_host_u32 (in->address.af)) + { + case ADDRESS_IP4: + out->fp_proto = FIB_PROTOCOL_IP4; + break; + case ADDRESS_IP6: + out->fp_proto = FIB_PROTOCOL_IP6; + break; + } + out->fp_len = in->len; + out->___fp___pad = 0; + ip_address_decode (&in->address, &out->fp_addr); +} + +void +ip_prefix_encode (const fib_prefix_t * in, vl_api_prefix_t * out) +{ + out->len = in->fp_len; + ip_address_encode (&in->fp_addr, + fib_proto_to_ip46 (in->fp_proto), &out->address); +} + ///////////////////////////////////////////////////// #define HICN_FACE_NULL ~0 @@ -193,7 +252,8 @@ _(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_route_nhop_del_reply) \ +_(hicn_api_punting_add_reply) #define _(n) \ static void vl_api_##n##_t_handler \ @@ -235,6 +295,7 @@ _(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_REGISTER_CONS_APP_REPLY, hicn_api_register_cons_app_reply) @@ -967,6 +1028,8 @@ api_hicn_api_route_get (vat_main_t * vam) } //Construct the API message M (HICN_API_ROUTE_GET, mp); + if (!ip46_address_is_ip4(&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); ip_prefix_encode (&prefix, &mp->prefix); //send it... @@ -1122,6 +1185,9 @@ api_hicn_api_route_nhops_add (vat_main_t * vam) M (HICN_API_ROUTE_NHOPS_ADD, mp); ip_prefix_encode (&prefix, &mp->prefix); + if (!ip46_address_is_ip4(&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + mp->face_ids[0] = clib_host_to_net_u32 (faceid); mp->n_faces = 1; @@ -1166,6 +1232,9 @@ api_hicn_api_route_del (vat_main_t * vam) M (HICN_API_ROUTE_DEL, mp); ip_prefix_encode (&prefix, &mp->prefix); + if (!ip46_address_is_ip4(&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + /* send it... */ S (mp); @@ -1211,6 +1280,9 @@ api_hicn_api_route_nhop_del (vat_main_t * vam) M (HICN_API_ROUTE_NHOP_DEL, mp); ip_prefix_encode (&prefix, &mp->prefix); + if (!ip46_address_is_ip4(&(prefix.fp_addr))) + prefix.fp_proto = fib_proto_from_ip46(IP46_TYPE_IP6); + mp->faceid = clib_host_to_net_u32 (faceid); /* send it... */ @@ -1339,6 +1411,142 @@ static void } fformat (vam->ofp, "%s", mp->description); } +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_register_prod_app (vat_main_t * vam) @@ -1485,6 +1693,8 @@ _(hicn_api_route_del, "prefix <IP4/IP6>/<subnet>") \ _(hicn_api_route_nhop_del, "del prefix <IP4/IP6>/<subnet> face <faceID>") \ _(hicn_api_strategies_get, "") \ _(hicn_api_strategy_get, "strategy <id>") \ +_(hicn_api_ip_punting_add, "prefix <IP4/IP6>/<subnet> intfc <swif>") \ +_(hicn_api_udp_punting_add, "prefix <IP4/IP6>/<subnet> intfc <swif> sport <port> dport <port> ip4/ip6") \ _(hicn_api_register_prod_app, "prefix <IP4/IP6>/<subnet> id <appif_id>") \ _(hicn_api_register_cons_app, "") diff --git a/hicn-plugin/src/punt.c b/hicn-plugin/src/punt.c index fe1ca495f..9fd91a795 100644 --- a/hicn-plugin/src/punt.c +++ b/hicn-plugin/src/punt.c @@ -483,12 +483,31 @@ hicn_punt_add_del_vnetssn_udp (ip_version_t * outer, ip_version_t * inner, u8 base_offset, u8 protocol, u16 sport, u16 dport, int is_add) { - 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); + 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) \ @@ -773,11 +792,15 @@ hicn_punt_interest_data_for_udp (vlib_main_t * vm, 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 == 0 && dport == 0) || !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) @@ -940,9 +963,10 @@ hicn_punt_interest_data_for_ip (vlib_main_t * vm, 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) + 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)) diff --git a/hicn-plugin/src/punt.h b/hicn-plugin/src/punt.h index 5e1126445..7ad96c791 100644 --- a/hicn-plugin/src/punt.h +++ b/hicn-plugin/src/punt.h @@ -41,6 +41,8 @@ #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 |