aboutsummaryrefslogtreecommitdiffstats
path: root/tests/vpp/perf
AgeCommit message (Collapse)AuthorFilesLines
2018-02-15FIX: 10ge2p1x520-eth-l2bdscale100kmaclrn-ndrpdrdisc.robotJan Gelety1-1/+1
- tc17-9000B-4t4c-eth-l2bdscale100kmaclrn-ndrdisc Change-Id: I605f4903deb07f3a29944348cb32ac0a6747cb09 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2018-02-12FIX: Missing KW in suite setupPeter Mikus44-0/+44
Change-Id: I278cb8a5381735694bad73031e534b080414305b Signed-off-by: Peter Mikus <pmikus@cisco.com>
2018-02-09Disable all plugins except DPDK by defaultJan Gelety92-182/+326
- enable corresponding plugin for ACL, NAT, MEMIF tests Change-Id: Ie8bfdcbf1734283b6412ef3015215a00ce3ebdf6 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2018-02-09Update the binary steps for perf test cases.Peter Mikus145-2559/+2514
- Reduce binary step fof: 64B -> 50Kpps 1518B -> 50Kpps 9000B -> 10Kpps IMIX -> 50Kpps Change-Id: Id88bff7b1c37b2a03583dd27ca3db720ec7ae4a2 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2018-01-17CSIT-675: SRv6 performance testsJan Gelety4-0/+758
- update L1 KWs - update L2 KWs - tests with one SID (no SRH insertion) - tests with two SIDs (SRH inserted) and decapsulation - tests with two SIDs (SRH inserted) without decapsulation - enabled packet traces and logged packet traces in the test case tear down if test failed Change-Id: I3a0f4c350eed3f42509c6d49e832faa78fe64dbb Signed-off-by: Jan Gelety <jgelety@cisco.com>
2018-01-16CSIT-898: WRK improvmentsTibor Frank1-7/+15
Change-Id: I92aafaaedce5891727a983b8cf024a0fb0db7524 Signed-off-by: Tibor Frank <tifrank@cisco.com>
2018-01-15FIX: Naming of test casesPeter Mikus17-236/+237
- Fix naming of VM testcases Change-Id: I1bf78f5f4ee60dd061a63280624ada9d73b34518 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2018-01-10CSIT-866: wrk onboarding in CSITTibor Frank1-0/+127
- CSIT-867: Low Level Description - CSIT-868: wrk traffic profile - parsing - CSIT-869: wrk implementation into CSIT Change-Id: I65e1037f5ae05b3a5b2020e4a6c54462766ae1b4 Signed-off-by: Tibor Frank <tifrank@cisco.com>
2018-01-08Update NDRCHK and PDRCHK ratesPeter Mikus10-20/+20
Change-Id: Ia51d29704d35e2c9f93dcbd1bccc355c9cf64419 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2018-01-04Fix doc in NAT44 tests.Tibor Frank7-82/+0
Change-Id: I2b4764c9da105564bd9e240bf92251007c0f9461 Signed-off-by: Tibor Frank <tifrank@cisco.com>
2017-12-30FIX: COP White List test casesPeter Mikus2-10/+9
Change-Id: I78f798da2e4dc7b4c8ee10b6f920687a279301b0 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-12-15CSIT-861: SW cryptodev perf testsJan Gelety5-193/+904
Change-Id: I687216ca43569542d38be681ca04c898010fc65d Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-12-14Update NestedVM to 1.7 in perf tests.Peter Mikus1-1/+1
Change-Id: If77b30e4597d24d1d44f1f60627b6b21b572bcfd Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-10-23FIX: IPSec tunnel interfaceJan Gelety4-96/+96
- add following line per interface tunnel: set int unnum <ipsec> use <interface> Change-Id: Iff75f27b7cf25f3d24eea92366b1fd4a718c253b Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-10-20Rename all container based test following name conventionsPeter Mikus3-12/+12
Change-Id: I84f6da2bede47e7ae35e6b4911d425d2402dbd1b Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-10-19FIX: apply changes implemented for FIB settingsJan Gelety4-108/+217
Change-Id: I00c3407f4324e282c438cb8fcd44470c331089c5 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-10-12CSIT-748 vnf-agent integrationPeter Mikus1-0/+1
CSIT-773 Implement RF keywords for k8s - Implementation of Test Suite Setup for Ligato vnf-agent testing - Implementation of KubernetesUtil for controlling kubectl - Yaml templates for L2XC topology with 1cswitch and 1cnf - Yaml templates for L2BD topology with 1cswitch and 1cnf - ligato bootstrap script for creating vnf-agent image Change-Id: Iebefde0eb984a27a0afcdf29fe549ca4edf8a61e Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-10-11CSIT-778: Add mac-ip binding acl l2bd perf testJan Gelety9-0/+1593
Change-Id: Iaced68458b0e4070f861be7854ee428ae8ca4e13 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-10-11CSIT-672: SNAT44 multi-thread multi-core perf testsTibor Frank8-667/+1614
- re-write existing tests using templates - add 2t2c, 4t4c tests Change-Id: I7061f4cfe2304d625de6afcb85cad30695fe6faa Signed-off-by: Tibor Frank <tifrank@cisco.com>
2017-10-09CSIT-768: Refactor Python container librariesPeter Mikus3-31/+261
CSIT-769: Implement L2 RF keywords for container orchestration Change-Id: I7637d1ecc3a45111522b8d6c578b3f88369aff6b Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-09-22CSIT-796: l2bd-memif perf testsJan Gelety1-0/+233
Change-Id: Ic714fa7baec49dcba1a8eb6a578183c6771e3493 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-09-04CSIT-786 L2FIB scale testingPeter Mikus7-76/+1882
L2FIB scale testing for 10k, 100k, 1m FIB entries ./l2: 10ge2p1x520-eth-l2bdscale10kmaclrn-ndrpdrdisc.robot 10ge2p1x520-eth-l2bdscale100kmaclrn-ndrpdrdisc.robot 10ge2p1x520-eth-l2bdscale1mmaclrn-ndrpdrdisc.robot 10ge2p1x520-eth-l2bdscale10kmaclrn-eth-2vhostvr1024-1vm-cfsrr1-ndrpdrdisc 10ge2p1x520-eth-l2bdscale100kmaclrn-eth-2vhostvr1024-1vm-cfsrr1-ndrpdrdisc 10ge2p1x520-eth-l2bdscale1mmaclrn-eth-2vhostvr1024-1vm-cfsrr1-ndrpdrdisc Change-Id: I7e3884bd5ab5294c289030a3465ec5b6def83cf7 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-08-28FIX: SNAT -> NAT renaming of APIPeter Mikus7-137/+137
- Based on https://gerrit.fd.io/r/#/c/8146/ Change-Id: I774483c7e2b419a9b9b6be78812ecf53a5c91eab Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-08-09CSIT-767: Add acl 64B 4t4c perf testsJan Gelety72-0/+1728
Change-Id: Id1b187c195c955d0e533d8d6864fff6a3fa8332e Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-08-07Use 100kpps step for ACL 64B perf testsJan Gelety72-576/+576
ACL 64B tests take a long time. Usage of 100kpps will provide results with adequate accurancy and test exectuion time. Change-Id: I6818963f3ce16b9aaae72cf579294f87d10a24a9 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-08-01CSIT-699: Add l2bd+dot1q perf testsJan Gelety1-0/+316
Change-Id: I3d8cbb235918331b3c60147f7870a4aa90036748 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-26FIX: typo in tc02-64B-1t1c-ethip4udp-ip4base-iacl50-stateful-flows100k-pdrdiscJan Gelety1-1/+1
Change-Id: I31db1ee3f661715e9066035bdc4819fdc9171bb7 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-24FIX: add missing PDRDISC tagJan Gelety4-8/+8
Change-Id: Ide3963cb7d776d94f512009b9f34c6b4b6554253 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-20FIX: 10ge2p1x520-ethip4-ip4base-eth-2vhostvr256-1vm-ndrpdrdiscJan Gelety1-1/+1
Change-Id: I5ca0649875c74bcd86106e53ba77d64f833cf28f Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-20FIX: fix of multiple perf test issuesJan Gelety76-149/+216
Change-Id: I24c823352b2832eb6da2aad0fd70570beb990f3f Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-20Fix order of TC blocks in l2bd alc perf testJan Gelety36-540/+504
Change-Id: I7862ef59813b6fd2f9b35897e04b4b9785e189e8 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-19FIX: CSIT rls1707 Report - Update IIIPeter Mikus6-0/+6
Change-Id: Ic857e004136b2d936c2a8affb779ada238eb007c Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-07-19CSIT-704: Add ACL IP4BASE perf testsJan Gelety36-0/+5292
Change-Id: I1fada28f2855534faf3b3051a3efe1cbb4dcdd03 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-18CSIT-703: Add ACL 2t2c perf test casesJan Gelety40-1284/+5292
Change-Id: I51f6015681d1fc62da56cf1cca110f7a4c82ba10 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-18FIX: Vhost taggingPeter Mikus9-9/+9
Change-Id: Id2111bdf45dd88e28c25917a3519ba59f3fad550 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-07-18FIX: Vhost 1024 - typoPeter Mikus1-18/+18
Change-Id: I341b8280dfb87e620387b3d7cbf3fc2019c85a53 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-07-17FIX: remove previous QEMU build when needed to change qszJan Gelety28-27/+350
Change-Id: I949f8800b45354c205c5a5d36ab2abeeb93409dc Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-14Fix: Memif IMIX frame size test casePeter Mikus1-3/+2
Fix the variable for calculating the IMIX_v4_1 in traffic profile. Change-Id: Ia5e643c0ec2c9cd67d4506b081a919f836ac1b26 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-07-12CSIT-688 Create test cases for memifPeter Mikus1-0/+233
Change-Id: Ia95850af4883474a0929df8e5269b59b3de95087 Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-07-06CSIT-622: Stateful Security Groups perf testsJan Gelety4-0/+1284
1. add L2BD iACL statefull and stateless tests with 1, 10 and 50 not-hitting ACEs in combination with 100, 10k and 100k flows per direction 2. add L2BD oACL statefull and stateless tests with 1, 10 and 50 not-hitting ACEs in combination with 100, 10k and 100k flows per direction Change-Id: Ia38589aa81b50c5ccdf2813ad6fadd22b46fffeb Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-06CSIT-660: add vring1024 tuned CFS for vpp workers and guest-testpmdJan Gelety3-0/+998
- add vhost tests (L2XBD, L2XC and IP4BASE) with vring set to 1024 and tuned CFS setting Change-Id: Ief8b4b86cdecfa39bf8cf0ec90fb844edfc6f396 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-06CSIT-661: re-add vring256 tuned CFS for vpp workers and guest-testpmdJan Gelety10-62/+2141
1. add vhost tests (L2XBD, L2XC and IP4BASE) with vring set to 256 and tuned CFS setting 2. add vhost tests (L2XBD, L2XC and IP4BASE) with vring set to 256 and default CFS setting Change-Id: I25aae6839d3e621316d35f5c9525389a6faabd56 Signed-off-by: Jan Gelety <jgelety@cisco.com>
2017-07-04XL710 Configure rxd/txd 2048Peter Mikus13-74/+251
Configure RX-desc and TX-desc to 2048 for FVL XL710 cards. Change-Id: I1876f332bdc6100bf24f2b2317de33c0d1a4c9bf Signed-off-by: Peter Mikus <pmikus@cisco.com>
2017-06-30CSIT-619 HC Test: Honeycomb performance testing - initial commitselias4-0/+332
- keywords and scripts for HC performance testing setup - basic performance suite: operational data read - traffic script and keywords used in tests Change-Id: Ic0290be73a7c925ea2561f8cd2524c5cb83fcda2 Signed-off-by: selias <samelias@cisco.com>
2017-06-29CSIT-687: Directory structure reorganizationTibor Frank99-0/+35057
Change-Id: I772c9e214be2461adf58124998d272e7d795220f Signed-off-by: Tibor Frank <tifrank@cisco.com> Signed-off-by: Maciek Konstantynowicz <mkonstan@cisco.com>
s="n">vl_api_registration_t *sock_rp; clib_file_main_t *fm = &file_main; clib_error_t *error; clib_file_t *cf; cf = vl_api_registration_file (rp); ASSERT (rp->registration_type > REGISTRATION_TYPE_SHMEM); if (msg_id >= vec_len (am->api_trace_cfg)) { clib_warning ("id out of range: %d", msg_id); vl_msg_api_free ((void *) elem); return; } sock_rp = pool_elt_at_index (sm->registration_pool, rp->vl_api_registration_pool_index); ASSERT (sock_rp); /* Add the msgbuf_t to the output vector */ vec_add (sock_rp->output_vector, (u8 *) mb, sizeof (*mb)); /* Try to send the message and save any error like * we do in the input epoll loop */ vec_add (sock_rp->output_vector, elem, ntohl (mb->data_len)); error = clib_file_write (cf); unix_save_error (&unix_main, error); /* If we didn't finish sending everything, wait for tx space */ if (vec_len (sock_rp->output_vector) > 0 && !(cf->flags & UNIX_FILE_DATA_AVAILABLE_TO_WRITE)) { cf->flags |= UNIX_FILE_DATA_AVAILABLE_TO_WRITE; fm->file_update (cf, UNIX_FILE_UPDATE_MODIFY); } #if CLIB_DEBUG > 1 output_length = sizeof (*mb) + ntohl (mb->data_len); clib_warning ("wrote %u bytes to fd %d", output_length, cf->file_descriptor); #endif vl_msg_api_free ((void *) elem); } void vl_socket_free_registration_index (u32 pool_index) { int i; vl_api_registration_t *rp; if (pool_is_free_index (socket_main.registration_pool, pool_index)) { clib_warning ("main pool index %d already free", pool_index); return; } rp = pool_elt_at_index (socket_main.registration_pool, pool_index); ASSERT (rp->registration_type != REGISTRATION_TYPE_FREE); for (i = 0; i < vec_len (rp->additional_fds_to_close); i++) if (close (rp->additional_fds_to_close[i]) < 0) clib_unix_warning ("close"); vec_free (rp->additional_fds_to_close); vec_free (rp->name); vec_free (rp->unprocessed_input); vec_free (rp->output_vector); rp->registration_type = REGISTRATION_TYPE_FREE; pool_put (socket_main.registration_pool, rp); } void vl_socket_process_api_msg (clib_file_t * uf, vl_api_registration_t * rp, i8 * input_v) { msgbuf_t *mbp = (msgbuf_t *) input_v; u8 *the_msg = (u8 *) (mbp->data); socket_main.current_uf = uf; socket_main.current_rp = rp; vl_msg_api_socket_handler (the_msg); socket_main.current_uf = 0; socket_main.current_rp = 0; } clib_error_t * vl_socket_read_ready (clib_file_t * uf) { clib_file_main_t *fm = &file_main; vlib_main_t *vm = vlib_get_main (); vl_api_registration_t *rp; int n; i8 *msg_buffer = 0; u8 *data_for_process; u32 msg_len; u32 save_input_buffer_length = vec_len (socket_main.input_buffer); vl_socket_args_for_process_t *a; msgbuf_t *mbp; int mbp_set = 0; rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data); n = read (uf->file_descriptor, socket_main.input_buffer, vec_len (socket_main.input_buffer)); if (n <= 0 && errno != EAGAIN) { clib_file_del (fm, uf); if (!pool_is_free (socket_main.registration_pool, rp)) { u32 index = rp - socket_main.registration_pool; vl_socket_free_registration_index (index); } else { clib_warning ("client index %d already free?", rp->vl_api_registration_pool_index); } return 0; } _vec_len (socket_main.input_buffer) = n; /* * Look for bugs here. This code is tricky because * data read from a stream socket does not honor message * boundaries. In the case of a long message (>4K bytes) * we have to do (at least) 2 reads, etc. */ do { if (vec_len (rp->unprocessed_input)) { vec_append (rp->unprocessed_input, socket_main.input_buffer); msg_buffer = rp->unprocessed_input; } else { msg_buffer = socket_main.input_buffer; mbp_set = 0; } if (mbp_set == 0) { /* Any chance that we have a complete message? */ if (vec_len (msg_buffer) <= sizeof (msgbuf_t)) goto save_and_split; mbp = (msgbuf_t *) msg_buffer; msg_len = ntohl (mbp->data_len); mbp_set = 1; } /* We don't have the entire message yet. */ if (mbp_set == 0 || (msg_len + sizeof (msgbuf_t)) > vec_len (msg_buffer)) { save_and_split: /* if we were using the input buffer save the fragment */ if (msg_buffer == socket_main.input_buffer) { ASSERT (vec_len (rp->unprocessed_input) == 0); vec_validate (rp->unprocessed_input, vec_len (msg_buffer) - 1); clib_memcpy_fast (rp->unprocessed_input, msg_buffer, vec_len (msg_buffer)); _vec_len (rp->unprocessed_input) = vec_len (msg_buffer); } _vec_len (socket_main.input_buffer) = save_input_buffer_length; return 0; } data_for_process = (u8 *) vec_dup (msg_buffer); _vec_len (data_for_process) = (msg_len + sizeof (msgbuf_t)); pool_get (socket_main.process_args, a); a->clib_file = uf; a->regp = rp; a->data = data_for_process; vlib_process_signal_event (vm, vl_api_clnt_node.index, SOCKET_READ_EVENT, a - socket_main.process_args); if (n > (msg_len + sizeof (*mbp))) vec_delete (msg_buffer, msg_len + sizeof (*mbp), 0); else _vec_len (msg_buffer) = 0; n -= msg_len + sizeof (msgbuf_t); msg_len = 0; mbp_set = 0; } while (n > 0); _vec_len (socket_main.input_buffer) = save_input_buffer_length; return 0; } clib_error_t * vl_socket_write_ready (clib_file_t * uf) { clib_file_main_t *fm = &file_main; vl_api_registration_t *rp; int n; rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data); /* Flush output vector. */ size_t total_bytes = vec_len (rp->output_vector); size_t bytes_to_send, remaining_bytes = total_bytes; void *p = rp->output_vector; while (remaining_bytes > 0) { bytes_to_send = remaining_bytes > 4096 ? 4096 : remaining_bytes; n = write (uf->file_descriptor, p, bytes_to_send); if (n < 0) { if (errno == EAGAIN) { break; } #if DEBUG > 2 clib_warning ("write error, close the file...\n"); #endif clib_file_del (fm, uf); vl_socket_free_registration_index (rp - socket_main.registration_pool); return 0; } remaining_bytes -= bytes_to_send; p += bytes_to_send; } vec_delete (rp->output_vector, total_bytes - remaining_bytes, 0); if (vec_len (rp->output_vector) <= 0 && (uf->flags & UNIX_FILE_DATA_AVAILABLE_TO_WRITE)) { uf->flags &= ~UNIX_FILE_DATA_AVAILABLE_TO_WRITE; fm->file_update (uf, UNIX_FILE_UPDATE_MODIFY); } return 0; } clib_error_t * vl_socket_error_ready (clib_file_t * uf) { vl_api_registration_t *rp; clib_file_main_t *fm = &file_main; rp = pool_elt_at_index (socket_main.registration_pool, uf->private_data); clib_file_del (fm, uf); vl_socket_free_registration_index (rp - socket_main.registration_pool); return 0; } void socksvr_file_add (clib_file_main_t * fm, int fd) { vl_api_registration_t *rp; clib_file_t template = { 0 }; pool_get (socket_main.registration_pool, rp); clib_memset (rp, 0, sizeof (*rp)); template.read_function = vl_socket_read_ready; template.write_function = vl_socket_write_ready; template.error_function = vl_socket_error_ready; template.file_descriptor = fd; template.private_data = rp - socket_main.registration_pool; rp->registration_type = REGISTRATION_TYPE_SOCKET_SERVER; rp->vl_api_registration_pool_index = rp - socket_main.registration_pool; rp->clib_file_index = clib_file_add (fm, &template); } static clib_error_t * socksvr_accept_ready (clib_file_t * uf) { clib_file_main_t *fm = &file_main; socket_main_t *sm = &socket_main; clib_socket_t *sock = &sm->socksvr_listen_socket; clib_socket_t client; clib_error_t *error; error = clib_socket_accept (sock, &client); if (error) return error; socksvr_file_add (fm, client.fd); return 0; } static clib_error_t * socksvr_bogus_write (clib_file_t * uf) { clib_warning ("why am I here?"); return 0; } /* * vl_api_sockclnt_create_t_handler */ void vl_api_sockclnt_create_t_handler (vl_api_sockclnt_create_t * mp) { vl_api_registration_t *regp; vl_api_sockclnt_create_reply_t *rp; api_main_t *am = &api_main; hash_pair_t *hp; int rv = 0; u32 nmsg = hash_elts (am->msg_index_by_name_and_crc); u32 i = 0; regp = socket_main.current_rp; ASSERT (regp->registration_type == REGISTRATION_TYPE_SOCKET_SERVER); regp->name = format (0, "%s%c", mp->name, 0); u32 size = sizeof (*rp) + (nmsg * sizeof (vl_api_message_table_entry_t)); rp = vl_msg_api_alloc_zero (size); rp->_vl_msg_id = htons (VL_API_SOCKCLNT_CREATE_REPLY); rp->index = htonl (sock_api_registration_handle (regp)); rp->context = mp->context; rp->response = htonl (rv); rp->count = htons (nmsg); /* *INDENT-OFF* */ hash_foreach_pair (hp, am->msg_index_by_name_and_crc, ({ rp->message_table[i].index = htons(hp->value[0]); strncpy_s((char *)rp->message_table[i].name, 64 /* bytes of space at dst */, (char *)hp->key, 64-1 /* chars to copy, without zero byte. */); i++; })); /* *INDENT-ON* */ vl_api_send_msg (regp, (u8 *) rp); } /* * vl_api_sockclnt_delete_t_handler */ void vl_api_sockclnt_delete_t_handler (vl_api_sockclnt_delete_t * mp) { vl_api_registration_t *regp; vl_api_sockclnt_delete_reply_t *rp; regp = vl_api_client_index_to_registration (mp->client_index); if (!regp) return; u32 reg_index = socket_api_registration_handle_to_index (ntohl (mp->index)); rp = vl_msg_api_alloc (sizeof (*rp)); rp->_vl_msg_id = htons (VL_API_SOCKCLNT_DELETE_REPLY); rp->context = mp->context; if (!pool_is_free_index (socket_main.registration_pool, reg_index)) { rp->response = htonl (1); vl_api_send_msg (regp, (u8 *) rp); vl_api_registration_del_file (regp); vl_socket_free_registration_index (reg_index); } else { clib_warning ("unknown client ID %d", reg_index); rp->response = htonl (-1); vl_api_send_msg (regp, (u8 *) rp); } } clib_error_t * vl_sock_api_send_fd_msg (int socket_fd, int fds[], int n_fds) { struct msghdr mh = { 0 }; struct iovec iov[1]; char ctl[CMSG_SPACE (sizeof (int) * n_fds)]; struct cmsghdr *cmsg; char *msg = "fdmsg"; int rv; iov[0].iov_base = msg; iov[0].iov_len = strlen (msg); mh.msg_iov = iov; mh.msg_iovlen = 1; clib_memset (&ctl, 0, sizeof (ctl)); mh.msg_control = ctl; mh.msg_controllen = sizeof (ctl); cmsg = CMSG_FIRSTHDR (&mh); cmsg->cmsg_len = CMSG_LEN (sizeof (int) * n_fds); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; clib_memcpy_fast (CMSG_DATA (cmsg), fds, sizeof (int) * n_fds); rv = sendmsg (socket_fd, &mh, 0); if (rv < 0) return clib_error_return_unix (0, "sendmsg"); return 0; } vl_api_shm_elem_config_t * vl_api_make_shm_config (vl_api_sock_init_shm_t * mp) { vl_api_shm_elem_config_t *config = 0, *c; u64 cfg; int i; if (!mp->nitems) { vec_validate (config, 6); config[0].type = VL_API_VLIB_RING; config[0].size = 256; config[0].count = 32; config[1].type = VL_API_VLIB_RING; config[1].size = 1024; config[1].count = 16; config[2].type = VL_API_VLIB_RING; config[2].size = 4096; config[2].count = 2; config[3].type = VL_API_CLIENT_RING; config[3].size = 256; config[3].count = 32; config[4].type = VL_API_CLIENT_RING; config[4].size = 1024; config[4].count = 16; config[5].type = VL_API_CLIENT_RING; config[5].size = 4096; config[5].count = 2; config[6].type = VL_API_QUEUE; config[6].count = 128; config[6].size = sizeof (uword); } else { vec_validate (config, mp->nitems - 1); for (i = 0; i < mp->nitems; i++) { cfg = mp->configs[i]; /* Pretty much a hack but it avoids defining our own api type * in memclnt.api */ c = (vl_api_shm_elem_config_t *) & cfg; config[i].type = c->type; config[i].count = c->count; config[i].size = c->size; } } return config; } /* * Bootstrap shm api using the socket api */ void vl_api_sock_init_shm_t_handler (vl_api_sock_init_shm_t * mp) { vl_api_sock_init_shm_reply_t *rmp; ssvm_private_t _memfd_private, *memfd = &_memfd_private; svm_map_region_args_t _args, *a = &_args; vl_api_registration_t *regp; api_main_t *am = &api_main; svm_region_t *vlib_rp; clib_file_t *cf; vl_api_shm_elem_config_t *config = 0; vl_shmem_hdr_t *shmem_hdr; int rv, tries = 1000; regp = vl_api_client_index_to_registration (mp->client_index); if (regp == 0) { clib_warning ("API client disconnected"); return; } if (regp->registration_type != REGISTRATION_TYPE_SOCKET_SERVER) { rv = -31; /* VNET_API_ERROR_INVALID_REGISTRATION */ goto reply; } /* * Set up a memfd segment of the requested size wherein the * shmem data structures will be initialized */ clib_memset (memfd, 0, sizeof (*memfd)); memfd->ssvm_size = mp->requested_size; memfd->requested_va = 0ULL; memfd->i_am_master = 1; memfd->name = format (0, "%s%c", regp->name, 0); if ((rv = ssvm_master_init_memfd (memfd))) goto reply; /* Remember to close this fd when the socket connection goes away */ vec_add1 (regp->additional_fds_to_close, memfd->fd); /* * Create a plausible svm_region in the memfd backed segment */ clib_memset (a, 0, sizeof (*a)); a->baseva = memfd->sh->ssvm_va + MMAP_PAGESIZE; a->size = memfd->ssvm_size - MMAP_PAGESIZE; /* $$$$ might want a different config parameter */ a->pvt_heap_size = am->api_pvt_heap_size; a->flags = SVM_FLAGS_MHEAP; svm_region_init_mapped_region (a, (svm_region_t *) a->baseva); /* * Part deux, initialize the svm_region_t shared-memory header * api allocation rings, and so on. */ config = vl_api_make_shm_config (mp); vlib_rp = (svm_region_t *) a->baseva; vl_init_shmem (vlib_rp, config, 1 /* is_vlib (dont-care) */ , 1 /* is_private */ ); /* Remember who created this. Needs to be post vl_init_shmem */ shmem_hdr = (vl_shmem_hdr_t *) vlib_rp->user_ctx; shmem_hdr->clib_file_index = vl_api_registration_file_index (regp); vec_add1 (am->vlib_private_rps, vlib_rp); memfd->sh->ready = 1; vec_free (config); /* Recompute the set of input queues to poll in memclnt_process */ vec_reset_length (vl_api_queue_cursizes); reply: rmp = vl_msg_api_alloc (sizeof (*rmp)); rmp->_vl_msg_id = htons (VL_API_SOCK_INIT_SHM_REPLY); rmp->context = mp->context; rmp->retval = htonl (rv); /* * Note: The reply message needs to make it out the back door * before we send the magic fd message. That's taken care of by * the send function. */ vl_socket_api_send (regp, (u8 *) rmp); if (rv != 0) return; /* Send the magic "here's your sign (aka fd)" socket message */ cf = vl_api_registration_file (regp); /* Wait for reply to be consumed before sending the fd */ while (tries-- > 0) { int bytes; rv = ioctl (cf->file_descriptor, TIOCOUTQ, &bytes); if (rv < 0) { clib_unix_warning ("ioctl returned"); break; } if (bytes == 0) break; usleep (1e3); } vl_sock_api_send_fd_msg (cf->file_descriptor, &memfd->fd, 1); } #define foreach_vlib_api_msg \ _(SOCKCLNT_CREATE, sockclnt_create) \ _(SOCKCLNT_DELETE, sockclnt_delete) \ _(SOCK_INIT_SHM, sock_init_shm) clib_error_t * vl_sock_api_init (vlib_main_t * vm) { clib_file_main_t *fm = &file_main; clib_file_t template = { 0 }; vl_api_registration_t *rp; socket_main_t *sm = &socket_main; clib_socket_t *sock = &sm->socksvr_listen_socket; clib_error_t *error; /* If not explicitly configured, do not bind/enable, etc. */ if (sm->socket_name == 0) return 0; #define _(N,n) \ vl_msg_api_set_handlers(VL_API_##N, #n, \ vl_api_##n##_t_handler, \ vl_noop_handler, \ vl_api_##n##_t_endian, \ vl_api_##n##_t_print, \ sizeof(vl_api_##n##_t), 1); foreach_vlib_api_msg; #undef _ vec_resize (sm->input_buffer, 4096); sock->config = (char *) sm->socket_name; /* mkdir of file socket, only under /run */ if (strncmp (sock->config, "/run", 4) == 0) { u8 *tmp = format (0, "%s", sock->config); int i = vec_len (tmp); while (i && tmp[--i] != '/') ; tmp[i] = 0; if (i) vlib_unix_recursive_mkdir ((char *) tmp); vec_free (tmp); } sock->flags = CLIB_SOCKET_F_IS_SERVER | CLIB_SOCKET_F_ALLOW_GROUP_WRITE; error = clib_socket_init (sock); if (error) return error; pool_get (sm->registration_pool, rp); clib_memset (rp, 0, sizeof (*rp)); rp->registration_type = REGISTRATION_TYPE_SOCKET_LISTEN; template.read_function = socksvr_accept_ready; template.write_function = socksvr_bogus_write; template.file_descriptor = sock->fd; template.private_data = rp - sm->registration_pool; rp->clib_file_index = clib_file_add (fm, &template); return 0; } static clib_error_t * socket_exit (vlib_main_t * vm) { socket_main_t *sm = &socket_main; vl_api_registration_t *rp; /* Defensive driving in case something wipes out early */ if (sm->registration_pool) { u32 index; /* *INDENT-OFF* */ pool_foreach (rp, sm->registration_pool, ({ vl_api_registration_del_file (rp); index = rp->vl_api_registration_pool_index; vl_socket_free_registration_index (index); })); /* *INDENT-ON* */ } return 0; } VLIB_MAIN_LOOP_EXIT_FUNCTION (socket_exit); static clib_error_t * socksvr_config (vlib_main_t * vm, unformat_input_t * input) { socket_main_t *sm = &socket_main; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "socket-name %s", &sm->socket_name)) ; else if (unformat (input, "default")) { sm->socket_name = format (0, "%s%c", API_SOCKET_FILE, 0); } else { return clib_error_return (0, "unknown input '%U'", format_unformat_error, input); } } return 0; } VLIB_CONFIG_FUNCTION (socksvr_config, "socksvr"); void vlibsocket_reference () { } /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */