diff options
author | YohanPipereau <ypiperea@cisco.com> | 2019-02-28 17:21:51 +0100 |
---|---|---|
committer | YohanPipereau <ypiperea@cisco.com> | 2019-03-05 16:36:48 +0100 |
commit | 3430b042873f2eac94acd323125eaaa4a5f7f3e9 (patch) | |
tree | 45335d45b94259f53426413bc5333a36dcfb8f07 | |
parent | 793682e6fcb9e39891c59c696e5f8e9c18f9d8e7 (diff) |
Merge IETF and Openconfig to use SCVPP
scvpp should eventually be the only interface with VAPI and should not
depend on sysrepo.
-All sysrepo error codes in scvpp codes have been changed for errno error
codes. scvpp might eventually needs its own error codes.
-All log messages in scvpp have been removed as error codes are the only
way of reporting failures in a library.
-Move VAPI symbol definition to SCVPP.
In scvpp, unused maccros SC_VPP_VAPI_RECV and SC_REGISTER_RPC_EVT_HANDLER have
been removed.
Regarding plugins update:
-Use Openconfig way to convert interface name to interface index.
-Use Openconfig way to enable/disable an interface.
-Use Openconfig way of configuring interface IPs but use more arguments like
IETF.
-Use Openconfig way of adding a new route.
-Use Openconfig way of dumping an IP.
-Use common interface dump operation for get_name and get_id.
-Delete unused create loopback
Change-Id: Icc513a064a2528c2b4cbda2b0dd57755a3b08ef9
Signed-off-by: Yohan Pipereau <ypiperea@cisco.com>
-rw-r--r-- | src/plugins/ietf/ietf_interface.c | 369 | ||||
-rw-r--r-- | src/plugins/openconfig/openconfig_interfaces.c | 192 | ||||
-rw-r--r-- | src/plugins/openconfig/openconfig_local_routing.c | 21 | ||||
-rw-r--r-- | src/plugins/openconfig/sys_util.h | 1 | ||||
-rw-r--r-- | src/plugins/sc_model.h | 4 | ||||
-rw-r--r-- | src/plugins/sc_plugins.c | 30 | ||||
-rw-r--r-- | src/plugins/sc_plugins.h | 26 | ||||
-rw-r--r-- | src/scvpp/src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/scvpp/src/sc_vpp_comm.c | 100 | ||||
-rw-r--r-- | src/scvpp/src/sc_vpp_comm.h | 89 | ||||
-rw-r--r-- | src/scvpp/src/sc_vpp_interface.c | 250 | ||||
-rw-r--r-- | src/scvpp/src/sc_vpp_interface.h | 43 | ||||
-rw-r--r-- | src/scvpp/src/sc_vpp_ip.c | 177 | ||||
-rw-r--r-- | src/scvpp/src/sc_vpp_ip.h | 28 |
14 files changed, 512 insertions, 820 deletions
diff --git a/src/plugins/ietf/ietf_interface.c b/src/plugins/ietf/ietf_interface.c index 728d20e..922c84f 100644 --- a/src/plugins/ietf/ietf_interface.c +++ b/src/plugins/ietf/ietf_interface.c @@ -18,50 +18,14 @@ #include <netinet/in.h> #include <arpa/inet.h> -#include <sysrepo.h> -#include <sysrepo/plugins.h> -#include <sysrepo/values.h> -#include <sysrepo/xpath.h> -#include <vnet/interface.h> -#include <vnet/vnet.h> -#include <vnet/ip/ip.h> -#include <vapi/interface.api.vapi.h> - #include "ietf_interface.h" -DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON; - -typedef struct _s_vpp_interface_ -{ - 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; -} scVppIntfc; - -typedef struct _ietf_sw_interface_dump_ctx -{ - u8 last_called; - int num_ifs; - int capacity; - scVppIntfc * intfcArray; -} ietf_sw_interface_dump_ctx; - -static i32 ietf_setInterfaceFlags(u32 sw_if_index, u8 admin_up_down); -static i32 ietf_interface_name2index(const char *name, u32* if_index); -static i32 ietf_interface_add_del_addr(u32 sw_if_index, u8 is_add, u8 is_ipv6, - u8 del_all, u8 address_length, - u8 address[VPP_IP6_ADDRESS_LEN]); -static int ietf_swInterfaceDump(ietf_sw_interface_dump_ctx * dctx); -static int ietf_initSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx); -static int ietf_freeSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx); +#include "sc_vpp_interface.h" +#include "sc_vpp_ip.h" /** - * @brief Helper function for converting netmask into prefix length. + * @brief Helper function for converting netmask (ex: 255.255.255.0) + * to prefix length (ex: 24). */ static uint8_t netmask_to_prefix(const char *netmask) @@ -80,65 +44,12 @@ netmask_to_prefix(const char *netmask) } /** - * @brief Helper function for converting IPv4/IPv6 address string into binary representation. + * @brief Callback to be called by any config change of + * "/ietf-interfaces:interfaces/interface/enabled" leaf. */ static int -ip_addr_str_to_binary(const char *ip_address_str, uint8_t *ip_address_bin, bool is_ipv6) -{ - struct in6_addr addr6 = { 0, }; - struct in_addr addr4 = { 0, }; - int ret = 0; - - if (is_ipv6) { - ret = inet_pton(AF_INET6, ip_address_str, &(addr6)); - if (1 == ret) - { - memcpy(ip_address_bin, &addr6, sizeof(addr6)); - } - } else { - ret = inet_pton(AF_INET, ip_address_str, &(addr4)); - if (1 == ret) - { - memcpy(ip_address_bin, &addr4, sizeof(addr4)); - } - } - - return ret; -} - -/** - * @brief Enable or disable given interface. - */ -static int -interface_enable_disable(const char *if_name, bool enable) -{ - uint32_t if_index = ~0; - int rc = 0; - - SRP_LOG_DBG("%s interface '%s'", enable ? "Enabling" : "Disabling", if_name); - - /* get interface index */ - rc = ietf_interface_name2index(if_name, &if_index); - if (0 != rc) { - SRP_LOG_ERR("Invalid interface name: %s", if_name); - return SR_ERR_INVAL_ARG; - } - - /* enable/disable interface */ - rc = ietf_setInterfaceFlags(if_index, (uint8_t)enable); - if (0 != rc) { - SRP_LOG_ERR("Error by processing of the sw_interface_set_flags request, rc=%d", rc); - return SR_ERR_OPERATION_FAILED; - } else { - return SR_ERR_OK; - } -} - -/** - * @brief Callback to be called by any config change of "/ietf-interfaces:interfaces/interface/enabled" leaf. - */ -static int -ietf_interface_enable_disable_cb(sr_session_ctx_t *session, const char *xpath, sr_notif_event_t event, void *private_ctx) +ietf_interface_enable_disable_cb(sr_session_ctx_t *session, const char *xpath, + sr_notif_event_t event, void *private_ctx) { char *if_name = NULL; sr_change_iter_t *iter = NULL; @@ -148,6 +59,7 @@ ietf_interface_enable_disable_cb(sr_session_ctx_t *session, const char *xpath, s sr_xpath_ctx_t xpath_ctx = { 0, }; int rc = SR_ERR_OK, op_rc = SR_ERR_OK; + SRP_LOG_INF("In %s", __FUNCTION__); /* no-op for apply, we only care about SR_EV_ENABLED, SR_EV_VERIFY, SR_EV_ABORT */ if (SR_EV_APPLY == event) { return SR_ERR_OK; @@ -170,10 +82,10 @@ ietf_interface_enable_disable_cb(sr_session_ctx_t *session, const char *xpath, s switch (op) { case SR_OP_CREATED: case SR_OP_MODIFIED: - op_rc = interface_enable_disable(if_name, new_val->data.bool_val); + op_rc = interface_enable(if_name, new_val->data.bool_val); break; case SR_OP_DELETED: - op_rc = interface_enable_disable(if_name, false /* !enable */); + op_rc = interface_enable(if_name, false /* !enable */); break; default: break; @@ -190,45 +102,7 @@ ietf_interface_enable_disable_cb(sr_session_ctx_t *session, const char *xpath, s return op_rc; } -/** - * @brief Add or remove IPv4/IPv6 address to/from an interface. - */ -static int -interface_ipv46_config_add_remove(const char *if_name, uint8_t *addr, uint8_t prefix, bool is_ipv6, bool add) -{ - uint32_t if_index = ~0; - int rc = 0; - - SRP_LOG_DBG("%s IP config on interface '%s'.", add ? "Adding" : "Removing", if_name); - - /* get interface index */ - rc = ietf_interface_name2index(if_name, &if_index); - if (0 != rc) { - SRP_LOG_ERR("Invalid interface name: %s", if_name); - return SR_ERR_INVAL_ARG; - } - - /* add del addr */ - rc = ietf_interface_add_del_addr(if_index, (uint8_t)add, (uint8_t)is_ipv6, 0, prefix, addr); - if (0 != rc) { - SRP_LOG_ERR("Error by processing of the sw_interface_set_flags request, rc=%d", rc); - return SR_ERR_OPERATION_FAILED; - } else { - return SR_ERR_OK; - } -} -int ietf_initSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx) -{ - if(dctx == NULL) - return -1; - - dctx->intfcArray = NULL; - dctx->last_called = false; - dctx->capacity = 0; - dctx->num_ifs = 0; - return 0; -} -int ietf_freeSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx) +static int free_sw_interface_dump_ctx(dump_all_ctx * dctx) { if(dctx == NULL) return -1; @@ -238,167 +112,22 @@ int ietf_freeSwInterfaceDumpCTX(ietf_sw_interface_dump_ctx * dctx) free(dctx->intfcArray); } - return ietf_initSwInterfaceDumpCTX(dctx); -} -vapi_error_e -ietf_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) -{ - ietf_sw_interface_dump_ctx *dctx = callback_ctx; - if (is_last) - { - dctx->last_called = true; - } - else - { - if(dctx->capacity == 0 && dctx->intfcArray == NULL) - { - dctx->capacity = 10; - dctx->intfcArray = (scVppIntfc*)malloc( sizeof(scVppIntfc)*dctx->capacity ); - } - if(dctx->num_ifs >= dctx->capacity-1) - { - - dctx->capacity += 10; - dctx->intfcArray = (scVppIntfc*)realloc(dctx->intfcArray, sizeof(scVppIntfc)*dctx->capacity ); - } - - scVppIntfc * thisIntfc = &dctx->intfcArray[dctx->num_ifs]; - - thisIntfc->sw_if_index = reply->sw_if_index; - strncpy(thisIntfc->interface_name, reply->interface_name, VPP_INTFC_NAME_LEN); - thisIntfc->l2_address_length = reply->l2_address_length; - memcpy(thisIntfc->l2_address, reply->l2_address, reply->l2_address_length ); - //thisIntfc->link_speed = reply->link_speed; -#define ONE_MEGABIT (uint64_t)1000000 - switch (reply->link_speed << VNET_HW_INTERFACE_FLAG_SPEED_SHIFT) - { - default: - thisIntfc->link_speed = 0; - break; - } - - thisIntfc->link_mtu = reply->link_mtu; - thisIntfc->admin_up_down = reply->admin_up_down; - thisIntfc->link_up_down = reply->link_up_down; - - dctx->num_ifs += 1; - } - return VAPI_OK; -} - -static int ietf_swInterfaceDump(ietf_sw_interface_dump_ctx * dctx) -{ - if(dctx == NULL) - { - return -1; - } - - //ietf_sw_interface_dump_ctx dctx = { false, 0, 0, 0 }; - vapi_msg_sw_interface_dump *dump; - vapi_error_e rv; - // dctx->last_called = false; - ietf_initSwInterfaceDumpCTX(dctx); - 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, ietf_sw_interface_dump_cb, - dctx))); - - return dctx->num_ifs; -} - -static i32 ietf_interface_name2index(const char *name, u32* if_index) -{ - ARG_CHECK2(-1, name, if_index); - - i32 ret = -1; - ietf_sw_interface_dump_ctx dctx = {false, 0, 0, 0}; - vapi_msg_sw_interface_dump *dump; - vapi_error_e rv; - dctx.last_called = false; - - dump = vapi_alloc_sw_interface_dump(g_vapi_ctx_instance); - dump->payload.name_filter_valid = true; - strncpy(dump->payload.name_filter, name, sizeof(dump->payload.name_filter)); - - while (VAPI_EAGAIN == (rv = vapi_sw_interface_dump(g_vapi_ctx_instance, dump, ietf_sw_interface_dump_cb, &dctx))) - ; - - int i = 0; - for (; i < dctx.num_ifs; ++i) - { - if (strcmp(dctx.intfcArray[i].interface_name, name) == 0) - { - *if_index = dctx.intfcArray[i].sw_if_index; - ret = 0; - break; - } - } - ietf_freeSwInterfaceDumpCTX(&dctx); - - return ret; -} - -i32 ietf_interface_add_del_addr( u32 sw_if_index, u8 is_add, u8 is_ipv6, u8 del_all, - u8 address_length, u8 address[VPP_IP6_ADDRESS_LEN] ) -{ - i32 ret = -1; - vapi_msg_sw_interface_add_del_address *msg = vapi_alloc_sw_interface_add_del_address(g_vapi_ctx_instance); - msg->payload.sw_if_index = sw_if_index; - msg->payload.is_add = is_add; - msg->payload.is_ipv6 = is_ipv6; - msg->payload.del_all = del_all; - msg->payload.address_length = address_length; - memcpy(msg->payload.address, address, VPP_IP6_ADDRESS_LEN); - vapi_msg_sw_interface_add_del_address_hton (msg); - - vapi_error_e rv = vapi_send (g_vapi_ctx_instance, msg); - - vapi_msg_sw_interface_add_del_address_reply *resp; - - SC_VPP_VAPI_RECV; - - vapi_msg_sw_interface_add_del_address_reply_hton(resp); - ret = resp->payload.retval; - vapi_msg_free (g_vapi_ctx_instance, resp); - return ret; -} - -i32 ietf_setInterfaceFlags(u32 sw_if_index, u8 admin_up_down) -{ - i32 ret = -1; - vapi_msg_sw_interface_set_flags *msg = vapi_alloc_sw_interface_set_flags(g_vapi_ctx_instance); - msg->payload.sw_if_index = sw_if_index; - msg->payload.admin_up_down = admin_up_down; - vapi_msg_sw_interface_set_flags_hton (msg); - - vapi_error_e rv = vapi_send (g_vapi_ctx_instance, msg); - - vapi_msg_sw_interface_set_flags_reply *resp; + dctx->intfcArray = NULL; + dctx->capacity = 0; + dctx->num_ifs = 0; - SC_VPP_VAPI_RECV; - - vapi_msg_sw_interface_set_flags_reply_ntoh(resp); - ret = resp->payload.retval; - vapi_msg_free (g_vapi_ctx_instance, resp); - return ret; + return 0; } - /** * @brief Modify existing IPv4/IPv6 config on an interface. */ static int -interface_ipv46_config_modify(sr_session_ctx_t *session, const char *if_name, - sr_val_t *old_val, sr_val_t *new_val, bool is_ipv6) +interface_ipv46_config_modify(const char *if_name, sr_val_t *old_val, + sr_val_t *new_val, bool is_ipv6) { sr_xpath_ctx_t xpath_ctx = { 0, }; - char *addr_str = NULL; - uint8_t addr[16] = { 0, }; + char *addr = NULL; uint8_t prefix = 0; int rc = SR_ERR_OK; @@ -412,12 +141,11 @@ interface_ipv46_config_modify(sr_session_ctx_t *session, const char *if_name, } else { return SR_ERR_INVAL_ARG; } - addr_str = sr_xpath_key_value((char*)old_val->xpath, "address", "ip", &xpath_ctx); - ip_addr_str_to_binary(addr_str, addr, is_ipv6); + addr = sr_xpath_key_value((char*)old_val->xpath, "address", "ip", &xpath_ctx); sr_xpath_recover(&xpath_ctx); /* delete old IP config */ - rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, false /* remove */); + rc = ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, false /* remove */); if (SR_ERR_OK != rc) { SRP_LOG_ERR("Unable to remove old IP address config, rc=%d", rc); return rc; @@ -431,7 +159,7 @@ interface_ipv46_config_modify(sr_session_ctx_t *session, const char *if_name, } /* set new IP config */ - rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, true /* add */); + rc = ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, true /* add */); if (SR_ERR_OK != rc) { SRP_LOG_ERR("Unable to remove old IP address config, rc=%d", rc); return rc; @@ -445,7 +173,10 @@ interface_ipv46_config_modify(sr_session_ctx_t *session, const char *if_name, * or "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address". */ static int -ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *xpath, sr_notif_event_t event, void *private_ctx) +ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, + const char *xpath, + sr_notif_event_t event, + void *private_ctx) { sr_change_iter_t *iter = NULL; sr_change_oper_t op = SR_OP_CREATED; @@ -453,11 +184,13 @@ ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *xp sr_val_t *new_val = NULL; sr_xpath_ctx_t xpath_ctx = { 0, }; bool is_ipv6 = false, has_addr = false, has_prefix = false; - uint8_t addr[16] = { 0, }; + char addr[VPP_IP6_ADDRESS_STRING_LEN] = {0}; uint8_t prefix = 0; char *node_name = NULL, *if_name = NULL; int rc = SR_ERR_OK, op_rc = SR_ERR_OK; + SRP_LOG_INF("In %s", __FUNCTION__); + /* no-op for apply, we only care about SR_EV_ENABLED, SR_EV_VERIFY, SR_EV_ABORT */ if (SR_EV_APPLY == event) { return SR_ERR_OK; @@ -493,7 +226,7 @@ ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *xp has_addr = has_prefix = false; } else { if (sr_xpath_node_name_eq(new_val->xpath, "ip")) { - ip_addr_str_to_binary(new_val->data.string_val, addr, is_ipv6); + strncpy(addr, new_val->data.string_val, strlen(new_val->data.string_val)); has_addr = true; } else if (sr_xpath_node_name_eq(new_val->xpath, "prefix-length")) { prefix = new_val->data.uint8_val; @@ -503,12 +236,13 @@ ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *xp has_prefix = true; } if (has_addr && has_prefix) { - op_rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, true /* add */); + op_rc = ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, true /* add */); } } break; case SR_OP_MODIFIED: - op_rc = interface_ipv46_config_modify(session, if_name, old_val, new_val, is_ipv6); + //TODO Why is it using old_val and new_val? + op_rc = interface_ipv46_config_modify(if_name, old_val, new_val, is_ipv6); break; case SR_OP_DELETED: if (SR_LIST_T == old_val->type) { @@ -516,7 +250,7 @@ ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *xp has_addr = has_prefix = false; } else { if (sr_xpath_node_name_eq(old_val->xpath, "ip")) { - ip_addr_str_to_binary(old_val->data.string_val, addr, is_ipv6); + strncpy(addr, old_val->data.string_val, strlen(old_val->data.string_val)); has_addr = true; } else if (sr_xpath_node_name_eq(old_val->xpath, "prefix-length")) { prefix = old_val->data.uint8_val; @@ -526,7 +260,7 @@ ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *xp has_prefix = true; } if (has_addr && has_prefix) { - op_rc = interface_ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, false /* !add */); + op_rc = ipv46_config_add_remove(if_name, addr, prefix, is_ipv6, false /* !add */); } } break; @@ -550,8 +284,10 @@ ietf_interface_ipv46_address_change_cb(sr_session_ctx_t *session, const char *xp * Does not provide any functionality, needed just to cover not supported config leaves. */ static int -ietf_interface_change_cb(sr_session_ctx_t *session, const char *xpath, sr_notif_event_t event, void *private_ctx) +ietf_interface_change_cb(sr_session_ctx_t *session, const char *xpath, + sr_notif_event_t event, void *private_ctx) { + SRP_LOG_INF("In %s", __FUNCTION__); SRP_LOG_DBG("'%s' modified, event=%d", xpath, event); return SR_ERR_OK; @@ -569,11 +305,12 @@ ietf_interface_state_cb(const char *xpath, sr_val_t **values, { sr_val_t *values_arr = NULL; int values_arr_size = 0, values_arr_cnt = 0; - ietf_sw_interface_dump_ctx dctx; - scVppIntfc* if_details; + dump_all_ctx dctx; + int nb_iface; + vpp_interface_t* if_details; int rc = 0; - SRP_LOG_DBG("Requesting state data for '%s'", xpath); + SRP_LOG_INF("In %s", __FUNCTION__); if (! sr_xpath_node_name_eq(xpath, "interface")) { /* statistics, ipv4 and ipv6 state data not supported */ @@ -583,23 +320,23 @@ ietf_interface_state_cb(const char *xpath, sr_val_t **values, } /* dump interfaces */ - rc = ietf_swInterfaceDump(&dctx); - if (rc <= 0) { + nb_iface = interface_dump_all(&dctx); + if (nb_iface <= 0) { SRP_LOG_ERR_MSG("Error by processing of a interface dump request."); - ietf_freeSwInterfaceDumpCTX(&dctx); + free_sw_interface_dump_ctx(&dctx); return SR_ERR_INTERNAL; } /* allocate array of values to be returned */ - values_arr_size = dctx.num_ifs * 5; + values_arr_size = nb_iface * 5; rc = sr_new_values(values_arr_size, &values_arr); if (0 != rc) { - ietf_freeSwInterfaceDumpCTX(&dctx); + free_sw_interface_dump_ctx(&dctx); return rc; } int i = 0; - for (; i < dctx.num_ifs; i++) { + for (; i < nb_iface; i++) { if_details = dctx.intfcArray+i; /* currently the only supported interface types are propVirtual / ethernetCsmacd */ @@ -623,10 +360,10 @@ ietf_interface_state_cb(const char *xpath, sr_val_t **values, if_details->l2_address[3], if_details->l2_address[4], if_details->l2_address[5]); values_arr_cnt++; } else { - sr_val_build_xpath(&values_arr[values_arr_cnt], "%s[name='%s']/phys-address", xpath, if_details->interface_name); - sr_val_build_str_data(&values_arr[values_arr_cnt], SR_STRING_T, "%02x:%02x:%02x:%02x:%02x:%02x", 0,0,0,0,0,0); - values_arr_cnt++; - } + sr_val_build_xpath(&values_arr[values_arr_cnt], "%s[name='%s']/phys-address", xpath, if_details->interface_name); + sr_val_build_str_data(&values_arr[values_arr_cnt], SR_STRING_T, "%02x:%02x:%02x:%02x:%02x:%02x", 0,0,0,0,0,0); + values_arr_cnt++; + } sr_val_build_xpath(&values_arr[values_arr_cnt], "%s[name='%s']/speed", xpath, if_details->interface_name); values_arr[values_arr_cnt].type = SR_UINT64_T; @@ -639,7 +376,7 @@ ietf_interface_state_cb(const char *xpath, sr_val_t **values, *values = values_arr; *values_cnt = values_arr_cnt; - ietf_freeSwInterfaceDumpCTX(&dctx); + free_sw_interface_dump_ctx(&dctx); return SR_ERR_OK; } diff --git a/src/plugins/openconfig/openconfig_interfaces.c b/src/plugins/openconfig/openconfig_interfaces.c index a1f66bb..85339af 100644 --- a/src/plugins/openconfig/openconfig_interfaces.c +++ b/src/plugins/openconfig/openconfig_interfaces.c @@ -14,43 +14,18 @@ * limitations under the License. */ +#include <assert.h> +#include <string.h> + #include "openconfig_interfaces.h" #include "sys_util.h" + #include "sc_vpp_comm.h" #include "sc_vpp_interface.h" #include "sc_vpp_ip.h" -#include <assert.h> -#include <string.h> -#include <sysrepo/xpath.h> -#include <sysrepo/values.h> -#include <sysrepo.h> - #define XPATH_SIZE 2000 -static int oi_enable_interface(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); - - if (false == get_interface_id(&query)) { - return -1; - } - - rc = bin_api_sw_interface_set_flags(query.sw_interface_details.sw_if_index, - enable); - if (VAPI_OK != rc) { - SRP_LOG_ERR_MSG("Call bin_api_sw_interface_set_flags."); - rc = -1; - } - - return rc; -} - // XPATH: /openconfig-interfaces:interfaces/interface[name='%s']/config/ int openconfig_interfaces_interfaces_interface_config_cb( sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event, @@ -64,6 +39,8 @@ int openconfig_interfaces_interfaces_interface_config_cb( char interface_name[XPATH_SIZE] = {0}; int rc = 0; + SRP_LOG_INF_MSG("In openconfig_interfaces_interfaces_interface_config_cb"); + ARG_CHECK2(SR_ERR_INVAL_ARG, ds, xpath); // if we receive event SR_EV_APPLY - config has changed @@ -128,7 +105,7 @@ int openconfig_interfaces_interfaces_interface_config_cb( "description")) { //TODO: LEAF: description, type: string } else if(sr_xpath_node_name_eq(new_val->xpath, "enabled")) { - rc = oi_enable_interface(interface_name, + rc = interface_enable(interface_name, new_val->data.bool_val); } else if(sr_xpath_node_name_eq(new_val->xpath, "oc-vlan:tpid")) { @@ -150,7 +127,7 @@ int openconfig_interfaces_interfaces_interface_config_cb( "description")) { //TODO: LEAF: description, type: string } else if(sr_xpath_node_name_eq(new_val->xpath, "enabled")) { - rc = oi_enable_interface(interface_name, + rc = interface_enable(interface_name, new_val->data.bool_val); } else if(sr_xpath_node_name_eq(new_val->xpath, "oc-vlan:tpid")) { @@ -175,7 +152,7 @@ int openconfig_interfaces_interfaces_interface_config_cb( "description")) { //TODO: LEAF: description, type: string } else if(sr_xpath_node_name_eq(old_val->xpath, "enabled")) { - rc = oi_enable_interface(interface_name, false); + rc = interface_enable(interface_name, false); } else if(sr_xpath_node_name_eq(old_val->xpath, "oc-vlan:tpid")) { //TODO: LEAF: oc-vlan:tpid, type: identityref @@ -204,13 +181,14 @@ int openconfig_interfaces_interfaces_interface_config_cb( return SR_ERR_OK; } +// openconfig-interfaces int openconfig_interface_mod_cb( __attribute__((unused)) sr_session_ctx_t *session, __attribute__((unused)) const char *module_name, __attribute__((unused)) sr_notif_event_t event, __attribute__((unused)) void *private_ctx) { - SRP_LOG_DBG("Interface module subscribe: %s", module_name); + SRP_LOG_INF_MSG("In openconfig_interface_mod_cb"); return SR_ERR_OK; } @@ -225,7 +203,6 @@ typedef struct #define NOT_AVAL "NA" -// XPATH: /openconfig-interfaces:interfaces/interface/state static int sw_interface_dump_cb_inner( vapi_payload_sw_interface_details * reply, @@ -301,8 +278,6 @@ static int sw_interface_dump_cb_inner( return SR_ERR_OK; } - -// XPATH: /openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/state static int sw_subinterface_dump_cb_inner( vapi_payload_sw_interface_details *reply, sys_sw_interface_dump_ctx *dctx) @@ -367,9 +342,9 @@ static int sw_subinterface_dump_cb_inner( return SR_ERR_OK; } -static -bool is_subinterface(const char* subif_name, const char* base_name, - const u32 subif_index) +static bool +is_subinterface(const char* subif_name, const char* base_name, + const u32 subif_index) { assert(subif_name && base_name); @@ -434,10 +409,12 @@ sw_interface_dump_vapi_cb(struct vapi_ctx_s *ctx, void *callback_ctx, static vapi_error_e sysr_sw_interface_dump(sys_sw_interface_dump_ctx * dctx) { + vapi_msg_sw_interface_dump *dump; + vapi_error_e rv; + ARG_CHECK(VAPI_EINVAL, dctx); - vapi_msg_sw_interface_dump *dump = vapi_alloc_sw_interface_dump(g_vapi_ctx_instance); - vapi_error_e rv; + dump = vapi_alloc_sw_interface_dump(g_vapi_ctx_instance); dump->payload.name_filter_valid = true; strcpy((char*)dump->payload.name_filter, (const char *)dctx->sw_interface_details_query.sw_interface_details.interface_name); @@ -463,11 +440,13 @@ int openconfig_interfaces_interfaces_interface_state_cb( char *tmp = NULL; char interface_name[XPATH_SIZE] = {0}; + SRP_LOG_INF_MSG("In openconfig_interfaces_interfaces_interface_state_cb"); + ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); tmp = xpath_find_first_key(xpath, "name", &state); if (NULL == tmp) { - SRP_LOG_DBG_MSG("interface_name not found."); + SRP_LOG_ERR_MSG("Interface name not found in sysrepo database"); return SR_ERR_INVAL_ARG; } @@ -487,7 +466,7 @@ int openconfig_interfaces_interfaces_interface_state_cb( sysr_sw_interface_dump(&dctx); if (!dctx.sw_interface_details_query.interface_found) { - SRP_LOG_DBG_MSG("interface not found"); + SRP_LOG_ERR_MSG("interface not found"); return SR_ERR_NOT_FOUND; } @@ -498,16 +477,14 @@ int openconfig_interfaces_interfaces_interface_state_cb( return SR_ERR_OK; } -// XPATH: /openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address/openconfig-if-ip:state -int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_vapi_cb( - vapi_payload_ip_address_details *reply, - sysr_values_ctx_t *sysr_values_ctx) +int oc_dump_ip_helper(char *address_ip, u8 prefix_len, + sysr_values_ctx_t *sysr_values_ctx) { sr_val_t *vals = NULL; int rc = 0; int vc = 0; - ARG_CHECK2(SR_ERR_INVAL_ARG, reply, sysr_values_ctx); + ARG_CHECK2(SR_ERR_INVAL_ARG, address_ip, sysr_values_ctx); vc = 3; /* convenient functions such as this can be found in sysrepo/values.h */ @@ -516,8 +493,6 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ return rc; } - char * address_ip = sc_ntoa(reply->ip); - sr_val_build_xpath(&vals[0], "%s/openconfig-if-ip:ip", sysr_values_ctx->xpath_root); sr_val_set_str_data(&vals[0], SR_STRING_T, address_ip); @@ -525,7 +500,7 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ sr_val_build_xpath(&vals[1], "%s/openconfig-if-ip:prefix-length", sysr_values_ctx->xpath_root); vals[1].type = SR_UINT8_T; - vals[1].data.uint8_val = reply->prefix_length; + vals[1].data.uint8_val = prefix_len; sr_val_build_xpath(&vals[2], "%s/openconfig-if-ip:origin", sysr_values_ctx->xpath_root); @@ -537,35 +512,6 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ return SR_ERR_OK; } -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) -{ - ARG_CHECK2(VAPI_EINVAL, ctx, callback_ctx); - - sysr_values_ctx_t *dctx = callback_ctx; - - if (is_last) - { - assert (NULL == reply); - } - else - { - assert (NULL != reply); - - printf ("ip address dump entry:" - "\tsw_if_index[%u]" - "\tip[%s/%u]\n" - , reply->sw_if_index, sc_ntoa(reply->ip), - reply->prefix_length); - - openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_vapi_cb(reply, dctx); - } - - return VAPI_OK; -} - //TODO: for some arcane reason, this doesn't work int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_cb( const char *xpath, sr_val_t **values, size_t *values_cnt, @@ -574,14 +520,17 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ __attribute__((unused)) void *private_ctx) { sr_xpath_ctx_t state = {0}; - vapi_error_e rv; + int rc; char *tmp = NULL; char interface_name[XPATH_SIZE] = {0}; char subinterface_index[XPATH_SIZE] = {0}; char address_ip[XPATH_SIZE] = {0}; + u8 prefix_len; ARG_CHECK3(SR_ERR_INVAL_ARG, xpath, values, values_cnt); + SRP_LOG_INF_MSG("In oc-interfaces oc-ip"); + tmp = xpath_find_first_key(xpath, "name", &state); if (NULL == tmp) { SRP_LOG_ERR_MSG("interface_name not found."); @@ -613,23 +562,16 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ snprintf(dctx.xpath_root, XPATH_SIZE, "/openconfig-interfaces:interfaces/interface[name='%s']/subinterfaces/subinterface[index='%s']/openconfig-if-ip:ipv4/openconfig-if-ip:addresses/openconfig-if-ip:address[ip='%s']/openconfig-if-ip:state", interface_name, subinterface_index, address_ip); - sw_interface_details_query_t query = {0}; - sw_interface_details_query_set_name(&query, interface_name); - - if (!get_interface_id(&query)) - { + rc = ipv46_address_dump(interface_name, address_ip, &prefix_len, false); + if (!rc) { + SRP_LOG_ERR_MSG("ipv46_address_dump failed"); return SR_ERR_INVAL_ARG; } - vapi_msg_ip_address_dump *mp = vapi_alloc_ip_address_dump (g_vapi_ctx_instance); - mp->payload.sw_if_index = query.sw_interface_details.sw_if_index; - mp->payload.is_ipv6 = 0; - - rv = vapi_ip_address_dump(g_vapi_ctx_instance, mp, ip_address_dump_cb, &dctx); - if (VAPI_OK != rv) - { - SRP_LOG_ERR_MSG("VAPI call failed"); - return SR_ERR_INVAL_ARG; + rc = oc_dump_ip_helper(address_ip, prefix_len, &dctx); + if (!rc) { + SRP_LOG_ERR_MSG("oc_dump_ip_helper failed"); + return rc; } sr_xpath_recover(&state); @@ -639,6 +581,7 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ return SR_ERR_OK; } +// openconfig-interfaces:interfaces/interface/subinterfaces/subinterface/state int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_state_cb( const char *xpath, sr_val_t **values, size_t *values_cnt, __attribute__((unused)) uint64_t request_id, @@ -695,31 +638,7 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_state_ return SR_ERR_OK; } -// VAPI_RETVAL_CB(sw_interface_add_del_address); - -static int oi_int_ipv4_conf(const char *interface_name, - const char *address_ip, u8 prefix_length, - bool is_add) -{ - ARG_CHECK2(-1, interface_name, address_ip); - - sw_interface_details_query_t query = {0}; - sw_interface_details_query_set_name(&query, interface_name); - if (!get_interface_id(&query)) { - return 0; - } - - if (VAPI_OK != bin_api_sw_interface_add_del_address(query.sw_interface_details.sw_if_index, - is_add, address_ip, prefix_length)) - { - SRP_LOG_ERR_MSG("Call vapi_sw_interface_add_del_address."); - return -1; - } - - return 0; -} - -// XPATH: /openconfig-interfaces:interfaces/interface[name='%s']/subinterfaces/subinterface[index='%s']/oc-ip:ipv4/oc-ip:addresses/oc-ip:address[ip='%s']/oc-ip:config/ +// openconfig-interfaces:interfaces/interface[name='%s']/subinterfaces/subinterface[index='%s']/oc-ip:ipv4/oc-ip:addresses/oc-ip:address[ip='%s']/oc-ip:config/ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_config_cb( sr_session_ctx_t *ds, const char *xpath, sr_notif_event_t event, __attribute__((unused)) void *private_ctx) @@ -756,8 +675,7 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ return SR_ERR_OK; } - while (sr_get_change_next(ds, it, &oper, - &old_val, &new_val) == SR_ERR_OK) { + while (sr_get_change_next(ds, it, &oper, &old_val, &new_val) == SR_ERR_OK) { log_recv_oper(oper, "subtree_change_cb received"); @@ -795,8 +713,9 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ } if (ip_set && prefix_len_set) { - rc = oi_int_ipv4_conf(interface_name, address_ip, - prefix_len, true); + //add ipv4 + rc = ipv46_config_add_remove(interface_name, address_ip, + prefix_len, false , true); } break; @@ -822,16 +741,18 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ } if (old_ip_set && old_prefix_len_set) { - rc = oi_int_ipv4_conf(interface_name, old_address_ip, - old_prefix_len, false); + //remove ipv4 + rc = ipv46_config_add_remove(interface_name, old_address_ip, + old_prefix_len, false, false); if (0 != rc) { break; } } if (ip_set && prefix_len_set) { - rc = oi_int_ipv4_conf(interface_name, address_ip, - prefix_len, true); + //add ipv4 + rc = ipv46_config_add_remove(interface_name, address_ip, + prefix_len, false, true); } break; @@ -850,8 +771,9 @@ int openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ } if (old_ip_set && old_prefix_len_set) { - rc = oi_int_ipv4_conf(interface_name, old_address_ip, - old_prefix_len, false); + //remove ipv4 + rc = ipv46_config_add_remove(interface_name, old_address_ip, + old_prefix_len, false, false); } break; } @@ -894,7 +816,7 @@ const xpath_t oc_interfaces_xpaths[OC_INTERFACES_SIZE] = { .datastore = SR_DS_RUNNING, .cb.scb = openconfig_interfaces_interfaces_interface_config_cb, .private_ctx = NULL, - .priority = 0, + .priority = 98, //.opts = SR_SUBSCR_DEFAULT .opts = SR_SUBSCR_CTX_REUSE }, @@ -904,7 +826,7 @@ const xpath_t oc_interfaces_xpaths[OC_INTERFACES_SIZE] = { .datastore = SR_DS_RUNNING, .cb.gcb = openconfig_interfaces_interfaces_interface_state_cb, .private_ctx = NULL, - .priority = 0, + .priority = 98, .opts = SR_SUBSCR_CTX_REUSE }, { @@ -913,7 +835,7 @@ const xpath_t oc_interfaces_xpaths[OC_INTERFACES_SIZE] = { .datastore = SR_DS_RUNNING, .cb.gcb = openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_state_cb, .private_ctx = NULL, - .priority = 0, + .priority = 99, .opts = SR_SUBSCR_CTX_REUSE }, { @@ -922,7 +844,7 @@ const xpath_t oc_interfaces_xpaths[OC_INTERFACES_SIZE] = { .datastore = SR_DS_RUNNING, .cb.scb = openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_config_cb, .private_ctx = NULL, - .priority = 0, + .priority = 100, //.opts = SR_SUBSCR_DEFAULT .opts = SR_SUBSCR_CTX_REUSE }, @@ -932,7 +854,7 @@ const xpath_t oc_interfaces_xpaths[OC_INTERFACES_SIZE] = { .datastore = SR_DS_RUNNING, .cb.gcb = openconfig_interfaces_interfaces_interface_subinterfaces_subinterface_oc_ip_ipv4_oc_ip_addresses_oc_ip_address_oc_ip_state_cb, .private_ctx = NULL, - .priority = 0, + .priority = 100, .opts = SR_SUBSCR_CTX_REUSE } }; diff --git a/src/plugins/openconfig/openconfig_local_routing.c b/src/plugins/openconfig/openconfig_local_routing.c index 59574a2..39481e1 100644 --- a/src/plugins/openconfig/openconfig_local_routing.c +++ b/src/plugins/openconfig/openconfig_local_routing.c @@ -14,18 +14,17 @@ * limitations under the License. */ +#include <assert.h> +#include <string.h> + #include "openconfig_local_routing.h" + #include "sys_util.h" + #include "sc_vpp_comm.h" #include "sc_vpp_interface.h" #include "sc_vpp_ip.h" -#include <assert.h> -#include <string.h> -#include <sysrepo.h> -#include <sysrepo/xpath.h> -#include <sysrepo/values.h> - #define XPATH_SIZE 2000 int openconfig_local_routing_mod_cb( @@ -87,15 +86,13 @@ static int set_route(sr_session_ctx_t *sess, const char *index, return SR_ERR_INVAL_ARG; } - vapi_payload_ip_add_del_route_reply reply = {0}; - - vapi_error_e rv = bin_api_ip_add_del_route(&reply, prefix, mask, - next_hop, is_add, 0, interface); - if (VAPI_OK != rv || reply.retval > 0) { + rc = ipv46_config_add_del_route(prefix, mask, next_hop, is_add, 0, + interface); + if (!rc) { return SR_ERR_INVAL_ARG; } - return VAPI_OK; + return SR_ERR_OK; } // XPATH: /openconfig-local-routing:local-routes/static-routes/static[prefix='%s']/next-hops/next-hop[index='%s']/config/ diff --git a/src/plugins/openconfig/sys_util.h b/src/plugins/openconfig/sys_util.h index 6c227c3..d525066 100644 --- a/src/plugins/openconfig/sys_util.h +++ b/src/plugins/openconfig/sys_util.h @@ -19,6 +19,7 @@ #include <sysrepo.h> #include <sysrepo/xpath.h> +#include <sysrepo/plugins.h> #define XPATH_SIZE 2000 diff --git a/src/plugins/sc_model.h b/src/plugins/sc_model.h index ec4bff4..ad4055b 100644 --- a/src/plugins/sc_model.h +++ b/src/plugins/sc_model.h @@ -25,6 +25,10 @@ */ #include <sysrepo.h> +#include <sysrepo/xpath.h> +#include <sysrepo/values.h> +#include <sysrepo/plugins.h> + #include "sc_vpp_comm.h" //for ARG_CHECK only typedef enum { diff --git a/src/plugins/sc_plugins.c b/src/plugins/sc_plugins.c index e0db8ed..093939c 100644 --- a/src/plugins/sc_plugins.c +++ b/src/plugins/sc_plugins.c @@ -12,25 +12,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <vapi/vapi.h> -#include <vapi/vpe.api.vapi.h> -#include <vapi/interface.api.vapi.h> -#include <vapi/l2.api.vapi.h> -#include <vapi/ip.api.vapi.h> -#include <vapi/tapv2.api.vapi.h> -#include <vapi/ipsec.api.vapi.h> -#include <vapi/vxlan.api.vapi.h> -#include <vnet/interface.h> -#include <vnet/mpls/mpls_types.h> - -// Use VAPI macros to define symbols -DEFINE_VAPI_MSG_IDS_VPE_API_JSON; -DEFINE_VAPI_MSG_IDS_INTERFACE_API_JSON; -DEFINE_VAPI_MSG_IDS_L2_API_JSON; -DEFINE_VAPI_MSG_IDS_IP_API_JSON; -DEFINE_VAPI_MSG_IDS_TAPV2_API_JSON; -DEFINE_VAPI_MSG_IDS_IPSEC_API_JSON; -DEFINE_VAPI_MSG_IDS_VXLAN_API_JSON; #include "sc_plugins.h" #include "sc_model.h" @@ -41,13 +22,12 @@ DEFINE_VAPI_MSG_IDS_VXLAN_API_JSON; int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx) { - SC_INVOKE_BEGIN; plugin_main_t plugin_main; int rc; rc = sc_connect_vpp(); if (0 != rc) { - SC_LOG_ERR("vpp connect error , with return %d.", rc); + SRP_LOG_ERR("vpp connect error , with return %d.", rc); return SR_ERR_INTERNAL; } @@ -61,22 +41,18 @@ int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx) /* set subscription as our private context */ *private_ctx = plugin_main.subscription; - SC_INVOKE_END; return SR_ERR_OK; } void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx) { - SC_INVOKE_BEGIN; - /* subscription was set as our private context */ if (private_ctx != NULL) sr_unsubscribe(session, private_ctx); - SC_LOG_DBG_MSG("unload plugin ok."); + SRP_LOG_DBG_MSG("unload plugin ok."); sc_disconnect_vpp(); - SC_LOG_DBG_MSG("plugin disconnect vpp ok."); - SC_INVOKE_END; + SRP_LOG_DBG_MSG("plugin disconnect vpp ok."); } diff --git a/src/plugins/sc_plugins.h b/src/plugins/sc_plugins.h index bdf88d7..f405300 100644 --- a/src/plugins/sc_plugins.h +++ b/src/plugins/sc_plugins.h @@ -20,6 +20,32 @@ #include <sysrepo/values.h> #include <sysrepo/plugins.h> +#define ARG_CHECK(retval, arg) \ + do \ + { \ + if (NULL == (arg)) \ + { \ + SRP_LOG_ERR_MSG(#arg ":NULL pointer passed."); \ + 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) + //functions that sysrepo-plugin need int sr_plugin_init_cb(sr_session_ctx_t *session, void **private_ctx); void sr_plugin_cleanup_cb(sr_session_ctx_t *session, void *private_ctx); diff --git a/src/scvpp/src/CMakeLists.txt b/src/scvpp/src/CMakeLists.txt index c2a2c40..baa03ed 100644 --- a/src/scvpp/src/CMakeLists.txt +++ b/src/scvpp/src/CMakeLists.txt @@ -32,7 +32,7 @@ set(SCVPP_HEADERS set(CMAKE_C_FLAGS " -g -O0 -fpic -fPIC -std=gnu99 -Wl,-rpath-link=/usr/lib") # libraries to link with -set(LINK_LIBRARIES sysrepo vlibmemoryclient vapiclient vppapiclient svm vppinfra pthread rt dl) +set(LINK_LIBRARIES vlibmemoryclient vapiclient vppapiclient svm vppinfra pthread rt dl) # build instructions add_library(scvpp SHARED ${SCVPP_SOURCES}) diff --git a/src/scvpp/src/sc_vpp_comm.c b/src/scvpp/src/sc_vpp_comm.c index 32e0303..241b4ce 100644 --- a/src/scvpp/src/sc_vpp_comm.c +++ b/src/scvpp/src/sc_vpp_comm.c @@ -26,60 +26,53 @@ vapi_ctx_t g_vapi_ctx_instance = NULL; vapi_mode_e g_vapi_mode = VAPI_MODE_NONBLOCKING; -////////////////////////// int sc_connect_vpp() { - SC_INVOKE_BEGIN; - // SC_LOG_DBG("*******cts %p \n", g_vapi_ctx_instance); - 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) - { - SC_LOG_ERR("*connect %s failed with error code %d", APP_NAME, rv); - vapi_ctx_free(g_vapi_ctx_instance); - g_vapi_ctx_instance = NULL; - return -1; - } - SC_LOG_DBG("*connected %s ok", APP_NAME); - } - else - { - SC_LOG_DBG("connection %s keeping", APP_NAME); - } - SC_INVOKE_END; - return 0; + 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; + 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; + 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; } -bool sc_aton(const char *cp, u8 * buf, size_t length) +int sc_aton(const char *cp, u8 * buf, size_t length) { ARG_CHECK2(false, cp, buf); @@ -87,18 +80,14 @@ bool sc_aton(const char *cp, u8 * buf, size_t length) int ret = inet_aton(cp, &addr); if (0 == ret) - { - SC_LOG_DBG("error: ipv4 address %s", cp); - return false; - } + return -EINVAL; - if (sizeof(addr) > length) { - SC_LOG_DBG_MSG("error: small buffer"); - return false; - } + if (sizeof(addr) > length) + return -EINVAL; memcpy(buf, &addr, sizeof (addr)); - return true; + + return 0; } char* sc_ntoa(const u8 * buf) @@ -109,14 +98,3 @@ char* sc_ntoa(const u8 * buf) memcpy(&addr, buf, sizeof(addr)); return inet_ntoa(addr); } - -vapi_error_e -vapi_retval_cb(const char* func_name, i32 retval) -{ - if (retval) - { - SC_LOG_DBG("%s: bad retval=%d", func_name, retval); - } - - return VAPI_OK; -} diff --git a/src/scvpp/src/sc_vpp_comm.h b/src/scvpp/src/sc_vpp_comm.h index ceb3a80..649295d 100644 --- a/src/scvpp/src/sc_vpp_comm.h +++ b/src/scvpp/src/sc_vpp_comm.h @@ -16,16 +16,15 @@ #ifndef __SC_VPP_COMMM_H__ #define __SC_VPP_COMMM_H__ + +#include <errno.h> + #include <vapi/vapi.h> #include <vapi/vapi_common.h> #include <vapi/vpe.api.vapi.h> -DEFINE_VAPI_MSG_IDS_VPE_API_JSON; -#include <sysrepo.h> -#include <sysrepo/values.h> -#include <sysrepo/plugins.h> //for SC_LOG_DBG - -extern vapi_mode_e g_vapi_mode; +// 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 @@ -39,38 +38,12 @@ extern vapi_mode_e g_vapi_mode; #define VPP_IKEV2_PSK_LEN VPP_INTFC_NAME_LEN #define VPP_IKEV2_ID_LEN 32 -#ifndef SC_THIS_FUNC -#ifdef __FUNCTION__ -#define SC_THIS_FUNC __FUNCTION__ -#else -#define SC_THIS_FUNC __func__ -#endif -#endif - -#ifndef SC_NOLOG -#define SC_LOG_DBG SRP_LOG_DBG -#define SC_LOG_ERR SRP_LOG_ERR -#define SC_LOG_DBG_MSG SRP_LOG_DBG_MSG -#define SC_LOG_ERR_MSG SRP_LOG_ERR_MSG -#else -#define SC_LOG_DBG //printf -#define SC_LOG_DBG //SRP_LOG_DBG -#define SC_LOG_ERR //SRP_LOG_ERR -#define SC_LOG_DBG_MSG //SRP_LOG_DBG_MSG -#define SC_LOG_ERR_MSG //SRP_LOG_ERR_MSG -#endif - -#define SC_INVOKE_BEGIN SC_LOG_DBG("inovke %s bein.",SC_THIS_FUNC); -#define SC_INVOKE_END SC_LOG_DBG("inovke %s end,with return OK.",SC_THIS_FUNC); -#define SC_INVOKE_ENDX(...) SC_LOG_DBG("inovke %s end,with %s.",SC_THIS_FUNC, ##__VA_ARGS__) - /**********************************MACROS**********************************/ #define ARG_CHECK(retval, arg) \ do \ { \ if (NULL == (arg)) \ { \ - SC_LOG_ERR_MSG(#arg ":NULL pointer passed."); \ return (retval); \ } \ } \ @@ -91,43 +64,12 @@ extern vapi_mode_e g_vapi_mode; ARG_CHECK(retval, arg3); \ ARG_CHECK(retval, arg4) -/** - * when use tihs must fist DEFINE_VAPI_MSG_IDS_VXLAN_API_JSON - */ -#define SC_VPP_VAPI_RECV \ -do { \ - size_t size; \ - int recv_vapimsgid = -1; \ - rv = vapi_recv (g_vapi_ctx_instance, (void *) &resp, &size, 0, 0); \ - recv_vapimsgid = vapi_lookup_vapi_msg_id_t(g_vapi_ctx_instance, ntohs(resp->header._vl_msg_id) ); \ - if(recv_vapimsgid <= vapi_msg_id_get_next_index_reply \ - || recv_vapimsgid >= vapi_get_message_count ()) { \ - SC_LOG_DBG("***recv error msgid[%d] not in [0-%d) ,try again!***\n", \ - recv_vapimsgid, vapi_get_message_count ()); \ - } else { \ - SC_LOG_DBG("recv msgid [%d]\n", recv_vapimsgid); \ - break; \ - } \ - } while(1); - -#define SC_REGISTER_RPC_EVT_HANDLER(rpc_evt_handle) \ -do { \ - sr_error_t rc = rpc_evt_handle(session, &subscription); \ - if (SR_ERR_OK != rc) \ - { \ - SC_LOG_ERR("load plugin failed: %s", sr_strerror(rc)); \ - sr_unsubscribe(session, subscription); \ - SC_INVOKE_ENDX(sr_strerror(rc)); \ - return rc; \ - } \ -} while(0); - #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) \ { \ - return vapi_retval_cb(__FUNCTION__, reply->retval); \ + return reply->retval; \ } #define VAPI_COPY_CB(api_name) \ @@ -160,21 +102,18 @@ api_name##_cb (vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_last, #define VAPI_CALL(call_code) VAPI_CALL_MODE(call_code, g_vapi_mode) -//returns true on success -bool sc_aton(const char *cp, u8 * buf, size_t length); +int sc_aton(const char *cp, u8 * buf, size_t length); char * sc_ntoa(const u8 * buf); -vapi_error_e -vapi_retval_cb(const char* func_name, i32 retval); +/* + * VPP + */ + +extern vapi_ctx_t g_vapi_ctx_instance; +extern vapi_mode_e g_vapi_mode; -/////////////////////////// -//VPP接口 int sc_connect_vpp(); int sc_disconnect_vpp(); int sc_end_with(const char* str, const char* end); -extern vapi_ctx_t g_vapi_ctx_instance; -#endif //__SC_VPP_COMMM_H__ - - - +#endif //__SC_VPP_COMMM_H__ diff --git a/src/scvpp/src/sc_vpp_interface.c b/src/scvpp/src/sc_vpp_interface.c index 333ddd7..73b29ae 100644 --- a/src/scvpp/src/sc_vpp_interface.c +++ b/src/scvpp/src/sc_vpp_interface.c @@ -14,15 +14,18 @@ * limitations under the License. */ -#include "sc_vpp_interface.h" - #include <assert.h> #include <stdbool.h> + #include <vapi/l2.api.vapi.h> #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) @@ -36,66 +39,109 @@ void sw_interface_details_query_set_name(sw_interface_details_query_t * query, } 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) +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) { - sw_interface_details_query_t *dctx = callback_ctx; - assert(dctx); + vapi_payload_sw_interface_details *passed; - if (!dctx->interface_found) - { - if (is_last) - { - assert(NULL == reply); - } - else - { - assert(NULL != reply); - SC_LOG_DBG("Interface dump entry: [%u]: %s\n", reply->sw_if_index, - reply->interface_name); + ARG_CHECK(-EINVAL, callback_ctx); - 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; - } - } - } + 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; } -bool get_interface_id(sw_interface_details_query_t * sw_interface_details_query) +static vapi_error_e +bin_api_sw_interface_dump(vapi_payload_sw_interface_details *details) { - ARG_CHECK(false, sw_interface_details_query); - sw_interface_details_query->interface_found = false; + vapi_msg_sw_interface_dump *mp; + vapi_error_e rv; - vapi_msg_sw_interface_dump *mp = vapi_alloc_sw_interface_dump (g_vapi_ctx_instance); + 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); - 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, sw_interface_dump_cb, details)); + if (!rv) + return -EINVAL; - vapi_error_e rv; - VAPI_CALL(vapi_sw_interface_dump(g_vapi_ctx_instance, mp, get_interface_id_cb, sw_interface_details_query)); + return rv; +} - if (VAPI_OK != rv) { - SC_LOG_DBG_MSG("vapi_sw_interface_dump"); - return false; +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) +{ + 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 ); } - if (!sw_interface_details_query->interface_found) - SC_LOG_ERR("interface name %s: Can't find index", - sw_interface_details_query->sw_interface_details.interface_name); + vpp_interface_t * iface = &dctx->intfcArray[dctx->num_ifs]; - return sw_interface_details_query->interface_found; + iface->sw_if_index = reply->sw_if_index; + strncpy(iface->interface_name, 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_name_cb (struct vapi_ctx_s *ctx, void *callback_ctx, +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) { @@ -110,10 +156,10 @@ get_interface_name_cb (struct vapi_ctx_s *ctx, void *callback_ctx, } else { - assert(reply && dctx); - SC_LOG_DBG("Interface dump entry: [%u]: %s\n", reply->sw_if_index, reply->interface_name); + assert(NULL != reply); - if (dctx->sw_interface_details.sw_if_index == reply->sw_if_index) + 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; @@ -124,74 +170,48 @@ get_interface_name_cb (struct vapi_ctx_s *ctx, void *callback_ctx, return VAPI_OK; } -bool get_interface_name(sw_interface_details_query_t * sw_interface_details_query) +// 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); - vapi_error_e rv; - VAPI_CALL(vapi_sw_interface_dump (g_vapi_ctx_instance, mp, get_interface_name_cb, sw_interface_details_query)); + 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)); - if (VAPI_OK != rv) { - SC_LOG_DBG_MSG("vapi_sw_interface_dump"); + 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; - } - - if (!sw_interface_details_query->interface_found) - SC_LOG_ERR("interface index %u: Can't find name", - sw_interface_details_query->sw_interface_details.sw_if_index); return sw_interface_details_query->interface_found; } -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) +int get_interface_name(sw_interface_details_query_t *query) { - if (is_last) - { - assert (NULL == reply); - } - else - { - assert (NULL != reply); - SC_LOG_DBG("Interface dump entry: [%u]: %s\n", reply->sw_if_index, - reply->interface_name); - } + vapi_error_e rv; - return VAPI_OK; -} + ARG_CHECK(-EINVAL, query); -vapi_error_e bin_api_sw_interface_dump(const char * interface_name) -{ - vapi_msg_sw_interface_dump *mp = vapi_alloc_sw_interface_dump (g_vapi_ctx_instance); - assert(NULL != mp); + query->interface_found = false; - if (NULL != interface_name) - { - mp->payload.name_filter_valid = true; - strncpy((char *)mp->payload.name_filter, interface_name, sizeof(mp->payload.name_filter)); - } - else - { - mp->payload.name_filter_valid = false; - memset(mp->payload.name_filter, 0, sizeof (mp->payload.name_filter)); - } + rv = bin_api_sw_interface_dump(&query->sw_interface_details); + if (rv == VAPI_OK) + query->interface_found = true; - vapi_error_e rv; - VAPI_CALL(vapi_sw_interface_dump (g_vapi_ctx_instance, mp, sw_interface_dump_cb, NULL)); - - return rv; + return query->interface_found; } - VAPI_RETVAL_CB(sw_interface_set_flags); -vapi_error_e bin_api_sw_interface_set_flags(uint32_t if_index, uint8_t up) +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); @@ -207,46 +227,42 @@ vapi_error_e bin_api_sw_interface_set_flags(uint32_t if_index, uint8_t up) VAPI_RETVAL_CB(sw_interface_set_l2_bridge); -vapi_error_e bin_api_sw_interface_set_l2_bridge(u32 bd_id, u32 rx_sw_if_index, - bool enable) +//set interface l2 bridge <interface> <bridge-domain-id> [bvi|uu-fwd] [shg] +static vapi_error_e +bin_api_sw_interface_set_l2_bridge(u32 bd_id, u32 rx_sw_if_index, bool enable) { - vapi_msg_sw_interface_set_l2_bridge *mp = - vapi_alloc_sw_interface_set_l2_bridge (g_vapi_ctx_instance); + vapi_msg_sw_interface_set_l2_bridge *mp; + vapi_error_e rv; + + mp = vapi_alloc_sw_interface_set_l2_bridge (g_vapi_ctx_instance); assert(NULL != mp); - //set interface l2 bridge <interface> <bridge-domain-id> [bvi|uu-fwd] [shg] - /* - typedef struct __attribute__ ((__packed__)) { - u32 rx_sw_if_index; - u32 bd_id; - vapi_enum_l2_port_type port_type; - u8 shg; - u8 enable; - } vapi_payload_sw_interface_set_l2_bridge; - */ + mp->payload.enable = enable; mp->payload.bd_id = bd_id; mp->payload.rx_sw_if_index = rx_sw_if_index; - vapi_error_e rv; VAPI_CALL(vapi_sw_interface_set_l2_bridge (g_vapi_ctx_instance, mp, sw_interface_set_l2_bridge_cb, NULL)); return rv; } -VAPI_COPY_CB(create_loopback) - -vapi_error_e bin_api_create_loopback(vapi_payload_create_loopback_reply *reply) +int interface_enable(const char *interface_name, const bool enable) { - ARG_CHECK(VAPI_EINVAL, reply); + ARG_CHECK(-1, interface_name); - vapi_msg_create_loopback *mp = vapi_alloc_create_loopback (g_vapi_ctx_instance); - assert(NULL != mp); + int rc = 0; + sw_interface_details_query_t query = {0}; + sw_interface_details_query_set_name(&query, interface_name); - //mp->payload.mac_address = + rc = get_interface_id(&query); + if (!rc) + return -1; - vapi_error_e rv; - VAPI_CALL(vapi_create_loopback (g_vapi_ctx_instance, mp, create_loopback_cb, reply)); + rc = bin_api_sw_interface_set_flags(query.sw_interface_details.sw_if_index, + enable); + if (VAPI_OK != rc) + return -1; - return rv; + return 0; } diff --git a/src/scvpp/src/sc_vpp_interface.h b/src/scvpp/src/sc_vpp_interface.h index 45cc2ef..32b61bc 100644 --- a/src/scvpp/src/sc_vpp_interface.h +++ b/src/scvpp/src/sc_vpp_interface.h @@ -17,36 +17,45 @@ #ifndef __BAPI_INTERFACE_H__ #define __BAPI_INTERFACE_H__ - #include <vapi/interface.api.vapi.h> +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 bool get_interface_id(sw_interface_details_query_t * sw_interface_details_query); +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 bool get_interface_name(sw_interface_details_query_t * sw_interface_details_query); - - - -extern vapi_error_e bin_api_sw_interface_dump(const char * interface_name); - -extern vapi_error_e bin_api_sw_interface_set_flags(u32 if_index, u8 up); - -extern vapi_error_e bin_api_sw_interface_set_l2_bridge(u32 bd_id, - u32 rx_sw_if_index, - bool enable); - -extern vapi_error_e bin_api_create_loopback( - vapi_payload_create_loopback_reply *reply); - +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 index a09bf3a..77e79fb 100644 --- a/src/scvpp/src/sc_vpp_ip.c +++ b/src/scvpp/src/sc_vpp_ip.c @@ -21,47 +21,52 @@ #include <assert.h> +// Use VAPI macros to define symbols DEFINE_VAPI_MSG_IDS_IP_API_JSON VAPI_RETVAL_CB(sw_interface_add_del_address); -vapi_error_e -bin_api_sw_interface_add_del_address(u32 sw_if_index, bool is_add, - const char * ip_address, u8 address_length) +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); - vapi_msg_sw_interface_add_del_address *mp = - vapi_alloc_sw_interface_add_del_address (g_vapi_ctx_instance); + 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 = 0; + 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))) + if (sc_aton(ip_address, mp->payload.address, sizeof(mp->payload.address))) return VAPI_EINVAL; - vapi_error_e rv; - VAPI_CALL(vapi_sw_interface_add_del_address (g_vapi_ctx_instance, mp, sw_interface_add_del_address_cb, NULL)); + VAPI_CALL(vapi_sw_interface_add_del_address(g_vapi_ctx_instance, mp, + sw_interface_add_del_address_cb, NULL)); return rv; } -vapi_error_e +static vapi_error_e bin_api_sw_interface_del_all_address(u32 sw_if_index) { - vapi_msg_sw_interface_add_del_address *mp = - vapi_alloc_sw_interface_add_del_address (g_vapi_ctx_instance); + vapi_msg_sw_interface_add_del_address *mp; + vapi_error_e rv; + + 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 = 0; mp->payload.del_all = 1; - vapi_error_e rv; - VAPI_CALL(vapi_sw_interface_add_del_address (g_vapi_ctx_instance, mp, + VAPI_CALL(vapi_sw_interface_add_del_address(g_vapi_ctx_instance, mp, sw_interface_add_del_address_cb, NULL)); return rv; @@ -69,28 +74,23 @@ bin_api_sw_interface_del_all_address(u32 sw_if_index) VAPI_COPY_CB(ip_add_del_route) -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) +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) { - ARG_CHECK4(VAPI_EINVAL, reply, dst_address, next_hop, interface_name); + sw_interface_details_query_t query = {0}; + vapi_msg_ip_add_del_route *mp; - SC_LOG_DBG("Interface: %s", interface_name); + ARG_CHECK4(VAPI_EINVAL, reply, dst_address, next_hop, interface_name); - sw_interface_details_query_t query = {0}; sw_interface_details_query_set_name(&query, interface_name); if (!get_interface_id(&query)) - { return VAPI_EINVAL; - } - vapi_msg_ip_add_del_route *mp = vapi_alloc_ip_add_del_route (g_vapi_ctx_instance, 1); + 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 @@ -100,12 +100,11 @@ vapi_error_e bin_api_ip_add_del_route( 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; - SC_LOG_DBG("Interface: %s, index: %d", interface_name, query.sw_interface_details.sw_if_index); - if (!sc_aton(dst_address, mp->payload.dst_address, + 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, + if (sc_aton(next_hop, mp->payload.next_hop_address, sizeof(mp->payload.next_hop_address))) return VAPI_EINVAL; @@ -116,9 +115,8 @@ vapi_error_e bin_api_ip_add_del_route( } static vapi_error_e -ip_fib_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx, - vapi_error_e rv, bool is_last, - vapi_payload_ip_fib_details * reply) +ip_fib_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, + bool is_last, vapi_payload_ip_fib_details * reply) { if (is_last) { @@ -139,8 +137,6 @@ ip_fib_dump_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_type_fib_path path[0]; } vapi_payload_ip_fib_details; */ - printf ("ip_fib_dump_cb table %u details: network %s/%u\n", - reply->table_id, sc_ntoa(reply->address), reply->address_length); for (u32 i = 0; i < reply->count; ++i) { @@ -175,14 +171,13 @@ b+>│494 s = format (s, "%U", format_ip46_address, */ - printf("\tnext hop: %s\n", sc_ntoa(reply->path[i].next_hop)); } } return VAPI_OK; } -vapi_error_e +static vapi_error_e bin_api_ip_fib_dump() { vapi_msg_ip_fib_dump *mp = vapi_alloc_ip_fib_dump (g_vapi_ctx_instance); @@ -199,7 +194,7 @@ bin_api_ip_fib_dump() VAPI_RETVAL_CB(ip_table_add_del) -vapi_error_e +static vapi_error_e bin_api_table_add_del(u8 is_add, u32 table_id) { vapi_msg_ip_table_add_del *mp = vapi_alloc_ip_table_add_del(g_vapi_ctx_instance); @@ -214,9 +209,111 @@ bin_api_table_add_del(u8 is_add, u32 table_id) 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) +{ + 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, false, &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 index 0940fe8..a9f19d4 100644 --- a/src/scvpp/src/sc_vpp_ip.h +++ b/src/scvpp/src/sc_vpp_ip.h @@ -21,26 +21,16 @@ #include <vapi/interface.api.vapi.h> #include <vapi/ip.api.vapi.h> +/* 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 vapi_error_e bin_api_sw_interface_add_del_address( - u32 sw_if_index, - bool is_add, - const char * ip_address, - u8 address_length); +extern int ipv46_config_add_remove(const char *if_name, const char *addr, + uint8_t prefix, bool is_ipv6, bool add); -extern vapi_error_e bin_api_sw_interface_del_all_address(u32 sw_if_index); - -//ip_add_del_route -extern vapi_error_e bin_api_ip_add_del_route( - vapi_payload_ip_add_del_route_reply * reply, - const char* dst_address, - u8 dst_address_length, - const char* next_address, - u8 is_add, - u32 table_id, - const char *interface); - -extern vapi_error_e bin_api_ip_fib_dump(); -extern vapi_error_e bin_api_table_add_del(u8 is_add, u32 table_id); +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__ */ |