From f7a55ad74c90928d86f1bbf56590d9571c1b828f Mon Sep 17 00:00:00 2001 From: Ole Troan Date: Tue, 16 May 2017 14:59:29 +0200 Subject: PUNT socket: External control plane processes connected via UNIX domain sockets. An external (to VPP) process can register (over the VPP binary API) to receive control plane packets over a UNIX domain socket. The packets are prepended with a packet descriptor containing meta-data (if_index of interface, etc). Currently only UDP is supported. The socket supports sending of packets/frames as well. The sent packet is prepended with a descriptor, telling VPP to route the packet (via ip4-lookup, ip6-lookup) or as an pre-formed Ethernet frame that is sent directly to interface-output. The intended use case for this is for an external DHCP client or a RIP implementation. New configuration option: punt { socket } To register use the punt_socket API message. TODO: - Add support for pre-routing. I.e send L3 packet to given TX interface, but do ARP/ND (ip[46]-rewrite) - Add test scripts - Support for abstract names (starting with \0) - Add rate limiting (COP) - Support for other protocols, e.g. IPv6 ND Change-Id: I4a0afc8020deebb3d9d74686dde694ee5bcb8d0f Signed-off-by: Ole Troan --- src/vpp/api/api.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/vpp/api/vpe.api | 33 +++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) (limited to 'src/vpp/api') diff --git a/src/vpp/api/api.c b/src/vpp/api/api.c index 4e892431..e8bc22ae 100644 --- a/src/vpp/api/api.c +++ b/src/vpp/api/api.c @@ -144,6 +144,8 @@ _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \ ip_source_and_port_range_check_interface_add_del) \ _(DELETE_SUBIF, delete_subif) \ _(PUNT, punt) \ +_(PUNT_SOCKET_REGISTER, punt_socket_register) \ +_(PUNT_SOCKET_DEREGISTER, punt_socket_deregister) \ _(FEATURE_ENABLE_DISABLE, feature_enable_disable) #define QUOTE_(x) #x @@ -1940,6 +1942,68 @@ vl_api_punt_t_handler (vl_api_punt_t * mp) REPLY_MACRO (VL_API_PUNT_REPLY); } +static void +vl_api_punt_socket_register_t_handler (vl_api_punt_socket_register_t * mp) +{ + vl_api_punt_socket_register_reply_t *rmp; + vlib_main_t *vm = vlib_get_main (); + int rv = 0; + clib_error_t *error; + unix_shared_memory_queue_t *q; + u32 handle; + + error = vnet_punt_socket_add (vm, ntohl (mp->header_version), + mp->is_ip4, mp->l4_protocol, + ntohs (mp->l4_port), (char *) mp->pathname); + if (error) + { + rv = -1; + clib_error_report (error); + } + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (!q) + return; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + rmp->_vl_msg_id = htons (VL_API_PUNT_SOCKET_REGISTER_REPLY); + rmp->context = mp->context; + rmp->retval = htonl (rv); + char *p = vnet_punt_get_server_pathname (); + /* Abstract pathnames start with \0 */ + memcpy ((char *) rmp->pathname, p, sizeof (rmp->pathname)); + vl_msg_api_send_shmem (q, (u8 *) & rmp); +} + +static void +vl_api_punt_socket_deregister_t_handler (vl_api_punt_socket_deregister_t * mp) +{ + vl_api_punt_socket_deregister_reply_t *rmp; + vlib_main_t *vm = vlib_get_main (); + int rv = 0; + clib_error_t *error; + unix_shared_memory_queue_t *q; + u32 handle; + + error = vnet_punt_socket_del (vm, mp->is_ip4, mp->l4_protocol, + ntohs (mp->l4_port)); + if (error) + { + rv = -1; + clib_error_report (error); + } + + q = vl_api_client_index_to_input_queue (mp->client_index); + if (!q) + return; + + rmp = vl_msg_api_alloc (sizeof (*rmp)); + rmp->_vl_msg_id = htons (VL_API_PUNT_SOCKET_DEREGISTER_REPLY); + rmp->context = mp->context; + rmp->retval = htonl (rv); + vl_msg_api_send_shmem (q, (u8 *) & rmp); +} + static void vl_api_feature_enable_disable_t_handler (vl_api_feature_enable_disable_t * mp) { diff --git a/src/vpp/api/vpe.api b/src/vpp/api/vpe.api index ec5ffbe9..0dee1533 100644 --- a/src/vpp/api/vpe.api +++ b/src/vpp/api/vpe.api @@ -991,6 +991,39 @@ autoreply define punt { u16 l4_port; }; +/** \brief Punt traffic to the host via socket + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param header_version - expected meta data header version (currently 1) + @param is_ip4 - L3 protocol 1 - IPv4, 0 - IPv6 + @param l4_protocol - L4 protocol to be punted, only UDP (0x11) is supported + @param l4_port - TCP/UDP port to be punted +*/ +define punt_socket_register { + u32 client_index; + u32 context; + u32 header_version; + u8 is_ip4; + u8 l4_protocol; + u16 l4_port; + u8 pathname[64]; +}; + +define punt_socket_register_reply +{ + u32 context; + i32 retval; + u8 pathname[64]; +}; + +autoreply define punt_socket_deregister { + u32 client_index; + u32 context; + u8 is_ip4; + u8 l4_protocol; + u16 l4_port; +}; + /** \brief Feature path enable/disable request @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request -- cgit 1.2.3-korg