Compare commits
54 Commits
master
...
stable/200
Author | SHA1 | Date | |
---|---|---|---|
|
3c1021a679 | ||
|
f53edbc3b4 | ||
|
09f1679977 | ||
|
202978f31a | ||
|
69e6364cd8 | ||
|
b639d50299 | ||
|
9ba2ead1a7 | ||
|
b1500e9fff | ||
|
9736d6f328 | ||
|
49ab961abf | ||
|
fa729ec6cd | ||
|
bc69426737 | ||
|
82103e9fe1 | ||
|
5ac8c6f1f3 | ||
|
d4b5fdde42 | ||
|
6d52257a2d | ||
|
42382f5427 | ||
|
93dd1da259 | ||
|
a37c63c6d8 | ||
|
ecbca13d7e | ||
|
7037fde018 | ||
|
53b5233057 | ||
|
369dc2c67a | ||
|
e0db09034a | ||
|
201c8e4d2a | ||
|
4ee279b03e | ||
|
4e4d3fd016 | ||
|
5e69119cdd | ||
|
ab572152d9 | ||
|
550da2b75a | ||
|
aecb10b97f | ||
|
af3022f0e8 | ||
|
449f34e2f3 | ||
|
e2e3c38be6 | ||
|
77d12df8eb | ||
|
bc69eca2ab | ||
|
61f368a80f | ||
|
0f878da203 | ||
|
89c12dbe23 | ||
|
11974e5f5a | ||
|
8b4221ee8f | ||
|
04d4d92f96 | ||
|
be955ef316 | ||
|
63f9e7cc0e | ||
|
d3088e94ec | ||
|
d657203443 | ||
|
00b060a778 | ||
|
a3674c0e18 | ||
|
06107a7243 | ||
|
0762fbc46e | ||
|
b5898d2f77 | ||
|
8337806b5f | ||
|
765ef37670 | ||
|
b8e9009400 |
@ -2,3 +2,4 @@
|
||||
host=gerrit.fd.io
|
||||
port=29418
|
||||
project=vpp
|
||||
defaultbranch=stable/2005
|
||||
|
7
Makefile
7
Makefile
@ -135,6 +135,11 @@ endif
|
||||
# +ganglia-devel if building the ganglia plugin
|
||||
|
||||
RPM_DEPENDS += chrpath libffi-devel rpm-build
|
||||
|
||||
RPM_DEPENDS_DEBUG = glibc-debuginfo e2fsprogs-debuginfo
|
||||
RPM_DEPENDS_DEBUG += krb5-debuginfo openssl-debuginfo
|
||||
RPM_DEPENDS_DEBUG += zlib-debuginfo nss-softokn-debuginfo
|
||||
RPM_DEPENDS_DEBUG += yum-plugin-auto-update-debug-info
|
||||
# lowercase- replace spaces with dashes.
|
||||
SUSE_NAME= $(shell grep '^NAME=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g' | sed -e 's/ /-/' | awk '{print tolower($$0)}')
|
||||
SUSE_ID= $(shell grep '^VERSION_ID=' /etc/os-release | cut -f2- -d= | sed -e 's/\"//g' | cut -d' ' -f2)
|
||||
@ -323,7 +328,7 @@ else ifeq ($(OS_ID),centos)
|
||||
@sudo -E yum install $(CONFIRM) centos-release-scl-rh epel-release
|
||||
@sudo -E yum groupinstall $(CONFIRM) $(RPM_DEPENDS_GROUPS)
|
||||
@sudo -E yum install $(CONFIRM) $(RPM_DEPENDS)
|
||||
@sudo -E debuginfo-install $(CONFIRM) glibc openssl-libs mbedtls-devel zlib
|
||||
@sudo -E yum install $(CONFIRM) --enablerepo=base-debuginfo $(RPM_DEPENDS_DEBUG)
|
||||
else ifeq ($(OS_ID),fedora)
|
||||
@sudo -E dnf groupinstall $(CONFIRM) $(RPM_DEPENDS_GROUPS)
|
||||
@sudo -E dnf install $(CONFIRM) $(RPM_DEPENDS)
|
||||
|
768
RELEASE.md
768
RELEASE.md
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@ Google Sanitizers
|
||||
|
||||
VPP is instrumented to support `Google Sanitizers <https://github.com/google/sanitizers>`_.
|
||||
As of today, only `AddressSanitizer <https://github.com/google/sanitizers/wiki/AddressSanitizer>`_
|
||||
is supported and only for the heap.
|
||||
is supported, only for GCC and only for the heap.
|
||||
|
||||
AddressSanitizer
|
||||
================
|
||||
@ -20,19 +20,19 @@ build option, so all VPP targets should be supported. For example:
|
||||
.. code-block:: console
|
||||
|
||||
# build a debug image with ASan support:
|
||||
$ make rebuild VPP_EXTRA_CMAKE_ARGS=-DENABLE_SANITIZE_ADDR=ON
|
||||
$ make rebuild VPP_EXTRA_CMAKE_ARGS=-DVPP_ENABLE_SANITIZE_ADDR=ON CC=gcc-8
|
||||
....
|
||||
|
||||
# build a release image with ASan support:
|
||||
$ make rebuild-release VPP_EXTRA_CMAKE_ARGS=-DENABLE_SANITIZE_ADDR=ON
|
||||
$ make rebuild-release VPP_EXTRA_CMAKE_ARGS=-DVPP_ENABLE_SANITIZE_ADDR=ON CC=gcc-8
|
||||
....
|
||||
|
||||
# build packages in debug mode with ASan support:
|
||||
$ make pkg-deb-debug VPP_EXTRA_CMAKE_ARGS=-DENABLE_SANITIZE_ADDR=ON
|
||||
$ make pkg-deb-debug VPP_EXTRA_CMAKE_ARGS=-DVPP_ENABLE_SANITIZE_ADDR=ON CC=gcc-8
|
||||
....
|
||||
|
||||
# run GBP plugin tests in debug mode with ASan
|
||||
$ make test-debug TEST=test_gbp VPP_EXTRA_CMAKE_ARGS=-DENABLE_SANITIZE_ADDR=ON
|
||||
$ make test-debug TEST=test_gbp VPP_EXTRA_CMAKE_ARGS=-DVPP_ENABLE_SANITIZE_ADDR=ON CC=gcc-8
|
||||
....
|
||||
|
||||
Once VPP has been built with ASan support you can use it as usual including
|
||||
|
@ -4,6 +4,7 @@ Test Framework Documentation {#test_framework_doc}
|
||||
PyDoc generated documentation for the "make test" framework is available for
|
||||
the following releases:
|
||||
|
||||
- [Test framework documentation for VPP 20.05](https://docs.fd.io/vpp/20.05/vpp_make_test/html)
|
||||
- [Test framework documentation for VPP 20.01](https://docs.fd.io/vpp/20.01/vpp_make_test/html)
|
||||
- [Test framework documentation for VPP 19.08](https://docs.fd.io/vpp/19.08/vpp_make_test/html)
|
||||
- [Test framework documentation for VPP 19.04](https://docs.fd.io/vpp/19.04/vpp_make_test/html)
|
||||
|
@ -1,82 +0,0 @@
|
||||
---
|
||||
title: Home
|
||||
---
|
||||
|
||||
# VPP Status
|
||||
|
||||
### Here's the version...
|
||||
|
||||
VPP version: <div id="VPPversion"></div>
|
||||
|
||||
build date: <div id="VPPbuilddate"></div>
|
||||
|
||||
<div id="like_button_container"></div>
|
||||
|
||||
### Show Interface
|
||||
|
||||
<p>Enter the interface name, then click "Submit" to display interface stats:</p>
|
||||
|
||||
<input id="ifacename" type="text"></input>
|
||||
<button onclick="getStats()">Get Stats</button>
|
||||
|
||||
<div id="ifacestats"></div>
|
||||
|
||||
{{< rawhtml >}}
|
||||
|
||||
<script>
|
||||
function getStats() {
|
||||
var url="http://192.168.10.1:1234/interface_stats.json?";
|
||||
var iface=document.getElementById("ifacename").value;
|
||||
url=url.concat(iface);
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
mode: 'no-cors',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(function(obj) {
|
||||
console.log(obj)
|
||||
var result=obj.interface_stats.name;
|
||||
result = result.concat(": rx-pkts: ");
|
||||
result = result.concat(obj.interface_stats.rx_packets);
|
||||
result = result.concat(" rx-bytes: ");
|
||||
result = result.concat(obj.interface_stats.rx_bytes);
|
||||
result = result.concat(": tx-pkts: ");
|
||||
result = result.concat(obj.interface_stats.tx_packets);
|
||||
result = result.concat(" tx-bytes: ");
|
||||
result = result.concat(obj.interface_stats.tx_bytes);
|
||||
result = result.concat(" drops: ");
|
||||
result = result.concat(obj.interface_stats.drops);
|
||||
result = result.concat(" ip4: ");
|
||||
result = result.concat(obj.interface_stats.ip4);
|
||||
result = result.concat(" ip6: ");
|
||||
result = result.concat(obj.interface_stats.ip6);
|
||||
|
||||
document.getElementById("ifacestats").innerHTML=result;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log(error);
|
||||
})}
|
||||
// unconditionally populate vpp version info ->
|
||||
fetch('http://192.168.10.1:1234/version.json', {
|
||||
method: 'GET',
|
||||
mode: 'no-cors',
|
||||
cache: 'no-cache',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then((response) => response.json())
|
||||
.then(function(obj) {
|
||||
document.getElementById("VPPbuilddate").innerHTML=obj.vpp_details.build_date;
|
||||
document.getElementById("VPPversion").innerHTML=obj.vpp_details.version;
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log(error);
|
||||
});
|
||||
</script>
|
||||
|
||||
{{< /rawhtml >}}
|
@ -2605,10 +2605,12 @@ ixge_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, u32 flags)
|
||||
|
||||
old = r->filter_control;
|
||||
|
||||
if (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL)
|
||||
if (flags == ETHERNET_INTERFACE_FLAG_ACCEPT_ALL)
|
||||
r->filter_control = old | (1 << 9) /* unicast promiscuous */ ;
|
||||
else
|
||||
else if (flags == ETHERNET_INTERFACE_FLAGS_DEFAULT_L3)
|
||||
r->filter_control = old & ~(1 << 9);
|
||||
else
|
||||
return ~0;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
@ -169,7 +169,10 @@ Requires(post): python3-policycoreutils
|
||||
This package contains a tailored VPP SELinux policy
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}-%{_version}
|
||||
%setup -q -c -T -n %{name}-%{_version}
|
||||
cd ..
|
||||
unxz --stdout ./SOURCES/%{name}-%{_version}-%{_release}.tar.xz | tar --extract --touch
|
||||
cd -
|
||||
|
||||
%pre
|
||||
# Add the vpp group
|
||||
@ -180,7 +183,7 @@ groupadd -f -r vpp
|
||||
. /opt/rh/devtoolset-9/enable
|
||||
%endif
|
||||
%if %{with aesni}
|
||||
make bootstrap
|
||||
make install-dep
|
||||
make -C build-root PLATFORM=vpp TAG=%{_vpp_tag} install-packages
|
||||
%else
|
||||
make bootstrap AESNI=n
|
||||
|
@ -1125,25 +1125,29 @@ avf_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, u32 flags)
|
||||
vlib_main_t *vm = vlib_get_main ();
|
||||
avf_main_t *am = &avf_main;
|
||||
avf_device_t *ad = vec_elt_at_index (am->devices, hw->dev_instance);
|
||||
if (ETHERNET_INTERFACE_FLAG_CONFIG_PROMISC (flags))
|
||||
clib_error_t *error;
|
||||
u8 promisc_enabled;
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
clib_error_t *error;
|
||||
int promisc_enabled = (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL) != 0;
|
||||
u32 new_flags = promisc_enabled ?
|
||||
ad->flags | AVF_DEVICE_F_PROMISC : ad->flags & ~AVF_DEVICE_F_PROMISC;
|
||||
|
||||
if (new_flags == ad->flags)
|
||||
return flags;
|
||||
|
||||
if ((error = avf_config_promisc_mode (vm, ad, promisc_enabled)))
|
||||
{
|
||||
avf_log_err (ad, "%s: %U", format_clib_error, error);
|
||||
clib_error_free (error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ad->flags = new_flags;
|
||||
case ETHERNET_INTERFACE_FLAG_DEFAULT_L3:
|
||||
ad->flags &= ~AVF_DEVICE_F_PROMISC;
|
||||
break;
|
||||
case ETHERNET_INTERFACE_FLAG_ACCEPT_ALL:
|
||||
ad->flags |= AVF_DEVICE_F_PROMISC;
|
||||
break;
|
||||
default:
|
||||
return ~0;
|
||||
}
|
||||
|
||||
promisc_enabled = ((ad->flags & AVF_DEVICE_F_PROMISC) != 0);
|
||||
if ((error = avf_config_promisc_mode (vm, ad, promisc_enabled)))
|
||||
{
|
||||
avf_log_err (ad, "%s: %U", format_clib_error, error);
|
||||
clib_error_free (error);
|
||||
return ~0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1470,6 +1474,13 @@ avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args)
|
||||
if (error)
|
||||
goto error;
|
||||
|
||||
/* Indicate ability to support L3 DMAC filtering and
|
||||
* initialize interface to L3 non-promisc mode */
|
||||
vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, ad->hw_if_index);
|
||||
hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_MAC_FILTER;
|
||||
ethernet_set_flags (vnm, ad->hw_if_index,
|
||||
ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
|
||||
|
||||
vnet_sw_interface_t *sw = vnet_get_hw_sw_interface (vnm, ad->hw_if_index);
|
||||
args->sw_if_index = ad->sw_if_index = sw->sw_if_index;
|
||||
|
||||
|
@ -76,7 +76,8 @@ openssl_ops_enc_cbc (vlib_main_t * vm, vnet_crypto_op_t * ops[],
|
||||
int out_len = 0;
|
||||
int iv_len;
|
||||
|
||||
if (op->op == VNET_CRYPTO_OP_3DES_CBC_ENC)
|
||||
if (op->op == VNET_CRYPTO_OP_3DES_CBC_ENC
|
||||
|| op->op == VNET_CRYPTO_OP_DES_CBC_ENC)
|
||||
iv_len = 8;
|
||||
else
|
||||
iv_len = 16;
|
||||
|
@ -91,6 +91,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;
|
||||
|
@ -113,30 +113,33 @@ dpdk_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags)
|
||||
{
|
||||
dpdk_main_t *dm = &dpdk_main;
|
||||
dpdk_device_t *xd = vec_elt_at_index (dm->devices, hi->dev_instance);
|
||||
u32 old = 0;
|
||||
u32 old = (xd->flags & DPDK_DEVICE_FLAG_PROMISC) != 0;
|
||||
|
||||
if (ETHERNET_INTERFACE_FLAG_CONFIG_PROMISC (flags))
|
||||
{
|
||||
old = (xd->flags & DPDK_DEVICE_FLAG_PROMISC) != 0;
|
||||
|
||||
if (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL)
|
||||
xd->flags |= DPDK_DEVICE_FLAG_PROMISC;
|
||||
else
|
||||
xd->flags &= ~DPDK_DEVICE_FLAG_PROMISC;
|
||||
|
||||
if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
|
||||
{
|
||||
if (xd->flags & DPDK_DEVICE_FLAG_PROMISC)
|
||||
rte_eth_promiscuous_enable (xd->port_id);
|
||||
else
|
||||
rte_eth_promiscuous_disable (xd->port_id);
|
||||
}
|
||||
}
|
||||
else if (ETHERNET_INTERFACE_FLAG_CONFIG_MTU (flags))
|
||||
switch (flags)
|
||||
{
|
||||
case ETHERNET_INTERFACE_FLAG_DEFAULT_L3:
|
||||
/* set to L3/non-promisc mode */
|
||||
xd->flags &= ~DPDK_DEVICE_FLAG_PROMISC;
|
||||
break;
|
||||
case ETHERNET_INTERFACE_FLAG_ACCEPT_ALL:
|
||||
xd->flags |= DPDK_DEVICE_FLAG_PROMISC;
|
||||
break;
|
||||
case ETHERNET_INTERFACE_FLAG_MTU:
|
||||
xd->port_conf.rxmode.max_rx_pkt_len = hi->max_packet_bytes;
|
||||
dpdk_device_setup (xd);
|
||||
return 0;
|
||||
default:
|
||||
return ~0;
|
||||
}
|
||||
|
||||
if (xd->flags & DPDK_DEVICE_FLAG_ADMIN_UP)
|
||||
{
|
||||
if (xd->flags & DPDK_DEVICE_FLAG_PROMISC)
|
||||
rte_eth_promiscuous_enable (xd->port_id);
|
||||
else
|
||||
rte_eth_promiscuous_disable (xd->port_id);
|
||||
}
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
@ -737,6 +740,12 @@ dpdk_lib_init (dpdk_main_t * dm)
|
||||
hi->max_packet_bytes = mtu;
|
||||
hi->max_supported_packet_bytes = max_rx_frame;
|
||||
hi->numa_node = xd->cpu_socket;
|
||||
|
||||
/* Indicate ability to support L3 DMAC filtering and
|
||||
* initialize interface to L3 non-promisc mode */
|
||||
hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_MAC_FILTER;
|
||||
ethernet_set_flags (dm->vnet_main, xd->hw_if_index,
|
||||
ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
|
||||
}
|
||||
|
||||
if (dm->conf->no_tx_checksum_offload == 0)
|
||||
|
@ -1118,10 +1118,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
{
|
||||
if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment)
|
||||
{
|
||||
udp0->src_port = s0->out2in.port;
|
||||
if (PREDICT_FALSE (udp0->checksum))
|
||||
{
|
||||
old_port0 = vnet_buffer (b0)->ip.reass.l4_src_port;
|
||||
new_port0 = udp0->src_port = s0->out2in.port;
|
||||
new_port0 = udp0->src_port;
|
||||
sum0 = udp0->checksum;
|
||||
sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, dst_address /* changed member */
|
||||
);
|
||||
@ -1325,10 +1326,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
{
|
||||
if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment)
|
||||
{
|
||||
udp1->src_port = s1->out2in.port;
|
||||
if (PREDICT_FALSE (udp1->checksum))
|
||||
{
|
||||
old_port1 = vnet_buffer (b1)->ip.reass.l4_src_port;
|
||||
new_port1 = udp1->src_port = s1->out2in.port;
|
||||
new_port1 = udp1->src_port;
|
||||
sum1 = udp1->checksum;
|
||||
sum1 = ip_csum_update (sum1, old_addr1, new_addr1, ip4_header_t, dst_address /* changed member */
|
||||
);
|
||||
@ -1567,10 +1569,11 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
|
||||
{
|
||||
if (!vnet_buffer (b0)->ip.reass.is_non_first_fragment)
|
||||
{
|
||||
udp0->src_port = s0->out2in.port;
|
||||
if (PREDICT_FALSE (udp0->checksum))
|
||||
{
|
||||
old_port0 = vnet_buffer (b0)->ip.reass.l4_src_port;
|
||||
new_port0 = udp0->src_port = s0->out2in.port;
|
||||
new_port0 = udp0->src_port;
|
||||
sum0 = udp0->checksum;
|
||||
sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, dst_address /* changed member */
|
||||
);
|
||||
|
@ -386,7 +386,6 @@ slow_path_ed (snat_main_t * sm,
|
||||
{
|
||||
nat_elog_notice ("addresses exhausted");
|
||||
b->error = node->errors[NAT_IN2OUT_ED_ERROR_OUT_OF_PORTS];
|
||||
nat_free_session_data (sm, s, thread_index, 0);
|
||||
nat_ed_session_delete (sm, s, thread_index, 1);
|
||||
return NAT_NEXT_DROP;
|
||||
}
|
||||
|
@ -493,6 +493,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];
|
||||
@ -521,7 +522,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);
|
||||
|
@ -4712,6 +4712,53 @@ class TestNAT44EndpointDependent(MethodHolder):
|
||||
sessions = self.statistics.get_counter('/nat44/total-sessions')
|
||||
self.assertEqual(sessions[0][0], 3)
|
||||
|
||||
def test_dynamic_out_of_ports(self):
|
||||
""" NAT44 dynamic translation test: out of ports """
|
||||
|
||||
flags = self.config_flags.NAT_IS_INSIDE
|
||||
self.vapi.nat44_interface_add_del_feature(
|
||||
sw_if_index=self.pg0.sw_if_index,
|
||||
flags=flags, is_add=1)
|
||||
self.vapi.nat44_interface_add_del_feature(
|
||||
sw_if_index=self.pg1.sw_if_index,
|
||||
is_add=1)
|
||||
|
||||
nat_config = self.vapi.nat_show_config()
|
||||
self.assertEqual(1, nat_config.endpoint_dependent)
|
||||
|
||||
# in2out and no NAT addresses added
|
||||
err_old = self.statistics.get_err_counter(
|
||||
'/err/nat44-ed-in2out-slowpath/out of ports')
|
||||
|
||||
pkts = self.create_stream_in(self.pg0, self.pg1)
|
||||
self.pg0.add_stream(pkts)
|
||||
self.pg_enable_capture(self.pg_interfaces)
|
||||
self.pg_start()
|
||||
self.pg1.get_capture(0, timeout=1)
|
||||
|
||||
err_new = self.statistics.get_err_counter(
|
||||
'/err/nat44-ed-in2out-slowpath/out of ports')
|
||||
|
||||
self.assertEqual(err_new - err_old, len(pkts))
|
||||
|
||||
# in2out after NAT addresses added
|
||||
self.nat44_add_address(self.nat_addr)
|
||||
|
||||
err_old = self.statistics.get_err_counter(
|
||||
'/err/nat44-ed-in2out-slowpath/out of ports')
|
||||
|
||||
pkts = self.create_stream_in(self.pg0, self.pg1)
|
||||
self.pg0.add_stream(pkts)
|
||||
self.pg_enable_capture(self.pg_interfaces)
|
||||
self.pg_start()
|
||||
capture = self.pg1.get_capture(len(pkts))
|
||||
self.verify_capture_out(capture)
|
||||
|
||||
err_new = self.statistics.get_err_counter(
|
||||
'/err/nat44-ed-in2out-slowpath/out of ports')
|
||||
|
||||
self.assertEqual(err_new, err_old)
|
||||
|
||||
def test_dynamic_output_feature_vrf(self):
|
||||
""" NAT44 dynamic translation test: output-feature, VRF"""
|
||||
|
||||
|
@ -182,7 +182,7 @@ rdma_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, u32 flags)
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
case 0:
|
||||
case ETHERNET_INTERFACE_FLAG_DEFAULT_L3:
|
||||
return rdma_dev_set_ucast (rd);
|
||||
case ETHERNET_INTERFACE_FLAG_ACCEPT_ALL:
|
||||
return rdma_dev_set_promisc (rd);
|
||||
@ -339,9 +339,18 @@ rdma_async_event_cleanup (rdma_device_t * rd)
|
||||
static clib_error_t *
|
||||
rdma_register_interface (vnet_main_t * vnm, rdma_device_t * rd)
|
||||
{
|
||||
return ethernet_register_interface (vnm, rdma_device_class.index,
|
||||
rd->dev_instance, rd->hwaddr.bytes,
|
||||
&rd->hw_if_index, rdma_flag_change);
|
||||
clib_error_t *err =
|
||||
ethernet_register_interface (vnm, rdma_device_class.index,
|
||||
rd->dev_instance, rd->hwaddr.bytes,
|
||||
&rd->hw_if_index, rdma_flag_change);
|
||||
|
||||
/* Indicate ability to support L3 DMAC filtering and
|
||||
* initialize interface to L3 non-promisc mode */
|
||||
vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, rd->hw_if_index);
|
||||
hi->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_MAC_FILTER;
|
||||
ethernet_set_flags (vnm, rd->hw_if_index,
|
||||
ETHERNET_INTERFACE_FLAG_DEFAULT_L3);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3,22 +3,29 @@ SRv6 Mobile User Plane Plugins {#srv6_mobile_plugin_doc}
|
||||
|
||||
# Introduction
|
||||
|
||||
This plugin module can provide the stateless mobile user plane protocols translation between GTP-U and SRv6. The functions of the translation take advantage of SRv6 network programmability.
|
||||
This plugin module can provide the stateless mobile user plane protocols translation between GTP-U and SRv6. The plugin also provides FIB table lookup for an IPv4/IPv6 packet encapsulated in GTP-U. These plugin functions take advantage of SRv6 network programmability.
|
||||
|
||||
[SRv6 Mobile User Plane](https://tools.ietf.org/html/draft-ietf-dmm-srv6-mobile-uplane) defines the user plane protocol using SRv6
|
||||
including following stateless translation functions:
|
||||
|
||||
- **T.M.GTP4.D:**
|
||||
- **T.M.GTP4.D:**
|
||||
GTP-U over UDP/IPv4 -> SRv6
|
||||
- **End.M.GTP4.E:**
|
||||
- **End.M.GTP4.E:**
|
||||
SRv6 -> GTP-U over UDP/IPv4
|
||||
- **End.M.GTP6.D:**
|
||||
- **End.M.GTP6.D:**
|
||||
GTP-U over UDP/IPv6 -> SRv6
|
||||
- **End.M.GTP6.E:**
|
||||
- **End.M.GTP6.E:**
|
||||
SRv6 -> GTP-U over UDP/IPv6
|
||||
|
||||
These functions benefit user plane(overlay) to be able to utilize data plane(underlay) networks properly. And also it benefits data plane to be able to handle user plane in routing paradigm.
|
||||
|
||||
In addition to the above functions, the plugin supports following functions:
|
||||
|
||||
- **T.M.GTP4.DT{4|6|46}:**
|
||||
FIB table lookup for IPv4/IP6 encapsulated in GTP-U over UDP/IPv4
|
||||
- **End.M.GTP6.DT{4|6|46}:**
|
||||
FIB table lookup for IPv4/IP6 encapsulated in GTP-U over UDP/IPv6
|
||||
|
||||
Noted that the prefix of function names follow naming convention of SRv6 network programming. "T" means transit function, "End" means end function, "M" means Mobility specific function. The suffix "D" and "E" mean that "decapsulation" and "encapsulation" respectively.
|
||||
|
||||
|
||||
@ -138,5 +145,57 @@ For example, the below command configures the SID prefix 2001:db8::/64 with `end
|
||||
sr localsid prefix 2001:db8::/64 behavior end.m.gtp6.e
|
||||
```
|
||||
|
||||
## FIB Table Lookup for Inner IPv4/IPv6 packet
|
||||
|
||||
SRv6 Mobile functions of `t.m.gtp4.dt*` and `end.m.gtp6.dt*` support decapsulating outer IP/UDP/GTP-U headers and forwarding inner IP packet based on specific fib table.
|
||||
|
||||
In case of the both outer and inner IP address families are IPv4, `t.m.gtp4.dt4` function supports GTP-U decapsulation and fib lookup for inner IPv4 with an associated steering policy and the following parameters:
|
||||
|
||||
- SID: A SRv6 SID to represents the function
|
||||
- FIB: fib-table number for inner IPv4 packet lookup and forwarding
|
||||
|
||||
The following command instantiates a new T.M.GTP4.DT4 function.
|
||||
|
||||
```
|
||||
sr policy add bsid SID behavior t.m.gtp4.dt4 fib-table FIB
|
||||
```
|
||||
|
||||
For example, the below commands configure D5:: as the SID instantiates `t.m.gtp4.dt4` function. A steering policy for packets destine to 172.20.0.1 binds to the SID.
|
||||
|
||||
```
|
||||
sr steer l3 172.20.0.1/32 via bsid D5::
|
||||
sr policy add bsid D5:: behavior t.m.gtp4.dt4 fib-table 0
|
||||
```
|
||||
|
||||
In addition, inner IPv6, or mix of IPv4 and IPv6 inner packet cases require the function to be configured with local-fib table.
|
||||
|
||||
- LOCAL-FIB: fib-table number for lookup and forward GTP-U packet based on outer IP destination address
|
||||
|
||||
This is inner IPv6 case specific. The reason is that GTP-U encapsulates link local IPv6 packet for NDP (Neighber Discovery Protocol). Outer GTP-U header should be kept until the packets reach to the node responsible for NDP handling. It is typically UPF(User Plane Function) node.
|
||||
|
||||
The following command instantiate a new T.M.GTP4.DT6 function.
|
||||
|
||||
```
|
||||
sr policy add bsid D5:: behavior t.m.gtp4.dt6 fib-table 0 local-fib-table LOCAL-FIB
|
||||
```
|
||||
|
||||
Following example configures fib 0 for inner packet and fib 1 for outer GTP-U packet forwarding:
|
||||
|
||||
```
|
||||
sr policy add bsid D5:: behavior t.m.gtp4.dt6 fib-table 0 local-fib-table 1
|
||||
```
|
||||
|
||||
If you need to suport both IPv4 and IPv6 inner packet lookup with just one SID, you can configure `t.m.gtp4.dt46` function:
|
||||
|
||||
```
|
||||
sr policy add bsid D5:: behavior t.m.gtp4.dt46 fib-table 0 local-fib-table 1
|
||||
```
|
||||
|
||||
In case of GTP-U over IPv6 case, `end.m.gtp6.dt4`, `end.m.gtp6.dt6` and `end.m.gtp6.dt46` functions support inner IPv4, IPv6 and IPv4/IPv6 lookup and forwarding respectively. Specifiyng fib table for inner IP packet forwarding is required as same as GTP-U over IPv4 case, and local-fib table for inner IPv6 and IPv4/IPv6 cases as well.
|
||||
|
||||
```
|
||||
sr localsid prefix D::/64 behavior end.m.gtp6.dt46 fib-table 0 local-fib-table 0
|
||||
```
|
||||
|
||||
To run some demo setup please refer to: @subpage srv6_mobile_runner_doc
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <vnet/vnet.h>
|
||||
#include <vnet/pg/pg.h>
|
||||
#include <vppinfra/error.h>
|
||||
#include <vppinfra/mpcap.h>
|
||||
#include <vnet/mpcap.h>
|
||||
#include <vnet/ethernet/ethernet.h>
|
||||
|
||||
static mpcap_main_t test_mpcap_main = {
|
||||
|
@ -637,6 +637,32 @@ tcp_test_sack_rx (vlib_main_t * vm, unformat_input_t * input)
|
||||
TCP_TEST ((sb->rxt_sacked == 300), "last rxt sacked bytes %d",
|
||||
sb->rxt_sacked);
|
||||
|
||||
/*
|
||||
* Restart
|
||||
*/
|
||||
scoreboard_clear (sb);
|
||||
vec_reset_length (tc->rcv_opts.sacks);
|
||||
|
||||
/*
|
||||
* Broken sacks:
|
||||
* block.start > snd_nxt
|
||||
* && block.start < blk.end
|
||||
* && block.end <= snd_nxt
|
||||
*/
|
||||
tc->flags = 0;
|
||||
block.start = 2147483647;
|
||||
block.end = 4294967295;
|
||||
vec_add1 (tc->rcv_opts.sacks, block);
|
||||
tc->snd_una = tc->snd_nxt = 1969067947;
|
||||
|
||||
tcp_rcv_sacks (tc, tc->snd_una);
|
||||
|
||||
/*
|
||||
* Clear
|
||||
*/
|
||||
scoreboard_clear (sb);
|
||||
vec_reset_length (tc->rcv_opts.sacks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2901,7 +2901,7 @@ unformat_nsh_address (unformat_input_t * input, va_list * args)
|
||||
return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
|
||||
}
|
||||
|
||||
u8 *
|
||||
static u8 *
|
||||
format_nsh_address_vat (u8 * s, va_list * args)
|
||||
{
|
||||
nsh_t *a = va_arg (*args, nsh_t *);
|
||||
@ -2958,7 +2958,7 @@ vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
|
||||
s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
|
||||
|
||||
eid = format (0, "%U", format_lisp_eid_vat,
|
||||
mp->deid, mp->seid, mp->is_src_dst);
|
||||
&mp->deid, &mp->seid, mp->is_src_dst);
|
||||
vec_add1 (eid, 0);
|
||||
|
||||
print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
|
||||
@ -3007,7 +3007,7 @@ vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
|
||||
else
|
||||
{
|
||||
eid = format (0, "%U", format_lisp_eid_vat,
|
||||
mp->deid, mp->seid, mp->is_src_dst);
|
||||
&mp->deid, &mp->seid, mp->is_src_dst);
|
||||
vec_add1 (eid, 0);
|
||||
vat_json_object_add_string_copy (node, "eid", eid);
|
||||
vec_free (eid);
|
||||
@ -3031,9 +3031,9 @@ vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
|
||||
u8 *seid = 0, *deid = 0;
|
||||
ip46_address_t lloc, rloc;
|
||||
|
||||
deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
|
||||
deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
|
||||
|
||||
seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
|
||||
seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
|
||||
|
||||
vec_add1 (deid, 0);
|
||||
vec_add1 (seid, 0);
|
||||
@ -3079,9 +3079,9 @@ vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
|
||||
node = vat_json_array_add (&vam->json_tree);
|
||||
|
||||
vat_json_init_object (node);
|
||||
deid = format (0, "%U", format_lisp_eid_vat, mp->deid, 0);
|
||||
deid = format (0, "%U", format_lisp_eid_vat, &mp->deid, 0, 0);
|
||||
|
||||
seid = format (0, "%U", format_lisp_eid_vat, mp->seid, 0);
|
||||
seid = format (0, "%U", format_lisp_eid_vat, &mp->seid, 0, 0);
|
||||
|
||||
vec_add1 (deid, 0);
|
||||
vec_add1 (seid, 0);
|
||||
|
@ -477,17 +477,11 @@ writev (int fd, const struct iovec * iov, int iovcnt)
|
||||
return size;
|
||||
}
|
||||
|
||||
int
|
||||
fcntl (int fd, int cmd, ...)
|
||||
static int
|
||||
fcntl_internal (int fd, int cmd, va_list ap)
|
||||
{
|
||||
vls_handle_t vlsh;
|
||||
int rv = 0;
|
||||
va_list ap;
|
||||
|
||||
if ((errno = -ldp_init ()))
|
||||
return -1;
|
||||
|
||||
va_start (ap, cmd);
|
||||
|
||||
vlsh = ldp_fd_to_vlsh (fd);
|
||||
LDBG (0, "fd %u vlsh %d, cmd %u", fd, vlsh, cmd);
|
||||
@ -533,6 +527,20 @@ fcntl (int fd, int cmd, ...)
|
||||
#endif
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
fcntl (int fd, int cmd, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int rv;
|
||||
|
||||
if ((errno = -ldp_init ()))
|
||||
return -1;
|
||||
|
||||
va_start (ap, cmd);
|
||||
rv = fcntl_internal (fd, cmd, ap);
|
||||
va_end (ap);
|
||||
|
||||
return rv;
|
||||
@ -544,8 +552,11 @@ fcntl64 (int fd, int cmd, ...)
|
||||
va_list ap;
|
||||
int rv;
|
||||
|
||||
if ((errno = -ldp_init ()))
|
||||
return -1;
|
||||
|
||||
va_start (ap, cmd);
|
||||
rv = fcntl (fd, cmd, ap);
|
||||
rv = fcntl_internal (fd, cmd, ap);
|
||||
va_end (ap);
|
||||
return rv;
|
||||
}
|
||||
|
@ -550,45 +550,16 @@ libc_eventfd (int count, int flags)
|
||||
int
|
||||
libc_vfcntl (int fd, int cmd, va_list ap)
|
||||
{
|
||||
long int args[4];
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
swrap_bind_symbol_libc (fcntl);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
args[i] = va_arg (ap, long int);
|
||||
}
|
||||
|
||||
rc = swrap.libc.symbols._libc_fcntl.f (fd,
|
||||
cmd,
|
||||
args[0], args[1], args[2], args[3]);
|
||||
|
||||
return rc;
|
||||
return swrap.libc.symbols._libc_fcntl.f (fd, cmd, va_arg (ap, long int));
|
||||
}
|
||||
|
||||
#ifdef HAVE_FCNTL64
|
||||
int
|
||||
libc_vfcntl64 (int fd, int cmd, va_list ap)
|
||||
{
|
||||
long int args[4];
|
||||
int rc;
|
||||
int i;
|
||||
|
||||
swrap_bind_symbol_libc (fcntl64);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
args[i] = va_arg (ap, long int);
|
||||
}
|
||||
|
||||
rc = swrap.libc.symbols._libc_fcntl64.f (fd,
|
||||
cmd,
|
||||
args[0], args[1], args[2],
|
||||
args[3]);
|
||||
|
||||
return rc;
|
||||
return swrap.libc.symbols._libc_fcntl64.f (fd, cmd, va_arg (ap, long int));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -122,7 +122,9 @@ int libc_eventfd (int count, int flags);
|
||||
|
||||
int libc_vfcntl (int fd, int cmd, va_list ap);
|
||||
|
||||
#ifdef HAVE_FCNTL64
|
||||
int libc_vfcntl64 (int fd, int cmd, va_list ap);
|
||||
#endif
|
||||
|
||||
int libc_vioctl (int fd, int cmd, va_list ap);
|
||||
|
||||
|
@ -529,7 +529,7 @@ static inline u8
|
||||
vcl_session_is_cl (vcl_session_t * s)
|
||||
{
|
||||
if (s->session_type == VPPCOM_PROTO_UDP)
|
||||
return 1;
|
||||
return !(s->flags & VCL_SESSION_F_CONNECTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -548,6 +548,12 @@ vcl_session_is_closing (vcl_session_t * s)
|
||||
|| s->session_state == STATE_DISCONNECT);
|
||||
}
|
||||
|
||||
static inline u8
|
||||
vcl_session_is_closed (vcl_session_t * s)
|
||||
{
|
||||
return (!s || (s->session_state == STATE_CLOSED));
|
||||
}
|
||||
|
||||
static inline int
|
||||
vcl_session_closing_error (vcl_session_t * s)
|
||||
{
|
||||
|
@ -209,6 +209,8 @@ vcl_send_session_listen (vcl_worker_t * wrk, vcl_session_t * s)
|
||||
clib_memcpy_fast (&mp->ip, &s->transport.lcl_ip, sizeof (mp->ip));
|
||||
mp->port = s->transport.lcl_port;
|
||||
mp->proto = s->session_type;
|
||||
if (s->flags & VCL_SESSION_F_CONNECTED)
|
||||
mp->flags = TRANSPORT_CFG_F_CONNECTED;
|
||||
app_send_ctrl_evt_to_vpp (mq, app_evt);
|
||||
}
|
||||
|
||||
@ -550,7 +552,8 @@ vcl_session_reset_handler (vcl_worker_t * wrk,
|
||||
return VCL_INVALID_SESSION_INDEX;
|
||||
}
|
||||
|
||||
session->session_state = STATE_DISCONNECT;
|
||||
if (session->session_state != STATE_CLOSED)
|
||||
session->session_state = STATE_DISCONNECT;
|
||||
VDBG (0, "reset session %u [0x%llx]", sid, reset_msg->handle);
|
||||
return sid;
|
||||
}
|
||||
@ -1556,10 +1559,6 @@ vppcom_unformat_proto (uint8_t * proto, char *proto_str)
|
||||
*proto = VPPCOM_PROTO_UDP;
|
||||
else if (!strcmp (proto_str, "udp"))
|
||||
*proto = VPPCOM_PROTO_UDP;
|
||||
else if (!strcmp (proto_str, "UDPC"))
|
||||
*proto = VPPCOM_PROTO_UDPC;
|
||||
else if (!strcmp (proto_str, "udpc"))
|
||||
*proto = VPPCOM_PROTO_UDPC;
|
||||
else if (!strcmp (proto_str, "TLS"))
|
||||
*proto = VPPCOM_PROTO_TLS;
|
||||
else if (!strcmp (proto_str, "tls"))
|
||||
@ -2780,7 +2779,8 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
|
||||
{
|
||||
case SESSION_IO_EVT_RX:
|
||||
sid = e->session_index;
|
||||
if (!(session = vcl_session_get (wrk, sid)))
|
||||
session = vcl_session_get (wrk, sid);
|
||||
if (vcl_session_is_closed (session))
|
||||
break;
|
||||
vcl_fifo_rx_evt_valid_or_break (session);
|
||||
session_events = session->vep.ev.events;
|
||||
@ -2793,7 +2793,8 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
|
||||
break;
|
||||
case SESSION_IO_EVT_TX:
|
||||
sid = e->session_index;
|
||||
if (!(session = vcl_session_get (wrk, sid)))
|
||||
session = vcl_session_get (wrk, sid);
|
||||
if (vcl_session_is_closed (session))
|
||||
break;
|
||||
session_events = session->vep.ev.events;
|
||||
if (!(EPOLLOUT & session_events))
|
||||
@ -2821,7 +2822,8 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
|
||||
connected_msg = (session_connected_msg_t *) e->data;
|
||||
sid = vcl_session_connected_handler (wrk, connected_msg);
|
||||
/* Generate EPOLLOUT because there's no connected event */
|
||||
if (!(session = vcl_session_get (wrk, sid)))
|
||||
session = vcl_session_get (wrk, sid);
|
||||
if (vcl_session_is_closed (session))
|
||||
break;
|
||||
session_events = session->vep.ev.events;
|
||||
if (!(EPOLLOUT & session_events))
|
||||
@ -2835,7 +2837,7 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
|
||||
case SESSION_CTRL_EVT_DISCONNECTED:
|
||||
disconnected_msg = (session_disconnected_msg_t *) e->data;
|
||||
session = vcl_session_disconnected_handler (wrk, disconnected_msg);
|
||||
if (!session)
|
||||
if (vcl_session_is_closed (session))
|
||||
break;
|
||||
session_events = session->vep.ev.events;
|
||||
add_event = 1;
|
||||
@ -2844,7 +2846,8 @@ vcl_epoll_wait_handle_mq_event (vcl_worker_t * wrk, session_event_t * e,
|
||||
break;
|
||||
case SESSION_CTRL_EVT_RESET:
|
||||
sid = vcl_session_reset_handler (wrk, (session_reset_msg_t *) e->data);
|
||||
if (!(session = vcl_session_get (wrk, sid)))
|
||||
session = vcl_session_get (wrk, sid);
|
||||
if (vcl_session_is_closed (session))
|
||||
break;
|
||||
session_events = session->vep.ev.events;
|
||||
add_event = 1;
|
||||
@ -2923,7 +2926,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:
|
||||
@ -2931,7 +2934,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);
|
||||
@ -2961,7 +2967,7 @@ vppcom_epoll_wait_condvar (vcl_worker_t * wrk, struct epoll_event *events,
|
||||
continue;
|
||||
|
||||
now = clib_time_now (&wrk->clib_time);
|
||||
wait -= now - start;
|
||||
wait -= (now - start) * 1e3;
|
||||
start = now;
|
||||
}
|
||||
while (wait > 0);
|
||||
@ -3593,6 +3599,11 @@ vppcom_session_attr (uint32_t session_handle, uint32_t op,
|
||||
*(int *) buffer = SHUT_RDWR;
|
||||
*buflen = sizeof (int);
|
||||
break;
|
||||
|
||||
case VPPCOM_ATTR_SET_CONNECTED:
|
||||
session->flags |= VCL_SESSION_F_CONNECTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = VPPCOM_EINVAL;
|
||||
break;
|
||||
|
@ -51,7 +51,6 @@ typedef enum
|
||||
VPPCOM_PROTO_UDP,
|
||||
VPPCOM_PROTO_NONE,
|
||||
VPPCOM_PROTO_TLS,
|
||||
VPPCOM_PROTO_UDPC,
|
||||
VPPCOM_PROTO_QUIC,
|
||||
} vppcom_proto_t;
|
||||
|
||||
@ -71,9 +70,6 @@ vppcom_proto_str (vppcom_proto_t proto)
|
||||
case VPPCOM_PROTO_TLS:
|
||||
proto_str = "TLS";
|
||||
break;
|
||||
case VPPCOM_PROTO_UDPC:
|
||||
proto_str = "UDPC";
|
||||
break;
|
||||
case VPPCOM_PROTO_QUIC:
|
||||
proto_str = "QUIC";
|
||||
break;
|
||||
@ -87,7 +83,7 @@ vppcom_proto_str (vppcom_proto_t proto)
|
||||
static inline int
|
||||
vcl_proto_is_dgram (uint8_t proto)
|
||||
{
|
||||
return proto == VPPCOM_PROTO_UDP || proto == VPPCOM_PROTO_UDPC;
|
||||
return proto == VPPCOM_PROTO_UDP;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
@ -164,6 +160,7 @@ typedef enum
|
||||
VPPCOM_ATTR_SET_TCP_USER_MSS,
|
||||
VPPCOM_ATTR_SET_SHUT,
|
||||
VPPCOM_ATTR_GET_SHUT,
|
||||
VPPCOM_ATTR_SET_CONNECTED,
|
||||
} vppcom_attr_op_t;
|
||||
|
||||
typedef struct _vcl_poll
|
||||
|
@ -96,7 +96,7 @@ typedef struct vlib_main_t
|
||||
u64 cpu_time_main_loop_start;
|
||||
|
||||
/* Incremented once for each main loop. */
|
||||
u32 main_loop_count;
|
||||
volatile u32 main_loop_count;
|
||||
|
||||
/* Count of vectors processed this main loop. */
|
||||
u32 main_loop_vectors_processed;
|
||||
|
@ -1434,6 +1434,18 @@ vlib_worker_thread_initial_barrier_sync_and_release (vlib_main_t * vm)
|
||||
*vlib_worker_threads->wait_at_barrier = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the wroker thread barrier is held
|
||||
*/
|
||||
u8
|
||||
vlib_worker_thread_barrier_held (void)
|
||||
{
|
||||
if (vec_len (vlib_mains) < 2)
|
||||
return (1);
|
||||
|
||||
return (*vlib_worker_threads->wait_at_barrier == 1);
|
||||
}
|
||||
|
||||
void
|
||||
vlib_worker_thread_barrier_sync_int (vlib_main_t * vm, const char *func_name)
|
||||
{
|
||||
@ -1630,6 +1642,41 @@ vlib_worker_thread_barrier_release (vlib_main_t * vm)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait until each of the workers has been once around the track
|
||||
*/
|
||||
void
|
||||
vlib_worker_wait_one_loop (void)
|
||||
{
|
||||
ASSERT (vlib_get_thread_index () == 0);
|
||||
|
||||
if (vec_len (vlib_mains) < 2)
|
||||
return;
|
||||
|
||||
if (vlib_worker_thread_barrier_held ())
|
||||
return;
|
||||
|
||||
u32 *counts = 0;
|
||||
u32 ii;
|
||||
|
||||
vec_validate (counts, vec_len (vlib_mains) - 1);
|
||||
|
||||
/* record the current loop counts */
|
||||
vec_foreach_index (ii, vlib_mains)
|
||||
counts[ii] = vlib_mains[ii]->main_loop_count;
|
||||
|
||||
/* spin until each changes, apart from the main thread, or we'd be
|
||||
* a while */
|
||||
for (ii = 1; ii < vec_len (counts); ii++)
|
||||
{
|
||||
while (counts[ii] == vlib_mains[ii]->main_loop_count)
|
||||
CLIB_PAUSE ();
|
||||
}
|
||||
|
||||
vec_free (counts);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the frame queue to see if any frames are available.
|
||||
* If so, pull the packets off the frames and put them to
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user