From 99cb335ac1209d5bb7ede754f59d7df898ae0e81 Mon Sep 17 00:00:00 2001 From: Chris Luke Date: Tue, 26 Apr 2016 10:49:53 -0400 Subject: 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 --- vpp/api/api.c | 33 +++++++++++++++++++++++++++------ vpp/api/custom_dump.c | 8 ++++---- vpp/api/vpe.api | 10 ++++++---- 3 files changed, 37 insertions(+), 14 deletions(-) (limited to 'vpp') diff --git a/vpp/api/api.c b/vpp/api/api.c index b7f2a16bcaf..1b6d52be28d 100644 --- a/vpp/api/api.c +++ b/vpp/api/api.c @@ -4196,13 +4196,25 @@ static void vl_api_vxlan_add_del_tunnel_t_handler } encap_fib_index = p[0]; + /* Check src & dst are different */ + if ((a->is_ip6 && memcmp(mp->src_address, mp->dst_address, 16) == 0) || + (!a->is_ip6 && memcmp(mp->src_address, mp->dst_address, 4) == 0)) { + rv = VNET_API_ERROR_SAME_SRC_DST; + goto out; + } memset (a, 0, sizeof (*a)); a->is_add = mp->is_add; + a->is_ip6 = mp->is_ipv6; /* ip addresses sent in network byte order */ - a->src.as_u32 = mp->src_address; - a->dst.as_u32 = mp->dst_address; + if (a->is_ip6) { + memcpy(&(a->src.ip6), mp->src_address, 16); + memcpy(&(a->dst.ip6), mp->dst_address, 16); + } else { + memcpy(&(a->src.ip4), mp->src_address, 4); + memcpy(&(a->dst.ip4), mp->dst_address, 4); + } a->encap_fib_index = encap_fib_index; a->decap_next_index = ntohl(mp->decap_next_index); @@ -4220,17 +4232,26 @@ static void send_vxlan_tunnel_details (vxlan_tunnel_t * t, unix_shared_memory_queue_t * q) { vl_api_vxlan_tunnel_details_t * rmp; - ip4_main_t * im = &ip4_main; + ip4_main_t * im4 = &ip4_main; + ip6_main_t * im6 = &ip6_main; + u8 is_ipv6 = !(t->flags & VXLAN_TUNNEL_IS_IPV4); rmp = vl_msg_api_alloc (sizeof (*rmp)); memset (rmp, 0, sizeof (*rmp)); rmp->_vl_msg_id = ntohs(VL_API_VXLAN_TUNNEL_DETAILS); - rmp->src_address = t->src.data_u32; - rmp->dst_address = t->dst.data_u32; - rmp->encap_vrf_id = htonl(im->fibs[t->encap_fib_index].table_id); + if (is_ipv6) { + memcpy(rmp->src_address, &(t->src.ip6), 16); + memcpy(rmp->dst_address, &(t->dst.ip6), 16); + rmp->encap_vrf_id = htonl(im6->fibs[t->encap_fib_index].table_id); + } else { + memcpy(rmp->src_address, &(t->src.ip4), 4); + memcpy(rmp->dst_address, &(t->dst.ip4), 4); + rmp->encap_vrf_id = htonl(im4->fibs[t->encap_fib_index].table_id); + } rmp->vni = htonl(t->vni); rmp->decap_next_index = htonl(t->decap_next_index); rmp->sw_if_index = htonl(t->sw_if_index); + rmp->is_ipv6 = is_ipv6; vl_msg_api_send_shmem (q, (u8 *)&rmp); } diff --git a/vpp/api/custom_dump.c b/vpp/api/custom_dump.c index 6bdbdc55803..6ffc8c95592 100644 --- a/vpp/api/custom_dump.c +++ b/vpp/api/custom_dump.c @@ -1266,11 +1266,11 @@ static void * vl_api_vxlan_add_del_tunnel_t_print s = format (0, "SCRIPT: vxlan_add_del_tunnel "); - s = format (s, "dst %U ", format_ip4_address, - (ip4_address_t *)&(mp->dst_address)); + s = format (s, "dst %U ", format_ip46_address, + (ip46_address_t *)&(mp->dst_address), mp->is_ipv6); - s = format (s, "src %U ", format_ip4_address, - (ip4_address_t *)&(mp->src_address)); + s = format (s, "src %U ", format_ip46_address, + (ip46_address_t *)&(mp->src_address), mp->is_ipv6); if (mp->encap_vrf_id) s = format (s, "encap-vrf-id %d ", ntohl(mp->encap_vrf_id)); diff --git a/vpp/api/vpe.api b/vpp/api/vpe.api index 50f971416bc..52893b58ef0 100644 --- a/vpp/api/vpe.api +++ b/vpp/api/vpe.api @@ -1769,8 +1769,9 @@ define vxlan_add_del_tunnel { u32 client_index; u32 context; u8 is_add; - u32 src_address; - u32 dst_address; + u8 is_ipv6; + u8 src_address[16]; + u8 dst_address[16]; u32 encap_vrf_id; u32 decap_next_index; u32 vni; @@ -1791,11 +1792,12 @@ manual_java define vxlan_tunnel_dump { manual_java define vxlan_tunnel_details { u32 context; u32 sw_if_index; - u32 src_address; - u32 dst_address; + u8 src_address[16]; + u8 dst_address[16]; u32 encap_vrf_id; u32 decap_next_index; u32 vni; + u8 is_ipv6; }; /** \brief L2 interface vlan tag rewrite configure request -- cgit 1.2.3-korg