diff options
author | Ed Warnicke <eaw@cisco.com> | 2015-12-14 17:36:44 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@projectrotterdam.info> | 2015-12-14 17:36:44 +0000 |
commit | 64f98e91b669ecda59fcb587e095d0fb6b3dc48d (patch) | |
tree | 73771e86a59fd087c5b88ee4f9df37841664af0d | |
parent | ee4e9ec5b3d94c580329ee8fa98304055be052fe (diff) | |
parent | 4e281a48e2afd258188c9ad996c46f166d4cfd9f (diff) |
Merge "Move rpc handler where it belongs, related cleanup"
-rw-r--r-- | vlib-api/vlibmemory/api.h | 4 | ||||
-rw-r--r-- | vlib-api/vlibmemory/memclnt.api | 20 | ||||
-rw-r--r-- | vlib-api/vlibmemory/memory_vlib.c | 85 | ||||
-rw-r--r-- | vnet/Makefile.am | 9 | ||||
-rw-r--r-- | vnet/Makefile.in | 40 | ||||
-rw-r--r-- | vnet/example/main_stub.c | 203 | ||||
-rw-r--r-- | vnet/example/rtt_test.c | 827 | ||||
-rw-r--r-- | vnet/vnet/devices/dpdk/threads.c | 84 | ||||
-rw-r--r-- | vnet/vnet/devices/dpdk/threads.h | 2 | ||||
-rw-r--r-- | vpp/vnet/main.c | 13 |
10 files changed, 99 insertions, 1188 deletions
diff --git a/vlib-api/vlibmemory/api.h b/vlib-api/vlibmemory/api.h index 7f2f6fa6..117bf433 100644 --- a/vlib-api/vlibmemory/api.h +++ b/vlib-api/vlibmemory/api.h @@ -109,8 +109,6 @@ static inline u32 vl_msg_api_handle_from_index_and_epoch (u32 index, u32 epoch) return handle; } - - void *vl_msg_api_alloc(int nbytes); void *vl_msg_api_alloc_as_if_client (int nbytes); void vl_msg_api_free(void *a); @@ -136,4 +134,6 @@ int vl_client_connect_to_vlib_no_rx_pthread (char *svm_name, char *client_name, int rx_queue_size); u16 vl_client_get_first_plugin_msg_id (char * plugin_name); +void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length); + #endif /* included_vlibmemory_api_h */ diff --git a/vlib-api/vlibmemory/memclnt.api b/vlib-api/vlibmemory/memclnt.api index 6a108b81..c2758238 100644 --- a/vlib-api/vlibmemory/memclnt.api +++ b/vlib-api/vlibmemory/memclnt.api @@ -14,26 +14,6 @@ * limitations under the License. */ -/* - *------------------------------------------------------------------ - * memclnt.api - API message(s) to hook up clients, pass traffic - * to client processes on the same system element - * - * Copyright (c) 2009 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------ - */ - /* * Create a client registration */ diff --git a/vlib-api/vlibmemory/memory_vlib.c b/vlib-api/vlibmemory/memory_vlib.c index 165cdf30..57cb8f74 100644 --- a/vlib-api/vlibmemory/memory_vlib.c +++ b/vlib-api/vlibmemory/memory_vlib.c @@ -1122,3 +1122,88 @@ VLIB_CLI_COMMAND (cli_show_api_plugin_command, static) = { .short_help = "show api plugin", .function = vl_api_show_plugin_command, }; + +static void vl_api_rpc_call_t_handler (vl_api_rpc_call_t * mp) +{ + vl_api_rpc_reply_t * rmp; + int (*fp)(void *); + i32 rv = 0; + vlib_main_t * vm = vlib_get_main(); + + if (mp->function == 0) + { + rv = -1; + clib_warning ("rpc NULL function pointer"); + } + + else + { + if (mp->need_barrier_sync) + vlib_worker_thread_barrier_sync (vm); + + fp = (void *)(mp->function); + rv = (*fp)(mp->data); + + if (mp->need_barrier_sync) + vlib_worker_thread_barrier_release (vm); + } + + if (mp->send_reply) + { + unix_shared_memory_queue_t * q = + vl_api_client_index_to_input_queue (mp->client_index); + if (q) + { + rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp)); + rmp->_vl_msg_id = ntohs (VL_API_RPC_REPLY); + rmp->context = mp->context; + rmp->retval = rv; + vl_msg_api_send_shmem (q, (u8 *)&rmp); + } + } + if (mp->multicast) + { + clib_warning ("multicast not yet implemented..."); + } +} + +static void vl_api_rpc_reply_t_handler (vl_api_rpc_reply_t * mp) +{ clib_warning ("unimplemented"); } + +void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length) +{ + vl_api_rpc_call_t * mp; + api_main_t *am = &api_main; + vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr; + + mp = vl_msg_api_alloc_as_if_client (sizeof (*mp) + data_length); + memset (mp, 0, sizeof (*mp)); + memcpy (mp->data, data, data_length); + mp->_vl_msg_id = ntohs (VL_API_RPC_CALL); + mp->function = (u64)fp; + mp->need_barrier_sync = 1; + + /* Use the "normal" control-plane mechanism for the main thread */ + vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *)&mp); +} + +#define foreach_rpc_api_msg \ +_(RPC_CALL,rpc_call) \ +_(RPC_REPLY,rpc_reply) + +static clib_error_t * +rpc_api_hookup (vlib_main_t *vm) +{ +#define _(N,n) \ + vl_msg_api_set_handlers(VL_API_##N, #n, \ + vl_api_##n##_t_handler, \ + vl_noop_handler, \ + vl_noop_handler, \ + vl_api_##n##_t_print, \ + sizeof(vl_api_##n##_t), 0 /* do not trace */); + foreach_rpc_api_msg; +#undef _ + return 0; +} + +VLIB_API_INIT_FUNCTION(rpc_api_hookup); diff --git a/vnet/Makefile.am b/vnet/Makefile.am index ee01bff1..1bde1e80 100644 --- a/vnet/Makefile.am +++ b/vnet/Makefile.am @@ -18,6 +18,7 @@ AM_CFLAGS = -Wall @DPDK@ @VIRL@ libvnet_la_SOURCES = libvnetplugin_la_SOURCES = nobase_include_HEADERS = +noinst_PROGRAMS = ######################################## # Generic stuff @@ -608,20 +609,12 @@ nobase_include_HEADERS += \ lib_LTLIBRARIES = libvnet.la libvnetplugin.la -noinst_PROGRAMS = vnet_unix - -vnet_unix_SOURCES = \ - example/main_stub.c - -vnet_unix_LDFLAGS = -static dpdk_libs = if WITH_DPDK dpdk_libs += -l:libdpdk.a endif -vnet_unix_LDADD = libvnet.la -l:libvlib_unix.a -l:libvlib.a -l:libvppinfra.a -lpthread -lvlibapi -lvlibmemory -lsvm -lm -ldl $(dpdk_libs) -lrt - pcap2pg_SOURCES = \ vnet/unix/pcap2pg.c \ vnet/unix/pcap.h diff --git a/vnet/Makefile.in b/vnet/Makefile.in index 82000f41..7cbe871c 100644 --- a/vnet/Makefile.in +++ b/vnet/Makefile.in @@ -93,6 +93,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ +noinst_PROGRAMS = pcap2pg$(EXEEXT) ######################################## # Layer 3 protocol: IPSec @@ -139,7 +140,6 @@ host_triplet = @host@ @WITH_DPDK_TRUE@am__append_4 = vnet/devices/dpdk/dpdk.h \ @WITH_DPDK_TRUE@ vnet/devices/dpdk/threads.h \ @WITH_DPDK_TRUE@ vnet/devices/virtio/vhost-user.h -noinst_PROGRAMS = vnet_unix$(EXEEXT) pcap2pg$(EXEEXT) @WITH_DPDK_TRUE@am__append_5 = -l:libdpdk.a subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ @@ -382,14 +382,6 @@ pcap2pg_DEPENDENCIES = libvnet.la pcap2pg_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(pcap2pg_LDFLAGS) $(LDFLAGS) -o $@ -am_vnet_unix_OBJECTS = example/main_stub.$(OBJEXT) -vnet_unix_OBJECTS = $(am_vnet_unix_OBJECTS) -am__DEPENDENCIES_1 = -am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) -vnet_unix_DEPENDENCIES = libvnet.la $(am__DEPENDENCIES_2) -vnet_unix_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(vnet_unix_LDFLAGS) $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -425,10 +417,9 @@ am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libvnet_la_SOURCES) $(libvnetplugin_la_SOURCES) \ - $(pcap2pg_SOURCES) $(vnet_unix_SOURCES) + $(pcap2pg_SOURCES) DIST_SOURCES = $(am__libvnet_la_SOURCES_DIST) \ - $(libvnetplugin_la_SOURCES) $(pcap2pg_SOURCES) \ - $(vnet_unix_SOURCES) + $(libvnetplugin_la_SOURCES) $(pcap2pg_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -908,12 +899,7 @@ nobase_include_HEADERS = vnet/api_errno.h vnet/buffer.h vnet/config.h \ vnet/unix/pcap.h vnet/unix/tuntap.h vnet/unix/tapcli.h \ vnet/plugin/plugin.h lib_LTLIBRARIES = libvnet.la libvnetplugin.la -vnet_unix_SOURCES = \ - example/main_stub.c - -vnet_unix_LDFLAGS = -static dpdk_libs = $(am__append_5) -vnet_unix_LDADD = libvnet.la -l:libvlib_unix.a -l:libvlib.a -l:libvppinfra.a -lpthread -lvlibapi -lvlibmemory -lsvm -lm -ldl $(dpdk_libs) -lrt pcap2pg_SOURCES = \ vnet/unix/pcap2pg.c \ vnet/unix/pcap.h @@ -1583,22 +1569,9 @@ vnet/unix/pcap2pg.$(OBJEXT): vnet/unix/$(am__dirstamp) \ pcap2pg$(EXEEXT): $(pcap2pg_OBJECTS) $(pcap2pg_DEPENDENCIES) $(EXTRA_pcap2pg_DEPENDENCIES) @rm -f pcap2pg$(EXEEXT) $(AM_V_CCLD)$(pcap2pg_LINK) $(pcap2pg_OBJECTS) $(pcap2pg_LDADD) $(LIBS) -example/$(am__dirstamp): - @$(MKDIR_P) example - @: > example/$(am__dirstamp) -example/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) example/$(DEPDIR) - @: > example/$(DEPDIR)/$(am__dirstamp) -example/main_stub.$(OBJEXT): example/$(am__dirstamp) \ - example/$(DEPDIR)/$(am__dirstamp) - -vnet_unix$(EXEEXT): $(vnet_unix_OBJECTS) $(vnet_unix_DEPENDENCIES) $(EXTRA_vnet_unix_DEPENDENCIES) - @rm -f vnet_unix$(EXEEXT) - $(AM_V_CCLD)$(vnet_unix_LINK) $(vnet_unix_OBJECTS) $(vnet_unix_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) - -rm -f example/*.$(OBJEXT) -rm -f vnet/*.$(OBJEXT) -rm -f vnet/*.lo -rm -f vnet/classify/*.$(OBJEXT) @@ -1669,7 +1642,6 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@example/$(DEPDIR)/main_stub.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vnet/$(DEPDIR)/config.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vnet/$(DEPDIR)/interface.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@vnet/$(DEPDIR)/interface_cli.Plo@am__quote@ @@ -2203,8 +2175,6 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f example/$(DEPDIR)/$(am__dirstamp) - -rm -f example/$(am__dirstamp) -rm -f vnet/$(DEPDIR)/$(am__dirstamp) -rm -f vnet/$(am__dirstamp) -rm -f vnet/classify/$(DEPDIR)/$(am__dirstamp) @@ -2282,7 +2252,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf example/$(DEPDIR) vnet/$(DEPDIR) vnet/classify/$(DEPDIR) vnet/devices/dpdk/$(DEPDIR) vnet/devices/ssvm/$(DEPDIR) vnet/devices/virtio/$(DEPDIR) vnet/dhcp/$(DEPDIR) vnet/dhcpv6/$(DEPDIR) vnet/ethernet/$(DEPDIR) vnet/flow/$(DEPDIR) vnet/gre/$(DEPDIR) vnet/hdlc/$(DEPDIR) vnet/ip/$(DEPDIR) vnet/ipsec/$(DEPDIR) vnet/l2/$(DEPDIR) vnet/l2tp/$(DEPDIR) vnet/lawful-intercept/$(DEPDIR) vnet/lisp-gpe/$(DEPDIR) vnet/llc/$(DEPDIR) vnet/map/$(DEPDIR) vnet/mpls-gre/$(DEPDIR) vnet/nsh-gre/$(DEPDIR) vnet/nsh-vxlan-gpe/$(DEPDIR) vnet/osi/$(DEPDIR) vnet/pg/$(DEPDIR) vnet/plugin/$(DEPDIR) vnet/policer/$(DEPDIR) vnet/ppp/$(DEPDIR) vnet/snap/$(DEPDIR) vnet/sr/$(DEPDIR) vnet/srp/$(DEPDIR) vnet/unix/$(DEPDIR) vnet/vcgn/$(DEPDIR) vnet/vxlan/$(DEPDIR) + -rm -rf vnet/$(DEPDIR) vnet/classify/$(DEPDIR) vnet/devices/dpdk/$(DEPDIR) vnet/devices/ssvm/$(DEPDIR) vnet/devices/virtio/$(DEPDIR) vnet/dhcp/$(DEPDIR) vnet/dhcpv6/$(DEPDIR) vnet/ethernet/$(DEPDIR) vnet/flow/$(DEPDIR) vnet/gre/$(DEPDIR) vnet/hdlc/$(DEPDIR) vnet/ip/$(DEPDIR) vnet/ipsec/$(DEPDIR) vnet/l2/$(DEPDIR) vnet/l2tp/$(DEPDIR) vnet/lawful-intercept/$(DEPDIR) vnet/lisp-gpe/$(DEPDIR) vnet/llc/$(DEPDIR) vnet/map/$(DEPDIR) vnet/mpls-gre/$(DEPDIR) vnet/nsh-gre/$(DEPDIR) vnet/nsh-vxlan-gpe/$(DEPDIR) vnet/osi/$(DEPDIR) vnet/pg/$(DEPDIR) vnet/plugin/$(DEPDIR) vnet/policer/$(DEPDIR) vnet/ppp/$(DEPDIR) vnet/snap/$(DEPDIR) vnet/sr/$(DEPDIR) vnet/srp/$(DEPDIR) vnet/unix/$(DEPDIR) vnet/vcgn/$(DEPDIR) vnet/vxlan/$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-libtool distclean-tags @@ -2330,7 +2300,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf example/$(DEPDIR) vnet/$(DEPDIR) vnet/classify/$(DEPDIR) vnet/devices/dpdk/$(DEPDIR) vnet/devices/ssvm/$(DEPDIR) vnet/devices/virtio/$(DEPDIR) vnet/dhcp/$(DEPDIR) vnet/dhcpv6/$(DEPDIR) vnet/ethernet/$(DEPDIR) vnet/flow/$(DEPDIR) vnet/gre/$(DEPDIR) vnet/hdlc/$(DEPDIR) vnet/ip/$(DEPDIR) vnet/ipsec/$(DEPDIR) vnet/l2/$(DEPDIR) vnet/l2tp/$(DEPDIR) vnet/lawful-intercept/$(DEPDIR) vnet/lisp-gpe/$(DEPDIR) vnet/llc/$(DEPDIR) vnet/map/$(DEPDIR) vnet/mpls-gre/$(DEPDIR) vnet/nsh-gre/$(DEPDIR) vnet/nsh-vxlan-gpe/$(DEPDIR) vnet/osi/$(DEPDIR) vnet/pg/$(DEPDIR) vnet/plugin/$(DEPDIR) vnet/policer/$(DEPDIR) vnet/ppp/$(DEPDIR) vnet/snap/$(DEPDIR) vnet/sr/$(DEPDIR) vnet/srp/$(DEPDIR) vnet/unix/$(DEPDIR) vnet/vcgn/$(DEPDIR) vnet/vxlan/$(DEPDIR) + -rm -rf vnet/$(DEPDIR) vnet/classify/$(DEPDIR) vnet/devices/dpdk/$(DEPDIR) vnet/devices/ssvm/$(DEPDIR) vnet/devices/virtio/$(DEPDIR) vnet/dhcp/$(DEPDIR) vnet/dhcpv6/$(DEPDIR) vnet/ethernet/$(DEPDIR) vnet/flow/$(DEPDIR) vnet/gre/$(DEPDIR) vnet/hdlc/$(DEPDIR) vnet/ip/$(DEPDIR) vnet/ipsec/$(DEPDIR) vnet/l2/$(DEPDIR) vnet/l2tp/$(DEPDIR) vnet/lawful-intercept/$(DEPDIR) vnet/lisp-gpe/$(DEPDIR) vnet/llc/$(DEPDIR) vnet/map/$(DEPDIR) vnet/mpls-gre/$(DEPDIR) vnet/nsh-gre/$(DEPDIR) vnet/nsh-vxlan-gpe/$(DEPDIR) vnet/osi/$(DEPDIR) vnet/pg/$(DEPDIR) vnet/plugin/$(DEPDIR) vnet/policer/$(DEPDIR) vnet/ppp/$(DEPDIR) vnet/snap/$(DEPDIR) vnet/sr/$(DEPDIR) vnet/srp/$(DEPDIR) vnet/unix/$(DEPDIR) vnet/vcgn/$(DEPDIR) vnet/vxlan/$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/vnet/example/main_stub.c b/vnet/example/main_stub.c deleted file mode 100644 index c45932ba..00000000 --- a/vnet/example/main_stub.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vlib/vlib.h> -#include <vlib/unix/unix.h> -#include <vnet/pg/pg.h> -#include <vnet/ethernet/ethernet.h> -#include <vnet/ip/ip.h> -#include <vnet/ip/tcp.h> - -#include <vlib/unix/cj.h> - -DECLARE_CJ_GLOBAL_LOG - -static clib_error_t * -vnet_example_init (vlib_main_t * vm) -{ - clib_error_t * error = 0; - - /* Due to crude comment-out of eliot's smp stuff */ - vm->heap_size = 256<<20; - - if ((error = vlib_call_init_function (vm, pg_init))) - return error; - if ((error = vlib_call_init_function (vm, ip_main_init))) - return error; - if ((error = vlib_call_init_function (vm, ethernet_init))) - return error; - if ((error = vlib_call_init_function (vm, ethernet_arp_init))) - return error; - if ((error = vlib_call_init_function (vm, osi_init))) - return error; - if ((error = vlib_call_init_function (vm, srp_init))) - return error; -#if DPDK == 0 - if ((error = vlib_call_init_function (vm, ixge_init))) - return error; - if ((error = vlib_call_init_function (vm, ixgev_init))) - return error; - if ((error = vlib_call_init_function (vm, ige_init))) - return error; -#else - if ((error = vlib_call_init_function (vm, dpdk_init))) - return error; -#endif - - if ((error = vlib_call_init_function (vm, dhcp_proxy_init))) - return error; - if ((error = vlib_call_init_function (vm, mpls_init))) - return error; - if ((error = vlib_call_init_function (vm, mpls_interface_init))) - return error; - - if ((error = vlib_call_init_function (vm, l2_init))) - return error; - if ((error = vlib_call_init_function (vm, l2tp_init))) - return error; - - if ((error = unix_physmem_init (vm, /* physical_memory_required */ 0))) - return error; - - if ((error = unix_physmem_init (vm, /* physical_memory_required */ 0))) - return error; - - if ((error = vlib_call_init_function (vm, tuntap_init))) - return error; - - vlib_unix_cli_set_prompt ("VNET: "); - - return error; -} - -VLIB_INIT_FUNCTION (vnet_example_init); - -int main (int argc, char * argv[]) -{ - clib_mem_init (0, (2ULL << 30)); - return vlib_unix_main (argc, argv); -} - -#if 0 -#define foreach_tcp_test_error \ - _ (SEGMENTS_RECEIVED, "segments received") - -typedef enum { -#define _(sym,str) TCP_TEST_ERROR_##sym, - foreach_tcp_test_error -#undef _ - TCP_TEST_N_ERROR, -} tcp_test_error_t; - -static char * tcp_test_error_strings[] = { -#define _(sym,string) string, - foreach_tcp_test_error -#undef _ -}; - -static uword -tcp_test (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - uword n_packets = frame->n_vectors; - u32 * from, * to_next; - u32 n_left_from, n_left_to_next, next; - - from = vlib_frame_vector_args (frame); - n_left_from = n_packets; - next = node->cached_next_index; - - while (n_left_from > 0) - { - vlib_get_next_frame (vm, node, next, to_next, n_left_to_next); - - while (n_left_from > 0 && n_left_to_next > 0) - { - vlib_buffer_t * p0; - u32 bi0; - u8 error0, next0; - - bi0 = to_next[0] = from[0]; - - from += 1; - n_left_from -= 1; - to_next += 1; - n_left_to_next -= 1; - - p0 = vlib_get_buffer (vm, bi0); - - clib_warning ("got '%U'", format_vlib_buffer_contents, vm, p0); - - error0 = next0 = 0; - p0->error = node->errors[error0]; - - if (PREDICT_FALSE (next0 != next)) - { - to_next -= 1; - n_left_to_next += 1; - - vlib_put_next_frame (vm, node, next, n_left_to_next); - - next = next0; - vlib_get_next_frame (vm, node, next, to_next, n_left_to_next); - to_next[0] = bi0; - to_next += 1; - n_left_to_next -= 1; - } - } - - vlib_put_next_frame (vm, node, next, n_left_to_next); - } - - return frame->n_vectors; -} - -VLIB_REGISTER_NODE (tcp_test_node) = { - .function = tcp_test, - .name = "tcp-test", - - .vector_size = sizeof (u32), - - .n_next_nodes = 1, - .next_nodes = { - [0] = "error-drop", - }, - - .n_errors = TCP_TEST_N_ERROR, - .error_strings = tcp_test_error_strings, -}; - -static clib_error_t * -tcp_test_init (vlib_main_t * vm) -{ - clib_error_t * error = 0; - - { - tcp_listener_registration_t r = { - .port = 1234, - .flags = TCP_LISTENER_IP4, - .data_node_index = tcp_test_node.index, - .event_function = 0, - }; - - tcp_register_listener (vm, &r); - } - - return error; -} - -VLIB_INIT_FUNCTION (tcp_test_init); - -#endif diff --git a/vnet/example/rtt_test.c b/vnet/example/rtt_test.c deleted file mode 100644 index 98f0cdf2..00000000 --- a/vnet/example/rtt_test.c +++ /dev/null @@ -1,827 +0,0 @@ -/* - * Copyright (c) 2015 Cisco and/or its affiliates. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <vnet/ip/ip.h> -#include <math.h> - -/* 20 byte TCP + 12 bytes of options (timestamps) = 32 bytes */ -typedef struct { - u64 sequence_number; - f64 time_stamp; - u32 stream_index; - u32 unused[3]; -} __attribute__ ((packed)) rtt_test_header_t; - -typedef struct { - ip4_header_t ip4; - rtt_test_header_t rtt; - u8 payload[0]; -} __attribute__ ((packed)) rtt_test_packet_t; - -typedef struct { - ip4_address_t src_address, dst_address; - - f64 n_packets_to_send; - - f64 send_rate_bits_per_second; - f64 send_rate_packets_per_second; - - f64 packet_accumulator; - - u64 n_packets_sent; - - /* [0] from past, [1] in sequence, [2] from future. */ - u64 n_packets_received[3]; - - f64 tx_time_stream_created; - f64 tx_time_last_sent; - - f64 rx_ack_times[2]; - - u64 rx_expected_sequence_number; - - u32 n_bytes_payload; - - /* Including IP & L2 header. */ - u32 n_bytes_per_packet_on_wire; - - f64 ave_rtt, rms_rtt, rtt_count; - - u32 max_n_rx_ack_dts; - f64 * rx_ack_dts; - - u32 * rtt_histogram; - - vlib_packet_template_t packet_template; -} rtt_test_stream_t; - -typedef struct { - /* Size of encapsulation (e.g. 14 for ethernet). */ - u32 n_encap_bytes; - - u32 is_sender; - - u32 verbose; - - f64 rms_histogram_units; - - rtt_test_stream_t stream_history[32]; - u32 stream_history_index; - - rtt_test_stream_t * stream_pool; - - vlib_packet_template_t ack_packet_template; - u16 ack_packet_template_ip4_checksum; -} rtt_test_main_t; - -/* Use 2 IP protocols 253/254 which are assigned for experimental testing. */ -typedef enum { - RTT_TEST_IP_PROTOCOL_DATA = 253, - RTT_TEST_IP_PROTOCOL_ACK = 254, -} rtt_test_ip_protcol_t; - -always_inline void -rtt_test_stream_free (vlib_main_t * vm, rtt_test_main_t * tm, rtt_test_stream_t * s) -{ - vlib_packet_template_free (vm, &s->packet_template); - memset (&s->packet_template, 0, sizeof (s->packet_template)); - - tm->stream_history[tm->stream_history_index++] = s[0]; - if (tm->stream_history_index >= ARRAY_LEN (tm->stream_history)) - tm->stream_history_index = 0; - - s->rtt_histogram = 0; - pool_put (tm->stream_pool, s); -} - -rtt_test_main_t rtt_test_main; - -#define foreach_rtt_test_error \ - _ (packets_received, "packets received") \ - _ (listener_acks_dropped, "listener acks dropped") \ - _ (unknown_stream, "unknown stream") - -typedef enum { -#define _(sym,str) RTT_TEST_ERROR_##sym, - foreach_rtt_test_error -#undef _ - RTT_TEST_N_ERROR, -} rtt_test_error_t; - -static char * rtt_test_error_strings[] = { -#define _(sym,string) string, - foreach_rtt_test_error -#undef _ -}; - -typedef enum { - RTT_TEST_RX_NEXT_DROP, - RTT_TEST_RX_NEXT_ECHO, - RTT_TEST_RX_N_NEXT, -} rtt_test_rx_next_t; - -static uword -rtt_test_rx_data (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - rtt_test_main_t * tm = &rtt_test_main; - uword n_packets = frame->n_vectors; - u32 * from, * to_drop, * to_echo; - u32 n_left_from, n_left_to_drop, n_left_to_echo; - - from = vlib_frame_vector_args (frame); - n_left_from = n_packets; - - while (n_left_from > 0) - { - vlib_get_next_frame (vm, node, RTT_TEST_RX_NEXT_DROP, to_drop, n_left_to_drop); - vlib_get_next_frame (vm, node, RTT_TEST_RX_NEXT_ECHO, to_echo, n_left_to_echo); - - while (n_left_from > 0 && n_left_to_drop > 0 && n_left_to_echo > 0) - { - vlib_buffer_t * p0; - ip4_header_t * ip0; - rtt_test_header_t * r0; - rtt_test_packet_t * ack0; - ip_csum_t sum0; - u32 bi0; - - bi0 = to_drop[0] = from[0]; - - from += 1; - n_left_from -= 1; - to_drop += 1; - n_left_to_drop -= 1; - - p0 = vlib_get_buffer (vm, bi0); - ip0 = vlib_buffer_get_current (p0); - - r0 = ip4_next_header (ip0); - - p0->error = node->errors[RTT_TEST_ERROR_listener_acks_dropped]; - - ack0 = vlib_packet_template_get_packet (vm, &tm->ack_packet_template, to_echo); - - to_echo += 1; - n_left_to_echo -= 1; - - sum0 = tm->ack_packet_template_ip4_checksum; - - ack0->ip4.src_address = ip0->dst_address; - sum0 = ip_csum_add_even (sum0, ack0->ip4.src_address.as_u32); - - ack0->ip4.dst_address = ip0->src_address; - sum0 = ip_csum_add_even (sum0, ack0->ip4.dst_address.as_u32); - - ack0->ip4.checksum = ip_csum_fold (sum0); - - ASSERT (ack0->ip4.checksum == ip4_header_checksum (&ack0->ip4)); - - ack0->rtt = r0[0]; - } - - vlib_put_next_frame (vm, node, RTT_TEST_RX_NEXT_DROP, n_left_to_drop); - vlib_put_next_frame (vm, node, RTT_TEST_RX_NEXT_ECHO, n_left_to_echo); - } - - return frame->n_vectors; -} - -VLIB_REGISTER_NODE (rtt_test_rx_data_node) = { - .function = rtt_test_rx_data, - .name = "rtt-test-rx-data", - - .vector_size = sizeof (u32), - - .n_next_nodes = RTT_TEST_RX_N_NEXT, - .next_nodes = { - [RTT_TEST_RX_NEXT_DROP] = "error-drop", - [RTT_TEST_RX_NEXT_ECHO] = "ip4-input-no-checksum", - }, - - .n_errors = RTT_TEST_N_ERROR, - .error_strings = rtt_test_error_strings, -}; - -static uword -rtt_test_rx_ack (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - rtt_test_main_t * tm = &rtt_test_main; - uword n_packets = frame->n_vectors; - u32 * from, * to_drop; - u32 n_left_from, n_left_to_drop; - f64 now = vlib_time_now (vm); - vlib_node_runtime_t * error_node = vlib_node_get_runtime (vm, rtt_test_rx_data_node.index); - - from = vlib_frame_vector_args (frame); - n_left_from = n_packets; - - while (n_left_from > 0) - { - vlib_get_next_frame (vm, node, RTT_TEST_RX_NEXT_DROP, to_drop, n_left_to_drop); - - while (n_left_from > 0 && n_left_to_drop > 0) - { - vlib_buffer_t * p0; - ip4_header_t * ip0; - rtt_test_header_t * r0; - rtt_test_stream_t * s0; - u32 bi0, i0; - u64 rseq0, eseq0; - - i0 = 0; - bi0 = to_drop[0] = from[0]; - - from += 1; - n_left_from -= 1; - to_drop += 1; - n_left_to_drop -= 1; - - p0 = vlib_get_buffer (vm, bi0); - ip0 = vlib_buffer_get_current (p0); - - r0 = ip4_next_header (ip0); - - p0->error = error_node->errors[RTT_TEST_ERROR_listener_acks_dropped]; - - if (pool_is_free_index (tm->stream_pool, r0->stream_index)) - goto bad_stream_x1; - - s0 = pool_elt_at_index (tm->stream_pool, r0->stream_index); - - rseq0 = r0->sequence_number; - eseq0 = s0->rx_expected_sequence_number; - - if (rseq0 != eseq0) - goto out_of_sequence_x1; - - s0->rx_expected_sequence_number = rseq0 + 1; - s0->n_packets_received[1] += 1; - - vec_add1 (s0->rx_ack_dts, now - r0->time_stamp); - _vec_len (s0->rx_ack_dts) -= _vec_len (s0->rx_ack_dts) >= s0->max_n_rx_ack_dts; - - i0 = rseq0 != 0; - s0->rx_ack_times[i0] = now; - continue; - - bad_stream_x1: - { - ELOG_TYPE_DECLARE (e) = { - .format = "rtt-test: unknown stream %d", - .format_args = "i4", - }; - struct { u32 stream; } * ed; - ed = ELOG_DATA (&vm->elog_main, e); - ed->stream = r0->stream_index; - } - continue; - - out_of_sequence_x1: - i0 = (r0->sequence_number < s0->rx_expected_sequence_number - ? 0 - : (i0 ? 1 : 2)); - if (i0 != 1) - { - ELOG_TYPE_DECLARE (e) = { - .format = "rtt-test: out-of-seq expected %Ld got %Ld", - .format_args = "i8i8", - }; - struct { u64 expected, got; } * ed; - ed = ELOG_DATA (&vm->elog_main, e); - ed->expected = s0->rx_expected_sequence_number; - ed->got = r0->sequence_number; - } - - s0->rx_expected_sequence_number = i0 > 0 ? r0->sequence_number + 1 : s0->rx_expected_sequence_number; - - s0->n_packets_received[i0] += 1; - - i0 = r0->sequence_number > 0; - s0->rx_ack_times[i0] = now; - } - - vlib_put_next_frame (vm, node, RTT_TEST_RX_NEXT_DROP, n_left_to_drop); - } - - return frame->n_vectors; -} - -VLIB_REGISTER_NODE (rtt_test_rx_ack_node) = { - .function = rtt_test_rx_ack, - .name = "rtt-test-rx-ack", - - .vector_size = sizeof (u32), - - .n_next_nodes = RTT_TEST_RX_N_NEXT, - .next_nodes = { - [RTT_TEST_RX_NEXT_DROP] = "error-drop", - [RTT_TEST_RX_NEXT_ECHO] = "ip4-input-no-checksum", - }, -}; - -always_inline void -rtt_test_tx_packets (vlib_main_t * vm, - vlib_node_runtime_t * node, - rtt_test_stream_t * s, - f64 time_now, - uword n_packets_to_send) -{ - u32 * to_next, n_this_frame, n_left, n_trace, next, i; - rtt_test_packet_t * p; - vlib_buffer_t * b; - - next = 0; - while (n_packets_to_send > 0) - { - vlib_get_next_frame (vm, node, next, to_next, n_left); - - n_this_frame = clib_min (n_packets_to_send, n_left); - - for (i = 0; i < n_this_frame; i++) - { - p = vlib_packet_template_get_packet (vm, &s->packet_template, to_next + i); - p->rtt.time_stamp = time_now; - p->rtt.sequence_number = s->n_packets_sent + i; - } - - n_trace = vlib_get_trace_count (vm, node); - if (n_trace > 0) - { - u32 n = clib_min (n_trace, n_this_frame); - - vlib_set_trace_count (vm, node, n_trace - n); - for (i = 0; i < n_this_frame; i++) - { - b = vlib_get_buffer (vm, to_next[i]); - vlib_trace_buffer (vm, node, next, b, /* follow_chain */ 1); - } - } - - s->n_packets_sent += n_this_frame; - n_packets_to_send -= n_this_frame; - n_left -= n_this_frame; - - vlib_put_next_frame (vm, node, next, n_left); - } -} - -always_inline uword -rtt_test_stream_is_done (rtt_test_stream_t * s, f64 time_now) -{ - /* Need to send more packets? */ - if (s->n_packets_to_send > 0 && s->n_packets_sent < s->n_packets_to_send) - return 0; - - /* Received everything we've sent? */ - if (s->n_packets_received[0] + s->n_packets_received[1] + s->n_packets_received[2] >= s->n_packets_to_send) - return 1; - - /* No ACK received after 5 seconds of sending. */ - if (s->rx_ack_times[0] == 0 - && s->n_packets_sent > 0 - && time_now - s->tx_time_stream_created > 5) - return 1; - - /* No ACK received after 5 seconds of waiting? */ - if (time_now - s->rx_ack_times[1] > 5) - return 1; - - return 0; -} - -static_always_inline uword -rtt_test_tx_stream (vlib_main_t * vm, - vlib_node_runtime_t * node, - rtt_test_stream_t * s) -{ - rtt_test_main_t * tm = &rtt_test_main; - uword n_packets; - f64 time_now, dt; - - time_now = vlib_time_now (vm); - - if (rtt_test_stream_is_done (s, time_now)) - { - { - ELOG_TYPE_DECLARE (e) = { - .format = "rtt-test: done stream %d", - .format_args = "i4", - }; - struct { u32 stream_index; } * ed; - ed = ELOG_DATA (&vm->elog_main, e); - ed->stream_index = s - tm->stream_pool; - } - - rtt_test_stream_free (vm, tm, s); - if (pool_elts (tm->stream_pool) == 0) - vlib_node_set_state (vm, node->node_index, VLIB_NODE_STATE_DISABLED); - return 0; - } - - /* Apply rate limit. */ - dt = time_now - s->tx_time_last_sent; - s->tx_time_last_sent = time_now; - - n_packets = VLIB_FRAME_SIZE; - if (s->send_rate_packets_per_second > 0) - { - s->packet_accumulator += dt * s->send_rate_packets_per_second; - n_packets = s->packet_accumulator; - - /* Never allow accumulator to grow if we get behind. */ - s->packet_accumulator -= n_packets; - } - - /* Apply fixed limit. */ - if (s->n_packets_to_send > 0 - && s->n_packets_sent + n_packets > s->n_packets_to_send) - n_packets = s->n_packets_to_send - s->n_packets_sent; - - /* Generate up to one frame's worth of packets. */ - if (n_packets > VLIB_FRAME_SIZE) - n_packets = VLIB_FRAME_SIZE; - - if (n_packets > 0) - rtt_test_tx_packets (vm, node, s, time_now, n_packets); - - return n_packets; -} - -static uword -rtt_test_tx (vlib_main_t * vm, - vlib_node_runtime_t * node, - vlib_frame_t * frame) -{ - rtt_test_main_t * tm = &rtt_test_main; - rtt_test_stream_t * s; - uword n_packets = 0; - - pool_foreach (s, tm->stream_pool, ({ - n_packets += rtt_test_tx_stream (vm, node, s); - })); - - return n_packets; -} - -VLIB_REGISTER_NODE (rtt_test_tx_node) = { - .function = rtt_test_tx, - .name = "rtt-test-tx", - .type = VLIB_NODE_TYPE_INPUT, - .state = VLIB_NODE_STATE_DISABLED, - - .vector_size = sizeof (u32), - - .n_next_nodes = 1, - .next_nodes = { - [0] = "ip4-input-no-checksum", - }, -}; - -static void rtt_test_stream_compute (rtt_test_main_t * tm, rtt_test_stream_t * s) -{ - int i; - - /* Compute average and standard deviation of RTT time. */ - if (vec_len (s->rx_ack_dts) == 0) - return; - - { - f64 c = vec_len (s->rx_ack_dts); - - s->ave_rtt = s->rms_rtt = 0; - vec_foreach_index (i, s->rx_ack_dts) - { - f64 dt = s->rx_ack_dts[i]; - s->ave_rtt += dt; - s->rms_rtt += dt*dt; - } - s->ave_rtt /= c; - s->rms_rtt = sqrt (s->rms_rtt / c - s->ave_rtt*s->ave_rtt); - s->rtt_count = c; - } - - if (! tm->rms_histogram_units) - tm->rms_histogram_units = .1; - - /* Generate historgram. */ - vec_foreach_index (i, s->rx_ack_dts) - { - i32 bin = flt_round_nearest ((s->rx_ack_dts[i] - s->ave_rtt) / (tm->rms_histogram_units * s->rms_rtt)); - u32 ib = bin < 0 ? 2*(-bin) + 1 : 2 *bin; - vec_validate (s->rtt_histogram, ib); - s->rtt_histogram[ib] += 1; - } - - if (s->n_packets_sent >= s->n_packets_to_send) - vec_free (s->rx_ack_dts); -} - -static clib_error_t * -do_plot_stream (rtt_test_main_t * tm, rtt_test_stream_t * s, char * file_name, int n) -{ - FILE * out; - char * f; - clib_error_t * error = 0; - u32 i; - - f = (char *) format (0, "%s.%d%c", file_name, n, 0); - out = fopen (f, "w"); - - if (! out) - { - error = clib_error_return_unix (0, "open `%s'", f); - goto done; - } - - rtt_test_stream_compute (tm, s); - vec_foreach_index (i, s->rtt_histogram) - { - if (s->rtt_histogram[i] > 0) - { - i32 bi = (i & 1) ? -(i/2) : (i/2); - f64 dt = s->ave_rtt + (bi * tm->rms_histogram_units * s->rms_rtt); - fformat (out, "%.6e %.6e\n", - dt, s->rtt_histogram[i] / s->rtt_count); - } - } - clib_warning ("wrote `%s'", f); - - done: - vec_free (f); - fclose (out); - return error; -} - -static clib_error_t * -do_plot (rtt_test_main_t * tm, char * file_name) -{ - rtt_test_stream_t * s; - clib_error_t * error = 0; - int i, n; - - n = 0; - for (i = 0; i < ARRAY_LEN (tm->stream_history); i++) - { - s = tm->stream_history + i; - if (s->n_packets_sent > 0) - { - error = do_plot_stream (tm, s, file_name, n++); - if (error) - return error; - } - } - - pool_foreach (s, tm->stream_pool, ({ - error = do_plot_stream (tm, s, file_name, n++); - if (error) - return error; - })); - - return error; -} - -static clib_error_t * -rtt_test_command (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - rtt_test_main_t * tm = &rtt_test_main; - rtt_test_stream_t * s; - - { - char * file_name; - - if (unformat (input, "plot %s", &file_name)) - { - clib_error_t * e = do_plot (tm, file_name); - vec_free (file_name); - return e; - } - } - - pool_get (tm->stream_pool, s); - - memset (s, 0, sizeof (s[0])); - s->n_packets_to_send = 1; - s->send_rate_bits_per_second = 1e6; - s->n_bytes_payload = 1448; - s->max_n_rx_ack_dts = 0; - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "%U -> %U", - unformat_ip4_address, &s->src_address, - unformat_ip4_address, &s->dst_address)) - ; - else if (unformat (input, "count %f", &s->n_packets_to_send)) - ; - else if (unformat (input, "hist %d", &s->max_n_rx_ack_dts)) - ; - else if (unformat (input, "rate %f", &s->send_rate_bits_per_second)) - ; - else if (unformat (input, "size %d", &s->n_bytes_payload)) - ; - else - return clib_error_return (0, "parse error: %U", format_unformat_error, input); - } - - if (pool_elts (tm->stream_pool) == 1) - vlib_node_set_state (vm, rtt_test_tx_node.index, VLIB_NODE_STATE_POLLING); - - if (! s->max_n_rx_ack_dts) - s->max_n_rx_ack_dts = s->n_packets_to_send; - vec_validate (s->rx_ack_dts, s->max_n_rx_ack_dts - 1); - _vec_len (s->rx_ack_dts) = 0; - - s->tx_time_stream_created = vlib_time_now (vm); - s->tx_time_last_sent = s->tx_time_stream_created; - s->n_bytes_per_packet_on_wire - = (s->n_bytes_payload - + sizeof (rtt_test_header_t) - + sizeof (ip4_header_t) - + tm->n_encap_bytes); - - s->send_rate_packets_per_second = s->send_rate_bits_per_second / (s->n_bytes_per_packet_on_wire * BITS (u8)); - - { - rtt_test_packet_t * t; - int i; - - t = clib_mem_alloc_no_fail (sizeof (t[0]) + s->n_bytes_payload); - memset (t, 0, sizeof (t[0])); - - t->ip4.ip_version_and_header_length = 0x45; - t->ip4.length = clib_host_to_net_u16 (sizeof (t[0]) + s->n_bytes_payload); - t->ip4.flags_and_fragment_offset = clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT); - t->ip4.protocol = RTT_TEST_IP_PROTOCOL_DATA; - t->ip4.ttl = 64; - - t->ip4.src_address = s->src_address; - t->ip4.dst_address = s->dst_address; - - t->ip4.checksum = ip4_header_checksum (&t->ip4); - - t->rtt.stream_index = s - tm->stream_pool; - - for (i = 0; i < s->n_bytes_payload; i++) - t->payload[i] = i; - - vlib_packet_template_init (vm, &s->packet_template, - t, sizeof (t[0]) + s->n_bytes_payload, - /* alloc chunk size */ VLIB_FRAME_SIZE, - "rtt-test stream %d data", s - tm->stream_pool); - - clib_mem_free (t); - } - - { - ELOG_TYPE_DECLARE (e) = { - .format = "rtt-test: start stream %d", - .format_args = "i4", - }; - struct { u32 stream_index; } * ed; - ed = ELOG_DATA (&vm->elog_main, e); - ed->stream_index = s - tm->stream_pool; - } - - return 0; -} - -VLIB_CLI_COMMAND (rtt_test_cli_command, static) = { - .path = "test rtt", - .short_help = "Measure RTT test protocol", - .function = rtt_test_command, -}; - -static u8 * format_rtt_test_stream (u8 * s, va_list * args) -{ - rtt_test_stream_t * t = va_arg (*args, rtt_test_stream_t *); - uword indent = format_get_indent (s); - - s = format (s, "%U -> %U", - format_ip4_address, &t->src_address, - format_ip4_address, &t->dst_address); - - s = format (s, "\n%U sent %Ld, received: from-past %Ld in-sequence %Ld from-future %Ld", - format_white_space, indent, - t->n_packets_sent, - t->n_packets_received[0], t->n_packets_received[1], t->n_packets_received[2]); - - s = format (s, "\n%U rx-rate %.4e bits/sec", - format_white_space, indent, - (((f64) (t->n_packets_received[0] + t->n_packets_received[1] + t->n_packets_received[2]) * (f64) t->n_bytes_per_packet_on_wire * BITS (u8)) - / (t->rx_ack_times[1] - t->rx_ack_times[0]))); - - rtt_test_stream_compute (&rtt_test_main, t); - - s = format (s, "\n%U rtt %.4e +- %.4e", - format_white_space, indent, - t->ave_rtt, t->rms_rtt); - - return s; -} - -static clib_error_t * -rtt_show_command (vlib_main_t * vm, - unformat_input_t * input, - vlib_cli_command_t * cmd) -{ - rtt_test_main_t * tm = &rtt_test_main; - rtt_test_stream_t * s; - int i; - - for (i = 0; i < ARRAY_LEN (tm->stream_history); i++) - { - s = tm->stream_history + i; - if (s->n_packets_sent > 0) - vlib_cli_output (vm, "%U", format_rtt_test_stream, s); - } - - pool_foreach (s, tm->stream_pool, ({ - vlib_cli_output (vm, "%U", format_rtt_test_stream, s); - })); - - return 0; -} - -VLIB_CLI_COMMAND (rtt_show_cli_command, static) = { - .path = "show rtt", - .short_help = "Show RTT measurements", - .function = rtt_show_command, -}; - -static clib_error_t * -rtt_test_init (vlib_main_t * vm) -{ - rtt_test_main_t * tm = &rtt_test_main; - - ip4_register_protocol (RTT_TEST_IP_PROTOCOL_DATA, rtt_test_rx_data_node.index); - ip4_register_protocol (RTT_TEST_IP_PROTOCOL_ACK, rtt_test_rx_ack_node.index); - - { - rtt_test_packet_t ack; - - memset (&ack, 0, sizeof (ack)); - - ack.ip4.ip_version_and_header_length = 0x45; - ack.ip4.length = clib_host_to_net_u16 (sizeof (ack)); - ack.ip4.flags_and_fragment_offset = clib_host_to_net_u16 (IP4_HEADER_FLAG_DONT_FRAGMENT); - ack.ip4.protocol = RTT_TEST_IP_PROTOCOL_ACK; - ack.ip4.ttl = 64; - - ack.ip4.checksum = ip4_header_checksum (&ack.ip4); - tm->ack_packet_template_ip4_checksum = ack.ip4.checksum; - - vlib_packet_template_init (vm, &tm->ack_packet_template, - &ack, - sizeof (ack), - /* alloc chunk size */ VLIB_FRAME_SIZE, - "rtt-test ack"); - } - - return /* no error */ 0; -} - -static VLIB_INIT_FUNCTION (rtt_test_init); - -static clib_error_t * -rtt_test_config (vlib_main_t * vm, unformat_input_t * input) -{ - rtt_test_main_t * tm = &rtt_test_main; - clib_error_t * error = 0; - - tm->rms_histogram_units = .1; - tm->n_encap_bytes = - (14 /* ethernet header */ - + 8 /* preamble */ - + 12 /* inter packet gap */ - + 4 /* crc */); - tm->verbose = 1; - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (input, "rms-histogram-units %f", &tm->rms_histogram_units)) - ; - else if (unformat (input, "silent")) - tm->verbose = 0; - else - clib_error ("%U", format_unformat_error, input); - } - - return error; -} - -VLIB_CONFIG_FUNCTION (rtt_test_config, "rtt-test"); diff --git a/vnet/vnet/devices/dpdk/threads.c b/vnet/vnet/devices/dpdk/threads.c index aa32f100..b1f13ef3 100644 --- a/vnet/vnet/devices/dpdk/threads.c +++ b/vnet/vnet/devices/dpdk/threads.c @@ -291,88 +291,10 @@ VLIB_REGISTER_THREAD (io_thread_reg, static) = { }; #endif -static void vl_api_rpc_call_t_handler (vl_api_rpc_call_t * mp) -{ - vl_api_rpc_reply_t * rmp; - int (*fp)(void *); - i32 rv = 0; - vlib_main_t * vm = vlib_get_main(); - - if (mp->function == 0) - { - rv = -1; - clib_warning ("rpc NULL function pointer"); - } - - else - { - if (mp->need_barrier_sync) - vlib_worker_thread_barrier_sync (vm); - - fp = (void *)(mp->function); - rv = (*fp)(mp->data); - - if (mp->need_barrier_sync) - vlib_worker_thread_barrier_release (vm); - } - - if (mp->send_reply) - { - unix_shared_memory_queue_t * q = - vl_api_client_index_to_input_queue (mp->client_index); - if (q) - { - rmp = vl_msg_api_alloc_as_if_client (sizeof (*rmp)); - rmp->_vl_msg_id = ntohs (VL_API_RPC_REPLY); - rmp->context = mp->context; - rmp->retval = rv; - vl_msg_api_send_shmem (q, (u8 *)&rmp); - } - } - if (mp->multicast) - { - clib_warning ("multicast not yet implemented..."); - } -} - -static void vl_api_rpc_reply_t_handler (vl_api_rpc_reply_t * mp) -{ clib_warning ("unimplemented"); } - -void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length) -{ - vl_api_rpc_call_t * mp; - api_main_t *am = &api_main; - vl_shmem_hdr_t *shmem_hdr = am->shmem_hdr; - - mp = vl_msg_api_alloc_as_if_client (sizeof (*mp) + data_length); - memset (mp, 0, sizeof (*mp)); - memcpy (mp->data, data, data_length); - mp->_vl_msg_id = ntohs (VL_API_RPC_CALL); - mp->function = (u64)fp; - mp->need_barrier_sync = 1; - - /* Use the "normal" control-plane mechanism for the main thread */ - vl_msg_api_send_shmem (shmem_hdr->vl_input_queue, (u8 *)&mp); -} - - -#define foreach_rpc_api_msg \ -_(RPC_CALL,rpc_call) \ -_(RPC_REPLY,rpc_reply) - static clib_error_t * -rpc_api_hookup (vlib_main_t *vm) +dpdk_thread_init (vlib_main_t *vm) { -#define _(N,n) \ - vl_msg_api_set_handlers(VL_API_##N, #n, \ - vl_api_##n##_t_handler, \ - vl_noop_handler, \ - vl_noop_handler, \ - vl_api_##n##_t_print, \ - sizeof(vl_api_##n##_t), 0 /* do not trace */); - foreach_rpc_api_msg; -#undef _ - return 0; + return (0); } -VLIB_API_INIT_FUNCTION(rpc_api_hookup); +VLIB_INIT_FUNCTION(dpdk_thread_init); diff --git a/vnet/vnet/devices/dpdk/threads.h b/vnet/vnet/devices/dpdk/threads.h index 8f0fcbdb..f2b0532b 100644 --- a/vnet/vnet/devices/dpdk/threads.h +++ b/vnet/vnet/devices/dpdk/threads.h @@ -17,8 +17,6 @@ #include <vnet/vnet.h> -void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length); - typedef void (*dpdk_worker_thread_callback_t) (vlib_main_t *vm); void dpdk_worker_thread (vlib_worker_thread_t * w, diff --git a/vpp/vnet/main.c b/vpp/vnet/main.c index fb981605..09adfea3 100644 --- a/vpp/vnet/main.c +++ b/vpp/vnet/main.c @@ -65,18 +65,11 @@ vpe_main_init (vlib_main_t * vm) if ((error = vlib_call_init_function (vm, lisp_gpe_init))) return error; -#if DPDK == 0 - if ((error = vlib_call_init_function (vm, ixge_init))) - return error; - if ((error = vlib_call_init_function (vm, ixgev_init))) - return error; - if ((error = vlib_call_init_function (vm, ige_init))) - return error; - if ((error = vlib_call_init_function (vm, vice_init))) - return error; -#else +#if DPDK == 1 if ((error = vlib_call_init_function (vm, dpdk_init))) return error; + if ((error = vlib_call_init_function (vm, dpdk_thread_init))) + return error; if ((error = vlib_call_init_function (vm, vhost_user_init))) return error; if ((error = vlib_call_init_function (vm, ipsec_init))) |