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