From adc56bc5ddcdf947864d982cda809588b7ccd8bc Mon Sep 17 00:00:00 2001 From: jackiechen1985 Date: Wed, 3 Jul 2019 17:07:56 +0800 Subject: Enable mutil-thread VPP API calling support. - Lock/Unlock before and after invoke VPP API; - Introduce sc_vpp_main_t for warpping VPP API context, mode and pid; Change-Id: If1b1c040cb4723ecc4e88c5060c0380de7c715c0 Signed-off-by: jackiechen1985 --- src/scvpp/inc/scvpp/comm.h | 30 +++++++++--- src/scvpp/src/comm.c | 114 +++++++++++++++++++++++++++++++-------------- src/scvpp/src/interface.c | 16 ++++--- src/scvpp/src/ip.c | 16 +++---- src/scvpp/src/nat.c | 28 +++++------ src/scvpp/src/v3po.c | 8 ++-- 6 files changed, 139 insertions(+), 73 deletions(-) (limited to 'src/scvpp') diff --git a/src/scvpp/inc/scvpp/comm.h b/src/scvpp/inc/scvpp/comm.h index 687db5d..a7bac5d 100644 --- a/src/scvpp/inc/scvpp/comm.h +++ b/src/scvpp/inc/scvpp/comm.h @@ -112,6 +112,7 @@ api_name##_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, \ #define VAPI_CALL_MODE(call_code, vapi_mode) \ do \ { \ + pthread_mutex_lock (&sc_vpp_main.vapi_lock); \ if (VAPI_MODE_BLOCKING == (vapi_mode)) \ { \ rv = call_code; \ @@ -120,13 +121,14 @@ api_name##_cb (struct vapi_ctx_s *ctx, void *callback_ctx, vapi_error_e rv, \ { \ while (VAPI_EAGAIN == (rv = call_code)); \ if (rv != VAPI_OK) { /* try once more to get reply */ \ - rv = vapi_dispatch (g_vapi_ctx); \ + rv = vapi_dispatch (sc_vpp_main.vapi_ctx); \ } \ } \ + pthread_mutex_unlock (&sc_vpp_main.vapi_lock); \ } \ while (0) -#define VAPI_CALL(call_code) VAPI_CALL_MODE(call_code, g_vapi_mode) +#define VAPI_CALL(call_code) VAPI_CALL_MODE(call_code, sc_vpp_main.vapi_mode) struct elt { void *data; //vapi_payload structure @@ -200,7 +202,7 @@ api_name##_all_cb(vapi_ctx_t ctx, void *caller_ctx, vapi_error_e rv, bool is_las #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); @@ -219,11 +221,25 @@ uint32_t hardntohlu32(uint8_t host[4]); * VPP */ -extern vapi_ctx_t g_vapi_ctx; -extern vapi_mode_e g_vapi_mode; +typedef struct sc_vpp_main_t { + /* VAPI context */ + vapi_ctx_t vapi_ctx; + + /* VAPI calling mode: VAPI_MODE_BLOCKING, VAPI_MODE_NONBLOCKING */ + vapi_mode_e vapi_mode; + + /* Mutex for keeping atomicity when calling VAPI */ + pthread_mutex_t vapi_lock; + + /* pid of VPP */ + pid_t pid; +} sc_vpp_main_t; + +extern sc_vpp_main_t sc_vpp_main; -int sc_connect_vpp(); -int sc_disconnect_vpp(); +sc_vpp_main_t *sc_connect_vpp(); +void sc_disconnect_vpp(); +pid_t sc_get_vpp_pid(); int sc_end_with(const char* str, const char* end); #endif //__SC_VPP_COMMM_H__ diff --git a/src/scvpp/src/comm.c b/src/scvpp/src/comm.c index b679880..11ed8a9 100644 --- a/src/scvpp/src/comm.c +++ b/src/scvpp/src/comm.c @@ -14,51 +14,97 @@ */ #include -#include -#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; +sc_vpp_main_t sc_vpp_main = { + .vapi_ctx = NULL, + .vapi_mode = VAPI_MODE_BLOCKING, + .pid = 0 +}; -int sc_connect_vpp() +sc_vpp_main_t *sc_connect_vpp() { - if (g_vapi_ctx == NULL) - { - vapi_error_e rv = vapi_ctx_alloc(&g_vapi_ctx); - if (rv != VAPI_OK) { - g_vapi_ctx = NULL; - return -1; - } - 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; - } - } + vapi_error_e rv; + + if (sc_vpp_main.vapi_ctx == NULL) { + if ((rv = vapi_ctx_alloc(&sc_vpp_main.vapi_ctx)) != VAPI_OK) { + return NULL; + } + + if ((rv = + vapi_connect(sc_vpp_main.vapi_ctx, APP_NAME, NULL, + MAX_OUTSTANDING_REQUESTS, RESPONSE_QUEUE_SIZE, + sc_vpp_main.vapi_mode, true)) != VAPI_OK) { + vapi_ctx_free(sc_vpp_main.vapi_ctx); + sc_vpp_main.vapi_ctx = NULL; + return NULL; + } + } + + sc_vpp_main.pid = sc_get_vpp_pid(); + pthread_mutex_init(&sc_vpp_main.vapi_lock, NULL); + return &sc_vpp_main; +} - return 0; +void sc_disconnect_vpp() +{ + if (NULL != sc_vpp_main.vapi_ctx) { + pthread_mutex_destroy(&sc_vpp_main.vapi_lock); + sc_vpp_main.pid = 0; + vapi_disconnect(sc_vpp_main.vapi_ctx); + vapi_ctx_free(sc_vpp_main.vapi_ctx); + sc_vpp_main.vapi_ctx = NULL; + } } -int sc_disconnect_vpp() +/* get vpp pid in system */ +pid_t sc_get_vpp_pid() { - if (NULL != g_vapi_ctx) - { - vapi_disconnect(g_vapi_ctx); - vapi_ctx_free(g_vapi_ctx); - g_vapi_ctx = NULL; - } - return 0; + DIR *dir; + struct dirent *ptr; + FILE *fp; + char cmdline_path[PATH_MAX]; + char cmdline_data[PATH_MAX]; + const char vpp_path[] = "/usr/bin/vpp"; + + dir = opendir("/proc"); + pid_t pid = 0; + /* read vpp pid file in proc, return pid of vpp */ + if (NULL != dir) { + while (NULL != (ptr = readdir(dir))) { + if ((0 == strcmp(ptr->d_name, ".")) + || (0 == strcmp(ptr->d_name, ".."))) { + continue; + } + + if (DT_DIR != ptr->d_type) { + continue; + } + + sprintf(cmdline_path, "/proc/%s/cmdline", ptr->d_name); + fp = fopen(cmdline_path, "r"); + + if (NULL != fp) { + fread(cmdline_data, 1, sizeof(vpp_path), fp); + cmdline_data[sizeof(vpp_path) - 1] = '\0'; + + if (cmdline_data == + strstr(cmdline_data, "/usr/bin/vpp")) { + pid = atoi(ptr->d_name); + } + + fclose(fp); + } + } + closedir(dir); + } + + return pid; } int sc_end_with(const char* str, const char* end) diff --git a/src/scvpp/src/interface.c b/src/scvpp/src/interface.c index 3a30dc5..b6b1216 100644 --- a/src/scvpp/src/interface.c +++ b/src/scvpp/src/interface.c @@ -34,6 +34,10 @@ sw_interface_dump_cb(struct vapi_ctx_s *ctx, void *callback_ctx, vapi_payload_sw_interface_details *passed; + if (is_last) { + return VAPI_OK; + } + ARG_CHECK2(VAPI_EINVAL, callback_ctx, reply); //copy @@ -50,14 +54,14 @@ 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); + mp = vapi_alloc_sw_interface_dump(sc_vpp_main.vapi_ctx); assert(NULL != mp); /* Dump a specific interfaces */ mp->payload.name_filter_valid = true; strncpy((char *)mp->payload.name_filter, iface_name, IFACE_SUBSTR); - VAPI_CALL(vapi_sw_interface_dump(g_vapi_ctx, mp, + VAPI_CALL(vapi_sw_interface_dump(sc_vpp_main.vapi_ctx, mp, sw_interface_dump_cb, details)); if (rv != VAPI_OK) return -SCVPP_EINVAL; @@ -111,13 +115,13 @@ struct elt* interface_dump_all() vapi_msg_sw_interface_dump *mp; vapi_error_e rv; - mp = vapi_alloc_sw_interface_dump(g_vapi_ctx); + mp = vapi_alloc_sw_interface_dump(sc_vpp_main.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, + VAPI_CALL(vapi_sw_interface_dump(sc_vpp_main.vapi_ctx, mp, sw_interface_all_cb, &stack)); if (VAPI_OK != rv) return NULL; @@ -140,12 +144,12 @@ int interface_enable(const char *interface_name, const bool enable) if (rc != 0) return -SCVPP_NOT_FOUND; - mp = vapi_alloc_sw_interface_set_flags(g_vapi_ctx); + mp = vapi_alloc_sw_interface_set_flags(sc_vpp_main.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, + VAPI_CALL(vapi_sw_interface_set_flags(sc_vpp_main.vapi_ctx, mp, sw_interface_set_flags_cb, NULL)); if (VAPI_OK != rv) return -SCVPP_EINVAL; diff --git a/src/scvpp/src/ip.c b/src/scvpp/src/ip.c index f2234f2..ec44f64 100644 --- a/src/scvpp/src/ip.c +++ b/src/scvpp/src/ip.c @@ -36,7 +36,7 @@ bin_api_sw_interface_add_del_address(u32 sw_if_index, bool is_add, bool is_ipv6, ARG_CHECK(VAPI_EINVAL, ip_address); - mp = vapi_alloc_sw_interface_add_del_address(g_vapi_ctx); + mp = vapi_alloc_sw_interface_add_del_address(sc_vpp_main.vapi_ctx); assert(NULL != mp); mp->payload.sw_if_index = sw_if_index; @@ -47,7 +47,7 @@ bin_api_sw_interface_add_del_address(u32 sw_if_index, bool is_add, bool is_ipv6, 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, + VAPI_CALL(vapi_sw_interface_add_del_address(sc_vpp_main.vapi_ctx, mp, sw_interface_add_del_address_cb, NULL)); return rv; @@ -72,7 +72,7 @@ bin_api_ip_add_del_route(vapi_payload_ip_add_del_route_reply * reply, if (!next_interface && !next_hop) return VAPI_EINVAL; - mp = vapi_alloc_ip_add_del_route(g_vapi_ctx, 1); + mp = vapi_alloc_ip_add_del_route(sc_vpp_main.vapi_ctx, 1); assert(NULL != mp); if (next_interface) { @@ -92,7 +92,7 @@ bin_api_ip_add_del_route(vapi_payload_ip_add_del_route_reply * reply, 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, + VAPI_CALL(vapi_ip_add_del_route(sc_vpp_main.vapi_ctx, mp, ip_add_del_route_cb, reply)); return rv; @@ -123,13 +123,13 @@ bin_api_ip_address_dump(u32 sw_if_index, bool is_ipv6, vapi_msg_ip_address_dump *mp; vapi_error_e rv; - mp = vapi_alloc_ip_address_dump(g_vapi_ctx); + mp = vapi_alloc_ip_address_dump(sc_vpp_main.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, + VAPI_CALL(vapi_ip_address_dump(sc_vpp_main.vapi_ctx, mp, ip_address_dump_cb, dctx)); if (rv != VAPI_OK) return rv; @@ -159,10 +159,10 @@ struct elt* ipv4_fib_dump_all() vapi_msg_ip_fib_dump *mp; vapi_error_e rv; - mp = vapi_alloc_ip_fib_dump(g_vapi_ctx); + mp = vapi_alloc_ip_fib_dump(sc_vpp_main.vapi_ctx); assert(mp != NULL); - VAPI_CALL(vapi_ip_fib_dump(g_vapi_ctx, mp, ip_fib_all_cb, &stack)); + VAPI_CALL(vapi_ip_fib_dump(sc_vpp_main.vapi_ctx, mp, ip_fib_all_cb, &stack)); if(VAPI_OK != rv) return NULL; diff --git a/src/scvpp/src/nat.c b/src/scvpp/src/nat.c index 1ff59f3..4519c3e 100644 --- a/src/scvpp/src/nat.c +++ b/src/scvpp/src/nat.c @@ -55,10 +55,10 @@ bin_api_nat44_interface_dump(vapi_payload_nat44_interface_details *reply) ARG_CHECK(VAPI_EINVAL, reply); - mp = vapi_alloc_nat44_interface_dump(g_vapi_ctx); + mp = vapi_alloc_nat44_interface_dump(sc_vpp_main.vapi_ctx); assert(NULL != mp); - VAPI_CALL(vapi_nat44_interface_dump(g_vapi_ctx, mp, + VAPI_CALL(vapi_nat44_interface_dump(sc_vpp_main.vapi_ctx, mp, nat44_interface_dump_cb, reply)); return rv; @@ -75,12 +75,12 @@ bin_api_nat44_add_del_interface_addr( ARG_CHECK(VAPI_EINVAL, msg); - mp = vapi_alloc_nat44_add_del_interface_addr(g_vapi_ctx); + mp = vapi_alloc_nat44_add_del_interface_addr(sc_vpp_main.vapi_ctx); assert(NULL != mp); mp->payload = *msg; - VAPI_CALL(vapi_nat44_add_del_interface_addr(g_vapi_ctx, mp, + VAPI_CALL(vapi_nat44_add_del_interface_addr(sc_vpp_main.vapi_ctx, mp, nat44_add_del_interface_addr_cb, NULL)); @@ -98,13 +98,13 @@ bin_api_nat44_add_del_addr_range( ARG_CHECK(VAPI_EINVAL, range); - mp = vapi_alloc_nat44_add_del_address_range(g_vapi_ctx); + mp = vapi_alloc_nat44_add_del_address_range(sc_vpp_main.vapi_ctx); assert(NULL != mp); mp->payload = *range; - VAPI_CALL(vapi_nat44_add_del_address_range(g_vapi_ctx, mp, + VAPI_CALL(vapi_nat44_add_del_address_range(sc_vpp_main.vapi_ctx, mp, nat44_add_del_address_range_cb, NULL)); @@ -122,12 +122,12 @@ bin_api_nat44_add_del_static_mapping( ARG_CHECK(VAPI_EINVAL, msg); - mp = vapi_alloc_nat44_add_del_static_mapping(g_vapi_ctx); + mp = vapi_alloc_nat44_add_del_static_mapping(sc_vpp_main.vapi_ctx); assert(NULL != mp); mp->payload = *msg; - VAPI_CALL(vapi_nat44_add_del_static_mapping(g_vapi_ctx, mp, + VAPI_CALL(vapi_nat44_add_del_static_mapping(sc_vpp_main.vapi_ctx, mp, nat44_add_del_static_mapping_cb, NULL)); @@ -163,10 +163,10 @@ bin_api_nat44_static_mapping_dump( ARG_CHECK(VAPI_EINVAL, reply); - msg = vapi_alloc_nat44_static_mapping_dump(g_vapi_ctx); + msg = vapi_alloc_nat44_static_mapping_dump(sc_vpp_main.vapi_ctx); assert(NULL != msg); - VAPI_CALL(vapi_nat44_static_mapping_dump(g_vapi_ctx, msg, + VAPI_CALL(vapi_nat44_static_mapping_dump(sc_vpp_main.vapi_ctx, msg, nat44_static_mapping_dump_cb, reply)); @@ -183,13 +183,13 @@ static vapi_error_e bin_api_nat44_forwarding_enable_disable( ARG_CHECK(VAPI_EINVAL, msg); - mp = vapi_alloc_nat44_forwarding_enable_disable(g_vapi_ctx); + mp = vapi_alloc_nat44_forwarding_enable_disable(sc_vpp_main.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)); + sc_vpp_main.vapi_ctx, mp, nat44_forwarding_enable_disable_cb, NULL)); return rv; } @@ -204,12 +204,12 @@ bin_api_nat_set_workers(const vapi_payload_nat_set_workers *msg) ARG_CHECK(VAPI_EINVAL, msg); - mp = vapi_alloc_nat_set_workers(g_vapi_ctx); + mp = vapi_alloc_nat_set_workers(sc_vpp_main.vapi_ctx); assert(NULL != mp); mp->payload = *msg; - VAPI_CALL(vapi_nat_set_workers(g_vapi_ctx, mp, nat_set_workers_cb, NULL)); + VAPI_CALL(vapi_nat_set_workers(sc_vpp_main.vapi_ctx, mp, nat_set_workers_cb, NULL)); return rv; } diff --git a/src/scvpp/src/v3po.c b/src/scvpp/src/v3po.c index bdb15e1..8fd83ba 100644 --- a/src/scvpp/src/v3po.c +++ b/src/scvpp/src/v3po.c @@ -38,12 +38,12 @@ 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); + mp = vapi_alloc_tap_delete_v2(sc_vpp_main.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)); + VAPI_CALL(vapi_tap_delete_v2(sc_vpp_main.vapi_ctx, mp, tap_delete_v2_cb, NULL)); if (rv != VAPI_OK) return -rv; @@ -76,12 +76,12 @@ 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); + mp = vapi_alloc_tap_create_v2(sc_vpp_main.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)); + VAPI_CALL(vapi_tap_create_v2(sc_vpp_main.vapi_ctx, mp, tap_create_v2_cb, NULL)); if (rv != VAPI_OK) return -EAGAIN; -- cgit 1.2.3-korg