Simple ip4 NAT plugin
Change-Id: Iffe77bf2a05ced41474540ff54a842101aad7c41 Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
@ -38,6 +38,10 @@ vnet_configure_args_vpp = --with-dpdk
|
||||
# Set these parameters carefully. The vlib_buffer_t is 128 bytes, i.e.
|
||||
vlib_configure_args_vpp = --with-pre-data=128
|
||||
|
||||
# Enable plugins here, and no place else, via multiple --enable-XXX-plugin
|
||||
# stanzas.
|
||||
plugins_configure_args_vpp = --with-dpdk --enable-sixrd-plugin
|
||||
|
||||
# DPDK configuration parameters
|
||||
# vpp_uses_external_dpdk = yes
|
||||
# vpp_dpdk_inc_dir = /usr/include/dpdk
|
||||
|
@ -29,3 +29,7 @@ endif
|
||||
if ENABLE_VCGN_PLUGIN
|
||||
SUBDIRS += vcgn-plugin
|
||||
endif
|
||||
|
||||
if ENABLE_SNAT_PLUGIN
|
||||
SUBDIRS += snat-plugin
|
||||
endif
|
||||
|
@ -17,10 +17,30 @@ AC_ARG_WITH(plugin-toolkit,
|
||||
[with_plugin_toolkit=${prefix}/include],
|
||||
[with_plugin_toolkit=.])
|
||||
|
||||
AC_ARG_WITH(dpdk,
|
||||
AC_HELP_STRING([--with-dpdk],[Use the Intel dpdk]),
|
||||
[with_dpdk=1],
|
||||
[with_dpdk=0])
|
||||
|
||||
AC_SUBST(TOOLKIT_INCLUDE,[${with_plugin_toolkit}])
|
||||
AM_CONDITIONAL(WITH_PLUGIN_TOOLKIT, test "$with_plugin_toolkit" != ".")
|
||||
AM_CONDITIONAL(ENABLE_TESTS, test "$enable_tests" = "1")
|
||||
|
||||
AM_CONDITIONAL(WITH_DPDK, test "$with_dpdk" = "1")
|
||||
AC_SUBST(DPDK,["-DDPDK=${with_dpdk}"])
|
||||
|
||||
|
||||
#
|
||||
# Please DO NOT, UNDER ANY CIRCUMSTANCES enable or disable
|
||||
# plugins by "clever" manipulation of the arguments to AC_ARG_ENABLE
|
||||
#
|
||||
# Instead, please configure the default set of plugins in
|
||||
# .../build-data/platforms/<platform>.mk, by adding --enable-XXX-plugin
|
||||
# stanzas to plugins_configure_args_<platform>
|
||||
|
||||
# The following per-plugin boilerplate is begging for an additional
|
||||
# macro, but the first 10 tries at making one didn't work. Another day.
|
||||
|
||||
#
|
||||
# Sample plugin
|
||||
#
|
||||
@ -40,8 +60,8 @@ AM_CONDITIONAL(ENABLE_SAMPLE_PLUGIN, test "$enable_sample_plugin" = "1")
|
||||
#
|
||||
AC_ARG_ENABLE(sixrd_plugin,
|
||||
AC_HELP_STRING([--enable-sixrd-plugin], [Build sixrd plugin]),
|
||||
[],
|
||||
[enable_sixrd_plugin=1])
|
||||
[enable_sixrd_plugin=1],
|
||||
[enable_sixrd_plugin=0])
|
||||
|
||||
if test "x$enable_sixrd_plugin" = x1; then
|
||||
AC_CONFIG_SUBDIRS([sixrd-plugin])
|
||||
@ -54,8 +74,8 @@ AM_CONDITIONAL(ENABLE_SIXRD_PLUGIN, test "$enable_sixrd_plugin" = "1")
|
||||
#
|
||||
AC_ARG_ENABLE(ioam_plugin,
|
||||
AC_HELP_STRING([--enable-ioam-plugin], [Build ioam plugin]),
|
||||
[],
|
||||
[enable_ioam_plugin=1])
|
||||
[enable_ioam_plugin=1],
|
||||
[enable_ioam_plugin=0])
|
||||
|
||||
if test "x$enable_ioam_plugin" = x1; then
|
||||
AC_CONFIG_SUBDIRS([ioam-plugin])
|
||||
@ -77,4 +97,19 @@ fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_VCGN_PLUGIN, test "$enable_vcgn_plugin" = "1")
|
||||
|
||||
#
|
||||
# SNAT plugin
|
||||
#
|
||||
AC_ARG_ENABLE(snat_plugin,
|
||||
AC_HELP_STRING([--enable-snat-plugin], [Build snat plugin]),
|
||||
[enable_snat_plugin=1],
|
||||
[enable_snat_plugin=0])
|
||||
|
||||
if test "x$enable_snat_plugin" = x1; then
|
||||
AC_CONFIG_SUBDIRS([snat-plugin])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_SNAT_PLUGIN, test "$enable_snat_plugin" = "1")
|
||||
|
||||
|
||||
AC_OUTPUT([Makefile])
|
||||
|
55
plugins/snat-plugin/Makefile.am
Normal file
55
plugins/snat-plugin/Makefile.am
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
# Copyright (c) <current-year> <your-organization>
|
||||
# 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.
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
AM_CFLAGS = -Wall -I@TOOLKIT_INCLUDE@ @DPDK@
|
||||
|
||||
lib_LTLIBRARIES = snat_plugin.la snat_test_plugin.la
|
||||
|
||||
snat_plugin_la_SOURCES = snat/snat.c \
|
||||
snat/in2out.c \
|
||||
snat/out2in.c \
|
||||
snat/snat_plugin.api.h
|
||||
|
||||
snat_plugin_la_LDFLAGS = -module
|
||||
|
||||
BUILT_SOURCES = snat/snat.api.h
|
||||
|
||||
SUFFIXES = .api.h .api
|
||||
|
||||
%.api.h: %.api
|
||||
mkdir -p `dirname $@` ; \
|
||||
$(CC) $(CPPFLAGS) -E -P -C -x c $^ \
|
||||
| vppapigen --input - --output $@ --show-name $@
|
||||
|
||||
nobase_include_HEADERS = \
|
||||
snat/snat_all_api_h.h \
|
||||
snat/snat_msg_enum.h \
|
||||
snat/snat.api.h
|
||||
|
||||
snat_test_plugin_la_SOURCES = \
|
||||
snat/snat_test.c snat/snat_plugin.api.h
|
||||
snat_test_plugin_la_LDFLAGS = -module
|
||||
|
||||
if WITH_PLUGIN_TOOLKIT
|
||||
install-data-hook:
|
||||
mkdir /usr/lib/vpp_plugins || true
|
||||
mkdir /usr/lib/vpp_api_test_plugins || true
|
||||
cp -L $(prefix)/lib/snat_plugin.so /usr/lib/vpp_plugins
|
||||
cp -L $(prefix)/lib/snat_test_plugin.so \
|
||||
/usr/lib/vpp_api_test_plugins
|
||||
rm -f $(prefix)/lib/snat_plugin.*
|
||||
rm -f $(prefix)/lib/snat_test_plugin.*
|
||||
endif
|
27
plugins/snat-plugin/configure.ac
Normal file
27
plugins/snat-plugin/configure.ac
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
AC_INIT(snat_plugin, 1.0)
|
||||
AM_INIT_AUTOMAKE
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
AM_PROG_AS
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
|
||||
AC_ARG_WITH(dpdk,
|
||||
AC_HELP_STRING([--with-dpdk],[Use the Intel dpdk]),
|
||||
[with_dpdk=1],
|
||||
[with_dpdk=0])
|
||||
|
||||
AM_CONDITIONAL(WITH_DPDK, test "$with_dpdk" = "1")
|
||||
AC_SUBST(DPDK,["-DDPDK=${with_dpdk}"])
|
||||
|
||||
AC_ARG_WITH(plugin-toolkit,
|
||||
AC_HELP_STRING([--with-plugin-toolkit],
|
||||
[build using the vpp toolkit]),
|
||||
[with_plugin_toolkit=${prefix}/include],
|
||||
[with_plugin_toolkit=.])
|
||||
|
||||
AC_SUBST(TOOLKIT_INCLUDE,[${with_plugin_toolkit}])
|
||||
AM_CONDITIONAL(WITH_PLUGIN_TOOLKIT, test "$with_plugin_toolkit" != ".")
|
||||
|
||||
AC_OUTPUT([Makefile])
|
953
plugins/snat-plugin/snat/in2out.c
Normal file
953
plugins/snat-plugin/snat/in2out.c
Normal file
File diff suppressed because it is too large
Load Diff
601
plugins/snat-plugin/snat/out2in.c
Normal file
601
plugins/snat-plugin/snat/out2in.c
Normal file
File diff suppressed because it is too large
Load Diff
25
plugins/snat-plugin/snat/snat.api
Normal file
25
plugins/snat-plugin/snat/snat.api
Normal file
@ -0,0 +1,25 @@
|
||||
define snat_add_address_range {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u8 is_ip4;
|
||||
u8 first_ip_address[16];
|
||||
u8 last_ip_address[16];
|
||||
};
|
||||
|
||||
define snat_add_address_range_reply {
|
||||
u32 context;
|
||||
i32 retval;
|
||||
};
|
||||
|
||||
define snat_interface_add_del_feature {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
u8 is_add;
|
||||
u8 is_inside;
|
||||
u32 sw_if_index;
|
||||
};
|
||||
|
||||
define snat_interface_add_del_feature_reply {
|
||||
u32 context;
|
||||
i32 retval;
|
||||
};
|
716
plugins/snat-plugin/snat/snat.c
Normal file
716
plugins/snat-plugin/snat/snat.c
Normal file
File diff suppressed because it is too large
Load Diff
181
plugins/snat-plugin/snat/snat.h
Normal file
181
plugins/snat-plugin/snat/snat.h
Normal file
@ -0,0 +1,181 @@
|
||||
|
||||
/*
|
||||
* snat.h - simple nat definitions
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __included_snat_h__
|
||||
#define __included_snat_h__
|
||||
|
||||
#include <vnet/vnet.h>
|
||||
#include <vnet/ip/ip.h>
|
||||
#include <vnet/ethernet/ethernet.h>
|
||||
#include <vnet/ip/icmp46_packet.h>
|
||||
#include <vnet/api_errno.h>
|
||||
#include <vppinfra/bihash_8_8.h>
|
||||
#include <vppinfra/dlist.h>
|
||||
#include <vppinfra/error.h>
|
||||
#include <vlibapi/api.h>
|
||||
|
||||
/* Key */
|
||||
typedef struct {
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ip4_address_t addr;
|
||||
u16 port;
|
||||
u16 protocol:3,
|
||||
fib_index:13;
|
||||
};
|
||||
u64 as_u64;
|
||||
};
|
||||
} snat_session_key_t;
|
||||
|
||||
typedef struct {
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
ip4_address_t addr;
|
||||
u32 fib_index;
|
||||
};
|
||||
u64 as_u64;
|
||||
};
|
||||
} snat_user_key_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
SNAT_PROTOCOL_UDP = 0,
|
||||
SNAT_PROTOCOL_TCP,
|
||||
SNAT_PROTOCOL_ICMP,
|
||||
} snat_protocol_t;
|
||||
|
||||
|
||||
typedef CLIB_PACKED(struct {
|
||||
snat_session_key_t out2in; /* 0-15 */
|
||||
|
||||
snat_session_key_t in2out; /* 16-31 */
|
||||
|
||||
u32 flags; /* 32-35 */
|
||||
|
||||
/* per-user translations */
|
||||
u32 per_user_index; /* 36-39 */
|
||||
|
||||
u32 per_user_list_head_index; /* 40-43 */
|
||||
|
||||
/* Last heard timer */
|
||||
f64 last_heard; /* 44-51 */
|
||||
|
||||
u64 total_bytes; /* 52-59 */
|
||||
|
||||
u32 total_pkts; /* 60-63 */
|
||||
|
||||
/* Outside address */
|
||||
u32 outside_address_index; /* 64-67 */
|
||||
|
||||
}) snat_session_t;
|
||||
|
||||
#define SNAT_SESSION_STATIC (1<<0)
|
||||
|
||||
typedef struct {
|
||||
ip4_address_t addr;
|
||||
u32 sessions_per_user_list_head_index;
|
||||
u32 nsessions;
|
||||
} snat_user_t;
|
||||
|
||||
typedef struct {
|
||||
ip4_address_t addr;
|
||||
u32 busy_ports;
|
||||
uword * busy_port_bitmap;
|
||||
} snat_address_t;
|
||||
|
||||
typedef struct {
|
||||
/* Main lookup tables */
|
||||
clib_bihash_8_8_t out2in;
|
||||
clib_bihash_8_8_t in2out;
|
||||
|
||||
/* Find-a-user => src address lookup */
|
||||
clib_bihash_8_8_t user_hash;
|
||||
|
||||
/* User pool */
|
||||
snat_user_t * users;
|
||||
|
||||
/* Session pool */
|
||||
snat_session_t * sessions;
|
||||
|
||||
/* Vector of outside addresses */
|
||||
snat_address_t * addresses;
|
||||
|
||||
/* Pool of doubly-linked list elements */
|
||||
dlist_elt_t * list_pool;
|
||||
|
||||
/* Randomize port allocation order */
|
||||
u32 random_seed;
|
||||
|
||||
/* ip4 feature path indices */
|
||||
u32 rx_feature_in2out;
|
||||
u32 rx_feature_out2in;
|
||||
|
||||
/* Config parameters */
|
||||
u32 translation_buckets;
|
||||
u32 translation_memory_size;
|
||||
u32 user_buckets;
|
||||
u32 user_memory_size;
|
||||
u32 max_translations_per_user;
|
||||
u32 outside_vrf_id;
|
||||
u32 outside_fib_index;
|
||||
|
||||
/* API message ID base */
|
||||
u16 msg_id_base;
|
||||
|
||||
/* convenience */
|
||||
vlib_main_t * vlib_main;
|
||||
vnet_main_t * vnet_main;
|
||||
ip4_main_t * ip4_main;
|
||||
ip_lookup_main_t * ip4_lookup_main;
|
||||
ethernet_main_t * ethernet_main;
|
||||
api_main_t * api_main;
|
||||
} snat_main_t;
|
||||
|
||||
extern snat_main_t snat_main;
|
||||
extern vlib_node_registration_t snat_in2out_node;
|
||||
extern vlib_node_registration_t snat_out2in_node;
|
||||
|
||||
void snat_free_outside_address_and_port (snat_main_t * sm,
|
||||
snat_session_key_t * k,
|
||||
u32 address_index);
|
||||
|
||||
int snat_alloc_outside_address_and_port (snat_main_t * sm,
|
||||
snat_session_key_t * k,
|
||||
u32 * address_indexp);
|
||||
format_function_t format_snat_user;
|
||||
|
||||
typedef struct {
|
||||
u32 cached_sw_if_index;
|
||||
u32 cached_ip4_address;
|
||||
} snat_runtime_t;
|
||||
|
||||
/*
|
||||
* Why is this here? Because we don't need to touch this layer to
|
||||
* simply reply to an icmp. We need to change id to a unique
|
||||
* value to NAT an echo request/reply.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u16 identifier;
|
||||
u16 sequence;
|
||||
} icmp_echo_header_t;
|
||||
|
||||
#endif /* __included_snat_h__ */
|
19
plugins/snat-plugin/snat/snat_all_api_h.h
Normal file
19
plugins/snat-plugin/snat/snat_all_api_h.h
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
/*
|
||||
* snat_all_api_h.h - skeleton vpp engine plug-in api #include file
|
||||
*
|
||||
* Copyright (c) <current-year> <your-organization>
|
||||
* 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 the generated file, see BUILT_SOURCES in Makefile.am */
|
||||
#include <snat/snat.api.h>
|
31
plugins/snat-plugin/snat/snat_msg_enum.h
Normal file
31
plugins/snat-plugin/snat/snat_msg_enum.h
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
/*
|
||||
* snat_msg_enum.h - skeleton vpp engine plug-in message enumeration
|
||||
*
|
||||
* Copyright (c) <current-year> <your-organization>
|
||||
* 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.
|
||||
*/
|
||||
#ifndef included_snat_msg_enum_h
|
||||
#define included_snat_msg_enum_h
|
||||
|
||||
#include <vppinfra/byte_order.h>
|
||||
|
||||
#define vl_msg_id(n,h) n,
|
||||
typedef enum {
|
||||
#include <snat/snat_all_api_h.h>
|
||||
/* We'll want to know how many messages IDs we need... */
|
||||
VL_MSG_FIRST_AVAILABLE,
|
||||
} vl_msg_id_t;
|
||||
#undef vl_msg_id
|
||||
|
||||
#endif /* included_snat_msg_enum_h */
|
265
plugins/snat-plugin/snat/snat_test.c
Normal file
265
plugins/snat-plugin/snat/snat_test.c
Normal file
@ -0,0 +1,265 @@
|
||||
|
||||
/*
|
||||
* snat.c - skeleton vpp-api-test plug-in
|
||||
*
|
||||
* Copyright (c) <current-year> <your-organization>
|
||||
* 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 <vat/vat.h>
|
||||
#include <vlibapi/api.h>
|
||||
#include <vlibmemory/api.h>
|
||||
#include <vlibsocket/api.h>
|
||||
#include <vppinfra/error.h>
|
||||
#include <vnet/ip/ip.h>
|
||||
|
||||
uword unformat_sw_if_index (unformat_input_t * input, va_list * args);
|
||||
|
||||
/* Declare message IDs */
|
||||
#include <snat/snat_msg_enum.h>
|
||||
|
||||
/* define message structures */
|
||||
#define vl_typedefs
|
||||
#include <snat/snat_all_api_h.h>
|
||||
#undef vl_typedefs
|
||||
|
||||
/* declare message handlers for each api */
|
||||
|
||||
#define vl_endianfun /* define message structures */
|
||||
#include <snat/snat_all_api_h.h>
|
||||
#undef vl_endianfun
|
||||
|
||||
/* instantiate all the print functions we know about */
|
||||
#define vl_print(handle, ...)
|
||||
#define vl_printfun
|
||||
#include <snat/snat_all_api_h.h>
|
||||
#undef vl_printfun
|
||||
|
||||
/* Get the API version number. */
|
||||
#define vl_api_version(n,v) static u32 api_version=(v);
|
||||
#include <snat/snat_all_api_h.h>
|
||||
#undef vl_api_version
|
||||
|
||||
typedef struct {
|
||||
/* API message ID base */
|
||||
u16 msg_id_base;
|
||||
vat_main_t *vat_main;
|
||||
} snat_test_main_t;
|
||||
|
||||
snat_test_main_t snat_test_main;
|
||||
|
||||
#define foreach_standard_reply_retval_handler \
|
||||
_(snat_add_address_range_reply) \
|
||||
_(snat_interface_add_del_feature_reply)
|
||||
|
||||
#define _(n) \
|
||||
static void vl_api_##n##_t_handler \
|
||||
(vl_api_##n##_t * mp) \
|
||||
{ \
|
||||
vat_main_t * vam = snat_test_main.vat_main; \
|
||||
i32 retval = ntohl(mp->retval); \
|
||||
if (vam->async_mode) { \
|
||||
vam->async_errors += (retval < 0); \
|
||||
} else { \
|
||||
vam->retval = retval; \
|
||||
vam->result_ready = 1; \
|
||||
} \
|
||||
}
|
||||
foreach_standard_reply_retval_handler;
|
||||
#undef _
|
||||
|
||||
/*
|
||||
* Table of message reply handlers, must include boilerplate handlers
|
||||
* we just generated
|
||||
*/
|
||||
#define foreach_vpe_api_reply_msg \
|
||||
_(SNAT_ADD_ADDRESS_RANGE_REPLY, snat_add_address_range_reply) \
|
||||
_(SNAT_INTERFACE_ADD_DEL_FEATURE_REPLY, \
|
||||
snat_interface_add_del_feature_reply)
|
||||
|
||||
/* M: construct, but don't yet send a message */
|
||||
#define M(T,t) \
|
||||
do { \
|
||||
vam->result_ready = 0; \
|
||||
mp = vl_msg_api_alloc(sizeof(*mp)); \
|
||||
memset (mp, 0, sizeof (*mp)); \
|
||||
mp->_vl_msg_id = ntohs (VL_API_##T + sm->msg_id_base); \
|
||||
mp->client_index = vam->my_client_index; \
|
||||
} while(0);
|
||||
|
||||
#define M2(T,t,n) \
|
||||
do { \
|
||||
vam->result_ready = 0; \
|
||||
mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
|
||||
memset (mp, 0, sizeof (*mp)); \
|
||||
mp->_vl_msg_id = ntohs (VL_API_##T + sm->msg_id_base); \
|
||||
mp->client_index = vam->my_client_index; \
|
||||
} while(0);
|
||||
|
||||
/* S: send a message */
|
||||
#define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
|
||||
|
||||
/* W: wait for results, with timeout */
|
||||
#define W \
|
||||
do { \
|
||||
timeout = vat_time_now (vam) + 1.0; \
|
||||
\
|
||||
while (vat_time_now (vam) < timeout) { \
|
||||
if (vam->result_ready == 1) { \
|
||||
return (vam->retval); \
|
||||
} \
|
||||
} \
|
||||
return -99; \
|
||||
} while(0);
|
||||
|
||||
static int api_snat_add_address_range (vat_main_t * vam)
|
||||
{
|
||||
snat_test_main_t * sm = &snat_test_main;
|
||||
unformat_input_t * i = vam->input;
|
||||
f64 timeout;
|
||||
ip4_address_t start_addr, end_addr;
|
||||
u32 start_host_order, end_host_order;
|
||||
vl_api_snat_add_address_range_t * mp;
|
||||
int count;
|
||||
|
||||
if (unformat (i, "%U - %U",
|
||||
unformat_ip4_address, &start_addr,
|
||||
unformat_ip4_address, &end_addr))
|
||||
;
|
||||
else if (unformat (i, "%U", unformat_ip4_address, &start_addr))
|
||||
end_addr = start_addr;
|
||||
|
||||
start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
|
||||
end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
|
||||
|
||||
if (end_host_order < start_host_order)
|
||||
{
|
||||
errmsg ("end address less than start address\n");
|
||||
return -99;
|
||||
}
|
||||
|
||||
count = (end_host_order - start_host_order) + 1;
|
||||
|
||||
if (count > 1024)
|
||||
{
|
||||
errmsg ("%U - %U, %d addresses...\n",
|
||||
format_ip4_address, &start_addr,
|
||||
format_ip4_address, &end_addr,
|
||||
count);
|
||||
}
|
||||
|
||||
M(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range);
|
||||
|
||||
memcpy (mp->first_ip_address, &start_addr, 4);
|
||||
memcpy (mp->last_ip_address, &end_addr, 4);
|
||||
mp->is_ip4 = 1;
|
||||
|
||||
S; W;
|
||||
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int api_snat_interface_add_del_feature (vat_main_t * vam)
|
||||
{
|
||||
snat_test_main_t * sm = &snat_test_main;
|
||||
unformat_input_t * i = vam->input;
|
||||
f64 timeout;
|
||||
vl_api_snat_interface_add_del_feature_t * mp;
|
||||
u32 sw_if_index;
|
||||
u8 sw_if_index_set = 0;
|
||||
u8 is_inside = 1;
|
||||
u8 is_add = 1;
|
||||
|
||||
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
|
||||
{
|
||||
if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
|
||||
sw_if_index_set = 1;
|
||||
else if (unformat (i, "sw_if_index %d", &sw_if_index))
|
||||
sw_if_index_set = 1;
|
||||
else if (unformat (i, "out"))
|
||||
is_inside = 0;
|
||||
else if (unformat (i, "in"))
|
||||
is_inside = 1;
|
||||
else if (unformat (i, "del"))
|
||||
is_add = 0;
|
||||
}
|
||||
|
||||
if (sw_if_index_set == 0)
|
||||
{
|
||||
errmsg ("interface / sw_if_index required\n");
|
||||
return -99;
|
||||
}
|
||||
|
||||
M(SNAT_INTERFACE_ADD_DEL_FEATURE, snat_interface_add_del_feature);
|
||||
mp->sw_if_index = ntohl(sw_if_index);
|
||||
mp->is_add = is_add;
|
||||
mp->is_inside = is_inside;
|
||||
|
||||
S; W;
|
||||
/* NOTREACHED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* List of messages that the api test plugin sends,
|
||||
* and that the data plane plugin processes
|
||||
*/
|
||||
#define foreach_vpe_api_msg \
|
||||
_(snat_add_address_range, "<start-addr> [- <end-addr]") \
|
||||
_(snat_interface_add_del_feature, \
|
||||
"<intfc> | sw_if_index <id> [in] [out] [del]")
|
||||
|
||||
void vat_api_hookup (vat_main_t *vam)
|
||||
{
|
||||
snat_test_main_t * sm __attribute__((unused)) = &snat_test_main;
|
||||
/* Hook up handlers for replies from the data plane plug-in */
|
||||
#define _(N,n) \
|
||||
vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
|
||||
#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_reply_msg;
|
||||
#undef _
|
||||
|
||||
/* API messages we can send */
|
||||
#define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
|
||||
foreach_vpe_api_msg;
|
||||
#undef _
|
||||
|
||||
/* Help strings */
|
||||
#define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
|
||||
foreach_vpe_api_msg;
|
||||
#undef _
|
||||
}
|
||||
|
||||
clib_error_t * vat_plugin_register (vat_main_t *vam)
|
||||
{
|
||||
snat_test_main_t * sm = &snat_test_main;
|
||||
u8 * name;
|
||||
|
||||
sm->vat_main = vam;
|
||||
|
||||
/* Ask the vpp engine for the first assigned message-id */
|
||||
name = format (0, "snat_%08x%c", api_version, 0);
|
||||
sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
|
||||
|
||||
if (sm->msg_id_base != (u16) ~0)
|
||||
vat_api_hookup (vam);
|
||||
|
||||
vec_free(name);
|
||||
|
||||
return 0;
|
||||
}
|
@ -71,6 +71,12 @@ BUILT_SOURCES += vpp_plugin_configure
|
||||
|
||||
.PHONY: vpp_plugin_configure
|
||||
|
||||
if WITH_DPDK
|
||||
PLUGIN_DPDK_ARG="--with-dpdk"
|
||||
else
|
||||
PLUGIN_DPDK_ARG=""
|
||||
endif
|
||||
|
||||
vpp_plugin_configure:
|
||||
@echo "PLUGIN CONFIGURE " $@
|
||||
@echo "#!/bin/bash" > $@
|
||||
@ -78,10 +84,10 @@ vpp_plugin_configure:
|
||||
@echo "set +eu" >> $@
|
||||
@echo " " >> $@
|
||||
@echo "if [ -f ./configure ] ; then" >> $@
|
||||
@echo " CFLAGS='$(CFLAGS) $(AM_CFLAGS) -I/usr/include/vpp-dpdk' ./configure --with-plugin-toolkit" >> $@
|
||||
@echo " CFLAGS='$(CFLAGS) $(AM_CFLAGS) -I/usr/include/vpp-dpdk' ./configure --with-plugin-toolkit $(PLUGIN_DPDK_ARG)" >> $@
|
||||
@echo "else" >> $@
|
||||
@echo " if [ -f ../configure ] ; then" >> $@
|
||||
@echo " CFLAGS='$(CFLAGS) $(AM_CFLAGS) -I/usr/include/vpp-dpdk' ../configure --with-plugin-toolkit" >> $@
|
||||
@echo " CFLAGS='$(CFLAGS) $(AM_CFLAGS) -I/usr/include/vpp-dpdk' ../configure --with-plugin-toolkit $(PLUGIN_DPDK_ARG)" >> $@
|
||||
@echo " else" >> $@
|
||||
@echo " echo Couldnt find ./configure or ../configure " >> $@
|
||||
@echo " exit 1" >> $@
|
||||
|
Reference in New Issue
Block a user