laforge has submitted this change. (
https://gerrit.osmocom.org/c/upf-benchmark/+/39468?usp=email )
Change subject: gtplab-sysmo2025: Initial tunend test setup
......................................................................
gtplab-sysmo2025: Initial tunend test setup
Change-Id: I834b62d29c8dcf2553fc665821135fb08a8bae9e
---
A testsuites/gtplab-sysmo2025/tunend/README.md
A testsuites/gtplab-sysmo2025/tunend/cpf/0.gtp_flood.vty
A testsuites/gtplab-sysmo2025/tunend/cpf/configure.sh
A testsuites/gtplab-sysmo2025/tunend/cpf/gen_gtpu_concurrent_ue_addr_range.py
A testsuites/gtplab-sysmo2025/tunend/cpf/osmo-upf-load-gen.cfg
A testsuites/gtplab-sysmo2025/tunend/cpf/run.sh
A testsuites/gtplab-sysmo2025/tunend/topology.dot
A testsuites/gtplab-sysmo2025/tunend/trex/configure.sh
A testsuites/gtplab-sysmo2025/tunend/trex/gtpu_topo.py
A testsuites/gtplab-sysmo2025/tunend/trex/run.sh
A testsuites/gtplab-sysmo2025/tunend/trex/trex_cfg.yaml
A testsuites/gtplab-sysmo2025/tunend/trex/udp_simple.py
A testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/configure.sh
A testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/osmo-upf.cfg
A testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/run.sh
15 files changed, 549 insertions(+), 0 deletions(-)
Approvals:
laforge: Looks good to me, approved
Jenkins Builder: Verified
osmith: Looks good to me, but someone else must approve
diff --git a/testsuites/gtplab-sysmo2025/tunend/README.md
b/testsuites/gtplab-sysmo2025/tunend/README.md
new file mode 100644
index 0000000..7a20f3a
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/README.md
@@ -0,0 +1,17 @@
+In this testsuite, TRex is used to generate Uplink GTPU traffic on the RAN side
+towards UPF on its 1st iface and which which should be sent back decapsulated
+(tunend) towards CN and received at TRex 2nd interface.
+
+The GTPU traffic is generated by gtp_1pkt_simply.py profile passed to TRex,
+which emulates <enb-ip-addr,TEID> sessions based on parameters passed through
+trex-console when launching the test, and which should match those configured in
+cpf/0.gtp_flood.vty used by osmo-upf-load-gen to allocated the sessions at the
+UPF.
+
+```
+[trex-ran](172.16.32.{2-101}) ----GTPU--> ()[upf]
+ |
+[trex-cn](172.16.31.{100-200}) <----IP---- ()[upf]
+```
+
+See topoology.dot for a more detailed graph.
\ No newline at end of file
diff --git a/testsuites/gtplab-sysmo2025/tunend/cpf/0.gtp_flood.vty
b/testsuites/gtplab-sysmo2025/tunend/cpf/0.gtp_flood.vty
new file mode 100644
index 0000000..6f4d605
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/cpf/0.gtp_flood.vty
@@ -0,0 +1,133 @@
+# Establish N PFCP sessions for tunend, and emit massive GTP traffic to the UPF
+# to each established tunnel.
+#
+# osmo-upf-load-gen UPF "internet host"
+# |GTP-ep -------GTP-----> GTP-ep|UE-IP-addr -------IP------> arbitrary-IP|
+# |172.16.32.2 172.16.32.1|192.168.10.23 123.234.42.23|
+# |172.16.32.3
+# ^ ^ ^
+# ^ | | |
+# | | configure by configure by
+# configure by from UPF 'ue ip' 'payload target
ip',
+# 'gtp local' ("F-TEID=choose")
'payload target port'
+
+# Configure one or more local GTP endpoints to emit GTP packets from.
+# Established sessions will use these round-robin.
+no gtp local bind
+gtp local 172.16.32.2 2152 ue-ip-range 193.0.0.0 193.0.255.255
+gtp local 172.16.32.3 2152 ue-ip-range 193.1.0.0 193.1.255.255
+gtp local 172.16.32.4 2152 ue-ip-range 193.2.0.0 193.2.255.255
+gtp local 172.16.32.5 2152 ue-ip-range 193.3.0.0 193.3.255.255
+gtp local 172.16.32.6 2152 ue-ip-range 193.4.0.0 193.4.255.255
+gtp local 172.16.32.7 2152 ue-ip-range 193.5.0.0 193.5.255.255
+gtp local 172.16.32.8 2152 ue-ip-range 193.6.0.0 193.6.255.255
+gtp local 172.16.32.9 2152 ue-ip-range 193.7.0.0 193.7.255.255
+gtp local 172.16.32.10 2152 ue-ip-range 193.8.0.0 193.8.255.255
+gtp local 172.16.32.11 2152 ue-ip-range 193.9.0.0 193.9.255.255
+gtp local 172.16.32.12 2152 ue-ip-range 193.10.0.0 193.10.255.255
+gtp local 172.16.32.13 2152 ue-ip-range 193.11.0.0 193.11.255.255
+gtp local 172.16.32.14 2152 ue-ip-range 193.12.0.0 193.12.255.255
+gtp local 172.16.32.15 2152 ue-ip-range 193.13.0.0 193.13.255.255
+gtp local 172.16.32.16 2152 ue-ip-range 193.14.0.0 193.14.255.255
+gtp local 172.16.32.17 2152 ue-ip-range 193.15.0.0 193.15.255.255
+gtp local 172.16.32.18 2152 ue-ip-range 193.16.0.0 193.16.255.255
+gtp local 172.16.32.19 2152 ue-ip-range 193.17.0.0 193.17.255.255
+gtp local 172.16.32.20 2152 ue-ip-range 193.18.0.0 193.18.255.255
+gtp local 172.16.32.21 2152 ue-ip-range 193.19.0.0 193.19.255.255
+gtp local 172.16.32.22 2152 ue-ip-range 193.20.0.0 193.20.255.255
+gtp local 172.16.32.23 2152 ue-ip-range 193.21.0.0 193.21.255.255
+gtp local 172.16.32.24 2152 ue-ip-range 193.22.0.0 193.22.255.255
+gtp local 172.16.32.25 2152 ue-ip-range 193.23.0.0 193.23.255.255
+gtp local 172.16.32.26 2152 ue-ip-range 193.24.0.0 193.24.255.255
+gtp local 172.16.32.27 2152 ue-ip-range 193.25.0.0 193.25.255.255
+gtp local 172.16.32.28 2152 ue-ip-range 193.26.0.0 193.26.255.255
+gtp local 172.16.32.29 2152 ue-ip-range 193.27.0.0 193.27.255.255
+gtp local 172.16.32.30 2152 ue-ip-range 193.28.0.0 193.28.255.255
+gtp local 172.16.32.31 2152 ue-ip-range 193.29.0.0 193.29.255.255
+gtp local 172.16.32.32 2152 ue-ip-range 193.30.0.0 193.30.255.255
+gtp local 172.16.32.33 2152 ue-ip-range 193.31.0.0 193.31.255.255
+gtp local 172.16.32.34 2152 ue-ip-range 193.32.0.0 193.32.255.255
+gtp local 172.16.32.35 2152 ue-ip-range 193.33.0.0 193.33.255.255
+gtp local 172.16.32.36 2152 ue-ip-range 193.34.0.0 193.34.255.255
+gtp local 172.16.32.37 2152 ue-ip-range 193.35.0.0 193.35.255.255
+gtp local 172.16.32.38 2152 ue-ip-range 193.36.0.0 193.36.255.255
+gtp local 172.16.32.39 2152 ue-ip-range 193.37.0.0 193.37.255.255
+gtp local 172.16.32.40 2152 ue-ip-range 193.38.0.0 193.38.255.255
+gtp local 172.16.32.41 2152 ue-ip-range 193.39.0.0 193.39.255.255
+gtp local 172.16.32.42 2152 ue-ip-range 193.40.0.0 193.40.255.255
+gtp local 172.16.32.43 2152 ue-ip-range 193.41.0.0 193.41.255.255
+gtp local 172.16.32.44 2152 ue-ip-range 193.42.0.0 193.42.255.255
+gtp local 172.16.32.45 2152 ue-ip-range 193.43.0.0 193.43.255.255
+gtp local 172.16.32.46 2152 ue-ip-range 193.44.0.0 193.44.255.255
+gtp local 172.16.32.47 2152 ue-ip-range 193.45.0.0 193.45.255.255
+gtp local 172.16.32.48 2152 ue-ip-range 193.46.0.0 193.46.255.255
+gtp local 172.16.32.49 2152 ue-ip-range 193.47.0.0 193.47.255.255
+gtp local 172.16.32.50 2152 ue-ip-range 193.48.0.0 193.48.255.255
+gtp local 172.16.32.51 2152 ue-ip-range 193.49.0.0 193.49.255.255
+gtp local 172.16.32.52 2152 ue-ip-range 193.50.0.0 193.50.255.255
+gtp local 172.16.32.53 2152 ue-ip-range 193.51.0.0 193.51.255.255
+gtp local 172.16.32.54 2152 ue-ip-range 193.52.0.0 193.52.255.255
+gtp local 172.16.32.55 2152 ue-ip-range 193.53.0.0 193.53.255.255
+gtp local 172.16.32.56 2152 ue-ip-range 193.54.0.0 193.54.255.255
+gtp local 172.16.32.57 2152 ue-ip-range 193.55.0.0 193.55.255.255
+gtp local 172.16.32.58 2152 ue-ip-range 193.56.0.0 193.56.255.255
+gtp local 172.16.32.59 2152 ue-ip-range 193.57.0.0 193.57.255.255
+gtp local 172.16.32.60 2152 ue-ip-range 193.58.0.0 193.58.255.255
+gtp local 172.16.32.61 2152 ue-ip-range 193.59.0.0 193.59.255.255
+gtp local 172.16.32.62 2152 ue-ip-range 193.60.0.0 193.60.255.255
+gtp local 172.16.32.63 2152 ue-ip-range 193.61.0.0 193.61.255.255
+gtp local 172.16.32.64 2152 ue-ip-range 193.62.0.0 193.62.255.255
+gtp local 172.16.32.65 2152 ue-ip-range 193.63.0.0 193.63.255.255
+gtp local 172.16.32.66 2152 ue-ip-range 193.64.0.0 193.64.255.255
+gtp local 172.16.32.67 2152 ue-ip-range 193.65.0.0 193.65.255.255
+gtp local 172.16.32.68 2152 ue-ip-range 193.66.0.0 193.66.255.255
+gtp local 172.16.32.69 2152 ue-ip-range 193.67.0.0 193.67.255.255
+gtp local 172.16.32.70 2152 ue-ip-range 193.68.0.0 193.68.255.255
+gtp local 172.16.32.71 2152 ue-ip-range 193.69.0.0 193.69.255.255
+gtp local 172.16.32.72 2152 ue-ip-range 193.70.0.0 193.70.255.255
+gtp local 172.16.32.73 2152 ue-ip-range 193.71.0.0 193.71.255.255
+gtp local 172.16.32.74 2152 ue-ip-range 193.72.0.0 193.72.255.255
+gtp local 172.16.32.75 2152 ue-ip-range 193.73.0.0 193.73.255.255
+gtp local 172.16.32.76 2152 ue-ip-range 193.74.0.0 193.74.255.255
+gtp local 172.16.32.77 2152 ue-ip-range 193.75.0.0 193.75.255.255
+gtp local 172.16.32.78 2152 ue-ip-range 193.76.0.0 193.76.255.255
+gtp local 172.16.32.79 2152 ue-ip-range 193.77.0.0 193.77.255.255
+gtp local 172.16.32.80 2152 ue-ip-range 193.78.0.0 193.78.255.255
+gtp local 172.16.32.81 2152 ue-ip-range 193.79.0.0 193.79.255.255
+gtp local 172.16.32.82 2152 ue-ip-range 193.80.0.0 193.80.255.255
+gtp local 172.16.32.83 2152 ue-ip-range 193.81.0.0 193.81.255.255
+gtp local 172.16.32.84 2152 ue-ip-range 193.82.0.0 193.82.255.255
+gtp local 172.16.32.85 2152 ue-ip-range 193.83.0.0 193.83.255.255
+gtp local 172.16.32.86 2152 ue-ip-range 193.84.0.0 193.84.255.255
+gtp local 172.16.32.87 2152 ue-ip-range 193.85.0.0 193.85.255.255
+gtp local 172.16.32.88 2152 ue-ip-range 193.86.0.0 193.86.255.255
+gtp local 172.16.32.89 2152 ue-ip-range 193.87.0.0 193.87.255.255
+gtp local 172.16.32.90 2152 ue-ip-range 193.88.0.0 193.88.255.255
+gtp local 172.16.32.91 2152 ue-ip-range 193.89.0.0 193.89.255.255
+gtp local 172.16.32.92 2152 ue-ip-range 193.90.0.0 193.90.255.255
+gtp local 172.16.32.93 2152 ue-ip-range 193.91.0.0 193.91.255.255
+gtp local 172.16.32.94 2152 ue-ip-range 193.92.0.0 193.92.255.255
+gtp local 172.16.32.95 2152 ue-ip-range 193.93.0.0 193.93.255.255
+gtp local 172.16.32.96 2152 ue-ip-range 193.94.0.0 193.94.255.255
+gtp local 172.16.32.97 2152 ue-ip-range 193.95.0.0 193.95.255.255
+gtp local 172.16.32.98 2152 ue-ip-range 193.96.0.0 193.96.255.255
+gtp local 172.16.32.99 2152 ue-ip-range 193.97.0.0 193.97.255.255
+gtp local 172.16.32.100 2152 ue-ip-range 193.98.0.0 193.98.255.255
+gtp local 172.16.32.101 2152 ue-ip-range 193.99.0.0 193.99.255.255
+
+
+gtp core 172.16.32.200
+
+# now associate with UPF and start N sessions.
+pfcp-peer 172.16.31.2
+ tx assoc-setup-req
+ sleep 1
+ date
+
+ n 200000 session create tunend
+ wait responses
+ # All sessions established
+ date
+
+# give some time to gather counters before the tunnel is removed
+sleep 999999
diff --git a/testsuites/gtplab-sysmo2025/tunend/cpf/configure.sh
b/testsuites/gtplab-sysmo2025/tunend/cpf/configure.sh
new file mode 100755
index 0000000..2b24a65
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/cpf/configure.sh
@@ -0,0 +1 @@
+#!/bin/bash -xe
diff --git a/testsuites/gtplab-sysmo2025/tunend/cpf/gen_gtpu_concurrent_ue_addr_range.py
b/testsuites/gtplab-sysmo2025/tunend/cpf/gen_gtpu_concurrent_ue_addr_range.py
new file mode 100755
index 0000000..926381f
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/cpf/gen_gtpu_concurrent_ue_addr_range.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python3
+import argparse
+
+def inc_addr(addr_str, inc):
+ li = addr_str.split(".")
+ num_0 = (int(li[0]) << (3*8))
+ num_1 = (int(li[1]) << (2*8))
+ num_2 = (int(li[2]) << (1*8))
+ num_3 = int(li[3])
+ num = num_0 | num_1 | num_2 | num_3
+ num += inc
+ li[0] = str((num >> (3*8)) & 0xff)
+ li[1] = str((num >> (2*8)) & 0xff)
+ li[2] = str((num >> (1*8)) & 0xff)
+ li[3] = str(num & 0xff)
+ return ".".join(li)
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument('--num-streams',
+ type=int,
+ default=200000,
+ help="The number of streams (UE sessions).")
+parser.add_argument('--num-addrs',
+ type=int,
+ default=100,
+ help="The number of src IP addresses.")
+parser.add_argument('--gtp-local-port',
+ type=int,
+ default=2152,
+ help="The GTPU local port, 2152 by default")
+parser.add_argument('--gtp-local-addr',
+ type=str,
+ default='172.16.32.2',
+ help='The first GTPU local IP address in the concurrent list')
+parser.add_argument('--ue-addr',
+ type=str,
+ default='193.0.0.0',
+ help='The first UE IP address in the concurrent list')
+
+args = parser.parse_args()
+
+streams_per_tun = (args.num_streams // args.num_addrs)
+total_ue_addr_end = inc_addr(args.ue_addr, args.num_streams - 1)
+print("# num-streams: %d, num-addrs: %d, UE sessions per GTPU address: %d"
%(args.num_streams, args.num_addrs, streams_per_tun))
+print("# start UE addr: %s, end UE addr: %s" %(args.ue_addr,
total_ue_addr_end))
+
+for addr_idx in range(args.num_addrs):
+ gtp_local_addr = inc_addr(args.gtp_local_addr, addr_idx)
+ ue_addr_start = '193.%d.0.0' % addr_idx
+ ue_addr_end = inc_addr(ue_addr_start, streams_per_tun - 1)
+ print("gtp local %s\t%d ue-ip-range %s\t%s" % (gtp_local_addr,
args.gtp_local_port, ue_addr_start, ue_addr_end))
diff --git a/testsuites/gtplab-sysmo2025/tunend/cpf/osmo-upf-load-gen.cfg
b/testsuites/gtplab-sysmo2025/tunend/cpf/osmo-upf-load-gen.cfg
new file mode 100644
index 0000000..6e80e6e
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/cpf/osmo-upf-load-gen.cfg
@@ -0,0 +1,12 @@
+log stderr
+ logging color 1
+ logging print category-hex 0
+ logging print category 1
+ logging timestamp 0
+ logging print file basename last
+ logging print level 1
+ logging level set-all info
+ logging level lpfcp error
+
+local-addr 0.0.0.0
+listen
diff --git a/testsuites/gtplab-sysmo2025/tunend/cpf/run.sh
b/testsuites/gtplab-sysmo2025/tunend/cpf/run.sh
new file mode 100755
index 0000000..fb65c2b
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/cpf/run.sh
@@ -0,0 +1,5 @@
+#!/bin/bash -xe
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &>
/dev/null && pwd )
+
+osmo-upf-load-gen -c "$SCRIPT_DIR/osmo-upf-load-gen.cfg"
"$SCRIPT_DIR/0.gtp_flood.vty"
diff --git a/testsuites/gtplab-sysmo2025/tunend/topology.dot
b/testsuites/gtplab-sysmo2025/tunend/topology.dot
new file mode 100644
index 0000000..7a10319
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/topology.dot
@@ -0,0 +1,40 @@
+digraph G {
+ rankdir=TB;
+ labelloc=t;
+ label="gtplab @ sysmocom";
+
+ subgraph cluster_gtplab2 {
+ label="TRex (gtplab2)";
+ trex [label="TRex",shape=box3d];
+ gtplab2_172_32 [label="172.16.32.{2-101}/24"];
+ gtplab2_172_31 [label="172.16.31.{100-200}/24"];
+ }
+ subgraph cluster_switch {
+ label="Switch (100gb)";
+ switch_vlan1 [label="vlan1"];
+ switch_vlan2 [label="vlan2"];
+ }
+ subgraph cluster_gtplab1 {
+ label="UPF (gtplab1)";
+ gtplab1_172_31 [label="172.16.31.2/24"];
+ gtplab1_172_32 [label="172.16.32.1/24"];
+
+ upf [label="UPF\ntunend",shape=box3d];
+ }
+ subgraph cluster_gtplab0 {
+ label="CPF (gtplab0)";
+ rankdir=TB;
+ gtplab0_172_31 [label="172.16.31.1/24"];
+ pfcp_tool [label="osmo-udp-load-gen",shape=box3d];
+ }
+
+
+ pfcp_tool -> gtplab0_172_31 -> switch_vlan1 -> gtplab1_172_31 -> upf
[label="PFCP",dir=both,style=dashed,color=black];
+
+ trex -> gtplab2_172_32 -> switch_vlan2 -> gtplab1_172_32 -> upf
[label="GTPU UL (RAN)",style=bold, color=red];
+ upf -> gtplab1_172_31 -> switch_vlan1 -> gtplab2_172_31 -> trex
[label="IP UL (CN)",style=bold, color=purple];
+
+ trex -> gtplab2_172_31 -> switch_vlan1 -> gtplab1_172_31 -> upf
[label="IP DL (CN)",style=bold,color=blue];
+ upf -> gtplab1_172_32 -> switch_vlan2 -> gtplab2_172_32 -> trex
[label="GTPU DL (RAN)",style=bold,color=darkgreen];
+
+}
diff --git a/testsuites/gtplab-sysmo2025/tunend/trex/configure.sh
b/testsuites/gtplab-sysmo2025/tunend/trex/configure.sh
new file mode 100755
index 0000000..aa3b97e
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/trex/configure.sh
@@ -0,0 +1,8 @@
+#!/bin/bash -xe
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &>
/dev/null && pwd )
+
+sudo sysctl -w vm.nr_hugepages=4096
+
+cd /opt/trex
+sudo /opt/trex/t-rex-64 -i --astf --software --tso-disable --no-scapy-server --cfg
"${SCRIPT_DIR}/trex_cfg.yaml" --no-ofed-check
diff --git a/testsuites/gtplab-sysmo2025/tunend/trex/gtpu_topo.py
b/testsuites/gtplab-sysmo2025/tunend/trex/gtpu_topo.py
new file mode 100644
index 0000000..9c8223c
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/trex/gtpu_topo.py
@@ -0,0 +1,49 @@
+from trex.astf.api import *
+from trex.astf.tunnels_topo import TunnelsTopo
+import argparse
+
+def calc_src_addr(addr_str, inc):
+ li = addr_str.split(".")
+ num_0 = (int(li[0]) << (3*8))
+ num_1 = (int(li[1]) << (2*8))
+ num_2 = (int(li[2]) << (1*8))
+ num_3 = int(li[3])
+ num = num_0 | num_1 | num_2 | num_3
+ num += inc
+ li[0] = str((num >> (3*8)) & 0xff)
+ li[1] = str((num >> (2*8)) & 0xff)
+ li[2] = str((num >> (1*8)) & 0xff)
+ li[3] = str(num & 0xff)
+ return ".".join(li)
+
+
+def add_tun(topo, num_streams, num_addrs, tun_idx):
+ streams_per_tun = num_streams // num_addrs
+ src_gtpu_ip = calc_src_addr('172.16.32.2', tun_idx)
+ start_teid = 0x00000001 + tun_idx
+ teid_jump = 1*num_addrs
+ src_start = '193.%d.0.0' % tun_idx
+ src_end = calc_src_addr(src_start, streams_per_tun)
+ topo.add_tunnel_ctx(
+ src_start = src_start,
+ src_end = src_end,
+ initial_teid = start_teid,
+ teid_jump = teid_jump,
+ sport = 2152,
+ version = 4,
+ tunnel_type = 1,
+ src_ip = src_gtpu_ip,
+ dst_ip = '172.16.32.1',
+ activate = True
+ )
+
+
+def get_topo(**kwargs):
+ print("get_topo params: %r" % (kwargs))
+ num_streams = kwargs.get('num-streams', 1)
+ num_addrs = kwargs.get('num-addrs', 1)
+ topo = TunnelsTopo()
+
+ for tun_idx in range(num_addrs):
+ add_tun(topo, num_streams, num_addrs, tun_idx)
+ return topo
diff --git a/testsuites/gtplab-sysmo2025/tunend/trex/run.sh
b/testsuites/gtplab-sysmo2025/tunend/trex/run.sh
new file mode 100755
index 0000000..0bc0b73
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/trex/run.sh
@@ -0,0 +1,28 @@
+#!/bin/bash -xe
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &>
/dev/null && pwd )
+
+# see
https://trex-tgn.cisco.com/trex/doc/trex_astf.html#_gtpu_traffic_tutorials
+
+NUM_STREAMS=200000
+NUM_ADDRS=100
+
+set +x
+echo "To start the test, run: >"
+echo "tunnel --type gtpu;"
+echo "tunnels_topo load -f ${SCRIPT_DIR}/gtpu_topo.py -t
num-streams=${NUM_STREAMS},num-addrs=${NUM_ADDRS};"
+echo "start -f ${SCRIPT_DIR}/udp_simple.py -m 50000 -d 600 -t
num-streams=${NUM_STREAMS},num-addrs=${NUM_ADDRS},dir=ul;"
+echo ""
+printf "Once the test finished, run: >\ntunnel --type gtpu --off;\n
stats\n"
+set -x
+# Needs to be executed from /opt/trex ...
+cd /opt/trex/
+/opt/trex/trex-console
+
+# Troubleshooting:
+# > portattr
+# > service
+# > ping -p 0 -d 172.16.32.1 -n 3
+# > ping -p 1 -d 172.16.31.2 -n 3
+# > service --off
+# > tunnels_topo show
diff --git a/testsuites/gtplab-sysmo2025/tunend/trex/trex_cfg.yaml
b/testsuites/gtplab-sysmo2025/tunend/trex/trex_cfg.yaml
new file mode 100644
index 0000000..26dfe65
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/trex/trex_cfg.yaml
@@ -0,0 +1,23 @@
+### Config file generated by dpdk_setup_ports.py ###
+
+- version: 2
+ interfaces: ['02:00.0', '02:00.1']
+ c: 10
+ rx_desc: 4096
+ tx_desc: 4096
+ port_info:
+ - ip: 172.16.32.2
+ default_gw: 172.16.32.1
+ - ip: 172.16.31.200
+ default_gw: 172.16.31.2
+
+ platform:
+ master_thread_id: 0
+ latency_thread_id: 1
+ dual_if:
+ - socket: 0
+ threads: [2,3,4,5,6,7,8,9,10,11]
+
+ memory:
+ mbuf_2048: 128000
+
diff --git a/testsuites/gtplab-sysmo2025/tunend/trex/udp_simple.py
b/testsuites/gtplab-sysmo2025/tunend/trex/udp_simple.py
new file mode 100644
index 0000000..99ef6d4
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/trex/udp_simple.py
@@ -0,0 +1,93 @@
+from trex.astf.api import *
+import argparse
+
+ul_pkt = (1400*'x')
+dl_pkt = (1400*'y')
+
+class Prof1():
+ def __init__(self):
+ pass
+
+ def calc_src_addr(self, addr_str, inc):
+ li = addr_str.split(".")
+ num_0 = (int(li[0]) << (3*8))
+ num_1 = (int(li[1]) << (2*8))
+ num_2 = (int(li[2]) << (1*8))
+ num_3 = int(li[3])
+ num = num_0 | num_1 | num_2 | num_3
+ num += inc
+ li[0] = str((num >> (3*8)) & 0xff)
+ li[1] = str((num >> (2*8)) & 0xff)
+ li[2] = str((num >> (1*8)) & 0xff)
+ li[3] = str(num & 0xff)
+ return ".".join(li)
+
+ def create_ip_gen(self, prog_c, prog_s, addr_idx):
+ # ip generator
+ start_ms_addr = "193.%d.0.0" % addr_idx
+ end_ms_addr = self.calc_src_addr(start_ms_addr, (self.num_streams //
self.num_addrs) - 1)
+ start_srv_addr = "48.0.0.1"
+ end_srv_addr = self.calc_src_addr(start_srv_addr, self.num_addrs - 1)
+ ip_gen_c = ASTFIPGenDist(ip_range=[start_ms_addr, end_ms_addr],
distribution="seq")
+ ip_gen_s = ASTFIPGenDist(ip_range=[start_srv_addr, end_srv_addr],
distribution="seq")
+ ip_gen = ASTFIPGen(glob=ASTFIPGenGlobal(ip_offset="1.0.0.0"),
+ dist_client=ip_gen_c,
+ dist_server=ip_gen_s)
+ return ip_gen
+
+ def create_template(self, prog_c, prog_s, addr_idx):
+ # ip generator
+ ip_gen = self.create_ip_gen(prog_c, prog_s, addr_idx)
+ # template
+ temp_c = ASTFTCPClientTemplate(program=prog_c, ip_gen=ip_gen)
+ temp_s = ASTFTCPServerTemplate(program=prog_s,
assoc=ASTFAssociation(rules=ASTFAssociationRule(port=80+addr_idx)))
+ template = ASTFTemplate(client_template=temp_c, server_template=temp_s)
+ return template
+
+ def get_profile(self, tunables, **kwargs):
+ parser = argparse.ArgumentParser(description='Argparser for
{}'.format(os.path.basename(__file__)),
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ parser.add_argument('--num-streams',
+ type=int,
+ default=1,
+ help="The number of streams.")
+ parser.add_argument('--num-addrs',
+ type=int,
+ default=1,
+ help="The number of src IP addresses.")
+ parser.add_argument('--dir',
+ type=str,
+ default='ul',
+ choices={'ul', 'dl', 'uldl'},
+ help='')
+ args = parser.parse_args(tunables)
+ self.num_streams = args.num_streams
+ self.num_addrs = args.num_addrs
+ do_ul = "ul" in args.dir.lower()
+ do_dl = "dl" in args.dir.lower()
+
+ # client commands
+ prog_c = ASTFProgram(stream=False, udp_mtu=1400)
+ if do_ul:
+ prog_c.send_msg(ul_pkt)
+ if do_dl:
+ prog_c.recv_msg(1)
+
+ prog_s = ASTFProgram(stream=False, udp_mtu=1400)
+ if do_ul:
+ prog_s.recv_msg(1)
+ if do_dl:
+ prog_s.send_msg(dl_pkt)
+
+ # Not really used, but must be passed to ASTFProfile:
+ default_ip_gen = self.create_ip_gen(prog_c, prog_s, 0)
+
+ templates = []
+ for addr_idx in range(self.num_addrs):
+ templates.append(self.create_template(prog_c, prog_s, addr_idx = addr_idx))
+
+ return ASTFProfile(default_ip_gen=default_ip_gen, templates=templates)
+
+def register():
+ return Prof1()
+
diff --git a/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/configure.sh
b/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/configure.sh
new file mode 100755
index 0000000..350647d
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/configure.sh
@@ -0,0 +1,50 @@
+#!/bin/bash -xe
+
+# Interface towards UPF:
+IFACE_RAN="enp2s0f1np1"
+IFACE_CN="enp2s0f0np0"
+IFACE_APN="apn-flood"
+ADDR_GW_CN="172.16.31.200"
+NUM_ENB=100
+
+# Disable ethernet flow control:
+sudo ethtool -A $IFACE_RAN autoneg off rx off tx off
+sudo ethtool -A $IFACE_CN autoneg off rx off tx off
+# Disable GRO / LRO:
+sudo ethtool -K $IFACE_RAN gro off lro off
+sudo ethtool -K $IFACE_CN gro off lro off
+# Increase NIC buffers:
+sudo ethtool -G $IFACE_RAN rx 8192 tx 8192
+sudo ethtool -G $IFACE_CN rx 8192 tx 8192
+
+# Enable IP forwarding:
+sudo sysctl -w net.ipv4.ip_forward=1
+
+# Increase UDP buffer memory:
+sudo sysctl -w net.ipv4.udp_mem="763563 900000000 1000000000"
+sudo sysctl -w net.core.optmem_max=16000000
+sudo sysctl -w net.core.rmem_max=2000000000
+sudo sysctl -w net.core.rmem_default=2000000000
+sudo sysctl -w net.core.wmem_max=2000000000
+sudo sysctl -w net.core.wmem_default=2000000000
+sudo sysctl -w net.core.netdev_max_backlog=2000
+sudo sysctl -w net.core.netdev_budget=600
+
+# Set up UPF address:
+sudo ip addr add 172.16.32.1/24 dev $IFACE_RAN || true
+sudo ip addr add 172.16.31.2/24 dev $IFACE_CN || true
+
+# TRex doesn't answer ARPs, so we need to set up the peers:
+for i in $(seq "2" "$((NUM_ENB + 1))"); do
+ # Delete needed to potentially drop incomplet entries created when trying to Tx
traffic:
+ sudo ip neigh del "$(printf "172.16.32.%02u" "$i")"
lladdr ec:0d:9a:8a:27:52 nud permanent dev $IFACE_RAN || true
+ sudo ip neigh add "$(printf "172.16.32.%02u" "$i")"
lladdr ec:0d:9a:8a:27:52 nud permanent dev $IFACE_RAN || true
+done
+sudo ip neigh add 172.16.31.200 lladdr ec:0d:9a:8a:27:53 nud permanent dev $IFACE_CN ||
true
+
+# Add route towards HTTP server on the CN side, aka "the Internet"
+sudo ip route add 48.0.0.0/16 via $ADDR_GW_CN dev $IFACE_CN || true
+
+# Set up UE IP routes:
+# FIXME: This one below need to be done *after* osmo-upf creates the iface....
+sudo ip route add 193.0.0.0/8 dev $IFACE_APN
diff --git a/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/osmo-upf.cfg
b/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/osmo-upf.cfg
new file mode 100644
index 0000000..3ba93db
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/osmo-upf.cfg
@@ -0,0 +1,29 @@
+log stderr
+ logging filter all 1
+ logging color 1
+ logging print category-hex 0
+ logging print category 1
+ logging timestamp 0
+ logging print file basename last
+ logging print level 1
+ logging level set-all notice
+ logging level set-all info
+ logging level session debug
+ logging level nft debug
+ logging level gtp debug
+ logging level set-all error
+
+line vty
+ bind 127.0.0.1
+ctrl
+ bind 127.0.0.1
+
+timer pfcp x24 5000
+timer nft x32 100
+timer nft x33 100
+pfcp
+ local-addr 172.16.31.2
+tunend
+ dev create apn-flood 172.16.32.1
+netinst
+ add netinst-flood 172.16.32.1
diff --git a/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/run.sh
b/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/run.sh
new file mode 100755
index 0000000..6a9f679
--- /dev/null
+++ b/testsuites/gtplab-sysmo2025/tunend/upf/osmo-upf/run.sh
@@ -0,0 +1,9 @@
+#!/bin/bash -xe
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &>
/dev/null && pwd )
+
+sudo osmo-upf -c "$SCRIPT_DIR/osmo-upf.cfg"
+
+# TODO: Route needs to be set up manually on the tun iface once it becomes created, since
osmo-upf is not yet doing it (OS#6585).
+# For now, run this manually after starting osmo-upf with the current run.sh script:
+# ip route add 193.0.0.0/8 dev apn-flood
--
To view, visit
https://gerrit.osmocom.org/c/upf-benchmark/+/39468?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: upf-benchmark
Gerrit-Branch: master
Gerrit-Change-Id: I834b62d29c8dcf2553fc665821135fb08a8bae9e
Gerrit-Change-Number: 39468
Gerrit-PatchSet: 8
Gerrit-Owner: pespin <pespin(a)sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: osmith <osmith(a)sysmocom.de>