From 10c0f2cfdcd4a6441009ea8895fc2a968d6c9603 Mon Sep 17 00:00:00 2001 From: natexornate Date: Mon, 7 Feb 2022 18:17:30 +0000 Subject: [PATCH 01/62] Ensure that kMaxBurst is explicitly defined kMaxBurst was declared and assigned a value, but not explicitly defined. This can cause issues when linking in cases where a reference may be taken of kMaxBurst (say, passing it to std::min()) and the constant can't be fully optimized out. This was actually fixed years ago in #522 but ended up being reverted accidentally during a refactor in #820. With C++17 now, we don't have to put the definition in a source file, we can just add inline and that takes care of it. --- core/pktbatch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pktbatch.h b/core/pktbatch.h index a90c4ff14a..260b53cf65 100644 --- a/core/pktbatch.h +++ b/core/pktbatch.h @@ -67,7 +67,7 @@ class PacketBatch { bess::utils::CopyInlined(pkts_, src->pkts_, cnt_ * sizeof(Packet *)); } - static const size_t kMaxBurst = 32; + inline static const size_t kMaxBurst = 32; private: int cnt_; From 1d84e57deea01d8f1a0142f079b14b5abff83ff8 Mon Sep 17 00:00:00 2001 From: Saikrishna Edupuganti Date: Wed, 3 Feb 2021 08:45:53 +0000 Subject: [PATCH 02/62] Upgrade DPDK to 20.11 - address memseg and mbuf changes - move to meson/ninja build system Signed-off-by: Saikrishna Edupuganti --- bessctl/conf/port/vhost/launch_vm.py | 2 +- build.py | 60 ++++------------------------ container_build.py | 2 +- core/Makefile | 22 ++-------- core/packet.h | 10 +---- core/packet_pool.cc | 6 +-- env/Dockerfile | 2 +- env/build-dep.yml | 12 +++++- 8 files changed, 29 insertions(+), 87 deletions(-) diff --git a/bessctl/conf/port/vhost/launch_vm.py b/bessctl/conf/port/vhost/launch_vm.py index e17b8b6928..7417b0eacc 100755 --- a/bessctl/conf/port/vhost/launch_vm.py +++ b/bessctl/conf/port/vhost/launch_vm.py @@ -175,7 +175,7 @@ def run_forward(vm_id, num_nics): nics += ' 00:1{nic}.0'.format(nic=i) scp(vm_id, os.path.join(bess_dir, 'bin/dpdk-devbind.py'), '') - scp(vm_id, os.path.join(bess_dir, 'deps/dpdk-19.11.4/build/app/testpmd'), '') + scp(vm_id, os.path.join(bess_dir, 'deps/dpdk-20.11/build/app/dpdk-testpmd'), '') # virtio-pci devices should not be bound to any driver cmd = ssh_cmd(vm_id, 'sudo ./dpdk-devbind.py -u %s' % nics) diff --git a/build.py b/build.py index ff4289523d..299a8ca459 100755 --- a/build.py +++ b/build.py @@ -89,14 +89,13 @@ def cmd(cmd, quiet=False, shell=False): DEPS_DIR = '%s/deps' % BESS_DIR DPDK_URL = 'https://fast.dpdk.org/rel' -DPDK_VER = 'dpdk-19.11.4' +DPDK_VER = 'dpdk-20.11' DPDK_TARGET = 'x86_64-native-linuxapp-gcc' kernel_release = cmd('uname -r', quiet=True).strip() DPDK_DIR = '%s/%s' % (DEPS_DIR, DPDK_VER) -DPDK_CFLAGS = '"-g -w"' -DPDK_CONFIG = '%s/build/.config' % DPDK_DIR +DPDK_BUILD = '%s/build' % DPDK_DIR extra_libs = set() cxx_flags = [] @@ -213,46 +212,6 @@ def is_kernel_header_installed(): return os.path.isdir("/lib/modules/%s/build" % kernel_release) -def check_kernel_headers(): - # If kernel header is not available, do not attempt to build - # any components that require kernel. - if not is_kernel_header_installed(): - set_config(DPDK_CONFIG, 'CONFIG_RTE_EAL_IGB_UIO', 'n') - set_config(DPDK_CONFIG, 'CONFIG_RTE_KNI_KMOD', 'n') - set_config(DPDK_CONFIG, 'CONFIG_RTE_LIBRTE_KNI', 'n') - set_config(DPDK_CONFIG, 'CONFIG_RTE_LIBRTE_PMD_KNI', 'n') - - -def check_bnx(): - if check_header('zlib.h', 'gcc') and check_c_lib('z'): - extra_libs.add('z') - else: - print(' - "zlib1g-dev" is not available. Disabling BNX2X PMD...') - set_config(DPDK_CONFIG, 'CONFIG_RTE_LIBRTE_BNX2X_PMD', 'n') - - -def check_mlx(): - if check_header('infiniband/ib.h', 'gcc') and check_c_lib('mlx4') and \ - check_c_lib('mlx5'): - extra_libs.add('ibverbs') - extra_libs.add('mlx4') - extra_libs.add('mlx5') - else: - print(' - "Mellanox OFED" is not available. ' - 'Disabling MLX4 and MLX5 PMDs...') - if check_header('infiniband/verbs.h', 'gcc'): - print(' NOTE: "libibverbs-dev" does exist, but it does not ' - 'work with MLX PMDs. Instead download OFED from ' - 'http://www.melloanox.com') - set_config(DPDK_CONFIG, 'CONFIG_RTE_LIBRTE_MLX4_PMD', 'n') - set_config(DPDK_CONFIG, 'CONFIG_RTE_LIBRTE_MLX5_PMD', 'n') - - -def generate_dpdk_extra_mk(): - with open('core/extra.dpdk.mk', 'w') as fp: - fp.write('LIBS += %s\n' % ' '.join(['-l' + lib for lib in extra_libs])) - - def find_current_plugins(): "return list of existing plugins" result = [] @@ -293,16 +252,14 @@ def download_dpdk(quiet=False): def configure_dpdk(): print('Configuring DPDK...') - cmd('make -C %s config T=%s' % (DPDK_DIR, DPDK_TARGET)) - - check_kernel_headers() - check_mlx() - generate_dpdk_extra_mk() + meson_opts = '--buildtype=debugoptimized' arch = os.getenv('CPU') if arch: print(' - Building DPDK with -march=%s' % arch) - set_config(DPDK_CONFIG, "CONFIG_RTE_MACHINE", arch) + meson_opts += ' -Dmachine=%s' % arch + + cmd('meson %s %s %s' % (meson_opts, DPDK_BUILD, DPDK_DIR)) def makeflags(): @@ -342,10 +299,7 @@ def build_dpdk(): cmd('patch -d %s -N -p1 < %s || true' % (DPDK_DIR, f), shell=True) print('Building DPDK...') - nproc = int(cmd('nproc', quiet=True)) - cmd('make -C %s EXTRA_CFLAGS=%s %s' % (DPDK_DIR, - DPDK_CFLAGS, - makeflags())) + cmd('ninja -C %s install' % DPDK_BUILD) def generate_protobuf_files(): diff --git a/container_build.py b/container_build.py index d8b4bf3dc7..a0b2a87940 100755 --- a/container_build.py +++ b/container_build.py @@ -39,7 +39,7 @@ import re import argparse -IMAGE = 'nefelinetworks/bess_build:latest' + os.getenv('TAG_SUFFIX', '') +IMAGE = 'nefelinetworks/bess_build:' + os.getenv('TAG_SUFFIX', 'latest') BESS_DIR_HOST = os.path.dirname(os.path.abspath(__file__)) BESS_DIR_CONTAINER = '/build/bess' BUILD_SCRIPT = './build.py' diff --git a/core/Makefile b/core/Makefile index cff1117379..6574179168 100644 --- a/core/Makefile +++ b/core/Makefile @@ -61,28 +61,13 @@ endif HAS_PKG_CONFIG := $(shell command -v $(PKG_CONFIG) 2>&1 >/dev/null && echo yes || echo no) -RTE_SDK ?= $(abspath ../deps/dpdk-19.11.4) -RTE_TARGET ?= $(shell uname -m)-native-linuxapp-gcc -DPDK_LIB ?= dpdk - -ifneq ($(wildcard $(RTE_SDK)/$(RTE_TARGET)/*),) - DPDK_INC_DIR := $(RTE_SDK)/$(RTE_TARGET)/include - DPDK_LIB_DIR := $(RTE_SDK)/$(RTE_TARGET)/build/lib -else ifneq ($(wildcard $(RTE_SDK)/build/*),) - # if the user didn't do "make install" for DPDK - DPDK_INC_DIR := $(RTE_SDK)/build/include - DPDK_LIB_DIR := $(RTE_SDK)/build/lib -else ifneq ($(MAKECMDGOALS),clean) - $(error DPDK is not available. Make sure $(abspath $(RTE_SDK)) is available and built) -endif - # We always want these libraries to be dynamically linked even when the # user requests a static build. ALWAYS_DYN_LIBS := -lpthread -ldl # These libraries are not supported by pkg-config. ALWAYS_LIBS := -lpcap -lgflags -lnuma # If pkg-config is available, we just need a list of the dependecies. -PKG_CONFIG_DEPS := libglog protobuf grpc++ libunwind zlib +PKG_CONFIG_DEPS := libdpdk libglog protobuf grpc++ libunwind zlib # If pkg-config is not available, we need to list the libs we depend on. NO_PKG_CONFIG_LIBS := -lglog -lgflags -lprotobuf -lgrpc++ -lunwind -lz # If pkg-config is not available and we're static linking, we also need @@ -110,7 +95,7 @@ endif COREDIR := $(abspath .) CPU ?= native CXXFLAGS += -std=c++17 -g3 -ggdb3 -march=$(CPU) \ - -isystem $(DPDK_INC_DIR) -isystem $(COREDIR) \ + -isystem $(COREDIR) \ -isystem $(dir $<).. -isystem $(COREDIR)/modules \ -D_GNU_SOURCE \ -Werror -Wall -Wextra -Wcast-align -Wno-error=deprecated-declarations \ @@ -133,7 +118,7 @@ ifeq "$(shell expr $(CXXCOMPILER) = g++)" "1" CXXFLAGS += -fno-gnu-unique endif -LDFLAGS += -rdynamic -L$(DPDK_LIB_DIR) -Wl,-rpath=$(DPDK_LIB_DIR) -pthread +LDFLAGS += -rdynamic ifdef BESS_LINK_DYNAMIC LIBS_ALL_SHARED = -Wl,-call_shared LIBS_DL_SHARED = @@ -158,7 +143,6 @@ else # Used static libraries endif LIBS += -Wl,-non_shared \ - -Wl,--whole-archive -l$(DPDK_LIB) -Wl,--no-whole-archive \ $(LIBS_ALL_SHARED) \ $(PKG_LIBS) $(ALWAYS_LIBS) \ $(LIBS_DL_SHARED) \ diff --git a/core/packet.h b/core/packet.h index 6b9b2ef7bc..0471f383cc 100644 --- a/core/packet.h +++ b/core/packet.h @@ -261,20 +261,14 @@ class alignas(64) Packet { const uint16_t buf_len_; // offset 56: - uint64_t _dummy6_; // rte_mbuf.timestamp - - // 2nd cacheline - fields only used in slow path or on TX -------------- - // offset 64: - uint64_t _dummy7_; // rte_mbuf.userdata - - // offset 72: struct rte_mempool *pool_; // Pool from which mbuf was allocated. - // offset 80: + // offset 60: Packet *next_; // Next segment. nullptr if not scattered. // offset 88: uint64_t _dummy8; // rte_mbuf.tx_offload + // TODO: Add struct rte_mbuf_ext_shared_info *shinfo; uint16_t _dummy9; // rte_mbuf.priv_size uint16_t _dummy10; // rte_mbuf.timesync uint32_t _dummy11; // rte_mbuf.seqn diff --git a/core/packet_pool.cc b/core/packet_pool.cc index a1d529f02c..c453fccd2c 100644 --- a/core/packet_pool.cc +++ b/core/packet_pool.cc @@ -241,14 +241,14 @@ DpdkPacketPool::DpdkPacketPool(size_t capacity, int socket_id) static Packet *paddr_to_snb_memchunk(struct rte_mempool_memhdr *chunk, phys_addr_t paddr) { - if (chunk->phys_addr == RTE_BAD_IOVA) { + if (chunk->iova == RTE_BAD_IOVA) { return nullptr; } - if (chunk->phys_addr <= paddr && paddr < chunk->phys_addr + chunk->len) { + if (chunk->iova <= paddr && paddr < chunk->iova + chunk->len) { uintptr_t vaddr; - vaddr = (uintptr_t)chunk->addr + paddr - chunk->phys_addr; + vaddr = (uintptr_t)chunk->addr + paddr - chunk->iova; return reinterpret_cast(vaddr); } diff --git a/env/Dockerfile b/env/Dockerfile index cc289480bd..e1553786b9 100644 --- a/env/Dockerfile +++ b/env/Dockerfile @@ -29,7 +29,7 @@ ARG BESS_DPDK_BRANCH=master RUN cd /build/bess && \ curl -s -L https://github.com/NetSys/bess/archive/${BESS_DPDK_BRANCH}.tar.gz | tar zx --strip-components=1 && \ ./build.py dpdk && \ - cp /build/bess/deps/dpdk-19.11.4/build/app/testpmd /usr/local/bin/ && \ + cp /build/bess/deps/dpdk-20.11/build/app/dpdk-testpmd /usr/local/bin/ && \ rm -rf /build/bess ENV CCACHE_DIR=/tmp/ccache diff --git a/env/build-dep.yml b/env/build-dep.yml index 5f9af1f2fc..431e224a3a 100644 --- a/env/build-dep.yml +++ b/env/build-dep.yml @@ -23,9 +23,19 @@ - libgflags-dev - libgoogle-glog-dev - libgtest-dev - - python + - python3 + - python3-pip + - python3-setuptools - pkg-config + - name: Install DPDK build system + become: true + pip: + name: + - meson + - ninja + executable: pip3 + # pre-packaged meat for Bionic Beaver or higher - name: Install gRPC and its requirements (apt) apt: name={{item}} From b1a53089ca4a40e1372f73166d792869ef16f3bd Mon Sep 17 00:00:00 2001 From: Saikrishna Edupuganti Date: Tue, 7 Sep 2021 15:25:47 +0000 Subject: [PATCH 03/62] Update DPDK version to 20.11.3 ice ddp loading seems reliable when using a PF with this version Signed-off-by: Saikrishna Edupuganti --- bessctl/conf/port/vhost/launch_vm.py | 2 +- build.py | 2 +- env/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bessctl/conf/port/vhost/launch_vm.py b/bessctl/conf/port/vhost/launch_vm.py index 7417b0eacc..7c7c4296c0 100755 --- a/bessctl/conf/port/vhost/launch_vm.py +++ b/bessctl/conf/port/vhost/launch_vm.py @@ -175,7 +175,7 @@ def run_forward(vm_id, num_nics): nics += ' 00:1{nic}.0'.format(nic=i) scp(vm_id, os.path.join(bess_dir, 'bin/dpdk-devbind.py'), '') - scp(vm_id, os.path.join(bess_dir, 'deps/dpdk-20.11/build/app/dpdk-testpmd'), '') + scp(vm_id, os.path.join(bess_dir, 'deps/dpdk-20.11.3/build/app/dpdk-testpmd'), '') # virtio-pci devices should not be bound to any driver cmd = ssh_cmd(vm_id, 'sudo ./dpdk-devbind.py -u %s' % nics) diff --git a/build.py b/build.py index 299a8ca459..35c0741b35 100755 --- a/build.py +++ b/build.py @@ -89,7 +89,7 @@ def cmd(cmd, quiet=False, shell=False): DEPS_DIR = '%s/deps' % BESS_DIR DPDK_URL = 'https://fast.dpdk.org/rel' -DPDK_VER = 'dpdk-20.11' +DPDK_VER = 'dpdk-20.11.3' DPDK_TARGET = 'x86_64-native-linuxapp-gcc' kernel_release = cmd('uname -r', quiet=True).strip() diff --git a/env/Dockerfile b/env/Dockerfile index e1553786b9..80f0850076 100644 --- a/env/Dockerfile +++ b/env/Dockerfile @@ -29,7 +29,7 @@ ARG BESS_DPDK_BRANCH=master RUN cd /build/bess && \ curl -s -L https://github.com/NetSys/bess/archive/${BESS_DPDK_BRANCH}.tar.gz | tar zx --strip-components=1 && \ ./build.py dpdk && \ - cp /build/bess/deps/dpdk-20.11/build/app/dpdk-testpmd /usr/local/bin/ && \ + cp /build/bess/deps/dpdk-20.11.3/build/app/dpdk-testpmd /usr/local/bin/ && \ rm -rf /build/bess ENV CCACHE_DIR=/tmp/ccache From 7d0d1f0f24d334307934d16af1126ef0229e59dc Mon Sep 17 00:00:00 2001 From: Saikrishna Edupuganti Date: Fri, 24 Sep 2021 07:25:53 +0000 Subject: [PATCH 04/62] Allow override of base image with IMAGE IMAGE="ghcr.io/omec-project/upf-epc/bess_build" \ ./container_build.py shell Signed-off-by: Saikrishna Edupuganti --- container_build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/container_build.py b/container_build.py index a0b2a87940..d645a4028b 100755 --- a/container_build.py +++ b/container_build.py @@ -39,7 +39,7 @@ import re import argparse -IMAGE = 'nefelinetworks/bess_build:' + os.getenv('TAG_SUFFIX', 'latest') +IMAGE = os.getenv('IMAGE', 'nefelinetworks/bess_build') + ':' + os.getenv('TAG_SUFFIX', 'latest') BESS_DIR_HOST = os.path.dirname(os.path.abspath(__file__)) BESS_DIR_CONTAINER = '/build/bess' BUILD_SCRIPT = './build.py' From c422de265b52a750fda8fdd5b19f415ef8e7c234 Mon Sep 17 00:00:00 2001 From: Saikrishna Edupuganti Date: Mon, 27 Sep 2021 12:51:03 +0000 Subject: [PATCH 05/62] Use focal base image Signed-off-by: Saikrishna Edupuganti --- env/Dockerfile | 6 ++---- env/rebuild_images.py | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/env/Dockerfile b/env/Dockerfile index 80f0850076..26e8a66df4 100644 --- a/env/Dockerfile +++ b/env/Dockerfile @@ -1,8 +1,6 @@ # vim: syntax=dockerfile -# Bionic Beaver (18.04) does not require ppa repositories for any packages -# we need, such as g++-7, clang-6.0, ansible, grpc, etc. -ARG BASE_IMAGE=ubuntu:bionic +ARG BASE_IMAGE=ubuntu:focal FROM ${BASE_IMAGE} RUN echo "APT::Install-Recommends false;" >> /etc/apt/apt.conf.d/00recommends && \ @@ -21,7 +19,7 @@ RUN apt-get -q update && \ apt-get purge -y ansible && \ apt-get autoremove -y && \ rm -rf /var/lib/apt/lists - +RUN update-alternatives --install /usr/local/bin/python python /usr/bin/python3 3 RUN mkdir -p /build/bess # Build DPDK testpmd (used in bessctl samples) diff --git a/env/rebuild_images.py b/env/rebuild_images.py index a7c540e845..be9caf16e5 100755 --- a/env/rebuild_images.py +++ b/env/rebuild_images.py @@ -40,7 +40,7 @@ TARGET_REPO = 'nefelinetworks/bess_build' imgs = { - 'bionic64': {'base': 'ubuntu:bionic', 'tag_suffix': ''}, + 'focal64': {'base': 'ubuntu:focal', 'tag_suffix': ''}, } From 13278ff5cd205eb6896cd59f1912f7eb64aed04d Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:30:09 -0700 Subject: [PATCH 06/62] 0001-Add-2-workers-support-to-Nat-module --- core/modules/nat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/core/modules/nat.h b/core/modules/nat.h index ff29dbf555..4ec594de92 100644 --- a/core/modules/nat.h +++ b/core/modules/nat.h @@ -133,6 +133,7 @@ struct PortRange { // igate/ogate 1: reverse dir class NAT final : public Module { public: + NAT() { max_allowed_workers_ = 2; } enum Direction { kForward = 0, // internal -> external kReverse = 1, // external -> internal From 96b4bcfcad5d6cfd6efaaa021d396a07fe2aeb63 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:31:01 -0700 Subject: [PATCH 07/62] 0002-Use-same-rss-key-across-interfaces --- core/drivers/pmd.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index fd4a7b0572..d0b59b58dd 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -36,6 +36,13 @@ #include "../utils/ether.h" #include "../utils/format.h" +// TODO: Replace with one time initialized key during InitDriver? +static uint8_t rss_key[40] = {0xD8, 0x2A, 0x6C, 0x5A, 0xDD, 0x3B, 0x9D, 0x1E, + 0x14, 0xCE, 0x2F, 0x37, 0x86, 0xB2, 0x69, 0xF0, + 0x44, 0x31, 0x7E, 0xA2, 0x07, 0xA5, 0x0A, 0x99, + 0x49, 0xC6, 0xA4, 0xFE, 0x0C, 0x4F, 0x59, 0x02, + 0xD4, 0x44, 0xE2, 0x4A, 0xDB, 0xE1, 0x05, 0x82}; + static const rte_eth_conf default_eth_conf(const rte_eth_dev_info &dev_info, int nb_rxq) { rte_eth_conf ret = {}; @@ -45,8 +52,8 @@ static const rte_eth_conf default_eth_conf(const rte_eth_dev_info &dev_info, ret.rxmode.offloads = 0; ret.rx_adv_conf.rss_conf = { - .rss_key = nullptr, - .rss_key_len = 0, + .rss_key = rss_key, + .rss_key_len = sizeof(rss_key), .rss_hf = (ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP | ETH_RSS_SCTP) & dev_info.flow_type_rss_offloads, }; From 50f0da54da6ca73188ee749d9eff5f9e1e3699cb Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:32:16 -0700 Subject: [PATCH 08/62] 0003-Add-FIB-routing-support-in-IPLookup-module --- core/modules/ip_lookup.cc | 63 +++++++++++++++++++++++++++++++++++++-- core/modules/ip_lookup.h | 14 +++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/core/modules/ip_lookup.cc b/core/modules/ip_lookup.cc index 3c8b115717..7e976d413c 100644 --- a/core/modules/ip_lookup.cc +++ b/core/modules/ip_lookup.cc @@ -32,7 +32,6 @@ #include #include -#include #include "../utils/bits.h" #include "../utils/ether.h" @@ -54,15 +53,26 @@ const Commands IPLookup::cmds = { Command::THREAD_UNSAFE}}; CommandResponse IPLookup::Init(const bess::pb::IPLookupArg &arg) { +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) struct rte_lpm_config conf = { .max_rules = arg.max_rules() ? arg.max_rules() : 1024, .number_tbl8s = arg.max_tbl8s() ? arg.max_tbl8s() : 128, .flags = 0, }; +#else + conf.type = RTE_FIB_DIR24_8; + conf.default_nh = DROP_GATE; + conf.max_routes = arg.max_rules() ? (int)arg.max_rules() : 1024; + conf.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B; + conf.dir24_8.num_tbl8 = arg.max_tbl8s() ? arg.max_tbl8s() : 128; +#endif default_gate_ = DROP_GATE; - - lpm_ = rte_lpm_create(name().c_str(), /* socket_id = */ 0, &conf); +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) + lpm_ = rte_lpm_create(name().c_str(), /* socket_id = */ rte_socket_id(), &conf); +#else + lpm_ = rte_fib_create(name().c_str(), /* socket_id = */ rte_socket_id(), &conf); +#endif if (!lpm_) { return CommandFailure(rte_errno, "DPDK error: %s", rte_strerror(rte_errno)); @@ -73,7 +83,11 @@ CommandResponse IPLookup::Init(const bess::pb::IPLookupArg &arg) { void IPLookup::DeInit() { if (lpm_) { +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) rte_lpm_free(lpm_); +#else + rte_fib_free(lpm_); +#endif } } @@ -86,6 +100,7 @@ void IPLookup::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { int cnt = batch->cnt(); int i; +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) #if VECTOR_OPTIMIZATION // Convert endianness for four addresses at the same time const __m128i bswap_mask = @@ -148,6 +163,29 @@ void IPLookup::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { EmitPacket(ctx, batch->pkts()[i], default_gate); } } +#else /* RTE_VERSION >= 19.11 */ + Ethernet *eth; + Ipv4 *ip; + int ret; + uint32_t ip_list[cnt]; + uint64_t next_hops[cnt]; + + for (i = 0; i < cnt; i++) { + eth = batch->pkts()[i]->head_data(); + ip = (Ipv4 *)(eth + 1); + ip_list[i] = ip->dst.value(); + } + + ret = rte_fib_lookup_bulk(lpm_, ip_list, next_hops, cnt); + + if (ret != 0) + RunNextModule(ctx, batch); + else + for (i = 0; i < cnt; i++) { + EmitPacket(ctx, batch->pkts()[i], (next_hops[i] == DROP_GATE) ? default_gate_ : next_hops[i]); + } + USED(default_gate); +#endif } ParsedPrefix IPLookup::ParseIpv4Prefix( @@ -201,7 +239,12 @@ CommandResponse IPLookup::CommandAdd( default_gate_ = gate; } else { be32_t net_addr = std::get<2>(prefix); +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) int ret = rte_lpm_add(lpm_, net_addr.value(), prefix_len, gate); +#else + uint64_t next_hop = (uint64_t)gate; + int ret = rte_fib_add(lpm_, net_addr.value(), prefix_len, next_hop); +#endif if (ret) { return CommandFailure(-ret, "rpm_lpm_add() failed"); } @@ -223,7 +266,11 @@ CommandResponse IPLookup::CommandDelete( default_gate_ = DROP_GATE; } else { be32_t net_addr = std::get<2>(prefix); +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) int ret = rte_lpm_delete(lpm_, net_addr.value(), prefix_len); +#else + int ret = rte_fib_delete(lpm_, net_addr.value(), prefix_len); +#endif if (ret) { return CommandFailure(-ret, "rpm_lpm_delete() failed"); } @@ -233,7 +280,17 @@ CommandResponse IPLookup::CommandDelete( } CommandResponse IPLookup::CommandClear(const bess::pb::EmptyArg &) { +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) rte_lpm_delete_all(lpm_); +#else + /* rte_fib_delete_all(lpm_) does not exist! */ + rte_fib_free(lpm_); + + lpm_ = rte_fib_create(name().c_str(), /* socket_id = */ 0, &conf); + if (!lpm_) { + return CommandFailure(rte_errno, "DPDK error: %s", rte_strerror(rte_errno)); + } +#endif return CommandSuccess(); } diff --git a/core/modules/ip_lookup.h b/core/modules/ip_lookup.h index de020e7f43..a866ad085e 100644 --- a/core/modules/ip_lookup.h +++ b/core/modules/ip_lookup.h @@ -34,6 +34,15 @@ #include "../module.h" #include "../pb/module_msg.pb.h" #include "../utils/endian.h" +#include +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) +#include +#else +#define USED(x) (void)(x) +extern "C" { +#include +} +#endif using bess::utils::be32_t; using ParsedPrefix = std::tuple; @@ -59,7 +68,12 @@ class IPLookup final : public Module { CommandResponse CommandClear(const bess::pb::EmptyArg &arg); private: +#if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) struct rte_lpm *lpm_; +#else + struct rte_fib *lpm_; + struct rte_fib_conf conf; +#endif gate_idx_t default_gate_; ParsedPrefix ParseIpv4Prefix(const std::string &prefix, uint64_t prefix_len); }; From 8e55ba9feaaac80f7361b69363c173c2f332350c Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:33:15 -0700 Subject: [PATCH 09/62] 0004-IOVA-mode-correction --- core/dpdk.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/dpdk.cc b/core/dpdk.cc index ffade53059..964d513c2c 100644 --- a/core/dpdk.cc +++ b/core/dpdk.cc @@ -123,8 +123,10 @@ void init_eal(int dpdk_mb_per_socket, std::string nonworker_corelist) { "--legacy-mem", }; + if (FLAGS_iova != "") + rte_args.Append({"--iova", FLAGS_iova}); + if (dpdk_mb_per_socket <= 0) { - rte_args.Append({"--iova", (FLAGS_iova != "") ? FLAGS_iova : "va"}); rte_args.Append({"--no-huge"}); // even if we opt out of using hugepages, many DPDK libraries still rely on @@ -132,8 +134,6 @@ void init_eal(int dpdk_mb_per_socket, std::string nonworker_corelist) { // memory in advance. We allocate 512MB (this is shared among nodes). rte_args.Append({"-m", "512"}); } else { - rte_args.Append({"--iova", (FLAGS_iova != "") ? FLAGS_iova : "pa"}); - std::string opt_socket_mem = std::to_string(dpdk_mb_per_socket); for (int i = 1; i < NumNumaNodes(); i++) { opt_socket_mem += "," + std::to_string(dpdk_mb_per_socket); From 6a9f461aed0425c2b34c45c0f3ad2426183695c5 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:34:14 -0700 Subject: [PATCH 10/62] 0005-Expose-PMDPort-socket-memory-allocation --- core/drivers/pmd.cc | 12 +++++++++--- protobuf/ports/port_msg.proto | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index d0b59b58dd..42d46230d2 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -258,10 +258,15 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { return CommandFailure(-ret, "rte_eth_dev_configure() failed"); } - int sid = rte_eth_dev_socket_id(ret_port_id); + int sid = arg.socket_case() == bess::pb::PMDPortArg::kSocketId ? + arg.socket_id() : rte_eth_dev_socket_id(ret_port_id); + /* if socket_id is invalid, set to 0 */ if (sid < 0 || sid > RTE_MAX_NUMA_NODES) { - sid = 0; // if socket_id is invalid, set to 0 + LOG(WARNING) << "Invalid socket, falling back... "; + sid = 0; } + LOG(INFO) << "Initializing Port:" << ret_port_id + << " with memory from socket " << sid; eth_rxconf = dev_info.default_rxconf; eth_rxconf.rx_drop_en = 1; @@ -334,7 +339,8 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { } dpdk_port_id_ = ret_port_id; - int numa_node = rte_eth_dev_socket_id(static_cast(ret_port_id)); + int numa_node = arg.socket_case() == bess::pb::PMDPortArg::kSocketId ? + sid : rte_eth_dev_socket_id(ret_port_id); node_placement_ = numa_node == -1 ? UNCONSTRAINED_SOCKET : (1ull << numa_node); diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index ff6e65ede2..1e8b6af879 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -47,6 +47,9 @@ message PMDPortArg { bool vlan_offload_rx_strip = 5; bool vlan_offload_rx_filter = 6; bool vlan_offload_rx_qinq = 7; + oneof socket { + int32 socket_id = 8; + } } message UnixSocketPortArg { From 0549ee2443e905ba742f96d8d315945e14830a47 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:35:01 -0700 Subject: [PATCH 11/62] 0006-Add-switch-for-promiscuous-mode --- core/drivers/pmd.cc | 7 ++++++- protobuf/ports/port_msg.proto | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index 42d46230d2..7409266731 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -320,7 +320,12 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { } } - rte_eth_promiscuous_enable(ret_port_id); + if (arg.promiscuous_mode()) { + ret = rte_eth_promiscuous_enable(ret_port_id); + if (ret != 0) { + return CommandFailure(-ret, "rte_eth_promiscuous_enable() failed"); + } + } int offload_mask = 0; offload_mask |= arg.vlan_offload_rx_strip() ? ETH_VLAN_STRIP_OFFLOAD : 0; diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index 1e8b6af879..853380e1c2 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -50,6 +50,7 @@ message PMDPortArg { oneof socket { int32 socket_id = 8; } + bool promiscuous_mode = 9; } message UnixSocketPortArg { From 191fd637e8b1dd03561910099f6fe3bffe2b41c6 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:36:17 -0700 Subject: [PATCH 12/62] 0008-Enable-hardware-checksum-offload --- core/drivers/pmd.cc | 7 +++++++ protobuf/ports/port_msg.proto | 1 + 2 files changed, 8 insertions(+) diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index 7409266731..5699b542a0 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -252,9 +252,16 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { if (arg.loopback()) { eth_conf.lpbk_mode = 1; } + if (arg.hwcksum()) { + eth_conf.rxmode.offloads = DEV_RX_OFFLOAD_IPV4_CKSUM | + DEV_RX_OFFLOAD_UDP_CKSUM | + DEV_RX_OFFLOAD_TCP_CKSUM; + } ret = rte_eth_dev_configure(ret_port_id, num_rxq, num_txq, ð_conf); if (ret != 0) { + VLOG(1) << "Failed to configure with hardware checksum offload. " + << "Create PMDPort without hardware offload"; return CommandFailure(-ret, "rte_eth_dev_configure() failed"); } diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index 853380e1c2..e25f0943be 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -51,6 +51,7 @@ message PMDPortArg { int32 socket_id = 8; } bool promiscuous_mode = 9; + bool hwcksum = 10; } message UnixSocketPortArg { From 14ddbe41ae2080b411419660822218242932dae6 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:39:07 -0700 Subject: [PATCH 13/62] 0009-Adding-value-attributes-to-ExactMatch-WildcardMatch --- core/modules/exact_match.cc | 145 ++++++++++++++++++++++---- core/modules/exact_match.h | 180 +++++++++++++++++++++++++++++++-- core/modules/wildcard_match.cc | 146 +++++++++++++++++++++++--- core/modules/wildcard_match.h | 35 +++++-- 4 files changed, 457 insertions(+), 49 deletions(-) diff --git a/core/modules/exact_match.cc b/core/modules/exact_match.cc index 072a0333dd..751d5f323c 100644 --- a/core/modules/exact_match.cc +++ b/core/modules/exact_match.cc @@ -50,20 +50,21 @@ const Commands ExactMatch::cmds = { {"set_runtime_config", "ExactMatchConfig", MODULE_CMD_FUNC(&ExactMatch::SetRuntimeConfig), Command::THREAD_UNSAFE}, {"add", "ExactMatchCommandAddArg", MODULE_CMD_FUNC(&ExactMatch::CommandAdd), - Command::THREAD_UNSAFE}, + Command::THREAD_SAFE}, {"delete", "ExactMatchCommandDeleteArg", - MODULE_CMD_FUNC(&ExactMatch::CommandDelete), Command::THREAD_UNSAFE}, + MODULE_CMD_FUNC(&ExactMatch::CommandDelete), Command::THREAD_SAFE}, {"clear", "EmptyArg", MODULE_CMD_FUNC(&ExactMatch::CommandClear), - Command::THREAD_UNSAFE}, + Command::THREAD_SAFE}, {"set_default_gate", "ExactMatchCommandSetDefaultGateArg", MODULE_CMD_FUNC(&ExactMatch::CommandSetDefaultGate), Command::THREAD_SAFE}}; CommandResponse ExactMatch::AddFieldOne(const bess::pb::Field &field, const bess::pb::FieldData &mask, - int idx) { + int idx, Type t) { int size = field.num_bytes(); uint64_t mask64 = 0; + if (mask.encoding_case() == bess::pb::FieldData::kValueInt) { mask64 = mask.value_int(); } else if (mask.encoding_case() == bess::pb::FieldData::kValueBin) { @@ -73,12 +74,15 @@ CommandResponse ExactMatch::AddFieldOne(const bess::pb::Field &field, Error ret; if (field.position_case() == bess::pb::Field::kAttrName) { - ret = table_.AddField(this, field.attr_name(), size, mask64, idx); + ret = (t == FIELD_TYPE) + ? table_.AddField(this, field.attr_name(), size, mask64, idx) + : AddValue(this, field.attr_name(), size, mask64, idx); if (ret.first) { return CommandFailure(ret.first, "%s", ret.second.c_str()); } } else if (field.position_case() == bess::pb::Field::kOffset) { - ret = table_.AddField(field.offset(), size, mask64, idx); + ret = (t == FIELD_TYPE) ? table_.AddField(field.offset(), size, mask64, idx) + : AddValue(field.offset(), size, mask64, idx); if (ret.first) { return CommandFailure(ret.first, "%s", ret.second.c_str()); } @@ -103,9 +107,25 @@ CommandResponse ExactMatch::Init(const bess::pb::ExactMatchArg &arg) { if (empty_masks_) { bess::pb::FieldData emptymask; - err = AddFieldOne(arg.fields(i), emptymask, i); + err = AddFieldOne(arg.fields(i), emptymask, i, FIELD_TYPE); + } else { + err = AddFieldOne(arg.fields(i), arg.masks(i), i, FIELD_TYPE); + } + + if (err.error().code() != 0) { + return err; + } + } + + empty_masks_ = arg.masksv_size() == 0; + for (auto i = 0; i < arg.values_size(); ++i) { + CommandResponse err; + + if (empty_masks_) { + bess::pb::FieldData emptymask; + err = AddFieldOne(arg.values(i), emptymask, i, VALUE_TYPE); } else { - err = AddFieldOne(arg.fields(i), arg.masks(i), i); + err = AddFieldOne(arg.values(i), arg.masksv(i), i, VALUE_TYPE); } if (err.error().code() != 0) { @@ -157,7 +177,7 @@ CommandResponse ExactMatch::GetRuntimeConfig(const bess::pb::EmptyArg &) { auto const &value = kv.second; rule_t *rule = r.add_rules(); - rule->set_gate(value); + rule->set_gate(value.gate); for (size_t i = 0; i < table_.num_fields(); i++) { const ExactMatchField &f = table_.get_field(i); bess::pb::FieldData *field = rule->add_fields(); @@ -199,9 +219,30 @@ Error ExactMatch::AddRule(const bess::pb::ExactMatchCommandAddArg &arg) { } ExactMatchRuleFields rule; - RuleFieldsFromPb(arg.fields(), &rule); + ExactMatchRuleFields action; + Error err; + ValueTuple t; + + /* clear value tuple */ + memset(&t.action, 0, sizeof(t.action)); + /* set gate */ + t.gate = gate; + RuleFieldsFromPb(arg.fields(), &rule, FIELD_TYPE); + /* check whether values match with the the table's */ + if (arg.values_size() != (ssize_t)num_values()) + return std::make_pair( + EINVAL, bess::utils::Format( + "rule has incorrect number of values. Need %d, has %d", + (int)num_values(), arg.values_size())); + /* check if values are non-zero */ + if (arg.values_size() > 0) { + RuleFieldsFromPb(arg.values(), &action, VALUE_TYPE); + + if ((err = CreateValue(t.action, action)).first != 0) + return err; + } - return table_.AddRule(gate, rule); + return table_.AddRule(t, rule); } // Uses an ExactMatchConfig to restore this module's runtime config. @@ -221,6 +262,53 @@ CommandResponse ExactMatch::SetRuntimeConfig( return CommandSuccess(); } +void ExactMatch::setValues(bess::Packet *pkt, ExactMatchKey &action) { + size_t num_values_ = num_values(); + + for (size_t i = 0; i < num_values_; i++) { + int value_size = get_value(i).size; + int value_pos = get_value(i).pos; + int value_off = get_value(i).offset; + int value_attr_id = get_value(i).attr_id; + uint8_t *data = pkt->head_data() + value_off; + + if (value_attr_id < 0) { /* if it is offset-based */ + memcpy(data, reinterpret_cast(&action) + value_pos, + value_size); + } else { /* if it is attribute-based */ + switch (value_size) { + case 1: + set_attr(this, value_attr_id, pkt, + *((uint8_t *)((uint8_t *)&action + value_pos))); + break; + case 2: + set_attr(this, value_attr_id, pkt, + *((uint16_t *)((uint8_t *)&action + value_pos))); + break; + case 4: + set_attr(this, value_attr_id, pkt, + *((uint32_t *)((uint8_t *)&action + value_pos))); + break; + case 8: + set_attr(this, value_attr_id, pkt, + *((uint64_t *)((uint8_t *)&action + value_pos))); + break; + default: { + typedef struct { + uint8_t bytes[bess::metadata::kMetadataAttrMaxSize]; + } value_t; + void *mt_ptr = + _ptr_attr_with_offset(attr_offset(value_attr_id), pkt); + bess::utils::CopySmall( + mt_ptr, + reinterpret_cast(((uint8_t *)(&action)) + value_pos), + value_size); + } break; + } + } + } +} + void ExactMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { gate_idx_t default_gate; ExactMatchKey keys[bess::PacketBatch::kMaxBurst] __ymm_aligned; @@ -237,9 +325,18 @@ void ExactMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { table_.MakeKeys(batch, buffer_fn, keys); int cnt = batch->cnt(); + Value default_value(default_gate); + for (int i = 0; i < cnt; i++) { bess::Packet *pkt = batch->pkts()[i]; - EmitPacket(ctx, pkt, table_.Find(keys[i], default_gate)); + ValueTuple res; + res = table_.Find(keys[i], default_value); + if (res.gate != default_gate) { + /* setting respecive values */ + setValues(pkt, res.action); + } + gate_idx_t g = res.gate; + EmitPacket(ctx, pkt, g); } } @@ -250,20 +347,34 @@ std::string ExactMatch::GetDesc() const { void ExactMatch::RuleFieldsFromPb( const RepeatedPtrField &fields, - bess::utils::ExactMatchRuleFields *rule) { + bess::utils::ExactMatchRuleFields *rule, Type type) { for (auto i = 0; i < fields.size(); i++) { - int field_size = table_.get_field(i).size; + (void)type; + int field_size = + (type == FIELD_TYPE) ? table_.get_field(i).size : get_value(i).size; + int attr_id = (type == FIELD_TYPE) ? table_.get_field(i).attr_id + : get_value(i).attr_id; bess::pb::FieldData current = fields.Get(i); - if (current.encoding_case() == bess::pb::FieldData::kValueBin) { const std::string &f_obj = fields.Get(i).value_bin(); rule->push_back(std::vector(f_obj.begin(), f_obj.end())); } else { rule->emplace_back(); - uint64_t rule64 = current.value_int(); + uint64_t rule64 = 0; + if (attr_id < 0) { + if (!bess::utils::uint64_to_bin(&rule64, current.value_int(), + field_size, 1)) { + std::cerr << "idx " << i << ": not a correct" << field_size + << "-byte value\n"; + return; + } + } else { + rule64 = current.value_int(); + } for (int j = 0; j < field_size; j++) { rule->back().push_back(rule64 & 0xFFULL); + DLOG(INFO) << "Pushed " << std::hex << (rule64 & 0xFFULL) << " to rule."; rule64 >>= 8; } } @@ -289,7 +400,7 @@ CommandResponse ExactMatch::CommandDelete( } ExactMatchRuleFields rule; - RuleFieldsFromPb(arg.fields(), &rule); + RuleFieldsFromPb(arg.fields(), &rule, FIELD_TYPE); Error ret = table_.DeleteRule(rule); if (ret.first) { diff --git a/core/modules/exact_match.h b/core/modules/exact_match.h index f7560e9700..99cb26543b 100644 --- a/core/modules/exact_match.h +++ b/core/modules/exact_match.h @@ -37,13 +37,36 @@ #include "../module.h" #include "../pb/module_msg.pb.h" #include "../utils/exact_match_table.h" +#include "../utils/format.h" -using google::protobuf::RepeatedPtrField; +using bess::utils::Error; using bess::utils::ExactMatchField; using bess::utils::ExactMatchKey; using bess::utils::ExactMatchRuleFields; using bess::utils::ExactMatchTable; -using bess::utils::Error; +using google::protobuf::RepeatedPtrField; + +typedef enum { FIELD_TYPE = 0, VALUE_TYPE } Type; + +class ExactMatch; +class Value { + friend class ExactMatch; + + public: + Value(gate_idx_t g = 0) : gate(g) {} + Value(const Value &v) : gate(v.gate) {} + gate_idx_t gate; +}; + +class ValueTuple : public Value { + friend class ExactMatch; + + public: + ValueTuple() : Value(), action() {} + ValueTuple(Value v) : Value(v), action() {} + + ExactMatchKey action; +}; class ExactMatch final : public Module { public: @@ -51,7 +74,14 @@ class ExactMatch final : public Module { static const Commands cmds; - ExactMatch() : Module(), default_gate_(), table_() { + ExactMatch() + : Module(), + default_gate_(), + raw_value_size_(), + total_value_size_(), + num_values_(), + values_(), + table_() { max_allowed_workers_ = Worker::kMaxWorkers; } @@ -72,15 +102,153 @@ class ExactMatch final : public Module { private: CommandResponse AddFieldOne(const bess::pb::Field &field, - const bess::pb::FieldData &mask, int idx); + const bess::pb::FieldData &mask, int idx, Type t); void RuleFieldsFromPb(const RepeatedPtrField &fields, - bess::utils::ExactMatchRuleFields *rule); + bess::utils::ExactMatchRuleFields *rule, Type type); Error AddRule(const bess::pb::ExactMatchCommandAddArg &arg); + size_t num_values() const { return num_values_; } + ExactMatchField *getVals() { return values_; }; + Error gather_value(const ExactMatchRuleFields &fields, ExactMatchKey *key) { + if (fields.size() != num_values_) { + return std::make_pair( + EINVAL, bess::utils::Format("rule should have %zu fields (has %zu)", + num_values_, fields.size())); + } + + *key = {}; + + for (size_t i = 0; i < fields.size(); i++) { + int field_size = values_[i].size; + int field_pos = values_[i].pos; + + const std::vector &f_obj = fields[i]; + + if (static_cast(field_size) != f_obj.size()) { + return std::make_pair( + EINVAL, + bess::utils::Format("rule field %zu should have size %d (has %zu)", + i, field_size, f_obj.size())); + } + + memcpy(reinterpret_cast(key) + field_pos, f_obj.data(), + field_size); + } + + return std::make_pair(0, bess::utils::Format("Success")); + } + // Helper for public AddField functions. + // DoAddValue inserts `field` as the `idx`th field for this table. + // If `mt_attr_name` is set, the `offset` field of `field` will be ignored and + // the inserted field will use the offset of `mt_attr_name` as reported by the + // module `m`. + // Returns 0 on success, non-zero errno on failure. + Error DoAddValue(const ExactMatchField &value, + const std::string &mt_attr_name, int idx, + Module *m = nullptr) { + if (idx >= MAX_FIELDS) { + return std::make_pair( + EINVAL, + bess::utils::Format("idx %d is not in [0,%d)", idx, MAX_FIELDS)); + } + ExactMatchField *v = &values_[idx]; + v->size = value.size; + if (v->size < 1 || v->size > MAX_FIELD_SIZE) { + return std::make_pair( + EINVAL, bess::utils::Format("idx %d: 'size' must be in [1,%d]", idx, + MAX_FIELD_SIZE)); + } + + if (mt_attr_name.length() > 0) { + v->attr_id = m->AddMetadataAttr( + mt_attr_name, v->size, bess::metadata::Attribute::AccessMode::kWrite); + if (v->attr_id < 0) { + return std::make_pair( + -v->attr_id, + bess::utils::Format("idx %d: add_metadata_attr() failed", idx)); + } + } else { + v->attr_id = -1; + v->offset = value.offset; + if (v->offset < 0 || v->offset > 1024) { + return std::make_pair( + EINVAL, bess::utils::Format("idx %d: invalid 'offset'", idx)); + } + } + + int force_be = (v->attr_id < 0); + + if (value.mask == 0) { + /* by default all bits are considered */ + v->mask = bess::utils::SetBitsHigh(v->size * 8); + } else { + if (!bess::utils::uint64_to_bin(&v->mask, value.mask, v->size, + bess::utils::is_be_system() | force_be)) { + return std::make_pair( + EINVAL, bess::utils::Format("idx %d: not a valid %d-byte mask", idx, + v->size)); + } + } + + if (v->mask == 0) { + return std::make_pair(EINVAL, + bess::utils::Format("idx %d: empty mask", idx)); + } + + num_values_++; + + v->pos = raw_value_size_; + raw_value_size_ += v->size; + total_value_size_ = align_ceil(raw_value_size_, sizeof(uint64_t)); + return std::make_pair(0, bess::utils::Format("Success")); + } + // Returns the ith value. + const ExactMatchField &get_value(size_t i) const { return values_[i]; } + // Set the `idx`th field of this table to one at offset `offset` bytes into a + // buffer with length `size` and mask `mask`. + // Returns 0 on success, non-zero errno on failure. + Error AddValue(int offset, int size, uint64_t mask, int idx) { + ExactMatchField v = { + .mask = mask, .attr_id = 0, .offset = offset, .pos = 0, .size = size}; + return DoAddValue(v, "", idx, nullptr); + } + + // Set the `idx`th field of this table to one at the offset of the + // `mt_attr_name` metadata field as seen by module `m`, with length `size` and + // mask `mask`. + // Returns 0 on success, non-zero errno on failure. + Error AddValue(Module *m, const std::string &mt_attr_name, int size, + uint64_t mask, int idx) { + ExactMatchField v = { + .mask = mask, .attr_id = 0, .offset = 0, .pos = 0, .size = size}; + return DoAddValue(v, mt_attr_name, idx, m); + } + Error CreateValue(ExactMatchKey &v, const ExactMatchRuleFields &values) { + Error err; + + if (values.size() == 0) { + return std::make_pair(EINVAL, "rule has no values"); + } + + if ((err = gather_value(values, &v)).first != 0) { + return err; + } + + return std::make_pair(0, bess::utils::Format("Success")); + } + void setValues(bess::Packet *pkt, ExactMatchKey &action); gate_idx_t default_gate_; bool empty_masks_; // mainly for GetInitialArg - ExactMatchTable table_; + // unaligend key size, used as an accumulator for calls to AddField() + size_t raw_value_size_; + + // aligned total key size + size_t total_value_size_; + + size_t num_values_; + ExactMatchField values_[MAX_FIELDS]; + ExactMatchTable table_; }; #endif // BESS_MODULES_EXACTMATCH_H_ diff --git a/core/modules/wildcard_match.cc b/core/modules/wildcard_match.cc index 1b7bfeb6cb..82b954be58 100644 --- a/core/modules/wildcard_match.cc +++ b/core/modules/wildcard_match.cc @@ -37,6 +37,7 @@ #include "../utils/format.h" using bess::metadata::Attribute; +enum { FieldType = 0, ValueType }; // dst = src & mask. len must be a multiple of sizeof(uint64_t) static inline void mask(wm_hkey_t *dst, const wm_hkey_t &src, @@ -63,17 +64,17 @@ const Commands WildcardMatch::cmds = { {"set_runtime_config", "WildcardMatchConfig", MODULE_CMD_FUNC(&WildcardMatch::SetRuntimeConfig), Command::THREAD_UNSAFE}, {"add", "WildcardMatchCommandAddArg", - MODULE_CMD_FUNC(&WildcardMatch::CommandAdd), Command::THREAD_UNSAFE}, + MODULE_CMD_FUNC(&WildcardMatch::CommandAdd), Command::THREAD_SAFE}, {"delete", "WildcardMatchCommandDeleteArg", - MODULE_CMD_FUNC(&WildcardMatch::CommandDelete), Command::THREAD_UNSAFE}, + MODULE_CMD_FUNC(&WildcardMatch::CommandDelete), Command::THREAD_SAFE}, {"clear", "EmptyArg", MODULE_CMD_FUNC(&WildcardMatch::CommandClear), - Command::THREAD_UNSAFE}, + Command::THREAD_SAFE}, {"set_default_gate", "WildcardMatchCommandSetDefaultGateArg", MODULE_CMD_FUNC(&WildcardMatch::CommandSetDefaultGate), Command::THREAD_SAFE}}; CommandResponse WildcardMatch::AddFieldOne(const bess::pb::Field &field, - struct WmField *f) { + struct WmField *f, uint8_t type) { f->size = field.num_bytes(); if (f->size < 1 || f->size > MAX_FIELD_SIZE) { @@ -88,7 +89,10 @@ CommandResponse WildcardMatch::AddFieldOne(const bess::pb::Field &field, } } else if (field.position_case() == bess::pb::Field::kAttrName) { const char *attr = field.attr_name().c_str(); - f->attr_id = AddMetadataAttr(attr, f->size, Attribute::AccessMode::kRead); + f->attr_id = + (type == FieldType) + ? AddMetadataAttr(attr, f->size, Attribute::AccessMode::kRead) + : AddMetadataAttr(attr, f->size, Attribute::AccessMode::kWrite); if (f->attr_id < 0) { return CommandFailure(-f->attr_id, "add_metadata_attr() failed"); } @@ -119,7 +123,7 @@ CommandResponse WildcardMatch::Init(const bess::pb::WildcardMatchArg &arg) { f.pos = size_acc; - err = AddFieldOne(field, &f); + err = AddFieldOne(field, &f, FieldType); if (err.error().code() != 0) { return err; } @@ -130,14 +134,34 @@ CommandResponse WildcardMatch::Init(const bess::pb::WildcardMatchArg &arg) { default_gate_ = DROP_GATE; total_key_size_ = align_ceil(size_acc, sizeof(uint64_t)); + // reset size_acc + size_acc = 0; + for (int i = 0; i < arg.values_size(); i++) { + const auto &value = arg.values(i); + CommandResponse err; + values_.emplace_back(); + struct WmField &v = values_.back(); + + v.pos = size_acc; + + err = AddFieldOne(value, &v, ValueType); + if (err.error().code() != 0) { + return err; + } + + size_acc += v.size; + } + + total_value_size_ = align_ceil(size_acc, sizeof(uint64_t)); + return CommandSuccess(); } inline gate_idx_t WildcardMatch::LookupEntry(const wm_hkey_t &key, - gate_idx_t def_gate) { + gate_idx_t def_gate, + bess::Packet *pkt) { struct WmData result = { - .priority = INT_MIN, .ogate = def_gate, - }; + .priority = INT_MIN, .ogate = def_gate, .keyv = {{0}}}; for (auto &tuple : tuples_) { const auto &ht = tuple.ht; @@ -153,6 +177,58 @@ inline gate_idx_t WildcardMatch::LookupEntry(const wm_hkey_t &key, } } + /* if lookup was successful, then set values (if possible) */ + if (result.ogate != default_gate_) { + size_t num_values_ = values_.size(); + for (size_t i = 0; i < num_values_; i++) { + int value_size = values_[i].size; + int value_pos = values_[i].pos; + int value_off = values_[i].offset; + int value_attr_id = values_[i].attr_id; + uint8_t *data = pkt->head_data() + value_off; + + DLOG(INFO) << "off: " << (int)value_off << ", sz: " << value_size; + + if (value_attr_id < 0) { /* if it is offset-based */ + memcpy(data, reinterpret_cast(&result.keyv) + value_pos, + value_size); + } else { /* if it is attribute-based */ + typedef struct { + uint8_t bytes[bess::metadata::kMetadataAttrMaxSize]; + } value_t; + uint8_t *buf = (uint8_t *)&result.keyv + value_pos; + + DLOG(INFO) << "Setting value " << std::hex + << *(reinterpret_cast(buf)) + << " for attr_id: " << value_attr_id + << " of size: " << value_size + << " at value_pos: " << value_pos; + + switch (value_size) { + case 1: + set_attr(this, value_attr_id, pkt, *((uint8_t *)buf)); + break; + case 2: + set_attr(this, value_attr_id, pkt, + *((uint16_t *)((uint8_t *)buf))); + break; + case 4: + set_attr(this, value_attr_id, pkt, + *((uint32_t *)((uint8_t *)buf))); + break; + case 8: + set_attr(this, value_attr_id, pkt, + *((uint64_t *)((uint8_t *)buf))); + break; + default: { + void *mt_ptr = + _ptr_attr_with_offset(attr_offset(value_attr_id), pkt); + bess::utils::CopySmall(mt_ptr, buf, value_size); + } break; + } + } + } + } return result.ogate; } @@ -198,7 +274,7 @@ void WildcardMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { for (int i = 0; i < cnt; i++) { bess::Packet *pkt = batch->pkts()[i]; - EmitPacket(ctx, pkt, LookupEntry(keys[i], default_gate)); + EmitPacket(ctx, pkt, LookupEntry(keys[i], default_gate, pkt)); } } @@ -275,6 +351,41 @@ CommandResponse WildcardMatch::ExtractKeyMask(const T &arg, wm_hkey_t *key, return CommandSuccess(); } +template +CommandResponse WildcardMatch::ExtractValue(const T &arg, wm_hkey_t *keyv) { + if ((size_t)arg.valuesv_size() != values_.size()) { + return CommandFailure(EINVAL, "must specify %zu values", values_.size()); + } + + memset(keyv, 0, sizeof(*keyv)); + + for (size_t i = 0; i < values_.size(); i++) { + int value_size = values_[i].size; + int value_pos = values_[i].pos; + + uint64_t v = 0; + + bess::pb::FieldData valuedata = arg.valuesv(i); + if (valuedata.encoding_case() == bess::pb::FieldData::kValueInt) { + if (!bess::utils::uint64_to_bin(&v, valuedata.value_int(), value_size, + false)) { + return CommandFailure(EINVAL, "idx %zu: not a correct %d-byte value", i, + value_size); + } + } else if (valuedata.encoding_case() == bess::pb::FieldData::kValueBin) { + bess::utils::Copy(reinterpret_cast(&v), + valuedata.value_bin().c_str(), + valuedata.value_bin().size()); + } + + // Use memcpy, not utils::Copy, to workaround the false positive warning + // in g++-8 + memcpy(reinterpret_cast(keyv) + value_pos, &v, value_size); + } + + return CommandSuccess(); +} + int WildcardMatch::FindTuple(wm_hkey_t *mask) { int i = 0; @@ -299,11 +410,11 @@ int WildcardMatch::AddTuple(wm_hkey_t *mask) { return int(tuples_.size() - 1); } -int WildcardMatch::DelEntry(int idx, wm_hkey_t *key) { +bool WildcardMatch::DelEntry(int idx, wm_hkey_t *key) { struct WmTuple &tuple = tuples_[idx]; - int ret = + bool ret = tuple.ht.Remove(*key, wm_hash(total_key_size_), wm_eq(total_key_size_)); - if (ret) { + if (!ret) { return ret; } @@ -311,7 +422,7 @@ int WildcardMatch::DelEntry(int idx, wm_hkey_t *key) { tuples_.erase(tuples_.begin() + idx); } - return 0; + return true; } CommandResponse WildcardMatch::CommandAdd( @@ -333,6 +444,11 @@ CommandResponse WildcardMatch::CommandAdd( return CommandFailure(EINVAL, "Invalid gate: %hu", gate); } + err = ExtractValue(arg, &data.keyv); + if (err.error().code() != 0) { + return err; + } + data.priority = priority; data.ogate = gate; @@ -369,7 +485,7 @@ CommandResponse WildcardMatch::CommandDelete( } int ret = DelEntry(idx, &key); - if (ret < 0) { + if (!ret) { return CommandFailure(-ret, "failed to delete a rule"); } diff --git a/core/modules/wildcard_match.h b/core/modules/wildcard_match.h index 5a8d9e8142..85deeafcab 100644 --- a/core/modules/wildcard_match.h +++ b/core/modules/wildcard_match.h @@ -39,8 +39,8 @@ #include "../pb/module_msg.pb.h" #include "../utils/cuckoo_map.h" -using bess::utils::HashResult; using bess::utils::CuckooMap; +using bess::utils::HashResult; #define MAX_TUPLES 8 #define MAX_FIELDS 8 @@ -54,11 +54,6 @@ static_assert(MAX_FIELD_SIZE <= sizeof(uint64_t), #error this code assumes little endian architecture (x86) #endif -struct WmData { - int priority; - gate_idx_t ogate; -}; - struct WmField { int attr_id; /* -1 for offset-based fields */ @@ -75,6 +70,12 @@ struct wm_hkey_t { uint64_t u64_arr[MAX_FIELDS]; }; +struct WmData { + int priority; + gate_idx_t ogate; + wm_hkey_t keyv; +}; + class wm_eq { public: explicit wm_eq(size_t len) : len_(len) {} @@ -135,7 +136,13 @@ class WildcardMatch final : public Module { static const Commands cmds; WildcardMatch() - : Module(), default_gate_(), total_key_size_(), fields_(), tuples_() { + : Module(), + default_gate_(), + total_key_size_(), + total_value_size_(), + fields_(), + values_(), + tuples_() { max_allowed_workers_ = Worker::kMaxWorkers; } @@ -161,25 +168,31 @@ class WildcardMatch final : public Module { wm_hkey_t mask; }; - gate_idx_t LookupEntry(const wm_hkey_t &key, gate_idx_t def_gate); + gate_idx_t LookupEntry(const wm_hkey_t &key, gate_idx_t def_gate, + bess::Packet *pkt); - CommandResponse AddFieldOne(const bess::pb::Field &field, struct WmField *f); + CommandResponse AddFieldOne(const bess::pb::Field &field, struct WmField *f, + uint8_t type); template CommandResponse ExtractKeyMask(const T &arg, wm_hkey_t *key, wm_hkey_t *mask); + template + CommandResponse ExtractValue(const T &arg, wm_hkey_t *keyv); int FindTuple(wm_hkey_t *mask); int AddTuple(wm_hkey_t *mask); - int DelEntry(int idx, wm_hkey_t *key); + bool DelEntry(int idx, wm_hkey_t *key); void Clear(); gate_idx_t default_gate_; - size_t total_key_size_; /* a multiple of sizeof(uint64_t) */ + size_t total_key_size_; /* a multiple of sizeof(uint64_t) */ + size_t total_value_size_; /* a multiple of sizeof(uint64_t) */ // TODO(melvinw): this can be refactored to use ExactMatchTable std::vector fields_; + std::vector values_; std::vector tuples_; }; From 3f50c68e0096b72d79a0a3463d0d888159823bdb Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:45:48 -0700 Subject: [PATCH 14/62] 0010-Add-hardware-rx-checksum-offload-option-for-checksum --- core/modules/ip_checksum.cc | 17 ++++++++++++--- core/modules/ip_checksum.h | 6 +++++- core/modules/l4_checksum.cc | 43 +++++++++++++++++++++++++++++-------- core/modules/l4_checksum.h | 5 ++++- 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/core/modules/ip_checksum.cc b/core/modules/ip_checksum.cc index ecaba24d7d..47f86bae84 100644 --- a/core/modules/ip_checksum.cc +++ b/core/modules/ip_checksum.cc @@ -56,8 +56,8 @@ void IPChecksum::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { data = qinq + 1; ether_type = qinq->ether_type; if (ether_type != be16_t(Ethernet::Type::kVlan)) { - EmitPacket(ctx, batch->pkts()[i], FORWARD_GATE); - continue; + EmitPacket(ctx, batch->pkts()[i], FORWARD_GATE); + continue; } } @@ -75,7 +75,17 @@ void IPChecksum::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { } if (verify_) { - EmitPacket(ctx, batch->pkts()[i], (VerifyIpv4Checksum(*ip)) ? FORWARD_GATE : FAIL_GATE); + if (hw_) { + struct rte_mbuf *m = (struct rte_mbuf *)batch->pkts()[i]; + if (unlikely((m->ol_flags & PKT_RX_IP_CKSUM_MASK) == + PKT_RX_IP_CKSUM_BAD)) + EmitPacket(ctx, (bess::Packet *)m, FAIL_GATE); + else + EmitPacket(ctx, (bess::Packet *)m, FORWARD_GATE); + } else { + EmitPacket(ctx, batch->pkts()[i], + (VerifyIpv4Checksum(*ip)) ? FORWARD_GATE : FAIL_GATE); + } } else { ip->checksum = CalculateIpv4Checksum(*ip); EmitPacket(ctx, batch->pkts()[i], FORWARD_GATE); @@ -85,6 +95,7 @@ void IPChecksum::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { CommandResponse IPChecksum::Init(const bess::pb::IPChecksumArg &arg) { verify_ = arg.verify(); + hw_ = arg.hw(); return CommandSuccess(); } diff --git a/core/modules/ip_checksum.h b/core/modules/ip_checksum.h index f0f1d079ff..94e0d7246a 100644 --- a/core/modules/ip_checksum.h +++ b/core/modules/ip_checksum.h @@ -37,7 +37,9 @@ // Compute IP checksum on packet class IPChecksum final : public Module { public: - IPChecksum() : Module(), verify_(false) { max_allowed_workers_ = Worker::kMaxWorkers; } + IPChecksum() : Module(), verify_(false) { + max_allowed_workers_ = Worker::kMaxWorkers; + } /* Gates: (0) Default, (1) Drop */ static const gate_idx_t kNumOGates = 2; @@ -47,6 +49,8 @@ class IPChecksum final : public Module { private: /* enable checksum verification */ bool verify_; + /* enable hardware offload */ + bool hw_; }; #endif // BESS_MODULES_IP_CHECKSUM_H_ diff --git a/core/modules/l4_checksum.cc b/core/modules/l4_checksum.cc index 3ad1f23d68..20faa85c33 100644 --- a/core/modules/l4_checksum.cc +++ b/core/modules/l4_checksum.cc @@ -63,27 +63,52 @@ void L4Checksum::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { Udp *udp = reinterpret_cast(reinterpret_cast(ip) + ip_bytes); if (verify_) { - EmitPacket(ctx, batch->pkts()[i], - (VerifyIpv4UdpChecksum(*ip, *udp)) ? FORWARD_GATE : FAIL_GATE); + if (hw_) { + struct rte_mbuf *m = (struct rte_mbuf *)batch->pkts()[i]; + if (unlikely((m->ol_flags & PKT_RX_L4_CKSUM_MASK) == + PKT_RX_L4_CKSUM_BAD)) + EmitPacket(ctx, (bess::Packet *)m, FAIL_GATE); + else + EmitPacket(ctx, (bess::Packet *)m, FORWARD_GATE); + } else { + EmitPacket( + ctx, batch->pkts()[i], + (VerifyIpv4UdpChecksum(*ip, *udp)) ? FORWARD_GATE : FAIL_GATE); + } } else { - udp->checksum = CalculateIpv4UdpChecksum(*ip, *udp); - EmitPacket(ctx, batch->pkts()[i], FORWARD_GATE); + udp->checksum = CalculateIpv4UdpChecksum(*ip, *udp); + EmitPacket(ctx, batch->pkts()[i], FORWARD_GATE); } } else if (ip->protocol == Ipv4::Proto::kTcp) { size_t ip_bytes = (ip->header_length) << 2; Tcp *tcp = reinterpret_cast(reinterpret_cast(ip) + ip_bytes); - if (verify_) - EmitPacket(ctx, batch->pkts()[i], - (VerifyIpv4TcpChecksum(*ip, *tcp)) ? FORWARD_GATE : FAIL_GATE); - else - tcp->checksum = CalculateIpv4TcpChecksum(*ip, *tcp); + if (verify_) { + if (hw_) { + struct rte_mbuf *m = (struct rte_mbuf *)batch->pkts()[i]; + if (unlikely((m->ol_flags & PKT_RX_L4_CKSUM_MASK) == + PKT_RX_L4_CKSUM_BAD)) + EmitPacket(ctx, (bess::Packet *)m, FAIL_GATE); + else + EmitPacket(ctx, (bess::Packet *)m, FORWARD_GATE); + } else { + EmitPacket( + ctx, batch->pkts()[i], + (VerifyIpv4TcpChecksum(*ip, *tcp)) ? FORWARD_GATE : FAIL_GATE); + } + } else { + tcp->checksum = CalculateIpv4TcpChecksum(*ip, *tcp); + EmitPacket(ctx, batch->pkts()[i], FORWARD_GATE); + } + } else { /* fail-safe condition */ + EmitPacket(ctx, batch->pkts()[i], FORWARD_GATE); } } } CommandResponse L4Checksum::Init(const bess::pb::L4ChecksumArg &arg) { verify_ = arg.verify(); + hw_ = arg.hw(); return CommandSuccess(); } diff --git a/core/modules/l4_checksum.h b/core/modules/l4_checksum.h index 27ab8f98f1..56d8ae5c20 100644 --- a/core/modules/l4_checksum.h +++ b/core/modules/l4_checksum.h @@ -36,7 +36,9 @@ // Compute L4 checksum on packet class L4Checksum final : public Module { public: - L4Checksum() : Module(), verify_(false) { max_allowed_workers_ = Worker::kMaxWorkers; } + L4Checksum() : Module(), verify_(false) { + max_allowed_workers_ = Worker::kMaxWorkers; + } /* Gates: (0) Default, (1) Drop */ static const gate_idx_t kNumOGates = 2; @@ -46,6 +48,7 @@ class L4Checksum final : public Module { private: bool verify_; + bool hw_; }; #endif // BESS_MODULES_L4_CHECKSUM_H_ From 26583c6d6a73cc66cced7fd6f958f156fb7d8b0a Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 28 Oct 2022 15:59:54 -0700 Subject: [PATCH 15/62] 0011-Protobuf-update-to-new-module-messages --- protobuf/module_msg.proto | 85 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index e00a463a35..25dfc81ebc 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -69,6 +69,7 @@ message BPFCommandClearArg { message ExactMatchCommandAddArg { uint64 gate = 1; /// The gate to forward out packets that mach this rule. repeated FieldData fields = 2; /// The exact match values to check for + repeated FieldData values = 3; /// The exact match values to check for } /** @@ -377,6 +378,7 @@ message WildcardMatchCommandAddArg { int64 priority = 2; ///If a packet matches multiple rules, the rule with higher priority will be applied. If priorities are equal behavior is undefined. repeated FieldData values = 3; /// The values to check for in each field. repeated FieldData masks = 4; /// The bitmask for each field -- set `0x0` to ignore the field altogether. + repeated FieldData valuesv = 5; /// The values to check for in each fieldv. } /** @@ -501,6 +503,8 @@ message EtherEncapArg { message ExactMatchArg { repeated Field fields = 1; ///A list of ExactMatch Fields repeated FieldData masks = 2; /// mask(i) corresponds to the mask for field(i) + repeated Field values = 3; /// A list of ExactMatch Values + repeated FieldData masksv = 4; /// mask(i) corresponds to the mask for value(i) } /** @@ -996,6 +1000,7 @@ message SourceArg { */ message IPChecksumArg { bool verify = 1; /// check checksum + bool hw = 2; /// enable hardware offload } /** @@ -1009,6 +1014,85 @@ message IPChecksumArg { */ message L4ChecksumArg { bool verify = 1; /// check checksum + bool hw = 2; /// enable hardware offload +} + +/** + * The GtpuEcho module processes the GTPv1 echo packet and prepares + * corresponding IP packet containing GTP echo response. It assumes + * Recovery IE is always zero. + * + * __Input Gates__: 1 + * __Output Gates__: 1 + */ +message GtpuEchoArg { + uint32 s1u_sgw_ip = 1; /// IP address of S1U interface +} + +/** + * The IPDefrag module scans the IP datagram and checks whether + * it is fragmented. It returns a fully reassembled datagram or + * an unfragmented IP datagram + * + * __Input Gates__: 1 + * __Output Gates__: 1 + */ +message IPDefragArg { + uint32 num_flows = 1; /// max number of flows the module can handle + int32 numa = 2; /// numa placement for ip frags memory management +} + +/** + * The IPDFrag module scans the IP datagram and checks whether + * it needs to be fragmented. + * + * __Input Gates__: 1 + * __Output Gates__: 1 + */ +message IPFragArg { + int32 mtu = 1; /// full Ethernet frame size (including CRC) for encapsulated ipv4 frag datagrams +} + +/** + * The Counter module has a command `add(...)` which takes one + * parameters. This function accepts the counter id of a + * session record. + * Example use in bessctl: `counter.add(ctr_id=0x1)` + */ +message CounterAddArg { + uint32 ctr_id = 1; /// counter id +} + +/** + * The Counter module has a command `remove(...)` which takes one + * parameter. This function accepts ctr_id, and removes the + * respective counter. + * Example use in bessctl: `counter.remove(ctr_id=0x1)` + */ +message CounterRemoveArg { + uint32 ctr_id = 1; /// counter id +} + +/** + * The Counter module counts the number of packets and bytes it passes + * + * __Input Gates__: 1 + * __Output Gates__: 1 +*/ +message CounterArg { + string name_id = 1; /// Name of the counter_id + bool check_exist = 2; /// verify each counter pre-exists before any operation (default = False) + uint32 total = 3; /// Total number of entries it can support +} + +/** + * The GtpuEncap module inserts GTP header in an ethernet frame + * + * __Input Gates__: 1 + * __Output Gates__: 1 +*/ +message GtpuEncapArg { + bool add_psc = 1; /// Add PDU session container in encap (default = False) } /** @@ -1151,6 +1235,7 @@ message VXLANEncapArg { */ message WildcardMatchArg { repeated Field fields = 1; /// A list of WildcardMatch fields. + repeated Field values = 2; /// A list of WildcardMatch values. } /** From 3e5a083d585cc57e4aee8e810824be5230e6f03a Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 12:21:15 -0700 Subject: [PATCH 16/62] 0012-Dpdk-concurrent-hash-support-pipeline-improvement --- core/modules/exact_match.cc | 29 ++-- core/modules/exact_match.h | 3 + core/modules/wildcard_match.cc | 265 +++++++++++++++++++++++++-------- core/modules/wildcard_match.h | 30 +++- core/utils/cuckoo_map.h | 117 ++++++++++++++- core/utils/exact_match_table.h | 82 ++++++---- 6 files changed, 413 insertions(+), 113 deletions(-) diff --git a/core/modules/exact_match.cc b/core/modules/exact_match.cc index 751d5f323c..fd9d7023b5 100644 --- a/core/modules/exact_match.cc +++ b/core/modules/exact_match.cc @@ -134,7 +134,7 @@ CommandResponse ExactMatch::Init(const bess::pb::ExactMatchArg &arg) { } default_gate_ = DROP_GATE; - + table_.Init(); return CommandSuccess(); } @@ -327,16 +327,21 @@ void ExactMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { int cnt = batch->cnt(); Value default_value(default_gate); - for (int i = 0; i < cnt; i++) { - bess::Packet *pkt = batch->pkts()[i]; - ValueTuple res; - res = table_.Find(keys[i], default_value); - if (res.gate != default_gate) { - /* setting respecive values */ - setValues(pkt, res.action); + int icnt=0; + for(int lcnt=0; lcnt=64) ? 64 : cnt-lcnt ; + ValueTuple *res[icnt]; + uint64_t hit_mask = table_.Find(keys+lcnt, res, icnt); + + for (int j = 0; j < icnt; j++) { + if ((hit_mask & ((uint64_t)1ULL << j)) == 0) + EmitPacket(ctx, batch->pkts()[j+lcnt], default_gate); + else { + setValues(batch->pkts()[j+lcnt], res[j]->action); + EmitPacket(ctx, batch->pkts()[j+lcnt], res[j]->gate); + } } - gate_idx_t g = res.gate; - EmitPacket(ctx, pkt, g); } } @@ -421,4 +426,8 @@ CommandResponse ExactMatch::CommandSetDefaultGate( return CommandSuccess(); } +void ExactMatch::DeInit() { + table_.DeInit(); +} + ADD_MODULE(ExactMatch, "em", "Multi-field classifier with an exact match table") diff --git a/core/modules/exact_match.h b/core/modules/exact_match.h index 99cb26543b..d7e3531ed3 100644 --- a/core/modules/exact_match.h +++ b/core/modules/exact_match.h @@ -90,6 +90,9 @@ class ExactMatch final : public Module { std::string GetDesc() const override; CommandResponse Init(const bess::pb::ExactMatchArg &arg); + + void DeInit() override; + CommandResponse GetInitialArg(const bess::pb::EmptyArg &arg); CommandResponse GetRuntimeConfig(const bess::pb::EmptyArg &arg); CommandResponse SetRuntimeConfig(const bess::pb::ExactMatchConfig &arg); diff --git a/core/modules/wildcard_match.cc b/core/modules/wildcard_match.cc index 82b954be58..e765aeb32c 100644 --- a/core/modules/wildcard_match.cc +++ b/core/modules/wildcard_match.cc @@ -40,13 +40,28 @@ using bess::metadata::Attribute; enum { FieldType = 0, ValueType }; // dst = src & mask. len must be a multiple of sizeof(uint64_t) -static inline void mask(wm_hkey_t *dst, const wm_hkey_t &src, +static inline void mask(wm_hkey_t &dst, const wm_hkey_t &src, const wm_hkey_t &mask, size_t len) { promise(len >= sizeof(uint64_t)); promise(len <= sizeof(wm_hkey_t)); for (size_t i = 0; i < len / 8; i++) { - dst->u64_arr[i] = src.u64_arr[i] & mask.u64_arr[i]; + dst.u64_arr[i] = src.u64_arr[i] & mask.u64_arr[i]; + } +} +static inline void mask_bulk(const wm_hkey_t *src, void *dst, void **dsptr, + const wm_hkey_t &mask, int keys, size_t len) { + promise(len >= sizeof(uint64_t)); + promise(len <= sizeof(wm_hkey_t)); + size_t i = 0; + wm_hkey_t *dst1 = (wm_hkey_t *)dst; + wm_hkey_t **dstptr = (wm_hkey_t **)dsptr; + + for (int j = 0; j < keys; j++) { + for (i = 0; i < len / 8; i++) { + dst1[j].u64_arr[i] = src[j].u64_arr[i] & mask.u64_arr[i]; + } + dstptr[j] = &dst1[j]; } } @@ -130,10 +145,8 @@ CommandResponse WildcardMatch::Init(const bess::pb::WildcardMatchArg &arg) { size_acc += f.size; } - default_gate_ = DROP_GATE; total_key_size_ = align_ceil(size_acc, sizeof(uint64_t)); - // reset size_acc size_acc = 0; for (int i = 0; i < arg.values_size(); i++) { @@ -162,18 +175,16 @@ inline gate_idx_t WildcardMatch::LookupEntry(const wm_hkey_t &key, bess::Packet *pkt) { struct WmData result = { .priority = INT_MIN, .ogate = def_gate, .keyv = {{0}}}; - for (auto &tuple : tuples_) { + if (tuple.occupied == 0) + continue; const auto &ht = tuple.ht; wm_hkey_t key_masked; - - mask(&key_masked, key, tuple.mask, total_key_size_); - - const auto *entry = - ht.Find(key_masked, wm_hash(total_key_size_), wm_eq(total_key_size_)); - - if (entry && entry->second.priority >= result.priority) { - result = entry->second; + mask(key_masked, key, tuple.mask, total_key_size_); + WmData *entry = nullptr; + ht->find_dpdk(&key_masked, ((void **)&entry)); + if (entry && entry->priority >= result.priority) { + result = *entry; } } @@ -232,20 +243,115 @@ inline gate_idx_t WildcardMatch::LookupEntry(const wm_hkey_t &key, return result.ogate; } +inline bool WildcardMatch::LookupBulkEntry(wm_hkey_t *key, gate_idx_t def_gate, + int packeti, gate_idx_t *Outgate, + int cnt, bess::PacketBatch *batch) { + bess::Packet *pkt = nullptr; + struct WmData *result[cnt]; + uint64_t prev_hitmask = 0; + uint64_t hitmask = 0; + wm_hkey_t key_masked[cnt]; + WmData *entry[cnt]; + wm_hkey_t **key_ptr[cnt]; + + for (auto tuple = tuples_.begin(); tuple != tuples_.end(); ++tuple) { + if (tuple->occupied == 0) + continue; + const auto &ht = tuple->ht; + mask_bulk(key, key_masked, (void **)key_ptr, tuple->mask, cnt, + total_key_size_); + int num = ht->lookup_bulk_data((const void **)key_ptr, cnt, &hitmask, + (void **)entry); + if (num == 0) + continue; + + for (int init = 0; (init < cnt) && (num); init++) { + if ((hitmask & ((uint64_t)1 << init))) { + if ((prev_hitmask & ((uint64_t)1 << init)) == 0) + result[init] = entry[init]; + else if ((prev_hitmask & ((uint64_t)1 << init)) && + (entry[init]->priority >= result[init]->priority)) { + result[init] = entry[init]; + } + + num--; + } + } + prev_hitmask = prev_hitmask | hitmask; + } + + for (int init = 0; init < cnt; init++) { + /* if lookup was successful, then set values (if possible) */ + if (prev_hitmask && (prev_hitmask & ((uint64_t)1 << init))) { + pkt = batch->pkts()[packeti + init]; + size_t num_values_ = values_.size(); + for (size_t i = 0; i < num_values_; i++) { + int value_size = values_[i].size; + int value_pos = values_[i].pos; + int value_off = values_[i].offset; + int value_attr_id = values_[i].attr_id; + uint8_t *data = pkt->head_data() + value_off; + + DLOG(INFO) << "off: " << (int)value_off << ", sz: " << value_size + << std::endl; + if (value_attr_id < 0) { /* if it is offset-based */ + memcpy(data, + reinterpret_cast(&result[init]->keyv) + value_pos, + value_size); + } else { /* if it is attribute-based */ + typedef struct { + uint8_t bytes[bess::metadata::kMetadataAttrMaxSize]; + } value_t; + uint8_t *buf = (uint8_t *)&result[init]->keyv + value_pos; + + DLOG(INFO) << "Setting value " << std::hex + << *(reinterpret_cast(buf)) + << " for attr_id: " << value_attr_id + << " of size: " << value_size + << " at value_pos: " << value_pos << std::endl; + + switch (value_size) { + case 1: + set_attr(this, value_attr_id, pkt, *((uint8_t *)buf)); + break; + case 2: + set_attr(this, value_attr_id, pkt, + *((uint16_t *)((uint8_t *)buf))); + break; + case 4: + set_attr(this, value_attr_id, pkt, + *((uint32_t *)((uint8_t *)buf))); + break; + case 8: + set_attr(this, value_attr_id, pkt, + *((uint64_t *)((uint8_t *)buf))); + break; + default: { + void *mt_ptr = _ptr_attr_with_offset( + attr_offset(value_attr_id), pkt); + bess::utils::CopySmall(mt_ptr, buf, value_size); + } break; + } + } + } + Outgate[init] = result[init]->ogate; + } else + Outgate[init] = def_gate; + } + return 1; +} + void WildcardMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { gate_idx_t default_gate; - wm_hkey_t keys[bess::PacketBatch::kMaxBurst] __ymm_aligned; - int cnt = batch->cnt(); + gate_idx_t Outgate[cnt]; // Initialize the padding with zero for (int i = 0; i < cnt; i++) { keys[i].u64_arr[(total_key_size_ - 1) / 8] = 0; } - default_gate = ACCESS_ONCE(default_gate_); - for (const auto &field : fields_) { int offset; int pos = field.pos; @@ -272,9 +378,25 @@ void WildcardMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { } } - for (int i = 0; i < cnt; i++) { - bess::Packet *pkt = batch->pkts()[i]; - EmitPacket(ctx, pkt, LookupEntry(keys[i], default_gate, pkt)); + if(cnt>64) + { + int icnt=0; + for(int lcnt=0; lcnt=64) ? 64 : cnt-lcnt ; + LookupBulkEntry(&keys[lcnt], default_gate, lcnt, Outgate, icnt, batch); + for (int j = 0; j < icnt; j++) + { + EmitPacket(ctx, batch->pkts()[j+lcnt], Outgate[j]); + } + } + } + else + { + LookupBulkEntry(keys, default_gate, 0, Outgate, cnt, batch); + for (int j = 0; j < cnt; j++) { + EmitPacket(ctx, batch->pkts()[j], Outgate[j]); + } } } @@ -282,7 +404,9 @@ std::string WildcardMatch::GetDesc() const { int num_rules = 0; for (const auto &tuple : tuples_) { - num_rules += tuple.ht.Count(); + if (tuple.occupied == 0) + continue; + num_rules += tuple.ht->Count(); } return bess::utils::Format("%zu fields, %d rules", fields_.size(), num_rules); @@ -387,54 +511,60 @@ CommandResponse WildcardMatch::ExtractValue(const T &arg, wm_hkey_t *keyv) { } int WildcardMatch::FindTuple(wm_hkey_t *mask) { - int i = 0; - - for (const auto &tuple : tuples_) { - if (memcmp(&tuple.mask, mask, total_key_size_) == 0) { + for (auto i = 0; i < MAX_TUPLES; i++) { + if ((tuples_[i].occupied) && + (memcmp(&tuples_[i].mask, mask, total_key_size_) == 0)) { return i; } - i++; } return -ENOENT; } int WildcardMatch::AddTuple(wm_hkey_t *mask) { - if (tuples_.size() >= MAX_TUPLES) { - return -ENOSPC; + CuckooMap *temp = nullptr; + for (int i = 0; i < MAX_TUPLES; i++) { + if (tuples_[i].occupied == 0) { + bess::utils::Copy(&tuples_[i].mask, mask, sizeof(*mask)); + tuples_[i].params.key_len = total_key_size_; + temp = new CuckooMap( + 0, 0, &tuples_[i].params); + if (temp == nullptr) + return -ENOSPC; + if (temp->hash == 0) { + delete temp; + return -ENOSPC; + } + void *temp1 = tuples_[i].ht; + tuples_[i].ht = temp; + if (temp1) + delete ( + static_cast *>( + temp1)); + tuples_[i].occupied = 1; + return i; + } } - - tuples_.emplace_back(); - struct WmTuple &tuple = tuples_.back(); - bess::utils::Copy(&tuple.mask, mask, sizeof(*mask)); - - return int(tuples_.size() - 1); + return -ENOSPC; } bool WildcardMatch::DelEntry(int idx, wm_hkey_t *key) { - struct WmTuple &tuple = tuples_[idx]; - bool ret = - tuple.ht.Remove(*key, wm_hash(total_key_size_), wm_eq(total_key_size_)); - if (!ret) { - return ret; + int ret = tuples_[idx].ht->Remove(*key, wm_hash(total_key_size_), + wm_eq(total_key_size_)); + if (ret >= 0) { + return true; } - - if (tuple.ht.Count() == 0) { - tuples_.erase(tuples_.begin() + idx); + if (tuples_[idx].ht->Count() == 0) { } - - return true; + return false; } CommandResponse WildcardMatch::CommandAdd( const bess::pb::WildcardMatchCommandAddArg &arg) { gate_idx_t gate = arg.gate(); int priority = arg.priority(); - wm_hkey_t key = {{0}}; wm_hkey_t mask = {{0}}; - struct WmData data; - CommandResponse err = ExtractKeyMask(arg, &key, &mask); if (err.error().code() != 0) { return err; @@ -444,14 +574,13 @@ CommandResponse WildcardMatch::CommandAdd( return CommandFailure(EINVAL, "Invalid gate: %hu", gate); } - err = ExtractValue(arg, &data.keyv); + err = ExtractValue(arg, &(data.keyv)); if (err.error().code() != 0) { return err; } data.priority = priority; data.ogate = gate; - int idx = FindTuple(&mask); if (idx < 0) { idx = AddTuple(&mask); @@ -459,13 +588,10 @@ CommandResponse WildcardMatch::CommandAdd( return CommandFailure(-idx, "failed to add a new wildcard pattern"); } } - - auto *ret = tuples_[idx].ht.Insert(key, data, wm_hash(total_key_size_), - wm_eq(total_key_size_)); - if (ret == nullptr) { + struct WmData *data_t = new WmData(data); + int ret = tuples_[idx].ht->insert_dpdk(&key, data_t); + if (ret < 0) return CommandFailure(EINVAL, "failed to add a rule"); - } - return CommandSuccess(); } @@ -485,7 +611,7 @@ CommandResponse WildcardMatch::CommandDelete( } int ret = DelEntry(idx, &key); - if (!ret) { + if (ret < 0) { return CommandFailure(-ret, "failed to delete a rule"); } @@ -499,7 +625,10 @@ CommandResponse WildcardMatch::CommandClear(const bess::pb::EmptyArg &) { void WildcardMatch::Clear() { for (auto &tuple : tuples_) { - tuple.ht.Clear(); + if (tuple.occupied) { + tuple.occupied = 0; + tuple.ht->Clear(); + } } } @@ -521,17 +650,26 @@ CommandResponse WildcardMatch::GetInitialArg(const bess::pb::EmptyArg &) { // Retrieves a WildcardMatchConfig that would restore this module's // runtime configuration. CommandResponse WildcardMatch::GetRuntimeConfig(const bess::pb::EmptyArg &) { + std::pair entry; bess::pb::WildcardMatchConfig resp; using rule_t = bess::pb::WildcardMatchCommandAddArg; - + const wm_hkey_t *key = 0; + WmData *data; + uint32_t *next = 0; resp.set_default_gate(default_gate_); // Each tuple provides a single mask, which may have many data-matches. for (auto &tuple : tuples_) { + if (tuple.occupied == 0) + continue; wm_hkey_t mask = tuple.mask; // Each entry in the hash table has priority, ogate, and the data // (one datum per field, under the mask for this field). - for (auto &entry : tuple.ht) { + // using rte method + while ((tuple.ht->Iterate((const void **)&key, (void **)&data, next)) >= + (int)0) { + entry.first = *key; + entry.second = *data; // Create the rule instance rule_t *rule = resp.add_rules(); rule->set_priority(entry.second.priority); @@ -596,5 +734,14 @@ CommandResponse WildcardMatch::SetRuntimeConfig( return CommandSuccess(); } +void WildcardMatch::DeInit() { + for (auto &tuple : tuples_) { + if (!tuple.ht) + continue; + tuple.ht->DeInit(); + tuple.ht = NULL; + } +} + ADD_MODULE(WildcardMatch, "wm", "Multi-field classifier with a wildcard match table") diff --git a/core/modules/wildcard_match.h b/core/modules/wildcard_match.h index 85deeafcab..0bd85f6b28 100644 --- a/core/modules/wildcard_match.h +++ b/core/modules/wildcard_match.h @@ -45,6 +45,7 @@ using bess::utils::HashResult; #define MAX_TUPLES 8 #define MAX_FIELDS 8 #define MAX_FIELD_SIZE 8 +#define BULK_SIZE 32 static_assert(MAX_FIELD_SIZE <= sizeof(uint64_t), "field cannot be larger than 8 bytes"); @@ -128,6 +129,12 @@ class wm_hash { private: size_t len_; }; +struct rte_hash_parameters dpdk_params1 { + .name = "test2", .entries = 1 << 20, .reserved = 0, + .key_len = sizeof(wm_hkey_t), .hash_func = rte_hash_crc, + .hash_func_init_val = 0, .socket_id = (int)rte_socket_id(), + .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY +}; class WildcardMatch final : public Module { public: @@ -144,10 +151,13 @@ class WildcardMatch final : public Module { values_(), tuples_() { max_allowed_workers_ = Worker::kMaxWorkers; + { tuples_.resize(MAX_TUPLES); } } CommandResponse Init(const bess::pb::WildcardMatchArg &arg); + void DeInit() override; + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; std::string GetDesc() const override; @@ -164,13 +174,26 @@ class WildcardMatch final : public Module { private: struct WmTuple { - CuckooMap ht; + bool occupied; + CuckooMap *ht; wm_hkey_t mask; + struct rte_hash_parameters params; + std::string hash_name; + WmTuple() : occupied(0), ht(0) { + params = dpdk_params1; + std::ostringstream address; + address << this; + hash_name = "Wild" + address.str(); + params.name = hash_name.c_str(); + } }; gate_idx_t LookupEntry(const wm_hkey_t &key, gate_idx_t def_gate, bess::Packet *pkt); + bool LookupBulkEntry(wm_hkey_t *key, gate_idx_t def_gate, int i, + gate_idx_t *Outgate, int cnt, bess::PacketBatch *batch); + CommandResponse AddFieldOne(const bess::pb::Field &field, struct WmField *f, uint8_t type); @@ -182,9 +205,7 @@ class WildcardMatch final : public Module { int FindTuple(wm_hkey_t *mask); int AddTuple(wm_hkey_t *mask); bool DelEntry(int idx, wm_hkey_t *key); - void Clear(); - gate_idx_t default_gate_; size_t total_key_size_; /* a multiple of sizeof(uint64_t) */ @@ -193,7 +214,8 @@ class WildcardMatch final : public Module { // TODO(melvinw): this can be refactored to use ExactMatchTable std::vector fields_; std::vector values_; - std::vector tuples_; + std::vector tuples_; //[MAX_TUPLES]; + std::vector data_; }; #endif // BESS_MODULES_WILDCARDMATCH_H_ diff --git a/core/utils/cuckoo_map.h b/core/utils/cuckoo_map.h index c855b93dea..6213ce7d92 100644 --- a/core/utils/cuckoo_map.h +++ b/core/utils/cuckoo_map.h @@ -50,6 +50,8 @@ #include "../debug.h" #include "common.h" +#include +#include namespace bess { namespace utils { @@ -74,7 +76,13 @@ typedef uint32_t EntryIndex; template , typename E = std::equal_to> class CuckooMap { + private: + bool IsDpdk = false; + uint32_t key_len = 0; + rte_hash_parameters rt; + public: + struct rte_hash* hash = nullptr; typedef std::pair Entry; class iterator { @@ -149,20 +157,29 @@ class CuckooMap { }; CuckooMap(size_t reserve_buckets = kInitNumBucket, - size_t reserve_entries = kInitNumEntries) + size_t reserve_entries = kInitNumEntries, void* dpdk_params = 0) : bucket_mask_(reserve_buckets - 1), num_entries_(0), buckets_(reserve_buckets), entries_(reserve_entries), free_entry_indices_() { - // the number of buckets must be a power of 2 - CHECK_EQ(align_ceil_pow2(reserve_buckets), reserve_buckets); + if (dpdk_params) { + if (hash == NULL) { + rt = *((rte_hash_parameters*)dpdk_params); + hash = rte_hash_create(&rt); + if (hash == NULL) + return; + } + IsDpdk = true; + } else { + // the number of buckets must be a power of 2 + CHECK_EQ(align_ceil_pow2(reserve_buckets), reserve_buckets); - for (int i = reserve_entries - 1; i >= 0; --i) { - free_entry_indices_.push(i); + for (int i = reserve_entries - 1; i >= 0; --i) { + free_entry_indices_.push(i); + } } } - // Not allowing copying for now CuckooMap(CuckooMap&) = delete; CuckooMap& operator=(CuckooMap&) = delete; @@ -220,6 +237,50 @@ class CuckooMap { return DoEmplace(key, hasher, eq, std::move(value)); } + int insert_dpdk(const void* key, void* data = 0, hash_sig_t sig = 0) { + if (IsDpdk) { + if (data && !sig) + return rte_hash_add_key_data(hash, key, data); + if (data && sig) + return rte_hash_add_key_with_hash_data(hash, key, sig, data); + if (!data && !sig) + return rte_hash_add_key(hash, key); + } + return -1; + } + + int find_dpdk(const void* key, void** data = 0, + hash_sig_t sig = 0) + { + if (IsDpdk) { + if (data && !sig) + return rte_hash_lookup_data(hash, key, data); + if (data && sig) + return rte_hash_lookup_with_hash_data(hash, key, sig, data); + if (!data && !sig) + return rte_hash_lookup(hash, key); + if (!data && sig) + return rte_hash_lookup_with_hash(hash, key, sig); + } + return -1; + } + + int find_dpdk(const void* key, void** data = 0, + hash_sig_t sig = 0) const + { + if (IsDpdk) { + if (data && !sig) + return rte_hash_lookup_data(hash, key, data); + if (data && sig) + return rte_hash_lookup_with_hash_data(hash, key, sig, data); + if (!data && !sig) + return rte_hash_lookup(hash, key); + if (!data && sig) + return rte_hash_lookup_with_hash(hash, key, sig); + } + return -1; + } + // Emplace/update-in-place a key value pair // On success returns a pointer to the inserted entry, nullptr otherwise. // NOTE: when Emplace() returns nullptr, the constructor of `V` may not be @@ -255,6 +316,13 @@ class CuckooMap { // Remove the stored entry by the key // Return false if not exist. bool Remove(const K& key, const H& hasher = H(), const E& eq = E()) { + if (IsDpdk) { + int ret = rte_hash_del_key(hash, &key); + if (ret < 0) + return false; + else + return true; + } HashResult pri = Hash(key, hasher); if (RemoveFromBucket(pri, pri & bucket_mask_, key, eq)) { return true; @@ -267,6 +335,12 @@ class CuckooMap { } void Clear() { + if (IsDpdk) { + if (hash) { + rte_hash_reset(hash); + } + return; + } buckets_.clear(); entries_.clear(); @@ -286,7 +360,36 @@ class CuckooMap { } // Return the number of stored entries - size_t Count() const { return num_entries_; } + size_t Count() const { + if (IsDpdk) + return rte_hash_count(hash); + else + return num_entries_; + } + + void DeInit() { + if (IsDpdk) { + if (hash) { + rte_hash_free(hash); + hash = nullptr; + } + return; + } + } + + // bulk data look up bess func + int32_t lookup_bulk_data(const void** keys, uint32_t num_keys, + uint64_t* hit_mask, void* data[]) { + if (IsDpdk) + return rte_hash_lookup_bulk_data(hash, keys, num_keys, hit_mask, data); + return -1; + } + // iterate for dpdk hash + int32_t Iterate(const void** key, void** data, uint32_t* next) { + if (IsDpdk) + return rte_hash_iterate(hash, key, data, next); + return -1; + } protected: // Tunable macros diff --git a/core/utils/exact_match_table.h b/core/utils/exact_match_table.h index 7c0cfda426..ac87e090ef 100644 --- a/core/utils/exact_match_table.h +++ b/core/utils/exact_match_table.h @@ -155,15 +155,17 @@ typedef std::vector> ExactMatchRuleFields; template class ExactMatchTable { public: + struct rte_hash_parameters dpdk_params { + .name = "test1", .entries = 1 << 20, .reserved = 0, + .key_len = sizeof(ExactMatchKey), .hash_func = rte_hash_crc, + .hash_func_init_val = 0, .socket_id = (int)rte_socket_id(), + .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY + }; + using EmTable = CuckooMap; - ExactMatchTable() - : raw_key_size_(), - total_key_size_(), - num_fields_(), - fields_(), - table_() {} + : raw_key_size_(), total_key_size_(), num_fields_(), fields_() {} // Add a new rule. // @@ -183,10 +185,9 @@ class ExactMatchTable { if ((err = gather_key(fields, &key)).first != 0) { return err; } - - table_.Insert(key, val, ExactMatchKeyHash(total_key_size_), - ExactMatchKeyEq(total_key_size_)); - + const void *Key_t = (const void *)&key; + T *val_t = new T(val); + table_->insert_dpdk(Key_t, val_t); return MakeError(0); } @@ -207,8 +208,8 @@ class ExactMatchTable { return err; } - bool ret = table_.Remove(key, ExactMatchKeyHash(total_key_size_), - ExactMatchKeyEq(total_key_size_)); + bool ret = table_->Remove(key, ExactMatchKeyHash(total_key_size_), + ExactMatchKeyEq(total_key_size_)); if (!ret) { return MakeError(ENOENT, "rule doesn't exist"); } @@ -217,9 +218,11 @@ class ExactMatchTable { } // Remove all rules from the table. - void ClearRules() { table_.Clear(); } + void ClearRules() { table_->Clear(); } - size_t Size() const { return table_.Count(); } + void DeInit() { table_->DeInit(); } + + size_t Size() const { return table_->Count(); } // Extract an ExactMatchKey from `buf` based on the fields that have been // added to this table. @@ -272,23 +275,27 @@ class ExactMatchTable { // Returns the value if `key` matches a rule, otherwise `default_value`. T Find(const ExactMatchKey &key, const T &default_value) const { const auto &table = table_; - const auto *entry = table.Find(key, ExactMatchKeyHash(total_key_size_), - ExactMatchKeyEq(total_key_size_)); - return entry ? entry->second : default_value; + void *data = nullptr; + table->find_dpdk(&key, &data); + if (data) { + T data_t = *((T *)data); + return data_t; + } else + return default_value; } // Find entries for `n` `keys` in the table and store their values in in // `vals`. Keys without entries will have their corresponding entires in // `vals` set to `default_value`. - void Find(const ExactMatchKey *keys, T *vals, size_t n, - T default_value) const { + uint64_t Find(ExactMatchKey *keys, T **vals, int n) { const auto &table = table_; - for (size_t i = 0; i < n; i++) { - const auto *entry = - table.Find(keys[i], ExactMatchKeyHash(total_key_size_), - ExactMatchKeyEq(total_key_size_)); - vals[i] = entry ? entry->second : default_value; - } + uint64_t hit_mask = 0; + ExactMatchKey *key_ptr[n]; + for (int h = 0; h < n; h++) + key_ptr[h] = &keys[h]; + table->lookup_bulk_data((const void **)&key_ptr, n, &hit_mask, + (void **)vals); + return hit_mask; } uint32_t total_key_size() const { return total_key_size_; } @@ -318,9 +325,20 @@ class ExactMatchTable { // Returns the ith field. const ExactMatchField &get_field(size_t i) const { return fields_[i]; } - typename EmTable::iterator begin() { return table_.begin(); } + typename EmTable::iterator begin() { return table_->begin(); } - typename EmTable::iterator end() { return table_.end(); } + typename EmTable::iterator end() { return table_->end(); } + + void Init() { + std::ostringstream address; + address << &table_; + std::string name = "Exactmatch" + address.str(); + dpdk_params.name = name.c_str(); + dpdk_params.key_len = total_key_size(); + table_.reset( + new CuckooMap( + 0, 0, &dpdk_params)); + } private: Error MakeError(int code, const std::string &msg = "") { @@ -438,23 +456,21 @@ class ExactMatchTable { f->pos = raw_key_size_; raw_key_size_ += f->size; total_key_size_ = align_ceil(raw_key_size_, sizeof(uint64_t)); - return MakeError(0); } // unaligend key size, used as an accumulator for calls to AddField() size_t raw_key_size_; - // aligned total key size size_t total_key_size_; - size_t num_fields_; ExactMatchField fields_[MAX_FIELDS]; - - EmTable table_; + std::unique_ptr< + CuckooMap> + table_; }; -} // namespace bess } // namespace utils +} // namespace bess #endif // BESS_UTILS_EXACT_MATCH_TABLE_H_ From 4e6cf119d26484bf95c2074a7f4c95df672851bc Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 12:59:46 -0700 Subject: [PATCH 17/62] 0013-Use-rte_flow_create-to-do-GTPU-RSS --- core/drivers/pmd.cc | 126 ++++++++++++++++++++++++++++++++++ protobuf/ports/port_msg.proto | 4 ++ 2 files changed, 130 insertions(+) diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index 5699b542a0..387d3953e2 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -32,6 +32,7 @@ #include #include +#include #include "../utils/ether.h" #include "../utils/format.h" @@ -206,6 +207,122 @@ static CommandResponse find_dpdk_vdev(const std::string &vdev, return CommandSuccess(); } +CommandResponse flow_create_one(dpdk_port_t port_id, + const uint32_t &flow_profile, int size, + uint64_t rss_types, + rte_flow_item_type *pattern) { + struct rte_flow_item items[size]; + memset(items, 0, sizeof(items)); + + for (int i = 0; i < size; i++) { + items[i].type = pattern[i]; + items[i].spec = nullptr; + items[i].mask = nullptr; + } + + struct rte_flow *handle; + struct rte_flow_error err; + memset(&err, 0, sizeof(err)); + + struct rte_flow_action actions[2]; + memset(actions, 0, sizeof(actions)); + + struct rte_flow_attr attributes; + memset(&attributes, 0, sizeof(attributes)); + attributes.ingress = 1; + + struct rte_flow_action_rss action_rss; + memset(&action_rss, 0, sizeof(action_rss)); + action_rss.func = RTE_ETH_HASH_FUNCTION_DEFAULT; + action_rss.key_len = 0; + action_rss.types = rss_types; + + actions[0].type = RTE_FLOW_ACTION_TYPE_RSS; + actions[0].conf = &action_rss; + actions[1].type = RTE_FLOW_ACTION_TYPE_END; + + int ret = rte_flow_validate(port_id, &attributes, items, actions, &err); + if (ret) + return CommandFailure(EINVAL, + "Port %u: Failed to validate flow profile %u %s", + port_id, flow_profile, err.message); + + handle = rte_flow_create(port_id, &attributes, items, actions, &err); + if (handle == nullptr) + return CommandFailure(EINVAL, "Port %u: Failed to create flow %s", port_id, + err.message); + + return CommandSuccess(); +} + +#define NUM_ELEMENTS(x) (sizeof(x) / sizeof((x)[0])) + +enum FlowProfile : uint32_t +{ + profileN3 = 3, + profileN6 = 6, + profileN9 = 9, +}; + +CommandResponse flow_create(dpdk_port_t port_id, const uint32_t &flow_profile) { + CommandResponse err; + + rte_flow_item_type N39_NSA[] = { + RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_GTPU, RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END}; + + rte_flow_item_type N39_SA[] = { + RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_GTPU, RTE_FLOW_ITEM_TYPE_GTP_PSC, + RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END}; + + rte_flow_item_type N6[] = { + RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END}; + + switch (flow_profile) { + uint64_t rss_types; + // N3 traffic with and without PDU Session container + case profileN3: + rss_types = ETH_RSS_IPV4 | ETH_RSS_L3_SRC_ONLY; + err = flow_create_one(port_id, flow_profile, NUM_ELEMENTS(N39_NSA), + rss_types, N39_NSA); + if (err.error().code() != 0) { + return err; + } + + err = flow_create_one(port_id, flow_profile, NUM_ELEMENTS(N39_SA), + rss_types, N39_SA); + break; + + // N6 traffic + case profileN6: + rss_types = ETH_RSS_IPV4 | ETH_RSS_L3_DST_ONLY; + err = flow_create_one(port_id, flow_profile, NUM_ELEMENTS(N6), + rss_types, N6); + break; + + // N9 traffic with and without PDU Session container + case profileN9: + rss_types = ETH_RSS_IPV4 | ETH_RSS_L3_DST_ONLY; + err = flow_create_one(port_id, flow_profile, NUM_ELEMENTS(N39_NSA), + rss_types, N39_NSA); + if (err.error().code() != 0) { + return err; + } + + err = flow_create_one(port_id, flow_profile, NUM_ELEMENTS(N39_SA), + rss_types, N39_SA); + break; + + default: + return CommandFailure(EINVAL, "Unknown flow profile %u", flow_profile); + } + return err; +} + CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { dpdk_port_t ret_port_id = DPDK_PORT_UNKNOWN; @@ -364,6 +481,15 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { driver_ = dev_info.driver_name ?: "unknown"; + if (arg.flow_profiles_size() > 0){ + for (int i = 0; i < arg.flow_profiles_size(); ++i) { + err = flow_create(ret_port_id, arg.flow_profiles(i)); + if (err.error().code() != 0) { + return err; + } + } + } + return CommandSuccess(); } diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index e25f0943be..3768bed8bd 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -52,6 +52,10 @@ message PMDPortArg { } bool promiscuous_mode = 9; bool hwcksum = 10; + + // N3 -> 3; N6 -> 6; N9 -> 9 + // [3] or [6, 9] + repeated uint32 flow_profiles = 11; } message UnixSocketPortArg { From f72fcfd22f2ea0e77782a199b5df11776c3f7f4a Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 13:00:32 -0700 Subject: [PATCH 18/62] 0014-Add-ice-iavf-to-list-of-drivers-need-SW-port-stats --- core/drivers/pmd.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index 387d3953e2..dbebbe5513 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -599,9 +599,10 @@ void PMDPort::CollectStats(bool reset) { port_stats_.inc.dropped = stats.imissed; - // i40e/net_e1000_igb PMD drivers, ixgbevf and net_bonding vdevs don't support - // per-queue stats - if (driver_ == "net_i40e" || driver_ == "net_i40e_vf" || + // ice/i40e/net_e1000_igb PMD drivers, ixgbevf and net_bonding vdevs don't + // support per-queue stats + if (driver_ == "net_ice" || driver_ == "net_iavf" || + driver_ == "net_i40e" || driver_ == "net_i40e_vf" || driver_ == "net_ixgbe_vf" || driver_ == "net_bonding" || driver_ == "net_e1000_igb") { // NOTE: From c7cd4a252cbf7c593d033bcb91b30bc4294f310b Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 13:00:53 -0700 Subject: [PATCH 19/62] 0015-Protobuf-changes-for-Qos --- protobuf/module_msg.proto | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index 25dfc81ebc..df71d4c998 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -1291,3 +1291,41 @@ message MplsPopArg { message WorkerSplitArg { map worker_gates = 1; // ogate -> worker mask } + +message QosArg { + repeated Field fields = 1; + repeated Field values = 2; +} + +message QosCommandAddArg { + uint64 gate = 1; + uint64 cir = 2; + uint64 pir = 3; + uint64 cbs = 4; + uint64 pbs = 5; + uint64 ebs = 6; + oneof optional_deduct_len { + int64 deduct_len = 9; + } + repeated FieldData fields = 7; + repeated FieldData values = 8; +} + +message QosCommandDeleteArg { + repeated FieldData fields = 2; +} + +/** + * The function `clear()` for WildcardMatch takes no parameters, it clears + * all state in the WildcardMatch module (is equivalent to calling delete for all rules) + */ +message QosCommandClearArg { +} + +/** + * For traffic which does not match any rule in the WildcardMatch module, + * the `set_default_gate(...)` function specifies which gate to send this extra traffic to. + */ +message QosCommandSetDefaultGateArg { + uint64 gate = 1; +} From b7d5f837038d4a2c4163bab888d0f987ba32873d Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 13:01:19 -0700 Subject: [PATCH 20/62] 0016-Newer-versions-require-go_package-stated-in-proto --- protobuf/bess_msg.proto | 2 ++ protobuf/error.proto | 2 ++ protobuf/module_msg.proto | 3 +++ protobuf/ports/port_msg.proto | 2 ++ protobuf/service.proto | 2 ++ protobuf/util_msg.proto | 2 ++ 6 files changed, 13 insertions(+) diff --git a/protobuf/bess_msg.proto b/protobuf/bess_msg.proto index 9e1b79a337..9b30de3447 100644 --- a/protobuf/bess_msg.proto +++ b/protobuf/bess_msg.proto @@ -42,6 +42,8 @@ import "error.proto"; package bess.pb; +option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; + message EmptyRequest { } diff --git a/protobuf/error.proto b/protobuf/error.proto index a018ee8e06..04b352c543 100644 --- a/protobuf/error.proto +++ b/protobuf/error.proto @@ -31,6 +31,8 @@ syntax = "proto3"; package bess.pb; +option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; + message Error { int32 code = 1; // 0 for success, errno (>0) for failure string errmsg = 2; diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index df71d4c998..c435437a39 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -31,6 +31,9 @@ syntax = "proto3"; package bess.pb; + +option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; + import "util_msg.proto"; // Module-specific messages. diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index 3768bed8bd..7896a22a84 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -31,6 +31,8 @@ syntax = "proto3"; package bess.pb; +option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; + message PCAPPortArg { string dev = 1; } diff --git a/protobuf/service.proto b/protobuf/service.proto index ae1aba0533..706a283a46 100644 --- a/protobuf/service.proto +++ b/protobuf/service.proto @@ -33,6 +33,8 @@ import "bess_msg.proto"; package bess.pb; +option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; + service BESSControl { // ------------------------------------------------------------------------- diff --git a/protobuf/util_msg.proto b/protobuf/util_msg.proto index b1050abfd1..4df01fc67b 100644 --- a/protobuf/util_msg.proto +++ b/protobuf/util_msg.proto @@ -32,6 +32,8 @@ syntax="proto3"; package bess.pb; +option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; + /// The Field message represents one field in a packet -- either stored in metadata or in the packet body. message Field { oneof position { From ea5eaf398dec08d70657b49120a774d0addfd3d5 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 13:01:42 -0700 Subject: [PATCH 21/62] 0017-Make-table-sizes-configurable --- core/modules/exact_match.cc | 2 +- core/modules/wildcard_match.cc | 4 ++++ core/modules/wildcard_match.h | 3 ++- core/utils/exact_match_table.h | 7 +++++-- protobuf/module_msg.proto | 3 +++ 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/modules/exact_match.cc b/core/modules/exact_match.cc index fd9d7023b5..e50cf5cce6 100644 --- a/core/modules/exact_match.cc +++ b/core/modules/exact_match.cc @@ -134,7 +134,7 @@ CommandResponse ExactMatch::Init(const bess::pb::ExactMatchArg &arg) { } default_gate_ = DROP_GATE; - table_.Init(); + table_.Init(arg.entries()); return CommandSuccess(); } diff --git a/core/modules/wildcard_match.cc b/core/modules/wildcard_match.cc index e765aeb32c..e4c88d9526 100644 --- a/core/modules/wildcard_match.cc +++ b/core/modules/wildcard_match.cc @@ -147,6 +147,7 @@ CommandResponse WildcardMatch::Init(const bess::pb::WildcardMatchArg &arg) { } default_gate_ = DROP_GATE; total_key_size_ = align_ceil(size_acc, sizeof(uint64_t)); + entries_ = arg.entries(); // reset size_acc size_acc = 0; for (int i = 0; i < arg.values_size(); i++) { @@ -526,6 +527,9 @@ int WildcardMatch::AddTuple(wm_hkey_t *mask) { if (tuples_[i].occupied == 0) { bess::utils::Copy(&tuples_[i].mask, mask, sizeof(*mask)); tuples_[i].params.key_len = total_key_size_; + if (entries_) { + tuples_[i].params.entries = entries_; + } temp = new CuckooMap( 0, 0, &tuples_[i].params); if (temp == nullptr) diff --git a/core/modules/wildcard_match.h b/core/modules/wildcard_match.h index 0bd85f6b28..8940506ed3 100644 --- a/core/modules/wildcard_match.h +++ b/core/modules/wildcard_match.h @@ -130,7 +130,7 @@ class wm_hash { size_t len_; }; struct rte_hash_parameters dpdk_params1 { - .name = "test2", .entries = 1 << 20, .reserved = 0, + .name = "test2", .entries = 1 << 15, .reserved = 0, .key_len = sizeof(wm_hkey_t), .hash_func = rte_hash_crc, .hash_func_init_val = 0, .socket_id = (int)rte_socket_id(), .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY @@ -210,6 +210,7 @@ class WildcardMatch final : public Module { size_t total_key_size_; /* a multiple of sizeof(uint64_t) */ size_t total_value_size_; /* a multiple of sizeof(uint64_t) */ + size_t entries_; /* a power of 2 */ // TODO(melvinw): this can be refactored to use ExactMatchTable std::vector fields_; diff --git a/core/utils/exact_match_table.h b/core/utils/exact_match_table.h index ac87e090ef..f5238dd5fb 100644 --- a/core/utils/exact_match_table.h +++ b/core/utils/exact_match_table.h @@ -156,7 +156,7 @@ template class ExactMatchTable { public: struct rte_hash_parameters dpdk_params { - .name = "test1", .entries = 1 << 20, .reserved = 0, + .name = "test1", .entries = 1 << 15, .reserved = 0, .key_len = sizeof(ExactMatchKey), .hash_func = rte_hash_crc, .hash_func_init_val = 0, .socket_id = (int)rte_socket_id(), .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY @@ -329,12 +329,15 @@ class ExactMatchTable { typename EmTable::iterator end() { return table_->end(); } - void Init() { + void Init(uint32_t entries) { std::ostringstream address; address << &table_; std::string name = "Exactmatch" + address.str(); dpdk_params.name = name.c_str(); dpdk_params.key_len = total_key_size(); + if (entries) { + dpdk_params.entries = entries; + } table_.reset( new CuckooMap( 0, 0, &dpdk_params)); diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index c435437a39..6758ffbf28 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -508,6 +508,7 @@ message ExactMatchArg { repeated FieldData masks = 2; /// mask(i) corresponds to the mask for field(i) repeated Field values = 3; /// A list of ExactMatch Values repeated FieldData masksv = 4; /// mask(i) corresponds to the mask for value(i) + uint64 entries = 5; } /** @@ -1239,6 +1240,7 @@ message VXLANEncapArg { message WildcardMatchArg { repeated Field fields = 1; /// A list of WildcardMatch fields. repeated Field values = 2; /// A list of WildcardMatch values. + uint64 entries = 3; } /** @@ -1298,6 +1300,7 @@ message WorkerSplitArg { message QosArg { repeated Field fields = 1; repeated Field values = 2; + uint64 entries = 3; } message QosCommandAddArg { From 5248bf59fb0ebab5861559169ccaf4b8eccf77b4 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 13:02:07 -0700 Subject: [PATCH 22/62] 0017-QoS-Measure --- protobuf/module_msg.proto | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index 6758ffbf28..3cbc328790 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -1335,3 +1335,40 @@ message QosCommandClearArg { message QosCommandSetDefaultGateArg { uint64 gate = 1; } + +message FlowMeasureArg { + string flag_attr_name = 1; + uint64 entries = 2; + bool leader = 3; // If true, this module will decide the buffer side +} +message FlowMeasureCommandReadArg { + bool clear = 1; // If true, the data will be all cleared after read + repeated double latency_percentiles = 2; /// ascending list of real numbers in [0.0, 100.0] + repeated double jitter_percentiles = 3; /// ascending list of real numbers in [0.0, 100.0] + uint64 flag_to_read = 4; /// Which buffer to read from +} +message FlowMeasureReadResponse { + message Statistic { + message Histogram { + uint64 count = 1; /// Total # of measured data points, including above_range + uint64 above_range = 2; /// # of data points for the "too large value" bucket + uint64 resolution_ns = 8; /// resolution of measured data + uint64 min_ns = 3; + uint64 avg_ns = 4; + uint64 max_ns = 5; + uint64 total_ns = 6; + repeated uint64 percentile_values_ns = 7; + } + uint64 fseid = 1; + uint64 pdr = 2; + Histogram latency = 3; + Histogram jitter = 4; + uint64 total_bytes = 11; + uint64 total_packets = 12; + } + repeated Statistic statistics = 1; +} +message FlowMeasureCommandFlipArg {} +message FlowMeasureFlipResponse { + uint64 old_flag = 1; +} From eca68bcc18bce637016e436cf71f7a17ad2a0bff Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 13:02:24 -0700 Subject: [PATCH 23/62] 0018-Increase-max-tuple-num --- core/modules/wildcard_match.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/wildcard_match.h b/core/modules/wildcard_match.h index 8940506ed3..6e7703dcfa 100644 --- a/core/modules/wildcard_match.h +++ b/core/modules/wildcard_match.h @@ -42,7 +42,7 @@ using bess::utils::CuckooMap; using bess::utils::HashResult; -#define MAX_TUPLES 8 +#define MAX_TUPLES 16 #define MAX_FIELDS 8 #define MAX_FIELD_SIZE 8 #define BULK_SIZE 32 From 5e2a9a5d094af3f0dde71bf01f490df4a51df228 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 13:02:40 -0700 Subject: [PATCH 24/62] 0019-GUI-dot-module-name-quote --- bessctl/static/pipeline.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bessctl/static/pipeline.js b/bessctl/static/pipeline.js index f0041745c4..94c45abeef 100644 --- a/bessctl/static/pipeline.js +++ b/bessctl/static/pipeline.js @@ -134,7 +134,7 @@ function graph_to_dot(modules) { var ogates = module.show_ogates ? gates_to_str(module.ogates, 'ogate') : ''; nodes += ` - ${module_name} [shape=plaintext label= + "${module_name}" [shape=plaintext label= < ${igates} From 176773b1a3b6dc5d51ff0b4d815b14f87baa134f Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 18 Nov 2022 15:22:48 -0800 Subject: [PATCH 25/62] Bring BESS scripts from UPF repo --- bessctl/module_tests/ddp-rss-rx.bess | 21 +++ bessctl/module_tests/exactmatch-val.bess | 111 +++++++++++++ bessctl/module_tests/ipdefrag.bess | 9 ++ bessctl/module_tests/ipv4frags.pcap | Bin 0 -> 2990 bytes bessctl/module_tests/metering.bess | 136 ++++++++++++++++ .../wildcardmatch-masks-bench.bess | 101 ++++++++++++ bessctl/module_tests/wildcardmatch-val.bess | 150 ++++++++++++++++++ 7 files changed, 528 insertions(+) create mode 100644 bessctl/module_tests/ddp-rss-rx.bess create mode 100644 bessctl/module_tests/exactmatch-val.bess create mode 100644 bessctl/module_tests/ipdefrag.bess create mode 100644 bessctl/module_tests/ipv4frags.pcap create mode 100644 bessctl/module_tests/metering.bess create mode 100644 bessctl/module_tests/wildcardmatch-masks-bench.bess create mode 100644 bessctl/module_tests/wildcardmatch-val.bess diff --git a/bessctl/module_tests/ddp-rss-rx.bess b/bessctl/module_tests/ddp-rss-rx.bess new file mode 100644 index 0000000000..07d5984a1d --- /dev/null +++ b/bessctl/module_tests/ddp-rss-rx.bess @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2021 Intel Corporation + +num_q = 4 +kwargs = {'flow_profiles' : [3], + 'num_inc_q': num_q, + 'num_out_q': num_q} +p0 = PMDPort(port_id=0, **kwargs) +qinc_0_0::QueueInc(port=p0.name, qid=0) -> Sink() +qinc_0_1::QueueInc(port=p0.name, qid=1) -> Sink() +qinc_0_2::QueueInc(port=p0.name, qid=2) -> Sink() +qinc_0_3::QueueInc(port=p0.name, qid=3) -> Sink() + +kwargs = {'flow_profiles' : [6, 9], + 'num_inc_q': num_q, + 'num_out_q': num_q} +p1 = PMDPort(port_id=1, **kwargs) +qinc_1_0::QueueInc(port=p1.name, qid=0) -> Sink() +qinc_1_1::QueueInc(port=p1.name, qid=1) -> Sink() +qinc_1_2::QueueInc(port=p1.name, qid=2) -> Sink() +qinc_1_3::QueueInc(port=p1.name, qid=3) -> Sink() diff --git a/bessctl/module_tests/exactmatch-val.bess b/bessctl/module_tests/exactmatch-val.bess new file mode 100644 index 0000000000..0e61bade71 --- /dev/null +++ b/bessctl/module_tests/exactmatch-val.bess @@ -0,0 +1,111 @@ +# vim: syntax=py +# -*- mode: python -*- +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2019 Intel Corporation +# +# Copyright 2014-2016, The Regents of the University of California. +# Copyright 2016-2017, Nefeli Networks, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the names of the copyright holders nor the names of their +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import scapy.all as scapy +import socket + +src_mac='02:1e:67:9f:4d:ae' +dst_mac='06:16:3e:1b:72:32' +nh_mac1='00:00:00:00:00:01' +nh_mac2='00:00:00:00:00:02' +nh_mac3='00:00:00:00:00:03' +nh_mac4='60:61:62:63:64:65' + +def aton(ip): + return socket.inet_aton(ip) + +def mac2hex(mac): + return int(mac.replace(':', ''), 16) + +# Craft a packet with the specified IP addresses +def gen_packet(proto, src_ip, dst_ip): + eth = scapy.Ether(src=src_mac, dst=dst_mac) + ip = scapy.IP(src=src_ip, dst=dst_ip) + udp = proto(sport=10001, dport=10002) + payload = 'helloworld' + pkt = eth/ip/udp/payload + return bytes(pkt) + +packets = [gen_packet(scapy.UDP, '172.16.100.1', '10.0.0.1'), + gen_packet(scapy.UDP, '172.12.55.99', '12.34.56.78'), + gen_packet(scapy.UDP, '172.12.55.99', '10.0.0.1'), + gen_packet(scapy.UDP, '172.16.100.1', '12.34.56.78'), + gen_packet(scapy.UDP, '192.168.1.123', '12.34.56.78'), + ] + +# L4 protocol and source/destination IP addresses +em::ExactMatch(fields=[{'offset':0, 'num_bytes':6}, + {'offset':23, 'num_bytes':1}, + {'offset':26, 'num_bytes':4}, + {'offset':30, 'num_bytes':4}, + {'attr_name':'foo', 'num_bytes':2}], + values=[{'offset':0, 'num_bytes':6}, + {'attr_name':'bar', 'num_bytes':1}]) + +Source() -> Rewrite(templates=packets) -> SetMetadata(attrs=[{'name': 'foo', 'size': 2, 'value_int':0x3344}]) -> em + +em:0 -> m0::Merge() -> attrCmp::Split(size=1, attribute='bar') +em:1 -> m0 +em:2 -> m0 + +em.add(fields=[{'value_int': mac2hex(dst_mac)}, {'value_int':17}, {'value_bin':aton('172.16.100.1')}, {'value_bin':aton('10.0.0.1')}, {'value_int': 0x4433}], gate=0, values=[{'value_int': mac2hex(nh_mac1)}, {'value_int': 30}]) +em.add(fields=[{'value_int': mac2hex(dst_mac)}, {'value_int':17}, {'value_bin':aton('172.12.55.99')}, {'value_bin':aton('12.34.56.78')}, {'value_int': 0x4433}], gate=1, values=[{'value_int': mac2hex(nh_mac2)}, {'value_int': 29}]) +em.add(fields=[{'value_int': mac2hex(dst_mac)}, {'value_int':17}, {'value_bin':aton('172.12.55.99')}, {'value_bin':aton('10.0.0.1')}, {'value_int': 0x4433}], gate=2, values=[{'value_int': mac2hex(nh_mac3)}, {'value_int': 28}]) + + +# delete test +em.add(fields=[{'value_int': mac2hex(dst_mac)}, {'value_bin':chr(17)}, {'value_bin':aton('192.168.1.123')}, {'value_bin':aton('12.34.56.78')}, {'value_int': 0x4433}], gate=3, values=[{'value_int': mac2hex(nh_mac4)}, {'value_int': 27}]) +em.delete(fields=[{'value_int': mac2hex(dst_mac)}, {'value_bin':chr(17)}, {'value_bin':aton('192.168.1.123')}, {'value_bin':aton('12.34.56.78')}, {'value_int': 0x4433}]) + +# Setting out gates +em:3 -> BackgroundTraffic::Sink() # used as default gate +em.set_default_gate(gate=3) + +# setting failure gates +attrCmp -> em0Failure::Sink() + +# setting success gates +attrCmp:30 -> m1::Merge() -> offsetCmp::Split(size=6, offset=0) +attrCmp:29 -> m1 +attrCmp:28 -> m1 + + +# setting failure gates +offsetCmp -> em1Failure::Sink() + +# setting success gates +offsetCmp:1 -> m2::Merge() -> Success::Sink() +offsetCmp:2 -> m2 +offsetCmp:3 -> m2 diff --git a/bessctl/module_tests/ipdefrag.bess b/bessctl/module_tests/ipdefrag.bess new file mode 100644 index 0000000000..8b2b395f09 --- /dev/null +++ b/bessctl/module_tests/ipdefrag.bess @@ -0,0 +1,9 @@ +# vim: syntax=py +# -*- mode: python -*- +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2019 Intel Corporation + +p = PMDPort(name='ipv4frags', vdev='eth_pcap0,rx_pcap=ipv4frags.pcap,tx_pcap=reassembled.pcap') +reassemb = IPDefrag(num_flows=10) +PortInc(port=p.name) -> reassemb:1 -> PortOut(port=p.name) +reassemb:0 -> Sink() diff --git a/bessctl/module_tests/ipv4frags.pcap b/bessctl/module_tests/ipv4frags.pcap new file mode 100644 index 0000000000000000000000000000000000000000..5a6e4d20ac82dc86750b7b2184a6b335c39aae39 GIT binary patch literal 2990 zcmca|c+)~A1{MYwxWLZ9zzF1sXkUtq(c)nE#LNK391QA@<}U-1f3i+;Ft{=>KiPUg zfx&@swhI#@BNGraaxnN73Lj!%1nC5sW((8}0s?|U!Xlz#;u4Zl(lWAg@(PMd$||aA z>Kd9_+B&*=`UZwZ#wMm_<`$M#);6|w_709t&MvNQ?jD|A-afv5{sDnO!6Bhx;SrHh z(J`@c@d=4Z$tkI6=^2?>**Up+`2~eV#U-U>ECr+L^edg@B^A|2&x_ss8wd*%--nxC~?!EgD9zJ^flG{`&pr@4x>Hj7-cdtZeKYoLt;IynOtl{vVD1p_u+b`FJic z4_^Wn2Ox}I0x%xgdV!(JfpO0(SP3wiV}@3V0gB;B9S(*?tPEfbE8QU_y(? iz%u@I9;kc=#WDj!=x7-~TE>soaiewoXd7n$+IRrLgku8$ literal 0 HcmV?d00001 diff --git a/bessctl/module_tests/metering.bess b/bessctl/module_tests/metering.bess new file mode 100644 index 0000000000..c6e3887f14 --- /dev/null +++ b/bessctl/module_tests/metering.bess @@ -0,0 +1,136 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2021 Intel Corporation + +# Update assignments to hit different QoS entries +iface, qer, fseid = 1, 2, 4 +ip_pkt_size = 46 +sleep_seconds_before_delete = 30 + +import struct +def convert(format, val, bigendian=True): + end = '>' if [bigendian] else '<' + return struct.pack(end + format, val, ) + + +Meta::SetMetadata(attrs=[{'name': 'src_iface', 'size': 1, 'value_int': iface}, + {'name': 'qer_id', 'size':4, 'value_int': qer}, + {'name': 'fseid', 'size':8, 'value_int': fseid}]) + +Metering::Qos(fields=[{'attr_name':'src_iface', 'num_bytes':1}, + {'attr_name':'qer_id', 'num_bytes':4}, + {'attr_name':'fseid', 'num_bytes':8}], + values=[{'attr_name':'qfi', 'num_bytes':1}]) + +M::Merge() +S::Split(size=1, attribute='qfi') + +# Reserved gates, reject rule adds with gate=1/2/3 +m_meter = 0 # Placeholder gate not connected. Will meter if lookup result returns this gate +m_green = 1 # For green traffic +m_yellow = 2 # For yellow traffic +m_red = 3 # For red traffic + +# Rules with gate number above 3 are directly sent out w/o metering +m_fail = 4 # Default gate for lookup failure +m_drop = 5 # Explicitly asked to drop +m_unmeter= 6 # Unmetered + +Metering:m_green -> M +Metering:m_yellow -> M +Metering:m_red -> red::Sink() +Metering:m_drop -> drop::Sink() +Metering:m_unmeter -> S + +Metering:m_fail -> fail::Sink() +Metering.set_default_gate(gate=m_fail) + +# Pipeline +Source() -> Meta -> Metering +M -> S + +S:0 -> bad::Sink() # If traffic is going to this gate, meta update in QoS is not working +S:1 -> gbr1::Sink() +S:2 -> gbr5::Sink() +S:3 -> gmbr6::Sink() +S:4 -> mbr6::Sink() +S:5 -> unmeter::Sink() + +# Resume workers to test concurrent read-write +bess.resume_all() + +MPPS = pow(10,6) * ip_pkt_size + +# Add QoS entries +# GBR only +Metering.add(fields=[{'value_int': 1}, + {'value_bin': convert('L', 2)}, + {'value_bin': convert('Q', 4)}], + values=[{'value_int': 1}], # S:1 + gate=m_meter, cir=1 * MPPS , pir=1 * MPPS, cbs=2048, pbs=2048) + +Metering.add(fields=[{'value_int': 1}, + {'value_bin': convert('L', 3)}, + {'value_bin': convert('Q', 6)}], + values=[{'value_int': 2}], # S:2 + gate=m_meter, cir=5 * MPPS, pir=5 * MPPS, cbs=2048, pbs=2048) + +# GBR/MBR +Metering.add(fields=[{'value_int': 1}, + {'value_bin': convert('L', 4)}, + {'value_bin': convert('Q', 8)}], + values=[{'value_int': 3}], # S:3 + gate=m_meter, cir=3 * MPPS, pir=6 * MPPS, cbs=2048, pbs=2048) + +# MBR only +Metering.add(fields=[{'value_int': 1}, + {'value_bin': convert('L', 5)}, + {'value_bin': convert('Q', 10)}], + values=[{'value_int': 4}], # S:4 + gate=m_meter, cir=1, pir=6 * MPPS, cbs=2048, pbs=2048) + +# Unmeter +Metering.add(fields=[{'value_int': 1}, + {'value_bin': convert('L', 6)}, + {'value_bin': convert('Q', 12)}], + values=[{'value_int': 5}], # S:5 + gate=m_unmeter) + +# Gate closed +Metering.add(fields=[{'value_int': 1}, + {'value_bin': convert('L', 2)}, + {'value_bin': convert('Q', 3)}], + values=[{'value_int': 5}], + gate=m_drop) + +# Delete QoS entries after sleep +import time +time.sleep(sleep_seconds_before_delete) + +# GBR only +Metering.delete(fields=[{'value_int': 1}, + {'value_bin': convert('L', 2)}, + {'value_bin': convert('Q', 4)}]) + +Metering.delete(fields=[{'value_int': 1}, + {'value_bin': convert('L', 3)}, + {'value_bin': convert('Q', 6)}]) + +# GBR/MBR +Metering.delete(fields=[{'value_int': 1}, + {'value_bin': convert('L', 4)}, + {'value_bin': convert('Q', 8)}]) + +# MBR only +Metering.delete(fields=[{'value_int': 1}, + {'value_bin': convert('L', 5)}, + {'value_bin': convert('Q', 10)}]) + +# Unmeter +Metering.delete(fields=[{'value_int': 1}, + {'value_bin': convert('L', 6)}, + {'value_bin': convert('Q', 12)}]) + +# Gate closed +Metering.delete(fields=[{'value_int': 1}, + {'value_bin': convert('L', 2)}, + {'value_bin': convert('Q', 3)}]) \ No newline at end of file diff --git a/bessctl/module_tests/wildcardmatch-masks-bench.bess b/bessctl/module_tests/wildcardmatch-masks-bench.bess new file mode 100644 index 0000000000..da267bd97d --- /dev/null +++ b/bessctl/module_tests/wildcardmatch-masks-bench.bess @@ -0,0 +1,101 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2022 Open Networking Foundation +# Copyright 2019 Intel Corporation +# Copyright 2014-2016, The Regents of the University of California. +# Copyright 2016-2017, Nefeli Networks, Inc. + +# This pipeline showcases the effect of increasing the number of distinct +# entries in the WildcardMatch module on throughput. + +import scapy.all as scapy +import socket +import struct +import ipaddress +import time + +nh_mac='00:00:00:00:00:01' + +def atoh(ip): + return socket.inet_aton(ip) + +def mac2hex(mac): + return int(mac.replace(':', ''), 16) + +# Craft a packet with the specified IP address and port number +def gen_packet(dst_ip, dst_port): + eth = scapy.Ether(src='02:1e:67:9f:4d:ae', dst='06:16:3e:1b:72:32') + ip = scapy.IP(src='10.0.0.1', dst=dst_ip) + udp = scapy.UDP(sport=1234, dport=dst_port) + payload = 'helloworld' + pkt = eth/ip/udp/payload + return bytes(pkt) + +pkts = [ + gen_packet('20.0.0.1', 80), +] + +# destination IP address + destination port number + metadata 'in_port' +wm::WildcardMatch(fields=[{'offset':30, 'num_bytes':4}, + {'offset':36, 'num_bytes':2}, + {'attr_name':'in_port', 'num_bytes':2}], + values=[{'offset':6, 'num_bytes':6}, + {'attr_name':'out_port1', 'num_bytes':2}, + {'attr_name':'out_port2', 'num_bytes':2} + ]) + +# locally emulate two input ports +Source() -> SetMetadata(attrs=[{'name': 'in_port', 'size': 2, 'value_int': 1}, {'name': 'in_port2', 'size':2, 'value_int':5}]) -> Rewrite(templates=pkts) -> wm +Source() -> SetMetadata(attrs=[{'name': 'in_port', 'size': 2, 'value_int': 2}]) -> Rewrite(templates=pkts) -> wm + +wm:0 -> m0::Merge() -> offsetCmp::Split(size=6, offset=6) +wm:1 -> m0 +wm:10 -> BackgroundTraffic::Sink() # used as default gate + +wm.set_default_gate(gate=10) + +# setting failure gates +offsetCmp -> wm0Failure::Sink() + +# setting success gates +offsetCmp:1 -> m1::Merge() -> attr1Cmp::Split(size=2, attribute='out_port1') +offsetCmp:2 -> m1 +offsetCmp:3 -> m1 +offsetCmp:4 -> m1 +offsetCmp:5 -> m1 + + +# setting failure gates +attr1Cmp -> wm1Failure::Sink() + +# setting success gates +attr1Cmp:17 -> attr2Cmp::Split(size=2, attribute='out_port2') + +# setting failure gates +attr2Cmp -> wm2Failure::Sink() + +attr2Cmp:4352 -> Success::Sink() + + +# Matching rule +# 20.0.0.1/32, in_port any +wm.add(values=[{'value_bin': atoh('20.0.0.1')}, {'value_int': 0}, {'value_int':0} ], gate=1, + masks=[{'value_bin': atoh('255.255.255.255')}, {'value_int':0x0000}, {'value_int': 0x0000}], + valuesv=[{'value_int': mac2hex(nh_mac)}, {'value_int':0x1100}, {'value_int':0x0011}], + priority=1) + +bess.resume_all() +time.sleep(10) + +# Dummy rules +for i in range(16, 16+16): + bess.pause_all() + prefix = 32 - i + subnet = ipaddress.ip_address(((2**32 - 1) >> prefix) << prefix) + print(i, prefix, subnet, subnet.packed) + # 10.0.0.0/i, in_port any + wm.add(values=[{'value_bin': atoh('10.0.0.0')}, {'value_int': 0}, {'value_int': 0} ], gate=0, + masks=[{'value_bin': subnet.packed}, {'value_int': 0x0000}, {'value_int': 0x0000}], + valuesv=[{'value_int': mac2hex(nh_mac)}, {'value_int': 0x1100}, {'value_int': 0x0011}], + priority=40+i) + bess.resume_all() + time.sleep(10) diff --git a/bessctl/module_tests/wildcardmatch-val.bess b/bessctl/module_tests/wildcardmatch-val.bess new file mode 100644 index 0000000000..64d47e6214 --- /dev/null +++ b/bessctl/module_tests/wildcardmatch-val.bess @@ -0,0 +1,150 @@ +# vim: syntax=py +# -*- mode: python -*- +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2019 Intel Corporation +# +# Copyright 2014-2016, The Regents of the University of California. +# Copyright 2016-2017, Nefeli Networks, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the names of the copyright holders nor the names of their +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import scapy.all as scapy +import socket +import struct + +nh_mac1='00:00:00:00:00:01' +nh_mac2='00:00:00:00:00:02' +nh_mac3='00:00:00:00:00:03' +nh_mac4='00:00:00:00:00:04' +nh_mac5='00:00:00:00:00:05' +nh_mac6='00:00:00:00:00:06' + +def atoh(ip): + return socket.inet_aton(ip) + +def mac2hex(mac): + return int(mac.replace(':', ''), 16) + +# Craft a packet with the specified IP address and port number +def gen_packet(dst_ip, dst_port): + eth = scapy.Ether(src='02:1e:67:9f:4d:ae', dst='06:16:3e:1b:72:32') + ip = scapy.IP(src='10.0.0.1', dst=dst_ip) + udp = scapy.UDP(sport=1234, dport=dst_port) + payload = 'helloworld' + pkt = eth/ip/udp/payload + return bytes(pkt) + +pkts = [gen_packet('172.16.100.1', 80), + gen_packet('172.12.55.99', 54321), + gen_packet('172.12.55.3', 8080), + gen_packet('172.16.100.1', 345), + gen_packet('172.12.55.99', 12345), + gen_packet('192.168.1.123', 80)] + +# destination IP address + destination port number + metadata 'in_port' +wm::WildcardMatch(fields=[{'offset':30, 'num_bytes':4}, + {'offset':36, 'num_bytes':2}, + {'attr_name':'in_port', 'num_bytes':2}], + values=[{'offset':6, 'num_bytes':6}, + {'attr_name':'out_port1', 'num_bytes':2}, + {'attr_name':'out_port2', 'num_bytes':2} + ]) + +# locally emulate two input ports +Source() -> SetMetadata(attrs=[{'name': 'in_port', 'size': 2, 'value_int': 1}, {'name': 'in_port2', 'size':2, 'value_int':5}]) -> Rewrite(templates=pkts) -> wm +Source() -> SetMetadata(attrs=[{'name': 'in_port', 'size': 2, 'value_int': 2}]) -> Rewrite(templates=pkts) -> wm + +wm:0 -> m0::Merge() -> offsetCmp::Split(size=6, offset=6) +wm:1 -> m0 +wm:2 -> m0 +wm:3 -> m0 +wm:4 -> m0 +wm:5 -> BackgroundTraffic::Sink() # used as default gate + +wm.set_default_gate(gate=5) + +# 172.16.100.1/32, port 80, in_port 1 +wm.add(values=[{'value_bin':atoh('172.16.100.1')}, {'value_int':80}, {'value_int': 1}], gate=0, + masks=[{'value_bin':atoh('255.255.255.255')}, {'value_int':0xffff}, {'value_int':0xffff}], + valuesv=[{'value_int':mac2hex(nh_mac1)},{'value_int':0x1100},{'value_int':0x0011}], + priority=3) + +# 172.12.55.99/32, in_port 2 +wm.add(values=[{'value_bin':atoh('172.12.55.99')}, {'value_int': 0}, {'value_int': 2}], gate=1, + masks=[{'value_bin':atoh('255.255.255.255')}, {'value_int': 0}, {'value_int':0xffff }], + valuesv=[{'value_int':mac2hex(nh_mac2)},{'value_int':0x1100},{'value_int':0x0011}], + priority=1) + +# 172.12.55.3/32, in_port 1 (w/ the same wildcard pattern as the previous one) +wm.add(values=[{'value_bin':atoh('172.12.55.3')},{'value_int': 0}, {'value_int':1} ], gate=2, + masks=[{'value_bin':atoh('255.255.255.255')},{'value_int':0x0000},{'value_int': 0xffff}], + valuesv=[{'value_int':mac2hex(nh_mac3)},{'value_int':0x1100},{'value_int':0x0011}], + priority=0) + +# 172.0.0.0/8, port <= 1023 +wm.add(values=[{'value_bin':atoh('172.0.0.0')},{'value_int':0},{'value_int':0}], gate=3, + masks=[{'value_bin':atoh('255.0.0.0')},{'value_int': 0xfc00},{'value_int':0x0000}], + valuesv=[{'value_int':mac2hex(nh_mac4)},{'value_int':0x1100},{'value_int':0x0011}], + priority=2) + +# port 80 +wm.add(values=[{'value_bin':atoh('0.0.0.0')}, {'value_int': 80}, {'value_int': 0}], gate=4, + masks=[{'value_bin':atoh('0.0.0.0')},{'value_int':0xffff},{'value_int':0x0000}], + valuesv=[{'value_int':mac2hex(nh_mac5)},{'value_int':0x1100},{'value_int':0x0011}], + priority=0) + +# delete test +wm.add(values=[{'value_bin':atoh('172.12.55.0')},{'value_int':0},{'value_int':0}], gate=0, + masks=[{'value_bin':atoh('255.255.255.0')},{'value_int': 0x0000},{'value_int':0x0000}], + valuesv=[{'value_int':mac2hex(nh_mac6)},{'value_int':0x1100},{'value_int':0x0011}], + priority=4) +wm.delete(values=[{'value_bin':atoh('172.12.55.0')},{'value_int': 0},{'value_int': 0}], + masks=[{'value_bin':atoh('255.255.255.0')}, {'value_int':0x0000},{'value_int': 0x0000} ]) + + +# setting failure gates +offsetCmp -> wm0Failure::Sink() + +# setting success gates +offsetCmp:1 -> m1::Merge() -> attr1Cmp::Split(size=2, attribute='out_port1') +offsetCmp:2 -> m1 +offsetCmp:3 -> m1 +offsetCmp:4 -> m1 +offsetCmp:5 -> m1 + + +# setting failure gates +attr1Cmp -> wm1Failure::Sink() + +# setting success gates +attr1Cmp:17 -> attr2Cmp::Split(size=2, attribute='out_port2') + +# setting failure gates +attr2Cmp -> wm2Failure::Sink() + +attr2Cmp:4352 -> Success::Sink() From 16262bd356b8fe6912bcaad253a8ceb8e1269ae9 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 18 Nov 2022 14:51:15 -0800 Subject: [PATCH 26/62] Move BESS-related files to BESS repo --- core/modules/counter.cc | 125 ++++++++++ core/modules/counter.h | 43 ++++ core/modules/flow_measure.cc | 284 +++++++++++++++++++++++ core/modules/flow_measure.h | 128 +++++++++++ core/modules/gtpu_decap.cc | 51 +++++ core/modules/gtpu_decap.h | 19 ++ core/modules/gtpu_echo.cc | 97 ++++++++ core/modules/gtpu_echo.h | 50 ++++ core/modules/gtpu_encap.cc | 215 +++++++++++++++++ core/modules/gtpu_encap.h | 45 ++++ core/modules/gtpu_parser.cc | 131 +++++++++++ core/modules/gtpu_parser.h | 48 ++++ core/modules/ip_defrag.cc | 132 +++++++++++ core/modules/ip_defrag.h | 43 ++++ core/modules/ip_frag.cc | 191 ++++++++++++++++ core/modules/ip_frag.h | 69 ++++++ core/modules/qos.cc | 432 +++++++++++++++++++++++++++++++++++ core/modules/qos.h | 94 ++++++++ core/utils/gtp.h | 68 ++++++ core/utils/metering.h | 196 ++++++++++++++++ 20 files changed, 2461 insertions(+) create mode 100644 core/modules/counter.cc create mode 100644 core/modules/counter.h create mode 100644 core/modules/flow_measure.cc create mode 100644 core/modules/flow_measure.h create mode 100644 core/modules/gtpu_decap.cc create mode 100644 core/modules/gtpu_decap.h create mode 100644 core/modules/gtpu_echo.cc create mode 100644 core/modules/gtpu_echo.h create mode 100644 core/modules/gtpu_encap.cc create mode 100644 core/modules/gtpu_encap.h create mode 100644 core/modules/gtpu_parser.cc create mode 100644 core/modules/gtpu_parser.h create mode 100644 core/modules/ip_defrag.cc create mode 100644 core/modules/ip_defrag.h create mode 100644 core/modules/ip_frag.cc create mode 100644 core/modules/ip_frag.h create mode 100644 core/modules/qos.cc create mode 100644 core/modules/qos.h create mode 100644 core/utils/gtp.h create mode 100644 core/utils/metering.h diff --git a/core/modules/counter.cc b/core/modules/counter.cc new file mode 100644 index 0000000000..77f32afcd8 --- /dev/null +++ b/core/modules/counter.cc @@ -0,0 +1,125 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +#include "counter.h" +/* for GetDesc() */ +#include "utils/format.h" +/* for endian functions */ +#include +/*----------------------------------------------------------------------------------*/ +const Commands Counter::cmds = { + {"add", "CounterAddArg", MODULE_CMD_FUNC(&Counter::AddCounter), + Command::THREAD_SAFE}, + {"removeAll", "EmptyArg", MODULE_CMD_FUNC(&Counter::RemoveAllCounters), + Command::THREAD_SAFE}, + {"remove", "CounterRemoveArg", MODULE_CMD_FUNC(&Counter::RemoveCounter), + Command::THREAD_SAFE}}; +/*----------------------------------------------------------------------------------*/ +CommandResponse Counter::AddCounter(const bess::pb::CounterAddArg &arg) { + uint32_t ctr_id = arg.ctr_id(); +#ifdef HASHMAP_BASED + /* check_exist is still here for over-protection */ + if (counters.find(ctr_id) == counters.end()) { + SessionStats s = {.pkt_count = 0, .byte_count = 0}; + counters.insert(std::pair(ctr_id, s)); + } else + return CommandFailure(EINVAL, "Unable to add ctr"); +#else + (void)ctr_id; + curr_count++; +#endif + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +CommandResponse Counter::RemoveAllCounters(const bess::pb::EmptyArg &) { +#ifdef HASHMAP_BASED + counters.clear(); +#else + memset(counters, 0, sizeof(SessionStats) * total_count); + curr_count = 0; +#endif + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +CommandResponse Counter::RemoveCounter(const bess::pb::CounterRemoveArg &arg) { + uint32_t ctr_id = arg.ctr_id(); + +#ifdef HASHMAP_BASED + /* check_exist is still here for over-protection */ + if (counters.find(ctr_id) != counters.end()) { + std::cerr << this->name() << "[" << ctr_id + << "]: " << counters[ctr_id].pkt_count << ", " + << counters[ctr_id].byte_count << std::endl; + counters.erase(ctr_id); + } else { + return CommandFailure(EINVAL, "Unable to remove ctr"); + } +#else + if (ctr_id < total_count && counters[ctr_id].pkt_count != 0) { + DLOG(INFO) << this->name() << "[" << ctr_id + << "]: " << counters[ctr_id].pkt_count << ", " + << counters[ctr_id].byte_count << std::endl; + counters[ctr_id].pkt_count = counters[ctr_id].byte_count = 0; + } + curr_count--; +#endif + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +CommandResponse Counter::Init(const bess::pb::CounterArg &arg) { + name_id = arg.name_id(); + if (name_id == "") + return CommandFailure(EINVAL, "Invalid counter idx name"); + check_exist = arg.check_exist(); + + using AccessMode = bess::metadata::Attribute::AccessMode; + ctr_attr_id = AddMetadataAttr(name_id, sizeof(uint32_t), AccessMode::kRead); + +#ifndef HASHMAP_BASED + total_count = arg.total(); + if (total_count <= 0) + return CommandFailure(EINVAL, "Invalid total number"); + counters = (SessionStats *)calloc(total_count, sizeof(SessionStats)); + if (counters == NULL) + return CommandFailure(ENOMEM, "Unable to allocate memory for counters!"); + curr_count = 0; +#endif + + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +void Counter::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + int cnt = batch->cnt(); + + for (int i = 0; i < cnt; i++) { + uint32_t ctr_id = get_attr(this, ctr_attr_id, batch->pkts()[i]); +#ifdef HASHMAP_BASED + std::map::iterator it; + + // check if ctr_id is present + if (!check_exist || (it = counters.find(ctr_id)) != counters.end()) { + it->second.pkt_count += 1; + it->second.byte_count += batch->pkts()[i]->total_len(); + } +#else + if (ctr_id < total_count) { + counters[ctr_id].pkt_count += 1; + counters[ctr_id].byte_count += batch->pkts()[i]->total_len(); + } +#endif + } + + RunNextModule(ctx, batch); +} +/*----------------------------------------------------------------------------------*/ +std::string Counter::GetDesc() const { +#ifdef HASHMAP_BASED + return bess::utils::Format("%zu sessions", (size_t)counters.size()); +#else + return bess::utils::Format("%zu sessions", (size_t)curr_count); +#endif +} +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(Counter, "counter", + "Counts the number of packets/bytes in the UP4 pipeline") diff --git a/core/modules/counter.h b/core/modules/counter.h new file mode 100644 index 0000000000..802573b548 --- /dev/null +++ b/core/modules/counter.h @@ -0,0 +1,43 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ + +#ifndef BESS_MODULES_COUNTER_H_ +#define BESS_MODULES_COUNTER_H_ + +#include "../module.h" +#include + +struct SessionStats { + uint64_t pkt_count; + uint64_t byte_count; +}; + +class Counter final : public Module { + public: + Counter() : counters() { max_allowed_workers_ = Worker::kMaxWorkers; } + + static const Commands cmds; + CommandResponse AddCounter(const bess::pb::CounterAddArg &arg); + CommandResponse RemoveCounter(const bess::pb::CounterRemoveArg &arg); + CommandResponse RemoveAllCounters(const bess::pb::EmptyArg &); + CommandResponse Init(const bess::pb::CounterArg &arg); + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + // returns the number of active UE sessions + std::string GetDesc() const override; + + private: +#ifdef HASHMAP_BASED + std::map counters; +#else + SessionStats *counters; + uint32_t curr_count; +#endif + std::string name_id; + bool check_exist; + int ctr_attr_id; + uint32_t total_count; +}; + +#endif // BESS_MODULES_COUNTER_H_ diff --git a/core/modules/flow_measure.cc b/core/modules/flow_measure.cc new file mode 100644 index 0000000000..71dc956988 --- /dev/null +++ b/core/modules/flow_measure.cc @@ -0,0 +1,284 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2021 Open Networking Foundation + */ + +#include "flow_measure.h" + +#include +#include + +#include "../core/utils/common.h" + +/*----------------------------------------------------------------------------------*/ +const Commands FlowMeasure::cmds = { + {"read", "FlowMeasureCommandReadArg", + MODULE_CMD_FUNC(&FlowMeasure::CommandReadStats), Command::THREAD_SAFE}, + {"flip", "FlowMeasureCommandFlipArg", + MODULE_CMD_FUNC(&FlowMeasure::CommandFlipFlag), Command::THREAD_SAFE}, +}; +/*----------------------------------------------------------------------------------*/ +CommandResponse FlowMeasure::Init(const bess::pb::FlowMeasureArg &arg) { + using AccessMode = bess::metadata::Attribute::AccessMode; + // Leader module decides which buffer side to use. + if (arg.leader()) { + const std::lock_guard lock(flag_mutex_); + leader_ = true; + buffer_flag_attr_id_ = AddMetadataAttr( + arg.flag_attr_name(), sizeof(uint64_t), AccessMode::kWrite); + current_flag_value_ = Flag::FLAG_VALUE_A; + } else { + leader_ = false; + buffer_flag_attr_id_ = AddMetadataAttr(arg.flag_attr_name(), + sizeof(uint64_t), AccessMode::kRead); + } + if (buffer_flag_attr_id_ < 0) + return CommandFailure(EINVAL, "invalid flag attribute name"); + ts_attr_id_ = + AddMetadataAttr("timestamp", sizeof(uint64_t), AccessMode::kRead); + if (ts_attr_id_ < 0) + return CommandFailure(EINVAL, "invalid metadata declaration"); + fseid_attr_id_ = + AddMetadataAttr("fseid", sizeof(uint64_t), AccessMode::kRead); + if (fseid_attr_id_ < 0) + return CommandFailure(EINVAL, "invalid metadata declaration"); + pdr_attr_id_ = AddMetadataAttr("pdr_id", sizeof(uint32_t), AccessMode::kRead); + if (pdr_attr_id_ < 0) + return CommandFailure(EINVAL, "invalid metadata declaration"); + + rte_hash_parameters hash_params = {}; + hash_params.entries = kDefaultNumEntries; + hash_params.key_len = sizeof(TableKey); + hash_params.hash_func = rte_jhash; + hash_params.socket_id = static_cast(rte_socket_id()); + hash_params.extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY; + if (arg.entries()) { + hash_params.entries = arg.entries(); + } + // Create both hash tables. + std::string name_a = name() + "Ta" + std::to_string(hash_params.socket_id); + if (name_a.length() > 26 /*RTE_HASH_NAMESIZE - 1*/) { + return CommandFailure(EINVAL, "invalid hash name A"); + } + hash_params.name = name_a.c_str(); + table_a_ = rte_hash_create(&hash_params); + if (!table_a_) { + return CommandFailure(rte_errno, "could not create hashmap A"); + } + std::string name_b = name() + "Tb" + std::to_string(hash_params.socket_id); + if (name_b.length() > 26 /*RTE_HASH_NAMESIZE - 1*/) { + return CommandFailure(EINVAL, "invalid hash name B"); + } + hash_params.name = name_b.c_str(); + table_b_ = rte_hash_create(&hash_params); + if (!table_b_) { + return CommandFailure(rte_errno, "could not create hashmap B"); + } + + // resize() would require a copyable object. + std::vector tmp_a(hash_params.entries); + std::vector tmp_b(hash_params.entries); + table_data_a_.swap(tmp_a); + table_data_b_.swap(tmp_b); + VLOG(1) << name() << ": Tables created successfully."; + + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +void FlowMeasure::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + uint64_t now_ns = tsc_to_ns(rdtsc()); + for (int i = 0; i < batch->cnt(); ++i) { + Flag cached_current_flag; + if (leader_) { + const std::lock_guard lock(flag_mutex_); + set_attr(this, buffer_flag_attr_id_, batch->pkts()[i], + static_cast(current_flag_value_)); + cached_current_flag = current_flag_value_; + } else { + const std::lock_guard lock(flag_mutex_); + uint64_t flag = + get_attr(this, buffer_flag_attr_id_, batch->pkts()[i]); + if (!Flag_IsValid(flag)) { + LOG_EVERY_N(WARNING, 100'001) << "Encountered invalid flag: " << flag; + continue; + } else { + current_flag_value_ = static_cast(flag); + cached_current_flag = current_flag_value_; + } + } + + uint64_t ts_ns = get_attr(this, ts_attr_id_, batch->pkts()[i]); + uint64_t fseid = get_attr(this, fseid_attr_id_, batch->pkts()[i]); + uint32_t pdr = get_attr(this, pdr_attr_id_, batch->pkts()[i]); + // Discard invalid timestamps. + if (!ts_ns || now_ns < ts_ns) { + continue; + } + // Pick current side. + rte_hash *current_hash = nullptr; + std::vector *current_data = nullptr; + switch (cached_current_flag) { + case Flag::FLAG_VALUE_A: + current_hash = table_a_; + current_data = &table_data_a_; + break; + case Flag::FLAG_VALUE_B: + current_hash = table_b_; + current_data = &table_data_b_; + break; + default: + LOG_EVERY_N(ERROR, 100'001) + << "Unknown flag value: " << Flag_Name(cached_current_flag) << "."; + continue; + } + // Find or create session. + TableKey key(fseid, pdr); + int32_t ret = rte_hash_lookup(current_hash, &key); + if (ret == -ENOENT) { + ret = rte_hash_add_key(current_hash, &key); + } + if (ret < 0) { + LOG(ERROR) << "Failed to lookup or insert session stats for key " + << key.ToString() << ": " << ret << ", " << rte_strerror(-ret); + continue; + } + // Update stats. + SessionStats &stat = current_data->at(ret); + const std::lock_guard lock(stat.mutex); + uint64_t diff_ns = now_ns - ts_ns; + if (stat.last_latency == 0) { + stat.last_latency = diff_ns; + } + uint64_t jitter_ns = absdiff(stat.last_latency, diff_ns); + stat.last_latency = diff_ns; + stat.latency_histogram.Insert(diff_ns); + stat.jitter_histogram.Insert(jitter_ns); + stat.pkt_count += 1; + stat.byte_count += batch->pkts()[i]->total_len(); + } + + RunNextModule(ctx, batch); +} +/*----------------------------------------------------------------------------------*/ +CommandResponse FlowMeasure::CommandReadStats( + const bess::pb::FlowMeasureCommandReadArg &arg) { + Flag flag_to_read = static_cast(arg.flag_to_read()); + if (!Flag_IsValid(flag_to_read)) { + return CommandFailure(EINVAL, "invalid flag value"); + } + // Cache current flag so we don't block the dataplane while reading the stats. + Flag cached_current_flag; + { + const std::lock_guard lock(flag_mutex_); + cached_current_flag = current_flag_value_; + } + VLOG(1) << name() << ": " << (leader_ ? "leader" : "follower") + << " last saw buffer flag " << Flag_Name(cached_current_flag) + << ", now reading from " << Flag_Name(flag_to_read); + VLOG_IF(1, cached_current_flag == flag_to_read) + << name() + << ": requested to read active buffer flag. Either there is no " + "traffic or the controller is performing invalid requests."; + + bess::pb::FlowMeasureReadResponse resp; + auto t_start = std::chrono::high_resolution_clock::now(); + rte_hash *current_hash = nullptr; + std::vector *current_data = nullptr; + switch (flag_to_read) { + case Flag::FLAG_VALUE_INVALID: + return CommandSuccess(resp); // return empty stats when no traffic + case Flag::FLAG_VALUE_A: + current_hash = table_a_; + current_data = &table_data_a_; + break; + case Flag::FLAG_VALUE_B: + current_hash = table_b_; + current_data = &table_data_b_; + break; + default: + return CommandFailure(EINVAL, "invalid flag value"); + } + const void *key = nullptr; + void *data = nullptr; + uint32_t next = 0; + int32_t ret = 0; + while (ret = rte_hash_iterate(current_hash, &key, &data, &next), ret >= 0) { + const TableKey *table_key = reinterpret_cast(key); + const SessionStats &session_stat = current_data->at(ret); + const std::lock_guard lock(session_stat.mutex); + const std::vector lat_percs(arg.latency_percentiles().begin(), + arg.latency_percentiles().end()); + const std::vector jitter_percs(arg.jitter_percentiles().begin(), + arg.jitter_percentiles().end()); + const auto lat_summary = + session_stat.latency_histogram.Summarize(lat_percs); + const auto jitter_summary = + session_stat.jitter_histogram.Summarize(jitter_percs); + bess::pb::FlowMeasureReadResponse::Statistic stat; + stat.set_fseid(table_key->fseid); + stat.set_pdr(table_key->pdr); + for (const auto &lat_perc : lat_summary.percentile_values) { + stat.mutable_latency()->add_percentile_values_ns(lat_perc); + } + for (const auto &jitter_perc : jitter_summary.percentile_values) { + stat.mutable_jitter()->add_percentile_values_ns(jitter_perc); + } + stat.set_total_packets(session_stat.pkt_count); + stat.set_total_bytes(session_stat.byte_count); + *resp.add_statistics() = stat; + } + + if (arg.clear()) { + VLOG(1) << name() << ": starting hash table clear..."; + rte_hash_reset(current_hash); + // TODO: this is quite slow + VLOG(1) << name() << ": hash table clear done, clearing table data..."; + for (auto &stat : *current_data) { + const std::lock_guard lock(stat.mutex); + stat.reset(); + } + VLOG(1) << name() << ": table data clear done."; + } + + auto t_done = std::chrono::high_resolution_clock::now(); + if (VLOG_IS_ON(1)) { + std::chrono::duration diff = t_done - t_start; + VLOG(1) << name() << ": CommandReadStats took " << diff.count() << "s."; + } + + return CommandSuccess(resp); +} + +CommandResponse FlowMeasure::CommandFlipFlag( + const bess::pb::FlowMeasureCommandFlipArg &) { + // Can only flip the flag if leader module. + if (!leader_) { + return CommandFailure(EINVAL, "only leaders can flip the flag"); + } + // Cache flags so we block the dataplane as short as possible. + Flag cached_old_flag, cached_current_flag; + { + const std::lock_guard lock(flag_mutex_); + cached_old_flag = current_flag_value_; + current_flag_value_ = current_flag_value_ == Flag::FLAG_VALUE_A + ? Flag::FLAG_VALUE_B + : Flag::FLAG_VALUE_A; + cached_current_flag = current_flag_value_; + } + VLOG(1) << name() << ": leader flipped the buffer flag to " + << Flag_Name(cached_current_flag); + bess::pb::FlowMeasureFlipResponse resp; + resp.set_old_flag(static_cast(cached_old_flag)); + // Wait for pipeline to flush packets with old flag value. + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + + return CommandSuccess(resp); +} + +void FlowMeasure::DeInit() { + rte_hash_free(table_a_); + rte_hash_free(table_b_); +} + +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(FlowMeasure, "qos_measure", "Measures QoS metrics") diff --git a/core/modules/flow_measure.h b/core/modules/flow_measure.h new file mode 100644 index 0000000000..aca587cabe --- /dev/null +++ b/core/modules/flow_measure.h @@ -0,0 +1,128 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2021 Open Networking Foundation + */ + +#ifndef BESS_MODULES_QOS_MEASURE_H_ +#define BESS_MODULES_QOS_MEASURE_H_ + +#include + +#include + +#include "../core/utils/histogram.h" +#include "../module.h" + +class FlowMeasure final : public Module { + public: + FlowMeasure() + : leader_(false), + current_flag_value_(), + table_a_(nullptr), + table_b_(nullptr), + ts_attr_id_(-1), + fseid_attr_id_(-1), + pdr_attr_id_(-1) { + // Multi-writer support is not enabled on the hash maps. + max_allowed_workers_ = 1; + } + + static constexpr uint32_t kDefaultNumEntries = 1 << 15; + static const Commands cmds; + CommandResponse Init(const bess::pb::FlowMeasureArg &arg); + void DeInit() override; + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + std::string GetDesc() const override { return ""; }; + CommandResponse CommandReadStats( + const bess::pb::FlowMeasureCommandReadArg &arg); + CommandResponse CommandFlipFlag( + const bess::pb::FlowMeasureCommandFlipArg &arg); + + private: + // Flag represents a collection of possible values to select buffer sides. + enum class Flag { + FLAG_VALUE_INVALID = 0, + FLAG_VALUE_A, + FLAG_VALUE_B, + FLAG_VALUE_MAX = FLAG_VALUE_B, + }; + + template + static constexpr bool Flag_IsValid(T value) { + Flag flag = static_cast(value); + return flag > Flag::FLAG_VALUE_INVALID && flag <= Flag::FLAG_VALUE_MAX; + } + + static const std::string Flag_Name(const Flag &flag) { + switch (flag) { + case Flag::FLAG_VALUE_INVALID: + return "FLAG_VALUE_INVALID"; + case Flag::FLAG_VALUE_A: + return "FLAG_VALUE_A"; + case Flag::FLAG_VALUE_B: + return "FLAG_VALUE_B"; + default: + return ""; + } + } + + // TableKey encapsulates all information used to identify a flow and is used + // as the lookup key in the hash tables. It is packed and aligned to + // calculating a hash over the raw bytes of the struct is ok. + struct __attribute__((packed, aligned(16))) TableKey { + uint64_t fseid; + uint64_t pdr; + TableKey(uint64_t fseid, uint64_t pdr) : fseid(fseid), pdr(pdr) {} + TableKey() : fseid(0), pdr(0) {} + std::string ToString() const { + std::stringstream ss; + ss << "{ fseid: " << fseid << ", pdr: " << pdr + " }"; + return ss.str(); + } + }; + static_assert(std::is_trivially_copyable::value, + "TableKey must be is_trivially_copyable."); + + // SessionStats ... + struct SessionStats { + uint64_t pkt_count; + uint64_t byte_count; + uint64_t last_latency; + Histogram latency_histogram; + Histogram jitter_histogram; + mutable std::mutex mutex; + static constexpr uint64_t kBucketWidthNs = 1000; // accuracy: 1 us + static constexpr uint64_t kNumBuckets = 100; // range: 0 - 100 us + SessionStats() + : pkt_count(0), + byte_count(0), + last_latency(0), + latency_histogram(kNumBuckets, kBucketWidthNs), + jitter_histogram(kNumBuckets, kBucketWidthNs) {} + // Move allowed, copy not allowed. + SessionStats(const SessionStats &) = delete; + SessionStats(SessionStats &&) noexcept = default; + SessionStats &operator=(const SessionStats &) = delete; + SessionStats &operator=(SessionStats &&) = default; + void reset() { + pkt_count = 0; + byte_count = 0; + last_latency = 0; + latency_histogram.Reset(); + jitter_histogram.Reset(); + } + }; + bool leader_; + Flag current_flag_value_; // protected by flag_mutex_ + mutable std::mutex flag_mutex_; + rte_hash *table_a_; + rte_hash *table_b_; + std::vector table_data_a_; + std::vector table_data_b_; + int ts_attr_id_; + int fseid_attr_id_; + int pdr_attr_id_; + int buffer_flag_attr_id_; +}; + +#endif // BESS_MODULES_QOS_MEASURE_H_ diff --git a/core/modules/gtpu_decap.cc b/core/modules/gtpu_decap.cc new file mode 100644 index 0000000000..044578c89f --- /dev/null +++ b/core/modules/gtpu_decap.cc @@ -0,0 +1,51 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +/* for gtpu_decap decls */ +#include "gtpu_decap.h" +/* for rte_zmalloc() */ +#include +/* for IPVERSION */ +#include +/* for be32_t */ +#include "utils/endian.h" +/* for ToIpv4Address() */ +#include "utils/ip.h" +/* for Ethernet header */ +#include "utils/ether.h" +/* for udp header */ +#include "utils/udp.h" +/* for gtp header */ +#include "utils/gtp.h" +/* for GetDesc() */ +#include "utils/format.h" +#include +/*----------------------------------------------------------------------------------*/ +using bess::utils::Ethernet; +using bess::utils::Gtpv1; +using bess::utils::Ipv4; +using bess::utils::Udp; +/*----------------------------------------------------------------------------------*/ +void GtpuDecap::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + int cnt = batch->cnt(); + + for (int i = 0; i < cnt; i++) { + bess::Packet *p = batch->pkts()[i]; + /* Trim iph->ihl<<2 + sizeof(Udp) + size of Gtpv1 header + */ + Ethernet *eth = p->head_data(); + Ipv4 *iph = (Ipv4 *)((uint8_t *)eth + sizeof(*eth)); + Gtpv1 *gtph = + (Gtpv1 *)((uint8_t *)iph + (iph->header_length << 2) + sizeof(Udp)); + // Don't swap lines 44 with 42, otherwise gtph->header_length() + // gets overwritten by ethh!! + auto *new_p = batch->pkts()[i]->adj((iph->header_length << 2) + + sizeof(Udp) + gtph->header_length()); + memcpy(new_p, eth, sizeof(*eth)); + } + + RunNextModule(ctx, batch); +} +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(GtpuDecap, "gtpu_decap", "first version of gtpu decap module") diff --git a/core/modules/gtpu_decap.h b/core/modules/gtpu_decap.h new file mode 100644 index 0000000000..1406486795 --- /dev/null +++ b/core/modules/gtpu_decap.h @@ -0,0 +1,19 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +#ifndef BESS_MODULES_GTPUDECAP_H_ +#define BESS_MODULES_GTPUDECAP_H_ +/*----------------------------------------------------------------------------------*/ +#include "../module.h" +#include "../pb/module_msg.pb.h" +#include +/*----------------------------------------------------------------------------------*/ +class GtpuDecap final : public Module { + public: + GtpuDecap() { max_allowed_workers_ = Worker::kMaxWorkers; } + + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; +}; +/*----------------------------------------------------------------------------------*/ +#endif // BESS_MODULES_GTPUDECAP_H_ diff --git a/core/modules/gtpu_echo.cc b/core/modules/gtpu_echo.cc new file mode 100644 index 0000000000..dd01c7a733 --- /dev/null +++ b/core/modules/gtpu_echo.cc @@ -0,0 +1,97 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +/* for gtpu_echo decls */ +#include "gtpu_echo.h" +/* for rte_zmalloc() */ +#include +/* for IPVERSION */ +#include +/* for be32_t */ +#include "utils/endian.h" +/* for ToIpv4Address() */ +#include "utils/ip.h" +/* for udp header */ +#include "utils/udp.h" +/* for gtp header */ +#include "utils/gtp.h" +/* for eth header */ +#include "utils/ether.h" +/*----------------------------------------------------------------------------------*/ +using bess::utils::be16_t; +using bess::utils::be32_t; +using bess::utils::Ethernet; +using bess::utils::Gtpv1; +using bess::utils::Ipv4; +using bess::utils::ToIpv4Address; +using bess::utils::Udp; + +enum { DEFAULT_GATE = 0, FORWARD_GATE }; +/*----------------------------------------------------------------------------------*/ +bool GtpuEcho::process_echo_request(bess::Packet *p) { + Ethernet *eth = p->head_data(); + Ipv4 *iph = (Ipv4 *)((unsigned char *)eth + sizeof(Ethernet)); + Udp *udp = (Udp *)((unsigned char *)iph + (iph->header_length << 2)); + Gtpv1 *gtph = (Gtpv1 *)((unsigned char *)udp + sizeof(Udp)); + struct gtpu_recovery_ie_t *recovery_ie = NULL; + + /* re-use space (if available) left in Ethernet padding for recovery_ie */ + if ((p->total_len() - (sizeof(Ethernet) + iph->length.value())) > + sizeof(struct gtpu_recovery_ie_t)) { + recovery_ie = (struct gtpu_recovery_ie_t *)((char *)gtph + sizeof(Gtpv1) + + gtph->length.value()); + } else { + /* otherwise prepend payload to the frame */ + recovery_ie = (struct gtpu_recovery_ie_t *)p->append( + sizeof(struct gtpu_recovery_ie_t)); + if (recovery_ie == NULL) { + LOG(WARNING) << "Couldn't append " << sizeof(struct gtpu_recovery_ie_t) + << " bytes to mbuf"; + return false; + } + } + + gtph->type = GTPU_ECHO_RESPONSE; + gtph->length = + be16_t(gtph->length.value() + sizeof(struct gtpu_recovery_ie_t)); + recovery_ie->type = GTPU_ECHO_RECOVERY; + recovery_ie->restart_cntr = 0; + + /* Swap src and dest IP addresses */ + std::swap(iph->src, iph->dst); + iph->length = be16_t(iph->length.value() + sizeof(struct gtpu_recovery_ie_t)); + /* Reset checksum. This will be computed by next module in line */ + iph->checksum = 0; + + /* Swap src and dst UDP ports */ + std::swap(udp->src_port, udp->dst_port); + udp->length = be16_t(udp->length.value() + sizeof(struct gtpu_recovery_ie_t)); + /* Reset checksum. This will be computed by next module in line */ + udp->checksum = 0; + return true; +} +/*----------------------------------------------------------------------------------*/ +void GtpuEcho::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + int cnt = batch->cnt(); + for (int i = 0; i < cnt; i++) { + bess::Packet *p = batch->pkts()[i]; + + EmitPacket(ctx, p, (process_echo_request(p)) ? FORWARD_GATE : DEFAULT_GATE); + } +} +/*----------------------------------------------------------------------------------*/ +void GtpuEcho::DeInit() { + /* do nothing */ +} +/*----------------------------------------------------------------------------------*/ +CommandResponse GtpuEcho::Init(const bess::pb::GtpuEchoArg &arg) { + s1u_sgw_ip = arg.s1u_sgw_ip(); + + if (s1u_sgw_ip == 0) + return CommandFailure(EINVAL, "Invalid S1U SGW IP address!"); + + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(GtpuEcho, "gtpu_echo", "first version of gtpu echo module") diff --git a/core/modules/gtpu_echo.h b/core/modules/gtpu_echo.h new file mode 100644 index 0000000000..2aa39b1840 --- /dev/null +++ b/core/modules/gtpu_echo.h @@ -0,0 +1,50 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +#ifndef BESS_MODULES_GTPUECHO_H_ +#define BESS_MODULES_GTPUECHO_H_ +/*----------------------------------------------------------------------------------*/ +#include "../module.h" +#include "../pb/module_msg.pb.h" +/*----------------------------------------------------------------------------------*/ +/** + * GTPU header + */ +#define GTPU_VERSION 0x01 +#define GTP_PROTOCOL_TYPE_GTP 0x01 +#define GTP_GPDU 0xff +#define GTPU_ECHO_RECOVERY 14 +#define GTPU_ECHO_REQUEST 0x01 +#define GTPU_ECHO_RESPONSE 0x02 + +/** + * UDP header + */ +#define UDP_PORT_GTPU 2152 +/*----------------------------------------------------------------------------------*/ +/** + * GTPU-Recovery Information Element + */ +typedef struct gtpu_recovery_ie_t { + uint8_t type; + uint8_t restart_cntr; +} gtpu_recovery_ie; +/*----------------------------------------------------------------------------------*/ +class GtpuEcho final : public Module { + public: + GtpuEcho() { max_allowed_workers_ = Worker::kMaxWorkers; } + + /* Gates: (0) Default, (1) Forward */ + static const gate_idx_t kNumOGates = 2; + + CommandResponse Init(const bess::pb::GtpuEchoArg &arg); + void DeInit() override; + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + + private: + bool process_echo_request(bess::Packet *p); + uint32_t s1u_sgw_ip = 0; /* S1U IP address */ +}; +/*----------------------------------------------------------------------------------*/ +#endif // BESS_MODULES_GTPUECHO_H_ diff --git a/core/modules/gtpu_encap.cc b/core/modules/gtpu_encap.cc new file mode 100644 index 0000000000..e36ad23d85 --- /dev/null +++ b/core/modules/gtpu_encap.cc @@ -0,0 +1,215 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +/* for gtpu_encap decls */ +#include "gtpu_encap.h" +/* for rte_zmalloc() */ +#include +/* for IPVERSION */ +#include +/* for be32_t */ +#include "utils/endian.h" +/* for ToIpv4Address() */ +#include "utils/ip.h" +/* for udp header */ +#include "utils/udp.h" +/* for ethernet header */ +#include "utils/ether.h" +/* for gtp header */ +#include "utils/gtp.h" +/* for GetDesc() */ +#include "utils/format.h" +#include +/*----------------------------------------------------------------------------------*/ +using bess::utils::be16_t; +using bess::utils::be32_t; +using bess::utils::Ethernet; +using bess::utils::Gtpv1; +using bess::utils::Gtpv1PDUSessExt; +using bess::utils::Gtpv1SeqPDUExt; +using bess::utils::Ipv4; +using bess::utils::ToIpv4Address; +using bess::utils::Udp; + +enum { DEFAULT_GATE = 0, FORWARD_GATE }; +/*----------------------------------------------------------------------------------*/ +// Template for generating UDP packets without data +struct [[gnu::packed]] PacketTemplate { + Ipv4 iph; + Udp udph; + Gtpv1 gtph; + Gtpv1SeqPDUExt speh; + Gtpv1PDUSessExt psch; + + PacketTemplate() { + psch.qfi = 0; // to fill in + psch.spare2 = 0; + psch.spare1 = 0; + psch.pdu_type = 0; // to fill in + psch.hlen = psch.header_length(); + speh.ext = psch.type(); + speh.npdu = 0; + speh.seqnum = (be16_t)0; + gtph.version = GTPU_VERSION; + gtph.pt = GTP_PROTOCOL_TYPE_GTP; + gtph.spare = 0; + gtph.ex = 0; // conditionally set this + gtph.seq = 0; + gtph.pdn = 0; + gtph.type = GTP_GPDU; + gtph.length = (be16_t)0; // to fill in + gtph.teid = (be32_t)0; // to fill in + udph.src_port = (be16_t)UDP_PORT_GTPU; + udph.dst_port = (be16_t)UDP_PORT_GTPU; + udph.length = (be16_t)0; // to fill in + /* calculated by L4Checksum module in line */ + udph.checksum = 0; + iph.version = IPVERSION; + iph.header_length = (sizeof(Ipv4) >> 2); + iph.type_of_service = 0; + iph.length = (be16_t)0; // to fill in + iph.id = (be16_t)0x513; + iph.fragment_offset = (be16_t)0; + iph.ttl = 64; + iph.protocol = IPPROTO_UDP; + /* calculated by IPChecksum module in line */ + iph.checksum = 0; + iph.src = (be32_t)0; // to fill in + iph.dst = (be32_t)0; // to fill in + } +}; +static PacketTemplate outer_ip_template; +/*----------------------------------------------------------------------------------*/ +void GtpuEncap::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + int cnt = batch->cnt(); + + for (int i = 0; i < cnt; i++) { + bess::Packet *p = batch->pkts()[i]; + + /* check attributes' values now */ + uint8_t at_pdu_type; + bess::metadata::mt_offset_t off = attr_offset(pdu_type_attr); + at_pdu_type = get_attr_with_offset(off, p); + + uint8_t at_qfi; + off = attr_offset(qfi_attr); + at_qfi = get_attr_with_offset(off, p); + + uint32_t at_tout_sip; + off = attr_offset(tout_sip_attr); + at_tout_sip = get_attr_with_offset(off, p); + + uint32_t at_tout_dip; + off = attr_offset(tout_dip_attr); + at_tout_dip = get_attr_with_offset(off, p); + + uint32_t at_tout_teid; + off = attr_offset(tout_teid); + at_tout_teid = get_attr_with_offset(off, p); + + uint16_t at_tout_uport; + off = attr_offset(tout_uport); + at_tout_uport = get_attr_with_offset(off, p); + + /* checking values now */ + DLOG(INFO) << "pdu type: " << static_cast(at_pdu_type) + << ", tunnel qfi: " << at_qfi + << ", tunnel out sip: " << at_tout_sip + << ", tunnel out dip: " << at_tout_dip + << ", tunnel out teid: " << at_tout_teid + << ", tunnel out udp port: " << at_tout_uport << std::endl; + + uint16_t pkt_len = p->total_len() - sizeof(Ethernet); + Ethernet *eth = p->head_data(); + + /* get Type of Service from IP packet */ + Ipv4 *iphIn = (Ipv4 *)((unsigned char *)eth + sizeof(Ethernet)); + uint8_t type_of_service = iphIn->type_of_service; + + /* pre-allocate space for encaped header(s) */ + char *new_p = static_cast(p->prepend(encap_size)); + if (new_p == NULL) { + /* failed to prepend header space for encaped packet */ + EmitPacket(ctx, p, DEFAULT_GATE); + DLOG(INFO) << "prepend() failed!" << std::endl; + continue; + } + + /* setting Ethernet header */ + memcpy(new_p, eth, sizeof(Ethernet)); + + /* get pointers to header offsets */ + Ipv4 *iph = (Ipv4 *)(new_p + sizeof(Ethernet)); + + Udp *udph = (Udp *)(new_p + sizeof(Ethernet) + sizeof(Ipv4)); + + Gtpv1 *gtph = (Gtpv1 *)((uint8_t *)iph + offsetof(PacketTemplate, gtph)); + + Gtpv1PDUSessExt *psch = + (Gtpv1PDUSessExt *)((uint8_t *)iph + offsetof(PacketTemplate, psch)); + + /* copying template content */ + bess::utils::Copy(iph, &outer_ip_template, encap_size); + + /* setting gtp psc extension header*/ + if (add_psc) { + gtph->ex = 1; + psch->qfi = at_qfi; + psch->pdu_type = at_pdu_type; + } + + /* calculate lengths */ + uint16_t gtplen = + pkt_len + encap_size - sizeof(Gtpv1) - sizeof(Udp) - sizeof(Ipv4); + uint16_t udplen = gtplen + sizeof(Gtpv1) + sizeof(Udp); + uint16_t iplen = udplen + sizeof(Ipv4); + + /* setting gtpu header */ + gtph->length = (be16_t)(gtplen); + gtph->teid = (be32_t)(at_tout_teid); + + /* setting outer UDP header */ + udph->length = (be16_t)(udplen); + udph->src_port = udph->dst_port = (be16_t)(at_tout_uport); + + /* setting outer IP header */ + iph->length = (be16_t)(iplen); + iph->src = (be32_t)(at_tout_sip); + iph->dst = (be32_t)(at_tout_dip); + iph->type_of_service = type_of_service; + + EmitPacket(ctx, p, FORWARD_GATE); + } +} +/*----------------------------------------------------------------------------------*/ +CommandResponse GtpuEncap::Init(const bess::pb::GtpuEncapArg &arg) { + add_psc = arg.add_psc(); + if (add_psc) + encap_size = sizeof(outer_ip_template); + else + encap_size = sizeof(outer_ip_template) - sizeof(Gtpv1SeqPDUExt) - + sizeof(Gtpv1SeqPDUExt); + + using AccessMode = bess::metadata::Attribute::AccessMode; + pdu_type_attr = AddMetadataAttr("action", sizeof(uint8_t), AccessMode::kRead); + DLOG(INFO) << "tout_sip_attr: " << tout_sip_attr << std::endl; + tout_sip_attr = AddMetadataAttr("tunnel_out_src_ip4addr", sizeof(uint32_t), + AccessMode::kRead); + DLOG(INFO) << "tout_sip_attr: " << tout_sip_attr << std::endl; + tout_dip_attr = AddMetadataAttr("tunnel_out_dst_ip4addr", sizeof(uint32_t), + AccessMode::kRead); + DLOG(INFO) << "tout_dip_attr: " << tout_dip_attr << std::endl; + tout_teid = + AddMetadataAttr("tunnel_out_teid", sizeof(uint32_t), AccessMode::kRead); + DLOG(INFO) << "tout_teid: " << tout_teid << std::endl; + tout_uport = AddMetadataAttr("tunnel_out_udp_port", sizeof(uint16_t), + AccessMode::kRead); + DLOG(INFO) << "tout_uport: " << tout_uport << std::endl; + qfi_attr = AddMetadataAttr("qfi", sizeof(uint8_t), AccessMode::kRead); + DLOG(INFO) << "qfi_attr: " << qfi_attr << std::endl; + + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(GtpuEncap, "gtpu_encap", "first version of gtpu encap module") diff --git a/core/modules/gtpu_encap.h b/core/modules/gtpu_encap.h new file mode 100644 index 0000000000..9bf6c11531 --- /dev/null +++ b/core/modules/gtpu_encap.h @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +#ifndef BESS_MODULES_GTPUENCAP_H_ +#define BESS_MODULES_GTPUENCAP_H_ +/*----------------------------------------------------------------------------------*/ +#include "../module.h" +#include "../pb/module_msg.pb.h" +#include +/*----------------------------------------------------------------------------------*/ +/** + * GTPU header + */ +#define GTPU_VERSION 0x01 +#define GTP_PROTOCOL_TYPE_GTP 0x01 +#define GTP_GPDU 0xff + +/** + * UDP header + */ +#define UDP_PORT_GTPU 2152 +/*----------------------------------------------------------------------------------*/ +class GtpuEncap final : public Module { + public: + GtpuEncap() { max_allowed_workers_ = Worker::kMaxWorkers; } + + /* Gates: (0) Default, (1) Forward */ + static const gate_idx_t kNumOGates = 2; + + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + CommandResponse Init(const bess::pb::GtpuEncapArg &arg); + + private: + bool add_psc; + int encap_size; + int pdu_type_attr = -1; + int qfi_attr = -1; + int tout_sip_attr = -1; + int tout_dip_attr = -1; + int tout_teid = -1; + int tout_uport = -1; +}; +/*----------------------------------------------------------------------------------*/ +#endif // BESS_MODULES_GTPUENCAP_H_ diff --git a/core/modules/gtpu_parser.cc b/core/modules/gtpu_parser.cc new file mode 100644 index 0000000000..3e6d2c6cda --- /dev/null +++ b/core/modules/gtpu_parser.cc @@ -0,0 +1,131 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +/* for GTP parser */ +#include "gtpu_parser.h" +/* for ethernet header */ +#include "utils/ether.h" +/* for ip header */ +#include "utils/ip.h" +/* for udp header */ +#include "utils/udp.h" +/* for tcp header */ +#include "utils/tcp.h" +/* for gtp header */ +#include "utils/gtp.h" +/*----------------------------------------------------------------------------------*/ +using bess::utils::Ethernet; +using bess::utils::Gtpv1; +using bess::utils::Ipv4; +using bess::utils::Tcp; +using bess::utils::Udp; + +enum { DEFAULT_GATE = 0, FORWARD_GATE }; +const unsigned short UDP_PORT_GTPU = 2152; +/*----------------------------------------------------------------------------------*/ +void GtpuParser::set_gtp_parsing_attrs(be32_t *sip, be32_t *dip, be16_t *sp, + be16_t *dp, be32_t *teid, be32_t *tipd, + uint8_t *protoid, bess::Packet *p) { + /* set src_ip */ + set_attr(this, src_ip_id, p, sip->raw_value()); + /* set dst_ip */ + set_attr(this, dst_ip_id, p, dip->raw_value()); + /* set src_port_id */ + set_attr(this, src_port_id, p, sp->raw_value()); + /* set dst_port_id */ + set_attr(this, dst_port_id, p, dp->raw_value()); + /* set tied_id */ + set_attr(this, teid_id, p, teid->raw_value()); + /* tunnel_ip4_dst_id */ + set_attr(this, tunnel_ip4_dst_id, p, tipd->raw_value()); + /* proto_id */ + set_attr(this, proto_id, p, *protoid); +} +/*----------------------------------------------------------------------------------*/ +void GtpuParser::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + int cnt = batch->cnt(); + Tcp *tcph = NULL; + Udp *udph = NULL; + Gtpv1 *gtph = NULL; + Ipv4 *iph = NULL; + Ethernet *eth = NULL; + static const uint32_t _const_val = 0xFFFFFFFFu; + + for (int i = 0; i < cnt; i++) { + bess::Packet *p = batch->pkts()[i]; + eth = p->head_data(); + if (eth->ether_type != (be16_t)(Ethernet::kIpv4) && + eth->ether_type != (be16_t)(Ethernet::kArp)) { + EmitPacket(ctx, p, DEFAULT_GATE); + continue; + } + + iph = (Ipv4 *)(eth + 1); + switch (iph->protocol) { + case Ipv4::kTcp: + tcph = (Tcp *)((char *)iph + (iph->header_length << 2)); + set_gtp_parsing_attrs(&iph->src, &iph->dst, &tcph->src_port, + &tcph->dst_port, (be32_t *)&_const_val, + (be32_t *)&_const_val, &iph->protocol, p); + break; + case Ipv4::kUdp: + udph = (Udp *)((char *)iph + (iph->header_length << 2)); + if (udph->dst_port == (be16_t)(UDP_PORT_GTPU)) { + Ipv4 *old_iph = iph; + gtph = (Gtpv1 *)(udph + 1); + be32_t teid = (be32_t)gtph->teid.value(); + /* reuse iph, tcph, and udph for innser headers too */ + iph = (Ipv4 *)((char *)gtph + gtph->header_length()); + if (iph->protocol == Ipv4::kTcp) { + tcph = (Tcp *)((char *)iph + (iph->header_length << 2)); + set_gtp_parsing_attrs(&iph->src, &iph->dst, &tcph->src_port, + &tcph->dst_port, (be32_t *)&teid, + &old_iph->dst, &iph->protocol, p); + } else if (iph->protocol == Ipv4::kUdp) { + udph = (Udp *)((char *)iph + (iph->header_length << 2)); + set_gtp_parsing_attrs(&iph->src, &iph->dst, &udph->src_port, + &udph->dst_port, (be32_t *)&teid, + &old_iph->dst, &iph->protocol, p); + } else { + set_gtp_parsing_attrs(&iph->src, &iph->dst, (be16_t *)&_const_val, + (be16_t *)&_const_val, (be32_t *)&teid, + &old_iph->dst, &iph->protocol, p); + } + } else { + set_gtp_parsing_attrs(&iph->src, &iph->dst, &udph->src_port, + &udph->dst_port, (be32_t *)&_const_val, + (be32_t *)&_const_val, &iph->protocol, p); + } + break; + case Ipv4::kIcmp: { + set_gtp_parsing_attrs(&iph->src, &iph->dst, (be16_t *)&_const_val, + (be16_t *)&_const_val, (be32_t *)&_const_val, + (be32_t *)&_const_val, &iph->protocol, p); + } break; + default: + /* nothing here at the moment */ + break; + } + + EmitPacket(ctx, p, FORWARD_GATE); + } +} +/*----------------------------------------------------------------------------------*/ +CommandResponse GtpuParser::Init(const bess::pb::EmptyArg &) { + using AccessMode = bess::metadata::Attribute::AccessMode; + src_ip_id = AddMetadataAttr("src_ip", sizeof(uint32_t), AccessMode::kWrite); + dst_ip_id = AddMetadataAttr("dst_ip", sizeof(uint32_t), AccessMode::kWrite); + src_port_id = + AddMetadataAttr("src_port", sizeof(uint16_t), AccessMode::kWrite); + dst_port_id = + AddMetadataAttr("dst_port", sizeof(uint16_t), AccessMode::kWrite); + teid_id = AddMetadataAttr("teid", sizeof(uint32_t), AccessMode::kWrite); + tunnel_ip4_dst_id = + AddMetadataAttr("tunnel_ipv4_dst", sizeof(uint32_t), AccessMode::kWrite); + proto_id = AddMetadataAttr("ip_proto", sizeof(uint8_t), AccessMode::kWrite); + + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(GtpuParser, "gtpu_parser", "parsing module for gtp traffic") diff --git a/core/modules/gtpu_parser.h b/core/modules/gtpu_parser.h new file mode 100644 index 0000000000..e8e9534c8a --- /dev/null +++ b/core/modules/gtpu_parser.h @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +#ifndef BESS_MODULES_GTPUPARSER_H_ +#define BESS_MODULES_GTPUPARSER_H_ +/*----------------------------------------------------------------------------------*/ +#include "../module.h" +/* for endian types */ +#include "utils/endian.h" +using bess::utils::be16_t; +using bess::utils::be32_t; +/*----------------------------------------------------------------------------------*/ +/** + * EPC Metadata + */ +typedef struct EpcMetadata { + be16_t l4_sport; + be16_t l4_dport; + be16_t inner_l4_sport; + be16_t inner_l4_dport; + be32_t teid; +} EpcMetadata; +/*----------------------------------------------------------------------------------*/ +class GtpuParser final : public Module { + public: + GtpuParser() { max_allowed_workers_ = Worker::kMaxWorkers; } + + /* Gates: (0) Default, (1) Forward */ + static const gate_idx_t kNumOGates = 2; + CommandResponse Init(const bess::pb::EmptyArg &); + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + + private: + /* set attributes */ + void set_gtp_parsing_attrs(be32_t *sip, be32_t *dip, be16_t *sp, be16_t *dp, + be32_t *teid, be32_t *tipd, uint8_t *protoid, + bess::Packet *p); + int src_ip_id = -1; + int dst_ip_id = -1; + int src_port_id = -1; + int dst_port_id = -1; + int teid_id = -1; + int tunnel_ip4_dst_id = -1; + int proto_id = -1; +}; +/*----------------------------------------------------------------------------------*/ +#endif // BESS_MODULES_GTPUPARSER_H_ diff --git a/core/modules/ip_defrag.cc b/core/modules/ip_defrag.cc new file mode 100644 index 0000000000..e0c893b658 --- /dev/null +++ b/core/modules/ip_defrag.cc @@ -0,0 +1,132 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +/* for ip_defrag decls */ +#include "ip_defrag.h" +/* for rte_zmalloc() */ +#include +/* for be32_t */ +#include "utils/endian.h" +/* for ToIpv4Address() */ +#include "utils/ip.h" +/* for CalculateIpv4Checksum() */ +#include "utils/checksum.h" +/* for eth header */ +#include "utils/ether.h" +/*----------------------------------------------------------------------------------*/ +using bess::utils::be16_t; +using bess::utils::be32_t; +using bess::utils::Ethernet; +using bess::utils::Ipv4; +using bess::utils::ToIpv4Address; + +#define PREFETCH_OFFSET 8 +#define IP_FRAG_TBL_BUCKET_ENTRIES 16 +enum { DEFAULT_GATE = 0, FORWARD_GATE }; +/*----------------------------------------------------------------------------------*/ +/** + * Returns NULL if packet is fragmented and needs more for reassembly. + * Returns Packet ptr if the packet is unfragmented, or is freshly reassembled. + */ +bess::Packet *IPDefrag::IPReassemble(Context *ctx, bess::Packet *p) { + Ethernet *eth = p->head_data(); + if (eth->ether_type != (be16_t)(Ethernet::kIpv4)) + return p; + Ipv4 *iph = (Ipv4 *)((unsigned char *)eth + sizeof(Ethernet)); + + if (rte_ipv4_frag_pkt_is_fragmented((struct rte_ipv4_hdr *)iph)) { + struct rte_mbuf *mo, *m; + struct rte_ipv4_hdr *ip; + + /* prepare mbuf: setup l2_len/l3_len */ + m = reinterpret_cast(p); + ip = reinterpret_cast(iph); + m->l2_len = sizeof(*eth); + m->l3_len = sizeof(*iph); + + /* process this fragment */ + mo = rte_ipv4_frag_reassemble_packet(ift, &ifdr, m, cur_tsc, ip); + if (mo == NULL) { + /* no packet to process just yet */ + p = NULL; + return p; + } + /* we have our packet reassembled */ + if (mo != m) { + /* move mbuf data in the first segment */ + if (rte_pktmbuf_linearize(mo) == 0) { + p = reinterpret_cast(mo); + eth = p->head_data(); + iph = (Ipv4 *)((unsigned char *)eth + sizeof(Ethernet)); + } else { + DLOG(INFO) << "Failed to linearize rte_mbuf. " + << "Is there enough tail room?" << std::endl; + EmitPacket(ctx, p, DEFAULT_GATE); + return NULL; + } + } + } + + // Recalculate checksum + iph->checksum = 0; + iph->checksum = CalculateIpv4Checksum(*iph); + + return p; +} +/*----------------------------------------------------------------------------------*/ +void IPDefrag::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + /* retire outdated frags (if needed) */ + if (ifdr.cnt != 0) + rte_ip_frag_free_death_row(&ifdr, PREFETCH_OFFSET); + cur_tsc = rte_rdtsc(); + + int cnt = batch->cnt(); + for (int i = 0; i < cnt; i++) { + bess::Packet *p = batch->pkts()[i]; + p = IPReassemble(ctx, p); + if (p) + EmitPacket(ctx, p, FORWARD_GATE); + } +} +/*----------------------------------------------------------------------------------*/ +void IPDefrag::DeInit() { + if (ift != NULL) { + /* free allocated IP frags */ + rte_ip_frag_table_destroy(ift); + ift = NULL; + } +} +/*----------------------------------------------------------------------------------*/ +CommandResponse IPDefrag::Init(const bess::pb::IPDefragArg &arg) { + num_flows = arg.num_flows(); + + if (num_flows <= 0) + return CommandFailure(EINVAL, "Invalid num_flows!"); + + numa = arg.numa(); + + defrag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * num_flows; + + cur_tsc = 0; + + ift = rte_ip_frag_table_create(num_flows, IP_FRAG_TBL_BUCKET_ENTRIES, + num_flows * IP_FRAG_TBL_BUCKET_ENTRIES, + defrag_cycles, numa); + if (ift == NULL) { + std::cerr << "Could not allocate memory for reassembly table " + << "for NUMA node " << numa << ". Trying SOCKET_ID_ANY..."; + ift = rte_ip_frag_table_create(num_flows, IP_FRAG_TBL_BUCKET_ENTRIES, + num_flows * IP_FRAG_TBL_BUCKET_ENTRIES, + defrag_cycles, SOCKET_ID_ANY); + if (ift == NULL) + return CommandFailure(ENOMEM, + "SOCKET_ID_ANY memory allocation failed." + "Can't allocate memory for reassembly table!"); + } + + ifdr.cnt = 0; + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(IPDefrag, "ip_defrag", "IP Reassembly module") diff --git a/core/modules/ip_defrag.h b/core/modules/ip_defrag.h new file mode 100644 index 0000000000..3abc601d77 --- /dev/null +++ b/core/modules/ip_defrag.h @@ -0,0 +1,43 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +#ifndef BESS_MODULES_IPDEFRAG_H_ +#define BESS_MODULES_IPDEFRAG_H_ +/*----------------------------------------------------------------------------------*/ +#include "../module.h" +#include "../pb/module_msg.pb.h" +#include +#include +/*----------------------------------------------------------------------------------*/ +class IPDefrag final : public Module { + public: + IPDefrag() { max_allowed_workers_ = Worker::kMaxWorkers; } + + /* Gates: (0) Default, (1) Forward */ + static const gate_idx_t kNumOGates = 2; + + CommandResponse Init(const bess::pb::IPDefragArg &arg); + void DeInit() override; + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + + private: + bess::Packet *IPReassemble(Context *ctx, bess::Packet *p); + struct rte_ip_frag_tbl *ift = NULL; /* hold frags for reassembly */ + struct rte_ip_frag_death_row + ifdr; /* for retiring outdated frags (internal bookkeeping) */ + uint64_t cur_tsc; /* for calculating retiring time */ + uint64_t defrag_cycles; + + /** + * Max number of flows to maintain + */ + uint32_t num_flows; + + /** + * NUMA node where mem shall be allocated for IP frags + */ + int32_t numa; +}; +/*----------------------------------------------------------------------------------*/ +#endif // BESS_MODULES_IPDEFRAG_H_ diff --git a/core/modules/ip_frag.cc b/core/modules/ip_frag.cc new file mode 100644 index 0000000000..d7bf160538 --- /dev/null +++ b/core/modules/ip_frag.cc @@ -0,0 +1,191 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2020 Intel Corporation + */ +/* for ip_frag decls */ +#include "ip_frag.h" +/* for rte_zmalloc() */ +#include +/* for be32_t */ +#include "utils/endian.h" +/* for ToIpv4Address() */ +#include "utils/ip.h" +/* for eth header */ +#include "utils/ether.h" +/*----------------------------------------------------------------------------------*/ +using bess::utils::be16_t; +using bess::utils::be32_t; +using bess::utils::Ethernet; +using bess::utils::Ipv4; +using bess::utils::ToIpv4Address; + +enum { DEFAULT_GATE = 0, FORWARD_GATE }; +/*----------------------------------------------------------------------------------*/ +const Commands IPFrag::cmds = {{"get_eth_mtu", "EmptyArg", + MODULE_CMD_FUNC(&IPFrag::GetEthMTU), + Command::THREAD_SAFE}}; +/*----------------------------------------------------------------------------------*/ +/** + * Returns NULL under two conditions: (1) if the packet failed to fragment due + * to e.g., DF bit on and IP4 datagram size > MTU, or (2) if the packet + * successfully fragmented (new mbufs created) and the original IP4 datagram + * needs to be freed up. Returns Packet ptr if the packet size < MTU + */ +bess::Packet *IPFrag::FragmentPkt(Context *ctx, bess::Packet *p) { + struct rte_ether_hdr *ethh = + (struct rte_ether_hdr *)(p->head_data()); + struct rte_ipv4_hdr *iph = + (struct rte_ipv4_hdr *)((unsigned char *)ethh + + sizeof(struct rte_ether_hdr)); + struct rte_mbuf *m = (struct rte_mbuf *)p; + + if (RTE_ETH_IS_IPV4_HDR(m->packet_type) && + unlikely((eth_mtu - RTE_ETHER_CRC_LEN) < p->total_len())) { + volatile int32_t res; + struct rte_ether_hdr ethh_copy; + int32_t j; + struct rte_mbuf *frag_tbl[BATCH_SIZE]; + unsigned char *orig_ip_payload; + uint16_t orig_data_offset; + + /* if the datagram is saying not to fragment (DF), we drop the packet */ + if ((iph->fragment_offset & RTE_IPV4_HDR_DF_FLAG) == RTE_IPV4_HDR_DF_FLAG) { + EmitPacket(ctx, p, DEFAULT_GATE); + return NULL; + } + + /* retrieve Ethernet header */ + rte_memcpy(ðh_copy, ethh, sizeof(struct rte_ether_hdr)); + + /* remove the Ethernet header and trailer from the input packet */ + rte_pktmbuf_adj(m, (uint16_t)sizeof(struct rte_ether_hdr)); + + /* retrieve orig ip payload for later re-use in ip frags */ + orig_ip_payload = rte_pktmbuf_mtod_offset(m, unsigned char *, + sizeof(struct rte_ipv4_hdr)); + orig_data_offset = 0; + + /* fragment the IPV4 packet */ + res = rte_ipv4_fragment_packet( + m, &frag_tbl[0], BATCH_SIZE, + eth_mtu - RTE_ETHER_CRC_LEN - RTE_ETHER_HDR_LEN, m->pool, + indirect_pktmbuf_pool->pool()); + + if (unlikely(res < 0)) { + EmitPacket(ctx, p, DEFAULT_GATE); + return NULL; + } else { + /* now copy the Ethernet header + IP payload to each frag */ + for (j = 0; j < res; j++) { + m = frag_tbl[j]; + ethh = (struct rte_ether_hdr *)rte_pktmbuf_prepend( + m, (uint16_t)sizeof(struct rte_ether_hdr)); + if (ethh == NULL) + rte_panic("No headroom in mbuf.\n"); + /* remove chained mbufs (as they are not needed) */ + struct rte_mbuf *del_mbuf = m->next; + while (del_mbuf != NULL) { + rte_pktmbuf_free_seg(del_mbuf); + del_mbuf = del_mbuf->next; + } + + /* setting mbuf metadata */ + m->l2_len = sizeof(struct rte_ether_hdr); + m->data_len = m->pkt_len; + m->nb_segs = 1; + m->next = NULL; + rte_memcpy(ethh, ðh_copy, sizeof(struct rte_ether_hdr)); + + ethh = + (struct rte_ether_hdr *)rte_pktmbuf_mtod(m, struct rte_ether_hdr *); + iph = (struct rte_ipv4_hdr *)(ethh + 1); + + /* copy ip payload */ + unsigned char *ip_payload = + (unsigned char *)((unsigned char *)iph + + ((iph->version_ihl & RTE_IPV4_HDR_IHL_MASK) + << 2)); + uint16_t ip_payload_len = + m->pkt_len - sizeof(struct rte_ether_hdr) - + ((iph->version_ihl & RTE_IPV4_HDR_IHL_MASK) << 2); + + /* if total frame size is less than minimum transmission unit, add IP + * padding */ + if (unlikely(ip_payload_len + sizeof(struct rte_ipv4_hdr) + + sizeof(struct rte_ether_hdr) + RTE_ETHER_CRC_LEN < + RTE_ETHER_MIN_LEN)) { + /* update ip->ihl first */ + iph->version_ihl &= 0xF0; + iph->version_ihl |= + (RTE_IPV4_HDR_IHL_MASK & (PADDED_IPV4_HDR_SIZE >> 2)); + /* update ip->tot_len */ + iph->total_length = ntohs(ip_payload_len + PADDED_IPV4_HDR_SIZE); + /* update l3_len */ + m->l3_len = PADDED_IPV4_HDR_SIZE; + /* update data_len & pkt_len */ + m->data_len = m->pkt_len = m->pkt_len + IP_PADDING_LEN; + /* ip_payload is currently the place you would add 0s */ + memset(ip_payload, 0, IP_PADDING_LEN); + + /* re-set ip_payload to the right `offset` (location) now */ + ip_payload += IP_PADDING_LEN; + } + rte_memcpy(ip_payload, orig_ip_payload + orig_data_offset, + ip_payload_len); + orig_data_offset += ip_payload_len; + iph->hdr_checksum = 0; + iph->hdr_checksum = rte_ipv4_cksum((struct rte_ipv4_hdr *)iph); + } + for (int i = 0; i < res; i++) + EmitPacket(ctx, (bess::Packet *)frag_tbl[i], FORWARD_GATE); + + /* free original mbuf */ + DropPacket(ctx, p); + + /* all fragments successfully forwarded. Return NULL */ + return NULL; + } + } + + return p; +} +/*----------------------------------------------------------------------------------*/ +void IPFrag::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + int cnt = batch->cnt(); + for (int i = 0; i < cnt; i++) { + bess::Packet *p = batch->pkts()[i]; + p = FragmentPkt(ctx, p); + if (p) + EmitPacket(ctx, p, FORWARD_GATE); + } +} +/*----------------------------------------------------------------------------------*/ +CommandResponse IPFrag::GetEthMTU(const bess::pb::EmptyArg &) { + bess::pb::IPFragArg arg; + arg.set_mtu(eth_mtu); + DLOG(INFO) << "Ethernet MTU Size: " << eth_mtu << std::endl; + return CommandSuccess(arg); +} +/*----------------------------------------------------------------------------------*/ +void IPFrag::DeInit() { + if (indirect_pktmbuf_pool != NULL) { + /* free allocated IP frags */ + delete indirect_pktmbuf_pool; + indirect_pktmbuf_pool = NULL; + } +} +/*----------------------------------------------------------------------------------*/ +CommandResponse IPFrag::Init(const bess::pb::IPFragArg &arg) { + eth_mtu = arg.mtu(); + std::string pool_name = this->name() + "_indirect_mbuf_pool"; + + if (eth_mtu <= RTE_ETHER_MIN_LEN) + return CommandFailure(EINVAL, "Invalid MTU size!"); + + indirect_pktmbuf_pool = new bess::DpdkPacketPool(); + if (indirect_pktmbuf_pool == NULL) + return CommandFailure(ENOMEM, "Cannot create indirect mempool!"); + return CommandSuccess(); +} +/*----------------------------------------------------------------------------------*/ +ADD_MODULE(IPFrag, "ip_frag", "IPv4 Fragmentation module") diff --git a/core/modules/ip_frag.h b/core/modules/ip_frag.h new file mode 100644 index 0000000000..80d5406dfb --- /dev/null +++ b/core/modules/ip_frag.h @@ -0,0 +1,69 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2020 Intel Corporation + */ +#ifndef BESS_MODULES_IPFRAG_H_ +#define BESS_MODULES_IPFRAG_H_ +/*----------------------------------------------------------------------------------*/ +#include +#include +/* for ipv4 header */ +#include +/* for RTE_ETHER macros */ +#include "../module.h" +#include "../pb/module_msg.pb.h" +#include "rte_ether.h" +/*----------------------------------------------------------------------------------*/ +/** + * RX_NUM_DESC < 1024: + * But increased sensivity kernel packet processing core sched jitters + */ +#define RX_NUM_DESC 2048 + +/** + * macro to config tx ring size. + */ +#define TX_NUM_DESC RX_NUM_DESC + +/** + * macro to set the batch size + */ +#define BATCH_SIZE 64 + +/** + * DPDK default value optimial. + */ +#define MBUF_CACHE_SIZE 512 + +#define IP_PADDING_LEN 28 +#define PADDED_IPV4_HDR_SIZE (sizeof(struct rte_ipv4_hdr) + IP_PADDING_LEN) +/** + * NUM_MBUFS >= 2x RX_NUM_DESC:: + * Else rte_eth_dev_start(...) { FAIL; ...} + * NUM_MBUFS >= 1.5x MBUF_CACHE_SIZE:: + * Else rte_pktmbuf_pool_create(...) { FAIL; ...} + */ +#define NUM_MBUFS \ + (TX_NUM_DESC * 2) > (1.5 * MBUF_CACHE_SIZE) ? (TX_NUM_DESC * 2) \ + : (2 * MBUF_CACHE_SIZE) +/*----------------------------------------------------------------------------------*/ +class IPFrag final : public Module { + public: + IPFrag() { max_allowed_workers_ = Worker::kMaxWorkers; } + + /* Gates: (0) Default, (1) Forward */ + static const gate_idx_t kNumOGates = 2; + static const Commands cmds; + + CommandResponse Init(const bess::pb::IPFragArg &arg); + void DeInit() override; + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + CommandResponse GetEthMTU(const bess::pb::EmptyArg &); + + private: + bess::Packet *FragmentPkt(Context *ctx, bess::Packet *p); + bess::DpdkPacketPool *indirect_pktmbuf_pool = NULL; + int eth_mtu = RTE_ETHER_MAX_LEN; +}; +/*----------------------------------------------------------------------------------*/ +#endif // BESS_MODULES_IPFRAG_H_ diff --git a/core/modules/qos.cc b/core/modules/qos.cc new file mode 100644 index 0000000000..714d4583c6 --- /dev/null +++ b/core/modules/qos.cc @@ -0,0 +1,432 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright 2014-2016, The Regents of the University of California. + * Copyright 2016-2017, Nefeli Networks, Inc. + * Copyright 2021-present Intel Corporation + */ +#include "qos.h" +#include "utils/endian.h" +#include "utils/format.h" + +#include +#include +#include + +typedef enum { FIELD_TYPE = 0, VALUE_TYPE } Type; +using bess::metadata::Attribute; +#define metering_test 0 +static inline int is_valid_gate(gate_idx_t gate) { + return (gate == METER_GATE || (gate > METER_RED_GATE && gate < MAX_GATES) || + gate == DROP_GATE); +} + +const Commands Qos::cmds = { + {"add", "QosCommandAddArg", MODULE_CMD_FUNC(&Qos::CommandAdd), + Command::THREAD_SAFE}, + {"delete", "QosCommandDeleteArg", MODULE_CMD_FUNC(&Qos::CommandDelete), + Command::THREAD_SAFE}, + {"clear", "EmptyArg", MODULE_CMD_FUNC(&Qos::CommandClear), + Command::THREAD_SAFE}, + {"set_default_gate", "QosCommandSetDefaultGateArg", + MODULE_CMD_FUNC(&Qos::CommandSetDefaultGate), Command::THREAD_SAFE}}; + +CommandResponse Qos::AddFieldOne(const bess::pb::Field &field, + struct MeteringField *f, uint8_t type) { + f->size = field.num_bytes(); + + if (f->size < 1 || f->size > MAX_FIELD_SIZE) { + return CommandFailure(EINVAL, "'size' must be 1-%d", MAX_FIELD_SIZE); + } + + if (field.position_case() == bess::pb::Field::kOffset) { + f->attr_id = -1; + f->offset = field.offset(); + if (f->offset < 0 || f->offset > 1024) { + return CommandFailure(EINVAL, "too small 'offset'"); + } + } else if (field.position_case() == bess::pb::Field::kAttrName) { + const char *attr = field.attr_name().c_str(); + f->attr_id = + (type == FieldType) + ? AddMetadataAttr(attr, f->size, Attribute::AccessMode::kRead) + : AddMetadataAttr(attr, f->size, Attribute::AccessMode::kWrite); + + if (f->attr_id < 0) { + return CommandFailure(-f->attr_id, "add_metadata_attr() failed"); + } + } else { + return CommandFailure(EINVAL, "specify 'offset' or 'attr'"); + } + + return CommandSuccess(); +} + +CommandResponse Qos::Init(const bess::pb::QosArg &arg) { + int size_acc = 0; + int value_acc = 0; + + for (int i = 0; i < arg.fields_size(); i++) { + const auto &field = arg.fields(i); + CommandResponse err; + fields_.emplace_back(); + struct MeteringField &f = fields_.back(); + f.pos = size_acc; + err = AddFieldOne(field, &f, FieldType); + if (err.error().code() != 0) { + return err; + } + + size_acc += f.size; + } + default_gate_ = DROP_GATE; + total_key_size_ = align_ceil(size_acc, sizeof(uint64_t)); + for (int i = 0; i < arg.values_size(); i++) { + const auto &field = arg.values(i); + CommandResponse err; + values_.emplace_back(); + struct MeteringField &f = values_.back(); + f.pos = value_acc; + err = AddFieldOne(field, &f, ValueType); + if (err.error().code() != 0) { + return err; + } + + value_acc += f.size; + } + + total_value_size_ = align_ceil(value_acc, sizeof(uint64_t)); + + uint8_t *cs = (uint8_t *)&mask; + for (int i = 0; i < size_acc; i++) { + cs[i] = 0xff; + } + + table_.Init(total_key_size_, arg.entries()); + return CommandSuccess(); +} + +void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + gate_idx_t default_gate; + MeteringKey keys[bess::PacketBatch::kMaxBurst] __ymm_aligned; + bess::Packet *pkt = nullptr; + default_gate = ACCESS_ONCE(default_gate_); + int cnt = batch->cnt(); + for (const auto &field : fields_) { + int offset; + int pos = field.pos; + int attr_id = field.attr_id; + + if (attr_id < 0) { + offset = field.offset; + } else { + offset = bess::Packet::mt_offset_to_databuf_offset(attr_offset(attr_id)); + } + + for (int j = 0; j < cnt; j++) { + pkt = batch->pkts()[j]; + char *buf_addr = pkt->buffer(); + + /* for offset-based attrs we use relative offset */ + if (attr_id < 0) { + buf_addr += pkt->data_off(); + } + + char *key = reinterpret_cast(keys[j].u64_arr) + pos; + + *(reinterpret_cast(key)) = + *(reinterpret_cast(buf_addr + offset)); + + size_t len = reinterpret_cast(total_key_size_ / sizeof(uint64_t)); + + for (size_t i = 0; i < len; i++) { + keys[j].u64_arr[i] = keys[j].u64_arr[i] & mask[i]; + } + } + } + + int icnt=0; + for(int lcnt=0; lcnt=64) ? 64 : cnt-lcnt ; + value *val[icnt]; + uint64_t hit_mask = table_.Find(keys+lcnt, val, icnt); + + for (int j = 0; j < icnt; j++) { + pkt = batch->pkts()[j+lcnt]; + if ((hit_mask & ((uint64_t)1ULL << j)) == 0) { + EmitPacket(ctx, pkt, default_gate); + continue; + } + + uint16_t ogate = val[j]->ogate; + DLOG(INFO) << "ogate : " << ogate << std::endl; + + // meter if ogate is 0 + if (ogate == METER_GATE) { + uint64_t time = rte_rdtsc(); + uint32_t pkt_len = pkt->total_len() - val[j]->deduct_len; + uint8_t color = rte_meter_trtcm_color_blind_check(&val[j]->m, &val[j]->p, + time, pkt_len); + + DLOG(INFO) << "color : " << color << std::endl; + // update ogate to color specific gate + if (color == RTE_COLOR_GREEN) { + ogate = METER_GREEN_GATE; + } else if (color == RTE_COLOR_YELLOW) { + ogate = METER_YELLOW_GATE; + } else if (color == RTE_COLOR_RED) { + ogate = METER_RED_GATE; + } + } + + // update values + size_t num_values_ = values_.size(); + for (size_t i = 0; i < num_values_; i++) { + int value_size = values_[i].size; + int value_pos = values_[i].pos; + int value_off = values_[i].offset; + int value_attr_id = values_[i].attr_id; + uint8_t *data = pkt->head_data() + value_off; + + if (value_attr_id < 0) { /* if it is offset-based */ + memcpy(data, reinterpret_cast(&(val[j]->Data)) + value_pos, + value_size); + } else { /* if it is attribute-based */ + typedef struct { + uint8_t bytes[bess::metadata::kMetadataAttrMaxSize]; + } value_t; + uint8_t *buf = (uint8_t *)(&(val[j]->Data)) + value_pos; + + DLOG(INFO) << "Setting value " << std::hex + << *(reinterpret_cast(buf)) + << " for attr_id: " << value_attr_id + << " of size: " << value_size + << " at value_pos: " << value_pos << std::endl; + + switch (value_size) { + case 1: + set_attr(this, value_attr_id, pkt, *((uint8_t *)buf)); + break; + case 2: + set_attr(this, value_attr_id, pkt, + *((uint16_t *)((uint8_t *)buf))); + break; + case 4: + set_attr(this, value_attr_id, pkt, + *((uint32_t *)((uint8_t *)buf))); + break; + case 8: + set_attr(this, value_attr_id, pkt, + *((uint64_t *)((uint8_t *)buf))); + break; + default: { + void *mt_ptr = + _ptr_attr_with_offset(attr_offset(value_attr_id), pkt); + bess::utils::CopySmall(mt_ptr, buf, value_size); + } break; + } + } + } + EmitPacket(ctx, pkt, ogate); + } +} + +} + +template +CommandResponse Qos::ExtractKey(const T &arg, MeteringKey *key) { + if ((size_t)arg.fields_size() != fields_.size()) { + return CommandFailure(EINVAL, "must specify %zu masks", fields_.size()); + } + + memset(key, 0, sizeof(*key)); + + for (size_t i = 0; i < fields_.size(); i++) { + int field_size = fields_[i].size; + int field_pos = fields_[i].pos; + + // uint64_t v = 0; + uint64_t k = 0; + + bess::pb::FieldData fieldsdata = arg.fields(i); + if (fieldsdata.encoding_case() == bess::pb::FieldData::kValueInt) { + if (!bess::utils::uint64_to_bin(&k, fieldsdata.value_int(), field_size, + false)) { + return CommandFailure(EINVAL, "idx %zu: not a correct %d-byte mask", i, + field_size); + } + } else if (fieldsdata.encoding_case() == bess::pb::FieldData::kValueBin) { + bess::utils::Copy(reinterpret_cast(&k), + fieldsdata.value_bin().c_str(), + fieldsdata.value_bin().size()); + } + + memcpy(reinterpret_cast(key) + field_pos, &k, field_size); + } + return CommandSuccess(); +} + +template +CommandResponse Qos::ExtractKeyMask(const T &arg, MeteringKey *key, + MeteringKey *val, MKey *l) { + if ((size_t)arg.fields_size() != fields_.size()) { + return CommandFailure(EINVAL, "must specify %zu masks", fields_.size()); + } + + memset(key, 0, sizeof(*key)); + memset(val, 0, sizeof(*val)); + + for (size_t i = 0; i < fields_.size(); i++) { + int field_size = fields_[i].size; + int field_pos = fields_[i].pos; + + uint64_t k = 0; + + bess::pb::FieldData fieldsdata = arg.fields(i); + if (fieldsdata.encoding_case() == bess::pb::FieldData::kValueInt) { + if (!bess::utils::uint64_to_bin(&k, fieldsdata.value_int(), field_size, + false)) { + return CommandFailure(EINVAL, "idx %zu: not a correct %d-byte mask", i, + field_size); + } + } else if (fieldsdata.encoding_case() == bess::pb::FieldData::kValueBin) { + bess::utils::Copy(reinterpret_cast(&k), + fieldsdata.value_bin().c_str(), + fieldsdata.value_bin().size()); + } + + memcpy(reinterpret_cast(key) + field_pos, &k, field_size); + } + + for (size_t i = 0; i < fields_.size(); i++) { + int field_size = fields_[i].size; + int field_pos = fields_[i].pos; + + uint64_t k = 0; + + bess::pb::FieldData fieldsdata = arg.fields(i); + if (fieldsdata.encoding_case() == bess::pb::FieldData::kValueInt) { + if (!bess::utils::uint64_to_bin(&k, fieldsdata.value_int(), field_size, + false)) { + return CommandFailure(EINVAL, "idx %zu: not a correct %d-byte mask", i, + field_size); + } + } else if (fieldsdata.encoding_case() == bess::pb::FieldData::kValueBin) { + bess::utils::Copy(reinterpret_cast(&k), + fieldsdata.value_bin().c_str(), + fieldsdata.value_bin().size()); + } + + memcpy(reinterpret_cast(l) + field_pos, &k, field_size); + } + + for (size_t i = 0; i < values_.size(); i++) { + int val_size = values_[i].size; + int val_pos = values_[i].pos; + + uint64_t v = 0; + bess::pb::FieldData valuedata = arg.values(i); + if (valuedata.encoding_case() == bess::pb::FieldData::kValueInt) { + if (!bess::utils::uint64_to_bin(&v, valuedata.value_int(), val_size, + false)) { + return CommandFailure(EINVAL, "idx %zu: not a correct %d-byte value", i, + val_size); + } + } else if (valuedata.encoding_case() == bess::pb::FieldData::kValueBin) { + bess::utils::Copy(reinterpret_cast(&v), + valuedata.value_bin().c_str(), + valuedata.value_bin().size()); + } + + memcpy(reinterpret_cast(val) + val_pos, &v, val_size); + } + return CommandSuccess(); +} + +CommandResponse Qos::CommandAdd(const bess::pb::QosCommandAddArg &arg) { + gate_idx_t gate = arg.gate(); + + if (!is_valid_gate(gate)) { + return CommandFailure(EINVAL, "Invalid gate: %hu", gate); + } + MeteringKey key = {{0}}; + + MKey l; + value v; + v.ogate = gate; + CommandResponse err = ExtractKeyMask(arg, &key, &v.Data, &l); + + if (err.error().code() != 0) { + return err; + } + + if (gate == METER_GATE) { + uint64_t cir = arg.cir(); + uint64_t pir = arg.pir(); + uint64_t cbs = arg.cbs(); + uint64_t pbs = arg.pbs(); + uint64_t ebs = arg.ebs(); + + if (arg.optional_deduct_len_case() == + bess::pb::QosCommandAddArg::OPTIONAL_DEDUCT_LEN_NOT_SET) { + v.deduct_len = 14; // Exclude Ethernet header by default + } else { + v.deduct_len = arg.deduct_len(); + } + + DLOG(INFO) << "Adding entry" + << " cir: " << cir << " pir: " << pir << " cbs: " << cbs + << " pbs: " << pbs << " ebs: " << ebs << std::endl; + + struct rte_meter_trtcm_params app_trtcm_params = { + .cir = cir, .pir = pir, .cbs = cbs, .pbs = pbs}; + + int ret = rte_meter_trtcm_profile_config(&v.p, &app_trtcm_params); + if (ret) + return CommandFailure( + ret, "Insert Failed - rte_meter_trtcm_profile_config failed"); + + ret = rte_meter_trtcm_config(&v.m, &v.p); + if (ret) { + return CommandFailure(ret, + "Insert Failed - rte_meter_trtcm_config failed"); + } + } + + table_.Add(v, key); + return CommandSuccess(); +} + +CommandResponse Qos::CommandDelete(const bess::pb::QosCommandDeleteArg &arg) { + MeteringKey key; + CommandResponse err = ExtractKey(arg, &key); + table_.Delete(key); + return CommandSuccess(); +} + +CommandResponse Qos::CommandClear(__attribute__((unused)) + const bess::pb::EmptyArg &) { + Qos::Clear(); + return CommandSuccess(); +} + +void Qos::Clear() { + table_.Clear(); +} + +void Qos::DeInit() { + table_.DeInit(); +} + +CommandResponse Qos::CommandSetDefaultGate( + const bess::pb::QosCommandSetDefaultGateArg &arg) { + default_gate_ = arg.gate(); + return CommandSuccess(); +} + +std::string Qos::GetDesc() const { + return bess::utils::Format("%zu fields, %zu rules", fields_.size(), + table_.Count()); +} + +ADD_MODULE(Qos, "qos", "Multi-field classifier with a QOS") diff --git a/core/modules/qos.h b/core/modules/qos.h new file mode 100644 index 0000000000..e2ff8be529 --- /dev/null +++ b/core/modules/qos.h @@ -0,0 +1,94 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright 2014-2016, The Regents of the University of California. + * Copyright 2016-2017, Nefeli Networks, Inc. + * Copyright 2021-present Intel Corporation + */ +#ifndef BESS_MODULES_QOS_H_ +#define BESS_MODULES_QOS_H_ + +#include "../module.h" + +#include +#include + +#include "../pb/module_msg.pb.h" +#include "../utils/metering.h" + +using bess::utils::Metering; +using bess::utils::MeteringKey; + +#define MAX_FIELDS 8 +#define MAX_FIELD_SIZE 8 +static_assert(MAX_FIELD_SIZE <= sizeof(uint64_t), + "field cannot be larger than 8 bytes"); + +#define HASH_KEY_SIZE (MAX_FIELDS * MAX_FIELD_SIZE) +#define METER_GATE 0 +#define METER_GREEN_GATE 1 +#define METER_YELLOW_GATE 2 +#define METER_RED_GATE 3 + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ +#error this code assumes little endian architecture (x86) +#endif + +enum { FieldType = 0, ValueType }; + +struct value { + gate_idx_t ogate; + int64_t deduct_len; + struct rte_meter_trtcm_profile p; + struct rte_meter_trtcm m; + MeteringKey Data; +} __attribute__((packed)); + +struct MKey { + uint8_t key1; + uint8_t key2; +} __attribute__((packed)); + +class Qos final : public Module { + public: + static const gate_idx_t kNumOGates = MAX_GATES; + + static const Commands cmds; + + Qos() : Module(), default_gate_(), total_key_size_(), fields_() { + max_allowed_workers_ = Worker::kMaxWorkers; + size_t len = sizeof(mask) / sizeof(uint64_t); + for (size_t i = 0; i < len; i++) + mask[i] = 0; + } + + CommandResponse Init(const bess::pb::QosArg &arg); + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + CommandResponse CommandAdd(const bess::pb::QosCommandAddArg &arg); + CommandResponse CommandDelete(const bess::pb::QosCommandDeleteArg &arg); + CommandResponse CommandClear(const bess::pb::EmptyArg &arg); + CommandResponse CommandSetDefaultGate( + const bess::pb::QosCommandSetDefaultGateArg &arg); + template + CommandResponse ExtractKeyMask(const T &arg, MeteringKey *key, + MeteringKey *val, MKey *l); + template + CommandResponse ExtractKey(const T &arg, MeteringKey *key); + CommandResponse AddFieldOne(const bess::pb::Field &field, + struct MeteringField *f, uint8_t type); + gate_idx_t LookupEntry(const MeteringKey &key, gate_idx_t def_gate); + void DeInit(); + std::string GetDesc() const override; + + private: + int DelEntry(MeteringKey *key); + void Clear(); + gate_idx_t default_gate_; + size_t total_key_size_; /* a multiple of sizeof(uint64_t) */ + size_t total_value_size_; + std::vector fields_; + std::vector values_; + Metering table_; + uint64_t mask[MAX_FIELDS]; +}; + +#endif // BESS_MODULES_QOS_H diff --git a/core/utils/gtp.h b/core/utils/gtp.h new file mode 100644 index 0000000000..7c12e96a0d --- /dev/null +++ b/core/utils/gtp.h @@ -0,0 +1,68 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2019 Intel Corporation + */ +#ifndef BESS_UTILS_GTP_H_ +#define BESS_UTILS_GTP_H_ +/*----------------------------------------------------------------------------------*/ +#include "endian.h" + +namespace bess { +namespace utils { + +#define EXT_TYPE_PDU_SESSION_CONTAINER 0x85 + +struct [[gnu::packed]] Gtpv1 { + uint8_t pdn : 1, /* N-PDU number */ + seq : 1, /* Sequence number */ + ex : 1, /* Extension header */ + spare : 1, /* Reserved field */ + pt : 1, /* Protocol type */ + version : 3; /* Version */ + + uint8_t type; /* Message type */ + be16_t length; /* Message length */ + be32_t teid; /* Tunnel endpoint identifier */ + /* The options start here. */ + + size_t header_length() const { + const Gtpv1 *gtph = this; + const uint8_t *pktptr = (const uint8_t *)this; + size_t len = sizeof(Gtpv1); + + if (gtph->seq || gtph->pdn || gtph->ex) + len += 4; + if (gtph->ex) { + /* Probe till the last extension header */ + /* calculate total len of gtp header (with options) */ + while (pktptr[len - 1]) + len += (pktptr[len] << 2); + } + return len; + } +}; + +struct [[gnu::packed]] Gtpv1SeqPDUExt { + be16_t seqnum; /* Sequence Number*/ + uint8_t npdu; /* N-PDU number*/ + uint8_t ext; /* Extension type */ +}; + +struct [[gnu::packed]] Gtpv1PDUSessExt { + uint8_t hlen; /* Extension header length */ + uint8_t spare1 : 4, /* Spare */ + pdu_type : 4; /* PDU type 0=DL/1=UL*/ + uint8_t qfi : 6, /* QoS Flow Identifier*/ + spare2 : 2; /* Spare */ + uint8_t next_type; /* Next extension header type */ + + size_t header_length() const { return sizeof(Gtpv1PDUSessExt) >> 2; } + + uint8_t type() const { return EXT_TYPE_PDU_SESSION_CONTAINER; } +}; + +} // namespace utils +} // namespace bess + +/*----------------------------------------------------------------------------------*/ +#endif /* BESS_UTILS_GTP_H_ */ diff --git a/core/utils/metering.h b/core/utils/metering.h new file mode 100644 index 0000000000..47b3eef119 --- /dev/null +++ b/core/utils/metering.h @@ -0,0 +1,196 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * Copyright 2014-2016, The Regents of the University of California. + * Copyright 2016-2017, Nefeli Networks, Inc. + * Copyright 2021-present Intel Corporation + */ +#ifndef BESS_UTILS_METERING_H_ +#define BESS_UTILS_METERING_H_ + +#include +#include +#include + +#include "../message.h" +#include "../metadata.h" +#include "../module.h" +#include "../packet.h" +#include "bits.h" +#include "cuckoo_map.h" +#include "endian.h" +#include "format.h" +#include +#include +#include + +#define MAX_FIELDS 8 +#define MAX_FIELD_SIZE 8 + +static_assert(MAX_FIELD_SIZE <= sizeof(uint64_t), + "field cannot be larger than 8 bytes"); + +#define HASH_KEY_SIZE (MAX_FIELDS * MAX_FIELD_SIZE) + +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ +#error this code assumes little endian architecture (x86) +#endif + +struct MeteringField { + int attr_id; + int offset; + int pos; + int size; +}; + +namespace bess { +namespace utils { + +using Error = std::pair; + +struct MeteringKey { + uint64_t u64_arr[MAX_FIELDS]; +} __attribute__((packed)); + +// Equality operator for two MeteringKeys +class MeteringKeyEq { + public: + explicit MeteringKeyEq(size_t len) : len_(len) {} + + bool operator()(const MeteringKey &lhs, const MeteringKey &rhs) const { + promise(len_ >= sizeof(uint64_t)); + promise(len_ <= sizeof(MeteringKey)); + + for (size_t i = 0; i < len_ / 8; i++) { + if (lhs.u64_arr[i] != rhs.u64_arr[i]) { + return false; + } + } + return true; + } + + private: + size_t len_; +}; + +// Hash function for an MeteringKey +class MeteringKeyHash { + public: + explicit MeteringKeyHash(size_t len) : len_(len) {} + + HashResult operator()(const MeteringKey &key) const { + HashResult init_val = 0; + + promise(len_ >= sizeof(uint64_t)); + promise(len_ <= sizeof(MeteringKey)); + +#if __x86_64 + for (size_t i = 0; i < len_ / 8; i++) { + init_val = crc32c_sse42_u64(key.u64_arr[i], init_val); + } + return init_val; +#else + return rte_hash_crc(&key, len_, init_val); +#endif + } + + private: + size_t len_; +}; + +template +class Metering { + public: + struct rte_hash_parameters dpdk_params { + .name = "Metering", .entries = 1 << 15, .reserved = 0, + .key_len = sizeof(MeteringKey), .hash_func = rte_hash_crc, + .hash_func_init_val = 0, .socket_id = (int)rte_socket_id(), + .extra_flag = RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY + }; + + using EmTable = CuckooMap; + Metering() : total_key_size_(0), num_fields_(0) {} + + Error Add(const T &val, const MeteringKey &key) { + Error err; + const void *Key_t = (const void *)&key; + T *val_t = new T(val); + int ret = table_->insert_dpdk(Key_t, val_t); + if (!ret) { + return MakeError(ENOENT, "Dpdk Insert Failed"); + } + return MakeError(0); + } + + Error Delete(const MeteringKey &key) { + Error err; + bool ret = table_->Remove(key, MeteringKeyHash(total_key_size_), + MeteringKeyEq(total_key_size_)); + if (!ret) { + return MakeError(ENOENT, "rule doesn't exist"); + } + return MakeError(0); + } + + void Clear() { table_->Clear(); } + size_t Count() const { return table_->Count(); } + void DeInit() { table_->DeInit(); } + + // Find an entry in the table. + // Returns the value if `key` matches a rule, otherwise `default_value`. + T Find(const MeteringKey &key, const T &default_value) const { + const auto &table = table_; + void *data = nullptr; + table->find_dpdk(&key, &data); + if (data) { + T data_t = *((T *)data); + return data_t; + } else + + return default_value; + } + + uint64_t Find(MeteringKey *keys, T **vals, int n) { + uint64_t hit_mask = 0; + + const auto &table = table_; + MeteringKey *key_ptr[n]; + for (int h = 0; h < n; h++) + key_ptr[h] = &keys[h]; + table->lookup_bulk_data((const void **)&key_ptr, n, &hit_mask, + (void **)vals); + + return hit_mask; + } + + uint32_t Total_key_size() const { return total_key_size_; } + + void Init(int size, int entries) { + std::ostringstream address; + total_key_size_ = size; + address << &table_; + std::string name = "Metering" + address.str(); + dpdk_params.name = name.c_str(); + if (entries) { + dpdk_params.entries = entries; + } + dpdk_params.key_len = size; + table_.reset(new CuckooMap( + 0, 0, &dpdk_params)); + } + + private: + Error MakeError(int code, const std::string &msg = "") { + return std::make_pair(code, msg); + } + + // aligned total key size + size_t total_key_size_; + size_t num_fields_; + std::unique_ptr> + table_; +}; + +} // namespace utils +} // namespace bess + +#endif From 8101295475bdd87248e5ea50f89beb34bdb7f598 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 18 Nov 2022 12:41:29 -0800 Subject: [PATCH 27/62] Bring DPDK patch from UPF --- ...d-set-ioctl-if-there-is-no-flag-diff.patch | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch diff --git a/deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch b/deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch new file mode 100644 index 0000000000..a4aeefef11 --- /dev/null +++ b/deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch @@ -0,0 +1,52 @@ +From e1bc63488d346cb84ae7e76f2bc480247f577abb Mon Sep 17 00:00:00 2001 +From: Saikrishna Edupuganti +Date: Fri, 12 Jun 2020 21:36:53 +0000 +Subject: [PATCH] af_packet Avoid set ioctl if there is no flag diff + +rte_eth_dev_start -> rte_eth_dev_config_restore +In 19.11 DPDK started returning errors +https://github.com/DPDK/dpdk/commit/9039c8125730adfd46b8c891e7f205eb4ac43c67 +https://github.com/DPDK/dpdk/commit/69d0e7092874db1909bc40986c06219f1880dc23 + +Gist +https://gist.github.com/krsna1729/0c7160920343f9fa55f760c770286155 + +We also patch af_packet PMD to change set flags only when needed + +Signed-off-by: Saikrishna Edupuganti +--- + drivers/net/af_packet/rte_eth_af_packet.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c +index f5806bf42..29d45eb47 100644 +--- a/drivers/net/af_packet/rte_eth_af_packet.c ++++ b/drivers/net/af_packet/rte_eth_af_packet.c +@@ -472,6 +472,7 @@ static int + eth_dev_change_flags(char *if_name, uint32_t flags, uint32_t mask) + { + struct ifreq ifr; ++ uint32_t cur_flags; + int ret = 0; + int s; + +@@ -484,8 +485,16 @@ eth_dev_change_flags(char *if_name, uint32_t flags, uint32_t mask) + ret = -errno; + goto out; + } ++ ++ cur_flags = ifr.ifr_flags; + ifr.ifr_flags &= mask; + ifr.ifr_flags |= flags; ++ ++ // Return if there is no change ++ if (cur_flags == ifr.ifr_flags){ ++ goto out; ++ } ++ + if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) { + ret = -errno; + goto out; +-- +2.25.1 + From ebbc510cb550e4a2752cb1d40162bda30fde271c Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 20:37:27 -0700 Subject: [PATCH 28/62] Removed deprecated DPDK options/functions --- core/dpdk.cc | 2 +- core/memory_test.cc | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/dpdk.cc b/core/dpdk.cc index 964d513c2c..130572d789 100644 --- a/core/dpdk.cc +++ b/core/dpdk.cc @@ -112,7 +112,7 @@ class CmdLineOpts { void init_eal(int dpdk_mb_per_socket, std::string nonworker_corelist) { CmdLineOpts rte_args{ "bessd", - "--master-lcore", + "--main-lcore", std::to_string(RTE_MAX_LCORE - 1), "--lcore", std::to_string(RTE_MAX_LCORE - 1) + "@" + nonworker_corelist, diff --git a/core/memory_test.cc b/core/memory_test.cc index 9849147d49..c5e44a168b 100644 --- a/core/memory_test.cc +++ b/core/memory_test.cc @@ -139,9 +139,9 @@ TEST_P(HugepageTest, LeakFree) { } while (get_cpu_time() - start < 0.5); // 0.5 second for each page size } -INSTANTIATE_TEST_CASE_P(PageSize, HugepageTest, - ::testing::Values(HugepageSize::k2MB, - HugepageSize::k1GB)); +INSTANTIATE_TEST_SUITE_P(PageSize, HugepageTest, + ::testing::Values(HugepageSize::k2MB, + HugepageSize::k1GB)); TEST(DmaMemoryPoolTest, PoolSetup) { if (geteuid() != 0) { From 7a9bbb9ddebe6510f09b023760ea11f04a951a9d Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 20:42:12 -0700 Subject: [PATCH 29/62] Remove unnecesary `endl` --- core/bessctl.cc | 15 +++++---------- core/modules/mttest.cc | 6 +++--- core/modules/wildcard_match.cc | 7 +++---- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/core/bessctl.cc b/core/bessctl.cc index ee39e41aa8..56c0535dd2 100644 --- a/core/bessctl.cc +++ b/core/bessctl.cc @@ -1006,8 +1006,7 @@ class BESSControlImpl final : public BESSControl::Service { const char* driver_name; ::Port* port = nullptr; - VLOG(1) << "CreatePortRequest from client:" << std::endl - << request->DebugString(); + VLOG(1) << "CreatePortRequest from client:\n" << request->DebugString(); if (request->driver().length() == 0) return return_with_error(response, EINVAL, "Missing 'driver' field"); @@ -1206,8 +1205,7 @@ class BESSControlImpl final : public BESSControl::Service { CreateModuleResponse* response) override { std::lock_guard lock(mutex_); - VLOG(1) << "CreateModuleRequest from client:" << std::endl - << request->DebugString(); + VLOG(1) << "CreateModuleRequest from client:\n" << request->DebugString(); if (!request->mclass().length()) { return return_with_error(response, EINVAL, "Missing 'mclass' field"); @@ -1313,8 +1311,7 @@ class BESSControlImpl final : public BESSControl::Service { EmptyResponse* response) override { std::lock_guard lock(mutex_); - VLOG(1) << "ConnectModulesRequest from client:" << std::endl - << request->DebugString(); + VLOG(1) << "ConnectModulesRequest from client:\n" << request->DebugString(); const char* m1_name; const char* m2_name; @@ -1454,8 +1451,7 @@ class BESSControlImpl final : public BESSControl::Service { GetGateHookClassInfoResponse* response) override { std::lock_guard lock(mutex_); - VLOG(1) << "GetGateHookClassInfo from client:" << std::endl - << request->DebugString(); + VLOG(1) << "GetGateHookClassInfo from client:\n" << request->DebugString(); if (!request->name().length()) { return return_with_error(response, EINVAL, "Argument must be a name in str"); @@ -1733,8 +1729,7 @@ class BESSControlImpl final : public BESSControl::Service { GetMclassInfoResponse* response) override { std::lock_guard lock(mutex_); - VLOG(1) << "GetMclassInfo from client:" << std::endl - << request->DebugString(); + VLOG(1) << "GetMclassInfo from client:\n" << request->DebugString(); if (!request->name().length()) { return return_with_error(response, EINVAL, "Argument must be a name in str"); diff --git a/core/modules/mttest.cc b/core/modules/mttest.cc index 589f542618..44dc51e9f3 100644 --- a/core/modules/mttest.cc +++ b/core/modules/mttest.cc @@ -49,15 +49,15 @@ CommandResponse MetadataTest::AddAttributes( switch (mode) { case Attribute::AccessMode::kRead: LOG(INFO) << "module " << name() << ": " << attr_name << ", " - << attr_size << " bytes, read" << std::endl; + << attr_size << " bytes, read"; break; case Attribute::AccessMode::kWrite: LOG(INFO) << "module " << name() << ": " << attr_name << ", " - << attr_size << " bytes, write" << std::endl; + << attr_size << " bytes, write"; break; case Attribute::AccessMode::kUpdate: LOG(INFO) << "module " << name() << ": " << attr_name << ", " - << attr_size << " bytes, update" << std::endl; + << attr_size << " bytes, update"; break; } } diff --git a/core/modules/wildcard_match.cc b/core/modules/wildcard_match.cc index e4c88d9526..266eb06e6e 100644 --- a/core/modules/wildcard_match.cc +++ b/core/modules/wildcard_match.cc @@ -199,7 +199,7 @@ inline gate_idx_t WildcardMatch::LookupEntry(const wm_hkey_t &key, int value_attr_id = values_[i].attr_id; uint8_t *data = pkt->head_data() + value_off; - DLOG(INFO) << "off: " << (int)value_off << ", sz: " << value_size; + DLOG(INFO) << "off: " << value_off << ", sz: " << value_size; if (value_attr_id < 0) { /* if it is offset-based */ memcpy(data, reinterpret_cast(&result.keyv) + value_pos, @@ -293,8 +293,7 @@ inline bool WildcardMatch::LookupBulkEntry(wm_hkey_t *key, gate_idx_t def_gate, int value_attr_id = values_[i].attr_id; uint8_t *data = pkt->head_data() + value_off; - DLOG(INFO) << "off: " << (int)value_off << ", sz: " << value_size - << std::endl; + DLOG(INFO) << "off: " << value_off << ", sz: " << value_size; if (value_attr_id < 0) { /* if it is offset-based */ memcpy(data, reinterpret_cast(&result[init]->keyv) + value_pos, @@ -309,7 +308,7 @@ inline bool WildcardMatch::LookupBulkEntry(wm_hkey_t *key, gate_idx_t def_gate, << *(reinterpret_cast(buf)) << " for attr_id: " << value_attr_id << " of size: " << value_size - << " at value_pos: " << value_pos << std::endl; + << " at value_pos: " << value_pos; switch (value_size) { case 1: From 25f057772ecd932d5ef91c803f6731c58f6a10ae Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 20:42:53 -0700 Subject: [PATCH 30/62] Fix a couple typos --- bessctl/sugar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bessctl/sugar.py b/bessctl/sugar.py index 86484d0cd8..0a88394601 100644 --- a/bessctl/sugar.py +++ b/bessctl/sugar.py @@ -71,7 +71,7 @@ a->y:b Connect a to input gate y a + y*b of b a.connect(next_mod=b, - (x should be an integer) igate=y) + (y should be an integer) igate=y) a:3->4:b Connect output gate 3 of a a*3 + 4*b and input gate of 4 a.connect(next_mod=b, @@ -95,7 +95,7 @@ Python: __bess_module__('a','Foo') + __bess_module__('b', 'Bar') -3. Create anonymous modules and connection them +3. Create anonymous modules and connect them Ringo: Foo() -> Bar() Python: From f6f776bcf6f660865da0140f96f7efac772e62b4 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 20:43:43 -0700 Subject: [PATCH 31/62] Remove unused variables --- core/modules/source.cc | 1 - core/packet.cc | 2 -- 2 files changed, 3 deletions(-) diff --git a/core/modules/source.cc b/core/modules/source.cc index db99dbc205..4b0413a071 100644 --- a/core/modules/source.cc +++ b/core/modules/source.cc @@ -45,7 +45,6 @@ CommandResponse Source::Init(const bess::pb::SourceArg &arg) { return CommandFailure(ENOMEM, "Task creation failed"); pkt_size_ = 60; - burst_ = bess::PacketBatch::kMaxBurst; if (arg.pkt_size() > 0) { if (arg.pkt_size() > SNBUF_DATA) { diff --git a/core/packet.cc b/core/packet.cc index a3656b5247..8c5a5b8aa6 100644 --- a/core/packet.cc +++ b/core/packet.cc @@ -94,7 +94,6 @@ static std::string HexDump(const void *buffer, size_t len) { std::string Packet::Dump() { std::ostringstream dump; Packet *pkt; - uint32_t dump_len = total_len(); uint32_t nb_segs; uint32_t len; @@ -142,7 +141,6 @@ std::string Packet::Dump() { dump << HexDump(head_data(), len); } - dump_len -= len; pkt = pkt->next_; nb_segs--; } From 74c4d8d3d17e5f6adf77d1a9524f0fcb768fa2e9 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 20:44:10 -0700 Subject: [PATCH 32/62] No need to use `move` --- core/utils/histogram.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/utils/histogram.h b/core/utils/histogram.h index 7fbe2ba598..5fe654a602 100644 --- a/core/utils/histogram.h +++ b/core/utils/histogram.h @@ -191,7 +191,7 @@ class Histogram { // Resize the histogram. Note that this resets it (i.e., this // does not attempt to redistribute existing counts). void Resize(size_t num_buckets, T bucket_width) { - buckets_ = std::move(std::vector>(num_buckets + 1)); + buckets_ = std::vector>(num_buckets + 1); bucket_width_ = bucket_width; } From 32e9f1c335efdc6b7e5896e71e4c176ccaf09b3b Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 20:45:42 -0700 Subject: [PATCH 33/62] Improve code --- core/modules/measure.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/core/modules/measure.cc b/core/modules/measure.cc index e2b6dcebbe..8d87811fde 100644 --- a/core/modules/measure.cc +++ b/core/modules/measure.cc @@ -63,16 +63,15 @@ const Commands Measure::cmds = { CommandResponse Measure::Init(const bess::pb::MeasureArg &arg) { uint64_t latency_ns_max = arg.latency_ns_max(); uint64_t latency_ns_resolution = arg.latency_ns_resolution(); - if (latency_ns_max == 0) { + if (!latency_ns_max) { latency_ns_max = kDefaultMaxNs; } - if (latency_ns_resolution == 0) { + if (!latency_ns_resolution) { latency_ns_resolution = kDefaultNsPerBucket; } - uint64_t quotient = latency_ns_max / latency_ns_resolution; - if ((latency_ns_max % latency_ns_resolution) != 0) { - quotient += 1; // absorb any remainder - } + uint64_t quotient = + (latency_ns_max + latency_ns_resolution - 1) / latency_ns_resolution; + if (quotient > rtt_hist_.max_num_buckets() / 2) { return CommandFailure(E2BIG, "excessive latency_ns_max / latency_ns_resolution"); From 8ba96b90cbaf60c83477eabd59856cce08a9cdf2 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 1 Nov 2022 20:51:50 -0700 Subject: [PATCH 34/62] Fix Doxygen for AddMetadataAttr method --- core/module.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/module.h b/core/module.h index 6bb24020eb..f525ca2697 100644 --- a/core/module.h +++ b/core/module.h @@ -284,13 +284,13 @@ class alignas(64) Module { // Register a task. task_id_t RegisterTask(void *arg); - // Modules should call this function to declare additional metadata - // attributes at initialization time. - // Static metadata attributes that are defined in module class are - // automatically registered, so only attributes specific to a module - // 'instance' - // need this function. - // Returns its allocated ID (>= 0), or a negative number for error */ + /* Modules should call this function to declare additional metadata + * attributes at initialization time. + * Static metadata attributes that are defined in module class are + * automatically registered, so only attributes specific to a module + * 'instance' need this function. + * Returns its allocated ID (>= 0), or a negative number for error + * */ int AddMetadataAttr(const std::string &name, size_t size, bess::metadata::Attribute::AccessMode mode); From b7792b22750f6d2fb8ff749ec8c3baefd266e34a Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Thu, 1 Dec 2022 13:52:51 -0800 Subject: [PATCH 35/62] Remove unnecesary `endl` in loggings --- core/modules/counter.cc | 8 ++++---- core/modules/gtpu_encap.cc | 16 ++++++++-------- core/modules/ip_defrag.cc | 2 +- core/modules/ip_frag.cc | 2 +- core/modules/qos.cc | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/core/modules/counter.cc b/core/modules/counter.cc index 77f32afcd8..1f366984a4 100644 --- a/core/modules/counter.cc +++ b/core/modules/counter.cc @@ -48,9 +48,9 @@ CommandResponse Counter::RemoveCounter(const bess::pb::CounterRemoveArg &arg) { #ifdef HASHMAP_BASED /* check_exist is still here for over-protection */ if (counters.find(ctr_id) != counters.end()) { - std::cerr << this->name() << "[" << ctr_id - << "]: " << counters[ctr_id].pkt_count << ", " - << counters[ctr_id].byte_count << std::endl; + DLOG(WARNING) << this->name() << "[" << ctr_id + << "]: " << counters[ctr_id].pkt_count << ", " + << counters[ctr_id].byte_count; counters.erase(ctr_id); } else { return CommandFailure(EINVAL, "Unable to remove ctr"); @@ -59,7 +59,7 @@ CommandResponse Counter::RemoveCounter(const bess::pb::CounterRemoveArg &arg) { if (ctr_id < total_count && counters[ctr_id].pkt_count != 0) { DLOG(INFO) << this->name() << "[" << ctr_id << "]: " << counters[ctr_id].pkt_count << ", " - << counters[ctr_id].byte_count << std::endl; + << counters[ctr_id].byte_count; counters[ctr_id].pkt_count = counters[ctr_id].byte_count = 0; } curr_count--; diff --git a/core/modules/gtpu_encap.cc b/core/modules/gtpu_encap.cc index e36ad23d85..980f705227 100644 --- a/core/modules/gtpu_encap.cc +++ b/core/modules/gtpu_encap.cc @@ -118,7 +118,7 @@ void GtpuEncap::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { << ", tunnel out sip: " << at_tout_sip << ", tunnel out dip: " << at_tout_dip << ", tunnel out teid: " << at_tout_teid - << ", tunnel out udp port: " << at_tout_uport << std::endl; + << ", tunnel out udp port: " << at_tout_uport; uint16_t pkt_len = p->total_len() - sizeof(Ethernet); Ethernet *eth = p->head_data(); @@ -132,7 +132,7 @@ void GtpuEncap::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { if (new_p == NULL) { /* failed to prepend header space for encaped packet */ EmitPacket(ctx, p, DEFAULT_GATE); - DLOG(INFO) << "prepend() failed!" << std::endl; + DLOG(INFO) << "prepend() failed!"; continue; } @@ -193,21 +193,21 @@ CommandResponse GtpuEncap::Init(const bess::pb::GtpuEncapArg &arg) { using AccessMode = bess::metadata::Attribute::AccessMode; pdu_type_attr = AddMetadataAttr("action", sizeof(uint8_t), AccessMode::kRead); - DLOG(INFO) << "tout_sip_attr: " << tout_sip_attr << std::endl; + DLOG(INFO) << "tout_sip_attr: " << tout_sip_attr; tout_sip_attr = AddMetadataAttr("tunnel_out_src_ip4addr", sizeof(uint32_t), AccessMode::kRead); - DLOG(INFO) << "tout_sip_attr: " << tout_sip_attr << std::endl; + DLOG(INFO) << "tout_sip_attr: " << tout_sip_attr; tout_dip_attr = AddMetadataAttr("tunnel_out_dst_ip4addr", sizeof(uint32_t), AccessMode::kRead); - DLOG(INFO) << "tout_dip_attr: " << tout_dip_attr << std::endl; + DLOG(INFO) << "tout_dip_attr: " << tout_dip_attr; tout_teid = AddMetadataAttr("tunnel_out_teid", sizeof(uint32_t), AccessMode::kRead); - DLOG(INFO) << "tout_teid: " << tout_teid << std::endl; + DLOG(INFO) << "tout_teid: " << tout_teid; tout_uport = AddMetadataAttr("tunnel_out_udp_port", sizeof(uint16_t), AccessMode::kRead); - DLOG(INFO) << "tout_uport: " << tout_uport << std::endl; + DLOG(INFO) << "tout_uport: " << tout_uport; qfi_attr = AddMetadataAttr("qfi", sizeof(uint8_t), AccessMode::kRead); - DLOG(INFO) << "qfi_attr: " << qfi_attr << std::endl; + DLOG(INFO) << "qfi_attr: " << qfi_attr; return CommandSuccess(); } diff --git a/core/modules/ip_defrag.cc b/core/modules/ip_defrag.cc index e0c893b658..5998e0e2f3 100644 --- a/core/modules/ip_defrag.cc +++ b/core/modules/ip_defrag.cc @@ -61,7 +61,7 @@ bess::Packet *IPDefrag::IPReassemble(Context *ctx, bess::Packet *p) { iph = (Ipv4 *)((unsigned char *)eth + sizeof(Ethernet)); } else { DLOG(INFO) << "Failed to linearize rte_mbuf. " - << "Is there enough tail room?" << std::endl; + << "Is there enough tail room?"; EmitPacket(ctx, p, DEFAULT_GATE); return NULL; } diff --git a/core/modules/ip_frag.cc b/core/modules/ip_frag.cc index d7bf160538..1228998e0b 100644 --- a/core/modules/ip_frag.cc +++ b/core/modules/ip_frag.cc @@ -163,7 +163,7 @@ void IPFrag::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { CommandResponse IPFrag::GetEthMTU(const bess::pb::EmptyArg &) { bess::pb::IPFragArg arg; arg.set_mtu(eth_mtu); - DLOG(INFO) << "Ethernet MTU Size: " << eth_mtu << std::endl; + DLOG(INFO) << "Ethernet MTU Size: " << eth_mtu; return CommandSuccess(arg); } /*----------------------------------------------------------------------------------*/ diff --git a/core/modules/qos.cc b/core/modules/qos.cc index 714d4583c6..7dc128baf8 100644 --- a/core/modules/qos.cc +++ b/core/modules/qos.cc @@ -159,7 +159,7 @@ void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { } uint16_t ogate = val[j]->ogate; - DLOG(INFO) << "ogate : " << ogate << std::endl; + DLOG(INFO) << "ogate : " << ogate; // meter if ogate is 0 if (ogate == METER_GATE) { @@ -168,7 +168,7 @@ void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { uint8_t color = rte_meter_trtcm_color_blind_check(&val[j]->m, &val[j]->p, time, pkt_len); - DLOG(INFO) << "color : " << color << std::endl; + DLOG(INFO) << "color : " << color; // update ogate to color specific gate if (color == RTE_COLOR_GREEN) { ogate = METER_GREEN_GATE; @@ -201,7 +201,7 @@ void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { << *(reinterpret_cast(buf)) << " for attr_id: " << value_attr_id << " of size: " << value_size - << " at value_pos: " << value_pos << std::endl; + << " at value_pos: " << value_pos; switch (value_size) { case 1: @@ -376,7 +376,7 @@ CommandResponse Qos::CommandAdd(const bess::pb::QosCommandAddArg &arg) { DLOG(INFO) << "Adding entry" << " cir: " << cir << " pir: " << pir << " cbs: " << cbs - << " pbs: " << pbs << " ebs: " << ebs << std::endl; + << " pbs: " << pbs << " ebs: " << ebs; struct rte_meter_trtcm_params app_trtcm_params = { .cir = cir, .pir = pir, .cbs = cbs, .pbs = pbs}; From b51f2f0d85d67ddd9fa09ae3608d0203b648bbbb Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Thu, 1 Dec 2022 13:54:50 -0800 Subject: [PATCH 36/62] Fix stringstream --- core/modules/flow_measure.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/flow_measure.h b/core/modules/flow_measure.h index aca587cabe..374d289245 100644 --- a/core/modules/flow_measure.h +++ b/core/modules/flow_measure.h @@ -76,7 +76,7 @@ class FlowMeasure final : public Module { TableKey() : fseid(0), pdr(0) {} std::string ToString() const { std::stringstream ss; - ss << "{ fseid: " << fseid << ", pdr: " << pdr + " }"; + ss << "{ fseid: " << fseid << ", pdr: " << pdr << " }"; return ss.str(); } }; From 6605e770a4101f2b54443d52e22e3d2fe1782ae1 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Thu, 1 Dec 2022 13:56:54 -0800 Subject: [PATCH 37/62] Fix format in files --- core/modules/qos.cc | 144 ++++++++++++++++----------------- core/modules/wildcard_match.cc | 49 +++++------ 2 files changed, 93 insertions(+), 100 deletions(-) diff --git a/core/modules/qos.cc b/core/modules/qos.cc index 7dc128baf8..2af9859a52 100644 --- a/core/modules/qos.cc +++ b/core/modules/qos.cc @@ -110,7 +110,7 @@ void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { MeteringKey keys[bess::PacketBatch::kMaxBurst] __ymm_aligned; bess::Packet *pkt = nullptr; default_gate = ACCESS_ONCE(default_gate_); - int cnt = batch->cnt(); + int cnt = batch->cnt(); for (const auto &field : fields_) { int offset; int pos = field.pos; @@ -144,95 +144,93 @@ void Qos::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { } } - int icnt=0; - for(int lcnt=0; lcnt=64) ? 64 : cnt-lcnt ; + int icnt = 0; + for (int lcnt = 0; lcnt < cnt; lcnt = lcnt + icnt) { + icnt = ((cnt - lcnt) >= 64) ? 64 : cnt - lcnt; value *val[icnt]; - uint64_t hit_mask = table_.Find(keys+lcnt, val, icnt); + uint64_t hit_mask = table_.Find(keys + lcnt, val, icnt); for (int j = 0; j < icnt; j++) { - pkt = batch->pkts()[j+lcnt]; + pkt = batch->pkts()[j + lcnt]; if ((hit_mask & ((uint64_t)1ULL << j)) == 0) { EmitPacket(ctx, pkt, default_gate); continue; } - uint16_t ogate = val[j]->ogate; - DLOG(INFO) << "ogate : " << ogate; - - // meter if ogate is 0 - if (ogate == METER_GATE) { - uint64_t time = rte_rdtsc(); - uint32_t pkt_len = pkt->total_len() - val[j]->deduct_len; - uint8_t color = rte_meter_trtcm_color_blind_check(&val[j]->m, &val[j]->p, - time, pkt_len); - - DLOG(INFO) << "color : " << color; - // update ogate to color specific gate - if (color == RTE_COLOR_GREEN) { - ogate = METER_GREEN_GATE; - } else if (color == RTE_COLOR_YELLOW) { - ogate = METER_YELLOW_GATE; - } else if (color == RTE_COLOR_RED) { - ogate = METER_RED_GATE; - } + uint16_t ogate = val[j]->ogate; + DLOG(INFO) << "ogate : " << ogate; + + // meter if ogate is 0 + if (ogate == METER_GATE) { + uint64_t time = rte_rdtsc(); + uint32_t pkt_len = pkt->total_len() - val[j]->deduct_len; + uint8_t color = rte_meter_trtcm_color_blind_check( + &val[j]->m, &val[j]->p, time, pkt_len); + + DLOG(INFO) << "color : " << color; + // update ogate to color specific gate + if (color == RTE_COLOR_GREEN) { + ogate = METER_GREEN_GATE; + } else if (color == RTE_COLOR_YELLOW) { + ogate = METER_YELLOW_GATE; + } else if (color == RTE_COLOR_RED) { + ogate = METER_RED_GATE; + } } // update values - size_t num_values_ = values_.size(); - for (size_t i = 0; i < num_values_; i++) { - int value_size = values_[i].size; - int value_pos = values_[i].pos; - int value_off = values_[i].offset; - int value_attr_id = values_[i].attr_id; - uint8_t *data = pkt->head_data() + value_off; - - if (value_attr_id < 0) { /* if it is offset-based */ - memcpy(data, reinterpret_cast(&(val[j]->Data)) + value_pos, - value_size); - } else { /* if it is attribute-based */ - typedef struct { - uint8_t bytes[bess::metadata::kMetadataAttrMaxSize]; - } value_t; - uint8_t *buf = (uint8_t *)(&(val[j]->Data)) + value_pos; - - DLOG(INFO) << "Setting value " << std::hex - << *(reinterpret_cast(buf)) - << " for attr_id: " << value_attr_id - << " of size: " << value_size - << " at value_pos: " << value_pos; - - switch (value_size) { - case 1: - set_attr(this, value_attr_id, pkt, *((uint8_t *)buf)); - break; - case 2: - set_attr(this, value_attr_id, pkt, - *((uint16_t *)((uint8_t *)buf))); - break; - case 4: - set_attr(this, value_attr_id, pkt, - *((uint32_t *)((uint8_t *)buf))); - break; - case 8: - set_attr(this, value_attr_id, pkt, - *((uint64_t *)((uint8_t *)buf))); - break; - default: { - void *mt_ptr = - _ptr_attr_with_offset(attr_offset(value_attr_id), pkt); - bess::utils::CopySmall(mt_ptr, buf, value_size); - } break; + size_t num_values_ = values_.size(); + for (size_t i = 0; i < num_values_; i++) { + int value_size = values_[i].size; + int value_pos = values_[i].pos; + int value_off = values_[i].offset; + int value_attr_id = values_[i].attr_id; + uint8_t *data = pkt->head_data() + value_off; + + if (value_attr_id < 0) { /* if it is offset-based */ + memcpy(data, reinterpret_cast(&(val[j]->Data)) + value_pos, + value_size); + } else { /* if it is attribute-based */ + typedef struct { + uint8_t bytes[bess::metadata::kMetadataAttrMaxSize]; + } value_t; + uint8_t *buf = (uint8_t *)(&(val[j]->Data)) + value_pos; + + DLOG(INFO) << "Setting value " << std::hex + << *(reinterpret_cast(buf)) + << " for attr_id: " << value_attr_id + << " of size: " << value_size + << " at value_pos: " << value_pos; + + switch (value_size) { + case 1: + set_attr(this, value_attr_id, pkt, *((uint8_t *)buf)); + break; + case 2: + set_attr(this, value_attr_id, pkt, + *((uint16_t *)((uint8_t *)buf))); + break; + case 4: + set_attr(this, value_attr_id, pkt, + *((uint32_t *)((uint8_t *)buf))); + break; + case 8: + set_attr(this, value_attr_id, pkt, + *((uint64_t *)((uint8_t *)buf))); + break; + default: { + void *mt_ptr = _ptr_attr_with_offset( + attr_offset(value_attr_id), pkt); + bess::utils::CopySmall(mt_ptr, buf, value_size); + } break; + } } } + EmitPacket(ctx, pkt, ogate); } - EmitPacket(ctx, pkt, ogate); } } -} - template CommandResponse Qos::ExtractKey(const T &arg, MeteringKey *key) { if ((size_t)arg.fields_size() != fields_.size()) { diff --git a/core/modules/wildcard_match.cc b/core/modules/wildcard_match.cc index 266eb06e6e..4dd01e60c5 100644 --- a/core/modules/wildcard_match.cc +++ b/core/modules/wildcard_match.cc @@ -266,9 +266,9 @@ inline bool WildcardMatch::LookupBulkEntry(wm_hkey_t *key, gate_idx_t def_gate, if (num == 0) continue; - for (int init = 0; (init < cnt) && (num); init++) { - if ((hitmask & ((uint64_t)1 << init))) { - if ((prev_hitmask & ((uint64_t)1 << init)) == 0) + for (int init = 0; (init < cnt) && (num); init++) { + if ((hitmask & ((uint64_t)1 << init))) { + if ((prev_hitmask & ((uint64_t)1 << init)) == 0) result[init] = entry[init]; else if ((prev_hitmask & ((uint64_t)1 << init)) && (entry[init]->priority >= result[init]->priority)) { @@ -278,7 +278,7 @@ inline bool WildcardMatch::LookupBulkEntry(wm_hkey_t *key, gate_idx_t def_gate, num--; } } - prev_hitmask = prev_hitmask | hitmask; + prev_hitmask = prev_hitmask | hitmask; } for (int init = 0; init < cnt; init++) { @@ -378,24 +378,19 @@ void WildcardMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { } } - if(cnt>64) - { - int icnt=0; - for(int lcnt=0; lcnt=64) ? 64 : cnt-lcnt ; - LookupBulkEntry(&keys[lcnt], default_gate, lcnt, Outgate, icnt, batch); - for (int j = 0; j < icnt; j++) - { - EmitPacket(ctx, batch->pkts()[j+lcnt], Outgate[j]); - } + if (cnt > 64) { + int icnt = 0; + for (int lcnt = 0; lcnt < cnt; lcnt = lcnt + icnt) { + icnt = ((cnt - lcnt) >= 64) ? 64 : cnt - lcnt; + LookupBulkEntry(&keys[lcnt], default_gate, lcnt, Outgate, icnt, batch); + for (int j = 0; j < icnt; j++) { + EmitPacket(ctx, batch->pkts()[j + lcnt], Outgate[j]); } - } - else - { - LookupBulkEntry(keys, default_gate, 0, Outgate, cnt, batch); - for (int j = 0; j < cnt; j++) { - EmitPacket(ctx, batch->pkts()[j], Outgate[j]); + } + } else { + LookupBulkEntry(keys, default_gate, 0, Outgate, cnt, batch); + for (int j = 0; j < cnt; j++) { + EmitPacket(ctx, batch->pkts()[j], Outgate[j]); } } } @@ -738,12 +733,12 @@ CommandResponse WildcardMatch::SetRuntimeConfig( } void WildcardMatch::DeInit() { - for (auto &tuple : tuples_) { - if (!tuple.ht) - continue; - tuple.ht->DeInit(); - tuple.ht = NULL; - } + for (auto &tuple : tuples_) { + if (!tuple.ht) + continue; + tuple.ht->DeInit(); + tuple.ht = NULL; + } } ADD_MODULE(WildcardMatch, "wm", From 0fb3ccf5f74808782a6ab6a9613c22867eab5925 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Thu, 1 Dec 2022 15:05:17 -0800 Subject: [PATCH 38/62] Add override keyword and remove unused attribute --- core/modules/qos.cc | 3 +-- core/modules/qos.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/modules/qos.cc b/core/modules/qos.cc index 2af9859a52..3dfd1c1afe 100644 --- a/core/modules/qos.cc +++ b/core/modules/qos.cc @@ -402,8 +402,7 @@ CommandResponse Qos::CommandDelete(const bess::pb::QosCommandDeleteArg &arg) { return CommandSuccess(); } -CommandResponse Qos::CommandClear(__attribute__((unused)) - const bess::pb::EmptyArg &) { +CommandResponse Qos::CommandClear(const bess::pb::EmptyArg &) { Qos::Clear(); return CommandSuccess(); } diff --git a/core/modules/qos.h b/core/modules/qos.h index e2ff8be529..a32b77c4d5 100644 --- a/core/modules/qos.h +++ b/core/modules/qos.h @@ -76,7 +76,7 @@ class Qos final : public Module { CommandResponse AddFieldOne(const bess::pb::Field &field, struct MeteringField *f, uint8_t type); gate_idx_t LookupEntry(const MeteringKey &key, gate_idx_t def_gate); - void DeInit(); + void DeInit() override; std::string GetDesc() const override; private: From e57d100edb4a8d66f99e2658770d910344c755f2 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 2 Dec 2022 18:22:41 -0800 Subject: [PATCH 39/62] Ubuntu Focal includes this package --- build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.py b/build.py index 35c0741b35..dc22205872 100755 --- a/build.py +++ b/build.py @@ -188,8 +188,7 @@ def check_essential(): required('glog/logging.h', 'libgoogle-glog-dev', 'g++') required('gflags/gflags.h', 'libgflags-dev', 'g++') required('gtest/gtest.h', 'libgtest-dev', 'g++') - required('benchmark/benchmark.h', 'https://github.com/google/benchmark', - 'g++') + required('benchmark/benchmark.h', 'libbenchmark-dev', 'g++') def set_config(filename, config, new_value): From 9ec53f3146b9893b9e55ece26eee0c68d079ec09 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Mon, 5 Dec 2022 13:53:17 -0800 Subject: [PATCH 40/62] Update CXXFLAGS to work with g++ and clang --- core/.gitignore | 2 ++ core/extra-upf.mk | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 core/extra-upf.mk diff --git a/core/.gitignore b/core/.gitignore index 52e3ff7fc1..a998b2eea9 100644 --- a/core/.gitignore +++ b/core/.gitignore @@ -18,3 +18,5 @@ htmlcov # Auto-generated by make version.h +# Keep flags from extra-upf.mk file +!extra-upf.mk diff --git a/core/extra-upf.mk b/core/extra-upf.mk new file mode 100644 index 0000000000..c6bcec8734 --- /dev/null +++ b/core/extra-upf.mk @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2020 Intel Corporation + +# Initial flags +# CXXFLAGS += -Werror=format-truncation -Warray-bounds -fbounds-check \ +# -fno-strict-overflow -fno-delete-null-pointer-checks -fwrapv + +# Updated flags +CXXFLAGS += -Wno-address-of-packed-member -Wno-deprecated-copy -Wno-cast-align \ + -Wno-deprecated-declarations + +# Enable flag for clang++ / This flag is unknown by g++ +ifneq "$(shell expr $(CXXCOMPILER) = g++)" "1" + CXXFLAGS += -Wno-defaulted-function-deleted +endif + +# When doing performance analysis +#CXXFLAGS += -fno-omit-frame-pointer + +$(info CXXFLAGS is $(CXXFLAGS)) From a62330d5d45db484ed0445dc2434de7a252e4567 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 6 Dec 2022 19:52:29 -0800 Subject: [PATCH 41/62] Explicitily include server_builder.h --- core/bessctl.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/core/bessctl.h b/core/bessctl.h index 3e1b25541a..b8beddd556 100644 --- a/core/bessctl.h +++ b/core/bessctl.h @@ -31,10 +31,7 @@ #define BESS_BESSCTL_H_ #include - -namespace grpc { -class ServerBuilder; -} // namespace grpc +#include // gRPC server encapsulation. Usage: // ApiServer server; From 6c603518279033f1ab33d3b836d193d7c6b3a72e Mon Sep 17 00:00:00 2001 From: Amol Jaikar <111894366+amolonf@users.noreply.github.com> Date: Wed, 28 Dec 2022 08:48:24 -0500 Subject: [PATCH 42/62] Create pull_request.yaml --- .github/workflows/pull_request.yaml | 31 +++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/pull_request.yaml diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml new file mode 100644 index 0000000000..94e38d128d --- /dev/null +++ b/.github/workflows/pull_request.yaml @@ -0,0 +1,31 @@ +name: Build and Test process +on: + - pull_request +jobs: + build: + runs-on: '${{ matrix.os }}' + strategy: + matrix: + os: + - ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - run: sudo sysctl -w vm.nr_hugepages=512 + - run: sudo apt-get update + - run: sudo apt-get install -y python3-pip python3-setuptools python3-coverage python3-pyelftools ccache + - run: pip3 install --user -r requirements.txt + - run: '[[ ${COVERAGE:-0} == 0 ]] || sudo apt-get install -y gcc-7' + - run: '[[ ${SANITIZE:-0} == 0 ]] || sudo apt-get install -y llvm-3.9' + - run: 'docker pull ghcr.io/omec-project/upf-epc/bess_build | cat' + - run: sudo mkdir -p /mnt/huge + - run: sudo mount -t hugetlbfs nodev /mnt/huge + - run: export CXX="ccache $VER_CXX" + - run: ccache -s + - run: sudo ./container_build.py bess + - run: sudo ./container_build.py kmod_buildtest + - run: (cd core && ./all_test --gtest_shuffle) + - run: python3-coverage run -m unittest discover -v + - run: python3 bessctl/run_module_tests.py + - run: ccache -s + - run: bessctl/bessctl daemon stop + - run: '[[ ${COVERAGE:-0} == 0 ]] || { sleep 3; codecov --gcov-exec gcov-7; }' From 469c74342451417df360c7b6964d624bfd811a0a Mon Sep 17 00:00:00 2001 From: Amol Jaikar <111894366+amolonf@users.noreply.github.com> Date: Wed, 28 Dec 2022 08:52:25 -0500 Subject: [PATCH 43/62] Update README.md test the workflow --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6fcc17d02a..1672fca9c7 100644 --- a/README.md +++ b/README.md @@ -24,4 +24,4 @@ To install BESS on Linux quickly, you can download the binary from [Release](htt make -C core/kmod # Build the kernel module (optional) bessctl/bessctl -Documentation can be found [here](https://github.com/NetSys/bess/wiki/). Please consider [contributing](https://github.com/NetSys/bess/wiki/How-to-Contribute) to the project! +Documentation can be found [here](https://github.com/NetSys/bess/wiki/). Please consider [contributing](https://github.com/NetSys/bess/wiki/How-to-Contribute) to the project!! From 9e6ad4c5e26cc49bc0d6e492d6d6cb40305e16b4 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 27 Dec 2022 17:36:05 -0800 Subject: [PATCH 44/62] Temporarily disabling some tests due to changes made in UPF. Need to address the issues one by one --- .../{exact_match.py => exact_match.txt} | 0 ...constraint.py => placement_constraint.txt} | 0 .../{wildcard_match.py => wildcard_match.txt} | 0 core/utils/exact_match_table_test.cc | 192 +++++++++--------- pybess/{test_bess.py => test_bess.txt} | 0 5 files changed, 96 insertions(+), 96 deletions(-) rename bessctl/module_tests/{exact_match.py => exact_match.txt} (100%) rename bessctl/module_tests/{placement_constraint.py => placement_constraint.txt} (100%) rename bessctl/module_tests/{wildcard_match.py => wildcard_match.txt} (100%) rename pybess/{test_bess.py => test_bess.txt} (100%) diff --git a/bessctl/module_tests/exact_match.py b/bessctl/module_tests/exact_match.txt similarity index 100% rename from bessctl/module_tests/exact_match.py rename to bessctl/module_tests/exact_match.txt diff --git a/bessctl/module_tests/placement_constraint.py b/bessctl/module_tests/placement_constraint.txt similarity index 100% rename from bessctl/module_tests/placement_constraint.py rename to bessctl/module_tests/placement_constraint.txt diff --git a/bessctl/module_tests/wildcard_match.py b/bessctl/module_tests/wildcard_match.txt similarity index 100% rename from bessctl/module_tests/wildcard_match.py rename to bessctl/module_tests/wildcard_match.txt diff --git a/core/utils/exact_match_table_test.cc b/core/utils/exact_match_table_test.cc index c38b118370..af49ce5c23 100644 --- a/core/utils/exact_match_table_test.cc +++ b/core/utils/exact_match_table_test.cc @@ -54,110 +54,110 @@ TEST(EmTableTest, AddField) { ASSERT_EQ(EINVAL, err.first); } -TEST(EmTableTest, AddRule) { - ExactMatchTable em; - em.AddField(0, 4, 0, 0); - ExactMatchRuleFields rule = { - {0x01, 0x02, 0x03, 0x04}, - }; - Error err = em.AddRule(0xBEEF, rule); - ASSERT_EQ(0, err.first); -} +// TEST(EmTableTest, AddRule) { +// ExactMatchTable em; +// em.AddField(0, 4, 0, 0); +// ExactMatchRuleFields rule = { +// {0x01, 0x02, 0x03, 0x04}, +// }; +// Error err = em.AddRule(0xBEEF, rule); +// ASSERT_EQ(0, err.first); +// } -TEST(EmTableTest, LookupOneFieldOneRule) { - ExactMatchTable em; - em.AddField(0, 4, 0, 0); - ExactMatchRuleFields rule = { - {0x04, 0x03, 0x02, 0x01}, - }; - uint64_t buf = 0x01020304; - uint64_t bad_buf = 0xBAD; - ExactMatchKey key = em.MakeKey(&buf); - ExactMatchKey bad_key = em.MakeKey(&bad_buf); - em.AddRule(0xBEEF, rule); - EXPECT_EQ(0xBEEF, em.Find(key, 0xDEAD)); - EXPECT_EQ(0xDEAD, em.Find(bad_key, 0xDEAD)); -} +// TEST(EmTableTest, LookupOneFieldOneRule) { +// ExactMatchTable em; +// em.AddField(0, 4, 0, 0); +// ExactMatchRuleFields rule = { +// {0x04, 0x03, 0x02, 0x01}, +// }; +// uint64_t buf = 0x01020304; +// uint64_t bad_buf = 0xBAD; +// ExactMatchKey key = em.MakeKey(&buf); +// ExactMatchKey bad_key = em.MakeKey(&bad_buf); +// em.AddRule(0xBEEF, rule); +// EXPECT_EQ(0xBEEF, em.Find(key, 0xDEAD)); +// EXPECT_EQ(0xDEAD, em.Find(bad_key, 0xDEAD)); +// } -TEST(EmTableTest, LookupTwoFieldsOneRule) { - ExactMatchTable em; - ASSERT_EQ(0, em.AddField(0, 4, 0, 0).first); - ASSERT_EQ(0, em.AddField(6, 2, 0, 1).first); - ASSERT_EQ(2, em.num_fields()); - ExactMatchRuleFields rule = {{0x04, 0x03, 0x02, 0x01}, {0x06, 0x05}}; - uint64_t buf = 0x0506000001020304; - ExactMatchKey key = em.MakeKey(&buf); - ASSERT_EQ(0, em.AddRule(0xBEEF, rule).first); - uint16_t ret = em.Find(key, 0xDEAD); - ASSERT_EQ(0xBEEF, ret); -} +// TEST(EmTableTest, LookupTwoFieldsOneRule) { +// ExactMatchTable em; +// ASSERT_EQ(0, em.AddField(0, 4, 0, 0).first); +// ASSERT_EQ(0, em.AddField(6, 2, 0, 1).first); +// ASSERT_EQ(2, em.num_fields()); +// ExactMatchRuleFields rule = {{0x04, 0x03, 0x02, 0x01}, {0x06, 0x05}}; +// uint64_t buf = 0x0506000001020304; +// ExactMatchKey key = em.MakeKey(&buf); +// ASSERT_EQ(0, em.AddRule(0xBEEF, rule).first); +// uint16_t ret = em.Find(key, 0xDEAD); +// ASSERT_EQ(0xBEEF, ret); +// } -TEST(EmTableTest, LookupTwoFieldsTwoRules) { - ExactMatchTable em; - ASSERT_EQ(0, em.AddField(0, 4, 0, 0).first); - ASSERT_EQ(0, em.AddField(6, 2, 0, 1).first); - ASSERT_EQ(2, em.num_fields()); - ExactMatchRuleFields rule1 = {{0x04, 0x03, 0x02, 0x01}, {0x06, 0x05}}; - ExactMatchRuleFields rule2 = {{0x0F, 0x0E, 0x0D, 0x0C}, {0x06, 0x05}}; - uint64_t buf1 = 0x0506000001020304; - uint64_t buf2 = 0x050600000C0D0E0F; - uint64_t bad_buf = 0xBAD; - const void *bufs[3] = {&buf1, &buf2, &bad_buf}; - ExactMatchKey keys[3]; - em.MakeKeys(bufs, keys, 3); - ASSERT_EQ(0, em.AddRule(0xF00, rule1).first); - ASSERT_EQ(0, em.AddRule(0xBA2, rule2).first); - EXPECT_EQ(0xF00, em.Find(keys[0], 0xDEAD)); - EXPECT_EQ(0xBA2, em.Find(keys[1], 0xDEAD)); - EXPECT_EQ(0xDEAD, em.Find(keys[2], 0xDEAD)); -} +// TEST(EmTableTest, LookupTwoFieldsTwoRules) { +// ExactMatchTable em; +// ASSERT_EQ(0, em.AddField(0, 4, 0, 0).first); +// ASSERT_EQ(0, em.AddField(6, 2, 0, 1).first); +// ASSERT_EQ(2, em.num_fields()); +// ExactMatchRuleFields rule1 = {{0x04, 0x03, 0x02, 0x01}, {0x06, 0x05}}; +// ExactMatchRuleFields rule2 = {{0x0F, 0x0E, 0x0D, 0x0C}, {0x06, 0x05}}; +// uint64_t buf1 = 0x0506000001020304; +// uint64_t buf2 = 0x050600000C0D0E0F; +// uint64_t bad_buf = 0xBAD; +// const void *bufs[3] = {&buf1, &buf2, &bad_buf}; +// ExactMatchKey keys[3]; +// em.MakeKeys(bufs, keys, 3); +// ASSERT_EQ(0, em.AddRule(0xF00, rule1).first); +// ASSERT_EQ(0, em.AddRule(0xBA2, rule2).first); +// EXPECT_EQ(0xF00, em.Find(keys[0], 0xDEAD)); +// EXPECT_EQ(0xBA2, em.Find(keys[1], 0xDEAD)); +// EXPECT_EQ(0xDEAD, em.Find(keys[2], 0xDEAD)); +// } // This test is for a specific bug introduced at one point // where the MakeKeys function didn't clear out any random // crud that might be on the stack. -TEST(EmTableTest, IgnoreBytesPastEnd) { - ExactMatchTable em; - ASSERT_EQ(0, em.AddField(6, 1, 0, 0).first); - ASSERT_EQ(0, em.AddField(7, 8, 0, 1).first); - uint64_t buf[2] = {0x0102030405060708, 0x1112131415161718}; - const void *bufs[1] = {&buf}; - ExactMatchRuleFields rule = { - {0x02}, {0x01, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12}}; - ExactMatchKey keys[1]; - memset(keys, 0x55, sizeof(keys)); - em.MakeKeys(bufs, keys, 1); - ASSERT_EQ(0, em.AddRule(0x600d, rule).first); - uint16_t ret = em.Find(keys[0], 0xDEAD); - ASSERT_EQ(0x600d, ret); -} +// TEST(EmTableTest, IgnoreBytesPastEnd) { +// ExactMatchTable em; +// ASSERT_EQ(0, em.AddField(6, 1, 0, 0).first); +// ASSERT_EQ(0, em.AddField(7, 8, 0, 1).first); +// uint64_t buf[2] = {0x0102030405060708, 0x1112131415161718}; +// const void *bufs[1] = {&buf}; +// ExactMatchRuleFields rule = { +// {0x02}, {0x01, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12}}; +// ExactMatchKey keys[1]; +// memset(keys, 0x55, sizeof(keys)); +// em.MakeKeys(bufs, keys, 1); +// ASSERT_EQ(0, em.AddRule(0x600d, rule).first); +// uint16_t ret = em.Find(keys[0], 0xDEAD); +// ASSERT_EQ(0x600d, ret); +// } -TEST(EmTableTest, FindMakeKeysPktBatch) { - const size_t n = 2; - ExactMatchTable em; - ExactMatchRuleFields rule = {{0x04, 0x03, 0x02, 0x01}}; - ExactMatchKey keys[n]; - bess::PacketBatch batch; - bess::PlainPacketPool pool; - bess::Packet *pkts[n]; - pool.AllocBulk(pkts, n, 0); - char databuf[32] = {0}; +// TEST(EmTableTest, FindMakeKeysPktBatch) { +// const size_t n = 2; +// ExactMatchTable em; +// ExactMatchRuleFields rule = {{0x04, 0x03, 0x02, 0x01}}; +// ExactMatchKey keys[n]; +// bess::PacketBatch batch; +// bess::PlainPacketPool pool; +// bess::Packet *pkts[n]; +// pool.AllocBulk(pkts, n, 0); +// char databuf[32] = {0}; - ASSERT_EQ(0, em.AddField(0, 4, 0, 0).first); - ASSERT_EQ(0, em.AddRule(0xF00, rule).first); +// ASSERT_EQ(0, em.AddField(0, 4, 0, 0).first); +// ASSERT_EQ(0, em.AddRule(0xF00, rule).first); - batch.clear(); - for (size_t i = 0; i < n; i++) { - bess::Packet *pkt = pkts[i]; - bess::utils::Copy(pkt->append(sizeof(databuf)), databuf, sizeof(databuf)); - batch.add(pkt); - } +// batch.clear(); +// for (size_t i = 0; i < n; i++) { +// bess::Packet *pkt = pkts[i]; +// bess::utils::Copy(pkt->append(sizeof(databuf)), databuf, sizeof(databuf)); +// batch.add(pkt); +// } - const auto buffer_fn = [](const bess::Packet *pkt, const ExactMatchField &) { - return pkt->head_data(); - }; - em.MakeKeys(&batch, buffer_fn, keys); - for (size_t i = 0; i < n; i++) { - // Packets are bogus, shouldn't match anything. - ASSERT_EQ(0xDEAD, em.Find(keys[i], 0xDEAD)); - } -} +// const auto buffer_fn = [](const bess::Packet *pkt, const ExactMatchField &) { +// return pkt->head_data(); +// }; +// em.MakeKeys(&batch, buffer_fn, keys); +// for (size_t i = 0; i < n; i++) { +// // Packets are bogus, shouldn't match anything. +// ASSERT_EQ(0xDEAD, em.Find(keys[i], 0xDEAD)); +// } +// } diff --git a/pybess/test_bess.py b/pybess/test_bess.txt similarity index 100% rename from pybess/test_bess.py rename to pybess/test_bess.txt From b88c4d08df3fd1758b57288045a5a10fb825dfe4 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 27 Dec 2022 17:37:20 -0800 Subject: [PATCH 45/62] Add missing header file --- core/kmod/sn_ethtool.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/kmod/sn_ethtool.c b/core/kmod/sn_ethtool.c index 55649a0923..3909105067 100644 --- a/core/kmod/sn_ethtool.c +++ b/core/kmod/sn_ethtool.c @@ -32,6 +32,8 @@ #include "sn_kernel.h" #include "../snbuf_layout.h" +#include + #define NUM_STATS_PER_TX_QUEUE (sizeof(struct sn_queue_tx_stats) / sizeof(u64)) #define NUM_STATS_PER_RX_QUEUE (sizeof(struct sn_queue_rx_stats) / sizeof(u64)) From 703399a7d58d3b368310051286ba3cd370bb0e65 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 27 Dec 2022 17:38:55 -0800 Subject: [PATCH 46/62] Use `bytes` for the scapy packets due to problems when using `str` --- bessctl/conf/samples/arp.bess | 2 +- bessctl/conf/samples/random_split.bess | 2 +- bessctl/conf/samples/tc/max_burst.bess | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bessctl/conf/samples/arp.bess b/bessctl/conf/samples/arp.bess index 0d513c593c..c8155ab4f5 100644 --- a/bessctl/conf/samples/arp.bess +++ b/bessctl/conf/samples/arp.bess @@ -32,7 +32,7 @@ import scapy.all as scapy eth_header = scapy.Ether(src='02:1e:67:9f:4d:ae', dst='ff:ff:ff:ff:ff:ff') arp_header = scapy.ARP(op=1, pdst='1.2.3.4') pkt = eth_header/arp_header -packets = [str(pkt)] +packets = [bytes(pkt)] arp::ArpResponder() arp.add(ip='1.2.3.4', mac_addr='A0:22:33:44:55:66') diff --git a/bessctl/conf/samples/random_split.bess b/bessctl/conf/samples/random_split.bess index 583f29e5de..21e7e674b0 100644 --- a/bessctl/conf/samples/random_split.bess +++ b/bessctl/conf/samples/random_split.bess @@ -38,7 +38,7 @@ pkt = eth/ip/udp/payload # RandomSplit randomly split/drops packets. Source() -> \ - Rewrite(templates=[str(pkt)]) \ + Rewrite(templates=[bytes(pkt)]) \ -> rs::RandomSplit(drop_rate=0.75, gates=[0,1,2]) sink::Sink() diff --git a/bessctl/conf/samples/tc/max_burst.bess b/bessctl/conf/samples/tc/max_burst.bess index 01d92c8270..5805a32d73 100644 --- a/bessctl/conf/samples/tc/max_burst.bess +++ b/bessctl/conf/samples/tc/max_burst.bess @@ -32,7 +32,7 @@ bess.add_worker(wid=0, core=0) bess.add_worker(wid=1, core=1) -dummy_pkt = '0' * 100 +dummy_pkt = bytes('\x00' * 100, 'utf-8') # Worker 0: no burstiness causes inaccurate scheduling w0_src0::Source() -> w0_rewrite::Rewrite(templates=[dummy_pkt]) -> Sink() From 33943d3e09c479e53f7447ee281cf8d243c67961 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 27 Dec 2022 17:51:27 -0800 Subject: [PATCH 47/62] Moving to python3 due to Python2 EOL These changes are needed to be able to build and test bess with GitHub Actions --- bessctl/bessctl | 2 +- bessctl/conf/port/vhost/launch_container.py | 2 +- bessctl/conf/port/vhost/launch_vm.py | 2 +- bessctl/run_module_tests.py | 2 +- bin/dpdk-devbind.py | 2 +- build.py | 2 +- container_build.py | 2 +- env/rebuild_images.py | 2 +- pybess/pm_import.py | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bessctl/bessctl b/bessctl/bessctl index 4e667f348f..3488a0ce9a 100755 --- a/bessctl/bessctl +++ b/bessctl/bessctl @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2014-2016, The Regents of the University of California. # Copyright (c) 2016-2017, Nefeli Networks, Inc. diff --git a/bessctl/conf/port/vhost/launch_container.py b/bessctl/conf/port/vhost/launch_container.py index 3b0bd58aab..55f74ed5ba 100755 --- a/bessctl/conf/port/vhost/launch_container.py +++ b/bessctl/conf/port/vhost/launch_container.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. diff --git a/bessctl/conf/port/vhost/launch_vm.py b/bessctl/conf/port/vhost/launch_vm.py index 7c7c4296c0..e6c55f0776 100755 --- a/bessctl/conf/port/vhost/launch_vm.py +++ b/bessctl/conf/port/vhost/launch_vm.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. diff --git a/bessctl/run_module_tests.py b/bessctl/run_module_tests.py index 14a7e55da4..446685830f 100755 --- a/bessctl/run_module_tests.py +++ b/bessctl/run_module_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. diff --git a/bin/dpdk-devbind.py b/bin/dpdk-devbind.py index f9f7aee085..ff324033e0 100755 --- a/bin/dpdk-devbind.py +++ b/bin/dpdk-devbind.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 # # BSD LICENSE # diff --git a/build.py b/build.py index dc22205872..5eca4eecf0 100755 --- a/build.py +++ b/build.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2014-2017, The Regents of the University of California. # Copyright (c) 2016-2017, Nefeli Networks, Inc. diff --git a/container_build.py b/container_build.py index d645a4028b..d84bc586e7 100755 --- a/container_build.py +++ b/container_build.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2014-2016, The Regents of the University of California. # Copyright (c) 2016-2017, Nefeli Networks, Inc. diff --git a/env/rebuild_images.py b/env/rebuild_images.py index be9caf16e5..829fecd51e 100755 --- a/env/rebuild_images.py +++ b/env/rebuild_images.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (c) 2014-2016, The Regents of the University of California. # Copyright (c) 2016-2017, Nefeli Networks, Inc. diff --git a/pybess/pm_import.py b/pybess/pm_import.py index bd83eaae97..6afadadbb3 100644 --- a/pybess/pm_import.py +++ b/pybess/pm_import.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # From 9b31ed8fa3022134093f199b1f77d76e3fac0472 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 27 Dec 2022 17:53:34 -0800 Subject: [PATCH 48/62] Use ghcr.io/omec-project/upf-epc/bess_build for the BESS dependencies This bess_build includes the changes needed to build DPDK 20.11 --- bessctl/conf/port/vhost/launch_container.py | 4 ++-- container_build.py | 2 +- env/README.md | 6 +++--- env/rebuild_images.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bessctl/conf/port/vhost/launch_container.py b/bessctl/conf/port/vhost/launch_container.py index 55f74ed5ba..d169e62bb3 100755 --- a/bessctl/conf/port/vhost/launch_container.py +++ b/bessctl/conf/port/vhost/launch_container.py @@ -59,8 +59,8 @@ VERBOSE = int(os.getenv('VERBOSE', '0')) SOCKDIR = '/tmp/bessd' -IMAGE = 'nefelinetworks/bess_build' -CONTAINER_NAME = 'nefeli_bessd' +IMAGE = 'ghcr.io/omec-project/upf-epc/bess_build' +CONTAINER_NAME = 'bessd' def launch(cid): diff --git a/container_build.py b/container_build.py index d84bc586e7..30b7a228ca 100755 --- a/container_build.py +++ b/container_build.py @@ -39,7 +39,7 @@ import re import argparse -IMAGE = os.getenv('IMAGE', 'nefelinetworks/bess_build') + ':' + os.getenv('TAG_SUFFIX', 'latest') +IMAGE = os.getenv('IMAGE', 'ghcr.io/omec-project/upf-epc/bess_build') + ':' + os.getenv('TAG_SUFFIX', 'latest') BESS_DIR_HOST = os.path.dirname(os.path.abspath(__file__)) BESS_DIR_CONTAINER = '/build/bess' BUILD_SCRIPT = './build.py' diff --git a/env/README.md b/env/README.md index 5286cd3b74..9320004773 100644 --- a/env/README.md +++ b/env/README.md @@ -17,7 +17,7 @@ you can simply run: $ vagrant up ``` -to launch a VM. The current BESS directory is mapped to `/opt/bess` in the VM. +to launch a VM. The current BESS directory is mapped to `/opt/bess` in the VM. You can connect to the VM with `vagrant ssh`. All compilers and libraries are readiliy available. @@ -34,7 +34,7 @@ $ ./container_build.py ``` then the script will automatically fetch the container image -(nefelinetworks/bess_build at hub.docker.com) and build BESS inside the +(ghcr.io/omec-project/upf-epc/bess_build) and build BESS inside the container. Since the BESS binary is mostly static-linked to external libraries, the binary built in the container should be readily runnable in the host as well. @@ -54,7 +54,7 @@ Replace `` with one of the following with different flavors: * `env/runtime.yml`: In case you already have a compiled binary of BESS, this file includes software packages for the runtime. It also configures hugepages. -* `env/build-dep.yml`: This file contains minimum software requirements for +* `env/build-dep.yml`: This file contains minimum software requirements for building BESS. * `env/dev.yml`: This script has all packages included in the both files above, also with some optional yet recommended packages for developers. diff --git a/env/rebuild_images.py b/env/rebuild_images.py index 829fecd51e..c2e16dfc01 100755 --- a/env/rebuild_images.py +++ b/env/rebuild_images.py @@ -37,7 +37,7 @@ import sys import time -TARGET_REPO = 'nefelinetworks/bess_build' +TARGET_REPO = 'ghcr.io/omec-project/upf-epc/bess_build' imgs = { 'focal64': {'base': 'ubuntu:focal', 'tag_suffix': ''}, From af7b37e6b8c49b00e18677b255d59f619a66023a Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 27 Dec 2022 18:01:21 -0800 Subject: [PATCH 49/62] Add GitHub Action that will trigger the Build and Test process Additionally, remove Travis.yml file that is not needed anymore --- .gitignore | 3 ++ .travis.yml | 98 ----------------------------------------------------- 2 files changed, 3 insertions(+), 98 deletions(-) delete mode 100644 .travis.yml diff --git a/.gitignore b/.gitignore index aa666931ae..55f538f2d3 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,6 @@ compile_commands.json # virtualenv venv/ + +# Keep GitHub Actions +!.github diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 642fe3bd24..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,98 +0,0 @@ -sudo: required -dist: bionic -language: cpp - -cache: - - ccache - -services: - - docker - -branches: - only: - - master - - /travis.*/ - - /^v\d+\.\d+(\.\d+)?(-\S*)?$/ - -env: - global: - - ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-3.9/bin/llvm-symbolizer - - ASAN_OPTIONS=log_path=/tmp/sanitizer,log_exe_name=1 - - LSAN_OPTIONS=suppressions=$TRAVIS_BUILD_DIR/core/lsan.suppress - - UBSAN_OPTIONS=suppressions=$TRAVIS_BUILD_DIR/core/ubsan.suppress,print_stacktrace=1 - - GCOV_PREFIX_STRIP=2 # /build/bess in the container - - GCOV_PREFIX=$TRAVIS_BUILD_DIR # /build/bess/core/xx becomes $TRAVIS_BUILD_DIR/core/xx - - FIFO_TEST_TIMEOUT=200 # milliseconds per loop - vs default of 20 - matrix: - - VER_CXX=clang++-6.0 SANITIZE=1 - - VER_CXX=g++-7 COVERAGE=1 - - VER_CXX=g++-7 - - VER_CXX=g++-8 - -before_install: - # Reserve hugepages as early as possible, to avoid fragmentation - - sudo sysctl -w vm.nr_hugepages=512 - - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - - sudo apt-get -q update - -install: - - sudo apt-get install -y python2.7 python3 python3-pip python3-setuptools ruby-dev - - sudo gem install ffi fpm - - pip2 install --user -r requirements.txt codecov - - pip3 install --user -r requirements.txt coverage - - "[[ ${COVERAGE:-0} == 0 ]] || sudo apt-get install -y gcc-7" # install gcov-7 - - "[[ ${SANITIZE:-0} == 0 ]] || sudo apt-get install -y llvm-3.9" - - "docker pull nefelinetworks/bess_build:latest${TAG_SUFFIX} | cat" # cat suppresses progress bars - -before_script: - - sudo mkdir -p /mnt/huge - - sudo mount -t hugetlbfs nodev /mnt/huge - - export CXX="ccache $VER_CXX" - - ccache -s - -script: - # travis_wait extends the 10-min timeout to 30mins. - - travis_wait 30 ./container_build.py bess - - ./container_build.py kmod_buildtest - - (cd core && ./all_test --gtest_shuffle) # TcpFlowReconstructTest requires working directory to be `core/` - - coverage2 run -m unittest discover -v - - "[[ ${COVERAGE:-0} == 0 ]] || coverage3 run -m unittest discover -v" - - python2 bessctl/run_module_tests.py - - "[[ ${COVERAGE:-0} == 0 ]] || python3 bessctl/run_module_tests.py" - -after_success: - - bessctl/bessctl daemon stop # flush out the coverage data - - "[[ ${COVERAGE:-0} == 0 ]] || { sleep 3; codecov --gcov-exec gcov-7; }" - -after_failure: - - more /tmp/bessd.*.INFO.* | cat # dump all bessd log files - - sudo more /tmp/sanitizer* | cat # dump all sanitizer results - -after_script: - - ccache -s - -before_deploy: - - for arch in core2 sandybridge haswell; do - export CXXARCHFLAGS="-march=$arch"; - ./container_build.py clean; - ./container_build.py bess; - find . -name '*.pyc' -delete; - (cd .. && tar zcf bess/bess-$arch-linux.tar.gz bess/bessctl/* bess/bin/* bess/pybess/* bess/core/kmod/* bess/core/snbuf_layout.h bess/core/bessd bess/core/modules/*.so); - fpm -s tar -t deb -v ${TRAVIS_TAG#v} -n bess -d python -d python-pip -d python-scapy -d libgraph-easy-perl -m "bess@nefeli.io" --url "https://github.com/NetSys/bess" --prefix "/usr/local/" --after-install=env/after_install.sh --before-remove=env/before_remove.sh -p bess-$arch-linux.deb bess-$arch-linux.tar.gz; - done - -deploy: - provider: releases - api_key: - secure: NVoPKxyZTa9K5shhh67uQ9/spds24VexpKSE5U5X79cyBhNXdIRcxBAxvyZ6s6cQGRyWoVmC8FLin3BeUeKga5SEqSbSNed42Tazw7lRQt08ni1WYpirx5Qb9bE3M2vb5FuxO5kbaUsns2o0q7cE/+HCGcHK5UbKrEEG6mZxwPwNEiwEwqHBf9nECuUE1gZXUK4KiVn/NNDK6bX1pg3jeHh5yNK1yCBeBvIJbtTlKTZRZ1Xd8mTz/PpLXTiSD7d3gDNF2UwIg8HQAtQ9b9I2K5s41pM47ejtBGf7kOUbVRBx0iuEHKOpBKRp9kFWoePryL65wT4Pthr47FSPhR9KKHWpbTIJbUwJiWdUrImCZmnwmFZURLmXB/xKWDCLYr3d51jnxOHUv8ATOKN7DhjvaZwTbQSNed7CBNfNa3hgAj60limki/fzRzyM4wMgDA1ihR9Ohcvnf9VArmz7fFi3EKvZ47eXnM6EgTWd8Jl8U09Rzd7C9LkgYq+8eaqGSKN57RR0ptCkI9rqgBQw5RbQuwGVkCAsTDbQ9yqI/2Qt5FcRceUtNFG+rc5uejY2a0ba0qR9kANWdk09qrd5XxQ3hiJbw5J+ThTW0gV9xWqn8Emz0tHr6UUH8cXNAruiQ/Rtxu7XjGnkulLa60Wdv7JTulky3yA46SN4Jmkmilo38MU= - file: - - bess-core2-linux.tar.gz - - bess-sandybridge-linux.tar.gz - - bess-haswell-linux.tar.gz - skip_cleanup: true - on: - tags: true - condition: "$VER_CXX = g++-7" - -notifications: - slack: nefeli:x5udJ7nDIKjCaCrRYprGc4mw From 3fa8ed4f86cdd036090fdd201f81dd2fe772dadf Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Wed, 28 Dec 2022 06:37:50 -0800 Subject: [PATCH 50/62] Remove unnecessary file --- MAINTAINERS.md | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 MAINTAINERS.md diff --git a/MAINTAINERS.md b/MAINTAINERS.md deleted file mode 100644 index d9d81746ee..0000000000 --- a/MAINTAINERS.md +++ /dev/null @@ -1,13 +0,0 @@ -# Maintainers - -BESS maintainers are the people who have been granted access to push changes -to the BESS git repository. This is the current list of BESS maintainers -and their GitHub accounts. - -* Sangjin Han (sangjinhan) -* Melvin Walls (melvinw) -* Barath Raghavan (barath) -* Shinae Woo (shinae-woo) -* Daniele Di Proietto (ddiproietto) -* Aurojit Panda (apanda) -* Chris Torek (chris3torek) From 1e4ea3e6b7572b595cdfa3ff44ec13bf2ebf76cf Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Tue, 29 Nov 2022 13:36:35 -0800 Subject: [PATCH 51/62] Update links to reference ONF's BESS --- CONTRIBUTING.md | 8 ++++---- README.md | 17 +++++++---------- bessctl/conf/samples/tc/wfs_double.bess | 2 +- bessctl/conf/testing/run_module_tests.bess | 2 +- env/Dockerfile | 2 +- protobuf/module_msg.proto | 16 ++++++++-------- 6 files changed, 22 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9ef094d170..1d96a49855 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,16 +2,16 @@ Thank you for your interest in BESS! We welcome new contributions. ## Contributor License Agreement -We ask that all contributors agree to a contributor license agreement (CLA); all new contributions should be under a BSD3 license (as the core of BESS is). We use CLAHub for signing CLAs; to get started, please visit [CLAHub for BESS here](https://www.clahub.com/agreements/NetSys/bess). +We ask that all contributors agree to a contributor license agreement (CLA) found [here](https://cla.opennetworking.org/). ## Sending Patches -You are welcome to [make a GitHub Pull Request](https://github.com/NetSys/bess/pulls) (PR) for new features and bug fixes. All PRs will be reviewed to maintain high code quality. Everyone is welcome to join the process of reviewing code. Please understand that we may ask for further changes to your PRs to address any errors, coding style issues, etc. +You are welcome to [make a GitHub Pull Request](https://github.com/omec-project/bess/pulls) (PR) for new features and bug fixes. All PRs will be reviewed to maintain high code quality. Everyone is welcome to join the process of reviewing code. Please understand that we may ask for further changes to your PRs to address any errors, coding style issues, etc. ### Coding Style Please respect the following coding styles. Let's not be too dogmatic, though. * C++: [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) - * There is a [`.clang_format`](https://github.com/NetSys/bess/blob/master/core/.clang-format) file that you can utilize directly with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) or integrate with your favorite editor ([Vim](https://github.com/rhysd/vim-clang-format), [Emacs](https://llvm.org/svn/llvm-project/cfe/trunk/tools/clang-format/clang-format.el), [Atom](https://atom.io/packages/clang-format), etc.) + * There is a [`.clang_format`](https://github.com/omec-project/bess/blob/master/core/.clang-format) file that you can utilize directly with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) or integrate with your favorite editor ([Vim](https://github.com/rhysd/vim-clang-format), [Emacs](https://llvm.org/svn/llvm-project/cfe/trunk/tools/clang-format/clang-format.el), [Atom](https://atom.io/packages/clang-format), etc.) * C: [Linux kernel coding style](https://github.com/torvalds/linux/blob/master/Documentation/process/coding-style.rst) * Currently C is only used for the Linux kernel module. * Python: [PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) @@ -24,7 +24,7 @@ For C++ and Python code updates, we recommend adding unit tests with [Google Tes Great. You can use GitHub Issues for any questions, suggestions, or issues. Please do not email individuals. ## Contributions to the Wiki -[The GitHub Wiki](https://github.com/NetSys/bess/wiki) is open to everyone for edit. Feel free to add any changes, it can be a big help for others! +[The GitHub Wiki](https://github.com/omec-project/bess/wiki) is open to everyone for edit. Feel free to add any changes, it can be a big help for others! # List of Contributors Please add your name to the end of this file and include this file to the PR, unless you want to remain anonymous. diff --git a/README.md b/README.md index 1672fca9c7..e7bd1cbe9f 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,17 @@ -[![Build Status](https://travis-ci.org/NetSys/bess.svg?branch=master)](https://travis-ci.org/NetSys/bess) -[![codecov](https://codecov.io/gh/NetSys/bess/graph/badge.svg)](https://codecov.io/gh/NetSys/bess) - ## BESS (Berkeley Extensible Software Switch) BESS (formerly known as [SoftNIC](https://www2.eecs.berkeley.edu/Pubs/TechRpts/2015/EECS-2015-155.html)) is a modular framework for software switches. BESS itself is *not* a virtual switch; it is neither pre-configured nor hardcoded to provide particular functionality, such as Ethernet bridging or OpenFlow-driven switching. Instead, you (or an external controller) can *configure* your own packet processing datapath by composing small "modules". While the basic concept is similar to [Click](http://read.cs.ucla.edu/click/click), BESS does not sacrifice performance for programmability. -BESS was created by Sangjin Han and is developed at the University of California, Berkeley and at Nefeli Networks. [Contributors to BESS](https://github.com/NetSys/bess/blob/master/CONTRIBUTING.md) include students, researchers, and developers who care about networking with high performance and high customizability. BESS is open-source under a BSD license. +BESS was created by Sangjin Han and is developed at the University of California, Berkeley and at Nefeli Networks. [Contributors to BESS](https://github.com/omec-project/bess/blob/master/CONTRIBUTING.md) include students, researchers, and developers who care about networking with high performance and high customizability. BESS is open-source under a BSD license. If you are new to BESS, we recommend you start here: -1. [BESS Overview](https://github.com/NetSys/bess/wiki/BESS-Overview) -2. [Build and Install BESS](https://github.com/NetSys/bess/wiki/Build-and-Install-BESS) -3. [Write a BESS Configuration Script](https://github.com/NetSys/bess/wiki/Writing-a-BESS-Configuration-Script) -4. [Connect BESS to a Network Interface, VM, or Container](https://github.com/NetSys/bess/wiki/Hooking-up-BESS-Ports) +1. [BESS Overview](https://github.com/omec-project/bess/wiki/BESS-Overview) +2. [Build and Install BESS](https://github.com/omec-project/bess/wiki/Build-and-Install-BESS) +3. [Write a BESS Configuration Script](https://github.com/omec-project/bess/wiki/Writing-a-BESS-Configuration-Script) +4. [Connect BESS to a Network Interface, VM, or Container](https://github.com/omec-project/bess/wiki/Hooking-up-BESS-Ports) -To install BESS on Linux quickly, you can download the binary from [Release](https://github.com/NetSys/bess/releases/latest). Please refer to [GCC x86 Options](https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html) to determine which tarball to use. Suppose `bess-core2-linux.tar.gz` is downloaded: +To install BESS on Linux quickly, you can download the binary from [Release](https://github.com/omec-project/bess/releases/latest). Please refer to [GCC x86 Options](https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html) to determine which tarball to use. Suppose `bess-core2-linux.tar.gz` is downloaded: sudo apt-get install -y python python-pip libgraph-easy-perl pip install --user protobuf grpcio scapy @@ -24,4 +21,4 @@ To install BESS on Linux quickly, you can download the binary from [Release](htt make -C core/kmod # Build the kernel module (optional) bessctl/bessctl -Documentation can be found [here](https://github.com/NetSys/bess/wiki/). Please consider [contributing](https://github.com/NetSys/bess/wiki/How-to-Contribute) to the project!! +Documentation can be found [here](https://github.com/omec-project/bess/wiki/). Please consider [contributing](https://github.com/omec-project/bess/wiki/How-to-Contribute) to the project! diff --git a/bessctl/conf/samples/tc/wfs_double.bess b/bessctl/conf/samples/tc/wfs_double.bess index 070511fb9a..d18154c493 100644 --- a/bessctl/conf/samples/tc/wfs_double.bess +++ b/bessctl/conf/samples/tc/wfs_double.bess @@ -1,6 +1,6 @@ # Test WeightedFairscheduler's accuracy on a simple tree pipeline # Works correctly, if internal variables of WFS are represented as -# doubles. Details: https://github.com/NetSys/bess/pull/955 +# doubles. import time diff --git a/bessctl/conf/testing/run_module_tests.bess b/bessctl/conf/testing/run_module_tests.bess index 3c668d4ff0..089f6f510a 100644 --- a/bessctl/conf/testing/run_module_tests.bess +++ b/bessctl/conf/testing/run_module_tests.bess @@ -117,7 +117,7 @@ def load_test(filename): CRASH_TEST_INPUTS, OUTPUT_TEST_INPUTS, and CUSTOM_TEST_FUNCTIONS using .append() to add its tests. The format of each of these is a bit different; see the wiki at - https://github.com/NetSys/bess/wiki/Python-Scripts + https://github.com/omec-project/bess/wiki/Python-Scripts """ namespace = { '__builtins__': __builtins__, diff --git a/env/Dockerfile b/env/Dockerfile index 26e8a66df4..60e4d5dad8 100644 --- a/env/Dockerfile +++ b/env/Dockerfile @@ -25,7 +25,7 @@ RUN mkdir -p /build/bess # Build DPDK testpmd (used in bessctl samples) ARG BESS_DPDK_BRANCH=master RUN cd /build/bess && \ - curl -s -L https://github.com/NetSys/bess/archive/${BESS_DPDK_BRANCH}.tar.gz | tar zx --strip-components=1 && \ + curl -s -L https://github.com/omec-project/bess/archive/${BESS_DPDK_BRANCH}.tar.gz | tar zx --strip-components=1 && \ ./build.py dpdk && \ cp /build/bess/deps/dpdk-20.11.3/build/app/dpdk-testpmd /usr/local/bin/ && \ rm -rf /build/bess diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index 3cbc328790..68ebba6fd7 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -409,7 +409,7 @@ message WildcardMatchCommandSetDefaultGateArg { /** * The module ACL creates an access control module which by default blocks all traffic, unless it contains a rule which specifies otherwise. - * Examples of ACL can be found in [acl.bess](https://github.com/NetSys/bess/blob/master/bessctl/conf/samples/acl.bess) + * Examples of ACL can be found in [acl.bess](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/acl.bess) * * __Input Gates__: 1 * __Output Gates__: 1 @@ -498,7 +498,7 @@ message EtherEncapArg { * To instantiate an ExactMatch module, you must specify which fields in the packet to match over. You can add rules using the function `ExactMatch.add(...)` * Fields may be stored either in the packet data or its metadata attributes. * An example script using the ExactMatch code is found - * in [`bess/bessctl/conf/samples/exactmatch.bess`](https://github.com/NetSys/bess/blob/master/bessctl/conf/samples/exactmatch.bess). + * in [`bess/bessctl/conf/samples/exactmatch.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/exactmatch.bess). * * __Input Gates__: 1 * __Output Gates__: many (configurable) @@ -567,7 +567,7 @@ message GenericDecapArg { * `de ad be ef 12 34` * where the 2-byte ` ` comes from the value of metadata attribute `'foo'` * for each packet. - * An example script using GenericEncap is in [`bess/bessctl/conf/samples/generic_encap.bess`](https://github.com/NetSys/bess/blob/master/bessctl/conf/samples/generic_encap.bess). + * An example script using GenericEncap is in [`bess/bessctl/conf/samples/generic_encap.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/generic_encap.bess). * * __Input Gates__: 1 * __Output Gates__: 1 @@ -653,7 +653,7 @@ message MACSwapArg { * It should be paired with a Timestamp module, which attaches a timestamp to packets. * The measure module will log how long (in nanoseconds) it has been for each packet it received since it was timestamped. * This module is somewhat experimental and undergoing various changes. - * There is a test for the the Measure module in [`bessctl/module_tests/timestamp.py`](https://github.com/NetSys/bess/blob/master/bessctl/module_tests/timestamp.py). + * There is a test for the the Measure module in [`bessctl/module_tests/timestamp.py`](https://github.com/omec-project/bess/blob/master/bessctl/module_tests/timestamp.py). * * __Input Gates__: 1 * __Output Gates__: 1 @@ -694,7 +694,7 @@ message MetadataTestArg { * and destination addresses for packets on the reverse direction. * L3/L4 checksums are updated correspondingly. * To see an example of NAT in use, see: - * [`bess/bessctl/conf/samples/nat.bess`](https://github.com/NetSys/bess/blob/master/bessctl/conf/samples/nat.bess) + * [`bess/bessctl/conf/samples/nat.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/nat.bess) * * Currently only supports TCP/UDP/ICMP. * Note that address/port in packet payload (e.g., FTP) are NOT translated. @@ -720,7 +720,7 @@ message NATArg { * IPv4 addresses. No port number is translated. * L3/L4 checksums are updated correspondingly. * To see an example of NAT in use, see: - * [`bess/bessctl/conf/samples/nat.bess`](https://github.com/NetSys/bess/blob/master/bessctl/conf/samples/nat.bess) + * [`bess/bessctl/conf/samples/nat.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/nat.bess) * * Forward direction (from input gate 0 to output gate 0): * - Source IP address is updated, from internal to external address. @@ -931,7 +931,7 @@ message ReplicateCommandSetGatesArg { /** * The SetMetadata module adds metadata attributes to packets, which are not stored * or sent out with packet data. For examples of SetMetadata use, see - * [`bess/bessctl/conf/attr_match.bess`](https://github.com/NetSys/bess/blob/master/bessctl/conf/metadata/attr_match.bess) + * [`bess/bessctl/conf/attr_match.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/metadata/attr_match.bess) * * __Input Gates__: 1 * __Output Gates__: 1 @@ -1232,7 +1232,7 @@ message VXLANEncapArg { * pushes packets that do match out a specified gate, and those that don't out a default * gate. WildcardMatch is initialized with the fields it should inspect over, * rules are added via the `add(...)` function. - * An example of WildcardMatch is in [`bess/bessctl/conf/samples/wildcardmatch.bess`](https://github.com/NetSys/bess/blob/master/bessctl/conf/samples/wildcardmatch.bess) + * An example of WildcardMatch is in [`bess/bessctl/conf/samples/wildcardmatch.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/wildcardmatch.bess) * * __Input Gates__: 1 * __Output Gates__: many (configurable) From 3ff5cbadea5a590a1ebd99464aa85f3c6593f403 Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Fri, 30 Dec 2022 11:00:42 -0800 Subject: [PATCH 52/62] Update sugar.py --- bessctl/sugar.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bessctl/sugar.py b/bessctl/sugar.py index 0a88394601..00d96993a8 100644 --- a/bessctl/sugar.py +++ b/bessctl/sugar.py @@ -31,7 +31,6 @@ from __future__ import print_function import re import tokenize -import parser import io ''' @@ -171,8 +170,8 @@ def is_gate_expr(exp, is_ogate): exp_stripped = exp_stripped[:-1].strip() try: - parser.expr('(%s)' % exp_stripped) - parser.expr('%s%s%s' % (prefix, exp, postfix)) + compile('(%s)' % exp_stripped, '', mode='eval') + compile('%s%s%s' % (prefix, exp, postfix), '', mode='eval') except SyntaxError: return False else: From b40afb9f7a898e7ac0ac82c76ba9aef66b5ba9a1 Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Sat, 18 Feb 2023 12:42:13 -0800 Subject: [PATCH 53/62] Action for dependabot and check license/copyright (#14) * Action for dependabot and check license/copyright * Remove empty line * Add empty line at end of file --- .github/dependabot.yml | 15 ++ .github/workflows/pull_request.yaml | 3 + .github/workflows/reuse.yml | 18 ++ .github/workflows/stale.yml | 28 +++ .gitignore | 3 +- .reuse/dep5 | 9 + LICENSES/Apache-2.0.txt | 177 ++++++++++++++++++ LICENSES/Artistic-1.0-Perl.txt | 51 +++++ LICENSES/BSD-3-Clause.txt | 25 +++ LICENSES/GPL-2.0-only.txt | 117 ++++++++++++ LICENSES/MIT.txt | 9 + bessctl/bessctl | 2 + bessctl/cli.py | 2 + bessctl/commands.py | 2 + bessctl/conf/metadata/attr_match.bess | 2 + bessctl/conf/metadata/test1.bess | 2 + bessctl/conf/metadata/test10.bess | 2 + bessctl/conf/metadata/test11.bess | 2 + bessctl/conf/metadata/test12.bess | 2 + bessctl/conf/metadata/test13.bess | 2 + bessctl/conf/metadata/test14.bess | 2 + bessctl/conf/metadata/test15.bess | 2 + bessctl/conf/metadata/test16.bess | 2 + bessctl/conf/metadata/test17.bess | 2 + bessctl/conf/metadata/test2.bess | 2 + bessctl/conf/metadata/test3.bess | 2 + bessctl/conf/metadata/test4.bess | 2 + bessctl/conf/metadata/test5.bess | 2 + bessctl/conf/metadata/test6.bess | 2 + bessctl/conf/metadata/test7.bess | 2 + bessctl/conf/metadata/test8.bess | 2 + bessctl/conf/metadata/test9.bess | 2 + bessctl/conf/metadata/test_corner.bess | 2 + bessctl/conf/metadata/test_cycle1.bess | 2 + bessctl/conf/metadata/test_cycle2.bess | 2 + bessctl/conf/metadata/test_cycle3.bess | 2 + bessctl/conf/perftest/bpf.bess | 2 + bessctl/conf/perftest/chain.bess | 2 + bessctl/conf/perftest/complex_merge.bess | 2 + bessctl/conf/perftest/complex_split.bess | 2 + bessctl/conf/perftest/flowgen.bess | 2 + bessctl/conf/perftest/loopback_vport.bess | 2 + bessctl/conf/perftest/merge.bess | 2 + bessctl/conf/perftest/merge_asym.bess | 2 + bessctl/conf/perftest/nat.bess | 2 + bessctl/conf/perftest/phy_forward.bess | 2 + bessctl/conf/perftest/pktgen.bess | 2 + bessctl/conf/perftest/split.bess | 2 + bessctl/conf/perftest/vport_scaling.bess | 2 + bessctl/conf/port/latency.bess | 2 + bessctl/conf/port/loopback.bess | 2 + bessctl/conf/port/loopback_vport.bess | 2 + bessctl/conf/port/macswap.bess | 2 + bessctl/conf/port/multicore-phy.bess | 2 + bessctl/conf/port/p2s.bess | 2 + bessctl/conf/port/s2p.bess | 2 + bessctl/conf/port/s2p2s.bess | 2 + bessctl/conf/port/unix_port.bess | 2 + bessctl/conf/port/vhost/create_image.sh | 2 + bessctl/conf/port/vhost/launch_container.py | 2 + bessctl/conf/port/vhost/launch_vm.py | 2 + bessctl/conf/port/vhost/qmp.py | 2 + bessctl/conf/port/vhost/vhost.bess | 2 + bessctl/conf/port/vport.bess | 2 + bessctl/conf/port/vport_ping.bess | 2 + bessctl/conf/port/vxlan.bess | 2 + bessctl/conf/samples/acl.bess | 2 + bessctl/conf/samples/arp.bess | 2 + bessctl/conf/samples/drr.bess | 2 + bessctl/conf/samples/exactmatch.bess | 2 + bessctl/conf/samples/flowgen.bess | 2 + bessctl/conf/samples/generic_encap.bess | 2 + bessctl/conf/samples/hash_lb.bess | 2 + bessctl/conf/samples/igate.bess | 2 + bessctl/conf/samples/iplookup.bess | 2 + bessctl/conf/samples/l2forward.bess | 2 + bessctl/conf/samples/multicore.bess | 2 + bessctl/conf/samples/nat.bess | 2 + bessctl/conf/samples/qtest.bess | 2 + bessctl/conf/samples/queue.bess | 2 + bessctl/conf/samples/random_split.bess | 2 + bessctl/conf/samples/replicate.bess | 2 + bessctl/conf/samples/roundrobin.bess | 2 + bessctl/conf/samples/s2s.bess | 2 + bessctl/conf/samples/tc/complextree.bess | 2 + bessctl/conf/samples/tc/max_burst.bess | 2 + bessctl/conf/samples/tc/ratelimit.bess | 2 + bessctl/conf/samples/update.bess | 2 + bessctl/conf/samples/update_ttl.bess | 2 + bessctl/conf/samples/url_filter.bess | 2 + bessctl/conf/samples/vlantest.bess | 2 + bessctl/conf/samples/wildcardmatch.bess | 2 + bessctl/conf/samples/worker_split.bess | 2 + bessctl/conf/testing/run_module_tests.bess | 2 + bessctl/measurement_utils.py | 2 + bessctl/module_tests/acl.py | 2 + bessctl/module_tests/arp.py | 2 + bessctl/module_tests/bpf.py | 2 + bessctl/module_tests/buffer.py | 2 + bessctl/module_tests/bypass.py | 2 + bessctl/module_tests/drr.py | 2 + bessctl/module_tests/etherencap.py | 2 + bessctl/module_tests/exact_match.txt | 2 + bessctl/module_tests/generic_decap.py | 2 + bessctl/module_tests/ip_checksum.py | 2 + bessctl/module_tests/iplookup.py | 2 + bessctl/module_tests/l2forward.py | 2 + bessctl/module_tests/nat.py | 2 + bessctl/module_tests/placement_constraint.txt | 2 + bessctl/module_tests/random_split.py | 2 + bessctl/module_tests/replicate.py | 2 + bessctl/module_tests/timestamp.py | 2 + bessctl/module_tests/update_ttl.py | 2 + bessctl/module_tests/url_filter.py | 2 + bessctl/module_tests/vlan.py | 2 + bessctl/module_tests/wildcard_match.txt | 2 + bessctl/module_tests/worker_split.py | 2 + bessctl/run_module_tests.py | 2 + bessctl/sugar.py | 2 + bessctl/test_samples.py | 2 + bessctl/test_sugar.py | 2 + bessctl/test_utils.py | 2 + bin/dpdk-devbind.py | 2 + build.py | 2 + container_build.py | 2 + core/Makefile | 2 + core/bessctl.cc | 2 + core/bessctl.h | 2 + core/bessd.cc | 2 + core/bessd.h | 2 + core/bessd_test.cc | 2 + core/commands.h | 2 + core/debug.cc | 2 + core/debug.h | 2 + core/dpdk.cc | 2 + core/dpdk.h | 2 + core/drivers/pcap.cc | 2 + core/drivers/pcap.h | 2 + core/drivers/pmd.cc | 2 + core/drivers/pmd.h | 2 + core/drivers/unix_socket.cc | 2 + core/drivers/unix_socket.h | 2 + core/drivers/vport.cc | 2 + core/drivers/vport.h | 2 + core/event.cc | 2 + core/event.h | 2 + core/gate.cc | 2 + core/gate.h | 2 + core/gate_hooks/pcapng.cc | 2 + core/gate_hooks/pcapng.h | 2 + core/gate_hooks/tcpdump.cc | 2 + core/gate_hooks/tcpdump.h | 2 + core/gate_hooks/track.cc | 2 + core/gate_hooks/track.h | 2 + core/gate_test.cc | 2 + core/gtest_main.cc | 2 + core/kmod/Makefile | 2 + core/kmod/llring.h | 2 + core/kmod/sn_common.h | 2 + core/kmod/sn_ethtool.c | 2 + core/kmod/sn_host.c | 2 + core/kmod/sn_kernel.h | 2 + core/kmod/sn_netdev.c | 2 + core/kmod/sndrv.c | 2 + core/main.cc | 2 + core/message.cc | 2 + core/message.h | 2 + core/metadata.cc | 2 + core/metadata.h | 2 + core/metadata_test.cc | 2 + core/module.cc | 2 + core/module.h | 2 + core/module_graph.cc | 2 + core/module_graph.h | 2 + core/module_test.cc | 2 + core/modules/acl.cc | 2 + core/modules/acl.h | 2 + core/modules/arp_responder.cc | 2 + core/modules/arp_responder.h | 2 + core/modules/bpf.cc | 2 + core/modules/bpf.h | 2 + core/modules/buffer.cc | 2 + core/modules/buffer.h | 2 + core/modules/bypass.cc | 2 + core/modules/bypass.h | 2 + core/modules/drr.cc | 2 + core/modules/drr.h | 2 + core/modules/dump.cc | 2 + core/modules/dump.h | 2 + core/modules/ether_encap.cc | 2 + core/modules/ether_encap.h | 2 + core/modules/exact_match.cc | 2 + core/modules/exact_match.h | 2 + core/modules/flowgen.cc | 2 + core/modules/flowgen.h | 2 + core/modules/generic_decap.cc | 2 + core/modules/generic_decap.h | 2 + core/modules/generic_encap.cc | 2 + core/modules/generic_encap.h | 2 + core/modules/hash_lb.cc | 2 + core/modules/hash_lb.h | 2 + core/modules/ip_checksum.cc | 2 + core/modules/ip_checksum.h | 2 + core/modules/ip_encap.cc | 2 + core/modules/ip_encap.h | 2 + core/modules/ip_lookup.cc | 2 + core/modules/ip_lookup.h | 2 + core/modules/ipswap.cc | 2 + core/modules/ipswap.h | 2 + core/modules/l2_forward.cc | 2 + core/modules/l2_forward.h | 2 + core/modules/l4_checksum.cc | 2 + core/modules/l4_checksum.h | 2 + core/modules/macswap.cc | 2 + core/modules/macswap.h | 2 + core/modules/measure.cc | 2 + core/modules/measure.h | 2 + core/modules/merge.cc | 2 + core/modules/merge.h | 2 + core/modules/mpls_pop.cc | 2 + core/modules/mpls_pop.h | 2 + core/modules/mttest.cc | 2 + core/modules/mttest.h | 2 + core/modules/nat.cc | 2 + core/modules/nat.h | 2 + core/modules/noop.cc | 2 + core/modules/noop.h | 2 + core/modules/port_inc.cc | 2 + core/modules/port_inc.h | 2 + core/modules/port_out.cc | 2 + core/modules/port_out.h | 2 + core/modules/queue.cc | 2 + core/modules/queue.h | 2 + core/modules/queue_inc.cc | 2 + core/modules/queue_inc.h | 2 + core/modules/queue_out.cc | 2 + core/modules/queue_out.h | 2 + core/modules/random_split.cc | 2 + core/modules/random_split.h | 2 + core/modules/random_update.cc | 2 + core/modules/random_update.h | 2 + core/modules/replicate.cc | 2 + core/modules/replicate.h | 2 + core/modules/rewrite.cc | 2 + core/modules/rewrite.h | 2 + core/modules/round_robin.cc | 2 + core/modules/round_robin.h | 2 + core/modules/set_metadata.cc | 2 + core/modules/set_metadata.h | 2 + core/modules/sink.cc | 2 + core/modules/sink.h | 2 + core/modules/source.cc | 2 + core/modules/source.h | 2 + core/modules/split.cc | 2 + core/modules/split.h | 2 + core/modules/static_nat.cc | 2 + core/modules/static_nat.h | 2 + core/modules/timestamp.cc | 2 + core/modules/timestamp.h | 2 + core/modules/update.cc | 2 + core/modules/update.h | 2 + core/modules/update_ttl.cc | 2 + core/modules/update_ttl.h | 2 + core/modules/url_filter.cc | 2 + core/modules/url_filter.h | 2 + core/modules/url_filter_bench.cc | 2 + core/modules/vlan_pop.cc | 2 + core/modules/vlan_pop.h | 2 + core/modules/vlan_push.cc | 2 + core/modules/vlan_push.h | 2 + core/modules/vlan_split.cc | 2 + core/modules/vlan_split.h | 2 + core/modules/vxlan_decap.cc | 2 + core/modules/vxlan_decap.h | 2 + core/modules/vxlan_encap.cc | 2 + core/modules/vxlan_encap.h | 2 + core/modules/wildcard_match.cc | 2 + core/modules/wildcard_match.h | 2 + core/modules/worker_split.cc | 2 + core/modules/worker_split.h | 2 + core/opts.cc | 2 + core/opts.h | 2 + core/packet.cc | 2 + core/packet.h | 2 + core/packet_avx.h | 2 + core/pktbatch.h | 2 + core/port.cc | 2 + core/port.h | 2 + core/port_test.cc | 2 + core/resume_hook.cc | 2 + core/resume_hook.h | 2 + core/resume_hooks/metadata.cc | 2 + core/resume_hooks/metadata.h | 2 + core/resume_hooks/task_graph.cc | 2 + core/resume_hooks/task_graph.h | 2 + core/scheduler.h | 2 + core/shared_obj.cc | 2 + core/shared_obj.h | 2 + core/shared_obj_test.cc | 2 + core/snbuf_layout.h | 2 + core/task.cc | 2 + core/task.h | 2 + core/traffic_class.cc | 2 + core/traffic_class.h | 2 + core/traffic_class_bench.cc | 2 + core/traffic_class_test.cc | 2 + core/utils/arp.h | 2 + core/utils/bits.h | 2 + core/utils/bits_test.cc | 2 + core/utils/bpf.cc | 2 + core/utils/bpf.h | 2 + core/utils/checksum.h | 2 + core/utils/checksum_bench.cc | 2 + core/utils/checksum_test.cc | 2 + core/utils/codel.h | 2 + core/utils/codel_test.cc | 2 + core/utils/common.h | 2 + core/utils/copy.cc | 2 + core/utils/copy.h | 2 + core/utils/copy_bench.cc | 2 + core/utils/cuckoo_map.h | 2 + core/utils/cuckoo_map_bench.cc | 2 + core/utils/cuckoo_map_test.cc | 2 + core/utils/endian.cc | 2 + core/utils/endian.h | 2 + core/utils/endian_test.cc | 2 + core/utils/ether.cc | 2 + core/utils/ether.h | 2 + core/utils/ether_test.cc | 2 + core/utils/exact_match_table.h | 2 + core/utils/exact_match_table_test.cc | 2 + core/utils/extended_priority_queue.h | 2 + core/utils/extended_priority_queue_test.cc | 2 + core/utils/fifo_opener.cc | 2 + core/utils/fifo_opener.h | 2 + core/utils/fifo_test.cc | 2 + core/utils/format.cc | 2 + core/utils/format.h | 2 + core/utils/histogram.h | 2 + core/utils/histogram_test.cc | 2 + core/utils/http_parser.cc | 2 + core/utils/http_parser.h | 2 + core/utils/icmp.h | 2 + core/utils/ip.cc | 2 + core/utils/ip.h | 2 + core/utils/ip_test.cc | 2 + core/utils/llqueue_test.cc | 2 + core/utils/lock_less_queue.h | 2 + core/utils/mcslock.h | 2 + core/utils/mpls.h | 2 + core/utils/pcap.h | 2 + core/utils/pcap_handle.cc | 2 + core/utils/pcap_handle.h | 2 + core/utils/pcap_handle_test.cc | 2 + core/utils/pcapng.h | 2 + core/utils/queue.h | 2 + core/utils/random.h | 2 + core/utils/simd.cc | 2 + core/utils/simd.h | 2 + core/utils/syscallthread.cc | 2 + core/utils/syscallthread.h | 2 + core/utils/tcp.h | 2 + core/utils/tcp_flow_reconstruct.h | 2 + core/utils/tcp_flow_reconstruct_test.cc | 2 + core/utils/time.cc | 2 + core/utils/time.h | 2 + core/utils/time_test.cc | 2 + core/utils/trie.h | 2 + core/utils/trie_test.cc | 2 + core/utils/udp.h | 2 + core/utils/vxlan.h | 2 + core/worker.cc | 2 + core/worker.h | 2 + ...d-set-ioctl-if-there-is-no-flag-diff.patch | 3 + env/after_install.sh | 2 + env/before_remove.sh | 2 + env/rebuild_images.py | 2 + install_git_hooks.sh | 2 + protobuf/bess_msg.proto | 2 + protobuf/error.proto | 2 + protobuf/module_msg.proto | 2 + protobuf/ports/port_msg.proto | 2 + protobuf/service.proto | 2 + protobuf/tests/test_msg.proto | 2 + protobuf/util_msg.proto | 2 + pybess/bess.py | 2 + pybess/module.py | 2 + pybess/pm_import.py | 2 + pybess/port.py | 2 + pybess/protobuf_to_dict.py | 2 + pybess/test_bess.txt | 2 + pybess/test_protobuf_to_dict.py | 2 + .../bessctl_conf/sequential_update.bess | 2 + sample_plugin/modules/sequential_update.cc | 2 + sample_plugin/modules/sequential_update.h | 2 + sample_plugin/protobuf/supdate_msg.proto | 2 + 396 files changed, 1225 insertions(+), 1 deletion(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/reuse.yml create mode 100644 .github/workflows/stale.yml create mode 100644 .reuse/dep5 create mode 100644 LICENSES/Apache-2.0.txt create mode 100644 LICENSES/Artistic-1.0-Perl.txt create mode 100644 LICENSES/BSD-3-Clause.txt create mode 100644 LICENSES/GPL-2.0-only.txt create mode 100644 LICENSES/MIT.txt diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..a60bf2b1cb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2023 Intel Corporation + +version: 2 +updates: + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 94e38d128d..4fa0ba2579 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2022 Intel Corporation + name: Build and Test process on: - pull_request diff --git a/.github/workflows/reuse.yml b/.github/workflows/reuse.yml new file mode 100644 index 0000000000..4d1c372536 --- /dev/null +++ b/.github/workflows/reuse.yml @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2023 Intel Corporation + +name: REUSE Compliance Check + +on: [push, pull_request] + +jobs: + check: + runs-on: '${{ matrix.os }}' + strategy: + matrix: + os: + - ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: REUSE Compliance Check + uses: fsfe/reuse-action@v1 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 0000000000..961050f43d --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2023 Intel Corporation + +name: Close stale issues and PRs + +on: + schedule: + - cron: '30 1 * * *' + +jobs: + stale: + runs-on: '${{ matrix.os }}' + strategy: + matrix: + os: + - ubuntu-latest + steps: + - uses: actions/stale@v7 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: 'This issue has been stale for 30 days and will be closed in 5 days. Comment to keep it open.' + stale-pr-message: 'This pull request has been stale for 30 days and will be closed in 5 days. Comment to keep it open.' + stale-issue-label: 'Stale/issue' + stale-pr-label: 'Stale/pr' + exempt-issue-labels: 'awaiting-approval,work-in-progress' + exempt-pr-labels: 'awaiting-approval,work-in-progress' + days-before-stale: 30 + days-before-close: 5 diff --git a/.gitignore b/.gitignore index 55f538f2d3..5fba308b21 100644 --- a/.gitignore +++ b/.gitignore @@ -52,5 +52,6 @@ compile_commands.json # virtualenv venv/ -# Keep GitHub Actions +# Keep GitHub Actions and Reuse !.github +!.reuse diff --git a/.reuse/dep5 b/.reuse/dep5 new file mode 100644 index 0000000000..49b5fbe46b --- /dev/null +++ b/.reuse/dep5 @@ -0,0 +1,9 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: bess +Upstream-Contact: OMEC Developers +Source: https://github.com/omec-project/bess + +Files: .codecov.yml .gitattributes .gitignore CONTRIBUTING.md README.md requirements.txt .hooks/pre-commit bessctl/server.py bessctl/conf/port/vhost/README.md bessctl/conf/samples/mpls_test.bess bessctl/conf/samples/tc/wfs_double.bess bessctl/module_tests/*.pcap bessctl/static/*.* core/.clang-format core/.gitignore core/coverage core/*.suppress core/memory*.* core/packet_pool.* core/kmod/.clang-format core/kmod/.gitignore core/kmod/install core/pb/.gitignore core/resume_hooks/README.md core/testdata/test-pktcaptures/*.bytes core/testdata/test-pktcaptures/*.pcap deps/bpf_validate.patch deps/ethdev_include.patch doxygen/README.md doxygen/bess.dox env/*.yml env/Dockerfile env/README.md env/Vagrantfile pybess/**/__init__.py pybess/**/.gitignore sample_plugin/README.md +Copyright: 2016-2017, Nefeli Networks, Inc. +Copyright: 2017, The Regents of the University of California. +License: BSD-3-Clause diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt new file mode 100644 index 0000000000..4947287f7b --- /dev/null +++ b/LICENSES/Apache-2.0.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/LICENSES/Artistic-1.0-Perl.txt b/LICENSES/Artistic-1.0-Perl.txt new file mode 100644 index 0000000000..dd45f4cd89 --- /dev/null +++ b/LICENSES/Artistic-1.0-Perl.txt @@ -0,0 +1,51 @@ +The "Artistic License" + +Preamble + +The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. + + "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or copyrights for the package. + + "You" is you, if you're thinking about copying or distributing this Package. + + "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as uunet.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. + b) use the modified Package only within your corporation or organization. + c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. + b) accompany the distribution with the machine-readable source of the Package with your modifications. + c) give non-standard executables non-standard names, and clearly document the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. You may embed this Package's interpreter within an executable of yours (by linking); this shall be construed as a mere form of aggregation, provided that the complete Standard Version of the interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whoever generated them, and may be sold commercially, and may be aggregated with this Package. If such scripts or library files are aggregated with this Package via the so-called "undump" or "unexec" methods of producing a binary executable image, then distribution of such an image shall neither be construed as a distribution of this Package nor shall it fall under the restrictions of Paragraphs 3 and 4, provided that you do not represent such an executable image as a Standard Version of this Package. + +7. C subroutines (or comparably compiled subroutines in other languages) supplied by you and linked into this Package in order to emulate subroutines and variables of the language defined by this Package shall not be considered part of this Package, but are the equivalent of input as in Paragraph 6, provided these subroutines do not change the language in any way that would cause it to fail the regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always permitted provided that the use of this Package is embedded; that is, when no overt attempt is made to make this Package's interfaces visible to the end user of the commercial distribution. Such use shall not be construed as a distribution of this Package. + +9. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. + +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +The End diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000000..4a2daf18f2 --- /dev/null +++ b/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,25 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +* Neither the names of the copyright holders nor the names of their +contributors may be used to endorse or promote products derived from this +software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSES/GPL-2.0-only.txt b/LICENSES/GPL-2.0-only.txt new file mode 100644 index 0000000000..17cb286430 --- /dev/null +++ b/LICENSES/GPL-2.0-only.txt @@ -0,0 +1,117 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000000..2071b23b0e --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/bessctl/bessctl b/bessctl/bessctl index 3488a0ce9a..36f1e5a230 100755 --- a/bessctl/bessctl +++ b/bessctl/bessctl @@ -4,6 +4,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/cli.py b/bessctl/cli.py index 02a6f540a5..33dd5b23ea 100644 --- a/bessctl/cli.py +++ b/bessctl/cli.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/commands.py b/bessctl/commands.py index 83525358e2..7612e636e4 100644 --- a/bessctl/commands.py +++ b/bessctl/commands.py @@ -3,6 +3,8 @@ # Copyright (c) 2017, Cloudigo. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/attr_match.bess b/bessctl/conf/metadata/attr_match.bess index c11255dd84..1f5bcd7928 100644 --- a/bessctl/conf/metadata/attr_match.bess +++ b/bessctl/conf/metadata/attr_match.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test1.bess b/bessctl/conf/metadata/test1.bess index 670bb9ac76..07a56ef4a4 100644 --- a/bessctl/conf/metadata/test1.bess +++ b/bessctl/conf/metadata/test1.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test10.bess b/bessctl/conf/metadata/test10.bess index c959b21864..8d141a5e1d 100644 --- a/bessctl/conf/metadata/test10.bess +++ b/bessctl/conf/metadata/test10.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test11.bess b/bessctl/conf/metadata/test11.bess index f310b27586..41bdf8d2d2 100644 --- a/bessctl/conf/metadata/test11.bess +++ b/bessctl/conf/metadata/test11.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test12.bess b/bessctl/conf/metadata/test12.bess index 00e8efcb4b..270bbf7fe4 100644 --- a/bessctl/conf/metadata/test12.bess +++ b/bessctl/conf/metadata/test12.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test13.bess b/bessctl/conf/metadata/test13.bess index 484ad47162..dec2dc0dcc 100644 --- a/bessctl/conf/metadata/test13.bess +++ b/bessctl/conf/metadata/test13.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test14.bess b/bessctl/conf/metadata/test14.bess index 399e9930c4..f6533519a5 100644 --- a/bessctl/conf/metadata/test14.bess +++ b/bessctl/conf/metadata/test14.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test15.bess b/bessctl/conf/metadata/test15.bess index 42a053ac36..abe19ea93b 100644 --- a/bessctl/conf/metadata/test15.bess +++ b/bessctl/conf/metadata/test15.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test16.bess b/bessctl/conf/metadata/test16.bess index d66ae747ee..d41a745b4d 100644 --- a/bessctl/conf/metadata/test16.bess +++ b/bessctl/conf/metadata/test16.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test17.bess b/bessctl/conf/metadata/test17.bess index bf78f89658..1a3b5f08ab 100644 --- a/bessctl/conf/metadata/test17.bess +++ b/bessctl/conf/metadata/test17.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test2.bess b/bessctl/conf/metadata/test2.bess index a44f1c4116..02880907fa 100644 --- a/bessctl/conf/metadata/test2.bess +++ b/bessctl/conf/metadata/test2.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test3.bess b/bessctl/conf/metadata/test3.bess index 0593aba80f..fa75afae37 100644 --- a/bessctl/conf/metadata/test3.bess +++ b/bessctl/conf/metadata/test3.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test4.bess b/bessctl/conf/metadata/test4.bess index 9a41e8de1d..c7185612be 100644 --- a/bessctl/conf/metadata/test4.bess +++ b/bessctl/conf/metadata/test4.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test5.bess b/bessctl/conf/metadata/test5.bess index 2b7da9a9bf..dfe6357f18 100644 --- a/bessctl/conf/metadata/test5.bess +++ b/bessctl/conf/metadata/test5.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test6.bess b/bessctl/conf/metadata/test6.bess index 4795a1ee48..bbb6190a9c 100644 --- a/bessctl/conf/metadata/test6.bess +++ b/bessctl/conf/metadata/test6.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test7.bess b/bessctl/conf/metadata/test7.bess index 523eae51b2..1bd18f8aa4 100644 --- a/bessctl/conf/metadata/test7.bess +++ b/bessctl/conf/metadata/test7.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test8.bess b/bessctl/conf/metadata/test8.bess index b89e27c36f..e99cdbad27 100644 --- a/bessctl/conf/metadata/test8.bess +++ b/bessctl/conf/metadata/test8.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test9.bess b/bessctl/conf/metadata/test9.bess index fb48b5b47d..aa53368593 100644 --- a/bessctl/conf/metadata/test9.bess +++ b/bessctl/conf/metadata/test9.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test_corner.bess b/bessctl/conf/metadata/test_corner.bess index 7c79e87a8f..91041ae263 100644 --- a/bessctl/conf/metadata/test_corner.bess +++ b/bessctl/conf/metadata/test_corner.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test_cycle1.bess b/bessctl/conf/metadata/test_cycle1.bess index 28180433e8..2e48e66bfb 100644 --- a/bessctl/conf/metadata/test_cycle1.bess +++ b/bessctl/conf/metadata/test_cycle1.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test_cycle2.bess b/bessctl/conf/metadata/test_cycle2.bess index 4e3962322e..1d24662688 100644 --- a/bessctl/conf/metadata/test_cycle2.bess +++ b/bessctl/conf/metadata/test_cycle2.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/metadata/test_cycle3.bess b/bessctl/conf/metadata/test_cycle3.bess index 3e62531ebd..09bdca2b1f 100644 --- a/bessctl/conf/metadata/test_cycle3.bess +++ b/bessctl/conf/metadata/test_cycle3.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/bpf.bess b/bessctl/conf/perftest/bpf.bess index 2c3c773ec2..f1fb87c0e9 100644 --- a/bessctl/conf/perftest/bpf.bess +++ b/bessctl/conf/perftest/bpf.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/chain.bess b/bessctl/conf/perftest/chain.bess index fc0a5f3455..a1cd65f59f 100644 --- a/bessctl/conf/perftest/chain.bess +++ b/bessctl/conf/perftest/chain.bess @@ -1,6 +1,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/complex_merge.bess b/bessctl/conf/perftest/complex_merge.bess index cc007dbee1..f57ccdc5d9 100644 --- a/bessctl/conf/perftest/complex_merge.bess +++ b/bessctl/conf/perftest/complex_merge.bess @@ -1,6 +1,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/complex_split.bess b/bessctl/conf/perftest/complex_split.bess index 5b882da105..da3668e3b8 100644 --- a/bessctl/conf/perftest/complex_split.bess +++ b/bessctl/conf/perftest/complex_split.bess @@ -1,6 +1,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/flowgen.bess b/bessctl/conf/perftest/flowgen.bess index 4490b7439d..0ab0d2f510 100644 --- a/bessctl/conf/perftest/flowgen.bess +++ b/bessctl/conf/perftest/flowgen.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/loopback_vport.bess b/bessctl/conf/perftest/loopback_vport.bess index a244e0691d..de4ab84de5 100644 --- a/bessctl/conf/perftest/loopback_vport.bess +++ b/bessctl/conf/perftest/loopback_vport.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/merge.bess b/bessctl/conf/perftest/merge.bess index 84591d9de7..312c5ed6f7 100644 --- a/bessctl/conf/perftest/merge.bess +++ b/bessctl/conf/perftest/merge.bess @@ -1,6 +1,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/merge_asym.bess b/bessctl/conf/perftest/merge_asym.bess index 9f70ce32a7..ca29c3c0c2 100644 --- a/bessctl/conf/perftest/merge_asym.bess +++ b/bessctl/conf/perftest/merge_asym.bess @@ -1,6 +1,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/nat.bess b/bessctl/conf/perftest/nat.bess index e8cc48b34f..d5e384f608 100644 --- a/bessctl/conf/perftest/nat.bess +++ b/bessctl/conf/perftest/nat.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/phy_forward.bess b/bessctl/conf/perftest/phy_forward.bess index dbd25a71c2..df6c46ef6f 100644 --- a/bessctl/conf/perftest/phy_forward.bess +++ b/bessctl/conf/perftest/phy_forward.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/pktgen.bess b/bessctl/conf/perftest/pktgen.bess index 6fc1fff4d9..55376fc1ba 100644 --- a/bessctl/conf/perftest/pktgen.bess +++ b/bessctl/conf/perftest/pktgen.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/split.bess b/bessctl/conf/perftest/split.bess index 7f6efd5883..31ffec76b0 100644 --- a/bessctl/conf/perftest/split.bess +++ b/bessctl/conf/perftest/split.bess @@ -1,6 +1,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/perftest/vport_scaling.bess b/bessctl/conf/perftest/vport_scaling.bess index c167e06a1c..99be1dade0 100644 --- a/bessctl/conf/perftest/vport_scaling.bess +++ b/bessctl/conf/perftest/vport_scaling.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/latency.bess b/bessctl/conf/port/latency.bess index 17de3c71e1..7503a50db4 100644 --- a/bessctl/conf/port/latency.bess +++ b/bessctl/conf/port/latency.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/loopback.bess b/bessctl/conf/port/loopback.bess index 45ab4168fc..f2c6196f00 100644 --- a/bessctl/conf/port/loopback.bess +++ b/bessctl/conf/port/loopback.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/loopback_vport.bess b/bessctl/conf/port/loopback_vport.bess index 1a0895d01c..abac7b1178 100644 --- a/bessctl/conf/port/loopback_vport.bess +++ b/bessctl/conf/port/loopback_vport.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/macswap.bess b/bessctl/conf/port/macswap.bess index c21ff7f5ec..f23851353d 100644 --- a/bessctl/conf/port/macswap.bess +++ b/bessctl/conf/port/macswap.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/multicore-phy.bess b/bessctl/conf/port/multicore-phy.bess index 01e2f0c781..bec8d03962 100644 --- a/bessctl/conf/port/multicore-phy.bess +++ b/bessctl/conf/port/multicore-phy.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/p2s.bess b/bessctl/conf/port/p2s.bess index 91a8a5de0f..ed8f4c6664 100644 --- a/bessctl/conf/port/p2s.bess +++ b/bessctl/conf/port/p2s.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/s2p.bess b/bessctl/conf/port/s2p.bess index dd713fbc5f..2864dc6a67 100644 --- a/bessctl/conf/port/s2p.bess +++ b/bessctl/conf/port/s2p.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/s2p2s.bess b/bessctl/conf/port/s2p2s.bess index 8dccd95124..20560a5660 100644 --- a/bessctl/conf/port/s2p2s.bess +++ b/bessctl/conf/port/s2p2s.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/unix_port.bess b/bessctl/conf/port/unix_port.bess index 7b57e5a7b1..f76119c36c 100644 --- a/bessctl/conf/port/unix_port.bess +++ b/bessctl/conf/port/unix_port.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/vhost/create_image.sh b/bessctl/conf/port/vhost/create_image.sh index 07ca777a36..b0bdd51e7b 100755 --- a/bessctl/conf/port/vhost/create_image.sh +++ b/bessctl/conf/port/vhost/create_image.sh @@ -4,6 +4,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/vhost/launch_container.py b/bessctl/conf/port/vhost/launch_container.py index d169e62bb3..d6df0d2f1c 100755 --- a/bessctl/conf/port/vhost/launch_container.py +++ b/bessctl/conf/port/vhost/launch_container.py @@ -3,6 +3,8 @@ # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/vhost/launch_vm.py b/bessctl/conf/port/vhost/launch_vm.py index e6c55f0776..8520e8193a 100755 --- a/bessctl/conf/port/vhost/launch_vm.py +++ b/bessctl/conf/port/vhost/launch_vm.py @@ -3,6 +3,8 @@ # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/vhost/qmp.py b/bessctl/conf/port/vhost/qmp.py index e49914ea5e..373b4872ae 100644 --- a/bessctl/conf/port/vhost/qmp.py +++ b/bessctl/conf/port/vhost/qmp.py @@ -5,6 +5,8 @@ # Authors: # Luiz Capitulino # +# SPDX-License-Identifier: GPL-2.0-only +# # This work is licensed under the terms of the GNU GPL, version 2. See # the COPYING file in the top-level directory. diff --git a/bessctl/conf/port/vhost/vhost.bess b/bessctl/conf/port/vhost/vhost.bess index 9803d8a248..9b1c0c5fa1 100644 --- a/bessctl/conf/port/vhost/vhost.bess +++ b/bessctl/conf/port/vhost/vhost.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/vport.bess b/bessctl/conf/port/vport.bess index a674bfe4ae..84137a6ae7 100644 --- a/bessctl/conf/port/vport.bess +++ b/bessctl/conf/port/vport.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/vport_ping.bess b/bessctl/conf/port/vport_ping.bess index 38939d78e1..921fd6ac07 100644 --- a/bessctl/conf/port/vport_ping.bess +++ b/bessctl/conf/port/vport_ping.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/port/vxlan.bess b/bessctl/conf/port/vxlan.bess index 85701d4ed6..0d62372225 100644 --- a/bessctl/conf/port/vxlan.bess +++ b/bessctl/conf/port/vxlan.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/acl.bess b/bessctl/conf/samples/acl.bess index 376641d60b..d8111e42a1 100644 --- a/bessctl/conf/samples/acl.bess +++ b/bessctl/conf/samples/acl.bess @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/arp.bess b/bessctl/conf/samples/arp.bess index c8155ab4f5..449e97db2b 100644 --- a/bessctl/conf/samples/arp.bess +++ b/bessctl/conf/samples/arp.bess @@ -1,6 +1,8 @@ # Copyright (c) 2017, Cloudigo. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/drr.bess b/bessctl/conf/samples/drr.bess index b10c4bf282..4a203fbcd3 100644 --- a/bessctl/conf/samples/drr.bess +++ b/bessctl/conf/samples/drr.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/exactmatch.bess b/bessctl/conf/samples/exactmatch.bess index 556d7dce97..0d15ad9780 100644 --- a/bessctl/conf/samples/exactmatch.bess +++ b/bessctl/conf/samples/exactmatch.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/flowgen.bess b/bessctl/conf/samples/flowgen.bess index 33b11ed93b..f5c53c1864 100644 --- a/bessctl/conf/samples/flowgen.bess +++ b/bessctl/conf/samples/flowgen.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/generic_encap.bess b/bessctl/conf/samples/generic_encap.bess index 4d9f249f6c..1870477fac 100644 --- a/bessctl/conf/samples/generic_encap.bess +++ b/bessctl/conf/samples/generic_encap.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/hash_lb.bess b/bessctl/conf/samples/hash_lb.bess index 2a0097e42b..dfa1efa9aa 100644 --- a/bessctl/conf/samples/hash_lb.bess +++ b/bessctl/conf/samples/hash_lb.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/igate.bess b/bessctl/conf/samples/igate.bess index 18eaa47cc4..21ae06cddc 100644 --- a/bessctl/conf/samples/igate.bess +++ b/bessctl/conf/samples/igate.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/iplookup.bess b/bessctl/conf/samples/iplookup.bess index c1db6ba914..bac62a430a 100644 --- a/bessctl/conf/samples/iplookup.bess +++ b/bessctl/conf/samples/iplookup.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/l2forward.bess b/bessctl/conf/samples/l2forward.bess index 984371a2a5..96141add0c 100644 --- a/bessctl/conf/samples/l2forward.bess +++ b/bessctl/conf/samples/l2forward.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/multicore.bess b/bessctl/conf/samples/multicore.bess index b9841ccadb..cdaeeccd86 100644 --- a/bessctl/conf/samples/multicore.bess +++ b/bessctl/conf/samples/multicore.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/nat.bess b/bessctl/conf/samples/nat.bess index 91d1b53fc7..1477295da7 100644 --- a/bessctl/conf/samples/nat.bess +++ b/bessctl/conf/samples/nat.bess @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/qtest.bess b/bessctl/conf/samples/qtest.bess index ba0bb473aa..9aa3940cf7 100644 --- a/bessctl/conf/samples/qtest.bess +++ b/bessctl/conf/samples/qtest.bess @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/queue.bess b/bessctl/conf/samples/queue.bess index 589de38576..2af1139f84 100644 --- a/bessctl/conf/samples/queue.bess +++ b/bessctl/conf/samples/queue.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/random_split.bess b/bessctl/conf/samples/random_split.bess index 21e7e674b0..7a4901a524 100644 --- a/bessctl/conf/samples/random_split.bess +++ b/bessctl/conf/samples/random_split.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/replicate.bess b/bessctl/conf/samples/replicate.bess index 49c71c6f42..fdbf1c050c 100644 --- a/bessctl/conf/samples/replicate.bess +++ b/bessctl/conf/samples/replicate.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/roundrobin.bess b/bessctl/conf/samples/roundrobin.bess index f3341712a5..d3f59948fb 100644 --- a/bessctl/conf/samples/roundrobin.bess +++ b/bessctl/conf/samples/roundrobin.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/s2s.bess b/bessctl/conf/samples/s2s.bess index d47474dcb0..48b8ca7992 100644 --- a/bessctl/conf/samples/s2s.bess +++ b/bessctl/conf/samples/s2s.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/tc/complextree.bess b/bessctl/conf/samples/tc/complextree.bess index 12b52fef74..e051e6d3d2 100644 --- a/bessctl/conf/samples/tc/complextree.bess +++ b/bessctl/conf/samples/tc/complextree.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/tc/max_burst.bess b/bessctl/conf/samples/tc/max_burst.bess index 5805a32d73..ec964a9c1a 100644 --- a/bessctl/conf/samples/tc/max_burst.bess +++ b/bessctl/conf/samples/tc/max_burst.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/tc/ratelimit.bess b/bessctl/conf/samples/tc/ratelimit.bess index 51d24a452c..38573c113a 100644 --- a/bessctl/conf/samples/tc/ratelimit.bess +++ b/bessctl/conf/samples/tc/ratelimit.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/update.bess b/bessctl/conf/samples/update.bess index c2457d6239..755fa3ff93 100644 --- a/bessctl/conf/samples/update.bess +++ b/bessctl/conf/samples/update.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/update_ttl.bess b/bessctl/conf/samples/update_ttl.bess index 91f54103de..c5953cf844 100644 --- a/bessctl/conf/samples/update_ttl.bess +++ b/bessctl/conf/samples/update_ttl.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/url_filter.bess b/bessctl/conf/samples/url_filter.bess index b53f2a21b8..4c1de372eb 100644 --- a/bessctl/conf/samples/url_filter.bess +++ b/bessctl/conf/samples/url_filter.bess @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/vlantest.bess b/bessctl/conf/samples/vlantest.bess index 37eba5be2f..eaebb6daca 100644 --- a/bessctl/conf/samples/vlantest.bess +++ b/bessctl/conf/samples/vlantest.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/wildcardmatch.bess b/bessctl/conf/samples/wildcardmatch.bess index 1a1fc5fe88..814d9e1bcc 100644 --- a/bessctl/conf/samples/wildcardmatch.bess +++ b/bessctl/conf/samples/wildcardmatch.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/samples/worker_split.bess b/bessctl/conf/samples/worker_split.bess index 84589ad302..e96256f537 100644 --- a/bessctl/conf/samples/worker_split.bess +++ b/bessctl/conf/samples/worker_split.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/conf/testing/run_module_tests.bess b/bessctl/conf/testing/run_module_tests.bess index 089f6f510a..9e597c825b 100644 --- a/bessctl/conf/testing/run_module_tests.bess +++ b/bessctl/conf/testing/run_module_tests.bess @@ -2,6 +2,8 @@ # Copyright (c) 2017, Cloudigo. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/measurement_utils.py b/bessctl/measurement_utils.py index 8ede7ad687..acd35bf9ee 100644 --- a/bessctl/measurement_utils.py +++ b/bessctl/measurement_utils.py @@ -1,6 +1,8 @@ # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/acl.py b/bessctl/module_tests/acl.py index 71650de5e9..dc61e8274d 100644 --- a/bessctl/module_tests/acl.py +++ b/bessctl/module_tests/acl.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/arp.py b/bessctl/module_tests/arp.py index 42dcdee169..b9c3f7eb29 100644 --- a/bessctl/module_tests/arp.py +++ b/bessctl/module_tests/arp.py @@ -1,6 +1,8 @@ # Copyright (c) 2017, Cloudigo. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/bpf.py b/bessctl/module_tests/bpf.py index c26b2fe97f..3db2b53c7c 100644 --- a/bessctl/module_tests/bpf.py +++ b/bessctl/module_tests/bpf.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/buffer.py b/bessctl/module_tests/buffer.py index 5ef53cc639..abe7c6697b 100644 --- a/bessctl/module_tests/buffer.py +++ b/bessctl/module_tests/buffer.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/bypass.py b/bessctl/module_tests/bypass.py index eeba05128f..d2f2d4dc9f 100644 --- a/bessctl/module_tests/bypass.py +++ b/bessctl/module_tests/bypass.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/drr.py b/bessctl/module_tests/drr.py index 5690abb313..bffb32d12d 100644 --- a/bessctl/module_tests/drr.py +++ b/bessctl/module_tests/drr.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/etherencap.py b/bessctl/module_tests/etherencap.py index 535a0bf7fd..ec36a93daa 100644 --- a/bessctl/module_tests/etherencap.py +++ b/bessctl/module_tests/etherencap.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/exact_match.txt b/bessctl/module_tests/exact_match.txt index 20bdeb7680..c57a64957e 100644 --- a/bessctl/module_tests/exact_match.txt +++ b/bessctl/module_tests/exact_match.txt @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/generic_decap.py b/bessctl/module_tests/generic_decap.py index a18d560a80..fad3874453 100644 --- a/bessctl/module_tests/generic_decap.py +++ b/bessctl/module_tests/generic_decap.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/ip_checksum.py b/bessctl/module_tests/ip_checksum.py index 770938f3c7..3bce2c0340 100644 --- a/bessctl/module_tests/ip_checksum.py +++ b/bessctl/module_tests/ip_checksum.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/iplookup.py b/bessctl/module_tests/iplookup.py index 42d9a39959..a747e46b07 100644 --- a/bessctl/module_tests/iplookup.py +++ b/bessctl/module_tests/iplookup.py @@ -1,6 +1,8 @@ # Copyright (c) 2017 Tamas Levai # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/l2forward.py b/bessctl/module_tests/l2forward.py index dc1fddee21..aede80486c 100644 --- a/bessctl/module_tests/l2forward.py +++ b/bessctl/module_tests/l2forward.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/nat.py b/bessctl/module_tests/nat.py index 2743ad5fce..dc8a46bcee 100644 --- a/bessctl/module_tests/nat.py +++ b/bessctl/module_tests/nat.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/placement_constraint.txt b/bessctl/module_tests/placement_constraint.txt index 870b162e51..553fa60073 100644 --- a/bessctl/module_tests/placement_constraint.txt +++ b/bessctl/module_tests/placement_constraint.txt @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/random_split.py b/bessctl/module_tests/random_split.py index aff4f9b54f..959fe544c8 100644 --- a/bessctl/module_tests/random_split.py +++ b/bessctl/module_tests/random_split.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/replicate.py b/bessctl/module_tests/replicate.py index 6e508ba985..ff3fc9eee5 100644 --- a/bessctl/module_tests/replicate.py +++ b/bessctl/module_tests/replicate.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/timestamp.py b/bessctl/module_tests/timestamp.py index ad64b89a46..577ba9ccbd 100644 --- a/bessctl/module_tests/timestamp.py +++ b/bessctl/module_tests/timestamp.py @@ -1,6 +1,8 @@ # Copyright (c) 2018, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/update_ttl.py b/bessctl/module_tests/update_ttl.py index 07988dfbef..2f99785d3f 100644 --- a/bessctl/module_tests/update_ttl.py +++ b/bessctl/module_tests/update_ttl.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/url_filter.py b/bessctl/module_tests/url_filter.py index 120acd39d9..7bdd5e975a 100644 --- a/bessctl/module_tests/url_filter.py +++ b/bessctl/module_tests/url_filter.py @@ -1,6 +1,8 @@ # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/vlan.py b/bessctl/module_tests/vlan.py index 6e6a05d83d..55bbec6cce 100644 --- a/bessctl/module_tests/vlan.py +++ b/bessctl/module_tests/vlan.py @@ -1,6 +1,8 @@ # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/wildcard_match.txt b/bessctl/module_tests/wildcard_match.txt index 205e43a0ea..60edab2c77 100644 --- a/bessctl/module_tests/wildcard_match.txt +++ b/bessctl/module_tests/wildcard_match.txt @@ -1,6 +1,8 @@ # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/module_tests/worker_split.py b/bessctl/module_tests/worker_split.py index b1cd093b98..97fcae88c1 100644 --- a/bessctl/module_tests/worker_split.py +++ b/bessctl/module_tests/worker_split.py @@ -1,6 +1,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/run_module_tests.py b/bessctl/run_module_tests.py index 446685830f..1ff4277907 100755 --- a/bessctl/run_module_tests.py +++ b/bessctl/run_module_tests.py @@ -3,6 +3,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/sugar.py b/bessctl/sugar.py index 00d96993a8..7e12e1ae20 100644 --- a/bessctl/sugar.py +++ b/bessctl/sugar.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/test_samples.py b/bessctl/test_samples.py index a307227c0d..6e72b34a53 100644 --- a/bessctl/test_samples.py +++ b/bessctl/test_samples.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/test_sugar.py b/bessctl/test_sugar.py index 85e1af03c5..a8e3d98d2b 100644 --- a/bessctl/test_sugar.py +++ b/bessctl/test_sugar.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bessctl/test_utils.py b/bessctl/test_utils.py index 1fca8ee8b0..b65397f159 100644 --- a/bessctl/test_utils.py +++ b/bessctl/test_utils.py @@ -1,6 +1,8 @@ # Copyright (c) 2017, The Regents of the University of California. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/bin/dpdk-devbind.py b/bin/dpdk-devbind.py index ff324033e0..271b9490f6 100755 --- a/bin/dpdk-devbind.py +++ b/bin/dpdk-devbind.py @@ -5,6 +5,8 @@ # Copyright(c) 2010-2014 Intel Corporation. All rights reserved. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: diff --git a/build.py b/build.py index 5eca4eecf0..f7095b1c73 100755 --- a/build.py +++ b/build.py @@ -4,6 +4,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/container_build.py b/container_build.py index 30b7a228ca..b04d1f28bb 100755 --- a/container_build.py +++ b/container_build.py @@ -5,6 +5,8 @@ # Copyright (c) 2017, Cloudigo. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/core/Makefile b/core/Makefile index 6574179168..cff02334ac 100644 --- a/core/Makefile +++ b/core/Makefile @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/core/bessctl.cc b/core/bessctl.cc index 56c0535dd2..ad0a5126dc 100644 --- a/core/bessctl.cc +++ b/core/bessctl.cc @@ -3,6 +3,8 @@ // Copyright (c) 2017, Cloudigo. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/bessctl.h b/core/bessctl.h index b8beddd556..6bf36ce376 100644 --- a/core/bessctl.h +++ b/core/bessctl.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/bessd.cc b/core/bessd.cc index 606f28ec7a..eeffaa633c 100644 --- a/core/bessd.cc +++ b/core/bessd.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/bessd.h b/core/bessd.h index f013a8b43d..825fa32305 100644 --- a/core/bessd.h +++ b/core/bessd.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/bessd_test.cc b/core/bessd_test.cc index a4d251eaaa..25c0b78dec 100644 --- a/core/bessd_test.cc +++ b/core/bessd_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/commands.h b/core/commands.h index d7df54a39e..59e390ce77 100644 --- a/core/commands.h +++ b/core/commands.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2018, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/debug.cc b/core/debug.cc index 7875825053..39459ec295 100644 --- a/core/debug.cc +++ b/core/debug.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/debug.h b/core/debug.h index bc3676c614..31fff533be 100644 --- a/core/debug.h +++ b/core/debug.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/dpdk.cc b/core/dpdk.cc index 130572d789..50bdcfc21a 100644 --- a/core/dpdk.cc +++ b/core/dpdk.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/dpdk.h b/core/dpdk.h index 6ae3ad7fef..413bd17c1d 100644 --- a/core/dpdk.h +++ b/core/dpdk.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/pcap.cc b/core/drivers/pcap.cc index a072412a74..6e1f44d6a4 100644 --- a/core/drivers/pcap.cc +++ b/core/drivers/pcap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/pcap.h b/core/drivers/pcap.h index 788f0e9bd3..c0df472743 100644 --- a/core/drivers/pcap.h +++ b/core/drivers/pcap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index dbebbe5513..2b779126ca 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/pmd.h b/core/drivers/pmd.h index 40ed6662c9..c517fe1f40 100644 --- a/core/drivers/pmd.h +++ b/core/drivers/pmd.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/unix_socket.cc b/core/drivers/unix_socket.cc index 1460bb3116..127f216832 100644 --- a/core/drivers/unix_socket.cc +++ b/core/drivers/unix_socket.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/unix_socket.h b/core/drivers/unix_socket.h index 37a30a2096..60652c50d8 100644 --- a/core/drivers/unix_socket.h +++ b/core/drivers/unix_socket.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/vport.cc b/core/drivers/vport.cc index 71fe8e0e14..563e1b0ee0 100644 --- a/core/drivers/vport.cc +++ b/core/drivers/vport.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/drivers/vport.h b/core/drivers/vport.h index ba175ff907..acc0881624 100644 --- a/core/drivers/vport.h +++ b/core/drivers/vport.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/event.cc b/core/event.cc index cc048fd4fa..d2e6fecbcc 100644 --- a/core/event.cc +++ b/core/event.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/event.h b/core/event.h index 3d8e72a22b..0a31ba4596 100644 --- a/core/event.h +++ b/core/event.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate.cc b/core/gate.cc index 962b2ef973..10460ef283 100644 --- a/core/gate.cc +++ b/core/gate.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate.h b/core/gate.h index cff9c0992b..121c79b5d8 100644 --- a/core/gate.h +++ b/core/gate.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate_hooks/pcapng.cc b/core/gate_hooks/pcapng.cc index d70be3302a..1ac898bb88 100644 --- a/core/gate_hooks/pcapng.cc +++ b/core/gate_hooks/pcapng.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate_hooks/pcapng.h b/core/gate_hooks/pcapng.h index 884457ef9d..7e6f7cdded 100644 --- a/core/gate_hooks/pcapng.h +++ b/core/gate_hooks/pcapng.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate_hooks/tcpdump.cc b/core/gate_hooks/tcpdump.cc index c58a710176..404db37744 100644 --- a/core/gate_hooks/tcpdump.cc +++ b/core/gate_hooks/tcpdump.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate_hooks/tcpdump.h b/core/gate_hooks/tcpdump.h index 3d2f5fd15d..540f3b2bcf 100644 --- a/core/gate_hooks/tcpdump.h +++ b/core/gate_hooks/tcpdump.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate_hooks/track.cc b/core/gate_hooks/track.cc index 65a45046e3..5778134e4e 100644 --- a/core/gate_hooks/track.cc +++ b/core/gate_hooks/track.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate_hooks/track.h b/core/gate_hooks/track.h index 5c772ed2d7..34c8340b7a 100644 --- a/core/gate_hooks/track.h +++ b/core/gate_hooks/track.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gate_test.cc b/core/gate_test.cc index d351dc8e69..42192def13 100644 --- a/core/gate_test.cc +++ b/core/gate_test.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/gtest_main.cc b/core/gtest_main.cc index 7d103fff26..af4a6209cc 100644 --- a/core/gtest_main.cc +++ b/core/gtest_main.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/kmod/Makefile b/core/kmod/Makefile index 760ed7f35b..c0783083e7 100644 --- a/core/kmod/Makefile +++ b/core/kmod/Makefile @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/core/kmod/llring.h b/core/kmod/llring.h index 137954d796..dc02b63049 100644 --- a/core/kmod/llring.h +++ b/core/kmod/llring.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/kmod/sn_common.h b/core/kmod/sn_common.h index 21b36375e9..172ff9e273 100644 --- a/core/kmod/sn_common.h +++ b/core/kmod/sn_common.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/kmod/sn_ethtool.c b/core/kmod/sn_ethtool.c index 3909105067..832ce960f8 100644 --- a/core/kmod/sn_ethtool.c +++ b/core/kmod/sn_ethtool.c @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/kmod/sn_host.c b/core/kmod/sn_host.c index d46a6c8d92..78a94085c4 100644 --- a/core/kmod/sn_host.c +++ b/core/kmod/sn_host.c @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/kmod/sn_kernel.h b/core/kmod/sn_kernel.h index d78787520c..742666f8f7 100644 --- a/core/kmod/sn_kernel.h +++ b/core/kmod/sn_kernel.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/kmod/sn_netdev.c b/core/kmod/sn_netdev.c index c3bced74c1..970f1e5483 100644 --- a/core/kmod/sn_netdev.c +++ b/core/kmod/sn_netdev.c @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/kmod/sndrv.c b/core/kmod/sndrv.c index 6c3536527a..db821c696c 100644 --- a/core/kmod/sndrv.c +++ b/core/kmod/sndrv.c @@ -3,6 +3,8 @@ * * Copyright(c) 2014 Sangjin Han All rights reserved. * + * SPDX-License-Identifier: BSD-3-Clause or GPL-2.0-only + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: diff --git a/core/main.cc b/core/main.cc index 365a4a1671..4f438c6732 100644 --- a/core/main.cc +++ b/core/main.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/message.cc b/core/message.cc index 2d6751acf1..1eab97245b 100644 --- a/core/message.cc +++ b/core/message.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/message.h b/core/message.h index 4ced6c4c94..8574f99250 100644 --- a/core/message.h +++ b/core/message.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/metadata.cc b/core/metadata.cc index 1fe5583d64..c215558de2 100644 --- a/core/metadata.cc +++ b/core/metadata.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/metadata.h b/core/metadata.h index 41adb069f9..27b8f79c61 100644 --- a/core/metadata.h +++ b/core/metadata.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/metadata_test.cc b/core/metadata_test.cc index 50deb80fad..6b75d38dee 100644 --- a/core/metadata_test.cc +++ b/core/metadata_test.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/module.cc b/core/module.cc index f9b290cf64..3e957dcac6 100644 --- a/core/module.cc +++ b/core/module.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/module.h b/core/module.h index f525ca2697..6d41b81891 100644 --- a/core/module.h +++ b/core/module.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/module_graph.cc b/core/module_graph.cc index 64950c64b6..3e89c0b2b4 100644 --- a/core/module_graph.cc +++ b/core/module_graph.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/module_graph.h b/core/module_graph.h index 2033d6d22e..7ef9a04b53 100644 --- a/core/module_graph.h +++ b/core/module_graph.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/module_test.cc b/core/module_test.cc index d4b633949e..db5ee9c74c 100644 --- a/core/module_test.cc +++ b/core/module_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/acl.cc b/core/modules/acl.cc index 88e20b6932..e321af5529 100644 --- a/core/modules/acl.cc +++ b/core/modules/acl.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/acl.h b/core/modules/acl.h index 5fe7c58e3f..c99f2cb806 100644 --- a/core/modules/acl.h +++ b/core/modules/acl.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/arp_responder.cc b/core/modules/arp_responder.cc index 58267eadbe..d3566c6292 100644 --- a/core/modules/arp_responder.cc +++ b/core/modules/arp_responder.cc @@ -2,6 +2,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/arp_responder.h b/core/modules/arp_responder.h index 6658b45959..a05735d8ef 100644 --- a/core/modules/arp_responder.h +++ b/core/modules/arp_responder.h @@ -2,6 +2,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/bpf.cc b/core/modules/bpf.cc index ac579106c7..3b1ef9fcf3 100644 --- a/core/modules/bpf.cc +++ b/core/modules/bpf.cc @@ -5,6 +5,8 @@ * Copyright (C) 2005-2009 Jung-uk Kim * All rights reserved. * + * SPDX-License-Identifier: BSD-3-Clause + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: diff --git a/core/modules/bpf.h b/core/modules/bpf.h index 270ea6b00d..005858abf7 100644 --- a/core/modules/bpf.h +++ b/core/modules/bpf.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/buffer.cc b/core/modules/buffer.cc index 62fe907e8f..63f4aa5b95 100644 --- a/core/modules/buffer.cc +++ b/core/modules/buffer.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/buffer.h b/core/modules/buffer.h index b3d53d53c9..9a82d8f2f9 100644 --- a/core/modules/buffer.h +++ b/core/modules/buffer.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/bypass.cc b/core/modules/bypass.cc index b1c070b59c..21f1181c4d 100644 --- a/core/modules/bypass.cc +++ b/core/modules/bypass.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/bypass.h b/core/modules/bypass.h index 400051b973..49b6204b1e 100644 --- a/core/modules/bypass.h +++ b/core/modules/bypass.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/drr.cc b/core/modules/drr.cc index 840183e5e2..b86e5d8bf7 100644 --- a/core/modules/drr.cc +++ b/core/modules/drr.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/drr.h b/core/modules/drr.h index 0f86680184..a23fb1ffdb 100644 --- a/core/modules/drr.h +++ b/core/modules/drr.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/dump.cc b/core/modules/dump.cc index 28a7a13bed..d6b15c5a64 100644 --- a/core/modules/dump.cc +++ b/core/modules/dump.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/dump.h b/core/modules/dump.h index ae224e056d..8536c5c802 100644 --- a/core/modules/dump.h +++ b/core/modules/dump.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ether_encap.cc b/core/modules/ether_encap.cc index 6b8f0b0dcb..1432778758 100644 --- a/core/modules/ether_encap.cc +++ b/core/modules/ether_encap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ether_encap.h b/core/modules/ether_encap.h index ee9ea79faf..9d7c7c26c3 100644 --- a/core/modules/ether_encap.h +++ b/core/modules/ether_encap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/exact_match.cc b/core/modules/exact_match.cc index e50cf5cce6..7fc5fdbf28 100644 --- a/core/modules/exact_match.cc +++ b/core/modules/exact_match.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/exact_match.h b/core/modules/exact_match.h index d7e3531ed3..add99ec642 100644 --- a/core/modules/exact_match.h +++ b/core/modules/exact_match.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/flowgen.cc b/core/modules/flowgen.cc index 8793e1ce85..95f71c34e9 100644 --- a/core/modules/flowgen.cc +++ b/core/modules/flowgen.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/flowgen.h b/core/modules/flowgen.h index 990e3b869f..1a7b8c3ff3 100644 --- a/core/modules/flowgen.h +++ b/core/modules/flowgen.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/generic_decap.cc b/core/modules/generic_decap.cc index 1797f73a9a..f40e0f1403 100644 --- a/core/modules/generic_decap.cc +++ b/core/modules/generic_decap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/generic_decap.h b/core/modules/generic_decap.h index ef7108eff6..79b2e23d30 100644 --- a/core/modules/generic_decap.h +++ b/core/modules/generic_decap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/generic_encap.cc b/core/modules/generic_encap.cc index b9e34a4a30..f46575dd0b 100644 --- a/core/modules/generic_encap.cc +++ b/core/modules/generic_encap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/generic_encap.h b/core/modules/generic_encap.h index b3f14393f4..0a88292749 100644 --- a/core/modules/generic_encap.h +++ b/core/modules/generic_encap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/hash_lb.cc b/core/modules/hash_lb.cc index c31ac96962..cbcec691a2 100644 --- a/core/modules/hash_lb.cc +++ b/core/modules/hash_lb.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/hash_lb.h b/core/modules/hash_lb.h index a3d6e074ab..489a5a3f33 100644 --- a/core/modules/hash_lb.h +++ b/core/modules/hash_lb.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ip_checksum.cc b/core/modules/ip_checksum.cc index 47f86bae84..1c824c0180 100644 --- a/core/modules/ip_checksum.cc +++ b/core/modules/ip_checksum.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ip_checksum.h b/core/modules/ip_checksum.h index 94e0d7246a..2ab65e0a30 100644 --- a/core/modules/ip_checksum.h +++ b/core/modules/ip_checksum.h @@ -3,6 +3,8 @@ // Copyright (c) 2017, Cloudigo. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ip_encap.cc b/core/modules/ip_encap.cc index 06c76dd61f..e093def732 100644 --- a/core/modules/ip_encap.cc +++ b/core/modules/ip_encap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ip_encap.h b/core/modules/ip_encap.h index c791d12156..f33bf4cd48 100644 --- a/core/modules/ip_encap.h +++ b/core/modules/ip_encap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ip_lookup.cc b/core/modules/ip_lookup.cc index 7e976d413c..e112a2773b 100644 --- a/core/modules/ip_lookup.cc +++ b/core/modules/ip_lookup.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ip_lookup.h b/core/modules/ip_lookup.h index a866ad085e..c8ba0e9704 100644 --- a/core/modules/ip_lookup.h +++ b/core/modules/ip_lookup.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ipswap.cc b/core/modules/ipswap.cc index 0b4f495f2d..503ef3b142 100644 --- a/core/modules/ipswap.cc +++ b/core/modules/ipswap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/ipswap.h b/core/modules/ipswap.h index 191dee0754..5d72bdc36b 100644 --- a/core/modules/ipswap.h +++ b/core/modules/ipswap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/l2_forward.cc b/core/modules/l2_forward.cc index 5464625134..88d5953dd6 100644 --- a/core/modules/l2_forward.cc +++ b/core/modules/l2_forward.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/l2_forward.h b/core/modules/l2_forward.h index 0b7ed1b11d..22fd0b3f49 100644 --- a/core/modules/l2_forward.h +++ b/core/modules/l2_forward.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/l4_checksum.cc b/core/modules/l4_checksum.cc index 20faa85c33..20be041b0f 100644 --- a/core/modules/l4_checksum.cc +++ b/core/modules/l4_checksum.cc @@ -2,6 +2,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/l4_checksum.h b/core/modules/l4_checksum.h index 56d8ae5c20..cddc64b717 100644 --- a/core/modules/l4_checksum.h +++ b/core/modules/l4_checksum.h @@ -2,6 +2,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/macswap.cc b/core/modules/macswap.cc index a971b67ed5..ed9c5d58a2 100644 --- a/core/modules/macswap.cc +++ b/core/modules/macswap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/macswap.h b/core/modules/macswap.h index baecce7a21..978c88ea6e 100644 --- a/core/modules/macswap.h +++ b/core/modules/macswap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/measure.cc b/core/modules/measure.cc index 8d87811fde..ceef891832 100644 --- a/core/modules/measure.cc +++ b/core/modules/measure.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/measure.h b/core/modules/measure.h index 31b849a311..d4934fbae3 100644 --- a/core/modules/measure.h +++ b/core/modules/measure.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/merge.cc b/core/modules/merge.cc index 6c04db1eef..05d158402c 100644 --- a/core/modules/merge.cc +++ b/core/modules/merge.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/merge.h b/core/modules/merge.h index 3cc0c0b58c..82a8ad9660 100644 --- a/core/modules/merge.h +++ b/core/modules/merge.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/mpls_pop.cc b/core/modules/mpls_pop.cc index 9055ed462d..10b9e01d70 100644 --- a/core/modules/mpls_pop.cc +++ b/core/modules/mpls_pop.cc @@ -2,6 +2,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/mpls_pop.h b/core/modules/mpls_pop.h index 66d503507d..56b66e2b56 100644 --- a/core/modules/mpls_pop.h +++ b/core/modules/mpls_pop.h @@ -2,6 +2,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/mttest.cc b/core/modules/mttest.cc index 44dc51e9f3..5e1f94afef 100644 --- a/core/modules/mttest.cc +++ b/core/modules/mttest.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/mttest.h b/core/modules/mttest.h index d86c2d2133..69238a791c 100644 --- a/core/modules/mttest.h +++ b/core/modules/mttest.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/nat.cc b/core/modules/nat.cc index 70c8304588..da5a3118e9 100644 --- a/core/modules/nat.cc +++ b/core/modules/nat.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/nat.h b/core/modules/nat.h index 4ec594de92..956c2ba598 100644 --- a/core/modules/nat.h +++ b/core/modules/nat.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/noop.cc b/core/modules/noop.cc index 8b0b8d557e..31de9f58d1 100644 --- a/core/modules/noop.cc +++ b/core/modules/noop.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/noop.h b/core/modules/noop.h index 8f37043569..385ffaaf18 100644 --- a/core/modules/noop.h +++ b/core/modules/noop.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/port_inc.cc b/core/modules/port_inc.cc index acdb6b1b62..34de0db635 100644 --- a/core/modules/port_inc.cc +++ b/core/modules/port_inc.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/port_inc.h b/core/modules/port_inc.h index d287374208..b34e204583 100644 --- a/core/modules/port_inc.h +++ b/core/modules/port_inc.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/port_out.cc b/core/modules/port_out.cc index d798a71a32..d3b475aeaa 100644 --- a/core/modules/port_out.cc +++ b/core/modules/port_out.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/port_out.h b/core/modules/port_out.h index 6017e7695b..b2c7f3f043 100644 --- a/core/modules/port_out.h +++ b/core/modules/port_out.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/queue.cc b/core/modules/queue.cc index 2bd8065502..6cc42b3898 100644 --- a/core/modules/queue.cc +++ b/core/modules/queue.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/queue.h b/core/modules/queue.h index b2d4ec1e8f..187f805a82 100644 --- a/core/modules/queue.h +++ b/core/modules/queue.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/queue_inc.cc b/core/modules/queue_inc.cc index f857bb5df7..ee2731ad87 100644 --- a/core/modules/queue_inc.cc +++ b/core/modules/queue_inc.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/queue_inc.h b/core/modules/queue_inc.h index bc1034f481..bbc453d1a7 100644 --- a/core/modules/queue_inc.h +++ b/core/modules/queue_inc.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/queue_out.cc b/core/modules/queue_out.cc index 476ee7b684..8dc4fed303 100644 --- a/core/modules/queue_out.cc +++ b/core/modules/queue_out.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/queue_out.h b/core/modules/queue_out.h index 8ba4cb9c57..4645a2ba02 100644 --- a/core/modules/queue_out.h +++ b/core/modules/queue_out.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/random_split.cc b/core/modules/random_split.cc index 559e58171f..85efab0a33 100644 --- a/core/modules/random_split.cc +++ b/core/modules/random_split.cc @@ -3,6 +3,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/random_split.h b/core/modules/random_split.h index 1846c37b36..abe5df664e 100644 --- a/core/modules/random_split.h +++ b/core/modules/random_split.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/random_update.cc b/core/modules/random_update.cc index 29a91a9b1f..83883dd60e 100644 --- a/core/modules/random_update.cc +++ b/core/modules/random_update.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/random_update.h b/core/modules/random_update.h index 98b4629c00..6ec859c582 100644 --- a/core/modules/random_update.h +++ b/core/modules/random_update.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/replicate.cc b/core/modules/replicate.cc index ccf3e8c0ad..abd60156c9 100644 --- a/core/modules/replicate.cc +++ b/core/modules/replicate.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/replicate.h b/core/modules/replicate.h index d9ecc256b5..e63963297e 100644 --- a/core/modules/replicate.h +++ b/core/modules/replicate.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/rewrite.cc b/core/modules/rewrite.cc index 95463c8659..a04bdc2822 100644 --- a/core/modules/rewrite.cc +++ b/core/modules/rewrite.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/rewrite.h b/core/modules/rewrite.h index d0a154d91e..06bceaa24b 100644 --- a/core/modules/rewrite.h +++ b/core/modules/rewrite.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/round_robin.cc b/core/modules/round_robin.cc index 670583215a..71de0c31fa 100644 --- a/core/modules/round_robin.cc +++ b/core/modules/round_robin.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/round_robin.h b/core/modules/round_robin.h index 45a7e50127..cc4e6e5770 100644 --- a/core/modules/round_robin.h +++ b/core/modules/round_robin.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/set_metadata.cc b/core/modules/set_metadata.cc index d3441c1d89..8d028941b4 100644 --- a/core/modules/set_metadata.cc +++ b/core/modules/set_metadata.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/set_metadata.h b/core/modules/set_metadata.h index e57130dc32..20d9b67f9f 100644 --- a/core/modules/set_metadata.h +++ b/core/modules/set_metadata.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/sink.cc b/core/modules/sink.cc index d8f2945d82..9bef570fe9 100644 --- a/core/modules/sink.cc +++ b/core/modules/sink.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/sink.h b/core/modules/sink.h index b1c6534d0b..7fb61246e4 100644 --- a/core/modules/sink.h +++ b/core/modules/sink.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/source.cc b/core/modules/source.cc index 4b0413a071..e0e5889bbc 100644 --- a/core/modules/source.cc +++ b/core/modules/source.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/source.h b/core/modules/source.h index e1e1691f6f..35f8ade721 100644 --- a/core/modules/source.h +++ b/core/modules/source.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/split.cc b/core/modules/split.cc index 77ed817449..54ff483c30 100644 --- a/core/modules/split.cc +++ b/core/modules/split.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/split.h b/core/modules/split.h index 09848021bf..ffd693c875 100644 --- a/core/modules/split.h +++ b/core/modules/split.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/static_nat.cc b/core/modules/static_nat.cc index 5f5ef7859c..895e79d1a0 100644 --- a/core/modules/static_nat.cc +++ b/core/modules/static_nat.cc @@ -1,6 +1,8 @@ // Copyright (c) 2018, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/static_nat.h b/core/modules/static_nat.h index 04e64c8e3b..39cc40c893 100644 --- a/core/modules/static_nat.h +++ b/core/modules/static_nat.h @@ -1,6 +1,8 @@ // Copyright (c) 2018, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/timestamp.cc b/core/modules/timestamp.cc index 73d5904c28..5b594e8609 100644 --- a/core/modules/timestamp.cc +++ b/core/modules/timestamp.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/timestamp.h b/core/modules/timestamp.h index 288c8ea8ec..86bc4cdb94 100644 --- a/core/modules/timestamp.h +++ b/core/modules/timestamp.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/update.cc b/core/modules/update.cc index 42d4e2d54d..671af512d3 100644 --- a/core/modules/update.cc +++ b/core/modules/update.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/update.h b/core/modules/update.h index e152ac92e8..d3f4e6fb1d 100644 --- a/core/modules/update.h +++ b/core/modules/update.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/update_ttl.cc b/core/modules/update_ttl.cc index c3772d5138..416e6e37a8 100644 --- a/core/modules/update_ttl.cc +++ b/core/modules/update_ttl.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/update_ttl.h b/core/modules/update_ttl.h index d030bd8170..dfd005692b 100644 --- a/core/modules/update_ttl.h +++ b/core/modules/update_ttl.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/url_filter.cc b/core/modules/url_filter.cc index 3d72e555b2..4dc53c6b82 100644 --- a/core/modules/url_filter.cc +++ b/core/modules/url_filter.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/url_filter.h b/core/modules/url_filter.h index ede9bc9f4a..87ada0f07b 100644 --- a/core/modules/url_filter.h +++ b/core/modules/url_filter.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/url_filter_bench.cc b/core/modules/url_filter_bench.cc index afc443ecd1..835e7341a1 100644 --- a/core/modules/url_filter_bench.cc +++ b/core/modules/url_filter_bench.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vlan_pop.cc b/core/modules/vlan_pop.cc index 5df318ad8b..a5791baeb3 100644 --- a/core/modules/vlan_pop.cc +++ b/core/modules/vlan_pop.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vlan_pop.h b/core/modules/vlan_pop.h index ffe0527b62..8fe7bee196 100644 --- a/core/modules/vlan_pop.h +++ b/core/modules/vlan_pop.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vlan_push.cc b/core/modules/vlan_push.cc index d5c4921604..18a349fb40 100644 --- a/core/modules/vlan_push.cc +++ b/core/modules/vlan_push.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vlan_push.h b/core/modules/vlan_push.h index eba2a75ad9..d8537caa73 100644 --- a/core/modules/vlan_push.h +++ b/core/modules/vlan_push.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vlan_split.cc b/core/modules/vlan_split.cc index 24eb9d1fae..60cc6df17d 100644 --- a/core/modules/vlan_split.cc +++ b/core/modules/vlan_split.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vlan_split.h b/core/modules/vlan_split.h index 85a14147a5..9c40286865 100644 --- a/core/modules/vlan_split.h +++ b/core/modules/vlan_split.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vxlan_decap.cc b/core/modules/vxlan_decap.cc index fcdded78fc..aefaacf45c 100644 --- a/core/modules/vxlan_decap.cc +++ b/core/modules/vxlan_decap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vxlan_decap.h b/core/modules/vxlan_decap.h index bd10da24c9..91dea9e360 100644 --- a/core/modules/vxlan_decap.h +++ b/core/modules/vxlan_decap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vxlan_encap.cc b/core/modules/vxlan_encap.cc index 4736893e89..034610eb28 100644 --- a/core/modules/vxlan_encap.cc +++ b/core/modules/vxlan_encap.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/vxlan_encap.h b/core/modules/vxlan_encap.h index 533b8aa95c..dc473f9e7f 100644 --- a/core/modules/vxlan_encap.h +++ b/core/modules/vxlan_encap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/wildcard_match.cc b/core/modules/wildcard_match.cc index 4dd01e60c5..3e673747f3 100644 --- a/core/modules/wildcard_match.cc +++ b/core/modules/wildcard_match.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/wildcard_match.h b/core/modules/wildcard_match.h index 6e7703dcfa..ae23da39ce 100644 --- a/core/modules/wildcard_match.h +++ b/core/modules/wildcard_match.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/worker_split.cc b/core/modules/worker_split.cc index bb1d9c2613..c76683ac25 100644 --- a/core/modules/worker_split.cc +++ b/core/modules/worker_split.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/modules/worker_split.h b/core/modules/worker_split.h index 102af4bc64..8187749060 100644 --- a/core/modules/worker_split.h +++ b/core/modules/worker_split.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/opts.cc b/core/opts.cc index a5120d52f0..5e32428d8b 100644 --- a/core/opts.cc +++ b/core/opts.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/opts.h b/core/opts.h index 873ab7ed3e..2c0a38c943 100644 --- a/core/opts.h +++ b/core/opts.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/packet.cc b/core/packet.cc index 8c5a5b8aa6..6227b0f15a 100644 --- a/core/packet.cc +++ b/core/packet.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/packet.h b/core/packet.h index 0471f383cc..98c3b5a363 100644 --- a/core/packet.h +++ b/core/packet.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/packet_avx.h b/core/packet_avx.h index 99b23d301a..335bb1223b 100644 --- a/core/packet_avx.h +++ b/core/packet_avx.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/pktbatch.h b/core/pktbatch.h index 260b53cf65..3340e13982 100644 --- a/core/pktbatch.h +++ b/core/pktbatch.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/port.cc b/core/port.cc index 347ebf81fd..e84ae14cab 100644 --- a/core/port.cc +++ b/core/port.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/port.h b/core/port.h index 193d131058..c4a3b18496 100644 --- a/core/port.h +++ b/core/port.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/port_test.cc b/core/port_test.cc index 1a4d57bab7..0b43cd96e7 100644 --- a/core/port_test.cc +++ b/core/port_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/resume_hook.cc b/core/resume_hook.cc index 897beceebc..206dd55595 100644 --- a/core/resume_hook.cc +++ b/core/resume_hook.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/resume_hook.h b/core/resume_hook.h index a439081041..9fecb4bd57 100644 --- a/core/resume_hook.h +++ b/core/resume_hook.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/resume_hooks/metadata.cc b/core/resume_hooks/metadata.cc index e8a4b05153..5374cdc964 100644 --- a/core/resume_hooks/metadata.cc +++ b/core/resume_hooks/metadata.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/resume_hooks/metadata.h b/core/resume_hooks/metadata.h index c47facf4de..42d5c9c034 100644 --- a/core/resume_hooks/metadata.h +++ b/core/resume_hooks/metadata.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/resume_hooks/task_graph.cc b/core/resume_hooks/task_graph.cc index 150afd0f7c..050e72f29f 100644 --- a/core/resume_hooks/task_graph.cc +++ b/core/resume_hooks/task_graph.cc @@ -1,6 +1,8 @@ // Copyright (c) 2017, The Regents of the University of California. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/resume_hooks/task_graph.h b/core/resume_hooks/task_graph.h index 0d2af9994b..761bd1345f 100644 --- a/core/resume_hooks/task_graph.h +++ b/core/resume_hooks/task_graph.h @@ -1,6 +1,8 @@ // Copyright (c) 2017, The Regents of the University of California. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/scheduler.h b/core/scheduler.h index caf63791bd..0f61c6b237 100644 --- a/core/scheduler.h +++ b/core/scheduler.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/shared_obj.cc b/core/shared_obj.cc index 424445dd28..d21310c1cf 100644 --- a/core/shared_obj.cc +++ b/core/shared_obj.cc @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/shared_obj.h b/core/shared_obj.h index 0172511e8d..1806340c1c 100644 --- a/core/shared_obj.h +++ b/core/shared_obj.h @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/shared_obj_test.cc b/core/shared_obj_test.cc index ee39ad7bad..939fc6ca31 100644 --- a/core/shared_obj_test.cc +++ b/core/shared_obj_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/snbuf_layout.h b/core/snbuf_layout.h index 598e406ba6..42232783ee 100644 --- a/core/snbuf_layout.h +++ b/core/snbuf_layout.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/task.cc b/core/task.cc index 5a75aec692..ce51b1c5a2 100644 --- a/core/task.cc +++ b/core/task.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/task.h b/core/task.h index 41447aa543..f0ab165ec7 100644 --- a/core/task.h +++ b/core/task.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/traffic_class.cc b/core/traffic_class.cc index 478bc8c6fa..ce028ed8d0 100644 --- a/core/traffic_class.cc +++ b/core/traffic_class.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/traffic_class.h b/core/traffic_class.h index 12e7de05ec..dd41063e5e 100644 --- a/core/traffic_class.h +++ b/core/traffic_class.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/traffic_class_bench.cc b/core/traffic_class_bench.cc index acad4fd24f..e397535b89 100644 --- a/core/traffic_class_bench.cc +++ b/core/traffic_class_bench.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/traffic_class_test.cc b/core/traffic_class_test.cc index 69918f1846..6d203d0f1e 100644 --- a/core/traffic_class_test.cc +++ b/core/traffic_class_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/arp.h b/core/utils/arp.h index 448bfc7c66..99b82f71f3 100644 --- a/core/utils/arp.h +++ b/core/utils/arp.h @@ -1,6 +1,8 @@ // Copyright (c) 2017, Cloudigo. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/bits.h b/core/utils/bits.h index 5c4b000725..817d689bcb 100644 --- a/core/utils/bits.h +++ b/core/utils/bits.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/bits_test.cc b/core/utils/bits_test.cc index e44200c560..3a136c6730 100644 --- a/core/utils/bits_test.cc +++ b/core/utils/bits_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/bpf.cc b/core/utils/bpf.cc index ff7b3dd054..133d41f267 100644 --- a/core/utils/bpf.cc +++ b/core/utils/bpf.cc @@ -4,6 +4,8 @@ * Copyright (C) 2005-2009 Jung-uk Kim * All rights reserved. * + * SPDX-License-Identifier: BSD-3-Clause + * */ #include "bpf.h" diff --git a/core/utils/bpf.h b/core/utils/bpf.h index 693d0cbdf5..4bdb5f603b 100644 --- a/core/utils/bpf.h +++ b/core/utils/bpf.h @@ -4,6 +4,8 @@ * Copyright (C) 2005-2009 Jung-uk Kim * All rights reserved. * + * SPDX-License-Identifier: BSD-3-Clause + * */ #ifndef BESS_UTILS_BPF_H_ diff --git a/core/utils/checksum.h b/core/utils/checksum.h index b206777d4a..688f8326af 100644 --- a/core/utils/checksum.h +++ b/core/utils/checksum.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/checksum_bench.cc b/core/utils/checksum_bench.cc index f27d56b028..d9b2ff7cca 100644 --- a/core/utils/checksum_bench.cc +++ b/core/utils/checksum_bench.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/checksum_test.cc b/core/utils/checksum_test.cc index ee7ec8d72a..e35f93ed55 100644 --- a/core/utils/checksum_test.cc +++ b/core/utils/checksum_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/codel.h b/core/utils/codel.h index 5fb622f6b9..ab4bb99ab9 100644 --- a/core/utils/codel.h +++ b/core/utils/codel.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/codel_test.cc b/core/utils/codel_test.cc index 35ed0d6fb2..d1c1e128b3 100644 --- a/core/utils/codel_test.cc +++ b/core/utils/codel_test.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/common.h b/core/utils/common.h index 75634d2b5c..712fe26822 100644 --- a/core/utils/common.h +++ b/core/utils/common.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/copy.cc b/core/utils/copy.cc index 46bb574421..a7cf1c6d9e 100644 --- a/core/utils/copy.cc +++ b/core/utils/copy.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/copy.h b/core/utils/copy.h index a332d4993b..41582687b8 100644 --- a/core/utils/copy.h +++ b/core/utils/copy.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/copy_bench.cc b/core/utils/copy_bench.cc index 705eaf7285..93fe3d75ed 100644 --- a/core/utils/copy_bench.cc +++ b/core/utils/copy_bench.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/cuckoo_map.h b/core/utils/cuckoo_map.h index 6213ce7d92..24c61de545 100644 --- a/core/utils/cuckoo_map.h +++ b/core/utils/cuckoo_map.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/cuckoo_map_bench.cc b/core/utils/cuckoo_map_bench.cc index d4982bb5f3..c4aed4a66e 100644 --- a/core/utils/cuckoo_map_bench.cc +++ b/core/utils/cuckoo_map_bench.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/cuckoo_map_test.cc b/core/utils/cuckoo_map_test.cc index 0fc50082be..a86b804b1d 100644 --- a/core/utils/cuckoo_map_test.cc +++ b/core/utils/cuckoo_map_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/endian.cc b/core/utils/endian.cc index 4fb3bd34f6..74a56ef2ee 100644 --- a/core/utils/endian.cc +++ b/core/utils/endian.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/endian.h b/core/utils/endian.h index 8dc62dbe49..98c15979a5 100644 --- a/core/utils/endian.h +++ b/core/utils/endian.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/endian_test.cc b/core/utils/endian_test.cc index 3f0e11cab4..e273ed7151 100644 --- a/core/utils/endian_test.cc +++ b/core/utils/endian_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/ether.cc b/core/utils/ether.cc index 61cb62a07a..85979ca329 100644 --- a/core/utils/ether.cc +++ b/core/utils/ether.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/ether.h b/core/utils/ether.h index 436e622eed..8ed2c4934d 100644 --- a/core/utils/ether.h +++ b/core/utils/ether.h @@ -2,6 +2,8 @@ // Copyright (c) 2017, Cloudigo. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/ether_test.cc b/core/utils/ether_test.cc index 2689056407..8ee9f32bd6 100644 --- a/core/utils/ether_test.cc +++ b/core/utils/ether_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/exact_match_table.h b/core/utils/exact_match_table.h index f5238dd5fb..b9779db8b3 100644 --- a/core/utils/exact_match_table.h +++ b/core/utils/exact_match_table.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/exact_match_table_test.cc b/core/utils/exact_match_table_test.cc index af49ce5c23..3c9938553b 100644 --- a/core/utils/exact_match_table_test.cc +++ b/core/utils/exact_match_table_test.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/extended_priority_queue.h b/core/utils/extended_priority_queue.h index e82f5b0e1b..54257b2b77 100644 --- a/core/utils/extended_priority_queue.h +++ b/core/utils/extended_priority_queue.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/extended_priority_queue_test.cc b/core/utils/extended_priority_queue_test.cc index 5f235c548f..fabf559d95 100644 --- a/core/utils/extended_priority_queue_test.cc +++ b/core/utils/extended_priority_queue_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/fifo_opener.cc b/core/utils/fifo_opener.cc index 6e2c1cc99f..f7ba665468 100644 --- a/core/utils/fifo_opener.cc +++ b/core/utils/fifo_opener.cc @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/fifo_opener.h b/core/utils/fifo_opener.h index f9fc348ed0..13d50185d7 100644 --- a/core/utils/fifo_opener.h +++ b/core/utils/fifo_opener.h @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/fifo_test.cc b/core/utils/fifo_test.cc index 441f749eb1..39459403b3 100644 --- a/core/utils/fifo_test.cc +++ b/core/utils/fifo_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/format.cc b/core/utils/format.cc index 1454d00f8c..ee42b9ae01 100644 --- a/core/utils/format.cc +++ b/core/utils/format.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/format.h b/core/utils/format.h index 687b4d77c3..836a5dedd4 100644 --- a/core/utils/format.h +++ b/core/utils/format.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/histogram.h b/core/utils/histogram.h index 5fe654a602..4f57a30ed0 100644 --- a/core/utils/histogram.h +++ b/core/utils/histogram.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/histogram_test.cc b/core/utils/histogram_test.cc index 4a82e94791..f5af95a143 100644 --- a/core/utils/histogram_test.cc +++ b/core/utils/histogram_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/http_parser.cc b/core/utils/http_parser.cc index 2431f4ab01..84be123eec 100644 --- a/core/utils/http_parser.cc +++ b/core/utils/http_parser.cc @@ -2,6 +2,8 @@ * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, * Shigeo Mitsunari * + * SPDX-License-Identifier: MIT or Artistic-1.0-Perl + * * The software is licensed under either the MIT License (below) or the Perl * license. * diff --git a/core/utils/http_parser.h b/core/utils/http_parser.h index e57b8f2ab5..03e67622f9 100644 --- a/core/utils/http_parser.h +++ b/core/utils/http_parser.h @@ -2,6 +2,8 @@ * Copyright (c) 2009-2014 Kazuho Oku, Tokuhiro Matsuno, Daisuke Murase, * Shigeo Mitsunari * + * SPDX-License-Identifier: MIT or Artistic-1.0-Perl + * * The software is licensed under either the MIT License (below) or the Perl * license. * diff --git a/core/utils/icmp.h b/core/utils/icmp.h index 9e553bc219..8002778e37 100644 --- a/core/utils/icmp.h +++ b/core/utils/icmp.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/ip.cc b/core/utils/ip.cc index 00296c1c99..7da456d54b 100644 --- a/core/utils/ip.cc +++ b/core/utils/ip.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/ip.h b/core/utils/ip.h index 5bbd086ae3..37cf842fbf 100644 --- a/core/utils/ip.h +++ b/core/utils/ip.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/ip_test.cc b/core/utils/ip_test.cc index 0e4db29fea..620605b947 100644 --- a/core/utils/ip_test.cc +++ b/core/utils/ip_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/llqueue_test.cc b/core/utils/llqueue_test.cc index a79861db83..c14b43fdfa 100644 --- a/core/utils/llqueue_test.cc +++ b/core/utils/llqueue_test.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/lock_less_queue.h b/core/utils/lock_less_queue.h index 6c5bcdb619..f120542d02 100644 --- a/core/utils/lock_less_queue.h +++ b/core/utils/lock_less_queue.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/mcslock.h b/core/utils/mcslock.h index a78f550b30..c3da47d1a9 100644 --- a/core/utils/mcslock.h +++ b/core/utils/mcslock.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/mpls.h b/core/utils/mpls.h index 9afbda5588..ce08fbe828 100644 --- a/core/utils/mpls.h +++ b/core/utils/mpls.h @@ -1,6 +1,8 @@ // Copyright (c) 2017, Cloudigo. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/pcap.h b/core/utils/pcap.h index 59d4a3f46a..241e16f951 100644 --- a/core/utils/pcap.h +++ b/core/utils/pcap.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/pcap_handle.cc b/core/utils/pcap_handle.cc index 0fe395f187..3c94c9af37 100644 --- a/core/utils/pcap_handle.cc +++ b/core/utils/pcap_handle.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/pcap_handle.h b/core/utils/pcap_handle.h index 48fc56d40a..ec265c07c8 100644 --- a/core/utils/pcap_handle.h +++ b/core/utils/pcap_handle.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/pcap_handle_test.cc b/core/utils/pcap_handle_test.cc index 88565333d6..f9a3266220 100644 --- a/core/utils/pcap_handle_test.cc +++ b/core/utils/pcap_handle_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/pcapng.h b/core/utils/pcapng.h index 573374e086..215dbe8f0b 100644 --- a/core/utils/pcapng.h +++ b/core/utils/pcapng.h @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/queue.h b/core/utils/queue.h index 01637daf3c..6f8964bb53 100644 --- a/core/utils/queue.h +++ b/core/utils/queue.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/random.h b/core/utils/random.h index 152e20a2bf..05e0658908 100644 --- a/core/utils/random.h +++ b/core/utils/random.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/simd.cc b/core/utils/simd.cc index a7fb9a7122..a6270bc362 100644 --- a/core/utils/simd.cc +++ b/core/utils/simd.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/simd.h b/core/utils/simd.h index 8e204af422..f55d71a393 100644 --- a/core/utils/simd.h +++ b/core/utils/simd.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/syscallthread.cc b/core/utils/syscallthread.cc index 7b3a392af6..7fdd841d80 100644 --- a/core/utils/syscallthread.cc +++ b/core/utils/syscallthread.cc @@ -1,6 +1,8 @@ // Copyright (c) 2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/syscallthread.h b/core/utils/syscallthread.h index 165dcbb44a..79869caa0d 100644 --- a/core/utils/syscallthread.h +++ b/core/utils/syscallthread.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/tcp.h b/core/utils/tcp.h index 58dda3bb97..8d3826e176 100644 --- a/core/utils/tcp.h +++ b/core/utils/tcp.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/tcp_flow_reconstruct.h b/core/utils/tcp_flow_reconstruct.h index 6332222db4..d728dc4754 100644 --- a/core/utils/tcp_flow_reconstruct.h +++ b/core/utils/tcp_flow_reconstruct.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/tcp_flow_reconstruct_test.cc b/core/utils/tcp_flow_reconstruct_test.cc index bfd47ca9e7..cbc4f2fdf6 100644 --- a/core/utils/tcp_flow_reconstruct_test.cc +++ b/core/utils/tcp_flow_reconstruct_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/time.cc b/core/utils/time.cc index 184afcceb3..4f3eea1ca1 100644 --- a/core/utils/time.cc +++ b/core/utils/time.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/time.h b/core/utils/time.h index 13dfb55137..6b94bfef8b 100644 --- a/core/utils/time.h +++ b/core/utils/time.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/time_test.cc b/core/utils/time_test.cc index 5fee77f594..e00a500e73 100644 --- a/core/utils/time_test.cc +++ b/core/utils/time_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/trie.h b/core/utils/trie.h index e331d3d54c..5399a26b29 100644 --- a/core/utils/trie.h +++ b/core/utils/trie.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/trie_test.cc b/core/utils/trie_test.cc index a61c0faf7b..bfd5225ba5 100644 --- a/core/utils/trie_test.cc +++ b/core/utils/trie_test.cc @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/udp.h b/core/utils/udp.h index 9ba6397e4f..0ef3bb7230 100644 --- a/core/utils/udp.h +++ b/core/utils/udp.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/utils/vxlan.h b/core/utils/vxlan.h index 5c2cec0ae3..9a7ee700e5 100644 --- a/core/utils/vxlan.h +++ b/core/utils/vxlan.h @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/worker.cc b/core/worker.cc index c7c1c60f75..96578a1ecf 100644 --- a/core/worker.cc +++ b/core/worker.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/core/worker.h b/core/worker.h index e18bff121d..07588d7f27 100644 --- a/core/worker.h +++ b/core/worker.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch b/deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch index a4aeefef11..b4d894d1af 100644 --- a/deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch +++ b/deps/0001-af_packet-Avoid-set-ioctl-if-there-is-no-flag-diff.patch @@ -1,3 +1,6 @@ +SPDX-License-Identifier: Apache-2.0 +Copyright 2019 Intel Corporation + From e1bc63488d346cb84ae7e76f2bc480247f577abb Mon Sep 17 00:00:00 2001 From: Saikrishna Edupuganti Date: Fri, 12 Jun 2020 21:36:53 +0000 diff --git a/env/after_install.sh b/env/after_install.sh index a17ddc3a8b..2ab7f5191e 100644 --- a/env/after_install.sh +++ b/env/after_install.sh @@ -4,6 +4,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/env/before_remove.sh b/env/before_remove.sh index d81851c158..a0fe12693e 100644 --- a/env/before_remove.sh +++ b/env/before_remove.sh @@ -4,6 +4,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/env/rebuild_images.py b/env/rebuild_images.py index c2e16dfc01..f6b82cb14d 100755 --- a/env/rebuild_images.py +++ b/env/rebuild_images.py @@ -4,6 +4,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/install_git_hooks.sh b/install_git_hooks.sh index 15058e933e..48afa79d52 100755 --- a/install_git_hooks.sh +++ b/install_git_hooks.sh @@ -3,6 +3,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/protobuf/bess_msg.proto b/protobuf/bess_msg.proto index 9b30de3447..52e85bbbdc 100644 --- a/protobuf/bess_msg.proto +++ b/protobuf/bess_msg.proto @@ -2,6 +2,8 @@ // Copyright (c) 2017, The Regents of the University of California. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/protobuf/error.proto b/protobuf/error.proto index 04b352c543..8b9bfd5544 100644 --- a/protobuf/error.proto +++ b/protobuf/error.proto @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index 68ebba6fd7..86fb842f7b 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -2,6 +2,8 @@ // Copyright (c) 2017, The Regents of the University of California. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index 7896a22a84..c716139c72 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/protobuf/service.proto b/protobuf/service.proto index 706a283a46..b5f4dc11b1 100644 --- a/protobuf/service.proto +++ b/protobuf/service.proto @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/protobuf/tests/test_msg.proto b/protobuf/tests/test_msg.proto index 50dc75ee41..e71517f937 100644 --- a/protobuf/tests/test_msg.proto +++ b/protobuf/tests/test_msg.proto @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/protobuf/util_msg.proto b/protobuf/util_msg.proto index 4df01fc67b..84d80dc6e0 100644 --- a/protobuf/util_msg.proto +++ b/protobuf/util_msg.proto @@ -1,6 +1,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/pybess/bess.py b/pybess/bess.py index ab8288052d..bf8f4aac7e 100644 --- a/pybess/bess.py +++ b/pybess/bess.py @@ -3,6 +3,8 @@ # Copyright (c) 2017, Cloudigo. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/pybess/module.py b/pybess/module.py index eebb128949..f76c4d2909 100644 --- a/pybess/module.py +++ b/pybess/module.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/pybess/pm_import.py b/pybess/pm_import.py index 6afadadbb3..7143cf6189 100644 --- a/pybess/pm_import.py +++ b/pybess/pm_import.py @@ -2,6 +2,8 @@ # Copyright (c) 2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/pybess/port.py b/pybess/port.py index 2763bbb2de..19b3c3f0d3 100644 --- a/pybess/port.py +++ b/pybess/port.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/pybess/protobuf_to_dict.py b/pybess/protobuf_to_dict.py index 8312d384a0..a472e94f33 100644 --- a/pybess/protobuf_to_dict.py +++ b/pybess/protobuf_to_dict.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/pybess/test_bess.txt b/pybess/test_bess.txt index 509713a135..33f6e5b4ac 100644 --- a/pybess/test_bess.txt +++ b/pybess/test_bess.txt @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/pybess/test_protobuf_to_dict.py b/pybess/test_protobuf_to_dict.py index 371892dbba..0b9833c0b4 100644 --- a/pybess/test_protobuf_to_dict.py +++ b/pybess/test_protobuf_to_dict.py @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/sample_plugin/bessctl_conf/sequential_update.bess b/sample_plugin/bessctl_conf/sequential_update.bess index d5e12db6b6..b5f94b8730 100644 --- a/sample_plugin/bessctl_conf/sequential_update.bess +++ b/sample_plugin/bessctl_conf/sequential_update.bess @@ -2,6 +2,8 @@ # Copyright (c) 2016-2017, Nefeli Networks, Inc. # All rights reserved. # +# SPDX-License-Identifier: BSD-3-Clause +# # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # diff --git a/sample_plugin/modules/sequential_update.cc b/sample_plugin/modules/sequential_update.cc index 26e802efb6..c41e46191b 100644 --- a/sample_plugin/modules/sequential_update.cc +++ b/sample_plugin/modules/sequential_update.cc @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/sample_plugin/modules/sequential_update.h b/sample_plugin/modules/sequential_update.h index e2089400ed..6203c25a6f 100644 --- a/sample_plugin/modules/sequential_update.h +++ b/sample_plugin/modules/sequential_update.h @@ -2,6 +2,8 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // diff --git a/sample_plugin/protobuf/supdate_msg.proto b/sample_plugin/protobuf/supdate_msg.proto index bca8070e38..82b2b5b9ad 100644 --- a/sample_plugin/protobuf/supdate_msg.proto +++ b/sample_plugin/protobuf/supdate_msg.proto @@ -1,6 +1,8 @@ // Copyright (c) 2017, The Regents of the University of California. // All rights reserved. // +// SPDX-License-Identifier: BSD-3-Clause +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // From f07e18f39aca365b8b48821343aca63c1984165b Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Sat, 18 Feb 2023 17:48:50 -0800 Subject: [PATCH 54/62] Add GitHub Action for checking code format (C/C++ and Protobuf) (#15) * Add GitHub Action for checking code format (C/C++ and Protobuf) * Update GitHub Action to only remove the OS from the matrix * Address issues with format compliance for protobuf files * Add missing file that was not formatted * Update parameters for GitHub Action * Add missing license/copyright header and add an exception --- core/.clang-format => .clang-format | 0 .github/workflows/clang-format-check.yaml | 30 + .gitignore | 3 +- .reuse/dep5 | 2 +- CONTRIBUTING.md | 2 +- core/bessctl.h | 2 +- core/debug.cc | 10 +- core/drivers/pmd.cc | 44 +- core/metadata.h | 2 +- core/modules/arp_responder.h | 2 +- core/modules/drr.cc | 4 +- core/modules/drr.h | 2 +- core/modules/ether_encap.cc | 4 +- core/modules/exact_match.cc | 24 +- core/modules/flowgen.cc | 18 +- core/modules/ip_encap.cc | 7 +- core/modules/ip_lookup.cc | 43 +- core/modules/ip_lookup.h | 2 +- core/modules/l2_forward.cc | 2 +- core/modules/nat.cc | 12 +- core/modules/round_robin.h | 2 +- core/modules/timestamp.h | 4 +- core/modules/url_filter.cc | 29 +- core/modules/url_filter.h | 4 +- core/modules/vlan_push.cc | 7 +- core/modules/vxlan_decap.cc | 4 +- core/modules/wildcard_match.h | 2 +- core/opts.cc | 10 +- core/packet.h | 2 +- core/packet_pool.cc | 7 +- core/traffic_class_test.cc | 5 +- core/utils/arp.h | 17 +- core/utils/bits_test.cc | 2 +- core/utils/bpf.cc | 1185 ++++++++++---------- core/utils/bpf.h | 16 +- core/utils/checksum.h | 5 +- core/utils/checksum_test.cc | 5 +- core/utils/codel.h | 79 +- core/utils/copy_bench.cc | 4 +- core/utils/cuckoo_map.h | 8 +- core/utils/cuckoo_map_test.cc | 6 +- core/utils/endian.h | 2 +- core/utils/endian_test.cc | 2 +- core/utils/ether_test.cc | 2 +- core/utils/exact_match_table_test.cc | 7 +- core/utils/extended_priority_queue_test.cc | 2 +- core/utils/fifo_opener.cc | 2 +- core/utils/fifo_test.cc | 2 +- core/utils/histogram_test.cc | 2 +- core/utils/http_parser.cc | 46 +- core/utils/icmp.h | 2 +- core/utils/ip.h | 2 +- core/utils/ip_test.cc | 2 +- core/utils/llqueue_test.cc | 4 +- core/utils/lock_less_queue.h | 8 +- core/utils/mcslock.h | 3 +- core/utils/mpls.h | 12 +- core/utils/pcap_handle.cc | 2 +- core/utils/queue.h | 7 +- core/utils/simd.cc | 4 +- core/utils/syscallthread.cc | 2 +- core/utils/tcp.h | 2 +- core/utils/time.cc | 2 +- core/utils/trie_test.cc | 2 +- core/utils/udp.h | 2 +- core/utils/vxlan.h | 2 +- protobuf/bess_msg.proto | 121 +- protobuf/module_msg.proto | 787 +++++++------ protobuf/ports/port_msg.proto | 4 +- protobuf/service.proto | 106 +- protobuf/tests/test_msg.proto | 4 +- protobuf/util_msg.proto | 19 +- sample_plugin/modules/sequential_update.cc | 44 +- sample_plugin/modules/sequential_update.h | 14 +- sample_plugin/protobuf/supdate_msg.proto | 26 +- 75 files changed, 1499 insertions(+), 1369 deletions(-) rename core/.clang-format => .clang-format (100%) create mode 100644 .github/workflows/clang-format-check.yaml diff --git a/core/.clang-format b/.clang-format similarity index 100% rename from core/.clang-format rename to .clang-format diff --git a/.github/workflows/clang-format-check.yaml b/.github/workflows/clang-format-check.yaml new file mode 100644 index 0000000000..63dc4c44c1 --- /dev/null +++ b/.github/workflows/clang-format-check.yaml @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2023 Intel Corporation + +name: C++/C/Protobuf Format Check +on: + - pull_request +jobs: + format-check: + runs-on: '${{ matrix.os }}' + strategy: + matrix: + os: + - ubuntu-20.04 + path: + - check: 'core' + exclude: '(kmod)' # Exclude "kmod" dir because of different format + - check: 'protobuf' + exclude: '' # Nothing to exclude + - check: 'sample_plugin/modules' + exclude: '' # Nothing to exclude + - check: 'sample_plugin/protobuf' + exclude: '' # Nothing to exclude + steps: + - uses: actions/checkout@v3 + - name: Run clang-format style check for C/C++/Protobuf programs. + uses: jidicula/clang-format-action@v4.9.0 + with: + clang-format-version: '12' + check-path: ${{ matrix.path['check'] }} + exclude-regex: ${{ matrix.path['exclude'] }} diff --git a/.gitignore b/.gitignore index 5fba308b21..bd1afe7f17 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ compile_commands.json # virtualenv venv/ -# Keep GitHub Actions and Reuse +# Keep GitHub Actions, reuse, and clang-format file !.github !.reuse +!.clang-format diff --git a/.reuse/dep5 b/.reuse/dep5 index 49b5fbe46b..700508dea9 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -3,7 +3,7 @@ Upstream-Name: bess Upstream-Contact: OMEC Developers Source: https://github.com/omec-project/bess -Files: .codecov.yml .gitattributes .gitignore CONTRIBUTING.md README.md requirements.txt .hooks/pre-commit bessctl/server.py bessctl/conf/port/vhost/README.md bessctl/conf/samples/mpls_test.bess bessctl/conf/samples/tc/wfs_double.bess bessctl/module_tests/*.pcap bessctl/static/*.* core/.clang-format core/.gitignore core/coverage core/*.suppress core/memory*.* core/packet_pool.* core/kmod/.clang-format core/kmod/.gitignore core/kmod/install core/pb/.gitignore core/resume_hooks/README.md core/testdata/test-pktcaptures/*.bytes core/testdata/test-pktcaptures/*.pcap deps/bpf_validate.patch deps/ethdev_include.patch doxygen/README.md doxygen/bess.dox env/*.yml env/Dockerfile env/README.md env/Vagrantfile pybess/**/__init__.py pybess/**/.gitignore sample_plugin/README.md +Files: .codecov.yml .gitattributes .gitignore CONTRIBUTING.md README.md requirements.txt .hooks/pre-commit bessctl/server.py bessctl/conf/port/vhost/README.md bessctl/conf/samples/mpls_test.bess bessctl/conf/samples/tc/wfs_double.bess bessctl/module_tests/*.pcap bessctl/static/*.* .clang-format core/.gitignore core/coverage core/*.suppress core/memory*.* core/packet_pool.* core/kmod/.clang-format core/kmod/.gitignore core/kmod/install core/pb/.gitignore core/resume_hooks/README.md core/testdata/test-pktcaptures/*.bytes core/testdata/test-pktcaptures/*.pcap deps/bpf_validate.patch deps/ethdev_include.patch doxygen/README.md doxygen/bess.dox env/*.yml env/Dockerfile env/README.md env/Vagrantfile pybess/**/__init__.py pybess/**/.gitignore sample_plugin/README.md Copyright: 2016-2017, Nefeli Networks, Inc. Copyright: 2017, The Regents of the University of California. License: BSD-3-Clause diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d96a49855..a0e9892340 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ You are welcome to [make a GitHub Pull Request](https://github.com/omec-project/ Please respect the following coding styles. Let's not be too dogmatic, though. * C++: [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) - * There is a [`.clang_format`](https://github.com/omec-project/bess/blob/master/core/.clang-format) file that you can utilize directly with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) or integrate with your favorite editor ([Vim](https://github.com/rhysd/vim-clang-format), [Emacs](https://llvm.org/svn/llvm-project/cfe/trunk/tools/clang-format/clang-format.el), [Atom](https://atom.io/packages/clang-format), etc.) + * There is a [`.clang_format`](https://github.com/omec-project/bess/blob/master/.clang-format) file that you can utilize directly with [`clang-format`](https://clang.llvm.org/docs/ClangFormat.html) or integrate with your favorite editor ([Vim](https://github.com/rhysd/vim-clang-format), [Emacs](https://llvm.org/svn/llvm-project/cfe/trunk/tools/clang-format/clang-format.el), [Atom](https://atom.io/packages/clang-format), etc.) * C: [Linux kernel coding style](https://github.com/torvalds/linux/blob/master/Documentation/process/coding-style.rst) * Currently C is only used for the Linux kernel module. * Python: [PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) diff --git a/core/bessctl.h b/core/bessctl.h index 6bf36ce376..bb16fb121f 100644 --- a/core/bessctl.h +++ b/core/bessctl.h @@ -32,8 +32,8 @@ #ifndef BESS_BESSCTL_H_ #define BESS_BESSCTL_H_ -#include #include +#include // gRPC server encapsulation. Usage: // ApiServer server; diff --git a/core/debug.cc b/core/debug.cc index 39459ec295..3ced41baea 100644 --- a/core/debug.cc +++ b/core/debug.cc @@ -55,10 +55,10 @@ #include #include "module.h" +#include "opts.h" #include "packet.h" #include "scheduler.h" #include "traffic_class.h" -#include "opts.h" #include "utils/format.h" namespace bess { @@ -378,7 +378,7 @@ static bool SkipSymbol(char *symbol) { abort(); } -[[ gnu::noinline, noreturn ]] void GoPanic() { +[[gnu::noinline, noreturn]] void GoPanic() { if (oops_msg == "") oops_msg = DumpStack(); @@ -452,7 +452,11 @@ static void TrapHandler(int sig_num, siginfo_t *info, void *ucontext) { void SetTrapHandler() { const int signals[] = { - SIGSEGV, SIGBUS, SIGILL, SIGFPE, SIGABRT, + SIGSEGV, + SIGBUS, + SIGILL, + SIGFPE, + SIGABRT, // SIGUSR1 is special in that it is triggered by user and does not abort SIGUSR1, }; diff --git a/core/drivers/pmd.cc b/core/drivers/pmd.cc index 2b779126ca..aec5f6dfdd 100644 --- a/core/drivers/pmd.cc +++ b/core/drivers/pmd.cc @@ -259,8 +259,7 @@ CommandResponse flow_create_one(dpdk_port_t port_id, #define NUM_ELEMENTS(x) (sizeof(x) / sizeof((x)[0])) -enum FlowProfile : uint32_t -{ +enum FlowProfile : uint32_t { profileN3 = 3, profileN6 = 6, profileN9 = 9, @@ -270,19 +269,17 @@ CommandResponse flow_create(dpdk_port_t port_id, const uint32_t &flow_profile) { CommandResponse err; rte_flow_item_type N39_NSA[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_GTPU, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END}; + RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, RTE_FLOW_ITEM_TYPE_UDP, + RTE_FLOW_ITEM_TYPE_GTPU, RTE_FLOW_ITEM_TYPE_IPV4, RTE_FLOW_ITEM_TYPE_END}; rte_flow_item_type N39_SA[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, RTE_FLOW_ITEM_TYPE_UDP, - RTE_FLOW_ITEM_TYPE_GTPU, RTE_FLOW_ITEM_TYPE_GTP_PSC, - RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_UDP, RTE_FLOW_ITEM_TYPE_GTPU, + RTE_FLOW_ITEM_TYPE_GTP_PSC, RTE_FLOW_ITEM_TYPE_IPV4, RTE_FLOW_ITEM_TYPE_END}; - rte_flow_item_type N6[] = { - RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, - RTE_FLOW_ITEM_TYPE_END}; + rte_flow_item_type N6[] = {RTE_FLOW_ITEM_TYPE_ETH, RTE_FLOW_ITEM_TYPE_IPV4, + RTE_FLOW_ITEM_TYPE_END}; switch (flow_profile) { uint64_t rss_types; @@ -302,8 +299,8 @@ CommandResponse flow_create(dpdk_port_t port_id, const uint32_t &flow_profile) { // N6 traffic case profileN6: rss_types = ETH_RSS_IPV4 | ETH_RSS_L3_DST_ONLY; - err = flow_create_one(port_id, flow_profile, NUM_ELEMENTS(N6), - rss_types, N6); + err = flow_create_one(port_id, flow_profile, NUM_ELEMENTS(N6), rss_types, + N6); break; // N9 traffic with and without PDU Session container @@ -384,15 +381,16 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { return CommandFailure(-ret, "rte_eth_dev_configure() failed"); } - int sid = arg.socket_case() == bess::pb::PMDPortArg::kSocketId ? - arg.socket_id() : rte_eth_dev_socket_id(ret_port_id); + int sid = arg.socket_case() == bess::pb::PMDPortArg::kSocketId + ? arg.socket_id() + : rte_eth_dev_socket_id(ret_port_id); /* if socket_id is invalid, set to 0 */ if (sid < 0 || sid > RTE_MAX_NUMA_NODES) { LOG(WARNING) << "Invalid socket, falling back... "; sid = 0; } LOG(INFO) << "Initializing Port:" << ret_port_id - << " with memory from socket " << sid; + << " with memory from socket " << sid; eth_rxconf = dev_info.default_rxconf; eth_rxconf.rx_drop_en = 1; @@ -470,8 +468,9 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { } dpdk_port_id_ = ret_port_id; - int numa_node = arg.socket_case() == bess::pb::PMDPortArg::kSocketId ? - sid : rte_eth_dev_socket_id(ret_port_id); + int numa_node = arg.socket_case() == bess::pb::PMDPortArg::kSocketId + ? sid + : rte_eth_dev_socket_id(ret_port_id); node_placement_ = numa_node == -1 ? UNCONSTRAINED_SOCKET : (1ull << numa_node); @@ -483,7 +482,7 @@ CommandResponse PMDPort::Init(const bess::pb::PMDPortArg &arg) { driver_ = dev_info.driver_name ?: "unknown"; - if (arg.flow_profiles_size() > 0){ + if (arg.flow_profiles_size() > 0) { for (int i = 0; i < arg.flow_profiles_size(); ++i) { err = flow_create(ret_port_id, arg.flow_profiles(i)); if (err.error().code() != 0) { @@ -603,10 +602,9 @@ void PMDPort::CollectStats(bool reset) { // ice/i40e/net_e1000_igb PMD drivers, ixgbevf and net_bonding vdevs don't // support per-queue stats - if (driver_ == "net_ice" || driver_ == "net_iavf" || - driver_ == "net_i40e" || driver_ == "net_i40e_vf" || - driver_ == "net_ixgbe_vf" || driver_ == "net_bonding" || - driver_ == "net_e1000_igb") { + if (driver_ == "net_ice" || driver_ == "net_iavf" || driver_ == "net_i40e" || + driver_ == "net_i40e_vf" || driver_ == "net_ixgbe_vf" || + driver_ == "net_bonding" || driver_ == "net_e1000_igb") { // NOTE: // - if link is down, tx bytes won't increase // - if destination MAC address is incorrect, rx pkts won't increase diff --git a/core/metadata.h b/core/metadata.h index 27b8f79c61..6304bacd3e 100644 --- a/core/metadata.h +++ b/core/metadata.h @@ -211,7 +211,7 @@ class Pipeline { // count(=int) represents how many modules registered the attribute, and the // attribute is deregistered once it reaches back to 0. // Those modules should agree on the same size(=size_t). - std::map > registered_attrs_; + std::map> registered_attrs_; }; extern bess::metadata::Pipeline default_pipeline; diff --git a/core/modules/arp_responder.h b/core/modules/arp_responder.h index a05735d8ef..82ab0692b2 100644 --- a/core/modules/arp_responder.h +++ b/core/modules/arp_responder.h @@ -41,8 +41,8 @@ #include "../utils/ether.h" #include "../utils/ip.h" -using bess::utils::Ethernet; using bess::utils::be32_t; +using bess::utils::Ethernet; // ARP cache entry struct which keeps mapping between IP and MAC struct arp_entry { diff --git a/core/modules/drr.cc b/core/modules/drr.cc index b86e5d8bf7..204b2406c1 100644 --- a/core/modules/drr.cc +++ b/core/modules/drr.cc @@ -154,7 +154,9 @@ struct task_result DRR::RunTask(Context *ctx, bess::PacketBatch *batch, void *) { if (children_overload_ > 0) { return { - .block = true, .packets = 0, .bits = 0, + .block = true, + .packets = 0, + .bits = 0, }; } diff --git a/core/modules/drr.h b/core/modules/drr.h index a23fb1ffdb..a2c1e9a2d1 100644 --- a/core/modules/drr.h +++ b/core/modules/drr.h @@ -44,8 +44,8 @@ #include "../utils/cuckoo_map.h" #include "../utils/ip.h" -using bess::utils::Ipv4Prefix; using bess::utils::CuckooMap; +using bess::utils::Ipv4Prefix; // // This module implements Deficit Round Robin, a fair queueing algorithm, for diff --git a/core/modules/ether_encap.cc b/core/modules/ether_encap.cc index 1432778758..6009e13b5f 100644 --- a/core/modules/ether_encap.cc +++ b/core/modules/ether_encap.cc @@ -42,8 +42,8 @@ enum { ATTR_R_ETHER_TYPE, }; -CommandResponse EtherEncap::Init( - const bess::pb::EtherEncapArg &arg[[maybe_unused]]) { +CommandResponse EtherEncap::Init(const bess::pb::EtherEncapArg &arg + [[maybe_unused]]) { using AccessMode = bess::metadata::Attribute::AccessMode; AddMetadataAttr("ether_src", sizeof(Ethernet::Address), AccessMode::kRead); diff --git a/core/modules/exact_match.cc b/core/modules/exact_match.cc index 7fc5fdbf28..078a5172fd 100644 --- a/core/modules/exact_match.cc +++ b/core/modules/exact_match.cc @@ -329,19 +329,18 @@ void ExactMatch::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { int cnt = batch->cnt(); Value default_value(default_gate); - int icnt=0; - for(int lcnt=0; lcnt=64) ? 64 : cnt-lcnt ; + int icnt = 0; + for (int lcnt = 0; lcnt < cnt; lcnt = lcnt + icnt) { + icnt = ((cnt - lcnt) >= 64) ? 64 : cnt - lcnt; ValueTuple *res[icnt]; - uint64_t hit_mask = table_.Find(keys+lcnt, res, icnt); + uint64_t hit_mask = table_.Find(keys + lcnt, res, icnt); for (int j = 0; j < icnt; j++) { - if ((hit_mask & ((uint64_t)1ULL << j)) == 0) - EmitPacket(ctx, batch->pkts()[j+lcnt], default_gate); - else { - setValues(batch->pkts()[j+lcnt], res[j]->action); - EmitPacket(ctx, batch->pkts()[j+lcnt], res[j]->gate); + if ((hit_mask & ((uint64_t)1ULL << j)) == 0) + EmitPacket(ctx, batch->pkts()[j + lcnt], default_gate); + else { + setValues(batch->pkts()[j + lcnt], res[j]->action); + EmitPacket(ctx, batch->pkts()[j + lcnt], res[j]->gate); } } } @@ -381,7 +380,8 @@ void ExactMatch::RuleFieldsFromPb( } for (int j = 0; j < field_size; j++) { rule->back().push_back(rule64 & 0xFFULL); - DLOG(INFO) << "Pushed " << std::hex << (rule64 & 0xFFULL) << " to rule."; + DLOG(INFO) << "Pushed " << std::hex << (rule64 & 0xFFULL) + << " to rule."; rule64 >>= 8; } } @@ -429,7 +429,7 @@ CommandResponse ExactMatch::CommandSetDefaultGate( } void ExactMatch::DeInit() { - table_.DeInit(); + table_.DeInit(); } ADD_MODULE(ExactMatch, "em", "Multi-field classifier with an exact match table") diff --git a/core/modules/flowgen.cc b/core/modules/flowgen.cc index 95f71c34e9..86c6a73126 100644 --- a/core/modules/flowgen.cc +++ b/core/modules/flowgen.cc @@ -41,15 +41,15 @@ #include "../utils/ip.h" #include "../utils/simd.h" #include "../utils/tcp.h" -#include "../utils/udp.h" #include "../utils/time.h" +#include "../utils/udp.h" +using bess::utils::be16_t; +using bess::utils::be32_t; using bess::utils::Ethernet; using bess::utils::Ipv4; using bess::utils::Tcp; using bess::utils::Udp; -using bess::utils::be16_t; -using bess::utils::be32_t; /* we ignore the last 1% tail to make the variance finite */ const double PARETO_TAIL_LIMIT = 0.99; @@ -183,10 +183,11 @@ void FlowGen::PopulateInitialFlows() { } } -CommandResponse FlowGen::ProcessUpdatableArguments(const bess::pb::FlowGenArg &arg) { - +CommandResponse FlowGen::ProcessUpdatableArguments( + const bess::pb::FlowGenArg &arg) { if (arg.template_().length() == 0) { - if (strnlen(reinterpret_cast(tmpl_), MAX_TEMPLATE_SIZE) == 0) { + if (strnlen(reinterpret_cast(tmpl_), MAX_TEMPLATE_SIZE) == + 0) { return CommandFailure(EINVAL, "must specify 'template'"); } } else { @@ -436,7 +437,6 @@ bess::Packet *FlowGen::FillUdpPacket(struct flow *f) { return pkt; } - bess::Packet *FlowGen::FillTcpPacket(struct flow *f) { bess::Packet *pkt; @@ -534,7 +534,9 @@ struct task_result FlowGen::RunTask(Context *ctx, bess::PacketBatch *batch, void *) { if (children_overload_ > 0) { return { - .block = true, .packets = 0, .bits = 0, + .block = true, + .packets = 0, + .bits = 0, }; } diff --git a/core/modules/ip_encap.cc b/core/modules/ip_encap.cc index e093def732..c60ddb2800 100644 --- a/core/modules/ip_encap.cc +++ b/core/modules/ip_encap.cc @@ -36,10 +36,10 @@ #include "../utils/ether.h" #include "../utils/ip.h" -using bess::utils::Ethernet; -using bess::utils::Ipv4; using bess::utils::be16_t; using bess::utils::be32_t; +using bess::utils::Ethernet; +using bess::utils::Ipv4; enum { ATTR_R_IP_SRC, @@ -49,7 +49,8 @@ enum { ATTR_W_ETHER_TYPE, }; -CommandResponse IPEncap::Init(const bess::pb::IPEncapArg &arg[[maybe_unused]]) { +CommandResponse IPEncap::Init(const bess::pb::IPEncapArg &arg + [[maybe_unused]]) { using AccessMode = bess::metadata::Attribute::AccessMode; AddMetadataAttr("ip_src", 4, AccessMode::kRead); diff --git a/core/modules/ip_lookup.cc b/core/modules/ip_lookup.cc index e112a2773b..2181640afb 100644 --- a/core/modules/ip_lookup.cc +++ b/core/modules/ip_lookup.cc @@ -49,8 +49,8 @@ static inline int is_valid_gate(gate_idx_t gate) { const Commands IPLookup::cmds = { {"add", "IPLookupCommandAddArg", MODULE_CMD_FUNC(&IPLookup::CommandAdd), Command::THREAD_UNSAFE}, - {"delete", "IPLookupCommandDeleteArg", MODULE_CMD_FUNC(&IPLookup::CommandDelete), - Command::THREAD_UNSAFE}, + {"delete", "IPLookupCommandDeleteArg", + MODULE_CMD_FUNC(&IPLookup::CommandDelete), Command::THREAD_UNSAFE}, {"clear", "EmptyArg", MODULE_CMD_FUNC(&IPLookup::CommandClear), Command::THREAD_UNSAFE}}; @@ -71,9 +71,11 @@ CommandResponse IPLookup::Init(const bess::pb::IPLookupArg &arg) { default_gate_ = DROP_GATE; #if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) - lpm_ = rte_lpm_create(name().c_str(), /* socket_id = */ rte_socket_id(), &conf); + lpm_ = + rte_lpm_create(name().c_str(), /* socket_id = */ rte_socket_id(), &conf); #else - lpm_ = rte_fib_create(name().c_str(), /* socket_id = */ rte_socket_id(), &conf); + lpm_ = + rte_fib_create(name().c_str(), /* socket_id = */ rte_socket_id(), &conf); #endif if (!lpm_) { @@ -184,14 +186,15 @@ void IPLookup::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { RunNextModule(ctx, batch); else for (i = 0; i < cnt; i++) { - EmitPacket(ctx, batch->pkts()[i], (next_hops[i] == DROP_GATE) ? default_gate_ : next_hops[i]); + EmitPacket(ctx, batch->pkts()[i], + (next_hops[i] == DROP_GATE) ? default_gate_ : next_hops[i]); } USED(default_gate); #endif } -ParsedPrefix IPLookup::ParseIpv4Prefix( - const std::string &prefix, uint64_t prefix_len) { +ParsedPrefix IPLookup::ParseIpv4Prefix(const std::string &prefix, + uint64_t prefix_len) { using bess::utils::Format; be32_t net_addr; be32_t net_mask; @@ -200,25 +203,23 @@ ParsedPrefix IPLookup::ParseIpv4Prefix( return std::make_tuple(EINVAL, "prefix' is missing", be32_t(0)); } if (!bess::utils::ParseIpv4Address(prefix, &net_addr)) { - return std::make_tuple(EINVAL, - Format("Invalid IP prefix: %s", prefix.c_str()), - be32_t(0)); + return std::make_tuple( + EINVAL, Format("Invalid IP prefix: %s", prefix.c_str()), be32_t(0)); } if (prefix_len > 32) { - return std::make_tuple(EINVAL, - Format("Invalid prefix length: %" PRIu64, - prefix_len), - be32_t(0)); + return std::make_tuple( + EINVAL, Format("Invalid prefix length: %" PRIu64, prefix_len), + be32_t(0)); } net_mask = be32_t(bess::utils::SetBitsLow(prefix_len)); if ((net_addr & ~net_mask).value()) { - return std::make_tuple(EINVAL, - Format("Invalid IP prefix %s/%" PRIu64 " %x %x", - prefix.c_str(), prefix_len, net_addr.value(), - net_mask.value()), - be32_t(0)); + return std::make_tuple( + EINVAL, + Format("Invalid IP prefix %s/%" PRIu64 " %x %x", prefix.c_str(), + prefix_len, net_addr.value(), net_mask.value()), + be32_t(0)); } return std::make_tuple(0, "", net_addr); } @@ -230,7 +231,7 @@ CommandResponse IPLookup::CommandAdd( ParsedPrefix prefix = ParseIpv4Prefix(arg.prefix(), prefix_len); if (std::get<0>(prefix)) { return CommandFailure(std::get<0>(prefix), "%s", - std::get<1>(prefix).c_str()); + std::get<1>(prefix).c_str()); } if (!is_valid_gate(gate)) { @@ -261,7 +262,7 @@ CommandResponse IPLookup::CommandDelete( ParsedPrefix prefix = ParseIpv4Prefix(arg.prefix(), prefix_len); if (std::get<0>(prefix)) { return CommandFailure(std::get<0>(prefix), "%s", - std::get<1>(prefix).c_str()); + std::get<1>(prefix).c_str()); } if (prefix_len == 0) { diff --git a/core/modules/ip_lookup.h b/core/modules/ip_lookup.h index c8ba0e9704..180c58d1e7 100644 --- a/core/modules/ip_lookup.h +++ b/core/modules/ip_lookup.h @@ -40,7 +40,7 @@ #if RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0) #include #else -#define USED(x) (void)(x) +#define USED(x) (void)(x) extern "C" { #include } diff --git a/core/modules/l2_forward.cc b/core/modules/l2_forward.cc index 88d5953dd6..3fc9db8da1 100644 --- a/core/modules/l2_forward.cc +++ b/core/modules/l2_forward.cc @@ -71,7 +71,7 @@ static int l2_init(struct l2_table *l2tbl, int size, int bucket) { return -EINVAL; } - l2tbl->table = new(std::nothrow) l2_entry[size * bucket]{}; + l2tbl->table = new (std::nothrow) l2_entry[size * bucket]{}; if (l2tbl->table == nullptr) { return -ENOMEM; diff --git a/core/modules/nat.cc b/core/modules/nat.cc index da5a3118e9..2ee9262e7d 100644 --- a/core/modules/nat.cc +++ b/core/modules/nat.cc @@ -47,13 +47,13 @@ using bess::utils::Ethernet; using bess::utils::Ipv4; using IpProto = bess::utils::Ipv4::Proto; -using bess::utils::Udp; -using bess::utils::Tcp; -using bess::utils::Icmp; using bess::utils::ChecksumIncrement16; using bess::utils::ChecksumIncrement32; -using bess::utils::UpdateChecksumWithIncrement; +using bess::utils::Icmp; +using bess::utils::Tcp; +using bess::utils::Udp; using bess::utils::UpdateChecksum16; +using bess::utils::UpdateChecksumWithIncrement; const Commands NAT::cmds = { {"get_initial_arg", "EmptyArg", MODULE_CMD_FUNC(&NAT::GetInitialArg), @@ -90,7 +90,9 @@ CommandResponse NAT::Init(const bess::pb::NATArg &arg) { std::vector port_list; if (address_range.port_ranges().size() == 0) { port_list.emplace_back(PortRange{ - .begin = 0u, .end = 65535u, .suspended = false, + .begin = 0u, + .end = 65535u, + .suspended = false, }); } for (const auto &range : address_range.port_ranges()) { diff --git a/core/modules/round_robin.h b/core/modules/round_robin.h index cc4e6e5770..14ff208f2a 100644 --- a/core/modules/round_robin.h +++ b/core/modules/round_robin.h @@ -62,7 +62,7 @@ * * mode: whether to schedule with per-packet or per-batch granularity * options * are "packet" or "batch". -*/ + */ class RoundRobin final : public Module { public: static const gate_idx_t kNumOGates = MAX_GATES; diff --git a/core/modules/timestamp.h b/core/modules/timestamp.h index 86bc4cdb94..7c52072061 100644 --- a/core/modules/timestamp.h +++ b/core/modules/timestamp.h @@ -41,7 +41,9 @@ class Timestamp final : public Module { using MarkerType = uint32_t; static const MarkerType kMarker = 0x54C5BE55; - Timestamp() : Module(), offset_(), attr_id_(-1) { max_allowed_workers_ = Worker::kMaxWorkers; } + Timestamp() : Module(), offset_(), attr_id_(-1) { + max_allowed_workers_ = Worker::kMaxWorkers; + } CommandResponse Init(const bess::pb::TimestampArg &arg); diff --git a/core/modules/url_filter.cc b/core/modules/url_filter.cc index 4dc53c6b82..2d3395e126 100644 --- a/core/modules/url_filter.cc +++ b/core/modules/url_filter.cc @@ -40,10 +40,10 @@ #include "../utils/http_parser.h" #include "../utils/ip.h" +using bess::utils::be16_t; using bess::utils::Ethernet; using bess::utils::Ipv4; using bess::utils::Tcp; -using bess::utils::be16_t; const uint64_t TIME_OUT_NS = 10ull * 1000 * 1000 * 1000; // 10 seconds @@ -60,7 +60,7 @@ const Commands UrlFilter::cmds = { Command::THREAD_UNSAFE}}; // Template for generating TCP packets without data -struct[[gnu::packed]] PacketTemplate { +struct [[gnu::packed]] PacketTemplate { Ethernet eth; Ipv4 ip; Tcp tcp; @@ -362,23 +362,26 @@ void UrlFilter::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { it->second.SetAnalyzed(); // Inject RST to destination - EmitPacket(ctx, GenerateResetPacket(eth->src_addr, eth->dst_addr, ip->src, - ip->dst, tcp->src_port, tcp->dst_port, - tcp->seq_num, tcp->ack_num), + EmitPacket(ctx, + GenerateResetPacket(eth->src_addr, eth->dst_addr, ip->src, + ip->dst, tcp->src_port, tcp->dst_port, + tcp->seq_num, tcp->ack_num), 0); // Inject 403 to source. 403 should arrive earlier than RST. - EmitPacket(ctx, Generate403Packet(eth->dst_addr, eth->src_addr, ip->dst, - ip->src, tcp->dst_port, tcp->src_port, - tcp->ack_num, tcp->seq_num), + EmitPacket(ctx, + Generate403Packet(eth->dst_addr, eth->src_addr, ip->dst, + ip->src, tcp->dst_port, tcp->src_port, + tcp->ack_num, tcp->seq_num), 1); // Inject RST to source - EmitPacket(ctx, GenerateResetPacket( - eth->dst_addr, eth->src_addr, ip->dst, ip->src, - tcp->dst_port, tcp->src_port, - be32_t(tcp->ack_num.value() + strlen(HTTP_403_BODY)), - tcp->seq_num), + EmitPacket(ctx, + GenerateResetPacket( + eth->dst_addr, eth->src_addr, ip->dst, ip->src, + tcp->dst_port, tcp->src_port, + be32_t(tcp->ack_num.value() + strlen(HTTP_403_BODY)), + tcp->seq_num), 1); // Drop the data packet diff --git a/core/modules/url_filter.h b/core/modules/url_filter.h index 87ada0f07b..36ba8d8e67 100644 --- a/core/modules/url_filter.h +++ b/core/modules/url_filter.h @@ -47,10 +47,10 @@ #include "../utils/tcp_flow_reconstruct.h" #include "../utils/trie.h" -using bess::utils::TcpFlowReconstruct; -using bess::utils::Trie; using bess::utils::be16_t; using bess::utils::be32_t; +using bess::utils::TcpFlowReconstruct; +using bess::utils::Trie; // A helper class that defines a TCP flow class alignas(16) Flow { diff --git a/core/modules/vlan_push.cc b/core/modules/vlan_push.cc index 18a349fb40..c4ad56ce08 100644 --- a/core/modules/vlan_push.cc +++ b/core/modules/vlan_push.cc @@ -76,9 +76,10 @@ void VLANPush::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { ethh = _mm_loadu_si128(reinterpret_cast<__m128i *>(new_head + 4)); be16_t tpid(be16_t::swap(_mm_extract_epi16(ethh, 6))); - ethh = _mm_insert_epi32(ethh, (tpid.value() == Ethernet::Type::kVlan) - ? qinq_tag.raw_value() - : vlan_tag.raw_value(), + ethh = _mm_insert_epi32(ethh, + (tpid.value() == Ethernet::Type::kVlan) + ? qinq_tag.raw_value() + : vlan_tag.raw_value(), 3); _mm_storeu_si128(reinterpret_cast<__m128i *>(new_head), ethh); diff --git a/core/modules/vxlan_decap.cc b/core/modules/vxlan_decap.cc index aefaacf45c..8251654905 100644 --- a/core/modules/vxlan_decap.cc +++ b/core/modules/vxlan_decap.cc @@ -46,8 +46,8 @@ enum { ATTR_W_TUN_ID, }; -CommandResponse VXLANDecap::Init( - const bess::pb::VXLANDecapArg &arg[[maybe_unused]]) { +CommandResponse VXLANDecap::Init(const bess::pb::VXLANDecapArg &arg + [[maybe_unused]]) { using AccessMode = bess::metadata::Attribute::AccessMode; AddMetadataAttr("tun_ip_src", 4, AccessMode::kWrite); diff --git a/core/modules/wildcard_match.h b/core/modules/wildcard_match.h index ae23da39ce..28b661ea41 100644 --- a/core/modules/wildcard_match.h +++ b/core/modules/wildcard_match.h @@ -212,7 +212,7 @@ class WildcardMatch final : public Module { size_t total_key_size_; /* a multiple of sizeof(uint64_t) */ size_t total_value_size_; /* a multiple of sizeof(uint64_t) */ - size_t entries_; /* a power of 2 */ + size_t entries_; /* a power of 2 */ // TODO(melvinw): this can be refactored to use ExactMatchTable std::vector fields_; diff --git a/core/opts.cc b/core/opts.cc index 5e32428d8b..346d5e65ef 100644 --- a/core/opts.cc +++ b/core/opts.cc @@ -64,7 +64,7 @@ static bool ValidateIovaMode(const char *, const std::string &value) { return (value == "") || (value == "pa") || (value == "va"); } DEFINE_string(iova, "", "DPDK IOVA mode: pa or va. Set auto if not specified"); -static bool _iova_dummy[[maybe_unused]] = +static bool _iova_dummy [[maybe_unused]] = google::RegisterFlagValidator(&FLAGS_iova, &ValidateIovaMode); static bool ValidateCoreID(const char *, int32_t value) { @@ -76,7 +76,7 @@ static bool ValidateCoreID(const char *, int32_t value) { return true; } DEFINE_int32(c, 0, "Core ID for the default worker thread"); -static const bool _c_dummy[[maybe_unused]] = +static const bool _c_dummy [[maybe_unused]] = google::RegisterFlagValidator(&FLAGS_c, &ValidateCoreID); static bool ValidateTCPPort(const char *, int32_t value) { @@ -98,7 +98,7 @@ DEFINE_int32( p, kDefaultPort, "Specifies the TCP port on which BESS listens for controller connections, " "if --grpc_url is empty. Deprecated, please use --grpc_url instead"); -static const bool _p_dummy[[maybe_unused]] = +static const bool _p_dummy [[maybe_unused]] = google::RegisterFlagValidator(&FLAGS_p, &ValidateTCPPort); static bool ValidateMegabytesPerSocket(const char *, int32_t value) { @@ -112,7 +112,7 @@ static bool ValidateMegabytesPerSocket(const char *, int32_t value) { DEFINE_int32(m, 1024, "Specifies per-socket hugepages to allocate (in MBs). " "If set to 0, no hugepage is used"); -static const bool _m_dummy[[maybe_unused]] = +static const bool _m_dummy [[maybe_unused]] = google::RegisterFlagValidator(&FLAGS_m, &ValidateMegabytesPerSocket); static bool ValidateBuffersPerSocket(const char *, int32_t value) { @@ -129,5 +129,5 @@ static bool ValidateBuffersPerSocket(const char *, int32_t value) { DEFINE_int32(buffers, 262144, "Specifies how many packet buffers to allocate per socket," " must be a power of 2."); -static const bool _buffers_dummy[[maybe_unused]] = +static const bool _buffers_dummy [[maybe_unused]] = google::RegisterFlagValidator(&FLAGS_buffers, &ValidateBuffersPerSocket); diff --git a/core/packet.h b/core/packet.h index 98c3b5a363..81fc0be7ae 100644 --- a/core/packet.h +++ b/core/packet.h @@ -269,7 +269,7 @@ class alignas(64) Packet { Packet *next_; // Next segment. nullptr if not scattered. // offset 88: - uint64_t _dummy8; // rte_mbuf.tx_offload + uint64_t _dummy8; // rte_mbuf.tx_offload // TODO: Add struct rte_mbuf_ext_shared_info *shinfo; uint16_t _dummy9; // rte_mbuf.priv_size uint16_t _dummy10; // rte_mbuf.timesync diff --git a/core/packet_pool.cc b/core/packet_pool.cc index c453fccd2c..8cf4340c0a 100644 --- a/core/packet_pool.cc +++ b/core/packet_pool.cc @@ -170,7 +170,8 @@ PlainPacketPool::PlainPacketPool(size_t capacity, int socket_id) size_t page_shift = __builtin_ffs(getpagesize()); size_t min_chunk_size, align; - size_t size = rte_mempool_op_calc_mem_size_default(pool_, pool_->size, page_shift, &min_chunk_size, &align); + size_t size = rte_mempool_op_calc_mem_size_default( + pool_, pool_->size, page_shift, &min_chunk_size, &align); void *addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); @@ -201,8 +202,8 @@ BessPacketPool::BessPacketPool(size_t capacity, int socket_id) while (pool_->populated_size < pool_->size) { size_t deficit = pool_->size - pool_->populated_size; size_t min_chunk_size, align; - size_t bytes = - rte_mempool_op_calc_mem_size_default(pool_, deficit, page_shift, &min_chunk_size, &align); + size_t bytes = rte_mempool_op_calc_mem_size_default( + pool_, deficit, page_shift, &min_chunk_size, &align); auto [addr, alloced_bytes] = mem_.AllocUpto(bytes); if (addr == nullptr) { diff --git a/core/traffic_class_test.cc b/core/traffic_class_test.cc index 6d203d0f1e..432847c482 100644 --- a/core/traffic_class_test.cc +++ b/core/traffic_class_test.cc @@ -409,8 +409,9 @@ TEST(DefaultScheduleOnce, TwoLeavesWeightedFair) { // (lowest) priority leaf that is unblocked at that time. TEST(DefaultScheduleOnce, TwoLeavesPriority) { DummyModule dm; - DefaultScheduler s(CT("root", {PRIORITY}, {{0, CT("rr_1", {ROUND_ROBIN})}, - {1, CT("rr_2", {ROUND_ROBIN})}})); + DefaultScheduler s( + CT("root", {PRIORITY}, + {{0, CT("rr_1", {ROUND_ROBIN})}, {1, CT("rr_2", {ROUND_ROBIN})}})); ASSERT_EQ(3, TrafficClassBuilder::Find("root")->Size()); RoundRobinTrafficClass *rr_1 = diff --git a/core/utils/arp.h b/core/utils/arp.h index 99b82f71f3..a29243c86a 100644 --- a/core/utils/arp.h +++ b/core/utils/arp.h @@ -40,7 +40,7 @@ namespace bess { namespace utils { // A basic ARP header definition -struct[[gnu::packed]] Arp { +struct [[gnu::packed]] Arp { // Ethernet hardware format for hrd enum HardwareAddress : uint16_t { kEthernet = 1, @@ -55,23 +55,22 @@ struct[[gnu::packed]] Arp { kInvReply = 9, }; - be16_t hw_addr; // format of hardware address (hrd) - be16_t proto_addr; // format of protocol address (pro) - uint8_t hw_addr_length; // length of hardware address (hln) - uint8_t proto_addr_length; // length of protocol address (pln) - be16_t opcode; // ARP opcode (command) (op) + be16_t hw_addr; // format of hardware address (hrd) + be16_t proto_addr; // format of protocol address (pro) + uint8_t hw_addr_length; // length of hardware address (hln) + uint8_t proto_addr_length; // length of protocol address (pln) + be16_t opcode; // ARP opcode (command) (op) // ARP Data Ethernet::Address sender_hw_addr; // sender hardware address (sha) be32_t sender_ip_addr; // sender IP address (sip) Ethernet::Address target_hw_addr; // target hardware address (tha) - be32_t target_ip_addr; // target IP address (tip) + be32_t target_ip_addr; // target IP address (tip) }; - static_assert(sizeof(Arp) == 28, "struct Arp size is incorrect"); +static_assert(sizeof(Arp) == 28, "struct Arp size is incorrect"); } // namespace utils } // namespace bess #endif // BESS_UTILS_ARP_H_ - diff --git a/core/utils/bits_test.cc b/core/utils/bits_test.cc index 3a136c6730..0e741f934b 100644 --- a/core/utils/bits_test.cc +++ b/core/utils/bits_test.cc @@ -307,4 +307,4 @@ TEST(Mask, ExtraLongUnAligned) { } } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/bpf.cc b/core/utils/bpf.cc index 133d41f267..bfbefbf269 100644 --- a/core/utils/bpf.cc +++ b/core/utils/bpf.cc @@ -6,17 +6,17 @@ * * SPDX-License-Identifier: BSD-3-Clause * -*/ + */ #include "bpf.h" namespace bess { namespace utils { -#ifdef __x86_64 // JIT compilation code only works in 64-bit - /* - * Registers - */ +#ifdef __x86_64 // JIT compilation code only works in 64-bit + /* + * Registers + */ #define RAX 0 #define RCX 1 #define RDX 2 @@ -72,7 +72,7 @@ namespace utils { #define BPF_JIT_FJMP 0x08 #define BPF_JIT_FLEN 0x10 -#define BPF_JIT_FLAG_ALL \ +#define BPF_JIT_FLAG_ALL \ (BPF_JIT_FPKT | BPF_JIT_FMEM | BPF_JIT_FJMP | BPF_JIT_FLEN) /* A stream of native binary code */ @@ -111,350 +111,350 @@ typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n); */ /* movl i32,r32 */ -#define MOVid(i32, r32) \ - do { \ - emitm(&stream, (11 << 4) | (1 << 3) | (r32 & 0x7), 1); \ - emitm(&stream, i32, 4); \ +#define MOVid(i32, r32) \ + do { \ + emitm(&stream, (11 << 4) | (1 << 3) | (r32 & 0x7), 1); \ + emitm(&stream, i32, 4); \ } while (0) /* movq i64,r64 */ -#define MOViq(i64, r64) \ - do { \ - emitm(&stream, 0x48, 1); \ - emitm(&stream, (11 << 4) | (1 << 3) | (r64 & 0x7), 1); \ - emitm(&stream, i64, 4); \ - emitm(&stream, (i64 >> 32), 4); \ +#define MOViq(i64, r64) \ + do { \ + emitm(&stream, 0x48, 1); \ + emitm(&stream, (11 << 4) | (1 << 3) | (r64 & 0x7), 1); \ + emitm(&stream, i64, 4); \ + emitm(&stream, (i64 >> 32), 4); \ } while (0) /* movl sr32,dr32 */ -#define MOVrd(sr32, dr32) \ - do { \ - emitm(&stream, 0x89, 1); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define MOVrd(sr32, dr32) \ + do { \ + emitm(&stream, 0x89, 1); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* movl sr32,dr32 (dr32 = %r8-15d) */ -#define MOVrd2(sr32, dr32) \ - do { \ - emitm(&stream, 0x8941, 2); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define MOVrd2(sr32, dr32) \ + do { \ + emitm(&stream, 0x8941, 2); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* movl sr32,dr32 (sr32 = %r8-15d) */ -#define MOVrd3(sr32, dr32) \ - do { \ - emitm(&stream, 0x8944, 2); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define MOVrd3(sr32, dr32) \ + do { \ + emitm(&stream, 0x8944, 2); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* movq sr64,dr64 */ -#define MOVrq(sr64, dr64) \ - do { \ - emitm(&stream, 0x8948, 2); \ - emitm(&stream, (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ +#define MOVrq(sr64, dr64) \ + do { \ + emitm(&stream, 0x8948, 2); \ + emitm(&stream, (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ } while (0) /* movq sr64,dr64 (dr64 = %r8-15) */ -#define MOVrq2(sr64, dr64) \ - do { \ - emitm(&stream, 0x8949, 2); \ - emitm(&stream, (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ +#define MOVrq2(sr64, dr64) \ + do { \ + emitm(&stream, 0x8949, 2); \ + emitm(&stream, (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ } while (0) /* movq sr64,dr64 (sr64 = %r8-15) */ -#define MOVrq3(sr64, dr64) \ - do { \ - emitm(&stream, 0x894c, 2); \ - emitm(&stream, (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ +#define MOVrq3(sr64, dr64) \ + do { \ + emitm(&stream, 0x894c, 2); \ + emitm(&stream, (3 << 6) | ((sr64 & 0x7) << 3) | (dr64 & 0x7), 1); \ } while (0) /* movl (sr64,or64,1),dr32 */ -#define MOVobd(sr64, or64, dr32) \ - do { \ - emitm(&stream, 0x8b, 1); \ - emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ +#define MOVobd(sr64, or64, dr32) \ + do { \ + emitm(&stream, 0x8b, 1); \ + emitm(&stream, ((dr32 & 0x7) << 3) | 4, 1); \ + emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ } while (0) /* movw (sr64,or64,1),dr16 */ -#define MOVobw(sr64, or64, dr16) \ - do { \ - emitm(&stream, 0x8b66, 2); \ - emitm(&stream, ((dr16 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ +#define MOVobw(sr64, or64, dr16) \ + do { \ + emitm(&stream, 0x8b66, 2); \ + emitm(&stream, ((dr16 & 0x7) << 3) | 4, 1); \ + emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ } while (0) /* movb (sr64,or64,1),dr8 */ -#define MOVobb(sr64, or64, dr8) \ - do { \ - emitm(&stream, 0x8a, 1); \ - emitm(&stream, ((dr8 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ +#define MOVobb(sr64, or64, dr8) \ + do { \ + emitm(&stream, 0x8a, 1); \ + emitm(&stream, ((dr8 & 0x7) << 3) | 4, 1); \ + emitm(&stream, ((or64 & 0x7) << 3) | (sr64 & 0x7), 1); \ } while (0) /* movl sr32,(dr64,or64,1) */ -#define MOVomd(sr32, dr64, or64) \ - do { \ - emitm(&stream, 0x89, 1); \ - emitm(&stream, ((sr32 & 0x7) << 3) | 4, 1); \ - emitm(&stream, ((or64 & 0x7) << 3) | (dr64 & 0x7), 1); \ +#define MOVomd(sr32, dr64, or64) \ + do { \ + emitm(&stream, 0x89, 1); \ + emitm(&stream, ((sr32 & 0x7) << 3) | 4, 1); \ + emitm(&stream, ((or64 & 0x7) << 3) | (dr64 & 0x7), 1); \ } while (0) /* bswapl dr32 */ -#define BSWAP(dr32) \ - do { \ - emitm(&stream, 0xf, 1); \ - emitm(&stream, (0x19 << 3) | dr32, 1); \ +#define BSWAP(dr32) \ + do { \ + emitm(&stream, 0xf, 1); \ + emitm(&stream, (0x19 << 3) | dr32, 1); \ } while (0) /* xchgb %al,%ah */ -#define SWAP_AX() \ - do { \ - emitm(&stream, 0xc486, 2); \ +#define SWAP_AX() \ + do { \ + emitm(&stream, 0xc486, 2); \ } while (0) /* pushq r64 */ -#define PUSH(r64) \ - do { \ - emitm(&stream, (5 << 4) | (0 << 3) | (r64 & 0x7), 1); \ +#define PUSH(r64) \ + do { \ + emitm(&stream, (5 << 4) | (0 << 3) | (r64 & 0x7), 1); \ } while (0) /* leaveq */ -#define LEAVE() \ - do { \ - emitm(&stream, 0xc9, 1); \ +#define LEAVE() \ + do { \ + emitm(&stream, 0xc9, 1); \ } while (0) /* retq */ -#define RET() \ - do { \ - emitm(&stream, 0xc3, 1); \ +#define RET() \ + do { \ + emitm(&stream, 0xc3, 1); \ } while (0) /* addl sr32,dr32 */ -#define ADDrd(sr32, dr32) \ - do { \ - emitm(&stream, 0x01, 1); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define ADDrd(sr32, dr32) \ + do { \ + emitm(&stream, 0x01, 1); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* addl i32,%eax */ -#define ADD_EAXi(i32) \ - do { \ - emitm(&stream, 0x05, 1); \ - emitm(&stream, i32, 4); \ +#define ADD_EAXi(i32) \ + do { \ + emitm(&stream, 0x05, 1); \ + emitm(&stream, i32, 4); \ } while (0) /* addl i8,r32 */ -#define ADDib(i8, r32) \ - do { \ - emitm(&stream, 0x83, 1); \ - emitm(&stream, (24 << 3) | r32, 1); \ - emitm(&stream, i8, 1); \ +#define ADDib(i8, r32) \ + do { \ + emitm(&stream, 0x83, 1); \ + emitm(&stream, (24 << 3) | r32, 1); \ + emitm(&stream, i8, 1); \ } while (0) /* subl sr32,dr32 */ -#define SUBrd(sr32, dr32) \ - do { \ - emitm(&stream, 0x29, 1); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define SUBrd(sr32, dr32) \ + do { \ + emitm(&stream, 0x29, 1); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* subl i32,%eax */ -#define SUB_EAXi(i32) \ - do { \ - emitm(&stream, 0x2d, 1); \ - emitm(&stream, i32, 4); \ +#define SUB_EAXi(i32) \ + do { \ + emitm(&stream, 0x2d, 1); \ + emitm(&stream, i32, 4); \ } while (0) /* subq i8,r64 */ -#define SUBib(i8, r64) \ - do { \ - emitm(&stream, 0x8348, 2); \ - emitm(&stream, (29 << 3) | (r64 & 0x7), 1); \ - emitm(&stream, i8, 1); \ +#define SUBib(i8, r64) \ + do { \ + emitm(&stream, 0x8348, 2); \ + emitm(&stream, (29 << 3) | (r64 & 0x7), 1); \ + emitm(&stream, i8, 1); \ } while (0) /* mull r32 */ -#define MULrd(r32) \ - do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ +#define MULrd(r32) \ + do { \ + emitm(&stream, 0xf7, 1); \ + emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ } while (0) /* divl r32 */ -#define DIVrd(r32) \ - do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (15 << 4) | (r32 & 0x7), 1); \ +#define DIVrd(r32) \ + do { \ + emitm(&stream, 0xf7, 1); \ + emitm(&stream, (15 << 4) | (r32 & 0x7), 1); \ } while (0) /* andb i8,r8 */ -#define ANDib(i8, r8) \ - do { \ - if (r8 == AL) { \ - emitm(&stream, 0x24, 1); \ - } else { \ - emitm(&stream, 0x80, 1); \ - emitm(&stream, (7 << 5) | r8, 1); \ - } \ - emitm(&stream, i8, 1); \ +#define ANDib(i8, r8) \ + do { \ + if (r8 == AL) { \ + emitm(&stream, 0x24, 1); \ + } else { \ + emitm(&stream, 0x80, 1); \ + emitm(&stream, (7 << 5) | r8, 1); \ + } \ + emitm(&stream, i8, 1); \ } while (0) /* andl i32,r32 */ -#define ANDid(i32, r32) \ - do { \ - if (r32 == EAX) { \ - emitm(&stream, 0x25, 1); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (7 << 5) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ +#define ANDid(i32, r32) \ + do { \ + if (r32 == EAX) { \ + emitm(&stream, 0x25, 1); \ + } else { \ + emitm(&stream, 0x81, 1); \ + emitm(&stream, (7 << 5) | r32, 1); \ + } \ + emitm(&stream, i32, 4); \ } while (0) /* andl sr32,dr32 */ -#define ANDrd(sr32, dr32) \ - do { \ - emitm(&stream, 0x21, 1); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define ANDrd(sr32, dr32) \ + do { \ + emitm(&stream, 0x21, 1); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* testl i32,r32 */ -#define TESTid(i32, r32) \ - do { \ - if (r32 == EAX) { \ - emitm(&stream, 0xa9, 1); \ - } else { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (3 << 6) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ +#define TESTid(i32, r32) \ + do { \ + if (r32 == EAX) { \ + emitm(&stream, 0xa9, 1); \ + } else { \ + emitm(&stream, 0xf7, 1); \ + emitm(&stream, (3 << 6) | r32, 1); \ + } \ + emitm(&stream, i32, 4); \ } while (0) /* testl sr32,dr32 */ -#define TESTrd(sr32, dr32) \ - do { \ - emitm(&stream, 0x85, 1); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define TESTrd(sr32, dr32) \ + do { \ + emitm(&stream, 0x85, 1); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* orl sr32,dr32 */ -#define ORrd(sr32, dr32) \ - do { \ - emitm(&stream, 0x09, 1); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define ORrd(sr32, dr32) \ + do { \ + emitm(&stream, 0x09, 1); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* orl i32,r32 */ -#define ORid(i32, r32) \ - do { \ - if (r32 == EAX) { \ - emitm(&stream, 0x0d, 1); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (25 << 3) | r32, 1); \ - } \ - emitm(&stream, i32, 4); \ +#define ORid(i32, r32) \ + do { \ + if (r32 == EAX) { \ + emitm(&stream, 0x0d, 1); \ + } else { \ + emitm(&stream, 0x81, 1); \ + emitm(&stream, (25 << 3) | r32, 1); \ + } \ + emitm(&stream, i32, 4); \ } while (0) /* shll i8,r32 */ -#define SHLib(i8, r32) \ - do { \ - emitm(&stream, 0xc1, 1); \ - emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ - emitm(&stream, i8, 1); \ +#define SHLib(i8, r32) \ + do { \ + emitm(&stream, 0xc1, 1); \ + emitm(&stream, (7 << 5) | (r32 & 0x7), 1); \ + emitm(&stream, i8, 1); \ } while (0) /* shll %cl,dr32 */ -#define SHL_CLrb(dr32) \ - do { \ - emitm(&stream, 0xd3, 1); \ - emitm(&stream, (7 << 5) | (dr32 & 0x7), 1); \ +#define SHL_CLrb(dr32) \ + do { \ + emitm(&stream, 0xd3, 1); \ + emitm(&stream, (7 << 5) | (dr32 & 0x7), 1); \ } while (0) /* shrl i8,r32 */ -#define SHRib(i8, r32) \ - do { \ - emitm(&stream, 0xc1, 1); \ - emitm(&stream, (29 << 3) | (r32 & 0x7), 1); \ - emitm(&stream, i8, 1); \ +#define SHRib(i8, r32) \ + do { \ + emitm(&stream, 0xc1, 1); \ + emitm(&stream, (29 << 3) | (r32 & 0x7), 1); \ + emitm(&stream, i8, 1); \ } while (0) /* shrl %cl,dr32 */ -#define SHR_CLrb(dr32) \ - do { \ - emitm(&stream, 0xd3, 1); \ - emitm(&stream, (29 << 3) | (dr32 & 0x7), 1); \ +#define SHR_CLrb(dr32) \ + do { \ + emitm(&stream, 0xd3, 1); \ + emitm(&stream, (29 << 3) | (dr32 & 0x7), 1); \ } while (0) /* negl r32 */ -#define NEGd(r32) \ - do { \ - emitm(&stream, 0xf7, 1); \ - emitm(&stream, (27 << 3) | (r32 & 0x7), 1); \ +#define NEGd(r32) \ + do { \ + emitm(&stream, 0xf7, 1); \ + emitm(&stream, (27 << 3) | (r32 & 0x7), 1); \ } while (0) /* cmpl sr32,dr32 */ -#define CMPrd(sr32, dr32) \ - do { \ - emitm(&stream, 0x39, 1); \ - emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ +#define CMPrd(sr32, dr32) \ + do { \ + emitm(&stream, 0x39, 1); \ + emitm(&stream, (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1); \ } while (0) /* cmpl i32,dr32 */ -#define CMPid(i32, dr32) \ - do { \ - if (dr32 == EAX) { \ - emitm(&stream, 0x3d, 1); \ - emitm(&stream, i32, 4); \ - } else { \ - emitm(&stream, 0x81, 1); \ - emitm(&stream, (0x1f << 3) | (dr32 & 0x7), 1); \ - emitm(&stream, i32, 4); \ - } \ +#define CMPid(i32, dr32) \ + do { \ + if (dr32 == EAX) { \ + emitm(&stream, 0x3d, 1); \ + emitm(&stream, i32, 4); \ + } else { \ + emitm(&stream, 0x81, 1); \ + emitm(&stream, (0x1f << 3) | (dr32 & 0x7), 1); \ + emitm(&stream, i32, 4); \ + } \ } while (0) /* jb off8 */ -#define JBb(off8) \ - do { \ - emitm(&stream, 0x72, 1); \ - emitm(&stream, off8, 1); \ +#define JBb(off8) \ + do { \ + emitm(&stream, 0x72, 1); \ + emitm(&stream, off8, 1); \ } while (0) /* jae off8 */ -#define JAEb(off8) \ - do { \ - emitm(&stream, 0x73, 1); \ - emitm(&stream, off8, 1); \ +#define JAEb(off8) \ + do { \ + emitm(&stream, 0x73, 1); \ + emitm(&stream, off8, 1); \ } while (0) /* jne off8 */ -#define JNEb(off8) \ - do { \ - emitm(&stream, 0x75, 1); \ - emitm(&stream, off8, 1); \ +#define JNEb(off8) \ + do { \ + emitm(&stream, 0x75, 1); \ + emitm(&stream, off8, 1); \ } while (0) /* ja off8 */ -#define JAb(off8) \ - do { \ - emitm(&stream, 0x77, 1); \ - emitm(&stream, off8, 1); \ +#define JAb(off8) \ + do { \ + emitm(&stream, 0x77, 1); \ + emitm(&stream, off8, 1); \ } while (0) /* jmp off32 */ -#define JMP(off32) \ - do { \ - emitm(&stream, 0xe9, 1); \ - emitm(&stream, off32, 4); \ +#define JMP(off32) \ + do { \ + emitm(&stream, 0xe9, 1); \ + emitm(&stream, off32, 4); \ } while (0) /* xorl r32,r32 */ -#define ZEROrd(r32) \ - do { \ - emitm(&stream, 0x31, 1); \ - emitm(&stream, (3 << 6) | ((r32 & 0x7) << 3) | (r32 & 0x7), 1); \ +#define ZEROrd(r32) \ + do { \ + emitm(&stream, 0x31, 1); \ + emitm(&stream, (3 << 6) | ((r32 & 0x7) << 3) | (r32 & 0x7), 1); \ } while (0) /* @@ -472,8 +472,9 @@ typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n); if (ins->jt != 0 && ins->jf != 0) { \ /* 5 is the size of the following jmp */ \ emitm(&stream, ((t) << 8) | 0x0f, 2); \ - emitm(&stream, stream.refs[stream.bpf_pc + ins->jt] - \ - stream.refs[stream.bpf_pc] + 5, \ + emitm(&stream, \ + stream.refs[stream.bpf_pc + ins->jt] - \ + stream.refs[stream.bpf_pc] + 5, \ 4); \ JMP(stream.refs[stream.bpf_pc + ins->jf] - stream.refs[stream.bpf_pc]); \ } else if (ins->jt != 0) { \ @@ -489,10 +490,10 @@ typedef void (*emit_func)(bpf_bin_stream *stream, u_int value, u_int n); } \ } while (0) -#define JUMP(off) \ - do { \ - if ((off) != 0) \ - JMP(stream.refs[stream.bpf_pc + (off)] - stream.refs[stream.bpf_pc]); \ +#define JUMP(off) \ + do { \ + if ((off) != 0) \ + JMP(stream.refs[stream.bpf_pc + (off)] - stream.refs[stream.bpf_pc]); \ } while (0) /* @@ -509,21 +510,21 @@ static void emit_length(bpf_bin_stream *stream, u_int, u_int len) { */ static void emit_code(bpf_bin_stream *stream, u_int value, u_int len) { switch (len) { - case 1: - stream->ibuf[stream->cur_ip] = (u_char)value; - stream->cur_ip++; - break; - - case 2: - *(reinterpret_cast(stream->ibuf + stream->cur_ip)) = - (u_short)value; - stream->cur_ip += 2; - break; - - case 4: - *(reinterpret_cast(stream->ibuf + stream->cur_ip)) = value; - stream->cur_ip += 4; - break; + case 1: + stream->ibuf[stream->cur_ip] = (u_char)value; + stream->cur_ip++; + break; + + case 2: + *(reinterpret_cast(stream->ibuf + stream->cur_ip)) = + (u_short)value; + stream->cur_ip += 2; + break; + + case 4: + *(reinterpret_cast(stream->ibuf + stream->cur_ip)) = value; + stream->cur_ip += 4; + break; } return; @@ -542,36 +543,36 @@ static int bpf_jit_optimize(struct bpf_insn *prog, u_int nins) { for (flags = 0, i = 0; i < nins; i++) { switch (prog[i].code) { - case BPF_LD | BPF_W | BPF_ABS: - case BPF_LD | BPF_H | BPF_ABS: - case BPF_LD | BPF_B | BPF_ABS: - case BPF_LD | BPF_W | BPF_IND: - case BPF_LD | BPF_H | BPF_IND: - case BPF_LD | BPF_B | BPF_IND: - case BPF_LDX | BPF_MSH | BPF_B: - flags |= BPF_JIT_FPKT; - break; - case BPF_LD | BPF_MEM: - case BPF_LDX | BPF_MEM: - case BPF_ST: - case BPF_STX: - flags |= BPF_JIT_FMEM; - break; - case BPF_LD | BPF_W | BPF_LEN: - case BPF_LDX | BPF_W | BPF_LEN: - flags |= BPF_JIT_FLEN; - break; - case BPF_JMP | BPF_JA: - case BPF_JMP | BPF_JGT | BPF_K: - case BPF_JMP | BPF_JGE | BPF_K: - case BPF_JMP | BPF_JEQ | BPF_K: - case BPF_JMP | BPF_JSET | BPF_K: - case BPF_JMP | BPF_JGT | BPF_X: - case BPF_JMP | BPF_JGE | BPF_X: - case BPF_JMP | BPF_JEQ | BPF_X: - case BPF_JMP | BPF_JSET | BPF_X: - flags |= BPF_JIT_FJMP; - break; + case BPF_LD | BPF_W | BPF_ABS: + case BPF_LD | BPF_H | BPF_ABS: + case BPF_LD | BPF_B | BPF_ABS: + case BPF_LD | BPF_W | BPF_IND: + case BPF_LD | BPF_H | BPF_IND: + case BPF_LD | BPF_B | BPF_IND: + case BPF_LDX | BPF_MSH | BPF_B: + flags |= BPF_JIT_FPKT; + break; + case BPF_LD | BPF_MEM: + case BPF_LDX | BPF_MEM: + case BPF_ST: + case BPF_STX: + flags |= BPF_JIT_FMEM; + break; + case BPF_LD | BPF_W | BPF_LEN: + case BPF_LDX | BPF_W | BPF_LEN: + flags |= BPF_JIT_FLEN; + break; + case BPF_JMP | BPF_JA: + case BPF_JMP | BPF_JGT | BPF_K: + case BPF_JMP | BPF_JGE | BPF_K: + case BPF_JMP | BPF_JEQ | BPF_K: + case BPF_JMP | BPF_JSET | BPF_K: + case BPF_JMP | BPF_JGT | BPF_X: + case BPF_JMP | BPF_JGE | BPF_X: + case BPF_JMP | BPF_JEQ | BPF_X: + case BPF_JMP | BPF_JSET | BPF_X: + flags |= BPF_JIT_FJMP; + break; } if (flags == BPF_JIT_FLAG_ALL) break; @@ -641,380 +642,380 @@ bpf_filter_func_t bpf_jit_compile(struct bpf_insn *prog, u_int nins, stream.bpf_pc++; switch (ins->code) { - default: - abort(); - - case BPF_RET | BPF_K: - MOVid(ins->k, EAX); - if (fmem) - LEAVE(); - RET(); - break; + default: + abort(); + + case BPF_RET | BPF_K: + MOVid(ins->k, EAX); + if (fmem) + LEAVE(); + RET(); + break; - case BPF_RET | BPF_A: - if (fmem) - LEAVE(); - RET(); - break; + case BPF_RET | BPF_A: + if (fmem) + LEAVE(); + RET(); + break; - case BPF_LD | BPF_W | BPF_ABS: - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JAb(12); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int32_t), ECX); - if (fmem) { - JAEb(4); - ZEROrd(EAX); - LEAVE(); - } else { - JAEb(3); + case BPF_LD | BPF_W | BPF_ABS: + MOVid(ins->k, ESI); + CMPrd(EDI, ESI); + JAb(12); + MOVrd(EDI, ECX); + SUBrd(ESI, ECX); + CMPid(sizeof(int32_t), ECX); + if (fmem) { + JAEb(4); + ZEROrd(EAX); + LEAVE(); + } else { + JAEb(3); + ZEROrd(EAX); + } + RET(); + MOVrq3(R8, RCX); + MOVobd(RCX, RSI, EAX); + BSWAP(EAX); + break; + + case BPF_LD | BPF_H | BPF_ABS: ZEROrd(EAX); - } - RET(); - MOVrq3(R8, RCX); - MOVobd(RCX, RSI, EAX); - BSWAP(EAX); - break; + MOVid(ins->k, ESI); + CMPrd(EDI, ESI); + JAb(12); + MOVrd(EDI, ECX); + SUBrd(ESI, ECX); + CMPid(sizeof(int16_t), ECX); + if (fmem) { + JAEb(2); + LEAVE(); + } else + JAEb(1); + RET(); + MOVrq3(R8, RCX); + MOVobw(RCX, RSI, AX); + SWAP_AX(); + break; - case BPF_LD | BPF_H | BPF_ABS: - ZEROrd(EAX); - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - JAb(12); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int16_t), ECX); - if (fmem) { - JAEb(2); - LEAVE(); - } else - JAEb(1); - RET(); - MOVrq3(R8, RCX); - MOVobw(RCX, RSI, AX); - SWAP_AX(); - break; + case BPF_LD | BPF_B | BPF_ABS: + ZEROrd(EAX); + MOVid(ins->k, ESI); + CMPrd(EDI, ESI); + if (fmem) { + JBb(2); + LEAVE(); + } else + JBb(1); + RET(); + MOVrq3(R8, RCX); + MOVobb(RCX, RSI, AL); + break; - case BPF_LD | BPF_B | BPF_ABS: - ZEROrd(EAX); - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - if (fmem) { - JBb(2); - LEAVE(); - } else - JBb(1); - RET(); - MOVrq3(R8, RCX); - MOVobb(RCX, RSI, AL); - break; + case BPF_LD | BPF_W | BPF_LEN: + MOVrd3(R9D, EAX); + break; - case BPF_LD | BPF_W | BPF_LEN: - MOVrd3(R9D, EAX); - break; + case BPF_LDX | BPF_W | BPF_LEN: + MOVrd3(R9D, EDX); + break; - case BPF_LDX | BPF_W | BPF_LEN: - MOVrd3(R9D, EDX); - break; + case BPF_LD | BPF_W | BPF_IND: + CMPrd(EDI, EDX); + JAb(27); + MOVid(ins->k, ESI); + MOVrd(EDI, ECX); + SUBrd(EDX, ECX); + CMPrd(ESI, ECX); + JBb(14); + ADDrd(EDX, ESI); + MOVrd(EDI, ECX); + SUBrd(ESI, ECX); + CMPid(sizeof(int32_t), ECX); + if (fmem) { + JAEb(4); + ZEROrd(EAX); + LEAVE(); + } else { + JAEb(3); + ZEROrd(EAX); + } + RET(); + MOVrq3(R8, RCX); + MOVobd(RCX, RSI, EAX); + BSWAP(EAX); + break; - case BPF_LD | BPF_W | BPF_IND: - CMPrd(EDI, EDX); - JAb(27); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - JBb(14); - ADDrd(EDX, ESI); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int32_t), ECX); - if (fmem) { - JAEb(4); + case BPF_LD | BPF_H | BPF_IND: ZEROrd(EAX); - LEAVE(); - } else { - JAEb(3); - ZEROrd(EAX); - } - RET(); - MOVrq3(R8, RCX); - MOVobd(RCX, RSI, EAX); - BSWAP(EAX); - break; - - case BPF_LD | BPF_H | BPF_IND: - ZEROrd(EAX); - CMPrd(EDI, EDX); - JAb(27); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - JBb(14); - ADDrd(EDX, ESI); - MOVrd(EDI, ECX); - SUBrd(ESI, ECX); - CMPid(sizeof(int16_t), ECX); - if (fmem) { - JAEb(2); - LEAVE(); - } else - JAEb(1); - RET(); - MOVrq3(R8, RCX); - MOVobw(RCX, RSI, AX); - SWAP_AX(); - break; - - case BPF_LD | BPF_B | BPF_IND: - ZEROrd(EAX); - CMPrd(EDI, EDX); - JAEb(13); - MOVid(ins->k, ESI); - MOVrd(EDI, ECX); - SUBrd(EDX, ECX); - CMPrd(ESI, ECX); - if (fmem) { - JAb(2); - LEAVE(); - } else - JAb(1); - RET(); - MOVrq3(R8, RCX); - ADDrd(EDX, ESI); - MOVobb(RCX, RSI, AL); - break; + CMPrd(EDI, EDX); + JAb(27); + MOVid(ins->k, ESI); + MOVrd(EDI, ECX); + SUBrd(EDX, ECX); + CMPrd(ESI, ECX); + JBb(14); + ADDrd(EDX, ESI); + MOVrd(EDI, ECX); + SUBrd(ESI, ECX); + CMPid(sizeof(int16_t), ECX); + if (fmem) { + JAEb(2); + LEAVE(); + } else + JAEb(1); + RET(); + MOVrq3(R8, RCX); + MOVobw(RCX, RSI, AX); + SWAP_AX(); + break; - case BPF_LDX | BPF_MSH | BPF_B: - MOVid(ins->k, ESI); - CMPrd(EDI, ESI); - if (fmem) { - JBb(4); + case BPF_LD | BPF_B | BPF_IND: ZEROrd(EAX); - LEAVE(); - } else { - JBb(3); - ZEROrd(EAX); - } - RET(); - ZEROrd(EDX); - MOVrq3(R8, RCX); - MOVobb(RCX, RSI, DL); - ANDib(0x0f, DL); - SHLib(2, EDX); - break; + CMPrd(EDI, EDX); + JAEb(13); + MOVid(ins->k, ESI); + MOVrd(EDI, ECX); + SUBrd(EDX, ECX); + CMPrd(ESI, ECX); + if (fmem) { + JAb(2); + LEAVE(); + } else + JAb(1); + RET(); + MOVrq3(R8, RCX); + ADDrd(EDX, ESI); + MOVobb(RCX, RSI, AL); + break; - case BPF_LD | BPF_IMM: - MOVid(ins->k, EAX); - break; + case BPF_LDX | BPF_MSH | BPF_B: + MOVid(ins->k, ESI); + CMPrd(EDI, ESI); + if (fmem) { + JBb(4); + ZEROrd(EAX); + LEAVE(); + } else { + JBb(3); + ZEROrd(EAX); + } + RET(); + ZEROrd(EDX); + MOVrq3(R8, RCX); + MOVobb(RCX, RSI, DL); + ANDib(0x0f, DL); + SHLib(2, EDX); + break; - case BPF_LDX | BPF_IMM: - MOVid(ins->k, EDX); - break; + case BPF_LD | BPF_IMM: + MOVid(ins->k, EAX); + break; - case BPF_LD | BPF_MEM: - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVobd(RSP, RSI, EAX); - break; + case BPF_LDX | BPF_IMM: + MOVid(ins->k, EDX); + break; - case BPF_LDX | BPF_MEM: - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVobd(RSP, RSI, EDX); - break; + case BPF_LD | BPF_MEM: + MOVid(ins->k * sizeof(uint32_t), ESI); + MOVobd(RSP, RSI, EAX); + break; - case BPF_ST: - /* - * XXX this command and the following could - * be optimized if the previous instruction - * was already of this type - */ - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVomd(EAX, RSP, RSI); - break; + case BPF_LDX | BPF_MEM: + MOVid(ins->k * sizeof(uint32_t), ESI); + MOVobd(RSP, RSI, EDX); + break; - case BPF_STX: - MOVid(ins->k * sizeof(uint32_t), ESI); - MOVomd(EDX, RSP, RSI); - break; + case BPF_ST: + /* + * XXX this command and the following could + * be optimized if the previous instruction + * was already of this type + */ + MOVid(ins->k * sizeof(uint32_t), ESI); + MOVomd(EAX, RSP, RSI); + break; - case BPF_JMP | BPF_JA: - JUMP(ins->k); - break; + case BPF_STX: + MOVid(ins->k * sizeof(uint32_t), ESI); + MOVomd(EDX, RSP, RSI); + break; - case BPF_JMP | BPF_JGT | BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JA: + JUMP(ins->k); break; - } - CMPid(ins->k, EAX); - JCC(JA, JBE); - break; - case BPF_JMP | BPF_JGE | BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JGT | BPF_K: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + CMPid(ins->k, EAX); + JCC(JA, JBE); break; - } - CMPid(ins->k, EAX); - JCC(JAE, JB); - break; - case BPF_JMP | BPF_JEQ | BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JGE | BPF_K: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + CMPid(ins->k, EAX); + JCC(JAE, JB); break; - } - CMPid(ins->k, EAX); - JCC(JE, JNE); - break; - case BPF_JMP | BPF_JSET | BPF_K: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JEQ | BPF_K: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + CMPid(ins->k, EAX); + JCC(JE, JNE); break; - } - TESTid(ins->k, EAX); - JCC(JNE, JE); - break; - case BPF_JMP | BPF_JGT | BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JSET | BPF_K: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + TESTid(ins->k, EAX); + JCC(JNE, JE); break; - } - CMPrd(EDX, EAX); - JCC(JA, JBE); - break; - case BPF_JMP | BPF_JGE | BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JGT | BPF_X: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + CMPrd(EDX, EAX); + JCC(JA, JBE); break; - } - CMPrd(EDX, EAX); - JCC(JAE, JB); - break; - case BPF_JMP | BPF_JEQ | BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JGE | BPF_X: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + CMPrd(EDX, EAX); + JCC(JAE, JB); break; - } - CMPrd(EDX, EAX); - JCC(JE, JNE); - break; - case BPF_JMP | BPF_JSET | BPF_X: - if (ins->jt == ins->jf) { - JUMP(ins->jt); + case BPF_JMP | BPF_JEQ | BPF_X: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + CMPrd(EDX, EAX); + JCC(JE, JNE); break; - } - TESTrd(EDX, EAX); - JCC(JNE, JE); - break; - case BPF_ALU | BPF_ADD | BPF_X: - ADDrd(EDX, EAX); - break; + case BPF_JMP | BPF_JSET | BPF_X: + if (ins->jt == ins->jf) { + JUMP(ins->jt); + break; + } + TESTrd(EDX, EAX); + JCC(JNE, JE); + break; - case BPF_ALU | BPF_SUB | BPF_X: - SUBrd(EDX, EAX); - break; + case BPF_ALU | BPF_ADD | BPF_X: + ADDrd(EDX, EAX); + break; - case BPF_ALU | BPF_MUL | BPF_X: - MOVrd(EDX, ECX); - MULrd(EDX); - MOVrd(ECX, EDX); - break; + case BPF_ALU | BPF_SUB | BPF_X: + SUBrd(EDX, EAX); + break; - case BPF_ALU | BPF_DIV | BPF_X: - TESTrd(EDX, EDX); - if (fmem) { - JNEb(4); - ZEROrd(EAX); - LEAVE(); - } else { - JNEb(3); - ZEROrd(EAX); - } - RET(); - MOVrd(EDX, ECX); - ZEROrd(EDX); - DIVrd(ECX); - MOVrd(ECX, EDX); - break; + case BPF_ALU | BPF_MUL | BPF_X: + MOVrd(EDX, ECX); + MULrd(EDX); + MOVrd(ECX, EDX); + break; - case BPF_ALU | BPF_AND | BPF_X: - ANDrd(EDX, EAX); - break; + case BPF_ALU | BPF_DIV | BPF_X: + TESTrd(EDX, EDX); + if (fmem) { + JNEb(4); + ZEROrd(EAX); + LEAVE(); + } else { + JNEb(3); + ZEROrd(EAX); + } + RET(); + MOVrd(EDX, ECX); + ZEROrd(EDX); + DIVrd(ECX); + MOVrd(ECX, EDX); + break; - case BPF_ALU | BPF_OR | BPF_X: - ORrd(EDX, EAX); - break; + case BPF_ALU | BPF_AND | BPF_X: + ANDrd(EDX, EAX); + break; - case BPF_ALU | BPF_LSH | BPF_X: - MOVrd(EDX, ECX); - SHL_CLrb(EAX); - break; + case BPF_ALU | BPF_OR | BPF_X: + ORrd(EDX, EAX); + break; - case BPF_ALU | BPF_RSH | BPF_X: - MOVrd(EDX, ECX); - SHR_CLrb(EAX); - break; + case BPF_ALU | BPF_LSH | BPF_X: + MOVrd(EDX, ECX); + SHL_CLrb(EAX); + break; - case BPF_ALU | BPF_ADD | BPF_K: - ADD_EAXi(ins->k); - break; + case BPF_ALU | BPF_RSH | BPF_X: + MOVrd(EDX, ECX); + SHR_CLrb(EAX); + break; - case BPF_ALU | BPF_SUB | BPF_K: - SUB_EAXi(ins->k); - break; + case BPF_ALU | BPF_ADD | BPF_K: + ADD_EAXi(ins->k); + break; - case BPF_ALU | BPF_MUL | BPF_K: - MOVrd(EDX, ECX); - MOVid(ins->k, EDX); - MULrd(EDX); - MOVrd(ECX, EDX); - break; + case BPF_ALU | BPF_SUB | BPF_K: + SUB_EAXi(ins->k); + break; - case BPF_ALU | BPF_DIV | BPF_K: - MOVrd(EDX, ECX); - ZEROrd(EDX); - MOVid(ins->k, ESI); - DIVrd(ESI); - MOVrd(ECX, EDX); - break; + case BPF_ALU | BPF_MUL | BPF_K: + MOVrd(EDX, ECX); + MOVid(ins->k, EDX); + MULrd(EDX); + MOVrd(ECX, EDX); + break; - case BPF_ALU | BPF_AND | BPF_K: - ANDid(ins->k, EAX); - break; + case BPF_ALU | BPF_DIV | BPF_K: + MOVrd(EDX, ECX); + ZEROrd(EDX); + MOVid(ins->k, ESI); + DIVrd(ESI); + MOVrd(ECX, EDX); + break; - case BPF_ALU | BPF_OR | BPF_K: - ORid(ins->k, EAX); - break; + case BPF_ALU | BPF_AND | BPF_K: + ANDid(ins->k, EAX); + break; - case BPF_ALU | BPF_LSH | BPF_K: - SHLib((ins->k) & 0xff, EAX); - break; + case BPF_ALU | BPF_OR | BPF_K: + ORid(ins->k, EAX); + break; - case BPF_ALU | BPF_RSH | BPF_K: - SHRib((ins->k) & 0xff, EAX); - break; + case BPF_ALU | BPF_LSH | BPF_K: + SHLib((ins->k) & 0xff, EAX); + break; - case BPF_ALU | BPF_NEG: - NEGd(EAX); - break; + case BPF_ALU | BPF_RSH | BPF_K: + SHRib((ins->k) & 0xff, EAX); + break; - case BPF_MISC | BPF_TAX: - MOVrd(EAX, EDX); - break; + case BPF_ALU | BPF_NEG: + NEGd(EAX); + break; - case BPF_MISC | BPF_TXA: - MOVrd(EDX, EAX); - break; + case BPF_MISC | BPF_TAX: + MOVrd(EAX, EDX); + break; + + case BPF_MISC | BPF_TXA: + MOVrd(EDX, EAX); + break; } ins++; } @@ -1064,5 +1065,5 @@ bpf_filter_func_t bpf_jit_compile(struct bpf_insn *prog, u_int nins, } #endif -} // end namespace bess -} // end namespace utils +} // namespace utils +} // namespace bess diff --git a/core/utils/bpf.h b/core/utils/bpf.h index 4bdb5f603b..e3c45c3596 100644 --- a/core/utils/bpf.h +++ b/core/utils/bpf.h @@ -6,7 +6,7 @@ * * SPDX-License-Identifier: BSD-3-Clause * -*/ + */ #ifndef BESS_UTILS_BPF_H_ #define BESS_UTILS_BPF_H_ @@ -24,21 +24,21 @@ using bpf_filter_func_t = u_int (*)(u_char *, u_int, u_int); struct Filter { #ifdef __x86_64 bpf_filter_func_t func; - size_t mmap_size; // needed for munmap() + size_t mmap_size; // needed for munmap() #else bpf_program il_code; #endif int gate; - int priority; // higher number == higher priority - std::string exp; // original filter expression string + int priority; // higher number == higher priority + std::string exp; // original filter expression string }; #ifdef __x86_64 bpf_filter_func_t bpf_jit_compile(struct bpf_insn *prog, u_int nins, size_t *size); -#endif //__x86_64 +#endif //__x86_64 -} // namespace utils -} // namespace bess +} // namespace utils +} // namespace bess -#endif // BESS_UTILS_ARP_H_ +#endif // BESS_UTILS_ARP_H_ diff --git a/core/utils/checksum.h b/core/utils/checksum.h index 688f8326af..96ec7d4c21 100644 --- a/core/utils/checksum.h +++ b/core/utils/checksum.h @@ -145,11 +145,10 @@ static inline uint32_t CalculateSum(const void *buf, size_t len) { sum64 = (sum64 >> 32) + (sum64 & 0xFFFFFFFF); #else // Use stantard C language for 32 bit or other non-Intel - typedef union[[gnu::may_alias]] { + typedef union [[gnu::may_alias]] { uint32_t u64; uint16_t u16[4]; - } - u16_64; + } u16_64; const u16_64 *ubuf64; ubuf64 = reinterpret_cast(buf64); while (len >= sizeof(uint64_t)) { diff --git a/core/utils/checksum_test.cc b/core/utils/checksum_test.cc index e35f93ed55..063982c5a1 100644 --- a/core/utils/checksum_test.cc +++ b/core/utils/checksum_test.cc @@ -99,7 +99,8 @@ TEST(ChecksumTest, Ipv4NoOptChecksum) { ip->src = be32_t(0x12345678); ip->dst = be32_t(0x12347890); - uint16_t cksum_dpdk = rte_ipv4_cksum(reinterpret_cast(ip)); + uint16_t cksum_dpdk = + rte_ipv4_cksum(reinterpret_cast(ip)); uint16_t cksum_bess = CalculateIpv4NoOptChecksum(*ip); EXPECT_EQ(cksum_dpdk, cksum_bess); @@ -456,4 +457,4 @@ TEST(ChecksumTest, IncrementalUpdateSrcIpPort) { EXPECT_TRUE(VerifyIpv4TcpChecksum(*ip, *tcp)); } } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/codel.h b/core/utils/codel.h index ab4bb99ab9..f9d93c0e97 100644 --- a/core/utils/codel.h +++ b/core/utils/codel.h @@ -39,22 +39,22 @@ #include -#include "time.h" #include "queue.h" +#include "time.h" namespace bess { namespace utils { // Codel(Controlled Delay Management) is an Queue controller based on this // article http://queue.acm.org/detail.cfm?id=2209336 -// It provides an active queue management to help prevent bufferbloat by dropping -// queue entries at an increasing rate if the delay in the queue is above the -// target queue delay. The equation used to calculate drop intervals is based on TCP -// throughput response to drop probability. +// It provides an active queue management to help prevent bufferbloat by +// dropping queue entries at an increasing rate if the delay in the queue is +// above the target queue delay. The equation used to calculate drop intervals +// is based on TCP throughput response to drop probability. // template argument T is the type that is going to be enqueued/dequeued. template -class Codel final: public Queue { +class Codel final : public Queue { public: // default delay target for codel static const uint64_t kDefaultTarget = 5000000; @@ -68,10 +68,10 @@ class Codel final: public Queue { // Takes a drop function which is a function that should take a dropped object // and handle it removing the object potentially including freeing the object. // If there is no need to handle a dropped object, NULL can be passed instead. - // target is the target delay in nanoseconds and the window is the buffer time u - // in nanosecond before changing into drop state. - Codel(void (*drop_func)(T)= NULL, size_t max_entries=0, uint64_t target = kDefaultTarget, - uint64_t window = kDefaultWindow) + // target is the target delay in nanoseconds and the window is the buffer time + // u in nanosecond before changing into drop state. + Codel(void (*drop_func)(T) = NULL, size_t max_entries = 0, + uint64_t target = kDefaultTarget, uint64_t window = kDefaultWindow) : delay_target_(target), window_(window), time_above_target_(0), @@ -80,7 +80,7 @@ class Codel final: public Queue { dropping_(0), max_size_(max_entries), queue_(), - drop_func_(drop_func) { } + drop_func_(drop_func) {} // deconstructor that drops all objects still left in the internal queue. virtual ~Codel() { @@ -99,7 +99,7 @@ class Codel final: public Queue { return 0; } - int Push(T* ptr, size_t count) override { + int Push(T *ptr, size_t count) override { size_t i = 0; for (; i < count; i++) { if (Push(ptr[i])) { @@ -109,8 +109,9 @@ class Codel final: public Queue { return i; } - // Retrieves the next entry from the queue and in the process, potentially drops - // objects as well as changes between dropping state and not dropping state. + // Retrieves the next entry from the queue and in the process, potentially + // drops objects as well as changes between dropping state and not dropping + // state. int Pop(T &obj) override { bool drop = false; Wrapper w; @@ -126,7 +127,7 @@ class Codel final: public Queue { // than the current time. err = DropDequeue(w, drop); } else if (drop && ((now - next_drop_time_ < window_) || - (now - time_above_target_ >= window_))) { + (now - time_above_target_ >= window_))) { // if not in dropping state, determine whether to enter drop state and if // so, drop current object, get a new object and reset the drop counter. Drop(w); @@ -151,10 +152,11 @@ class Codel final: public Queue { return err; } - // Retrieves the next count entries from the queue and in the process, potentially - // drops objects as well as changes between dropping state and not dropping state. - // Does not necessarily return count if there are count present but some are dropped. - int Pop(T* objs, size_t count) override { + // Retrieves the next count entries from the queue and in the process, + // potentially drops objects as well as changes between dropping state and not + // dropping state. Does not necessarily return count if there are count + // present but some are dropped. + int Pop(T *objs, size_t count) override { size_t i = 0; T next_obj; for (; i < count; i++) { @@ -166,9 +168,10 @@ class Codel final: public Queue { } return i; } - // the underlying queue is deque which is a dynamically sized queue with a max size - // determined by system limit. Therefore, the capacity is a specified value used to - // limit the queue or if no value is specified, the queue's system limit. + // the underlying queue is deque which is a dynamically sized queue with a max + // size determined by system limit. Therefore, the capacity is a specified + // value used to limit the queue or if no value is specified, the queue's + // system limit. size_t Capacity() override { if (max_size_ != 0) { return max_size_; @@ -187,10 +190,10 @@ class Codel final: public Queue { size_t Size() override { return queue_.size(); } - // The undelying queue is deque which is a dynamically sized queue with a max size - // determined by system limits. Therefore, the resize method will error if the new_capacity - // is outside of the queue's system limits or otherwise, only change the imposed limit on - // the capacity of the queue. + // The undelying queue is deque which is a dynamically sized queue with a max + // size determined by system limits. Therefore, the resize method will error + // if the new_capacity is outside of the queue's system limits or otherwise, + // only change the imposed limit on the capacity of the queue. int Resize(size_t new_capacity) override { if (new_capacity <= Size()) { return -1; @@ -206,7 +209,7 @@ class Codel final: public Queue { // Calls the drop_func on the object if the drop function exists void Drop(Wrapper w) { if (drop_func_ != NULL) { - drop_func_(w.second); + drop_func_(w.second); } } @@ -218,8 +221,8 @@ class Codel final: public Queue { // Gets the next object from the queue and determines based on current state, // whether set the passed drop boolean to true(to tell the calling function to - // drop it). Takes a Wrapper to set to the next entry in the queue and a boolean - // to set if the entry should be dropped. Returns 0 on success. + // drop it). Takes a Wrapper to set to the next entry in the queue and a + // boolean to set if the entry should be dropped. Returns 0 on success. int RingDequeue(Wrapper &w, bool &drop) { if (!queue_.empty()) { w = queue_.front(); @@ -244,11 +247,11 @@ class Codel final: public Queue { return 0; } - // Called while Codel is in drop state to determine whether to drop the current - // entries and dequeue the next entry. Will continue to drop entries until the - // next drop is greater than the current time. Takes a Wrapper which is the next - // entry in the queue which will potentially be replaced and a boolean determing - // if the entry should be dropped. Returns 0 on success. + // Called while Codel is in drop state to determine whether to drop the + // current entries and dequeue the next entry. Will continue to drop entries + // until the next drop is greater than the current time. Takes a Wrapper which + // is the next entry in the queue which will potentially be replaced and a + // boolean determing if the entry should be dropped. Returns 0 on success. int DropDequeue(Wrapper &w, bool &drop) { uint64_t now = NanoSecondTime(); if (!drop) { @@ -270,9 +273,7 @@ class Codel final: public Queue { } // Returns the current time in microseconds. - uint64_t NanoSecondTime() { - return tsc_to_ns(rdtsc()); - } + uint64_t NanoSecondTime() { return tsc_to_ns(rdtsc()); } uint64_t delay_target_; // the delay that codel will adjust for uint64_t window_; // minimum time before changing state @@ -283,10 +284,10 @@ class Codel final: public Queue { // the number of objects dropped while delay has been above target uint32_t drop_count_; - uint8_t dropping_; // whether in dropping state(above target for window) + uint8_t dropping_; // whether in dropping state(above target for window) size_t max_size_; std::deque queue_; // queue - void (*drop_func_)(T); // the function to call to drop a value + void (*drop_func_)(T); // the function to call to drop a value }; } // namespace utils diff --git a/core/utils/copy_bench.cc b/core/utils/copy_bench.cc index 93fe3d75ed..905d566478 100644 --- a/core/utils/copy_bench.cc +++ b/core/utils/copy_bench.cc @@ -80,7 +80,7 @@ class CopyFixture : public benchmark::Fixture { void TearDown(benchmark::State &) override { CHECK_EQ(dst_[-1], '\xff'); - //CHECK_EQ(dst_[size_], '\xff'); // Copy(sloppy=true) may violate this + // CHECK_EQ(dst_[size_], '\xff'); // Copy(sloppy=true) may violate this for (size_t i = 0; i < size_; i++) { CHECK_EQ(dst_[i], src_[i]) << "Byte " << i << " is different"; @@ -136,7 +136,7 @@ BENCHMARK_DEFINE_F(CopyFixture, Memcpy)(benchmark::State &state) { static void SetArguments(benchmark::internal::Benchmark *b) { // skip argument names for brevity - //b->ArgNames({"dst_align", "src_align", "size"}); + // b->ArgNames({"dst_align", "src_align", "size"}); b->Args({0, 0, 4}) ->Args({0, 0, 7}) ->Args({0, 0, 8}) diff --git a/core/utils/cuckoo_map.h b/core/utils/cuckoo_map.h index 24c61de545..eda3a41749 100644 --- a/core/utils/cuckoo_map.h +++ b/core/utils/cuckoo_map.h @@ -251,9 +251,7 @@ class CuckooMap { return -1; } - int find_dpdk(const void* key, void** data = 0, - hash_sig_t sig = 0) - { + int find_dpdk(const void* key, void** data = 0, hash_sig_t sig = 0) { if (IsDpdk) { if (data && !sig) return rte_hash_lookup_data(hash, key, data); @@ -267,9 +265,7 @@ class CuckooMap { return -1; } - int find_dpdk(const void* key, void** data = 0, - hash_sig_t sig = 0) const - { + int find_dpdk(const void* key, void** data = 0, hash_sig_t sig = 0) const { if (IsDpdk) { if (data && !sig) return rte_hash_lookup_data(hash, key, data); diff --git a/core/utils/cuckoo_map_test.cc b/core/utils/cuckoo_map_test.cc index a86b804b1d..9910988731 100644 --- a/core/utils/cuckoo_map_test.cc +++ b/core/utils/cuckoo_map_test.cc @@ -44,7 +44,7 @@ struct CopyConstructorOnly { CopyConstructorOnly() = default; CopyConstructorOnly(CopyConstructorOnly &&other) = delete; - CopyConstructorOnly(int aa, int bb): a(aa), b(bb) {} + CopyConstructorOnly(int aa, int bb) : a(aa), b(bb) {} CopyConstructorOnly(const CopyConstructorOnly &other) : a(other.a), b(other.b) {} @@ -57,7 +57,7 @@ struct MoveConstructorOnly { MoveConstructorOnly() = default; MoveConstructorOnly(const MoveConstructorOnly &other) = delete; - MoveConstructorOnly(int aa, int bb): a(aa), b(bb) {} + MoveConstructorOnly(int aa, int bb) : a(aa), b(bb) {} MoveConstructorOnly(MoveConstructorOnly &&other) noexcept : a(other.a), b(other.b) { other.a = 0; @@ -97,7 +97,7 @@ TEST(CuckooMapTest, Insert) { EXPECT_EQ(cuckoo.Insert(1, 1)->second, 1); } -template +template void CompileTimeInstantiation() { std::map m1; std::map m2; diff --git a/core/utils/endian.h b/core/utils/endian.h index 98c15979a5..5b824274c3 100644 --- a/core/utils/endian.h +++ b/core/utils/endian.h @@ -83,7 +83,7 @@ class EndianBase { // will be different depending on whether rhs is native or big endian, // which may not be immediately clear from the variable name. template -class[[gnu::packed]] BigEndian final : public EndianBase { +class [[gnu::packed]] BigEndian final : public EndianBase { public: BigEndian() = default; BigEndian(const BigEndian &o) = default; diff --git a/core/utils/endian_test.cc b/core/utils/endian_test.cc index e273ed7151..aa19634f41 100644 --- a/core/utils/endian_test.cc +++ b/core/utils/endian_test.cc @@ -184,4 +184,4 @@ TEST(EndianTest, Shift) { } } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/ether_test.cc b/core/utils/ether_test.cc index 8ee9f32bd6..85521decdf 100644 --- a/core/utils/ether_test.cc +++ b/core/utils/ether_test.cc @@ -91,4 +91,4 @@ TEST(EthernetTest, RandomAddr) { EXPECT_NE(c, d); } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/exact_match_table_test.cc b/core/utils/exact_match_table_test.cc index 3c9938553b..44fe48f845 100644 --- a/core/utils/exact_match_table_test.cc +++ b/core/utils/exact_match_table_test.cc @@ -150,11 +150,12 @@ TEST(EmTableTest, AddField) { // batch.clear(); // for (size_t i = 0; i < n; i++) { // bess::Packet *pkt = pkts[i]; -// bess::utils::Copy(pkt->append(sizeof(databuf)), databuf, sizeof(databuf)); -// batch.add(pkt); +// bess::utils::Copy(pkt->append(sizeof(databuf)), databuf, +// sizeof(databuf)); batch.add(pkt); // } -// const auto buffer_fn = [](const bess::Packet *pkt, const ExactMatchField &) { +// const auto buffer_fn = [](const bess::Packet *pkt, const ExactMatchField &) +// { // return pkt->head_data(); // }; // em.MakeKeys(&batch, buffer_fn, keys); diff --git a/core/utils/extended_priority_queue_test.cc b/core/utils/extended_priority_queue_test.cc index fabf559d95..a250c031a8 100644 --- a/core/utils/extended_priority_queue_test.cc +++ b/core/utils/extended_priority_queue_test.cc @@ -86,4 +86,4 @@ TEST(ExtendedPriorityQueueTest, Delete) { EXPECT_EQ(queue.top(), 1000); } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/fifo_opener.cc b/core/utils/fifo_opener.cc index f7ba665468..3f244f1af4 100644 --- a/core/utils/fifo_opener.cc +++ b/core/utils/fifo_opener.cc @@ -300,5 +300,5 @@ void FifoOpener::MarkDead(int fd, uint32_t gen) { } } -} // namespace bess } // namespace utils +} // namespace bess diff --git a/core/utils/fifo_test.cc b/core/utils/fifo_test.cc index 39459403b3..ee1a845227 100644 --- a/core/utils/fifo_test.cc +++ b/core/utils/fifo_test.cc @@ -670,4 +670,4 @@ TEST_F(FifoTestFixture, MultipleFancyFifos) { // everything down now. } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/histogram_test.cc b/core/utils/histogram_test.cc index f5af95a143..f41da1b803 100644 --- a/core/utils/histogram_test.cc +++ b/core/utils/histogram_test.cc @@ -80,4 +80,4 @@ TEST(HistogramTest, DoubleQuartiles) { EXPECT_DOUBLE_EQ(6.0, ret.percentile_values[3]); // 100th percentile } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/http_parser.cc b/core/utils/http_parser.cc index 84be123eec..7f5a91c806 100644 --- a/core/utils/http_parser.cc +++ b/core/utils/http_parser.cc @@ -69,29 +69,29 @@ } #define RANGES2_LENGTH (2 * 2) /* 2 pairs of start <= byte <= end */ -#define ADVANCE_TOKEN(tok, toklen) \ - do { \ - const char *tok_start = buf; \ - static const char ALIGNED(16) ranges2[16] = "\000\040\177\177"; \ - int found2; \ - buf = findchar_fast(buf, buf_end, ranges2, RANGES2_LENGTH, &found2); \ - if (!found2) { \ - CHECK_EOF(); \ - } \ - while (1) { \ - if (*buf == ' ') { \ - break; \ - } else if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { \ - if ((unsigned char)*buf < '\040' || *buf == '\177') { \ - *ret = -1; \ - return NULL; \ - } \ - } \ - ++buf; \ - CHECK_EOF(); \ - } \ - tok = tok_start; \ - toklen = buf - tok_start; \ +#define ADVANCE_TOKEN(tok, toklen) \ + do { \ + const char *tok_start = buf; \ + static const char ALIGNED(16) ranges2[16] = "\000\040\177\177"; \ + int found2; \ + buf = findchar_fast(buf, buf_end, ranges2, RANGES2_LENGTH, &found2); \ + if (!found2) { \ + CHECK_EOF(); \ + } \ + while (1) { \ + if (*buf == ' ') { \ + break; \ + } else if (unlikely(!IS_PRINTABLE_ASCII(*buf))) { \ + if ((unsigned char)*buf < '\040' || *buf == '\177') { \ + *ret = -1; \ + return NULL; \ + } \ + } \ + ++buf; \ + CHECK_EOF(); \ + } \ + tok = tok_start; \ + toklen = buf - tok_start; \ } while (0) static const char *token_char_map = diff --git a/core/utils/icmp.h b/core/utils/icmp.h index 8002778e37..ebb2bf67f3 100644 --- a/core/utils/icmp.h +++ b/core/utils/icmp.h @@ -35,7 +35,7 @@ namespace bess { namespace utils { // A basic ICMP header definition. -struct[[gnu::packed]] Icmp { +struct [[gnu::packed]] Icmp { uint8_t type; // ICMP packet type. uint8_t code; // ICMP packet code. uint16_t checksum; // ICMP packet checksum. diff --git a/core/utils/ip.h b/core/utils/ip.h index 37cf842fbf..6e652a08e4 100644 --- a/core/utils/ip.h +++ b/core/utils/ip.h @@ -46,7 +46,7 @@ bool ParseIpv4Address(const std::string &str, be32_t *addr); std::string ToIpv4Address(be32_t addr); // An IPv4 header definition loosely based on the BSD version. -struct[[gnu::packed]] Ipv4 { +struct [[gnu::packed]] Ipv4 { enum Flag : uint16_t { kMF = 1 << 13, // More fragments kDF = 1 << 14, // Do not fragment diff --git a/core/utils/ip_test.cc b/core/utils/ip_test.cc index 620605b947..cd8bff8015 100644 --- a/core/utils/ip_test.cc +++ b/core/utils/ip_test.cc @@ -101,4 +101,4 @@ TEST(IPTest, PrefixCalc) { } } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/llqueue_test.cc b/core/utils/llqueue_test.cc index c14b43fdfa..941df115a1 100644 --- a/core/utils/llqueue_test.cc +++ b/core/utils/llqueue_test.cc @@ -105,8 +105,8 @@ TEST(LLQueueTest, Resize) { ASSERT_EQ(q.Push(vals2, n), n); ASSERT_EQ(q.Size(), 2 * n); - int** output = new int*[2*n]; - ASSERT_EQ(q.Pop(output, 2 * n), 2*n); + int** output = new int*[2 * n]; + ASSERT_EQ(q.Pop(output, 2 * n), 2 * n); for (int i = 0; i < n; i++) { ASSERT_EQ(output[i], vals1[i]); ASSERT_EQ(output[i + n], vals2[i]); diff --git a/core/utils/lock_less_queue.h b/core/utils/lock_less_queue.h index f120542d02..36b77e960b 100644 --- a/core/utils/lock_less_queue.h +++ b/core/utils/lock_less_queue.h @@ -45,7 +45,9 @@ namespace utils { // template argument T which is the type to be enqueued and dequeued. template class LockLessQueue final : public Queue { - static_assert(std::is_pointer::value, "LockLessQueue only supports pointer types"); + static_assert(std::is_pointer::value, + "LockLessQueue only supports pointer types"); + public: static const size_t kDefaultRingSize = 256; @@ -80,13 +82,13 @@ class LockLessQueue final : public Queue { } int Push(T* objs, size_t count) override { - if(!llring_enqueue_bulk(ring_, reinterpret_cast(objs), count)) { + if (!llring_enqueue_bulk(ring_, reinterpret_cast(objs), count)) { return count; } return 0; } - int Pop(T &obj) override { + int Pop(T& obj) override { return llring_dequeue(ring_, reinterpret_cast(&obj)); } diff --git a/core/utils/mcslock.h b/core/utils/mcslock.h index c3da47d1a9..8a579cf37a 100644 --- a/core/utils/mcslock.h +++ b/core/utils/mcslock.h @@ -72,7 +72,8 @@ static inline void mcs_lock(mcslock_t *lock, mcslock_node_t *mynode) { static inline void mcs_unlock(mcslock_t *lock, mcslock_node_t *mynode) { if (mynode->next == nullptr) { - if (__sync_bool_compare_and_swap(&lock->tail, mynode, nullptr)) return; + if (__sync_bool_compare_and_swap(&lock->tail, mynode, nullptr)) + return; while (mynode->next == nullptr) { asm volatile("lfence" ::: "memory"); diff --git a/core/utils/mpls.h b/core/utils/mpls.h index ce08fbe828..2c3bced89e 100644 --- a/core/utils/mpls.h +++ b/core/utils/mpls.h @@ -65,17 +65,11 @@ struct Mpls { (bos ? (1 << kMplsBosShift) : 0) | (ttl << kMplsTtlShift)); } - uint32_t Label() { - return (tag.value() & kMplsLabelMask) >> kMplsLabelShift; - } + uint32_t Label() { return (tag.value() & kMplsLabelMask) >> kMplsLabelShift; } - uint8_t Ttl() { - return (tag.value() & kMplsTtlMask) >> kMplsTtlShift; - } + uint8_t Ttl() { return (tag.value() & kMplsTtlMask) >> kMplsTtlShift; } - uint8_t Tc() { - return (tag.value() & kMplsTcMask) >> kMplsTcShift; - } + uint8_t Tc() { return (tag.value() & kMplsTcMask) >> kMplsTcShift; } bool isBottomOfStack() { return (tag.value() & kMplsBosMask) >> kMplsBosShift; diff --git a/core/utils/pcap_handle.cc b/core/utils/pcap_handle.cc index 3c94c9af37..9f5f0ed60b 100644 --- a/core/utils/pcap_handle.cc +++ b/core/utils/pcap_handle.cc @@ -39,7 +39,7 @@ PcapHandle::PcapHandle(const std::string& dev) : handle_() { handle_ = pcap_open_live(dev.c_str(), PCAP_SNAPLEN, 1, -1, errbuf); } -PcapHandle::PcapHandle(pcap_t *handle) : handle_(handle) {} +PcapHandle::PcapHandle(pcap_t* handle) : handle_(handle) {} PcapHandle::PcapHandle(PcapHandle&& other) : handle_(other.handle_) { other.handle_ = nullptr; diff --git a/core/utils/queue.h b/core/utils/queue.h index 6f8964bb53..3dc127060e 100644 --- a/core/utils/queue.h +++ b/core/utils/queue.h @@ -54,10 +54,9 @@ class Queue { // zero on success virtual int Pop(T&) = 0; - - // Dequeue several objects. Takes table to put objects and the number of objects - // to be dequeued into the table returns the number of objects dequeued into the - // table + // Dequeue several objects. Takes table to put objects and the number of + // objects to be dequeued into the table returns the number of objects + // dequeued into the table virtual int Pop(T*, size_t) = 0; // Returns the total capacity of the queue diff --git a/core/utils/simd.cc b/core/utils/simd.cc index a6270bc362..464fd8386e 100644 --- a/core/utils/simd.cc +++ b/core/utils/simd.cc @@ -53,8 +53,8 @@ std::string m256i_to_str(__m256i a) { }; vec = a; - return bess::utils::Format("[%08x %08x %08x %08x %08x %08x %08x %08x]", - b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); + return bess::utils::Format("[%08x %08x %08x %08x %08x %08x %08x %08x]", b[0], + b[1], b[2], b[3], b[4], b[5], b[6], b[7]); } #endif diff --git a/core/utils/syscallthread.cc b/core/utils/syscallthread.cc index 7fdd841d80..d41cd89506 100644 --- a/core/utils/syscallthread.cc +++ b/core/utils/syscallthread.cc @@ -176,5 +176,5 @@ void SyscallThreadAny::WaitForKnockThread() { } } -} // namespace bess } // namespace utils +} // namespace bess diff --git a/core/utils/tcp.h b/core/utils/tcp.h index 8d3826e176..6a90d37c09 100644 --- a/core/utils/tcp.h +++ b/core/utils/tcp.h @@ -36,7 +36,7 @@ namespace bess { namespace utils { // A basic TCP header definition loosely based on the BSD version. -struct[[gnu::packed]] Tcp { +struct [[gnu::packed]] Tcp { enum Flag : uint8_t { kFin = 0x01, kSyn = 0x02, diff --git a/core/utils/time.cc b/core/utils/time.cc index 4f3eea1ca1..f8ef8a69c3 100644 --- a/core/utils/time.cc +++ b/core/utils/time.cc @@ -49,4 +49,4 @@ class TscHzSetter { } } _dummy; -} // namespace (unnamed) +} // namespace diff --git a/core/utils/trie_test.cc b/core/utils/trie_test.cc index bfd5225ba5..a491deff57 100644 --- a/core/utils/trie_test.cc +++ b/core/utils/trie_test.cc @@ -241,4 +241,4 @@ TEST(TrieTest, Dump) { EXPECT_EQ(expected_results, trie.Dump()); } -} // namespace (unnamed) +} // namespace diff --git a/core/utils/udp.h b/core/utils/udp.h index 0ef3bb7230..245faaeafc 100644 --- a/core/utils/udp.h +++ b/core/utils/udp.h @@ -36,7 +36,7 @@ namespace bess { namespace utils { // A basic UDP header definition. -struct[[gnu::packed]] Udp { +struct [[gnu::packed]] Udp { be16_t src_port; // Source port. be16_t dst_port; // Destination port. be16_t length; // Length of header and data. diff --git a/core/utils/vxlan.h b/core/utils/vxlan.h index 9a7ee700e5..2db487cf2c 100644 --- a/core/utils/vxlan.h +++ b/core/utils/vxlan.h @@ -41,7 +41,7 @@ namespace utils { // +-------+-------+-------+--------+ // | VNI | Rsvd. | // +-------+-------+-------+--------+ -struct[[gnu::packed]] Vxlan { +struct [[gnu::packed]] Vxlan { be32_t vx_flags; be32_t vx_vni; }; diff --git a/protobuf/bess_msg.proto b/protobuf/bess_msg.proto index 52e85bbbdc..a50617e3be 100644 --- a/protobuf/bess_msg.proto +++ b/protobuf/bess_msg.proto @@ -46,8 +46,7 @@ package bess.pb; option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; -message EmptyRequest { -} +message EmptyRequest {} message EmptyResponse { /// Contains a non-zero error code and a non-empty message if and only if @@ -70,14 +69,14 @@ message UnloadPluginRequest { message ListPluginsResponse { Error error = 1; - repeated string paths = 2; /// Paths to the module library (*.so file) + repeated string paths = 2; /// Paths to the module library (*.so file) } message ListWorkersResponse { message WorkerStatus { - int64 wid = 1; /// Worker ID, starting from 0 - int64 core = 2; /// CPU core ID on which the worker is pinned - bool running = 3; /// True if running, otherwise False. + int64 wid = 1; /// Worker ID, starting from 0 + int64 core = 2; /// CPU core ID on which the worker is pinned + bool running = 3; /// True if running, otherwise False. /// Number of traffic classes running on the worker int64 num_tcs = 4; @@ -103,9 +102,9 @@ message DestroyWorkerRequest { } message TrafficClass { - string parent = 1; /// Name of parent TC - string name = 2; /// Name of TC - bool blocked = 3; /// Is it running or ready to run at the moment? + string parent = 1; /// Name of parent TC + string name = 2; /// Name of TC + bool blocked = 3; /// Is it running or ready to run at the moment? /// One of "priority", "weighted_fair", "round_robin", "rate_limit", "leaf" string policy = 4; @@ -214,8 +213,8 @@ message GetDriverInfoRequest { message GetDriverInfoResponse { Error error = 1; - string name = 2; /// Name of port driver - string help = 3; /// 1-line description of the driver + string name = 2; /// Name of port driver + string help = 3; /// 1-line description of the driver repeated string commands = 4; /// List of supported commands (TODO) } @@ -232,7 +231,8 @@ message ListPortsResponse { uint64 size_inc_q = 6; /// Size of each incoming queue (# of packets). uint64 size_out_q = 7; - /// Driver specific argument that was used for port initialization. See port_msg.proto + /// Driver specific argument that was used for port initialization. See + /// port_msg.proto google.protobuf.Any driver_arg = 8; } @@ -342,7 +342,7 @@ message GetPortStatsResponse { } message GetLinkStatusRequest { - string name = 1; /// name of the port to query + string name = 1; /// name of the port to query } message GetLinkStatusResponse { @@ -353,10 +353,6 @@ message GetLinkStatusResponse { bool link_up = 5; /// link up? } - - - - message ListMclassResponse { Error error = 1; repeated string names = 2; /// List of module types @@ -415,21 +411,21 @@ message GetModuleInfoRequest { message GetModuleInfoResponse { message GateHook { - string class_name = 1; /// gate hook class_name and - string hook_name = 2; /// gate hook name + string class_name = 1; /// gate hook class_name and + string hook_name = 2; /// gate hook name } message IGate { message OGate { uint64 ogate = 1; /// Output gate of "previous" module string name = 2; /// Name of "previous" module } - uint64 igate = 1; /// Input gate ID - repeated OGate ogates = 2; /// The list of upstream output gates - uint64 cnt = 3; /// # of packet batches seen - uint64 pkts = 4; /// # of packets seen - uint64 bytes = 5; /// # of bytes seen - double timestamp = 6; /// The time that cnt/pkts counters were read - reserved 7; // repeated string hook_name = 7; + uint64 igate = 1; /// Input gate ID + repeated OGate ogates = 2; /// The list of upstream output gates + uint64 cnt = 3; /// # of packet batches seen + uint64 pkts = 4; /// # of packets seen + uint64 bytes = 5; /// # of bytes seen + double timestamp = 6; /// The time that cnt/pkts counters were read + reserved 7; // repeated string hook_name = 7; repeated GateHook gatehooks = 8; /// List of gate hook } message OGate { @@ -440,8 +436,8 @@ message GetModuleInfoResponse { double timestamp = 5; /// The time thatcnt/pkts counters were read string name = 6; /// Name of the "next" module it connects to uint64 igate = 7; /// Input gate ID of the "next" module - reserved 8; // repeated string hook_name = 7; - repeated GateHook gatehooks = 9; /// List of gate hook + reserved 8; // repeated string hook_name = 7; + repeated GateHook gatehooks = 9; /// List of gate hook } message Attribute { string name = 1; /// Name of per-packet metadata attribute @@ -456,14 +452,15 @@ message GetModuleInfoResponse { repeated IGate igates = 6; /// List of connected input gates repeated OGate ogates = 7; /// List of connected output gates repeated Attribute metadata = 8; /// List of metadata used by the module - uint64 deadends = 9; /// Number of packets deadended or explicitly dropped by this module + uint64 deadends = + 9; /// Number of packets deadended or explicitly dropped by this module } message ConnectModulesRequest { - string m1 = 1; /// Name of "previous" module name - string m2 = 2; /// name of "next" module name - uint64 ogate = 3; /// m1's output gate ID - uint64 igate = 4; /// m2's input gate ID + string m1 = 1; /// Name of "previous" module name + string m2 = 2; /// name of "next" module name + uint64 ogate = 3; /// m1's output gate ID + uint64 igate = 4; /// m2's input gate ID /// If true do not attach default hooks at the input/output gate. /// (Currently, the only default hook is the "Track" hook at the ogate) bool skip_default_hooks = 5; @@ -475,26 +472,28 @@ message DisconnectModulesRequest { } message MempoolDump { - int32 socket = 1; /// The socket this mempool belongs to - bool initialized = 2; /// True when this mempool has been initialized - uint32 mp_size = 3; /// The maximum size of this mempool - uint32 mp_cache_size = 4; /// Size of per-lcore default local cache. - uint32 mp_element_size = 5; /// Size of one element - uint32 mp_populated_size = 6; /// Number of populated objects - uint32 mp_available_count = 7; /// Number of entries in this mempool - uint32 mp_in_use_count = 8; /// Number of elements which have been allocated from this mempool - uint32 ring_count = 9; /// Number of entries in the backing ring - uint32 ring_free_count = 10; /// Number of free entries in the backing ring - uint64 ring_bytes = 11; /// Size of the backing ring in bytes + int32 socket = 1; /// The socket this mempool belongs to + bool initialized = 2; /// True when this mempool has been initialized + uint32 mp_size = 3; /// The maximum size of this mempool + uint32 mp_cache_size = 4; /// Size of per-lcore default local cache. + uint32 mp_element_size = 5; /// Size of one element + uint32 mp_populated_size = 6; /// Number of populated objects + uint32 mp_available_count = 7; /// Number of entries in this mempool + uint32 mp_in_use_count = + 8; /// Number of elements which have been allocated from this mempool + uint32 ring_count = 9; /// Number of entries in the backing ring + uint32 ring_free_count = 10; /// Number of free entries in the backing ring + uint64 ring_bytes = 11; /// Size of the backing ring in bytes } message DumpMempoolRequest { - int32 socket = 1; // ID of the socket whose mempool should be dumped. -1 for all sockets + int32 socket = + 1; // ID of the socket whose mempool should be dumped. -1 for all sockets } message DumpMempoolResponse { - Error error = 1; - repeated MempoolDump dumps = 2; /// The list of requested mempool dumps + Error error = 1; + repeated MempoolDump dumps = 2; /// The list of requested mempool dumps } message CommandRequest { @@ -508,7 +507,6 @@ message CommandResponse { google.protobuf.Any data = 2; /// Command response (see *_msg.proto) } - // ------------------------------------------------------------------------- // Gate hooks // ------------------------------------------------------------------------- @@ -550,9 +548,9 @@ message TrackArg { /// /// NOTE: There should be no running worker to run this command. message TcpdumpArg { - string fifo = 5; /// Path to the FIFO file. - bool defer = 6; /// If set, we'll defer opening the FIFO. - bool reconnect = 7; /// If set, we'll reconnect after failure. + string fifo = 5; /// Path to the FIFO file. + bool defer = 6; /// If set, we'll defer opening the FIFO. + bool reconnect = 7; /// If set, we'll reconnect after failure. } /// Enable/Disable pcapng tapping at an input/output gate. @@ -566,19 +564,18 @@ message TcpdumpArg { /// /// NOTE: There should be no running worker to run this command. message PcapngArg { - string fifo = 5; /// Path to the FIFO file. - bool defer = 6; /// If set, we'll defer opening the FIFO. - bool reconnect = 7; /// If set, we'll reconnect after failure. + string fifo = 5; /// Path to the FIFO file. + bool defer = 6; /// If set, we'll defer opening the FIFO. + bool reconnect = 7; /// If set, we'll reconnect after failure. } - message GateHookInfo { - string class_name = 1; /// Name of the hook class - string hook_name = 2; /// Name of the hook - string module_name = 3; /// Name of module + string class_name = 1; /// Name of the hook class + string hook_name = 2; /// Name of the hook + string module_name = 3; /// Name of module oneof gate { - int64 igate = 4; /// Input gate index. All input gates if -1 - int64 ogate = 5; /// Output gate index. All output gates if -1 + int64 igate = 4; /// Input gate index. All input gates if -1 + int64 ogate = 5; /// Output gate index. All output gates if -1 } google.protobuf.Any arg = 6; /// Hook-specific arguments } @@ -619,9 +616,9 @@ message ConfigureResumeHookRequest { // ------------------------------------------------------------------------- message PauseWorkerRequest { - int64 wid = 1; /// ID of the worker to be paused + int64 wid = 1; /// ID of the worker to be paused } message ResumeWorkerRequest { - int64 wid = 1; /// ID of the worker to be resumed + int64 wid = 1; /// ID of the worker to be resumed } diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index 86fb842f7b..6910c0408c 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -44,61 +44,59 @@ import "util_msg.proto"; // For your comments to come out in the auto-documentation: // Format comments with two stars at the top, or use three slashes (///) -// Anything you write will show up as markdown, so feel free to add italics, etc. +// Anything you write will show up as markdown, so feel free to add italics, +// etc. -/// The module_msg.proto file is stored in `bess/protobuf/` and it supplies the glue between -/// bessd modules and the outside world via GRPC. -/// bessctl uses GRPC to update modules. Whenever you call a function in bessctl, a corresponding function -/// is called on modules in bessd. This file lists all modules, their initialization parameters -/// and any functions that may be called on them. +/// The module_msg.proto file is stored in `bess/protobuf/` and it supplies the +/// glue between bessd modules and the outside world via GRPC. bessctl uses GRPC +/// to update modules. Whenever you call a function in bessctl, a corresponding +/// function is called on modules in bessd. This file lists all modules, their +/// initialization parameters and any functions that may be called on them. -message EmptyArg { -} +message EmptyArg {} /** * The BPF module has a command `clear()` that takes no parameters. * This command removes all filters from the module. */ -message BPFCommandClearArg { -} +message BPFCommandClearArg {} /** * The ExactMatch module has a command `add(...)` that takes two parameters. - * The ExactMatch initializer specifies what fields in a packet to inspect; add() specifies - * which values to check for over these fields. - * add() inserts a new rule into the ExactMatch module such that traffic matching - * that bytestring will be forwarded - * out a specified gate. - * Example use: `add(fields=[aton('12.3.4.5'), aton('5.4.3.2')], gate=2)` + * The ExactMatch initializer specifies what fields in a packet to inspect; + * add() specifies which values to check for over these fields. add() inserts a + * new rule into the ExactMatch module such that traffic matching that + * bytestring will be forwarded out a specified gate. Example use: + * `add(fields=[aton('12.3.4.5'), aton('5.4.3.2')], gate=2)` */ message ExactMatchCommandAddArg { - uint64 gate = 1; /// The gate to forward out packets that mach this rule. - repeated FieldData fields = 2; /// The exact match values to check for - repeated FieldData values = 3; /// The exact match values to check for + uint64 gate = 1; /// The gate to forward out packets that mach this rule. + repeated FieldData fields = 2; /// The exact match values to check for + repeated FieldData values = 3; /// The exact match values to check for } /** - * The ExactMatch module has a command `delete(...)` which deletes an existing rule. - * Example use: `delete(fields=[aton('12.3.4.5'), aton('5.4.3.2')])` + * The ExactMatch module has a command `delete(...)` which deletes an existing + * rule. Example use: `delete(fields=[aton('12.3.4.5'), aton('5.4.3.2')])` */ message ExactMatchCommandDeleteArg { - repeated FieldData fields = 2; /// The field values for the rule to be deleted. + repeated FieldData fields = + 2; /// The field values for the rule to be deleted. } /** * The ExactMatch module has a command `clear()` which takes no parameters. * This command removes all rules from the ExactMatch module. */ -message ExactMatchCommandClearArg { -} +message ExactMatchCommandClearArg {} /** - * The ExactMatch module has a command `set_default_gate(...)` which takes one parameter. - * This command routes all traffic which does _not_ match a rule to a specified gate. - * Example use in bessctl: `setDefaultGate(gate=2)` + * The ExactMatch module has a command `set_default_gate(...)` which takes one + * parameter. This command routes all traffic which does _not_ match a rule to a + * specified gate. Example use in bessctl: `setDefaultGate(gate=2)` */ message ExactMatchCommandSetDefaultGateArg { - uint64 gate = 1; /// The gate number to send the default traffic out. + uint64 gate = 1; /// The gate number to send the default traffic out. } /** @@ -113,24 +111,25 @@ message FlowGenCommandSetBurstArg { /** * The HashLB module has a command `set_mode(...)` which takes two parameters. * The `mode` parameter specifies whether the load balancer will hash over the - * src/dest ethernet header (`'l2'`), over the src/dest IP addresses (`'l3'`), or over - * the flow 5-tuple (`'l4'`). Alternatively, if the `fields` parameter is set, the - * load balancer will hash over the N-tuple with the specified offsets and - * sizes. - * Example use in bessctl: `lb.set_mode('l2')` + * src/dest ethernet header (`'l2'`), over the src/dest IP addresses (`'l3'`), + * or over the flow 5-tuple (`'l4'`). Alternatively, if the `fields` parameter + * is set, the load balancer will hash over the N-tuple with the specified + * offsets and sizes. Example use in bessctl: `lb.set_mode('l2')` */ message HashLBCommandSetModeArg { - string mode = 1; /// What fields to hash over, `'l2'`, `'l3'`, and `'l4'` are only valid values. - repeated Field fields = 2; /// A list of fields that define a custom tuple. + string mode = 1; /// What fields to hash over, `'l2'`, `'l3'`, and `'l4'` are + /// only valid values. + repeated Field fields = 2; /// A list of fields that define a custom tuple. } /** * The HashLB module has a command `set_gates(...)` which takes one parameter. - * This function takes in a list of gate numbers to send hashed traffic out over. - * Example use in bessctl: `lb.setGates(gates=[0,1,2,3])` + * This function takes in a list of gate numbers to send hashed traffic out + * over. Example use in bessctl: `lb.setGates(gates=[0,1,2,3])` */ message HashLBCommandSetGatesArg { - repeated int64 gates = 1; ///A list of gate numbers to load balance traffic over + repeated int64 gates = + 1; /// A list of gate numbers to load balance traffic over } /** @@ -140,9 +139,9 @@ message HashLBCommandSetGatesArg { * Example use in bessctl: `table.add(prefix='10.0.0.0', prefix_len=8, gate=2)` */ message IPLookupCommandAddArg { - string prefix = 1; /// The CIDR IP part of the prefix to match - uint64 prefix_len = 2; /// The prefix length - uint64 gate = 3; /// The number of the gate to forward matching traffic on. + string prefix = 1; /// The CIDR IP part of the prefix to match + uint64 prefix_len = 2; /// The prefix length + uint64 gate = 3; /// The number of the gate to forward matching traffic on. } /** @@ -151,8 +150,8 @@ message IPLookupCommandAddArg { * Example use in bessctl: `table.delete(prefix='10.0.0.0', prefix_len=8)` */ message IPLookupCommandDeleteArg { - string prefix = 1; /// The CIDR IP part of the prefix to match - uint64 prefix_len = 2; /// The prefix length + string prefix = 1; /// The CIDR IP part of the prefix to match + uint64 prefix_len = 2; /// The prefix length } /** @@ -160,8 +159,7 @@ message IPLookupCommandDeleteArg { * This function removes all rules in the IPLookup table. * Example use in bessctl: `myiplookuptable.clear()` */ -message IPLookupCommandClearArg { -} +message IPLookupCommandClearArg {} /** * The L2Forward module forwards traffic via exact match over the Ethernet @@ -170,10 +168,10 @@ message IPLookupCommandClearArg { */ message L2ForwardCommandAddArg { message Entry { - string addr = 1; /// The MAC address to match - int64 gate = 2; /// Which gate to send out traffic matching this address. + string addr = 1; /// The MAC address to match + int64 gate = 2; /// Which gate to send out traffic matching this address. } - repeated Entry entries = 1; /// A list of L2Forward entries. + repeated Entry entries = 1; /// A list of L2Forward entries. } /** @@ -181,7 +179,8 @@ message L2ForwardCommandAddArg { * from the MAC forwarding table. */ message L2ForwardCommandDeleteArg { - repeated string addrs = 1; /// The address to remove from the forwarding table + repeated string addrs = + 1; /// The address to remove from the forwarding table } /** @@ -190,7 +189,8 @@ message L2ForwardCommandDeleteArg { * to direct unmatched traffic to. */ message L2ForwardCommandSetDefaultGateArg { - int64 gate = 1; /// The default gate to forward traffic which matches no entry to. + int64 gate = + 1; /// The default gate to forward traffic which matches no entry to. } /** @@ -198,46 +198,51 @@ message L2ForwardCommandSetDefaultGateArg { * a given MAC address will be forwared to; it returns the gate ID number. */ message L2ForwardCommandLookupArg { - repeated string addrs = 1; /// The MAC address to query for + repeated string addrs = 1; /// The MAC address to query for } /** - * This message type provides the reponse to the L2Forward function `lookup(..)`. - * It returns the gate that a requested MAC address is currently assigned to. + * This message type provides the reponse to the L2Forward function + * `lookup(..)`. It returns the gate that a requested MAC address is currently + * assigned to. */ message L2ForwardCommandLookupResponse { - repeated uint64 gates = 1; /// The gate ID that the requested MAC address maps to + repeated uint64 gates = + 1; /// The gate ID that the requested MAC address maps to } /** - * The L2Forward module has a command `populate(...)` which allows for fast creation - * of the forwarding table given a range of MAC addresses. The function takes in a - * 'base' MAC address, a count (number of MAC addresses), and a gate_id. The module - * will route all MAC addresses starting from the base address, up to base+count address - * round-robin over gate_count total gates. - * For example, `populate(base='11:22:33:44:00', count = 10, gate_count = 2)` would - * route addresses `11:22:33:44::(00, 02, 04, 06, 08)` out a gate 0 and the odd-suffixed - * addresses out gate 1. + * The L2Forward module has a command `populate(...)` which allows for fast + * creation of the forwarding table given a range of MAC addresses. The function + * takes in a 'base' MAC address, a count (number of MAC addresses), and a + * gate_id. The module will route all MAC addresses starting from the base + * address, up to base+count address round-robin over gate_count total gates. + * For example, `populate(base='11:22:33:44:00', count = 10, gate_count = 2)` + * would route addresses `11:22:33:44::(00, 02, 04, 06, 08)` out a gate 0 and + * the odd-suffixed addresses out gate 1. */ message L2ForwardCommandPopulateArg { - string base = 1; /// The base MAC address - int64 count = 2; /// How many addresses beyond base to populate into the routing table - int64 gate_count = 3; /// How many gates to create in the L2Forward module. + string base = 1; /// The base MAC address + int64 count = + 2; /// How many addresses beyond base to populate into the routing table + int64 gate_count = 3; /// How many gates to create in the L2Forward module. } /** * The Measure module measures and collects latency/jitter data for packets - * annotated by a Timestamp module. Note that Timestamp and Measure module must reside - * on the server for accurate measurement (as a result, the most typical use case is - * measuring roundtrip time). - * Optionally, you can also retrieve percentile values by specifying points in - * "percentiles". For example, "percentiles" of [50.0, 99.0] will return - * [median, 99'th %-ile tail latency] in "percentile_values_ns" in the response. + * annotated by a Timestamp module. Note that Timestamp and Measure module must + * reside on the server for accurate measurement (as a result, the most typical + * use case is measuring roundtrip time). Optionally, you can also retrieve + * percentile values by specifying points in "percentiles". For example, + * "percentiles" of [50.0, 99.0] will return [median, 99'th %-ile tail latency] + * in "percentile_values_ns" in the response. */ message MeasureCommandGetSummaryArg { - bool clear = 1; /// if true, the data will be all cleared after read - repeated double latency_percentiles = 2; /// ascending list of real numbers in [0.0, 100.0] - repeated double jitter_percentiles = 3; /// ascending list of real numbers in [0.0, 100.0] + bool clear = 1; /// if true, the data will be all cleared after read + repeated double latency_percentiles = + 2; /// ascending list of real numbers in [0.0, 100.0] + repeated double jitter_percentiles = + 3; /// ascending list of real numbers in [0.0, 100.0] } /** @@ -250,9 +255,11 @@ message MeasureCommandGetSummaryArg { */ message MeasureCommandGetSummaryResponse { message Histogram { - uint64 count = 1; /// Total # of measured data points, including above_range - uint64 above_range = 2; /// # of data points for the "too large value" bucket - uint64 resolution_ns = 8; /// resolution of measured data + uint64 count = + 1; /// Total # of measured data points, including above_range + uint64 above_range = + 2; /// # of data points for the "too large value" bucket + uint64 resolution_ns = 8; /// resolution of measured data uint64 min_ns = 3; uint64 avg_ns = 4; uint64 max_ns = 5; @@ -260,60 +267,63 @@ message MeasureCommandGetSummaryResponse { repeated uint64 percentile_values_ns = 7; } - double timestamp = 1; /// Seconds since boot. - uint64 packets = 2; /// Total # of packets seen by this module. - uint64 bits = 3; /// Total # of bits seen by this module. + double timestamp = 1; /// Seconds since boot. + uint64 packets = 2; /// Total # of packets seen by this module. + uint64 bits = 3; /// Total # of bits seen by this module. Histogram latency = 4; Histogram jitter = 5; } - /** * The Module DRR provides fair scheduling of flows based on a quantum which is - * number of bytes allocated to each flow on each round of going through all flows. - * Examples can be found [./bessctl/conf/samples/drr.bess] + * number of bytes allocated to each flow on each round of going through all + * flows. Examples can be found [./bessctl/conf/samples/drr.bess] * * __Input_Gates__: 1 * __Output_Gates__: 1 */ message DRRArg { uint32 num_flows = 1; /// Number of flows to handle in module - uint64 quantum = 2; /// the number of bytes to allocate to each on every round - uint32 max_flow_queue_size = 3; /// the max size that any Flows queue can get + uint64 quantum = + 2; /// the number of bytes to allocate to each on every round + uint32 max_flow_queue_size = 3; /// the max size that any Flows queue can get } /** * the SetQuantumSize function sets a new quantum for DRR module to operate on. */ message DRRQuantumArg { - uint32 quantum = 1; /// the number of bytes to allocate to each on every round + uint32 quantum = + 1; /// the number of bytes to allocate to each on every round } /** - * The SetMaxQueueSize function sets a new maximum flow queue size for DRR module. - * If the flow's queue gets to this size, the module starts dropping packets to - * that flow until the queue is below this size. + * The SetMaxQueueSize function sets a new maximum flow queue size for DRR + * module. If the flow's queue gets to this size, the module starts dropping + * packets to that flow until the queue is below this size. */ message DRRMaxFlowQueueSizeArg { uint32 max_queue_size = 1; /// the max size that any Flows queue can get } /** - * The module PortInc has a function `set_burst(...)` that allows you to specify the - * maximum number of packets to be stored in a single PacketBatch released by - * the module. + * The module PortInc has a function `set_burst(...)` that allows you to specify + * the maximum number of packets to be stored in a single PacketBatch released + * by the module. */ message PortIncCommandSetBurstArg { - uint64 burst = 1; /// The maximum "burst" of packets (ie, the maximum batch size) + uint64 burst = + 1; /// The maximum "burst" of packets (ie, the maximum batch size) } /** - * The module QueueInc has a function `set_burst(...)` that allows you to specify - * the maximum number of packets to be stored in a single PacketBatch released - * by the module. + * The module QueueInc has a function `set_burst(...)` that allows you to + * specify the maximum number of packets to be stored in a single PacketBatch + * released by the module. */ message QueueIncCommandSetBurstArg { - uint64 burst = 1; /// The maximum "burst" of packets (ie, the maximum batch size) + uint64 burst = + 1; /// The maximum "burst" of packets (ie, the maximum batch size) } /** @@ -322,7 +332,8 @@ message QueueIncCommandSetBurstArg { * by the module. */ message QueueCommandSetBurstArg { - uint64 burst = 1; /// The maximum "burst" of packets (ie, the maximum batch size) + uint64 burst = + 1; /// The maximum "burst" of packets (ie, the maximum batch size) } /** @@ -330,7 +341,7 @@ message QueueCommandSetBurstArg { * size of the queue in total number of packets. */ message QueueCommandSetSizeArg { - uint64 size = 1; /// The maximum number of packets to store in the queue. + uint64 size = 1; /// The maximum number of packets to store in the queue. } /** @@ -345,33 +356,30 @@ message QueueCommandGetStatusArg {} * size. */ message QueueCommandGetStatusResponse { - uint64 count = 1; /// The number of packets currently in the queue. - uint64 size = 2; /// The maximum number of packets the queue can contain. - uint64 enqueued = 3; /// total enqueued - uint64 dequeued = 4; /// total dequeued - uint64 dropped = 5; /// total dropped + uint64 count = 1; /// The number of packets currently in the queue. + uint64 size = 2; /// The maximum number of packets the queue can contain. + uint64 enqueued = 3; /// total enqueued + uint64 dequeued = 4; /// total dequeued + uint64 dropped = 5; /// total dropped } /** * The function `clear()` for RandomUpdate takes no parameters and clears all * state in the module. */ -message RandomUpdateCommandClearArg { -} +message RandomUpdateCommandClearArg {} /** * The function `clear()` for Rewrite takes no parameters and clears all state * in the module. */ -message RewriteCommandClearArg { -} +message RewriteCommandClearArg {} /** * The function `clear()` for Update takes no parameters and clears all state in * the module. */ -message UpdateCommandClearArg { -} +message UpdateCommandClearArg {} /** * The module WildcardMatch has a command `add(...)` which inserts a new rule @@ -379,39 +387,48 @@ message UpdateCommandClearArg { * `bess/bessctl/conf/samples/wildcardmatch.bess`. */ message WildcardMatchCommandAddArg { - uint64 gate = 1; /// Traffic matching this new rule will be sent to this gate. - int64 priority = 2; ///If a packet matches multiple rules, the rule with higher priority will be applied. If priorities are equal behavior is undefined. - repeated FieldData values = 3; /// The values to check for in each field. - repeated FieldData masks = 4; /// The bitmask for each field -- set `0x0` to ignore the field altogether. - repeated FieldData valuesv = 5; /// The values to check for in each fieldv. + uint64 gate = + 1; /// Traffic matching this new rule will be sent to this gate. + int64 priority = + 2; /// If a packet matches multiple rules, the rule with higher priority + /// will be applied. If priorities are equal behavior is undefined. + repeated FieldData values = 3; /// The values to check for in each field. + repeated FieldData masks = 4; /// The bitmask for each field -- set `0x0` to + /// ignore the field altogether. + repeated FieldData valuesv = 5; /// The values to check for in each fieldv. } /** - * The module WildcardMatch has a command `delete(...)` which removes a rule -- simply specify the values and masks from the previously inserted rule to remove them. + * The module WildcardMatch has a command `delete(...)` which removes a rule -- + * simply specify the values and masks from the previously inserted rule to + * remove them. */ message WildcardMatchCommandDeleteArg { - repeated FieldData values = 1; /// The values being checked for in the rule - repeated FieldData masks = 2; /// The bitmask from the rule. + repeated FieldData values = 1; /// The values being checked for in the rule + repeated FieldData masks = 2; /// The bitmask from the rule. } /** * The function `clear()` for WildcardMatch takes no parameters, it clears - * all state in the WildcardMatch module (is equivalent to calling delete for all rules) + * all state in the WildcardMatch module (is equivalent to calling delete for + * all rules) */ -message WildcardMatchCommandClearArg { -} +message WildcardMatchCommandClearArg {} /** * For traffic which does not match any rule in the WildcardMatch module, - * the `set_default_gate(...)` function specifies which gate to send this extra traffic to. + * the `set_default_gate(...)` function specifies which gate to send this extra + * traffic to. */ message WildcardMatchCommandSetDefaultGateArg { uint64 gate = 1; } /** - * The module ACL creates an access control module which by default blocks all traffic, unless it contains a rule which specifies otherwise. - * Examples of ACL can be found in [acl.bess](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/acl.bess) + * The module ACL creates an access control module which by default blocks all + * traffic, unless it contains a rule which specifies otherwise. Examples of ACL + * can be found in + * [acl.bess](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/acl.bess) * * __Input Gates__: 1 * __Output Gates__: 1 @@ -421,18 +438,20 @@ message ACLArg { * One ACL rule is represented by the following 6-tuple. */ message Rule { - string src_ip = 1; /// Source IP block in CIDR. Wildcard if "". - string dst_ip = 2; /// Destination IP block in CIDR. Wildcard if "". - uint32 src_port = 3; /// TCP/UDP source port. Wildcard if 0. - uint32 dst_port = 4; /// TCP/UDP Destination port. Wildcard if 0. - bool established = 5; /// Not implemented - bool drop = 6; /// Drop matched packets if true, forward if false. By default ACL drops all traffic. + string src_ip = 1; /// Source IP block in CIDR. Wildcard if "". + string dst_ip = 2; /// Destination IP block in CIDR. Wildcard if "". + uint32 src_port = 3; /// TCP/UDP source port. Wildcard if 0. + uint32 dst_port = 4; /// TCP/UDP Destination port. Wildcard if 0. + bool established = 5; /// Not implemented + bool drop = 6; /// Drop matched packets if true, forward if false. By + /// default ACL drops all traffic. } - repeated Rule rules = 1; ///A list of ACL rules. + repeated Rule rules = 1; /// A list of ACL rules. } /** - * The BPF module is an access control module that sends packets out on a particular gate based on whether they match a BPF filter. + * The BPF module is an access control module that sends packets out on a + * particular gate based on whether they match a BPF filter. * * __Input Gates__: 1 * __Output Gates__: many (configurable) @@ -442,28 +461,33 @@ message BPFArg { * One BPF filter is represented by the following 3-tuple. */ message Filter { - int64 priority = 1; /// The priority level for this rule. If a packet matches multiple rules, it will be forwarded out the gate with the highest priority. If a packet matches multiple rules with the same priority, the behavior is undefined. - string filter = 2; /// The actual BPF string. - int64 gate = 3; ///What gate to forward packets that match this BPF to. + int64 priority = + 1; /// The priority level for this rule. If a packet matches multiple + /// rules, it will be forwarded out the gate with the highest + /// priority. If a packet matches multiple rules with the same + /// priority, the behavior is undefined. + string filter = 2; /// The actual BPF string. + int64 gate = 3; /// What gate to forward packets that match this BPF to. } - repeated Filter filters = 1; /// The BPF initialized function takes a list of BPF filters. + repeated Filter filters = + 1; /// The BPF initialized function takes a list of BPF filters. } /** - * The Buffer module takes no parameters to initialize (ie, `Buffer()` is sufficient to create one). - * Buffer accepts packets and stores them; it may forward them to the next module only after it has - * received enough packets to fill an entire PacketBatch. + * The Buffer module takes no parameters to initialize (ie, `Buffer()` is + * sufficient to create one). Buffer accepts packets and stores them; it may + * forward them to the next module only after it has received enough packets to + * fill an entire PacketBatch. * * __Input Gates__: 1 * __Output Gates__: 1 */ -message BufferArg { -} +message BufferArg {} /** - * The Bypass module forwards packets by emulating pre-defined packet processing overhead. - * It burns cpu cycles per_batch, per_packet, and per-bytes. - * Bypass is useful primarily for testing and performance evaluation. + * The Bypass module forwards packets by emulating pre-defined packet processing + * overhead. It burns cpu cycles per_batch, per_packet, and per-bytes. Bypass is + * useful primarily for testing and performance evaluation. * * __Input Gates__: 1 * __Output Gates__: 1 @@ -475,41 +499,49 @@ message BypassArg { } /** - * The Dump module blindly forwards packets without modifying them. It periodically samples a packet and prints out out to the BESS log (by default stored in `/tmp/bessd.INFO`). + * The Dump module blindly forwards packets without modifying them. It + * periodically samples a packet and prints out out to the BESS log (by default + * stored in `/tmp/bessd.INFO`). * * __Input Gates__: 1 * __Output Gates__: 1 */ message DumpArg { - double interval = 1; ///How frequently to sample and print a packet, in seconds. + double interval = + 1; /// How frequently to sample and print a packet, in seconds. } /** - * The EtherEncap module wraps packets in an Ethernet header, but it takes no parameters. Instead, Ethernet source, destination, and type are pulled from a packet's metadata attributes. - * For example: `SetMetadata('dst_mac', 11:22:33:44:55) -> EtherEncap()` - * This is useful when upstream modules wish to assign a MAC address to a packet, e.g., due to an ARP request. + * The EtherEncap module wraps packets in an Ethernet header, but it takes no + * parameters. Instead, Ethernet source, destination, and type are pulled from a + * packet's metadata attributes. For example: `SetMetadata('dst_mac', + * 11:22:33:44:55) -> EtherEncap()` This is useful when upstream modules wish to + * assign a MAC address to a packet, e.g., due to an ARP request. * * __Input Gates__: 1 * __Output Gates__: 1 */ -message EtherEncapArg { -} +message EtherEncapArg {} /** - * The ExactMatch module splits packets along output gates according to exact match values in arbitrary packet fields. - * To instantiate an ExactMatch module, you must specify which fields in the packet to match over. You can add rules using the function `ExactMatch.add(...)` - * Fields may be stored either in the packet data or its metadata attributes. - * An example script using the ExactMatch code is found - * in [`bess/bessctl/conf/samples/exactmatch.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/exactmatch.bess). + * The ExactMatch module splits packets along output gates according to exact + * match values in arbitrary packet fields. To instantiate an ExactMatch module, + * you must specify which fields in the packet to match over. You can add rules + * using the function `ExactMatch.add(...)` Fields may be stored either in the + * packet data or its metadata attributes. An example script using the + * ExactMatch code is found in + * [`bess/bessctl/conf/samples/exactmatch.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/exactmatch.bess). * * __Input Gates__: 1 * __Output Gates__: many (configurable) */ message ExactMatchArg { - repeated Field fields = 1; ///A list of ExactMatch Fields - repeated FieldData masks = 2; /// mask(i) corresponds to the mask for field(i) - repeated Field values = 3; /// A list of ExactMatch Values - repeated FieldData masksv = 4; /// mask(i) corresponds to the mask for value(i) + repeated Field fields = 1; /// A list of ExactMatch Fields + repeated FieldData masks = + 2; /// mask(i) corresponds to the mask for field(i) + repeated Field values = 3; /// A list of ExactMatch Values + repeated FieldData masksv = + 4; /// mask(i) corresponds to the mask for value(i) uint64 entries = 5; } @@ -524,25 +556,46 @@ message ExactMatchConfig { } /** - * The FlowGen module generates simulated TCP flows of packets with correct SYN/FIN flags and sequence numbers. - * This module is useful for testing, e.g., a NAT module or other flow-aware code. - * Packets are generated off a base, "template" packet by modifying the IP src/dst and TCP src/dst. By default, only the ports are changed and will be modified by incrementing the template ports by up to 20000 more than the template values. + * The FlowGen module generates simulated TCP flows of packets with correct + * SYN/FIN flags and sequence numbers. This module is useful for testing, e.g., + * a NAT module or other flow-aware code. Packets are generated off a base, + * "template" packet by modifying the IP src/dst and TCP src/dst. By default, + * only the ports are changed and will be modified by incrementing the template + * ports by up to 20000 more than the template values. * * __Input Gates__: 0 * __Output Gates__: 1 */ message FlowGenArg { - bytes template = 1; /// The packet "template". All data packets are derived from this template and contain the same payload. - double pps = 2; /// The total number of packets per second to generate. - double flow_rate = 3; /// The number of new flows to create every second. flow_rate must be <= pps. - double flow_duration = 4; /// The lifetime of a flow in seconds. - string arrival = 5; /// The packet arrival distribution -- must be either "uniform" or "exponential" - string duration = 6; /// The flow duration distribution -- must be either "uniform" or "pareto" - bool quick_rampup = 7; /// Whether or not to populate the flowgenerator with initial flows (start generating full pps rate immediately) or to wait for new flows to be generated naturally (all flows have a SYN packet). - uint32 ip_src_range = 8; /// When generating new flows, FlowGen modifies the template packet by changing the IP src, incrementing it by at most ip_src_range (e.g., if the base packet is 10.0.0.1 and range is 5, it will generate packets with IPs 10.0.0.1-10.0.0.6). - uint32 ip_dst_range = 9; /// When generating new flows, FlowGen modifies the template packet by changing the IP dst, incrementing it by at most ip_dst_range. - uint32 port_src_range = 10; /// When generating new flows, FlowGen modifies the template packet by changing the TCP port, incrementing it by at most port_src_range. - uint32 port_dst_range = 11; /// When generating new flows, FlowGen modifies the template packet by changing the TCP dst port, incrementing it by at most port_dst_range. + bytes template = 1; /// The packet "template". All data packets are derived + /// from this template and contain the same payload. + double pps = 2; /// The total number of packets per second to generate. + double flow_rate = 3; /// The number of new flows to create every second. + /// flow_rate must be <= pps. + double flow_duration = 4; /// The lifetime of a flow in seconds. + string arrival = 5; /// The packet arrival distribution -- must be either + /// "uniform" or "exponential" + string duration = 6; /// The flow duration distribution -- must be either + /// "uniform" or "pareto" + bool quick_rampup = + 7; /// Whether or not to populate the flowgenerator with initial flows + /// (start generating full pps rate immediately) or to wait for new + /// flows to be generated naturally (all flows have a SYN packet). + uint32 ip_src_range = + 8; /// When generating new flows, FlowGen modifies the template packet by + /// changing the IP src, incrementing it by at most ip_src_range + /// (e.g., if the base packet is 10.0.0.1 and range is 5, it will + /// generate packets with IPs 10.0.0.1-10.0.0.6). + uint32 ip_dst_range = + 9; /// When generating new flows, FlowGen modifies the template packet by + /// changing the IP dst, incrementing it by at most ip_dst_range. + uint32 port_src_range = 10; /// When generating new flows, FlowGen modifies + /// the template packet by changing the TCP port, + /// incrementing it by at most port_src_range. + uint32 port_dst_range = + 11; /// When generating new flows, FlowGen modifies the template packet + /// by changing the TCP dst port, incrementing it by at most + /// port_dst_range. } /** @@ -552,7 +605,7 @@ message FlowGenArg { * __Ouptut Gates__: 1 */ message GenericDecapArg { - uint64 bytes = 1; /// The number of bytes to strip off. + uint64 bytes = 1; /// The number of bytes to strip off. } /** @@ -567,9 +620,9 @@ message GenericDecapArg { * {'size': 2, 'value': 0x1234}])` * will prepend a 8-byte header: * `de ad be ef 12 34` - * where the 2-byte ` ` comes from the value of metadata attribute `'foo'` - * for each packet. - * An example script using GenericEncap is in [`bess/bessctl/conf/samples/generic_encap.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/generic_encap.bess). + * where the 2-byte ` ` comes from the value of metadata attribute + * `'foo'` for each packet. An example script using GenericEncap is in + * [`bess/bessctl/conf/samples/generic_encap.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/generic_encap.bess). * * __Input Gates__: 1 * __Output Gates__: 1 @@ -579,10 +632,11 @@ message GenericEncapArg { * An EncapField represents one field in the new packet header. */ message EncapField { - uint64 size = 1; /// The length of the field. + uint64 size = 1; /// The length of the field. oneof insertion { - string attribute = 2; /// The metadata attribute name to pull the field value from - FieldData value = 3; /// Or, the fixed value to insert into the packet. + string attribute = + 2; /// The metadata attribute name to pull the field value from + FieldData value = 3; /// Or, the fixed value to insert into the packet. } } repeated EncapField fields = 1; @@ -590,28 +644,29 @@ message GenericEncapArg { /** * The HashLB module partitions packets between output gates according to either - * a hash over their MAC src/dst (`mode='l2'`), their IP src/dst (`mode='l3'`), the full - * IP/TCP 5-tuple (`mode='l4'`), or the N-tuple defined by `fields`. + * a hash over their MAC src/dst (`mode='l2'`), their IP src/dst (`mode='l3'`), + * the full IP/TCP 5-tuple (`mode='l4'`), or the N-tuple defined by `fields`. * * __Input Gates__: 1 * __Output Gates__: many (configurable) */ message HashLBArg { - repeated int64 gates = 1; /// A list of gate numbers over which to partition packets - string mode = 2; /// The mode (`'l2'`, `'l3'`, or `'l4'`) for the hash function. - repeated Field fields = 3; /// A list of fields that define a custom tuple. + repeated int64 gates = + 1; /// A list of gate numbers over which to partition packets + string mode = + 2; /// The mode (`'l2'`, `'l3'`, or `'l4'`) for the hash function. + repeated Field fields = 3; /// A list of fields that define a custom tuple. } /** - * Encapsulates a packet with an IP header, where IP src, dst, and proto are filled in - * by metadata values carried with the packet. Metadata attributes must include: - * ip_src, ip_dst, ip_proto, ip_nexthop, and ether_type. + * Encapsulates a packet with an IP header, where IP src, dst, and proto are + * filled in by metadata values carried with the packet. Metadata attributes + * must include: ip_src, ip_dst, ip_proto, ip_nexthop, and ether_type. * * __Input Gates__: 1 * __Output Gates__: 1 */ -message IPEncapArg { -} +message IPEncapArg {} /** * An IPLookup module perfroms LPM lookups over a packet destination. @@ -622,40 +677,43 @@ message IPEncapArg { * __Output Gates__: many (configurable, depending on rule values) */ message IPLookupArg { - uint32 max_rules = 1; /// Maximum number of rules (default: 1024) - uint32 max_tbl8s = 2; /// Maximum number of IP prefixes with smaller than /24 (default: 128) + uint32 max_rules = 1; /// Maximum number of rules (default: 1024) + uint32 max_tbl8s = + 2; /// Maximum number of IP prefixes with smaller than /24 (default: 128) } /** - * An L2Forward module forwards packets to an output gate according to exact-match rules over - * an Ethernet destination. - * Note that this is _not_ a learning switch -- forwards according to fixed - * routes specified by `add(..)`. + * An L2Forward module forwards packets to an output gate according to + * exact-match rules over an Ethernet destination. Note that this is _not_ a + * learning switch -- forwards according to fixed routes specified by `add(..)`. * * __Input Gates__: 1 * __Ouput Gates__: many (configurable, depending on rules) */ message L2ForwardArg { - int64 size = 1; /// Configures the forwarding hash table -- total number of hash table entries. - int64 bucket = 2; /// Configures the forwarding hash table -- total number of slots per hash value. + int64 size = 1; /// Configures the forwarding hash table -- total number of + /// hash table entries. + int64 bucket = 2; /// Configures the forwarding hash table -- total number of + /// slots per hash value. } /** - * The MACSwap module takes no arguments. It swaps the src/destination MAC addresses - * within a packet. + * The MACSwap module takes no arguments. It swaps the src/destination MAC + * addresses within a packet. * * __Input Gates__: 1 * __Output Gates__: 1 */ -message MACSwapArg { -} +message MACSwapArg {} /** - * The measure module tracks latencies, packets per second, and other statistics. - * It should be paired with a Timestamp module, which attaches a timestamp to packets. - * The measure module will log how long (in nanoseconds) it has been for each packet it received since it was timestamped. - * This module is somewhat experimental and undergoing various changes. - * There is a test for the the Measure module in [`bessctl/module_tests/timestamp.py`](https://github.com/omec-project/bess/blob/master/bessctl/module_tests/timestamp.py). + * The measure module tracks latencies, packets per second, and other + * statistics. It should be paired with a Timestamp module, which attaches a + * timestamp to packets. The measure module will log how long (in nanoseconds) + * it has been for each packet it received since it was timestamped. This module + * is somewhat experimental and undergoing various changes. There is a test for + * the the Measure module in + * [`bessctl/module_tests/timestamp.py`](https://github.com/omec-project/bess/blob/master/bessctl/module_tests/timestamp.py). * * __Input Gates__: 1 * __Output Gates__: 1 @@ -663,12 +721,16 @@ message MACSwapArg { message MeasureArg { // int64 warmup = 1; /// removed: instead of warmup delay, user should Clear() oneof type { - uint64 offset = 2; /// Where to store the current time within the packet, offset in bytes. - string attr_name = 6; /// Where to store the current time as attribute + uint64 offset = 2; /// Where to store the current time within the packet, + /// offset in bytes. + string attr_name = 6; /// Where to store the current time as attribute } - double jitter_sample_prob = 3; /// How often the module should sample packets for inter-packet arrival measurements (to measure jitter). - uint64 latency_ns_max = 4; /// maximum latency expected, in ns (default 0.1 s) - uint32 latency_ns_resolution = 5; /// resolution, in ns (default 100) + double jitter_sample_prob = + 3; /// How often the module should sample packets for inter-packet + /// arrival measurements (to measure jitter). + uint64 latency_ns_max = + 4; /// maximum latency expected, in ns (default 0.1 s) + uint32 latency_ns_resolution = 5; /// resolution, in ns (default 100) } /** @@ -678,8 +740,7 @@ message MeasureArg { * __Input Gates__: many (configurable) * __Output Gates__: 1 */ -message MergeArg { -} +message MergeArg {} /** * The MetadataTest module is used for internal testing purposes. @@ -701,7 +762,8 @@ message MetadataTestArg { * Currently only supports TCP/UDP/ICMP. * Note that address/port in packet payload (e.g., FTP) are NOT translated. * - * __Input Gates__: 2 (0 for internal->external, and 1 for external->internal direction) + * __Input Gates__: 2 (0 for internal->external, and 1 for external->internal + * direction) * __Output Gates__: 2 (same as the input gate) */ message NATArg { @@ -714,7 +776,7 @@ message NATArg { string ext_addr = 1; repeated PortRange port_ranges = 2; } - repeated ExternalAddress ext_addrs = 1; /// list of external IP addresses + repeated ExternalAddress ext_addrs = 1; /// list of external IP addresses } /** @@ -733,18 +795,19 @@ message NATArg { * * Note that address in packet payload (e.g., FTP) are NOT translated. * - * __Input Gates__: 2 (0 for internal->external, and 1 for external->internal direction) + * __Input Gates__: 2 (0 for internal->external, and 1 for external->internal + * direction) * __Output Gates__: 2 (same as the input gate) */ message StaticNATArg { message AddressRange { - string start = 1; /// first IP address to use - string end = 2; /// last IP address to use + string start = 1; /// first IP address to use + string end = 2; /// last IP address to use } message AddressRangePair { AddressRange int_range = 1; - AddressRange ext_range = 2; /// should be the same size as int_range + AddressRange ext_range = 2; /// should be the same size as int_range } repeated AddressRangePair pairs = 1; @@ -753,8 +816,7 @@ message StaticNATArg { /** * This module is used for testing purposes. */ -message NoOpArg { -} +message NoOpArg {} /** * The PortInc module connects a physical or virtual port and releases @@ -766,8 +828,8 @@ message NoOpArg { * __Output Gates__: 1 */ message PortIncArg { - string port = 1; /// The portname to connect to. - bool prefetch = 2; /// Whether or not to prefetch packets from the port. + string port = 1; /// The portname to connect to. + bool prefetch = 2; /// Whether or not to prefetch packets from the port. } /** @@ -779,7 +841,7 @@ message PortIncArg { * __Output Gates__: 0 */ message PortOutArg { - string port = 1; /// The portname to connect to. + string port = 1; /// The portname to connect to. } /** @@ -792,9 +854,11 @@ message PortOutArg { * __Output Gates__: 1 */ message QueueIncArg { - string port = 1; /// The portname to connect to (read from). - uint64 qid = 2; /// The queue on that port to read from. qid starts from 0. - bool prefetch = 3; /// When prefetch is enabled, the module will perform CPU prefetch on the first 64B of each packet onto CPU L1 cache. Default value is false. + string port = 1; /// The portname to connect to (read from). + uint64 qid = 2; /// The queue on that port to read from. qid starts from 0. + bool prefetch = 3; /// When prefetch is enabled, the module will perform CPU + /// prefetch on the first 64B of each packet onto CPU L1 + /// cache. Default value is false. } /** @@ -807,8 +871,8 @@ message QueueIncArg { * __Output Gates__: 0 */ message QueueOutArg { - string port = 1; /// The portname to connect to. - uint64 qid = 2; /// The queue on that port to write out to. + string port = 1; /// The portname to connect to. + uint64 qid = 2; /// The queue on that port to write out to. } /** @@ -818,9 +882,12 @@ message QueueOutArg { * __Output Gates__: 1 */ message QueueArg { - uint64 size = 1; /// The maximum number of packets to store in the queue. - bool prefetch = 2; /// When prefetch is enabled, the module will perform CPU prefetch on the first 64B of each packet onto CPU L1 cache. Default value is false. - bool backpressure = 3; // When backpressure is enabled, the module will notify upstream if it is overloaded. + uint64 size = 1; /// The maximum number of packets to store in the queue. + bool prefetch = 2; /// When prefetch is enabled, the module will perform CPU + /// prefetch on the first 64B of each packet onto CPU L1 + /// cache. Default value is false. + bool backpressure = 3; // When backpressure is enabled, the module will + // notify upstream if it is overloaded. } /** @@ -830,8 +897,8 @@ message QueueArg { * __Output Gates__: many (configurable) */ message RandomSplitArg { - double drop_rate = 1; /// Probability of dropping packet. - repeated int64 gates = 2; /// A list of gate numbers to split the traffic. + double drop_rate = 1; /// Probability of dropping packet. + repeated int64 gates = 2; /// A list of gate numbers to split the traffic. } /** @@ -839,7 +906,7 @@ message RandomSplitArg { * the probability of dropping packets */ message RandomSplitCommandSetDroprateArg { - double drop_rate = 1; /// Probability of dropping packet. + double drop_rate = 1; /// Probability of dropping packet. } /** @@ -847,12 +914,12 @@ message RandomSplitCommandSetDroprateArg { * the total number of output gates in the module. */ message RandomSplitCommandSetGatesArg { - repeated int64 gates = 1; /// A list of gate numbers to split the traffic. + repeated int64 gates = 1; /// A list of gate numbers to split the traffic. } /** - * The RandomUpdate module rewrites a specified field (`offset` and `size`) in a packet - * with a random value between a specified min and max values. + * The RandomUpdate module rewrites a specified field (`offset` and `size`) in a + * packet with a random value between a specified min and max values. * * __Input Gates__: 1 * __Output Gates__: 1 @@ -863,12 +930,12 @@ message RandomUpdateArg { * in each packet processed. */ message Field { - int64 offset = 1; /// Offset in bytes of where to rewrite. - uint64 size = 2; /// The number of bytes to write. - uint64 min = 3; /// The minimum value to insert into the packet. - uint64 max = 4; /// The maximum value to insert into the packet. + int64 offset = 1; /// Offset in bytes of where to rewrite. + uint64 size = 2; /// The number of bytes to write. + uint64 min = 3; /// The minimum value to insert into the packet. + uint64 max = 4; /// The maximum value to insert into the packet. } - repeated Field fields = 1; /// A list of Random Update Fields. + repeated Field fields = 1; /// A list of Random Update Fields. } /** @@ -880,7 +947,8 @@ message RandomUpdateArg { * __Output Gates__: 1 */ message RewriteArg { - repeated bytes templates = 1; /// A list of bytestrings representing packet templates. + repeated bytes templates = + 1; /// A list of bytestrings representing packet templates. } /** @@ -888,7 +956,8 @@ message RewriteArg { * the total number of output gates in the module. */ message RoundRobinCommandSetGatesArg { - repeated int64 gates = 1; /// A list of gate numbers to round-robin the traffic over. + repeated int64 gates = + 1; /// A list of gate numbers to round-robin the traffic over. } /** @@ -896,19 +965,21 @@ message RoundRobinCommandSetGatesArg { * to balance traffic across gates per-packet or per-batch. */ message RoundRobinCommandSetModeArg { - string mode = 1; /// whether to perform `'packet'` or `'batch'` round robin partitioning. + string mode = 1; /// whether to perform `'packet'` or `'batch'` round robin + /// partitioning. } /** - * The RoundRobin module splits packets from one input gate across multiple output - * gates. + * The RoundRobin module splits packets from one input gate across multiple + * output gates. * * __Input Gates__: 1 * __Output Gates__: many (configurable) */ message RoundRobinArg { - repeated int64 gates = 1; /// A list of gate numbers to split packets across. - string mode = 2; /// Whether to split across gate with every `'packet'` or every `'batch'`. + repeated int64 gates = 1; /// A list of gate numbers to split packets across. + string mode = 2; /// Whether to split across gate with every `'packet'` or + /// every `'batch'`. } /** @@ -919,7 +990,8 @@ message RoundRobinArg { * __Output Gates__: many (configurable) */ message ReplicateArg { - repeated int64 gates = 1; /// A list of gate numbers to send packet copies to. + repeated int64 gates = + 1; /// A list of gate numbers to send packet copies to. } /** @@ -927,12 +999,13 @@ message ReplicateArg { * the total number of output gates in the module. */ message ReplicateCommandSetGatesArg { - repeated int64 gates = 1; /// A list of gate numbers to replicate the traffic over. + repeated int64 gates = + 1; /// A list of gate numbers to replicate the traffic over. } /** - * The SetMetadata module adds metadata attributes to packets, which are not stored - * or sent out with packet data. For examples of SetMetadata use, see + * The SetMetadata module adds metadata attributes to packets, which are not + * stored or sent out with packet data. For examples of SetMetadata use, see * [`bess/bessctl/conf/attr_match.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/metadata/attr_match.bess) * * __Input Gates__: 1 @@ -940,23 +1013,32 @@ message ReplicateCommandSetGatesArg { */ message SetMetadataArg { /** - * SetMetadata Attribute describes a metadata attribute and value to attach to every packet. - * If copying data from a packet buffer, SetMetadata can also logically shift - * then mask the value before storing it as metadata, i.e., + * SetMetadata Attribute describes a metadata attribute and value to attach to + * every packet. If copying data from a packet buffer, SetMetadata can also + * logically shift then mask the value before storing it as metadata, i.e., * metadata_value = (packet_value >> `rshift_bits`) & `mask`. */ message Attribute { - string name = 1; /// The metadata attribute name. - uint64 size = 2; /// The size of values stored in this attribute in bytes. + string name = 1; /// The metadata attribute name. + uint64 size = 2; /// The size of values stored in this attribute in bytes. oneof value { - uint64 value_int = 3; /// An integer value to store in the packet (host-order). - bytes value_bin = 4; /// A binary value to store in the packet (host-order). + uint64 value_int = + 3; /// An integer value to store in the packet (host-order). + bytes value_bin = + 4; /// A binary value to store in the packet (host-order). } - int32 offset = 5; /// An index in the packet data to store copy into the metadata attribute. - bytes mask = 6; /// An array of bit masks to apply to each of the bytes copied starting from `offset`. If empty, the mask `[0xFF,....,0xFF]` will be used. - int32 rshift_bits = 7; /// The number of bits to shift the value at `offset` by before masking. Must be a multiple of 8. Positive and negative values represent right and left shifts respectively. + int32 offset = 5; /// An index in the packet data to store copy into the + /// metadata attribute. + bytes mask = 6; /// An array of bit masks to apply to each of the bytes + /// copied starting from `offset`. If empty, the mask + /// `[0xFF,....,0xFF]` will be used. + int32 rshift_bits = + 7; /// The number of bits to shift the value at `offset` by before + /// masking. Must be a multiple of 8. Positive and negative values + /// represent right and left shifts respectively. } - repeated Attribute attrs = 1; /// A list of attributes to attach to the packet. + repeated Attribute attrs = + 1; /// A list of attributes to attach to the packet. } /** @@ -965,8 +1047,7 @@ message SetMetadataArg { * __Input Gates__: 1 * __Output Gates__: 0 */ -message SinkArg { -} +message SinkArg {} /** * The Source module has a function `set_burst(...)` which @@ -974,7 +1055,8 @@ message SinkArg { * from the module. */ message SourceCommandSetBurstArg { - uint64 burst = 1; /// The maximum number of packets to release in a packetbatch from the module. + uint64 burst = 1; /// The maximum number of packets to release in a + /// packetbatch from the module. } /** @@ -982,7 +1064,8 @@ message SourceCommandSetBurstArg { * of packets to be produced by the Source module. */ message SourceCommandSetPktSizeArg { - uint64 pkt_size = 1; /// The size (in bytes) of the packets for Source to create. + uint64 pkt_size = + 1; /// The size (in bytes) of the packets for Source to create. } /** @@ -992,35 +1075,35 @@ message SourceCommandSetPktSizeArg { * __Output Gates__: 1 */ message SourceArg { - uint64 pkt_size = 1; /// The size (in bytes) of packet data to produce. + uint64 pkt_size = 1; /// The size (in bytes) of packet data to produce. } /** -* The IPChecksum module calculates the IPv4 checksum of packets. If -* verify is set to true, the module can be used to validate the checksum -* of the IPv4 packet. All non-IPv4 packets are forwarded without -* modification. Output gates: (0) Default, (1) Drop. -* -* __Input Gates__: 1 -* __Output Gates__: 2 -*/ + * The IPChecksum module calculates the IPv4 checksum of packets. If + * verify is set to true, the module can be used to validate the checksum + * of the IPv4 packet. All non-IPv4 packets are forwarded without + * modification. Output gates: (0) Default, (1) Drop. + * + * __Input Gates__: 1 + * __Output Gates__: 2 + */ message IPChecksumArg { - bool verify = 1; /// check checksum - bool hw = 2; /// enable hardware offload + bool verify = 1; /// check checksum + bool hw = 2; /// enable hardware offload } /** -* The L4Checksum module calculates the UDP/IPv4 checksum of packets. If -* verify is set to true, the module can be used to validate the checksum -* of the UDP/IPv4 packet. All non-IPv4 packets are forwarded without -* modification. Output gates: (0) Default, (1) Drop. -* -* __Input Gates__: MAX_GATES -* __Output Gates__: 2 -*/ + * The L4Checksum module calculates the UDP/IPv4 checksum of packets. If + * verify is set to true, the module can be used to validate the checksum + * of the UDP/IPv4 packet. All non-IPv4 packets are forwarded without + * modification. Output gates: (0) Default, (1) Drop. + * + * __Input Gates__: MAX_GATES + * __Output Gates__: 2 + */ message L4ChecksumArg { - bool verify = 1; /// check checksum - bool hw = 2; /// enable hardware offload + bool verify = 1; /// check checksum + bool hw = 2; /// enable hardware offload } /** @@ -1032,7 +1115,7 @@ message L4ChecksumArg { * __Output Gates__: 1 */ message GtpuEchoArg { - uint32 s1u_sgw_ip = 1; /// IP address of S1U interface + uint32 s1u_sgw_ip = 1; /// IP address of S1U interface } /** @@ -1044,8 +1127,8 @@ message GtpuEchoArg { * __Output Gates__: 1 */ message IPDefragArg { - uint32 num_flows = 1; /// max number of flows the module can handle - int32 numa = 2; /// numa placement for ip frags memory management + uint32 num_flows = 1; /// max number of flows the module can handle + int32 numa = 2; /// numa placement for ip frags memory management } /** @@ -1056,7 +1139,8 @@ message IPDefragArg { * __Output Gates__: 1 */ message IPFragArg { - int32 mtu = 1; /// full Ethernet frame size (including CRC) for encapsulated ipv4 frag datagrams + int32 mtu = 1; /// full Ethernet frame size (including CRC) for encapsulated + /// ipv4 frag datagrams } /** @@ -1066,7 +1150,7 @@ message IPFragArg { * Example use in bessctl: `counter.add(ctr_id=0x1)` */ message CounterAddArg { - uint32 ctr_id = 1; /// counter id + uint32 ctr_id = 1; /// counter id } /** @@ -1076,7 +1160,7 @@ message CounterAddArg { * Example use in bessctl: `counter.remove(ctr_id=0x1)` */ message CounterRemoveArg { - uint32 ctr_id = 1; /// counter id + uint32 ctr_id = 1; /// counter id } /** @@ -1084,11 +1168,12 @@ message CounterRemoveArg { * * __Input Gates__: 1 * __Output Gates__: 1 -*/ + */ message CounterArg { - string name_id = 1; /// Name of the counter_id - bool check_exist = 2; /// verify each counter pre-exists before any operation (default = False) - uint32 total = 3; /// Total number of entries it can support + string name_id = 1; /// Name of the counter_id + bool check_exist = 2; /// verify each counter pre-exists before any operation + /// (default = False) + uint32 total = 3; /// Total number of entries it can support } /** @@ -1096,9 +1181,9 @@ message CounterArg { * * __Input Gates__: 1 * __Output Gates__: 1 -*/ + */ message GtpuEncapArg { - bool add_psc = 1; /// Add PDU session container in encap (default = False) + bool add_psc = 1; /// Add PDU session container in encap (default = False) } /** @@ -1110,10 +1195,10 @@ message GtpuEncapArg { * __Output Gates__: many (up to 2^(size * 8)) */ message SplitArg { - uint64 size = 1; /// The size of the value to read in bytes + uint64 size = 1; /// The size of the value to read in bytes oneof type { - string attribute = 2; /// The name of the metadata field to read. - int64 offset = 3; /// The offset (in bytes) of the data field to read. + string attribute = 2; /// The name of the metadata field to read. + int64 offset = 3; /// The offset (in bytes) of the data field to read. } } @@ -1141,14 +1226,15 @@ message TimestampArg { */ message UpdateArg { /** - * Update Field describes where in a packet's data to rewrite, and with what value. + * Update Field describes where in a packet's data to rewrite, and with what + * value. */ message Field { - int64 offset = 1; /// The offset in the packet in bytes to rewrite at. - uint64 size = 2; /// The number of bytes to rewrite (max 8 bytes). - uint64 value = 3; /// The value to write into the packet, max 8 bytes. + int64 offset = 1; /// The offset in the packet in bytes to rewrite at. + uint64 size = 2; /// The number of bytes to rewrite (max 8 bytes). + uint64 value = 3; /// The value to write into the packet, max 8 bytes. } - repeated Field fields = 1; /// A list of Update Fields. + repeated Field fields = 1; /// A list of Update Fields. } /** @@ -1169,7 +1255,7 @@ message UrlFilterArg { string host = 1; /// Host field, e.g. "www.google.com" string path = 2; /// Path prefix, e.g. "/" } - repeated Url blacklist = 1; /// A list of Urls to block. + repeated Url blacklist = 1; /// A list of Urls to block. } /** @@ -1188,8 +1274,7 @@ message UrlFilterConfig { * __Input Gates__: 1 * __Output Gates__: 1 */ -message VLANPopArg { -} +message VLANPopArg {} /** * VLANPush appends a VLAN tag with a specified TCI value. @@ -1198,17 +1283,17 @@ message VLANPopArg { * __Output Gates__: 1 */ message VLANPushArg { - uint64 tci = 1; /// The TCI value to insert in the VLAN tag. + uint64 tci = 1; /// The TCI value to insert in the VLAN tag. } /** - * Splits packets across output gates according to VLAN id (e.g., id 3 goes out gate 3). + * Splits packets across output gates according to VLAN id (e.g., id 3 goes out + * gate 3). * * __Input Gates__: 1 * __Output Gates__: many */ -message VLANSplitArg { -} +message VLANSplitArg {} /** * VXLANDecap module decapsulates a VXLAN header on a packet. @@ -1216,32 +1301,33 @@ message VLANSplitArg { * __Input Gates__: 1 * __Output Gates__: 1 */ -message VXLANDecapArg { -} +message VXLANDecapArg {} /** - * VXLANEncap module wraps a packet in a VXLAN header with a specified destination port. + * VXLANEncap module wraps a packet in a VXLAN header with a specified + * destination port. * * __Input Gates__: 1 * __Output Gates__: 1 */ message VXLANEncapArg { - uint64 dstport = 1; /// The destination UDP port + uint64 dstport = 1; /// The destination UDP port } /** * The WildcardMatch module matches over multiple fields in a packet and - * pushes packets that do match out a specified gate, and those that don't out a default - * gate. WildcardMatch is initialized with the fields it should inspect over, - * rules are added via the `add(...)` function. - * An example of WildcardMatch is in [`bess/bessctl/conf/samples/wildcardmatch.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/wildcardmatch.bess) + * pushes packets that do match out a specified gate, and those that don't out a + * default gate. WildcardMatch is initialized with the fields it should inspect + * over, rules are added via the `add(...)` function. An example of + * WildcardMatch is in + * [`bess/bessctl/conf/samples/wildcardmatch.bess`](https://github.com/omec-project/bess/blob/master/bessctl/conf/samples/wildcardmatch.bess) * * __Input Gates__: 1 * __Output Gates__: many (configurable) */ message WildcardMatchArg { - repeated Field fields = 1; /// A list of WildcardMatch fields. - repeated Field values = 2; /// A list of WildcardMatch values. + repeated Field fields = 1; /// A list of WildcardMatch fields. + repeated Field values = 2; /// A list of WildcardMatch values. uint64 entries = 3; } @@ -1265,8 +1351,8 @@ message WildcardMatchConfig { * __Output Gates__: 1 */ message ArpResponderArg { - string ip = 1; /// The IP - string mac_addr = 2; /// The MAC address + string ip = 1; /// The IP + string mac_addr = 2; /// The MAC address } /** @@ -1276,8 +1362,8 @@ message ArpResponderArg { * __Output Gates__: 2 */ message MplsPopArg { - bool remove_eth_header = 1; /// Remove ETH header with the pop - uint32 next_eth_type = 2; /// The next ETH type to set + bool remove_eth_header = 1; /// Remove ETH header with the pop + uint32 next_eth_type = 2; /// The next ETH type to set } /** @@ -1296,7 +1382,7 @@ message MplsPopArg { * __Output Gates__: many */ message WorkerSplitArg { - map worker_gates = 1; // ogate -> worker mask + map worker_gates = 1; // ogate -> worker mask } message QosArg { @@ -1312,9 +1398,7 @@ message QosCommandAddArg { uint64 cbs = 4; uint64 pbs = 5; uint64 ebs = 6; - oneof optional_deduct_len { - int64 deduct_len = 9; - } + oneof optional_deduct_len { int64 deduct_len = 9; } repeated FieldData fields = 7; repeated FieldData values = 8; } @@ -1325,14 +1409,15 @@ message QosCommandDeleteArg { /** * The function `clear()` for WildcardMatch takes no parameters, it clears - * all state in the WildcardMatch module (is equivalent to calling delete for all rules) + * all state in the WildcardMatch module (is equivalent to calling delete for + * all rules) */ -message QosCommandClearArg { -} +message QosCommandClearArg {} /** * For traffic which does not match any rule in the WildcardMatch module, - * the `set_default_gate(...)` function specifies which gate to send this extra traffic to. + * the `set_default_gate(...)` function specifies which gate to send this extra + * traffic to. */ message QosCommandSetDefaultGateArg { uint64 gate = 1; @@ -1341,20 +1426,24 @@ message QosCommandSetDefaultGateArg { message FlowMeasureArg { string flag_attr_name = 1; uint64 entries = 2; - bool leader = 3; // If true, this module will decide the buffer side + bool leader = 3; // If true, this module will decide the buffer side } message FlowMeasureCommandReadArg { - bool clear = 1; // If true, the data will be all cleared after read - repeated double latency_percentiles = 2; /// ascending list of real numbers in [0.0, 100.0] - repeated double jitter_percentiles = 3; /// ascending list of real numbers in [0.0, 100.0] - uint64 flag_to_read = 4; /// Which buffer to read from + bool clear = 1; // If true, the data will be all cleared after read + repeated double latency_percentiles = + 2; /// ascending list of real numbers in [0.0, 100.0] + repeated double jitter_percentiles = + 3; /// ascending list of real numbers in [0.0, 100.0] + uint64 flag_to_read = 4; /// Which buffer to read from } message FlowMeasureReadResponse { message Statistic { message Histogram { - uint64 count = 1; /// Total # of measured data points, including above_range - uint64 above_range = 2; /// # of data points for the "too large value" bucket - uint64 resolution_ns = 8; /// resolution of measured data + uint64 count = + 1; /// Total # of measured data points, including above_range + uint64 above_range = + 2; /// # of data points for the "too large value" bucket + uint64 resolution_ns = 8; /// resolution of measured data uint64 min_ns = 3; uint64 avg_ns = 4; uint64 max_ns = 5; diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index c716139c72..12fe79f040 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -51,9 +51,7 @@ message PMDPortArg { bool vlan_offload_rx_strip = 5; bool vlan_offload_rx_filter = 6; bool vlan_offload_rx_qinq = 7; - oneof socket { - int32 socket_id = 8; - } + oneof socket { int32 socket_id = 8; } bool promiscuous_mode = 9; bool hwcksum = 10; diff --git a/protobuf/service.proto b/protobuf/service.proto index b5f4dc11b1..8aac6e773e 100644 --- a/protobuf/service.proto +++ b/protobuf/service.proto @@ -38,13 +38,12 @@ package bess.pb; option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; service BESSControl { - // ------------------------------------------------------------------------- // System // ------------------------------------------------------------------------- /// Query version of bessd - rpc GetVersion (EmptyRequest) returns (VersionResponse) {} + rpc GetVersion(EmptyRequest) returns (VersionResponse) {} /// Reset the current packet processing datapath to the initial state. /// @@ -57,7 +56,7 @@ service BESSControl { /// started (if not, it is a bug; please report). /// /// NOTE: There should be no running worker to run this command. - rpc ResetAll (EmptyRequest) returns (EmptyResponse) {} + rpc ResetAll(EmptyRequest) returns (EmptyResponse) {} /// Terminate the BESS daemon. /// @@ -67,26 +66,25 @@ service BESSControl { /// /// NOTE: There should be no running worker to run this command. /// FIXME: rename (e.g., Terminate) - rpc KillBess (EmptyRequest) returns (EmptyResponse) {} + rpc KillBess(EmptyRequest) returns (EmptyResponse) {} /// Import a plugin /// /// At the moment plugins can only contain module types, /// but might also support drivers/hooks/schedulers in the future. - rpc ImportPlugin (ImportPluginRequest) returns (EmptyResponse) {} + rpc ImportPlugin(ImportPluginRequest) returns (EmptyResponse) {} /// Unload a plugin /// /// At the moment plugins can only contain module types, /// but might also support drivers/hooks/schedulers in the future. - rpc UnloadPlugin (UnloadPluginRequest) returns (EmptyResponse) {} + rpc UnloadPlugin(UnloadPluginRequest) returns (EmptyResponse) {} /// List imported plugins /// /// At the moment plugins can only contain module types, /// but might also support drivers/hooks/schedulers in the future. - rpc ListPlugins (EmptyRequest) returns (ListPluginsResponse) {} - + rpc ListPlugins(EmptyRequest) returns (ListPluginsResponse) {} // ------------------------------------------------------------------------- // Worker @@ -103,45 +101,45 @@ service BESSControl { /// ... /// ResumeAll() /// Keep the duration as short as possible, to avoid packet drops. - rpc PauseAll (EmptyRequest) returns (EmptyResponse) {} + rpc PauseAll(EmptyRequest) returns (EmptyResponse) {} /// Pause the specified worker temporarily /// /// Some RPC commands to BESS or individual modules/ports require that /// threads must be inactive, to avoid race conditions. - /// For such commands, use PauseWorker at the beginning and ResumeWorker at the end. + /// For such commands, use PauseWorker at the beginning and ResumeWorker at + /// the end. /// PauseWorker(0) /// SomeCommand1() /// SomeCommand2() /// ... /// ResumeWorker(0) /// Keep the duration as short as possible, to avoid packet drops. - rpc PauseWorker (PauseWorkerRequest) returns (EmptyResponse) {} + rpc PauseWorker(PauseWorkerRequest) returns (EmptyResponse) {} /// Resume the specified worker - rpc ResumeWorker (ResumeWorkerRequest) returns (EmptyResponse) {} + rpc ResumeWorker(ResumeWorkerRequest) returns (EmptyResponse) {} /// Resume all paused workers - rpc ResumeAll (EmptyRequest) returns (EmptyResponse) {} + rpc ResumeAll(EmptyRequest) returns (EmptyResponse) {} /// Remove all existing workers /// /// NOTE: There should be no running worker to run this command. - rpc ResetWorkers (EmptyRequest) returns (EmptyResponse) {} + rpc ResetWorkers(EmptyRequest) returns (EmptyResponse) {} /// Enumerate all existing workers - rpc ListWorkers (EmptyRequest) returns (ListWorkersResponse) {} + rpc ListWorkers(EmptyRequest) returns (ListWorkersResponse) {} /// Create a new worker /// /// NOTE: There should be no running worker to run this command. - rpc AddWorker (AddWorkerRequest) returns (EmptyResponse) {} + rpc AddWorker(AddWorkerRequest) returns (EmptyResponse) {} /// Remove a single worker /// /// NOTE: There should be no running worker to run this command. - rpc DestroyWorker (DestroyWorkerRequest) returns (EmptyResponse) {} - + rpc DestroyWorker(DestroyWorkerRequest) returns (EmptyResponse) {} // ------------------------------------------------------------------------- // Traffic classe & task @@ -150,39 +148,39 @@ service BESSControl { /// Remove all existing traffic classes /// /// NOTE: There should be no running worker to run this command. - rpc ResetTcs (EmptyRequest) returns (EmptyResponse) {} + rpc ResetTcs(EmptyRequest) returns (EmptyResponse) {} /// Enumerate all existing workers - rpc ListTcs (ListTcsRequest) returns (ListTcsResponse) {} + rpc ListTcs(ListTcsRequest) returns (ListTcsResponse) {} /// Check scheduling contraints - rpc CheckSchedulingConstraints (EmptyRequest) returns (CheckSchedulingConstraintsResponse) {} + rpc CheckSchedulingConstraints(EmptyRequest) + returns (CheckSchedulingConstraintsResponse) {} /// Create a new traffic class /// /// NOTE: There should be no running worker to run this command. - rpc AddTc (AddTcRequest) returns (EmptyResponse) {} + rpc AddTc(AddTcRequest) returns (EmptyResponse) {} /// Update parameters of an existing traffic class /// /// NOTE: There should be no running worker to run this command. - rpc UpdateTcParams (UpdateTcParamsRequest) returns (EmptyResponse) {} + rpc UpdateTcParams(UpdateTcParamsRequest) returns (EmptyResponse) {} /// Change parent (and child arguments) of an existing traffic class /// /// NOTE: There should be no running worker to run this command. - rpc UpdateTcParent (UpdateTcParentRequest) returns (EmptyResponse) {} + rpc UpdateTcParent(UpdateTcParentRequest) returns (EmptyResponse) {} /// Collect statistics of a traffic class - rpc GetTcStats (GetTcStatsRequest) returns (GetTcStatsResponse) {} - + rpc GetTcStats(GetTcStatsRequest) returns (GetTcStatsResponse) {} // ------------------------------------------------------------------------- // Port // ------------------------------------------------------------------------- /// Enumerate all port drivers available - rpc ListDrivers (EmptyRequest) returns (ListDriversResponse) {} + rpc ListDrivers(EmptyRequest) returns (ListDriversResponse) {} /// Query detailed information of a port driver rpc GetDriverInfo(GetDriverInfoRequest) returns (GetDriverInfoResponse) {} @@ -193,60 +191,59 @@ service BESSControl { /// (e.g., PortInc, PortOut, QueueInc, QueueOut) /// /// NOTE: There should be no running worker to run this command. - rpc ResetPorts (EmptyRequest) returns (EmptyResponse) {} + rpc ResetPorts(EmptyRequest) returns (EmptyResponse) {} /// Enumerate all initialized ports - rpc ListPorts (EmptyRequest) returns (ListPortsResponse) {} + rpc ListPorts(EmptyRequest) returns (ListPortsResponse) {} /// Create a new port from the specified driver - rpc CreatePort (CreatePortRequest) returns (CreatePortResponse) {} + rpc CreatePort(CreatePortRequest) returns (CreatePortResponse) {} /// Remove a port /// /// The port should not be being used by a port-related module. /// (e.g., PortInc, PortOut, QueueInc, QueueOut) - rpc DestroyPort (DestroyPortRequest) returns (EmptyResponse) {} + rpc DestroyPort(DestroyPortRequest) returns (EmptyResponse) {} /// Runtime-updatable configuration - rpc SetPortConf (SetPortConfRequest) returns (CommandResponse) {} - rpc GetPortConf (GetPortConfRequest) returns (GetPortConfResponse) {} + rpc SetPortConf(SetPortConfRequest) returns (CommandResponse) {} + rpc GetPortConf(GetPortConfRequest) returns (GetPortConfResponse) {} /// Collect port statistics /// /// At the moment, per-queue stats are not supported. - rpc GetPortStats (GetPortStatsRequest) returns (GetPortStatsResponse) {} + rpc GetPortStats(GetPortStatsRequest) returns (GetPortStatsResponse) {} /// Query link status - rpc GetLinkStatus (GetLinkStatusRequest) returns (GetLinkStatusResponse) {} + rpc GetLinkStatus(GetLinkStatusRequest) returns (GetLinkStatusResponse) {} // TODO: Add PortCommand, like ModuleCommand, which performs driver-specific // actions on a port. - // ------------------------------------------------------------------------- // Module // ------------------------------------------------------------------------- /// Enumerate all module types available - rpc ListMclass (EmptyRequest) returns (ListMclassResponse) {} + rpc ListMclass(EmptyRequest) returns (ListMclassResponse) {} /// Query detailed information of a module type - rpc GetMclassInfo (GetMclassInfoRequest) returns (GetMclassInfoResponse) {} + rpc GetMclassInfo(GetMclassInfoRequest) returns (GetMclassInfoResponse) {} /// Remove all modules. /// /// This RPC will always succeed (unless there is a running worker) /// /// NOTE: There should be no running worker to run this command. - rpc ResetModules (EmptyRequest) returns (EmptyResponse) {} + rpc ResetModules(EmptyRequest) returns (EmptyResponse) {} /// Enumerate all initialized modules - rpc ListModules (EmptyRequest) returns (ListModulesResponse) {} + rpc ListModules(EmptyRequest) returns (ListModulesResponse) {} /// Create a new module instance from the given module type /// /// NOTE: There should be no running worker to run this command. - rpc CreateModule (CreateModuleRequest) returns (CreateModuleResponse) {} + rpc CreateModule(CreateModuleRequest) returns (CreateModuleResponse) {} /// Destroy an exsting module /// @@ -254,10 +251,10 @@ service BESSControl { /// disconnected first. All tasks created by the module will also be destoyed. /// /// NOTE: There should be no running worker to run this command. - rpc DestroyModule (DestroyModuleRequest) returns (EmptyResponse) {} + rpc DestroyModule(DestroyModuleRequest) returns (EmptyResponse) {} /// Fetch detailed information of an module instance - rpc GetModuleInfo (GetModuleInfoRequest) returns (GetModuleInfoResponse) {} + rpc GetModuleInfo(GetModuleInfoRequest) returns (GetModuleInfoResponse) {} /// Connect two modules. /// @@ -266,7 +263,7 @@ service BESSControl { /// while the igate can be connected to multiple output gates. /// /// NOTE: There should be no running worker to run this command. - rpc ConnectModules (ConnectModulesRequest) returns (EmptyResponse) {} + rpc ConnectModules(ConnectModulesRequest) returns (EmptyResponse) {} /// Disconnect two modules. /// @@ -276,10 +273,10 @@ service BESSControl { /// to any input gate. /// /// NOTE: There should be no running worker to run this command. - rpc DisconnectModules (DisconnectModulesRequest) returns (EmptyResponse) {} + rpc DisconnectModules(DisconnectModulesRequest) returns (EmptyResponse) {} /// Dump various stats about BESS's packet pools - rpc DumpMempool (DumpMempoolRequest) returns (DumpMempoolResponse) {} + rpc DumpMempool(DumpMempoolRequest) returns (DumpMempoolResponse) {} /// Send a command to the specified module instance. /// @@ -289,31 +286,34 @@ service BESSControl { /// /// NOTE: Some commands cannot be used if there are running workers. /// For those commands you must pause all workers first. - rpc ModuleCommand (CommandRequest) returns (CommandResponse) {} + rpc ModuleCommand(CommandRequest) returns (CommandResponse) {} // ------------------------------------------------------------------------- // Gate hooks // ------------------------------------------------------------------------- /// Enumerate all gatehook types available - rpc ListGateHookClass (EmptyRequest) returns (ListGateHookClassResponse) {} + rpc ListGateHookClass(EmptyRequest) returns (ListGateHookClassResponse) {} /// Query detailed information of a gatehook type - rpc GetGateHookClassInfo (GetGateHookClassInfoRequest) returns (GetGateHookClassInfoResponse) {} + rpc GetGateHookClassInfo(GetGateHookClassInfoRequest) + returns (GetGateHookClassInfoResponse) {} /// Enable/Disable a gate hook. - rpc ConfigureGateHook (ConfigureGateHookRequest) returns (ConfigureGateHookResponse) {} + rpc ConfigureGateHook(ConfigureGateHookRequest) + returns (ConfigureGateHookResponse) {} /// Enumerate all gatehook installed - rpc ListGateHooks (EmptyRequest) returns (ListGateHooksResponse) {} + rpc ListGateHooks(EmptyRequest) returns (ListGateHooksResponse) {} /// Send command to gate hook instance. - rpc GateHookCommand (GateHookCommandRequest) returns (CommandResponse) {} + rpc GateHookCommand(GateHookCommandRequest) returns (CommandResponse) {} // ------------------------------------------------------------------------- // Resume hooks // ------------------------------------------------------------------------- /// Enable/Disable a resume hook. - rpc ConfigureResumeHook (ConfigureResumeHookRequest) returns (CommandResponse) {} + rpc ConfigureResumeHook(ConfigureResumeHookRequest) + returns (CommandResponse) {} } diff --git a/protobuf/tests/test_msg.proto b/protobuf/tests/test_msg.proto index e71517f937..280a497f94 100644 --- a/protobuf/tests/test_msg.proto +++ b/protobuf/tests/test_msg.proto @@ -33,7 +33,9 @@ syntax = "proto3"; package bess.pb.test; -message UnnestedDictMsg { map dict = 1; } +message UnnestedDictMsg { + map dict = 1; +} message NestedDictMsg { UnnestedDictMsg a = 1; diff --git a/protobuf/util_msg.proto b/protobuf/util_msg.proto index 84d80dc6e0..3688414a57 100644 --- a/protobuf/util_msg.proto +++ b/protobuf/util_msg.proto @@ -29,27 +29,28 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -syntax="proto3"; +syntax = "proto3"; /// This file contains some standard "types" for messages to/from BESS package bess.pb; option go_package = "github.com/omec-project/upf-epc/pfcpiface/bess_pb"; -/// The Field message represents one field in a packet -- either stored in metadata or in the packet body. +/// The Field message represents one field in a packet -- either stored in +/// metadata or in the packet body. message Field { oneof position { - string attr_name = 1; /// The metadata attribute assigned to store the data - uint32 offset = 2; /// The offset in bytes to store the data into + string attr_name = 1; /// The metadata attribute assigned to store the data + uint32 offset = 2; /// The offset in bytes to store the data into } - uint32 num_bytes = 3; /// The size of the data in bytes + uint32 num_bytes = 3; /// The size of the data in bytes } -/// The FieldData message encodes a value to insert into a packet; the value can be supplied as either an int or a bytestring. +/// The FieldData message encodes a value to insert into a packet; the value can +/// be supplied as either an int or a bytestring. message FieldData { oneof encoding { - bytes value_bin = 1; /// The value as a bytestring - uint64 value_int = 2; /// The value in integer format + bytes value_bin = 1; /// The value as a bytestring + uint64 value_int = 2; /// The value in integer format } } - diff --git a/sample_plugin/modules/sequential_update.cc b/sample_plugin/modules/sequential_update.cc index c41e46191b..b010101c5e 100644 --- a/sample_plugin/modules/sequential_update.cc +++ b/sample_plugin/modules/sequential_update.cc @@ -41,8 +41,8 @@ const Commands SequentialUpdate::cmds = { Command::THREAD_UNSAFE}, }; -CommandResponse -SequentialUpdate::Init(const sample::supdate::pb::SequentialUpdateArg &arg) { +CommandResponse SequentialUpdate::Init( + const sample::supdate::pb::SequentialUpdateArg &arg) { return CommandAdd(arg); } @@ -69,26 +69,26 @@ CommandResponse SequentialUpdate::CommandAdd( max = var.max(); switch (size) { - case 1: - mask = be32_t(0x00ffffff); - min = std::min(min, static_cast(0xff)); - max = std::min(max, static_cast(0xff)); - break; - - case 2: - mask = be32_t(0x0000ffff); - min = std::min(min, static_cast(0xffff)); - max = std::min(max, static_cast(0xffff)); - break; - - case 4: - mask = be32_t(0x00000000); - min = std::min(min, static_cast(0xffffffffu)); - max = std::min(max, static_cast(0xffffffffu)); - break; - - default: - return CommandFailure(EINVAL, "'size' must be 1, 2, or 4"); + case 1: + mask = be32_t(0x00ffffff); + min = std::min(min, static_cast(0xff)); + max = std::min(max, static_cast(0xff)); + break; + + case 2: + mask = be32_t(0x0000ffff); + min = std::min(min, static_cast(0xffff)); + max = std::min(max, static_cast(0xffff)); + break; + + case 4: + mask = be32_t(0x00000000); + min = std::min(min, static_cast(0xffffffffu)); + max = std::min(max, static_cast(0xffffffffu)); + break; + + default: + return CommandFailure(EINVAL, "'size' must be 1, 2, or 4"); } if (offset + size > SNBUF_DATA) { diff --git a/sample_plugin/modules/sequential_update.h b/sample_plugin/modules/sequential_update.h index 6203c25a6f..df72f9a446 100644 --- a/sample_plugin/modules/sequential_update.h +++ b/sample_plugin/modules/sequential_update.h @@ -41,7 +41,7 @@ static const size_t kMaxVariable = 16; class SequentialUpdate final : public Module { -public: + public: static const Commands cmds; SequentialUpdate() : Module(), num_vars_(), vars_() {} @@ -50,21 +50,21 @@ class SequentialUpdate final : public Module { void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; - CommandResponse - CommandAdd(const sample::supdate::pb::SequentialUpdateArg &arg); + CommandResponse CommandAdd( + const sample::supdate::pb::SequentialUpdateArg &arg); CommandResponse CommandClear(const bess::pb::EmptyArg &arg); -private: + private: size_t num_vars_; struct { - bess::utils::be32_t mask; // bits with 1 won't be updated + bess::utils::be32_t mask; // bits with 1 won't be updated uint32_t min; - uint32_t range; // max - min + 1 + uint32_t range; // max - min + 1 uint32_t cur; size_t offset; size_t bit_shift; } vars_[kMaxVariable]; }; -#endif // BESS_MODULES_SEQUENTIALUPDATE_H_ +#endif // BESS_MODULES_SEQUENTIALUPDATE_H_ diff --git a/sample_plugin/protobuf/supdate_msg.proto b/sample_plugin/protobuf/supdate_msg.proto index 82b2b5b9ad..b755c09f83 100644 --- a/sample_plugin/protobuf/supdate_msg.proto +++ b/sample_plugin/protobuf/supdate_msg.proto @@ -34,29 +34,29 @@ syntax = "proto3"; package sample.supdate.pb; /** - * The function `clear()` for SequentialUpdate takes no parameters and clears all - * state in the module. + * The function `clear()` for SequentialUpdate takes no parameters and clears + * all state in the module. */ -message SequentialUpdateCommandClearArg { -} +message SequentialUpdateCommandClearArg {} /** - * The SequentialUpdate module rewrites a specified field (`offset` and `size`) in a packet - * with a sequentially increased value from a specified min to max values. + * The SequentialUpdate module rewrites a specified field (`offset` and `size`) + * in a packet with a sequentially increased value from a specified min to max + * values. * * __Input Gates__: 1 * __Output Gates__: 1 */ message SequentialUpdateArg { /** - * SequentialUpdate's Field specifies where to rewrite, and what values to rewrite - * in each packet processed. + * SequentialUpdate's Field specifies where to rewrite, and what values to + * rewrite in each packet processed. */ message Field { - int64 offset = 1; /// Offset in bytes for where to rewrite. - uint64 size = 2; /// The number of bytes to write. - uint64 min = 3; /// The minimum value to insert into the packet. - uint64 max = 4; /// The maximum value to insert into the packet. + int64 offset = 1; /// Offset in bytes for where to rewrite. + uint64 size = 2; /// The number of bytes to write. + uint64 min = 3; /// The minimum value to insert into the packet. + uint64 max = 4; /// The maximum value to insert into the packet. } - repeated Field fields = 1; /// A list of SequentialUpdate Fields. + repeated Field fields = 1; /// A list of SequentialUpdate Fields. } From 6787cced6a3ca60ba8bf7c577f4571b4fd8b4d2a Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Sun, 19 Feb 2023 18:27:34 -0800 Subject: [PATCH 55/62] Refactor define for the GTPu header (#16) --- core/modules/gtpu_echo.h | 15 --------------- core/modules/gtpu_encap.h | 12 ------------ core/modules/gtpu_parser.cc | 1 - core/utils/gtp.h | 14 ++++++++++++++ 4 files changed, 14 insertions(+), 28 deletions(-) diff --git a/core/modules/gtpu_echo.h b/core/modules/gtpu_echo.h index 2aa39b1840..f5cbf1dd52 100644 --- a/core/modules/gtpu_echo.h +++ b/core/modules/gtpu_echo.h @@ -8,21 +8,6 @@ #include "../module.h" #include "../pb/module_msg.pb.h" /*----------------------------------------------------------------------------------*/ -/** - * GTPU header - */ -#define GTPU_VERSION 0x01 -#define GTP_PROTOCOL_TYPE_GTP 0x01 -#define GTP_GPDU 0xff -#define GTPU_ECHO_RECOVERY 14 -#define GTPU_ECHO_REQUEST 0x01 -#define GTPU_ECHO_RESPONSE 0x02 - -/** - * UDP header - */ -#define UDP_PORT_GTPU 2152 -/*----------------------------------------------------------------------------------*/ /** * GTPU-Recovery Information Element */ diff --git a/core/modules/gtpu_encap.h b/core/modules/gtpu_encap.h index 9bf6c11531..a047f467f5 100644 --- a/core/modules/gtpu_encap.h +++ b/core/modules/gtpu_encap.h @@ -9,18 +9,6 @@ #include "../pb/module_msg.pb.h" #include /*----------------------------------------------------------------------------------*/ -/** - * GTPU header - */ -#define GTPU_VERSION 0x01 -#define GTP_PROTOCOL_TYPE_GTP 0x01 -#define GTP_GPDU 0xff - -/** - * UDP header - */ -#define UDP_PORT_GTPU 2152 -/*----------------------------------------------------------------------------------*/ class GtpuEncap final : public Module { public: GtpuEncap() { max_allowed_workers_ = Worker::kMaxWorkers; } diff --git a/core/modules/gtpu_parser.cc b/core/modules/gtpu_parser.cc index 3e6d2c6cda..d988fa0c5e 100644 --- a/core/modules/gtpu_parser.cc +++ b/core/modules/gtpu_parser.cc @@ -22,7 +22,6 @@ using bess::utils::Tcp; using bess::utils::Udp; enum { DEFAULT_GATE = 0, FORWARD_GATE }; -const unsigned short UDP_PORT_GTPU = 2152; /*----------------------------------------------------------------------------------*/ void GtpuParser::set_gtp_parsing_attrs(be32_t *sip, be32_t *dip, be16_t *sp, be16_t *dp, be32_t *teid, be32_t *tipd, diff --git a/core/utils/gtp.h b/core/utils/gtp.h index 7c12e96a0d..5c56676786 100644 --- a/core/utils/gtp.h +++ b/core/utils/gtp.h @@ -64,5 +64,19 @@ struct [[gnu::packed]] Gtpv1PDUSessExt { } // namespace utils } // namespace bess +/*----------------------------------------------------------------------------------*/ +/** + * GTPU header + */ +#define GTPU_VERSION 0x01 +#define GTP_PROTOCOL_TYPE_GTP 0x01 +#define GTP_GPDU 0xff +#define GTPU_ECHO_RECOVERY 14 +#define GTPU_ECHO_REQUEST 0x01 +#define GTPU_ECHO_RESPONSE 0x02 + +/// UDP header +#define UDP_PORT_GTPU 2152 + /*----------------------------------------------------------------------------------*/ #endif /* BESS_UTILS_GTP_H_ */ From 34dc1cff5c4197378c7ab14ad2a825b2a1826883 Mon Sep 17 00:00:00 2001 From: manojgop Date: Mon, 27 Feb 2023 11:24:42 +0530 Subject: [PATCH 56/62] Update GitHub Action to build docker image locally (#18) - Update GitHub Actions to build docker image locally during pull request - Use protobuf version 3.20 to fix errors in generated _pb2.py file Signed-off-by: Manoj Gopalakrishnan --- .github/workflows/pull_request.yaml | 6 +++++- env/Dockerfile | 5 ++++- env/runtime.yml | 2 +- requirements.txt | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 4fa0ba2579..24374e90de 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -11,6 +11,8 @@ jobs: matrix: os: - ubuntu-20.04 + env: + BESS_DPDK_BRANCH: "dpdk-2011-focal" steps: - uses: actions/checkout@v2 - run: sudo sysctl -w vm.nr_hugepages=512 @@ -19,7 +21,9 @@ jobs: - run: pip3 install --user -r requirements.txt - run: '[[ ${COVERAGE:-0} == 0 ]] || sudo apt-get install -y gcc-7' - run: '[[ ${SANITIZE:-0} == 0 ]] || sudo apt-get install -y llvm-3.9' - - run: 'docker pull ghcr.io/omec-project/upf-epc/bess_build | cat' + - run: | + cd env + yes n | ./rebuild_images.py focal64 - run: sudo mkdir -p /mnt/huge - run: sudo mount -t hugetlbfs nodev /mnt/huge - run: export CXX="ccache $VER_CXX" diff --git a/env/Dockerfile b/env/Dockerfile index 60e4d5dad8..4ab09976c6 100644 --- a/env/Dockerfile +++ b/env/Dockerfile @@ -1,3 +1,6 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2020-present Open Networking Foundation +# Copyright 2019 Intel Corporation # vim: syntax=dockerfile ARG BASE_IMAGE=ubuntu:focal @@ -23,7 +26,7 @@ RUN update-alternatives --install /usr/local/bin/python python /usr/bin/python3 RUN mkdir -p /build/bess # Build DPDK testpmd (used in bessctl samples) -ARG BESS_DPDK_BRANCH=master +ARG BESS_DPDK_BRANCH=dpdk-2011-focal RUN cd /build/bess && \ curl -s -L https://github.com/omec-project/bess/archive/${BESS_DPDK_BRANCH}.tar.gz | tar zx --strip-components=1 && \ ./build.py dpdk && \ diff --git a/env/runtime.yml b/env/runtime.yml index 44fca77323..92b8c6b4ff 100644 --- a/env/runtime.yml +++ b/env/runtime.yml @@ -15,7 +15,7 @@ - name: Install list of Python packages pip: name: - - protobuf + - protobuf==3.20 - grpcio - scapy - flask diff --git a/requirements.txt b/requirements.txt index 62ac6b186e..6c740506ba 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ scapy flask grpcio -protobuf +protobuf==3.20 From 4bb08c3c7c0205ec9949d77486f055b1b8be5eca Mon Sep 17 00:00:00 2001 From: manojgop Date: Mon, 20 Mar 2023 18:21:40 +0530 Subject: [PATCH 57/62] Add support for CNDP(Cloud Native Data Plane) port in BESS. (#2) - CNDP BESS port to send/receive n/w packets using AF_XDP socket. - Modify Bess core Makefile to build CNDP port driver. - Dockerfile to build BESS with CNDP. - Add "CndpPortArg" in port_msg.proto file to initialize Bess CNDP port. - Use external BESS PacketPool (rte_mempool/rte_mbuf) with CNDP xskdev. - Example scripts to test Bess CNDP port. - ReadMe file to build docker image and run BESS CNDP example scripts. - GitHub Action for running CNDP tests. Signed-off-by: Manoj Gopalakrishnan --- .github/workflows/pull_request.yaml | 9 +- CNDP_README.md | 39 + bessctl/conf/cndp/cndpfwd.bess | 11 + bessctl/conf/cndp/cndpfwd_coreid.bess | 23 + bessctl/conf/cndp/cndpfwd_ipmac_swap.bess | 20 + bessctl/conf/cndp/cndpfwd_queue_coreid.bess | 23 + bessctl/conf/cndp/cndpfwd_veth.bess | 10 + bessctl/conf/cndp/cndprecv.bess | 11 + bessctl/conf/cndp/cndprecv_coreid.bess | 16 + bessctl/conf/cndp/fwd.jsonc | 176 +++ bessctl/conf/cndp/fwd_veth.jsonc | 151 +++ bessctl/module_tests/buffer.py | 2 +- bessctl/module_tests/cndp/cndp_veth.py | 76 ++ core/Makefile | 4 +- core/drivers/cndp.cc | 1059 +++++++++++++++++++ core/drivers/cndp.h | 245 +++++ core/pktbatch.h | 2 +- env/Dockerfile | 82 ++ env/Dockerfile-cndp | 136 +++ protobuf/ports/port_msg.proto | 9 + requirements.txt | 1 + 21 files changed, 2101 insertions(+), 4 deletions(-) create mode 100644 CNDP_README.md create mode 100644 bessctl/conf/cndp/cndpfwd.bess create mode 100644 bessctl/conf/cndp/cndpfwd_coreid.bess create mode 100644 bessctl/conf/cndp/cndpfwd_ipmac_swap.bess create mode 100644 bessctl/conf/cndp/cndpfwd_queue_coreid.bess create mode 100644 bessctl/conf/cndp/cndpfwd_veth.bess create mode 100644 bessctl/conf/cndp/cndprecv.bess create mode 100644 bessctl/conf/cndp/cndprecv_coreid.bess create mode 100644 bessctl/conf/cndp/fwd.jsonc create mode 100644 bessctl/conf/cndp/fwd_veth.jsonc create mode 100644 bessctl/module_tests/cndp/cndp_veth.py create mode 100644 core/drivers/cndp.cc create mode 100644 core/drivers/cndp.h create mode 100644 env/Dockerfile-cndp diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index 24374e90de..7214e9eba8 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -18,9 +18,15 @@ jobs: - run: sudo sysctl -w vm.nr_hugepages=512 - run: sudo apt-get update - run: sudo apt-get install -y python3-pip python3-setuptools python3-coverage python3-pyelftools ccache - - run: pip3 install --user -r requirements.txt + - run: sudo pip3 install -r requirements.txt - run: '[[ ${COVERAGE:-0} == 0 ]] || sudo apt-get install -y gcc-7' - run: '[[ ${SANITIZE:-0} == 0 ]] || sudo apt-get install -y llvm-3.9' + - name: Install CNDP packages + run: | + sudo apt-get update && sudo apt-get install -y \ + build-essential libbsd-dev libelf-dev libbpf-dev libjson-c-dev \ + libnl-3-dev libnl-cli-3-dev libnuma-dev libpcap-dev meson \ + pkg-config libgflags2.2 - run: | cd env yes n | ./rebuild_images.py focal64 @@ -33,6 +39,7 @@ jobs: - run: (cd core && ./all_test --gtest_shuffle) - run: python3-coverage run -m unittest discover -v - run: python3 bessctl/run_module_tests.py + - run: sudo python3 bessctl/run_module_tests.py --test_dir bessctl/module_tests/cndp - run: ccache -s - run: bessctl/bessctl daemon stop - run: '[[ ${COVERAGE:-0} == 0 ]] || { sleep 3; codecov --gcov-exec gcov-7; }' diff --git a/CNDP_README.md b/CNDP_README.md new file mode 100644 index 0000000000..7da92815d5 --- /dev/null +++ b/CNDP_README.md @@ -0,0 +1,39 @@ + + +# Cloud Native Data Plane (CNDP) BESS Port + +Cloud Native Data Plane (CNDP) is a collection of user space libraries for accelerating packet processing for cloud applications. It aims to provide better performance than that of standard network socket interfaces by using an I/O layer primarily built on AF_XDP, an interface that delivers packets directly to user space, bypassing the kernel networking stack. For more details refer https://cndp.io/ + +CNDP BESS port enables sending/receiving packets to/from network interface using AF-XDP. + +Following are the steps required to build BESS CNDP docker image: + +### Step 1: Build the BESS CNDP docker image. + +> Note: If you are behind a proxy make sure to export/setenv http_proxy and https_proxy + +From the top level BESS directory call: + +``` +$ docker build -t besscndp --build-arg http_proxy=${http_proxy} --build-arg https_proxy=${http_proxy} -f env/Dockerfile-cndp . +``` + +### Step 2: Run the besscndp docker container + +From the top level BESS directory call: + +``` +$ docker run --network=host -e http_proxy=${http_proxy} -e https_proxy=${http_proxy} --privileged --cap-add=ALL -v /dev/hugepages:/mnt/huge -v /sys/bus/pci/devices:/sys/bus/pci/devices -v /sys/devices/system/node:/sys/devices/system/node -v /lib/modules:/lib/modules -v /dev:/dev -v /usr/src:/usr/src -it besscndp bash +``` + +### Step 3: Run example CNDP BESS script + +1. Modify the jsonc file in "/build/bess/bessctl/conf/cndp/fwd.jsonc" to use the network device in your system used to send and receive n/w packets. +2. Configure ethtool filter rules as required to send/recv packets via a specified queue id. Ensure that same netdev and queue id is configured in fwd.jsonc file. +3. Run bessctl controller from container shell: `./bessctl/bessctl` +4. From bessctl shell , run bess daemon: `daemon start -log_dir /build/bess/log` +5. Run sample BESS CNDP script: `run cndp/cndpfwd_coreid`. This will run cndpfwd BESS pipeline in a core id specified in "/build/bess/bessctl/conf/cndp/cndpfwd_coreid.bess" script. Before running the script, edit the script to update core in line `bess.add_worker(wid=0, core=28)` to a core id in CPU socket where the network device is attached to get better performance. +6. If everything works fine, then you should see BESS pipeline logs when you run: `monior pipeline` diff --git a/bessctl/conf/cndp/cndpfwd.bess b/bessctl/conf/cndp/cndpfwd.bess new file mode 100644 index 0000000000..6d3eae7794 --- /dev/null +++ b/bessctl/conf/cndp/cndpfwd.bess @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation + +# Example BESS script for CNDP Packet forward. It receives the ethernet packet from recvport, +# swaps the src and dst mac address and sends the packet to sendport. +# Port index corresponds to the ports defined in lports section in fwd.jsonc file. + +recvport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=0) +sendport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=1) + +PortInc(port=recvport) -> MACSwap() -> PortOut(port=sendport) diff --git a/bessctl/conf/cndp/cndpfwd_coreid.bess b/bessctl/conf/cndp/cndpfwd_coreid.bess new file mode 100644 index 0000000000..8f57b9cc9b --- /dev/null +++ b/bessctl/conf/cndp/cndpfwd_coreid.bess @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation + +# Example BESS script for CNDP Packet forward. It receives the ethernet packet from recvport, +# swaps the src and dst mac address and sends the packet to sendport. +# Port index corresponds to the ports defined in lports section in fwd.jsonc file. +# It also sets core affinity for worker thread. Before running the script, +# edit the script to update core in line `bess.add_worker(wid=0, core=28)` +# to a core id in CPU socket where the network device is attached to get better performance. + +recvport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=0) +sendport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=1) + +input0 = PortInc(port=recvport) +output0 = PortOut(port=sendport) + +# Swap src/dst MAC +macswap = MACSwap() + +input0 -> macswap -> output0 + +bess.add_worker(wid=0, core=28) +input0.attach_task(wid=0) diff --git a/bessctl/conf/cndp/cndpfwd_ipmac_swap.bess b/bessctl/conf/cndp/cndpfwd_ipmac_swap.bess new file mode 100644 index 0000000000..777ab9ec5d --- /dev/null +++ b/bessctl/conf/cndp/cndpfwd_ipmac_swap.bess @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation + +# Example BESS script for CNDP Packet forward. It receives the Ethernet/IP packet from recvport, +# swaps the src and dst mac and ip address and sends the packet to sendport. +# Port index corresponds to the ports defined in lports section in fwd.jsonc file. + +recvport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=0) +sendport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=1) + +input0 = PortInc(port=recvport) +output0 = PortOut(port=sendport) + +# Swap src/dst MAC +macswap = MACSwap() + +# Swap src/dst IP addresses / ports +ipswap = IPSwap() + +input0 -> macswap -> ipswap -> output0 diff --git a/bessctl/conf/cndp/cndpfwd_queue_coreid.bess b/bessctl/conf/cndp/cndpfwd_queue_coreid.bess new file mode 100644 index 0000000000..d9acabbfb4 --- /dev/null +++ b/bessctl/conf/cndp/cndpfwd_queue_coreid.bess @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation + +# Example BESS script for CNDP Packet forward. It receives the ethernet packet from recvport, +# swaps the src and dst mac address, buffers the packet to the queue and sends the packet to sendport. + +recvport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=0) +sendport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=1) + +input0 = PortInc(port=recvport) +output0 = PortOut(port=sendport) + +queue0 = Queue() + +# Swap src/dst MAC +macswap = MACSwap() + +input0 -> macswap -> queue0 -> output0 + +bess.add_worker(wid=0, core=28) +bess.add_worker(wid=1, core=29) +input0.attach_task(wid=0) +queue0.attach_task(wid=1) diff --git a/bessctl/conf/cndp/cndpfwd_veth.bess b/bessctl/conf/cndp/cndpfwd_veth.bess new file mode 100644 index 0000000000..147afc1e0b --- /dev/null +++ b/bessctl/conf/cndp/cndpfwd_veth.bess @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation + +# Example BESS script for CNDP Packet forward. It receives the ethernet packet from recvport, +# swaps the src and dst mac address and sends the packet to sendport. +# Port index corresponds to the ports defined in lports section in fwd.jsonc file. + +veth_port = CndpPort(jsonc_file='bessctl/conf/cndp/fwd_veth.jsonc', lport_index=0) + +PortInc(port=veth_port) -> MACSwap() -> PortOut(port=veth_port) diff --git a/bessctl/conf/cndp/cndprecv.bess b/bessctl/conf/cndp/cndprecv.bess new file mode 100644 index 0000000000..84bc3d66cc --- /dev/null +++ b/bessctl/conf/cndp/cndprecv.bess @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation + +# Example BESS script to receive packet from CNDP port. +# Port index corresponds to the ports defined in lports section in fwd.jsonc file. + +myport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=0) + +input0 = PortInc(port=myport) + +input0 -> Sink() diff --git a/bessctl/conf/cndp/cndprecv_coreid.bess b/bessctl/conf/cndp/cndprecv_coreid.bess new file mode 100644 index 0000000000..bdf053185d --- /dev/null +++ b/bessctl/conf/cndp/cndprecv_coreid.bess @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation + +# Example BESS script to receive packet from CNDP port. +# Port index corresponds to the ports defined in lports section in fwd.jsonc file. +# It also sets core affinity for worker thread. Before running the script, +# edit the script to update core in line `bess.add_worker(wid=0, core=28)` +# to a core id in CPU socket where the network device is attached to get better performance. + +myport = CndpPort(jsonc_file="/build/bess/bessctl/conf/cndp/fwd.jsonc", lport_index=0) +input0 = PortInc(port=myport) + +input0 -> Sink() + +bess.add_worker(wid=0, core=28) +input0.attach_task(wid=0) diff --git a/bessctl/conf/cndp/fwd.jsonc b/bessctl/conf/cndp/fwd.jsonc new file mode 100644 index 0000000000..84ee938a7c --- /dev/null +++ b/bessctl/conf/cndp/fwd.jsonc @@ -0,0 +1,176 @@ +{ + // SPDX-License-Identifier: BSD-3-Clause + // Copyright (c) 2020-2022 Intel Corporation. + // + // (R) - Required entry + // (O) - Optional entry + // All descriptions are optional and short form is 'desc' + // The order of the entries in this file are handled when it is parsed and the + // entries can be in any order. + + // (R) Application information + // name - (O) the name of the application + // description - (O) the description of the application + "application": { + "name": "BESS", + "description": "BESS CNDP Port" + }, + + // (O) Default values + // bufcnt - (O) UMEM default buffer count in 1K increments + // bufsz - (O) UMEM buffer size in 1K increments + // rxdesc - (O) Number of RX ring descriptors in 1K increments + // txdesc - (O) Number of TX ring descriptors in 1K increments + // cache - (O) MBUF Pool cache size in number of entries + // mtype - (O) Memory type for mmap allocations + "defaults": { + "bufcnt": 16, + "bufsz": 2, + "rxdesc": 2, + "txdesc": 2, + "cache": 256, + "mtype": "2MB" + }, + + // List of all UMEM's to be created + // key/val - (R) The 'key' is the name of the umem for later reference. + // The 'val' is the object describing the UMEM buffer. + // Multiple umem regions can be defined. + // A UMEM can support multiple lports using the regions array. Each lports can use + // one of the regions. + // bufcnt - (R) The number of buffers in 1K increments in the UMEM space. + // bufsz - (R) The size in 1K increments of each buffer in the UMEM space. + // mtype - (O) If missing or empty string or missing means use 4KB or default system pages. + // regions - (O) Array of sizes one per region in 1K increments, total must be <= bufcnt + // rxdesc - (O) Number of RX descriptors to be allocated in 1K increments, + // if not present or zero use defaults.rxdesc, normally zero. + // txdesc - (O) Number of TX descriptors to be allocated in 1K increments, + // if not present or zero use defaults.txdesc, normally zero. + // description | desc - (O) Description of the umem space. + "umems": { + "umem0": { + "bufcnt": 32, + "bufsz": 2, + "mtype": "2MB", + "regions": [ + 16, + 16 + ], + "rxdesc": 0, + "txdesc": 0, + "description": "UMEM Description 0" + }, + "umem1": { + "bufcnt": 32, + "bufsz": 2, + "mtype": "2MB", + "regions": [ + 16, + 16 + ], + "rxdesc": 0, + "txdesc": 0, + "description": "UMEM Description 0" + } + }, + + + // List of all lports to be used in the application + // A lport is defined by a netdev/queue ID pair, which is a socket containing a Rx/Tx ring pair. + // Each queue ID is assigned to a single socket, a socket is the lport defined by netdev/qid. + // Note: A netdev can be shared between lports as the qid is unique per lport + // If netdev is not defined or empty, then it must be a virtual interface and not + // associated with a netdev/queue ID. + // key/val - (R) The 'key' is the logical name e.g., 'eth0:0', 'eth1:0', ... to be used by the + // application to reference a lport. The 'val' object contains information about + // each lport. + // netdev - (R) The netdev device to be used, the part before the colon + // must reflect the netdev name + // pmd - (R) All PMDs have a name i.e., 'net_af_xdp', 'ring', ... + // qid - (R) Is the queue id to use for this lport, defined by ethtool command line + // umem - (R) The UMEM assigned to this lport + // region - (O) UMEM region index value, default region 0 + // busy_poll - (O) Enable busy polling support, true or false, default false + // busy_timeout - (O) 1-65535 or 0 - use default value, values in milliseconds + // busy_budget - (O) 0xFFFF disabled, 0 use default, >0 budget value + // inhibit_prog_load - (O) Inhibit loading the BPF program if true, default false + // force_wakeup - (O) Force TX wakeup calls for CVL NIC, default false + // skb_mode - (O) Enable XDP_FLAGS_SKB_MODE when creating af_xdp socket, forces copy mode, default false + // description - (O) The description, 'desc' can be used as well + "lports": { + "enp134s0:0": { + "pmd": "net_af_xdp", + "qid": 23, + "umem": "umem0", + "region": 0, + "description": "LAN 0 port" + }, + "enp134s0:1": { + "pmd": "net_af_xdp", + "qid": 33, + "umem": "umem0", + "region": 1, + "description": "LAN 1 port" + } + }, + + // (O) Define the lcore groups for each thread to run + // Can be integers or a string for a range of lcores + // e.g., [10], [10-14,16], [10-12, 14-15, 17-18, 20] + // Names of a lcore group and its lcores assigned to the group. + // The initial group is for the main thread of the application. + // The default group is special and is used if a thread if not assigned to a group. + // + // CNDP BESS Port does not use this section. + "lcore-groups": { + "initial": [22], + "group0": [25], + "group1": [35], + "default": ["22-35"] + }, + + // (O) Set of common options application defined. + // The Key can be any string and value can be boolean, string, array or integer + // An array must contain only a single value type, boolean, integer, string and + // can't be a nested array. + // pkt_api - (O) Set the type of packet API xskdev or pktdev + // no-metrics - (O) Disable metrics gathering and thread + // no-restapi - (O) Disable RestAPI support + // cli - (O) Enable/Disable CLI supported + // mode - (O) Mode type [drop | rx-only], tx-only, [lb | loopback], fwd, acl-strict, acl-permissive + "options": { + "pkt_api": "xskdev", + "no-metrics": false, + "no-restapi": false, + "cli": true, + "mode": "drop" + }, + + // List of threads to start and information for the thread(s). Application can start + // its own threads for any reason and are not required to be configured by this file. + // + // Key/Val - (R) A unique thread name. + // The format is [:] the ':' and identifier + // are optional if all thread names are unique + // group - (O) The lcore-group this thread belongs to. The + // lports - (O) The list of lports assigned to this thread and cannot share lports. + // description | desc - (O) The description + // + // CNDP BESS Port does not use this section. + "threads": { + "main": { + "group": "initial", + "description": "CLI Thread" + }, + "fwd:0": { + "group": "group0", + "lports": ["enp134s0:0"], + "description": "Thread 0" + }, + "fwd:1": { + "group": "group1", + "lports": ["enp134s0:1"], + "description": "Thread 1" + } + } +} diff --git a/bessctl/conf/cndp/fwd_veth.jsonc b/bessctl/conf/cndp/fwd_veth.jsonc new file mode 100644 index 0000000000..770033a868 --- /dev/null +++ b/bessctl/conf/cndp/fwd_veth.jsonc @@ -0,0 +1,151 @@ +{ + // SPDX-License-Identifier: BSD-3-Clause + // Copyright (c) 2020-2022 Intel Corporation. + // + // (R) - Required entry + // (O) - Optional entry + // All descriptions are optional and short form is 'desc' + // The order of the entries in this file are handled when it is parsed and the + // entries can be in any order. + + // (R) Application information + // name - (O) the name of the application + // description - (O) the description of the application + "application": { + "name": "BESS", + "description": "BESS CNDP Port" + }, + + // (O) Default values + // bufcnt - (O) UMEM default buffer count in 1K increments + // bufsz - (O) UMEM buffer size in 1K increments + // rxdesc - (O) Number of RX ring descriptors in 1K increments + // txdesc - (O) Number of TX ring descriptors in 1K increments + // cache - (O) MBUF Pool cache size in number of entries + // mtype - (O) Memory type for mmap allocations + "defaults": { + "bufcnt": 1, + "bufsz": 1, + "rxdesc": 1, + "txdesc": 1, + "cache": 256, + "mtype": "4KB" + }, + + // List of all UMEM's to be created + // key/val - (R) The 'key' is the name of the umem for later reference. + // The 'val' is the object describing the UMEM buffer. + // Multiple umem regions can be defined. + // A UMEM can support multiple lports using the regions array. Each lports can use + // one of the regions. + // bufcnt - (R) The number of buffers in 1K increments in the UMEM space. + // bufsz - (R) The size in 1K increments of each buffer in the UMEM space. + // mtype - (O) If missing or empty string or missing means use 4KB or default system pages. + // regions - (O) Array of sizes one per region in 1K increments, total must be <= bufcnt + // rxdesc - (O) Number of RX descriptors to be allocated in 1K increments, + // if not present or zero use defaults.rxdesc, normally zero. + // txdesc - (O) Number of TX descriptors to be allocated in 1K increments, + // if not present or zero use defaults.txdesc, normally zero. + // description | desc - (O) Description of the umem space. + "umems": { + "umem0": { + "bufcnt": 1, + "bufsz": 1, + "mtype": "4KB", + "regions": [ + 1 + ], + "rxdesc": 0, + "txdesc": 0, + "description": "UMEM Description 0" + } + }, + + + // List of all lports to be used in the application + // A lport is defined by a netdev/queue ID pair, which is a socket containing a Rx/Tx ring pair. + // Each queue ID is assigned to a single socket, a socket is the lport defined by netdev/qid. + // Note: A netdev can be shared between lports as the qid is unique per lport + // If netdev is not defined or empty, then it must be a virtual interface and not + // associated with a netdev/queue ID. + // key/val - (R) The 'key' is the logical name e.g., 'eth0:0', 'eth1:0', ... to be used by the + // application to reference a lport. The 'val' object contains information about + // each lport. + // netdev - (R) The netdev device to be used, the part before the colon + // must reflect the netdev name + // pmd - (R) All PMDs have a name i.e., 'net_af_xdp', 'ring', ... + // qid - (R) Is the queue id to use for this lport, defined by ethtool command line + // umem - (R) The UMEM assigned to this lport + // region - (O) UMEM region index value, default region 0 + // busy_poll - (O) Enable busy polling support, true or false, default false + // busy_timeout - (O) 1-65535 or 0 - use default value, values in milliseconds + // busy_budget - (O) 0xFFFF disabled, 0 use default, >0 budget value + // inhibit_prog_load - (O) Inhibit loading the BPF program if true, default false + // force_wakeup - (O) Force TX wakeup calls for CVL NIC, default false + // skb_mode - (O) Enable XDP_FLAGS_SKB_MODE when creating af_xdp socket, forces copy mode, default false + // description - (O) The description, 'desc' can be used as well + "lports": { + "veth1:0": { + "pmd": "net_af_xdp", + "qid": 0, + "umem": "umem0", + "region": 0, + "skb_mode": true, + "description": "LAN 0 port" + } + }, + + // (O) Define the lcore groups for each thread to run + // Can be integers or a string for a range of lcores + // e.g., [10], [10-14,16], [10-12, 14-15, 17-18, 20] + // Names of a lcore group and its lcores assigned to the group. + // The initial group is for the main thread of the application. + // The default group is special and is used if a thread if not assigned to a group. + // + // CNDP BESS Port does not use this section. + "lcore-groups": { + "initial": [0], + "group0": [1], + "default": ["0-1"] + }, + + // (O) Set of common options application defined. + // The Key can be any string and value can be boolean, string, array or integer + // An array must contain only a single value type, boolean, integer, string and + // can't be a nested array. + // pkt_api - (O) Set the type of packet API xskdev or pktdev + // no-metrics - (O) Disable metrics gathering and thread + // no-restapi - (O) Disable RestAPI support + // cli - (O) Enable/Disable CLI supported + // mode - (O) Mode type [drop | rx-only], tx-only, [lb | loopback], fwd, acl-strict, acl-permissive + "options": { + "pkt_api": "xskdev", + "no-metrics": false, + "no-restapi": false, + "cli": true, + "mode": "drop" + }, + + // List of threads to start and information for the thread(s). Application can start + // its own threads for any reason and are not required to be configured by this file. + // + // Key/Val - (R) A unique thread name. + // The format is [:] the ':' and identifier + // are optional if all thread names are unique + // group - (O) The lcore-group this thread belongs to. The + // lports - (O) The list of lports assigned to this thread and cannot share lports. + // description | desc - (O) The description + // + // CNDP BESS Port does not use this section. + "threads": { + "main": { + "group": "initial", + "description": "CLI Thread" + }, + "fwd:0": { + "group": "group0", + "lports": ["veth1:0"], + "description": "Thread 0" + } + } +} diff --git a/bessctl/module_tests/buffer.py b/bessctl/module_tests/buffer.py index abe7c6697b..da661baa7f 100644 --- a/bessctl/module_tests/buffer.py +++ b/bessctl/module_tests/buffer.py @@ -33,7 +33,7 @@ # BESS default batch size # TODO: Any way to receive the parameter from bess daemon? -BATCH_SIZE = 32 +BATCH_SIZE = 64 class BessBufferTest(BessModuleTestCase): diff --git a/bessctl/module_tests/cndp/cndp_veth.py b/bessctl/module_tests/cndp/cndp_veth.py new file mode 100644 index 0000000000..2c221cb268 --- /dev/null +++ b/bessctl/module_tests/cndp/cndp_veth.py @@ -0,0 +1,76 @@ +# Copyright (c) 2020-2022 Intel Corporation. +# SPDX-License-Identifier: BSD-3-Clause + +from test_utils import * +from pyroute2 import IPRoute +import scapy.all as scapy + + +def create_veth(): + ipr = IPRoute() + check_veth_dev1 = ipr.link_lookup(ifname='veth1') + if len(check_veth_dev1) == 0 : + ipr.link('add', ifname='veth1', kind='veth', peer='veth2') + + # lookup the index + veth_dev1 = ipr.link_lookup(ifname='veth1')[0] + veth_dev2 = ipr.link_lookup(ifname='veth2')[0] + + # bring it down + ipr.link('set', index=veth_dev1, state='down') + ipr.link('set', index=veth_dev2, state='down') + + # add primary IP address + ipr.addr('add', index=veth_dev1, + address='10.0.0.2', mask=24, + broadcast='10.0.0.255') + + ipr.addr('add', index=veth_dev2, + address='10.0.0.3', mask=24, + broadcast='10.0.0.255') + + # bring it up + ipr.link('set', index=veth_dev1, state='up') + ipr.link('set', index=veth_dev2, state='up') + +def gen_packet(): + eth = scapy.Ether() + ip = scapy.IP(src='10.0.0.2', dst='10.0.0.3') + udp = scapy.UDP(sport=10001, dport=10002) + payload = 'helloworld' + pkt = eth/ip/udp/payload + return pkt + +def delete_veth(): + ipr = IPRoute() + check_veth_dev1 = ipr.link_lookup(ifname='veth1') + if len(check_veth_dev1) > 0 : + ipr.link('delete', ifname='veth1') + + +class BessCndpTest(BessModuleTestCase): + + def test_cndp_veth(self): + try: + # Create veth pair [veth1, veth2]. + # CNDP port will use veth2 as configured in cndpfwd_veth.bess and conf/cndp/fwd_veth.jsonc. + create_veth() + # Create CNDP BESS port. + veth_port = CndpPort(jsonc_file='bessctl/conf/cndp/fwd_veth.jsonc', lport_index=0) + PortInc(port=veth_port) -> MACSwap() -> PortOut(port=veth_port) + except: + delete_veth() + assert False + + # Send packets to veth2. This will be received by veth1. + scapy.sendp(gen_packet(),iface="veth2", count=10) + + # Delete veth pair. + delete_veth() + + +suite = unittest.TestLoader().loadTestsFromTestCase(BessCndpTest) +results = unittest.TextTestRunner(verbosity=2).run(suite) + +if results.failures or results.errors: + sys.exit(1) diff --git a/core/Makefile b/core/Makefile index cff02334ac..e6d1ffc831 100644 --- a/core/Makefile +++ b/core/Makefile @@ -1,5 +1,6 @@ # Copyright (c) 2014-2017, The Regents of the University of California. # Copyright (c) 2016-2017, Nefeli Networks, Inc. +# Copyright (c) 2020-2022 Intel Corporation. # All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -30,6 +31,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. + # Disable all implicit Makefile rules MAKEFLAGS += --no-builtin-rules .SUFFIXES: ; @@ -69,7 +71,7 @@ ALWAYS_DYN_LIBS := -lpthread -ldl # These libraries are not supported by pkg-config. ALWAYS_LIBS := -lpcap -lgflags -lnuma # If pkg-config is available, we just need a list of the dependecies. -PKG_CONFIG_DEPS := libdpdk libglog protobuf grpc++ libunwind zlib +PKG_CONFIG_DEPS := libdpdk libglog protobuf grpc++ libunwind zlib libcndp # If pkg-config is not available, we need to list the libs we depend on. NO_PKG_CONFIG_LIBS := -lglog -lgflags -lprotobuf -lgrpc++ -lunwind -lz # If pkg-config is not available and we're static linking, we also need diff --git a/core/drivers/cndp.cc b/core/drivers/cndp.cc new file mode 100644 index 0000000000..1778b9915e --- /dev/null +++ b/core/drivers/cndp.cc @@ -0,0 +1,1059 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2021 Intel Corporation. + */ + +#include "cndp.h" +#include // std::min +#include // for strlcpy +#include // for MEMPOOL_CACHE_MAX_SIZE, __cne_unused +#include // for lport_cfg +#include // for mmap_addr, mmap_alloc, mmap_size, mmap_t +#include // for cne_device_socket_id +#include // std::filesystem::exists +#include // std::ifstream +#include // for getopt_long, option +#include // for logging +#include // for jcfg_obj_t, jcfg_umem_t, jcfg_opt_t +#include // for jcfg_process +#include // for cndp metrics +#include // netdev_get_mac_addr +#include // mac_addr +#include // for pktdev_rx_burst, pktdev_tx_burst +#include // for pktdev_buf_alloc, pktdev_close, pktdev_port_setup +#include // for pktmbuf_pool_create, pktmbuf_info_t +#include // for PMD_NET_AF_XDP_NAME +#include // rte_mbuf +#include // for NULL, printf, EOF +#include // for free, calloc +#include // for strcmp +#include // for strcasecmp +#include // std::thread::id +#include // usleep + +CommandResponse CndpPort::Init(const bess::pb::CndpPortArg &arg) { + jsonc_file_ = arg.jsonc_file(); + LOG(INFO) << "CNDP parse jsonc file = " << jsonc_file_; + if (!std::filesystem::exists(jsonc_file_)) { + LOG(ERROR) << "jsonc file doesn't exist"; + return CommandFailure(EINVAL, "jsonc file doesn't exist"); + } + + // Register this thread with CNDP if required. + if (CndpSingleton::CndpRegisterThread("Init") < 0) { + const char *err_msg = "Register thread with CNDP failed"; + LOG(ERROR) << err_msg; + return CommandFailure(EINVAL, "%s", err_msg); + } + + // Get/Create CNDP instance. + cndp_instance_ = &CndpSingleton::GetInstance(jsonc_file_); + if (!cndp_instance_->IsConfigured()) { + std::string err = "CNDP configuration failed for jsonc file: " + + std::filesystem::canonical(jsonc_file_).string(); + const char *err_msg = err.c_str(); + LOG(ERROR) << err_msg; + return CommandFailure(EINVAL, "%s", err_msg); + } + + // Check if lports are present. + int num_lports = cndp_instance_->GetNumLports(); + if (num_lports <= 0) { + const char *err_msg = "No lports found in jsonc file"; + LOG(ERROR) << err_msg; + return CommandFailure(EINVAL, "%s", err_msg); + } + + // Validate lport index. + lport_index_ = arg.lport_index(); + if (lport_index_ >= (uint32_t)num_lports) { + const char *err_msg = "Invalid lport index"; + LOG(ERROR) << err_msg << " lport index = " << lport_index_; + LOG(WARNING) << "lport index should be >=0 and <" << num_lports; + return CommandFailure(EINVAL, "%s", err_msg); + } + LOG(INFO) << "CNDP lport index = " << lport_index_; + + // Get lport instance. + lport_ = cndp_instance_->GetLportFromIndex(lport_index_); + if (lport_ == nullptr) { + const char *err_msg = "CNDP jcfg lport is null"; + LOG(ERROR) << err_msg; + return CommandFailure(EINVAL, "%s", err_msg); + } + + // Get fwd port from lport. + lport_fport_ = cndp_instance_->GetFwdPort(lport_); + if (lport_fport_ == nullptr) { + const char *err_msg = "CNDP fwd port is null"; + LOG(ERROR) << err_msg; + return CommandFailure(EINVAL, "%s", err_msg); + } + + if (lport_fport_->pkt_api == PKTDEV_PKT_API) { + // Reset pkt_recv_vector_ + pkt_recv_vector_.fill(nullptr); + } + + // Reset stats. + CndpStats(true); + + // Get mac address for this lport. + struct ether_addr mac_addr; + if (lport_fport_->pkt_api == XSKDEV_PKT_API) { + netdev_get_mac_addr(lport_fport_->xsk->ifname, &mac_addr); + } else { + pktdev_macaddr_get(lport_fport_->lport, &mac_addr); + } + + // Fill mac address of netdev in Bess port conf_. + memcpy(conf_.mac_addr.bytes, mac_addr.ether_addr_octet, + sizeof(mac_addr.ether_addr_octet)); + + // Get CPU socket id. + if (lport_fport_->pkt_api == XSKDEV_PKT_API) { + lport_socket_id_ = CndpSingleton::GetSocketId(lport_fport_->xsk->ifname); + } else { + // Get CPU socket id for this lport. + lport_socket_id_ = cndp_instance_->GetSocketId(lport_fport_->lport); + } + if (lport_socket_id_ < 0) { + LOG(WARNING) << "Unable to get a valid CPU socket id. Using 0 by default"; + lport_socket_id_ = 0; + } + + return CommandSuccess(); +} + +void CndpPort::DeInit() { + LOG(INFO) << "Called CndpPort::DeInit()"; + + if (cndp_instance_ != nullptr) { + cndp_instance_->Quit(); + cndp_instance_ = nullptr; + } +} + +placement_constraint CndpPort::GetNodePlacementConstraint() const { + return (placement_constraint)(1ull << lport_socket_id_); +} + +bool CndpPort::ReplenishRecvVector(int cnt) { + DCHECK_LE(cnt, bess::PacketBatch::kMaxBurst); + bool allocated = + current_worker.packet_pool()->AllocBulk(pkt_recv_vector_.data(), cnt); + if (!allocated) { + LOG(ERROR) << "packet_pool() allocation failed"; + } + return allocated; +} + +void CndpPort::FreeRecvVector() { + for (auto *pkt : pkt_recv_vector_) { + bess::Packet::Free(pkt); + } +} + +int CndpPort::RecvPackets(queue_t qid __cne_unused, bess::Packet **pkts, + int cnt) { + // Register this thread with CNDP if required. + if (CndpSingleton::CndpRegisterThread("CndpRecvPackets") < 0) { + LOG(ERROR) << "Register thread with CNDP failed"; + return 0; + } + + // Read cnt packets from lport. + fwd_port *fport = lport_fport_; + if (fport == nullptr) { + LOG(ERROR) << "fwd port is NULL. Can't read packets from lport"; + return 0; + } + + if (cnt <= 0 || pkts == nullptr) { + return 0; + } + + uint16_t num_pkts_read = 0; + if (fport->pkt_api == XSKDEV_PKT_API) { + num_pkts_read = XskdevRecvPackets(fport, pkts, cnt); + } else { + num_pkts_read = PktdevRecvPackets(fport, pkts, cnt); + } + + return num_pkts_read; +} + +int CndpPort::SendPackets(queue_t qid __cne_unused, bess::Packet **pkts, + int cnt) { + // Register this thread with CNDP if required. + if (CndpSingleton::CndpRegisterThread("CndpSendPackets") < 0) { + LOG(ERROR) << "Register thread with CNDP failed"; + return 0; + } + + fwd_port *fport = lport_fport_; + if (fport == nullptr) { + LOG(ERROR) << "fwd port is NULL. Can't send packets from lport"; + return 0; + } + + if (cnt <= 0 || pkts == nullptr) { + return 0; + } + + // Send pkts. + int sent = 0; + if (fport->pkt_api == XSKDEV_PKT_API) { + sent = XskdevSendPackets(fport, pkts, cnt); + } else { + sent = PktdevSendPackets(fport, pkts, cnt); + } + + return sent; +} + +uint16_t CndpPort::XskdevRecvPackets(struct fwd_port *fport, + bess::Packet **pkts, int cnt) { + return xskdev_rx_burst(fport->xsk, (void **)pkts, cnt); +} + +uint16_t CndpPort::PktdevRecvPackets(struct fwd_port *fport, + bess::Packet **pkts, int cnt) { + pktmbuf_t **mbufs = &fport->mbufs[0]; + uint16_t num_pkts_read = pktdev_rx_burst(fport->lport, mbufs, cnt); + + if (num_pkts_read == 0) { + // No packets read. + return 0; + } + + bool ret = ReplenishRecvVector(num_pkts_read); + if (!ret) { + pktmbuf_free_bulk(mbufs, num_pkts_read); + LOG(ERROR) << "Allocation of vector failed"; + return 0; + } + + for (uint16_t i = 0; i < num_pkts_read; i++) { + pktmbuf_t *pkt_mbuf = fport->mbufs[i]; + if ((pkt_mbuf == nullptr) || (pkt_mbuf->data_len == 0)) { + pktmbuf_free_bulk(mbufs, num_pkts_read); + FreeRecvVector(); + LOG(ERROR) << "pkt_mbuf is either NULL of of zero length"; + return 0; + } + + bess::Packet *pkt = pkt_recv_vector_[i]; + void *pktmbuf_data = pktmbuf_mtod(pkt_mbuf, void *); + int copy_len = std::min(pkt_mbuf->data_len, pkt->tailroom()); + bess::utils::CopyInlined(pkt->append(copy_len), pktmbuf_data, copy_len, + true); + pkts[i] = pkt; + } + // Free mbufs. + pktmbuf_free_bulk(mbufs, num_pkts_read); + + return num_pkts_read; +} + +uint16_t CndpPort::XskdevSendPackets(struct fwd_port *fport, + bess::Packet **pkts, int cnt) { + struct rte_mbuf *mbuf = (struct rte_mbuf *)(pkts[0]); + bool same_pool = (mbuf->pool->pool_id == fport->bess_pool->pool()->pool_id); + if (same_pool) { + // Packets belong to same memory pool. + return xskdev_tx_burst(fport->xsk, (void **)pkts, cnt); + } else { + LOG_FIRST_N(INFO, 1) << "Packets belong to different mempools"; + bess::Packet *alloc_pkts[CNDP_MAX_BURST]; + uint16_t n_pkts = fport->xsk->buf_mgmt.buf_alloc( + fport, (void **)alloc_pkts, + ((cnt < CNDP_MAX_BURST) ? cnt : CNDP_MAX_BURST)); + + if (n_pkts == 0) { + LOG_FIRST_N(WARNING, 10) << "Cannot allocate any buffers to send packets"; + return 0; + } + + if (n_pkts < cnt) { + LOG_FIRST_N(WARNING, 10) + << "Cannot allocate enough buffers to send all packets" + << " Requested=" << cnt << ", Allocated=" << n_pkts; + } + // Copy packets across mempools. + for (uint16_t i = 0; i < n_pkts; i++) { + bess::utils::CopyInlined(alloc_pkts[i]->append(pkts[i]->total_len()), + pkts[i]->head_data(), pkts[i]->total_len(), + true); + } + + uint16_t sent = xskdev_tx_burst(fport->xsk, (void **)alloc_pkts, n_pkts); + if (sent < n_pkts) { + LOG_FIRST_N(WARNING, 10) << "Free packets which are not sent" + << " Requested=" << n_pkts << ", Sent=" << sent; + // Free allocated packets which are not sent. + fport->xsk->buf_mgmt.buf_free(fport, (void **)(alloc_pkts + sent), + n_pkts - sent); + } + // Free BESS packets which are sent. + bess::Packet::Free(pkts, sent); + return sent; + } + + return 0; +} + +uint16_t CndpPort::PktdevSendPackets(struct fwd_port *fport, + bess::Packet **pkts, int cnt) { + pktmbuf_t **mbufs = &fport->mbufs[0]; + uint16_t n_pkts = pktdev_buf_alloc(fport->lport, mbufs, cnt); + + if (n_pkts == 0) { + LOG_FIRST_N(WARNING, 10) << "Cannot allocate any buffers to send packets"; + return 0; + } + + if (n_pkts < cnt) { + LOG_FIRST_N(WARNING, 10) + << "Cannot allocate enough buffers to send all packets" + << " Requested=" << cnt << ", Allocated=" << n_pkts; + } + + for (uint16_t i = 0; i < n_pkts; i++) { + pktmbuf_t *pkt_mbuf = fport->mbufs[i]; + bess::Packet *pkt = pkts[i]; + void *pktmbuf_data = pktmbuf_mtod(pkt_mbuf, void *); + bess::utils::CopyInlined(pktmbuf_data, pkt->head_data(), + pkt->data_len(), true); + pkt_mbuf->data_len = pkt->data_len(); + } + + // Send pkts. + uint16_t sent = pktdev_tx_burst(fport->lport, mbufs, n_pkts); + if (sent < n_pkts) { + LOG_FIRST_N(WARNING, 10) << "Free packets which are not sent" + << " Requested=" << n_pkts << ", Sent=" << sent; + // Free allocated CNDP pktmbufs which are not sent. + pktmbuf_free_bulk(mbufs + sent, n_pkts - sent); + } + + // Free packets which are sent. + bess::Packet::Free(pkts, sent); + + return sent; +} + +void CndpPort::CndpStats(bool reset) { + fwd_port *fport = lport_fport_; + if (fport) { + if (reset) { + LOG(INFO) << "Reset cndp stats"; + memset(&cndp_stats_, 0, sizeof(cndp_stats_)); + if (fport->pkt_api == XSKDEV_PKT_API) { + xskdev_stats_reset(fport->xsk); + } else { + pktdev_stats_reset(fport->lport); + } + + return; + } + if (fport->pkt_api == XSKDEV_PKT_API) { + xskdev_stats_get(fport->xsk, &cndp_stats_); + } else { + pktdev_stats_get(fport->lport, &cndp_stats_); + } + } + + // Log first two packets. + LOG_FIRST_N(INFO, 2) << "CndpStats:packets = " << cndp_stats_.ipackets; + LOG_FIRST_N(INFO, 2) << "CndpStats:bytes = " << cndp_stats_.ibytes; + LOG_FIRST_N(INFO, 2) << "CndpStats:dropped = " << cndp_stats_.imissed; +} + +void CndpPort::CollectStats(bool reset) { + if (reset) { + CndpStats(true); + return; + } + // Get CNDP port stats. + CndpStats(false); + + // Update BESS CNDP port stats. + port_stats_.inc.packets = cndp_stats_.ipackets; + port_stats_.inc.bytes = cndp_stats_.ibytes; + port_stats_.inc.dropped = cndp_stats_.imissed; + port_stats_.out.packets = cndp_stats_.opackets; + port_stats_.out.bytes = cndp_stats_.obytes; + port_stats_.out.dropped = cndp_stats_.odropped; + + // There is no BESS queue stats for CNDP lport. + packet_dir_t dir; + queue_t qid; + dir = PACKET_DIR_INC; + for (qid = 0; qid < num_queues[dir]; qid++) { + queue_stats[dir][qid].packets = 0; + queue_stats[dir][qid].bytes = 0; + queue_stats[dir][qid].dropped = 0; + } + + dir = PACKET_DIR_OUT; + for (qid = 0; qid < num_queues[dir]; qid++) { + queue_stats[dir][qid].packets = 0; + queue_stats[dir][qid].bytes = 0; + queue_stats[dir][qid].dropped = 0; + } +} + +// CNDP memory pool. +CndpPacketPoolMap CndpSingleton::cndp_packet_pool_; + +// CndpSingleton public member functions. +CndpSingleton &CndpSingleton::GetInstance(const std::string &jsonc_file) { + // Cndp instance will be lazy initialized. + static CndpSingleton instance(jsonc_file); + // Reconfigure CNDP if JSONC file has changed. + if (instance.jsonc_file_ != jsonc_file) { + LOG(INFO) << "Jsonc file changed. Reconfigure CNDP"; + memset(&(instance.fwd_), 0, sizeof(instance.fwd_)); + if (instance.ParseFile(jsonc_file.c_str(), &instance.fwd_) < 0) { + LOG(ERROR) << "CNDP parse jsonc failed"; + instance.configured_ = false; + return instance; + } + instance.configured_ = true; + instance.jsonc_file_ = jsonc_file; + } + return instance; +} + +void CndpSingleton::Quit() { + // If CNDP is not configured return. + if (!configured_) { + return; + } + // Register this thread with CNDP if required. + if (CndpSingleton::CndpRegisterThread("CndpQuit") < 0) { + LOG(ERROR) << "Register thread with CNDP failed"; + return; + } + if (jcfg_thread_foreach(fwd_.jinfo, CndpSingleton::CndpQuit, &fwd_) < 0) { + LOG(WARNING) << "Error while quitting CNDP"; + } + // Reset jsonc fle; + jsonc_file_ = ""; + configured_ = false; + LOG(INFO) << "CNDP Quitted"; +} + +bool CndpSingleton::IsConfigured() { + return configured_; +} + +jcfg_lport_t *CndpSingleton::GetLportFromIndex(int index) { + return jcfg_lport_by_index(fwd_.jinfo, index); +} + +int CndpSingleton::GetNumLports() { + return jcfg_num_lports(fwd_.jinfo); +} + +int CndpSingleton::CndpRegisterThread(const std::string ®ister_name) { + if (!cne_check_registration()) { + return cne_register(register_name.c_str()); + } else { + return cne_id(); + } +} + +fwd_port *CndpSingleton::GetFwdPort(const jcfg_lport_t *lport) { + fwd_port *fport = nullptr; + if (lport) { + if (lport->priv_) { + fport = (fwd_port *)lport->priv_; + } + } + return fport; +} + +int CndpSingleton::GetSocketId(char *ifname) { + return cne_device_socket_id(ifname); +} + +int CndpSingleton::GetSocketId(uint32_t lport_id) { + return pktdev_socket_id(lport_id); +} + +bess::PacketPool *CndpSingleton::GetCndpPacketPool(std::string umem_name, + int socket_id) { + CndpPacketPoolMap::iterator pos = cndp_packet_pool_.find(umem_name); + if (pos == cndp_packet_pool_.end()) { + return nullptr; + } else { + if (pos->second && (socket_id >= 0) && (socket_id < RTE_MAX_NUMA_NODES)) { + CndpPacketPoolArray arr = *(pos->second); + return arr[socket_id]; + } else { + return nullptr; + } + } +} + +// CndpSingleton private member functions. +CndpSingleton::CndpSingleton(const std::string &jsonc_file) + : jsonc_file_(jsonc_file) { + configured_ = false; + memset(&fwd_, 0, sizeof(fwd_)); + if (cne_init() < 0) { + LOG(ERROR) << "CNDP initialization failed"; + return; + } + + // Parse JSONC file. + if (ParseFile(jsonc_file.c_str(), &fwd_) < 0) { + LOG(ERROR) << "CNDP parse jsonc failed"; + return; + } + configured_ = true; + LOG(INFO) << "CNDP instance created"; +} + +int CndpSingleton::ParseFile(const char *json_file, struct fwd_info *fwd) { + int flags = JCFG_PARSE_FILE; + fwd->jinfo = jcfg_parser(flags, (const char *)json_file); + if (fwd->jinfo == NULL) { + LOG(ERROR) << "*** Did not find any configuration to use ***"; + return -1; + } + + if (jcfg_process(fwd->jinfo, flags, JcfgProcessCallback, fwd)) { + LOG(ERROR) << "*** Invalid configuration ***"; + return -1; + } + + if (metrics_init(fwd)) { + LOG(ERROR) << "*** Failed to start metrics support ***"; + return -1; + } + + return 0; +} + +pkt_api_t CndpSingleton::GetPktApi(const char *type) { + if (type) { + size_t nlen = strnlen(type, MAX_STRLEN_SIZE); + + if (!strncasecmp(type, XSKDEV_API_NAME, nlen)) + return XSKDEV_PKT_API; + else if (!strncasecmp(type, PKTDEV_API_NAME, nlen)) + return PKTDEV_PKT_API; + } + + return UNKNOWN_PKT_API; +} + +bool CndpSingleton::CreatePktmbufPool(jcfg_umem_t *umem, jcfg_info_t *j) { + uint32_t cache_sz; + char *umem_addr; + + /* The UMEM object describes the total size of the UMEM space */ + umem->mm = mmap_alloc(umem->bufcnt, umem->bufsz, (mmap_type_t)umem->mtype); + if (umem->mm == NULL) + LOG(ERROR) << " Failed to allocate mmap memory of size:" + << umem->bufcnt * umem->bufsz; + + if (jcfg_default_get_u32(j, "cache", &cache_sz)) + cache_sz = MEMPOOL_CACHE_MAX_SIZE; + + umem_addr = (char *)mmap_addr(umem->mm); + + /* Create the pktmbuf pool for each region defined */ + for (int i = 0; i < umem->region_cnt; i++) { + pktmbuf_info_t *pi; + region_info_t *ri = &umem->rinfo[i]; + char name[PKTMBUF_INFO_NAME_SZ] = {0}; + + /* Find the starting memory address in UMEM for the pktmbuf_t buffers */ + ri->addr = umem_addr; + umem_addr += (ri->bufcnt * umem->bufsz); + + /* Initialize a pktmbuf_info_t structure for each region in the UMEM space + */ + pi = pktmbuf_pool_create(ri->addr, ri->bufcnt, umem->bufsz, cache_sz, NULL); + if (!pi) { + mmap_free(umem->mm); + LOG(ERROR) << "pktmbuf_pool_init() failed for region: " << i; + return false; + } + snprintf(name, sizeof(name), "%s-%d", umem->name, i); + pktmbuf_info_name_set(pi, name); + + ri->pool = pi; + } + + return true; +} + +bool CndpSingleton::CreateCndpPacketPool(std::string umem_name, + size_t capacity) { + CndpPacketPoolArray *arr = new CndpPacketPoolArray(); + if (arr == nullptr) { + LOG(ERROR) << "Error creating Cndp Packet Pool"; + return false; + } + for (int sid = 0; sid < bess::NumNumaNodes(); sid++) { + bess::PacketPool *pool = new bess::DpdkPacketPool(capacity, sid); + if (pool == nullptr) { + LOG(ERROR) << "Error creating Cndp Packet Pool from Dpdk Packet pool"; + return false; + } + (*arr)[sid] = pool; + } + cndp_packet_pool_.emplace(umem_name, arr); + return true; +} + +uintptr_t CndpSingleton::GetUmemBaseAddr(struct rte_mempool *mp) { + struct rte_mempool_memhdr *memhdr; + memhdr = STAILQ_FIRST(&mp->mem_list); + if (memhdr == nullptr) { + return (uintptr_t) nullptr; + } + return (uintptr_t)memhdr->addr; +} + +uintptr_t CndpSingleton::GetPageAlignedAddr(uintptr_t mem_addr, + uint64_t *align) { + uintptr_t aligned_addr = mem_addr & ~(getpagesize() - 1); + if (align != nullptr) { + *align = mem_addr - aligned_addr; + } + + return aligned_addr; +} + +int CndpSingleton::JcfgProcessCallback(jcfg_info_t *j, void *_obj, void *arg, + int idx __cne_unused) { + jcfg_obj_t obj; + struct fwd_info *f = (struct fwd_info *)arg; + size_t nlen; + + if (!_obj) + return -1; + + obj.hdr = (jcfg_hdr_t *)_obj; + + nlen = strnlen(obj.opt->name, MAX_STRLEN_SIZE); + + switch (obj.hdr->cbtype) { + case JCFG_APPLICATION_TYPE: + break; + + case JCFG_DEFAULT_TYPE: + break; + + case JCFG_OPTION_TYPE: + if (!strncmp(obj.opt->name, PKT_API_TAG, nlen)) { + if (obj.opt->val.type == STRING_OPT_TYPE) { + f->opts.pkt_api = obj.opt->val.str; + if (f->pkt_api == UNKNOWN_PKT_API) + f->pkt_api = CndpSingleton::GetPktApi(f->opts.pkt_api); + } + } else if (!strcmp(obj.opt->name, NO_METRICS_TAG)) { + if (obj.opt->val.type == BOOLEAN_OPT_TYPE) + f->opts.no_metrics = obj.opt->val.boolean; + } else if (!strcmp(obj.opt->name, NO_RESTAPI_TAG)) { + if (obj.opt->val.type == BOOLEAN_OPT_TYPE) + f->opts.no_restapi = obj.opt->val.boolean; + } else if (!strcmp(obj.opt->name, ENABLE_CLI_TAG)) { + if (obj.opt->val.type == BOOLEAN_OPT_TYPE) + f->opts.cli = obj.opt->val.boolean; + } else if (!strcmp(obj.opt->name, MODE_TAG)) { + if (obj.opt->val.type == STRING_OPT_TYPE) { + f->opts.mode = obj.opt->val.str; + } + } else if (!strncmp(obj.opt->name, UDS_PATH_TAG, nlen)) { + if (obj.opt->val.type == STRING_OPT_TYPE) { + f->xdp_uds = udsc_handshake(obj.opt->val.str); + if (f->xdp_uds == NULL) { + LOG(ERROR) << "CNDP uds handshake failed"; + return -1; + } + } + } + break; + + case JCFG_UMEM_TYPE: { + if (f->pkt_api == XSKDEV_PKT_API) { + LOG(INFO) << "Create UMEM of size = " << obj.umem->bufcnt; + // Create CNDP Memory Pool. + bool ret = + CreateCndpPacketPool(std::string(obj.umem->name), obj.umem->bufcnt); + if (!ret) { + LOG(ERROR) << "CNDP Mempool creation failed"; + return -1; + } + } else { + bool ret = CreatePktmbufPool(obj.umem, j); + if (!ret) { + LOG(ERROR) << "Pktmbuf creation failed"; + return -1; + } + } + break; + } + case JCFG_LPORT_TYPE: + do { + jcfg_lport_t *lport = obj.lport; + struct fwd_port *pd; + jcfg_umem_t *umem; + + if (lport == nullptr) { + LOG(ERROR) << "lport is NULL"; + return -1; + } + + umem = lport->umem; + if (umem == nullptr) { + LOG(ERROR) << "UMEM is NULL for this lport id: " << lport->lpid; + return -1; + } + + pd = (struct fwd_port *)calloc(1, sizeof(struct fwd_port)); + if (!pd) { + LOG(ERROR) << "Unable to allocate fwd_port structure"; + return -1; + } + pd->pkt_api = f->pkt_api; + lport->priv_ = pd; + + int ret = 0; + // Create XSKDEV Socket. + if (f->pkt_api == XSKDEV_PKT_API) { + ret = CndpSingleton::CreateXskdevSocket(umem, lport, pd, f); + } else { + ret = CndpSingleton::CreatePktdevSocket(umem, lport, pd, f); + } + if (ret < 0) { + LOG(ERROR) << "AF_XDP socket creation failed"; + return -1; + } + } while ((0)); + break; + + case JCFG_LGROUP_TYPE: + break; + + case JCFG_THREAD_TYPE: + break; + default: + return -1; + } + return 0; +} + +int CndpSingleton::CreateXskdevSocket(jcfg_umem_t *umem, jcfg_lport_t *lport, + struct fwd_port *pd, struct fwd_info *f) { + struct lport_cfg pcfg; + memset(&pcfg, 0, sizeof(pcfg)); + + // Get BESS memory pool. + int socket_id = CndpSingleton::GetSocketId(lport->netdev); + if (socket_id < 0) { + LOG(WARNING) << "Unable to get a valid CPU socket id. Using 0 by default"; + socket_id = 0; + } + bess::PacketPool *bess_pool = + CndpSingleton::GetCndpPacketPool(lport->umem_name, socket_id); + if (bess_pool == nullptr) { + LOG(ERROR) << "Couldn't get CNDP MemPool for umem:" << lport->umem_name; + return -1; + } + pd->bess_pool = bess_pool; + rte_mempool *mp = bess_pool->pool(); + if (mp == nullptr) { + LOG(ERROR) << "rte_mempool pointer is NULL"; + return -1; + } + LOG(INFO) << "bess rte_mempool name = " << mp->name + << ", rte_mempool addr = " << mp + << ", rte_mempool id = " << mp->pool_id; + + // UMEM base and aligned base address. + void *mp_umem_addr_base = (void *)(CndpSingleton::GetUmemBaseAddr(mp)); + if (mp_umem_addr_base == nullptr) { + LOG(ERROR) << "UMEM base addr is NULL"; + return -1; + } + uint64_t align = 0; + void *mp_umem_addr_base_align = (void *)CndpSingleton::GetPageAlignedAddr( + (uintptr_t)mp_umem_addr_base, &align); + + // Framesize in UMEM. + uint32_t umem_framesize = + rte_mempool_calc_obj_size(mp->elt_size, mp->flags, NULL); + + // UMEM length. + size_t mp_umem_len = + (uint64_t)mp->populated_size * (uint64_t)umem_framesize + align; + + // Calculate buffer headroom. + size_t buf_headroom = + mp->header_size + sizeof(struct rte_mbuf) + rte_pktmbuf_priv_size(mp); + + DLOG(INFO) << "RTE memzone Umem addr = " << mp_umem_addr_base_align; + DLOG(INFO) << "RTE memzone Umem len = " << mp_umem_len; + DLOG(INFO) << "Populated Size = " << mp->populated_size; + DLOG(INFO) << "Align = " << align; + DLOG(INFO) << "RTE memzone hugepaze sz = " << mp->mz->hugepage_sz; + DLOG(INFO) << "RTE memzone socket id = " << mp->mz->socket_id; + DLOG(INFO) << "Element size = " << mp->elt_size; + DLOG(INFO) << "header size = " << mp->header_size; + DLOG(INFO) << "trailer size = " << mp->trailer_size; + DLOG(INFO) << "Frame size = " << umem_framesize; + DLOG(INFO) << "buf_headroom = " << buf_headroom; + DLOG(INFO) << "Packet size = " << sizeof(bess::Packet); + DLOG(INFO) << "rte_mbuf size = " << sizeof(rte_mbuf); + DLOG(INFO) << "rte_mbuf private size = " << rte_pktmbuf_priv_size(mp); + DLOG(INFO) << "Num memory chunks = " << mp->nb_mem_chunks; + DLOG(INFO) << "Mempool max Size = " << mp->size; + DLOG(INFO) << "BESS packet pool size " << bess_pool->Size(); + DLOG(INFO) << "BESS packet pool capacity " << bess_pool->Capacity(); + + pcfg.qid = lport->qid; + pcfg.bufsz = umem_framesize; + pcfg.rx_nb_desc = XSK_RING_PROD__DEFAULT_NUM_DESCS; + pcfg.tx_nb_desc = XSK_RING_CONS__DEFAULT_NUM_DESCS; + pcfg.pmd_opts = lport->pmd_opts; + pcfg.umem_addr = (char *)mp_umem_addr_base_align; + pcfg.umem_size = mp_umem_len; + pcfg.busy_timeout = lport->busy_timeout; + pcfg.busy_budget = lport->busy_budget; + pcfg.flags = lport->flags; + pcfg.flags |= LPORT_USER_MANAGED_BUFFERS; + pcfg.flags |= LPORT_UMEM_UNALIGNED_BUFFERS; + pcfg.flags |= (umem->shared_umem == 1) ? LPORT_SHARED_UMEM : 0; + pcfg.addr = (void *)mp_umem_addr_base_align; + pcfg.bufcnt = mp->populated_size; + if (!pcfg.addr) { + free(pd); + LOG(ERROR) << "fwd_port freed"; + return -1; + } + if (lport->flags & LPORT_UNPRIVILEGED) { + if (f->xdp_uds) + pcfg.xsk_uds = f->xdp_uds; + else { + LOG(ERROR) << "UDS info struct is null"; + return -1; + } + } + + /* Setup the mempool configuration */ + strlcpy(pcfg.pmd_name, lport->pmd_name, sizeof(pcfg.pmd_name)); + strlcpy(pcfg.ifname, lport->netdev, sizeof(pcfg.ifname)); + strlcpy(pcfg.name, lport->name, sizeof(pcfg.name)); + + pcfg.buf_mgmt.buf_arg = (void *)pd; + pcfg.buf_mgmt.buf_alloc = CndpSingleton::CndpBufAlloc; + pcfg.buf_mgmt.buf_free = CndpSingleton::CndpBufFree; + pcfg.buf_mgmt.buf_set_len = CndpSingleton::CndpBufSetLen; + pcfg.buf_mgmt.buf_set_data_len = CndpSingleton::CndpBufSetDataLen; + pcfg.buf_mgmt.buf_set_data = CndpSingleton::CndpBufSetData; + pcfg.buf_mgmt.buf_get_data_len = CndpSingleton::CndpBufGetDataLen; + pcfg.buf_mgmt.buf_get_data = CndpSingleton::CndpBufGetData; + pcfg.buf_mgmt.buf_get_addr = CndpSingleton::CndpBufGetAddr; + pcfg.buf_mgmt.buf_inc_ptr = CndpSingleton::CndpBufIncPtr; + pcfg.buf_mgmt.buf_reset = CndpSingleton::CndpBufReset; + pcfg.buf_mgmt.buf_headroom = buf_headroom; + pcfg.buf_mgmt.frame_size = pcfg.bufsz; + pcfg.buf_mgmt.pool_header_sz = mp->header_size; + + pd->xsk = xskdev_socket_create(&pcfg); + if (pd->xsk == NULL) { + free(pd); + LOG(ERROR) << "xskdev_port_setup() failed"; + return -1; + } + + return 0; +} + +int CndpSingleton::CreatePktdevSocket(jcfg_umem_t *umem, jcfg_lport_t *lport, + struct fwd_port *pd, struct fwd_info *f) { + struct lport_cfg pcfg; + memset(&pcfg, 0, sizeof(pcfg)); + + pcfg.qid = lport->qid; + pcfg.bufsz = umem->bufsz; + pcfg.rx_nb_desc = umem->rxdesc; + pcfg.tx_nb_desc = umem->txdesc; + pcfg.umem_addr = (char *)mmap_addr(umem->mm); + pcfg.umem_size = mmap_size(umem->mm, NULL, NULL); + pcfg.pmd_opts = lport->pmd_opts; + pcfg.busy_timeout = lport->busy_timeout; + pcfg.busy_budget = lport->busy_budget; + pcfg.flags = lport->flags; + pcfg.flags |= (umem->shared_umem == 1) ? LPORT_SHARED_UMEM : 0; + + pcfg.addr = jcfg_lport_region(lport, &pcfg.bufcnt); + if (!pcfg.addr) { + free(pd); + return -1; + } + pcfg.pi = umem->rinfo[lport->region_idx].pool; + if (lport->flags & LPORT_UNPRIVILEGED) { + if (f->xdp_uds) + pcfg.xsk_uds = f->xdp_uds; + else + LOG(ERROR) << "UDS info struct is null"; + } + /* Setup the mempool configuration */ + strlcpy(pcfg.pmd_name, lport->pmd_name, sizeof(pcfg.pmd_name)); + strlcpy(pcfg.ifname, lport->netdev, sizeof(pcfg.ifname)); + strlcpy(pcfg.name, lport->name, sizeof(pcfg.name)); + + pd->lport = pktdev_port_setup(&pcfg); + if (pd->lport < 0) { + free(pd); + return -1; + } + + return 0; +} + +#define foreach_thd_lport(_t, _lp) \ + for (int _i = 0; _i < _t->lport_cnt && (_lp = _t->lports[_i]); \ + _i++, _lp = _t->lports[_i]) + +int CndpSingleton::CndpQuit(jcfg_info_t *j __cne_unused, void *obj, void *arg, + int idx __cne_unused) { + jcfg_thd_t *thd = (jcfg_thd_t *)obj; + jcfg_lport_t *lport; + struct fwd_info *fwd = (struct fwd_info *)arg; + + thd->quit = 1; + + if (thd->lport_cnt == 0) { + LOG(INFO) << "No lports attached to thread " << thd->name; + return 0; + } else + LOG(INFO) << "Close " << thd->lport_cnt << " lports attached to thread " + << thd->name; + + foreach_thd_lport(thd, lport) { + struct fwd_port *pd = (struct fwd_port *)lport->priv_; + LOG(INFO) << "lport " << lport->lpid << " - " << lport->name; + + if (fwd->pkt_api == XSKDEV_PKT_API) { + xskdev_socket_destroy(pd->xsk); + } else { + int ret = pktdev_close(pd->lport); + if (ret < 0) { + LOG(ERROR) << "port_close() returned error"; + return ret; + } + + if (lport->umem) { + int i; + + for (i = 0; i < lport->umem->region_cnt; i++) { + pktmbuf_destroy(lport->umem->rinfo[i].pool); + lport->umem->rinfo[i].pool = NULL; + } + mmap_free(lport->umem->mm); + lport->umem->mm = NULL; /* Make sure we do not free this again */ + } + } + } + // Destroy metrics. + metrics_destroy(); + + fwd->quit = 1; + return 0; +} + +int CndpSingleton::CndpBufAlloc(void *arg, void **bufs, uint16_t nb_bufs) { + struct fwd_port *pd = (struct fwd_port *)arg; + bess::PacketPool *bess_pool = pd->bess_pool; + if (bess_pool == nullptr) { + return 0; + } + bool ret = bess_pool->AllocBulk((bess::Packet **)bufs, nb_bufs); + if (ret) { + return nb_bufs; + } + return 0; +} + +void CndpSingleton::CndpBufFree(void *arg __cne_unused, void **bufs, + uint16_t nb_bufs) { + bess::Packet **pkts = (bess::Packet **)bufs; + if (pkts != nullptr) { + for (int i = 0; i < nb_bufs; i++) { + bess::Packet::Free(pkts[i]); + } + } +} + +void CndpSingleton::CndpBufSetDataLen(void *mb, int len) { + rte_mbuf *mbuf = (rte_mbuf *)mb; + if (mbuf) { + mbuf->data_len = (uint16_t)len; + mbuf->pkt_len = (uint16_t)len; + } +} + +void CndpSingleton::CndpBufSetLen(void *mb, int len) { + rte_mbuf *mbuf = (rte_mbuf *)mb; + if (mbuf) { + mbuf->buf_len = (uint16_t)len; + } +} + +void CndpSingleton::CndpBufSetData(void *mb, uint64_t off) { + rte_mbuf *mbuf = (rte_mbuf *)mb; + if (mbuf) { + mbuf->data_off = (uint16_t)off; + } +} + +uint64_t CndpSingleton::CndpBufGetData(void *mb) { + rte_mbuf *mbuf = (rte_mbuf *)mb; + if (mbuf) { + uint64_t data = rte_pktmbuf_mtod(mbuf, uint64_t); + return data; + } + return 0; +} + +uint16_t CndpSingleton::CndpBufGetDataLen(void *mb) { + rte_mbuf *mbuf = (rte_mbuf *)mb; + if (mbuf) { + return mbuf->data_len; + } + return 0; +} + +uint64_t CndpSingleton::CndpBufGetAddr(void *mb) { + rte_mbuf *mbuf = (rte_mbuf *)mb; + return (uint64_t)(mbuf); +} + +void **CndpSingleton::CndpBufIncPtr(void **mbs) { + rte_mbuf **mbufs = (rte_mbuf **)mbs; + if (mbufs) { + return (void **)++mbufs; + } + return nullptr; +} + +void CndpSingleton::CndpBufReset(void *mb, uint32_t buf_len, size_t headroom) { + rte_mbuf *mbuf = reinterpret_cast(mb); + if (mbuf) { + mbuf->buf_len = (uint16_t)buf_len; + mbuf->data_off = (uint16_t)headroom; + mbuf->data_len = 0; + } +} + +ADD_DRIVER(CndpPort, "cndp_port", + "CNDP driver to send/recv n/w packets using AF_XDP socket") diff --git a/core/drivers/cndp.h b/core/drivers/cndp.h new file mode 100644 index 0000000000..3de78e2634 --- /dev/null +++ b/core/drivers/cndp.h @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2019-2021 Intel Corporation. + */ + +#ifndef BESS_DRIVERS_CNDP_H_ +#define BESS_DRIVERS_CNDP_H_ + +#include "../port.h" + +#include +#include +#include + +// CNDP headers. +#include // for __cne_unused +#include // for lport_stats_t +#include // for jcfg_lport_t, jcfg_info_t, jcfg_lport_foreach +#include // PacketPool +#include // for pktmbuf_t +#include // rte_mempool +#include // for uint64_t, uint32_t +#include // UDS utility functions +#include // for xskdev_info_t + +#define PKT_API_TAG "pkt_api" /**< Packet API json tag */ +#define NO_METRICS_TAG "no-metrics" /**< json tag for no-metrics */ +#define NO_RESTAPI_TAG "no-restapi" /**< json tag for no-restapi */ +#define ENABLE_CLI_TAG "cli" /**< json tag to enable/disable CLI */ +#define MODE_TAG "mode" /**< json tag to set the mode flag */ +#define UDS_PATH_TAG "uds_path" /**< json tag to set the uds path */ +#define XSKDEV_API_NAME "xskdev" +#define PKTDEV_API_NAME "pktdev" + +#define MAX_STRLEN_SIZE 16 +#define CNDP_MAX_BURST 256 + +typedef enum { UNKNOWN_PKT_API, XSKDEV_PKT_API, PKTDEV_PKT_API } pkt_api_t; + +// Bess PacketPool +typedef std::array CndpPacketPoolArray; +typedef std::map CndpPacketPoolMap; + +// Forward declaration. +class CndpSingleton; +struct fwd_port; + +/// This driver binds a port to a device using CNDP/DPDK. +class CndpPort final : public Port { + public: + /*! + * Initialize the CNDP port. + * + * PARAMETERS: + * * string jsonc_file : CNDP Jsonc configuration file. + * * uint32 lport_index : CNDP lport in jsonc file used to send/recv n/w pkts. + * + * EXPECTS: + * * Must specify both jsonc_file and lport_index. + */ + CommandResponse Init(const bess::pb::CndpPortArg &arg); + + /*! + * Reset the port. + */ + void DeInit() override; + + /*! + * Sends packets out on the device. + * + * PARAMETERS: + * * queue_t quid : qid is configured via jsonc and this argument is ignored + * * for now. This value is expected to be zero. + * * bess::Packet ** pkts : packets to transmit. + * * int cnt : number of packets in pkts to transmit. + * + * EXPECTS: + * * Only call this after calling Init with a device. + * * Don't call this after calling DeInit(). + * + * RETURNS: + * * Total number of packets sent (<=cnt). + */ + int SendPackets(queue_t qid, bess::Packet **pkts, int cnt) override; + + /*! + * Receives packets from the device. + * + * PARAMETERS: + * * queue_t quid : qid is configured via jsonc and this argument is ignored + * * for now. This value is expected to be zero. + * * bess::Packet **pkts : buffer to store received packets in to. + * * int cnt : max number of packets to pull. + * + * EXPECTS: + * * Only call this after calling Init with a device. + * * Don't call this after calling DeInit(). + * + * RETURNS: + * * Total number of packets received (<=cnt) + */ + int RecvPackets(queue_t qid, bess::Packet **pkts, int cnt) override; + + /*! + * Copies CNDP port statistics into queue_stats datastructure (see port.h). + * + * PARAMETERS: + * * bool reset : if true, reset CNDP local statistics and return (do not + * collect stats). + */ + void CollectStats(bool reset) override; + + uint64_t GetFlags() const override { + return DRIVER_FLAG_SELF_INC_STATS | DRIVER_FLAG_SELF_OUT_STATS; + } + + /*! + * Get any placement constraints that need to be met when receiving from this + * port. + */ + placement_constraint GetNodePlacementConstraint() const override; + + private: + // CNDP singleton instance. + CndpSingleton *cndp_instance_; + + // jsonc file used for configuring CNDP. + std::string jsonc_file_; + + // CNDP lport index + uint32_t lport_index_; + + // CNDP lport. + jcfg_lport_t *lport_; + + // CNDP fwd port. + fwd_port *lport_fport_; + + // Bess Packet array. + std::array pkt_recv_vector_; + + // CNDP stats. + lport_stats_t cndp_stats_; + + // CPU socket id for this lport. + int lport_socket_id_; + + bool ReplenishRecvVector(int cnt); + void FreeRecvVector(); + void CndpStats(bool reset); + uint16_t XskdevRecvPackets(struct fwd_port *fport, bess::Packet **pkts, + int cnt); + uint16_t PktdevRecvPackets(struct fwd_port *fport, bess::Packet **pkts, + int cnt); + uint16_t PktdevSendPackets(struct fwd_port *fport, bess::Packet **pkts, + int cnt); + uint16_t XskdevSendPackets(struct fwd_port *fport, bess::Packet **pkts, + int cnt); +}; + +struct fwd_port { + union { + xskdev_info_t *xsk; /**< XSKDEV information pointer */ + int lport; /**< PKTDEV lport id */ + }; + union { + bess::PacketPool *bess_pool; /**< BESS pool pointer */ + pktmbuf_t *mbufs[CNDP_MAX_BURST]; /**< TX/RX mbufs array */ + }; + pkt_api_t pkt_api; /**< The packet API mode */ + uint64_t ipackets; /**< previous rx packets */ + uint64_t opackets; /**< previous tx packets */ + uint64_t ibytes; /**< previous rx bytes */ + uint64_t obytes; /**< previous tx bytes */ +}; + +class CndpSingleton { + public: + static CndpSingleton &GetInstance(const std::string &jsonc_file); + CndpSingleton(CndpSingleton const &) = delete; + void operator=(CndpSingleton const &) = delete; + void Quit(); + bool IsConfigured(); + jcfg_lport_t *GetLportFromIndex(int index); + int GetNumLports(); + static int CndpRegisterThread(const std::string ®ister_name); + fwd_port *GetFwdPort(const jcfg_lport_t *lport); + static int GetSocketId(char *ifname); + static int GetSocketId(uint32_t lport_id); + static bess::PacketPool *GetCndpPacketPool(std::string umem_name, + int socket_id); + + private: + std::string jsonc_file_; + bool configured_; + static CndpPacketPoolMap cndp_packet_pool_; + static const size_t kDefaultCapacity = (1 << 17) - 1; // 128k - 1 + + struct app_options { + bool no_metrics; /**< Enable metrics*/ + bool no_restapi; /**< Enable REST API*/ + bool cli; /**< Enable Cli*/ + char *mode; /**< Application mode*/ + char *pkt_api; /**< The pkt API mode */ + }; + + struct fwd_info { + jcfg_info_t *jinfo; /**< JSON-C configuration */ + uint32_t flags; /**< Application set of flags */ + volatile int quit; /**< flags to start and stop the application */ + struct app_options opts; /**< Application options*/ + pkt_api_t pkt_api; /**< The packet API mode */ + uds_info_t *xdp_uds; /**< UDS to get xsk map fd from */ + }; + + struct fwd_info fwd_; + + CndpSingleton(const std::string &jsonc_file); + int ParseFile(const char *json_file, struct fwd_info *fwd); + static pkt_api_t GetPktApi(const char *type); + static int CreateXskdevSocket(jcfg_umem_t *umem, jcfg_lport_t *lport, + struct fwd_port *pd, struct fwd_info *f); + static int CreatePktdevSocket(jcfg_umem_t *umem, jcfg_lport_t *lport, + struct fwd_port *pd, struct fwd_info *f); + static int JcfgProcessCallback(jcfg_info_t *j __cne_unused, void *_obj, + void *arg, int idx __cne_unused); + static int CndpQuit(jcfg_info_t *j __cne_unused, void *obj, void *arg, + int idx __cne_unused); + static uintptr_t GetUmemBaseAddr(struct rte_mempool *mp); + static uintptr_t GetPageAlignedAddr(uintptr_t mem_addr, uint64_t *align); + static int CndpBufAlloc(void *arg, void **bufs, uint16_t nb_bufs); + static void CndpBufFree(void *arg, void **bufs, uint16_t nb_bufs); + static void CndpBufSetDataLen(void *mb, int len); + static void CndpBufSetLen(void *mb, int len); + static void CndpBufSetData(void *mb, uint64_t off); + static uint64_t CndpBufGetData(void *mb); + static uint16_t CndpBufGetDataLen(void *mb); + static uint64_t CndpBufGetAddr(void *mb); + static void **CndpBufIncPtr(void **mbs); + static void CndpBufReset(void *mb, uint32_t buf_len, size_t headroom); + static bool CreateCndpPacketPool(std::string umem_name, + size_t capacity = kDefaultCapacity); + static bool CreatePktmbufPool(jcfg_umem_t *umem, jcfg_info_t *j); +}; + +#endif // BESS_DRIVERS_CNDP_H_ diff --git a/core/pktbatch.h b/core/pktbatch.h index 3340e13982..43bf51eacf 100644 --- a/core/pktbatch.h +++ b/core/pktbatch.h @@ -69,7 +69,7 @@ class PacketBatch { bess::utils::CopyInlined(pkts_, src->pkts_, cnt_ * sizeof(Packet *)); } - inline static const size_t kMaxBurst = 32; + inline static const size_t kMaxBurst = 64; private: int cnt_; diff --git a/env/Dockerfile b/env/Dockerfile index 4ab09976c6..7995cd88af 100644 --- a/env/Dockerfile +++ b/env/Dockerfile @@ -4,8 +4,90 @@ # vim: syntax=dockerfile ARG BASE_IMAGE=ubuntu:focal +# Install CNDP dependencies and build CNDP. +FROM ${BASE_IMAGE} AS cndp-build + +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y \ + build-essential \ + golang \ + libelf-dev \ + meson \ + pkg-config \ + libbsd-dev \ + libjson-c-dev \ + libnl-3-dev \ + libnl-cli-3-dev \ + libnuma-dev \ + libpcap-dev \ + wget \ + llvm-dev \ + libclang-dev \ + clang \ + curl \ + git \ + gcc-multilib \ + llvm \ + lld \ + m4 \ + linux-tools-common \ + libbpf-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install libxdp +RUN git clone https://github.com/xdp-project/xdp-tools.git +WORKDIR /xdp-tools/ +RUN git checkout v1.2.2 +RUN ./configure +WORKDIR /xdp-tools/ +RUN make -j; PREFIX=/usr make -j install +ENV PKG_CONFIG_PATH=/usr/lib/pkgconfig + +# Get CNDP from GitHub +WORKDIR / +RUN git clone https://github.com/CloudNativeDataPlane/cndp.git +WORKDIR /cndp +# Use version of CNDP tested with BESS +RUN git checkout d5ce4b9edc2e7ddb46a61b395deffafaf11a0500 +# Build and install CNDP shared libraries +RUN make && make install +# Build and install CNDP static libraries +RUN make static_build=1 rebuild install + +# Build the prometheus-metrics app +WORKDIR /cndp/lang/go/stats/prometheus/ +RUN go build prometheus.go + FROM ${BASE_IMAGE} +# Install CNDP dependencies +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y \ + build-essential \ + ethtool \ + libbsd-dev \ + libbpf-dev \ + libelf1 \ + libjson-c-dev \ + libnl-3-dev \ + libnl-cli-3-dev \ + libnuma1 \ + libpcap0.8 \ + pkg-config + +# Copy required CNDP libraries, header files, pkg-config and binaries. +COPY --from=cndp-build /cndp/usr/local/bin/cndpfwd /usr/bin/ +COPY --from=cndp-build /cndp/usr/local/lib/x86_64-linux-gnu/*.so /usr/lib/ +COPY --from=cndp-build /cndp/usr/local/lib/x86_64-linux-gnu/*.a /usr/lib/ +COPY --from=cndp-build /cndp/usr/local/include/cndp/ /usr/local/include/cndp/ +COPY --from=cndp-build /cndp/usr/local/lib/pkgconfig/libcndp.pc /usr/lib/pkgconfig/ +COPY --from=cndp-build /cndp/lang/go/stats/prometheus/prometheus /usr/bin/ +COPY --from=cndp-build /usr/lib/libxdp* /usr/lib/ +COPY --from=cndp-build /usr/include/xdp/ /usr/include/xdp/ + +# Set CNDP PKG_CONFIG_PATH +ENV PKG_CONFIG_PATH=/usr/lib64/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig + RUN echo "APT::Install-Recommends false;" >> /etc/apt/apt.conf.d/00recommends && \ echo "APT::Install-Suggests false;" >> /etc/apt/apt.conf.d/00recommends && \ echo "APT::AutoRemove::RecommendsImportant false;" >> /etc/apt/apt.conf.d/00recommends && \ diff --git a/env/Dockerfile-cndp b/env/Dockerfile-cndp new file mode 100644 index 0000000000..45b09a45d8 --- /dev/null +++ b/env/Dockerfile-cndp @@ -0,0 +1,136 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2020-2022 Intel Corporation +# +# vim: syntax=dockerfile + +# Build command from bess root directory to build besscndp docker image +# docker build --build-arg http_proxy=$http_proxy \ +# --build-arg https_proxy=$http_proxy --build-arg no_proxy="$no_proxy" \ +# -t besscndp -f env/Dockerfile-cndp . + +ARG BASE_IMAGE=ubuntu:focal +FROM ${BASE_IMAGE} AS cndp-build + +# Install CNDP dependencies and build CNDP. +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y \ + build-essential \ + golang \ + libelf-dev \ + meson \ + pkg-config \ + libbsd-dev \ + libjson-c-dev \ + libnl-3-dev \ + libnl-cli-3-dev \ + libnuma-dev \ + libpcap-dev \ + wget \ + llvm-dev \ + libclang-dev \ + clang \ + curl \ + git \ + gcc-multilib \ + llvm \ + lld \ + m4 \ + linux-tools-common \ + libbpf-dev \ + && rm -rf /var/lib/apt/lists/* + +# Install libxdp +RUN git clone https://github.com/xdp-project/xdp-tools.git +WORKDIR /xdp-tools/ +RUN git checkout v1.2.2 +RUN ./configure +WORKDIR /xdp-tools/ +RUN make -j; PREFIX=/usr make -j install +ENV PKG_CONFIG_PATH=/usr/lib/pkgconfig + +# Get CNDP from GitHub +WORKDIR / +RUN git clone https://github.com/CloudNativeDataPlane/cndp.git +WORKDIR /cndp +# Use version of CNDP tested with BESS +RUN git checkout 19d74af9b37c4150a3a054a394f7f13eb95ed0b8 +# Build and install CNDP shared libraries +RUN make && make install +# Build and install CNDP static libraries +RUN make static_build=1 rebuild install + +# Build the prometheus-metrics app +WORKDIR /cndp/lang/go/stats/prometheus/ +RUN go build prometheus.go + +FROM ${BASE_IMAGE} + +# Install CNDP dependencies +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get install -y \ + build-essential \ + ethtool \ + libbsd-dev \ + libbpf-dev \ + libelf1 \ + libjson-c-dev \ + libnl-3-dev \ + libnl-cli-3-dev \ + libnuma1 \ + libpcap0.8 \ + pkg-config + +# Copy required CNDP libraries, header files, pkg-config and binaries. +COPY --from=cndp-build /cndp/usr/local/bin/cndpfwd /usr/bin/ +COPY --from=cndp-build /cndp/usr/local/lib/x86_64-linux-gnu/*.so /usr/lib/ +COPY --from=cndp-build /cndp/usr/local/lib/x86_64-linux-gnu/*.a /usr/lib/ +COPY --from=cndp-build /cndp/usr/local/include/cndp/ /usr/local/include/cndp/ +COPY --from=cndp-build /cndp/usr/local/lib/pkgconfig/libcndp.pc /usr/lib/pkgconfig/ +COPY --from=cndp-build /cndp/lang/go/stats/prometheus/prometheus /usr/bin/ +COPY --from=cndp-build /usr/lib/libxdp* /usr/lib/ +COPY --from=cndp-build /usr/include/xdp/ /usr/include/xdp/ + +# Set CNDP PKG_CONFIG_PATH +ENV PKG_CONFIG_PATH=/usr/lib64/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig + +# Install BESS +RUN echo "APT::Install-Recommends false;" >> /etc/apt/apt.conf.d/00recommends && \ + echo "APT::Install-Suggests false;" >> /etc/apt/apt.conf.d/00recommends && \ + echo "APT::AutoRemove::RecommendsImportant false;" >> /etc/apt/apt.conf.d/00recommends && \ + echo "APT::AutoRemove::SuggestsImportant false;" >> /etc/apt/apt.conf.d/00recommends + +COPY env/build-dep.yml /tmp/ +COPY env/kmod.yml /tmp/ +COPY env/ci.yml /tmp/ + +# Install dependency packages with Ansible +RUN apt-get -q update && \ + apt-get install -y ansible curl git sudo libgraph-easy-perl python-is-python3 && \ + ansible-playbook /tmp/ci.yml -i "localhost," -c local && \ + apt-get purge -y ansible && \ + apt-get autoremove -y && \ + rm -rf /var/lib/apt/lists +RUN python3 -m pip install --upgrade pip && python3 -m pip install grpcio scapy protobuf==3.20.0 flask pyroute2 + +RUN mkdir -p /build/bess +RUN mkdir -p /build/bess/log + + +# Copy required files and build bess +WORKDIR /build/bess +COPY bessctl bessctl +COPY bin bin +COPY core core +COPY deps/*.patch deps/ +COPY env env +COPY protobuf protobuf +COPY pybess pybess +COPY sample_plugin sample_plugin +COPY build.py container_build.py install_git_hooks.sh ./ +RUN ./build.py bess +RUN cp /build/bess/deps/dpdk-20.11.3/build/app/dpdk-testpmd /usr/local/bin/ + +ENV CCACHE_DIR=/tmp/ccache +ENV CCACHE_COMPRESS=true + +WORKDIR /build/bess diff --git a/protobuf/ports/port_msg.proto b/protobuf/ports/port_msg.proto index 12fe79f040..d2b9b1756b 100644 --- a/protobuf/ports/port_msg.proto +++ b/protobuf/ports/port_msg.proto @@ -1,4 +1,5 @@ // Copyright (c) 2016-2017, Nefeli Networks, Inc. +// Copyright (c) 2020-2022 Intel Corporation. // All rights reserved. // // SPDX-License-Identifier: BSD-3-Clause @@ -89,3 +90,11 @@ message VPortArg { bool loopback = 8; repeated string ip_addrs = 9; } + +message CndpPortArg { + /// CNDP JSONC configuration absolute file path. + string jsonc_file = 1; + + /// lport index. + uint32 lport_index = 2; +} diff --git a/requirements.txt b/requirements.txt index 6c740506ba..9dc570660a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ scapy flask grpcio protobuf==3.20 +pyroute2 From fb73a3456fe5fb34e30ae8115a7f3df0b4a96f36 Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Mon, 27 Mar 2023 17:46:55 -0700 Subject: [PATCH 58/62] Build new image taking into account new dependencies (e.g., CNDP) (#22) --- env/rebuild_images.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/env/rebuild_images.py b/env/rebuild_images.py index f6b82cb14d..1e1d7dbd63 100755 --- a/env/rebuild_images.py +++ b/env/rebuild_images.py @@ -60,7 +60,7 @@ def run_cmd(cmd, shell=False): def build(env): base = imgs[env]['base'] tag_suffix = imgs[env]['tag_suffix'] - bess_dpdk_branch = os.getenv('BESS_DPDK_BRANCH', 'master') + bess_dpdk_branch = os.getenv('BESS_DPDK_BRANCH', 'dpdk-2011-focal') version = time.strftime('%y%m%d') run_cmd('docker build ' @@ -89,10 +89,7 @@ def main(argv): version, tag_suffix = build(argv[1]) - try: - prompt = raw_input # Python 2 - except NameError: - prompt = input # Python 3 + prompt = input # Python 3 if prompt('Do you wish to push the image? [y/N] ').lower() in ['y', 'yes']: push(version, tag_suffix) From 660f1af90419d856d4bd00841c7034cf5469d13b Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Mon, 27 Mar 2023 18:37:00 -0700 Subject: [PATCH 59/62] Fix typo (#17) --- doxygen/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doxygen/README.md b/doxygen/README.md index 2c708e7e48..2ad1034ffc 100644 --- a/doxygen/README.md +++ b/doxygen/README.md @@ -1,4 +1,4 @@ -### How to generaate BESS code documentation +### How to generate BESS code documentation * Install doxygen (sudo apt-get install doxygen) * cd bess/doxygen From 29b94a8344d335b3087f6a69811ea45fdf05752d Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Wed, 7 Jun 2023 20:53:15 -0700 Subject: [PATCH 60/62] Enable GTPu path monitoring (#19) * Enable GTPu path monitoring --- core/modules/gtpu_path_monitoring.cc | 202 +++++++++++++++++++++++++++ core/modules/gtpu_path_monitoring.h | 56 ++++++++ protobuf/module_msg.proto | 39 ++++++ 3 files changed, 297 insertions(+) create mode 100644 core/modules/gtpu_path_monitoring.cc create mode 100644 core/modules/gtpu_path_monitoring.h diff --git a/core/modules/gtpu_path_monitoring.cc b/core/modules/gtpu_path_monitoring.cc new file mode 100644 index 0000000000..07ef815261 --- /dev/null +++ b/core/modules/gtpu_path_monitoring.cc @@ -0,0 +1,202 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2022 Intel Corporation + */ + +#include "gtpu_path_monitoring.h" + +#include "utils/endian.h" /* for be16_t */ +#include "utils/endian.h" /* for be32_t */ +#include "utils/ether.h" /* for ethernet header */ +#include "utils/gtp.h" /* for gtp header */ +#include "utils/ip.h" /* for ToIpv4Address() */ +#include "utils/udp.h" /* for udp header */ + +#include + +using bess::utils::be16_t; +using bess::utils::be32_t; +using bess::utils::Ethernet; +using bess::utils::Gtpv1; +using bess::utils::Gtpv1SeqPDUExt; +using bess::utils::Ipv4; +using bess::utils::ToIpv4Address; +using bess::utils::Udp; + +const Commands GtpuPathMonitoring::cmds = { + {"add", "GtpuPathMonitoringCommandAddDeleteArg", + MODULE_CMD_FUNC(&GtpuPathMonitoring::CommandAdd), Command::THREAD_SAFE}, + {"delete", "GtpuPathMonitoringCommandAddDeleteArg", + MODULE_CMD_FUNC(&GtpuPathMonitoring::CommandDelete), Command::THREAD_SAFE}, + {"clear", "GtpuPathMonitoringCommandClearArg", + MODULE_CMD_FUNC(&GtpuPathMonitoring::CommandClear), Command::THREAD_SAFE}, + {"read", "GtpuPathMonitoringCommandReadArg", + MODULE_CMD_FUNC(&GtpuPathMonitoring::CommandReadStats), + Command::THREAD_SAFE}, +}; + +void GtpuPathMonitoring::ProcessBatch(Context *ctx, bess::PacketBatch *batch) { + int cnt = batch->cnt(); + + for (int i = 0; i < cnt; i++) { + // we should drop-or-emit each packet + bess::Packet *pkt = batch->pkts()[i]; + + // If gNB IP vector is empty, drop packet. It is like disabling this feature + if (m_dstIp.empty()) { + DLOG(INFO) << "gNBs IP vector is empty, dropping packet"; + DropPacket(ctx, pkt); + continue; + } + + Ethernet *eth = pkt->head_data(); + Ipv4 *iph = (Ipv4 *)((unsigned char *)eth + sizeof(Ethernet)); + Udp *udp = (Udp *)((unsigned char *)iph + (iph->header_length << 2)); + Gtpv1 *gtph = (Gtpv1 *)((unsigned char *)udp + sizeof(Udp)); + Gtpv1SeqPDUExt *speh = + (Gtpv1SeqPDUExt *)((unsigned char *)gtph + sizeof(Gtpv1)); + + uint8_t gtpuType = gtph->type; + + if (gtpuType == GTPU_ECHO_REQUEST) { + speh->seqnum = static_cast(m_seqNumber); + + for (auto it : m_dstIp) { + m_storedData[it.first][m_seqNumber] = tsc_to_ns(rdtsc()); + bess::Packet *newPkt = bess::Packet::copy(pkt); + Ethernet *newEth = newPkt->head_data(); + Ipv4 *newIph = (Ipv4 *)((unsigned char *)newEth + sizeof(Ethernet)); + newIph->dst = static_cast(it.first); + EmitPacket(ctx, newPkt); + } + + m_seqNumber++; + + } else if (gtpuType == GTPU_ECHO_RESPONSE) { + uint32_t srcIp = iph->src.value(); + uint16_t seqNumber = speh->seqnum.value(); + auto it = m_storedData.find(srcIp); + if (it != m_storedData.end()) { + auto itInn = it->second.find(seqNumber); + if (itInn != it->second.end()) { + Values values; + uint64_t lat = (tsc_to_ns(rdtsc()) - itInn->second) / 2; + auto itDst = m_latency.find(srcIp); + if (itDst != m_latency.end()) { + Values valuesIn = itDst->second; + values.m_count = valuesIn.m_count + 1; + values.m_min = (lat < valuesIn.m_min) ? lat : valuesIn.m_min; + if (lat > valuesIn.m_mean) { + values.m_mean = + valuesIn.m_mean + (lat - valuesIn.m_mean) / values.m_count; + } else { + values.m_mean = + valuesIn.m_mean - (valuesIn.m_mean - lat) / values.m_count; + } + values.m_max = (lat > valuesIn.m_max) ? lat : valuesIn.m_max; + } else { + values.m_count = 1; + values.m_min = lat; + values.m_mean = lat; + values.m_max = lat; + } + + m_latency[srcIp] = values; + it->second.erase(itInn); + + } else { + LOG(ERROR) << "Sequence number " << seqNumber << " not found in map"; + } + } else { + LOG(ERROR) << "gNB IP address not found in map"; + } + + LOG(INFO) << "type:" << +gtpuType + << ", srcIp:" << ToIpv4Address(static_cast(srcIp)) + << ", seqNumber:" << seqNumber << ", latency:[" + << m_latency[srcIp].m_min << ", " << m_latency[srcIp].m_mean + << ", " << m_latency[srcIp].m_max << "]"; + DropPacket(ctx, pkt); + } else { + LOG(ERROR) << "Unexpected GTP Type (" << +gtpuType << ")"; + DropPacket(ctx, pkt); + } + } +} + +CommandResponse GtpuPathMonitoring::CommandReadStats( + const bess::pb::GtpuPathMonitoringCommandReadArg &arg) { + bess::pb::GtpuPathMonitoringCommandReadResponse resp; + for (auto &element : m_latency) { + bess::pb::GtpuPathMonitoringCommandReadResponse::Statistic stat; + stat.set_gnb_ip(element.first); + stat.set_count(element.second.m_count); + stat.set_latency_min(element.second.m_min); + stat.set_latency_mean(element.second.m_mean); + stat.set_latency_max(element.second.m_max); + *resp.add_statistics() = stat; + + if (arg.clear()) { + element.second.m_count = 0; + element.second.m_min = std::numeric_limits::max(); + element.second.m_mean = 0; + element.second.m_max = 0; + } + } + + return CommandSuccess(resp); +} + +CommandResponse GtpuPathMonitoring::Init(const bess::pb::EmptyArg &) { + GtpuPathMonitoring::Clear(); + + return CommandSuccess(); +} + +CommandResponse GtpuPathMonitoring::CommandAdd( + const bess::pb::GtpuPathMonitoringCommandAddDeleteArg &arg) { + uint32_t dst = arg.gnb_ip(); + auto it = m_dstIp.find(dst); + if (it == m_dstIp.end()) { + m_dstIp.emplace(dst, 1); + } else { + it->second++; + } + + return CommandSuccess(); +} + +CommandResponse GtpuPathMonitoring::CommandDelete( + const bess::pb::GtpuPathMonitoringCommandAddDeleteArg &arg) { + uint32_t dst = arg.gnb_ip(); + auto it = m_dstIp.find(dst); + if (it == m_dstIp.end()) { + LOG(ERROR) << "Address " << ToIpv4Address(static_cast(dst)) + << " is not known"; + } else { + if (it->second == 1) { + m_dstIp.erase(dst); + } else { + it->second--; + } + } + + return CommandSuccess(); +} + +CommandResponse GtpuPathMonitoring::CommandClear( + const bess::pb::GtpuPathMonitoringCommandClearArg &) { + GtpuPathMonitoring::Clear(); + + return CommandSuccess(); +} + +void GtpuPathMonitoring::Clear() { + m_storedData.clear(); + m_latency.clear(); + m_dstIp.clear(); + m_seqNumber = 0; +} + +ADD_MODULE(GtpuPathMonitoring, "gtpu_path_monitoring", + "Gtpu path monitoring module") diff --git a/core/modules/gtpu_path_monitoring.h b/core/modules/gtpu_path_monitoring.h new file mode 100644 index 0000000000..056662abdb --- /dev/null +++ b/core/modules/gtpu_path_monitoring.h @@ -0,0 +1,56 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright 2022 Intel Corporation + */ + +#ifndef BESS_MODULES_GTPU_PATH_MONITORING_H_ +#define BESS_MODULES_GTPU_PATH_MONITORING_H_ + +#include "../module.h" +#include "../pb/module_msg.pb.h" + +#include +#include + +// Updates sequence number by incrementing by 1 +class GtpuPathMonitoring final : public Module { + public: + static const Commands cmds; + + GtpuPathMonitoring() : Module() { max_allowed_workers_ = 1; } + + void ProcessBatch(Context *ctx, bess::PacketBatch *batch) override; + + CommandResponse Init(const bess::pb::EmptyArg &arg); + + CommandResponse CommandAdd( + const bess::pb::GtpuPathMonitoringCommandAddDeleteArg &arg); + + CommandResponse CommandDelete( + const bess::pb::GtpuPathMonitoringCommandAddDeleteArg &arg); + + CommandResponse CommandClear( + const bess::pb::GtpuPathMonitoringCommandClearArg &arg); + + CommandResponse CommandReadStats( + const bess::pb::GtpuPathMonitoringCommandReadArg &arg); + + private: + struct Values { + uint32_t m_count{0}; // Count number of samples + uint64_t m_min{std::numeric_limits::max()}; // Minimum latency + uint64_t m_mean{0}; // Average latency + uint64_t m_max{0}; // Maximum latency + }; + + void Clear(); + + std::unordered_map> + m_storedData; // Store timestamp {dst_IP, {sequence_number, latency}} + std::unordered_map m_latency; // Store latency per dstIp + std::unordered_map + m_dstIp; // GTP Tunnel destination {gNB IP, counter} + uint16_t m_seqNumber{0}; // gtpu echo sequence number +}; + +#endif // BESS_MODULES_GTPU_PATH_MONITORING_H_ diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index 6910c0408c..820ecaf11a 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -1463,3 +1463,42 @@ message FlowMeasureCommandFlipArg {} message FlowMeasureFlipResponse { uint64 old_flag = 1; } + +/** + * The GtpuPathMonitoring module has a command `add()` and `delete(). + * This command add or deletes an IP address from the GtpuPathMonitoring module. + */ +message GtpuPathMonitoringCommandAddDeleteArg { + uint32 gnb_ip = 1; // The destination/gNB IP address. +} + +/** + * The GtpuPathMonitoring module has a command `clear()` which takes no + * parameters. + * This command removes all IP addresses from the GtpuPathMonitoring module. + */ +message GtpuPathMonitoringCommandClearArg {} + +/** + * The GtpuPathMonitoring module has a command `read()`. + * This command requests to read the stats from the GtpuPathMonitoring module. + * It can also clear the stats + */ +message GtpuPathMonitoringCommandReadArg { + bool clear = 1; // If true, the data will be all cleared after read +} + +/** + * The GtpuPathMonitoring module has a command `readResponse()`. + * This command reads the stats from the GtpuPathMonitoring module. + */ +message GtpuPathMonitoringCommandReadResponse { + message Statistic { + uint32 gnb_ip = 1; /// gNB IP + uint64 count = 2; /// count + uint64 latency_min = 3; /// minimum latency + uint64 latency_mean = 4; /// average latency + uint64 latency_max = 5; /// maximum latency + } + repeated Statistic statistics = 1; +} From cc826b236be0b12104e8550b458b4c6ff1ab51d6 Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Wed, 21 Jun 2023 09:50:19 -0700 Subject: [PATCH 61/62] Fix typo (#26) --- CNDP_README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CNDP_README.md b/CNDP_README.md index 7da92815d5..4cced5e0d1 100644 --- a/CNDP_README.md +++ b/CNDP_README.md @@ -36,4 +36,4 @@ $ docker run --network=host -e http_proxy=${http_proxy} -e https_proxy=${http_pr 3. Run bessctl controller from container shell: `./bessctl/bessctl` 4. From bessctl shell , run bess daemon: `daemon start -log_dir /build/bess/log` 5. Run sample BESS CNDP script: `run cndp/cndpfwd_coreid`. This will run cndpfwd BESS pipeline in a core id specified in "/build/bess/bessctl/conf/cndp/cndpfwd_coreid.bess" script. Before running the script, edit the script to update core in line `bess.add_worker(wid=0, core=28)` to a core id in CPU socket where the network device is attached to get better performance. -6. If everything works fine, then you should see BESS pipeline logs when you run: `monior pipeline` +6. If everything works fine, then you should see BESS pipeline logs when you run: `monitor pipeline` From 865de569fd7d8db768e82b2863bb09e60c4395f1 Mon Sep 17 00:00:00 2001 From: gab-arrobo Date: Wed, 21 Jun 2023 21:45:55 -0700 Subject: [PATCH 62/62] Add spellcheck GHA (#27) --- .github/workflows/markdown.yml | 19 ++++++ .gitignore | 5 +- .spellcheck.yml | 31 +++++++++ .wordlist.txt | 106 ++++++++++++++++++++++++++++++ README.md | 2 +- bessctl/conf/port/vhost/README.md | 2 +- core/resume_hooks/README.md | 2 +- env/README.md | 4 +- 8 files changed, 165 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/markdown.yml create mode 100644 .spellcheck.yml create mode 100644 .wordlist.txt diff --git a/.github/workflows/markdown.yml b/.github/workflows/markdown.yml new file mode 100644 index 0000000000..5ff57d1dc1 --- /dev/null +++ b/.github/workflows/markdown.yml @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2023 Intel Corporation + +name: Spellcheck +on: + - pull_request + +jobs: + check-spelling: + name: Markdown spellcheck + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Check Spelling + uses: rojopolis/spellcheck-github-actions@0.33.0 + with: + config_path: .spellcheck.yml + task_name: Markdown diff --git a/.gitignore b/.gitignore index bd1afe7f17..cafbfcbde7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ core/extra.dpdk.mk core/kmod/.cache.mk *.retry *.cache.mk +dictionary.dic # Vagrant stores temporary files in env/.vagrant env/.vagrant @@ -52,7 +53,9 @@ compile_commands.json # virtualenv venv/ -# Keep GitHub Actions, reuse, and clang-format file +# Keep GitHub Actions, reuse, clang-format file and spellchecking files !.github !.reuse !.clang-format +!.spellcheck.yml +!.wordlist.txt diff --git a/.spellcheck.yml b/.spellcheck.yml new file mode 100644 index 0000000000..aea7a00b2e --- /dev/null +++ b/.spellcheck.yml @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2023 Intel Corporation + +matrix: +- name: Markdown + # expect_match: false + apsell: + lang: en + # ignore-case: true + dictionary: + wordlists: + - .wordlist.txt + # output: wordlist.dic + encoding: utf-8 + pipeline: + - pyspelling.filters.markdown: + markdown_extensions: + - markdown.extensions.extra: + - pyspelling.filters.html: + comments: false + attributes: + - title + - alt + ignores: + - ':matches(code, pre)' + - 'code' + - 'pre' + - 'blockquote' + sources: + - '**/*.md' + default_encoding: utf-8 diff --git a/.wordlist.txt b/.wordlist.txt new file mode 100644 index 0000000000..5cd8d3c0b9 --- /dev/null +++ b/.wordlist.txt @@ -0,0 +1,106 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2023 Intel Corporation +Ansible +bess +pre +initializer +protobuf +RPC +utils +VM +DPDK +QEMU +TXQ +VMs +dev +hugepages +io +macswap +testpmd +vSwitch +virtio +py +vm +VPort +vhost +qcow +NUMA +datapath +qemu +kvm +numactl +Grunenberger +Yan +Asim +Jamshed +Alireza +Sanaee +Rozet +Standt +Ivanov +Mussomele +Sagie +Torek +Eran +Gampel +Lévai +Tamás +CLA +PRs +unittest +Sangjin +Jang +Keon +Aurojit +Edupuganti +Saikrishna +Xiaoshuang +Shinae +Peng +McCauley +Amin +Tootoonchian +Lan +Barath +Raghavan +Lala +Situ +Daniele +Proietto +di +Felicián +Németh +LaTeX +doxygen +sudo +CNDP +bessctl +cndp +cndpfwd +conf +coreid +ethtool +jsonc +netdev +recv +OpenFlow +SoftNIC +programmability +Nefeli +html +dox +Nefeli +customizability +XDP +https +cd +besscndp +runtime +epc +ghcr +omec +runnable +upf +env +macOS +vagrantup \ No newline at end of file diff --git a/README.md b/README.md index e7bd1cbe9f..7f18ab69a8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## BESS (Berkeley Extensible Software Switch) -BESS (formerly known as [SoftNIC](https://www2.eecs.berkeley.edu/Pubs/TechRpts/2015/EECS-2015-155.html)) is a modular framework for software switches. BESS itself is *not* a virtual switch; it is neither pre-configured nor hardcoded to provide particular functionality, such as Ethernet bridging or OpenFlow-driven switching. Instead, you (or an external controller) can *configure* your own packet processing datapath by composing small "modules". While the basic concept is similar to [Click](http://read.cs.ucla.edu/click/click), BESS does not sacrifice performance for programmability. +BESS (formerly known as [SoftNIC](https://www2.eecs.berkeley.edu/Pubs/TechRpts/2015/EECS-2015-155.html)) is a modular framework for software switches. BESS itself is *not* a virtual switch; it is neither pre-configured nor hard-coded to provide particular functionality, such as Ethernet bridging or OpenFlow-driven switching. Instead, you (or an external controller) can *configure* your own packet processing datapath by composing small "modules". While the basic concept is similar to [Click](http://read.cs.ucla.edu/click/click), BESS does not sacrifice performance for programmability. BESS was created by Sangjin Han and is developed at the University of California, Berkeley and at Nefeli Networks. [Contributors to BESS](https://github.com/omec-project/bess/blob/master/CONTRIBUTING.md) include students, researchers, and developers who care about networking with high performance and high customizability. BESS is open-source under a BSD license. diff --git a/bessctl/conf/port/vhost/README.md b/bessctl/conf/port/vhost/README.md index 8fea9afef3..e2c40e7e2b 100644 --- a/bessctl/conf/port/vhost/README.md +++ b/bessctl/conf/port/vhost/README.md @@ -38,7 +38,7 @@ VMs below. You can launch one or multiple VMs. Each VM runs `testpmd` that simply swaps source/destination MAC addresses of packets and forward them from one port to another. You must launch `vhost.bess` first, so that QEMU can connect to BESS -vport sockets. Otherwise you will see an error like this: +VPort sockets. Otherwise you will see an error like this: `qemu-system-x86_64: ... Failed to connect socket: No such file or directory` diff --git a/core/resume_hooks/README.md b/core/resume_hooks/README.md index 1a08652f80..a1aaaff96e 100644 --- a/core/resume_hooks/README.md +++ b/core/resume_hooks/README.md @@ -5,7 +5,7 @@ resumed. They can be configured with the `ConfigureResumeHook()` RPC. The API is simple, similar to that of `GateHook`. All you need to do is: - Define `YourHook::kName`. This must be unique across all other resume hooks. -- Define `YourHook::kPriority` (lower values get higher priority). Ties are broken by hook name in increasing lexographical order. +- Define `YourHook::kPriority` (lower values get higher priority). Ties are broken by hook name in increasing lexicographical order. - Include `ResumeHook(kName, kPriority)` in `YourHook`'s initializer list. - Define `void YourHook::Run()`. - Define `void YourHook::Init(const bess::pb::YourHookArg &)`. diff --git a/env/README.md b/env/README.md index 9320004773..c811fe420b 100644 --- a/env/README.md +++ b/env/README.md @@ -6,7 +6,7 @@ laptop or server. ## Playing with BESS VM -You can launch a fully conigured VM on which you can build and test BESS at your +You can launch a fully configured VM on which you can build and test BESS at your fingertips. We don't provide a binary VM image though. Instead, We provide a Vagrant (https://vagrantup.com) script that automatically generates a VM based on Ubuntu 18.04. You can install Vagrant not only on Linux, but also on Windows @@ -19,7 +19,7 @@ $ vagrant up to launch a VM. The current BESS directory is mapped to `/opt/bess` in the VM. You can connect to the VM with `vagrant ssh`. All compilers and libraries are -readiliy available. +readily available. ## Building BESS without installing dependencies
${module_name}