ethernet: check destination mac for L3 in ethernet-input node 56/40756/4 master
authorSteven Luong <sluong@cisco.com>
Fri, 19 Apr 2024 16:49:20 +0000 (09:49 -0700)
committerDamjan Marion <dmarion@0xa5.net>
Wed, 8 May 2024 09:42:23 +0000 (09:42 +0000)
When the NIC does not support mac filter, we rely on ethernet-input
node to do the destination mac check, ie, when the interface is in L3,
the mac address for the packet must be the mac address of the
interface where the packet arrives. This works fine in ethernet-input
node when all packets in the frame might have different interfaces, ie,
ETH_INPUT_FRAME_F_SINGLE_SW_IF_ID is not set in the frame. However,
when all packets are having the same interface,
ETH_INPUT_FRAME_F_SINGLE_SW_IF_ID is set, ethernet-input node goes
through the optimized routine eth_input_single_int -> eth_input_process_frame.
That is where dmac check has a bug when all packets in the frame are
either, ip4, ip6, or mpls without vlan tags. Because without vlan tags,
the code handles all packets in fast path and ignores dmac check.
With vlan tags, the code goes to slow path where dmac check is handled
properly.

The fix is to check if we have a bad dmac in the fast path and force the
code to go to slow path which will handle dmac check properly.

Also do a wholesale correction on all the testcases which do not use
the proper dmac when sending L3 packets.

Type: fix

Change-Id: I73153a805cecdc24c4eefcc781676de04737ae2c
Signed-off-by: Steven Luong <sluong@cisco.com>
78 files changed:
.gitignore
build/external/packages/dpdk.mk
extras/hs-test/Makefile
extras/hs-test/cpu.go
extras/hs-test/go.mod
extras/hs-test/go.sum
extras/hs-test/hst_suite.go
extras/hs-test/http_test.go
extras/hs-test/script/build_hst.sh
extras/hs-test/test
src/plugins/acl/acl_test.c
src/plugins/crypto_native/CMakeLists.txt
src/plugins/crypto_native/aes_cbc.c
src/plugins/crypto_native/aes_ctr.c
src/plugins/crypto_native/aes_gcm.c
src/plugins/crypto_native/crypto_native.h
src/plugins/crypto_native/main.c
src/plugins/crypto_native/sha2.c [new file with mode: 0644]
src/plugins/dev_iavf/port.c
src/plugins/dev_octeon/init.c
src/plugins/dev_octeon/octeon.h
src/plugins/dev_octeon/tx_node.c
src/plugins/dpdk/device/cli.c
src/plugins/dpdk/device/init.c
src/plugins/hs_apps/http_client_cli.c
src/plugins/http/http.c
src/plugins/http/http.h
src/plugins/ikev2/ikev2_api.c
src/plugins/ikev2/ikev2_test.c
src/plugins/nat/nat44-ed/nat44_ed_api.c
src/plugins/nat/nat44-ei/nat44_ei_api.c
src/plugins/nat/pnat/pnat_api.c
src/plugins/unittest/gso_test.c
src/plugins/unittest/policer_test.c
src/tools/vppapigen/vppapigen_c.py
src/vat2/vat2_helpers.h
src/vcl/vppcom.c
src/vlib/CMakeLists.txt
src/vlib/linux/pci.c
src/vlib/pci/pci.c
src/vlib/threads.c
src/vlib/threads.h
src/vlib/unix/plugin.c
src/vlibapi/api_common.h
src/vlibapi/api_helper_macros.h
src/vlibapi/api_shared.c
src/vlibmemory/memclnt_api.c
src/vlibmemory/memory_api.c
src/vlibmemory/vlib_api_cli.c
src/vnet/ethernet/node.c
src/vnet/gso/gso.h
src/vnet/gso/node.c
src/vnet/interface_api.c
src/vnet/pg/input.c
src/vppinfra/cJSON.c
src/vppinfra/cJSON.h
src/vppinfra/unix-misc.c
src/vppinfra/unix.h
test/scripts/core_pinning.sh [deleted file]
test/test_abf.py
test/test_flowprobe.py
test/test_gso.py
test/test_gtpu.py
test/test_ip6.py
test/test_ip6_nd_mirror_proxy.py
test/test_ipip.py
test/test_l3xc.py
test/test_linux_cp.py
test/test_map.py
test/test_map_br.py
test/test_mpls.py
test/test_nat44_ed_output.py
test/test_neighbor.py
test/test_pcap.py
test/test_reassembly.py
test/test_srv6_mobile.py
test/test_trace_filter.py
test/test_vxlan.py

index 3d2c2fc..5c707a8 100644 (file)
@@ -122,7 +122,7 @@ compile_commands.json
 /extras/hs-test/vpp-data
 /extras/hs-test/hs-test
 /extras/hs-test/http_server
-/extras/hs-test/.build.vpp
+/extras/hs-test/.build.ok
 
 # ./configure
 /CMakeFiles
index e0a3ef2..c03d1a1 100644 (file)
@@ -33,8 +33,11 @@ dpdk_tarball_md5sum_21.11    := 58660bbbe9e95abce86e47692b196555
 dpdk_tarball_md5sum          := $(dpdk_tarball_md5sum_$(dpdk_version))
 dpdk_url                     := $(dpdk_base_url)/$(dpdk_tarball)
 dpdk_tarball_strip_dirs      := 1
+ifeq ($(shell uname), FreeBSD)
+dpdk_depends                := $(if $(ARCH_X86_64), ipsec-mb)
+else
 dpdk_depends                := rdma-core $(if $(ARCH_X86_64), ipsec-mb)
-
+endif
 DPDK_MLX_DEFAULT             := $(shell if grep -q "rdma=$(rdma-core_version) dpdk=$(dpdk_version)" mlx_rdma_dpdk_matrix.txt; then echo 'y'; else echo 'n'; fi)
 DPDK_MLX4_PMD                ?= $(DPDK_MLX_DEFAULT)
 DPDK_MLX5_PMD                ?= $(DPDK_MLX_DEFAULT)
@@ -134,14 +137,19 @@ endif
 DPDK_DRIVERS_DISABLED := $(shell echo $(DPDK_DRIVERS_DISABLED) | tr -d '\\\t ')
 DPDK_LIBS_DISABLED := $(shell echo $(DPDK_LIBS_DISABLED) | tr -d '\\\t ')
 
+SED=sed
+ifeq ($shell(uname), FreeBSD)
+SED=gsed
+endif
+
 HASH := \#
 # post-meson-setup snippet to alter rte_build_config.h
 define dpdk_config
 if grep -q RTE_$(1) $(dpdk_src_dir)/config/rte_config.h ; then \
-sed -i -e 's/$(HASH)define RTE_$(1).*/$(HASH)define RTE_$(1) $(DPDK_$(1))/' \
+$(SED) -i -e 's/$(HASH)define RTE_$(1).*/$(HASH)define RTE_$(1) $(DPDK_$(1))/' \
        $(dpdk_src_dir)/config/rte_config.h; \
 elif grep -q RTE_$(1) $(dpdk_build_dir)/rte_build_config.h ; then \
-sed -i -e 's/$(HASH)define RTE_$(1).*/$(HASH)define RTE_$(1) $(DPDK_$(1))/' \
+$(SED) -i -e 's/$(HASH)define RTE_$(1).*/$(HASH)define RTE_$(1) $(DPDK_$(1))/' \
        $(dpdk_build_dir)/rte_build_config.h; \
 else \
 echo '$(HASH)define RTE_$(1) $(DPDK_$(1))' \
@@ -157,7 +165,7 @@ if [[ "$(DPDK_$(1))" == "y" ]]; then \
           >> $(dpdk_build_dir)/rte_build_config.h ; \
     fi; \
 elif [[ "$(DPDK_$(1))" == "n" ]]; then \
-    sed -i '/$(HASH)define RTE_$(1) .*/d' $(dpdk_build_dir)/rte_build_config.h \
+    $(SED) -i '/$(HASH)define RTE_$(1) .*/d' $(dpdk_build_dir)/rte_build_config.h \
       $(dpdk_src_dir)/config/rte_config.h ; \
 fi
 endef
index 196bca5..d4e6999 100644 (file)
@@ -78,30 +78,38 @@ help:
 list-tests:
        $(call list_tests)
 
+.PHONY: build-vpp-release
 build-vpp-release:
        @make -C ../.. build-release
 
+.PHONY: build-vpp-debug
 build-vpp-debug:
        @make -C ../.. build
 
+.build.ok: build
+       @touch .build.ok
+
 .PHONY: test
-test: .deps.ok .build.vpp
+test: .deps.ok .build.ok
        @bash ./test --persist=$(PERSIST) --verbose=$(VERBOSE) \
                --unconfigure=$(UNCONFIGURE) --debug=$(DEBUG) --test=$(TEST) --cpus=$(CPUS) \
                --vppsrc=$(VPPSRC) --parallel=$(PARALLEL) --repeat=$(REPEAT)
 
+.PHONY: build-go
 build-go:
        go build ./tools/http_server
 
+.PHONY: build
 build: .deps.ok build-vpp-release build-go
-       @rm -f .build.vpp
+       @rm -f .build.ok
        bash ./script/build_hst.sh release
-       @touch .build.vpp
+       @touch .build.ok
 
+.PHONY: build-debug
 build-debug: .deps.ok build-vpp-debug build-go
-       @rm -f .build.vpp
+       @rm -f .build.ok
        bash ./script/build_hst.sh debug
-       @touch .build.vpp
+       @touch .build.ok
 
 .deps.ok:
        @sudo make install-deps
@@ -111,14 +119,13 @@ install-deps:
        @rm -f .deps.ok
        @apt-get update \
                && apt-get install -y apt-transport-https ca-certificates curl software-properties-common \
-               && apt-get install -y golang apache2-utils wrk bridge-utils
+               apache2-utils wrk bridge-utils
        @if [ ! -f /usr/share/keyrings/docker-archive-keyring.gpg ] ; then \
                curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg; \
                echo "deb [arch=$(ARCH) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(UBUNTU_CODENAME) stable" \
                        | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ; \
                apt-get update; \
        fi
-       @apt-get install -y docker-ce
        @touch .deps.ok
 
 .PHONY: fixstyle
index 9a034ed..a976f47 100644 (file)
@@ -2,11 +2,14 @@ package main
 
 import (
        "bufio"
+       "errors"
        "fmt"
        "os"
+       "os/exec"
+       "strings"
 )
 
-var CPU_PATH = "/sys/fs/cgroup/cpuset.cpus.effective"
+var CgroupPath = "/sys/fs/cgroup/"
 
 type CpuContext struct {
        cpuAllocator *CpuAllocatorT
@@ -38,7 +41,25 @@ func (c *CpuAllocatorT) Allocate(nCpus int) (*CpuContext, error) {
 
 func (c *CpuAllocatorT) readCpus() error {
        var first, last int
-       file, err := os.Open(CPU_PATH)
+
+       // Path depends on cgroup version. We need to check which version is in use.
+       // For that following command can be used: 'stat -fc %T /sys/fs/cgroup/'
+       // In case the output states 'cgroup2fs' then cgroups v2 is used, 'tmpfs' in case cgroups v1.
+       cmd := exec.Command("stat", "-fc", "%T", "/sys/fs/cgroup/")
+       byteOutput, err := cmd.CombinedOutput()
+       if err != nil {
+               return err
+       }
+       CpuPath := CgroupPath
+       if strings.Contains(string(byteOutput), "tmpfs") {
+               CpuPath += "cpuset/cpuset.effective_cpus"
+       } else if strings.Contains(string(byteOutput), "cgroup2fs") {
+               CpuPath += "cpuset.cpus.effective"
+       } else {
+               return errors.New("cgroup unknown fs: " + string(byteOutput))
+       }
+
+       file, err := os.Open(CpuPath)
        if err != nil {
                return err
        }
index 50d83a4..0f3854d 100644 (file)
@@ -4,7 +4,7 @@ go 1.21
 
 require (
        github.com/edwarnicke/exechelper v1.0.3
-       go.fd.io/govpp v0.9.0
+       go.fd.io/govpp v0.10.0
        gopkg.in/yaml.v3 v3.0.1
 )
 
@@ -24,7 +24,7 @@ require (
        github.com/kr/text v0.2.0 // indirect
        github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect
        github.com/onsi/ginkgo/v2 v2.16.0
-       github.com/onsi/gomega v1.30.0
+       github.com/onsi/gomega v1.32.0
        github.com/pkg/errors v0.9.1 // indirect
        github.com/sirupsen/logrus v1.9.3 // indirect
        github.com/vishvananda/netns v0.0.4 // indirect
index 0070725..479b028 100644 (file)
@@ -13,8 +13,6 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
 github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
 github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/pprof v0.0.0-20211214055906-6f57359322fd h1:1FjCyPC+syAzJ5/2S8fqdZK1R22vvA0J7JZKcuOIQ7Y=
@@ -32,8 +30,8 @@ github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0
 github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=
 github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
 github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
-github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
-github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
+github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
+github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -48,8 +46,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
 github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
 github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
-go.fd.io/govpp v0.9.0 h1:EHUXhQ+dph2K2An4YMqmd/WBE3Fcqsg97KVmdLJoSoU=
-go.fd.io/govpp v0.9.0/go.mod h1:9QoqjEbvfuuXNfjHS0A7YS+7QQVVaQ9cMioOWpSM4rY=
+go.fd.io/govpp v0.10.0 h1:lL93SbqOILjON2pMvazrlHRekGYTRy0Qmj57RuAkxR0=
+go.fd.io/govpp v0.10.0/go.mod h1:5m3bZM9ck+2EGC2O3ASmSSJAaoouyOlVWtiwj5BdCv0=
 golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
 golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
 golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -61,8 +59,8 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
 golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
index 4c6d5b2..bb49924 100644 (file)
@@ -149,7 +149,7 @@ func (s *HstSuite) hstFail() {
                out, err := container.log(20)
                if err != nil {
                        fmt.Printf("An error occured while obtaining '%s' container logs: %s\n", container.name, fmt.Sprint(err))
-                       break
+                       continue
                }
                fmt.Printf("\nvvvvvvvvvvvvvvv " +
                        container.name + ":\n" +
index 4277d43..fe12f5a 100644 (file)
@@ -13,7 +13,7 @@ func init() {
        registerNsTests(HttpTpsTest)
        registerVethTests(HttpCliTest)
        registerNoTopoTests(NginxHttp3Test, NginxAsServerTest,
-               NginxPerfCpsTest, NginxPerfRpsTest, NginxPerfWrkTest)
+               NginxPerfCpsTest, NginxPerfRpsTest, NginxPerfWrkTest, HeaderServerTest)
        registerNoTopoSoloTests(HttpStaticPromTest)
 }
 
@@ -49,7 +49,7 @@ func HttpCliTest(s *VethsSuite) {
        uri := "http://" + serverVeth.ip4AddressString() + "/80"
 
        o := clientContainer.vppInstance.vppctl("http cli client" +
-               " uri " + uri + " query /show/version")
+               " uri " + uri + " query /show/vlib/graph")
 
        s.log(o)
        s.assertContains(o, "<html>", "<html> not found in the result!")
@@ -91,6 +91,21 @@ func HttpStaticPromTest(s *NoTopoSuite) {
        s.assertNil(err)
 }
 
+func HeaderServerTest(s *NoTopoSuite) {
+       query := "show/version"
+       vpp := s.getContainerByName("vpp").vppInstance
+       serverAddress := s.getInterfaceByName(tapInterfaceName).peer.ip4AddressString()
+       vpp.vppctl("http cli server")
+
+       curlCont := s.getContainerByName("curl")
+       args := fmt.Sprintf("curl -i -s http://%s:80/%s", serverAddress, query)
+       curlCont.extraRunningArgs = args
+       o, err := curlCont.combinedOutput()
+       s.assertNil(err, fmt.Sprint(err))
+       s.log(o)
+       s.assertContains(o, "Server: http_cli_server")
+}
+
 func NginxAsServerTest(s *NoTopoSuite) {
        query := "return_ok"
        finished := make(chan error, 1)
index cc2d00b..33a8393 100755 (executable)
@@ -67,9 +67,9 @@ docker_build hs-test/vpp vpp
 docker_build hs-test/nginx-ldp nginx
 docker_build hs-test/nginx-server nginx-server
 docker_build hs-test/build build
+docker_build hs-test/curl curl
 if [ "$HST_EXTENDED_TESTS" = true ] ; then
     docker_build hs-test/nginx-http3 nginx-http3
-    docker_build hs-test/curl curl
 fi
 
 # cleanup detached images
index 58f08bd..94162b8 100755 (executable)
@@ -86,4 +86,4 @@ if [ $single_test -eq 0 ] && [ $debug_set -eq 1 ]; then
     exit 1
 fi
 
-sudo -E go run github.com/onsi/ginkgo/v2/ginkgo --trace $ginkgo_args -- $args
+sudo -E go run github.com/onsi/ginkgo/v2/ginkgo --no-color --trace $ginkgo_args -- $args
index fddb3d5..98803a9 100644 (file)
@@ -18,6 +18,8 @@
  *------------------------------------------------------------------
  */
 
+#include <byteswap.h>
+
 #include <vat/vat.h>
 #include <vlibapi/api.h>
 #include <vlibmemory/api.h>
@@ -112,7 +114,7 @@ static void vl_api_acl_interface_list_details_t_handler
         int i;
         vat_main_t * vam = acl_test_main.vat_main;
         u8 *out = 0;
-        vl_api_acl_interface_list_details_t_endian(mp);
+       vl_api_acl_interface_list_details_t_endian (mp, 0 /* from network */);
        out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
         out = format(out, "   input ");
        for(i=0; i<mp->count; i++) {
@@ -139,7 +141,8 @@ static void vl_api_acl_interface_etype_whitelist_details_t_handler
         int i;
         vat_main_t * vam = acl_test_main.vat_main;
         u8 *out = 0;
-        vl_api_acl_interface_etype_whitelist_details_t_endian(mp);
+       vl_api_acl_interface_etype_whitelist_details_t_endian (
+         mp, 0 /* from network */);
        out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input);
         out = format(out, "   input ");
        for(i=0; i<mp->count; i++) {
@@ -171,15 +174,15 @@ vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a)
   inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src));
   inet_ntop(af, &a->dst_prefix.address.un, (void *)dst, sizeof(dst));
 
-  out = format(out, "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport %d-%d tcpflags %d mask %d",
-                     a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit,
-                     src, a->src_prefix.len,
-                     dst, a->dst_prefix.len,
-                     a->proto,
-                     a->srcport_or_icmptype_first, a->srcport_or_icmptype_last,
-                    a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last,
-                     a->tcp_flags_value, a->tcp_flags_mask);
-  return(out);
+  out = format (out,
+               "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport "
+               "%d-%d tcpflags %d mask %d",
+               a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit, src,
+               a->src_prefix.len, dst, a->dst_prefix.len, a->proto,
+               a->srcport_or_icmptype_first, a->srcport_or_icmptype_last,
+               a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last,
+               a->tcp_flags_value, a->tcp_flags_mask);
+  return (out);
 }
 
 
@@ -189,9 +192,10 @@ static void vl_api_acl_details_t_handler
     {
         int i;
         vat_main_t * vam = acl_test_main.vat_main;
-        vl_api_acl_details_t_endian(mp);
-        u8 *out = 0;
-        out = format(0, "acl_index: %d, count: %d\n   tag {%s}\n", mp->acl_index, mp->count, mp->tag);
+       vl_api_acl_details_t_endian (mp, 0 /* from network */);
+       u8 *out = 0;
+       out = format (0, "acl_index: %d, count: %d\n   tag {%s}\n",
+                     mp->acl_index, mp->count, mp->tag);
        for(i=0; i<mp->count; i++) {
           out = format(out, "   ");
           out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]);
@@ -223,8 +227,9 @@ static void vl_api_macip_acl_details_t_handler
     {
         int i;
         vat_main_t * vam = acl_test_main.vat_main;
-        vl_api_macip_acl_details_t_endian(mp);
-        u8 *out = format(0,"MACIP acl_index: %d, count: %d\n   tag {%s}\n", mp->acl_index, mp->count, mp->tag);
+       vl_api_macip_acl_details_t_endian (mp, 0 /* from network */);
+       u8 *out = format (0, "MACIP acl_index: %d, count: %d\n   tag {%s}\n",
+                         mp->acl_index, mp->count, mp->tag);
        for(i=0; i<mp->count; i++) {
           out = format(out, "   ");
           out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]);
index 9b60916..5499ed4 100644 (file)
@@ -12,8 +12,8 @@
 # limitations under the License.
 
 if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
-  list(APPEND VARIANTS "slm\;-march=silvermont")
-  list(APPEND VARIANTS "hsw\;-march=haswell")
+  list(APPEND VARIANTS "slm\;-march=silvermont -maes")
+  list(APPEND VARIANTS "hsw\;-march=haswell -maes")
   if(compiler_flag_march_skylake_avx512 AND compiler_flag_mprefer_vector_width_256)
     list(APPEND VARIANTS "skx\;-march=skylake-avx512 -mprefer-vector-width=256")
   endif()
@@ -23,16 +23,15 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
   if(compiler_flag_march_alderlake)
     list(APPEND VARIANTS "adl\;-march=alderlake -mprefer-vector-width=256")
   endif()
-  set (COMPILE_FILES aes_cbc.c aes_gcm.c aes_ctr.c)
-  set (COMPILE_OPTS -Wall -fno-common -maes)
 endif()
 
 if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)")
   list(APPEND VARIANTS "armv8\;-march=armv8.1-a+crc+crypto")
-  set (COMPILE_FILES aes_cbc.c aes_gcm.c aes_ctr.c)
-  set (COMPILE_OPTS -Wall -fno-common)
 endif()
 
+set (COMPILE_FILES aes_cbc.c aes_gcm.c aes_ctr.c sha2.c)
+set (COMPILE_OPTS -Wall -fno-common)
+
 if (NOT VARIANTS)
   return()
 endif()
index c84390c..dd7ca3f 100644 (file)
@@ -249,18 +249,30 @@ decrypt:
   return n_ops;
 }
 
-#define foreach_aes_cbc_handler_type _(128) _(192) _(256)
-
-#define _(x) \
-static u32 aes_ops_dec_aes_cbc_##x \
-(vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \
-{ return aes_ops_dec_aes_cbc (vm, ops, n_ops, AES_KEY_##x); } \
-static u32 aes_ops_enc_aes_cbc_##x \
-(vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \
-{ return aes_ops_enc_aes_cbc (vm, ops, n_ops, AES_KEY_##x); } \
-
-foreach_aes_cbc_handler_type;
-#undef _
+static int
+aes_cbc_cpu_probe ()
+{
+#if defined(__VAES__) && defined(__AVX512F__)
+  if (clib_cpu_supports_vaes () && clib_cpu_supports_avx512f ())
+    return 50;
+#elif defined(__VAES__)
+  if (clib_cpu_supports_vaes ())
+    return 40;
+#elif defined(__AVX512F__)
+  if (clib_cpu_supports_avx512f ())
+    return 30;
+#elif defined(__AVX2__)
+  if (clib_cpu_supports_avx2 ())
+    return 20;
+#elif __AES__
+  if (clib_cpu_supports_aes ())
+    return 10;
+#elif __aarch64__
+  if (clib_cpu_supports_aarch64_aes ())
+    return 10;
+#endif
+  return -1;
+}
 
 static void *
 aes_cbc_key_exp_128 (vnet_crypto_key_t *key)
@@ -289,43 +301,39 @@ aes_cbc_key_exp_256 (vnet_crypto_key_t *key)
   return kd;
 }
 
-#include <fcntl.h>
-
-clib_error_t *
-#if defined(__VAES__) && defined(__AVX512F__)
-crypto_native_aes_cbc_init_icl (vlib_main_t *vm)
-#elif defined(__VAES__)
-crypto_native_aes_cbc_init_adl (vlib_main_t *vm)
-#elif __AVX512F__
-crypto_native_aes_cbc_init_skx (vlib_main_t * vm)
-#elif __aarch64__
-crypto_native_aes_cbc_init_neon (vlib_main_t * vm)
-#elif __AVX2__
-crypto_native_aes_cbc_init_hsw (vlib_main_t * vm)
-#else
-crypto_native_aes_cbc_init_slm (vlib_main_t * vm)
-#endif
-{
-  crypto_native_main_t *cm = &crypto_native_main;
+#define foreach_aes_cbc_handler_type _ (128) _ (192) _ (256)
+
+#define _(x)                                                                  \
+  static u32 aes_ops_enc_aes_cbc_##x (vlib_main_t *vm,                        \
+                                     vnet_crypto_op_t *ops[], u32 n_ops)     \
+  {                                                                           \
+    return aes_ops_enc_aes_cbc (vm, ops, n_ops, AES_KEY_##x);                 \
+  }                                                                           \
+                                                                              \
+  CRYPTO_NATIVE_OP_HANDLER (aes_##x##_cbc_enc) = {                            \
+    .op_id = VNET_CRYPTO_OP_AES_##x##_CBC_ENC,                                \
+    .fn = aes_ops_enc_aes_cbc_##x,                                            \
+    .probe = aes_cbc_cpu_probe,                                               \
+  };                                                                          \
+                                                                              \
+  static u32 aes_ops_dec_aes_cbc_##x (vlib_main_t *vm,                        \
+                                     vnet_crypto_op_t *ops[], u32 n_ops)     \
+  {                                                                           \
+    return aes_ops_dec_aes_cbc (vm, ops, n_ops, AES_KEY_##x);                 \
+  }                                                                           \
+                                                                              \
+  CRYPTO_NATIVE_OP_HANDLER (aes_##x##_cbc_dec) = {                            \
+    .op_id = VNET_CRYPTO_OP_AES_##x##_CBC_DEC,                                \
+    .fn = aes_ops_dec_aes_cbc_##x,                                            \
+    .probe = aes_cbc_cpu_probe,                                               \
+  };                                                                          \
+                                                                              \
+  CRYPTO_NATIVE_KEY_HANDLER (aes_##x##_cbc) = {                               \
+    .alg_id = VNET_CRYPTO_ALG_AES_##x##_CBC,                                  \
+    .key_fn = aes_cbc_key_exp_##x,                                            \
+    .probe = aes_cbc_cpu_probe,                                               \
+  };
 
-#define _(x) \
-  vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \
-                                   VNET_CRYPTO_OP_AES_##x##_CBC_ENC, \
-                                   aes_ops_enc_aes_cbc_##x); \
-  vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \
-                                   VNET_CRYPTO_OP_AES_##x##_CBC_DEC, \
-                                   aes_ops_dec_aes_cbc_##x); \
-  cm->key_fn[VNET_CRYPTO_ALG_AES_##x##_CBC] = aes_cbc_key_exp_##x;
-  foreach_aes_cbc_handler_type;
+foreach_aes_cbc_handler_type;
 #undef _
 
-  return 0;
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
index 3a21951..d02a7b6 100644 (file)
@@ -81,32 +81,50 @@ aes_ctr_key_exp (vnet_crypto_key_t *key, aes_key_size_t ks)
 foreach_aes_ctr_handler_type;
 #undef _
 
-clib_error_t *
+static int
+probe ()
+{
 #if defined(__VAES__) && defined(__AVX512F__)
-crypto_native_aes_ctr_init_icl (vlib_main_t *vm)
+  if (clib_cpu_supports_vaes () && clib_cpu_supports_avx512f ())
+    return 50;
 #elif defined(__VAES__)
-crypto_native_aes_ctr_init_adl (vlib_main_t *vm)
-#elif __AVX512F__
-crypto_native_aes_ctr_init_skx (vlib_main_t *vm)
-#elif __AVX2__
-crypto_native_aes_ctr_init_hsw (vlib_main_t *vm)
+  if (clib_cpu_supports_vaes ())
+    return 40;
+#elif defined(__AVX512F__)
+  if (clib_cpu_supports_avx512f ())
+    return 30;
+#elif defined(__AVX2__)
+  if (clib_cpu_supports_avx2 ())
+    return 20;
+#elif __AES__
+  if (clib_cpu_supports_aes ())
+    return 10;
 #elif __aarch64__
-crypto_native_aes_ctr_init_neon (vlib_main_t *vm)
-#else
-crypto_native_aes_ctr_init_slm (vlib_main_t *vm)
+  if (clib_cpu_supports_aarch64_aes ())
+    return 10;
 #endif
-{
-  crypto_native_main_t *cm = &crypto_native_main;
+  return -1;
+}
 
-#define _(x)                                                                  \
-  vnet_crypto_register_ops_handlers (                                         \
-    vm, cm->crypto_engine_index, VNET_CRYPTO_OP_AES_##x##_CTR_ENC,            \
-    aes_ops_aes_ctr_##x, aes_ops_aes_ctr_##x##_chained);                      \
-  vnet_crypto_register_ops_handlers (                                         \
-    vm, cm->crypto_engine_index, VNET_CRYPTO_OP_AES_##x##_CTR_DEC,            \
-    aes_ops_aes_ctr_##x, aes_ops_aes_ctr_##x##_chained);                      \
-  cm->key_fn[VNET_CRYPTO_ALG_AES_##x##_CTR] = aes_ctr_key_exp_##x;
-  foreach_aes_ctr_handler_type;
+#define _(b)                                                                  \
+  CRYPTO_NATIVE_OP_HANDLER (aes_##b##_ctr_enc) = {                            \
+    .op_id = VNET_CRYPTO_OP_AES_##b##_CTR_ENC,                                \
+    .fn = aes_ops_aes_ctr_##b,                                                \
+    .cfn = aes_ops_aes_ctr_##b##_chained,                                     \
+    .probe = probe,                                                           \
+  };                                                                          \
+                                                                              \
+  CRYPTO_NATIVE_OP_HANDLER (aes_##b##_ctr_dec) = {                            \
+    .op_id = VNET_CRYPTO_OP_AES_##b##_CTR_DEC,                                \
+    .fn = aes_ops_aes_ctr_##b,                                                \
+    .cfn = aes_ops_aes_ctr_##b##_chained,                                     \
+    .probe = probe,                                                           \
+  };                                                                          \
+  CRYPTO_NATIVE_KEY_HANDLER (aes_##b##_ctr) = {                               \
+    .alg_id = VNET_CRYPTO_ALG_AES_##b##_CTR,                                  \
+    .key_fn = aes_ctr_key_exp_##b,                                            \
+    .probe = probe,                                                           \
+  };
+
+_ (128) _ (192) _ (256)
 #undef _
-  return 0;
-}
index 6589d41..220788d 100644 (file)
@@ -118,40 +118,49 @@ aes_gcm_key_exp (vnet_crypto_key_t *key, aes_key_size_t ks)
 foreach_aes_gcm_handler_type;
 #undef _
 
-clib_error_t *
+static int
+probe ()
+{
 #if defined(__VAES__) && defined(__AVX512F__)
-crypto_native_aes_gcm_init_icl (vlib_main_t *vm)
+  if (clib_cpu_supports_vpclmulqdq () && clib_cpu_supports_vaes () &&
+      clib_cpu_supports_avx512f ())
+    return 50;
 #elif defined(__VAES__)
-crypto_native_aes_gcm_init_adl (vlib_main_t *vm)
-#elif __AVX512F__
-crypto_native_aes_gcm_init_skx (vlib_main_t *vm)
-#elif __AVX2__
-crypto_native_aes_gcm_init_hsw (vlib_main_t *vm)
+  if (clib_cpu_supports_vpclmulqdq () && clib_cpu_supports_vaes ())
+    return 40;
+#elif defined(__AVX512F__)
+  if (clib_cpu_supports_pclmulqdq () && clib_cpu_supports_avx512f ())
+    return 30;
+#elif defined(__AVX2__)
+  if (clib_cpu_supports_pclmulqdq () && clib_cpu_supports_avx2 ())
+    return 20;
+#elif __AES__
+  if (clib_cpu_supports_pclmulqdq () && clib_cpu_supports_aes ())
+    return 10;
 #elif __aarch64__
-crypto_native_aes_gcm_init_neon (vlib_main_t *vm)
-#else
-crypto_native_aes_gcm_init_slm (vlib_main_t *vm)
+  if (clib_cpu_supports_aarch64_aes ())
+    return 10;
 #endif
-{
-  crypto_native_main_t *cm = &crypto_native_main;
-
-#define _(x)                                                                  \
-  vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index,              \
-                                   VNET_CRYPTO_OP_AES_##x##_GCM_ENC,         \
-                                   aes_ops_enc_aes_gcm_##x);                 \
-  vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index,              \
-                                   VNET_CRYPTO_OP_AES_##x##_GCM_DEC,         \
-                                   aes_ops_dec_aes_gcm_##x);                 \
-  cm->key_fn[VNET_CRYPTO_ALG_AES_##x##_GCM] = aes_gcm_key_exp_##x;
-  foreach_aes_gcm_handler_type;
-#undef _
-  return 0;
+  return -1;
 }
 
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
+#define _(b)                                                                  \
+  CRYPTO_NATIVE_OP_HANDLER (aes_##b##_gcm_enc) = {                            \
+    .op_id = VNET_CRYPTO_OP_AES_##b##_GCM_ENC,                                \
+    .fn = aes_ops_enc_aes_gcm_##b,                                            \
+    .probe = probe,                                                           \
+  };                                                                          \
+                                                                              \
+  CRYPTO_NATIVE_OP_HANDLER (aes_##b##_gcm_dec) = {                            \
+    .op_id = VNET_CRYPTO_OP_AES_##b##_GCM_DEC,                                \
+    .fn = aes_ops_dec_aes_gcm_##b,                                            \
+    .probe = probe,                                                           \
+  };                                                                          \
+  CRYPTO_NATIVE_KEY_HANDLER (aes_##b##_gcm) = {                               \
+    .alg_id = VNET_CRYPTO_ALG_AES_##b##_GCM,                                  \
+    .key_fn = aes_gcm_key_exp_##b,                                            \
+    .probe = probe,                                                           \
+  };
+
+_ (128) _ (192) _ (256)
+#undef _
index c15b8cb..3d18e8c 100644 (file)
 #define __crypto_native_h__
 
 typedef void *(crypto_native_key_fn_t) (vnet_crypto_key_t * key);
+typedef int (crypto_native_variant_probe_t) ();
+
+typedef struct crypto_native_op_handler
+{
+  struct crypto_native_op_handler *next;
+  vnet_crypto_op_id_t op_id;
+  vnet_crypto_ops_handler_t *fn;
+  vnet_crypto_chained_ops_handler_t *cfn;
+  crypto_native_variant_probe_t *probe;
+  int priority;
+} crypto_native_op_handler_t;
+
+typedef struct crypto_native_key_handler
+{
+  struct crypto_native_key_handler *next;
+  vnet_crypto_alg_t alg_id;
+  crypto_native_key_fn_t *key_fn;
+  crypto_native_variant_probe_t *probe;
+  int priority;
+} crypto_native_key_handler_t;
 
 typedef struct
 {
   u32 crypto_engine_index;
   crypto_native_key_fn_t *key_fn[VNET_CRYPTO_N_ALGS];
   void **key_data;
+  crypto_native_op_handler_t *op_handlers;
+  crypto_native_key_handler_t *key_handlers;
 } crypto_native_main_t;
 
 extern crypto_native_main_t crypto_native_main;
 
-#define foreach_crypto_native_march_variant                                   \
-  _ (slm) _ (hsw) _ (skx) _ (icl) _ (adl) _ (neon)
-
-#define _(v)                                                                  \
-  clib_error_t __clib_weak *crypto_native_aes_cbc_init_##v (vlib_main_t *vm); \
-  clib_error_t __clib_weak *crypto_native_aes_ctr_init_##v (vlib_main_t *vm); \
-  clib_error_t __clib_weak *crypto_native_aes_gcm_init_##v (vlib_main_t *vm);
-
-foreach_crypto_native_march_variant;
-#undef _
+#define CRYPTO_NATIVE_OP_HANDLER(x)                                           \
+  static crypto_native_op_handler_t __crypto_native_op_handler_##x;           \
+  static void __clib_constructor __crypto_native_op_handler_cb_##x (void)     \
+  {                                                                           \
+    crypto_native_main_t *cm = &crypto_native_main;                           \
+    int priority = __crypto_native_op_handler_##x.probe ();                   \
+    if (priority >= 0)                                                        \
+      {                                                                       \
+       __crypto_native_op_handler_##x.priority = priority;                   \
+       __crypto_native_op_handler_##x.next = cm->op_handlers;                \
+       cm->op_handlers = &__crypto_native_op_handler_##x;                    \
+      }                                                                       \
+  }                                                                           \
+  static crypto_native_op_handler_t __crypto_native_op_handler_##x
 
+#define CRYPTO_NATIVE_KEY_HANDLER(x)                                          \
+  static crypto_native_key_handler_t __crypto_native_key_handler_##x;         \
+  static void __clib_constructor __crypto_native_key_handler_cb_##x (void)    \
+  {                                                                           \
+    crypto_native_main_t *cm = &crypto_native_main;                           \
+    int priority = __crypto_native_key_handler_##x.probe ();                  \
+    if (priority >= 0)                                                        \
+      {                                                                       \
+       __crypto_native_key_handler_##x.priority = priority;                  \
+       __crypto_native_key_handler_##x.next = cm->key_handlers;              \
+       cm->key_handlers = &__crypto_native_key_handler_##x;                  \
+      }                                                                       \
+  }                                                                           \
+  static crypto_native_key_handler_t __crypto_native_key_handler_##x
 #endif /* __crypto_native_h__ */
 
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
index 8a59be3..2bc0d98 100644 (file)
@@ -63,95 +63,52 @@ clib_error_t *
 crypto_native_init (vlib_main_t * vm)
 {
   crypto_native_main_t *cm = &crypto_native_main;
-  clib_error_t *error = 0;
 
-  if (clib_cpu_supports_x86_aes () == 0 &&
-      clib_cpu_supports_aarch64_aes () == 0)
+  if (cm->op_handlers == 0)
     return 0;
 
   cm->crypto_engine_index =
     vnet_crypto_register_engine (vm, "native", 100,
                                 "Native ISA Optimized Crypto");
 
-  if (0);
-#if __x86_64__
-  else if (crypto_native_aes_cbc_init_icl && clib_cpu_supports_vaes () &&
-          clib_cpu_supports_avx512f ())
-    error = crypto_native_aes_cbc_init_icl (vm);
-  else if (crypto_native_aes_cbc_init_adl && clib_cpu_supports_vaes ())
-    error = crypto_native_aes_cbc_init_adl (vm);
-  else if (crypto_native_aes_cbc_init_skx && clib_cpu_supports_avx512f ())
-    error = crypto_native_aes_cbc_init_skx (vm);
-  else if (crypto_native_aes_cbc_init_hsw && clib_cpu_supports_avx2 ())
-    error = crypto_native_aes_cbc_init_hsw (vm);
-  else if (crypto_native_aes_cbc_init_slm)
-    error = crypto_native_aes_cbc_init_slm (vm);
-#endif
-#if __aarch64__
-  else if (crypto_native_aes_cbc_init_neon)
-    error = crypto_native_aes_cbc_init_neon (vm);
-#endif
-  else
-    error = clib_error_return (0, "No AES CBC implemenation available");
-
-  if (error)
-    return error;
-
-  if (0)
-    ;
-#if __x86_64__
-  else if (crypto_native_aes_ctr_init_icl && clib_cpu_supports_vaes () &&
-          clib_cpu_supports_avx512f ())
-    error = crypto_native_aes_ctr_init_icl (vm);
-  else if (crypto_native_aes_ctr_init_adl && clib_cpu_supports_vaes ())
-    error = crypto_native_aes_ctr_init_adl (vm);
-  else if (crypto_native_aes_ctr_init_skx && clib_cpu_supports_avx512f ())
-    error = crypto_native_aes_ctr_init_skx (vm);
-  else if (crypto_native_aes_ctr_init_hsw && clib_cpu_supports_avx2 ())
-    error = crypto_native_aes_ctr_init_hsw (vm);
-  else if (crypto_native_aes_ctr_init_slm)
-    error = crypto_native_aes_ctr_init_slm (vm);
-#endif
-#if __aarch64__
-  else if (crypto_native_aes_ctr_init_neon)
-    error = crypto_native_aes_ctr_init_neon (vm);
-#endif
-  else
-    error = clib_error_return (0, "No AES CTR implemenation available");
-
-  if (error)
-    return error;
-
-#if __x86_64__
-  if (clib_cpu_supports_pclmulqdq ())
+  crypto_native_op_handler_t *oh = cm->op_handlers;
+  crypto_native_key_handler_t *kh = cm->key_handlers;
+  crypto_native_op_handler_t **best_by_op_id = 0;
+  crypto_native_key_handler_t **best_by_alg_id = 0;
+
+  while (oh)
     {
-      if (crypto_native_aes_gcm_init_icl && clib_cpu_supports_vaes () &&
-         clib_cpu_supports_avx512f ())
-       error = crypto_native_aes_gcm_init_icl (vm);
-      else if (crypto_native_aes_gcm_init_adl && clib_cpu_supports_vaes ())
-       error = crypto_native_aes_gcm_init_adl (vm);
-      else if (crypto_native_aes_gcm_init_skx && clib_cpu_supports_avx512f ())
-       error = crypto_native_aes_gcm_init_skx (vm);
-      else if (crypto_native_aes_gcm_init_hsw && clib_cpu_supports_avx2 ())
-       error = crypto_native_aes_gcm_init_hsw (vm);
-      else if (crypto_native_aes_gcm_init_slm)
-       error = crypto_native_aes_gcm_init_slm (vm);
-      else
-       error = clib_error_return (0, "No AES GCM implemenation available");
-
-      if (error)
-       return error;
+      vec_validate (best_by_op_id, oh->op_id);
+
+      if (best_by_op_id[oh->op_id] == 0 ||
+         best_by_op_id[oh->op_id]->priority < oh->priority)
+       best_by_op_id[oh->op_id] = oh;
+
+      oh = oh->next;
     }
-#endif
-#if __aarch64__
-  if (crypto_native_aes_gcm_init_neon)
-    error = crypto_native_aes_gcm_init_neon (vm);
-  else
-    error = clib_error_return (0, "No AES GCM implemenation available");
-
-  if (error)
-    return error;
-#endif
+
+  while (kh)
+    {
+      vec_validate (best_by_alg_id, kh->alg_id);
+
+      if (best_by_alg_id[kh->alg_id] == 0 ||
+         best_by_alg_id[kh->alg_id]->priority < kh->priority)
+       best_by_alg_id[kh->alg_id] = kh;
+
+      kh = kh->next;
+    }
+
+  vec_foreach_pointer (oh, best_by_op_id)
+    if (oh)
+      vnet_crypto_register_ops_handlers (vm, cm->crypto_engine_index,
+                                        oh->op_id, oh->fn, oh->cfn);
+
+  vec_foreach_pointer (kh, best_by_alg_id)
+    if (kh)
+      cm->key_fn[kh->alg_id] = kh->key_fn;
+
+  vec_free (best_by_op_id);
+  vec_free (best_by_alg_id);
 
   vnet_crypto_register_key_handler (vm, cm->crypto_engine_index,
                                    crypto_native_key_handler);
diff --git a/src/plugins/crypto_native/sha2.c b/src/plugins/crypto_native/sha2.c
new file mode 100644 (file)
index 0000000..459ce6d
--- /dev/null
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright(c) 2024 Cisco Systems, Inc.
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/plugin/plugin.h>
+#include <vnet/crypto/crypto.h>
+#include <crypto_native/crypto_native.h>
+#include <vppinfra/crypto/sha2.h>
+
+static_always_inline u32
+crypto_native_ops_hash_sha2 (vlib_main_t *vm, vnet_crypto_op_t *ops[],
+                            u32 n_ops, vnet_crypto_op_chunk_t *chunks,
+                            clib_sha2_type_t type, int maybe_chained)
+{
+  vnet_crypto_op_t *op = ops[0];
+  clib_sha2_ctx_t ctx;
+  u32 n_left = n_ops;
+
+next:
+  if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
+    {
+      vnet_crypto_op_chunk_t *chp = chunks + op->chunk_index;
+      clib_sha2_init (&ctx, type);
+      for (int j = 0; j < op->n_chunks; j++, chp++)
+       clib_sha2_update (&ctx, chp->src, chp->len);
+      clib_sha2_final (&ctx, op->digest);
+    }
+  else
+    clib_sha2 (type, op->src, op->len, op->digest);
+
+  op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
+
+  if (--n_left)
+    {
+      op += 1;
+      goto next;
+    }
+
+  return n_ops;
+}
+
+static_always_inline u32
+crypto_native_ops_hmac_sha2 (vlib_main_t *vm, vnet_crypto_op_t *ops[],
+                            u32 n_ops, vnet_crypto_op_chunk_t *chunks,
+                            clib_sha2_type_t type)
+{
+  crypto_native_main_t *cm = &crypto_native_main;
+  vnet_crypto_op_t *op = ops[0];
+  u32 n_left = n_ops;
+  clib_sha2_hmac_ctx_t ctx;
+  u8 buffer[64];
+  u32 sz, n_fail = 0;
+
+  for (; n_left; n_left--, op++)
+    {
+      clib_sha2_hmac_init (
+       &ctx, type, (clib_sha2_hmac_key_data_t *) cm->key_data[op->key_index]);
+      if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS)
+       {
+         vnet_crypto_op_chunk_t *chp = chunks + op->chunk_index;
+         for (int j = 0; j < op->n_chunks; j++, chp++)
+           clib_sha2_hmac_update (&ctx, chp->src, chp->len);
+       }
+      else
+       clib_sha2_hmac_update (&ctx, op->src, op->len);
+
+      clib_sha2_hmac_final (&ctx, buffer);
+
+      if (op->digest_len)
+       {
+         sz = op->digest_len;
+         if (op->flags & VNET_CRYPTO_OP_FLAG_HMAC_CHECK)
+           {
+             if ((memcmp (op->digest, buffer, sz)))
+               {
+                 n_fail++;
+                 op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
+                 continue;
+               }
+           }
+         else
+           clib_memcpy_fast (op->digest, buffer, sz);
+       }
+      else
+       {
+         sz = clib_sha2_variants[type].digest_size;
+         if (op->flags & VNET_CRYPTO_OP_FLAG_HMAC_CHECK)
+           {
+             if ((memcmp (op->digest, buffer, sz)))
+               {
+                 n_fail++;
+                 op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC;
+                 continue;
+               }
+           }
+         else
+           clib_memcpy_fast (op->digest, buffer, sz);
+       }
+
+      op->status = VNET_CRYPTO_OP_STATUS_COMPLETED;
+    }
+
+  return n_ops - n_fail;
+}
+
+static void *
+sha2_key_add (vnet_crypto_key_t *key, clib_sha2_type_t type)
+{
+  clib_sha2_hmac_key_data_t *kd;
+
+  kd = clib_mem_alloc_aligned (sizeof (*kd), CLIB_CACHE_LINE_BYTES);
+  clib_sha2_hmac_key_data (type, key->data, vec_len (key->data), kd);
+
+  return kd;
+}
+
+static int
+probe ()
+{
+#if defined(__SHA__) && defined(__x86_64__)
+  if (clib_cpu_supports_sha ())
+    return 50;
+#elif defined(__ARM_FEATURE_SHA2)
+  if (clib_cpu_supports_sha2 ())
+    return 10;
+#endif
+  return -1;
+}
+
+#define _(b)                                                                  \
+  static u32 crypto_native_ops_hash_sha##b (                                  \
+    vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops)                      \
+  {                                                                           \
+    return crypto_native_ops_hash_sha2 (vm, ops, n_ops, 0, CLIB_SHA2_##b, 0); \
+  }                                                                           \
+                                                                              \
+  static u32 crypto_native_ops_chained_hash_sha##b (                          \
+    vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
+    u32 n_ops)                                                                \
+  {                                                                           \
+    return crypto_native_ops_hash_sha2 (vm, ops, n_ops, chunks,               \
+                                       CLIB_SHA2_##b, 1);                    \
+  }                                                                           \
+                                                                              \
+  static u32 crypto_native_ops_hmac_sha##b (                                  \
+    vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops)                      \
+  {                                                                           \
+    return crypto_native_ops_hmac_sha2 (vm, ops, n_ops, 0, CLIB_SHA2_##b);    \
+  }                                                                           \
+                                                                              \
+  static u32 crypto_native_ops_chained_hmac_sha##b (                          \
+    vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \
+    u32 n_ops)                                                                \
+  {                                                                           \
+    return crypto_native_ops_hmac_sha2 (vm, ops, n_ops, chunks,               \
+                                       CLIB_SHA2_##b);                       \
+  }                                                                           \
+                                                                              \
+  static void *sha2_##b##_key_add (vnet_crypto_key_t *k)                      \
+  {                                                                           \
+    return sha2_key_add (k, CLIB_SHA2_##b);                                   \
+  }                                                                           \
+                                                                              \
+  CRYPTO_NATIVE_OP_HANDLER (crypto_native_hash_sha##b) = {                    \
+    .op_id = VNET_CRYPTO_OP_SHA##b##_HASH,                                    \
+    .fn = crypto_native_ops_hash_sha##b,                                      \
+    .cfn = crypto_native_ops_chained_hash_sha##b,                             \
+    .probe = probe,                                                           \
+  };                                                                          \
+  CRYPTO_NATIVE_OP_HANDLER (crypto_native_hmac_sha##b) = {                    \
+    .op_id = VNET_CRYPTO_OP_SHA##b##_HMAC,                                    \
+    .fn = crypto_native_ops_hmac_sha##b,                                      \
+    .cfn = crypto_native_ops_chained_hmac_sha##b,                             \
+    .probe = probe,                                                           \
+  };                                                                          \
+  CRYPTO_NATIVE_KEY_HANDLER (crypto_native_hmac_sha##b) = {                   \
+    .alg_id = VNET_CRYPTO_ALG_HMAC_SHA##b,                                    \
+    .key_fn = sha2_##b##_key_add,                                             \
+    .probe = probe,                                                           \
+  };
+
+_ (224)
+_ (256)
+
+#undef _
index 982436d..90e81e9 100644 (file)
@@ -42,29 +42,35 @@ iavf_port_vlan_strip_disable (vlib_main_t *vm, vnet_dev_port_t *port)
   vnet_dev_t *dev = port->dev;
   iavf_port_t *ap = vnet_dev_get_port_data (port);
   virtchnl_vlan_caps_t vc;
-  vnet_dev_rv_t rv;
+  vnet_dev_rv_t rv = VNET_DEV_ERR_NOT_SUPPORTED;
   u32 outer, inner;
   const u32 mask = VIRTCHNL_VLAN_ETHERTYPE_8100;
 
-  if ((ap->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) == 0)
-    return iavf_vc_op_disable_vlan_stripping (vm, dev);
+  if (ap->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2)
+    {
+      if ((rv = iavf_vc_op_get_offload_vlan_v2_caps (vm, dev, &vc)))
+       return rv;
 
-  if ((rv = iavf_vc_op_get_offload_vlan_v2_caps (vm, dev, &vc)))
-    return rv;
+      outer = vc.offloads.stripping_support.outer;
+      inner = vc.offloads.stripping_support.inner;
 
-  outer = vc.offloads.stripping_support.outer;
-  inner = vc.offloads.stripping_support.inner;
+      outer = outer & VIRTCHNL_VLAN_TOGGLE ? outer & mask : 0;
+      inner = inner & VIRTCHNL_VLAN_TOGGLE ? inner & mask : 0;
 
-  outer = outer & VIRTCHNL_VLAN_TOGGLE ? outer & mask : 0;
-  inner = inner & VIRTCHNL_VLAN_TOGGLE ? inner & mask : 0;
+      virtchnl_vlan_setting_t vs = {
+       .vport_id = ap->vsi_id,
+       .outer_ethertype_setting = outer,
+       .inner_ethertype_setting = inner,
+      };
 
-  virtchnl_vlan_setting_t vs = {
-    .vport_id = ap->vsi_id,
-    .outer_ethertype_setting = outer,
-    .inner_ethertype_setting = inner,
-  };
+      if ((rv = iavf_vc_op_disable_vlan_stripping_v2 (vm, dev, &vs)))
+       return rv;
+    }
 
-  return iavf_vc_op_disable_vlan_stripping_v2 (vm, dev, &vs);
+  if (ap->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN)
+    return iavf_vc_op_disable_vlan_stripping (vm, dev);
+
+  return rv;
 }
 
 vnet_dev_rv_t
@@ -275,7 +281,12 @@ iavf_port_init (vlib_main_t *vm, vnet_dev_port_t *port)
       u64_bit_set (&ap->intr_mode_per_rxq_bitmap, q->queue_id, 1);
 
   if ((rv = iavf_port_vlan_strip_disable (vm, port)))
-    return rv;
+    {
+      if (rv == VNET_DEV_ERR_NOT_SUPPORTED)
+       log_warn (port->dev, "device doesn't support vlan stripping");
+      else
+       return rv;
+    }
 
   if ((rv = iavf_port_init_rss (vm, port)))
     return rv;
index 03a1d59..97a11e0 100644 (file)
@@ -51,7 +51,8 @@ static struct
   }
 
   _ (0xa063, RVU_PF, "Marvell Octeon Resource Virtualization Unit PF"),
-  _ (0xa0f8, RVU_VF, "Marvell Octeon Resource Virtualization Unit VF"),
+  _ (0xa064, RVU_VF, "Marvell Octeon Resource Virtualization Unit VF"),
+  _ (0xa0f8, LBK_VF, "Marvell Octeon Loopback Unit VF"),
   _ (0xa0f7, SDP_VF, "Marvell Octeon System DPI Packet Interface Unit VF"),
   _ (0xa0f3, CPT_VF, "Marvell Octeon Cryptographic Accelerator Unit VF"),
 #undef _
@@ -114,7 +115,7 @@ oct_init_nix (vlib_main_t *vm, vnet_dev_t *dev)
   if ((rrv = roc_nix_dev_init (cd->nix)))
     return cnx_return_roc_err (dev, rrv, "roc_nix_dev_init");
 
-  if (roc_nix_npc_mac_addr_get (cd->nix, mac_addr))
+  if ((rrv = roc_nix_npc_mac_addr_get (cd->nix, mac_addr)))
     return cnx_return_roc_err (dev, rrv, "roc_nix_npc_mac_addr_get");
 
   vnet_dev_port_add_args_t port_add_args = {
index 92ec953..e43cde0 100644 (file)
@@ -22,6 +22,7 @@ typedef enum
   OCT_DEVICE_TYPE_UNKNOWN = 0,
   OCT_DEVICE_TYPE_RVU_PF,
   OCT_DEVICE_TYPE_RVU_VF,
+  OCT_DEVICE_TYPE_LBK_VF,
   OCT_DEVICE_TYPE_SDP_VF,
   OCT_DEVICE_TYPE_CPT_VF,
 } __clib_packed oct_device_type_t;
@@ -162,7 +163,8 @@ vnet_dev_rv_t oct_flow_query (vlib_main_t *, vnet_dev_port_t *, u32, uword,
   _ (AURA_BATCH_ALLOC_ISSUE_FAIL, aura_batch_alloc_issue_fail, ERROR,         \
      "aura batch alloc issue failed")                                         \
   _ (AURA_BATCH_ALLOC_NOT_READY, aura_batch_alloc_not_ready, ERROR,           \
-     "aura batch alloc not ready")
+     "aura batch alloc not ready")                                            \
+  _ (MTU_EXCEEDED, mtu_exceeded, ERROR, "mtu exceeded")
 
 typedef enum
 {
index 0dbf875..a2e4b07 100644 (file)
@@ -22,8 +22,11 @@ typedef struct
   u32 n_tx_bytes;
   u32 n_drop;
   vlib_buffer_t *drop[VLIB_FRAME_SIZE];
+  u32 n_exd_mtu;
+  vlib_buffer_t *exd_mtu[VLIB_FRAME_SIZE];
   u32 batch_alloc_not_ready;
   u32 batch_alloc_issue_fail;
+  int max_pkt_len;
   u16 lmt_id;
   u64 lmt_ioaddr;
   lmt_line_t *lmt_lines;
@@ -133,7 +136,8 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq)
 
 static_always_inline u8
 oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
-            lmt_line_t *line, u32 flags, int simple, int trace)
+            lmt_line_t *line, u32 flags, int simple, int trace, u32 *n,
+            u8 *dpl)
 {
   u8 n_dwords = 2;
   u32 total_len = 0;
@@ -148,6 +152,12 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
     },
   };
 
+  if (PREDICT_FALSE (vlib_buffer_length_in_chain (vm, b) > ctx->max_pkt_len))
+    {
+      ctx->exd_mtu[ctx->n_exd_mtu++] = b;
+      return 0;
+    }
+
   if (!simple && flags & VLIB_BUFFER_NEXT_PRESENT)
     {
       u8 n_tail_segs = 0;
@@ -159,7 +169,7 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
          tail_segs[n_tail_segs++] = t;
          if (n_tail_segs > 5)
            {
-             ctx->drop[ctx->n_drop++] = t;
+             ctx->drop[ctx->n_drop++] = b;
              return 0;
            }
        }
@@ -231,6 +241,9 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b,
   for (u32 i = 0; i < n_dwords; i++)
     line->dwords[i] = d.as_u128[i];
 
+  *dpl = n_dwords;
+  *n = *n + 1;
+
   return n_dwords;
 }
 
@@ -240,7 +253,7 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq,
 {
   u8 dwords_per_line[16], *dpl = dwords_per_line;
   u64 lmt_arg, ioaddr, n_lines;
-  u32 n_left, or_flags_16 = 0;
+  u32 n_left, or_flags_16 = 0, n = 0;
   const u32 not_simple_flags =
     VLIB_BUFFER_NEXT_PRESENT | VNET_BUFFER_F_OFFLOAD;
   lmt_line_t *l = ctx->lmt_lines;
@@ -248,7 +261,7 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq,
   /* Data Store Memory Barrier - outer shareable domain */
   asm volatile("dmb oshst" ::: "memory");
 
-  for (n_left = n_pkts; n_left >= 8; n_left -= 8, b += 8, l += 8)
+  for (n_left = n_pkts; n_left >= 8; n_left -= 8, b += 8)
     {
       u32 f0, f1, f2, f3, f4, f5, f6, f7, or_f = 0;
       vlib_prefetch_buffer_header (b[8], LOAD);
@@ -269,48 +282,54 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq,
       if ((or_f & not_simple_flags) == 0)
        {
          int simple = 1;
-         oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace);
-         oct_tx_enq1 (vm, ctx, b[1], l + 1, f1, simple, trace);
+         oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[1], l + n, f1, simple, trace, &n, &dpl[n]);
          vlib_prefetch_buffer_header (b[13], LOAD);
-         oct_tx_enq1 (vm, ctx, b[2], l + 2, f2, simple, trace);
-         oct_tx_enq1 (vm, ctx, b[3], l + 3, f3, simple, trace);
+         oct_tx_enq1 (vm, ctx, b[2], l + n, f2, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[3], l + n, f3, simple, trace, &n, &dpl[n]);
          vlib_prefetch_buffer_header (b[14], LOAD);
-         oct_tx_enq1 (vm, ctx, b[4], l + 4, f4, simple, trace);
-         oct_tx_enq1 (vm, ctx, b[5], l + 5, f5, simple, trace);
+         oct_tx_enq1 (vm, ctx, b[4], l + n, f4, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[5], l + n, f5, simple, trace, &n, &dpl[n]);
          vlib_prefetch_buffer_header (b[15], LOAD);
-         oct_tx_enq1 (vm, ctx, b[6], l + 6, f6, simple, trace);
-         oct_tx_enq1 (vm, ctx, b[7], l + 7, f7, simple, trace);
-         dpl[0] = dpl[1] = dpl[2] = dpl[3] = 2;
-         dpl[4] = dpl[5] = dpl[6] = dpl[7] = 2;
+         oct_tx_enq1 (vm, ctx, b[6], l + n, f6, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[7], l + n, f7, simple, trace, &n, &dpl[n]);
        }
       else
        {
          int simple = 0;
-         dpl[0] = oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace);
-         dpl[1] = oct_tx_enq1 (vm, ctx, b[1], l + 1, f1, simple, trace);
+         oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[1], l + n, f1, simple, trace, &n, &dpl[n]);
          vlib_prefetch_buffer_header (b[13], LOAD);
-         dpl[2] = oct_tx_enq1 (vm, ctx, b[2], l + 2, f2, simple, trace);
-         dpl[3] = oct_tx_enq1 (vm, ctx, b[3], l + 3, f3, simple, trace);
+         oct_tx_enq1 (vm, ctx, b[2], l + n, f2, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[3], l + n, f3, simple, trace, &n, &dpl[n]);
          vlib_prefetch_buffer_header (b[14], LOAD);
-         dpl[4] = oct_tx_enq1 (vm, ctx, b[4], l + 4, f4, simple, trace);
-         dpl[5] = oct_tx_enq1 (vm, ctx, b[5], l + 5, f5, simple, trace);
+         oct_tx_enq1 (vm, ctx, b[4], l + n, f4, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[5], l + n, f5, simple, trace, &n, &dpl[n]);
          vlib_prefetch_buffer_header (b[15], LOAD);
-         dpl[6] = oct_tx_enq1 (vm, ctx, b[6], l + 6, f6, simple, trace);
-         dpl[7] = oct_tx_enq1 (vm, ctx, b[7], l + 7, f7, simple, trace);
+         oct_tx_enq1 (vm, ctx, b[6], l + n, f6, simple, trace, &n, &dpl[n]);
+         oct_tx_enq1 (vm, ctx, b[7], l + n, f7, simple, trace, &n, &dpl[n]);
        }
-      dpl += 8;
+      dpl += n;
+      l += n;
+      n = 0;
     }
 
-  for (; n_left > 0; n_left -= 1, b += 1, l += 1)
+  for (; n_left > 0; n_left -= 1, b += 1)
     {
       u32 f0 = b[0]->flags;
-      dpl++[0] = oct_tx_enq1 (vm, ctx, b[0], l, f0, 0, trace);
+      oct_tx_enq1 (vm, ctx, b[0], l, f0, 0, trace, &n, &dpl[n]);
       or_flags_16 |= f0;
+      dpl += n;
+      l += n;
+      n = 0;
     }
 
   lmt_arg = ctx->lmt_id;
   ioaddr = ctx->lmt_ioaddr;
-  n_lines = n_pkts;
+  n_lines = dpl - dwords_per_line;
+
+  if (PREDICT_FALSE (!n_lines))
+    return n_pkts;
 
   if (PREDICT_FALSE (or_flags_16 & VLIB_BUFFER_NEXT_PRESENT))
     {
@@ -350,6 +369,8 @@ VNET_DEV_NODE_FN (oct_tx_node)
   vnet_dev_tx_node_runtime_t *rt = vnet_dev_get_tx_node_runtime (node);
   vnet_dev_tx_queue_t *txq = rt->tx_queue;
   oct_txq_t *ctq = vnet_dev_get_tx_queue_data (txq);
+  vnet_dev_t *dev = txq->port->dev;
+  oct_device_t *cd = vnet_dev_get_data (dev);
   u32 node_index = node->node_index;
   u32 *from = vlib_frame_vector_args (frame);
   u32 n, n_enq, n_left, n_pkts = frame->n_vectors;
@@ -363,6 +384,7 @@ VNET_DEV_NODE_FN (oct_tx_node)
       .sq = ctq->sq.qid,
       .sizem1 = 1,
     },
+    .max_pkt_len = roc_nix_max_pkt_len (cd->nix),
     .lmt_id = lmt_id,
     .lmt_ioaddr = ctq->io_addr,
     .lmt_lines = ctq->lmt_addr + (lmt_id << ROC_LMT_LINE_SIZE_LOG2),
@@ -396,7 +418,7 @@ VNET_DEV_NODE_FN (oct_tx_node)
        n += oct_tx_enq16 (vm, &ctx, txq, b, n_left, /* trace */ 0);
     }
 
-  ctq->n_enq = n_enq + n;
+  ctq->n_enq = n_enq + n - ctx.n_drop - ctx.n_exd_mtu;
 
   if (n < n_pkts)
     {
@@ -411,6 +433,10 @@ VNET_DEV_NODE_FN (oct_tx_node)
     vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_CHAIN_TOO_LONG,
                      ctx.n_drop);
 
+  if (PREDICT_FALSE (ctx.n_exd_mtu))
+    vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_MTU_EXCEEDED,
+                     ctx.n_exd_mtu);
+
   if (ctx.batch_alloc_not_ready)
     vlib_error_count (vm, node_index,
                      OCT_TX_NODE_CTR_AURA_BATCH_ALLOC_NOT_READY,
@@ -431,5 +457,13 @@ VNET_DEV_NODE_FN (oct_tx_node)
       n_pkts -= ctx.n_drop;
     }
 
+  if (PREDICT_FALSE (ctx.n_exd_mtu))
+    {
+      u32 bi[VLIB_FRAME_SIZE];
+      vlib_get_buffer_indices (vm, ctx.exd_mtu, bi, ctx.n_exd_mtu);
+      vlib_buffer_free (vm, bi, ctx.n_exd_mtu);
+      n_pkts -= ctx.n_exd_mtu;
+    }
+
   return n_pkts;
 }
index c838800..77f9a27 100644 (file)
@@ -89,12 +89,18 @@ show_dpdk_physmem (vlib_main_t * vm, unformat_input_t * input,
                   vlib_cli_command_t * cmd)
 {
   clib_error_t *err = 0;
-  u32 pipe_max_size;
   int fds[2];
   u8 *s = 0;
   int n, n_try;
   FILE *f;
 
+  /*
+   * XXX: Pipes on FreeBSD grow dynamically up to 64KB (FreeBSD 15), don't
+   * manually tweak this value on FreeBSD at the moment.
+   */
+#ifdef __linux__
+  u32 pipe_max_size;
+
   err = clib_sysfs_read ("/proc/sys/fs/pipe-max-size", "%u", &pipe_max_size);
 
   if (err)
@@ -112,6 +118,7 @@ show_dpdk_physmem (vlib_main_t * vm, unformat_input_t * input,
       err = clib_error_return_unix (0, "fcntl(F_SETPIPE_SZ)");
       goto error;
     }
+#endif /* __linux__ */
 
   if (fcntl (fds[0], F_SETFL, O_NONBLOCK) == -1)
     {
index 2d038b9..421f662 100644 (file)
@@ -1280,6 +1280,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
       vec_add1 (conf->eal_init_args, (u8 *) "--no-telemetry");
     }
 
+#ifdef __linux__
   if (!file_prefix)
     {
       tmp = format (0, "--file-prefix%c", 0);
@@ -1287,6 +1288,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input)
       tmp = format (0, "vpp%c", 0);
       vec_add1 (conf->eal_init_args, tmp);
     }
+#endif
 
   if (no_pci == 0 && geteuid () == 0)
     dpdk_bind_devices_to_uio (conf);
index 8de9ff8..1a321bf 100644 (file)
  * limitations under the License.
  */
 
-#include <vnet/session/application.h>
 #include <vnet/session/application_interface.h>
 #include <vnet/session/session.h>
 #include <http/http.h>
-#include <hs_apps/http_cli.h>
 
 #define HCC_DEBUG 0
 
@@ -68,6 +66,7 @@ typedef struct
 typedef enum
 {
   HCC_REPLY_RECEIVED = 100,
+  HCC_TRANSPORT_CLOSED,
 } hcc_cli_signal_t;
 
 static hcc_main_t hcc_main;
@@ -273,6 +272,17 @@ hcc_ts_cleanup_callback (session_t *s, session_cleanup_ntf_t ntf)
   hcc_session_free (s->thread_index, hs);
 }
 
+static void
+hcc_ts_transport_closed (session_t *s)
+{
+  hcc_main_t *hcm = &hcc_main;
+
+  HCC_DBG ("transport closed");
+
+  vlib_process_signal_event_mt (hcm->vlib_main, hcm->cli_node_index,
+                               HCC_TRANSPORT_CLOSED, 0);
+}
+
 static session_cb_vft_t hcc_session_cb_vft = {
   .session_accept_callback = hcc_ts_accept_callback,
   .session_disconnect_callback = hcc_ts_disconnect_callback,
@@ -281,6 +291,7 @@ static session_cb_vft_t hcc_session_cb_vft = {
   .builtin_app_tx_callback = hcc_ts_tx_callback,
   .session_reset_callback = hcc_ts_reset_callback,
   .session_cleanup_callback = hcc_ts_cleanup_callback,
+  .session_transport_closed_callback = hcc_ts_transport_closed,
 };
 
 static clib_error_t *
@@ -370,7 +381,7 @@ hcc_connect ()
 }
 
 static clib_error_t *
-hcc_run (vlib_main_t *vm)
+hcc_run (vlib_main_t *vm, int print_output)
 {
   vlib_thread_main_t *vtm = vlib_get_thread_main ();
   hcc_main_t *hcm = &hcc_main;
@@ -407,9 +418,13 @@ hcc_run (vlib_main_t *vm)
       goto cleanup;
 
     case HCC_REPLY_RECEIVED:
-      vlib_cli_output (vm, "%v", hcm->http_response);
+      if (print_output)
+       vlib_cli_output (vm, "%v", hcm->http_response);
       vec_free (hcm->http_response);
       break;
+    case HCC_TRANSPORT_CLOSED:
+      err = clib_error_return (0, "error, transport closed");
+      break;
     default:
       err = clib_error_return (0, "unexpected event %d", event_type);
       break;
@@ -448,7 +463,7 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input,
   u64 seg_size;
   u8 *appns_id = 0;
   clib_error_t *err = 0;
-  int rv;
+  int rv, print_output = 1;
 
   hcm->prealloc_fifos = 0;
   hcm->private_segment_size = 0;
@@ -472,6 +487,8 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input,
        hcm->fifo_size <<= 10;
       else if (unformat (line_input, "uri %s", &hcm->uri))
        ;
+      else if (unformat (line_input, "no-output"))
+       print_output = 0;
       else if (unformat (line_input, "appns %_%v%_", &appns_id))
        ;
       else if (unformat (line_input, "secret %lu", &hcm->appns_secret))
@@ -506,7 +523,7 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input,
   vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */);
   vlib_worker_thread_barrier_release (vm);
 
-  err = hcc_run (vm);
+  err = hcc_run (vm, print_output);
 
   if (hcc_detach ())
     {
@@ -526,7 +543,7 @@ done:
 VLIB_CLI_COMMAND (hcc_command, static) = {
   .path = "http cli client",
   .short_help = "[appns <app-ns> secret <appns-secret>] uri http://<ip-addr> "
-               "query <query-string>",
+               "query <query-string> [no-output]",
   .function = hcc_command_fn,
   .is_mp_safe = 1,
 };
index 036e692..855ab8d 100644 (file)
@@ -74,14 +74,14 @@ format_http_state (u8 *s, va_list *va)
   return format (s, "unknown");
 }
 
-static inline void
-http_state_change (http_conn_t *hc, http_state_t state)
-{
-  HTTP_DBG (1, "changing http state %U -> %U", format_http_state,
-           hc->http_state, format_http_state, state);
-  ASSERT (hc->http_state != state);
-  hc->http_state = state;
-}
+#define http_state_change(_hc, _state)                                        \
+  do                                                                          \
+    {                                                                         \
+      HTTP_DBG (1, "changing http state %U -> %U", format_http_state,         \
+               (_hc)->http_state, format_http_state, _state);                \
+      (_hc)->http_state = _state;                                             \
+    }                                                                         \
+  while (0)
 
 static inline http_worker_t *
 http_worker_get (u32 thread_index)
@@ -140,6 +140,7 @@ http_listener_free (http_conn_t *lhc)
 {
   http_main_t *hm = &http_main;
 
+  vec_free (lhc->app_name);
   if (CLIB_DEBUG)
     memset (lhc, 0xfc, sizeof (*lhc));
   pool_put (hm->listener_pool, lhc);
@@ -372,7 +373,7 @@ static const char *http_redirect_template = "HTTP/1.1 %s\r\n";
 static const char *http_response_template = "HTTP/1.1 %s\r\n"
                                            "Date: %U GMT\r\n"
                                            "Expires: %U GMT\r\n"
-                                           "Server: VPP Static\r\n"
+                                           "Server: %s\r\n"
                                            "Content-Type: %s\r\n"
                                            "Content-Length: %lu\r\n\r\n";
 
@@ -577,7 +578,7 @@ http_state_wait_server_reply (http_conn_t *hc, transport_send_params_t *sp)
        {
          hc->rx_buf_offset = 0;
          vec_reset_length (hc->rx_buf);
-         http_state_change (hc, HTTP_STATE_WAIT_CLIENT_METHOD);
+         http_state_change (hc, HTTP_STATE_WAIT_APP_METHOD);
        }
       else
        {
@@ -585,7 +586,8 @@ http_state_wait_server_reply (http_conn_t *hc, transport_send_params_t *sp)
        }
 
       app_wrk = app_worker_get_if_valid (as->app_wrk_index);
-      app_worker_rx_notify (app_wrk, as);
+      if (app_wrk)
+       app_worker_rx_notify (app_wrk, as);
       return HTTP_SM_STOP;
     }
   else
@@ -594,10 +596,8 @@ http_state_wait_server_reply (http_conn_t *hc, transport_send_params_t *sp)
       ec = HTTP_STATUS_METHOD_NOT_ALLOWED;
       goto error;
     }
-  return HTTP_SM_STOP;
 
 error:
-
   http_send_error (hc, ec);
   session_transport_closing_notify (&hc->connection);
   http_disconnect_transport (hc);
@@ -734,6 +734,7 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp)
    * Add headers. For now:
    * - current time
    * - expiration time
+   * - server name
    * - content type
    * - data length
    */
@@ -748,6 +749,8 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp)
                format_clib_timebase_time, now,
                /* Expires */
                format_clib_timebase_time, now + 600.0,
+               /* Server */
+               hc->app_name,
                /* Content type */
                http_content_type_str[msg.content_type],
                /* Length */
@@ -791,7 +794,6 @@ error:
 static http_sm_result_t
 http_state_wait_app_method (http_conn_t *hc, transport_send_params_t *sp)
 {
-  http_status_code_t sc;
   http_msg_t msg;
   session_t *as;
   u8 *buf = 0, *request;
@@ -806,19 +808,15 @@ http_state_wait_app_method (http_conn_t *hc, transport_send_params_t *sp)
   if (msg.data.type > HTTP_MSG_DATA_PTR)
     {
       clib_warning ("no data");
-      sc = HTTP_STATUS_INTERNAL_ERROR;
       goto error;
     }
 
   if (msg.type != HTTP_MSG_REQUEST)
     {
       clib_warning ("unexpected message type %d", msg.type);
-      sc = HTTP_STATUS_INTERNAL_ERROR;
       goto error;
     }
 
-  sc = msg.code;
-
   vec_validate (buf, msg.data.len - 1);
   rv = svm_fifo_dequeue (as->tx_fifo, msg.data.len, buf);
   ASSERT (rv == msg.data.len);
@@ -828,7 +826,6 @@ http_state_wait_app_method (http_conn_t *hc, transport_send_params_t *sp)
   if (offset != vec_len (request))
     {
       clib_warning ("sending request failed!");
-      sc = HTTP_STATUS_INTERNAL_ERROR;
       goto error;
     }
 
@@ -837,83 +834,85 @@ http_state_wait_app_method (http_conn_t *hc, transport_send_params_t *sp)
   vec_free (buf);
   vec_free (request);
 
-  return HTTP_SM_CONTINUE;
+  return HTTP_SM_STOP;
 
 error:
-  clib_warning ("unexpected msg type from app %u", msg.type);
-  http_send_error (hc, sc);
+  svm_fifo_dequeue_drop_all (as->tx_fifo);
   session_transport_closing_notify (&hc->connection);
+  session_transport_closed_notify (&hc->connection);
   http_disconnect_transport (hc);
-  return HTTP_SM_STOP;
-}
-
-static void
-http_app_enqueue (http_conn_t *hc, session_t *as)
-{
-  app_worker_t *app_wrk;
-  u32 dlen, max_enq, n_enq;
-  int rv;
-
-  dlen = vec_len (hc->rx_buf) - hc->rx_buf_offset;
-  if (!dlen)
-    return;
-
-  max_enq = svm_fifo_max_enqueue (as->rx_fifo);
-  n_enq = clib_min (max_enq, dlen);
-  rv = svm_fifo_enqueue (as->rx_fifo, n_enq, &hc->rx_buf[hc->rx_buf_offset]);
-  if (rv < 0)
-    return;
-
-  hc->rx_buf_offset += rv;
-  if (hc->rx_buf_offset >= vec_len (hc->rx_buf))
-    {
-      vec_reset_length (hc->rx_buf);
-      hc->rx_buf_offset = 0;
-    }
-
-  app_wrk = app_worker_get_if_valid (as->app_wrk_index);
-  ASSERT (app_wrk);
-  app_worker_rx_notify (app_wrk, as);
+  return HTTP_SM_ERROR;
 }
 
 static http_sm_result_t
 http_state_client_io_more_data (http_conn_t *hc, transport_send_params_t *sp)
 {
   session_t *as, *ts;
-  u32 max_deq;
-  int n_read;
+  app_worker_t *app_wrk;
+  svm_fifo_seg_t _seg, *seg = &_seg;
+  u32 max_len, max_deq, max_enq, n_segs = 1;
+  int rv, len;
 
   as = session_get_from_handle (hc->h_pa_session_handle);
   ts = session_get_from_handle (hc->h_tc_session_handle);
 
-  http_app_enqueue (hc, as);
+  max_deq = svm_fifo_max_dequeue (ts->rx_fifo);
+  if (max_deq == 0)
+    {
+      HTTP_DBG (1, "no data to deq");
+      return HTTP_SM_STOP;
+    }
 
-  if (hc->to_recv == 0)
+  max_enq = svm_fifo_max_enqueue (as->rx_fifo);
+  if (max_enq == 0)
     {
-      http_state_change (hc, HTTP_STATE_WAIT_CLIENT_METHOD);
+      HTTP_DBG (1, "app's rx fifo full");
+      svm_fifo_add_want_deq_ntf (as->rx_fifo, SVM_FIFO_WANT_DEQ_NOTIF);
       return HTTP_SM_STOP;
     }
 
-  max_deq = svm_fifo_max_dequeue (ts->rx_fifo);
-  if (max_deq > 0)
+  max_len = clib_min (max_enq, max_deq);
+  len = svm_fifo_segments (ts->rx_fifo, 0, seg, &n_segs, max_len);
+  if (len < 0)
     {
-      vec_validate (hc->rx_buf, max_deq - 1);
-      n_read = svm_fifo_dequeue (ts->rx_fifo, max_deq, hc->rx_buf);
-      ASSERT (n_read == max_deq);
+      HTTP_DBG (1, "svm_fifo_segments() len %d", len);
+      return HTTP_SM_STOP;
+    }
 
-      if (svm_fifo_is_empty (ts->rx_fifo))
-       svm_fifo_unset_event (ts->rx_fifo);
+  rv = svm_fifo_enqueue_segments (as->rx_fifo, seg, 1, 0 /* allow partial */);
+  if (rv < 0)
+    {
+      clib_warning ("data enqueue failed, rv: %d", rv);
+      return HTTP_SM_ERROR;
+    }
 
-      hc->to_recv -= n_read;
-      vec_set_len (hc->rx_buf, n_read);
+  svm_fifo_dequeue_drop (ts->rx_fifo, rv);
+  if (rv > hc->to_recv)
+    {
+      clib_warning ("http protocol error: received more data than expected");
+      session_transport_closing_notify (&hc->connection);
+      http_disconnect_transport (hc);
+      http_state_change (hc, HTTP_STATE_WAIT_APP_METHOD);
+      return HTTP_SM_ERROR;
     }
+  hc->to_recv -= rv;
+  HTTP_DBG (1, "drained %d from ts; remains %d", rv, hc->to_recv);
 
-  if (hc->rx_buf_offset < vec_len (hc->rx_buf) ||
-      svm_fifo_max_dequeue_cons (ts->rx_fifo))
+  if (hc->to_recv == 0)
     {
-       session_enqueue_notify (ts);
+      hc->rx_buf_offset = 0;
+      vec_reset_length (hc->rx_buf);
+      http_state_change (hc, HTTP_STATE_WAIT_APP_METHOD);
     }
-  return HTTP_SM_CONTINUE;
+
+  app_wrk = app_worker_get_if_valid (as->app_wrk_index);
+  if (app_wrk)
+    app_worker_rx_notify (app_wrk, as);
+
+  if (svm_fifo_max_dequeue_cons (ts->rx_fifo))
+    session_enqueue_notify (ts);
+
+  return HTTP_SM_STOP;
 }
 
 static http_sm_result_t
@@ -983,6 +982,7 @@ static void
 http_req_run_state_machine (http_conn_t *hc, transport_send_params_t *sp)
 {
   http_sm_result_t res;
+
   do
     {
       res = state_funcs[hc->http_state](hc, sp);
@@ -1010,6 +1010,12 @@ http_ts_rx_callback (session_t *ts)
       return -1;
     }
 
+  if (hc->state == HTTP_CONN_STATE_CLOSED)
+    {
+      svm_fifo_dequeue_drop_all (ts->tx_fifo);
+      return 0;
+    }
+
   http_req_run_state_machine (hc, 0);
 
   if (hc->state == HTTP_CONN_STATE_TRANSPORT_CLOSED)
@@ -1205,6 +1211,11 @@ http_start_listen (u32 app_listener_index, transport_endpoint_cfg_t *tep)
   lhc->c_s_index = app_listener_index;
   lhc->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP;
 
+  if (vec_len (app->name))
+    lhc->app_name = vec_dup (app->name);
+  else
+    lhc->app_name = format (0, "VPP server app");
+
   return lhc_index;
 }
 
@@ -1245,7 +1256,11 @@ http_transport_close (u32 hc_index, u32 thread_index)
       http_disconnect_transport (hc);
       return;
     }
-
+  else if (hc->state == HTTP_CONN_STATE_CLOSED)
+    {
+      HTTP_DBG (1, "nothing to do, already closed");
+      return;
+    }
   as = session_get_from_handle (hc->h_pa_session_handle);
 
   /* Nothing more to send, confirm close */
index dbae5ac..c9912dd 100644 (file)
@@ -227,6 +227,7 @@ typedef struct http_tc_
 
   http_conn_state_t state;
   u32 timer_handle;
+  u8 *app_name;
 
   /*
    * Current request
index a3e7166..c9608aa 100644 (file)
@@ -173,7 +173,7 @@ send_profile (ikev2_profile_t * profile, vl_api_registration_t * reg,
   rmp->profile.lifetime_jitter = profile->lifetime_jitter;
   rmp->profile.handover = profile->handover;
 
-  vl_api_ikev2_profile_t_endian (&rmp->profile);
+  vl_api_ikev2_profile_t_endian (&rmp->profile, 1 /* to network */);
 
   vl_api_send_msg (reg, (u8 *) rmp);
 }
@@ -291,7 +291,7 @@ send_sa (ikev2_sa_t * sa, vl_api_ikev2_sa_dump_t * mp, u32 api_sa_index)
 
     ikev2_copy_stats (&rsa->stats, &sa->stats);
 
-    vl_api_ikev2_sa_t_endian(rsa);
+    vl_api_ikev2_sa_t_endian (rsa, 1 /* to network */);
   });
 }
 
@@ -382,7 +382,7 @@ send_sa_v2 (ikev2_sa_t *sa, vl_api_ikev2_sa_v2_dump_t *mp, u32 api_sa_index)
 
     ikev2_copy_stats (&rsa->stats, &sa->stats);
 
-    vl_api_ikev2_sa_v2_t_endian (rsa);
+    vl_api_ikev2_sa_v2_t_endian (rsa, 1 /* to network */);
   });
 }
 
@@ -476,7 +476,7 @@ send_sa_v3 (ikev2_sa_t *sa, vl_api_ikev2_sa_v3_dump_t *mp, u32 api_sa_index)
 
     ikev2_copy_stats (&rsa->stats, &sa->stats);
 
-    vl_api_ikev2_sa_v3_t_endian (rsa);
+    vl_api_ikev2_sa_v3_t_endian (rsa, 1 /* to network */);
   });
 }
 
@@ -549,7 +549,7 @@ send_child_sa (ikev2_child_sa_t * child,
                     k->sk_ar_len);
       }
 
-    vl_api_ikev2_child_sa_t_endian (&rmp->child_sa);
+    vl_api_ikev2_child_sa_t_endian (&rmp->child_sa, 1 /* to network */);
   });
 }
 
@@ -628,7 +628,7 @@ send_child_sa_v2 (ikev2_child_sa_t *child, vl_api_ikev2_child_sa_v2_dump_t *mp,
        clib_memcpy (&k->sk_ar, child->sk_ar, k->sk_ar_len);
       }
 
-    vl_api_ikev2_child_sa_v2_t_endian (&rmp->child_sa);
+    vl_api_ikev2_child_sa_v2_t_endian (&rmp->child_sa, 1 /* to network */);
   });
 }
 
@@ -700,7 +700,7 @@ static void
       rmp->ts.sa_index = api_sa_index;
       rmp->ts.child_sa_index = child_sa_index;
       cp_ts (&rmp->ts, ts, mp->is_initiator);
-      vl_api_ikev2_ts_t_endian (&rmp->ts);
+      vl_api_ikev2_ts_t_endian (&rmp->ts, 1 /* to network */);
     });
   }
 }
index 5682d70..93683a5 100644 (file)
@@ -391,7 +391,7 @@ vl_api_ikev2_sa_details_t_handler (vl_api_ikev2_sa_details_t * mp)
   ip_address_t iaddr;
   ip_address_t raddr;
   vl_api_ikev2_keys_t *k = &sa->keys;
-  vl_api_ikev2_sa_t_endian (sa);
+  vl_api_ikev2_sa_t_endian (sa, 0 /* from network */);
 
   ip_address_decode2 (&sa->iaddr, &iaddr);
   ip_address_decode2 (&sa->raddr, &raddr);
@@ -461,7 +461,7 @@ vl_api_ikev2_sa_v2_details_t_handler (vl_api_ikev2_sa_v2_details_t *mp)
   ip_address_t iaddr;
   ip_address_t raddr;
   vl_api_ikev2_keys_t *k = &sa->keys;
-  vl_api_ikev2_sa_v2_t_endian (sa);
+  vl_api_ikev2_sa_v2_t_endian (sa, 0 /* from network */);
 
   ip_address_decode2 (&sa->iaddr, &iaddr);
   ip_address_decode2 (&sa->raddr, &raddr);
@@ -533,7 +533,7 @@ vl_api_ikev2_sa_v3_details_t_handler (vl_api_ikev2_sa_v3_details_t *mp)
   ip_address_t iaddr;
   ip_address_t raddr;
   vl_api_ikev2_keys_t *k = &sa->keys;
-  vl_api_ikev2_sa_v3_t_endian (sa);
+  vl_api_ikev2_sa_v3_t_endian (sa, 0 /* from network */);
 
   ip_address_decode2 (&sa->iaddr, &iaddr);
   ip_address_decode2 (&sa->raddr, &raddr);
@@ -619,7 +619,7 @@ vl_api_ikev2_child_sa_details_t_handler (vl_api_ikev2_child_sa_details_t * mp)
   vat_main_t *vam = ikev2_test_main.vat_main;
   vl_api_ikev2_child_sa_t *child_sa = &mp->child_sa;
   vl_api_ikev2_keys_t *k = &child_sa->keys;
-  vl_api_ikev2_child_sa_t_endian (child_sa);
+  vl_api_ikev2_child_sa_t_endian (child_sa, 0 /* from network */);
 
   fformat (vam->ofp, "  child sa %u:\n", child_sa->child_sa_index);
 
@@ -696,7 +696,7 @@ vl_api_ikev2_child_sa_v2_details_t_handler (
   vat_main_t *vam = ikev2_test_main.vat_main;
   vl_api_ikev2_child_sa_t *child_sa = &mp->child_sa;
   vl_api_ikev2_keys_t *k = &child_sa->keys;
-  vl_api_ikev2_child_sa_t_endian (child_sa);
+  vl_api_ikev2_child_sa_t_endian (child_sa, 0 /* from network */);
 
   fformat (vam->ofp, "  child sa %u:\n", child_sa->child_sa_index);
 
@@ -784,7 +784,7 @@ static void
   vat_main_t *vam = ikev2_test_main.vat_main;
   vl_api_ikev2_ts_t *ts = &mp->ts;
   ip_address_t start_addr, end_addr;
-  vl_api_ikev2_ts_t_endian (ts);
+  vl_api_ikev2_ts_t_endian (ts, 0 /* from network */);
 
   ip_address_decode2 (&ts->start_addr, &start_addr);
   ip_address_decode2 (&ts->end_addr, &end_addr);
index 1f01410..b6c9d51 100644 (file)
@@ -442,7 +442,8 @@ send_nat44_ed_output_interface_details (u32 index, vl_api_registration_t *rp,
 
       /* Endian hack until apigen registers _details
        * endian functions */
-      vl_api_nat44_ed_output_interface_details_t_endian (rmp);
+      vl_api_nat44_ed_output_interface_details_t_endian (rmp,
+                                                        1 /* to network */);
       rmp->_vl_msg_id = htons (rmp->_vl_msg_id);
       rmp->context = htonl (rmp->context);
     }));
index 8671a55..454a503 100644 (file)
@@ -751,7 +751,8 @@ send_nat44_ei_output_interface_details (u32 index, vl_api_registration_t *rp,
 
       /* Endian hack until apigen registers _details
        * endian functions */
-      vl_api_nat44_ei_output_interface_details_t_endian (rmp);
+      vl_api_nat44_ei_output_interface_details_t_endian (rmp,
+                                                        1 /* to network */);
       rmp->_vl_msg_id = htons (rmp->_vl_msg_id);
       rmp->context = htonl (rmp->context);
     }));
index 02e6121..a4e7ff1 100644 (file)
@@ -116,7 +116,8 @@ static void send_bindings_details(u32 index, vl_api_registration_t *rp,
 
                              /* Endian hack until apigen registers _details
                               * endian functions */
-                             vl_api_pnat_bindings_details_t_endian(rmp);
+                             vl_api_pnat_bindings_details_t_endian(
+                                 rmp, 1 /* to network */);
                              rmp->_vl_msg_id = htons(rmp->_vl_msg_id);
                              rmp->context = htonl(rmp->context);
                          }));
@@ -158,7 +159,7 @@ static void send_interfaces_details(u32 index, vl_api_registration_t *rp,
 
             /* Endian hack until apigen registers _details
              * endian functions */
-            vl_api_pnat_interfaces_details_t_endian(rmp);
+            vl_api_pnat_interfaces_details_t_endian(rmp, 1 /* to network */);
             rmp->_vl_msg_id = htons(rmp->_vl_msg_id);
             rmp->context = htonl(rmp->context);
         }));
index 54eb742..43c6143 100644 (file)
@@ -96,12 +96,94 @@ GSO_TEST_REGISTER_DATA (gso_ipv6_tcp, static) = {
   .is_ip6 = 1,
 };
 
+/*
+ * this does not support tunnel packets
+ */
+static void
+set_hdr_offsets (vlib_buffer_t *b0, u8 is_l2)
+{
+  u16 ethertype = 0, l2hdr_sz = 0;
+  vnet_buffer_oflags_t oflags = 0;
+  u8 l4_proto = 0;
+
+  if (!is_l2)
+    {
+      switch (b0->data[0] & 0xf0)
+       {
+       case 0x40:
+         ethertype = ETHERNET_TYPE_IP4;
+         break;
+       case 0x60:
+         ethertype = ETHERNET_TYPE_IP6;
+         break;
+       }
+    }
+  else
+    {
+      ethernet_header_t *eh = (ethernet_header_t *) b0->data;
+      ethertype = clib_net_to_host_u16 (eh->type);
+      l2hdr_sz = sizeof (ethernet_header_t);
+
+      if (ethernet_frame_is_tagged (ethertype))
+       {
+         ethernet_vlan_header_t *vlan = (ethernet_vlan_header_t *) (eh + 1);
+
+         ethertype = clib_net_to_host_u16 (vlan->type);
+         l2hdr_sz += sizeof (*vlan);
+         if (ethertype == ETHERNET_TYPE_VLAN)
+           {
+             vlan++;
+             ethertype = clib_net_to_host_u16 (vlan->type);
+             l2hdr_sz += sizeof (*vlan);
+           }
+       }
+    }
+
+  vnet_buffer (b0)->l2_hdr_offset = 0;
+  vnet_buffer (b0)->l3_hdr_offset = l2hdr_sz;
+
+  if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP4))
+    {
+      ip4_header_t *ip4 = (ip4_header_t *) (b0->data + l2hdr_sz);
+      vnet_buffer (b0)->l4_hdr_offset = l2hdr_sz + ip4_header_bytes (ip4);
+      l4_proto = ip4->protocol;
+      oflags |= VNET_BUFFER_OFFLOAD_F_IP_CKSUM;
+      b0->flags |= (VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
+                   VNET_BUFFER_F_L3_HDR_OFFSET_VALID |
+                   VNET_BUFFER_F_L4_HDR_OFFSET_VALID);
+    }
+  else if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP6))
+    {
+      ip6_header_t *ip6 = (ip6_header_t *) (b0->data + l2hdr_sz);
+      vnet_buffer (b0)->l4_hdr_offset = l2hdr_sz + sizeof (ip6_header_t);
+      /* FIXME IPv6 EH traversal */
+      l4_proto = ip6->protocol;
+      b0->flags |= (VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
+                   VNET_BUFFER_F_L3_HDR_OFFSET_VALID |
+                   VNET_BUFFER_F_L4_HDR_OFFSET_VALID);
+    }
+  if (l4_proto == IP_PROTOCOL_TCP)
+    {
+      oflags |= VNET_BUFFER_OFFLOAD_F_TCP_CKSUM;
+    }
+  else if (l4_proto == IP_PROTOCOL_UDP)
+    {
+      oflags |= VNET_BUFFER_OFFLOAD_F_UDP_CKSUM;
+    }
+  if (oflags)
+    vnet_buffer_offload_flags_set (b0, oflags);
+}
+
 static u32
-fill_buffers (vlib_main_t *vm, u32 *buffer_indices, u8 *data, u32 data_size,
-             u32 n_buffers, u32 buffer_size, u32 packet_size, u32 gso_size,
-             u32 l4_hdr_len)
+fill_buffers (vlib_main_t *vm, u32 *buffer_indices,
+             gso_test_data_t *gso_test_data, u32 n_buffers, u32 buffer_size,
+             u32 packet_size, u32 gso_size)
 {
   u32 i;
+  u8 *data = gso_test_data->data;
+  u32 data_size = gso_test_data->data_size;
+  u32 l4_hdr_len = gso_test_data->l4_hdr_len;
+  u8 is_l2 = gso_test_data->is_l2;
 
   for (i = 0; i < n_buffers; i++)
     {
@@ -153,6 +235,8 @@ fill_buffers (vlib_main_t *vm, u32 *buffer_indices, u8 *data, u32 data_size,
              len += fill_data_size;
            }
          while (k < n_bufs);
+
+         set_hdr_offsets (b, is_l2);
          b->flags |= VNET_BUFFER_F_GSO;
          vnet_buffer2 (b)->gso_size = gso_size;
          vnet_buffer2 (b)->gso_l4_hdr_sz = l4_hdr_len;
@@ -165,17 +249,14 @@ fill_buffers (vlib_main_t *vm, u32 *buffer_indices, u8 *data, u32 data_size,
 
 static_always_inline u32
 gso_segment_buffer_test (vlib_main_t *vm, u32 bi,
-                        vnet_interface_per_thread_data_t *ptd, u8 is_l2,
-                        u8 is_ip6)
+                        vnet_interface_per_thread_data_t *ptd, u8 is_l2)
 {
   vlib_buffer_t *b = vlib_get_buffer (vm, bi);
-  generic_header_offset_t gho = { 0 };
   u32 n_tx_bytes = 0;
 
   if (PREDICT_TRUE (b->flags & VNET_BUFFER_F_GSO))
     {
-      vnet_generic_header_offset_parser (b, &gho, is_l2, !is_ip6, is_ip6);
-      n_tx_bytes = gso_segment_buffer_inline (vm, ptd, b, &gho, is_l2, is_ip6);
+      n_tx_bytes = gso_segment_buffer_inline (vm, ptd, b, is_l2);
     }
 
   return n_tx_bytes;
@@ -237,19 +318,16 @@ test_gso_perf (vlib_main_t *vm, gso_test_main_t *gtm)
          vlib_buffer_free (vm, buffer_indices, n_alloc);
          goto done;
        }
-      n_filled =
-       fill_buffers (vm, buffer_indices, gso_test_data->data,
-                     gso_test_data->data_size, n_buffers, buffer_size,
-                     packet_size, gso_size, gso_test_data->l4_hdr_len);
+      n_filled = fill_buffers (vm, buffer_indices, gso_test_data, n_buffers,
+                              buffer_size, packet_size, gso_size);
 
       u8 is_l2 = gso_test_data->is_l2;
-      u8 is_ip6 = gso_test_data->is_ip6;
 
       for (k = 0; k < warmup_rounds; k++)
        {
          for (j = 0; j < n_filled; j++)
-           gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j], is_l2,
-                                    is_ip6);
+           gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j], is_l2);
+
          for (j = 0; j < n_filled; j++)
            {
              vlib_buffer_free (vm, ptd[j].split_buffers,
@@ -264,8 +342,9 @@ test_gso_perf (vlib_main_t *vm, gso_test_main_t *gtm)
            {
              t0 = clib_cpu_time_now ();
              for (j = 0; j < n_filled; j++)
-               gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j], is_l2,
-                                        is_ip6);
+               gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j],
+                                        is_l2);
+
              t1 = clib_cpu_time_now ();
              t2[i] += (t1 - t0);
              for (j = 0; j < n_filled; j++)
index 2b14bf6..41f7699 100644 (file)
@@ -21,7 +21,7 @@ policer_test (vlib_main_t *vm, unformat_input_t *input,
              vlib_cli_command_t *cmd_arg)
 {
   int policer_index, i;
-  uint rate_kbps, burst, num_pkts;
+  unsigned int rate_kbps, burst, num_pkts;
   double total_bytes, cpu_ticks_per_pkt, time = 0;
   double cpu_speed, cpu_ticks_per_byte;
   policer_result_e result, input_colour = POLICE_CONFORM;
index fb7de0a..c2e1e7d 100755 (executable)
@@ -365,7 +365,7 @@ class FromJSON:
             write("    char *p = cJSON_GetStringValue(item);\n")
             write("    size_t plen = strlen(p);\n")
             write(
-                "    {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen, {msgsize});\n".format(
+                "    {msgvar} = cJSON_realloc({msgvar}, {msgsize} + plen);\n".format(
                     msgvar=msgvar, msgsize=msgsize
                 )
             )
@@ -434,7 +434,7 @@ class FromJSON:
         cJSON *array = cJSON_GetObjectItem(o, "{n}");
         int size = cJSON_GetArraySize(array);
         {lfield} = size;
-        {realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size, {msgsize});
+        {realloc} = cJSON_realloc({realloc}, {msgsize} + sizeof({t}) * size);
         {t} *d = (void *){realloc} + {msgsize};
         {msgsize} += sizeof({t}) * size;
         for (i = 0; i < size; i++) {{
@@ -461,12 +461,12 @@ class FromJSON:
 
                 write(
                     "    {realloc} = cJSON_realloc({realloc}, {msgsize} + "
-                    "vec_len(s), {msgsize});\n".format(
+                    "vec_len(s));\n".format(
                         msgvar=msgvar, msgsize=msgsize, realloc=realloc
                     )
                 )
                 write(
-                    "    memcpy((void *){realloc} + {msgsize}, s, "
+                    "    clib_memcpy((void *){realloc} + {msgsize}, s, "
                     "vec_len(s));\n".format(realloc=realloc, msgsize=msgsize)
                 )
                 write("    {msgsize} += vec_len(s);\n".format(msgsize=msgsize))
@@ -1143,20 +1143,14 @@ ENDIAN_STRINGS = {
 }
 
 
-def get_endian_string(o, type):
+def get_endian_string(o, fieldtype):
     """Return proper endian string conversion function"""
-    try:
-        if o.to_network:
-            return ENDIAN_STRINGS[type].replace("net_to_host", "host_to_net")
-    except:
-        pass
-    return ENDIAN_STRINGS[type]
+    return ENDIAN_STRINGS[fieldtype]
 
 
 def endianfun_array(o):
     """Generate endian functions for arrays"""
     forloop = """\
-    {comment}
     ASSERT((u32){length} <= (u32)VL_API_MAX_ARRAY_SIZE);
     for (i = 0; i < {length}; i++) {{
         a->{name}[i] = {format}(a->{name}[i]);
@@ -1165,31 +1159,26 @@ def endianfun_array(o):
 
     forloop_format = """\
     for (i = 0; i < {length}; i++) {{
-        {type}_endian(&a->{name}[i]);
+        {type}_endian(&a->{name}[i], to_net);
     }}
 """
 
-    to_network_comment = ""
-    try:
-        if o.to_network:
-            to_network_comment = """/*
-     * Array fields processed first to handle variable length arrays and size
-     * field endian conversion in the proper order for to-network messages.
-     * Message fields have been sorted by type in the code generator, thus fields
-     * in this generated code may be converted in a different order than specified
-     * in the *.api file.
-     */"""
-    except:
-        pass
-
     output = ""
     if o.fieldtype == "u8" or o.fieldtype == "string" or o.fieldtype == "bool":
         output += "    /* a->{n} = a->{n} (no-op) */\n".format(n=o.fieldname)
     else:
         lfield = "a->" + o.lengthfield if o.lengthfield else o.length
+        if o.lengthfield:
+            output += (
+                f"    u32 count = to_net ? clib_host_to_net_u32(a->{o.lengthfield}) : "
+                f"a->{o.lengthfield};\n"
+            )
+            lfield = "count"
+        else:
+            lfield = o.length
+
         if o.fieldtype in ENDIAN_STRINGS:
             output += forloop.format(
-                comment=to_network_comment,
                 length=lfield,
                 format=get_endian_string(o, o.fieldtype),
                 name=o.fieldname,
@@ -1222,7 +1211,7 @@ def endianfun_obj(o):
             name=o.fieldname, format=get_endian_string(o, o.fieldtype)
         )
     elif o.fieldtype.startswith("vl_api_"):
-        output += "    {type}_endian(&a->{name});\n".format(
+        output += "    {type}_endian(&a->{name}, to_net);\n".format(
             type=o.fieldtype, name=o.fieldname
         )
     else:
@@ -1254,19 +1243,12 @@ def endianfun(objs, modulename):
     output = output.format(module=modulename)
 
     signature = """\
-static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
+static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a, bool to_net)
 {{
     int i __attribute__((unused));
 """
 
     for t in objs:
-        # Outbound (to network) messages are identified by message nomenclature
-        # i.e. message names ending with these suffixes are 'to network'
-        if t.name.endswith("_reply") or t.name.endswith("_details"):
-            t.to_network = True
-        else:
-            t.to_network = False
-
         if t.__class__.__name__ == "Enum" or t.__class__.__name__ == "EnumFlag":
             output += signature.format(name=t.name)
             if t.enumtype in ENDIAN_STRINGS:
@@ -1300,15 +1282,7 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
 
         output += signature.format(name=t.name)
 
-        # For outbound (to network) messages:
-        #   some arrays have dynamic length -- iterate over
-        #   them before changing endianness for the length field
-        #   by making the Array types show up first
-        if t.to_network:
-            t.block.sort(key=lambda x: x.type)
-
         for o in t.block:
-            o.to_network = t.to_network
             output += endianfun_obj(o)
         output += "}\n\n"
 
@@ -1852,7 +1826,7 @@ api_{n} (cJSON *o)
   }}
 
   mp->_vl_msg_id = vac_get_msg_index(VL_API_{N}_CRC);
-  vl_api_{n}_t_endian(mp);
+  vl_api_{n}_t_endian(mp, 1);
   vac_write((char *)mp, len);
   cJSON_free(mp);
 
@@ -1867,7 +1841,7 @@ api_{n} (cJSON *o)
     return 0;
   }}
   vl_api_{r}_t *rmp = (vl_api_{r}_t *)p;
-  vl_api_{r}_t_endian(rmp);
+  vl_api_{r}_t_endian(rmp, 0);
   return vl_api_{r}_t_tojson(rmp);
 }}
 
@@ -1885,7 +1859,7 @@ api_{n} (cJSON *o)
       return 0;
   }}
   mp->_vl_msg_id = msg_id;
-  vl_api_{n}_t_endian(mp);
+  vl_api_{n}_t_endian(mp, 1);
   vac_write((char *)mp, len);
   cJSON_free(mp);
 
@@ -1919,7 +1893,7 @@ api_{n} (cJSON *o)
             return 0;
         }}
         vl_api_{r}_t *rmp = (vl_api_{r}_t *)p;
-        vl_api_{r}_t_endian(rmp);
+        vl_api_{r}_t_endian(rmp, 0);
         cJSON_AddItemToArray(reply, vl_api_{r}_t_tojson(rmp));
     }}
   }}
@@ -1941,7 +1915,7 @@ api_{n} (cJSON *o)
   }}
   mp->_vl_msg_id = msg_id;
 
-  vl_api_{n}_t_endian(mp);
+  vl_api_{n}_t_endian(mp, 1);
   vac_write((char *)mp, len);
   cJSON_free(mp);
 
@@ -1962,14 +1936,14 @@ api_{n} (cJSON *o)
     u16 msg_id = ntohs(*((u16 *)p));
     if (msg_id == reply_msg_id) {{
         vl_api_{r}_t *rmp = (vl_api_{r}_t *)p;
-        vl_api_{r}_t_endian(rmp);
+        vl_api_{r}_t_endian(rmp, 0);
         cJSON_AddItemToArray(reply, vl_api_{r}_t_tojson(rmp));
         break;
     }}
 
     if (msg_id == details_msg_id) {{
         vl_api_{d}_t *rmp = (vl_api_{d}_t *)p;
-        vl_api_{d}_t_endian(rmp);
+        vl_api_{d}_t_endian(rmp, 0);
         cJSON_AddItemToArray(reply, vl_api_{d}_t_tojson(rmp));
     }}
   }}
index 7b19760..d9ce2af 100644 (file)
@@ -29,7 +29,7 @@ vat2_control_ping (u32 context)
     vl_api_control_ping_t mp = {0};
     mp._vl_msg_id = vac_get_msg_index(VL_API_CONTROL_PING_CRC);
     mp.context = context;
-    vl_api_control_ping_t_endian(&mp);
+    vl_api_control_ping_t_endian (&mp, 1 /* to network */);
     vac_write((char *)&mp, sizeof(mp));
 }
 
index 58f6ac0..a557093 100644 (file)
@@ -2087,7 +2087,16 @@ read_again:
   ASSERT (rv >= 0);
 
   if (peek)
-    return rv;
+    {
+      /* Request new notifications if more data enqueued */
+      if (rv < n || rv == svm_fifo_max_dequeue_cons (rx_fifo))
+       {
+         if (is_ct)
+           svm_fifo_unset_event (s->rx_fifo);
+         svm_fifo_unset_event (rx_fifo);
+       }
+      return rv;
+    }
 
   n_read += rv;
 
index 7ec9b20..3c354b7 100644 (file)
@@ -55,6 +55,7 @@ install(
 # vlib shared library
 ##############################################################################
 
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
 set(PLATFORM_SOURCES
   linux/pci.c
   linux/vfio.c
@@ -64,6 +65,11 @@ set(PLATFORM_SOURCES
 set(PLATFORM_HEADERS
   linux/vfio.h
 )
+elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
+set(PLATFORM_SOURCES
+  freebsd/pci.c
+)
+endif()
 
 add_vpp_library(vlib
   SOURCES
index 08923be..f7c63bc 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/ethtool.h>
 #include <linux/sockios.h>
 #include <linux/vfio.h>
+#include <limits.h>
 #include <sys/eventfd.h>
 
 #define SYSFS_DEVICES_PCI "/sys/devices/pci"
index 0bc90c5..7284e66 100644 (file)
@@ -119,7 +119,7 @@ vlib_pci_intr_enable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
 {
   const vlib_pci_config_reg_command_t cmd = { .intx_disable = 1 };
   clib_error_t *err;
-  int already_set;
+  int already_set = 0;
 
   err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 0, &already_set);
   log_debug (h, "interrupt%senabled", already_set ? " " : " already ");
@@ -131,7 +131,7 @@ vlib_pci_intr_disable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
 {
   const vlib_pci_config_reg_command_t cmd = { .intx_disable = 1 };
   clib_error_t *err;
-  int already_set;
+  int already_set = 0;
 
   err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 1, &already_set);
   log_debug (h, "interrupt%sdisabled", already_set ? " " : " already ");
@@ -143,7 +143,7 @@ vlib_pci_bus_master_enable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
 {
   const vlib_pci_config_reg_command_t cmd = { .bus_master = 1 };
   clib_error_t *err;
-  int already_set;
+  int already_set = 0;
 
   err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 1, &already_set);
   log_debug (h, "bus-master%senabled", already_set ? " " : " already ");
@@ -155,7 +155,7 @@ vlib_pci_bus_master_disable (vlib_main_t *vm, vlib_pci_dev_handle_t h)
 {
   const vlib_pci_config_reg_command_t cmd = { .bus_master = 1 };
   clib_error_t *err;
-  int already_set;
+  int already_set = 0;
 
   err = _vlib_pci_config_set_control_bit (vm, h, cmd.as_u16, 0, &already_set);
   log_debug (h, "bus-master%sdisabled", already_set ? " " : " already ");
index bbcb4ec..87b71ad 100644 (file)
@@ -182,9 +182,7 @@ vlib_thread_init (vlib_main_t * vm)
   u32 n_vlib_mains = 1;
   u32 first_index = 1;
   u32 i;
-  pid_t pid;
-  uword *avail_cpu, *affinity_cpu;
-  uword n_cpus;
+  uword *avail_cpu;
   u32 stats_num_worker_threads_dir_index;
 
   stats_num_worker_threads_dir_index =
@@ -195,39 +193,16 @@ vlib_thread_init (vlib_main_t * vm)
   tm->cpu_core_bitmap = os_get_online_cpu_core_bitmap ();
   tm->cpu_socket_bitmap = os_get_online_cpu_node_bitmap ();
 
-  /* get bitmap of active cpu cores vpp has affinity to */
-  pid = getpid ();
-  tm->cpu_affinity_bitmap = os_get_cpu_affinity_bitmap (pid);
-
-  /* if fetching affinity fails, return online cpu core bmp */
-  if (tm->cpu_affinity_bitmap == 0)
-    tm->cpu_affinity_bitmap = os_get_online_cpu_core_bitmap ();
-
   avail_cpu = clib_bitmap_dup (tm->cpu_core_bitmap);
-  affinity_cpu = clib_bitmap_dup (tm->cpu_affinity_bitmap);
 
   /* skip cores */
-  n_cpus = clib_bitmap_count_set_bits (avail_cpu);
-  if (tm->skip_cores >= n_cpus)
-    return clib_error_return (0, "skip-core greater than available cpus");
-  n_cpus = clib_bitmap_count_set_bits (affinity_cpu);
-  if (tm->skip_cores >= n_cpus)
-    return clib_error_return (0, "skip-core greater than affinity cpus");
-
   for (i = 0; i < tm->skip_cores; i++)
     {
-      uword c;
-      c = clib_bitmap_first_set (avail_cpu);
+      uword c = clib_bitmap_first_set (avail_cpu);
       if (c == ~0)
        return clib_error_return (0, "no available cpus to skip");
 
       avail_cpu = clib_bitmap_set (avail_cpu, c, 0);
-
-      c = clib_bitmap_first_set (affinity_cpu);
-      if (c == ~0)
-       return clib_error_return (0, "no available env cpus to skip");
-
-      affinity_cpu = clib_bitmap_set (affinity_cpu, c, 0);
     }
 
   /* grab cpu for main thread */
@@ -237,17 +212,6 @@ vlib_thread_init (vlib_main_t * vm)
        return clib_error_return (0, "cpu %u is not available to be used"
                                  " for the main thread", tm->main_lcore);
       avail_cpu = clib_bitmap_set (avail_cpu, tm->main_lcore, 0);
-      affinity_cpu = clib_bitmap_set (affinity_cpu, tm->main_lcore, 0);
-    }
-  /* if auto enabled, grab first cpu vpp has affinity to for main thread */
-  else if (tm->use_main_core_auto)
-    {
-      uword c = clib_bitmap_first_set (affinity_cpu);
-      if (c != ~0)
-       tm->main_lcore = c;
-
-      avail_cpu = clib_bitmap_set (avail_cpu, tm->main_lcore, 0);
-      affinity_cpu = clib_bitmap_set (affinity_cpu, tm->main_lcore, 0);
     }
 
   /* assume that there is socket 0 only if there is no data from sysfs */
@@ -332,23 +296,13 @@ vlib_thread_init (vlib_main_t * vm)
        }
       else
        {
-         /* for automatic pinning, use cpu affinity list */
-         uword n_env_cpu = 0;
-         n_env_cpu = clib_bitmap_count_set_bits (affinity_cpu);
-
-         if (n_env_cpu < tr->count)
-           return clib_error_return (0,
-                                     "no available cpus to be used for"
-                                     " the '%s' thread #%u",
-                                     tr->name, n_env_cpu);
-
          for (j = 0; j < tr->count; j++)
            {
              /* Do not use CPU 0 by default - leave it to the host and IRQs */
-             uword avail_c0 = clib_bitmap_get (affinity_cpu, 0);
-             affinity_cpu = clib_bitmap_set (affinity_cpu, 0, 0);
+             uword avail_c0 = clib_bitmap_get (avail_cpu, 0);
+             avail_cpu = clib_bitmap_set (avail_cpu, 0, 0);
 
-             uword c = clib_bitmap_first_set (affinity_cpu);
+             uword c = clib_bitmap_first_set (avail_cpu);
              /* Use CPU 0 as a last resort */
              if (c == ~0 && avail_c0)
                {
@@ -362,15 +316,14 @@ vlib_thread_init (vlib_main_t * vm)
                                          " the '%s' thread #%u",
                                          tr->name, tr->count);
 
-             affinity_cpu = clib_bitmap_set (affinity_cpu, 0, avail_c0);
-             affinity_cpu = clib_bitmap_set (affinity_cpu, c, 0);
+             avail_cpu = clib_bitmap_set (avail_cpu, 0, avail_c0);
+             avail_cpu = clib_bitmap_set (avail_cpu, c, 0);
              tr->coremask = clib_bitmap_set (tr->coremask, c, 1);
            }
        }
     }
 
   clib_bitmap_free (avail_cpu);
-  clib_bitmap_free (affinity_cpu);
 
   tm->n_vlib_mains = n_vlib_mains;
   vlib_stats_set_gauge (stats_num_worker_threads_dir_index, n_vlib_mains - 1);
@@ -1176,7 +1129,6 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input)
   tm->sched_policy = ~0;
   tm->sched_priority = ~0;
   tm->main_lcore = ~0;
-  tm->use_main_core_auto = 0;
 
   tr = tm->next;
 
@@ -1192,8 +1144,6 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input)
        tm->use_pthreads = 1;
       else if (unformat (input, "thread-prefix %v", &tm->thread_prefix))
        ;
-      else if (unformat (input, "main-core auto"))
-       tm->use_main_core_auto = 1;
       else if (unformat (input, "main-core %u", &tm->main_lcore))
        ;
       else if (unformat (input, "skip-cores %u", &tm->skip_cores))
@@ -1252,13 +1202,6 @@ cpu_config (vlib_main_t * vm, unformat_input_t * input)
        break;
     }
 
-  if (tm->main_lcore != ~0 && tm->use_main_core_auto)
-    {
-      return clib_error_return (
-       0, "cannot set both 'main-core %u' and 'main-core auto'",
-       tm->main_lcore);
-    }
-
   if (tm->sched_priority != ~0)
     {
       if (tm->sched_policy == SCHED_FIFO || tm->sched_policy == SCHED_RR)
index 3072d0e..ac0c1d5 100644 (file)
@@ -255,8 +255,6 @@ typedef struct
 
   int use_pthreads;
 
-  int use_main_core_auto;
-
   /* Number of vlib_main / vnet_main clones */
   u32 n_vlib_mains;
 
@@ -284,9 +282,6 @@ typedef struct
   /* Bitmap of available CPU sockets (NUMA nodes) */
   uword *cpu_socket_bitmap;
 
-  /* Bitmap of CPU affinity for VPP process */
-  uword *cpu_affinity_bitmap;
-
   /* Worker handoff queues */
   vlib_frame_queue_main_t *frame_queue_mains;
 
index fd3a050..5cac9ab 100644 (file)
@@ -306,8 +306,12 @@ process_reg:
     }
   vec_free (version_required);
 
+#if defined(RTLD_DEEPBIND)
   handle = dlopen ((char *) pi->filename,
                   RTLD_LAZY | (reg->deep_bind ? RTLD_DEEPBIND : 0));
+#else
+  handle = dlopen ((char *) pi->filename, RTLD_LAZY);
+#endif
 
   if (handle == 0)
     {
index 62a8d4c..c093341 100644 (file)
@@ -235,8 +235,8 @@ typedef struct
   /** Message convert function vector */
   void *(*fromjson_handler) (cJSON *, int *);
 
-  /** Message endian handler vector */
-  void (*endian_handler) (void *);
+  /** Message endian handler vector. */
+  void (*endian_handler) (void *, bool to_net);
 
   /** Message calc size function vector */
   uword (*calc_size_func) (void *);
index 9c93d33..0380692 100644 (file)
@@ -29,9 +29,9 @@
 
 #define _NATIVE_TO_NETWORK(t, rmp)                                            \
   api_main_t *am = vlibapi_get_main ();                                       \
-  void (*endian_fp) (void *);                                                 \
+  void (*endian_fp) (void *, bool);                                           \
   endian_fp = am->msg_data[t + (REPLY_MSG_ID_BASE)].endian_handler;           \
-  (*endian_fp) (rmp);
+  (*endian_fp) (rmp, 1 /* to network */);
 
 #define REPLY_MACRO(msg)                                                      \
   do                                                                          \
index 7de1906..79064b2 100644 (file)
@@ -230,7 +230,7 @@ vl_msg_api_trace_write_one (api_main_t *am, u8 *msg, FILE *fp)
 
   if (m && m->endian_handler)
     {
-      m->endian_handler (tmpmem);
+      m->endian_handler (tmpmem, 1);
     }
 
   if (m && m->tojson_handler)
@@ -561,7 +561,7 @@ msg_handler_internal (api_main_t *am, void *the_msg, uword msg_len,
            }
 
          if (m->is_autoendian)
-           m->endian_handler (the_msg);
+           m->endian_handler (the_msg, 0);
 
          if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0))
            clib_call_callbacks (am->perf_counter_cbs, am, id,
index d4106b1..b0b0c72 100644 (file)
@@ -197,6 +197,7 @@ vlib_api_init (void)
   cJSON_Hooks cjson_hooks = {
     .malloc_fn = clib_mem_alloc,
     .free_fn = clib_mem_free,
+    .realloc_fn = clib_mem_realloc,
   };
   cJSON_InitHooks (&cjson_hooks);
 
index 39c6b0f..57373b9 100644 (file)
@@ -823,9 +823,9 @@ vl_mem_api_handler_with_vm_node (api_main_t *am, svm_region_t *vlib_rp,
 
       if (m->is_autoendian)
        {
-         void (*endian_fp) (void *);
+         void (*endian_fp) (void *, bool);
          endian_fp = am->msg_data[id].endian_handler;
-         (*endian_fp) (the_msg);
+         (*endian_fp) (the_msg, 0);
        }
       if (PREDICT_FALSE (vec_len (am->perf_counter_cbs) != 0))
        clib_call_callbacks (am->perf_counter_cbs, am, id, 0 /* before */);
index 4492f5a..6ae81cd 100644 (file)
@@ -554,7 +554,7 @@ vl_msg_api_process_file (vlib_main_t * vm, u8 * filename,
            }
          if (m)
            {
-             m->endian_handler (tmpbuf + sizeof (uword));
+             m->endian_handler (tmpbuf + sizeof (uword), 1 /* to network */);
            }
        }
 
@@ -674,7 +674,7 @@ vl_msg_print_trace (u8 *msg, void *ctx)
       clib_memcpy_fast (tmpbuf, msg, msg_length);
       msg = tmpbuf;
 
-      m->endian_handler (tmpbuf);
+      m->endian_handler (tmpbuf, 0 /* from network */);
     }
 
   vlib_cli_output (a->vm, "%U\n",
@@ -824,7 +824,7 @@ vl_msg_exec_json_command (vlib_main_t *vm, cJSON *o)
        }
 
       if (clib_arch_is_little_endian)
-       m->endian_handler (msg);
+       m->endian_handler (msg, 1 /* to network */);
 
       if (!m->handler)
        {
index e2558ee..03cbdde 100644 (file)
@@ -982,8 +982,31 @@ eth_input_process_frame (vlib_main_t * vm, vlib_node_runtime_t * node,
              else
                {
                  for (int j = 0; j < 16; j++)
-                   if (next[j] == 0)
-                     slowpath_indices[n_slowpath++] = i + j;
+                   {
+                     if (next[j] == 0)
+                       slowpath_indices[n_slowpath++] = i + j;
+                     else if (dmac_check && main_is_l3 && dmacs_bad[i + j])
+                       {
+                         next[j] = 0;
+                         slowpath_indices[n_slowpath++] = i + j;
+                       }
+                   }
+               }
+           }
+         else
+           {
+             if (dmac_check && main_is_l3)
+               {
+                 u8x16 dmac_bad = u8x16_load_unaligned (&dmacs_bad[i]);
+                 if (!u8x16_is_all_zero (dmac_bad))
+                   {
+                     for (int j = 0; j < 16; j++)
+                       if (dmacs_bad[i + j])
+                         {
+                           next[j] = 0;
+                           slowpath_indices[n_slowpath++] = i + j;
+                         }
+                   }
                }
            }
 
@@ -994,7 +1017,12 @@ eth_input_process_frame (vlib_main_t * vm, vlib_node_runtime_t * node,
          continue;
        }
 #endif
-      if (main_is_l3 && etype[0] == et_ip4)
+      if (dmac_check && main_is_l3 && dmacs_bad[i])
+       {
+         next[0] = 0;
+         slowpath_indices[n_slowpath++] = i;
+       }
+      else if (main_is_l3 && etype[0] == et_ip4)
        next[0] = next_ip4;
       else if (main_is_l3 && etype[0] == et_ip6)
        next[0] = next_ip6;
@@ -1052,7 +1080,7 @@ eth_input_process_frame (vlib_main_t * vm, vlib_node_runtime_t * node,
            }
          else
            {
-             /* untagged packet with not well known etyertype */
+             /* untagged packet with not well known ethertype */
              if (last_unknown_etype != etype)
                {
                  last_unknown_etype = etype;
index 883a494..dee5da5 100644 (file)
@@ -39,13 +39,13 @@ gso_init_bufs_from_template_base (vlib_buffer_t **bufs, vlib_buffer_t *b0,
                                  u32 flags, u16 n_bufs, u16 hdr_sz)
 {
   u32 i = n_bufs;
-  while (i >= 4)
+  while (i >= 6)
     {
       /* prefetches */
       CLIB_PREFETCH (bufs[2], 2 * CLIB_CACHE_LINE_BYTES, LOAD);
       CLIB_PREFETCH (bufs[3], 2 * CLIB_CACHE_LINE_BYTES, LOAD);
-      vlib_prefetch_buffer_data (bufs[2], LOAD);
-      vlib_prefetch_buffer_data (bufs[3], LOAD);
+      vlib_prefetch_buffer_data (bufs[4], LOAD);
+      vlib_prefetch_buffer_data (bufs[5], LOAD);
 
       /* copying objects from cacheline 0 */
       bufs[0]->current_data = 0;
@@ -70,10 +70,26 @@ gso_init_bufs_from_template_base (vlib_buffer_t **bufs, vlib_buffer_t *b0,
       bufs[0]->total_length_not_including_first_buffer = 0;
       bufs[1]->total_length_not_including_first_buffer = 0;
 
+      clib_memcpy_fast (&bufs[0]->opaque2, &b0->opaque2, sizeof (b0->opaque2));
+      clib_memcpy_fast (&bufs[1]->opaque2, &b0->opaque2, sizeof (b0->opaque2));
+
       /* copying data */
       clib_memcpy_fast (bufs[0]->data, vlib_buffer_get_current (b0), hdr_sz);
       clib_memcpy_fast (bufs[1]->data, vlib_buffer_get_current (b0), hdr_sz);
 
+      /* header offset fixup */
+      vnet_buffer (bufs[0])->l2_hdr_offset -= b0->current_data;
+      vnet_buffer (bufs[0])->l3_hdr_offset -= b0->current_data;
+      vnet_buffer (bufs[0])->l4_hdr_offset -= b0->current_data;
+      vnet_buffer2 (bufs[0])->outer_l3_hdr_offset -= b0->current_data;
+      vnet_buffer2 (bufs[0])->outer_l4_hdr_offset -= b0->current_data;
+
+      vnet_buffer (bufs[1])->l2_hdr_offset -= b0->current_data;
+      vnet_buffer (bufs[1])->l3_hdr_offset -= b0->current_data;
+      vnet_buffer (bufs[1])->l4_hdr_offset -= b0->current_data;
+      vnet_buffer2 (bufs[1])->outer_l3_hdr_offset -= b0->current_data;
+      vnet_buffer2 (bufs[1])->outer_l4_hdr_offset -= b0->current_data;
+
       bufs += 2;
       i -= 2;
     }
@@ -92,10 +108,18 @@ gso_init_bufs_from_template_base (vlib_buffer_t **bufs, vlib_buffer_t *b0,
       /* copying objects from cacheline 1 */
       bufs[0]->trace_handle = b0->trace_handle;
       bufs[0]->total_length_not_including_first_buffer = 0;
+      clib_memcpy_fast (&bufs[0]->opaque2, &b0->opaque2, sizeof (b0->opaque2));
 
       /* copying data */
       clib_memcpy_fast (bufs[0]->data, vlib_buffer_get_current (b0), hdr_sz);
 
+      /* header offset fixup */
+      vnet_buffer (bufs[0])->l2_hdr_offset -= b0->current_data;
+      vnet_buffer (bufs[0])->l3_hdr_offset -= b0->current_data;
+      vnet_buffer (bufs[0])->l4_hdr_offset -= b0->current_data;
+      vnet_buffer2 (bufs[0])->outer_l3_hdr_offset -= b0->current_data;
+      vnet_buffer2 (bufs[0])->outer_l4_hdr_offset -= b0->current_data;
+
       bufs++;
       i--;
     }
@@ -103,28 +127,41 @@ gso_init_bufs_from_template_base (vlib_buffer_t **bufs, vlib_buffer_t *b0,
 
 static_always_inline void
 gso_fixup_segmented_buf (vlib_main_t *vm, vlib_buffer_t *b0, u32 next_tcp_seq,
-                        int is_l2, int is_ip6, generic_header_offset_t *gho,
-                        clib_ip_csum_t *c, u8 tcp_flags)
+                        int is_l2, u8 oflags, u16 hdr_sz, u16 l4_hdr_sz,
+                        clib_ip_csum_t *c, u8 tcp_flags, u8 is_prefetch,
+                        vlib_buffer_t *b1)
 {
 
-  ip4_header_t *ip4 =
-    (ip4_header_t *) (vlib_buffer_get_current (b0) + gho->l3_hdr_offset +
-                     gho->outer_hdr_sz);
-  ip6_header_t *ip6 =
-    (ip6_header_t *) (vlib_buffer_get_current (b0) + gho->l3_hdr_offset +
-                     gho->outer_hdr_sz);
-  tcp_header_t *tcp =
-    (tcp_header_t *) (vlib_buffer_get_current (b0) + gho->l4_hdr_offset +
-                     gho->outer_hdr_sz);
+  i16 l3_hdr_offset = vnet_buffer (b0)->l3_hdr_offset;
+  i16 l4_hdr_offset = vnet_buffer (b0)->l4_hdr_offset;
+
+  ip4_header_t *ip4 = (ip4_header_t *) (b0->data + l3_hdr_offset);
+  ip6_header_t *ip6 = (ip6_header_t *) (b0->data + l3_hdr_offset);
+  tcp_header_t *tcp = (tcp_header_t *) (b0->data + l4_hdr_offset);
 
   tcp->flags = tcp_flags;
   tcp->seq_number = clib_host_to_net_u32 (next_tcp_seq);
   c->odd = 0;
 
-  if (is_ip6)
+  if (oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM)
+    {
+      ip4->length =
+       clib_host_to_net_u16 (b0->current_length - hdr_sz +
+                             (l4_hdr_offset - l3_hdr_offset) + l4_hdr_sz);
+      ip4->checksum = 0;
+      ip4->checksum = ip4_header_checksum (ip4);
+      vnet_buffer_offload_flags_clear (b0, (VNET_BUFFER_OFFLOAD_F_IP_CKSUM |
+                                           VNET_BUFFER_OFFLOAD_F_TCP_CKSUM));
+      c->sum += clib_mem_unaligned (&ip4->src_address, u32);
+      c->sum += clib_mem_unaligned (&ip4->dst_address, u32);
+      c->sum += clib_host_to_net_u32 (
+       (clib_net_to_host_u16 (ip4->length) - ip4_header_bytes (ip4)) +
+       (ip4->protocol << 16));
+    }
+  else
     {
-      ip6->payload_length = clib_host_to_net_u16 (
-       b0->current_length - gho->l4_hdr_offset - gho->outer_hdr_sz);
+      ip6->payload_length =
+       clib_host_to_net_u16 (b0->current_length - hdr_sz + l4_hdr_sz);
       vnet_buffer_offload_flags_clear (b0, VNET_BUFFER_OFFLOAD_F_TCP_CKSUM);
       ip6_psh_t psh = { 0 };
       u32 *p = (u32 *) &psh;
@@ -135,24 +172,15 @@ gso_fixup_segmented_buf (vlib_main_t *vm, vlib_buffer_t *b0, u32 next_tcp_seq,
       for (int i = 0; i < 10; i++)
        c->sum += p[i];
     }
-  else
-    {
-      ip4->length = clib_host_to_net_u16 (
-       b0->current_length - gho->l3_hdr_offset - gho->outer_hdr_sz);
-      if (gho->gho_flags & GHO_F_IP4)
-       ip4->checksum = ip4_header_checksum (ip4);
-      vnet_buffer_offload_flags_clear (b0, (VNET_BUFFER_OFFLOAD_F_IP_CKSUM |
-                                           VNET_BUFFER_OFFLOAD_F_TCP_CKSUM));
-      c->sum += clib_mem_unaligned (&ip4->src_address, u32);
-      c->sum += clib_mem_unaligned (&ip4->dst_address, u32);
-      c->sum += clib_host_to_net_u32 (
-       (clib_net_to_host_u16 (ip4->length) - ip4_header_bytes (ip4)) +
-       (ip4->protocol << 16));
-    }
-  clib_ip_csum_chunk (c, (u8 *) tcp, gho->l4_hdr_sz);
+
+  if (is_prefetch)
+    CLIB_PREFETCH (vlib_buffer_get_current (b1) + hdr_sz,
+                  CLIB_CACHE_LINE_BYTES, LOAD);
+
+  clib_ip_csum_chunk (c, (u8 *) tcp, l4_hdr_sz);
   tcp->checksum = clib_ip_csum_fold (c);
 
-  if (!is_l2 && ((gho->gho_flags & GHO_F_TUNNEL) == 0))
+  if (!is_l2 && ((oflags & VNET_BUFFER_OFFLOAD_F_TNL_MASK) == 0))
     {
       u32 adj_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
 
@@ -169,16 +197,20 @@ gso_fixup_segmented_buf (vlib_main_t *vm, vlib_buffer_t *b0, u32 next_tcp_seq,
 static_always_inline u32
 gso_segment_buffer_inline (vlib_main_t *vm,
                           vnet_interface_per_thread_data_t *ptd,
-                          vlib_buffer_t *b, generic_header_offset_t *gho,
-                          int is_l2, int is_ip6)
+                          vlib_buffer_t *b, int is_l2)
 {
   vlib_buffer_t **bufs = 0;
   u32 n_tx_bytes = 0;
+
+  u8 oflags = vnet_buffer (b)->oflags;
+  i16 l4_hdr_offset = vnet_buffer (b)->l4_hdr_offset;
   u16 gso_size = vnet_buffer2 (b)->gso_size;
+  u16 l4_hdr_sz = vnet_buffer2 (b)->gso_l4_hdr_sz;
+
   u8 tcp_flags = 0, tcp_flags_no_fin_psh = 0;
   u32 default_bflags =
     b->flags & ~(VNET_BUFFER_F_GSO | VLIB_BUFFER_NEXT_PRESENT);
-  u16 hdr_sz = gho->hdr_sz + gho->outer_hdr_sz;
+  u16 hdr_sz = (l4_hdr_offset - b->current_data) + l4_hdr_sz;
   u32 next_tcp_seq = 0, tcp_seq = 0;
   u32 data_size = vlib_buffer_length_in_chain (vm, b) - hdr_sz;
   u16 size =
@@ -200,9 +232,8 @@ gso_segment_buffer_inline (vlib_main_t *vm,
   vec_validate (bufs, n_bufs - 1);
   vlib_get_buffers (vm, ptd->split_buffers, bufs, n_bufs);
 
-  tcp_header_t *tcp =
-    (tcp_header_t *) (vlib_buffer_get_current (b) + gho->l4_hdr_offset +
-                     gho->outer_hdr_sz);
+  tcp_header_t *tcp = (tcp_header_t *) (b->data + l4_hdr_offset);
+
   tcp_seq = next_tcp_seq = clib_net_to_host_u32 (tcp->seq_number);
   /* store original flags for last packet and reset FIN and PSH */
   tcp_flags = tcp->flags;
@@ -247,11 +278,11 @@ gso_segment_buffer_inline (vlib_main_t *vm,
       if (0 == dst_left && data_size)
        {
          vlib_prefetch_buffer_header (bufs[i + 1], LOAD);
-         vlib_prefetch_buffer_data (bufs[i + 1], LOAD);
 
          n_tx_bytes += bufs[i]->current_length;
-         gso_fixup_segmented_buf (vm, bufs[i], tcp_seq, is_l2, is_ip6, gho,
-                                  &c, tcp_flags_no_fin_psh);
+         gso_fixup_segmented_buf (vm, bufs[i], tcp_seq, is_l2, oflags, hdr_sz,
+                                  l4_hdr_sz, &c, tcp_flags_no_fin_psh, 1,
+                                  bufs[i + 1]);
          i++;
          dst_left = size;
          dst_ptr = vlib_buffer_get_current (bufs[i]) + hdr_sz;
@@ -264,8 +295,8 @@ gso_segment_buffer_inline (vlib_main_t *vm,
 
   ASSERT ((i + 1) == n_alloc);
   n_tx_bytes += bufs[i]->current_length;
-  gso_fixup_segmented_buf (vm, bufs[i], tcp_seq, is_l2, is_ip6, gho, &c,
-                          tcp_flags);
+  gso_fixup_segmented_buf (vm, bufs[i], tcp_seq, is_l2, oflags, hdr_sz,
+                          l4_hdr_sz, &c, tcp_flags, 0, NULL);
 
   vec_free (bufs);
   return n_tx_bytes;
index 910f158..c1d4459 100644 (file)
@@ -80,113 +80,108 @@ format_gso_trace (u8 * s, va_list * args)
   return s;
 }
 
-static_always_inline u16
-tso_segment_ipip_tunnel_fixup (vlib_main_t * vm,
-                              vnet_interface_per_thread_data_t * ptd,
-                              vlib_buffer_t * sb0,
-                              generic_header_offset_t * gho)
+static_always_inline void
+tso_segment_ipip_tunnel_fixup (vlib_main_t *vm,
+                              vnet_interface_per_thread_data_t *ptd,
+                              vlib_buffer_t *sb0)
 {
   u16 n_tx_bufs = vec_len (ptd->split_buffers);
-  u16 i = 0, n_tx_bytes = 0;
+  u16 i = 0;
 
   while (i < n_tx_bufs)
     {
       vlib_buffer_t *b0 = vlib_get_buffer (vm, ptd->split_buffers[i]);
+      i16 outer_l3_hdr_offset = vnet_buffer2 (b0)->outer_l3_hdr_offset;
+      i16 l3_hdr_offset = vnet_buffer (b0)->l3_hdr_offset;
 
-      ip4_header_t *ip4 =
-       (ip4_header_t *) (vlib_buffer_get_current (b0) +
-                         gho->outer_l3_hdr_offset);
-      ip6_header_t *ip6 =
-       (ip6_header_t *) (vlib_buffer_get_current (b0) +
-                         gho->outer_l3_hdr_offset);
+      ip4_header_t *ip4 = (ip4_header_t *) (b0->data + outer_l3_hdr_offset);
+      ip6_header_t *ip6 = (ip6_header_t *) (b0->data + outer_l3_hdr_offset);
 
-      if (gho->gho_flags & GHO_F_OUTER_IP4)
+      if (vnet_buffer (b0)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM)
        {
-         ip4->length =
-           clib_host_to_net_u16 (b0->current_length -
-                                 gho->outer_l3_hdr_offset);
+         ip4->length = clib_host_to_net_u16 (
+           b0->current_length - (outer_l3_hdr_offset - b0->current_data));
          ip4->checksum = ip4_header_checksum (ip4);
+         vnet_buffer_offload_flags_clear (
+           b0, VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM |
+                 VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
        }
-      else if (gho->gho_flags & GHO_F_OUTER_IP6)
+      else
        {
-         ip6->payload_length =
-           clib_host_to_net_u16 (b0->current_length -
-                                 gho->outer_l4_hdr_offset);
+         ip6->payload_length = clib_host_to_net_u16 (
+           b0->current_length - (l3_hdr_offset - b0->current_data));
+         vnet_buffer_offload_flags_clear (b0, VNET_BUFFER_OFFLOAD_F_TNL_IPIP);
        }
 
-      n_tx_bytes += gho->outer_hdr_sz;
       i++;
     }
-  return n_tx_bytes;
 }
 
 static_always_inline void
-tso_segment_vxlan_tunnel_headers_fixup (vlib_main_t * vm, vlib_buffer_t * b,
-                                       generic_header_offset_t * gho)
+tso_segment_vxlan_tunnel_headers_fixup (vlib_main_t *vm, vlib_buffer_t *b)
 {
-  u8 proto = 0;
   ip4_header_t *ip4 = 0;
   ip6_header_t *ip6 = 0;
   udp_header_t *udp = 0;
+  i16 outer_l3_hdr_offset = vnet_buffer2 (b)->outer_l3_hdr_offset;
+  i16 outer_l4_hdr_offset = vnet_buffer2 (b)->outer_l4_hdr_offset;
 
-  ip4 =
-    (ip4_header_t *) (vlib_buffer_get_current (b) + gho->outer_l3_hdr_offset);
-  ip6 =
-    (ip6_header_t *) (vlib_buffer_get_current (b) + gho->outer_l3_hdr_offset);
-  udp =
-    (udp_header_t *) (vlib_buffer_get_current (b) + gho->outer_l4_hdr_offset);
+  ip4 = (ip4_header_t *) (b->data + outer_l3_hdr_offset);
+  ip6 = (ip6_header_t *) (b->data + outer_l3_hdr_offset);
+  udp = (udp_header_t *) (b->data + outer_l4_hdr_offset);
 
-  if (gho->gho_flags & GHO_F_OUTER_IP4)
+  if (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM)
     {
-      proto = ip4->protocol;
-      ip4->length =
-       clib_host_to_net_u16 (b->current_length - gho->outer_l3_hdr_offset);
+      ip4->length = clib_host_to_net_u16 (
+       b->current_length - (outer_l3_hdr_offset - b->current_data));
       ip4->checksum = ip4_header_checksum (ip4);
+      if (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM)
+       {
+         udp->length = clib_host_to_net_u16 (
+           b->current_length - (outer_l4_hdr_offset - b->current_data));
+         // udp checksum is 0, in udp tunnel
+         udp->checksum = 0;
+       }
+      vnet_buffer_offload_flags_clear (
+       b, VNET_BUFFER_OFFLOAD_F_OUTER_IP_CKSUM |
+            VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM |
+            VNET_BUFFER_OFFLOAD_F_TNL_VXLAN);
     }
-  else if (gho->gho_flags & GHO_F_OUTER_IP6)
-    {
-      proto = ip6->protocol;
-      ip6->payload_length =
-       clib_host_to_net_u16 (b->current_length - gho->outer_l4_hdr_offset);
-    }
-  if (proto == IP_PROTOCOL_UDP)
+  else
     {
-      int bogus;
-      udp->length =
-       clib_host_to_net_u16 (b->current_length - gho->outer_l4_hdr_offset);
-      udp->checksum = 0;
-      if (gho->gho_flags & GHO_F_OUTER_IP6)
+      ip6->payload_length = clib_host_to_net_u16 (
+       b->current_length - (outer_l4_hdr_offset - b->current_data));
+
+      if (vnet_buffer (b)->oflags & VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM)
        {
+         int bogus;
+         udp->length = ip6->payload_length;
+         // udp checksum is 0, in udp tunnel
+         udp->checksum = 0;
          udp->checksum =
            ip6_tcp_udp_icmp_compute_checksum (vm, b, ip6, &bogus);
+         vnet_buffer_offload_flags_clear (
+           b, VNET_BUFFER_OFFLOAD_F_OUTER_UDP_CKSUM |
+                VNET_BUFFER_OFFLOAD_F_TNL_VXLAN);
        }
-      else if (gho->gho_flags & GHO_F_OUTER_IP4)
-       {
-         udp->checksum = ip4_tcp_udp_compute_checksum (vm, b, ip4);
-       }
-      /* FIXME: it should be OUTER_UDP_CKSUM */
-      vnet_buffer_offload_flags_clear (b, VNET_BUFFER_OFFLOAD_F_UDP_CKSUM);
     }
 }
 
-static_always_inline u16
-tso_segment_vxlan_tunnel_fixup (vlib_main_t * vm,
-                               vnet_interface_per_thread_data_t * ptd,
-                               vlib_buffer_t * sb0,
-                               generic_header_offset_t * gho)
+static_always_inline void
+tso_segment_vxlan_tunnel_fixup (vlib_main_t *vm,
+                               vnet_interface_per_thread_data_t *ptd,
+                               vlib_buffer_t *sb0)
 {
   u16 n_tx_bufs = vec_len (ptd->split_buffers);
-  u16 i = 0, n_tx_bytes = 0;
+  u16 i = 0;
 
   while (i < n_tx_bufs)
     {
       vlib_buffer_t *b0 = vlib_get_buffer (vm, ptd->split_buffers[i]);
 
-      tso_segment_vxlan_tunnel_headers_fixup (vm, b0, gho);
-      n_tx_bytes += gho->outer_hdr_sz;
+      tso_segment_vxlan_tunnel_headers_fixup (vm, b0);
       i++;
     }
-  return n_tx_bytes;
 }
 
 static_always_inline u16
@@ -682,32 +677,10 @@ vnet_gso_node_inline (vlib_main_t * vm,
                  to_next -= 1;
                  n_left_to_next += 1;
                  /* undo the counting. */
-                 generic_header_offset_t gho = { 0 };
                  u32 n_tx_bytes = 0;
-                 u32 inner_is_ip6 = is_ip6;
-
-                 vnet_generic_header_offset_parser (b[0], &gho, is_l2,
-                                                    is_ip4, is_ip6);
-
-                 if (PREDICT_FALSE (gho.gho_flags & GHO_F_TUNNEL))
-                   {
-                     if (PREDICT_FALSE
-                         (gho.gho_flags & (GHO_F_GRE_TUNNEL |
-                                           GHO_F_GENEVE_TUNNEL)))
-                       {
-                         /* not supported yet */
-                         drop_one_buffer_and_count (vm, vnm, node, from - 1,
-                                                    hi->sw_if_index,
-                                                    GSO_ERROR_UNHANDLED_TYPE);
-                         b += 1;
-                         continue;
-                       }
 
-                     inner_is_ip6 = (gho.gho_flags & GHO_F_IP6) != 0;
-                   }
-
-                 n_tx_bytes = gso_segment_buffer_inline (vm, ptd, b[0], &gho,
-                                                         is_l2, inner_is_ip6);
+                 n_tx_bytes =
+                   gso_segment_buffer_inline (vm, ptd, b[0], is_l2);
 
                  if (PREDICT_FALSE (n_tx_bytes == 0))
                    {
@@ -718,19 +691,15 @@ vnet_gso_node_inline (vlib_main_t * vm,
                      continue;
                    }
 
-
-                 if (PREDICT_FALSE (gho.gho_flags & GHO_F_VXLAN_TUNNEL))
+                 if (PREDICT_FALSE (vnet_buffer (b[0])->oflags &
+                                    VNET_BUFFER_OFFLOAD_F_TNL_VXLAN))
                    {
-                     n_tx_bytes +=
-                       tso_segment_vxlan_tunnel_fixup (vm, ptd, b[0], &gho);
+                     tso_segment_vxlan_tunnel_fixup (vm, ptd, b[0]);
                    }
-                 else
-                   if (PREDICT_FALSE
-                       (gho.gho_flags & (GHO_F_IPIP_TUNNEL |
-                                         GHO_F_IPIP6_TUNNEL)))
+                 else if (PREDICT_FALSE (vnet_buffer (b[0])->oflags &
+                                         VNET_BUFFER_OFFLOAD_F_TNL_IPIP))
                    {
-                     n_tx_bytes +=
-                       tso_segment_ipip_tunnel_fixup (vm, ptd, b[0], &gho);
+                     tso_segment_ipip_tunnel_fixup (vm, ptd, b[0]);
                    }
 
                  u16 n_tx_bufs = vec_len (ptd->split_buffers);
@@ -744,7 +713,6 @@ vnet_gso_node_inline (vlib_main_t * vm,
                        {
                          sbi0 = to_next[0] = from_seg[0];
                          sb0 = vlib_get_buffer (vm, sbi0);
-                         vnet_buffer_offload_flags_clear (sb0, 0x7F);
                          ASSERT (sb0->current_length > 0);
                          to_next += 1;
                          from_seg += 1;
index 2995836..c727e51 100644 (file)
@@ -1020,21 +1020,19 @@ vl_api_sw_interface_set_interface_name_t_handler (
 {
   vl_api_sw_interface_set_interface_name_reply_t *rmp;
   vnet_main_t *vnm = vnet_get_main ();
-  u32 sw_if_index = ntohl (mp->sw_if_index);
-  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
   clib_error_t *error;
   int rv = 0;
 
+  VALIDATE_SW_IF_INDEX (mp);
+
+  u32 sw_if_index = ntohl (mp->sw_if_index);
+  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
+
   if (mp->name[0] == 0)
     {
       rv = VNET_API_ERROR_INVALID_VALUE;
       goto out;
     }
-  if (si == 0)
-    {
-      rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
-      goto out;
-    }
 
   error = vnet_rename_interface (vnm, si->hw_if_index, (char *) mp->name);
   if (error)
@@ -1044,6 +1042,7 @@ vl_api_sw_interface_set_interface_name_t_handler (
     }
 
 out:
+  BAD_SW_IF_INDEX_LABEL;
   REPLY_MACRO (VL_API_SW_INTERFACE_SET_INTERFACE_NAME_REPLY);
 }
 
index f81485d..321472c 100644 (file)
@@ -1578,7 +1578,7 @@ fill_buffer_offload_flags (vlib_main_t *vm, u32 *buffers, u32 n_buffers,
            (VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
             VNET_BUFFER_F_L3_HDR_OFFSET_VALID |
             VNET_BUFFER_F_L4_HDR_OFFSET_VALID);
-         if (buffer_oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM)
+         if (buffer_oflags & VNET_BUFFER_OFFLOAD_F_IP_CKSUM || gso_enabled)
            oflags |= VNET_BUFFER_OFFLOAD_F_IP_CKSUM;
        }
       else if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP6))
@@ -1596,7 +1596,7 @@ fill_buffer_offload_flags (vlib_main_t *vm, u32 *buffers, u32 n_buffers,
 
       if (l4_proto == IP_PROTOCOL_TCP)
        {
-         if (buffer_oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM)
+         if (buffer_oflags & VNET_BUFFER_OFFLOAD_F_TCP_CKSUM || gso_enabled)
            oflags |= VNET_BUFFER_OFFLOAD_F_TCP_CKSUM;
 
          /* only set GSO flag for chained buffers */
index 448435d..24e0110 100644 (file)
@@ -20,6 +20,7 @@
   THE SOFTWARE.
 */
 /* clang-format off */
+
 /* cJSON */
 /* JSON parser in C. */
 
@@ -96,9 +97,9 @@ CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void)
     return (const char*) (global_error.json + global_error.position);
 }
 
-CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) 
+CJSON_PUBLIC (char *) cJSON_GetStringValue (const cJSON *const item)
 {
-    if (!cJSON_IsString(item)) 
+  if (!cJSON_IsString (item))
     {
         return NULL;
     }
@@ -106,9 +107,9 @@ CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item)
     return item->valuestring;
 }
 
-CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) 
+CJSON_PUBLIC (double) cJSON_GetNumberValue (const cJSON *const item)
 {
-    if (!cJSON_IsNumber(item)) 
+  if (!cJSON_IsNumber (item))
     {
         return (double) NAN;
     }
@@ -117,8 +118,9 @@ CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item)
 }
 
 /* This is a safeguard to prevent copy-pasters from using incompatible C and header files */
-#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 14)
-    #error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
+#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) ||               \
+  (CJSON_VERSION_PATCH != 17)
+#error cJSON.h and cJSON.c have different versions. Make sure that both have the same.
 #endif
 
 CJSON_PUBLIC(const char*) cJSON_Version(void)
@@ -157,7 +159,7 @@ typedef struct internal_hooks
 {
     void *(CJSON_CDECL *allocate)(size_t size);
     void (CJSON_CDECL *deallocate)(void *pointer);
-    void *(CJSON_CDECL *reallocate)(void *pointer, size_t new_size, size_t old_size);
+    void *(CJSON_CDECL *reallocate) (void *pointer, size_t size);
 } internal_hooks;
 
 #if defined(_MSC_VER)
@@ -170,20 +172,17 @@ static void CJSON_CDECL internal_free(void *pointer)
 {
     free(pointer);
 }
+static void *CJSON_CDECL
+internal_realloc (void *pointer, size_t size)
+{
+  return realloc (pointer, size);
+}
 #else
 #define internal_malloc malloc
 #define internal_free free
+#define internal_realloc realloc
 #endif
 
-static void * CJSON_CDECL internal_realloc(void *pointer, size_t new_size,
-    size_t old_size)
-{
-    return realloc(pointer, new_size);
-}
-
-static void *
-cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size);
-
 /* strlen of character literals resolved at compile time */
 #define static_strlen(string_literal) (sizeof(string_literal) - sizeof(""))
 
@@ -217,8 +216,8 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
         /* Reset hooks */
         global_hooks.allocate = malloc;
         global_hooks.deallocate = free;
-        global_hooks.reallocate = internal_realloc;
-        return;
+       global_hooks.reallocate = realloc;
+       return;
     }
 
     global_hooks.allocate = malloc;
@@ -233,16 +232,11 @@ CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
         global_hooks.deallocate = hooks->free_fn;
     }
 
-    /* use realloc only if both free and malloc are used */
-    global_hooks.reallocate = NULL;
-    if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
-    {
-        global_hooks.reallocate = internal_realloc;
-    }
-    else
-    {
-        global_hooks.reallocate = cjson_realloc_internal;
-    }
+    global_hooks.reallocate = realloc;
+    if (hooks->realloc_fn != NULL)
+      {
+       global_hooks.reallocate = hooks->realloc_fn;
+      }
 }
 
 /* Internal constructor. */
@@ -405,14 +399,22 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number)
     return object->valuedouble = number;
 }
 
+/* Note: when passing a NULL valuestring, cJSON_SetValuestring treats this as
+ * an error and return NULL */
 CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring)
 {
     char *copy = NULL;
     /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
-    if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
-    {
-        return NULL;
-    }
+    if ((object == NULL) || !(object->type & cJSON_String) ||
+       (object->type & cJSON_IsReference))
+      {
+       return NULL;
+      }
+    /* return NULL if the object is corrupted or valuestring is NULL */
+    if (object->valuestring == NULL || valuestring == NULL)
+      {
+       return NULL;
+      }
     if (strlen(valuestring) <= strlen(object->valuestring))
     {
         strcpy(object->valuestring, valuestring);
@@ -443,27 +445,6 @@ typedef struct
     internal_hooks hooks;
 } printbuffer;
 
-static void *
-cjson_realloc_internal (void *ptr, size_t new_size, size_t old_size)
-{
-    size_t copy_size;
-    if (old_size < new_size)
-      copy_size = old_size;
-    else
-      copy_size = new_size;
-
-    unsigned char *newbuffer = global_hooks.allocate(new_size);
-    if (!newbuffer)
-    {
-        global_hooks.deallocate(ptr);
-        return NULL;
-    }
-
-    memcpy (newbuffer, ptr, copy_size);
-    global_hooks.deallocate (ptr);
-    return newbuffer;
-}
-
 /* realloc printbuffer if necessary to have at least "needed" bytes more */
 static unsigned char* ensure(printbuffer * const p, size_t needed)
 {
@@ -515,14 +496,35 @@ static unsigned char* ensure(printbuffer * const p, size_t needed)
         newsize = needed * 2;
     }
 
-    newbuffer = p->hooks.reallocate (p->buffer, newsize, p->length);
-    if (newbuffer == NULL)
-    {
-        p->hooks.deallocate(p->buffer);
-        p->length = 0;
-        p->buffer = NULL;
-        return NULL;
-    }
+    if (p->hooks.reallocate != NULL)
+      {
+       /* reallocate with realloc if available */
+       newbuffer = (unsigned char *) p->hooks.reallocate (p->buffer, newsize);
+       if (newbuffer == NULL)
+         {
+           p->hooks.deallocate (p->buffer);
+           p->length = 0;
+           p->buffer = NULL;
+
+           return NULL;
+         }
+      }
+    else
+      {
+       /* otherwise reallocate manually */
+       newbuffer = (unsigned char *) p->hooks.allocate (newsize);
+       if (!newbuffer)
+         {
+           p->hooks.deallocate (p->buffer);
+           p->length = 0;
+           p->buffer = NULL;
+
+           return NULL;
+         }
+
+       memcpy (newbuffer, p->buffer, p->offset + 1);
+       p->hooks.deallocate (p->buffer);
+      }
     p->length = newsize;
     p->buffer = newbuffer;
 
@@ -570,6 +572,10 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
     {
         length = sprintf((char*)number_buffer, "null");
     }
+    else if (d == (double) item->valueint)
+      {
+       length = sprintf ((char *) number_buffer, "%d", item->valueint);
+      }
     else
     {
         /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
@@ -1111,7 +1117,7 @@ CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer
     }
 
     buffer.content = (const unsigned char*)value;
-    buffer.length = buffer_length; 
+    buffer.length = buffer_length;
     buffer.offset = 0;
     buffer.hooks = global_hooks;
 
@@ -1216,11 +1222,13 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
     /* check if reallocate is available */
     if (hooks->reallocate != NULL)
     {
-        printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1, default_buffer_size);
-        if (printed == NULL) {
-            goto fail;
-        }
-        buffer->buffer = NULL;
+      printed = (unsigned char *) hooks->reallocate (buffer->buffer,
+                                                    buffer->offset + 1);
+      if (printed == NULL)
+       {
+         goto fail;
+       }
+       buffer->buffer = NULL;
     }
     else /* otherwise copy the JSON over to a new buffer */
     {
@@ -1658,8 +1666,13 @@ static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_bu
             current_item = new_item;
         }
 
-        /* parse the name of the child */
-        input_buffer->offset++;
+       if (cannot_access_at_index (input_buffer, 1))
+         {
+           goto fail; /* nothing comes after the comma */
+         }
+
+       /* parse the name of the child */
+       input_buffer->offset++;
         buffer_skip_whitespace(input_buffer);
         if (!parse_string(current_item, input_buffer))
         {
@@ -2268,10 +2281,10 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
 {
     cJSON *after_inserted = NULL;
 
-    if (which < 0)
-    {
-        return false;
-    }
+    if (which < 0 || newitem == NULL)
+      {
+       return false;
+      }
 
     after_inserted = get_array_item(array, (size_t)which);
     if (after_inserted == NULL)
@@ -2279,6 +2292,12 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
         return add_item_to_array(array, newitem);
     }
 
+    if (after_inserted != array->child && after_inserted->prev == NULL)
+      {
+       /* return false if after_inserted is a corrupted array item */
+       return false;
+      }
+
     newitem->next = after_inserted;
     newitem->prev = after_inserted->prev;
     after_inserted->prev = newitem;
@@ -2295,7 +2314,8 @@ CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON
 
 CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement)
 {
-    if ((parent == NULL) || (replacement == NULL) || (item == NULL))
+  if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) ||
+      (item == NULL))
     {
         return false;
     }
@@ -2365,6 +2385,11 @@ static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSO
         cJSON_free(replacement->string);
     }
     replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks);
+    if (replacement->string == NULL)
+      {
+       return false;
+      }
+
     replacement->type &= ~cJSON_StringIsConst;
 
     return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement);
@@ -2639,9 +2664,9 @@ CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count)
 
     for (i = 0; a && (i < (size_t) count); i++)
       {
-       n = cJSON_CreateNumber(numbers[i]);
-        if(!n)
-        {
+       n = cJSON_CreateNumber (numbers[i]);
+       if (!n)
+         {
             cJSON_Delete(a);
             return NULL;
         }
@@ -2988,7 +3013,7 @@ CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item)
 
 CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive)
 {
-    if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)) || cJSON_IsInvalid(a))
+  if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF)))
     {
         return false;
     }
@@ -3121,7 +3146,7 @@ CJSON_PUBLIC(void) cJSON_free(void *object)
     global_hooks.deallocate(object);
 }
 
-CJSON_PUBLIC(void *) cJSON_realloc(void *object, size_t new_size, size_t old_size)
+CJSON_PUBLIC (void *) cJSON_realloc (void *object, size_t size)
 {
-    return global_hooks.reallocate(object, new_size, old_size);
+  return global_hooks.reallocate (object, size);
 }
index 1474c4e..1c98dfa 100644 (file)
@@ -81,7 +81,7 @@ then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJ
 /* project version */
 #define CJSON_VERSION_MAJOR 1
 #define CJSON_VERSION_MINOR 7
-#define CJSON_VERSION_PATCH 14
+#define CJSON_VERSION_PATCH 17
 
 #include <stddef.h>
 
@@ -127,8 +127,7 @@ typedef struct cJSON_Hooks
       /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
       void *(CJSON_CDECL *malloc_fn)(size_t sz);
       void (CJSON_CDECL *free_fn)(void *ptr);
-      void *(CJSON_CDECL *realloc_fn) (void *ptr, size_t new_size,
-                                      size_t old_size);
+      void *(CJSON_CDECL *realloc_fn) (void *ptr, size_t sz);
 } cJSON_Hooks;
 
 typedef int cJSON_bool;
@@ -256,9 +255,10 @@ CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
  * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
 CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
 
-/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
- * The input pointer json cannot point to a read-only address area, such as a string constant, 
- * but should point to a readable and writable adress area. */
+/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n')
+ * from strings. The input pointer json cannot point to a read-only address
+ * area, such as a string constant,
+ * but should point to a readable and writable address area. */
 CJSON_PUBLIC(void) cJSON_Minify(char *json);
 
 /* Helper functions for creating and adding items to an object at the same time.
@@ -281,14 +281,21 @@ CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
 /* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
 CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
 
+/* If the object is not a boolean type this does nothing and returns
+ * cJSON_Invalid else it returns the new type*/
+#define cJSON_SetBoolValue(object, boolValue)                                 \
+  ((object != NULL && ((object)->type & (cJSON_False | cJSON_True))) ?        \
+          (object)->type = ((object)->type & (~(cJSON_False | cJSON_True))) |      \
+                     ((boolValue) ? cJSON_True : cJSON_False) :              \
+          cJSON_Invalid)
+
 /* Macro for iterating over an array or object */
 #define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
 
 /* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
 CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
 CJSON_PUBLIC(void) cJSON_free(void *object);
-CJSON_PUBLIC (void *)
-cJSON_realloc (void *object, size_t new_size, size_t old_size);
+CJSON_PUBLIC (void *) cJSON_realloc (void *object, size_t size);
 
 #ifdef __cplusplus
 }
index 29cbe0a..5008f82 100644 (file)
 #include <vppinfra/format.h>
 #ifdef __linux__
 #include <vppinfra/linux/sysfs.h>
-#else
+#elif defined(__FreeBSD__)
 #include <sys/sysctl.h>
+#include <sys/param.h>
 #endif
 
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/syscall.h>
 #include <sys/uio.h>           /* writev */
 #include <fcntl.h>
 #include <stdio.h>             /* for sprintf */
@@ -277,36 +277,6 @@ os_get_online_cpu_core_bitmap ()
 #endif
 }
 
-__clib_export clib_bitmap_t *
-os_get_cpu_affinity_bitmap (int pid)
-{
-#if __linux
-  int index, ret;
-  cpu_set_t cpuset;
-  uword *affinity_cpus;
-
-  clib_bitmap_alloc (affinity_cpus, sizeof (cpu_set_t));
-  clib_bitmap_zero (affinity_cpus);
-
-  __CPU_ZERO_S (sizeof (cpu_set_t), &cpuset);
-
-  ret = syscall (SYS_sched_getaffinity, 0, sizeof (cpu_set_t), &cpuset);
-
-  if (ret < 0)
-    {
-      clib_bitmap_free (affinity_cpus);
-      return 0;
-    }
-
-  for (index = 0; index < sizeof (cpu_set_t); index++)
-    if (__CPU_ISSET_S (index, sizeof (cpu_set_t), &cpuset))
-      clib_bitmap_set (affinity_cpus, index, 1);
-  return affinity_cpus;
-#else
-  return 0;
-#endif
-}
-
 __clib_export clib_bitmap_t *
 os_get_online_cpu_node_bitmap ()
 {
index abda218..d0ddb93 100644 (file)
@@ -56,9 +56,6 @@ clib_error_t *unix_proc_file_contents (char *file, u8 ** result);
 /* Retrieve bitmap of online cpu cures */
 clib_bitmap_t *os_get_online_cpu_core_bitmap ();
 
-/* Retrieve bitmap of cpus vpp has affinity to */
-clib_bitmap_t *os_get_cpu_affinity_bitmap (int pid);
-
 /* Retrieve bitmap of online cpu nodes (sockets) */
 clib_bitmap_t *os_get_online_cpu_node_bitmap ();
 
diff --git a/test/scripts/core_pinning.sh b/test/scripts/core_pinning.sh
deleted file mode 100755 (executable)
index 941d538..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-#!/bin/bash
-#
-# core_pinning_auto.sh -- script to test vpp (debug-build) core-pinning
-#                      -- in bare-metal, containers (docker, lxc)
-#
-DOCKER_CONTAINER_NAME="vpp_core_pinning"
-VPP_SOCK_PATH=/run/vpp
-CONTAINER_CPU_RANGE="4-7"
-TEST_SUCCESS=0
-TEST_FAIL=0
-if [ ! $WS_ROOT ]
-then
-       if [ ! -d "../../../vpp" ]; then
-               echo "VPP workspace path invalid"
-               echo "Please execute script from vpp/test/scripts folder.."
-               exit 1
-       fi
-       WS_ROOT="$(dirname $(readlink -e "../../../vpp"))/$(basename "../../../vpp")"
-fi
-# Get available CPU count on host machine
-host_cpulist=$(cat /sys/devices/system/cpu/online)
-startcpu="${host_cpulist%-*}"
-endcpu="${host_cpulist#*\-}"
-cpucount="$(($endcpu - $startcpu + 1))"
-if [ $cpucount -lt 8 ]
-then
-       echo "Current host machine has $cpucount CPUs"
-    echo "A minimum of 8 CPUs is required to run testcases, exiting.."
-    exit 1
-fi
-# Check that container 'vpp_core_pinning' does not already exist
-count=$(docker ps -a | grep -c "$DOCKER_CONTAINER_NAME")
-if [ $count -ne 0 ]
-then
-       echo "Error: docker container $DOCKER_CONTAINER_NAME already exists"
-       echo "Remove it using 'docker stop/docker rm', then re-run test"
-       exit 1
-fi
-# Check that there is no vpp instance currently running on the machine
-count=$(pgrep vpp | wc -l)
-if [ $count -ne 0 ]
-then
-       echo "Error: a vpp instance is currently running on this machine"
-       echo "Please stop the running instance, then re-run test"
-       exit 1
-fi
-mkdir -p $VPP_SOCK_PATH
-
-# Function to parse main core
-parse_maincore () {
-    main_core_args=$1
-    main_core_parsed=$main_core_args
-    if [ $main_core_args = "auto" ];
-    then
-        main_core_parsed="0"
-        if [ -n "$SKIP_CORE" ]
-        then
-            main_core_parsed=$(($main_core_parsed + $SKIP_CORE))
-        fi
-        if [ -n "$CONTAINER_RESTRAIN_CPUSET" ]
-        then
-            main_core_parsed=(${container_cpus[ $main_core_parsed ]})
-        fi
-    fi
-    echo $main_core_parsed
-}
-
-# Function to parse n workers range to an array
-# e.g. "4" is parsed to ('0','1','2','3')
-parse_workers_n () {
-    workers_n_args=$1
-    workers_n_parsed=()
-    main_core_increment="0"
-    skip_core_increment="0"
-    if [ -n "$SKIP_CORE" ]
-        then
-            skip_core_increment=$(($SKIP_CORE))
-        fi
-
-    for ((i=0;i<$workers_n_args;i++)); do
-
-    if [ -n "$CONTAINER_RESTRAIN_CPUSET" ]
-        then
-        if [ $(( ${container_cpus[ $(($i + $skip_core_increment)) ]})) -eq $(("$parsed_main_core")) ]
-        then
-            main_core_increment=$(($main_core_increment + 1))
-        fi
-            workers_n_parsed+=" ${container_cpus[ $(($i + $main_core_increment + $skip_core_increment)) ]}"
-        else
-        if [ $(( $skip_core_increment + $i)) -eq $(("$parsed_main_core")) ]
-        then
-            main_core_increment=$(($main_core_increment + 1))
-        fi
-            workers_n_parsed+=" $(($i + $main_core_increment + $skip_core_increment))"
-        fi
-    done
-    echo $workers_n_parsed
-}
-
-# Function to parse corelist range to an array
-# e.g. "0,3-5,7" is parsed to ('0','3','4','5','7')
-parse_corelist () {
-    corelist_args=$1
-    corelist_args=$(echo $corelist_args | grep -Po '[0-9]+-[0-9]+|[0-9]+')
-    corelist_parsed=()
-    for corelist_elt in ${corelist_args[@]};do
-        if [ $(echo $corelist_elt | grep -Po '[0-9]+-[0-9]+') ]
-        then
-            startcpu="${corelist_elt%-*}"
-            endcpu="${corelist_elt#*\-}"
-            cpucount="$(($endcpu - $startcpu))"
-            for ((i=0;i<=$cpucount;i++)); do
-              corelist_parsed+=" $(($i+$startcpu))"
-            done
-        elif [ $(echo $corelist_elt | grep -Po '[0-9]+') ]
-        then
-            corelist_parsed+=" ${corelist_elt}"
-        fi
-    done
-    echo $corelist_parsed
-}
-# Test VPP core pinning configuration
-test_pinning_conf () {
-    VPP_CPU_EXTRA_OPTIONS=""
-       if [ -n "$CORELIST_WORKERS" ];
-       then
-               VPP_CPU_EXTRA_OPTIONS=" corelist-workers ${CORELIST_WORKERS}"
-       fi
-    if [ -n "$WORKERS_AUTO" ];
-       then
-               VPP_CPU_EXTRA_OPTIONS=" workers ${WORKERS_AUTO}"
-       fi
-    if [ -n "$SKIP_CORE" ];
-       then
-               VPP_CPU_EXTRA_OPTIONS="${VPP_CPU_EXTRA_OPTIONS} skip-cores ${SKIP_CORE}"
-       fi
-       echo "TEST - conf 'cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS}}'"
-       if [ -z "$CONTAINER_RESTRAIN_CPUSET" ];
-       then
-               VPP_CONTAINER_CPUSET=""
-               echo "(Running vpp in container with full host cpuset $host_cpulist)"
-       else
-               VPP_CONTAINER_CPUSET="--cpuset-cpus $CONTAINER_CPU_RANGE"
-               echo "(Running vpp in container with limited cpuset $CONTAINER_CPU_RANGE)"
-       fi
-       (docker run -d ${VPP_CONTAINER_CPUSET} --name="$DOCKER_CONTAINER_NAME" \
-       -e LD_LIBRARY_PATH="/vpp/build-root/build-vpp_debug-native/vpp/lib/x86_64-linux-gnu/" -v $VPP_SOCK_PATH:$VPP_SOCK_PATH \
-       -v $WS_ROOT:/vpp  ubuntu:22.04 sh -c "/vpp/build-root/build-vpp_debug-native/vpp/bin/vpp unix {interactive \
-       nodaemon cli-listen $VPP_SOCK_PATH/cli.sock} cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS} } plugins \
-       { plugin dpdk_plugin.so {disable } }" > /dev/null )
-       sleep 3 # wait for VPP to initialize socket
-       # Change access permissions on vpp cli socket
-       # docker exec -it "$DOCKER_CONTAINER_NAME" /bin/bash -c "chmod 777  $VPP_SOCK_PATH/cli.sock"  > /dev/null
-       # check if vppctl can connect to vpp container instance
-       $WS_ROOT/build-root/build-vpp_debug-native/vpp/bin/vppctl -s $VPP_SOCK_PATH/cli.sock show threads  1> /dev/null
-       # get CPUs vpp instance in container is running on
-       taskset_vpp_cpus=($( taskset --all-tasks -pc $(pgrep vpp) | grep -e ".$" -o))
-       rc=$?
-       # parse list of user requested CPUs for vpp
-       requested_cpus=()
-    parsed_main_core=$(parse_maincore ${MAIN_CORE})
-       requested_cpus+=($parsed_main_core)
-    if [ -n "$CORELIST_WORKERS" ];
-    then
-           requested_cpus+=($(parse_corelist ${CORELIST_WORKERS}))
-    fi
-    if [ -n "$WORKERS_AUTO" ];
-    then
-           requested_cpus+=($(parse_workers_n ${WORKERS_AUTO}))
-    fi
-
-       # parse list of expected CPUs used by vpp
-       expected_cpu_mapping=()
-    expected_cpu_mapping=("${requested_cpus[@]}")
-       echo "CPUs requested by user:      [${requested_cpus[@]}]"
-       echo "--------------------"
-       echo "Expected CPU Mapping:        [${expected_cpu_mapping[@]}]"
-       echo "VPP pinning (taskset):       [${taskset_vpp_cpus[@]}]"
-       #check if expected CPU mapping matches CPUs vpp instance in container is running on
-       failure_cond=""
-       for index in ${!taskset_vpp_cpus[@]}; do
-               if [ ${taskset_vpp_cpus[$index]} -ne  ${expected_cpu_mapping[ $index ]} ]
-               then
-                       failure_cond="t"
-               fi
-       done
-       if [ $rc -eq 0 ] && [ -z "$failure_cond" ]
-       then
-               echo "Test Successful"
-               TEST_SUCCESS=$(($TEST_SUCCESS+1))
-       else
-               echo "Test Failed"
-               TEST_FAIL=$(($TEST_FAIL+1))
-       fi
-       echo "=============================================="
-       echo " "
-       # Stop & destroy container instance
-       docker stop $DOCKER_CONTAINER_NAME  &> /dev/null
-       docker rm -f $DOCKER_CONTAINER_NAME &> /dev/null
-}
-test_invalid_conf () {
-       if [ -n "$CORELIST_WORKERS" ];
-       then
-               VPP_CPU_EXTRA_OPTIONS=" corelist-workers ${CORELIST_WORKERS}"
-       fi
-    if [ -n "$WORKERS_AUTO" ];
-       then
-               VPP_CPU_EXTRA_OPTIONS=" workers ${WORKERS_AUTO}"
-       fi
-    if [ -n "$SKIP_CORE" ];
-       then
-               VPP_CPU_EXTRA_OPTIONS="${VPP_CPU_EXTRA_OPTIONS} skip-cores ${SKIP_CORE}"
-       fi
-       echo "TEST - conf 'cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS}}'"
-       if [ -z "$CONTAINER_RESTRAIN_CPUSET" ];
-       then
-               VPP_CONTAINER_CPUSET=""
-               echo "(Running vpp in container with full host cpuset $host_cpulist)"
-       else
-               VPP_CONTAINER_CPUSET="--cpuset-cpus $CONTAINER_CPU_RANGE"
-               echo "(Running vpp in container with limited cpuset $CONTAINER_CPU_RANGE)"
-       fi
-       (docker run -d --cpuset-cpus $CONTAINER_CPU_RANGE --name="$DOCKER_CONTAINER_NAME" \
-       -e LD_LIBRARY_PATH="/vpp/build-root/build-vpp_debug-native/vpp/lib/x86_64-linux-gnu/" -v $VPP_SOCK_PATH:$VPP_SOCK_PATH \
-       -v $WS_ROOT:/vpp  ubuntu:22.04 sh -c "/vpp/build-root/build-vpp_debug-native/vpp/bin/vpp unix {interactive \
-       nodaemon cli-listen $VPP_SOCK_PATH/cli.sock} cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS}} plugins \
-       { plugin dpdk_plugin.so {disable } }"  > /dev/null)
-       sleep 3 # wait for vpp to initialize socket
-       # check if vpp launched with invalid configuration
-       taskset --all-tasks -pc $(pgrep vpp) &> /dev/null
-       rc=$?
-       if [ $rc -eq 1 ]
-       then
-        echo " "
-               echo "OK... VPP did not launch with invalid configuration"
-               TEST_SUCCESS=$(($TEST_SUCCESS+1))
-       else
-        echo " "
-               echo "Failure... VPP launched with wrong configuration"
-               TEST_FAIL=$(($TEST_FAIL+1))
-       fi
-       echo "=============================================="
-       echo " "
-       # Stop & destroy container instance
-       docker stop $DOCKER_CONTAINER_NAME  &> /dev/null
-       docker rm -f $DOCKER_CONTAINER_NAME &> /dev/null
-}
-run_tests () {
-       container_cpus=($(parse_corelist ${CONTAINER_CPU_RANGE}))
-       echo "TESTING VALID CORE PINNING CONFIGURATIONS"
-       echo " "
-    WORKERS_AUTO=""
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET=""
-       CORELIST_WORKERS="1-3"
-       MAIN_CORE="0"
-       test_pinning_conf
-    WORKERS_AUTO=""
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET=""
-       CORELIST_WORKERS="0,2-3"
-       MAIN_CORE="1"
-       test_pinning_conf
-    WORKERS_AUTO=""
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET=""
-       CORELIST_WORKERS="0-2"
-       MAIN_CORE="3"
-       test_pinning_conf
-    WORKERS_AUTO="2"
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET=""
-    CORELIST_WORKERS=""
-       MAIN_CORE="auto"
-       test_pinning_conf
-    WORKERS_AUTO="3"
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET="t"
-    CORELIST_WORKERS=""
-       MAIN_CORE="auto"
-       test_pinning_conf
-    WORKERS_AUTO="2"
-    SKIP_CORE="1"
-       CONTAINER_RESTRAIN_CPUSET="t"
-    CORELIST_WORKERS=""
-       MAIN_CORE="auto"
-       test_pinning_conf
-    WORKERS_AUTO="2"
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET="t"
-    CORELIST_WORKERS=""
-       MAIN_CORE="5"
-       test_pinning_conf
-       echo "TESTING NON-VALID CORE PINNING CONFIGURATIONS"
-       echo " "
-    WORKERS_AUTO=""
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET="t"
-       CORELIST_WORKERS="1-3"
-       MAIN_CORE="0"
-       test_invalid_conf
-       WORKERS_AUTO="3"
-    SKIP_CORE="1"
-       CONTAINER_RESTRAIN_CPUSET="t"
-       CORELIST_WORKERS=""
-       MAIN_CORE="auto"
-       test_invalid_conf
-       WORKERS_AUTO="5"
-    SKIP_CORE=""
-       CONTAINER_RESTRAIN_CPUSET="t"
-       CORELIST_WORKERS=""
-       MAIN_CORE="auto"
-       test_invalid_conf
-       WORKERS_AUTO=""
-    SKIP_CORE="4"
-       CONTAINER_RESTRAIN_CPUSET="t"
-       CORELIST_WORKERS=""
-       MAIN_CORE="auto"
-       test_invalid_conf
-       echo " "
-       echo "========================"
-       echo "RESULTS:"
-       echo "SUCCESS: $TEST_SUCCESS"
-       echo "FAILURE: $TEST_FAIL"
-       echo "========================"
-       echo " "
-}
-run_tests
\ No newline at end of file
index 3baec9f..ec329a0 100644 (file)
@@ -391,7 +391,7 @@ class TestAbf(VppTestCase):
         # a packet matching the deny rule
         #
         p_deny = (
-            Ether(src=self.pg0.remote_mac, dst=self.pg3.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IP(src=self.pg0.remote_ip4, dst=self.pg3.remote_ip4)
             / UDP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 100)
@@ -402,7 +402,7 @@ class TestAbf(VppTestCase):
         # a packet matching the permit rule
         #
         p_permit = (
-            Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IP(src=self.pg0.remote_ip4, dst=self.pg2.remote_ip4)
             / UDP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 100)
@@ -454,7 +454,7 @@ class TestAbf(VppTestCase):
         # a packet matching the deny rule
         #
         p_deny = (
-            Ether(src=self.pg0.remote_mac, dst=self.pg3.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg3.remote_ip6)
             / UDP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 100)
@@ -465,7 +465,7 @@ class TestAbf(VppTestCase):
         # a packet matching the permit rule
         #
         p_permit = (
-            Ether(src=self.pg0.remote_mac, dst=self.pg2.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg2.remote_ip6)
             / UDP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 100)
index ac0433a..8e3fecf 100644 (file)
@@ -559,7 +559,7 @@ class Flowprobe(MethodHolder):
         # make a tcp packet
         self.pkts = [
             (
-                Ether(src=self.pg3.remote_mac, dst=self.pg4.local_mac)
+                Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac)
                 / IP(src=self.pg3.remote_ip4, dst=self.pg4.remote_ip4)
                 / TCP(sport=1234, dport=4321)
                 / Raw(b"\xa5" * 50)
index 78c5c73..3d9ce5f 100644 (file)
@@ -405,7 +405,7 @@ class TestGSO(VppTestCase):
         # IPv4/IPv4 - VXLAN
         #
         p45 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags="DF")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -419,12 +419,12 @@ class TestGSO(VppTestCase):
             self.assertEqual(rx[IP].src, self.pg0.local_ip4)
             self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
             self.assert_ip_checksum_valid(rx)
-            self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
+            self.assert_udp_checksum_valid(rx, ignore_zero_checksum=True)
             self.assertEqual(rx[VXLAN].vni, 10)
             inner = rx[VXLAN].payload
             self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
             self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
-            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
+            self.assertEqual(inner[Ether].dst, self.pg2.local_mac)
             self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
             self.assertEqual(inner[IP].dst, "172.16.3.3")
             self.assert_ip_checksum_valid(inner)
@@ -438,7 +438,7 @@ class TestGSO(VppTestCase):
         # IPv4/IPv6 - VXLAN
         #
         p65 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -452,12 +452,12 @@ class TestGSO(VppTestCase):
             self.assertEqual(rx[IP].src, self.pg0.local_ip4)
             self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
             self.assert_ip_checksum_valid(rx)
-            self.assert_udp_checksum_valid(rx, ignore_zero_checksum=False)
+            self.assert_udp_checksum_valid(rx, ignore_zero_checksum=True)
             self.assertEqual(rx[VXLAN].vni, 10)
             inner = rx[VXLAN].payload
             self.assertEqual(rx[IP].len - 20 - 8 - 8, len(inner))
             self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
-            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
+            self.assertEqual(inner[Ether].dst, self.pg2.local_mac)
             self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
             self.assertEqual(inner[IPv6].dst, "fd01:3::3")
             self.assert_tcp_checksum_valid(inner)
@@ -483,7 +483,7 @@ class TestGSO(VppTestCase):
         # IPv6/IPv4 - VXLAN
         #
         p46 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IP(src=self.pg2.remote_ip4, dst="172.16.3.3", flags="DF")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -501,7 +501,7 @@ class TestGSO(VppTestCase):
             inner = rx[VXLAN].payload
             self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
             self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
-            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
+            self.assertEqual(inner[Ether].dst, self.pg2.local_mac)
             self.assertEqual(inner[IP].src, self.pg2.remote_ip4)
             self.assertEqual(inner[IP].dst, "172.16.3.3")
             self.assert_ip_checksum_valid(inner)
@@ -515,7 +515,7 @@ class TestGSO(VppTestCase):
         # IPv6/IPv6 - VXLAN
         #
         p66 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IPv6(src=self.pg2.remote_ip6, dst="fd01:3::3")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -533,7 +533,7 @@ class TestGSO(VppTestCase):
             inner = rx[VXLAN].payload
             self.assertEqual(rx[IPv6].plen - 8 - 8, len(inner))
             self.assertEqual(inner[Ether].src, self.pg2.remote_mac)
-            self.assertEqual(inner[Ether].dst, "02:fe:60:1e:a2:79")
+            self.assertEqual(inner[Ether].dst, self.pg2.local_mac)
             self.assertEqual(inner[IPv6].src, self.pg2.remote_ip6)
             self.assertEqual(inner[IPv6].dst, "fd01:3::3")
             self.assert_tcp_checksum_valid(inner)
@@ -590,7 +590,7 @@ class TestGSO(VppTestCase):
         # IPv4/IPv4 - IPIP
         #
         p47 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -633,7 +633,7 @@ class TestGSO(VppTestCase):
         # IPv4/IPv6 - IPIP
         #
         p67 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -731,7 +731,7 @@ class TestGSO(VppTestCase):
         # IPv6/IPv4 - IPIP
         #
         p48 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -774,7 +774,7 @@ class TestGSO(VppTestCase):
         # IPv6/IPv6 - IPIP
         #
         p68 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -842,7 +842,7 @@ class TestGSO(VppTestCase):
         self.ip4_via_gre4_tunnel.add_vpp_config()
 
         pgre4 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -952,7 +952,7 @@ class TestGSO(VppTestCase):
         # Create IPv6 packet
         #
         pgre6 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -1078,7 +1078,7 @@ class TestGSO(VppTestCase):
         # IPv4/IPv4 - IPSEC
         #
         ipsec44 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -1116,7 +1116,7 @@ class TestGSO(VppTestCase):
         # IPv4/IPv6 - IPSEC
         #
         ipsec46 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -1213,7 +1213,7 @@ class TestGSO(VppTestCase):
         # IPv6/IPv4 - IPSEC
         #
         ipsec64 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IP(src=self.pg2.remote_ip4, dst="172.16.10.3", flags="DF")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
@@ -1252,7 +1252,7 @@ class TestGSO(VppTestCase):
         # IPv6/IPv6 - IPSEC
         #
         ipsec66 = (
-            Ether(src=self.pg2.remote_mac, dst="02:fe:60:1e:a2:79")
+            Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
             / IPv6(src=self.pg2.remote_ip6, dst="fd01:10::3")
             / TCP(sport=1234, dport=1234)
             / Raw(b"\xa5" * 65200)
index fd97205..5fe4f36 100644 (file)
@@ -36,7 +36,7 @@ class TestGtpuUDP(VppTestCase):
 
     def _check_udp_port_ip4(self, enabled=True):
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
             / UDP(sport=self.dport, dport=self.dport, chksum=0)
         )
@@ -55,7 +55,7 @@ class TestGtpuUDP(VppTestCase):
 
     def _check_udp_port_ip6(self, enabled=True):
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
             / UDP(sport=self.dport, dport=self.dport, chksum=0)
         )
index a1cd943..84b060a 100644 (file)
@@ -3409,9 +3409,11 @@ class TestIP6LinkLocal(VppTestCase):
         # Use the specific link-local API on pg1
         #
         VppIp6LinkLocalAddress(self, self.pg1, ll1).add_vpp_config()
+        p_echo_request_1.dst = self.pg1.local_mac
         self.send_and_expect(self.pg1, [p_echo_request_1], self.pg1)
 
         VppIp6LinkLocalAddress(self, self.pg1, ll3).add_vpp_config()
+        p_echo_request_3.dst = self.pg1.local_mac
         self.send_and_expect(self.pg1, [p_echo_request_3], self.pg1)
 
     def test_ip6_ll_p2p(self):
index 6520992..10dc77e 100644 (file)
@@ -161,7 +161,7 @@ class TestNDPROXY(VppTestCase):
         redirect.add_vpp_config()
 
         echo_reply = (
-            Ether(dst=self.pg0.remote_mac, src=self.pg0.local_mac)
+            Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
             / IPv6(dst=self.pg0.local_ip6, src=self.pg0.remote_ip6)
             / ICMPv6EchoReply(seq=1, id=id)
         )
index 2817d5a..9574c2c 100644 (file)
@@ -677,7 +677,7 @@ class TestIPIP(VppTestCase):
                 / Raw(b"0x44" * 100)
             )
             tx_e = [
-                (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / inner)
+                (Ether(dst=self.pg2.local_mac, src=self.pg0.remote_mac) / inner)
                 for x in range(63)
             ]
 
@@ -1454,7 +1454,7 @@ class TestIPIPMPLS(VppTestCase):
         # Tunnel Decap
         #
         p4 = (
-            self.p_ether
+            Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
             / IP(src=self.pg1.remote_ip4, dst=self.pg1.local_ip4)
             / MPLS(label=44, ttl=4)
             / IP(src="1.1.1.1", dst="2.2.2.2")
@@ -1468,7 +1468,7 @@ class TestIPIPMPLS(VppTestCase):
             self.assertEqual(rx[IP].dst, "2.2.2.2")
 
         p6 = (
-            self.p_ether
+            Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
             / IPv6(src=self.pg1.remote_ip6, dst=self.pg1.local_ip6)
             / MPLS(label=66, ttl=4)
             / IPv6(src="1::1", dst="2::2")
index 351c599..69267b3 100644 (file)
@@ -126,7 +126,7 @@ class TestL3xc(VppTestCase):
         p_2 = []
         for ii in range(NUM_PKTS):
             p_2.append(
-                Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
+                Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac)
                 / IP(src="1.1.1.1", dst="1.1.1.2")
                 / UDP(sport=1000 + ii, dport=1234)
                 / Raw(b"\xa5" * 100)
index a9ff242..95a9f1a 100644 (file)
@@ -126,7 +126,7 @@ class TestLinuxCP(VppTestCase):
         for phy, host in zip(phys, hosts):
             for j in range(N_HOSTS):
                 p = (
-                    Ether(src=phy.local_mac, dst=phy.remote_hosts[j].mac)
+                    Ether(src=phy.local_mac, dst=host.local_mac)
                     / IP(src=phy.local_ip4, dst=phy.remote_hosts[j].ip4)
                     / UDP(sport=1234, dport=1234)
                     / Raw()
index 565f7da..c65c5df 100644 (file)
@@ -494,7 +494,7 @@ class TestMAP(VppTestCase):
         #
         # Send a v4 packet that will be encapped.
         #
-        p_ether = Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac)
+        p_ether = Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac)
         p_ip4 = IP(src=self.pg0.remote_ip4, dst="192.168.1.1")
         p_tcp = TCP(sport=20000, dport=30000, flags="S", options=[("MSS", 1455)])
         p4 = p_ether / p_ip4 / p_tcp
index 0de0e31..a2c00d8 100644 (file)
@@ -280,7 +280,7 @@ class TestMAPBR(VppTestCase):
     def test_map_t_echo_request_ip4_to_ip6(self):
         """MAP-T echo request IPv4 -> IPv6"""
 
-        eth = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
+        eth = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
         ip = IP(src=self.pg0.remote_ip4, dst=self.ipv4_map_address)
         icmp = ICMP(type="echo-request", id=self.ipv6_udp_or_tcp_map_port)
         payload = "H" * 10
@@ -306,7 +306,7 @@ class TestMAPBR(VppTestCase):
     def test_map_t_echo_reply_ip4_to_ip6(self):
         """MAP-T echo reply IPv4 -> IPv6"""
 
-        eth = Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
+        eth = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
         ip = IP(src=self.pg0.remote_ip4, dst=self.ipv4_map_address)
         icmp = ICMP(type="echo-reply", id=self.ipv6_udp_or_tcp_map_port)
         payload = "H" * 10
index 9c07251..0e747ec 100644 (file)
@@ -2018,7 +2018,7 @@ class TestMPLS(VppTestCase):
         binding.add_vpp_config()
 
         tx = (
-            Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / MPLS(label=44, ttl=64)
             / IP(src=self.pg0.remote_ip4, dst=self.pg0.remote_ip4)
             / UDP(sport=1234, dport=1234)
index ad1c561..dbf1dc4 100644 (file)
@@ -216,7 +216,7 @@ class TestNAT44EDOutput(VppTestCase):
         # send FIN+ACK packet in->out - will cause session to be wiped
         # but won't create a new session
         p = (
-            Ether(src=pg0.remote_mac, dst=pg0.local_mac)
+            Ether(src=pg1.remote_mac, dst=pg1.local_mac)
             / IP(src=local_host, dst=remote_host)
             / TCP(sport=local_sport, dport=remote_dport, flags="FA", seq=300, ack=101)
         )
index 6fcf13f..d11d4ab 100644 (file)
@@ -2176,6 +2176,7 @@ class ARPTestCase(VppTestCase):
             table_id=1,
         ).add_vpp_config()
 
+        p2.dst = self.pg3.local_mac
         rxs = self.send_and_expect(self.pg3, [p2], self.pg1)
         for rx in rxs:
             self.verify_arp_req(rx, self.pg1.local_mac, "10.0.1.2", "10.0.1.128")
index ae3a298..72d215c 100644 (file)
@@ -135,7 +135,7 @@ class TestPcap(VppTestCase):
         self.vapi.cli("classify filter pcap del mask l3 ip4 src")
 
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             # wrong destination address
             / IP(src=self.pg0.local_ip4, dst=self.pg0.local_ip4, ttl=2)
             / UDP(sport=1234, dport=2345)
index e407252..98c50f9 100644 (file)
@@ -1604,16 +1604,6 @@ class TestIPv6Reassembly(VppTestCase):
         self.assertIn(ICMPv6ParamProblem, icmp)
         self.assert_equal(icmp[ICMPv6ParamProblem].code, 3, "ICMP code")
 
-    def test_truncated_fragment(self):
-        """truncated fragment"""
-        pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
-            / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6, nh=44, plen=2)
-            / IPv6ExtHdrFragment(nh=6)
-        )
-
-        self.send_and_assert_no_replies(self.pg0, [pkt], self.pg0)
-
     def test_invalid_frag_size(self):
         """fragment size not a multiple of 8"""
         p = (
@@ -1657,7 +1647,7 @@ class TestIPv6Reassembly(VppTestCase):
     def test_atomic_fragment(self):
         """IPv6 atomic fragment"""
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6, nh=44, plen=65535)
             / IPv6ExtHdrFragment(
                 offset=8191, m=1, res1=0xFF, res2=0xFF, nh=255, id=0xFFFF
@@ -1679,7 +1669,7 @@ class TestIPv6Reassembly(VppTestCase):
         self.send_and_assert_no_replies(self.pg0, [pkt])
 
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.remote_ip6)
             / ICMPv6EchoRequest()
         )
@@ -1688,7 +1678,7 @@ class TestIPv6Reassembly(VppTestCase):
     def test_one_fragment(self):
         """whole packet in one fragment processed independently"""
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
             / ICMPv6EchoRequest()
             / Raw("X" * 1600)
@@ -1700,7 +1690,7 @@ class TestIPv6Reassembly(VppTestCase):
 
         # send an atomic fragment with same id - should be reassembled
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
             / IPv6ExtHdrFragment(id=1)
             / ICMPv6EchoRequest()
@@ -1715,7 +1705,7 @@ class TestIPv6Reassembly(VppTestCase):
     def test_bunch_of_fragments(self):
         """valid fragments followed by rogue fragments and atomic fragment"""
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
             / ICMPv6EchoRequest()
             / Raw("X" * 1600)
@@ -1733,7 +1723,7 @@ class TestIPv6Reassembly(VppTestCase):
         self.send_and_assert_no_replies(self.pg0, inc_frag * 604)
 
         pkt = (
-            Ether(src=self.pg0.local_mac, dst=self.pg0.remote_mac)
+            Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
             / IPv6(src=self.pg0.remote_ip6, dst=self.pg0.local_ip6)
             / IPv6ExtHdrFragment(id=1)
             / ICMPv6EchoRequest()
@@ -1748,7 +1738,7 @@ class TestIPv6Reassembly(VppTestCase):
         )
         self.vapi.ip_local_reass_enable_disable(enable_ip6=True)
         pkt = (
-            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
+            Ether(src=self.src_if.remote_mac, dst=self.src_if.local_mac)
             / IPv6(src=self.src_if.remote_ip6, dst=self.src_if.local_ip6)
             / ICMPv6EchoRequest(id=1234)
             / Raw("X" * 1600)
@@ -2194,7 +2184,7 @@ class TestIPv6SVReassembly(VppTestCase):
     def test_one_fragment(self):
         """whole packet in one fragment processed independently"""
         pkt = (
-            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
+            Ether(src=self.src_if.remote_mac, dst=self.src_if.local_mac)
             / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
             / ICMPv6EchoRequest()
             / Raw("X" * 1600)
@@ -2206,7 +2196,7 @@ class TestIPv6SVReassembly(VppTestCase):
 
         # send an atomic fragment with same id - should be reassembled
         pkt = (
-            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
+            Ether(src=self.src_if.remote_mac, dst=self.src_if.local_mac)
             / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
             / IPv6ExtHdrFragment(id=1)
             / ICMPv6EchoRequest()
@@ -2219,7 +2209,7 @@ class TestIPv6SVReassembly(VppTestCase):
     def test_bunch_of_fragments(self):
         """valid fragments followed by rogue fragments and atomic fragment"""
         pkt = (
-            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
+            Ether(src=self.src_if.remote_mac, dst=self.src_if.local_mac)
             / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
             / ICMPv6EchoRequest()
             / Raw("X" * 1600)
@@ -2228,7 +2218,7 @@ class TestIPv6SVReassembly(VppTestCase):
         rx = self.send_and_expect(self.src_if, frags, self.dst_if)
 
         rogue = (
-            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
+            Ether(src=self.src_if.remote_mac, dst=self.src_if.local_mac)
             / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
             / IPv6ExtHdrFragment(id=1, nh=58, offset=608)
             / Raw("X" * 308)
@@ -2237,7 +2227,7 @@ class TestIPv6SVReassembly(VppTestCase):
         self.send_and_expect(self.src_if, rogue * 604, self.dst_if)
 
         pkt = (
-            Ether(src=self.src_if.local_mac, dst=self.src_if.remote_mac)
+            Ether(src=self.src_if.remote_mac, dst=self.src_if.local_mac)
             / IPv6(src=self.src_if.remote_ip6, dst=self.dst_if.remote_ip6)
             / IPv6ExtHdrFragment(id=1)
             / ICMPv6EchoRequest()
index 9d39f19..314dfc1 100644 (file)
@@ -60,7 +60,7 @@ class TestSRv6EndMGTP4E(VppTestCase):
         pkts = list()
         for d, s in inner:
             pkt = (
-                Ether()
+                Ether(dst=self.pg0.local_mac)
                 / IPv6(dst=str(ip6_dst), src=str(ip6_src))
                 / IPv6ExtHdrSegmentRouting()
                 / IPv6(dst=d, src=s)
@@ -149,7 +149,7 @@ class TestSRv6TMGTP4D(VppTestCase):
         pkts = list()
         for d, s in inner:
             pkt = (
-                Ether()
+                Ether(dst=self.pg0.local_mac)
                 / IP(dst=str(ip4_dst), src=str(ip4_src))
                 / UDP(sport=2152, dport=2152)
                 / GTP_U_Header(gtp_type="g_pdu", teid=200)
@@ -254,7 +254,7 @@ class TestSRv6EndMGTP6E(VppTestCase):
         pkts = list()
         for d, s in inner:
             pkt = (
-                Ether()
+                Ether(dst=self.pg0.local_mac)
                 / IPv6(dst=str(ip6_dst), src=str(ip6_src))
                 / IPv6ExtHdrSegmentRouting(
                     segleft=1, lastentry=0, tag=0, addresses=["a1::1"]
@@ -344,7 +344,7 @@ class TestSRv6EndMGTP6D(VppTestCase):
         pkts = list()
         for d, s in inner:
             pkt = (
-                Ether()
+                Ether(dst=self.pg0.local_mac)
                 / IPv6(dst=str(ip6_dst), src=str(ip6_src))
                 / UDP(sport=2152, dport=2152)
                 / GTP_U_Header(gtp_type="g_pdu", teid=200)
index 58494cd..c188631 100644 (file)
@@ -386,7 +386,7 @@ class TestTraceFilterInner(TemplateTraceFilter):
 
     def __gen_encrypt_pkt(self, scapy_sa, pkt):
         return Ether(
-            src=self.pg0.local_mac, dst=self.pg0.remote_mac
+            src=self.pg0.remote_mac, dst=self.pg0.local_mac
         ) / scapy_sa.encrypt(pkt)
 
     def test_encrypted_encap(self):
index 6128d10..284e135 100644 (file)
@@ -580,6 +580,7 @@ class TestVxlanL2Mode(VppTestCase):
 
         # Send packets
         NUM_PKTS = 128
+        p.dst = self.pg1.local_mac
         rx = self.send_and_expect(self.pg1, p * NUM_PKTS, self.pg0)
         self.assertEqual(NUM_PKTS, len(rx))