Compare commits

...

17 Commits

Author SHA1 Message Date
Benoît Ganne 11a2212087 ipsec: fix AES CBC IV generation (CVE-2022-46397)
For AES-CBC, the IV must be unpredictable (see NIST SP800-38a Appendix
C). Chaining IVs like is done by ipsecmb and native backends for the
VNET_CRYPTO_OP_FLAG_INIT_IV is fully predictable.
Encrypt a counter as part of the message, making the (predictable)
counter-generated IV unpredictable.

Fixes: VPP-2037
Type: fix

Change-Id: If4f192d62bf97dda553e7573331c75efa11822ae
Signed-off-by: Benoît Ganne <bganne@cisco.com>
2023-02-07 17:55:49 +01:00
Andrew Yourtchenko 54f8aff02a misc: 21.01.1 Release Notes
Change-Id: If637d21d3c8340ae146ac6f4264945fa94328774
Type: docs
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2021-07-13 14:35:10 +00:00
Jieqiang Wang 9330de53eb avf: fix gcc compiling warning on Arm
Initializing struct avf_ip6_psh by {0} using gcc with O2 optimize option
will trigger the -Werror=maybe-uninitialized compiling warning on Arm
because gcc compiler will think some members of the struct avf_ip6_psh
may not be initialized, which probably is a false positive in this case.
The compiling error log is shown as below. Avoid this compiling warning
by explicitly declaring the IPv6 src and dst ip in avf_ip6_psh as
ip6_address_t.

ccache /usr/lib/ccache/gcc-10 -DHAVE_FCNTL64 -DHAVE_GETCPU -DHAVE_MEMFD_CREATE -I/home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src -I. -Iinclude -I/home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/plugins -Iplugins -Iplugins/avf -Wno-address-of-packed-member -g -fPIC -Werror -Wall -march=armv8-a+crc  -O2 -fstack-protector -DFORTIFY_SOURCE=2 -fno-common  -fPIC   -DCLIB_MARCH_VARIANT=cortexa72 -march=armv8-a+crc+crypto -mtune=cortex-a72 -DCLIB_N_PREFETCHES=6 -MD -MT plugins/avf/CMakeFiles/avf_plugin_cortexa72.dir/output.c.o -MF plugins/avf/CMakeFiles/avf_plugin_cortexa72.dir/output.c.o.d -o plugins/avf/CMakeFiles/avf_plugin_cortexa72.dir/output.c.o   -c /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/plugins/avf/output.c
In file included from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/vector_funcs.h:41,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/vector.h:196,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/string.h:48,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/mem.h:49,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/vec.h:42,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/format.h:44,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/elf.h:41,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/elf_clib.h:41,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vlib/vlib.h:44,
                 from /home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/plugins/avf/output.c:18:
/home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/plugins/avf/output.c: In function ‘avf_device_class_tx_fn_cortexa72’:
/home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/vppinfra/byte_order.h:59:10: error: ‘*((void *)&psh+32)’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   59 |   return __builtin_bswap16 (x);
      |          ^~~~~~~~~~~~~~~~~~~~~
/home/snowball/tasks/test_vpp_build/test-patch-9/vpp/src/plugins/avf/output.c:115:23: note: ‘*((void *)&psh+32)’ was declared here
  115 |    struct avf_ip6_psh psh = { 0 };
      |                       ^~~

Type: fix

Change-Id: I2684b101b07823dfacc4a56cc29d152828d0cf37
Signed-off-by: Jieqiang Wang <jieqiang.wang@arm.com>
(cherry picked from commit 3daf1f5d3a)
2021-07-09 22:24:16 +00:00
zhangyoufeng d004ecdb57 nat : variable 'ctx' MAY not initialized before use
Type: fix

Change-Id: Ib22cc8a358d17782a01b7ebeded02d186898bc3a
Signed-off-by: zyf <807896415@qq.com>
2021-06-16 07:41:02 +00:00
Juraj Linkeš b12b3c6b03 dpdk: disable i40evf in favor of iavf patch
Fix an issue where multiple VPP instances with DPDK starting at the
same time would not initialize VFs properly. This is done by using the
iavf PMD (where the issue can't be reproduced) instead of the i40evf
PMD.

Type: fix
Ticket: VPP-1943
Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
Change-Id: I023138896610dc2b3bb731759f62afc605e9bb09
2021-06-03 19:12:52 +00:00
Mohammed Hawari 6bd1c77fdc rdma: fix buggy cqe parsing (truncated packets)
Change-Id: I17228bd35cc7aa0d207a16502bf1376c75675302
Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
Type: fix
(cherry picked from commit 933b0ca073)
2021-04-19 15:10:44 +00:00
Mohammed Hawari dd3d991606 rdma: fix pkg_config file
When building DPDK with rdma linkage, this patch avoids linking against
useless verb providers. It also hard-codes the library directory to lib
to fix CentOS behavior.

Change-Id: I3acd94adf1b7e59e023346b3c254bd4bba6157df
Type: fix
Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
(cherry picked from commit df849f8ea8)
2021-04-01 10:11:07 +00:00
Ray Kinsella ded6dbdb29 dpdk: enable AVX-512 on ICL
Enable DPDK AVX-512 Vector PMDs on Intel Icelake

Type: improvement

Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Change-Id: Ie5d5bf54ccaa65c1d053d56a2f2973fe8625193b
(cherry picked from commit 1cebf98e1c)
2021-03-04 14:19:47 +00:00
Július Milan 2e591554b8 fib: fix sa selection for fib routed destinations
The move from ip4(6)_src_address_for_packet to fib_sas4(6)_get changed
the behavior, so that the new looked only to adjacent gleans. This
caused a problem for destinations routed according to FIB table.

To reproduce:
vpp# create tap
vpp# set interface state tap0 up
vpp# set interface ip address tap0 192.168.11.1/24
vpp# ip route add 192.168.20.0/24 via 192.168.11.2

linux$ sudo ip addr add 192.168.20.1/24 dev lo
linux$ sudo ip link set tap0 up
linux$ sudo ip addr add 192.168.11.2/24 dev tap0

vpp# ping 192.168.20.1
Failed: no source address for egress interface

Type: fix
Signed-off-by: Július Milan <julius.milan@pantheon.tech>
Signed-off-by: Neale Ranns <neale@graphiant.com>
Change-Id: I22899f4dbbf8c1c85ccce72f801b92c183195b5d
(cherry picked from commit 98874cda58)
2021-02-24 18:35:52 +00:00
Steven Luong fa065f96d1 l2: crash on l2_input_is_xconnect
Running vpp without any interface configured and then invoking the
binary-api l2_xconnect_dump causes vpp to crash in l2_input_is_xconnect due
to l2input_main.configs has no memory allocated to it, not even for the local
interface which exists all the times.

The reason that l2input_main.configs has no memory allocated to it was due to
gerrit patch 29232 which took out a line in l2input_init

  /* Create the config vector */
  vec_validate (mp->configs, 100);

The fix is to iterate through l2input_main.configs for each interface in
l2 to call l2_input_is_xconnect when dumping l2_xconnect interfaces.

Type: fix
Fixes: gerrit 29232

Signed-off-by: Steven Luong <sluong@cisco.com>
Change-Id: I8d9cba4b7eba4c2e0c60887c4fd57d5ec3b06d3b
(cherry picked from commit 16f0865775)
2021-02-09 22:43:43 +00:00
Andrew Yourtchenko 3d2d96e554 misc: 21.01 Release Notes
Change-Id: I8fa48e631b9405f2882ea975927c42dbbd32cf1f
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
Type: docs
2021-01-27 15:15:48 +00:00
Andrew Yourtchenko de569048a5 docs: fix up the markdown
Type: docs
Change-Id: Ia541839e1f1ceddfae4579dece43b9cc820702e2
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
2021-01-27 14:05:39 +00:00
Radu Nicolau 5f48784da3 vlib: startup multi-arch variant configuration fix for interfaces
Propagate the multi-arch variant selection to interfaces.

Type: fix

Signed-off-by: Radu Nicolau <radu.nicolau@intel.com>
Change-Id: I99c4a7896f172f0d14d2ded22a27383825529a7d
(cherry picked from commit 5a48b3b9d8)
2021-01-25 10:07:10 +00:00
Dave Barach 9479838d08 docs: vpp stateless traffic generator
Add a use-case writeup.

Type: docs

Signed-off-by: Dave Barach <dave@barachs.net>
Change-Id: Ib6e79e80455edbdeedcc96943dd98f16c57c559e
(cherry picked from commit b8f6122b4f)
2021-01-22 14:03:19 +00:00
Andrew Yourtchenko ddb39ff0fd build: fix the version in 'show version' for RPM
The RPM build ends up with "vXX.YY" to vstring,
which is not what we'd expect - so fix it up.

Change-Id: I0af68e69b1e40fc49ade759bb2f0ed9f47614217
Type: fix
Signed-off-by: Andrew Yourtchenko <ayourtch@gmail.com>
(cherry picked from commit 072def4738)
2021-01-21 17:01:57 +00:00
Mohammed Hawari 0b374922d2 avf: fix l2_len for csum offload
Use vlib_buffer_t::current_data instead of
vnet_buffer_opaque_t::l2_hdr_offset to compute l2_len for checksum
offload (l2_hdr_offset might be invalid if packet originates from an L3
interface)

Change-Id: I2031ea6fd6a7af4b6e186751e119ebd6161641b5
Type: fix
Signed-off-by: Mohammed Hawari <mohammed@hawari.fr>
(cherry picked from commit 533ac64330)
2021-01-19 17:09:26 +01:00
Dave Wallace 66b80310fb build: add missing openssl-devel package for centos-8 vpp-ext-deps
- In a new centos-8 installation, vpp-ext-deps fails on missing
  ssl.h header file after 'make install-deps'.

Type: fix

Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
Change-Id: I521d817dd1f1e21aff427d98b9832ea7c7b89339
2021-01-14 21:50:20 +00:00
25 changed files with 1228 additions and 59 deletions
+1 -1
View File
@@ -122,7 +122,7 @@ ifeq ($(OS_ID),fedora)
RPM_DEPENDS_GROUPS = 'C Development Tools and Libraries'
else ifeq ($(OS_ID)-$(OS_VERSION_ID),centos-8)
RPM_DEPENDS += yum-utils
RPM_DEPENDS += compat-openssl10
RPM_DEPENDS += compat-openssl10 openssl-devel
RPM_DEPENDS += python2-devel python36-devel python3-ply
RPM_DEPENDS += python3-virtualenv python3-jsonschema
RPM_DEPENDS += cmake
+672 -1
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -39,6 +39,7 @@ define rdma-core_config_cmds
$(CMAKE) -G Ninja $(rdma-core_src_dir) \
-DENABLE_STATIC=1 -DENABLE_RESOLVE_NEIGH=0 -DNO_PYVERBS=1 -DENABLE_VALGRIND=0\
-DCMAKE_BUILD_TYPE=$(RDMA_BUILD_TYPE) -DCMAKE_INSTALL_PREFIX=$(rdma-core_install_dir) \
-DCMAKE_INSTALL_LIBDIR=lib \
-DCMAKE_C_FLAGS='-fPIC -fvisibility=hidden' > $(rdma-core_config_log)
endef
@@ -52,6 +53,8 @@ define rdma-core_install_cmds
find $(rdma-core_install_dir) -name '*.a' -exec mv -v {} $(rdma-core_install_dir)/lib \; >> $(rdma-core_install_log)
rmdir -v $(rdma-core_install_dir)/util $(rdma-core_install_dir)/lib/statics >> $(rdma-core_install_log)
sed '/Libs.private:/ s/$$/ -lrdma_util -lccan/' -i $(rdma-core_install_dir)/lib/pkgconfig/libibverbs.pc
sed '/Libs.private:/ s/ \S*\(rdmav25\)\S*//g' -i $(rdma-core_install_dir)/lib/pkgconfig/libibverbs.pc
sed '/Libs.private:/ s/-lefa//g' -i $(rdma-core_install_dir)/lib/pkgconfig/libibverbs.pc
endef
$(eval $(call package,rdma-core))
@@ -0,0 +1,232 @@
From 7b44e3f10ac886eaece0ee3ed217ba7219ec41c1 Mon Sep 17 00:00:00 2001
From: Robin Zhang <robinx.zhang@intel.com>
Date: Mon, 19 Apr 2021 03:05:39 +0000
Subject: [PATCH] net/iavf: deprecate i40evf pmd
The i40evf PMD will be deprecated, iavf will be the only VF driver for
Intel 700 serial (i40e) NIC family. To reach this, there will be 2 steps:
Step 1: iavf will be the default VF driver, while i40evf still can be
selected by devarg: "driver=i40evf".
This is covered by this patch, which include:
1) add all 700 serial NIC VF device ID into iavf PMD
2) skip probe if devargs contain "driver=i40evf" in iavf
3) continue probe if devargs contain "driver=i40evf" in i40evf
Step 2: i40evf and related devarg are removed, this will happen at DPDK
21.11
Between step 1 and step 2, no new feature will be added into i40evf except
bug fix.
Signed-off-by: Robin Zhang <robinx.zhang@intel.com>
Acked-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
Acked-by: Beilei Xing <beilei.xing@intel.com>
---
doc/guides/nics/intel_vf.rst | 6 +++
doc/guides/rel_notes/deprecation.rst | 8 ++++
drivers/common/iavf/iavf_devids.h | 2 +
drivers/net/i40e/i40e_ethdev_vf.c | 45 ++++++++++++++++++++++
drivers/net/iavf/iavf_ethdev.c | 57 +++++++++++++++++++++++++++-
5 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/doc/guides/nics/intel_vf.rst b/doc/guides/nics/intel_vf.rst
index 529ff4a955..fcea8151bf 100644
--- a/doc/guides/nics/intel_vf.rst
+++ b/doc/guides/nics/intel_vf.rst
@@ -88,6 +88,12 @@ For more detail on SR-IOV, please refer to the following documents:
assignment in hypervisor. Take qemu for example, the device assignment should carry the IAVF device id (0x1889) like
``-device vfio-pci,x-pci-device-id=0x1889,host=03:0a.0``.
+ Starting from DPDK 21.05, the default VF driver for Intel® 700 Series Ethernet Controller will be IAVF. No new feature
+ will be added into i40evf except bug fix until it's removed in DPDK 21.11. Between DPDK 21.05 and 21.11, by using the
+ ``devargs`` option ``driver=i40evf``, i40evf PMD still can be used on Intel® 700 Series Ethernet Controller, for example::
+
+ -a 81:02.0,driver=i40evf
+
When IAVF is backed by an Intel® E810 device, the "Protocol Extraction" feature which is supported by ice PMD is also
available for IAVF PMD. The same devargs with the same parameters can be applied to IAVF PMD, for detail please reference
the section ``Protocol extraction for per queue`` of ice.rst.
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 82c1a90a37..ea41be51a7 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -125,3 +125,11 @@ Deprecation Notices
* cmdline: ``cmdline`` structure will be made opaque to hide platform-specific
content. On Linux and FreeBSD, supported prior to DPDK 20.11,
original structure will be kept until DPDK 21.11.
+
+* i40e: As there are both i40evf and iavf pmd, the functions of them are
+ duplicated. And now more and more advanced features are developed on iavf.
+ To keep consistent with kernel driver's name
+ (https://patchwork.ozlabs.org/patch/970154/), i40evf is no need to maintain.
+ Starting from 21.05, the default VF driver of i40e will be iavf, but i40evf
+ can still be used if users specify the devarg "driver=i40evf". I40evf will
+ be deleted in DPDK 21.11.
diff --git a/drivers/common/iavf/iavf_devids.h b/drivers/common/iavf/iavf_devids.h
index 722c2e4f49..0f98375a09 100644
--- a/drivers/common/iavf/iavf_devids.h
+++ b/drivers/common/iavf/iavf_devids.h
@@ -13,5 +13,7 @@
#define IAVF_DEV_ID_VF_HV 0x1571
#define IAVF_DEV_ID_ADAPTIVE_VF 0x1889
#define IAVF_DEV_ID_X722_VF 0x37CD
+#define IAVF_DEV_ID_X722_A0_VF 0x374D
+
#endif /* _IAVF_DEVIDS_H_ */
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 2909b4d894..b5706a6a7f 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1656,9 +1656,53 @@ i40evf_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
+static int
+i40evf_check_driver_handler(__rte_unused const char *key,
+ const char *value, __rte_unused void *opaque)
+{
+ if (strcmp(value, "i40evf"))
+ return -1;
+
+ return 0;
+}
+
+static int
+i40evf_driver_selected(struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvlist;
+ const char *key = "driver";
+ int ret = 0;
+
+ if (devargs == NULL)
+ return 0;
+
+ kvlist = rte_kvargs_parse(devargs->args, NULL);
+ if (kvlist == NULL)
+ return 0;
+
+ if (!rte_kvargs_count(kvlist, key))
+ goto exit;
+
+ /* i40evf driver selected when there's a key-value pair:
+ * driver=i40evf
+ */
+ if (rte_kvargs_process(kvlist, key,
+ i40evf_check_driver_handler, NULL) < 0)
+ goto exit;
+
+ ret = 1;
+
+exit:
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
static int eth_i40evf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
{
+ if (!i40evf_driver_selected(pci_dev->device.devargs))
+ return 1;
+
return rte_eth_dev_pci_generic_probe(pci_dev,
sizeof(struct i40e_adapter), i40evf_dev_init);
}
@@ -1681,6 +1725,7 @@ static struct rte_pci_driver rte_i40evf_pmd = {
RTE_PMD_REGISTER_PCI(net_i40e_vf, rte_i40evf_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_i40e_vf, pci_id_i40evf_map);
RTE_PMD_REGISTER_KMOD_DEP(net_i40e_vf, "* igb_uio | vfio-pci");
+RTE_PMD_REGISTER_PARAM_STRING(net_i40e_vf, "driver=i40evf");
static int
i40evf_dev_configure(struct rte_eth_dev *dev)
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 4d37722022..721cdcc14e 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -127,6 +127,10 @@ static int iavf_set_mc_addr_list(struct rte_eth_dev *dev,
static const struct rte_pci_id pci_id_iavf_map[] = {
{ RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_ADAPTIVE_VF) },
+ { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_VF) },
+ { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_VF_HV) },
+ { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_X722_VF) },
+ { RTE_PCI_DEVICE(IAVF_INTEL_VENDOR_ID, IAVF_DEV_ID_X722_A0_VF) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -2331,10 +2335,59 @@ iavf_dcf_cap_selected(struct rte_devargs *devargs)
return ret;
}
+static int
+iavf_drv_i40evf_check_handler(__rte_unused const char *key,
+ const char *value, __rte_unused void *opaque)
+{
+ if (strcmp(value, "i40evf"))
+ return -1;
+
+ return 0;
+}
+
+static int
+iavf_drv_i40evf_selected(struct rte_devargs *devargs, uint16_t device_id)
+{
+ struct rte_kvargs *kvlist;
+ const char *key = "driver";
+ int ret = 0;
+
+ if (device_id != IAVF_DEV_ID_VF &&
+ device_id != IAVF_DEV_ID_VF_HV &&
+ device_id != IAVF_DEV_ID_X722_VF &&
+ device_id != IAVF_DEV_ID_X722_A0_VF)
+ return 0;
+
+ if (devargs == NULL)
+ return 0;
+
+ kvlist = rte_kvargs_parse(devargs->args, NULL);
+ if (kvlist == NULL)
+ return 0;
+
+ if (!rte_kvargs_count(kvlist, key))
+ goto exit;
+
+ /* i40evf driver selected when there's a key-value pair:
+ * driver=i40evf
+ */
+ if (rte_kvargs_process(kvlist, key,
+ iavf_drv_i40evf_check_handler, NULL) < 0)
+ goto exit;
+
+ ret = 1;
+
+exit:
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
static int eth_iavf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
struct rte_pci_device *pci_dev)
{
- if (iavf_dcf_cap_selected(pci_dev->device.devargs))
+ if (iavf_dcf_cap_selected(pci_dev->device.devargs) ||
+ iavf_drv_i40evf_selected(pci_dev->device.devargs,
+ pci_dev->id.device_id))
return 1;
return rte_eth_dev_pci_generic_probe(pci_dev,
@@ -2357,7 +2410,7 @@ static struct rte_pci_driver rte_iavf_pmd = {
RTE_PMD_REGISTER_PCI(net_iavf, rte_iavf_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_iavf, pci_id_iavf_map);
RTE_PMD_REGISTER_KMOD_DEP(net_iavf, "* igb_uio | vfio-pci");
-RTE_PMD_REGISTER_PARAM_STRING(net_iavf, "cap=dcf");
+RTE_PMD_REGISTER_PARAM_STRING(net_iavf, "cap=dcf driver=i40evf");
RTE_LOG_REGISTER(iavf_logtype_init, pmd.net.iavf.init, NOTICE);
RTE_LOG_REGISTER(iavf_logtype_driver, pmd.net.iavf.driver, NOTICE);
#ifdef RTE_LIBRTE_IAVF_DEBUG_RX
--
2.20.1
+1
View File
@@ -20,3 +20,4 @@ extensive list, but should give a sampling of the many features contained in FD.
networksim
webapp
container_test
trafficgen
+105
View File
@@ -0,0 +1,105 @@
Vpp Stateless Traffic Generation
================================
It's simple to configure vpp as a high-performance stateless traffic
generator. A couple of vpp worker threads running on an older system
can easily generate 20 MPPS' worth of traffic.
In the configurations shown below, we connect a vpp traffic generator
and a vpp UUT using two 40 gigabit ethernet ports on each system:
```
+-------------------+ +-------------------+
| traffic generator | | UUT |
| port 0 | <=======> | port 0 |
| 192.168.40.2/24 | | 192.168.40.1/24 |
+-------------------+ +-------------------+
+-------------------+ +-------------------+
| traffic generator | | UUT |
| port 1 | <=======> | port 1 |
| 192.168.41.2/24 | | 192.168.41.1/24 |
+-------------------+ +-------------------+
```
Traffic Generator Setup Script
------------------------------
```
set int ip address FortyGigabitEthernet2/0/0 192.168.40.2/24
set int ip address FortyGigabitEthernet2/0/1 192.168.41.2/24
set int state FortyGigabitEthernet2/0/0 up
set int state FortyGigabitEthernet2/0/1 up
comment { send traffic to the VPP UUT }
packet-generator new {
name worker0
worker 0
limit 0
rate 1.2e7
size 128-128
tx-interface FortyGigabitEthernet2/0/0
node FortyGigabitEthernet2/0/0-output
data { IP4: 1.2.40 -> 3cfd.fed0.b6c8
UDP: 192.168.40.10 -> 192.168.50.10
UDP: 1234 -> 2345
incrementing 114
}
}
packet-generator new {
name worker1
worker 1
limit 0
rate 1.2e7
size 128-128
tx-interface FortyGigabitEthernet2/0/1
node FortyGigabitEthernet2/0/1-output
data { IP4: 1.2.4 -> 3cfd.fed0.b6c9
UDP: 192.168.41.10 -> 192.168.51.10
UDP: 1234 -> 2345
incrementing 114
}
}
comment { delete return traffic on sight }
ip route add 192.168.50.0/24 via drop
ip route add 192.168.51.0/24 via drop
```
Note 1: the destination MAC addresses shown in the configuration (e.g.
3cfd.fed0.b6c8 and 3cfd.fed0.b6c9) **must** match the vpp UUT port MAC
addresses.
Note 2: this script assumes that /etc/vpp/startup.conf and/or the
command-line in use specifies (at least) two worker threads. Uncomment
"workers 2" in the cpu configuration section of /etc/vpp/startup.conf:
```
## Specify a number of workers to be created
## Workers are pinned to N consecutive CPU cores while skipping "skip-cores" CPU core(s)
## and main thread's CPU core
workers 2
```
Any plausible packet generator script - including one which replays
pcap captures - can be used.
UUT Setup Script
----------------
The vpp UUT uses a couple of static routes to forward traffic back to
the traffic generator:
```
set int ip address FortyGigabitEthernet2/0/0 192.168.40.1/24
set int ip address FortyGigabitEthernet2/0/1 192.168.41.1/24
set int state FortyGigabitEthernet2/0/0 up
set int state FortyGigabitEthernet2/0/1 up
ip route add 192.168.50.10/32 via 192.168.41.2
ip route add 192.168.51.10/32 via 192.168.40.2
```
+1
View File
@@ -19,4 +19,5 @@ Programming notes for developers.
- @subpage handoff_queue_demo_plugin
- @subpage lcov_code_coverage
- @subpage mdata_doc
- @subpage mempreload_doc
+2
View File
@@ -29,3 +29,5 @@ Several modules provide operational, dataplane-user focused documentation.
- @subpage srv6_doc
- @subpage vcl_ldpreload_doc
- @subpage vmxnet3_doc
- @subpage af_xdp_doc
- @subpage wireguard_plugin_doc
+7 -8
View File
@@ -47,8 +47,8 @@ struct avf_ip4_psh
struct avf_ip6_psh
{
u32 src[4];
u32 dst[4];
ip6_address_t src;
ip6_address_t dst;
u32 l4len;
u32 proto;
};
@@ -67,7 +67,7 @@ avf_tx_prepare_cksum (vlib_buffer_t * b, u8 is_tso)
u32 is_ip6 = b->flags & VNET_BUFFER_F_IS_IP6;
ASSERT (!is_tcp || !is_udp);
ASSERT (is_ip4 || is_ip6);
i16 l2_hdr_offset = vnet_buffer (b)->l2_hdr_offset;
i16 l2_hdr_offset = b->current_data;
i16 l3_hdr_offset = vnet_buffer (b)->l3_hdr_offset;
i16 l4_hdr_offset = vnet_buffer (b)->l4_hdr_offset;
u16 l2_len = l3_hdr_offset - l2_hdr_offset;
@@ -113,8 +113,8 @@ avf_tx_prepare_cksum (vlib_buffer_t * b, u8 is_tso)
else
{
struct avf_ip6_psh psh = { 0 };
clib_memcpy_fast (&psh.src, &ip6->src_address, 16);
clib_memcpy_fast (&psh.dst, &ip6->dst_address, 16);
psh.src = ip6->src_address;
psh.dst = ip6->dst_address;
psh.proto = clib_host_to_net_u32 ((u32) ip6->protocol);
psh.l4len = is_tso ? 0 : ip6->payload_length;
sum = ~ip_csum (&psh, sizeof (psh));
@@ -156,9 +156,8 @@ avf_tx_fill_ctx_desc (vlib_main_t * vm, avf_txq_t * txq, avf_tx_desc_t * d,
/* Acquire a reference on the placeholder buffer */
ctx_ph->ref_count++;
u16 l234hdr_sz =
vnet_buffer (b)->l4_hdr_offset -
vnet_buffer (b)->l2_hdr_offset + vnet_buffer2 (b)->gso_l4_hdr_sz;
u16 l234hdr_sz = vnet_buffer (b)->l4_hdr_offset - b->current_data +
vnet_buffer2 (b)->gso_l4_hdr_sz;
u16 tlen = vlib_buffer_length_in_chain (vm, b) - l234hdr_sz;
d[0].qword[0] = 0;
d[0].qword[1] = AVF_TXD_DTYP_CTX | AVF_TXD_CTX_CMD_TSO
+5
View File
@@ -29,6 +29,7 @@
#include <vlib/vmbus/vmbus.h>
#include <rte_ring.h>
#include <rte_vect.h>
#include <stdio.h>
#include <stdlib.h>
@@ -1527,6 +1528,10 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
ret = rte_eal_init (vec_len (conf->eal_init_args),
(char **) conf->eal_init_args);
/* enable the AVX-512 vPMDs in DPDK */
if (clib_cpu_supports_avx512_bitalg ())
rte_vect_set_max_simd_bitwidth (RTE_VECT_SIMD_512);
/* lazy umount hugepages */
umount2 ((char *) huge_dir_path, MNT_DETACH);
rmdir ((char *) huge_dir_path);
+4 -2
View File
@@ -366,6 +366,10 @@ slow_path_ed (snat_main_t * sm,
ip4_address_t sm_addr;
u16 sm_port;
u32 sm_fib_index;
ctx.now = now;
ctx.thread_index = thread_index;
/* First try to match static mapping by local address and port */
if (snat_static_mapping_match
(sm, l_addr, l_port, rx_fib_index, nat_proto, &sm_addr, &sm_port,
@@ -458,8 +462,6 @@ slow_path_ed (snat_main_t * sm,
clib_bihash_kv_16_8_t in2out_ed_kv;
init_ed_kv (&in2out_ed_kv, l_addr, l_port, r_addr, r_port, rx_fib_index,
proto, thread_index, s - tsm->sessions);
ctx.now = now;
ctx.thread_index = thread_index;
if (clib_bihash_add_or_overwrite_stale_16_8 (&tsm->in2out_ed, &in2out_ed_kv,
nat44_i2o_ed_is_idle_session_cb,
&ctx))
+1 -1
View File
@@ -974,7 +974,7 @@ rdma_device_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
n_rx_packets, bc);
n_rx_bytes =
rdma_device_mlx5dv_fast_input (vm, rxq, bufs, mask, &bt, to_next,
n_rx_packets, bc, ~1);
n_rx_packets, bc, ~0);
/* If there are chained buffers, some of the head buffers have a current length
higher than buf_sz: it needs to be fixed */
+1 -1
View File
@@ -1,4 +1,4 @@
# Wireguard vpp-plugin
# Wireguard vpp-plugin {#wireguard_plugin_doc}
## Overview
This plugin is an implementation of [wireguard protocol](https://www.wireguard.com/) for VPP. It allows one to create secure VPN tunnels.
+5
View File
@@ -30,6 +30,11 @@ TAG=$(echo ${vstring} | cut -d- -f1 | sed -e 's/^v//')
ADD=$(echo ${vstring} | cut -s -d- -f2)
POINT=$(echo ${TAG} | cut -d. -f3)
# during make pkg-rpm vstring ends up being vXX.YY, which is not what we expect. Fix it up.
if [ -z "${ADD}" ]; then
ADD="0"
fi
# if this is a "implicit zeroth" release (e.g. 19.08), check if we need to add ".0"
# to fix the artifact versioning sorting
if [ -z "${POINT}" ]; then
+18 -4
View File
@@ -40,6 +40,7 @@
#include <sys/types.h>
#include <fcntl.h>
#include <vlib/vlib.h>
#include <vnet/vnet.h>
typedef struct _vlib_node_march_variant
{
@@ -89,9 +90,9 @@ unformat_vlib_node_variant (unformat_input_t * input, va_list * args)
}
static_always_inline void
vlib_update_nr_variant_default (vlib_node_registration_t * nr, u8 * variant)
vlib_update_nr_variant_default (vlib_node_fn_registration_t * fnr,
u8 * variant)
{
vlib_node_fn_registration_t *fnr = nr->node_fn_registrations;
vlib_node_fn_registration_t *p_reg = 0;
vlib_node_fn_registration_t *v_reg = 0;
u32 tmp;
@@ -127,6 +128,8 @@ vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
{
clib_error_t *error = 0;
vlib_node_registration_t *nr, **all;
vnet_device_class_t *c;
vnet_main_t *vnm = vnet_get_main ();
unformat_input_t sub_input;
uword *hash = 0, *p;
u8 *variant = 0;
@@ -161,10 +164,20 @@ vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
nr = vm->node_main.node_registrations;
while (nr)
{
vlib_update_nr_variant_default (nr, variant);
vlib_update_nr_variant_default (nr->node_fn_registrations,
variant);
nr = nr->next_registration;
}
/* also apply it to interfaces */
c = vnm->device_class_registrations;
while (c)
{
vlib_update_nr_variant_default (c->tx_fn_registrations,
variant);
c = c->next_class_registration;
}
vec_free (variant);
}
}
@@ -192,7 +205,8 @@ vlib_early_node_config (vlib_main_t * vm, unformat_input_t * input)
"please specify a valid node variant");
vec_add1 (variant, 0);
vlib_update_nr_variant_default (nr, variant);
vlib_update_nr_variant_default (nr->node_fn_registrations,
variant);
vec_free (variant);
}
+14 -4
View File
@@ -258,8 +258,8 @@ adj_glean_get_src (fib_protocol_t proto,
u32 sw_if_index,
const ip46_address_t *nh)
{
const ip46_address_t *conn, *source;
const ip_adjacency_t *adj;
ip46_address_t *conn;
adj_index_t ai;
if (vec_len(adj_gleans[proto]) <= sw_if_index ||
@@ -274,23 +274,33 @@ adj_glean_get_src (fib_protocol_t proto,
if (nh)
pfx.fp_addr = *nh;
/*
* An interface can have more than one glean address. Where
* possible we want to return a source address from the same
* subnet as the destination. If this is not possible then any address
* will do.
*/
source = NULL;
hash_foreach_mem(conn, ai, adj_gleans[proto][sw_if_index],
({
adj = adj_get(ai);
if (adj->sub_type.glean.rx_pfx.fp_len > 0)
{
source = &adj->sub_type.glean.rx_pfx.fp_addr;
/* if no destination is specified use the just glean */
if (NULL == nh)
return (&adj->sub_type.glean.rx_pfx.fp_addr);
return (source);
/* check the clean covers the desintation */
if (fib_prefix_is_cover(&adj->sub_type.glean.rx_pfx, &pfx))
return (&adj->sub_type.glean.rx_pfx.fp_addr);
return (source);
}
}));
return (NULL);
return (source);
}
void
+2 -2
View File
@@ -306,7 +306,7 @@ typedef struct
i16 integ_start_offset;
u32 crypto_total_length;
/* adj total_length for integ, e.g.4 bytes for IPSec ESN */
u16 integ_length_adj;
i16 integ_length_adj;
u8 *iv;
union
{
@@ -605,7 +605,7 @@ vnet_crypto_async_add_to_frame (vlib_main_t * vm,
u32 key_index,
u32 crypto_len, i16 integ_len_adj,
i16 crypto_start_offset,
u16 integ_start_offset,
i16 integ_start_offset,
u32 buffer_index,
u16 next_node,
u8 * iv, u8 * tag, u8 * aad, u8 flags)
+1 -1
View File
@@ -807,7 +807,7 @@ vnet_register_interface (vnet_main_t * vnm,
vnet_config_main_t *cm;
u32 hw_index, i;
char *tx_node_name = NULL, *output_node_name = NULL;
vlib_node_function_t *output_node = vnet_interface_output_node_get ();
vlib_node_function_t *output_node = vnet_interface_output_node_get (vm);
pool_get (im->hw_interfaces, hw);
clib_memset (hw, 0, sizeof (*hw));
+2 -1
View File
@@ -326,6 +326,7 @@ CLIB_MARCH_SFX (devclass##_tx_fn_multiarch_register) (void) \
vlib_node_fn_registration_t *r; \
r = &CLIB_MARCH_SFX (devclass##_tx_fn_registration); \
r->priority = CLIB_MARCH_FN_PRIORITY(); \
r->name = CLIB_MARCH_VARIANT_STR; \
r->next_registration = devclass.tx_fn_registrations; \
devclass.tx_fn_registrations = r; \
} \
@@ -918,7 +919,7 @@ void vnet_pcap_drop_trace_filter_add_del (u32 error_index, int is_add);
int vnet_interface_name_renumber (u32 sw_if_index, u32 new_show_dev_instance);
vlib_node_function_t *vnet_interface_output_node_get (void);
vlib_node_function_t *vnet_interface_output_node_get (vlib_main_t * vm);
void vnet_register_format_buffer_opaque_helper
(vnet_buffer_opquae_formatter_t fn);
+28 -2
View File
@@ -513,9 +513,35 @@ CLIB_MARCH_FN_REGISTRATION (vnet_interface_output_node);
#ifndef CLIB_MARCH_VARIANT
vlib_node_function_t *
vnet_interface_output_node_get (void)
vnet_interface_output_node_get (vlib_main_t * vm)
{
return CLIB_MARCH_FN_POINTER (vnet_interface_output_node);
vlib_node_function_t *fn = 0;
vlib_node_fn_registration_t *fnr;
char *name = 0;
vlib_node_t *node = vlib_get_node_by_name (vm, (u8 *) "interface-output");
ASSERT (node);
/* search for the same name */
fnr = node->node_fn_registrations;
while (fnr)
{
if (fnr->function == node->function)
{
name = fnr->name;
break;
}
fnr = fnr->next_registration;
}
if (name)
{
fn = CLIB_MARCH_FN_POINTER_BY_NAME (vnet_interface_output_node, name);
}
if (!fn) /* revert to march type selection if search failed */
{
fn = CLIB_MARCH_FN_POINTER (vnet_interface_output_node);
}
return fn;
}
#endif /* CLIB_MARCH_VARIANT */
+69 -19
View File
@@ -233,6 +233,24 @@ esp_get_ip6_hdr_len (ip6_header_t * ip6, ip6_ext_header_t ** ext_hdr)
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_chained_ops (vlib_main_t * vm, vlib_node_runtime_t * node,
vnet_crypto_op_t * ops, vlib_buffer_t * b[],
@@ -395,10 +413,16 @@ esp_prepare_sync_op (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
vnet_crypto_op_t *op;
vec_add2_aligned (crypto_ops[0], op, 1, CLIB_CACHE_LINE_BYTES);
vnet_crypto_op_init (op, sa0->crypto_enc_op_id);
u8 *crypto_start = payload;
/* esp_add_footer_and_icv() in esp_encrypt_inline() makes sure we always
* have enough space for ESP header and footer which includes ICV */
ASSERT (payload_len > icv_sz);
u16 crypto_len = payload_len - icv_sz;
/* generate the IV in front of the payload */
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;
op->user_data = b - bufs;
if (ipsec_sa_is_set_IS_AEAD (sa0))
@@ -410,18 +434,21 @@ esp_prepare_sync_op (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
op->aad = payload - hdr_len - sizeof (esp_aead_t);
op->aad_len = esp_aad_fill (op->aad, esp, sa0);
op->tag = payload + op->len;
op->tag = payload + crypto_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;
}
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 */
crypto_start -= iv_sz;
crypto_len += iv_sz;
}
if (lb != b[0])
@@ -430,8 +457,15 @@ esp_prepare_sync_op (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
op->flags |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
op->chunk_index = vec_len (ptd->chunks);
op->tag = vlib_buffer_get_tail (lb) - icv_sz;
esp_encrypt_chain_crypto (vm, ptd, sa0, b[0], lb, icv_sz, payload,
payload_len, &op->n_chunks);
esp_encrypt_chain_crypto (vm, ptd, sa0, b[0], lb, icv_sz,
crypto_start, crypto_len + icv_sz,
&op->n_chunks);
}
else
{
/* not chained */
op->src = op->dst = crypto_start;
op->len = crypto_len;
}
}
@@ -481,16 +515,19 @@ esp_prepare_async_frame (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
u8 *tag, *iv, *aad = 0;
u8 flag = 0;
u32 key_index;
i16 crypto_start_offset, integ_start_offset = 0;
i16 crypto_start_offset, integ_start_offset;
u16 crypto_total_len, integ_total_len;
post->next_index = next;
/* crypto */
crypto_start_offset = payload - b->data;
crypto_start_offset = integ_start_offset = payload - b->data;
crypto_total_len = integ_total_len = payload_len - icv_sz;
tag = payload + crypto_total_len;
/* generate the IV in front of the payload */
void *pkt_iv = esp_generate_iv (sa, payload, iv_sz);
/* aead */
if (ipsec_sa_is_set_IS_AEAD (sa))
{
@@ -501,7 +538,7 @@ esp_prepare_async_frame (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
esp_aad_fill (aad, esp, sa);
nonce = (esp_gcm_nonce_t *) (aad - sizeof (*nonce));
nonce->salt = sa->salt;
nonce->iv = *pkt_iv = clib_host_to_net_u64 (sa->gcm_iv_counter++);
nonce->iv = *(u64 *) pkt_iv;
iv = (u8 *) nonce;
key_index = sa->crypto_key_index;
@@ -511,25 +548,38 @@ esp_prepare_async_frame (vlib_main_t * vm, ipsec_per_thread_data_t * ptd,
flag |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
tag = vlib_buffer_get_tail (lb) - icv_sz;
crypto_total_len = esp_encrypt_chain_crypto (vm, ptd, sa, b, lb,
icv_sz, payload,
payload_len, 0);
icv_sz,
b->data +
crypto_start_offset,
crypto_total_len +
icv_sz, 0);
}
goto out;
}
else
{
/* construct zero iv in front of the IP header */
iv = pkt_iv - hdr_len - iv_sz;
clib_memset_u8 (iv, 0, iv_sz);
/* include iv field in crypto */
crypto_start_offset -= iv_sz;
crypto_total_len += iv_sz;
}
/* cipher then hash */
iv = payload - iv_sz;
integ_start_offset = crypto_start_offset - iv_sz - sizeof (esp_header_t);
integ_start_offset -= iv_sz + sizeof (esp_header_t);
integ_total_len += iv_sz + sizeof (esp_header_t);
flag |= VNET_CRYPTO_OP_FLAG_INIT_IV;
key_index = sa->linked_key_index;
if (b != lb)
{
flag |= VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS;
crypto_total_len = esp_encrypt_chain_crypto (vm, ptd, sa, b, lb,
icv_sz, payload,
payload_len, 0);
icv_sz,
b->data +
crypto_start_offset,
crypto_total_len + icv_sz,
0);
tag = vlib_buffer_get_tail (lb) - icv_sz;
integ_total_len = esp_encrypt_chain_integ (vm, ptd, sa, b, lb, icv_sz,
payload - iv_sz -
+1 -1
View File
@@ -152,7 +152,7 @@ typedef struct
CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
u64 gcm_iv_counter;
u64 iv_counter;
union
{
ip4_header_t ip4_hdr;
+8 -10
View File
@@ -98,10 +98,8 @@ static void
vl_api_l2_xconnect_dump_t_handler (vl_api_l2_xconnect_dump_t * mp)
{
vl_api_registration_t *reg;
vnet_main_t *vnm = vnet_get_main ();
vnet_interface_main_t *im = &vnm->interface_main;
l2input_main_t *l2im = &l2input_main;
vnet_sw_interface_t *swif;
u32 sw_if_index;
l2_input_config_t *config;
reg = vl_api_client_index_to_registration (mp->client_index);
@@ -109,13 +107,13 @@ vl_api_l2_xconnect_dump_t_handler (vl_api_l2_xconnect_dump_t * mp)
return;
/* *INDENT-OFF* */
pool_foreach (swif, im->sw_interfaces)
{
config = vec_elt_at_index (l2im->configs, swif->sw_if_index);
if (l2_input_is_xconnect(config))
send_l2_xconnect_details (reg, mp->context, swif->sw_if_index,
config->output_sw_if_index);
}
vec_foreach_index (sw_if_index, l2im->configs)
{
config = vec_elt_at_index (l2im->configs, sw_if_index);
if (l2_input_is_xconnect (config))
send_l2_xconnect_details (reg, mp->context, sw_if_index,
config->output_sw_if_index);
}
/* *INDENT-ON* */
}
+20
View File
@@ -84,9 +84,29 @@ clib_march_select_fn_ptr (clib_march_fn_registration * r)
return rv;
}
static_always_inline void *
clib_march_select_fn_ptr_by_name (clib_march_fn_registration * r, char *name)
{
void *rv = 0;
while (r)
{
if (strncmp (name, r->name, vec_len (r->name) - 1) == 0)
{
rv = r->function;
break;
}
r = r->next;
}
return rv;
}
#define CLIB_MARCH_FN_POINTER(fn) \
clib_march_select_fn_ptr (fn##_march_fn_registrations);
#define CLIB_MARCH_FN_POINTER_BY_NAME(fn, name) \
clib_march_select_fn_ptr_by_name (fn##_march_fn_registrations, name);
#define _CLIB_MARCH_FN_REGISTRATION(fn) \
static clib_march_fn_registration \
CLIB_MARCH_SFX(fn##_march_fn_registration) = \
+25 -1
View File
@@ -7,7 +7,7 @@ from scapy.packet import Raw
from framework import VppTestCase
from util import ppp
from vpp_ip_route import VppIpInterfaceAddress
from vpp_ip_route import VppIpInterfaceAddress, VppIpRoute, VppRoutePath
from vpp_neighbor import VppNeighbor
""" TestPing is a subclass of VPPTestCase classes.
@@ -150,3 +150,27 @@ class TestPing(VppTestCase):
for p in out:
icmp = self.verify_ping_request(p, "10.0.0.1", nbr_addr, icmp_seq)
icmp_seq = icmp_seq + 1
def test_ping_fib_routed_dst(self):
""" ping destination routed according to FIB table """
try:
self.pg1.generate_remote_hosts(1)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
routed_dst = "10.0.2.0"
self.logger.info(self.vapi.cli("show ip4 neighbors"))
VppIpRoute(self, routed_dst, 24,
[VppRoutePath(self.pg1.remote_hosts[0].ip4,
self.pg1.sw_if_index)]).add_vpp_config()
ping_cmd = "ping %s interval 0.01 repeat 3" % routed_dst
ret = self.vapi.cli(ping_cmd)
self.logger.info(ret)
out = self.pg1.get_capture(3)
icmp_seq = 1
for p in out:
self.verify_ping_request(p, self.pg1.local_ip4, routed_dst,
icmp_seq)
icmp_seq = icmp_seq + 1
finally:
self.vapi.cli("show error")