From a760dfb253161911fc3aa3c8b879c461d53ade6e Mon Sep 17 00:00:00 2001 From: YohanPipereau Date: Wed, 6 Mar 2019 14:01:58 +0100 Subject: Sweetcomb global cleanup -Merge IETF and Openconfig to use SCVPP 2 -Move L2 bridge from sc_vpp_interface to sc_vpp_v3po -Implement tav2 dump -Make openconfig-interfaces functions static -Try one more dispatch after failure in VAPI_CALL -Add error return code for scvpp -Remove unused length maccros -Return appropriate error code for interface dump when interface not found -Improve scvpp test suite -Change get_interface_id prototype -Use interface_dump_iface in openconfig_interface. -No more vapi types in openconfig_interfaces.c -Move openconfig_local_routing VAPI operations to sc_vpp_ip -Implement a multiple dump with a stack data structure -Comment out state_cb code from openconfig_local_routing to use new functions later. -Rename YANG model to their fully qualified name : @ -Remove headers almost empty and put registration declaration in sc_model.h -Shorten vapi context global variable name -Reorganize scvpp unit test suite -Add instructions to Makefile to install/uninstall YANG models in sysrepo. -Add this new instructions to README.md. -Reimplement interface_dump_all -Use a common message at INFO Log Level to know when sysrepo callbacks are triggered -Remove old structure to perform dump of all interfaces -Reimplement get_interface_name and add scvpp test for it -Clean sys_util -Use UNUSED maccro everywhere to have lighter prototypes -Have ietf-interfaces:interfaces-state work with new dump function -Add setup and teardown for NAT tests -Remove unused tapv2 dump -Remove useless sysrepo module callback -Remove xpath_find_first_key usage in openconfig-interfaces -Remove xpath_find_first_key in oc_local_routing and in the rest of sweetcomb -Reorganize scvpp include dir and fix scvpp_test new warnings -Fix scvpp tests for ip routes -Factorize scvpp nat and test return code of its function -Correct test_dump_if_all if there is an existing hardware interface -Implement a per-prefix dump in scvpp -free changes iterator in ietf-interfaces -Add new XPATH in oc local-routing -Introduce helper methods for sysrepo config callbacks -Factorize config callback -Refactor the openconfig-local-routing config callback -Use common foreach_change to iterate over changes in all models -Create a sample directory gathering example of configurations supposed to work with sweetcomb -Fix state callback of oc-local-routing -Add new sample for get operation on next-hop -foreach_elt maccro condition forgets to read one element Change-Id: I8e87fce577a00337977588f057a6e095a20f457c Signed-off-by: YohanPipereau --- src/scvpp/CMakeLists.txt | 66 ++++++-- src/scvpp/inc/scvpp/comm.h | 213 +++++++++++++++++++++++++ src/scvpp/inc/scvpp/interface.h | 69 ++++++++ src/scvpp/inc/scvpp/ip.h | 77 +++++++++ src/scvpp/inc/scvpp/nat.h | 61 +++++++ src/scvpp/inc/scvpp/v3po.h | 54 +++++++ src/scvpp/src/CMakeLists.txt | 57 ------- src/scvpp/src/comm.c | 113 +++++++++++++ src/scvpp/src/interface.c | 176 ++++++++++++++++++++ src/scvpp/src/ip.c | 259 ++++++++++++++++++++++++++++++ src/scvpp/src/nat.c | 294 ++++++++++++++++++++++++++++++++++ src/scvpp/src/sc_vpp_comm.c | 113 ------------- src/scvpp/src/sc_vpp_comm.h | 136 ---------------- src/scvpp/src/sc_vpp_interface.c | 252 ----------------------------- src/scvpp/src/sc_vpp_interface.h | 61 ------- src/scvpp/src/sc_vpp_ip.c | 206 ------------------------ src/scvpp/src/sc_vpp_ip.h | 36 ----- src/scvpp/src/sc_vpp_nat.c | 319 ------------------------------------- src/scvpp/src/sc_vpp_nat.h | 61 ------- src/scvpp/src/sc_vpp_v3po.c | 107 ------------- src/scvpp/src/sc_vpp_v3po.h | 26 --- src/scvpp/src/v3po.c | 89 +++++++++++ src/scvpp/tests/CMakeLists.txt | 37 +++-- src/scvpp/tests/scvpp_iface_test.c | 130 +++++++++++++++ src/scvpp/tests/scvpp_ip_test.c | 184 +++++++++++++++++++++ src/scvpp/tests/scvpp_nat_test.c | 51 +++--- src/scvpp/tests/scvpp_nat_test.h | 24 --- src/scvpp/tests/scvpp_test.c | 160 +++++++------------ src/scvpp/tests/scvpp_test.h | 31 ++++ 29 files changed, 1912 insertions(+), 1550 deletions(-) create mode 100644 src/scvpp/inc/scvpp/comm.h create mode 100644 src/scvpp/inc/scvpp/interface.h create mode 100644 src/scvpp/inc/scvpp/ip.h create mode 100644 src/scvpp/inc/scvpp/nat.h create mode 100644 src/scvpp/inc/scvpp/v3po.h delete mode 100644 src/scvpp/src/CMakeLists.txt create mode 100644 src/scvpp/src/comm.c create mode 100644 src/scvpp/src/interface.c create mode 100644 src/scvpp/src/ip.c create mode 100644 src/scvpp/src/nat.c delete mode 100644 src/scvpp/src/sc_vpp_comm.c delete mode 100644 src/scvpp/src/sc_vpp_comm.h delete mode 100644 src/scvpp/src/sc_vpp_interface.c delete mode 100644 src/scvpp/src/sc_vpp_interface.h delete mode 100644 src/scvpp/src/sc_vpp_ip.c delete mode 100644 src/scvpp/src/sc_vpp_ip.h delete mode 100644 src/scvpp/src/sc_vpp_nat.c delete mode 100644 src/scvpp/src/sc_vpp_nat.h delete mode 100644 src/scvpp/src/sc_vpp_v3po.c delete mode 100644 src/scvpp/src/sc_vpp_v3po.h create mode 100644 src/scvpp/src/v3po.c create mode 100644 src/scvpp/tests/scvpp_iface_test.c create mode 100644 src/scvpp/tests/scvpp_ip_test.c delete mode 100644 src/scvpp/tests/scvpp_nat_test.h create mode 100644 src/scvpp/tests/scvpp_test.h (limited to 'src/scvpp') diff --git a/src/scvpp/CMakeLists.txt b/src/scvpp/CMakeLists.txt index 2dc42d6..8d04085 100644 --- a/src/scvpp/CMakeLists.txt +++ b/src/scvpp/CMakeLists.txt @@ -16,8 +16,57 @@ cmake_minimum_required(VERSION 2.8) project(scvpp) -# DEPENDENCIES -############## +# COMPILER & LINKER +################### + +# scvpp sources +set(SCVPP_SOURCES + src/comm.c + src/interface.c + src/ip.c + src/v3po.c + src/nat.c +) + +# scvpp public headers +set(SCVPP_HEADERS + inc/scvpp/comm.h + inc/scvpp/interface.h + inc/scvpp/ip.h + inc/scvpp/v3po.h + inc/scvpp/nat.h +) + +#define CMAKE_INSTALL_LIBDIR/INCLUDEDIR +include(GNUInstallDirs) + +# Generate a compile_commands.json with compile options +set(CMAKE_EXPORT_COMPILE_COMMANDS 1) + +#set compiler and linker flags +set(RIGOROUS_C_FLAGS "-Wlogical-op -Wformat=2") +set(CMAKE_C_FLAGS "-Wall -Wextra -std=gnu99 ${RIGOROUS_C_FLAGS}") +set(CMAKE_C_FLAGS_DEBUG "-Wall -Wextra -std=gnu99 -g -O0 ${RIGOROUS_C_FLAGS}") +#NDEBUG to skip assert checks +set(CMAKE_C_FLAGS_RELEASE "-Wall -Wextra -std=gnu99 -DNDEBUG -O2 ${RIGOROUS_C_FLAGS}") + +# libraries to link with +set(LINK_LIBRARIES vlibmemoryclient vapiclient vppapiclient svm vppinfra pthread rt dl) + +# build instructions +add_library(scvpp SHARED ${SCVPP_SOURCES}) +add_library(scvpp_a ${SCVPP_SOURCES}) + +# linker instructions +target_link_libraries(scvpp ${LINK_LIBRARIES}) +target_link_libraries(scvpp_a ${LINK_LIBRARIES}) + +# to build shared and static library for scvpp, include project private directory inc before installing header file +target_include_directories(scvpp PRIVATE inc) +target_include_directories(scvpp_a PRIVATE inc) + +# TESTING +######### # enable testing if requested and possible SET(ENABLE_TESTS 1 CACHE BOOL "Enable unit tests.") @@ -32,16 +81,13 @@ if(ENABLE_TESTS) endif(CMOCKA_FOUND) endif(ENABLE_TESTS) -# COMPILER & LINKER & INSTALL -############################# - -#define CMAKE_INSTALL_LIBDIR/INCLUDEDIR -include(GNUInstallDirs) -add_subdirectory(src) +# INSTALL +######### -# MORE INSTALL -############## +# install rules +install(TARGETS scvpp DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES ${SCVPP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/scvpp) find_package(PkgConfig QUIET) #QUIET disables message if not found if(PKG_CONFIG_FOUND) diff --git a/src/scvpp/inc/scvpp/comm.h b/src/scvpp/inc/scvpp/comm.h new file mode 100644 index 0000000..9a27517 --- /dev/null +++ b/src/scvpp/inc/scvpp/comm.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2018 HUACHENTEL and/or its affiliates. + * Copyright (c) 2018 PANTHEON.tech + * 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 __SC_VPP_COMMM_H__ +#define __SC_VPP_COMMM_H__ + +#include + +#include +#include +#include + +typedef enum { + SCVPP_OK = 0, /* Success */ + SCVPP_EINVAL, /* Invalid value encountered */ + SCVPP_EAGAIN, /* Operation would block */ + SCVPP_ENOTSUP, /* Operation not supported */ + SCVPP_ENOMEM, /* Out of memory */ + SCVPP_NOT_FOUND, /* Required element can not be found */ +} scvpp_error_e; + +// Use VAPI macros to define symbols +DEFINE_VAPI_MSG_IDS_VPE_API_JSON; + +#define VPP_IP4_HOST_PREFIX_LEN 32 +#define VPP_INTFC_NAME_LEN 64 /* Interface name max length */ +#define VPP_IP4_ADDRESS_LEN 4 /* IPv4 length in VPP format */ +#define VPP_IP6_ADDRESS_LEN 16 /* IPv6 length in VPP format */ +#define VPP_MAC_ADDRESS_LEN 8 /* MAC length in VPP format */ +/* IPv4 and IPv6 length in string format */ +#define VPP_IP4_ADDRESS_STRING_LEN INET_ADDRSTRLEN //16, include '\0' +#define VPP_IP6_ADDRESS_STRING_LEN INET6_ADDRSTRLEN //46, include '\0' +#define VPP_IP4_PREFIX_STRING_LEN \ + INET_ADDRSTRLEN + sizeof('/') + 2 // include '\0' +#define VPP_IP6_PREFIX_STRING_LEN \ + INET6_ADDRSTRLEN + sizeof('/') + 3 // include '\0' + +/**********************************MACROS**********************************/ +#define ARG_CHECK(retval, arg) \ + do \ + { \ + if (NULL == (arg)) \ + { \ + return (retval); \ + } \ + } \ + while (0) + +#define ARG_CHECK2(retval, arg1, arg2) \ + ARG_CHECK(retval, arg1); \ + ARG_CHECK(retval, arg2) + +#define ARG_CHECK3(retval, arg1, arg2, arg3) \ + ARG_CHECK(retval, arg1); \ + ARG_CHECK(retval, arg2); \ + ARG_CHECK(retval, arg3) + +#define ARG_CHECK4(retval, arg1, arg2, arg3, arg4) \ + ARG_CHECK(retval, arg1); \ + ARG_CHECK(retval, arg2); \ + ARG_CHECK(retval, arg3); \ + ARG_CHECK(retval, arg4) + +/* Suppress compiler warning about unused variable. + * This must be used only for callback function else suppress your unused + * parameter in function prototype. */ +#define UNUSED(x) (void)x + +#define VAPI_RETVAL_CB(api_name) \ +static vapi_error_e \ +api_name##_cb (vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, \ + vapi_payload_##api_name##_reply * reply) \ +{ \ + UNUSED(ctx); UNUSED(caller_ctx); UNUSED(rv); UNUSED(is_last); \ + return reply->retval; \ +} + +#define VAPI_COPY_CB(api_name) \ +static vapi_error_e \ +api_name##_cb (vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, \ + vapi_payload_##api_name##_reply * reply) \ +{ \ + UNUSED(ctx); UNUSED(rv); UNUSED(is_last); \ + vapi_payload_##api_name##_reply * passed; \ + if (caller_ctx) \ + { \ + passed = (vapi_payload_##api_name##_reply *)caller_ctx; \ + *passed = *reply; \ + } \ + return VAPI_OK; \ +}\ + +#define VAPI_CALL_MODE(call_code, vapi_mode) \ + do \ + { \ + if (VAPI_MODE_BLOCKING == (vapi_mode)) \ + { \ + rv = call_code; \ + } \ + else \ + { \ + while (VAPI_EAGAIN == (rv = call_code)); \ + if (rv != VAPI_OK) { /* try once more to get reply */ \ + rv = vapi_dispatch (g_vapi_ctx); \ + } \ + } \ + } \ + while (0) + +#define VAPI_CALL(call_code) VAPI_CALL_MODE(call_code, g_vapi_mode) + +struct elt { + void *data; //vapi_payload structure + struct elt *next; + int id; //id of the stack element to count total nb of elements +}; + +static inline int push(struct elt **stack, void *data, int length) +{ + struct elt *el; + + //new stack node + el = malloc(sizeof(struct elt)); + if (!el) + return -ENOMEM; + el->data = malloc(length); + if (!el->data) + return -ENOMEM; + + memcpy(el->data, data, length); + if (*stack) + el->id = (*stack)->id++; + else + el->id = 0; + el->next = *stack; //point to old value of stack + *stack = el; //el is new stack head + + return 0; +} + +static inline void * pop(struct elt **stack) +{ + struct elt *prev; + void *data; + + if (!(*stack)) + return NULL; + + data = (*stack)->data; //get data at stack head + prev = *stack; //save stack to free memory later + *stack = (*stack)->next; //new stack + + free(prev); + prev = NULL; + + return data; +} + +#define VAPI_DUMP_LIST_CB(api_name) \ +static vapi_error_e \ +api_name##_all_cb(vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, \ + vapi_payload_##api_name##_details *reply) \ +{ \ + UNUSED(ctx); UNUSED(rv); UNUSED(is_last); \ + struct elt **stackp; \ + ARG_CHECK2(VAPI_EINVAL, caller_ctx, reply); \ + \ + stackp = (struct elt**) caller_ctx; \ + push(stackp, reply, sizeof(*reply)); \ + \ + return VAPI_OK; \ +} + +#define foreach_stack_elt(stack) \ + for(void *data = pop(&stack); data != NULL ; data = pop(&stack)) +//for(void *data = pop(&stack); stack != NULL ; data = pop(&stack)) // No!! + +int sc_aton(const char *cp, u8 * buf, size_t length); +char * sc_ntoa(const u8 * buf); + +/** + * @brief Function converts the u8 array from network byte order to host byte order. + * + * @param[in] host IPv4 address. + * @return host byte order value. + */ +uint32_t hardntohlu32(uint8_t host[4]); + +/* + * VPP + */ + +extern vapi_ctx_t g_vapi_ctx; +extern vapi_mode_e g_vapi_mode; + +int sc_connect_vpp(); +int sc_disconnect_vpp(); +int sc_end_with(const char* str, const char* end); + +#endif //__SC_VPP_COMMM_H__ diff --git a/src/scvpp/inc/scvpp/interface.h b/src/scvpp/inc/scvpp/interface.h new file mode 100644 index 0000000..86cd185 --- /dev/null +++ b/src/scvpp/inc/scvpp/interface.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018 PANTHEON.tech. + * + * 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 __BAPI_INTERFACE_H__ +#define __BAPI_INTERFACE_H__ + +#include +#include + +typedef vapi_payload_sw_interface_details sw_interface_dump_t; + +/** + * @brief Change an interface state + * @param interface_name - name of target interface + * @param enable - true=state up, false=state down + * @return 0 for success, else negative SCVPP error code + */ +int interface_enable(const char *interface_name, const bool enable); + +/** + * @brief Dump details about all existing interfaces + * @return stack structure containing all interfaces or NULL if empty + */ +extern struct elt * interface_dump_all(); + + +/** + * @brief Dump details about a specific interface + * @param details - where answer will be written + * @param interface_name - name of the interface to dump + * @return 0 for success or negative SCVPP error code + */ +extern int interface_dump_iface(sw_interface_dump_t *details, + const char *interface_name); + +/* + * Library internal helper functions. Symbols should not be exported eventually + */ + +/* + * @brief Get VPP internal index for an interface + * @param interface_name - name of the interface to get id from + * @param sw_if_index - pointer to interface index to be returned + * @return 0 upon success or negative SCVPP error code + */ +extern int get_interface_id(const char *interface_name, uint32_t *sw_if_index); + +/* @brief Get interface name from an interface ID. This is a super expensive + * operation !!! Avoid using it. + * @param interface_name - pointer to string holding returned interface name + * @param sw_if_index - interface index provided + * @return 0 upon success or negative SCVPP error code + */ +extern int get_interface_name(char *interface_name, uint32_t sw_if_index); + +#endif /* __BAPI_INTERFACE_H__ */ diff --git a/src/scvpp/inc/scvpp/ip.h b/src/scvpp/inc/scvpp/ip.h new file mode 100644 index 0000000..f8805b3 --- /dev/null +++ b/src/scvpp/inc/scvpp/ip.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018 PANTHEON.tech. + * + * 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 __BAPI_IP_H__ +#define __BAPI_IP_H__ + +#include +#include + +typedef vapi_payload_ip_fib_details fib_dump_t; + +/* + * @brief Dump IPv4/IPv6 address from an interface. + * @param interface_name - name of the interface to get ip from. + * @param ip_addr - where dump will store IP. If IP not found, returns 0.0.0.0 + * @param prefix_len - pointer where dump will store prefix + * @param is_ipv6 - true = IPv6, false = IPv4 + * @return 0 on success, or nergative SCVPP error code + */ +extern int ipv46_address_dump(const char *interface_name, char *ip_addr, + u8 *prefix_len, bool is_ipv6); + +/** + * @brief Add or remove IPv4/IPv6 address to/from an interface. + * @param interface_name - name of interface to configure + * @param addr - address to add + * @param prefix_len - prefix length of interface + * @param is_ipv6 - true if ipv6, false otherwise + * @param add - true to add, false to remove + */ +extern int ipv46_config_add_remove(const char *interface_name, const char *addr, + uint8_t prefix_len, bool is_ipv6, bool add); + +/* + * TODO should add a field is_ipv6 because it only do ipv4 now + * @brief Add or remove an IP route + * @param dst_address - subnet IP you wish to route + * @param dst_address_length - prefix length for subnet you wish to route + * @param next_address - Next hop IP (can use next_hop_interface instead) + * @param is_add - true to add, false to remove + * @param table_id - id of the tab in FIB + * @param next_hop_interface - Next hop interface (can use next_address instead) + */ +extern int +ipv46_config_add_del_route(const char* dst_address, u8 dst_address_length, + const char* next_address, u8 is_add, u32 table_id, + const char *next_hop_interface); + +/** + * @brief Dump all FIB tables entries + * @return stacked answers on success, or NULL on failure + */ +extern struct elt* ipv4_fib_dump_all(); + +/* + * @brief Dump information about a prefix, based on fib_dump_all + * @param prefix_xpath - prefix to look for in FIB + * @param reply - FIB entry dump replied + * @return SCVPP_OK if prefix found or SCVPP_NOT_FOUND + */ +extern int ipv4_fib_dump_prefix(const char *prefix_xpath, fib_dump_t **reply); + +#endif /* __BAPI_IP_H__ */ diff --git a/src/scvpp/inc/scvpp/nat.h b/src/scvpp/inc/scvpp/nat.h new file mode 100644 index 0000000..40e727e --- /dev/null +++ b/src/scvpp/inc/scvpp/nat.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2018 PANTHEON.tech. + * + * 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 __BAPI_NAT_H__ +#define __BAPI_NAT_H__ + +#include + +typedef vapi_payload_nat44_interface_details nat44_interface_details_t; +typedef vapi_payload_nat44_add_del_interface_addr nat44_add_del_interface_addr_t; +typedef vapi_payload_nat44_add_del_address_range nat44_add_del_address_range_t; +typedef vapi_payload_nat44_add_del_static_mapping nat44_add_del_static_mapping_t; +typedef vapi_payload_nat44_static_mapping_details nat44_static_mapping_details_t; +typedef vapi_payload_nat44_forwarding_enable_disable nat44_forwarding_enable_disable_t; +typedef vapi_payload_nat_set_workers nat_set_workers_t; + + +//Wrapper function, if we want hide the VAPI return value +extern int nat44_interface_dump(nat44_interface_details_t *reply); +extern int nat44_add_del_interface_addr( + const nat44_add_del_interface_addr_t *msg); +extern int nat44_add_del_addr_range(const nat44_add_del_address_range_t *range); +extern int nat44_add_del_static_mapping( + const nat44_add_del_static_mapping_t *msg); +extern int nat44_static_mapping_dump(nat44_static_mapping_details_t *reply); +extern int nat44_forwarding_enable_disable( + const nat44_forwarding_enable_disable_t *msg); +extern int nat_set_workers(const nat_set_workers_t *msg); + + +// Alternative, if we don't want hide VAPI return value + +// extern vapi_error_e bin_api_nat44_interface_dump(nat44_interface_details_t *reply); +// extern vapi_error_e bin_api_nat44_add_del_interface_addr( +// const nat44_add_del_interface_addr_t *msg); +// extern vapi_error_e bin_api_nat44_add_del_addr_range( +// const nat44_add_del_address_range_t *range); +// extern vapi_error_e bin_api_nat44_add_del_static_mapping( +// const nat44_add_del_static_mapping_t *msg); +// extern vapi_error_e bin_api_nat44_static_mapping_dump( +// nat44_static_mapping_details_t *reply); +// extern vapi_error_e bin_api_nat44_forwarding_enable_disable( +// const nat44_forwarding_enable_disable_t *msg); +// extern vapi_error_e bin_api_nat_set_workers(const nat_set_workers_t *msg); + + +#endif /* __BAPI_NAT_H__ */ + diff --git a/src/scvpp/inc/scvpp/v3po.h b/src/scvpp/inc/scvpp/v3po.h new file mode 100644 index 0000000..f876ab4 --- /dev/null +++ b/src/scvpp/inc/scvpp/v3po.h @@ -0,0 +1,54 @@ +/* + * 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 _V3PO__INTERFACE_H__ +#define _V3PO__INTERFACE_H__ + +#include +#include + +/** + * V3PO defines operations for specific interfaces used by VPP like: + * - tapv2 + */ + +/* tapv2 */ + +typedef vapi_payload_tap_create_v2 tapv2_create_t; +typedef vapi_payload_sw_interface_tap_v2_details tapv2_dump_t; + +/** + * TODO problem: vapi_payload_sw_interface_tap_v2_details reply is NULL + * @brief Dump information about a tap interface + * @param dump - where dump information will be stored + * @return 0 on success, or negative SCVPP error code + */ +extern int dump_tapv2(tapv2_dump_t *dump); + +/** + * @brief Create a tapv2 interface + * @param query - required structure for the creation of a VPP tapv2 interface + * @return 0 on success, or negative SCVPP error code + */ +extern int create_tapv2(tapv2_create_t *query); + +/** + * @brief Delete a tapv2 interface + * @param interface_name - name of the interface to delete + * @return 0 on success, or negative SCVPP error code + */ +extern int delete_tapv2(char *interface_name); + +#endif /* __V3PO_INTERFACE_H__ */ diff --git a/src/scvpp/src/CMakeLists.txt b/src/scvpp/src/CMakeLists.txt deleted file mode 100644 index 71a891f..0000000 --- a/src/scvpp/src/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -# -# Copyright (c) 2018 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. -# - -# scvpp sources -set(SCVPP_SOURCES - sc_vpp_comm.c - sc_vpp_interface.c - sc_vpp_ip.c - sc_vpp_v3po.c - sc_vpp_nat.c -) - -# scvpp public headers -set(SCVPP_HEADERS - sc_vpp_comm.h - sc_vpp_interface.h - sc_vpp_ip.h - sc_vpp_v3po.h - sc_vpp_nat.h -) - -# Generate a compile_commands.json with compile options -set(CMAKE_EXPORT_COMPILE_COMMANDS 1) - -#set compiler and linker flags -set(RIGOROUS_C_FLAGS "-Wlogical-op -Wformat=2") -set(CMAKE_C_FLAGS "-Wall -Wextra -std=gnu99 ${RIGOROUS_C_FLAGS}") -set(CMAKE_C_FLAGS_DEBUG "-Wall -Wextra -std=gnu99 -g -O0 ${RIGOROUS_C_FLAGS}") -#NDEBUG to skip assert checks -set(CMAKE_C_FLAGS_RELEASE "-Wall -Wextra -std=gnu99 -DNDEBUG -O2 ${RIGOROUS_C_FLAGS}") - -# libraries to link with -set(LINK_LIBRARIES vlibmemoryclient vapiclient vppapiclient svm vppinfra pthread rt dl) - -# build instructions -add_library(scvpp SHARED ${SCVPP_SOURCES}) -add_library(scvpp_a ${SCVPP_SOURCES}) - -# linker instructions -target_link_libraries(scvpp ${LINK_LIBRARIES}) -target_link_libraries(scvpp_a ${LINK_LIBRARIES}) - -# install rules -install(TARGETS scvpp DESTINATION ${CMAKE_INSTALL_LIBDIR}) -install(FILES ${SCVPP_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/src/scvpp/src/comm.c b/src/scvpp/src/comm.c new file mode 100644 index 0000000..a065b58 --- /dev/null +++ b/src/scvpp/src/comm.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2018 HUACHENTEL 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 + +#define APP_NAME "sweetcomb_vpp" +#define MAX_OUTSTANDING_REQUESTS 4 +#define RESPONSE_QUEUE_SIZE 2 + +vapi_ctx_t g_vapi_ctx = NULL; +vapi_mode_e g_vapi_mode = VAPI_MODE_NONBLOCKING; + +int sc_connect_vpp() +{ + if (g_vapi_ctx == NULL) + { + vapi_error_e rv = vapi_ctx_alloc(&g_vapi_ctx); + rv = vapi_connect(g_vapi_ctx, APP_NAME, NULL, + MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, + VAPI_MODE_BLOCKING, true); + if (rv != VAPI_OK) + { + vapi_ctx_free(g_vapi_ctx); + g_vapi_ctx = NULL; + return -1; + } + } + + return 0; +} + +int sc_disconnect_vpp() +{ + if (NULL != g_vapi_ctx) + { + vapi_disconnect(g_vapi_ctx); + vapi_ctx_free(g_vapi_ctx); + g_vapi_ctx = NULL; + } + return 0; +} + +int sc_end_with(const char* str, const char* end) +{ + if (str != NULL && end != NULL) + { + int l1 = strlen(str); + int l2 = strlen(end); + if (l1 >= l2) + { + if (strcmp(str + l1 - l2, end) == 0) + return 1; + } + } + return 0; +} + +int sc_aton(const char *cp, u8 * buf, size_t length) +{ + ARG_CHECK2(false, cp, buf); + + struct in_addr addr; + int ret = inet_aton(cp, &addr); + + if (0 == ret) + return -EINVAL; + + if (sizeof(addr) > length) + return -EINVAL; + + memcpy(buf, &addr, sizeof (addr)); + + return 0; +} + +char* sc_ntoa(const u8 * buf) +{ + ARG_CHECK(NULL, buf); + + struct in_addr addr; + memcpy(&addr, buf, sizeof(addr)); + return inet_ntoa(addr); +} + +/** + * @brief Function converts the u8 array from network byte order to host byte order. + * + * @param[in] host IPv4 address. + * @return host byte order value. + */ +uint32_t hardntohlu32(uint8_t host[4]) +{ + uint32_t tmp = host[3] | host[2] | host[1] | host[0]; + + return ntohl(tmp); +} diff --git a/src/scvpp/src/interface.c b/src/scvpp/src/interface.c new file mode 100644 index 0000000..53cea1c --- /dev/null +++ b/src/scvpp/src/interface.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2018 PANTHEON.tech. + * + * 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 + +// Use VAPI macros to define symbols +DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON + +static vapi_error_e +sw_interface_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx, + vapi_error_e rv, bool is_last, + vapi_payload_sw_interface_details *reply) +{ + UNUSED(rv); UNUSED(ctx); UNUSED(is_last); + + vapi_payload_sw_interface_details *passed; + + ARG_CHECK2(VAPI_EINVAL, callback_ctx, reply); + + //copy + passed = (vapi_payload_sw_interface_details *) callback_ctx; + *passed = *reply; + + return VAPI_OK; +} + +static vapi_error_e +bin_api_sw_interface_dump(vapi_payload_sw_interface_details *details, + const char *iface_name) +{ + vapi_msg_sw_interface_dump *mp; + vapi_error_e rv; + + mp = vapi_alloc_sw_interface_dump(g_vapi_ctx); + assert(NULL != mp); + + /* Dump a specific interfaces */ + mp->payload.name_filter_valid = true; + strncpy((char *)mp->payload.name_filter, iface_name, VPP_INTFC_NAME_LEN); + + VAPI_CALL(vapi_sw_interface_dump(g_vapi_ctx, mp, + sw_interface_dump_cb, details)); + if (rv != VAPI_OK) + return -SCVPP_EINVAL; + + return rv; +} + +int get_interface_id(const char *if_name, uint32_t *sw_if_index) +{ + vapi_payload_sw_interface_details details = {0}; + vapi_error_e rv; + + ARG_CHECK2(-SCVPP_EINVAL, if_name, sw_if_index); + + rv = bin_api_sw_interface_dump(&details, if_name); + if (rv != VAPI_OK) + return -SCVPP_EINVAL; + + if (strncmp(if_name, (char*) details.interface_name, VPP_INTFC_NAME_LEN) + != 0) + return -SCVPP_NOT_FOUND; + + *sw_if_index = details.sw_if_index; + + return 0; +} + +/* + * dump only a specific interface + */ +int interface_dump_iface(sw_interface_dump_t *details, const char *iface_name) +{ + vapi_error_e rv; + + rv = bin_api_sw_interface_dump(details, iface_name); + if (rv != VAPI_OK) + return -SCVPP_EINVAL; + + if (strncmp(iface_name, (char*) details->interface_name, VPP_INTFC_NAME_LEN) + != 0) + return -SCVPP_NOT_FOUND; + + return SCVPP_OK; +} + +VAPI_DUMP_LIST_CB(sw_interface) + +struct elt* interface_dump_all() +{ + struct elt* stack = NULL; + vapi_msg_sw_interface_dump *mp; + vapi_error_e rv; + + mp = vapi_alloc_sw_interface_dump(g_vapi_ctx); + + /* Dump all */ + mp->payload.name_filter_valid = false; + memset(mp->payload.name_filter, 0, sizeof(mp->payload.name_filter)); + + VAPI_CALL(vapi_sw_interface_dump(g_vapi_ctx, mp, sw_interface_all_cb, + &stack)); + if (VAPI_OK != rv) + return NULL; + + return stack; +} + +VAPI_RETVAL_CB(sw_interface_set_flags); + +int interface_enable(const char *interface_name, const bool enable) +{ + vapi_msg_sw_interface_set_flags *mp; + uint32_t sw_if_index; + vapi_error_e rv; + int rc; + + ARG_CHECK(-SCVPP_EINVAL, interface_name); + + rc = get_interface_id(interface_name, &sw_if_index); + if (rc != 0) + return -SCVPP_NOT_FOUND; + + mp = vapi_alloc_sw_interface_set_flags(g_vapi_ctx); + assert(NULL != mp); + mp->payload.sw_if_index = sw_if_index; + mp->payload.admin_up_down = enable; + + VAPI_CALL(vapi_sw_interface_set_flags(g_vapi_ctx, mp, + sw_interface_set_flags_cb, NULL)); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return 0; +} + +int get_interface_name(char *interface_name, uint32_t sw_if_index) +{ + struct elt *stack= NULL; + sw_interface_dump_t *dump; + int rc = -SCVPP_NOT_FOUND; + + stack = interface_dump_all(); + if (!stack) + return -SCVPP_NOT_FOUND; + + foreach_stack_elt(stack) { + dump = (sw_interface_dump_t *) data; + + if (dump->sw_if_index == sw_if_index) { + strncpy(interface_name, (char *)dump->interface_name, VPP_INTFC_NAME_LEN); + rc = SCVPP_OK; + } + + free(dump); + } + + return rc; +} diff --git a/src/scvpp/src/ip.c b/src/scvpp/src/ip.c new file mode 100644 index 0000000..2dc991c --- /dev/null +++ b/src/scvpp/src/ip.c @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2018 PANTHEON.tech. + * + * 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 + +// Use VAPI macros to define symbols +DEFINE_VAPI_MSG_IDS_IP_API_JSON + +VAPI_RETVAL_CB(sw_interface_add_del_address); + +static vapi_error_e +bin_api_sw_interface_add_del_address(u32 sw_if_index, bool is_add, bool is_ipv6, + bool del_all, u8 address_length, + const char *ip_address) +{ + vapi_msg_sw_interface_add_del_address *mp; + vapi_error_e rv; + + ARG_CHECK(VAPI_EINVAL, ip_address); + + mp = vapi_alloc_sw_interface_add_del_address(g_vapi_ctx); + assert(NULL != mp); + + mp->payload.sw_if_index = sw_if_index; + mp->payload.is_add = is_add; + mp->payload.is_ipv6 = is_ipv6; + mp->payload.del_all = del_all; + mp->payload.address_length = address_length; + if (sc_aton(ip_address, mp->payload.address, VPP_IP4_ADDRESS_LEN)) + return VAPI_EINVAL; + + VAPI_CALL(vapi_sw_interface_add_del_address(g_vapi_ctx, mp, + sw_interface_add_del_address_cb, NULL)); + + return rv; +} + +VAPI_COPY_CB(ip_add_del_route) + +static vapi_error_e +bin_api_ip_add_del_route(vapi_payload_ip_add_del_route_reply * reply, + const char* dst_address, uint8_t dst_address_length, + const char* next_hop, uint8_t is_add, + uint32_t table_id, const char *next_interface) +{ + vapi_msg_ip_add_del_route *mp; + uint32_t sw_if_index; + vapi_error_e rv ; + int rc; + + ARG_CHECK2(VAPI_EINVAL, reply, dst_address); + + //Require interface or next hop IP or both + if (!next_interface && !next_hop) + return VAPI_EINVAL; + + mp = vapi_alloc_ip_add_del_route(g_vapi_ctx, 1); + assert(NULL != mp); + + if (next_interface) { + rc = get_interface_id(next_interface, &sw_if_index); + if (rc < 0) + return VAPI_EINVAL; + } + + mp->payload.is_add = is_add; + mp->payload.table_id = table_id; + mp->payload.is_ipv6 = false; + mp->payload.is_local = false; + sc_aton(dst_address, mp->payload.dst_address, VPP_IP4_ADDRESS_LEN); + mp->payload.dst_address_length = dst_address_length; + if (next_interface) //interface is not mandatory + mp->payload.next_hop_sw_if_index = sw_if_index; + if (next_hop) //next hop ip is not mandatory + sc_aton(next_hop, mp->payload.next_hop_address, VPP_IP4_ADDRESS_LEN); + + VAPI_CALL(vapi_ip_add_del_route(g_vapi_ctx, mp, + ip_add_del_route_cb, reply)); + + return rv; +} + +static vapi_error_e +ip_address_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, + bool is_last, vapi_payload_ip_address_details *reply) +{ + UNUSED(rv); + vapi_payload_ip_address_details *passed; + + ARG_CHECK3(VAPI_EINVAL, ctx, callback_ctx, reply); + + //copy dump reply in callback context + if (!is_last) { + passed = (vapi_payload_ip_address_details *) callback_ctx; + *passed = *reply; + } + + return VAPI_OK; +} + +static vapi_error_e +bin_api_ip_address_dump(u32 sw_if_index, bool is_ipv6, + vapi_payload_ip_address_details *dctx) +{ + vapi_msg_ip_address_dump *mp; + vapi_error_e rv; + + mp = vapi_alloc_ip_address_dump(g_vapi_ctx); + assert(mp != NULL); + + mp->payload.sw_if_index = sw_if_index; + mp->payload.is_ipv6 = is_ipv6; + + VAPI_CALL(vapi_ip_address_dump(g_vapi_ctx, mp, ip_address_dump_cb, + dctx)); + if (rv != VAPI_OK) + return rv; + + return VAPI_OK; +} + +///VAPI_DUMP_LIST_CB(ip_fib); can not be used because of path flexible array + +static vapi_error_e +ip_fib_all_cb(vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, + vapi_payload_ip_fib_details *reply) +{ + UNUSED(ctx); UNUSED(rv); UNUSED(is_last); + struct elt **stackp; + ARG_CHECK2(VAPI_EINVAL, caller_ctx, reply); + + stackp = (struct elt**) caller_ctx; + push(stackp, reply, sizeof(*reply)+reply->count*sizeof(vapi_type_fib_path)); + + return VAPI_OK; +} + +struct elt* ipv4_fib_dump_all() +{ + struct elt *stack = NULL; + vapi_msg_ip_fib_dump *mp; + vapi_error_e rv; + + mp = vapi_alloc_ip_fib_dump(g_vapi_ctx); + assert(mp != NULL); + + VAPI_CALL(vapi_ip_fib_dump(g_vapi_ctx, mp, ip_fib_all_cb, &stack)); + if(VAPI_OK != rv) + return NULL; + + return stack; +} + +int ipv4_fib_dump_prefix(const char *prefix_xpath, fib_dump_t **reply) +{ + struct elt *stack = NULL; + char prefix[VPP_IP4_PREFIX_STRING_LEN]; + fib_dump_t *dump; + int rc = -SCVPP_NOT_FOUND; + + stack = ipv4_fib_dump_all(); + if (!stack) + return rc; + + foreach_stack_elt(stack) { + dump = (fib_dump_t *) data; + + if (rc == -SCVPP_NOT_FOUND) { + snprintf(prefix, VPP_IP4_PREFIX_STRING_LEN, "%s/%u", + sc_ntoa(dump->address), dump->address_length); + if (!strncmp(prefix_xpath, prefix, VPP_IP4_PREFIX_STRING_LEN)) { + *reply = dump; + rc = SCVPP_OK; + continue; + } + } + + free(dump); + } + + return rc; +} + +int ipv46_address_dump(const char *interface_name, char *ip_addr, + u8 *prefix_len, bool is_ipv6) +{ + vapi_payload_ip_address_details dctx = {0}; + uint32_t sw_if_index; + vapi_error_e rv; + int rc; + + rc = get_interface_id(interface_name, &sw_if_index); + if (rc < 0) + return rc; + + rv = bin_api_ip_address_dump(sw_if_index, is_ipv6, &dctx); + if (rv != VAPI_OK) + return -SCVPP_EINVAL; + + strcpy(ip_addr, sc_ntoa(dctx.ip)); //IP string + *prefix_len = dctx.prefix_length; //prefix length + + return SCVPP_OK; +} + +int ipv46_config_add_remove(const char *if_name, const char *addr, + uint8_t prefix, bool is_ipv6, bool add) +{ + vapi_error_e rv; + uint32_t sw_if_index; + int rc; + + ARG_CHECK2(-1, if_name, addr); + + rc = get_interface_id(if_name, &sw_if_index); + if (rc < 0) + return rc; + + /* add del addr */ + rv = bin_api_sw_interface_add_del_address(sw_if_index, add, is_ipv6, 0, + prefix, addr); + if (rv != VAPI_OK) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + +int ipv46_config_add_del_route(const char* dst_address, u8 dst_address_length, + const char* next_address, u8 is_add, + u32 table_id, const char *interface) +{ + vapi_payload_ip_add_del_route_reply reply = {0}; + vapi_error_e rv; + + rv = bin_api_ip_add_del_route(&reply, dst_address, dst_address_length, + next_address, is_add, table_id, interface); + if (VAPI_OK != rv || reply.retval > 0) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} diff --git a/src/scvpp/src/nat.c b/src/scvpp/src/nat.c new file mode 100644 index 0000000..17ace64 --- /dev/null +++ b/src/scvpp/src/nat.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2018 PANTHEON.tech. + * + * 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 + + +DEFINE_VAPI_MSG_IDS_NAT_API_JSON + +static vapi_error_e +nat44_interface_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx, + vapi_error_e rv, bool is_last, + vapi_payload_nat44_interface_details *reply) +{ + UNUSED(ctx); UNUSED(rv); + vapi_payload_nat44_interface_details *dctx = callback_ctx; + assert(dctx); + + if (is_last) + { + assert(NULL == reply); + } + else + { + //TODO: Use LOG message for scvpp +// SC_LOG_DBG("NAT Interface dump entry: [%u]: %u\n", reply->sw_if_index, +// reply->is_inside); + *dctx = *reply; + } + + return VAPI_OK; +} + +static vapi_error_e +bin_api_nat44_interface_dump(vapi_payload_nat44_interface_details *reply) +{ + vapi_error_e rv; + vapi_msg_nat44_interface_dump *mp; + + ARG_CHECK(VAPI_EINVAL, reply); + + mp = vapi_alloc_nat44_interface_dump(g_vapi_ctx); + assert(NULL != mp); + + VAPI_CALL(vapi_nat44_interface_dump(g_vapi_ctx, mp, + nat44_interface_dump_cb, reply)); + + return rv; +} + +VAPI_RETVAL_CB(nat44_add_del_interface_addr); + +static vapi_error_e +bin_api_nat44_add_del_interface_addr( + const vapi_payload_nat44_add_del_interface_addr *msg) +{ + vapi_error_e rv; + vapi_msg_nat44_add_del_interface_addr *mp; + + ARG_CHECK(VAPI_EINVAL, msg); + + mp = vapi_alloc_nat44_add_del_interface_addr(g_vapi_ctx); + assert(NULL != mp); + + mp->payload = *msg; + + VAPI_CALL(vapi_nat44_add_del_interface_addr(g_vapi_ctx, mp, + nat44_add_del_interface_addr_cb, + NULL)); + + return rv; +} + +VAPI_RETVAL_CB(nat44_add_del_address_range); + +static vapi_error_e +bin_api_nat44_add_del_addr_range( + const vapi_payload_nat44_add_del_address_range *range) +{ + vapi_error_e rv; + vapi_msg_nat44_add_del_address_range *mp; + + ARG_CHECK(VAPI_EINVAL, range); + + mp = vapi_alloc_nat44_add_del_address_range(g_vapi_ctx); + + assert(NULL != mp); + + mp->payload = *range; + + VAPI_CALL(vapi_nat44_add_del_address_range(g_vapi_ctx, mp, + nat44_add_del_address_range_cb, + NULL)); + + return rv; +} + +VAPI_RETVAL_CB(nat44_add_del_static_mapping); + +static vapi_error_e +bin_api_nat44_add_del_static_mapping( + const vapi_payload_nat44_add_del_static_mapping *msg) +{ + vapi_error_e rv; + vapi_msg_nat44_add_del_static_mapping *mp; + + ARG_CHECK(VAPI_EINVAL, msg); + + mp = vapi_alloc_nat44_add_del_static_mapping(g_vapi_ctx); + assert(NULL != mp); + + mp->payload = *msg; + + VAPI_CALL(vapi_nat44_add_del_static_mapping(g_vapi_ctx, mp, + nat44_add_del_static_mapping_cb, + NULL)); + + return rv; +} + +static vapi_error_e nat44_static_mapping_dump_cb( + struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, + bool is_last,vapi_payload_nat44_static_mapping_details *reply) +{ + UNUSED(rv); UNUSED(ctx); + vapi_payload_nat44_static_mapping_details *dctx = callback_ctx; + assert(dctx); + + if (is_last) + { + assert(NULL == reply); + } + else + { + *dctx = *reply; + } + + return VAPI_OK; +} + +static vapi_error_e +bin_api_nat44_static_mapping_dump( + vapi_payload_nat44_static_mapping_details *reply) +{ + vapi_error_e rv; + vapi_msg_nat44_static_mapping_dump *msg; + + ARG_CHECK(VAPI_EINVAL, reply); + + msg = vapi_alloc_nat44_static_mapping_dump(g_vapi_ctx); + assert(NULL != msg); + + VAPI_CALL(vapi_nat44_static_mapping_dump(g_vapi_ctx, msg, + nat44_static_mapping_dump_cb, + reply)); + + return rv; +} + +VAPI_RETVAL_CB(nat44_forwarding_enable_disable); + +static vapi_error_e bin_api_nat44_forwarding_enable_disable( + const vapi_payload_nat44_forwarding_enable_disable *msg) +{ + vapi_error_e rv; + vapi_msg_nat44_forwarding_enable_disable *mp; + + ARG_CHECK(VAPI_EINVAL, msg); + + mp = vapi_alloc_nat44_forwarding_enable_disable(g_vapi_ctx); + assert(NULL != mp); + + mp->payload = *msg; + + VAPI_CALL(vapi_nat44_forwarding_enable_disable( + g_vapi_ctx, mp, nat44_forwarding_enable_disable_cb, NULL)); + + return rv; +} + +VAPI_RETVAL_CB(nat_set_workers); + +static vapi_error_e +bin_api_nat_set_workers(const vapi_payload_nat_set_workers *msg) +{ + vapi_error_e rv; + vapi_msg_nat_set_workers *mp; + + ARG_CHECK(VAPI_EINVAL, msg); + + mp = vapi_alloc_nat_set_workers(g_vapi_ctx); + assert(NULL != mp); + + mp->payload = *msg; + + VAPI_CALL(vapi_nat_set_workers(g_vapi_ctx, mp, nat_set_workers_cb, NULL)); + + return rv; +} + +int nat44_interface_dump(nat44_interface_details_t *reply) +{ + vapi_error_e rv; + + rv = bin_api_nat44_interface_dump(reply); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + +int nat44_add_del_interface_addr(const nat44_add_del_interface_addr_t *msg) +{ + vapi_error_e rv; + + rv = bin_api_nat44_add_del_interface_addr(msg); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + +int nat44_add_del_addr_range(const nat44_add_del_address_range_t *range) +{ + vapi_error_e rv; + + rv = bin_api_nat44_add_del_addr_range(range); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + +int nat44_add_del_static_mapping(const nat44_add_del_static_mapping_t *msg) +{ + vapi_error_e rv; + + rv = bin_api_nat44_add_del_static_mapping(msg); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + +int nat44_static_mapping_dump(nat44_static_mapping_details_t *reply) +{ + vapi_error_e rv; + + rv = bin_api_nat44_static_mapping_dump(reply); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + +int +nat44_forwarding_enable_disable(const nat44_forwarding_enable_disable_t *msg) +{ + vapi_error_e rv; + + rv = bin_api_nat44_forwarding_enable_disable(msg); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return 0; +} + +int nat_set_workers(const nat_set_workers_t *msg) +{ + vapi_error_e rv; + + rv = bin_api_nat_set_workers(msg); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + diff --git a/src/scvpp/src/sc_vpp_comm.c b/src/scvpp/src/sc_vpp_comm.c deleted file mode 100644 index cd0b035..0000000 --- a/src/scvpp/src/sc_vpp_comm.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2018 HUACHENTEL 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 "sc_vpp_comm.h" - -#include -#include -#include -#include -#include - -#define APP_NAME "sweetcomb_vpp" -#define MAX_OUTSTANDING_REQUESTS 4 -#define RESPONSE_QUEUE_SIZE 2 - -vapi_ctx_t g_vapi_ctx_instance = NULL; -vapi_mode_e g_vapi_mode = VAPI_MODE_NONBLOCKING; - -int sc_connect_vpp() -{ - if (g_vapi_ctx_instance == NULL) - { - vapi_error_e rv = vapi_ctx_alloc(&g_vapi_ctx_instance); - rv = vapi_connect(g_vapi_ctx_instance, APP_NAME, NULL, - MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, - VAPI_MODE_BLOCKING, true); - if (rv != VAPI_OK) - { - vapi_ctx_free(g_vapi_ctx_instance); - g_vapi_ctx_instance = NULL; - return -1; - } - } - - return 0; -} - -int sc_disconnect_vpp() -{ - if (NULL != g_vapi_ctx_instance) - { - vapi_disconnect(g_vapi_ctx_instance); - vapi_ctx_free(g_vapi_ctx_instance); - g_vapi_ctx_instance = NULL; - } - return 0; -} - -int sc_end_with(const char* str, const char* end) -{ - if (str != NULL && end != NULL) - { - int l1 = strlen(str); - int l2 = strlen(end); - if (l1 >= l2) - { - if (strcmp(str + l1 - l2, end) == 0) - return 1; - } - } - return 0; -} - -int sc_aton(const char *cp, u8 * buf, size_t length) -{ - ARG_CHECK2(false, cp, buf); - - struct in_addr addr; - int ret = inet_aton(cp, &addr); - - if (0 == ret) - return -EINVAL; - - if (sizeof(addr) > length) - return -EINVAL; - - memcpy(buf, &addr, sizeof (addr)); - - return 0; -} - -char* sc_ntoa(const u8 * buf) -{ - ARG_CHECK(NULL, buf); - - struct in_addr addr; - memcpy(&addr, buf, sizeof(addr)); - return inet_ntoa(addr); -} - -/** - * @brief Function converts the u8 array from network byte order to host byte order. - * - * @param[in] host IPv4 address. - * @return host byte order value. - */ -uint32_t hardntohlu32(uint8_t host[4]) -{ - uint32_t tmp = host[3] | host[2] | host[1] | host[0]; - - return ntohl(tmp); -} diff --git a/src/scvpp/src/sc_vpp_comm.h b/src/scvpp/src/sc_vpp_comm.h deleted file mode 100644 index eeeaaf9..0000000 --- a/src/scvpp/src/sc_vpp_comm.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2018 HUACHENTEL and/or its affiliates. - * Copyright (c) 2018 PANTHEON.tech - * 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 __SC_VPP_COMMM_H__ -#define __SC_VPP_COMMM_H__ - -#include - -#include -#include -#include - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_VPE_API_JSON; - -#define VPP_INTFC_NAME_LEN 64 -#define VPP_TAPV2_NAME_LEN VPP_INTFC_NAME_LEN -#define VPP_IP4_ADDRESS_LEN 4 -#define VPP_IP6_ADDRESS_LEN 16 -#define VPP_IP4_ADDRESS_STRING_LEN 16 -#define VPP_IP4_PREFIX_STRING_LEN 19 -#define VPP_IP4_HOST_PREFIX_LEN 32 -#define VPP_IP6_ADDRESS_STRING_LEN 46 -#define VPP_MAC_ADDRESS_LEN 8 -#define VPP_TAG_LEN VPP_INTFC_NAME_LEN -#define VPP_IKEV2_PROFILE_NAME_LEN VPP_INTFC_NAME_LEN -#define VPP_IKEV2_PSK_LEN VPP_INTFC_NAME_LEN -#define VPP_IKEV2_ID_LEN 32 - -/**********************************MACROS**********************************/ -#define ARG_CHECK(retval, arg) \ - do \ - { \ - if (NULL == (arg)) \ - { \ - return (retval); \ - } \ - } \ - while (0) - -#define ARG_CHECK2(retval, arg1, arg2) \ - ARG_CHECK(retval, arg1); \ - ARG_CHECK(retval, arg2) - -#define ARG_CHECK3(retval, arg1, arg2, arg3) \ - ARG_CHECK(retval, arg1); \ - ARG_CHECK(retval, arg2); \ - ARG_CHECK(retval, arg3) - -#define ARG_CHECK4(retval, arg1, arg2, arg3, arg4) \ - ARG_CHECK(retval, arg1); \ - ARG_CHECK(retval, arg2); \ - ARG_CHECK(retval, arg3); \ - ARG_CHECK(retval, arg4) - -/* Suppress compiler warning about unused variable. - * This must be used only for callback function else suppress your unused - * parameter in function prototype. */ -#define UNUSED(x) (void)x - -#define VAPI_RETVAL_CB(api_name) \ -static vapi_error_e \ -api_name##_cb (vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, \ - vapi_payload_##api_name##_reply * reply) \ -{ \ - UNUSED(ctx); UNUSED(caller_ctx); UNUSED(rv); UNUSED(is_last); \ - return reply->retval; \ -} - -#define VAPI_COPY_CB(api_name) \ -static vapi_error_e \ -api_name##_cb (vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, \ - vapi_payload_##api_name##_reply * reply) \ -{ \ - UNUSED(ctx); UNUSED(rv); UNUSED(is_last); \ - if (caller_ctx) \ - { \ - vapi_payload_##api_name##_reply * passed = (vapi_payload_##api_name##_reply *)caller_ctx; \ - *passed = *reply; \ - } \ - return VAPI_OK; \ -}\ - -#define VAPI_CALL_MODE(call_code, vapi_mode) \ - do \ - { \ - if (VAPI_MODE_BLOCKING == (vapi_mode)) \ - { \ - rv = call_code; \ - } \ - else \ - { \ - while (VAPI_EAGAIN == (rv = call_code)); \ - rv = vapi_dispatch (g_vapi_ctx_instance); \ - } \ - } \ - while (0) - -#define VAPI_CALL(call_code) VAPI_CALL_MODE(call_code, g_vapi_mode) - -int sc_aton(const char *cp, u8 * buf, size_t length); -char * sc_ntoa(const u8 * buf); - -/** - * @brief Function converts the u8 array from network byte order to host byte order. - * - * @param[in] host IPv4 address. - * @return host byte order value. - */ -uint32_t hardntohlu32(uint8_t host[4]); - -/* - * VPP - */ - -extern vapi_ctx_t g_vapi_ctx_instance; -extern vapi_mode_e g_vapi_mode; - -int sc_connect_vpp(); -int sc_disconnect_vpp(); -int sc_end_with(const char* str, const char* end); - -#endif //__SC_VPP_COMMM_H__ diff --git a/src/scvpp/src/sc_vpp_interface.c b/src/scvpp/src/sc_vpp_interface.c deleted file mode 100644 index bc5befc..0000000 --- a/src/scvpp/src/sc_vpp_interface.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 "sc_vpp_comm.h" -#include "sc_vpp_interface.h" - - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON -DEFINE_VAPI_MSG_IDS_L2_API_JSON; - -void sw_interface_details_query_set_name(sw_interface_details_query_t * query, - const char * interface_name) -{ - assert(query && interface_name); - - memset(query, 0, sizeof(*query)); - - strncpy((char*) query->sw_interface_details.interface_name, interface_name, - sizeof(query->sw_interface_details.interface_name)); -} - -static vapi_error_e -sw_interface_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_sw_interface_details *reply) -{ - UNUSED(rv); UNUSED(ctx); UNUSED(is_last); - - vapi_payload_sw_interface_details *passed; - - ARG_CHECK(-EINVAL, callback_ctx); - - passed = (vapi_payload_sw_interface_details *) callback_ctx; - - //Interface is found if index of query equals index of reply - if (passed->sw_if_index != reply->sw_if_index) - return -EINVAL; - - //copy - *passed = *reply; - - return VAPI_OK; -} - -static vapi_error_e -bin_api_sw_interface_dump(vapi_payload_sw_interface_details *details) -{ - vapi_msg_sw_interface_dump *mp; - vapi_error_e rv; - - mp = vapi_alloc_sw_interface_dump(g_vapi_ctx_instance); - - mp->payload.name_filter_valid = 0; - memset(mp->payload.name_filter, 0, sizeof(mp->payload.name_filter)); - assert(NULL != mp); - - VAPI_CALL(vapi_sw_interface_dump(g_vapi_ctx_instance, mp, sw_interface_dump_cb, details)); - if (!rv) - return -EINVAL; - - return rv; -} - -static vapi_error_e -interface_dump_all_cb(struct vapi_ctx_s *ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_sw_interface_details * reply) -{ - UNUSED(ctx); UNUSED(rv); - dump_all_ctx *dctx = callback_ctx; - - if (is_last) - return VAPI_OK; - - if(dctx->capacity == 0 && dctx->intfcArray == NULL) { - dctx->capacity = 10; - dctx->intfcArray = (vpp_interface_t*)malloc( sizeof(vpp_interface_t)*dctx->capacity ); - } - if(dctx->num_ifs >= dctx->capacity-1) { - dctx->capacity += 10; - dctx->intfcArray = (vpp_interface_t*)realloc(dctx->intfcArray, sizeof(vpp_interface_t)*dctx->capacity ); - } - - vpp_interface_t * iface = &dctx->intfcArray[dctx->num_ifs]; - - iface->sw_if_index = reply->sw_if_index; - strncpy(iface->interface_name, (char*) reply->interface_name, - VPP_INTFC_NAME_LEN); - iface->l2_address_length = reply->l2_address_length; - memcpy(iface->l2_address, reply->l2_address, reply->l2_address_length ); - iface->link_speed = reply->link_speed; - - iface->link_mtu = reply->link_mtu; - iface->admin_up_down = reply->admin_up_down; - iface->link_up_down = reply->link_up_down; - - dctx->num_ifs += 1; - - return VAPI_OK; -} - -int interface_dump_all(dump_all_ctx * dctx) -{ - vapi_msg_sw_interface_dump *dump; - vapi_error_e rv; - - ARG_CHECK(-1, dctx); - - if(dctx == NULL) - return -1; - - dctx->intfcArray = NULL; - dctx->capacity = 0; - dctx->num_ifs = 0; - - dump = vapi_alloc_sw_interface_dump(g_vapi_ctx_instance); - - dump->payload.name_filter_valid = 0; - memset(dump->payload.name_filter, 0, sizeof(dump->payload.name_filter)); - while (VAPI_EAGAIN == - (rv = - vapi_sw_interface_dump(g_vapi_ctx_instance, dump, interface_dump_all_cb, - dctx))); - - return dctx->num_ifs; -} - -static vapi_error_e -get_interface_id_cb (struct vapi_ctx_s *ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_sw_interface_details * reply) -{ - UNUSED(ctx); UNUSED(rv); - - sw_interface_details_query_t *dctx = callback_ctx; - assert(dctx); - - if (!dctx->interface_found) - { - if (is_last) - { - assert(NULL == reply); - } - else - { - assert(NULL != reply); - - if (0 == strcmp((const char*)dctx->sw_interface_details.interface_name, - (const char*)reply->interface_name)) - { - dctx->interface_found = true; - dctx->sw_interface_details = *reply; - } - } - } - - return VAPI_OK; -} - -// return error code instead of boolean -int get_interface_id(sw_interface_details_query_t * sw_interface_details_query) -{ - vapi_error_e rv; - - ARG_CHECK(false, sw_interface_details_query); - - sw_interface_details_query->interface_found = false; - - vapi_msg_sw_interface_dump *mp = vapi_alloc_sw_interface_dump (g_vapi_ctx_instance); - assert(NULL != mp); - - mp->payload.name_filter_valid = true; - memcpy(mp->payload.name_filter, sw_interface_details_query->sw_interface_details.interface_name, - sizeof(mp->payload.name_filter)); - - VAPI_CALL(vapi_sw_interface_dump(g_vapi_ctx_instance, mp, get_interface_id_cb, sw_interface_details_query)); - if (VAPI_OK != rv) - return false; - - return sw_interface_details_query->interface_found; -} - -int get_interface_name(sw_interface_details_query_t *query) -{ - vapi_error_e rv; - - ARG_CHECK(-EINVAL, query); - - query->interface_found = false; - - rv = bin_api_sw_interface_dump(&query->sw_interface_details); - if (rv == VAPI_OK) - query->interface_found = true; - - return query->interface_found; -} - -VAPI_RETVAL_CB(sw_interface_set_flags); - -static vapi_error_e -bin_api_sw_interface_set_flags(uint32_t if_index, uint8_t up) -{ - vapi_msg_sw_interface_set_flags *mp = vapi_alloc_sw_interface_set_flags (g_vapi_ctx_instance); - assert(NULL != mp); - - mp->payload.sw_if_index = if_index; - mp->payload.admin_up_down = up; - - vapi_error_e rv; - VAPI_CALL(vapi_sw_interface_set_flags(g_vapi_ctx_instance, mp, sw_interface_set_flags_cb, NULL)); - - return rv; -} - -int interface_enable(const char *interface_name, const bool enable) -{ - ARG_CHECK(-1, interface_name); - - int rc = 0; - sw_interface_details_query_t query = {0}; - sw_interface_details_query_set_name(&query, interface_name); - - rc = get_interface_id(&query); - if (!rc) - return -1; - - rc = bin_api_sw_interface_set_flags(query.sw_interface_details.sw_if_index, - enable); - if (VAPI_OK != rc) - return -1; - - return 0; -} diff --git a/src/scvpp/src/sc_vpp_interface.h b/src/scvpp/src/sc_vpp_interface.h deleted file mode 100644 index 32b61bc..0000000 --- a/src/scvpp/src/sc_vpp_interface.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 __BAPI_INTERFACE_H__ -#define __BAPI_INTERFACE_H__ - -#include - -int interface_enable(const char *interface_name, const bool enable); - -//TODO remove the following structures ASAP -typedef struct { - bool interface_found; - vapi_payload_sw_interface_details sw_interface_details; -} sw_interface_details_query_t; - -typedef struct _vpp_interface_t -{ - u32 sw_if_index; - char interface_name[VPP_INTFC_NAME_LEN]; - u8 l2_address[VPP_MAC_ADDRESS_LEN]; - u32 l2_address_length; - u64 link_speed; - u16 link_mtu; - u8 admin_up_down; - u8 link_up_down; -} vpp_interface_t; - -typedef struct _dump_all_ctx -{ - int num_ifs; - int capacity; - vpp_interface_t * intfcArray; -} dump_all_ctx; - -/* return the number of interfaces or a negative error code */ -extern int interface_dump_all(dump_all_ctx * dctx); - -extern void sw_interface_details_query_set_name(sw_interface_details_query_t * query, - const char * interface_name); - -//input - sw_interface_details_query shall contain interface_name -extern int get_interface_id(sw_interface_details_query_t * sw_interface_details_query); - -//input - sw_interface_details_query shall contain sw_if_index -extern int get_interface_name(sw_interface_details_query_t * sw_interface_details_query); - -#endif /* __BAPI_INTERFACE_H__ */ diff --git a/src/scvpp/src/sc_vpp_ip.c b/src/scvpp/src/sc_vpp_ip.c deleted file mode 100644 index 0dfd108..0000000 --- a/src/scvpp/src/sc_vpp_ip.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 "sc_vpp_comm.h" -#include "sc_vpp_ip.h" - -#include "sc_vpp_interface.h" - -#include - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_IP_API_JSON - -VAPI_RETVAL_CB(sw_interface_add_del_address); - -static vapi_error_e -bin_api_sw_interface_add_del_address(u32 sw_if_index, bool is_add, bool is_ipv6, - bool del_all, u8 address_length, - const char *ip_address) -{ - vapi_msg_sw_interface_add_del_address *mp; - vapi_error_e rv; - - ARG_CHECK(VAPI_EINVAL, ip_address); - - mp = vapi_alloc_sw_interface_add_del_address(g_vapi_ctx_instance); - assert(NULL != mp); - - mp->payload.sw_if_index = sw_if_index; - mp->payload.is_add = is_add; - mp->payload.is_ipv6 = is_ipv6; - mp->payload.del_all = del_all; - mp->payload.address_length = address_length; - if (sc_aton(ip_address, mp->payload.address, sizeof(mp->payload.address))) - return VAPI_EINVAL; - - VAPI_CALL(vapi_sw_interface_add_del_address(g_vapi_ctx_instance, mp, - sw_interface_add_del_address_cb, NULL)); - - return rv; -} - -VAPI_COPY_CB(ip_add_del_route) - -static vapi_error_e -bin_api_ip_add_del_route(vapi_payload_ip_add_del_route_reply * reply, - const char* dst_address, uint8_t dst_address_length, - const char* next_hop, uint8_t is_add, - uint32_t table_id, const char *interface_name) -{ - sw_interface_details_query_t query = {0}; - vapi_msg_ip_add_del_route *mp; - - ARG_CHECK4(VAPI_EINVAL, reply, dst_address, next_hop, interface_name); - - sw_interface_details_query_set_name(&query, interface_name); - - if (!get_interface_id(&query)) - return VAPI_EINVAL; - - mp = vapi_alloc_ip_add_del_route (g_vapi_ctx_instance, 1); - assert(NULL != mp); - - //ip route add 2.2.2.2/24 via 5.5.5.5 - //show ip fib table 0 2.2.2.0/24 detail - - mp->payload.is_add = is_add; - mp->payload.dst_address_length = dst_address_length; - mp->payload.table_id = table_id; - mp->payload.next_hop_sw_if_index = query.sw_interface_details.sw_if_index; - - if (sc_aton(dst_address, mp->payload.dst_address, - sizeof(mp->payload.dst_address))) - return VAPI_EINVAL; - if (sc_aton(next_hop, mp->payload.next_hop_address, - sizeof(mp->payload.next_hop_address))) - return VAPI_EINVAL; - - vapi_error_e rv ; - VAPI_CALL(vapi_ip_add_del_route(g_vapi_ctx_instance, mp, ip_add_del_route_cb, reply)); - - return rv; -} - -static vapi_error_e -ip_address_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, - bool is_last, vapi_payload_ip_address_details *reply) -{ - UNUSED(rv); - ARG_CHECK3(VAPI_EINVAL, ctx, callback_ctx, reply); - - //copy dump reply in callback context - if (!is_last && callback_ctx) { - vapi_payload_ip_address_details *passed = - (vapi_payload_ip_address_details *) callback_ctx; - *passed = *reply; - } - - return VAPI_OK; -} - -static vapi_error_e -bin_api_ip_address_dump(u32 sw_if_index, bool is_ipv6, - vapi_payload_ip_address_details *dctx) -{ - vapi_msg_ip_address_dump *mp; - vapi_error_e rv; - - mp = vapi_alloc_ip_address_dump(g_vapi_ctx_instance); - mp->payload.sw_if_index = sw_if_index; - mp->payload.is_ipv6 = is_ipv6; - - VAPI_CALL(vapi_ip_address_dump(g_vapi_ctx_instance, mp, ip_address_dump_cb, - dctx)); - if (rv != VAPI_OK) - return rv; - - return VAPI_OK; -} - -/* - * @brief Dump IPv4/IPv6 address from an interface. - * @param interface_name Name of the interface to dump. - * @param ip_addr pointer where dump will store IP. - * @param prefix_len pointer where dump will store prefix - */ -int ipv46_address_dump(const char *interface_name, char *ip_addr, - u8 *prefix_len, bool is_ipv6) -{ - vapi_payload_ip_address_details dctx = {0}; - sw_interface_details_query_t query = {0}; - vapi_error_e rv; - - sw_interface_details_query_set_name(&query, interface_name); - - if (!get_interface_id(&query)) - return -EINVAL; - - rv = bin_api_ip_address_dump(query.sw_interface_details.sw_if_index, is_ipv6, &dctx); - if (rv != VAPI_OK) - return -EAGAIN; - - strcpy(ip_addr, sc_ntoa(dctx.ip)); //IP string - *prefix_len = dctx.prefix_length; //prefix length - - return 0; -} - -/** - * @brief Add or remove IPv4/IPv6 address to/from an interface. - */ -int ipv46_config_add_remove(const char *if_name, const char *addr, - uint8_t prefix, bool is_ipv6, bool add) -{ - vapi_error_e rv; - int rc; - - ARG_CHECK2(-1, if_name, addr); - - /* get interface index */ - sw_interface_details_query_t query = {0}; - sw_interface_details_query_set_name(&query, if_name); - rc = get_interface_id(&query); - if (!rc) - return -EINVAL; - - /* add del addr */ - rv = bin_api_sw_interface_add_del_address(query.sw_interface_details.sw_if_index, - add, is_ipv6, 0, prefix, addr); - if (rv != VAPI_OK) - return -EINVAL; - - return 0; -} - -/* - * @brief Add or remove an IP route - */ -int ipv46_config_add_del_route(const char* dst_address, u8 dst_address_length, - const char* next_address, u8 is_add, - u32 table_id, const char *interface) -{ - vapi_payload_ip_add_del_route_reply reply = {0}; - vapi_error_e rv; - - rv = bin_api_ip_add_del_route(&reply, dst_address, dst_address_length, - next_address, is_add, table_id, interface); - if (VAPI_OK != rv || reply.retval > 0) { - return -EINVAL; - } - - return 0; -} diff --git a/src/scvpp/src/sc_vpp_ip.h b/src/scvpp/src/sc_vpp_ip.h deleted file mode 100644 index a9f19d4..0000000 --- a/src/scvpp/src/sc_vpp_ip.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 __BAPI_IP_H__ -#define __BAPI_IP_H__ - -#include -#include - -/* If no IP has been found ip_addr will be "0.0.0.0" */ -extern int ipv46_address_dump(const char *interface_name, char *ip_addr, - u8 *prefix_len, bool is_ipv6); - -extern int ipv46_config_add_remove(const char *if_name, const char *addr, - uint8_t prefix, bool is_ipv6, bool add); - -extern int -ipv46_config_add_del_route(const char* dst_address, u8 dst_address_length, - const char* next_address, u8 is_add, u32 table_id, - const char *interface); - -#endif /* __BAPI_IP_H__ */ diff --git a/src/scvpp/src/sc_vpp_nat.c b/src/scvpp/src/sc_vpp_nat.c deleted file mode 100644 index e4bf2b7..0000000 --- a/src/scvpp/src/sc_vpp_nat.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 "sc_vpp_comm.h" -#include "sc_vpp_nat.h" - -#include -#include - - -DEFINE_VAPI_MSG_IDS_NAT_API_JSON - -static vapi_error_e -nat44_interface_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_nat44_interface_details *reply) -{ - UNUSED(ctx); - UNUSED(rv); - vapi_payload_nat44_interface_details *dctx = callback_ctx; - assert(dctx); - - if (is_last) - { - assert(NULL == reply); - } - else - { - //TODO: Use LOG message for scvpp -// SC_LOG_DBG("NAT Interface dump entry: [%u]: %u\n", reply->sw_if_index, -// reply->is_inside); - *dctx = *reply; - } - - return VAPI_OK; -} - -static vapi_error_e -bin_api_nat44_interface_dump(vapi_payload_nat44_interface_details *reply) -{ - vapi_error_e rv; - vapi_msg_nat44_interface_dump *mp; - - ARG_CHECK(VAPI_EINVAL, reply); - - mp = vapi_alloc_nat44_interface_dump(g_vapi_ctx_instance); - assert(NULL != mp); - - VAPI_CALL(vapi_nat44_interface_dump(g_vapi_ctx_instance, mp, - nat44_interface_dump_cb, reply)); - - return rv; -} - -VAPI_RETVAL_CB(nat44_add_del_interface_addr); - -static vapi_error_e -bin_api_nat44_add_del_interface_addr( - const vapi_payload_nat44_add_del_interface_addr *msg) -{ - vapi_error_e rv; - vapi_msg_nat44_add_del_interface_addr *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat44_add_del_interface_addr(g_vapi_ctx_instance); - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat44_add_del_interface_addr(g_vapi_ctx_instance, mp, - nat44_add_del_interface_addr_cb, - NULL)); - - return rv; -} - -VAPI_RETVAL_CB(nat44_add_del_address_range); - -static vapi_error_e -bin_api_nat44_add_del_addr_range( - const vapi_payload_nat44_add_del_address_range *range) -{ - vapi_error_e rv; - vapi_msg_nat44_add_del_address_range *mp; - - ARG_CHECK(VAPI_EINVAL, range); - - mp = vapi_alloc_nat44_add_del_address_range(g_vapi_ctx_instance); - - assert(NULL != mp); - - mp->payload = *range; - - VAPI_CALL(vapi_nat44_add_del_address_range(g_vapi_ctx_instance, mp, - nat44_add_del_address_range_cb, - NULL)); - - return rv; -} - -VAPI_RETVAL_CB(nat44_add_del_static_mapping); - -static vapi_error_e -bin_api_nat44_add_del_static_mapping( - const vapi_payload_nat44_add_del_static_mapping *msg) -{ - vapi_error_e rv; - vapi_msg_nat44_add_del_static_mapping *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat44_add_del_static_mapping(g_vapi_ctx_instance); - - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat44_add_del_static_mapping(g_vapi_ctx_instance, mp, - nat44_add_del_static_mapping_cb, - NULL)); - - return rv; -} - -static vapi_error_e nat44_static_mapping_dump_cb( - struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, - bool is_last,vapi_payload_nat44_static_mapping_details *reply) -{ - UNUSED(rv); - UNUSED(ctx); - vapi_payload_nat44_static_mapping_details *dctx = callback_ctx; - assert(dctx); - - if (is_last) - { - assert(NULL == reply); - } - else - { - *dctx = *reply; - } - - return VAPI_OK; -} - -static vapi_error_e -bin_api_nat44_static_mapping_dump( - vapi_payload_nat44_static_mapping_details *reply) -{ - vapi_error_e rv; - vapi_msg_nat44_static_mapping_dump *msg; - - ARG_CHECK(VAPI_EINVAL, reply); - - msg = vapi_alloc_nat44_static_mapping_dump(g_vapi_ctx_instance); - assert(NULL != msg); - - VAPI_CALL(vapi_nat44_static_mapping_dump(g_vapi_ctx_instance, msg, - nat44_static_mapping_dump_cb, - reply)); - - return rv; -} - -VAPI_RETVAL_CB(nat44_forwarding_enable_disable); - -static vapi_error_e bin_api_nat44_forwarding_enable_disable( - const vapi_payload_nat44_forwarding_enable_disable *msg) -{ - vapi_error_e rv; - vapi_msg_nat44_forwarding_enable_disable *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat44_forwarding_enable_disable(g_vapi_ctx_instance); - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat44_forwarding_enable_disable( - g_vapi_ctx_instance, mp, nat44_forwarding_enable_disable_cb, NULL)); - - return rv; -} - -VAPI_RETVAL_CB(nat_set_workers); - -static vapi_error_e -bin_api_nat_set_workers(const vapi_payload_nat_set_workers *msg) -{ - vapi_error_e rv; - vapi_msg_nat_set_workers *mp; - - ARG_CHECK(VAPI_EINVAL, msg); - - mp = vapi_alloc_nat_set_workers(g_vapi_ctx_instance); - assert(NULL != mp); - - mp->payload = *msg; - - VAPI_CALL(vapi_nat_set_workers(g_vapi_ctx_instance, mp, nat_set_workers_cb, - NULL)); - - return rv; -} - -int nat44_interface_dump(nat44_interface_details_t *reply) -{ - vapi_error_e rc; - - rc = bin_api_nat44_interface_dump(reply); - if (VAPI_OK != rc) { - //TODO: Need implement log function -// ERROR("Error in nat44_interface_dump, error: %u", rc); - return -1; - } - - return 0; -} - -int nat44_add_del_interface_addr(const nat44_add_del_interface_addr_t *msg) -{ - vapi_error_e rc; - - rc = bin_api_nat44_add_del_interface_addr(msg); - if (VAPI_OK != rc) { - //TODO: Need implement log function -// ERROR("Error in nat44_interface_dump, error: %u", rc); - return -1; - } - - return 0; -} - -int nat44_add_del_addr_range(const nat44_add_del_address_range_t *range) -{ - vapi_error_e rc; - - rc = bin_api_nat44_add_del_addr_range(range); - if (VAPI_OK != rc) { - //TODO: Need implement log function -// ERROR("Error in nat44_interface_dump, error: %u", rc); - return -1; - } - - return 0; -} - -int nat44_add_del_static_mapping(const nat44_add_del_static_mapping_t *msg) -{ - vapi_error_e rc; - - rc = bin_api_nat44_add_del_static_mapping(msg); - if (VAPI_OK != rc) { - //TODO: Need implement log function -// ERROR("Error in nat44_interface_dump, error: %u", rc); - return -1; - } - - return 0; -} - -int nat44_static_mapping_dump(nat44_static_mapping_details_t *reply) -{ - vapi_error_e rc; - - rc = bin_api_nat44_static_mapping_dump(reply); - if (VAPI_OK != rc) { - //TODO: Need implement log function -// ERROR("Error in nat44_interface_dump, error: %u", rc); - return -1; - } - - return 0; -} - -int nat44_forwarding_enable_disable( - const nat44_forwarding_enable_disable_t *msg) -{ - vapi_error_e rc; - - rc = bin_api_nat44_forwarding_enable_disable(msg); - if (VAPI_OK != rc) { - //TODO: Need implement log function -// ERROR("Error in nat44_interface_dump, error: %u", rc); - return -1; - } - - return 0; -} - -int nat_set_workers(const nat_set_workers_t *msg) -{ - vapi_error_e rc; - - rc = bin_api_nat_set_workers(msg); - if (VAPI_OK != rc) { - //TODO: Need implement log function -// ERROR("Error in nat44_interface_dump, error: %u", rc); - return -1; - } - - return 0; -} - diff --git a/src/scvpp/src/sc_vpp_nat.h b/src/scvpp/src/sc_vpp_nat.h deleted file mode 100644 index 40e727e..0000000 --- a/src/scvpp/src/sc_vpp_nat.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2018 PANTHEON.tech. - * - * 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 __BAPI_NAT_H__ -#define __BAPI_NAT_H__ - -#include - -typedef vapi_payload_nat44_interface_details nat44_interface_details_t; -typedef vapi_payload_nat44_add_del_interface_addr nat44_add_del_interface_addr_t; -typedef vapi_payload_nat44_add_del_address_range nat44_add_del_address_range_t; -typedef vapi_payload_nat44_add_del_static_mapping nat44_add_del_static_mapping_t; -typedef vapi_payload_nat44_static_mapping_details nat44_static_mapping_details_t; -typedef vapi_payload_nat44_forwarding_enable_disable nat44_forwarding_enable_disable_t; -typedef vapi_payload_nat_set_workers nat_set_workers_t; - - -//Wrapper function, if we want hide the VAPI return value -extern int nat44_interface_dump(nat44_interface_details_t *reply); -extern int nat44_add_del_interface_addr( - const nat44_add_del_interface_addr_t *msg); -extern int nat44_add_del_addr_range(const nat44_add_del_address_range_t *range); -extern int nat44_add_del_static_mapping( - const nat44_add_del_static_mapping_t *msg); -extern int nat44_static_mapping_dump(nat44_static_mapping_details_t *reply); -extern int nat44_forwarding_enable_disable( - const nat44_forwarding_enable_disable_t *msg); -extern int nat_set_workers(const nat_set_workers_t *msg); - - -// Alternative, if we don't want hide VAPI return value - -// extern vapi_error_e bin_api_nat44_interface_dump(nat44_interface_details_t *reply); -// extern vapi_error_e bin_api_nat44_add_del_interface_addr( -// const nat44_add_del_interface_addr_t *msg); -// extern vapi_error_e bin_api_nat44_add_del_addr_range( -// const nat44_add_del_address_range_t *range); -// extern vapi_error_e bin_api_nat44_add_del_static_mapping( -// const nat44_add_del_static_mapping_t *msg); -// extern vapi_error_e bin_api_nat44_static_mapping_dump( -// nat44_static_mapping_details_t *reply); -// extern vapi_error_e bin_api_nat44_forwarding_enable_disable( -// const nat44_forwarding_enable_disable_t *msg); -// extern vapi_error_e bin_api_nat_set_workers(const nat_set_workers_t *msg); - - -#endif /* __BAPI_NAT_H__ */ - diff --git a/src/scvpp/src/sc_vpp_v3po.c b/src/scvpp/src/sc_vpp_v3po.c deleted file mode 100644 index d312331..0000000 --- a/src/scvpp/src/sc_vpp_v3po.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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 "sc_vpp_comm.h" -#include "sc_vpp_v3po.h" -#include "sc_vpp_interface.h" - -/* - * tap-v2 interfaces - */ - -DEFINE_VAPI_MSG_IDS_TAPV2_API_JSON - -// Dump tapv2 - -//typedef struct __attribute__ ((__packed__)) { -// u32 sw_if_index; -// u32 id; -// u8 dev_name[64]; -// u16 tx_ring_sz; -// u16 rx_ring_sz; -// u8 host_mac_addr[6]; -// u8 host_if_name[64]; -// u8 host_namespace[64]; -// u8 host_bridge[64]; -// u8 host_ip4_addr[4]; -// u8 host_ip4_prefix_len; -// u8 host_ip6_addr[16]; -// u8 host_ip6_prefix_len; -// u32 tap_flags; -//} vapi_payload_sw_interface_tap_v2_details; - -// Delete tapv2 - -VAPI_RETVAL_CB(tap_delete_v2); - -static vapi_error_e bin_api_delete_tapv2(u32 sw_if_index) -{ - vapi_msg_tap_delete_v2 *mp; - vapi_error_e rv; - - mp = vapi_alloc_tap_delete_v2(g_vapi_ctx_instance); - assert(NULL != mp); - - mp->payload.sw_if_index = sw_if_index; - - VAPI_CALL(vapi_tap_delete_v2(g_vapi_ctx_instance, mp, tap_delete_v2_cb, - NULL)); - if (rv != VAPI_OK) - return -EAGAIN; - - return rv; -} - -int delete_tapv2(char *iface_name) -{ - int rc; - sw_interface_details_query_t query = {0}; - - sw_interface_details_query_set_name(&query, iface_name); - - rc = get_interface_id(&query); - if (!rc) - return -1; - - rc = bin_api_delete_tapv2(query.sw_interface_details.sw_if_index); - if (VAPI_OK != rc) - return -1; - - return 0; -} - -// Create tapv2 - -VAPI_RETVAL_CB(tap_create_v2); - -int create_tapv2(tapv2_create_t *query) -{ - vapi_msg_tap_create_v2 *mp; - vapi_error_e rv; - - mp = vapi_alloc_tap_create_v2(g_vapi_ctx_instance); - assert(NULL != mp); - - memcpy(&mp->payload, query, sizeof(tapv2_create_t)); - - VAPI_CALL(vapi_tap_create_v2(g_vapi_ctx_instance, mp, tap_create_v2_cb, - NULL)); - if (rv != VAPI_OK) - return -EAGAIN; - - return 0; -} diff --git a/src/scvpp/src/sc_vpp_v3po.h b/src/scvpp/src/sc_vpp_v3po.h deleted file mode 100644 index 9c13569..0000000 --- a/src/scvpp/src/sc_vpp_v3po.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 _V3PO__INTERFACE_H__ -#define _V3PO__INTERFACE_H__ - -#include - -typedef vapi_payload_tap_create_v2 tapv2_create_t; - -int create_tapv2(tapv2_create_t *query); -int delete_tapv2(char *iface_name); - -#endif /* __V3PO_INTERFACE_H__ */ diff --git a/src/scvpp/src/v3po.c b/src/scvpp/src/v3po.c new file mode 100644 index 0000000..f0a41c5 --- /dev/null +++ b/src/scvpp/src/v3po.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * Copyright (c) 2018 PANTHEON.tech. + * + * 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 + +// Use VAPI macros to define symbols +DEFINE_VAPI_MSG_IDS_L2_API_JSON; +DEFINE_VAPI_MSG_IDS_TAPV2_API_JSON + +/* + * tap-v2 interfaces + */ + +// Delete tapv2 + +VAPI_RETVAL_CB(tap_delete_v2); + +static vapi_error_e bin_api_delete_tapv2(u32 sw_if_index) +{ + vapi_msg_tap_delete_v2 *mp; + vapi_error_e rv; + + mp = vapi_alloc_tap_delete_v2(g_vapi_ctx); + assert(NULL != mp); + + mp->payload.sw_if_index = sw_if_index; + + VAPI_CALL(vapi_tap_delete_v2(g_vapi_ctx, mp, tap_delete_v2_cb, NULL)); + if (rv != VAPI_OK) + return -rv; + + return VAPI_OK; +} + +int delete_tapv2(char *iface_name) +{ + uint32_t sw_if_index; + vapi_error_e rv; + int rc; + + rc = get_interface_id(iface_name, &sw_if_index); + if (rc < 0) + return rc; + + rv = bin_api_delete_tapv2(sw_if_index); + if (VAPI_OK != rv) + return -SCVPP_EINVAL; + + return SCVPP_OK; +} + +// Create tapv2 + +VAPI_RETVAL_CB(tap_create_v2); + +int create_tapv2(tapv2_create_t *query) +{ + vapi_msg_tap_create_v2 *mp; + vapi_error_e rv; + + mp = vapi_alloc_tap_create_v2(g_vapi_ctx); + assert(NULL != mp); + + memcpy(&mp->payload, query, sizeof(tapv2_create_t)); + + VAPI_CALL(vapi_tap_create_v2(g_vapi_ctx, mp, tap_create_v2_cb, NULL)); + if (rv != VAPI_OK) + return -EAGAIN; + + return 0; +} diff --git a/src/scvpp/tests/CMakeLists.txt b/src/scvpp/tests/CMakeLists.txt index 3153fe0..2b6de4a 100644 --- a/src/scvpp/tests/CMakeLists.txt +++ b/src/scvpp/tests/CMakeLists.txt @@ -18,24 +18,23 @@ include_directories ("${PROJECT_SOURCE_DIR}/src") # check whether valgrind is installed find_program(valgrind_FOUND valgrind) -# macro for adding of an unit test -macro(ADD_UNIT_TEST TEST_NAME) - set(TEST_SRC - ${TEST_NAME}.c - scvpp_nat_test.c - ) - add_executable(${TEST_NAME} ${TEST_SRC}) - target_link_libraries(${TEST_NAME} ${CMOCKA_LIBRARIES} scvpp_a) - add_test(${TEST_NAME} ${TEST_NAME}) +set(TEST_SRC + scvpp_test.h + scvpp_test.c + scvpp_iface_test.c + scvpp_ip_test.c + scvpp_nat_test.c +) - if(valgrind_FOUND) - add_test(${TEST_NAME}_valgrind valgrind - --error-exitcode=1 --read-var-info=yes - --leak-check=full --show-leak-kinds=all - ./${TEST_NAME} - ) - endif(valgrind_FOUND) -endmacro(ADD_UNIT_TEST) +add_executable(scvpp_test ${TEST_SRC}) +target_link_libraries(scvpp_test ${CMOCKA_LIBRARIES} scvpp_a) +target_include_directories(scvpp_test PRIVATE ../inc) +add_test(scvpp_test scvpp_test) -# add individual unit-tests -ADD_UNIT_TEST(scvpp_test) +if(valgrind_FOUND) + add_test(${TEST_NAME}_valgrind valgrind + --error-exitcode=1 --read-var-info=yes + --leak-check=full --show-leak-kinds=all + ./${TEST_NAME} + ) +endif(valgrind_FOUND) diff --git a/src/scvpp/tests/scvpp_iface_test.c b/src/scvpp/tests/scvpp_iface_test.c new file mode 100644 index 0000000..6a96694 --- /dev/null +++ b/src/scvpp/tests/scvpp_iface_test.c @@ -0,0 +1,130 @@ +/* + * 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 "scvpp_test.h" + +#include +#include + +static void test_enable_disable(void **state) +{ + UNUSED(state); + sw_interface_dump_t dump = {0}; + int rc; + + rc = interface_enable("tap0", 1); + assert_int_equal(rc, SCVPP_OK); + + rc = interface_dump_iface(&dump, "tap0"); + assert_int_equal(rc, SCVPP_OK); + + assert_int_equal(dump.admin_up_down, true); + + rc = interface_enable("tap0", 0); + assert_int_equal(rc, SCVPP_OK); +} + +static void test_create_tapv2(void **state) +{ + UNUSED(state); + tapv2_create_t query = {0}; + sw_interface_dump_t dump = {0}; + int rc; + + query.id = 1; + query.use_random_mac = 1; + + rc = create_tapv2(&query); + assert_int_equal(rc, SCVPP_OK); + + rc = interface_dump_iface(&dump, "tap1"); + assert_int_equal(rc, SCVPP_OK); +} + +static int teardown_tapv2(void **state) +{ + UNUSED(state); + return delete_tapv2("tap1"); +} + +static void test_dump_iface_all(void **state) +{ + UNUSED(state); + struct elt *stack = NULL; + sw_interface_dump_t *dump; + bool exist = false; + + stack = interface_dump_all(); + assert_non_null(stack); + foreach_stack_elt(stack) { + dump = (sw_interface_dump_t *) data; + if (!strncmp((char*) dump->interface_name, "tap0", VPP_INTFC_NAME_LEN)) + exist = true; + free(dump); + } + assert_true(exist); +} + +static void test_dump_iface_exist(void **state) +{ + UNUSED(state); + vapi_payload_sw_interface_details details = {0}; + int rc; + + rc = interface_dump_iface(&details, "local0"); + assert_int_equal(rc, SCVPP_OK); + + assert_string_equal(details.interface_name, "local0"); +} + +static void test_dump_iface_unexist(void **state) +{ + UNUSED(state); + vapi_payload_sw_interface_details details = {0}; + int rc; + + rc = interface_dump_iface(&details, "unexisting"); + assert_int_equal(rc, -SCVPP_NOT_FOUND); +} + +static void test_get_interface_name(void **state) +{ + UNUSED(state); + char interface_name[VPP_INTFC_NAME_LEN]; + uint32_t tap0_if_index; + int rc; + + rc = get_interface_id("tap0", &tap0_if_index); + assert_int_equal(rc, SCVPP_OK); + + rc = get_interface_name(interface_name, tap0_if_index); + assert_int_equal(rc, SCVPP_OK); + + assert_string_equal(interface_name, "tap0"); +} + +const struct CMUnitTest iface_tests[IFACE_TEST_SIZE] = { + cmocka_unit_test_teardown(test_create_tapv2, teardown_tapv2), + cmocka_unit_test(test_enable_disable), + cmocka_unit_test(test_dump_iface_all), + cmocka_unit_test(test_dump_iface_exist), + cmocka_unit_test(test_dump_iface_unexist), + cmocka_unit_test(test_get_interface_name), +}; diff --git a/src/scvpp/tests/scvpp_ip_test.c b/src/scvpp/tests/scvpp_ip_test.c new file mode 100644 index 0000000..5e28123 --- /dev/null +++ b/src/scvpp/tests/scvpp_ip_test.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2019 Cisco + * + * 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 "scvpp_test.h" + +#include +#include +#include + +static void test_add_remove_ipv4(void **state) +{ + UNUSED(state); + const char ip_q[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.144"; + char ip_r[VPP_IP4_ADDRESS_STRING_LEN]; + u8 prefix_q = 24; + u8 prefix_r; + int rc; + + //add ipv4 on tap0 + rc = ipv46_config_add_remove("tap0", ip_q, prefix_q, false, true); + assert_int_equal(rc, SCVPP_OK); + + //dump ipv4 on tap0 and check if it mach + rc = ipv46_address_dump("tap0", ip_r, &prefix_r, false); + assert_int_equal(rc, SCVPP_OK); + assert_string_equal(ip_q, ip_r); + assert_int_equal(prefix_q, prefix_r); + + //remove ipv4 on tap0 + rc = ipv46_config_add_remove("tap0", ip_q, prefix_q, false, false); + assert_int_equal(rc, SCVPP_OK); + + //dump ipv4 after removal and check if equals 0.0.0.0 + rc = ipv46_address_dump("tap0", ip_r, &prefix_r, false); + assert_int_equal(rc, SCVPP_OK); + assert_string_equal(ip_r, "0.0.0.0"); +} + +static void test_ipv4_add_del_route_no_iface(void **state) +{ + UNUSED(state); + int rc; + char dst_address[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.0"; + uint8_t prefix_len = 24; + char next_hop[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.100"; + uint32_t table_id = 0; + fib_dump_t *dump; + struct elt *stack; + bool route_found = false; + + /* Must fail, can not have both interface and next hop IP null */ + rc = ipv46_config_add_del_route(dst_address, prefix_len, NULL, true, + table_id, NULL); + assert_int_equal(rc, -SCVPP_EINVAL); + + rc = ipv46_config_add_del_route(dst_address, prefix_len, next_hop, true, + table_id, NULL); + assert_int_equal(rc, SCVPP_OK); + + /* Dump all FIB routes and check if we find ours */ + stack = ipv4_fib_dump_all(); + assert_non_null(stack); + foreach_stack_elt(stack) { + dump = (fib_dump_t *) data; + + if (strncmp(sc_ntoa(dump->address), dst_address, + VPP_IP4_ADDRESS_STRING_LEN) == 0 && + dump->address_length == prefix_len) { + route_found = true; + assert_int_equal(dump->table_id, table_id); + assert_int_equal(dump->count, 1); + assert_string_equal(sc_ntoa(dump->path[0].next_hop), next_hop); + } + free(dump); + } + assert_true(route_found); + + /* Delete previously set route */ + rc = ipv46_config_add_del_route(dst_address, prefix_len, next_hop, false, + table_id, NULL); + assert_int_equal(rc, SCVPP_OK); + + /* Check our route has been deleted */ + route_found = false; + stack = ipv4_fib_dump_all(); + assert_non_null(stack); + foreach_stack_elt(stack) { + dump = (fib_dump_t *) data; + if (strncmp(sc_ntoa(dump->address), dst_address, + VPP_IP4_ADDRESS_STRING_LEN) == 0 && + dump->address_length == prefix_len) { + route_found = true; + } + free(dump); + } + assert_false(route_found); +} + +static void test_ipv4_add_del_route_no_next_hop_ip(void **state) +{ + UNUSED(state); + int rc; + char dst_address[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.0"; + uint8_t prefix_len = 24; + char interface[VPP_IP4_ADDRESS_STRING_LEN] = "tap0"; + uint32_t table_id = 0; + uint32_t sw_if_index; + fib_dump_t *dump; + struct elt *stack; + bool route_found = false; + + //Add a new route + rc = ipv46_config_add_del_route(dst_address, prefix_len, NULL, true, + table_id, interface); + assert_int_equal(rc, SCVPP_OK); + + //Dump all FIB routes and check we find ours + stack = ipv4_fib_dump_all(); + assert_non_null(stack); + + rc = get_interface_id(interface, &sw_if_index); + assert_int_equal(rc, SCVPP_OK); + + foreach_stack_elt(stack) { + dump = (fib_dump_t *) data; + + if (strncmp(sc_ntoa(dump->address), dst_address, + VPP_IP4_ADDRESS_STRING_LEN) == 0 && + dump->address_length == prefix_len) { + route_found = true; + assert_int_equal(dump->table_id, table_id); + assert_int_equal(dump->count, 1); + assert_int_equal(dump->path[0].sw_if_index, sw_if_index); + } + free(dump); + } + assert_true(route_found); + + //Delete route + rc = ipv46_config_add_del_route(dst_address, prefix_len, NULL, false, + table_id, interface); + assert_int_equal(rc, SCVPP_OK); + + //Check our route has been deleted + route_found = false; + stack = ipv4_fib_dump_all(); + assert_non_null(stack); + + foreach_stack_elt(stack) { + dump = (fib_dump_t *) data; + if (strncmp(sc_ntoa(dump->address), dst_address, + VPP_IP4_ADDRESS_STRING_LEN) == 0 && + dump->address_length == prefix_len) { + route_found = true; + } + free(dump); + } + assert_false(route_found); +} + + +const struct CMUnitTest ip_tests[IP_TEST_SIZE] = { + cmocka_unit_test(test_add_remove_ipv4), + cmocka_unit_test(test_ipv4_add_del_route_no_next_hop_ip), + cmocka_unit_test(test_ipv4_add_del_route_no_iface), +}; diff --git a/src/scvpp/tests/scvpp_nat_test.c b/src/scvpp/tests/scvpp_nat_test.c index fae9615..044102e 100644 --- a/src/scvpp/tests/scvpp_nat_test.c +++ b/src/scvpp/tests/scvpp_nat_test.c @@ -20,36 +20,37 @@ #include #include -#include "scvpp_nat_test.h" -#include "sc_vpp_comm.h" -#include "sc_vpp_nat.h" +#include "scvpp_test.h" -void test_nat44_static_mapping(__attribute__((unused)) void **state) +#include +#include + + +void test_nat44_static_mapping(void **state) { + UNUSED(state); nat44_add_del_static_mapping_t map = {0}; nat44_static_mapping_details_t dump = {0}; u8 empty_ip[4] = {0}; + int rc; /*Configure the static mapping Alternative to this CLI command: nat44 add static mapping local 172.168.0.1 external 172.168.8.5 */ - sc_aton("172.168.0.1", map.local_ip_address, sizeof(map.local_ip_address)); - sc_aton("172.168.8.5", map.external_ip_address, sizeof(map.external_ip_address)); - map.addr_only = 1; - map.external_sw_if_index = ~0; - map.is_add = 1; - nat44_add_del_static_mapping(&map); + rc = nat44_add_del_static_mapping(&map); + assert_int_equal(rc, SCVPP_OK); - nat44_static_mapping_dump(&dump); + rc = nat44_static_mapping_dump(&dump); + assert_int_equal(rc, SCVPP_OK); assert_int_equal(dump.addr_only, map.addr_only); @@ -62,11 +63,13 @@ void test_nat44_static_mapping(__attribute__((unused)) void **state) /* Remove previous config*/ map.is_add = 0; - nat44_add_del_static_mapping(&map); + rc = nat44_add_del_static_mapping(&map); + assert_int_equal(rc, SCVPP_OK); memset(&dump, 0, sizeof(dump)); - nat44_static_mapping_dump(&dump); + rc = nat44_static_mapping_dump(&dump); + assert_int_equal(rc, SCVPP_OK); assert_int_equal(dump.addr_only, 0); @@ -77,14 +80,16 @@ void test_nat44_static_mapping(__attribute__((unused)) void **state) sizeof(dump.external_ip_address)); } -void test_nat44_static_mapping_with_ports(__attribute__((unused)) void **state) +void test_nat44_static_mapping_with_ports(void **state) { + UNUSED(state); nat44_add_del_static_mapping_t map = {0}; nat44_static_mapping_details_t dump = {0}; nat44_add_del_address_range_t range = {0}; u8 empty_ip[4] = {0}; const u16 lport = 77; const u16 eport = 88; + int rc; /*Configure address pool Alternative to this CLI: @@ -98,7 +103,8 @@ void test_nat44_static_mapping_with_ports(__attribute__((unused)) void **state) range.is_add = 1; - nat44_add_del_addr_range(&range); + rc = nat44_add_del_addr_range(&range); + assert_int_equal(rc, SCVPP_OK); /*Configure NAT with ports Alternative to this CLI: @@ -122,9 +128,11 @@ void test_nat44_static_mapping_with_ports(__attribute__((unused)) void **state) map.is_add = 1; - nat44_add_del_static_mapping(&map); + rc = nat44_add_del_static_mapping(&map); + assert_int_equal(rc, SCVPP_OK); - nat44_static_mapping_dump(&dump); + rc = nat44_static_mapping_dump(&dump); + assert_int_equal(rc, SCVPP_OK); assert_int_equal(dump.addr_only, map.addr_only); @@ -142,11 +150,13 @@ void test_nat44_static_mapping_with_ports(__attribute__((unused)) void **state) map.is_add = 0; - nat44_add_del_static_mapping(&map); + rc = nat44_add_del_static_mapping(&map); + assert_int_equal(rc, SCVPP_OK); memset(&dump, 0, sizeof(dump)); - nat44_static_mapping_dump(&dump); + rc = nat44_static_mapping_dump(&dump); + assert_int_equal(rc, SCVPP_OK); assert_int_equal(dump.addr_only, 0); @@ -162,7 +172,8 @@ void test_nat44_static_mapping_with_ports(__attribute__((unused)) void **state) range.is_add = 0; - nat44_add_del_addr_range(&range); + rc = nat44_add_del_addr_range(&range); + assert_int_equal(rc, SCVPP_OK); } const struct CMUnitTest nat_tests[] = { diff --git a/src/scvpp/tests/scvpp_nat_test.h b/src/scvpp/tests/scvpp_nat_test.h deleted file mode 100644 index 8a22f87..0000000 --- a/src/scvpp/tests/scvpp_nat_test.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2019 PANTHEON.tech. - * - * 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. - */ - -/* inclusion guard */ -#ifndef __SCVPP_NAT_TEST_H__ -#define __SCVPP_NAT_TEST_H__ - -#define NAT_TEST_SIZE 2 -extern const struct CMUnitTest nat_tests[NAT_TEST_SIZE]; - -#endif /* __SCVPP_NAT_TEST_H__ */ diff --git a/src/scvpp/tests/scvpp_test.c b/src/scvpp/tests/scvpp_test.c index cc23e43..f6e99a0 100644 --- a/src/scvpp/tests/scvpp_test.c +++ b/src/scvpp/tests/scvpp_test.c @@ -14,89 +14,19 @@ */ #include -#include #include +#include #include -#include - -#include "sc_vpp_comm.h" -#include "sc_vpp_interface.h" -#include "sc_vpp_ip.h" -#include "sc_vpp_v3po.h" -#include "scvpp_nat_test.h" - -//TODO Check with future function get_interface_state -static void test_enable_disable(void **state) -{ - int rc; - - rc = interface_enable("tap0", 1); - assert_int_equal(rc, 0); - - rc = interface_enable("tap0", 0); - assert_int_equal(rc, 0); -} - -//TODO would need to make sure tap0 is index 1 -//TODO delete eventually because get_interface_id will not be extern -static void test_name2index(void **state) -{ - int rc; - const char iface_name[] = "tap0"; - sw_interface_details_query_t query = {0}; - sw_interface_details_query_set_name(&query, iface_name); - - rc = get_interface_id(&query); - assert_int_equal(rc, 1); - - assert_string_equal(iface_name, query.sw_interface_details.interface_name); - assert_int_equal(query.sw_interface_details.sw_if_index, 1); -} - -static void test_add_ipv4(void **state) -{ - const char ip_q[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.144"; - char ip_r[VPP_IP4_ADDRESS_STRING_LEN]; - u8 prefix_q = 24; - u8 prefix_r; - int rc; - - //add ipv4 on tap0 - rc = ipv46_config_add_remove("tap0", ip_q, prefix_q, false, true); - assert_int_equal(rc, 0); - - rc = ipv46_address_dump("tap0", ip_r, &prefix_r, false); - assert_int_equal(rc, 0); - - assert_string_equal(ip_q, ip_r); - assert_int_equal(prefix_q, prefix_r); -} - -static void test_remove_ipv4(void **state) -{ - const char ip_q[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.144"; - char ip_r[VPP_IP4_ADDRESS_STRING_LEN]; - u8 prefix_q = 24; - u8 prefix_r; - int rc; - - //add ipv4 on tap0 - rc = ipv46_config_add_remove("tap0", ip_q, prefix_q, false, true); - assert_int_equal(rc, 0); - //remove ipv4 on tap0 - rc = ipv46_config_add_remove("tap0", ip_q, prefix_q, false, false); - assert_int_equal(rc, 0); - - //dump ipv4 - rc = ipv46_address_dump("tap0", ip_r, &prefix_r, false); - assert_int_equal(rc, 0); +#include +#include - assert_string_equal(ip_r, "0.0.0.0"); -} +#include "scvpp_test.h" +/* test "AAA.BBB.CCC.DDD" -> {A, B, C, D} */ static void test_sc_ntoa(void **state) { + UNUSED(state); u8 buf[4] = {192, 168, 100, 44}; char *res; @@ -104,52 +34,76 @@ static void test_sc_ntoa(void **state) assert_string_equal(res, "192.168.100.44"); } -static void test_create_tapv2(void **state) +/* test {A, B, C, D} -> "AAA.BBB.CCC.DDD" */ +static void test_sc_aton(void **state) { - tapv2_create_t query = {0}; + UNUSED(state); + char ip[VPP_IP4_ADDRESS_STRING_LEN] = "192.168.100.44"; + uint8_t buf[4]; int rc; - query.id = 1; - query.use_random_mac = 1; - - rc = create_tapv2(&query); + rc = sc_aton(ip, buf, VPP_IP4_ADDRESS_LEN); assert_int_equal(rc, 0); - //TODO dump_tav2 and compare values - - rc = delete_tapv2("tap1"); - assert_int_equal(rc, 0); + assert_int_equal(buf[0], 192); + assert_int_equal(buf[1], 168); + assert_int_equal(buf[2], 100); + assert_int_equal(buf[3], 44); } -int main() +static int setup(void **state) { + UNUSED(state); tapv2_create_t query = {0}; - const struct CMUnitTest tests[] = { - cmocka_unit_test_setup_teardown(test_enable_disable, NULL, NULL), - cmocka_unit_test_setup_teardown(test_name2index, NULL, NULL), - cmocka_unit_test_setup_teardown(test_add_ipv4, NULL, NULL), - cmocka_unit_test_setup_teardown(test_remove_ipv4, NULL, NULL), - cmocka_unit_test_setup_teardown(test_sc_ntoa, NULL, NULL), - cmocka_unit_test_setup_teardown(test_create_tapv2, NULL, NULL), - }; - if (sc_connect_vpp() != 0) + if (sc_connect_vpp() != 0) { fprintf(stderr, "Error connecting to VPP\n"); + return -1; + } /* Create interface tap0 to test several functions */ query.id = 0; query.use_random_mac = 1; - if (create_tapv2(&query) != 0) + if (create_tapv2(&query) != 0) { fprintf(stderr, "Error creating tap0\n"); + return -1; + } - cmocka_run_group_tests(tests, NULL, NULL); - - print_message("\nNAT Tests\n"); - cmocka_run_group_tests(nat_tests, NULL, NULL); + return 0; +} +static int teardown(void **state) +{ + UNUSED(state); /* Delete tap0 */ - if (delete_tapv2("tap0") != 0) + if (delete_tapv2("tap0") != 0) { fprintf(stderr, "Failed deleting tap0\n"); + return -1; + } + + sc_disconnect_vpp(); + + return 0; +} + +/* return code for scvpp-test binary is the number of failed test */ +int main() +{ + int rc = 0; + + const struct CMUnitTest common_tests[] = { + cmocka_unit_test(test_sc_ntoa), + cmocka_unit_test(test_sc_aton), + }; + + print_message("Common tests\n"); + rc |= cmocka_run_group_tests(common_tests, NULL, NULL); + print_message("Interface tests\n"); + rc |= cmocka_run_group_tests(iface_tests, setup, teardown); + print_message("IP tests\n"); + rc |= cmocka_run_group_tests(ip_tests, setup, teardown); + print_message("NAT tests\n"); + rc |= cmocka_run_group_tests(nat_tests, setup, teardown); - return sc_disconnect_vpp(); + return rc; } diff --git a/src/scvpp/tests/scvpp_test.h b/src/scvpp/tests/scvpp_test.h new file mode 100644 index 0000000..28bd514 --- /dev/null +++ b/src/scvpp/tests/scvpp_test.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019 Cisco + * + * 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 __SCVPP_TEST_H +#define __SCVPP_TEST_H__ + +#include + +#define IFACE_TEST_SIZE 6 +extern const struct CMUnitTest iface_tests[IFACE_TEST_SIZE]; + +#define IP_TEST_SIZE 3 +extern const struct CMUnitTest ip_tests[IP_TEST_SIZE]; + +#define NAT_TEST_SIZE 2 +extern const struct CMUnitTest nat_tests[NAT_TEST_SIZE]; + +#endif /* __SCVPP_TEST_H__ */ -- cgit 1.2.3-korg