diff options
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/fib/fib_types.c | 34 | ||||
-rw-r--r-- | src/vnet/fib/fib_types.h | 10 | ||||
-rw-r--r-- | src/vnet/ip/format.h | 6 | ||||
-rw-r--r-- | src/vnet/ip/ip6_packet.h | 7 | ||||
-rw-r--r-- | src/vnet/ip/ip_types.api | 7 | ||||
-rw-r--r-- | src/vnet/ip/ip_types_api.c | 143 | ||||
-rw-r--r-- | src/vnet/ip/ip_types_api.h | 18 | ||||
-rw-r--r-- | src/vnet/udp/udp.api | 83 | ||||
-rw-r--r-- | src/vnet/udp/udp_api.c | 101 |
9 files changed, 297 insertions, 112 deletions
diff --git a/src/vnet/fib/fib_types.c b/src/vnet/fib/fib_types.c index 1046e45b2f7..542cf1d7faf 100644 --- a/src/vnet/fib/fib_types.c +++ b/src/vnet/fib/fib_types.c @@ -282,6 +282,40 @@ fib_proto_to_link (fib_protocol_t proto) return (0); } +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); +} + +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; +} + fib_forward_chain_type_t fib_forw_chain_type_from_dpo_proto (dpo_proto_t proto) { diff --git a/src/vnet/fib/fib_types.h b/src/vnet/fib/fib_types.h index 7f186ac6f6a..805f8e1b964 100644 --- a/src/vnet/fib/fib_types.h +++ b/src/vnet/fib/fib_types.h @@ -83,6 +83,16 @@ fib_ip_proto(bool is_ip6) } /** + * @brief Convert from fib_protocol to ip46_type + */ +extern ip46_type_t fib_proto_to_ip46(fib_protocol_t fproto); + +/** + * @brief Convert from ip46_type to fib_protocol + */ +extern fib_protocol_t fib_proto_from_ip46(ip46_type_t iproto); + +/** * @brief Convert from a protocol to a link type */ vnet_link_t fib_proto_to_link (fib_protocol_t proto); diff --git a/src/vnet/ip/format.h b/src/vnet/ip/format.h index 9ebcf084be3..4d63ba43653 100644 --- a/src/vnet/ip/format.h +++ b/src/vnet/ip/format.h @@ -60,12 +60,6 @@ format_function_t format_ip_adjacency_packet_data; format_function_t format_ip46_address; -typedef enum -{ - IP46_TYPE_ANY, - IP46_TYPE_IP4, - IP46_TYPE_IP6 -} ip46_type_t; /* unformat_ip46_address expects arguments (ip46_address_t *, ip46_type_t) * The type argument is used to enforce a particular IP version. */ unformat_function_t unformat_ip46_address; diff --git a/src/vnet/ip/ip6_packet.h b/src/vnet/ip/ip6_packet.h index b8f8d6e8657..ceaa7ec7acc 100644 --- a/src/vnet/ip/ip6_packet.h +++ b/src/vnet/ip/ip6_packet.h @@ -67,6 +67,13 @@ typedef CLIB_PACKED (struct { }) ip6_address_fib_t; /* *INDENT-ON* */ +typedef enum +{ + IP46_TYPE_ANY, + IP46_TYPE_IP4, + IP46_TYPE_IP6 +} ip46_type_t; + /* *INDENT-OFF* */ typedef CLIB_PACKED (union { struct { diff --git a/src/vnet/ip/ip_types.api b/src/vnet/ip/ip_types.api index 72eadaf92df..e418ed3a1c6 100644 --- a/src/vnet/ip/ip_types.api +++ b/src/vnet/ip/ip_types.api @@ -41,3 +41,10 @@ typedef prefix { vl_api_address_t address; u8 address_length; }; + +typedef mprefix { + vl_api_address_family_t af; + u16 grp_address_length; + vl_api_address_union_t grp_address; + vl_api_address_union_t src_address; +}; diff --git a/src/vnet/ip/ip_types_api.c b/src/vnet/ip/ip_types_api.c index 7fa8e404c78..f173c28c83b 100644 --- a/src/vnet/ip/ip_types_api.c +++ b/src/vnet/ip/ip_types_api.c @@ -29,42 +29,75 @@ #include <vnet/vnet_all_api_h.h> #undef vl_printfun - -void -ip_address_decode (const vl_api_address_t * in, ip46_address_t * out) +static ip46_type_t +ip_address_union_decode (const vl_api_address_union_t * in, + vl_api_address_family_t af, ip46_address_t * out) { - switch (in->af) + ip46_type_t type; + + switch (clib_net_to_host_u32 (af)) { case ADDRESS_IP4: memset (out, 0, sizeof (*out)); - clib_memcpy (&out->ip4, &in->un.ip4, sizeof (out->ip4)); + clib_memcpy (&out->ip4, &in->ip4, sizeof (out->ip4)); + type = IP46_TYPE_IP4; break; case ADDRESS_IP6: - clib_memcpy (&out->ip6, &in->un.ip6, sizeof (out->ip6)); + clib_memcpy (&out->ip6, &in->ip6, sizeof (out->ip6)); + type = IP46_TYPE_IP6; + break; + default: + ASSERT (!"Unkown address family in API address type"); + type = IP46_TYPE_ANY; break; } + + return type; } -void -ip_address_encode (const ip46_address_t * in, vl_api_address_t * out) +ip46_type_t +ip_address_decode (const vl_api_address_t * in, ip46_address_t * out) { - if (ip46_address_is_ip4 (in)) - { - memset (out, 0, sizeof (*out)); - out->af = ADDRESS_IP4; - clib_memcpy (&out->un.ip4, &in->ip4, sizeof (out->un.ip4)); - } + return (ip_address_union_decode (&in->un, in->af, out)); +} + +static void +ip_address_union_encode (const ip46_address_t * in, + vl_api_address_family_t af, + vl_api_address_union_t * out) +{ + if (ADDRESS_IP6 == clib_net_to_host_u32 (af)) + memcpy (out->ip6.address, &in->ip6, sizeof (out->ip6)); else + memcpy (out->ip4.address, &in->ip4, sizeof (out->ip4)); +} + +void +ip_address_encode (const ip46_address_t * in, + ip46_type_t type, vl_api_address_t * out) +{ + switch (type) { - out->af = ADDRESS_IP6; - clib_memcpy (&out->un.ip6, &in->ip6, sizeof (out->un.ip6)); + case IP46_TYPE_IP4: + out->af = clib_net_to_host_u32 (ADDRESS_IP4); + break; + case IP46_TYPE_IP6: + out->af = clib_net_to_host_u32 (ADDRESS_IP6); + break; + case IP46_TYPE_ANY: + if (ip46_address_is_ip4 (in)) + out->af = clib_net_to_host_u32 (ADDRESS_IP4); + else + out->af = clib_net_to_host_u32 (ADDRESS_IP6); + break; } + ip_address_union_encode (in, out->af, &out->un); } void ip_prefix_decode (const vl_api_prefix_t * in, fib_prefix_t * out) { - switch (in->address.af) + switch (clib_net_to_host_u32 (in->address.af)) { case ADDRESS_IP4: out->fp_proto = FIB_PROTOCOL_IP4; @@ -80,20 +113,70 @@ ip_prefix_decode (const vl_api_prefix_t * in, fib_prefix_t * out) void ip_prefix_encode (const fib_prefix_t * in, vl_api_prefix_t * out) { - switch (in->fp_proto) - { - case FIB_PROTOCOL_IP4: - out->address.af = ADDRESS_IP4; - break; - case FIB_PROTOCOL_IP6: - out->address.af = ADDRESS_IP6; - break; - case FIB_PROTOCOL_MPLS: - ASSERT (0); - break; - } out->address_length = in->fp_len; - ip_address_encode (&in->fp_addr, &out->address); + ip_address_encode (&in->fp_addr, + fib_proto_to_ip46 (in->fp_proto), &out->address); +} + +void +ip_mprefix_encode (const mfib_prefix_t * in, vl_api_mprefix_t * out) +{ + out->af = (FIB_PROTOCOL_IP6 == in->fp_proto ? ADDRESS_IP6 : ADDRESS_IP4); + out->af = clib_host_to_net_u32 (out->af); + out->grp_address_length = clib_host_to_net_u16 (in->fp_len); + + ip_address_union_encode (&in->fp_grp_addr, out->af, &out->grp_address); + ip_address_union_encode (&in->fp_src_addr, out->af, &out->src_address); +} + +void +ip_mprefix_decode (const vl_api_mprefix_t * in, mfib_prefix_t * out) +{ + out->fp_proto = (ADDRESS_IP6 == clib_net_to_host_u32 (in->af) ? + FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4); + out->fp_len = clib_net_to_host_u16 (in->grp_address_length); + + ip_address_union_decode (&in->grp_address, in->af, &out->fp_grp_addr); + ip_address_union_decode (&in->src_address, in->af, &out->fp_src_addr); +} + +u8 * +format_vl_api_address (u8 * s, va_list * args) +{ + const vl_api_address_t *addr = va_arg (*args, vl_api_address_t *); + + if (ADDRESS_IP6 == clib_net_to_host_u32 (addr->af)) + s = format (s, "ip6:%U", format_ip6_address, addr->un.ip6.address); + else + s = format (s, "ip4:%U", format_ip4_address, addr->un.ip4.address); + + return s; +} + +u8 * +format_vl_api_address_union (u8 * s, va_list * args) +{ + const vl_api_address_union_t *addr = + va_arg (*args, vl_api_address_union_t *); + vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t); + + if (ADDRESS_IP6 == af) + s = format (s, "ip6:%U", format_ip6_address, addr->ip6.address); + else + s = format (s, "ip4:%U", format_ip4_address, addr->ip4.address); + + return s; +} + +u8 * +format_vl_api_prefix (u8 * s, va_list * args) +{ + const vl_api_prefix_t *pfx = va_arg (*args, vl_api_prefix_t *); + + s = format (s, "%U/%d", format_vl_api_address, + &pfx->address, pfx->address_length); + + return s; } /* diff --git a/src/vnet/ip/ip_types_api.h b/src/vnet/ip/ip_types_api.h index 2ad59ae438e..1bc899a4588 100644 --- a/src/vnet/ip/ip_types_api.h +++ b/src/vnet/ip/ip_types_api.h @@ -22,23 +22,35 @@ #include <vnet/ip/ip.h> #include <vnet/fib/fib_types.h> +#include <vnet/mfib/mfib_types.h> /** * Forward declarations so we need not #include the API definitions here */ struct _vl_api_address; struct _vl_api_prefix; +struct _vl_api_mprefix; -extern void ip_address_decode (const struct _vl_api_address *in, - ip46_address_t * out); +extern ip46_type_t ip_address_decode (const struct _vl_api_address *in, + ip46_address_t * out); extern void ip_address_encode (const ip46_address_t * in, - struct _vl_api_address *out); + ip46_type_t type, struct _vl_api_address *out); extern void ip_prefix_decode (const struct _vl_api_prefix *in, fib_prefix_t * out); extern void ip_prefix_encode (const fib_prefix_t * in, struct _vl_api_prefix *out); +extern void ip_mprefix_decode (const struct _vl_api_mprefix *in, + mfib_prefix_t * out); +extern void ip_mprefix_encode (const mfib_prefix_t * in, + struct _vl_api_mprefix *out); + +extern u8 *format_vl_api_address (u8 * s, va_list * args); +extern u8 *format_vl_api_address_union (u8 * s, va_list * args); +extern u8 *format_vl_api_prefix (u8 * s, va_list * args); +extern u8 *format_vl_api_mprefix (u8 * s, va_list * args); + #endif /* diff --git a/src/vnet/udp/udp.api b/src/vnet/udp/udp.api index 9f5e2ece6ba..8788fba162d 100644 --- a/src/vnet/udp/udp.api +++ b/src/vnet/udp/udp.api @@ -1,5 +1,6 @@ +/* Hey Emacs use -*- mode: C -*- */ /* - * Copyright (c) 2016 Cisco and/or its affiliates. + * Copyright (c) 2018 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -13,51 +14,79 @@ * limitations under the License. */ -/** \file +/** + * @file + * + * This file defines vpp UDP control-plane API messages which are generally + * called through a shared memory interface. + */ - This file defines vpp UDP control-plane API messages which are generally - called through a shared memory interface. -*/ +option version = "1.1.0"; -option version = "1.0.0"; +import "vnet/ip/ip_types.api"; -/** \brief Add / del table request - A table can be added multiple times, but need be deleted only once. - @param client_index - opaque cookie to identify the sender - @param context - sender context, to match reply w/ request - @param is_ipv6 - V4 or V6 table - @param table_id - table ID associated with the encap destination -*/ -autoreply define udp_encap_add_del + +/** + * @brief UDP Encap object + * @param table_id - table ID associated with the encap destination + * @param dst_ip - Encap destination address + * @param src_ip - Encap source address + * @param dst_port - Encap destination port + * @param src_port - Encap source port + * @param id - The ID assigned to this encap object by the caller + */ +typedef udp_encap { - u32 client_index; - u32 context; u32 id; u32 table_id; - u8 is_ip6; - u8 is_add; u16 src_port; u16 dst_port; - u8 src_ip[16]; - u8 dst_ip[16]; + vl_api_address_t src_ip; + vl_api_address_t dst_ip; +}; + +/** + * @brief Add UDP encap + * @param client_index - opaque cookie to identify the sender + * @param context - sender context, to match reply w/ request + * @param udp_encap - UDP encap description + */ +autoreply define udp_encap_add +{ + u32 client_index; + u32 context; + vl_api_udp_encap_t udp_encap; }; +/** + * @brief Del UDP encap + * @param client_index - opaque cookie to identify the sender + * @param context - sender context, to match reply w/ request + * @param id - ID of the encap object the client chose during the add +*/ +autoreply define udp_encap_del +{ + u32 client_index; + u32 context; + u32 id; +}; + +/** + * @brief dump UDP encaps + */ define udp_encap_dump { u32 client_index; u32 context; }; +/** + * @brief UDP encap details during dump + */ define udp_encap_details { u32 context; - u32 id; - u32 table_id; - u8 is_ip6; - u16 src_port; - u16 dst_port; - u8 src_ip[16]; - u8 dst_ip[16]; + vl_api_udp_encap_t udp_encap; }; /* diff --git a/src/vnet/udp/udp_api.c b/src/vnet/udp/udp_api.c index d643f682a30..43a39b82ef0 100644 --- a/src/vnet/udp/udp_api.c +++ b/src/vnet/udp/udp_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Cisco and/or its affiliates. + * Copyright (c) 2018 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -18,6 +18,7 @@ #include <vnet/udp/udp_encap.h> #include <vnet/fib/fib_table.h> +#include <vnet/ip/ip_types_api.h> #include <vnet/vnet_msg_enum.h> @@ -38,8 +39,9 @@ #include <vlibapi/api_helper_macros.h> -#define foreach_udp_api_msg \ - _(UDP_ENCAP_ADD_DEL, udp_encap_add_del) \ +#define foreach_udp_api_msg \ +_(UDP_ENCAP_DEL, udp_encap_del) \ +_(UDP_ENCAP_ADD, udp_encap_add) \ _(UDP_ENCAP_DUMP, udp_encap_dump) static void @@ -47,33 +49,44 @@ send_udp_encap_details (const udp_encap_t * ue, vl_api_registration_t * reg, u32 context) { vl_api_udp_encap_details_t *mp; - fib_table_t *fib_table; mp = vl_msg_api_alloc (sizeof (*mp)); memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = ntohs (VL_API_UDP_ENCAP_DETAILS); mp->context = context; - mp->is_ip6 = (ue->ue_ip_proto == FIB_PROTOCOL_IP6); - if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto) { - clib_memcpy (mp->src_ip, &ue->ue_hdrs.ip4.ue_ip4.src_address, 4); - clib_memcpy (mp->dst_ip, &ue->ue_hdrs.ip4.ue_ip4.dst_address, 4); - mp->src_port = htons (ue->ue_hdrs.ip4.ue_udp.src_port); - mp->dst_port = htons (ue->ue_hdrs.ip4.ue_udp.dst_port); + clib_memcpy (&mp->udp_encap.src_ip.un.ip4, + &ue->ue_hdrs.ip4.ue_ip4.src_address, 4); + clib_memcpy (&mp->udp_encap.dst_ip.un.ip4, + &ue->ue_hdrs.ip4.ue_ip4.dst_address, 4); + mp->udp_encap.dst_ip.af = clib_host_to_net_u32 (ADDRESS_IP4); + mp->udp_encap.src_ip.af = clib_host_to_net_u32 (ADDRESS_IP4); + + /* ports aren't byte swapped because they are stored in network + * byte order */ + mp->udp_encap.src_port = ue->ue_hdrs.ip4.ue_udp.src_port; + mp->udp_encap.dst_port = ue->ue_hdrs.ip4.ue_udp.dst_port; } else { - clib_memcpy (mp->src_ip, &ue->ue_hdrs.ip6.ue_ip6.src_address, 16); - clib_memcpy (mp->dst_ip, &ue->ue_hdrs.ip6.ue_ip6.dst_address, 16); - mp->src_port = htons (ue->ue_hdrs.ip6.ue_udp.src_port); - mp->dst_port = htons (ue->ue_hdrs.ip6.ue_udp.dst_port); + clib_memcpy (&mp->udp_encap.src_ip.un.ip6, + &ue->ue_hdrs.ip6.ue_ip6.src_address, 16); + clib_memcpy (&mp->udp_encap.dst_ip.un.ip6, + &ue->ue_hdrs.ip6.ue_ip6.dst_address, 16); + mp->udp_encap.dst_ip.af = clib_host_to_net_u32 (ADDRESS_IP6); + mp->udp_encap.src_ip.af = clib_host_to_net_u32 (ADDRESS_IP6); + + /* ports aren't byte swapped because they are stored in network + * byte order */ + mp->udp_encap.src_port = ue->ue_hdrs.ip6.ue_udp.src_port; + mp->udp_encap.dst_port = ue->ue_hdrs.ip6.ue_udp.dst_port; } - fib_table = fib_table_get (ue->ue_fib_index, ue->ue_ip_proto); - mp->table_id = htonl (fib_table->ft_table_id); - mp->id = htonl (ue->ue_id); + mp->udp_encap.table_id = + htonl (fib_table_get_table_id (ue->ue_fib_index, ue->ue_ip_proto)); + mp->udp_encap.id = htonl (ue->ue_id); vl_api_send_msg (reg, (u8 *) mp); } @@ -98,19 +111,21 @@ vl_api_udp_encap_dump_t_handler (vl_api_udp_encap_dump_t * mp, } static void -vl_api_udp_encap_add_del_t_handler (vl_api_udp_encap_add_del_t * mp, - vlib_main_t * vm) +vl_api_udp_encap_add_t_handler (vl_api_udp_encap_add_t * mp, vlib_main_t * vm) { - vl_api_udp_encap_add_del_reply_t *rmp; + vl_api_udp_encap_add_reply_t *rmp; ip46_address_t src_ip, dst_ip; u32 fib_index, table_id, ue_id; fib_protocol_t fproto; + ip46_type_t itype; int rv = 0; - ue_id = ntohl (mp->id); - table_id = ntohl (mp->table_id); - fproto = (mp->is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4); + ue_id = ntohl (mp->udp_encap.id); + table_id = ntohl (mp->udp_encap.table_id); + itype = ip_address_decode (&mp->udp_encap.src_ip, &src_ip); + itype = ip_address_decode (&mp->udp_encap.dst_ip, &dst_ip); + fproto = fib_proto_from_ip46 (itype); fib_index = fib_table_find (fproto, table_id); if (~0 == fib_index) @@ -119,31 +134,25 @@ vl_api_udp_encap_add_del_t_handler (vl_api_udp_encap_add_del_t * mp, goto done; } - if (FIB_PROTOCOL_IP4 == fproto) - { - clib_memcpy (&src_ip.ip4, mp->src_ip, 4); - clib_memcpy (&dst_ip.ip4, mp->dst_ip, 4); - } - else - { - clib_memcpy (&src_ip.ip6, mp->src_ip, 16); - clib_memcpy (&dst_ip.ip6, mp->dst_ip, 16); - } - - if (mp->is_add) - { - udp_encap_add_and_lock (ue_id, fproto, fib_index, - &src_ip, &dst_ip, - ntohs (mp->src_port), - ntohs (mp->dst_port), UDP_ENCAP_FIXUP_NONE); - } - else - { - udp_encap_unlock (ue_id); - } + udp_encap_add_and_lock (ue_id, fproto, fib_index, + &src_ip, &dst_ip, + ntohs (mp->udp_encap.src_port), + ntohs (mp->udp_encap.dst_port), + UDP_ENCAP_FIXUP_NONE); done: - REPLY_MACRO (VL_API_UDP_ENCAP_ADD_DEL_REPLY); + REPLY_MACRO (VL_API_UDP_ENCAP_ADD_REPLY); +} + +static void +vl_api_udp_encap_del_t_handler (vl_api_udp_encap_del_t * mp, vlib_main_t * vm) +{ + vl_api_udp_encap_del_reply_t *rmp; + int rv = 0; + + udp_encap_unlock (ntohl (mp->id)); + + REPLY_MACRO (VL_API_UDP_ENCAP_DEL_REPLY); } #define vl_msg_name_crc_list |