From: Pavel Kotucek Date: Mon, 19 Dec 2016 13:47:09 +0000 (+0100) Subject: API refactoring : vxlan-gpe X-Git-Tag: v17.04-rc1~472 X-Git-Url: https://gerrit.fd.io/r/gitweb?p=vpp.git;a=commitdiff_plain;h=296b20162affd0b3bb4168ced045fe7bcb15b03b API refactoring : vxlan-gpe Change-Id: Ia31de797e0ff79ceff010b496af30f5196de9fd6 Signed-off-by: Pavel Kotucek --- diff --git a/vnet/Makefile.am b/vnet/Makefile.am index e871b1c37ad..a4031824e39 100644 --- a/vnet/Makefile.am +++ b/vnet/Makefile.am @@ -35,7 +35,9 @@ BUILT_SOURCES = \ vnet/unix/tap.api.h \ vnet/unix/tap.api.json \ vnet/vxlan/vxlan.api.h \ - vnet/vxlan/vxlan.api.json + vnet/vxlan/vxlan.api.json \ + vnet/vxlan-gpe/vxlan_gpe.api.h \ + vnet/vxlan-gpe/vxlan_gpe.api.json libvnet_la_SOURCES = libvnetplugin_la_SOURCES = @@ -515,12 +517,14 @@ nobase_include_HEADERS += \ libvnet_la_SOURCES += \ vnet/vxlan-gpe/vxlan_gpe.c \ vnet/vxlan-gpe/encap.c \ - vnet/vxlan-gpe/decap.c + vnet/vxlan-gpe/decap.c \ + vnet/vxlan-gpe/vxlan_gpe_api.c nobase_include_HEADERS += \ vnet/vxlan-gpe/vxlan_gpe.h \ vnet/vxlan-gpe/vxlan_gpe_packet.h \ - vnet/vxlan-gpe/vxlan_gpe_error.def + vnet/vxlan-gpe/vxlan_gpe_error.def \ + vnet/vxlan-gpe/vxlan_gpe.api.h ######################################## # Tunnel protocol: ipsec+gre @@ -958,8 +962,9 @@ api_DATA = \ vnet/map/map.api.json \ vnet/span/span.api.json \ vnet/unix/tap.api.json \ - vnet/vxlan/vxlan.api.json - + vnet/vxlan/vxlan.api.json \ + vnet/vxlan-gpe/vxlan_gpe.api.json + # The actual %.api.h rule is in .../build-data/packages/suffix-rules.mk # and requires a symbolic link at the top of the vnet source tree diff --git a/vnet/vnet/vnet_all_api_h.h b/vnet/vnet/vnet_all_api_h.h index 4f4eb76d13c..d2498633e69 100644 --- a/vnet/vnet/vnet_all_api_h.h +++ b/vnet/vnet/vnet_all_api_h.h @@ -39,6 +39,7 @@ #include #include #include +#include /* * fd.io coding-style-patch-verification: ON diff --git a/vnet/vnet/vxlan-gpe/vxlan_gpe.api b/vnet/vnet/vxlan-gpe/vxlan_gpe.api new file mode 100644 index 00000000000..6c6973f8384 --- /dev/null +++ b/vnet/vnet/vxlan-gpe/vxlan_gpe.api @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015-2016 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: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +define vxlan_gpe_add_del_tunnel +{ + u32 client_index; + u32 context; + u8 is_ipv6; + u8 local[16]; + u8 remote[16]; + u32 encap_vrf_id; + u32 decap_vrf_id; + u8 protocol; + u32 vni; + u8 is_add; +}; + +define vxlan_gpe_add_del_tunnel_reply +{ + u32 context; + i32 retval; + u32 sw_if_index; +}; + +define vxlan_gpe_tunnel_dump +{ + u32 client_index; + u32 context; + u32 sw_if_index; +}; + +define vxlan_gpe_tunnel_details +{ + u32 context; + u32 sw_if_index; + u8 local[16]; + u8 remote[16]; + u32 vni; + u8 protocol; + u32 encap_vrf_id; + u32 decap_vrf_id; + u8 is_ipv6; +}; + +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ \ No newline at end of file diff --git a/vnet/vnet/vxlan-gpe/vxlan_gpe_api.c b/vnet/vnet/vxlan-gpe/vxlan_gpe_api.c new file mode 100644 index 00000000000..012a41dabbb --- /dev/null +++ b/vnet/vnet/vxlan-gpe/vxlan_gpe_api.c @@ -0,0 +1,249 @@ +/* + *------------------------------------------------------------------ + * vxlan_gpe_api.c - vxlan_gpe api + * + * Copyright (c) 2016 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: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------ + */ + +#include +#include + +#include +#include +#include +#include + +#include + +#define vl_typedefs /* define message structures */ +#include +#undef vl_typedefs + +#define vl_endianfun /* define message structures */ +#include +#undef vl_endianfun + +/* instantiate all the print functions we know about */ +#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__) +#define vl_printfun +#include +#undef vl_printfun + +#include + +#define foreach_vpe_api_msg \ +_(VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel) \ +_(VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump) \ + +static void + vl_api_vxlan_gpe_add_del_tunnel_t_handler + (vl_api_vxlan_gpe_add_del_tunnel_t * mp) +{ + vl_api_vxlan_gpe_add_del_tunnel_reply_t *rmp; + int rv = 0; + vnet_vxlan_gpe_add_del_tunnel_args_t _a, *a = &_a; + u32 encap_fib_index, decap_fib_index; + u8 protocol; + uword *p; + ip4_main_t *im = &ip4_main; + u32 sw_if_index = ~0; + + + p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id)); + if (!p) + { + rv = VNET_API_ERROR_NO_SUCH_FIB; + goto out; + } + encap_fib_index = p[0]; + + protocol = mp->protocol; + + /* Interpret decap_vrf_id as an opaque if sending to other-than-ip4-input */ + if (protocol == VXLAN_GPE_INPUT_NEXT_IP4_INPUT) + { + p = hash_get (im->fib_index_by_table_id, ntohl (mp->decap_vrf_id)); + if (!p) + { + rv = VNET_API_ERROR_NO_SUCH_INNER_FIB; + goto out; + } + decap_fib_index = p[0]; + } + else + { + decap_fib_index = ntohl (mp->decap_vrf_id); + } + + /* Check src & dst are different */ + if ((mp->is_ipv6 && memcmp (mp->local, mp->remote, 16) == 0) || + (!mp->is_ipv6 && memcmp (mp->local, mp->remote, 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 */ + if (a->is_ip6) + { + clib_memcpy (&(a->local.ip6), mp->local, 16); + clib_memcpy (&(a->remote.ip6), mp->remote, 16); + } + else + { + clib_memcpy (&(a->local.ip4), mp->local, 4); + clib_memcpy (&(a->remote.ip4), mp->remote, 4); + } + a->encap_fib_index = encap_fib_index; + a->decap_fib_index = decap_fib_index; + a->protocol = protocol; + a->vni = ntohl (mp->vni); + rv = vnet_vxlan_gpe_add_del_tunnel (a, &sw_if_index); + +out: + /* *INDENT-OFF* */ + REPLY_MACRO2(VL_API_VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, + ({ + rmp->sw_if_index = ntohl (sw_if_index); + })); + /* *INDENT-ON* */ +} + +static void send_vxlan_gpe_tunnel_details + (vxlan_gpe_tunnel_t * t, unix_shared_memory_queue_t * q, u32 context) +{ + vl_api_vxlan_gpe_tunnel_details_t *rmp; + ip4_main_t *im4 = &ip4_main; + ip6_main_t *im6 = &ip6_main; + u8 is_ipv6 = !(t->flags & VXLAN_GPE_TUNNEL_IS_IPV4); + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + memset (rmp, 0, sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_VXLAN_GPE_TUNNEL_DETAILS); + if (is_ipv6) + { + memcpy (rmp->local, &(t->local.ip6), 16); + memcpy (rmp->remote, &(t->remote.ip6), 16); + rmp->encap_vrf_id = htonl (im6->fibs[t->encap_fib_index].ft_table_id); + rmp->decap_vrf_id = htonl (im6->fibs[t->decap_fib_index].ft_table_id); + } + else + { + memcpy (rmp->local, &(t->local.ip4), 4); + memcpy (rmp->remote, &(t->remote.ip4), 4); + rmp->encap_vrf_id = htonl (im4->fibs[t->encap_fib_index].ft_table_id); + rmp->decap_vrf_id = htonl (im4->fibs[t->decap_fib_index].ft_table_id); + } + rmp->vni = htonl (t->vni); + rmp->protocol = t->protocol; + rmp->sw_if_index = htonl (t->sw_if_index); + rmp->is_ipv6 = is_ipv6; + rmp->context = context; + + vl_msg_api_send_shmem (q, (u8 *) & rmp); +} + +static void vl_api_vxlan_gpe_tunnel_dump_t_handler + (vl_api_vxlan_gpe_tunnel_dump_t * mp) +{ + unix_shared_memory_queue_t *q; + vxlan_gpe_main_t *vgm = &vxlan_gpe_main; + vxlan_gpe_tunnel_t *t; + u32 sw_if_index; + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (q == 0) + { + return; + } + + sw_if_index = ntohl (mp->sw_if_index); + + if (~0 == sw_if_index) + { + /* *INDENT-OFF* */ + pool_foreach (t, vgm->tunnels, + ({ + send_vxlan_gpe_tunnel_details(t, q, mp->context); + })); + /* *INDENT-ON* */ + } + else + { + if ((sw_if_index >= vec_len (vgm->tunnel_index_by_sw_if_index)) || + (~0 == vgm->tunnel_index_by_sw_if_index[sw_if_index])) + { + return; + } + t = &vgm->tunnels[vgm->tunnel_index_by_sw_if_index[sw_if_index]]; + send_vxlan_gpe_tunnel_details (t, q, mp->context); + } +} + + +/* + * vpe_api_hookup + * Add vpe's API message handlers to the table. + * vlib has alread mapped shared memory and + * added the client registration handlers. + * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process() + */ +#define vl_msg_name_crc_list +#include +#undef vl_msg_name_crc_list + +static void +setup_message_id_table (api_main_t * am) +{ +#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id); + foreach_vl_msg_name_crc_span; +#undef _ +} + +static clib_error_t * +vxlan_gpe_api_hookup (vlib_main_t * vm) +{ + api_main_t *am = &api_main; + +#define _(N,n) \ + vl_msg_api_set_handlers(VL_API_##N, #n, \ + vl_api_##n##_t_handler, \ + vl_noop_handler, \ + vl_api_##n##_t_endian, \ + vl_api_##n##_t_print, \ + sizeof(vl_api_##n##_t), 1); + foreach_vpe_api_msg; +#undef _ + + /* + * Set up the (msg_name, crc, message-id) table + */ + setup_message_id_table (am); + + return 0; +} + +VLIB_API_INIT_FUNCTION (vxlan_gpe_api_hookup); + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/vpp-api/java/Makefile.am b/vpp-api/java/Makefile.am index d1ed33d170d..1d0a6758536 100644 --- a/vpp-api/java/Makefile.am +++ b/vpp-api/java/Makefile.am @@ -91,7 +91,8 @@ jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: \ $(prefix)/../vpp/vpp-api/vpe.api.json \ $(prefix)/../vnet/vnet/ip.api.json \ $(prefix)/../vnet/vnet/tap.api.json \ - $(prefix)/../vnet/vnet/vxlan.api.json + $(prefix)/../vnet/vnet/vxlan.api.json \ + $(prefix)/../vnet/vnet/vxlan_gpe.api.json cp -rf @srcdir@/jvpp-core/* -t jvpp-core/ mkdir -p jvpp-core/target cd jvpp-core \ @@ -108,6 +109,7 @@ jvpp-core/io_fd_vpp_jvpp_core_JVppCoreImpl.h: \ $(prefix)/../vnet/vnet/span.api.json \ $(prefix)/../vnet/vnet/tap.api.json \ $(prefix)/../vnet/vnet/vxlan.api.json \ + $(prefix)/../vnet/vnet/vxlan_gpe.api.json \ && cp -rf types dto future callfacade callback notification *.java -t $(packagedir_jvpp_core) \ && rm -rf types dto future callfacade callback notification *.java diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index 2bd3006447e..7ed4041a41d 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -29,6 +29,7 @@ * AF-PACKET APIs: ... see /vnet/devices/af_packet/{af_packet.api, af_packet_api.c} * NETMAP APIs: see ... /vnet/vnet/devices/netmap/{netmap.api, netmap_api.c} * VHOST-USER APIs: see .../vnet/devices/virtio/{vhost_user.api, vhost_user_api.c} + * VXLAN GPE APIs: see .../vnet/vnet/vxlan-gpe/{vxlan_gpe.api, vxlan_gpe_api.c} */ /** \brief Create a new subinterface with the given vlan id @@ -1627,47 +1628,6 @@ define l2_fib_table_dump u32 bd_id; }; -define vxlan_gpe_add_del_tunnel -{ - u32 client_index; - u32 context; - u8 is_ipv6; - u8 local[16]; - u8 remote[16]; - u32 encap_vrf_id; - u32 decap_vrf_id; - u8 protocol; - u32 vni; - u8 is_add; -}; - -define vxlan_gpe_add_del_tunnel_reply -{ - u32 context; - i32 retval; - u32 sw_if_index; -}; - -define vxlan_gpe_tunnel_dump -{ - u32 client_index; - u32 context; - u32 sw_if_index; -}; - -define vxlan_gpe_tunnel_details -{ - u32 context; - u32 sw_if_index; - u8 local[16]; - u8 remote[16]; - u32 vni; - u8 protocol; - u32 encap_vrf_id; - u32 decap_vrf_id; - u8 is_ipv6; -}; - /** \brief add or delete locator_set @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request