diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/hs_apps/http_client.c | 362 | ||||
-rw-r--r-- | src/vcl/ldp.c | 26 | ||||
-rw-r--r-- | src/vnet/fib/ip4_fib.c | 5 | ||||
-rw-r--r-- | src/vnet/pg/pg.h | 51 | ||||
-rw-r--r-- | src/vpp-api/python/setup.py | 2 | ||||
-rw-r--r-- | src/vpp-api/python/vpp_papi/__init__.py | 9 | ||||
-rw-r--r-- | src/vpp-api/python/vpp_papi/vpp_papi.py | 9 |
7 files changed, 296 insertions, 168 deletions
diff --git a/src/plugins/hs_apps/http_client.c b/src/plugins/hs_apps/http_client.c index 05a87ec7de8..a86bf1f3db3 100644 --- a/src/plugins/hs_apps/http_client.c +++ b/src/plugins/hs_apps/http_client.c @@ -23,9 +23,19 @@ typedef struct typedef struct { + u64 request_count; + f64 start, end; + f64 elapsed_time; +} hc_stats_t; + +typedef struct +{ hc_session_t *sessions; u32 thread_index; vlib_main_t *vlib_main; + u8 *headers_buf; + http_header_t *req_headers; + http_msg_t msg; } hc_worker_t; typedef struct @@ -36,7 +46,6 @@ typedef struct u8 *uri; session_endpoint_cfg_t connect_sep; u8 *target; - u8 *headers_buf; u8 *data; u64 data_offset; hc_worker_t *wrk; @@ -50,6 +59,9 @@ typedef struct bool verbose; f64 timeout; http_req_method_t req_method; + u64 repeat_count; + f64 duration; + bool repeat; } hc_main_t; typedef enum @@ -57,9 +69,12 @@ typedef enum HC_CONNECT_FAILED = 1, HC_TRANSPORT_CLOSED, HC_REPLY_RECEIVED, + HC_GENERIC_ERR, + HC_REPEAT_DONE, } hc_cli_signal_t; static hc_main_t hc_main; +static hc_stats_t hc_stats; static inline hc_worker_t * hc_worker_get (u32 thread_index) @@ -95,39 +110,94 @@ hc_session_alloc (hc_worker_t *wrk) } static int -hc_session_connected_callback (u32 app_index, u32 hc_session_index, - session_t *s, session_error_t err) +hc_request (session_t *s, session_error_t err) { hc_main_t *hcm = &hc_main; - hc_session_t *hc_session, *new_hc_session; - hc_worker_t *wrk; - http_msg_t msg; u64 to_send; u32 n_enq; u8 n_segs; int rv; - http_header_ht_t *header; - http_header_t *req_headers = 0; - u32 new_hc_index; + hc_worker_t *wrk = hc_worker_get (s->thread_index); + + if (hcm->use_ptr) + { + uword target = pointer_to_uword (hcm->target); + uword headers = pointer_to_uword (wrk->headers_buf); + uword body = pointer_to_uword (hcm->data); + svm_fifo_seg_t segs[4] = { + { (u8 *) &wrk->msg, sizeof (wrk->msg) }, + { (u8 *) &target, sizeof (target) }, + { (u8 *) &headers, sizeof (headers) }, + { (u8 *) &body, sizeof (body) }, + }; + + n_segs = (hcm->req_method == HTTP_REQ_GET) ? 3 : 4; + rv = svm_fifo_enqueue_segments (s->tx_fifo, segs, n_segs, + 0 /* allow partial */); + if (hcm->req_method == HTTP_REQ_POST) + ASSERT (rv == (sizeof (wrk->msg) + sizeof (target) + sizeof (headers) + + sizeof (body))); + else + ASSERT (rv == + (sizeof (wrk->msg) + sizeof (target) + sizeof (headers))); + goto done; + } + + rv = svm_fifo_enqueue (s->tx_fifo, sizeof (wrk->msg), (u8 *) &wrk->msg); + ASSERT (rv == sizeof (wrk->msg)); + + rv = svm_fifo_enqueue (s->tx_fifo, vec_len (hcm->target), hcm->target); + ASSERT (rv == vec_len (hcm->target)); + + rv = svm_fifo_enqueue (s->tx_fifo, vec_len (wrk->headers_buf), + wrk->headers_buf); + ASSERT (rv == wrk->msg.data.headers_len); + + if (hcm->req_method == HTTP_REQ_POST) + { + to_send = vec_len (hcm->data); + n_enq = clib_min (svm_fifo_size (s->tx_fifo), to_send); + + rv = svm_fifo_enqueue (s->tx_fifo, n_enq, hcm->data); + if (rv < to_send) + { + hcm->data_offset = (rv > 0) ? rv : 0; + svm_fifo_add_want_deq_ntf (s->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF); + } + } + +done: + if (svm_fifo_set_event (s->tx_fifo)) + { + session_program_tx_io_evt (s->handle, SESSION_IO_EVT_TX); + } + return 0; +} +static int +hc_session_connected_callback (u32 app_index, u32 hc_session_index, + session_t *s, session_error_t err) +{ + hc_main_t *hcm = &hc_main; + hc_worker_t *wrk; + u32 new_hc_index; + http_header_ht_t *header; HTTP_DBG (1, "ho hc_index: %d", hc_session_index); if (err) { clib_warning ("hc_session_index[%d] connected error: %U", hc_session_index, format_session_error, err); - vlib_process_signal_event_mt (hcm->wrk->vlib_main, hcm->cli_node_index, - HC_CONNECT_FAILED, 0); + vlib_process_signal_event_mt (vlib_get_main_by_index (s->thread_index), + hcm->cli_node_index, HC_CONNECT_FAILED, 0); return -1; } - hc_session = hc_session_get (hc_session_index, 0); wrk = hc_worker_get (s->thread_index); - new_hc_session = hc_session_alloc (wrk); + hc_session_t *hc_session, *new_hc_session = hc_session_alloc (wrk); + hc_session = hc_session_get (hc_session_index, 0); new_hc_index = new_hc_session->session_index; clib_memcpy_fast (new_hc_session, hc_session, sizeof (*hc_session)); - hc_session->vpp_session_index = s->session_index; - new_hc_session->session_index = new_hc_index; new_hc_session->thread_index = s->thread_index; new_hc_session->vpp_session_index = s->session_index; @@ -138,104 +208,64 @@ hc_session_connected_callback (u32 app_index, u32 hc_session_index, { if (hcm->is_file) http_add_header ( - &req_headers, http_header_name_token (HTTP_HEADER_CONTENT_TYPE), + &wrk->req_headers, http_header_name_token (HTTP_HEADER_CONTENT_TYPE), http_content_type_token (HTTP_CONTENT_APP_OCTET_STREAM)); else http_add_header ( - &req_headers, http_header_name_token (HTTP_HEADER_CONTENT_TYPE), + &wrk->req_headers, http_header_name_token (HTTP_HEADER_CONTENT_TYPE), http_content_type_token (HTTP_CONTENT_APP_X_WWW_FORM_URLENCODED)); } vec_foreach (header, hcm->custom_header) - http_add_header (&req_headers, (const char *) header->name, + http_add_header (&wrk->req_headers, (const char *) header->name, vec_len (header->name), (const char *) header->value, vec_len (header->value)); - hcm->headers_buf = http_serialize_headers (req_headers); - vec_free (req_headers); + wrk->headers_buf = http_serialize_headers (wrk->req_headers); + vec_free (wrk->req_headers); - msg.method_type = hcm->req_method; + wrk->msg.method_type = hcm->req_method; if (hcm->req_method == HTTP_REQ_POST) - msg.data.body_len = vec_len (hcm->data); + wrk->msg.data.body_len = vec_len (hcm->data); else - msg.data.body_len = 0; + wrk->msg.data.body_len = 0; - msg.type = HTTP_MSG_REQUEST; + wrk->msg.type = HTTP_MSG_REQUEST; /* request target */ - msg.data.target_form = HTTP_TARGET_ORIGIN_FORM; - msg.data.target_path_len = vec_len (hcm->target); + wrk->msg.data.target_form = HTTP_TARGET_ORIGIN_FORM; + wrk->msg.data.target_path_len = vec_len (hcm->target); /* custom headers */ - msg.data.headers_len = vec_len (hcm->headers_buf); + wrk->msg.data.headers_len = vec_len (wrk->headers_buf); /* total length */ - msg.data.len = - msg.data.target_path_len + msg.data.headers_len + msg.data.body_len; + wrk->msg.data.len = wrk->msg.data.target_path_len + + wrk->msg.data.headers_len + wrk->msg.data.body_len; if (hcm->use_ptr) { - uword target = pointer_to_uword (hcm->target); - uword headers = pointer_to_uword (hcm->headers_buf); - uword body = pointer_to_uword (hcm->data); - msg.data.type = HTTP_MSG_DATA_PTR; - svm_fifo_seg_t segs[4] = { - { (u8 *) &msg, sizeof (msg) }, - { (u8 *) &target, sizeof (target) }, - { (u8 *) &headers, sizeof (headers) }, - { (u8 *) &body, sizeof (body) }, - }; - - n_segs = (hcm->req_method == HTTP_REQ_GET) ? 3 : 4; - rv = svm_fifo_enqueue_segments (s->tx_fifo, segs, n_segs, - 0 /* allow partial */); - if (hcm->req_method == HTTP_REQ_POST) - ASSERT (rv == (sizeof (msg) + sizeof (target) + sizeof (headers) + - sizeof (body))); - else - ASSERT (rv == (sizeof (msg) + sizeof (target) + sizeof (headers))); - goto done; + wrk->msg.data.type = HTTP_MSG_DATA_PTR; } - - msg.data.type = HTTP_MSG_DATA_INLINE; - msg.data.target_path_offset = 0; - msg.data.headers_offset = msg.data.target_path_len; - msg.data.body_offset = msg.data.headers_offset + msg.data.headers_len; - - rv = svm_fifo_enqueue (s->tx_fifo, sizeof (msg), (u8 *) &msg); - ASSERT (rv == sizeof (msg)); - - rv = svm_fifo_enqueue (s->tx_fifo, vec_len (hcm->target), hcm->target); - ASSERT (rv == vec_len (hcm->target)); - - rv = svm_fifo_enqueue (s->tx_fifo, vec_len (hcm->headers_buf), - hcm->headers_buf); - ASSERT (rv == msg.data.headers_len); - - if (hcm->req_method == HTTP_REQ_POST) + else { - to_send = vec_len (hcm->data); - n_enq = clib_min (svm_fifo_size (s->tx_fifo), to_send); - - rv = svm_fifo_enqueue (s->tx_fifo, n_enq, hcm->data); - if (rv < to_send) - { - hcm->data_offset = (rv > 0) ? rv : 0; - svm_fifo_add_want_deq_ntf (s->tx_fifo, SVM_FIFO_WANT_DEQ_NOTIF); - } + wrk->msg.data.type = HTTP_MSG_DATA_INLINE; + wrk->msg.data.target_path_offset = 0; + wrk->msg.data.headers_offset = wrk->msg.data.target_path_len; + wrk->msg.data.body_offset = + wrk->msg.data.headers_offset + wrk->msg.data.headers_len; } -done: - if (svm_fifo_set_event (s->tx_fifo)) - session_program_tx_io_evt (s->handle, SESSION_IO_EVT_TX); + if (hcm->repeat) + hc_stats.start = vlib_time_now (vlib_get_main_by_index (s->thread_index)); - return 0; + return hc_request (s, err); } static void hc_session_disconnect_callback (session_t *s) { hc_main_t *hcm = &hc_main; + HTTP_DBG (1, "disconnecting"); vnet_disconnect_args_t _a = { 0 }, *a = &_a; int rv; - a->handle = session_handle (s); a->app_index = hcm->app_index; if ((rv = vnet_disconnect_session (a))) @@ -252,10 +282,10 @@ hc_session_transport_closed_callback (session_t *s) } static void -hc_ho_cleanup_callback (session_t *ts) +hc_ho_cleanup_callback (session_t *s) { - HTTP_DBG (1, "ho hc_index: %d:", ts->opaque); - hc_ho_session_free (ts->opaque); + HTTP_DBG (1, "ho hc_index: %d:", s->opaque); + hc_ho_session_free (s->opaque); } static void @@ -280,9 +310,12 @@ static int hc_rx_callback (session_t *s) { hc_main_t *hcm = &hc_main; + hc_worker_t *wrk = hc_worker_get (s->thread_index); hc_session_t *hc_session; http_msg_t msg; int rv; + session_error_t session_err = 0; + int send_err = 0; hc_session = hc_session_get (s->opaque, s->thread_index); @@ -300,28 +333,35 @@ hc_rx_callback (session_t *s) if (msg.type != HTTP_MSG_REPLY) { clib_warning ("unexpected msg type %d", msg.type); + vlib_process_signal_event_mt (wrk->vlib_main, hcm->cli_node_index, + HC_GENERIC_ERR, 0); return -1; } if (msg.data.headers_len) { + hcm->response_status = + format (0, "%U", format_http_status_code, msg.code); + svm_fifo_dequeue_drop (s->rx_fifo, msg.data.headers_offset); + http_header_table_t *ht; vec_validate (hcm->resp_headers, msg.data.headers_len - 1); - rv = svm_fifo_peek (s->rx_fifo, msg.data.headers_offset, - msg.data.headers_len, hcm->resp_headers); + vec_set_len (hcm->resp_headers, msg.data.headers_len); + rv = svm_fifo_dequeue (s->rx_fifo, msg.data.headers_len, + hcm->resp_headers); ASSERT (rv == msg.data.headers_len); - HTTP_DBG (1, (char *) hcm->resp_headers); - + HTTP_DBG (1, (char *) format (0, "%v", hcm->resp_headers)); if (http_parse_headers (hcm->resp_headers, &ht)) { clib_warning ("invalid headers received"); + vlib_process_signal_event_mt ( + wrk->vlib_main, hcm->cli_node_index, HC_GENERIC_ERR, 0); return -1; } http_free_header_table (ht); - - hcm->response_status = - format (0, "%U", format_http_status_code, msg.code); + msg.data.body_offset -= + msg.data.headers_len + msg.data.headers_offset; } if (msg.data.body_len == 0) @@ -342,13 +382,18 @@ hc_rx_callback (session_t *s) } u32 max_deq = svm_fifo_max_dequeue (s->rx_fifo); - + if (!max_deq) + { + goto done; + } u32 n_deq = clib_min (hc_session->to_recv, max_deq); u32 curr = vec_len (hcm->http_response); rv = svm_fifo_dequeue (s->rx_fifo, n_deq, hcm->http_response + curr); if (rv < 0) { clib_warning ("app dequeue(n=%d) failed; rv = %d", n_deq, rv); + vlib_process_signal_event_mt (wrk->vlib_main, hcm->cli_node_index, + HC_GENERIC_ERR, 0); return -1; } @@ -360,11 +405,33 @@ hc_rx_callback (session_t *s) done: if (hc_session->to_recv == 0) { - hc_session_disconnect_callback (s); - vlib_process_signal_event_mt (hcm->wrk->vlib_main, hcm->cli_node_index, - HC_REPLY_RECEIVED, 0); - } + if (hcm->repeat) + { + hc_stats.request_count++; + hc_stats.end = vlib_time_now (wrk->vlib_main); + hc_stats.elapsed_time = hc_stats.end - hc_stats.start; + if (hc_stats.elapsed_time >= hcm->duration && + hc_stats.request_count >= hcm->repeat_count) + { + vlib_process_signal_event_mt ( + wrk->vlib_main, hcm->cli_node_index, HC_REPEAT_DONE, 0); + hc_session_disconnect_callback (s); + } + else + { + send_err = hc_request (s, session_err); + if (send_err) + clib_warning ("failed to send request, error %d", send_err); + } + } + else + { + vlib_process_signal_event_mt (wrk->vlib_main, hcm->cli_node_index, + HC_REPLY_RECEIVED, 0); + hc_session_disconnect_callback (s); + } + } return 0; } @@ -455,6 +522,7 @@ hc_connect () vnet_connect_args_t *a = 0; hc_worker_t *wrk; hc_session_t *hc_session; + transport_endpt_ext_cfg_t *ext_cfg; vec_validate (a, 0); clib_memset (a, 0, sizeof (a[0])); @@ -462,6 +530,10 @@ hc_connect () clib_memcpy (&a->sep_ext, &hcm->connect_sep, sizeof (hcm->connect_sep)); a->app_index = hcm->app_index; + ext_cfg = session_endpoint_add_ext_cfg ( + &a->sep_ext, TRANSPORT_ENDPT_EXT_CFG_HTTP, sizeof (ext_cfg->opaque)); + ext_cfg->opaque = hcm->timeout; + /* allocate http session on main thread */ wrk = hc_worker_get (0); hc_session = hc_session_alloc (wrk); @@ -472,29 +544,19 @@ hc_connect () } static clib_error_t * -hc_run (vlib_main_t *vm) +hc_get_event (vlib_main_t *vm) { hc_main_t *hcm = &hc_main; - vlib_thread_main_t *vtm = vlib_get_thread_main (); - u32 num_threads; - hc_worker_t *wrk; uword event_type, *event_data = 0; - clib_error_t *err; + clib_error_t *err = NULL; FILE *file_ptr; + u64 event_timeout = 10; - num_threads = 1 /* main thread */ + vtm->n_threads; - vec_validate (hcm->wrk, num_threads - 1); - vec_foreach (wrk, hcm->wrk) - wrk->thread_index = wrk - hcm->wrk; - - if ((err = hc_attach ())) - return clib_error_return (0, "http client attach: %U", format_clib_error, - err); - - hc_connect (); - - vlib_process_wait_for_event_or_clock (vm, hcm->timeout); + if (event_timeout == hcm->timeout || event_timeout == hcm->duration) + event_timeout += 5; + vlib_process_wait_for_event_or_clock (vm, event_timeout); event_type = vlib_process_get_events (vm, &event_data); + switch (event_type) { case ~0: @@ -506,11 +568,14 @@ hc_run (vlib_main_t *vm) case HC_TRANSPORT_CLOSED: err = clib_error_return (0, "error: transport closed"); break; + case HC_GENERIC_ERR: + err = clib_error_return (0, "error: unknown"); + break; case HC_REPLY_RECEIVED: if (hcm->filename) { file_ptr = - fopen ((char *) format (0, "/tmp/%v", hcm->filename), "w"); + fopen ((char *) format (0, "/tmp/%v", hcm->filename), "a"); if (file_ptr == NULL) { vlib_cli_output (vm, "couldn't open file %v", hcm->filename); @@ -524,10 +589,17 @@ hc_run (vlib_main_t *vm) } } if (hcm->verbose) - vlib_cli_output (vm, "< %v\n< %v", hcm->response_status, + vlib_cli_output (vm, "< %v< %v", hcm->response_status, hcm->resp_headers); - vlib_cli_output (vm, "<\n%v", hcm->http_response); - + vlib_cli_output (vm, "\n%v\n", hcm->http_response); + break; + case HC_REPEAT_DONE: + vlib_cli_output (vm, + "< %d request(s) in %.6fs\n< avg latency " + "%.4fms\n< %.2f req/sec", + hc_stats.request_count, hc_stats.elapsed_time, + (hc_stats.elapsed_time / hc_stats.request_count) * 1000, + hc_stats.request_count / hc_stats.elapsed_time); break; default: err = clib_error_return (0, "error: unexpected event %d", event_type); @@ -538,6 +610,29 @@ hc_run (vlib_main_t *vm) return err; } +static clib_error_t * +hc_run (vlib_main_t *vm) +{ + hc_main_t *hcm = &hc_main; + vlib_thread_main_t *vtm = vlib_get_thread_main (); + u32 num_threads; + hc_worker_t *wrk; + clib_error_t *err; + + num_threads = 1 /* main thread */ + vtm->n_threads; + vec_validate (hcm->wrk, num_threads - 1); + vec_foreach (wrk, hcm->wrk) + wrk->thread_index = wrk - hcm->wrk; + + if ((err = hc_attach ())) + return clib_error_return (0, "http client attach: %U", format_clib_error, + err); + + hc_connect (); + + return hc_get_event (vm); +} + static int hc_detach () { @@ -560,12 +655,15 @@ hc_detach () static void hcc_worker_cleanup (hc_worker_t *wrk) { + HTTP_DBG (1, "worker cleanup"); + vec_free (wrk->headers_buf); pool_free (wrk->sessions); } static void hc_cleanup () { + HTTP_DBG (1, "cleanup"); hc_main_t *hcm = &hc_main; hc_worker_t *wrk; http_header_ht_t *header; @@ -575,7 +673,6 @@ hc_cleanup () vec_free (hcm->uri); vec_free (hcm->target); - vec_free (hcm->headers_buf); vec_free (hcm->data); vec_free (hcm->resp_headers); vec_free (hcm->http_response); @@ -604,12 +701,14 @@ hc_command_fn (vlib_main_t *vm, unformat_input_t *input, u8 *value; int rv; hcm->timeout = 10; + hcm->repeat_count = 0; + hcm->duration = 0; + hcm->repeat = false; + hc_stats.request_count = 0; if (hcm->attached) return clib_error_return (0, "failed: already running!"); - hcm->use_ptr = 0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, "expected required arguments"); @@ -652,6 +751,12 @@ hc_command_fn (vlib_main_t *vm, unformat_input_t *input, hcm->verbose = true; else if (unformat (line_input, "timeout %f", &hcm->timeout)) ; + else if (unformat (line_input, "repeat %d", &hcm->repeat_count)) + { + hcm->repeat = true; + } + else if (unformat (line_input, "duration %f", &hcm->duration)) + hcm->repeat = true; else { err = clib_error_return (0, "unknown input `%U'", @@ -685,6 +790,12 @@ hc_command_fn (vlib_main_t *vm, unformat_input_t *input, goto done; } } + if (hcm->duration && hcm->repeat_count) + { + err = clib_error_return ( + 0, "combining duration and repeat is not supported"); + goto done; + } if ((rv = parse_uri ((char *) hcm->uri, &hcm->connect_sep))) { @@ -693,6 +804,9 @@ hc_command_fn (vlib_main_t *vm, unformat_input_t *input, goto done; } + if (hcm->repeat) + vlib_cli_output (vm, "Running, please wait..."); + session_enable_disable_args_t args = { .is_en = 1, .rt_engine_type = RT_BACKEND_ENGINE_RULE_TABLE }; @@ -701,7 +815,6 @@ hc_command_fn (vlib_main_t *vm, unformat_input_t *input, vlib_worker_thread_barrier_release (vm); hcm->cli_node_index = vlib_get_current_process (vm)->node_runtime.node_index; - err = hc_run (vm); if ((rv = hc_detach ())) @@ -724,10 +837,11 @@ done: VLIB_CLI_COMMAND (hc_command, static) = { .path = "http client", - .short_help = "[post] uri http://<ip-addr> target <origin-form> " - "[data <form-urlencoded> | file <file-path>] [use-ptr] " - "[save-to <filename>] [header <Key:Value>] [verbose] " - "[timeout <seconds> (default = 10)]", + .short_help = + "[post] uri http://<ip-addr> target <origin-form> " + "[data <form-urlencoded> | file <file-path>] [use-ptr] " + "[save-to <filename>] [header <Key:Value>] [verbose] " + "[timeout <seconds> (default = 10)] [repeat <count> | duration <seconds>]", .function = hc_command_fn, .is_mp_safe = 1, }; diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c index 4510bf85e1b..befb30851cd 100644 --- a/src/vcl/ldp.c +++ b/src/vcl/ldp.c @@ -105,6 +105,8 @@ typedef struct ldp_worker_ctx_ int vcl_mq_epfd; } ldp_worker_ctx_t; +__thread ldp_worker_ctx_t _ldp_worker = {}; + /* clib_bitmap_t, fd_mask and vcl_si_set are used interchangeably. Make sure * they are the same size */ STATIC_ASSERT (sizeof (clib_bitmap_t) == sizeof (fd_mask), @@ -114,7 +116,6 @@ STATIC_ASSERT (sizeof (vcl_si_set) == sizeof (fd_mask), typedef struct { - ldp_worker_ctx_t *workers; int init; char app_name[LDP_APP_NAME_MAX]; u32 vlsh_bit_val; @@ -154,7 +155,7 @@ static ldp_main_t *ldp = &ldp_main; static inline ldp_worker_ctx_t * ldp_worker_get_current (void) { - return (ldp->workers + vppcom_worker_index ()); + return &_ldp_worker; } /* @@ -191,14 +192,6 @@ ldp_fd_to_vlsh (int fd) } static void -ldp_alloc_workers (void) -{ - if (ldp->workers) - return; - ldp->workers = vec_new (ldp_worker_ctx_t, LDP_MAX_NWORKERS); -} - -static void ldp_init_cfg (void) { char *env_var_str = getenv (LDP_ENV_DEBUG); @@ -285,7 +278,6 @@ ldp_init_cfg (void) static int ldp_init (void) { - ldp_worker_ctx_t *ldpw; int rv; if (ldp->init) @@ -311,10 +303,6 @@ ldp_init (void) return rv; } ldp->vcl_needs_real_epoll = 0; - ldp_alloc_workers (); - - vec_foreach (ldpw, ldp->workers) - clib_memset (&ldpw->clib_time, 0, sizeof (ldpw->clib_time)); LDBG (0, "LDP initialization: done!"); @@ -2397,14 +2385,9 @@ epoll_create1 (int flags) if (ldp->vcl_needs_real_epoll || vls_use_real_epoll ()) { - /* Make sure workers have been allocated */ - if (!ldp->workers) - { - ldp_alloc_workers (); - ldpw = ldp_worker_get_current (); - } rv = libc_epoll_create1 (flags); ldp->vcl_needs_real_epoll = 0; + /* Assume this is a request to create the mq epfd */ ldpw->vcl_mq_epfd = rv; LDBG (0, "created vcl epfd %u", rv); return rv; @@ -2665,6 +2648,7 @@ ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events, if (PREDICT_FALSE (!ldpw->mq_epfd_added)) { struct epoll_event e = { 0 }; + ldpw->vcl_mq_epfd = vppcom_mq_epoll_fd (); e.events = EPOLLIN; e.data.fd = ldpw->vcl_mq_epfd; if (libc_epoll_ctl (libc_epfd, EPOLL_CTL_ADD, ldpw->vcl_mq_epfd, &e) < diff --git a/src/vnet/fib/ip4_fib.c b/src/vnet/fib/ip4_fib.c index 23f70a770bf..b1198564754 100644 --- a/src/vnet/fib/ip4_fib.c +++ b/src/vnet/fib/ip4_fib.c @@ -354,8 +354,7 @@ ip4_show_fib (vlib_main_t * vm, else if (unformat (input, "mtrie")) mtrie = 1; - else if (unformat (input, "mem") || - unformat (input, "memory")) + else if (unformat (input, "memory") || unformat (input, "mem")) memory = 1; else if (unformat (input, "%U/%d", @@ -620,7 +619,7 @@ ip4_show_fib (vlib_main_t * vm, ?*/ VLIB_CLI_COMMAND (ip4_show_fib_command, static) = { .path = "show ip fib", - .short_help = "show ip fib [summary] [table <table-id>] [index <fib-id>] [<ip4-addr>[/<mask>]] [mtrie] [detail]", + .short_help = "show ip fib [summary] [table <table-id>] [index <fib-id>] [<ip4-addr>[/<mask>]] [mtrie] [detail] [memory]", .function = ip4_show_fib, }; diff --git a/src/vnet/pg/pg.h b/src/vnet/pg/pg.h index 5e99d9af9f6..5e63b58caf6 100644 --- a/src/vnet/pg/pg.h +++ b/src/vnet/pg/pg.h @@ -182,14 +182,38 @@ typedef struct pg_stream_t } pg_stream_t; always_inline void -pg_buffer_index_free (pg_buffer_index_t * bi) +pg_free_buffers (pg_buffer_index_t *bi) { vlib_main_t *vm = vlib_get_main (); - word n_alloc; - vec_free (bi->edits); - n_alloc = clib_fifo_elts (bi->buffer_fifo); - vlib_buffer_free (vm, bi->buffer_fifo, n_alloc); - clib_fifo_free (bi->buffer_fifo); + uword n_elts, head, len; + + if (!bi || !bi->buffer_fifo) + return; + + n_elts = clib_fifo_elts (bi->buffer_fifo); + if (n_elts) + { + len = clib_fifo_len (bi->buffer_fifo); + head = clib_fifo_head_index (bi->buffer_fifo); + + if (head + n_elts <= len) + vlib_buffer_free (vm, &bi->buffer_fifo[head], n_elts); + else + { + vlib_buffer_free (vm, &bi->buffer_fifo[head], len - head); + vlib_buffer_free (vm, bi->buffer_fifo, n_elts - (len - head)); + } + } +} + +always_inline void +pg_buffer_index_free (pg_buffer_index_t *bi) +{ + if (bi) + { + vec_free (bi->edits); + clib_fifo_free (bi->buffer_fifo); + } } always_inline void @@ -220,11 +244,16 @@ pg_stream_free (pg_stream_t * s) vec_free (s->replay_packet_templates); vec_free (s->replay_packet_timestamps); - { - pg_buffer_index_t *bi; - vec_foreach (bi, s->buffer_indices) pg_buffer_index_free (bi); - vec_free (s->buffer_indices); - } + if (s->buffer_indices) + { + pg_buffer_index_t *bi; + // We only need to free the buffers from the first array, as the buffers + // are chained when packet-generator enable is issued. + pg_free_buffers (s->buffer_indices); + vec_foreach (bi, s->buffer_indices) + pg_buffer_index_free (bi); + vec_free (s->buffer_indices); + } } always_inline int diff --git a/src/vpp-api/python/setup.py b/src/vpp-api/python/setup.py index 784013fc606..832b6386352 100644 --- a/src/vpp-api/python/setup.py +++ b/src/vpp-api/python/setup.py @@ -21,7 +21,7 @@ requirements = [] setup( name="vpp_papi", - version="2.1.0", + version="2.2.0", description="VPP Python binding", author="Ole Troan", author_email="ot@cisco.com", diff --git a/src/vpp-api/python/vpp_papi/__init__.py b/src/vpp-api/python/vpp_papi/__init__.py index dc58c1e18cb..80a374ce1bb 100644 --- a/src/vpp-api/python/vpp_papi/__init__.py +++ b/src/vpp-api/python/vpp_papi/__init__.py @@ -10,9 +10,10 @@ from .vpp_serializer import BaseTypes # noqa: F401 from .vpp_serializer import VPPEnumType, VPPType, VPPTypeAlias # noqa: F401 from .vpp_serializer import VPPMessage, VPPUnionType # noqa: F401 -import pkg_resources # part of setuptools +import importlib.metadata as metadata try: - __version__ = pkg_resources.get_distribution("vpp_papi").version -except pkg_resources.DistributionNotFound: - """Can't find vpp_papi via setuptools""" + __version__ = metadata.version("vpp_papi") +except metadata.PackageNotFoundError: + # Can't find vpp_papi via importlib.metadata + __version__ = "0.0.0" diff --git a/src/vpp-api/python/vpp_papi/vpp_papi.py b/src/vpp-api/python/vpp_papi/vpp_papi.py index 30c00cd8dd3..61e67d162be 100644 --- a/src/vpp-api/python/vpp_papi/vpp_papi.py +++ b/src/vpp-api/python/vpp_papi/vpp_papi.py @@ -29,7 +29,8 @@ import fnmatch import weakref import atexit import time -import pkg_resources +import importlib.resources as resources + from .vpp_format import verify_enum_hint from .vpp_serializer import VPPType, VPPEnumType, VPPEnumFlagType, VPPUnionType from .vpp_serializer import VPPMessage, vpp_get_type, VPPTypeAlias @@ -502,10 +503,10 @@ class VPPApiClient: raise e else: # Bootstrap the API (memclnt.api bundled with VPP PAPI) - resource_path = "/".join(("data", "memclnt.api.json")) - file_content = pkg_resources.resource_string(__name__, resource_path) + with resources.open_text("vpp_papi.data", "memclnt.api.json") as f: + resource_content = f.read() self.messages, self.services = VPPApiJSONFiles.process_json_str( - file_content + resource_content ) # Basic sanity check |