diff options
113 files changed, 1048 insertions, 577 deletions
diff --git a/INFO.yaml b/INFO.yaml index 5fe9ca7eae8..06f749d368e 100644 --- a/INFO.yaml +++ b/INFO.yaml @@ -34,65 +34,70 @@ repositories: - 'vpp' committers: - <<: *vpp_ptl - - name: 'Keith Burns' - company: 'gmail' - email: 'alagalah@gmail.com' - id: 'alagalah' - timezone: '' - - name: 'Chris Luke' - company: 'comcast' - email: 'chris_luke@comcast.com' - id: 'chrisluke' - timezone: '' - name: 'Dave Barach' - company: 'barachs' + company: 'cisco' email: 'openvpp@barachs.net' id: 'dbarach' timezone: '' - - name: 'Damjan Marion' - company: 'cisco' - email: 'damarion@cisco.com' - id: 'dmarion' - timezone: '' - - name: 'Dave Wallace' - company: 'gmail' - email: 'dwallacelf@gmail.com' - id: 'dwallacelf' - timezone: '' - name: 'Florin Coras' - company: 'gmail' + company: 'cisco' email: 'florin.coras@gmail.com' id: 'florin.coras' timezone: '' - - name: 'Ed Warnicke' - company: 'gmail' - email: 'hagbard@gmail.com' - id: 'hagbard' + - name: 'Benoit Ganne' + company: 'cisco' + email: 'bganne@cisco.com' + id: 'bganne' timezone: '' - name: 'John Lo' company: 'cisco' email: 'loj@cisco.com' id: 'lojohn' timezone: '' - - name: 'Marco Varlese' - company: 'suse' - email: 'marco.varlese@suse.de' - id: 'marco.varlese' + - name: 'Chris Luke' + company: 'comcast' + email: 'chris_luke@comcast.com' + id: 'chrisluke' + timezone: '' + - name: 'Damjan Marion' + company: 'cisco' + email: 'damarion@cisco.com' + id: 'dmarion' timezone: '' - name: 'Neale Ranns' company: 'cisco' email: 'nranns@cisco.com' id: 'nranns' timezone: '' + - name: 'Matthew Smith' + company: 'netgate' + email: 'mgsmith@netgate.com' + id: 'mgsmith' + timezone: '' - name: 'Ole Trøan' company: 'employees' email: 'otroan@employees.org' id: 'otroan' timezone: '' - - name: 'Sergio Gonzalez Monroy' - company: 'outlook' - email: 'sergio.gonzalez.monroy@outlook.com' - id: 'smonroy' + - name: 'Paul Vinciguerra' + company: 'vinciconsulting' + email: 'pvinci@vinciconsulting.com' + id: 'pvinci' + timezone: '' + - name: 'Dave Wallace' + company: 'gmail' + email: 'dwallacelf@gmail.com' + id: 'dwallacelf' + timezone: '' + - name: 'Ed Warnicke' + company: 'gmail' + email: 'hagbard@gmail.com' + id: 'hagbard' + timezone: '' + - name: 'Andrew Yourtchenko' + company: 'cisco' + email: 'ayourtch@cisco.com' + id: 'ayourtch' timezone: '' tsc: # yamllint disable rule:line-length diff --git a/MAINTAINERS b/MAINTAINERS index 586e3e0c722..ad3dd1649e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -67,6 +67,13 @@ M: Damjan Marion <damarion@cisco.com> M: Dave Barach <dave@barachs.net> F: src/vlib/buffer*.[ch] +Vector Library - PCI +I: pci +M: Damjan Marion <damarion@cisco.com> +F: src/vlib/pci/ +F: src/vlib/linux/pci.[ch] +F: src/vlib/linux/vfio.[ch] + Binary API Libraries I: api M: Dave Barach <dave@barachs.net> @@ -556,6 +563,10 @@ Plugin - SCTP I: sctp F: src/plugins/sctp/ +IOAM +I: ioam +F: src/plugins/ioam + THE REST I: misc C: Contact vpp-dev Mailing List <vpp-dev@fd.io> diff --git a/RELEASE.md b/RELEASE.md index b3a1b18cf1b..0c7ab96cc20 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,6 @@ # Release Notes {#release_notes} +* @subpage release_notes_19083 * @subpage release_notes_19082 * @subpage release_notes_19081 * @subpage release_notes_1908 @@ -25,6 +26,14 @@ * @subpage release_notes_1609 * @subpage release_notes_1606 +@page release_notes_19083 Release notes for VPP 19.08.3 + +This is bug fix release. + +For the full list of fixed issues please refer to: +- fd.io [JIRA](https://jira.fd.io) +- git [commit log](https://git.fd.io/vpp/log/?h=stable/1908) + @page release_notes_19082 Release notes for VPP 19.08.2 The 19.08.2 is an LTS release. It contains numerous fixes, diff --git a/build/external/packages/dpdk.mk b/build/external/packages/dpdk.mk index 7e8af071f53..d38e015a037 100644 --- a/build/external/packages/dpdk.mk +++ b/build/external/packages/dpdk.mk @@ -155,7 +155,8 @@ endif endif endif -DPDK_EXTRA_CFLAGS += -L$(I)/lib -I$(I)/include +DPDK_EXTRA_CFLAGS += -I$(I)/include +DPDK_EXTRA_LDFLAGS += -L$(I)/lib # assemble DPDK make arguments DPDK_MAKE_ARGS := -C $(DPDK_SOURCE) -j $(JOBS) \ diff --git a/src/vppinfra/qsort.c b/extras/deprecated/vppinfra/qsort.c index 145ae40fe91..145ae40fe91 100644 --- a/src/vppinfra/qsort.c +++ b/extras/deprecated/vppinfra/qsort.c diff --git a/extras/scripts/check_commit_msg.sh b/extras/scripts/check_commit_msg.sh index acad40344e9..e2d2735bc6a 100755 --- a/extras/scripts/check_commit_msg.sh +++ b/extras/scripts/check_commit_msg.sh @@ -2,7 +2,7 @@ KNOWN_FEATURES=$(cat MAINTAINERS | sed -ne 's/^I:[[:space:]]*//p') FEATURES=$(git show -s --format=%s --no-color \ - | sed -ne 's/^\([a-z0-9 -]*\):.*$/\1/p') + | sed -ne 's/^\([a-z0-9_ -]*\):.*$/\1/p') KNOWN_TYPES="feature fix refactor style docs test make" TYPE=$(git show -s --format=%b --no-color | sed -ne 's/^Type:[[:space:]]*//p') ERR="=============================== ERROR ===============================" diff --git a/extras/vpp_config/vpplib/AutoConfig.py b/extras/vpp_config/vpplib/AutoConfig.py index c4777104c0b..c287c5b669a 100644 --- a/extras/vpp_config/vpplib/AutoConfig.py +++ b/extras/vpp_config/vpplib/AutoConfig.py @@ -507,7 +507,6 @@ class AutoConfig(object): total_mbufs = (((rx_queues * desc_entries) + (tx_queues * desc_entries)) * total_ports_per_numa) - total_mbufs = total_mbufs return total_mbufs diff --git a/src/plugins/acl/acl_test.c b/src/plugins/acl/acl_test.c index ec951ad7057..d6a6d582702 100644 --- a/src/plugins/acl/acl_test.c +++ b/src/plugins/acl/acl_test.c @@ -669,10 +669,13 @@ api_acl_add_replace_from_file (vat_main_t * vam) break; } + if (file_name == NULL) + goto done; + fd = open(file_name, O_RDONLY); if (fd < 0) { - clib_warning("Could not open file '%s'"); + clib_warning("Could not open file '%s'", file_name); goto done; } diff --git a/src/plugins/dns/dns.c b/src/plugins/dns/dns.c index 870cfae5074..47955452d3c 100644 --- a/src/plugins/dns/dns.c +++ b/src/plugins/dns/dns.c @@ -2795,7 +2795,7 @@ vnet_send_dns4_reply (dns_main_t * dm, dns_pending_request_t * pr, u8 *reply; vl_api_dns_resolve_name_reply_t _rnr, *rnr = &_rnr; vl_api_dns_resolve_ip_reply_t _rir, *rir = &_rir; - u32 ttl, tmp; + u32 ttl = 64, tmp; u32 qp_offset; dns_query_t *qp; dns_rr_t *rr; diff --git a/src/plugins/dns/dns_test.c b/src/plugins/dns/dns_test.c index 6b0b371dca1..ada9c0b7aa1 100644 --- a/src/plugins/dns/dns_test.c +++ b/src/plugins/dns/dns_test.c @@ -186,6 +186,12 @@ api_dns_resolve_name (vat_main_t * vam) break; } + if (name == 0) + { + errmsg ("missing name to resolve"); + return -99; + } + if (vec_len (name) > 127) { errmsg ("name too long"); diff --git a/src/plugins/dpdk/buffer.c b/src/plugins/dpdk/buffer.c index a1c1ea1ca46..251b678a5fb 100644 --- a/src/plugins/dpdk/buffer.c +++ b/src/plugins/dpdk/buffer.c @@ -90,6 +90,7 @@ dpdk_buffer_pool_init (vlib_main_t * vm, vlib_buffer_pool_t * bp) rte_mempool_set_ops_byname (nmp, "vpp-no-cache", NULL); /* Call the mempool priv initializer */ + memset (&priv, 0, sizeof (priv)); priv.mbuf_data_room_size = VLIB_BUFFER_PRE_DATA_SIZE + vlib_buffer_get_default_data_size (vm); priv.mbuf_priv_size = VLIB_BUFFER_HDR_SIZE; diff --git a/src/plugins/dpdk/device/format.c b/src/plugins/dpdk/device/format.c index 942def63b0a..436466fa1ad 100644 --- a/src/plugins/dpdk/device/format.c +++ b/src/plugins/dpdk/device/format.c @@ -676,12 +676,10 @@ format_dpdk_device (u8 * s, va_list * args) xstat = vec_elt_at_index(xd->xstats, i); if (verbose == 2 || (verbose && xstat->value)) { - /* format_c_identifier doesn't like c strings inside vector */ - u8 * name = format(0,"%s", xstat_names[i].name); xs = format(xs, "\n%U%-38U%16Lu", format_white_space, indent + 4, - format_c_identifier, name, xstat->value); - vec_free(name); + format_c_identifier, xstat_names[i].name, + xstat->value); } } /* *INDENT-ON* */ diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index 8ebfaac3580..0523770971c 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -279,7 +279,6 @@ dpdk_lib_init (dpdk_main_t * dm) int vlan_off; struct rte_eth_dev_info dev_info; struct rte_pci_device *pci_dev; - struct rte_eth_link l; dpdk_portid_t next_port_id; dpdk_device_config_t *devconf = 0; vlib_pci_addr_t pci_addr; @@ -288,7 +287,6 @@ dpdk_lib_init (dpdk_main_t * dm) if (!rte_eth_dev_is_valid_port(i)) continue; - rte_eth_link_get_nowait (i, &l); rte_eth_dev_info_get (i, &dev_info); if (dev_info.device == 0) @@ -504,9 +502,13 @@ dpdk_lib_init (dpdk_main_t * dm) /* Cisco VIC */ case VNET_DPDK_PMD_ENIC: - xd->port_type = port_type_from_link_speed (l.link_speed); - if (dm->conf->enable_tcp_udp_checksum) - dpdk_enable_l4_csum_offload (xd); + { + struct rte_eth_link l; + rte_eth_link_get_nowait (i, &l); + xd->port_type = port_type_from_link_speed (l.link_speed); + if (dm->conf->enable_tcp_udp_checksum) + dpdk_enable_l4_csum_offload (xd); + } break; /* Intel Red Rock Canyon */ @@ -551,7 +553,11 @@ dpdk_lib_init (dpdk_main_t * dm) break; case VNET_DPDK_PMD_NETVSC: - xd->port_type = port_type_from_link_speed (l.link_speed); + { + struct rte_eth_link l; + rte_eth_link_get_nowait (i, &l); + xd->port_type = port_type_from_link_speed (l.link_speed); + } break; default: diff --git a/src/plugins/gbp/test/test_gbp.py b/src/plugins/gbp/test/test_gbp.py index 87266492dca..dcbe976cc6e 100644 --- a/src/plugins/gbp/test/test_gbp.py +++ b/src/plugins/gbp/test/test_gbp.py @@ -36,7 +36,7 @@ NUM_PKTS = 67 def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, - tep=None, sclass=None): + tep=None, sclass=None, flags=None): if ip: vip = VppIpAddress(ip) if mac: @@ -56,6 +56,9 @@ def find_gbp_endpoint(test, sw_if_index=None, ip=None, mac=None, if sclass: if ep.endpoint.sclass != sclass: continue + if flags: + if flags != (flags & ep.endpoint.flags): + continue if ip: for eip in ep.endpoint.ips: if vip == eip: @@ -1542,12 +1545,17 @@ class TestGBP(VppTestCase): def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None, tep=None, n_tries=100, s_time=1): + # only learnt EP can timeout + ep_flags = VppEnum.vl_api_gbp_endpoint_flags_t + flags = ep_flags.GBP_API_ENDPOINT_FLAG_LEARNT while (n_tries): - if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep): + if not find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, + flags=flags): return True n_tries = n_tries - 1 self.sleep(s_time) - self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac)) + self.assertFalse(find_gbp_endpoint(self, sw_if_index, ip, mac, tep=tep, + flags=flags)) return False def test_gbp_learn_l2(self): @@ -5877,6 +5885,8 @@ class TestGBP(VppTestCase): self.vlan_101.set_vtr(L2_VTR_OP.L2_DISABLED) self.vlan_100.set_vtr(L2_VTR_OP.L2_DISABLED) self.pg7.unconfig_ip4() + # make sure the programmed EP is no longer learnt from DP + self.wait_for_ep_timeout(sw_if_index=rep.itf.sw_if_index, ip=rep.ip4) if __name__ == '__main__': diff --git a/src/plugins/hs_apps/http_server.c b/src/plugins/hs_apps/http_server.c index cc998a6f661..ce8a3e868f2 100644 --- a/src/plugins/hs_apps/http_server.c +++ b/src/plugins/hs_apps/http_server.c @@ -193,17 +193,6 @@ http_server_session_timer_stop (http_session_t * hs) } static void -http_server_session_cleanup (http_session_t * hs) -{ - if (!hs) - return; - http_server_session_lookup_del (hs->thread_index, hs->vpp_session_index); - vec_free (hs->rx_buf); - http_server_session_timer_stop (hs); - http_server_session_free (hs); -} - -static void http_server_session_disconnect (http_session_t * hs) { vnet_disconnect_args_t _a = { 0 }, *a = &_a; @@ -605,7 +594,6 @@ send_data: close_session: http_server_session_disconnect (hs); - http_server_session_cleanup (hs); return 0; postpone: @@ -651,16 +639,6 @@ http_server_session_disconnect_callback (session_t * s) { http_server_main_t *hsm = &http_server_main; vnet_disconnect_args_t _a = { 0 }, *a = &_a; - http_session_t *hs; - - if (!hsm->is_static) - http_server_sessions_writer_lock (); - - hs = http_server_session_lookup (s->thread_index, s->session_index); - http_server_session_cleanup (hs); - - if (!hsm->is_static) - http_server_sessions_writer_unlock (); a->handle = session_handle (s); a->app_index = hsm->app_index; @@ -672,16 +650,6 @@ http_server_session_reset_callback (session_t * s) { http_server_main_t *hsm = &http_server_main; vnet_disconnect_args_t _a = { 0 }, *a = &_a; - http_session_t *hs; - - if (!hsm->is_static) - http_server_sessions_writer_lock (); - - hs = http_server_session_lookup (s->thread_index, s->session_index); - http_server_session_cleanup (hs); - - if (!hsm->is_static) - http_server_sessions_writer_unlock (); a->handle = session_handle (s); a->app_index = hsm->app_index; @@ -703,13 +671,41 @@ http_server_add_segment_callback (u32 client_index, u64 segment_handle) return -1; } +static void +http_server_cleanup_callback (session_t * s, session_cleanup_ntf_t ntf) +{ + http_server_main_t *hsm = &http_server_main; + http_session_t *hs; + + if (ntf == SESSION_CLEANUP_TRANSPORT) + return; + + if (!hsm->is_static) + http_server_sessions_writer_lock (); + + hs = http_server_session_lookup (s->thread_index, s->session_index); + if (!hs) + goto done; + + http_server_session_lookup_del (hs->thread_index, hs->vpp_session_index); + vec_free (hs->rx_buf); + http_server_session_timer_stop (hs); + http_server_session_free (hs); + +done: + + if (!hsm->is_static) + http_server_sessions_writer_unlock (); +} + static session_cb_vft_t http_server_session_cb_vft = { .session_accept_callback = http_server_session_accept_callback, .session_disconnect_callback = http_server_session_disconnect_callback, .session_connected_callback = http_server_session_connected_callback, .add_segment_callback = http_server_add_segment_callback, .builtin_app_rx_callback = http_server_rx_callback, - .session_reset_callback = http_server_session_reset_callback + .session_reset_callback = http_server_session_reset_callback, + .session_cleanup_callback = http_server_cleanup_callback, }; static int @@ -778,7 +774,7 @@ http_server_listen () } static void -http_server_session_cleanup_cb (void *hs_handlep) +http_server_session_close_cb (void *hs_handlep) { http_session_t *hs; uword hs_handle; @@ -788,7 +784,6 @@ http_server_session_cleanup_cb (void *hs_handlep) return; hs->timer_handle = ~0; http_server_session_disconnect (hs); - http_server_session_cleanup (hs); } static void @@ -802,7 +797,7 @@ http_expired_timers_dispatch (u32 * expired_timers) /* Get session handle. The first bit is the timer id */ hs_handle = expired_timers[i] & 0x7FFFFFFF; session_send_rpc_evt_to_thread (hs_handle >> 24, - http_server_session_cleanup_cb, + http_server_session_close_cb, uword_to_pointer (hs_handle, void *)); } } diff --git a/src/plugins/http_static/static_server.c b/src/plugins/http_static/static_server.c index ef9d3d77e41..77e3ebd8e13 100644 --- a/src/plugins/http_static/static_server.c +++ b/src/plugins/http_static/static_server.c @@ -243,26 +243,8 @@ http_static_server_detach_cache_entry (http_session_t * hs) vec_free (hs->path); } -/** \brief clean up a session - */ - -static void -http_static_server_session_cleanup (http_session_t * hs) -{ - if (!hs) - return; - - http_static_server_detach_cache_entry (hs); - - http_static_server_session_lookup_del (hs->thread_index, - hs->vpp_session_index); - vec_free (hs->rx_buf); - http_static_server_session_free (hs); -} - /** \brief Disconnect a session */ - static void http_static_server_session_disconnect (http_session_t * hs) { @@ -531,7 +513,6 @@ static void close_session (http_session_t * hs) { http_static_server_session_disconnect (hs); - http_static_server_session_cleanup (hs); } /** \brief Register a builtin GET or POST handler @@ -799,7 +780,7 @@ find_end: dp = pool_elt_at_index (hsm->cache_pool, kv.value); hs->data = dp->data; /* Update the cache entry, mark it in-use */ - lru_update (hsm, dp, vlib_time_now (hsm->vlib_main)); + lru_update (hsm, dp, vlib_time_now (vlib_get_main ())); hs->cache_pool_index = dp - hsm->cache_pool; dp->inuse++; if (hsm->debug_level > 1) @@ -871,7 +852,7 @@ find_end: if (hsm->debug_level > 1) clib_warning ("index %d refcnt now %d", hs->cache_pool_index, dp->inuse); - lru_add (hsm, dp, vlib_time_now (hsm->vlib_main)); + lru_add (hsm, dp, vlib_time_now (vlib_get_main ())); kv.key = (u64) vec_dup (hs->path); kv.value = dp - hsm->cache_pool; /* Add to the lookup table */ @@ -933,7 +914,7 @@ state_sent_ok (session_t * s, http_session_t * hs, /* What kind of dog food are we serving? */ suffix = (char *) (hs->path + vec_len (hs->path) - 1); - while (*suffix != '.') + while ((u8 *) suffix >= hs->path && *suffix != '.') suffix--; suffix++; http_type = "text/html"; @@ -1078,14 +1059,6 @@ http_static_server_session_disconnect_callback (session_t * s) { http_static_server_main_t *hsm = &http_static_server_main; vnet_disconnect_args_t _a = { 0 }, *a = &_a; - http_session_t *hs; - - http_static_server_sessions_writer_lock (); - - hs = http_static_server_session_lookup (s->thread_index, s->session_index); - http_static_server_session_cleanup (hs); - - http_static_server_sessions_writer_unlock (); a->handle = session_handle (s); a->app_index = hsm->app_index; @@ -1100,14 +1073,6 @@ http_static_server_session_reset_callback (session_t * s) { http_static_server_main_t *hsm = &http_static_server_main; vnet_disconnect_args_t _a = { 0 }, *a = &_a; - http_session_t *hs; - - http_static_server_sessions_writer_lock (); - - hs = http_static_server_session_lookup (s->thread_index, s->session_index); - http_static_server_session_cleanup (hs); - - http_static_server_sessions_writer_unlock (); a->handle = session_handle (s); a->app_index = hsm->app_index; @@ -1129,6 +1094,30 @@ http_static_server_add_segment_callback (u32 client_index, u64 segment_handle) return -1; } +static void +http_static_session_cleanup (session_t * s, session_cleanup_ntf_t ntf) +{ + http_session_t *hs; + + if (ntf == SESSION_CLEANUP_TRANSPORT) + return; + + http_static_server_sessions_writer_lock (); + + hs = http_static_server_session_lookup (s->thread_index, s->session_index); + if (!hs) + goto done; + + http_static_server_detach_cache_entry (hs); + http_static_server_session_lookup_del (hs->thread_index, + hs->vpp_session_index); + vec_free (hs->rx_buf); + http_static_server_session_free (hs); + +done: + http_static_server_sessions_writer_unlock (); +} + /** \brief Session-layer virtual function table */ static session_cb_vft_t http_static_server_session_cb_vft = { @@ -1139,7 +1128,8 @@ static session_cb_vft_t http_static_server_session_cb_vft = { .add_segment_callback = http_static_server_add_segment_callback, .builtin_app_rx_callback = http_static_server_rx_callback, .builtin_app_tx_callback = http_static_server_tx_callback, - .session_reset_callback = http_static_server_session_reset_callback + .session_reset_callback = http_static_server_session_reset_callback, + .session_cleanup_callback = http_static_session_cleanup, }; static int @@ -1209,7 +1199,7 @@ http_static_server_listen () } static void -http_static_server_session_cleanup_cb (void *hs_handlep) +http_static_server_session_close_cb (void *hs_handlep) { http_static_server_main_t *hsm = &http_static_server_main; http_session_t *hs; @@ -1225,7 +1215,6 @@ http_static_server_session_cleanup_cb (void *hs_handlep) return; hs->timer_handle = ~0; http_static_server_session_disconnect (hs); - http_static_server_session_cleanup (hs); } /** \brief Expired session timer-wheel callback @@ -1241,7 +1230,7 @@ http_expired_timers_dispatch (u32 * expired_timers) /* Get session handle. The first bit is the timer id */ hs_handle = expired_timers[i] & 0x7FFFFFFF; session_send_rpc_evt_to_thread (hs_handle >> 24, - http_static_server_session_cleanup_cb, + http_static_server_session_close_cb, uword_to_pointer (hs_handle, void *)); } } diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index 16c21cb2418..cc45d14b56f 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -1498,7 +1498,7 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, { a.local_ip.ip4.as_u32 = sa->iaddr.as_u32; a.remote_ip.ip4.as_u32 = sa->raddr.as_u32; - proposals = child->i_proposals; + proposals = child->r_proposals; a.local_spi = child->r_proposals[0].spi; a.remote_spi = child->i_proposals[0].spi; } @@ -1506,7 +1506,7 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, { a.local_ip.ip4.as_u32 = sa->raddr.as_u32; a.remote_ip.ip4.as_u32 = sa->iaddr.as_u32; - proposals = child->r_proposals; + proposals = child->i_proposals; a.local_spi = child->i_proposals[0].spi; a.remote_spi = child->r_proposals[0].spi; } @@ -2611,7 +2611,6 @@ ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa, { vec_add1 (proposal->transforms, *td); error = 0; - break; } } if (error) @@ -3000,7 +2999,7 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name) ikev2_sa_free_proposal_vector (&proposals); sa.is_initiator = 1; - sa.profile_index = km->profiles - p; + sa.profile_index = p - km->profiles; sa.is_profile_index_set = 1; sa.state = IKEV2_STATE_SA_INIT; ikev2_generate_sa_init_data (&sa); diff --git a/src/plugins/ikev2/ikev2_api.c b/src/plugins/ikev2/ikev2_api.c index bff13ac4626..cfb0cc14514 100644 --- a/src/plugins/ikev2/ikev2_api.c +++ b/src/plugins/ikev2/ikev2_api.c @@ -144,7 +144,7 @@ static void static void vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp) { - vl_api_ikev2_profile_add_del_reply_t *rmp; + vl_api_ikev2_profile_set_id_reply_t *rmp; int rv = 0; #if WITH_LIBSSL > 0 @@ -195,7 +195,7 @@ vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp) static void vl_api_ikev2_set_local_key_t_handler (vl_api_ikev2_set_local_key_t * mp) { - vl_api_ikev2_profile_set_ts_reply_t *rmp; + vl_api_ikev2_set_local_key_reply_t *rmp; int rv = 0; #if WITH_LIBSSL > 0 diff --git a/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_api.c b/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_api.c index e46d0fbf866..cafb83be38a 100644 --- a/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_api.c +++ b/src/plugins/ioam/lib-vxlan-gpe/vxlan_gpe_api.c @@ -272,7 +272,7 @@ setup_message_id_table (vxlan_gpe_ioam_main_t * sm, api_main_t * am) } static clib_error_t * -vxlan_gpe_init (vlib_main_t * vm) +ioam_vxlan_gpe_init (vlib_main_t * vm) { vxlan_gpe_ioam_main_t *sm = &vxlan_gpe_ioam_main; clib_error_t *error = 0; @@ -321,7 +321,7 @@ vxlan_gpe_init (vlib_main_t * vm) return error; } -VLIB_INIT_FUNCTION (vxlan_gpe_init); +VLIB_INIT_FUNCTION (ioam_vxlan_gpe_init); /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/lacp/cli.c b/src/plugins/lacp/cli.c index 36a6f9bfbdf..fee1be19463 100644 --- a/src/plugins/lacp/cli.c +++ b/src/plugins/lacp/cli.c @@ -38,12 +38,12 @@ lacp_dump_ifs (lacp_interface_details_t ** out_lacpifs) hi = vnet_get_hw_interface (vnm, sif->hw_if_index); clib_memcpy(lacpif->interface_name, hi->name, MIN (ARRAY_LEN (lacpif->interface_name) - 1, - strlen ((const char *) hi->name))); + vec_len (hi->name))); bif = bond_get_master_by_dev_instance (sif->bif_dev_instance); hi = vnet_get_hw_interface (vnm, bif->hw_if_index); clib_memcpy(lacpif->bond_interface_name, hi->name, MIN (ARRAY_LEN (lacpif->bond_interface_name) - 1, - strlen ((const char *) hi->name))); + vec_len (hi->name))); clib_memcpy (lacpif->actor_system, sif->actor.system, 6); lacpif->actor_system_priority = sif->actor.system_priority; lacpif->actor_key = sif->actor.key; diff --git a/src/plugins/lacp/input.c b/src/plugins/lacp/input.c index befb2ed408b..57e30b43662 100644 --- a/src/plugins/lacp/input.c +++ b/src/plugins/lacp/input.c @@ -276,11 +276,11 @@ lacp_input_format_trace (u8 * s, va_list * args) s = format (s, " Marker Information TLV: length %u\n", marker->marker_info.tlv_length); s = format (s, " Requester port: %u\n", - marker->marker_info.requester_port); + ntohs (marker->marker_info.requester_port)); s = format (s, " Requester system: %U\n", format_ethernet_address, marker->marker_info.requester_system); s = format (s, " Requester transaction ID: %u\n", - marker->marker_info.requester_transaction_id); + ntohl (marker->marker_info.requester_transaction_id)); break; case LACP_SUBTYPE: diff --git a/src/plugins/mactime/mactime.c b/src/plugins/mactime/mactime.c index 57895404390..84aba5f72a4 100644 --- a/src/plugins/mactime/mactime.c +++ b/src/plugins/mactime/mactime.c @@ -513,6 +513,11 @@ show_mactime_command_fn (vlib_main_t * vm, vlib_counter_t allow, drop; ethernet_arp_ip4_entry_t *n, *pool; + if (mm->feature_initialized == 0) + return clib_error_return + (0, + "Feature not initialized, suggest 'help mactime enable-disable'..."); + vec_reset_length (mm->arp_cache_copy); pool = ip4_neighbors_pool (); @@ -668,7 +673,9 @@ clear_mactime_command_fn (vlib_main_t * vm, mactime_main_t *mm = &mactime_main; if (mm->feature_initialized == 0) - return clib_error_return (0, "feature not enabled"); + return clib_error_return + (0, + "Feature not initialized, suggest 'help mactime enable-disable'..."); vlib_clear_combined_counters (&mm->allow_counters); vlib_clear_combined_counters (&mm->drop_counters); diff --git a/src/plugins/memif/node.c b/src/plugins/memif/node.c index dd8f9ba597e..82a7cbc142c 100644 --- a/src/plugins/memif/node.c +++ b/src/plugins/memif/node.c @@ -509,7 +509,7 @@ memif_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_increment_combined_counter (vnm->interface_main.combined_sw_if_counters + VNET_INTERFACE_COUNTER_RX, thread_index, - mif->hw_if_index, n_rx_packets, + mif->sw_if_index, n_rx_packets, n_rx_bytes); /* refill ring with empty buffers */ @@ -772,7 +772,7 @@ memif_device_input_zc_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_increment_combined_counter (vnm->interface_main.combined_sw_if_counters + VNET_INTERFACE_COUNTER_RX, thread_index, - mif->hw_if_index, n_rx_packets, + mif->sw_if_index, n_rx_packets, n_rx_bytes); /* refill ring with empty buffers */ diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44_cli.c index e9d3ff5426f..8910f1c6c0a 100644 --- a/src/plugins/nat/nat44_cli.c +++ b/src/plugins/nat/nat44_cli.c @@ -1528,8 +1528,13 @@ snat_det_map_command_fn (vlib_main_t * vm, } } - rv = snat_det_add_map (sm, &in_addr, (u8) in_plen, &out_addr, (u8) out_plen, - is_add); + if (in_plen > 32 || out_plen > 32) + { + error = clib_error_return (0, "network prefix length must be <= 32"); + goto done; + } + + rv = snat_det_add_map (sm, &in_addr, in_plen, &out_addr, out_plen, is_add); if (rv) { diff --git a/src/plugins/nat/nat44_hairpinning.c b/src/plugins/nat/nat44_hairpinning.c index 331e7ca96bd..a0a06c04c05 100644 --- a/src/plugins/nat/nat44_hairpinning.c +++ b/src/plugins/nat/nat44_hairpinning.c @@ -94,7 +94,7 @@ snat_hairpinning (snat_main_t * sm, tcp_header_t * tcp0, u32 proto0, int is_ed) { snat_session_key_t key0, sm0; - snat_session_t *s0; + snat_session_t *s0 = NULL; clib_bihash_kv_8_8_t kv0, value0; ip_csum_t sum0; u32 new_dst_addr0 = 0, old_dst_addr0, ti = 0, si; diff --git a/src/plugins/nat/nat_det.c b/src/plugins/nat/nat_det.c index 0ab96dc1026..65a669bceb9 100644 --- a/src/plugins/nat/nat_det.c +++ b/src/plugins/nat/nat_det.c @@ -71,18 +71,35 @@ snat_det_add_map (snat_main_t * sm, ip4_address_t * in_addr, u8 in_plen, if (is_add) { + u32 num_sessions = (1 << (32 - in_plen)); + if (num_sessions > UINT32_MAX / 1000) + { + // don't let it overflow + return VNET_API_ERROR_INVALID_VALUE; + } + else + { + num_sessions = num_sessions * 1000 - 1; + } + + u32 sharing_ratio = (1 << (32 - in_plen)) / (1 << (32 - out_plen)); + if (!sharing_ratio) + { + // avoid division by zero + return VNET_API_ERROR_INVALID_VALUE; + } + pool_get (sm->det_maps, det_map); clib_memset (det_map, 0, sizeof (*det_map)); det_map->in_addr.as_u32 = in_cmp.as_u32; det_map->in_plen = in_plen; det_map->out_addr.as_u32 = out_cmp.as_u32; det_map->out_plen = out_plen; - det_map->sharing_ratio = (1 << (32 - in_plen)) / (1 << (32 - out_plen)); + det_map->sharing_ratio = sharing_ratio; det_map->ports_per_host = (65535 - 1023) / det_map->sharing_ratio; - vec_validate_init_empty (det_map->sessions, - SNAT_DET_SES_PER_USER * (1 << (32 - in_plen)) - - 1, empty_snat_det_session); + vec_validate_init_empty (det_map->sessions, num_sessions, + empty_snat_det_session); } else { diff --git a/src/plugins/nat/nat_ipfix_logging.c b/src/plugins/nat/nat_ipfix_logging.c index c24c2372b54..e85becba121 100755 --- a/src/plugins/nat/nat_ipfix_logging.c +++ b/src/plugins/nat/nat_ipfix_logging.c @@ -565,6 +565,7 @@ snat_ipfix_header_create (flow_report_main_t * frm, u32 stream_index; ip4_header_t *ip; udp_header_t *udp; + vlib_main_t *vm = vlib_get_main (); stream_index = clib_atomic_fetch_or(&silm->stream_index, 0); stream = &frm->streams[stream_index]; @@ -593,7 +594,7 @@ snat_ipfix_header_create (flow_report_main_t * frm, h->export_time = clib_host_to_net_u32 ((u32) (((f64) frm->unix_time_0) + - (vlib_time_now (frm->vlib_main) - + (vlib_time_now (vm) - frm->vlib_time_0))); sequence_number = clib_atomic_fetch_add (&stream->sequence_number, 1); diff --git a/src/plugins/nat/test/test_nat.py b/src/plugins/nat/test/test_nat.py index f2b1dbf79ac..963970b10e4 100644 --- a/src/plugins/nat/test/test_nat.py +++ b/src/plugins/nat/test/test_nat.py @@ -2927,7 +2927,7 @@ class TestNAT44(MethodHolder): self.pg1.assert_nothing_captured() sleep(1) self.vapi.ipfix_flush() - capture = self.pg3.get_capture(9) + capture = self.pg3.get_capture(7) ipfix = IPFIXDecoder() # first load template for p in capture: @@ -8934,7 +8934,7 @@ class TestNAT64(MethodHolder): self.pg1.assert_nothing_captured() sleep(1) self.vapi.ipfix_flush() - capture = self.pg3.get_capture(9) + capture = self.pg3.get_capture(7) ipfix = IPFIXDecoder() # first load template for p in capture: diff --git a/src/plugins/pppoe/pppoe.h b/src/plugins/pppoe/pppoe.h index 471727ce893..3e331ee6a11 100644 --- a/src/plugins/pppoe/pppoe.h +++ b/src/plugins/pppoe/pppoe.h @@ -94,6 +94,7 @@ typedef enum PPPOE_N_ERROR, } pppoe_input_error_t; +extern char *pppoe_error_strings[]; #define MTU 1500 #define MTU_BUFFERS ((MTU + vlib_buffer_get_default_data_size(vm) - 1) / vlib_buffer_get_default_data_size(vm)) diff --git a/src/plugins/pppoe/pppoe_cp_node.c b/src/plugins/pppoe/pppoe_cp_node.c index 3f866450cfb..bf9018e8c90 100644 --- a/src/plugins/pppoe/pppoe_cp_node.c +++ b/src/plugins/pppoe/pppoe_cp_node.c @@ -237,6 +237,9 @@ VLIB_REGISTER_NODE (pppoe_cp_dispatch_node) = { /* Takes a vector of packets. */ .vector_size = sizeof (u32), + .n_errors = PPPOE_N_ERROR, + .error_strings = pppoe_error_strings, + .n_next_nodes = PPPOE_CP_N_NEXT, .next_nodes = { #define _(s,n) [PPPOE_CP_NEXT_##s] = n, diff --git a/src/plugins/pppoe/pppoe_decap.c b/src/plugins/pppoe/pppoe_decap.c index 256dd83e43d..d3f4a5fedf3 100644 --- a/src/plugins/pppoe/pppoe_decap.c +++ b/src/plugins/pppoe/pppoe_decap.c @@ -390,12 +390,14 @@ VLIB_NODE_FN (pppoe_input_node) (vlib_main_t * vm, return from_frame->n_vectors; } -static char * pppoe_error_strings[] = { +#ifndef CLIB_MARCH_VARIANT +char * pppoe_error_strings[] = { #define pppoe_error(n,s) s, #include <pppoe/pppoe_error.def> #undef pppoe_error #undef _ }; +#endif /* CLIB_MARCH_VARIANT */ VLIB_REGISTER_NODE (pppoe_input_node) = { .name = "pppoe-input", diff --git a/src/plugins/rdma/CMakeLists.txt b/src/plugins/rdma/CMakeLists.txt index bf111195ecc..b04c5c12d18 100644 --- a/src/plugins/rdma/CMakeLists.txt +++ b/src/plugins/rdma/CMakeLists.txt @@ -29,8 +29,15 @@ endif() string_append(RDMA_LINK_FLAGS "-Wl,--whole-archive,${MLX5_LIB},--no-whole-archive") -set(CMAKE_REQUIRED_FLAGS "-fPIC -shared -pthread ${RDMA_LINK_FLAGS} ${IBVERBS_LIB} ${RDMA_UTIL_LIB}") -CHECK_C_SOURCE_COMPILES("int main(void) { return 0; }" IBVERBS_COMPILES_CHECK) +set(CMAKE_REQUIRED_FLAGS "-fPIC -shared -pthread -Wno-unused-command-line-argument ${RDMA_LINK_FLAGS} ${IBVERBS_LIB} ${RDMA_UTIL_LIB}") +set(CMAKE_REQUIRED_INCLUDES "${IBVERBS_INCLUDE_DIR}") +set(CMAKE_REQUIRED_LIBRARIES "c") # force linkage by including libc explicitely +CHECK_C_SOURCE_COMPILES(" +#include <infiniband/verbs.h> +int main(void) +{ + return 0 != ibv_get_device_list(0); +}" IBVERBS_COMPILES_CHECK) if (NOT IBVERBS_COMPILES_CHECK) message(WARNING "rdma plugins - no working ibverbs found - rdma plugin disabled") diff --git a/src/plugins/srv6-ad/ad.c b/src/plugins/srv6-ad/ad.c index 73ea3f6ac1f..9bf48147188 100644 --- a/src/plugins/srv6-ad/ad.c +++ b/src/plugins/srv6-ad/ad.c @@ -105,8 +105,12 @@ srv6_ad_localsid_creation_fn (ip6_sr_localsid_t * localsid) /* Set interface in promiscuous mode */ vnet_main_t *vnm = vnet_get_main (); - ethernet_set_flags (vnm, ls_mem->sw_if_index_in, - ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); + vnet_hw_interface_t *hi = + vnet_get_sup_hw_interface (vnm, ls_mem->sw_if_index_in); + /* Make sure it is main interface */ + if (hi->sw_if_index == ls_mem->sw_if_index_in) + ethernet_set_flags (vnm, hi->hw_if_index, + ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); /* Associate local SID index to this interface (resize vector if needed) */ if (ls_mem->sw_if_index_in >= vec_len (sm->sw_iface_localsid2)) @@ -196,7 +200,11 @@ srv6_ad_localsid_removal_fn (ip6_sr_localsid_t * localsid) /* Disable promiscuous mode on the interface */ vnet_main_t *vnm = vnet_get_main (); - ethernet_set_flags (vnm, ls_mem->sw_if_index_in, 0); + vnet_hw_interface_t *hi = + vnet_get_sup_hw_interface (vnm, ls_mem->sw_if_index_in); + /* Make sure it is main interface */ + if (hi->sw_if_index == ls_mem->sw_if_index_in) + ethernet_set_flags (vnm, hi->hw_if_index, 0); /* Remove local SID index from interface table */ sm->sw_iface_localsid2[ls_mem->sw_if_index_in] = ~(u32) 0; diff --git a/src/plugins/srv6-as/as.c b/src/plugins/srv6-as/as.c index 3a476044d60..69efc99e429 100644 --- a/src/plugins/srv6-as/as.c +++ b/src/plugins/srv6-as/as.c @@ -177,8 +177,12 @@ srv6_as_localsid_creation_fn (ip6_sr_localsid_t * localsid) /* Set interface in promiscuous mode */ vnet_main_t *vnm = vnet_get_main (); - ethernet_set_flags (vnm, ls_mem->sw_if_index_in, - ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); + vnet_hw_interface_t *hi = + vnet_get_sup_hw_interface (vnm, ls_mem->sw_if_index_in); + /* Make sure it is main interface */ + if (hi->sw_if_index == ls_mem->sw_if_index_in) + ethernet_set_flags (vnm, hi->hw_if_index, + ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); /* Prepare rewrite string */ ls_mem->rewrite = prepare_rewrite (ls_mem->src_addr, ls_mem->sid_list, @@ -278,7 +282,11 @@ srv6_as_localsid_removal_fn (ip6_sr_localsid_t * localsid) /* Disable promiscuous mode on the interface */ vnet_main_t *vnm = vnet_get_main (); - ethernet_set_flags (vnm, ls_mem->sw_if_index_in, 0); + vnet_hw_interface_t *hi = + vnet_get_sup_hw_interface (vnm, ls_mem->sw_if_index_in); + /* Make sure it is main interface */ + if (hi->sw_if_index == ls_mem->sw_if_index_in) + ethernet_set_flags (vnm, hi->hw_if_index, 0); /* Remove local SID index from interface table */ sm->sw_iface_localsid2[ls_mem->sw_if_index_in] = ~(u32) 0; diff --git a/src/tools/g2/CMakeLists.txt b/src/tools/g2/CMakeLists.txt index 36dd6e9e625..e8011912e9e 100644 --- a/src/tools/g2/CMakeLists.txt +++ b/src/tools/g2/CMakeLists.txt @@ -15,6 +15,7 @@ option(VPP_BUILD_G2 "Build g2 tool." OFF) if(VPP_BUILD_G2) find_package(GTK2 COMPONENTS gtk) if(GTK2_FOUND) + set(CMAKE_C_FLAGS "-Wno-deprecated-declarations ${CMAKE_C_FLAGS}") include_directories(${GTK2_INCLUDE_DIRS}) add_vpp_executable(g2 SOURCES @@ -29,8 +30,6 @@ if(VPP_BUILD_G2) view1.c LINK_LIBRARIES vppinfra Threads::Threads m ${GTK2_LIBRARIES} - NO_INSTALL ) endif() endif() - diff --git a/src/vat/api_format.c b/src/vat/api_format.c index c82c367cd5d..e81300013b2 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -762,9 +762,9 @@ increment_v6_address (vl_api_ip6_address_t * i) static void increment_address (vl_api_address_t * a) { - if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4) + if (a->af == ADDRESS_IP4) increment_v4_address (&a->un.ip4); - else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6) + else if (a->af == ADDRESS_IP6) increment_v6_address (&a->un.ip6); } diff --git a/src/vat/json_format.h b/src/vat/json_format.h index 260c32ede25..71db79eacf5 100644 --- a/src/vat/json_format.h +++ b/src/vat/json_format.h @@ -94,8 +94,7 @@ vat_json_set_string_copy (vat_json_node_t * json, const u8 * str) { u8 *ns = NULL; int len = strlen ((const char *) str); - vec_validate (ns, len); - memcpy ((char *) ns, (const char *) str, len + 1); + vec_validate_init_c_string (ns, str, len); vat_json_set_string (json, ns); } diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c index af9742063fa..304a70a3c6a 100644 --- a/src/vcl/ldp.c +++ b/src/vcl/ldp.c @@ -477,13 +477,8 @@ writev (int fd, const struct iovec * iov, int iovcnt) return size; } -#ifdef HAVE_FCNTL64 -int -fcntl64 (int fd, int cmd, ...) -#else int fcntl (int fd, int cmd, ...) -#endif { vls_handle_t vlsh; int rv = 0; @@ -544,6 +539,18 @@ fcntl (int fd, int cmd, ...) } int +fcntl64 (int fd, int cmd, ...) +{ + va_list ap; + int rv; + + va_start (ap, cmd); + rv = fcntl (fd, cmd, ap); + va_end (ap); + return rv; +} + +int ioctl (int fd, unsigned long int cmd, ...) { vls_handle_t vlsh; @@ -620,12 +627,13 @@ ldp_select_init_maps (fd_set * __restrict original, if (vlsh == VLS_INVALID_HANDLE) clib_bitmap_set_no_check (*libcb, fd, 1); else - clib_bitmap_set_no_check (*vclb, vlsh_to_session_index (vlsh), 1); + *vclb = clib_bitmap_set (*vclb, vlsh_to_session_index (vlsh), 1); })); /* *INDENT-ON* */ si_bits_set = clib_bitmap_last_set (*vclb) + 1; *si_bits = (si_bits_set > *si_bits) ? si_bits_set : *si_bits; + clib_bitmap_validate (*resultb, *si_bits); libc_bits_set = clib_bitmap_last_set (*libcb) + 1; *libc_bits = (libc_bits_set > *libc_bits) ? libc_bits_set : *libc_bits; @@ -756,15 +764,15 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, { if (readfds) clib_memcpy_fast (ldpw->rd_bitmap, ldpw->si_rd_bitmap, - vec_len (ldpw->rd_bitmap) * + vec_len (ldpw->si_rd_bitmap) * sizeof (clib_bitmap_t)); if (writefds) clib_memcpy_fast (ldpw->wr_bitmap, ldpw->si_wr_bitmap, - vec_len (ldpw->wr_bitmap) * + vec_len (ldpw->si_wr_bitmap) * sizeof (clib_bitmap_t)); if (exceptfds) clib_memcpy_fast (ldpw->ex_bitmap, ldpw->si_ex_bitmap, - vec_len (ldpw->ex_bitmap) * + vec_len (ldpw->si_ex_bitmap) * sizeof (clib_bitmap_t)); rv = vls_select (si_bits, readfds ? ldpw->rd_bitmap : NULL, @@ -774,6 +782,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, { errno = -rv; rv = -1; + goto done; } else if (rv > 0) { diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 0925246f8a1..bdbd9256a7a 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -1090,8 +1090,8 @@ vppcom_app_create (char *app_name) void vppcom_app_destroy (void) { + vcl_worker_t *wrk, *current_wrk; struct dlmallinfo mi; - vcl_worker_t *wrk; mspace heap; if (!pool_elts (vcm->workers)) @@ -1099,16 +1099,20 @@ vppcom_app_destroy (void) vcl_evt (VCL_EVT_DETACH, vcm); - vcl_send_app_detach (vcl_worker_get_current ()); + current_wrk = vcl_worker_get_current (); /* *INDENT-OFF* */ pool_foreach (wrk, vcm->workers, ({ - vcl_worker_cleanup (wrk, 0 /* notify vpp */ ); + if (current_wrk != wrk) + vcl_worker_cleanup (wrk, 0 /* notify vpp */ ); })); /* *INDENT-ON* */ + vcl_send_app_detach (current_wrk); + vppcom_disconnect_from_vpp (); + vcl_worker_cleanup (current_wrk, 0 /* notify vpp */ ); + vcl_elog_stop (vcm); - vl_client_disconnect_from_vlib (); /* * Free the heap and fix vcm @@ -1118,6 +1122,7 @@ vppcom_app_destroy (void) munmap (mspace_least_addr (heap), mi.arena); vcm = &_vppcom_main; + vcm->is_init = 0; } int @@ -2024,7 +2029,7 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, case SESSION_IO_EVT_RX: sid = e->session_index; session = vcl_session_get (wrk, sid); - if (!session) + if (!session || !vcl_session_is_open (session)) break; vcl_fifo_rx_evt_valid_or_break (session); if (sid < n_bits && read_map) @@ -2036,7 +2041,7 @@ vcl_select_handle_mq_event (vcl_worker_t * wrk, session_event_t * e, case SESSION_IO_EVT_TX: sid = e->session_index; session = vcl_session_get (wrk, sid); - if (!session) + if (!session || !vcl_session_is_open (session)) break; if (sid < n_bits && write_map) { @@ -2217,7 +2222,7 @@ vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_map, u32 sid, minbits = clib_max (n_bits, BITS (uword)), bits_set = 0; vcl_worker_t *wrk = vcl_worker_get_current (); vcl_session_t *session = 0; - int rv, i; + int i; if (n_bits && read_map) { @@ -2251,13 +2256,12 @@ vppcom_select (int n_bits, vcl_si_set * read_map, vcl_si_set * write_map, clib_bitmap_foreach (sid, wrk->wr_bitmap, ({ if (!(session = vcl_session_get (wrk, sid))) { - if (except_map && sid < minbits) - clib_bitmap_set_no_check (except_map, sid, 1); - continue; + clib_bitmap_set_no_check ((uword*)write_map, sid, 1); + bits_set++; + continue; } - rv = svm_fifo_is_full_prod (session->tx_fifo); - if (!rv) + if (vcl_session_write_ready (session)) { clib_bitmap_set_no_check ((uword*)write_map, sid, 1); bits_set++; @@ -2273,13 +2277,12 @@ check_rd: clib_bitmap_foreach (sid, wrk->rd_bitmap, ({ if (!(session = vcl_session_get (wrk, sid))) { - if (except_map && sid < minbits) - clib_bitmap_set_no_check (except_map, sid, 1); - continue; + clib_bitmap_set_no_check ((uword*)read_map, sid, 1); + bits_set++; + continue; } - rv = vcl_session_read_ready (session); - if (rv) + if (vcl_session_read_ready (session)) { clib_bitmap_set_no_check ((uword*)read_map, sid, 1); bits_set++; @@ -2749,7 +2752,7 @@ vcl_epoll_wait_handle_mq (vcl_worker_t * wrk, svm_msg_q_t * mq, } } ASSERT (maxevents > *num_ev); - vcl_mq_dequeue_batch (wrk, mq, maxevents - *num_ev); + vcl_mq_dequeue_batch (wrk, mq, ~0); svm_msg_q_unlock (mq); handle_dequeued: @@ -2757,7 +2760,10 @@ handle_dequeued: { msg = vec_elt_at_index (wrk->mq_msg_vector, i); e = svm_msg_q_msg_data (mq, msg); - vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev); + if (*num_ev < maxevents) + vcl_epoll_wait_handle_mq_event (wrk, e, events, num_ev); + else + vcl_handle_mq_event (wrk, e); svm_msg_q_free_msg (mq, msg); } vec_reset_length (wrk->mq_msg_vector); @@ -3633,6 +3639,12 @@ vppcom_worker_unregister (void) vcl_set_worker_index (~0); } +void +vppcom_worker_index_set (int index) +{ + vcl_set_worker_index (index); +} + int vppcom_worker_index (void) { diff --git a/src/vcl/vppcom.h b/src/vcl/vppcom.h index 62613037575..771443021b3 100644 --- a/src/vcl/vppcom.h +++ b/src/vcl/vppcom.h @@ -334,6 +334,11 @@ extern void vppcom_worker_unregister (void); extern int vppcom_worker_index (void); /** + * Set current worker index + */ +extern void vppcom_worker_index_set (int); + +/** * Returns the current worker's message queues epoll fd * * This only works if vcl is configured to do eventfd based message queue diff --git a/src/vlib/buffer.c b/src/vlib/buffer.c index 53d60364df8..c0b899ce809 100644 --- a/src/vlib/buffer.c +++ b/src/vlib/buffer.c @@ -504,6 +504,13 @@ vlib_buffer_chain_append_data_with_alloc (vlib_main_t * vm, return copied; } +static uword +vlib_buffer_alloc_size (uword ext_hdr_size, uword data_size) +{ + return CLIB_CACHE_LINE_ROUND (ext_hdr_size + sizeof (vlib_buffer_t) + + data_size); +} + u8 vlib_buffer_pool_create (vlib_main_t * vm, char *name, u32 data_size, u32 physmem_map_index) @@ -559,7 +566,7 @@ vlib_buffer_pool_create (vlib_main_t * vm, char *name, u32 data_size, vec_validate_aligned (bp->threads, vec_len (vlib_mains) - 1, CLIB_CACHE_LINE_BYTES); - alloc_size = data_size + sizeof (vlib_buffer_t) + bm->ext_hdr_size; + alloc_size = vlib_buffer_alloc_size (bm->ext_hdr_size, data_size); n_alloc_per_page = (1ULL << m->log2_page_size) / alloc_size; /* preallocate buffer indices memory */ @@ -672,10 +679,9 @@ vlib_buffer_main_init_numa_node (struct vlib_main_t *vm, u32 numa_node, u32 physmem_map_index; uword n_pages, pagesize; u32 buffers_per_numa; - u32 buffer_size = CLIB_CACHE_LINE_ROUND (bm->ext_hdr_size + - sizeof (vlib_buffer_t) + - vlib_buffer_get_default_data_size - (vm)); + u32 buffer_size = vlib_buffer_alloc_size (bm->ext_hdr_size, + vlib_buffer_get_default_data_size + (vm)); u8 *name; pagesize = clib_mem_get_default_hugepage_size (); @@ -685,6 +691,16 @@ vlib_buffer_main_init_numa_node (struct vlib_main_t *vm, u32 numa_node, VLIB_BUFFER_DEFAULT_BUFFERS_PER_NUMA; retry: + + if (buffer_size > pagesize) + { + error = + clib_error_return (0, + "buffer size (%llu) is greater than page size (%llu)", + buffer_size, pagesize); + goto done; + } + n_pages = (buffers_per_numa - 1) / (pagesize / buffer_size) + 1; error = vlib_physmem_shared_map_create (vm, (char *) name, n_pages * pagesize, diff --git a/src/vlib/buffer.h b/src/vlib/buffer.h index 02b65264724..4e44a7a802c 100644 --- a/src/vlib/buffer.h +++ b/src/vlib/buffer.h @@ -178,7 +178,7 @@ typedef union u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE]; /** Packet data */ - u8 data[0]; + u8 data[]; }; #ifdef CLIB_HAVE_VEC128 u8x16 as_u8x16[4]; diff --git a/src/vlib/counter.c b/src/vlib/counter.c index faf106942b7..c134229b751 100644 --- a/src/vlib/counter.c +++ b/src/vlib/counter.c @@ -91,6 +91,20 @@ vlib_validate_simple_counter (vlib_simple_counter_main_t * cm, u32 index) } void +vlib_free_simple_counter (vlib_simple_counter_main_t * cm) +{ + int i; + + vlib_stats_delete_cm (cm); + + void *oldheap = vlib_stats_push_heap (cm->counters); + for (i = 0; i < vec_len (cm->counters); i++) + vec_free (cm->counters[i]); + vec_free (cm->counters); + clib_mem_set_heap (oldheap); +} + +void vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index) { vlib_thread_main_t *tm = vlib_get_thread_main (); @@ -105,6 +119,58 @@ vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index) 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ ); } +int + vlib_validate_combined_counter_will_expand + (vlib_combined_counter_main_t * cm, u32 index) +{ + vlib_thread_main_t *tm = vlib_get_thread_main (); + int i; + void *oldheap = vlib_stats_push_heap (cm->counters); + + /* Possibly once in recorded history */ + if (PREDICT_FALSE (vec_len (cm->counters) == 0)) + { + vlib_stats_pop_heap (cm, oldheap, index, + 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ ); + return 1; + } + + for (i = 0; i < tm->n_vlib_mains; i++) + { + /* Trivially OK, and proves that index >= vec_len(...) */ + if (index < vec_len (cm->counters[i])) + continue; + if (_vec_resize_will_expand + (cm->counters[i], + index - vec_len (cm->counters[i]) /* length_increment */ , + sizeof (cm->counters[i]) /* data_bytes */ , + 0 /* header_bytes */ , + CLIB_CACHE_LINE_BYTES /* data_alignment */ )) + { + vlib_stats_pop_heap (cm, oldheap, index, + 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ ); + return 1; + } + } + vlib_stats_pop_heap (cm, oldheap, index, + 3 /*STAT_DIR_TYPE_COUNTER_VECTOR_COMBINED */ ); + return 0; +} + +void +vlib_free_combined_counter (vlib_combined_counter_main_t * cm) +{ + int i; + + vlib_stats_delete_cm (cm); + + void *oldheap = vlib_stats_push_heap (cm->counters); + for (i = 0; i < vec_len (cm->counters); i++) + vec_free (cm->counters[i]); + vec_free (cm->counters); + clib_mem_set_heap (oldheap); +} + u32 vlib_combined_counter_n_counters (const vlib_combined_counter_main_t * cm) { diff --git a/src/vlib/counter.h b/src/vlib/counter.h index 092bd00c879..6e8c65ede08 100644 --- a/src/vlib/counter.h +++ b/src/vlib/counter.h @@ -304,6 +304,8 @@ vlib_zero_combined_counter (vlib_combined_counter_main_t * cm, u32 index) void vlib_validate_simple_counter (vlib_simple_counter_main_t * cm, u32 index); +void vlib_free_simple_counter (vlib_simple_counter_main_t * cm); + /** validate a combined counter @param cm - (vlib_combined_counter_main_t *) pointer to the counter collection @@ -312,6 +314,10 @@ void vlib_validate_simple_counter (vlib_simple_counter_main_t * cm, void vlib_validate_combined_counter (vlib_combined_counter_main_t * cm, u32 index); +int vlib_validate_combined_counter_will_expand + (vlib_combined_counter_main_t * cm, u32 index); + +void vlib_free_combined_counter (vlib_combined_counter_main_t * cm); /** Obtain the number of simple or combined counters allocated. A macro which reduces to to vec_len(cm->maxi), the answer in either diff --git a/src/vlib/error.c b/src/vlib/error.c index 0918f624a66..7357f17c278 100644 --- a/src/vlib/error.c +++ b/src/vlib/error.c @@ -247,10 +247,10 @@ show_errors (vlib_main_t * vm, continue; if (verbose) - vlib_cli_output (vm, "%10Ld%=40v%=20s%=6d", c, n->name, + vlib_cli_output (vm, "%10lu%=40v%=20s%=6d", c, n->name, em->error_strings_heap[i], i); else - vlib_cli_output (vm, "%10d%=40v%s", c, n->name, + vlib_cli_output (vm, "%10lu%=40v%s", c, n->name, em->error_strings_heap[i]); } } @@ -270,7 +270,7 @@ show_errors (vlib_main_t * vm, if (sums[i]) { if (verbose) - vlib_cli_output (vm, "%10Ld%=40v%=20s%=10d", sums[i], n->name, + vlib_cli_output (vm, "%10lu%=40v%=20s%=10d", sums[i], n->name, em->error_strings_heap[i], i); } } diff --git a/src/vlib/linux/pci.c b/src/vlib/linux/pci.c index 8af1cdab0d4..722fb888117 100644 --- a/src/vlib/linux/pci.c +++ b/src/vlib/linux/pci.c @@ -1137,7 +1137,7 @@ vlib_pci_map_region_int (vlib_main_t * vm, vlib_pci_dev_handle_t h, if (*result == (void *) -1) { error = clib_error_return_unix (0, "mmap `BAR%u'", bar); - if (p->type == LINUX_PCI_DEVICE_TYPE_UIO) + if (p->type == LINUX_PCI_DEVICE_TYPE_UIO && (fd != -1)) close (fd); return error; } diff --git a/src/vlib/linux/vfio.c b/src/vlib/linux/vfio.c index 1ed99ceee55..1b901af0c8b 100644 --- a/src/vlib/linux/vfio.c +++ b/src/vlib/linux/vfio.c @@ -185,8 +185,9 @@ linux_vfio_group_get_device_fd (vlib_pci_addr_t * addr, int *fdp, int fd; *is_noiommu = 0; - s = format (s, "/sys/bus/pci/devices/%U/iommu_group", format_vlib_pci_addr, - addr); + s = + format (s, "/sys/bus/pci/devices/%U/iommu_group%c", format_vlib_pci_addr, + addr, 0); tmpstr = clib_sysfs_link_to_name ((char *) s); if (tmpstr) { @@ -201,8 +202,8 @@ linux_vfio_group_get_device_fd (vlib_pci_addr_t * addr, int *fdp, } vec_reset_length (s); - s = format (s, "/sys/bus/pci/devices/%U/iommu_group/name", - format_vlib_pci_addr, addr); + s = format (s, "/sys/bus/pci/devices/%U/iommu_group/name%c", + format_vlib_pci_addr, addr, 0); err = clib_sysfs_read ((char *) s, "%s", &tmpstr); if (err == 0) { diff --git a/src/vlib/node.c b/src/vlib/node.c index 2bb5bceadbc..fb250e2ce61 100644 --- a/src/vlib/node.c +++ b/src/vlib/node.c @@ -72,32 +72,6 @@ node_set_elog_name (vlib_main_t * vm, uword node_index) n->name_elog_string = elog_string (&vm->elog_main, "%v%c", n->name, 0); } -static void -vlib_worker_thread_node_rename (u32 node_index) -{ - int i; - vlib_main_t *vm; - vlib_node_t *n; - - if (vec_len (vlib_mains) == 1) - return; - - vm = vlib_mains[0]; - n = vlib_get_node (vm, node_index); - - ASSERT (vlib_get_thread_index () == 0); - ASSERT (*vlib_worker_threads->wait_at_barrier == 1); - - for (i = 1; i < vec_len (vlib_mains); i++) - { - vlib_main_t *vm_worker = vlib_mains[i]; - vlib_node_t *n_worker = vlib_get_node (vm_worker, node_index); - - n_worker->name = n->name; - n_worker->name_elog_string = n->name_elog_string; - } -} - void vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...) { @@ -115,7 +89,7 @@ vlib_node_rename (vlib_main_t * vm, u32 node_index, char *fmt, ...) node_set_elog_name (vm, node_index); /* Propagate the change to all worker threads */ - vlib_worker_thread_node_rename (node_index); + vlib_worker_thread_node_runtime_update (); } static void diff --git a/src/vlib/stat_weak_inlines.h b/src/vlib/stat_weak_inlines.h index d288a04c477..a1311e864b3 100644 --- a/src/vlib/stat_weak_inlines.h +++ b/src/vlib/stat_weak_inlines.h @@ -57,5 +57,10 @@ void vlib_stat_segment_unlock (void) { } +void vlib_stats_delete_cm (void *) __attribute__ ((weak)); +void +vlib_stats_delete_cm (void *notused) +{ +} #endif diff --git a/src/vlib/threads.c b/src/vlib/threads.c index 3488d70cec3..fe3a8746825 100644 --- a/src/vlib/threads.c +++ b/src/vlib/threads.c @@ -1837,17 +1837,19 @@ vlib_frame_queue_main_init (u32 node_index, u32 frame_queue_nelts) vlib_frame_queue_main_t *fqm; vlib_frame_queue_t *fq; int i; + u32 num_threads; if (frame_queue_nelts == 0) frame_queue_nelts = FRAME_QUEUE_MAX_NELTS; - ASSERT (frame_queue_nelts >= 8); + num_threads = 1 /* main thread */ + tm->n_threads; + ASSERT (frame_queue_nelts >= 8 + num_threads); vec_add2 (tm->frame_queue_mains, fqm, 1); fqm->node_index = node_index; fqm->frame_queue_nelts = frame_queue_nelts; - fqm->queue_hi_thresh = frame_queue_nelts - 2; + fqm->queue_hi_thresh = frame_queue_nelts - num_threads; vec_validate (fqm->vlib_frame_queues, tm->n_vlib_mains - 1); vec_validate (fqm->per_thread_data, tm->n_vlib_mains - 1); diff --git a/src/vlib/unix/cli.c b/src/vlib/unix/cli.c index 1a7d2d56300..f6daf928ef5 100644 --- a/src/vlib/unix/cli.c +++ b/src/vlib/unix/cli.c @@ -3232,6 +3232,23 @@ vlib_unix_cli_set_prompt (char *prompt) cm->cli_prompt = format (0, fmt, prompt); } +static unix_cli_file_t * +unix_cli_file_if_exists (unix_cli_main_t * cm) +{ + if (!cm->cli_file_pool) + return 0; + return pool_elt_at_index (cm->cli_file_pool, cm->current_input_file_index); +} + +static unix_cli_file_t * +unix_cli_file_if_interactive (unix_cli_main_t * cm) +{ + unix_cli_file_t *cf; + if ((cf = unix_cli_file_if_exists (cm)) && !cf->is_interactive) + return 0; + return cf; +} + /** CLI command to quit the terminal session. * @note If this is a stdin session then this will * shutdown VPP also. @@ -3241,8 +3258,10 @@ unix_cli_quit (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unix_cli_main_t *cm = &unix_cli_main; - unix_cli_file_t *cf = pool_elt_at_index (cm->cli_file_pool, - cm->current_input_file_index); + unix_cli_file_t *cf; + + if (!(cf = unix_cli_file_if_exists (cm))) + return clib_error_return (0, "invalid session"); /* Cosmetic: suppress the final prompt from appearing before we die */ cf->is_interactive = 0; @@ -3494,9 +3513,7 @@ unix_cli_show_history (vlib_main_t * vm, unix_cli_file_t *cf; int i, j; - cf = pool_elt_at_index (cm->cli_file_pool, cm->current_input_file_index); - - if (!cf->is_interactive) + if (!(cf = unix_cli_file_if_interactive (cm))) return clib_error_return (0, "invalid for non-interactive sessions"); if (cf->has_history && cf->history_limit) @@ -3534,7 +3551,9 @@ unix_cli_show_terminal (vlib_main_t * vm, unix_cli_file_t *cf; vlib_node_t *n; - cf = pool_elt_at_index (cm->cli_file_pool, cm->current_input_file_index); + if (!(cf = unix_cli_file_if_exists (cm))) + return clib_error_return (0, "invalid session"); + n = vlib_get_node (vm, cf->process_node_index); vlib_cli_output (vm, "Terminal name: %v\n", n->name); @@ -3686,9 +3705,7 @@ unix_cli_set_terminal_pager (vlib_main_t * vm, unformat_input_t _line_input, *line_input = &_line_input; clib_error_t *error = 0; - cf = pool_elt_at_index (cm->cli_file_pool, cm->current_input_file_index); - - if (!cf->is_interactive) + if (!(cf = unix_cli_file_if_interactive (cm))) return clib_error_return (0, "invalid for non-interactive sessions"); if (!unformat_user (input, unformat_line_input, line_input)) @@ -3745,9 +3762,7 @@ unix_cli_set_terminal_history (vlib_main_t * vm, u32 limit; clib_error_t *error = 0; - cf = pool_elt_at_index (cm->cli_file_pool, cm->current_input_file_index); - - if (!cf->is_interactive) + if (!(cf = unix_cli_file_if_interactive (cm))) return clib_error_return (0, "invalid for non-interactive sessions"); if (!unformat_user (input, unformat_line_input, line_input)) @@ -3815,9 +3830,7 @@ unix_cli_set_terminal_ansi (vlib_main_t * vm, unix_cli_main_t *cm = &unix_cli_main; unix_cli_file_t *cf; - cf = pool_elt_at_index (cm->cli_file_pool, cm->current_input_file_index); - - if (!cf->is_interactive) + if (!(cf = unix_cli_file_if_interactive (cm))) return clib_error_return (0, "invalid for non-interactive sessions"); if (unformat (input, "on")) diff --git a/src/vlibapi/api_shared.c b/src/vlibapi/api_shared.c index ce7c4aec712..6849ab0783c 100644 --- a/src/vlibapi/api_shared.c +++ b/src/vlibapi/api_shared.c @@ -595,7 +595,7 @@ vl_msg_api_handler_with_vm_node (api_main_t * am, * Special-case, so we can e.g. bounce messages off the vnet * main thread without copying them... */ - if (!(am->message_bounce[id])) + if (id >= vec_len (am->message_bounce) || !(am->message_bounce[id])) vl_msg_api_free (the_msg); if (PREDICT_FALSE (am->elog_trace_api_messages)) diff --git a/src/vnet/adj/adj.c b/src/vnet/adj/adj.c index 03c82062cc0..3871e2c1612 100644 --- a/src/vnet/adj/adj.c +++ b/src/vnet/adj/adj.c @@ -63,15 +63,35 @@ ip_adjacency_t * adj_alloc (fib_protocol_t proto) { ip_adjacency_t *adj; + u8 need_barrier_sync = 0; + vlib_main_t *vm; + vm = vlib_get_main(); + + ASSERT (vm->thread_index == 0); + + pool_get_aligned_will_expand (adj_pool, need_barrier_sync, + CLIB_CACHE_LINE_BYTES); + /* If the adj_pool will expand, stop the parade. */ + if (need_barrier_sync) + vlib_worker_thread_barrier_sync (vm); pool_get_aligned(adj_pool, adj, CLIB_CACHE_LINE_BYTES); adj_poison(adj); - /* Make sure certain fields are always initialized. */ /* Validate adjacency counters. */ + if (need_barrier_sync == 0) + { + /* If the adj counter pool will expand, stop the parade */ + need_barrier_sync = vlib_validate_combined_counter_will_expand + (&adjacency_counters, adj_get_index (adj)); + if (need_barrier_sync) + vlib_worker_thread_barrier_sync (vm); + } vlib_validate_combined_counter(&adjacency_counters, adj_get_index(adj)); + + /* Make sure certain fields are always initialized. */ vlib_zero_combined_counter(&adjacency_counters, adj_get_index(adj)); fib_node_init(&adj->ia_node, @@ -88,6 +108,9 @@ adj_alloc (fib_protocol_t proto) clib_memset(&adj->sub_type.midchain.next_dpo, 0, sizeof(adj->sub_type.midchain.next_dpo)); + if (need_barrier_sync) + vlib_worker_thread_barrier_release (vm); + return (adj); } diff --git a/src/vnet/bonding/cli.c b/src/vnet/bonding/cli.c index 631a97b3a82..c49b6efc176 100644 --- a/src/vnet/bonding/cli.c +++ b/src/vnet/bonding/cli.c @@ -675,12 +675,11 @@ bond_enslave (vlib_main_t * vm, bond_enslave_args_t * args) } if (bif_hw->l2_if_count) - { - ethernet_set_flags (vnm, sif_hw->hw_if_index, - ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); - /* ensure all packets go to ethernet-input */ - ethernet_set_rx_redirect (vnm, sif_hw, 1); - } + ethernet_set_flags (vnm, sif_hw->hw_if_index, + ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); + else + ethernet_set_flags (vnm, sif_hw->hw_if_index, + /*ETHERNET_INTERFACE_FLAG_DEFAULT_L3 */ 0); if (bif->mode == BOND_MODE_LACP) { diff --git a/src/vnet/bonding/device.c b/src/vnet/bonding/device.c index 21bbcb51f1d..ad52f621511 100644 --- a/src/vnet/bonding/device.c +++ b/src/vnet/bonding/device.c @@ -99,9 +99,6 @@ bond_set_l2_mode_function (vnet_main_t * vnm, sif_hw = vnet_get_sup_hw_interface (vnm, *sw_if_index); ethernet_set_flags (vnm, sif_hw->hw_if_index, ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); - - /* ensure all packets go to ethernet-input */ - ethernet_set_rx_redirect (vnm, sif_hw, 1); } } else if ((bif_hw->l2_if_count == 0) && (l2_if_adjust == -1)) @@ -110,9 +107,8 @@ bond_set_l2_mode_function (vnet_main_t * vnm, vec_foreach (sw_if_index, bif->slaves) { sif_hw = vnet_get_sup_hw_interface (vnm, *sw_if_index); - - /* Allow ip packets to go directly to ip4-input etc */ - ethernet_set_rx_redirect (vnm, sif_hw, 0); + ethernet_set_flags (vnm, sif_hw->hw_if_index, + /*ETHERNET_INTERFACE_FLAG_DEFAULT_L3 */ 0); } } diff --git a/src/vnet/classify/vnet_classify.c b/src/vnet/classify/vnet_classify.c index d97042eda36..dd846cbe3d2 100755 --- a/src/vnet/classify/vnet_classify.c +++ b/src/vnet/classify/vnet_classify.c @@ -1037,7 +1037,7 @@ unformat_ip6_mask (unformat_input_t * input, va_list * args) { u8 **maskp = va_arg (*args, u8 **); u8 *mask = 0; - u8 found_something = 0; + u8 found_something; ip6_header_t *ip; u32 ip_version_traffic_class_and_flow_label; @@ -1070,6 +1070,10 @@ unformat_ip6_mask (unformat_input_t * input, va_list * args) break; } + /* Account for "special" field names */ + found_something = version + traffic_class + flow_label + + src_address + dst_address + protocol; + #define _(a) found_something += a; foreach_ip6_proto_field; #undef _ diff --git a/src/vnet/config.c b/src/vnet/config.c index 9beda4a5706..73fed66d13a 100644 --- a/src/vnet/config.c +++ b/src/vnet/config.c @@ -267,11 +267,16 @@ vnet_config_add_feature (vlib_main_t * vm, f->feature_index = feature_index; f->node_index = node_index; - n_feature_config_u32s = - round_pow2 (n_feature_config_bytes, - sizeof (f->feature_config[0])) / - sizeof (f->feature_config[0]); - vec_add (f->feature_config, feature_config, n_feature_config_u32s); + if (n_feature_config_bytes) + { + n_feature_config_u32s = + round_pow2 (n_feature_config_bytes, + sizeof (f->feature_config[0])) / + sizeof (f->feature_config[0]); + vec_validate (f->feature_config, n_feature_config_u32s - 1); + clib_memcpy_fast (f->feature_config, feature_config, + n_feature_config_bytes); + } /* Sort (prioritize) features. */ if (vec_len (new_features) > 1) diff --git a/src/vnet/devices/netlink.c b/src/vnet/devices/netlink.c index a954fef74fd..298a3e43c5a 100644 --- a/src/vnet/devices/netlink.c +++ b/src/vnet/devices/netlink.c @@ -184,7 +184,7 @@ vnet_netlink_set_link_state (int ifindex, int up) vnet_netlink_msg_t m; struct ifinfomsg ifmsg = { 0 }; - ifmsg.ifi_flags = IFF_UP; + ifmsg.ifi_flags = ((up) ? IFF_UP : 0); ifmsg.ifi_change = IFF_UP; ifmsg.ifi_index = ifindex; diff --git a/src/vnet/devices/virtio/vhost_user_input.c b/src/vnet/devices/virtio/vhost_user_input.c index 2cc192d9dc8..e2ad5cf7cae 100644 --- a/src/vnet/devices/virtio/vhost_user_input.c +++ b/src/vnet/devices/virtio/vhost_user_input.c @@ -296,15 +296,11 @@ vhost_user_handle_rx_offload (vlib_buffer_t * b0, u8 * b0_data, tcp_header_t *tcp = (tcp_header_t *) (b0_data + vnet_buffer (b0)->l4_hdr_offset); l4_hdr_sz = tcp_header_bytes (tcp); - tcp->checksum = 0; b0->flags |= VNET_BUFFER_F_OFFLOAD_TCP_CKSUM; } else if (l4_proto == IP_PROTOCOL_UDP) { - udp_header_t *udp = - (udp_header_t *) (b0_data + vnet_buffer (b0)->l4_hdr_offset); - l4_hdr_sz = sizeof (*udp); - udp->checksum = 0; + l4_hdr_sz = sizeof (udp_header_t); b0->flags |= VNET_BUFFER_F_OFFLOAD_UDP_CKSUM; } } diff --git a/src/vnet/devices/virtio/virtio.c b/src/vnet/devices/virtio/virtio.c index 5e23bef0889..0fdac9cbd6c 100644 --- a/src/vnet/devices/virtio/virtio.c +++ b/src/vnet/devices/virtio/virtio.c @@ -55,7 +55,8 @@ call_read_ready (clib_file_t * uf) CLIB_UNUSED (ssize_t size) = read (uf->file_descriptor, &b, sizeof (b)); if ((qid & 1) == 0) - vnet_device_input_set_interrupt_pending (vnm, vif->hw_if_index, qid); + vnet_device_input_set_interrupt_pending (vnm, vif->hw_if_index, + RX_QUEUE_ACCESS (qid)); return 0; } diff --git a/src/vnet/dhcp/client.c b/src/vnet/dhcp/client.c index 5412dab3f7e..3aa92c3ebb7 100644 --- a/src/vnet/dhcp/client.c +++ b/src/vnet/dhcp/client.c @@ -276,10 +276,10 @@ dhcp_client_for_us (u32 bi, vlib_buffer_t * b, udp_header_t * udp, dhcp_header_t * dhcp) { dhcp_client_main_t *dcm = &dhcp_client_main; - vlib_main_t *vm = dcm->vlib_main; + vlib_main_t *vm = vlib_get_main (); dhcp_client_t *c; uword *p; - f64 now = vlib_time_now (dcm->vlib_main); + f64 now = vlib_time_now (vm); u8 dhcp_message_type = 0; dhcp_option_t *o; diff --git a/src/vnet/dpo/classify_dpo.c b/src/vnet/dpo/classify_dpo.c index 08fab83f2ee..bc536a10266 100644 --- a/src/vnet/dpo/classify_dpo.c +++ b/src/vnet/dpo/classify_dpo.c @@ -26,8 +26,13 @@ static classify_dpo_t * classify_dpo_alloc (void) { classify_dpo_t *cd; + vlib_main_t *vm; + u8 did_barrier_sync; + dpo_pool_barrier_sync (vm, classify_dpo_pool, did_barrier_sync); pool_get_aligned(classify_dpo_pool, cd, CLIB_CACHE_LINE_BYTES); + dpo_pool_barrier_release (vm, did_barrier_sync); + clib_memset(cd, 0, sizeof(*cd)); return (cd); diff --git a/src/vnet/dpo/dpo.h b/src/vnet/dpo/dpo.h index 19b47f268b0..0658f4216c6 100644 --- a/src/vnet/dpo/dpo.h +++ b/src/vnet/dpo/dpo.h @@ -16,7 +16,7 @@ * @brief * A Data-Path Object is an object that represents actions that are * applied to packets are they are switched through VPP's data-path. - * + * * The DPO can be considered to be like is a base class that is specialised * by other objects to provide concreate actions * @@ -328,7 +328,7 @@ extern void dpo_stack(dpo_type_t child_type, const dpo_id_t *parent_dpo); /** - * @brief + * @brief * Set and stack a DPO. * The DPO passed is set to the parent DPO and the necessary * VLIB graph arcs are created, from the child_node passed. @@ -341,7 +341,7 @@ extern void dpo_stack(dpo_type_t child_type, * * @param parent_dpo * The parent DPO to stack onto. - */ + */ extern void dpo_stack_from_node(u32 child_node, dpo_id_t *dpo, const dpo_id_t *parent); @@ -443,7 +443,7 @@ typedef struct dpo_vft_t_ * (see above). * * @param type - * The type being registered. + * The type being registered. * * @param vft * The virtual function table to register for the type. @@ -497,4 +497,49 @@ dpo_get_next_node_by_type_and_proto (dpo_type_t child_type, dpo_proto_t child_proto, dpo_type_t parent_type, dpo_proto_t parent_proto); + + +/** + * @brief Barrier sync if a dpo pool is about to expand + * + * @param VM (output) + * vlib_main_t *, invariably &vlib_global_main + * + * @param P + * pool pointer + * + * @param YESNO (output) + * typically a u8, 1 => expand will occur, worker barrier held + * 0 => no expand, barrier not held + * + * @return YESNO set + */ + +#define dpo_pool_barrier_sync(VM,P,YESNO) \ +do { \ + pool_get_aligned_will_expand ((P), YESNO, CLIB_CACHE_LINE_BYTES); \ + \ + if (YESNO) \ + { \ + VM = vlib_get_main(); \ + ASSERT ((VM)->thread_index == 0); \ + vlib_worker_thread_barrier_sync((VM)); \ + } \ +} while(0); + +/** + * @brief Release barrier sync after dpo pool expansion + * + * @param VM + * vlib_main_t pointer, must be &vlib_global_main + * + * @param YESNO + * typically a u8, 1 => release required + * 0 => no release required + * @return none + */ + +#define dpo_pool_barrier_release(VM,YESNO) \ + if ((YESNO)) vlib_worker_thread_barrier_release((VM)); + #endif diff --git a/src/vnet/dpo/load_balance.c b/src/vnet/dpo/load_balance.c index 7acccca61bf..c029341f147 100644 --- a/src/vnet/dpo/load_balance.c +++ b/src/vnet/dpo/load_balance.c @@ -93,12 +93,33 @@ static load_balance_t * load_balance_alloc_i (void) { load_balance_t *lb; + u8 need_barrier_sync = 0; + vlib_main_t *vm = vlib_get_main(); + ASSERT (vm->thread_index == 0); + + pool_get_aligned_will_expand (load_balance_pool, need_barrier_sync, + CLIB_CACHE_LINE_BYTES); + if (need_barrier_sync) + vlib_worker_thread_barrier_sync (vm); pool_get_aligned(load_balance_pool, lb, CLIB_CACHE_LINE_BYTES); clib_memset(lb, 0, sizeof(*lb)); lb->lb_map = INDEX_INVALID; lb->lb_urpf = INDEX_INVALID; + + if (need_barrier_sync == 0) + { + need_barrier_sync += vlib_validate_combined_counter_will_expand + (&(load_balance_main.lbm_to_counters), + load_balance_get_index(lb)); + need_barrier_sync += vlib_validate_combined_counter_will_expand + (&(load_balance_main.lbm_via_counters), + load_balance_get_index(lb)); + if (need_barrier_sync) + vlib_worker_thread_barrier_sync (vm); + } + vlib_validate_combined_counter(&(load_balance_main.lbm_to_counters), load_balance_get_index(lb)); vlib_validate_combined_counter(&(load_balance_main.lbm_via_counters), @@ -108,6 +129,9 @@ load_balance_alloc_i (void) vlib_zero_combined_counter(&(load_balance_main.lbm_via_counters), load_balance_get_index(lb)); + if (need_barrier_sync) + vlib_worker_thread_barrier_release (vm); + return (lb); } @@ -1121,7 +1145,7 @@ load_balance_inline (vlib_main_t * vm, vnet_buffer(b0)->ip.flow_hash = bier_compute_flow_hash(bh0); } - dpo0 = load_balance_get_bucket_i(lb0, + dpo0 = load_balance_get_bucket_i(lb0, vnet_buffer(b0)->ip.flow_hash & (lb0->lb_n_buckets_minus_1)); diff --git a/src/vnet/dpo/load_balance_map.c b/src/vnet/dpo/load_balance_map.c index 7da360b88ac..c03acaf2d70 100644 --- a/src/vnet/dpo/load_balance_map.c +++ b/src/vnet/dpo/load_balance_map.c @@ -387,8 +387,13 @@ load_balance_map_alloc (const load_balance_path_t *paths) { load_balance_map_t *lbm; u32 ii; + vlib_main_t *vm; + u8 did_barrier_sync; + dpo_pool_barrier_sync (vm, load_balance_map_pool, did_barrier_sync); pool_get_aligned(load_balance_map_pool, lbm, CLIB_CACHE_LINE_BYTES); + dpo_pool_barrier_release (vm, did_barrier_sync); + clib_memset(lbm, 0, sizeof(*lbm)); vec_validate(lbm->lbm_paths, vec_len(paths)-1); diff --git a/src/vnet/dpo/lookup_dpo.c b/src/vnet/dpo/lookup_dpo.c index daa2352f649..677a19fe862 100644 --- a/src/vnet/dpo/lookup_dpo.c +++ b/src/vnet/dpo/lookup_dpo.c @@ -63,8 +63,12 @@ static lookup_dpo_t * lookup_dpo_alloc (void) { lookup_dpo_t *lkd; + vlib_main_t *vm; + u8 did_barrier_sync; + dpo_pool_barrier_sync (vm, lookup_dpo_pool, did_barrier_sync); pool_get_aligned(lookup_dpo_pool, lkd, CLIB_CACHE_LINE_BYTES); + dpo_pool_barrier_release (vm, did_barrier_sync); return (lkd); } @@ -1076,7 +1080,7 @@ lookup_dpo_mpls_inline (vlib_main_t * vm, */ if (table_from_interface) { - fib_index0 = + fib_index0 = mpls_fib_table_get_index_for_sw_if_index( vnet_buffer(b0)->sw_if_index[VLIB_RX]); } @@ -1142,9 +1146,9 @@ lookup_dpo_mpls_inline (vlib_main_t * vm, if (PREDICT_FALSE(vnet_buffer2(b0)->loop_counter > MAX_LUKPS_PER_PACKET)) next0 = MPLS_LOOKUP_NEXT_DROP; - if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) + if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) { - lookup_trace_t *tr = vlib_add_trace (vm, node, + lookup_trace_t *tr = vlib_add_trace (vm, node, b0, sizeof (*tr)); tr->fib_index = fib_index0; tr->lbi = lbi0; diff --git a/src/vnet/dpo/mpls_label_dpo.c b/src/vnet/dpo/mpls_label_dpo.c index 9d147f98f13..683b5449513 100644 --- a/src/vnet/dpo/mpls_label_dpo.c +++ b/src/vnet/dpo/mpls_label_dpo.c @@ -39,8 +39,13 @@ static mpls_label_dpo_t * mpls_label_dpo_alloc (void) { mpls_label_dpo_t *mld; + vlib_main_t *vm; + u8 did_barrier_sync; + dpo_pool_barrier_sync (vm, mpls_label_dpo_pool, did_barrier_sync); pool_get_aligned(mpls_label_dpo_pool, mld, CLIB_CACHE_LINE_BYTES); + dpo_pool_barrier_release (vm, did_barrier_sync); + clib_memset(mld, 0, sizeof(*mld)); dpo_reset(&mld->mld_dpo); diff --git a/src/vnet/dpo/receive_dpo.c b/src/vnet/dpo/receive_dpo.c index 949dbfa6587..b12b382ce64 100644 --- a/src/vnet/dpo/receive_dpo.c +++ b/src/vnet/dpo/receive_dpo.c @@ -35,8 +35,13 @@ static receive_dpo_t * receive_dpo_alloc (void) { receive_dpo_t *rd; + vlib_main_t *vm; + u8 did_barrier_sync; + dpo_pool_barrier_sync (vm, receive_dpo_pool, did_barrier_sync); pool_get_aligned(receive_dpo_pool, rd, CLIB_CACHE_LINE_BYTES); + dpo_pool_barrier_release (vm, did_barrier_sync); + clib_memset(rd, 0, sizeof(*rd)); return (rd); diff --git a/src/vnet/ethernet/p2p_ethernet_api.c b/src/vnet/ethernet/p2p_ethernet_api.c index 3f537168a8e..74b5e0c8658 100644 --- a/src/vnet/ethernet/p2p_ethernet_api.c +++ b/src/vnet/ethernet/p2p_ethernet_api.c @@ -52,7 +52,7 @@ vl_api_p2p_ethernet_add_t_handler (vl_api_p2p_ethernet_add_t * mp) u32 parent_if_index = htonl (mp->parent_if_index); u32 sub_id = htonl (mp->subif_id); - u32 p2pe_if_index; + u32 p2pe_if_index = ~0; u8 remote_mac[6]; clib_memcpy (remote_mac, mp->remote_mac, 6); diff --git a/src/vnet/fib/fib_entry_src_interpose.c b/src/vnet/fib/fib_entry_src_interpose.c index 2220fa4debd..15accac5533 100644 --- a/src/vnet/fib/fib_entry_src_interpose.c +++ b/src/vnet/fib/fib_entry_src_interpose.c @@ -115,6 +115,20 @@ fib_entry_src_interpose_activate (fib_entry_src_t *src, */ src->fes_pl = best_src->fes_pl; } + else + { + /* + * the best source won't install so will use a drop + */ + dpo_proto_t dproto; + + dproto = fib_proto_to_dpo(fib_entry->fe_prefix.fp_proto); + + src->fes_pl = + fib_path_list_create_special(dproto, + FIB_PATH_LIST_FLAG_DROP, + drop_dpo_get(dproto)); + } } else { diff --git a/src/vnet/interface_cli.c b/src/vnet/interface_cli.c index 6c4df198548..2356f268435 100644 --- a/src/vnet/interface_cli.c +++ b/src/vnet/interface_cli.c @@ -65,16 +65,15 @@ compare_interface_names (void *a1, void *a2) static clib_error_t * show_or_clear_hw_interfaces (vlib_main_t * vm, unformat_input_t * input, - vlib_cli_command_t * cmd) + vlib_cli_command_t * cmd, int is_show) { clib_error_t *error = 0; vnet_main_t *vnm = vnet_get_main (); vnet_interface_main_t *im = &vnm->interface_main; vnet_hw_interface_t *hi; u32 hw_if_index, *hw_if_indices = 0; - int i, verbose = -1, is_show, show_bond = 0; + int i, verbose = -1, show_bond = 0; - is_show = strstr (cmd->path, "show") != 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { /* See if user wants to show a specific interface. */ @@ -168,6 +167,21 @@ done: return error; } +static clib_error_t * +show_hw_interfaces (vlib_main_t * vm, + unformat_input_t * input, vlib_cli_command_t * cmd) +{ + return show_or_clear_hw_interfaces (vm, input, cmd, 1 /* is_show */ ); +} + +static clib_error_t * +clear_hw_interfaces (vlib_main_t * vm, + unformat_input_t * input, vlib_cli_command_t * cmd) +{ + return show_or_clear_hw_interfaces (vm, input, cmd, 0 /* is_show */ ); +} + + /*? * Display more detailed information about all or a list of given interfaces. * The verboseness of the output can be controlled by the following optional @@ -229,7 +243,7 @@ VLIB_CLI_COMMAND (show_hw_interfaces_command, static) = { .path = "show hardware-interfaces", .short_help = "show hardware-interfaces [brief|verbose|detail] [bond] " "[<interface> [<interface> [..]]] [<sw_idx> [<sw_idx> [..]]]", - .function = show_or_clear_hw_interfaces, + .function = show_hw_interfaces, }; /* *INDENT-ON* */ @@ -250,7 +264,7 @@ VLIB_CLI_COMMAND (clear_hw_interface_counters_command, static) = { .path = "clear hardware-interfaces", .short_help = "clear hardware-interfaces " "[<interface> [<interface> [..]]] [<sw_idx> [<sw_idx> [..]]]", - .function = show_or_clear_hw_interfaces, + .function = clear_hw_interfaces, }; /* *INDENT-ON* */ diff --git a/src/vnet/ip/ip.c b/src/vnet/ip/ip.c index 785cd491b57..3ecea9b8b27 100644 --- a/src/vnet/ip/ip.c +++ b/src/vnet/ip/ip.c @@ -81,7 +81,10 @@ void ip_copy (ip46_address_t * dst, ip46_address_t * src, u8 is_ip4) { if (is_ip4) - dst->ip4.as_u32 = src->ip4.as_u32; + { + ip46_address_mask_ip4 (dst); + dst->ip4.as_u32 = src->ip4.as_u32; + } else clib_memcpy_fast (&dst->ip6, &src->ip6, sizeof (ip6_address_t)); } @@ -90,7 +93,10 @@ void ip_set (ip46_address_t * dst, void *src, u8 is_ip4) { if (is_ip4) - dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32; + { + ip46_address_mask_ip4 (dst); + dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32; + } else clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src, sizeof (ip6_address_t)); diff --git a/src/vnet/ip/ip4_punt_drop.c b/src/vnet/ip/ip4_punt_drop.c index fc5a68fc66a..819eaa14861 100644 --- a/src/vnet/ip/ip4_punt_drop.c +++ b/src/vnet/ip/ip4_punt_drop.c @@ -337,10 +337,10 @@ ip4_punt_redirect_cmd (vlib_main_t * vm, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; - fib_route_path_t *rpaths = NULL, rpath; - dpo_proto_t payload_proto; + ip46_address_t nh = { 0 }; clib_error_t *error = 0; u32 rx_sw_if_index = ~0; + u32 tx_sw_if_index = ~0; vnet_main_t *vnm; u8 is_add; @@ -361,9 +361,13 @@ ip4_punt_redirect_cmd (vlib_main_t * vm, else if (unformat (line_input, "rx %U", unformat_vnet_sw_interface, vnm, &rx_sw_if_index)) ; + else if (unformat (line_input, "via %U %U", + unformat_ip4_address, &nh.ip4, + unformat_vnet_sw_interface, vnm, &tx_sw_if_index)) + ; else if (unformat (line_input, "via %U", - unformat_fib_route_path, &rpath, &payload_proto)) - vec_add1 (rpaths, rpath); + unformat_vnet_sw_interface, vnm, &tx_sw_if_index)) + ; else { error = unformat_parse_error (line_input); @@ -379,8 +383,7 @@ ip4_punt_redirect_cmd (vlib_main_t * vm, if (is_add) { - if (vec_len (rpaths)) - ip4_punt_redirect_add_paths (rx_sw_if_index, rpaths); + ip4_punt_redirect_add (rx_sw_if_index, tx_sw_if_index, &nh); } else { diff --git a/src/vnet/ip/ip6_format.c b/src/vnet/ip/ip6_format.c index 4d1793970df..6287195507b 100644 --- a/src/vnet/ip/ip6_format.c +++ b/src/vnet/ip/ip6_format.c @@ -127,13 +127,12 @@ format_ip6_address_and_mask (u8 * s, va_list * args) return format (s, "any"); if (am->mask.as_u64[0] == ~0 && am->mask.as_u64[1] == ~0) - return format (s, "%U", format_ip4_address, &am->addr); + return format (s, "%U", format_ip6_address, &am->addr); return format (s, "%U/%U", format_ip6_address, &am->addr, - format_ip4_address, &am->mask); + format_ip6_address, &am->mask); } - /* Parse an IP6 address. */ uword unformat_ip6_address (unformat_input_t * input, va_list * args) diff --git a/src/vnet/ip/punt.c b/src/vnet/ip/punt.c index a2952773f97..a3ccc43375e 100644 --- a/src/vnet/ip/punt.c +++ b/src/vnet/ip/punt.c @@ -424,8 +424,9 @@ vnet_punt_add_del (vlib_main_t * vm, const punt_reg_t * pr, bool is_add) static clib_error_t * punt_cli (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) + unformat_input_t * input__, vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; bool is_add = true; /* *INDENT-OFF* */ @@ -442,6 +443,9 @@ punt_cli (vlib_main_t * vm, u32 port; /* *INDENT-ON* */ + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "del")) @@ -476,6 +480,7 @@ punt_cli (vlib_main_t * vm, } done: + unformat_free (input); return error; } @@ -509,8 +514,10 @@ VLIB_CLI_COMMAND (punt_command, static) = { static clib_error_t * punt_socket_register_cmd (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) + unformat_input_t * input__, + vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; u8 *socket_name = 0; clib_error_t *error = NULL; /* *INDENT-OFF* */ @@ -526,6 +533,9 @@ punt_socket_register_cmd (vlib_main_t * vm, }; /* *INDENT-ON* */ + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "ipv4")) @@ -556,6 +566,7 @@ punt_socket_register_cmd (vlib_main_t * vm, error = vnet_punt_socket_add (vm, 1, &pr, (char *) socket_name); done: + unformat_free (input); return error; } @@ -577,9 +588,10 @@ VLIB_CLI_COMMAND (punt_socket_register_command, static) = static clib_error_t * punt_socket_deregister_cmd (vlib_main_t * vm, - unformat_input_t * input, + unformat_input_t * input__, vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; /* *INDENT-OFF* */ punt_reg_t pr = { @@ -594,6 +606,9 @@ punt_socket_deregister_cmd (vlib_main_t * vm, }; /* *INDENT-ON* */ + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "ipv4")) @@ -618,6 +633,7 @@ punt_socket_deregister_cmd (vlib_main_t * vm, error = vnet_punt_socket_del (vm, &pr); done: + unformat_free (input); return error; } @@ -723,13 +739,17 @@ punt_client_show_one (const punt_client_t * pc, void *ctx) static clib_error_t * punt_socket_show_cmd (vlib_main_t * vm, - unformat_input_t * input, vlib_cli_command_t * cmd) + unformat_input_t * input__, vlib_cli_command_t * cmd) { + unformat_input_t line_input, *input = &line_input; clib_error_t *error = NULL; punt_type_t pt; pt = PUNT_TYPE_L4; + if (!unformat_user (input__, unformat_line_input, input)) + return 0; + while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "exception")) @@ -749,6 +769,7 @@ punt_socket_show_cmd (vlib_main_t * vm, punt_client_walk (pt, punt_client_show_one, vm); done: + unformat_free (input); return (error); } diff --git a/src/vnet/ip/reass/ip4_full_reass.c b/src/vnet/ip/reass/ip4_full_reass.c index a2d08a4909c..cebc6a0e965 100644 --- a/src/vnet/ip/reass/ip4_full_reass.c +++ b/src/vnet/ip/reass/ip4_full_reass.c @@ -459,15 +459,15 @@ again: if (!clib_bihash_search_16_8 (&rm->hash, (clib_bihash_kv_16_8_t *) kv, (clib_bihash_kv_16_8_t *) kv)) { + if (vm->thread_index != kv->v.memory_owner_thread_index) + { + *do_handoff = 1; + return NULL; + } reass = pool_elt_at_index (rm->per_thread_data [kv->v.memory_owner_thread_index].pool, kv->v.reass_index); - if (vm->thread_index != reass->memory_owner_thread_index) - { - *do_handoff = 1; - return reass; - } if (now > reass->last_heard + rm->timeout) { diff --git a/src/vnet/ip/reass/ip6_full_reass.c b/src/vnet/ip/reass/ip6_full_reass.c index 6848f59c65c..69ba452840e 100644 --- a/src/vnet/ip/reass/ip6_full_reass.c +++ b/src/vnet/ip/reass/ip6_full_reass.c @@ -471,16 +471,17 @@ again: if (!clib_bihash_search_48_8 (&rm->hash, (clib_bihash_kv_48_8_t *) kv, (clib_bihash_kv_48_8_t *) kv)) { - reass = - pool_elt_at_index (rm->per_thread_data - [kv->v.memory_owner_thread_index].pool, - kv->v.reass_index); if (vm->thread_index != kv->v.memory_owner_thread_index) { *do_handoff = 1; - return reass; + return NULL; } + reass = + pool_elt_at_index (rm->per_thread_data + [kv->v.memory_owner_thread_index].pool, + kv->v.reass_index); + if (now > reass->last_heard + rm->timeout) { ip6_full_reass_on_timeout (vm, node, rm, reass, icmp_bi); diff --git a/src/vnet/ipfix-export/flow_report.c b/src/vnet/ipfix-export/flow_report.c index d904479c9c9..56a2d16b8d5 100644 --- a/src/vnet/ipfix-export/flow_report.c +++ b/src/vnet/ipfix-export/flow_report.c @@ -500,7 +500,8 @@ set_ipfix_exporter_command_fn (vlib_main_t * vm, { if (unformat (input, "collector %U", unformat_ip4_address, &collector)) ; - else if (unformat (input, "port %u", &collector_port)) + else if (unformat (input, "port %U", unformat_udp_port, + &collector_port)) ; else if (unformat (input, "src %U", unformat_ip4_address, &src)) ; @@ -569,7 +570,7 @@ VLIB_CLI_COMMAND (set_ipfix_exporter_command, static) = { "collector <ip4-address> [port <port>] " "src <ip4-address> [fib-id <fib-id>] " "[path-mtu <path-mtu>] " - "[template-interval <template-interval>]", + "[template-interval <template-interval>] " "[udp-checksum]", .function = set_ipfix_exporter_command_fn, }; diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 6170603ded1..1023a1a981e 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -97,7 +97,7 @@ esp_add_footer_and_icv (vlib_buffer_t * b, u8 block_size, u8 icv_sz, { static const u8 pad_data[ESP_MAX_BLOCK_SIZE] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, - 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x00, 0x00, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, }; u16 min_length = b->current_length + sizeof (esp_footer_t); @@ -201,6 +201,24 @@ esp_get_ip6_hdr_len (ip6_header_t * ip6) return len; } +/* IPsec IV generation: IVs requirements differ depending of the + * encryption mode: IVs must be unpredictable for AES-CBC whereas it can + * be predictable but should never be reused with the same key material + * for CTR and GCM. + * We use a packet counter as the IV for CTR and GCM, and to ensure the + * IV is unpredictable for CBC, it is then encrypted using the same key + * as the message. You can refer to NIST SP800-38a and NIST SP800-38d + * for more details. */ +static_always_inline void * +esp_generate_iv (ipsec_sa_t * sa, void *payload, int iv_sz) +{ + ASSERT (iv_sz >= sizeof (u64)); + u64 *iv = (u64 *) (payload - iv_sz); + clib_memset_u8 (iv, 0, iv_sz); + *iv = sa->iv_counter++; + return iv; +} + static_always_inline void esp_process_ops (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_crypto_op_t * ops, vlib_buffer_t * b[], u16 * nexts) @@ -463,6 +481,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_crypto_op_t *op; vec_add2_aligned (ptd->crypto_ops, op, 1, CLIB_CACHE_LINE_BYTES); vnet_crypto_op_init (op, sa0->crypto_enc_op_id); + void *pkt_iv = esp_generate_iv (sa0, payload, iv_sz); op->src = op->dst = payload; op->key_index = sa0->crypto_key_index; op->len = payload_len - icv_sz; @@ -481,16 +500,19 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, op->tag = payload + op->len; op->tag_len = 16; - u64 *iv = (u64 *) (payload - iv_sz); nonce->salt = sa0->salt; - nonce->iv = *iv = clib_host_to_net_u64 (sa0->gcm_iv_counter++); + nonce->iv = *(u64 *) pkt_iv; op->iv = (u8 *) nonce; nonce++; } else { - op->iv = payload - iv_sz; - op->flags = VNET_CRYPTO_OP_FLAG_INIT_IV; + /* construct zero iv in front of the IP header */ + op->iv = pkt_iv - hdr_len - iv_sz; + clib_memset_u8 (op->iv, 0, iv_sz); + /* include iv field in crypto */ + op->src -= iv_sz; + op->len += iv_sz; } } diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index b3e138bfbea..bc9f3b47683 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -122,6 +122,8 @@ typedef struct u64 replay_window; dpo_id_t dpo; + u64 iv_counter; + vnet_crypto_key_index_t crypto_key_index; vnet_crypto_key_index_t integ_key_index; vnet_crypto_op_id_t crypto_enc_op_id:16; @@ -161,7 +163,6 @@ typedef struct /* Salt used in GCM modes - stored in network byte order */ u32 salt; - u64 gcm_iv_counter; } ipsec_sa_t; STATIC_ASSERT_OFFSET_OF (ipsec_sa_t, cacheline1, CLIB_CACHE_LINE_BYTES); diff --git a/src/vnet/l2/l2_input.c b/src/vnet/l2/l2_input.c index 7b93fba20b1..8a7ab802175 100644 --- a/src/vnet/l2/l2_input.c +++ b/src/vnet/l2/l2_input.c @@ -800,9 +800,6 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */ config->feature_bitmap &= ~(L2INPUT_FEAT_LEARN | L2INPUT_FEAT_FWD | L2INPUT_FEAT_FLOOD); shg = 0; /* not used in xconnect */ - - /* Insure all packets go to ethernet-input */ - ethernet_set_rx_redirect (vnet_main, hi, 1); } /* set up split-horizon group and set output feature bit */ @@ -827,25 +824,18 @@ set_int_l2_mode (vlib_main_t * vm, vnet_main_t * vnet_main, /* */ { if ((hi->l2_if_count == 1) && (l2_if_adjust == 1)) { - /* Just added first L2 interface on this port */ - - /* Set promiscuous mode on the l2 interface */ + /* Just added first L2 interface on this port + * Set promiscuous mode on the l2 interface */ ethernet_set_flags (vnet_main, hi->hw_if_index, ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); - - /* ensure all packets go to ethernet-input */ - ethernet_set_rx_redirect (vnet_main, hi, 1); - } else if ((hi->l2_if_count == 0) && (l2_if_adjust == -1)) { - /* Just removed only L2 subinterface on this port */ - - /* Disable promiscuous mode on the l2 interface */ - ethernet_set_flags (vnet_main, hi->hw_if_index, 0); + /* Just removed only L2 subinterface on this port + * Disable promiscuous mode on the l2 interface */ + ethernet_set_flags (vnet_main, hi->hw_if_index, + /*ETHERNET_INTERFACE_FLAG_DEFAULT_L3 */ 0); - /* Allow ip packets to go directly to ip4-input etc */ - ethernet_set_rx_redirect (vnet_main, hi, 0); } } diff --git a/src/vnet/l2/l2_patch.c b/src/vnet/l2/l2_patch.c index fb8849dc261..618ae20536d 100644 --- a/src/vnet/l2/l2_patch.c +++ b/src/vnet/l2/l2_patch.c @@ -270,15 +270,15 @@ vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index, int is_add) ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); vnet_feature_enable_disable ("device-input", "l2-patch", - rxhi->hw_if_index, 1, 0, 0); + rxhi->sw_if_index, 1, 0, 0); } else { ethernet_set_flags (l2pm->vnet_main, rxhi->hw_if_index, - 0 /* disable promiscuous mode */ ); + /*ETHERNET_INTERFACE_FLAG_DEFAULT_L3 */ 0); vnet_feature_enable_disable ("device-input", "l2-patch", - rxhi->hw_if_index, 0, 0, 0); + rxhi->sw_if_index, 0, 0, 0); if (vec_len (l2pm->tx_next_by_rx_sw_if_index) > rx_sw_if_index) { l2pm->tx_next_by_rx_sw_if_index[rx_sw_if_index] = ~0; diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c index d2cc8da717b..6f26d1e2aeb 100644 --- a/src/vnet/lisp-cp/control.c +++ b/src/vnet/lisp-cp/control.c @@ -1398,19 +1398,19 @@ vnet_lisp_del_mapping (gid_address_t * eid, u32 * res_map_index) gid_address_copy (&m_args->eid, eid); m_args->locator_set_index = old_map->locator_set_index; - /* delete mapping associated from map-cache */ - vnet_lisp_map_cache_add_del (m_args, 0); - ls_args->is_add = 0; ls_args->index = old_map->locator_set_index; - /* delete locator set */ - vnet_lisp_add_del_locator_set (ls_args, 0); - /* delete timer associated to the mapping if any */ if (old_map->timer_set) mapping_delete_timer (lcm, mi); + /* delete locator set */ + vnet_lisp_add_del_locator_set (ls_args, 0); + + /* delete mapping associated from map-cache */ + vnet_lisp_map_cache_add_del (m_args, 0); + /* return old mapping index */ if (res_map_index) res_map_index[0] = mi; @@ -2004,8 +2004,8 @@ vnet_lisp_add_del_locator (vnet_lisp_add_del_locator_set_args_t * a, removed = 1; remove_locator_from_locator_set (ls, locit, ls_index, loc_id); } - if (0 == loc->local && - !gid_address_cmp (&loc->address, &itloc->address)) + else if (0 == loc->local && + !gid_address_cmp (&loc->address, &itloc->address)) { removed = 1; remove_locator_from_locator_set (ls, locit, ls_index, loc_id); @@ -2083,14 +2083,9 @@ vnet_lisp_add_del_locator_set (vnet_lisp_add_del_locator_set_args_t * a, ls->name = vec_dup (a->name); if (!lcm->locator_set_index_by_name) - lcm->locator_set_index_by_name = hash_create_vec ( - /* size */ - 0, - sizeof - (ls->name - [0]), - sizeof - (uword)); + lcm->locator_set_index_by_name = + hash_create_vec ( /* size */ 0, sizeof (ls->name[0]), + sizeof (uword)); hash_set_mem (lcm->locator_set_index_by_name, ls->name, ls_index); diff --git a/src/vnet/lisp-cp/lisp_cli.c b/src/vnet/lisp-cp/lisp_cli.c index 5cd183402b0..817fb50156b 100644 --- a/src/vnet/lisp-cp/lisp_cli.c +++ b/src/vnet/lisp-cp/lisp_cli.c @@ -418,14 +418,16 @@ done: return error; } -VLIB_CLI_COMMAND (lisp_add_del_remote_mapping_command) = -{ -.path = "lisp remote-mapping",.short_help = - "lisp remote-mapping add|del [del-all] vni <vni> " - "eid <est-eid> [action <no-action|natively-forward|" - "send-map-request|drop>] rloc <dst-locator> p <prio> w <weight> " - "[rloc <dst-locator> ... ]",.function = - lisp_add_del_remote_mapping_command_fn,}; +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (lisp_add_del_remote_mapping_command) = { + .path = "lisp remote-mapping", + .short_help = "lisp remote-mapping add|del [del-all] vni <vni> " + "eid <est-eid> [action <no-action|natively-forward|" + "send-map-request|drop>] rloc <dst-locator> p <prio> " + "w <weight> [rloc <dst-locator> ... ]", + .function = lisp_add_del_remote_mapping_command_fn, +}; +/* *INDENT-ON* */ /** * Handler for add/del adjacency CLI. @@ -892,54 +894,44 @@ VLIB_CLI_COMMAND (lisp_cp_show_eid_table_command) = { static clib_error_t * -lisp_enable_disable_command_fn (vlib_main_t * vm, unformat_input_t * input, - vlib_cli_command_t * cmd) +lisp_enable_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, *line_input = &_line_input; - u8 is_enabled = 0; - u8 is_set = 0; - clib_error_t *error = NULL; + if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + return clib_error_return (0, "parse error: '%U'", format_unformat_error, + input); - /* Get a line of input. */ - if (!unformat_user (input, unformat_line_input, line_input)) - return clib_error_return (0, "expected enable | disable"); + vnet_lisp_enable_disable (1); - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "enable")) - { - is_set = 1; - is_enabled = 1; - } - else if (unformat (line_input, "disable")) - is_set = 1; - else - { - error = clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); - goto done; - } - } + return 0; +} - if (!is_set) - { - error = clib_error_return (0, "state not set"); - goto done; - } +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (lisp_cp_enable_command) = { + .path = "lisp enable", + .short_help = "lisp enable", + .function = lisp_enable_command_fn, +}; +/* *INDENT-ON* */ - vnet_lisp_enable_disable (is_enabled); +static clib_error_t * +lisp_disable_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + return clib_error_return (0, "parse error: '%U'", format_unformat_error, + input); -done: - unformat_free (line_input); + vnet_lisp_enable_disable (0); - return error; + return 0; } /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (lisp_cp_enable_disable_command) = { - .path = "lisp", - .short_help = "lisp [enable|disable]", - .function = lisp_enable_disable_command_fn, +VLIB_CLI_COMMAND (lisp_cp_disable_command) = { + .path = "lisp disable", + .short_help = "lisp disable", + .function = lisp_disable_command_fn, }; /* *INDENT-ON* */ @@ -1163,7 +1155,7 @@ lisp_add_del_locator_set_command_fn (vlib_main_t * vm, /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) - return 0; + return clib_error_return (0, "missing parameters"); while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { @@ -1187,6 +1179,7 @@ lisp_add_del_locator_set_command_fn (vlib_main_t * vm, } } + vec_terminate_c_string (locator_set_name); a->name = locator_set_name; a->locators = locators; a->is_add = is_add; diff --git a/src/vnet/lisp-cp/one_api.c b/src/vnet/lisp-cp/one_api.c index 56cb74b0c77..e96e950cfea 100644 --- a/src/vnet/lisp-cp/one_api.c +++ b/src/vnet/lisp-cp/one_api.c @@ -1214,7 +1214,7 @@ one_adjacency_copy (vl_api_one_adjacency_t * dst, lisp_adjacency_t * adjs) clib_memcpy (a.leid, &nsh, sizeof (nsh)); break; default: - ASSERT (0); + ALWAYS_ASSERT (0); } dst[i] = a; } diff --git a/src/vnet/lisp-cp/one_cli.c b/src/vnet/lisp-cp/one_cli.c index d5a0ee00015..e44632f9760 100644 --- a/src/vnet/lisp-cp/one_cli.c +++ b/src/vnet/lisp-cp/one_cli.c @@ -1369,54 +1369,44 @@ VLIB_CLI_COMMAND (one_cp_enable_disable_xtr_mode_command) = { /* *INDENT-ON* */ static clib_error_t * -lisp_enable_disable_command_fn (vlib_main_t * vm, unformat_input_t * input, - vlib_cli_command_t * cmd) +one_enable_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) { - unformat_input_t _line_input, *line_input = &_line_input; - u8 is_enabled = 0; - u8 is_set = 0; - clib_error_t *error = NULL; + if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + return clib_error_return (0, "parse error: '%U'", format_unformat_error, + input); - /* Get a line of input. */ - if (!unformat_user (input, unformat_line_input, line_input)) - return clib_error_return (0, "expected enable | disable"); + vnet_lisp_enable_disable (1); - while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) - { - if (unformat (line_input, "enable")) - { - is_set = 1; - is_enabled = 1; - } - else if (unformat (line_input, "disable")) - is_set = 1; - else - { - error = clib_error_return (0, "parse error: '%U'", - format_unformat_error, line_input); - goto done; - } - } + return 0; +} - if (!is_set) - { - error = clib_error_return (0, "state not set"); - goto done; - } +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (one_cp_enable_command) = { + .path = "one enable", + .short_help = "one enable", + .function = one_enable_command_fn, +}; +/* *INDENT-ON* */ - vnet_lisp_enable_disable (is_enabled); +static clib_error_t * +one_disable_command_fn (vlib_main_t * vm, unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + if (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) + return clib_error_return (0, "parse error: '%U'", format_unformat_error, + input); -done: - unformat_free (line_input); + vnet_lisp_enable_disable (0); - return error; + return 0; } /* *INDENT-OFF* */ -VLIB_CLI_COMMAND (one_cp_enable_disable_command) = { - .path = "one", - .short_help = "one [enable|disable]", - .function = lisp_enable_disable_command_fn, +VLIB_CLI_COMMAND (one_cp_disable_command) = { + .path = "one disable", + .short_help = "one disable", + .function = one_disable_command_fn, }; /* *INDENT-ON* */ diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index 258a15898b6..ec3c9cbde15 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -573,6 +573,11 @@ session_enqueue_notify_inline (session_t * s) SESSION_EVT (SESSION_EVT_ENQ, s, svm_fifo_max_dequeue_prod (s->rx_fifo)); s->flags &= ~SESSION_F_RX_EVT; + + /* Application didn't confirm accept yet */ + if (PREDICT_FALSE (s->session_state == SESSION_STATE_ACCEPTING)) + return 0; + if (PREDICT_FALSE (app_worker_lock_and_send_event (app_wrk, s, SESSION_IO_EVT_RX))) return -1; @@ -745,8 +750,11 @@ session_stream_connect_notify_inline (transport_connection_t * tc, u8 is_fail, if (app_worker_connect_notify (app_wrk, s, opaque)) { + session_lookup_del_connection (tc); + /* Avoid notifying app about rejected session cleanup */ s = session_get (new_si, new_ti); - session_free_w_fifos (s); + segment_manager_dealloc_fifos (s->rx_fifo, s->tx_fifo); + session_free (s); return -1; } diff --git a/src/vnet/session/session_lookup.c b/src/vnet/session/session_lookup.c index 604344a27cd..6c787fbe34b 100644 --- a/src/vnet/session/session_lookup.c +++ b/src/vnet/session/session_lookup.c @@ -156,25 +156,28 @@ make_v6_ss_kv_from_tc (session_kv6_t * kv, transport_connection_t * tc) } static session_table_t * -session_table_get_or_alloc (u8 fib_proto, u8 fib_index) +session_table_get_or_alloc (u8 fib_proto, u32 fib_index) { session_table_t *st; u32 table_index; - if (vec_len (fib_index_to_table_index[fib_proto]) <= fib_index) + ASSERT (fib_index != ~0); + if (vec_len (fib_index_to_table_index[fib_proto]) > fib_index && + fib_index_to_table_index[fib_proto][fib_index] != ~0) + { + table_index = fib_index_to_table_index[fib_proto][fib_index]; + return session_table_get (table_index); + } + else { st = session_table_alloc (); table_index = session_table_index (st); - vec_validate (fib_index_to_table_index[fib_proto], fib_index); + vec_validate_init_empty (fib_index_to_table_index[fib_proto], fib_index, + ~0); fib_index_to_table_index[fib_proto][fib_index] = table_index; st->active_fib_proto = fib_proto; session_table_init (st, fib_proto); return st; } - else - { - table_index = fib_index_to_table_index[fib_proto][fib_index]; - return session_table_get (table_index); - } } static session_table_t * diff --git a/src/vnet/session/session_node.c b/src/vnet/session/session_node.c index eb5876d2c3d..ebb3503ff6b 100644 --- a/src/vnet/session/session_node.c +++ b/src/vnet/session/session_node.c @@ -906,6 +906,8 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk, return SESSION_TX_NO_BUFFERS; } + transport_connection_update_tx_bytes (ctx->tc, ctx->max_len_to_snd); + ctx->left_to_snd = ctx->max_len_to_snd; n_left = ctx->n_segs_per_evt; @@ -979,7 +981,6 @@ session_tx_fifo_read_and_snd_i (session_worker_t * wrk, vlib_buffer_free (vm, wrk->tx_buffers, n_bufs); *n_tx_packets += ctx->n_segs_per_evt; - transport_connection_update_tx_bytes (ctx->tc, ctx->max_len_to_snd); SESSION_EVT (SESSION_EVT_DEQ, ctx->s, ctx->max_len_to_snd, ctx->max_dequeue, ctx->s->tx_fifo->has_event, wrk->last_vlib_time); diff --git a/src/vnet/srv6/sr_policy_rewrite.c b/src/vnet/srv6/sr_policy_rewrite.c index feac151665a..1d6b7816b52 100755 --- a/src/vnet/srv6/sr_policy_rewrite.c +++ b/src/vnet/srv6/sr_policy_rewrite.c @@ -1012,7 +1012,7 @@ show_sr_policies_command_fn (vlib_main_t * vm, unformat_input_t * input, } s = format (s, "\b\b > "); s = format (s, "weight: %u", segment_list->weight); - vlib_cli_output (vm, " %s", s); + vlib_cli_output (vm, " %v", s); } vlib_cli_output (vm, "-----------"); } diff --git a/src/vnet/srv6/sr_steering.c b/src/vnet/srv6/sr_steering.c index 566ba1fe5a0..aa98a45d3da 100755 --- a/src/vnet/srv6/sr_steering.c +++ b/src/vnet/srv6/sr_steering.c @@ -146,14 +146,11 @@ sr_steering_policy (int is_del, ip6_address_t * bsid, u32 sr_policy_index, /* Remove promiscous mode from interface */ vnet_main_t *vnm = vnet_get_main (); - ethernet_main_t *em = ðernet_main; - ethernet_interface_t *eif = - ethernet_get_interface (em, sw_if_index); - - if (!eif) - goto cleanup_error_redirection; - - ethernet_set_flags (vnm, sw_if_index, 0); + vnet_hw_interface_t *hi = + vnet_get_sup_hw_interface (vnm, sw_if_index); + /* Make sure it is main interface */ + if (hi->sw_if_index == sw_if_index) + ethernet_set_flags (vnm, hi->hw_if_index, 0); } /* Delete SR steering policy entry */ @@ -289,14 +286,11 @@ sr_steering_policy (int is_del, ip6_address_t * bsid, u32 sr_policy_index, /* Set promiscous mode on interface */ vnet_main_t *vnm = vnet_get_main (); - ethernet_main_t *em = ðernet_main; - ethernet_interface_t *eif = ethernet_get_interface (em, sw_if_index); - - if (!eif) - goto cleanup_error_redirection; - - ethernet_set_flags (vnm, sw_if_index, - ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); + vnet_hw_interface_t *hi = vnet_get_sup_hw_interface (vnm, sw_if_index); + /* Make sure it is main interface */ + if (hi->sw_if_index == sw_if_index) + ethernet_set_flags (vnm, hi->hw_if_index, + ETHERNET_INTERFACE_FLAG_ACCEPT_ALL); } else if (traffic_type == SR_STEER_IPV4) if (!sr_policy->is_encap) diff --git a/src/vnet/tcp/tcp_bt.c b/src/vnet/tcp/tcp_bt.c index b6649444eb5..e5162515da6 100644 --- a/src/vnet/tcp/tcp_bt.c +++ b/src/vnet/tcp/tcp_bt.c @@ -336,6 +336,7 @@ tcp_bt_track_rxt (tcp_connection_t * tc, u32 start, u32 end) tcp_bt_sample_t *bts, *next, *cur, *prev, *nbts; u32 bts_index, cur_index, next_index, prev_index, max_seq; u8 is_end = end == tc->snd_nxt; + tcp_bts_flags_t bts_flags; /* Contiguous blocks retransmitted at the same time */ bts = bt_get_sample (bt, bt->last_ooo); @@ -350,8 +351,10 @@ tcp_bt_track_rxt (tcp_connection_t * tc, u32 start, u32 end) return; } - /* Find original tx sample */ + /* Find original tx sample and cache flags in case the sample + * is freed or the pool moves */ bts = bt_lookup_seq (bt, start); + bts_flags = bts->flags; ASSERT (bts != 0 && seq_geq (start, bts->min_seq)); @@ -364,11 +367,12 @@ tcp_bt_track_rxt (tcp_connection_t * tc, u32 start, u32 end) { prev_index = bts->prev; next = bt_fix_overlapped (bt, bts, end, is_end); + /* bts might no longer be valid from here */ next_index = bt_sample_index (bt, next); cur = tcp_bt_alloc_tx_sample (tc, start, end); cur->flags |= TCP_BTS_IS_RXT; - if (bts->flags & TCP_BTS_IS_RXT) + if (bts_flags & TCP_BTS_IS_RXT) cur->flags |= TCP_BTS_IS_RXT_LOST; cur->next = next_index; cur->prev = prev_index; @@ -410,7 +414,7 @@ tcp_bt_track_rxt (tcp_connection_t * tc, u32 start, u32 end) /* Have to split or tail overlap */ cur = tcp_bt_alloc_tx_sample (tc, start, end); cur->flags |= TCP_BTS_IS_RXT; - if (bts->flags & TCP_BTS_IS_RXT) + if (bts_flags & TCP_BTS_IS_RXT) cur->flags |= TCP_BTS_IS_RXT_LOST; cur->prev = bts_index; cur_index = bt_sample_index (bt, cur); @@ -587,11 +591,12 @@ tcp_bt_sample_delivery_rate (tcp_connection_t * tc, tcp_rate_sample_t * rs) return; delivered = tc->bytes_acked + tc->sack_sb.last_sacked_bytes; + /* Do not count bytes that were previously sacked again */ + delivered -= tc->sack_sb.last_bytes_delivered; if (!delivered || tc->bt->head == TCP_BTS_INVALID_INDEX) return; - /* Do not count bytes that were previously sacked again */ - tc->delivered += delivered - tc->sack_sb.last_bytes_delivered; + tc->delivered += delivered; tc->delivered_time = tcp_time_now_us (tc->c_thread_index); if (tc->app_limited && tc->delivered > tc->app_limited) diff --git a/src/vnet/tcp/tcp_output.c b/src/vnet/tcp/tcp_output.c index 9eba05eb71e..f0f5e82177f 100644 --- a/src/vnet/tcp/tcp_output.c +++ b/src/vnet/tcp/tcp_output.c @@ -121,6 +121,11 @@ tcp_update_rcv_wnd (tcp_connection_t * tc) * Figure out how much space we have available */ available_space = transport_max_rx_enqueue (&tc->connection); + + /* Make sure we have a multiple of 1 << rcv_wscale. We round down to + * avoid advertising a window larger than what can be buffered */ + available_space = round_down_pow2 (available_space, 1 << tc->rcv_wscale); + if (PREDICT_FALSE (available_space < tc->rcv_opts.mss)) { tc->rcv_wnd = 0; @@ -136,7 +141,7 @@ tcp_update_rcv_wnd (tcp_connection_t * tc) /* Bad. Thou shalt not shrink */ if (PREDICT_FALSE ((i32) available_space < observed_wnd)) { - wnd = clib_max (observed_wnd, 0); + wnd = round_pow2 (clib_max (observed_wnd, 0), 1 << tc->rcv_wscale); TCP_EVT (TCP_EVT_RCV_WND_SHRUNK, tc, observed_wnd, available_space); } else @@ -144,14 +149,6 @@ tcp_update_rcv_wnd (tcp_connection_t * tc) wnd = available_space; } - /* Make sure we have a multiple of rcv_wscale */ - if (wnd && tc->rcv_wscale) - { - wnd &= ~((1 << tc->rcv_wscale) - 1); - if (wnd == 0) - wnd = 1 << tc->rcv_wscale; - } - tc->rcv_wnd = clib_min (wnd, TCP_WND_MAX << tc->rcv_wscale); } diff --git a/src/vnet/udp/udp.h b/src/vnet/udp/udp.h index 5ff613b568a..a5c7b53394e 100644 --- a/src/vnet/udp/udp.h +++ b/src/vnet/udp/udp.h @@ -256,6 +256,7 @@ udp_get_dst_port_info (udp_main_t * um, udp_dst_port_t dst_port, u8 is_ip4) format_function_t format_udp_header; format_function_t format_udp_rx_trace; unformat_function_t unformat_udp_header; +unformat_function_t unformat_udp_port; void udp_register_dst_port (vlib_main_t * vm, udp_dst_port_t dst_port, diff --git a/src/vnet/udp/udp_encap.h b/src/vnet/udp/udp_encap.h index 888efa8c37c..9d82e59ba55 100644 --- a/src/vnet/udp/udp_encap.h +++ b/src/vnet/udp/udp_encap.h @@ -68,14 +68,14 @@ typedef struct udp_encap_t_ } __attribute__ ((packed)) ue_hdrs; /** - * Flags controlling fixup behaviour + * The DPO used to forward to the next node in the VLIB graph */ - udp_encap_fixup_flags_t ue_flags; + dpo_id_t ue_dpo; /** - * The DPO used to forward to the next node in the VLIB graph + * Flags controlling fixup behaviour */ - dpo_id_t ue_dpo; + udp_encap_fixup_flags_t ue_flags; /** * the protocol of the IP header imposed diff --git a/src/vnet/udp/udp_format.c b/src/vnet/udp/udp_format.c index 2277e18bcdb..93e7508711b 100644 --- a/src/vnet/udp/udp_format.c +++ b/src/vnet/udp/udp_format.c @@ -82,6 +82,23 @@ format_udp_header (u8 * s, va_list * args) return s; } +uword +unformat_udp_port (unformat_input_t * input, va_list * args) +{ + u16 *result = va_arg (*args, u16 *); + int port; + + /* Numeric type. */ + if (unformat (input, "0x%x", &port) || unformat (input, "%d", &port)) + { + if (port <= 0 || port >= (1 << 16)) + return 0; + *result = port; + return 1; + } + return 0; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vpp-api/vapi/vapi_c_gen.py b/src/vpp-api/vapi/vapi_c_gen.py index 9a285eb98ad..870e225e9a1 100755 --- a/src/vpp-api/vapi/vapi_c_gen.py +++ b/src/vpp-api/vapi/vapi_c_gen.py @@ -153,6 +153,12 @@ class CSimpleType (SimpleType): 'i64': 'be64toh', 'u64': 'be64toh', } + __packed = "__attribute__((packed))" + pack_dict = { + 'i8': __packed, 'u8': __packed, + 'i16': __packed, 'u16': __packed, + } + def get_c_name(self): return self.name @@ -162,6 +168,9 @@ class CSimpleType (SimpleType): def get_swap_to_host_func_name(self): return self.swap_to_host_dict[self.name] + def get_packed_string(self): + return self.pack_dict[self.name] + def get_swap_to_be_code(self, struct, var, cast=None): x = "%s%s" % (struct, var) return "%s = %s%s(%s);" % (x, @@ -182,14 +191,18 @@ class CSimpleType (SimpleType): pass return False + def get_packed(self): + return self.pack_dict.get(self.name, "") + class CEnum(Enum): def get_c_name(self): return "vapi_enum_%s" % self.name def get_c_def(self): - return "typedef enum {\n%s\n} %s;" % ( + return "typedef enum {\n%s\n} %s %s;" % ( "\n".join([" %s = %s," % (i, j) for i, j in self.value_pairs]), + self.type.get_packed(), self.get_c_name() ) @@ -678,7 +691,7 @@ def gen_json_unified_header(parser, logger, j, io, name): orig_stdout = sys.stdout sys.stdout = io include_guard = "__included_%s" % ( - j.replace(".", "_").replace("/", "_").replace("-", "_")) + j.replace(".", "_").replace("/", "_").replace("-", "_").replace("+", "_")) print("#ifndef %s" % include_guard) print("#define %s" % include_guard) print("") diff --git a/src/vpp/stats/stat_segment.c b/src/vpp/stats/stat_segment.c index 9e117657467..a5797a68785 100644 --- a/src/vpp/stats/stat_segment.c +++ b/src/vpp/stats/stat_segment.c @@ -148,6 +148,44 @@ vlib_stats_delete_counter (u32 index, void *oldheap) e->type = STAT_DIR_TYPE_EMPTY; } +/* + * Called from main heap + */ +void +vlib_stats_delete_cm (void *cm_arg) +{ + vlib_simple_counter_main_t *cm = (vlib_simple_counter_main_t *) cm_arg; + stat_segment_main_t *sm = &stat_segment_main; + stat_segment_directory_entry_t *e; + stat_segment_shared_header_t *shared_header = sm->shared_header; + + /* Not all counters have names / hash-table entries */ + if (!cm->name && !cm->stat_segment_name) + { + return; + } + vlib_stat_segment_lock (); + + /* Lookup hash-table is on the main heap */ + char *stat_segment_name = + cm->stat_segment_name ? cm->stat_segment_name : cm->name; + u32 index = lookup_hash_index ((u8 *) stat_segment_name); + + e = &sm->directory_vector[index]; + hash_unset (sm->directory_vector_by_name, &e->name); + + u64 *offset_vector = stat_segment_pointer (shared_header, e->offset_vector); + + void *oldheap = clib_mem_set_heap (sm->heap); /* Enter stats segment */ + vec_free (offset_vector); + clib_mem_set_heap (oldheap); /* Exit stats segment */ + + memset (e, 0, sizeof (*e)); + e->type = STAT_DIR_TYPE_EMPTY; + + vlib_stat_segment_unlock (); +} + void vlib_stats_pop_heap (void *cm_arg, void *oldheap, u32 cindex, stat_directory_type_t type) @@ -172,6 +210,7 @@ vlib_stats_pop_heap (void *cm_arg, void *oldheap, u32 cindex, /* Lookup hash-table is on the main heap */ stat_segment_name = cm->stat_segment_name ? cm->stat_segment_name : cm->name; + clib_mem_set_heap (oldheap); /* Exit stats segment */ u32 vector_index = lookup_hash_index ((u8 *) stat_segment_name); /* Back to stats segment */ diff --git a/src/vppinfra/CMakeLists.txt b/src/vppinfra/CMakeLists.txt index 8af6120bd5e..87568d6d139 100644 --- a/src/vppinfra/CMakeLists.txt +++ b/src/vppinfra/CMakeLists.txt @@ -180,6 +180,7 @@ set(VPPINFRA_HEADERS vector.h vector_neon.h vector_sse42.h + warnings.h xxhash.h xy.h zvec.h diff --git a/src/vppinfra/bihash_template.c b/src/vppinfra/bihash_template.c index de59abe63af..268da6b7e89 100644 --- a/src/vppinfra/bihash_template.c +++ b/src/vppinfra/bihash_template.c @@ -118,7 +118,7 @@ void BV (clib_bihash_init) #define MFD_ALLOW_SEALING 0x0002U #endif -void BV (clib_bihash_master_init_svm) +void BV (clib_bihash_initiator_init_svm) (BVT (clib_bihash) * h, char *name, u32 nbuckets, u64 memory_size) { uword bucket_size; @@ -188,7 +188,7 @@ void BV (clib_bihash_master_init_svm) h->instantiated = 1; } -void BV (clib_bihash_slave_init_svm) +void BV (clib_bihash_responder_init_svm) (BVT (clib_bihash) * h, char *name, int fd) { u8 *mmap_addr; diff --git a/src/vppinfra/bihash_template.h b/src/vppinfra/bihash_template.h index ebd70c03371..43930b849eb 100644 --- a/src/vppinfra/bihash_template.h +++ b/src/vppinfra/bihash_template.h @@ -305,9 +305,9 @@ void BV (clib_bihash_init) void BV (clib_bihash_init2) (BVT (clib_bihash_init2_args) * a); #if BIHASH_32_64_SVM -void BV (clib_bihash_master_init_svm) +void BV (clib_bihash_initiator_init_svm) (BVT (clib_bihash) * h, char *name, u32 nbuckets, u64 memory_size); -void BV (clib_bihash_slave_init_svm) +void BV (clib_bihash_responder_init_svm) (BVT (clib_bihash) * h, char *name, int fd); #endif diff --git a/src/vppinfra/clib.h b/src/vppinfra/clib.h index 8aec1f16beb..ecd70980996 100644 --- a/src/vppinfra/clib.h +++ b/src/vppinfra/clib.h @@ -38,6 +38,7 @@ #ifndef included_clib_h #define included_clib_h +#include <stddef.h> #include <vppinfra/config.h> /* Standalone means to not assume we are running on a Unix box. */ @@ -62,8 +63,8 @@ #define ARRAY_LEN(x) (sizeof (x)/sizeof (x[0])) #define _STRUCT_FIELD(t,f) (((t *) 0)->f) -#define STRUCT_OFFSET_OF(t,f) ((uword) & _STRUCT_FIELD (t, f)) -#define STRUCT_BIT_OFFSET_OF(t,f) (BITS(u8) * (uword) & _STRUCT_FIELD (t, f)) +#define STRUCT_OFFSET_OF(t,f) offsetof(t, f) +#define STRUCT_BIT_OFFSET_OF(t,f) (BITS(u8) * STRUCT_OFFSET_OF (t, f)) #define STRUCT_SIZE_OF(t,f) (sizeof (_STRUCT_FIELD (t, f))) #define STRUCT_BITS_OF(t,f) (BITS (_STRUCT_FIELD (t, f))) #define STRUCT_ARRAY_LEN(t,f) ARRAY_LEN (_STRUCT_FIELD (t, f)) @@ -238,6 +239,12 @@ is_pow2 (uword x) } always_inline uword +round_down_pow2 (uword x, uword pow2) +{ + return (x) & ~(pow2 - 1); +} + +always_inline uword round_pow2 (uword x, uword pow2) { return (x + pow2 - 1) & ~(pow2 - 1); diff --git a/src/vppinfra/error_bootstrap.h b/src/vppinfra/error_bootstrap.h index 8dbbc7f359d..185f4c6c4af 100644 --- a/src/vppinfra/error_bootstrap.h +++ b/src/vppinfra/error_bootstrap.h @@ -108,11 +108,7 @@ do { \ } while (0) #endif /* __COVERITY */ -#if defined(__clang__) -#define STATIC_ASSERT(truth,...) -#else #define STATIC_ASSERT(truth,...) _Static_assert(truth, __VA_ARGS__) -#endif #define STATIC_ASSERT_SIZEOF(d, s) \ STATIC_ASSERT (sizeof (d) == s, "Size of " #d " must be " # s " bytes") diff --git a/src/vppinfra/heap.c b/src/vppinfra/heap.c index f7b1f6bb31e..e91dc64f568 100644 --- a/src/vppinfra/heap.c +++ b/src/vppinfra/heap.c @@ -297,6 +297,7 @@ search_free_list (void *v, uword size) /* Find an object that is large enough. Search list in reverse so that more recently freed objects will be allocated again sooner. */ + u8 found = 0; do { l--; @@ -304,12 +305,15 @@ search_free_list (void *v, uword size) f = elt_at (h, f_index); f_size = heap_elt_size (v, f); if ((s = f_size - size) >= 0) - break; + { + found = 1; + break; + } } - while (l >= 0); + while (l > 0); /* If we fail to find a large enough object, try the next larger size. */ - if (l < 0) + if (found == 0) continue; ASSERT (heap_is_free (f)); diff --git a/src/vppinfra/memcpy_avx2.h b/src/vppinfra/memcpy_avx2.h index caff4f6afde..f3f0d3f1943 100644 --- a/src/vppinfra/memcpy_avx2.h +++ b/src/vppinfra/memcpy_avx2.h @@ -50,6 +50,11 @@ #include <stdint.h> #include <x86intrin.h> +#include <vppinfra/warnings.h> + +/* *INDENT-OFF* */ +WARN_OFF (stringop-overflow) +/* *INDENT-ON* */ static inline void clib_mov16 (u8 * dst, const u8 * src) @@ -228,6 +233,9 @@ clib_memcpy_fast (void *dst, const void *src, size_t n) goto COPY_BLOCK_128_BACK31; } +/* *INDENT-OFF* */ +WARN_ON (stringop-overflow) +/* *INDENT-ON* */ #endif /* included_clib_memcpy_avx2_h */ diff --git a/src/vppinfra/memcpy_avx512.h b/src/vppinfra/memcpy_avx512.h index 9032b5436a3..1444c271ff1 100644 --- a/src/vppinfra/memcpy_avx512.h +++ b/src/vppinfra/memcpy_avx512.h @@ -50,6 +50,11 @@ #include <stdint.h> #include <x86intrin.h> +#include <vppinfra/warnings.h> + +/* *INDENT-OFF* */ +WARN_OFF (stringop-overflow) +/* *INDENT-ON* */ static inline void clib_mov16 (u8 * dst, const u8 * src) @@ -264,6 +269,9 @@ clib_memcpy_fast (void *dst, const void *src, size_t n) goto COPY_BLOCK_128_BACK63; } +/* *INDENT-OFF* */ +WARN_ON (stringop-overflow) +/* *INDENT-ON* */ #endif /* included_clib_memcpy_avx512_h */ diff --git a/src/vppinfra/memcpy_sse3.h b/src/vppinfra/memcpy_sse3.h index 5346e913817..d9e4ac668e9 100644 --- a/src/vppinfra/memcpy_sse3.h +++ b/src/vppinfra/memcpy_sse3.h @@ -50,6 +50,11 @@ #include <stdint.h> #include <x86intrin.h> +#include <vppinfra/warnings.h> + +/* *INDENT-OFF* */ +WARN_OFF (stringop-overflow) +/* *INDENT-ON* */ static inline void clib_mov16 (u8 * dst, const u8 * src) @@ -344,6 +349,9 @@ clib_memcpy_fast (void *dst, const void *src, size_t n) goto COPY_BLOCK_64_BACK15; } +/* *INDENT-OFF* */ +WARN_ON (stringop-overflow) +/* *INDENT-ON* */ #undef CLIB_MVUNALIGN_LEFT47_IMM #undef CLIB_MVUNALIGN_LEFT47 diff --git a/src/vppinfra/random_buffer.h b/src/vppinfra/random_buffer.h index eb318548b0a..320394d1862 100644 --- a/src/vppinfra/random_buffer.h +++ b/src/vppinfra/random_buffer.h @@ -40,6 +40,11 @@ #include <vppinfra/clib.h> #include <vppinfra/random_isaac.h> +#include <vppinfra/warnings.h> + +/* *INDENT-OFF* */ +WARN_OFF(array-bounds) +/* *INDENT-ON* */ typedef struct { @@ -107,6 +112,10 @@ clib_random_buffer_get_data (clib_random_buffer_t * b, uword n_bytes) return b->buffer + i; } +/* *INDENT-OFF* */ +WARN_ON(array-bounds) +/* *INDENT-ON* */ + #endif /* included_clib_random_buffer_h */ /* diff --git a/src/vppinfra/std-formats.c b/src/vppinfra/std-formats.c index b771b947e27..62d309e2fb0 100644 --- a/src/vppinfra/std-formats.c +++ b/src/vppinfra/std-formats.c @@ -281,7 +281,7 @@ format_c_identifier (u8 * s, va_list * va) l = vec_len (id); if (id) - for (i = 0; id[i] != 0 && i < l; i++) + for (i = 0; i < l && id[i] != 0; i++) { u8 c = id[i]; diff --git a/src/vppinfra/string.h b/src/vppinfra/string.h index a3db9264cac..ba5988e5a9a 100644 --- a/src/vppinfra/string.h +++ b/src/vppinfra/string.h @@ -472,8 +472,8 @@ clib_count_equal_u64 (u64 * data, uword max_count) uword count; u64 first; - if (max_count == 1) - return 1; + if (max_count <= 1) + return max_count; if (data[0] != data[1]) return 1; @@ -482,23 +482,20 @@ clib_count_equal_u64 (u64 * data, uword max_count) #if defined(CLIB_HAVE_VEC256) u64x4 splat = u64x4_splat (first); - while (1) + while (count + 3 < max_count) { u64 bmp; bmp = u8x32_msb_mask ((u8x32) (u64x4_load_unaligned (data) == splat)); if (bmp != 0xffffffff) { count += count_trailing_zeros (~bmp) / 8; - return clib_min (count, max_count); + return count; } data += 4; count += 4; - - if (count >= max_count) - return max_count; } -#endif +#else count += 2; data += 2; while (count + 3 < max_count && @@ -508,6 +505,7 @@ clib_count_equal_u64 (u64 * data, uword max_count) data += 4; count += 4; } +#endif while (count < max_count && (data[0] == first)) { data += 1; @@ -522,8 +520,8 @@ clib_count_equal_u32 (u32 * data, uword max_count) uword count; u32 first; - if (max_count == 1) - return 1; + if (max_count <= 1) + return max_count; if (data[0] != data[1]) return 1; @@ -532,41 +530,35 @@ clib_count_equal_u32 (u32 * data, uword max_count) #if defined(CLIB_HAVE_VEC256) u32x8 splat = u32x8_splat (first); - while (1) + while (count + 7 < max_count) { u64 bmp; bmp = u8x32_msb_mask ((u8x32) (u32x8_load_unaligned (data) == splat)); if (bmp != 0xffffffff) { count += count_trailing_zeros (~bmp) / 4; - return clib_min (count, max_count); + return count; } data += 8; count += 8; - - if (count >= max_count) - return max_count; } #elif defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_MSB_MASK) u32x4 splat = u32x4_splat (first); - while (1) + while (count + 3 < max_count) { u64 bmp; bmp = u8x16_msb_mask ((u8x16) (u32x4_load_unaligned (data) == splat)); if (bmp != 0xffff) { count += count_trailing_zeros (~bmp) / 4; - return clib_min (count, max_count); + return count; } data += 4; count += 4; - - if (count >= max_count) - return max_count; } -#endif +#else count += 2; data += 2; while (count + 3 < max_count && @@ -576,6 +568,7 @@ clib_count_equal_u32 (u32 * data, uword max_count) data += 4; count += 4; } +#endif while (count < max_count && (data[0] == first)) { data += 1; @@ -590,8 +583,8 @@ clib_count_equal_u16 (u16 * data, uword max_count) uword count; u16 first; - if (max_count == 1) - return 1; + if (max_count <= 1) + return max_count; if (data[0] != data[1]) return 1; @@ -600,41 +593,35 @@ clib_count_equal_u16 (u16 * data, uword max_count) #if defined(CLIB_HAVE_VEC256) u16x16 splat = u16x16_splat (first); - while (1) + while (count + 15 < max_count) { u64 bmp; bmp = u8x32_msb_mask ((u8x32) (u16x16_load_unaligned (data) == splat)); if (bmp != 0xffffffff) { count += count_trailing_zeros (~bmp) / 2; - return clib_min (count, max_count); + return count; } data += 16; count += 16; - - if (count >= max_count) - return max_count; } #elif defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_MSB_MASK) u16x8 splat = u16x8_splat (first); - while (1) + while (count + 7 < max_count) { u64 bmp; bmp = u8x16_msb_mask ((u8x16) (u16x8_load_unaligned (data) == splat)); if (bmp != 0xffff) { count += count_trailing_zeros (~bmp) / 2; - return clib_min (count, max_count); + return count; } data += 8; count += 8; - - if (count >= max_count) - return max_count; } -#endif +#else count += 2; data += 2; while (count + 3 < max_count && @@ -644,6 +631,7 @@ clib_count_equal_u16 (u16 * data, uword max_count) data += 4; count += 4; } +#endif while (count < max_count && (data[0] == first)) { data += 1; @@ -658,8 +646,8 @@ clib_count_equal_u8 (u8 * data, uword max_count) uword count; u8 first; - if (max_count == 1) - return 1; + if (max_count <= 1) + return max_count; if (data[0] != data[1]) return 1; @@ -668,41 +656,35 @@ clib_count_equal_u8 (u8 * data, uword max_count) #if defined(CLIB_HAVE_VEC256) u8x32 splat = u8x32_splat (first); - while (1) + while (count + 31 < max_count) { u64 bmp; bmp = u8x32_msb_mask ((u8x32) (u8x32_load_unaligned (data) == splat)); if (bmp != 0xffffffff) { count += count_trailing_zeros (~bmp); - return clib_min (count, max_count); + return max_count; } data += 32; count += 32; - - if (count >= max_count) - return max_count; } #elif defined(CLIB_HAVE_VEC128) && defined(CLIB_HAVE_VEC128_MSB_MASK) u8x16 splat = u8x16_splat (first); - while (1) + while (count + 15 < max_count) { u64 bmp; bmp = u8x16_msb_mask ((u8x16) (u8x16_load_unaligned (data) == splat)); if (bmp != 0xffff) { count += count_trailing_zeros (~bmp); - return clib_min (count, max_count); + return count; } data += 16; count += 16; - - if (count >= max_count) - return max_count; } -#endif +#else count += 2; data += 2; while (count + 3 < max_count && @@ -712,6 +694,7 @@ clib_count_equal_u8 (u8 * data, uword max_count) data += 4; count += 4; } +#endif while (count < max_count && (data[0] == first)) { data += 1; diff --git a/src/vppinfra/test_bihash_template.c b/src/vppinfra/test_bihash_template.c index c1a44691966..f8ad631e99c 100644 --- a/src/vppinfra/test_bihash_template.c +++ b/src/vppinfra/test_bihash_template.c @@ -73,9 +73,9 @@ test_bihash_vec64 (test_main_t * tm) h = &tm->hash; #if BIHASH_32_64_SVM - BV (clib_bihash_master_init_svm) (h, "test", user_buckets, - 0x30000000 /* base_addr */ , - user_memory_size); + BV (clib_bihash_initiator_init_svm) (h, "test", user_buckets, + 0x30000000 /* base_addr */ , + user_memory_size); #else BV (clib_bihash_init) (h, "test", user_buckets, user_memory_size); #endif @@ -123,9 +123,9 @@ test_bihash_stale_overwrite (test_main_t * tm) h = &tm->hash; #if BIHASH_32_64_SVM - BV (clib_bihash_master_init_svm) (h, "test", tm->nbuckets, - 0x30000000 /* base_addr */ , - tm->hash_memory_size); + BV (clib_bihash_initiator_init_svm) (h, "test", tm->nbuckets, + 0x30000000 /* base_addr */ , + tm->hash_memory_size); #else BV (clib_bihash_init) (h, "test", tm->nbuckets, tm->hash_memory_size); #endif @@ -208,9 +208,9 @@ test_bihash_threads (test_main_t * tm) h = &tm->hash; #if BIHASH_32_64_SVM - BV (clib_bihash_master_init_svm) (h, "test", tm->nbuckets, - 0x30000000 /* base_addr */ , - tm->hash_memory_size); + BV (clib_bihash_initiator_init_svm) (h, "test", tm->nbuckets, + 0x30000000 /* base_addr */ , + tm->hash_memory_size); #else BV (clib_bihash_init) (h, "test", tm->nbuckets, tm->hash_memory_size); #endif @@ -262,9 +262,9 @@ test_bihash (test_main_t * tm) h = &tm->hash; #if BIHASH_32_64_SVM - BV (clib_bihash_master_init_svm) (h, "test", tm->nbuckets, - 0x30000000 /* base_addr */ , - tm->hash_memory_size); + BV (clib_bihash_initiator_init_svm) (h, "test", tm->nbuckets, + 0x30000000 /* base_addr */ , + tm->hash_memory_size); #else BV (clib_bihash_init) (h, "test", tm->nbuckets, tm->hash_memory_size); #endif diff --git a/src/vppinfra/vec.h b/src/vppinfra/vec.h index 461c0de3347..da7d0896109 100644 --- a/src/vppinfra/vec.h +++ b/src/vppinfra/vec.h @@ -974,12 +974,16 @@ do { \ /** \brief Sort a vector using the supplied element comparison function + Does not depend on the underlying implementation to deal correctly + with null, zero-long, or 1-long vectors + @param vec vector to sort @param f comparison function */ -#define vec_sort_with_function(vec,f) \ -do { \ - qsort (vec, vec_len (vec), sizeof (vec[0]), (void *) (f)); \ +#define vec_sort_with_function(vec,f) \ +do { \ + if (vec_len (vec) > 1) \ + qsort (vec, vec_len (vec), sizeof (vec[0]), (void *) (f)); \ } while (0) /** \brief Make a vector containing a NULL terminated c-string. diff --git a/src/vppinfra/vector_sse42.h b/src/vppinfra/vector_sse42.h index 0c1b2f0324f..7a5cc189d6a 100644 --- a/src/vppinfra/vector_sse42.h +++ b/src/vppinfra/vector_sse42.h @@ -690,7 +690,7 @@ u64x2_gather (void *p0, void *p1) } static_always_inline u32x4 -u32x4_gather (void *p0, void *p1, void *p2, void *p3, void *p4) +u32x4_gather (void *p0, void *p1, void *p2, void *p3) { u32x4 r = { *(u32 *) p0, *(u32 *) p1, *(u32 *) p2, *(u32 *) p3 }; return r; |