aboutsummaryrefslogtreecommitdiffstats
path: root/vpp-api-test/vat/api_format.c
diff options
context:
space:
mode:
authorChris Luke <chrisy@flirble.org>2016-04-28 13:44:38 -0400
committerDave Barach <openvpp@barachs.net>2016-04-29 14:32:58 +0000
commit27fe48f6990d00829c5b60f7cc4b532705baea25 (patch)
tree212e370453d011928a3f2636d0b603b68568a66b /vpp-api-test/vat/api_format.c
parent210bfc8eaa31d5fae80e603ca4f7972944486e4b (diff)
VPP-25 Add API for GRE tunnel create/delete/show.
Add API methods to create, delete and show GRE tunnels. Also add missing CLI functionality for deleting and listing configured tunnels. Change-Id: I7565966037d94ade07938e4ff0d9333419716857 Signed-off-by: Chris Luke <chrisy@flirble.org>
Diffstat (limited to 'vpp-api-test/vat/api_format.c')
-rw-r--r--vpp-api-test/vat/api_format.c164
1 files changed, 163 insertions, 1 deletions
diff --git a/vpp-api-test/vat/api_format.c b/vpp-api-test/vat/api_format.c
index 72eb3392d97..bbb3e252c38 100644
--- a/vpp-api-test/vat/api_format.c
+++ b/vpp-api-test/vat/api_format.c
@@ -26,6 +26,7 @@
#include <vnet/l2/l2_input.h>
#include <vnet/l2tp/l2tp.h>
#include <vnet/vxlan/vxlan.h>
+#include <vnet/gre/gre.h>
#include <vnet/nsh-gre/nsh_gre.h>
#include <vnet/nsh-vxlan-gpe/nsh_vxlan_gpe.h>
#include <vnet/lisp-gpe/lisp_gpe.h>
@@ -1354,6 +1355,36 @@ static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
vam->result_ready = 1;
}
+static void vl_api_gre_add_del_tunnel_reply_t_handler
+(vl_api_gre_add_del_tunnel_reply_t * mp)
+{
+ vat_main_t * vam = &vat_main;
+ i32 retval = ntohl(mp->retval);
+ if (vam->async_mode) {
+ vam->async_errors += (retval < 0);
+ } else {
+ vam->retval = retval;
+ vam->result_ready = 1;
+ }
+}
+
+static void vl_api_gre_add_del_tunnel_reply_t_handler_json
+(vl_api_gre_add_del_tunnel_reply_t * mp)
+{
+ vat_main_t * vam = &vat_main;
+ vat_json_node_t node;
+
+ vat_json_init_object(&node);
+ vat_json_object_add_int(&node, "retval", ntohl(mp->retval));
+ vat_json_object_add_uint(&node, "sw_if_index", ntohl(mp->sw_if_index));
+
+ vat_json_print(vam->ofp, &node);
+ vat_json_free(&node);
+
+ vam->retval = ntohl(mp->retval);
+ vam->result_ready = 1;
+}
+
static void vl_api_create_vhost_user_if_reply_t_handler
(vl_api_create_vhost_user_if_reply_t * mp)
{
@@ -2283,6 +2314,8 @@ _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply) \
_(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details) \
_(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply) \
_(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details) \
+_(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply) \
+_(GRE_TUNNEL_DETAILS, gre_tunnel_details) \
_(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply) \
_(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply) \
_(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
@@ -7255,6 +7288,132 @@ static int api_vxlan_tunnel_dump (vat_main_t * vam)
W;
}
+static int api_gre_add_del_tunnel (vat_main_t * vam)
+{
+ unformat_input_t * line_input = vam->input;
+ vl_api_gre_add_del_tunnel_t *mp;
+ f64 timeout;
+ ip4_address_t src4, dst4;
+ u8 is_add = 1;
+ u8 src_set = 0;
+ u8 dst_set = 0;
+ u32 outer_fib_id = 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (line_input, "del"))
+ is_add = 0;
+ else if (unformat (line_input, "src %U",
+ unformat_ip4_address, &src4))
+ src_set = 1;
+ else if (unformat (line_input, "dst %U",
+ unformat_ip4_address, &dst4))
+ dst_set = 1;
+ else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
+ ;
+ else {
+ errmsg ("parse error '%U'\n", format_unformat_error, line_input);
+ return -99;
+ }
+ }
+
+ if (src_set == 0) {
+ errmsg ("tunnel src address not specified\n");
+ return -99;
+ }
+ if (dst_set == 0) {
+ errmsg ("tunnel dst address not specified\n");
+ return -99;
+ }
+
+
+ M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
+
+ clib_memcpy(&mp->src_address, &src4, sizeof(src4));
+ clib_memcpy(&mp->dst_address, &dst4, sizeof(dst4));
+ mp->outer_table_id = ntohl(outer_fib_id);
+ mp->is_add = is_add;
+
+ S; W;
+ /* NOTREACHED */
+ return 0;
+}
+
+static void vl_api_gre_tunnel_details_t_handler
+(vl_api_gre_tunnel_details_t * mp)
+{
+ vat_main_t * vam = &vat_main;
+
+ fformat(vam->ofp, "%11d%15U%15U%14d\n",
+ ntohl(mp->sw_if_index),
+ format_ip4_address, &mp->src_address,
+ format_ip4_address, &mp->dst_address,
+ ntohl(mp->outer_table_id));
+}
+
+static void vl_api_gre_tunnel_details_t_handler_json
+(vl_api_gre_tunnel_details_t * mp)
+{
+ vat_main_t * vam = &vat_main;
+ vat_json_node_t *node = NULL;
+ struct in_addr ip4;
+
+ if (VAT_JSON_ARRAY != vam->json_tree.type) {
+ ASSERT(VAT_JSON_NONE == vam->json_tree.type);
+ vat_json_init_array(&vam->json_tree);
+ }
+ node = vat_json_array_add(&vam->json_tree);
+
+ vat_json_init_object(node);
+ vat_json_object_add_uint(node, "sw_if_index", ntohl(mp->sw_if_index));
+ clib_memcpy(&ip4, &mp->src_address, sizeof(ip4));
+ vat_json_object_add_ip4(node, "src_address", ip4);
+ clib_memcpy(&ip4, &mp->dst_address, sizeof(ip4));
+ vat_json_object_add_ip4(node, "dst_address", ip4);
+ vat_json_object_add_uint(node, "outer_fib_id", ntohl(mp->outer_table_id));
+}
+
+static int api_gre_tunnel_dump (vat_main_t * vam)
+{
+ unformat_input_t * i = vam->input;
+ vl_api_gre_tunnel_dump_t *mp;
+ f64 timeout;
+ u32 sw_if_index;
+ u8 sw_if_index_set = 0;
+
+ /* Parse args required to build the message */
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) {
+ if (unformat (i, "sw_if_index %d", &sw_if_index))
+ sw_if_index_set = 1;
+ else
+ break;
+ }
+
+ if (sw_if_index_set == 0) {
+ sw_if_index = ~0;
+ }
+
+ if (!vam->json_output) {
+ fformat(vam->ofp, "%11s%15s%15s%14s\n",
+ "sw_if_index", "src_address", "dst_address",
+ "outer_fib_id");
+ }
+
+ /* Get list of gre-tunnel interfaces */
+ M(GRE_TUNNEL_DUMP, gre_tunnel_dump);
+
+ mp->sw_if_index = htonl(sw_if_index);
+
+ S;
+
+ /* Use a control ping for synchronization */
+ {
+ vl_api_control_ping_t * mp;
+ M(CONTROL_PING, control_ping);
+ S;
+ }
+ W;
+}
+
static int api_l2_fib_clear_table (vat_main_t * vam)
{
// unformat_input_t * i = vam->input;
@@ -10378,9 +10537,12 @@ _(l2tpv3_set_lookup_key, \
"lookup_v6_src | lookup_v6_dst | lookup_session_id") \
_(sw_if_l2tpv3_tunnel_dump, "") \
_(vxlan_add_del_tunnel, \
- "src <ip4-addr> dst <ip4-addr> vni [encap-vrf-id <nn>]\n" \
+ "src <ip4-addr> dst <ip4-addr> vni <vni> [encap-vrf-id <nn>]\n" \
" [decap-next l2|ip4|ip6] [del]") \
_(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
+_(gre_add_del_tunnel, \
+ "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n") \
+_(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]") \
_(l2_fib_clear_table, "") \
_(l2_interface_efp_filter, "sw_if_index <nn> enable | disable") \
_(l2_interface_vlan_tag_rewrite, \
s="k">$(DOXY_SRC)/vpp \ $(DOXY_SRC)/vpp-api \ $(DOXY_SRC)/examples # Input directories and files DOXY_INPUT ?= \ $(wildcard $(WS_ROOT)/*.md) \ $(wildcard $(DOXY_DIR)/*.md) \ $(DOXY_SRC_DIRECTORIES) \ $(DOXY_SRC)/plugins \ extras # Strip leading workspace path from input names DOXY_INPUT := $(subst $(WS_ROOT)/,,$(DOXY_INPUT)) # Files to exclude, from pre-Doxygen steps, eg because they're # selectively compiled. # Examples would be to exclude non-DPDK related sources when # there's a DPDK equivalent that conflicts. # These must be left-anchored paths for the regexp below to work. DOXY_EXCLUDE ?= \ $(DOXY_SRC)/vpp-api/lua # Generate a regexp for filenames to exclude DOXY_EXCLUDE_REGEXP = ($(subst .,\.,$(shell echo '$(strip $(DOXY_EXCLUDE))' | sed -e 's/ /|/g'))) # Include all the normal source directories in the include file path DOXY_INCLUDE_PATH = $(DOXY_SRC_DIRECTORIES) # Find API header directories and include them in the header path. # This is only useful if VPP and plugins are already built; nothing # here depends on those targets. We don't build documentation for these # header files, they're just added to the INCLUDE search path for Doxygen. _vpp_br = $(shell find "$(BR)" -maxdepth 1 -type d \ '(' -name build-vpp_debug-native -o -name build-vpp-native ')' -print \ | sed -e 's@^$(WS_ROOT)/*@@' -e 1q) ifneq ($(strip $(_vpp_br)),) DOXY_INCLUDE_PATH += \ $(_vpp_br)/vlib-api \ $(_vpp_br)/vpp # Also include any plugin directories that exist DOXY_INCLUDE_PATH += \ $(shell find $(WS_ROOT)/$(_vpp_br)/plugins -maxdepth 1 -type d | sed -e 's@^$(WS_ROOT)/*@@') endif # Discover if we have CPP available _cpp = $(shell which cpp) ifneq ($(strip $(_cpp)),) # Add whatever directories CPP normally includes to the header path DOXY_INCLUDE_PATH += $(shell set -e; $(_cpp) -v </dev/null 2>&1 | awk 'f&&/^ /{print $$1} /^\#include/{f=1}') endif # Target directory for doxygen output DOXY_OUTPUT ?= $(BR)/docs # Siphoned fragments end up in here SIPHON_INPUT ?= $(DOXY_OUTPUT)/siphon_fragments # Siphoned fragements are processed into here SIPHON_OUTPUT ?= $(DOXY_OUTPUT)/siphon_docs # Extra document inputs that are processed in addition to DOXY_INPUT EXTRA_DOXY_INPUT += $(SIPHON_OUTPUT) # All the siphon types we know about SIPHONS ?= clicmd syscfg SIPHON_FILES = $(addprefix $(SIPHON_INPUT)/,$(addsuffix .siphon,$(SIPHONS))) SIPHON_DOCS = $(addprefix $(SIPHON_OUTPUT)/,$(addsuffix .md,$(SIPHONS))) SIPHON_ITEMLIST = $(addprefix $(SIPHON_OUTPUT)/,$(addsuffix .itemlist,$(filter clicmd,$(SIPHONS)))) $(BR)/.doxygen-bootstrap.ok: Makefile @echo "Checking whether dependencies for Doxygen are installed..." ifeq ($(OS_ID),ubuntu) @set -e; inst=; \ for i in $(DOC_DEB_DEPENDS); do \ dpkg-query --show $$i >/dev/null 2>&1 || inst="$$inst $$i"; \ done; \ if [ "$$inst" ]; then \ sudo apt-get update; \ sudo apt-get $(CONFIRM) $(FORCE) install $$inst; \ fi @if [ ! -s /usr/lib/graphviz/config6a ]; then \ echo "Rebuilding system Graphviz configuration."; \ sudo dot -c; \ fi else ifneq ("$(wildcard /etc/redhat-release)","") @sudo yum install $(CONFIRM) $(DOC_RPM_DEPENDS) else ifeq ($(OS_ID),darwin) @set -e; \ for bin in $(DOC_MAC_BIN_DEPENDS); do \ which -s $${bin} || (\ echo "Program '$${bin}' not found, please install it."; \ false; \ ); \ done @set -e; \ for py in $(DOC_MAC_PY_DEPENDS); do \ python -c "import $${py}" >/dev/null 2>&1 || (\ echo "Python package '$${py}' not found, please install it."; \ false; \ ); \ done else ifeq ($(OS_ID),opensuse) @sudo zypper install $(CONFIRM) $(DOC_SUSE_RPM_DEPENDS) else $(error "Building documentation currently works only on Ubuntu, CentOS, MacOS and OpenSUSE systems.") endif @touch $@ .PHONY: bootstrap-doxygen bootstrap-doxygen: $(BR)/.doxygen-bootstrap.ok .DELETE_ON_ERROR: $(BR)/.doxygen-siphon.dep $(BR)/.doxygen-siphon.dep: Makefile \ $(addprefix,$(WSROOT),$(DOXY_INPUT)) @echo "Building siphon dependencies..." @rm -f "$@"; for input in $(DOXY_INPUT); do \ [ -e "$(WS_ROOT)/$$input" ] && \ find "$(WS_ROOT)/$$input" -type f \ \( -name '*.[ch]' -or -name '*.dox' \) -print \ | grep -v -E '^$(WS_ROOT)/$(DOXY_EXCLUDE_REGEXP)' \ | sed -e "s/^/\$$(SIPHON_FILES): /" \ >> $@; \ done # Include the source -> siphon dependencies -include $(BR)/.doxygen-siphon.dep # Generate .siphon files that contain fragments of source file that # relate to the siphons we support. .NOTPARALLEL: $(SIPHON_FILES) $(SIPHON_FILES): $(BR)/.doxygen-bootstrap.ok \ $(DOXY_DIR)/siphon-generate \ $(addprefix,$(WSROOT),$(DOXY_INPUT)) \ $(wildcard $(DOXY_DIR)/siphon/*.py) @echo "Validating source tree..." @set -e; for input in $(DOXY_INPUT); do \ if [ ! -e "$(WS_ROOT)/$$input" ]; then \ echo "ERROR: Input path '$$input' does not exist." >&2; \ exit 1; \ fi; \ done @rm -rf "$(SIPHON_INPUT)" "$(SIPHON_OUTPUT)" @mkdir -p "$(SIPHON_INPUT)" "$(SIPHON_OUTPUT)" @touch $(SIPHON_INPUT)/files @echo "Collating source file list for siphoning..." @for input in $(DOXY_INPUT); do \ cd "$(WS_ROOT)"; \ find "$$input" -type f \ \( -name '*.[ch]' -or -name '*.dox' \) -print \ | grep -v -E '^src/examples/' \ | grep -v -E '^$(DOXY_EXCLUDE_REGEXP)' \ >> $(SIPHON_INPUT)/files; \ done @echo "Generating siphons..." @set -e; \ cd "$(WS_ROOT)"; \ $(DOXY_DIR)/siphon-generate \ --output="$(SIPHON_INPUT)" \ "@$(SIPHON_INPUT)/files" # Evaluate this to build a siphon doc output target for each desired # output type: # $(eval $(call siphon-process,file_extension,output_type_name)) define siphon-process $(SIPHON_OUTPUT)/%.$(1): $(SIPHON_INPUT)/%.siphon \ $(DOXY_DIR)/siphon-process \ $(wildcard $(DOXY_DIR)/siphon/*.py) \ $(wildcard $(DOXY_DIR)/siphon_templates/$(2)/*/*.$(1)) @echo "Processing siphon for $(2) from $$(notdir $$<)..." @set -e; \ cd "$(WS_ROOT)"; \ $(DOXY_DIR)/siphon-process \ --type=$$(basename $$(notdir $$<)) \ --format=$(2) \ --output="$$@" \ "$$<" endef # Process the .siphon source fragments and render them into doxygen flavored # markdown documentation .DELETE_ON_ERROR: $(SIPHON_DOCS) $(eval $(call siphon-process,md,markdown)) # Process the .siphon source fragments and render them into a list of cli # commands. .DELETE_ON_ERROR: $(SIPHON_ITEMLIST) $(eval $(call siphon-process,itemlist,itemlist)) # This target can be used just to generate the siphoned things .PHONY: doxygen-siphon doxygen-siphon: $(SIPHON_DOCS) $(SIPHON_ITEMLIST) # Generate the doxygen docs .PHONY: doxygen doxygen: $(SIPHON_DOCS) @mkdir -p "$(DOXY_OUTPUT)" @echo "Running Doxygen..." set -e; cd "$(WS_ROOT)"; \ ROOT="$(WS_ROOT)" \ BUILD_ROOT="$(BR)" \ INPUT="$(addprefix $(WS_ROOT)/,$(DOXY_INPUT)) $(EXTRA_DOXY_INPUT)" \ INCLUDE_PATH="$(DOXY_INCLUDE_PATH)" \ EXCLUDE="$(DOXY_EXCLUDE)" \ HTML=YES \ VERSION="`git describe --tags --dirty`" \ doxygen $(DOXY_DIR)/doxygen.cfg .PHONY: wipe-doxygen wipe-doxygen: rm -rf "$(BR)/docs" "$(BR)/.doxygen-siphon.d" .PHONY: clean clean: wipe-doxygen