From c7e8dfb337ad0c6fb13f100cada91f7673bc9ef8 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 13:45:25 -0800 Subject: [PATCH 01/15] cpu pinning --- docker-compose/b2b-pinning/Makefile | 94 +++++++++++++ docker-compose/b2b-pinning/README.md | 184 +++++++++++++++++++++++++ docker-compose/b2b-pinning/compose.yml | 26 ++++ docker-compose/b2b-pinning/diagram.png | Bin 0 -> 48004 bytes docker-compose/b2b-pinning/otg.yml | 58 ++++++++ 5 files changed, 362 insertions(+) create mode 100644 docker-compose/b2b-pinning/Makefile create mode 100644 docker-compose/b2b-pinning/README.md create mode 100644 docker-compose/b2b-pinning/compose.yml create mode 100644 docker-compose/b2b-pinning/diagram.png create mode 100644 docker-compose/b2b-pinning/otg.yml diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile new file mode 100644 index 00000000..b529b0f0 --- /dev/null +++ b/docker-compose/b2b-pinning/Makefile @@ -0,0 +1,94 @@ +SHELL = /bin/bash + +.PHONY: all +all: install network deploy run + +.PHONY: clean +clean: remove-lab network-clean + +.PHONY: clean-all +clean-all: clean install-clean + +############################### +# Install components +############################### + +.PHONY: install +install: install-docker-compose install-otgen + +install-docker-compose: /usr/local/bin/docker-compose +/usr/local/bin/docker-compose: + sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$$(uname -s)-$$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + +install-otgen: /usr/local/bin/otgen +/usr/local/bin/otgen: + curl -L "https://github.com/open-traffic-generator/otgen/releases/download/v0.2.0/otgen_0.2.0_$$(uname -s)_$$(uname -m).tar.gz" | tar xzv otgen + sudo mv otgen /usr/local/bin/otgen + sudo chmod +x /usr/local/bin/otgen + +install-clean: + -sudo rm -f `command -v docker-compose` + -sudo rm -f `command -v otgen` + +############################### +# Test network +############################### + +.PHONY: network +network:veth0 + +veth0: /sys/class/net/veth0 +/sys/class/net/veth0: + sudo ip link add name veth0 type veth peer name veth1 + sudo ip link set dev veth0 up + sudo ip link set dev veth1 up + sudo sysctl net.ipv6.conf.veth0.disable_ipv6=1 + sudo sysctl net.ipv6.conf.veth1.disable_ipv6=1 + +network-mtu: + sudo ip link set veth0 mtu 9500 + sudo ip link set veth1 mtu 9500 + +network-clean: veth0-clean +veth0-clean: +#TODO run only if veth0 exists + sudo ip link del name veth0 type veth peer name veth1 + +############################### +# Deploy lab +############################### + +.PHONY: deploy +deploy: deploy-lab + +deploy-lab: + sudo docker-compose up -d + +remove-lab: + sudo docker-compose down + +############################### +# Run tests +############################### + +.PHONY: run +run: network-mtu otgen-run otgen-run-as-table-port otgen-run-as-table-flow otgen-run-as-table-flow-bytes + +otgen-run: + cat otg.yml | otgen run -k -a https://localhost:8443 + +otgen-run-as-table-port: + @echo "cat otg.yml | otgen run -k -a https://localhost:8443 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformPortFramesTable.tmpl" + @echo "│Port│ FramesTx │ FramesRx │Port│ FramesTx │ FramesRx │" + @cat otg.yml | otgen run -k 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformPortFramesTable.tmpl + +otgen-run-as-table-flow: + @echo "cat otg.yml | otgen run -k -a https://localhost:8443 -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowFramesTable.tmpl" + @echo "│ Flow │ FramesTx │ FramesRx │" + @cat otg.yml | otgen run -k -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowFramesTable.tmpl + +otgen-run-as-table-flow-bytes: + @echo "cat otg.yml | otgen run -k -a https://localhost:8443 -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowBytesTable.tmpl" + @echo "│ Flow │ BytesTx │ BytesRx │" + @cat otg.yml | otgen run -k -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowBytesTable.tmpl \ No newline at end of file diff --git a/docker-compose/b2b-pinning/README.md b/docker-compose/b2b-pinning/README.md new file mode 100644 index 00000000..5ee98f99 --- /dev/null +++ b/docker-compose/b2b-pinning/README.md @@ -0,0 +1,184 @@ +# Ixia-c traffic engine back-to-back setup with CPU Core Pinning + +## Overview + +This lab demonstrates how to maximize performance of [Ixia-c](https://github.com/open-traffic-generator/ixia-c) Traffic Engine ports via CPU pinning. The lab has two traffic ports connected back-2-back using a veth pair. The lab is defined via Docker Compose YAML file. + +![Diagram](./diagram.png) + +## Deployment Details + +In the deployment steps listed below, two `traffic-engine` containers will be started. The table below describes parameters that are unique among them: + +- **Listen Port**: Port on which the `traffic-engine` will listen to for communication with the `controller`. +- **CPU Cores Allocated**: Each instance of `traffic-engine` uses three cores. Two dedicated cores are used for + sending and receiving packets and one is used for configuration, control and statistics. In the example above all + instances of `traffic-engine` are sharing core number 2 for the configuration, control and statistics while + instance 1 is using cores 3/4 for Tx/Rx, instance 2 is using cores 5/6 for Tx/Rx, and so on. + +| Instance | Listen Port | Cores Allocated | vEth Interface Used | +|----------|-------------|-----------------|-------------------------| +| 1 | 5555 | 2, 3, 4 | veth0 | +| 2 | 5556 | 2, 5, 6 | veth1 | + + +**Note**: The Tx/Rx cores allocated to a `traffic-engine` instance (using the ARG_CORE_LIST environment variable) +MUST NOT overlap across other such instances (even if they are idle and not sending/receiving any traffic). +Sharing Tx/Rx cores will result in undefined behavior including but not limited to loss of performance. +Further due to a NUMA-related limitation with DPDK 19.11 used by Ixia-C Traffic Engine, the core used for control +needs to be same across all `traffic-engine` instances. In the example above, core number 2 is used for control in all three containers. + + + ```Shell + cat > compose.yml << EOF + services: + controller: + image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 + command: --accept-eula --http-port 8443 + network_mode: "host" + restart: always + traffic_engine_1: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,3,4 + environment: + - OPT_LISTEN_PORT=5555 + - ARG_IFACE_LIST=virtual@af_packet,veth0 + - OPT_NO_HUGEPAGES=Yes + traffic_engine_2: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,5,6 + environment: + - OPT_LISTEN_PORT=5556 + - ARG_IFACE_LIST=virtual@af_packet,veth1 + - OPT_NO_HUGEPAGES=Yes + EOF + ``` + +## System Prerequisites + +### CPU and RAM + +* `traffic-engine` - each instance requires 2 dedicated CPU cores and 3GB dedicated RAM. +* `controller` - each instance requires at least 1 CPU core and 2GB RAM. + +### Platform + +* x86_64 Linux Distribution (Centos 7+ or Ubuntu 18+) with sudo permissions and Docker support +* [Docker 19+](https://docs.docker.com/engine/install/) + +## Install components + +1. Install `docker-compose` + + ```Shell + sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + sudo chmod +x /usr/local/bin/docker-compose + ``` + +2. Install `otgen` + + ```Shell + curl -L "https://github.com/open-traffic-generator/otgen/releases/download/v0.2.0/otgen_0.2.0_$(uname -s)_$(uname -m).tar.gz" | tar xzv otgen + sudo mv otgen /usr/local/bin/otgen + sudo chmod +x /usr/local/bin/otgen + ``` + +3. Make sure `/usr/local/bin` is in your `$PATH` variable (by default this is not the case on CentOS 7) + + ```Shell + cmd=docker-compose + dir=/usr/local/bin + if ! command -v ${cmd} &> /dev/null && [ -x ${dir}/${cmd} ]; then + echo "${cmd} exists in ${dir} but not in the PATH, updating PATH to:" + PATH="/usr/local/bin:${PATH}" + echo $PATH + fi + ``` + +4. Clone this repository (optional, only needed to use `make all` to run all the steps automatically) + + ```Shell + git clone --recursive https://github.com/open-traffic-generator/otg-examples.git + cd otg-examples/docker-compose/b2b-pinning + ``` + +## Deploy Ixia-c lab + +1. Create veth pair `veth0 - veth1` + + ```Shell + sudo ip link add name veth0 type veth peer name veth1 + sudo ip link set dev veth0 up + sudo ip link set dev veth1 up + ``` + +2. Launch the deployment + + ```Shell + sudo docker-compose up -d + ``` + +4. Make sure you have all three containers running, check CPU pinning + + ```Shell + sudo docker ps + docker logs cpupin_traffic_engine_1_1 2>&1 | grep cores + docker logs cpupin_traffic_engine_2_1 2>&1 | grep cores + ``` + +## Run OTG traffic flows + +1. Download an example of OTG traffic flow configuration file: + + ```Shell + wget https://raw.githubusercontent.com/open-traffic-generator/otg-examples/main/docker-compose/b2b/otg.yml + ``` + +2. Start with using `otgen` to request Ixia-c to run traffic flows defined in `otg.yml`. If successful, the result will come as OTG port metrics in JSON format + + ```Shell + cat otg.yml | otgen run -k -a https://localhost:8443 + ``` + +3. You can now repeat this exercise, but transform output to a table + + ```Shell + cat otg.yml | otgen run -k -a https://localhost:8443 | otgen transform -m port | otgen display -m table + ``` + +4. The same, but with flow metrics + + ```Shell + cat otg.yml | otgen run -k -a https://localhost:8443 -m flow | otgen transform -m flow | otgen display -m table + ``` + +5. The same, but with byte instead of frame count (only receive stats are reported) + + ```Shell + cat otg.yml | otgen run -k -a https://localhost:8443 -m flow | otgen transform -m flow -c bytes | otgen display -m table + ``` + +6. Now report packet per second rate, as a line chart (end with `Crtl-c`) + + ```Shell + cat otg.yml | otgen run -k -a https://localhost:8443 -m flow | otgen transform -m flow -c pps | otgen display -m chart + ``` + +## Destroy the lab + +To destroy the lab, including veth pair, use: + +```Shell +docker-compose down +sudo ip link del name veth0 type veth peer name veth1 +``` + +## Credits + +* [Diana Galan](https://github.com/dgalan-xxia) is an author of `compose.yml` example. diff --git a/docker-compose/b2b-pinning/compose.yml b/docker-compose/b2b-pinning/compose.yml new file mode 100644 index 00000000..20806462 --- /dev/null +++ b/docker-compose/b2b-pinning/compose.yml @@ -0,0 +1,26 @@ +services: + controller: + image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 + command: --accept-eula --http-port 8443 + network_mode: "host" + restart: always + traffic_engine_1: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,3,4 + environment: + - OPT_LISTEN_PORT=5555 + - ARG_IFACE_LIST=virtual@af_packet,veth0 + - OPT_NO_HUGEPAGES=Yes + traffic_engine_2: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,5,6 + environment: + - OPT_LISTEN_PORT=5556 + - ARG_IFACE_LIST=virtual@af_packet,veth1 + - OPT_NO_HUGEPAGES=Yes diff --git a/docker-compose/b2b-pinning/diagram.png b/docker-compose/b2b-pinning/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..2c58aa5b5dbaa8925f8839febb953341c899efe7 GIT binary patch literal 48004 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 MxFcUAXA$&&0BJ#0S^xk5 literal 0 HcmV?d00001 diff --git a/docker-compose/b2b-pinning/otg.yml b/docker-compose/b2b-pinning/otg.yml new file mode 100644 index 00000000..4505d3d6 --- /dev/null +++ b/docker-compose/b2b-pinning/otg.yml @@ -0,0 +1,58 @@ +flows: +- name: p1-p2 + duration: + choice: fixed_packets + fixed_packets: + gap: 12 + packets: 1000000 + rate: + choice: pps + pps: 1000000 + size: + choice: fixed + fixed: 128 + metrics: + enable: true + loss: false + timestamps: false + packet: + - choice: ethernet + ethernet: + dst: + choice: value + value: 00:00:00:00:00:bb + src: + choice: value + value: 00:00:00:00:00:aa + - choice: ipv4 + ipv4: + dst: + choice: value + value: 192.0.2.1 + src: + choice: increment + increment: + start: 1.1.1.1 + step: 0.1.2.3 + count: 100 + - choice: tcp + tcp: + dst_port: + choice: value + value: 80 + src_port: + choice: increment + increment: + start: 23250 + step: 7 + count: 100 + tx_rx: + choice: port + port: + tx_name: p1 + rx_name: p2 +ports: +- location: localhost:5555 + name: p1 +- location: localhost:5556 + name: p2 \ No newline at end of file From 235b140017f06bdc3812699ca21831caeba0bb75 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 13:46:41 -0800 Subject: [PATCH 02/15] yaml --- docker-compose/b2b-pinning/README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docker-compose/b2b-pinning/README.md b/docker-compose/b2b-pinning/README.md index 5ee98f99..623532d9 100644 --- a/docker-compose/b2b-pinning/README.md +++ b/docker-compose/b2b-pinning/README.md @@ -29,8 +29,7 @@ Further due to a NUMA-related limitation with DPDK 19.11 used by Ixia-C Traffic needs to be same across all `traffic-engine` instances. In the example above, core number 2 is used for control in all three containers. - ```Shell - cat > compose.yml << EOF + ```Yaml services: controller: image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 @@ -57,7 +56,6 @@ needs to be same across all `traffic-engine` instances. In the example above, co - OPT_LISTEN_PORT=5556 - ARG_IFACE_LIST=virtual@af_packet,veth1 - OPT_NO_HUGEPAGES=Yes - EOF ``` ## System Prerequisites From fa1df236b278ec721a51c95fffb9261537bdc97a Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 13:47:09 -0800 Subject: [PATCH 03/15] ident --- docker-compose/b2b-pinning/README.md | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docker-compose/b2b-pinning/README.md b/docker-compose/b2b-pinning/README.md index 623532d9..9ed97901 100644 --- a/docker-compose/b2b-pinning/README.md +++ b/docker-compose/b2b-pinning/README.md @@ -29,34 +29,34 @@ Further due to a NUMA-related limitation with DPDK 19.11 used by Ixia-C Traffic needs to be same across all `traffic-engine` instances. In the example above, core number 2 is used for control in all three containers. - ```Yaml - services: - controller: - image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 - command: --accept-eula --http-port 8443 - network_mode: "host" - restart: always - traffic_engine_1: - image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 - network_mode: "host" - restart: always - privileged: true - cpuset: 2,3,4 - environment: - - OPT_LISTEN_PORT=5555 - - ARG_IFACE_LIST=virtual@af_packet,veth0 - - OPT_NO_HUGEPAGES=Yes - traffic_engine_2: - image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 - network_mode: "host" - restart: always - privileged: true - cpuset: 2,5,6 - environment: - - OPT_LISTEN_PORT=5556 - - ARG_IFACE_LIST=virtual@af_packet,veth1 - - OPT_NO_HUGEPAGES=Yes - ``` +```Yaml +services: + controller: + image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 + command: --accept-eula --http-port 8443 + network_mode: "host" + restart: always + traffic_engine_1: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,3,4 + environment: + - OPT_LISTEN_PORT=5555 + - ARG_IFACE_LIST=virtual@af_packet,veth0 + - OPT_NO_HUGEPAGES=Yes + traffic_engine_2: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,5,6 + environment: + - OPT_LISTEN_PORT=5556 + - ARG_IFACE_LIST=virtual@af_packet,veth1 + - OPT_NO_HUGEPAGES=Yes +``` ## System Prerequisites From bf32576b8b09665f12d50aee38abaafdaddfb5e3 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 13:47:52 -0800 Subject: [PATCH 04/15] ident fix --- docker-compose/b2b-pinning/README.md | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/docker-compose/b2b-pinning/README.md b/docker-compose/b2b-pinning/README.md index 9ed97901..767c9056 100644 --- a/docker-compose/b2b-pinning/README.md +++ b/docker-compose/b2b-pinning/README.md @@ -29,34 +29,34 @@ Further due to a NUMA-related limitation with DPDK 19.11 used by Ixia-C Traffic needs to be same across all `traffic-engine` instances. In the example above, core number 2 is used for control in all three containers. -```Yaml -services: - controller: - image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 - command: --accept-eula --http-port 8443 - network_mode: "host" - restart: always - traffic_engine_1: - image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 - network_mode: "host" - restart: always - privileged: true - cpuset: 2,3,4 - environment: - - OPT_LISTEN_PORT=5555 - - ARG_IFACE_LIST=virtual@af_packet,veth0 - - OPT_NO_HUGEPAGES=Yes - traffic_engine_2: - image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 - network_mode: "host" - restart: always - privileged: true - cpuset: 2,5,6 - environment: - - OPT_LISTEN_PORT=5556 - - ARG_IFACE_LIST=virtual@af_packet,veth1 - - OPT_NO_HUGEPAGES=Yes -``` + ```Yaml + services: + controller: + image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 + command: --accept-eula --http-port 8443 + network_mode: "host" + restart: always + traffic_engine_1: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,3,4 + environment: + - OPT_LISTEN_PORT=5555 + - ARG_IFACE_LIST=virtual@af_packet,veth0 + - OPT_NO_HUGEPAGES=Yes + traffic_engine_2: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,5,6 + environment: + - OPT_LISTEN_PORT=5556 + - ARG_IFACE_LIST=virtual@af_packet,veth1 + - OPT_NO_HUGEPAGES=Yes + ``` ## System Prerequisites From 5a8d88a1c66a72794ca7ae857fec62c97278b5a7 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 19:19:21 -0800 Subject: [PATCH 05/15] removed ARG_CORE_LIST --- docker-compose/b2b-pinning/README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/docker-compose/b2b-pinning/README.md b/docker-compose/b2b-pinning/README.md index 767c9056..d0230b48 100644 --- a/docker-compose/b2b-pinning/README.md +++ b/docker-compose/b2b-pinning/README.md @@ -10,23 +10,20 @@ This lab demonstrates how to maximize performance of [Ixia-c](https://github.com In the deployment steps listed below, two `traffic-engine` containers will be started. The table below describes parameters that are unique among them: -- **Listen Port**: Port on which the `traffic-engine` will listen to for communication with the `controller`. +- **Listen Port**: Port on which the `traffic-engine` will listen to for communication with the `controller` +- **Network Interfaces**: Interfaces on which the `traffic-engine` will transmit and receive traffic - **CPU Cores Allocated**: Each instance of `traffic-engine` uses three cores. Two dedicated cores are used for sending and receiving packets and one is used for configuration, control and statistics. In the example above all instances of `traffic-engine` are sharing core number 2 for the configuration, control and statistics while - instance 1 is using cores 3/4 for Tx/Rx, instance 2 is using cores 5/6 for Tx/Rx, and so on. + instance 1 is using cores 3/4 for Tx/Rx, instance 2 is using cores 5/6 for Tx/Rx, and so on -| Instance | Listen Port | Cores Allocated | vEth Interface Used | +| Instance | Listen Port | Cores Allocated | Network Interfaces | |----------|-------------|-----------------|-------------------------| | 1 | 5555 | 2, 3, 4 | veth0 | | 2 | 5556 | 2, 5, 6 | veth1 | -**Note**: The Tx/Rx cores allocated to a `traffic-engine` instance (using the ARG_CORE_LIST environment variable) -MUST NOT overlap across other such instances (even if they are idle and not sending/receiving any traffic). -Sharing Tx/Rx cores will result in undefined behavior including but not limited to loss of performance. -Further due to a NUMA-related limitation with DPDK 19.11 used by Ixia-C Traffic Engine, the core used for control -needs to be same across all `traffic-engine` instances. In the example above, core number 2 is used for control in all three containers. +**Note**: The Tx/Rx cores allocated to a `traffic-engine` instance using `cpuset` parameter MUST NOT overlap across other such instances (even if they are idle and not sending/receiving any traffic). Sharing Tx/Rx cores will result in undefined behavior including but not limited to loss of performance. Further due to a NUMA-related limitation with DPDK 19.11 used by Ixia-C Traffic Engine, the core used for control needs to be same across all `traffic-engine` instances. In the example above, core number 2 is used for control in all three containers. ```Yaml From 9ba2f1737eac03697fda778cf77e3b538ee4c0f6 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 19:30:17 -0800 Subject: [PATCH 06/15] makefile --- docker-compose/b2b-pinning/Makefile | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index b529b0f0..6b27fa32 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -43,17 +43,10 @@ veth0: /sys/class/net/veth0 sudo ip link add name veth0 type veth peer name veth1 sudo ip link set dev veth0 up sudo ip link set dev veth1 up - sudo sysctl net.ipv6.conf.veth0.disable_ipv6=1 - sudo sysctl net.ipv6.conf.veth1.disable_ipv6=1 - -network-mtu: - sudo ip link set veth0 mtu 9500 - sudo ip link set veth1 mtu 9500 network-clean: veth0-clean veth0-clean: -#TODO run only if veth0 exists - sudo ip link del name veth0 type veth peer name veth1 + -sudo ip link del name veth0 type veth peer name veth1 ############################### # Deploy lab @@ -73,22 +66,7 @@ remove-lab: ############################### .PHONY: run -run: network-mtu otgen-run otgen-run-as-table-port otgen-run-as-table-flow otgen-run-as-table-flow-bytes +run: otgen-run otgen-run: - cat otg.yml | otgen run -k -a https://localhost:8443 - -otgen-run-as-table-port: - @echo "cat otg.yml | otgen run -k -a https://localhost:8443 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformPortFramesTable.tmpl" - @echo "│Port│ FramesTx │ FramesRx │Port│ FramesTx │ FramesRx │" - @cat otg.yml | otgen run -k 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformPortFramesTable.tmpl - -otgen-run-as-table-flow: - @echo "cat otg.yml | otgen run -k -a https://localhost:8443 -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowFramesTable.tmpl" - @echo "│ Flow │ FramesTx │ FramesRx │" - @cat otg.yml | otgen run -k -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowFramesTable.tmpl - -otgen-run-as-table-flow-bytes: - @echo "cat otg.yml | otgen run -k -a https://localhost:8443 -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowBytesTable.tmpl" - @echo "│ Flow │ BytesTx │ BytesRx │" - @cat otg.yml | otgen run -k -m flow 2>/dev/null | otgen transform -f ../../submodules/otgen/templates/transformFlowBytesTable.tmpl \ No newline at end of file + otgen run -f otg.yml -k --api https://localhost:8443 -m flow | otgen transform -m flow -c pps | otgen display -m table From cbe9f99d1b866e0d67f0809a35b2ada3291fd41a Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 19:32:43 -0800 Subject: [PATCH 07/15] otgen install script --- docker-compose/b2b-pinning/Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index 6b27fa32..2c7528b6 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -23,9 +23,7 @@ install-docker-compose: /usr/local/bin/docker-compose install-otgen: /usr/local/bin/otgen /usr/local/bin/otgen: - curl -L "https://github.com/open-traffic-generator/otgen/releases/download/v0.2.0/otgen_0.2.0_$$(uname -s)_$$(uname -m).tar.gz" | tar xzv otgen - sudo mv otgen /usr/local/bin/otgen - sudo chmod +x /usr/local/bin/otgen + bash -c "$(curl -sL https://get.otgcdn.net/otgen)" -- -v 0.4.0 install-clean: -sudo rm -f `command -v docker-compose` From bf62c98203460006e70c63f46014cf12d4a63275 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 19:33:33 -0800 Subject: [PATCH 08/15] ignore errors on clean --- docker-compose/b2b-pinning/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index 2c7528b6..86a8e648 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -57,7 +57,7 @@ deploy-lab: sudo docker-compose up -d remove-lab: - sudo docker-compose down + -sudo docker-compose down ############################### # Run tests From 75bbb0c80a245d4d1d14def09a9ef5a73e063c6d Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 19:34:28 -0800 Subject: [PATCH 09/15] fix otgen install --- docker-compose/b2b-pinning/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index 86a8e648..c654e8d3 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -23,7 +23,7 @@ install-docker-compose: /usr/local/bin/docker-compose install-otgen: /usr/local/bin/otgen /usr/local/bin/otgen: - bash -c "$(curl -sL https://get.otgcdn.net/otgen)" -- -v 0.4.0 + bash -c "$$(curl -sL https://get.otgcdn.net/otgen)" -- -v 0.4.0 install-clean: -sudo rm -f `command -v docker-compose` From e2681511de42eccdb525dbbc79ae3fc9b2c22453 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 19:40:11 -0800 Subject: [PATCH 10/15] nopinning --- docker-compose/b2b-pinning/Makefile | 18 ++++++++++++- .../b2b-pinning/compose.nopinning.yml | 26 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 docker-compose/b2b-pinning/compose.nopinning.yml diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index c654e8d3..9e8c0a99 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -3,11 +3,17 @@ SHELL = /bin/bash .PHONY: all all: install network deploy run +.PHONY: all-nopinning +all: install network deploy-nopinning run + .PHONY: clean clean: remove-lab network-clean +.PHONY: clean-nopinning +clean: remove-lab-nopinning network-clean + .PHONY: clean-all -clean-all: clean install-clean +clean-all: clean clean-nopinning install-clean ############################### # Install components @@ -53,12 +59,22 @@ veth0-clean: .PHONY: deploy deploy: deploy-lab +.PHONY: deploy-nopinning +deploy: deploy-lab-nopinning + deploy-lab: sudo docker-compose up -d remove-lab: -sudo docker-compose down +deploy-lab-nopinning: + sudo docker-compose -f compose.nopinning.yml up -d + +remove-lab-nopinning: + -sudo docker-compose -f compose.nopinning.yml down + + ############################### # Run tests ############################### diff --git a/docker-compose/b2b-pinning/compose.nopinning.yml b/docker-compose/b2b-pinning/compose.nopinning.yml new file mode 100644 index 00000000..fdefff16 --- /dev/null +++ b/docker-compose/b2b-pinning/compose.nopinning.yml @@ -0,0 +1,26 @@ +services: + controller: + image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 + command: --accept-eula --http-port 8443 + network_mode: "host" + restart: always + traffic_engine_1: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + environment: + - OPT_LISTEN_PORT=5555 + - ARG_IFACE_LIST=virtual@af_packet,veth0 + - OPT_NO_HUGEPAGES=Yes + - OPT_NO_PINNING=Yes + traffic_engine_2: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + environment: + - OPT_LISTEN_PORT=5556 + - ARG_IFACE_LIST=virtual@af_packet,veth1 + - OPT_NO_HUGEPAGES=Yes + - OPT_NO_PINNING=Yes From 3d60b4ebb3d013c8b7a5576b7d6f91c8d3da56cb Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 19:41:22 -0800 Subject: [PATCH 11/15] fix --- docker-compose/b2b-pinning/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index 9e8c0a99..68ed589a 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -60,7 +60,7 @@ veth0-clean: deploy: deploy-lab .PHONY: deploy-nopinning -deploy: deploy-lab-nopinning +deploy-nopinning: deploy-lab-nopinning deploy-lab: sudo docker-compose up -d From b585182d58999c106ca84f5d2846127ce4ec5b86 Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 21:39:18 -0800 Subject: [PATCH 12/15] nopin --- docker-compose/b2b-pinning/Makefile | 22 +++++++++---------- ...ompose.nopinning.yml => compose.nopin.yml} | 0 2 files changed, 11 insertions(+), 11 deletions(-) rename docker-compose/b2b-pinning/{compose.nopinning.yml => compose.nopin.yml} (100%) diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index 68ed589a..3cbdb040 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -3,17 +3,17 @@ SHELL = /bin/bash .PHONY: all all: install network deploy run -.PHONY: all-nopinning -all: install network deploy-nopinning run +.PHONY: all-nopin +all-nopin: install network deploy-nopin run .PHONY: clean clean: remove-lab network-clean -.PHONY: clean-nopinning -clean: remove-lab-nopinning network-clean +.PHONY: clean-nopin +clean-nopin: remove-lab-nopin network-clean .PHONY: clean-all -clean-all: clean clean-nopinning install-clean +clean-all: clean clean-nopin install-clean ############################### # Install components @@ -59,8 +59,8 @@ veth0-clean: .PHONY: deploy deploy: deploy-lab -.PHONY: deploy-nopinning -deploy-nopinning: deploy-lab-nopinning +.PHONY: deploy-nopin +deploy-nopin: deploy-lab-nopin deploy-lab: sudo docker-compose up -d @@ -68,11 +68,11 @@ deploy-lab: remove-lab: -sudo docker-compose down -deploy-lab-nopinning: - sudo docker-compose -f compose.nopinning.yml up -d +deploy-lab-nopin: + sudo docker-compose -f compose.nopin.yml up -d -remove-lab-nopinning: - -sudo docker-compose -f compose.nopinning.yml down +remove-lab-nopin: + -sudo docker-compose -f compose.nopin.yml down ############################### diff --git a/docker-compose/b2b-pinning/compose.nopinning.yml b/docker-compose/b2b-pinning/compose.nopin.yml similarity index 100% rename from docker-compose/b2b-pinning/compose.nopinning.yml rename to docker-compose/b2b-pinning/compose.nopin.yml From aafeebf898c2f43d00b59e2d0b4f825047cb9d7a Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 21:42:57 -0800 Subject: [PATCH 13/15] argpin --- docker-compose/b2b-pinning/Makefile | 17 ++++++++++- docker-compose/b2b-pinning/compose.pinarg.yml | 28 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 docker-compose/b2b-pinning/compose.pinarg.yml diff --git a/docker-compose/b2b-pinning/Makefile b/docker-compose/b2b-pinning/Makefile index 3cbdb040..538b91fe 100644 --- a/docker-compose/b2b-pinning/Makefile +++ b/docker-compose/b2b-pinning/Makefile @@ -6,14 +6,20 @@ all: install network deploy run .PHONY: all-nopin all-nopin: install network deploy-nopin run +.PHONY: all-argpin +all-argpin: install network deploy-argpin run + .PHONY: clean clean: remove-lab network-clean .PHONY: clean-nopin clean-nopin: remove-lab-nopin network-clean +.PHONY: clean-argpin +clean-argpin: remove-lab-argpin network-clean + .PHONY: clean-all -clean-all: clean clean-nopin install-clean +clean-all: clean clean-nopin clean-argpin install-clean ############################### # Install components @@ -62,6 +68,9 @@ deploy: deploy-lab .PHONY: deploy-nopin deploy-nopin: deploy-lab-nopin +.PHONY: deploy-argpin +deploy-argpin: deploy-lab-argpin + deploy-lab: sudo docker-compose up -d @@ -74,6 +83,12 @@ deploy-lab-nopin: remove-lab-nopin: -sudo docker-compose -f compose.nopin.yml down +deploy-lab-argpin: + sudo docker-compose -f compose.argpin.yml up -d + +remove-lab-argpin: + -sudo docker-compose -f compose.argpin.yml down + ############################### # Run tests diff --git a/docker-compose/b2b-pinning/compose.pinarg.yml b/docker-compose/b2b-pinning/compose.pinarg.yml new file mode 100644 index 00000000..2dd12b19 --- /dev/null +++ b/docker-compose/b2b-pinning/compose.pinarg.yml @@ -0,0 +1,28 @@ +services: + controller: + image: ghcr.io/open-traffic-generator/ixia-c-controller:0.0.1-3724 + command: --accept-eula --http-port 8443 + network_mode: "host" + restart: always + traffic_engine_1: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,3,4 + environment: + - OPT_LISTEN_PORT=5555 + - ARG_IFACE_LIST=virtual@af_packet,veth0 + - ARG_CORE_LIST=2,3,4 + - OPT_NO_HUGEPAGES=Yes + traffic_engine_2: + image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 + network_mode: "host" + restart: always + privileged: true + cpuset: 2,5,6 + environment: + - OPT_LISTEN_PORT=5556 + - ARG_IFACE_LIST=virtual@af_packet,veth1 + - ARG_CORE_LIST=2,5,6 + - OPT_NO_HUGEPAGES=Yes From 05869509e0e3b91934203a3a3b831a241968b05e Mon Sep 17 00:00:00 2001 From: Alex Bortok Date: Tue, 14 Feb 2023 21:43:41 -0800 Subject: [PATCH 14/15] argpin rename --- .../b2b-pinning/{compose.pinarg.yml => compose.argpin.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docker-compose/b2b-pinning/{compose.pinarg.yml => compose.argpin.yml} (100%) diff --git a/docker-compose/b2b-pinning/compose.pinarg.yml b/docker-compose/b2b-pinning/compose.argpin.yml similarity index 100% rename from docker-compose/b2b-pinning/compose.pinarg.yml rename to docker-compose/b2b-pinning/compose.argpin.yml From 6de062cfc42839e288ae64725dd23b107bebde3d Mon Sep 17 00:00:00 2001 From: Daniel-Florin Dosaru Date: Wed, 15 Feb 2023 16:12:10 +0200 Subject: [PATCH 15/15] Update compose.argpin.yml The traffic engine expects a space separated list of core ids for the ARG_CORE_LIST parameter, not a comma separated one. --- docker-compose/b2b-pinning/compose.argpin.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose/b2b-pinning/compose.argpin.yml b/docker-compose/b2b-pinning/compose.argpin.yml index 2dd12b19..c36076c2 100644 --- a/docker-compose/b2b-pinning/compose.argpin.yml +++ b/docker-compose/b2b-pinning/compose.argpin.yml @@ -13,7 +13,7 @@ services: environment: - OPT_LISTEN_PORT=5555 - ARG_IFACE_LIST=virtual@af_packet,veth0 - - ARG_CORE_LIST=2,3,4 + - ARG_CORE_LIST=2 3 4 - OPT_NO_HUGEPAGES=Yes traffic_engine_2: image: ghcr.io/open-traffic-generator/ixia-c-traffic-engine:1.6.0.24 @@ -24,5 +24,5 @@ services: environment: - OPT_LISTEN_PORT=5556 - ARG_IFACE_LIST=virtual@af_packet,veth1 - - ARG_CORE_LIST=2,5,6 + - ARG_CORE_LIST=2 5 6 - OPT_NO_HUGEPAGES=Yes