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 --- .../org/openvpp/vppjapi/vppVxlanTunnelDetails.java | 10 ++-- vpp-api/java/japi/vppjni.c | 60 ++++++++++++++++++++-- vpp-api/java/japi/vppjni.h | 5 +- 3 files changed, 64 insertions(+), 11 deletions(-) (limited to 'vpp-api') diff --git a/vpp-api/java/japi/org/openvpp/vppjapi/vppVxlanTunnelDetails.java b/vpp-api/java/japi/org/openvpp/vppjapi/vppVxlanTunnelDetails.java index dd81e98c..fe3d0bca 100644 --- a/vpp-api/java/japi/org/openvpp/vppjapi/vppVxlanTunnelDetails.java +++ b/vpp-api/java/japi/org/openvpp/vppjapi/vppVxlanTunnelDetails.java @@ -16,18 +16,20 @@ package org.openvpp.vppjapi; public final class vppVxlanTunnelDetails { - public final int srcAddress; - public final int dstAddress; + public final byte[] srcAddress; + public final byte[] dstAddress; public final int encapVrfId; public final int vni; public final int decapNextIndex; + public final boolean isIpv6; - public vppVxlanTunnelDetails(int srcAddress, int dstAddress, - int encapVrfId, int vni, int decapNextIndex) { + public vppVxlanTunnelDetails(byte[] srcAddress, byte[] dstAddress, + int encapVrfId, int vni, int decapNextIndex, boolean isIpv6) { this.srcAddress = srcAddress; this.dstAddress = dstAddress; this.encapVrfId = encapVrfId; this.vni = vni; this.decapNextIndex = decapNextIndex; + this.isIpv6 = isIpv6; } } diff --git a/vpp-api/java/japi/vppjni.c b/vpp-api/java/japi/vppjni.c index c3a1078b..5645263a 100644 --- a/vpp-api/java/japi/vppjni.c +++ b/vpp-api/java/japi/vppjni.c @@ -1471,14 +1471,24 @@ JNIEXPORT jobjectArray JNICALL Java_org_openvpp_vppjapi_vppConn_vxlanTunnelDump0 for (i = 0; i < count; i++) { vxlan_tunnel_details_t *details = &jm->vxlan_tunnel_details[i]; - jint src_address = details->src_address; - jint dst_address = details->dst_address; + + /* This interface to support both v4 and v6 addresses is nasty */ + jbyteArray src_address = (*env)->NewByteArray(env, 16); + (*env)->SetByteArrayRegion(env, src_address, 0, 16, + (signed char*)details->src_address); + + jbyteArray dst_address = (*env)->NewByteArray(env, 16); + (*env)->SetByteArrayRegion(env, dst_address, 0, 16, + (signed char*)details->dst_address); + jint encap_vrf_id = details->encap_vrf_id; jint vni = details->vni; jint decap_next_index = details->decap_next_index; + jboolean is_ipv6 = details->is_ipv6 ? 1 : 0; jobject vxlanTunnelDetailsObj = vppVxlanTunnelDetailsObject(env, - src_address, dst_address, encap_vrf_id, vni, decap_next_index); + src_address, dst_address, encap_vrf_id, vni, + decap_next_index, is_ipv6); (*env)->SetObjectArrayElement(env, vxlanTunnelDetailsArray, i, vxlanTunnelDetailsObj); @@ -1498,11 +1508,51 @@ static void vl_api_vxlan_tunnel_details_t_handler vxlan_tunnel_details_t *tunnel_details; vec_add2(jm->vxlan_tunnel_details, tunnel_details, 1); - tunnel_details->src_address = ntohl(mp->src_address); - tunnel_details->dst_address = ntohl(mp->dst_address); + if (mp->is_ipv6){ + u64 *s, *d; + + /* this is ugly - why is this in host order at all? -cluke */ + /* Per notes from Ole, Maros and Keith, this should all be + * superceded with a new api builder soon, so this interface will + * be short lived -cluke */ + s = (void *)mp->src_address; + d = (void *)tunnel_details->src_address; +#if CLIB_ARCH_IS_LITTLE_ENDIAN + d[0] = clib_net_to_host_u64(s[1]); + d[1] = clib_net_to_host_u64(s[0]); +#else /* big endian */ + d[0] = s[0]; + d[1] = s[1]; +#endif + + s = (void *)mp->dst_address; + d = (void *)tunnel_details->dst_address; +#if CLIB_ARCH_IS_LITTLE_ENDIAN + d[0] = clib_net_to_host_u64(s[1]); + d[1] = clib_net_to_host_u64(s[0]); +#else /* big endian */ + d[0] = s[0]; + d[1] = s[1]; +#endif + } else { + u32 *s, *d; + + /* the type changed from a u32 to u8[16] - this does + * the same as dst = ntohl(src) with the u32 of a v4 + * address in the first 32 bits */ + + s = (void *)mp->src_address; + d = (void *)tunnel_details->src_address; + d[0] = ntohl(s[0]); + + s = (void *)mp->dst_address; + d = (void *)tunnel_details->dst_address; + d[0] = ntohl(s[0]); + } tunnel_details->encap_vrf_id = ntohl(mp->encap_vrf_id); tunnel_details->vni = ntohl(mp->vni); tunnel_details->decap_next_index = ntohl(mp->decap_next_index); + tunnel_details->is_ipv6 = mp->is_ipv6; } /* cleanup handler for RX thread */ diff --git a/vpp-api/java/japi/vppjni.h b/vpp-api/java/japi/vppjni.h index bd0683ae..bc738367 100644 --- a/vpp-api/java/japi/vppjni.h +++ b/vpp-api/java/japi/vppjni.h @@ -124,11 +124,12 @@ typedef struct { } sw_interface_stats_t; typedef struct { - u32 src_address; - u32 dst_address; + u8 src_address[16]; + u8 dst_address[16]; u32 encap_vrf_id; u32 vni; u32 decap_next_index; + u8 is_ipv6; } vxlan_tunnel_details_t; -- cgit 1.2.3-korg