aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2019-11-18 14:52:25 +0100
committerAlberto Compagno <acompagn+fdio@cisco.com>2019-11-18 14:52:25 +0100
commit569dda3ae64bbfa3579d4c42e30ee684d51b88d9 (patch)
treed74c4cb17ea687d7e34473f424ab077f5f44bafc
parentf1590834352d863d238d38c5a58d5a31ab042e3f (diff)
[HICN-397] Added punting add message for punting on udp ports
Change-Id: Ieb5faf5d01e460179028eaba92170ee95cf35edf Signed-off-by: Alberto Compagno <acompagn+fdio@cisco.com>
-rw-r--r--hicn-plugin/src/hicn.api67
-rw-r--r--hicn-plugin/src/hicn_api.c40
-rw-r--r--hicn-plugin/src/hicn_api_test.c212
-rw-r--r--hicn-plugin/src/punt.c40
-rw-r--r--hicn-plugin/src/punt.h2
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