summaryrefslogtreecommitdiffstats
path: root/vpp-api-test/vat/api_format.c
diff options
context:
space:
mode:
authorChris Luke <chrisy@flirble.org>2016-04-26 10:49:53 -0400
committerChris Luke <chrisy@flirble.org>2016-04-28 15:13:01 -0400
commit99cb335ac1209d5bb7ede754f59d7df898ae0e81 (patch)
tree406b1741f6cbd1750ded32e6f047645080e74313 /vpp-api-test/vat/api_format.c
parent1589576c57e4bfb2b81dc5237e0af74130cb908f (diff)
VXLAN over IPv6.
Refactors the VXLAN node to work with both IPv4 and IPv6 transports. There is a discussion thread for this change at https://lists.fd.io/pipermail/vpp-dev/2016-March/000279.html Note that this changes the binary configuration API to support both address families; each address uses the same memory for either address type and a flag to indicate which is in use. This also includes changes to the Java API to support both address families. The CLI and VAT syntax remains unchanged; the code detects whether an IPv4 or an IPv6 address was given. Configuration examples: IPv4 CLI: create vxlan tunnel src 192.168.1.1 dst 192.168.1.2 vni 10 encap-vrf-id 0 decap-next l2 IPv6 CLI: create vxlan tunnel src 2620:124:9000::1 dst 2620:124:9000::2 vni 16 encap-vrf-id 0 decap-next l2 IPv4 VAT: vxlan_add_del_tunnel src 192.168.1.1 dst 192.168.1.2 vni 10 encap-vrf-id 0 decap-next l2 IPv6 VAT: vxlan_add_del_tunnel src 2620:124:9000::1 dst 2620:124:9000::2 vni 16 encap-vrf-id 0 decap-next l2 TODO: The encap path is not as optimal as it could be. Change-Id: I87be8bf0501e0c9cd7e401be4542bb599f1b6e47 Signed-off-by: Chris Luke <chrisy@flirble.org>
Diffstat (limited to 'vpp-api-test/vat/api_format.c')
-rw-r--r--vpp-api-test/vat/api_format.c79
1 files changed, 64 insertions, 15 deletions
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c
index ed96af71a4c..72eb3392d97 100644
--- a/vpp-api-test/vat/api_format.c
+++ b/vpp-api-test/vat/api_format.c
@@ -419,6 +419,15 @@ u8 * format_ip6_address (u8 * s, va_list * args)
return s;
}
+/* Format an IP46 address. */
+u8 * format_ip46_address (u8 * s, va_list * args)
+{
+ ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
+ return ip46_address_is_ip4(ip46)?
+ format(s, "%U", format_ip4_address, &ip46->ip4):
+ format(s, "%U", format_ip6_address, &ip46->ip6);
+}
+
u8 * format_ethernet_address (u8 * s, va_list * args)
{
u8 * a = va_arg (*args, u8 *);
@@ -7068,8 +7077,10 @@ static int api_vxlan_add_del_tunnel (vat_main_t * vam)
unformat_input_t * line_input = vam->input;
vl_api_vxlan_add_del_tunnel_t *mp;
f64 timeout;
- ip4_address_t src, dst;
+ ip4_address_t src4, dst4;
+ ip6_address_t src6, dst6;
u8 is_add = 1;
+ u8 ipv4_set = 0, ipv6_set = 0;
u8 src_set = 0;
u8 dst_set = 0;
u32 encap_vrf_id = 0;
@@ -7080,11 +7091,29 @@ static int api_vxlan_add_del_tunnel (vat_main_t * vam)
if (unformat (line_input, "del"))
is_add = 0;
else if (unformat (line_input, "src %U",
- unformat_ip4_address, &src))
+ unformat_ip4_address, &src4))
+ {
+ ipv4_set = 1;
src_set = 1;
+ }
else if (unformat (line_input, "dst %U",
- unformat_ip4_address, &dst))
+ unformat_ip4_address, &dst4))
+ {
+ ipv4_set = 1;
+ dst_set = 1;
+ }
+ else if (unformat (line_input, "src %U",
+ unformat_ip6_address, &src6))
+ {
+ ipv6_set = 1;
+ src_set = 1;
+ }
+ else if (unformat (line_input, "dst %U",
+ unformat_ip6_address, &dst6))
+ {
+ ipv6_set = 1;
dst_set = 1;
+ }
else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
;
else if (unformat (line_input, "decap-next %U",
@@ -7107,19 +7136,30 @@ static int api_vxlan_add_del_tunnel (vat_main_t * vam)
return -99;
}
+ if (ipv4_set && ipv6_set) {
+ errmsg ("both IPv4 and IPv6 addresses specified");
+ return -99;
+ }
+
if ((vni == 0) || (vni>>24)) {
errmsg ("vni not specified or out of range\n");
return -99;
}
M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
-
- mp->src_address = src.as_u32;
- mp->dst_address = dst.as_u32;
+
+ if (ipv6_set) {
+ clib_memcpy(&mp->dst_address, &src6, sizeof(src6));
+ clib_memcpy(&mp->dst_address, &src6, sizeof(dst6));
+ } else {
+ clib_memcpy(&mp->src_address, &src4, sizeof(src4));
+ clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
+ }
mp->encap_vrf_id = ntohl(encap_vrf_id);
mp->decap_next_index = ntohl(decap_next_index);
mp->vni = ntohl(vni);
mp->is_add = is_add;
+ mp->is_ipv6 = ipv6_set;
S; W;
/* NOTREACHED */
@@ -7131,10 +7171,10 @@ static void vl_api_vxlan_tunnel_details_t_handler
{
vat_main_t * vam = &vat_main;
- fformat(vam->ofp, "%11d%13U%13U%14d%18d%13d\n",
+ fformat(vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
ntohl(mp->sw_if_index),
- format_ip4_address, &mp->src_address,
- format_ip4_address, &mp->dst_address,
+ format_ip46_address, &(mp->src_address[0]),
+ format_ip46_address, &(mp->dst_address[0]),
ntohl(mp->encap_vrf_id),
ntohl(mp->decap_next_index),
ntohl(mp->vni));
@@ -7146,6 +7186,7 @@ static void vl_api_vxlan_tunnel_details_t_handler_json
vat_main_t * vam = &vat_main;
vat_json_node_t *node = NULL;
struct in_addr ip4;
+ struct in6_addr ip6;
if (VAT_JSON_ARRAY != vam->json_tree.type) {
ASSERT(VAT_JSON_NONE == vam->json_tree.type);
@@ -7155,13 +7196,21 @@ static void vl_api_vxlan_tunnel_details_t_handler_json
vat_json_init_object(node);
vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
- clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
- vat_json_object_add_ip4(node, "src_address", ip4);
- clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
- vat_json_object_add_ip4(node, "dst_address", ip4);
+ if (mp->is_ipv6) {
+ clib_memcpy(&ip6, &(mp->src_address[0]), sizeof(ip6));
+ vat_json_object_add_ip6(node, "src_address", ip6);
+ clib_memcpy(&ip6, &(mp->dst_address[0]), sizeof(ip6));
+ vat_json_object_add_ip6(node, "dst_address", ip6);
+ } else {
+ clib_memcpy(&ip4, &(mp->src_address[0]), sizeof(ip4));
+ vat_json_object_add_ip4(node, "src_address", ip4);
+ clib_memcpy(&ip4, &(mp->dst_address[0]), sizeof(ip4));
+ vat_json_object_add_ip4(node, "dst_address", ip4);
+ }
vat_json_object_add_uint(node, "encap_vrf_id", ntohl(mp->encap_vrf_id));
vat_json_object_add_uint(node, "decap_next_index", ntohl(mp->decap_next_index));
vat_json_object_add_uint(node, "vni", ntohl(mp->vni));
+ vat_json_object_add_uint(node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
}
static int api_vxlan_tunnel_dump (vat_main_t * vam)
@@ -7185,12 +7234,12 @@ static int api_vxlan_tunnel_dump (vat_main_t * vam)
}
if (!vam->json_output) {
- fformat(vam->ofp, "%11s%13s%13s%14s%18s%13s\n",
+ fformat(vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
"sw_if_index", "src_address", "dst_address",
"encap_vrf_id", "decap_next_index", "vni");
}
- /* Get list of l2tpv3-tunnel interfaces */
+ /* Get list of vxlan-tunnel interfaces */
M(VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
mp->sw_if_index = htonl(sw_if_index);