Simulate Network Latency » History » Revision 7
Revision 6 (neels, 08/31/2021 12:26 PM) → Revision 7/9 (neels, 08/31/2021 01:05 PM)
h1. Simulate Network Latency
This describes how to virtually introduce network latency on a specific ethernet link,
based on the practical example of introducing latency on the Abis link (between BSC and BTS).
All of this on a single machine using the loopback interface.
{{graphviz_link()
digraph G {
rankdir = LR;
subgraph cluster_abis {
label="namespace: abis";style=dotted
TRX [rank="min"]
BTS [rank="min"]
abisin [label="link: abis-in\n10.9.8.2/24";shape=box]
}
subgraph cluster_root {
label="namespace: root";style=dotted
abisout [label="link: abis-out\n10.9.8.1/24";shape=box]
BSC
MSC
}
TRX -> BTS -> abisin [dir=both]
abisin -> abisout [label="netem delay"]
abisout -> abisin [label="netem delay"]
abisout -> BSC -> MSC [dir=both]
}
}}
h2. setup virtual ethernet link
The following setup is volatile, i.e. a reboot of the operating system will wipe out all of it.
(Perform the following steps as root user.)
create network namespace "abis",
create a virtual ethernet link "abis-in" <-> "abis-out"
and put "abis-in" in the new network namespace:
<pre>
ip netns add abis
ip link add abis-in type veth peer name abis-out
ip link set abis-in netns abis
</pre>
make up a new local IP subnet, here 10.9.8.0/24,
and give each link an address in that subnet.
First for "abis-out" in the root namespace:
<pre>
ip link set abis-out up
ip addr add 10.9.8.1/24 dev abis-out
</pre>
And for "abis-in" within the "abis" namespace,
first opening a shell in that namespace:
<pre>
ip netns exec abis bash
ip link set abis-in up
ip addr add 10.9.8.2/24 dev abis-in
</pre>
h2. verify the link
Any shell within the "abis" namespace should show only the "abis-in" and loopback links,
and the "abis-in" link should be in state UP:
(I repeat the 'ip netns exec' step below just to clarify, of course it suffices to keep one shell within the "abis" namespace open)
<pre>
# ip netns exec abis bash
# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: abis-in@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether f6:c6:b5:47:46:4f brd ff:ff:ff:ff:ff:ff link-netnsid 0
# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: abis-in@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether f6:c6:b5:47:46:4f brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.9.8.2/24 scope global abis-in
valid_lft forever preferred_lft forever
inet6 fe80::f4c6:b5ff:fe47:464f/64 scope link
valid_lft forever preferred_lft forever
</pre>
A shell running in the "root" namespace should show the "abis-out" link
and any other links your machine may have configured:
<pre>
# ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
[...]
5: abis-out@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc netem state UP mode DEFAULT group default qlen 1000
link/ether be:49:d6:ef:35:38 brd ff:ff:ff:ff:ff:ff link-netns abis
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
[...]
5: abis-out@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc netem state UP group default qlen 1000
link/ether be:49:d6:ef:35:38 brd ff:ff:ff:ff:ff:ff link-netns abis
inet 10.9.8.1/24 scope global abis-out
valid_lft forever preferred_lft forever
inet6 fe80::bc49:d6ff:feef:3538/64 scope link
valid_lft forever preferred_lft forever
</pre>
A shell run within the "abis" namespace should be able to ping the "root" namespace:
<pre>
# ip netns exec abis bash
# ping 10.9.8.1
PING 10.9.8.1 (10.9.8.1) 56(84) bytes of data.
64 bytes from 10.9.8.1: icmp_seq=1 ttl=64 time=0.133 ms
64 bytes from 10.9.8.1: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 10.9.8.1: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 10.9.8.1: icmp_seq=4 ttl=64 time=0.058 ms
^C
</pre>
And a running in the "root" namespace should be able to ping into the "abis" namespace:
<pre>
# ping 10.9.8.2
PING 10.9.8.2 (10.9.8.2) 56(84) bytes of data.
64 bytes from 10.9.8.2: icmp_seq=1 ttl=64 time=0.133 ms
64 bytes from 10.9.8.2: icmp_seq=2 ttl=64 time=0.059 ms
64 bytes from 10.9.8.2: icmp_seq=3 ttl=64 time=0.059 ms
64 bytes from 10.9.8.2: icmp_seq=4 ttl=64 time=0.058 ms
^C
</pre>
h2. add latency
In a shell running in the "root" namespace, add a netem delay, for example:
<pre>
tc qdisc add dev abis-out root handle 1:0 netem delay 200ms 50ms 50%
</pre>
From here on, there is latency in *only one* direction on the virtual ethernet.
It already shows in the ping time on both sides, because ping always includes the entire roundtrip.
Also add similar latency in the other direction:
<pre>
ip netns exec abis bash
tc qdisc add dev abis-in root handle 1:0 netem delay 200ms 50ms 50%
</pre>
At this point there is latency in both directions between "abis-in" and "abis-out"
h2. use the link
In my specific example, I configure the BSC to listen for Abis on 10.9.8.1.
I am running osmo-bsc in a normal shell in the "root" namespace, as usual.
The other side of Abis, osmo-bts-trx and osmo-trx-uhd, shall run within the "abis" namespace.
In my specific case, I am running osmo-trx-uhd as root user to allow it to set realtime priority:
<pre>
sudo ip netns exec abis bash
osmo-trx-uhd -C osmo-trx.cfg
</pre>
osmo-bts-trx should run as my normal user, but I need to enter the "abis" netns first and su back to my user:
<pre>
sudo ip netns exec abis bash
su - neels
osmo-bts-trx -c osmo-bts.cfg
</pre>
h2. troubleshooting
In the new netns, the loopback interface will still be in state DOWN.
To be able to use loopback addresses like 127.0.0.1, set the lo link to UP:
ip link set lo up
h2. Clean up
When done using the virtual latency link, it suffices to remove the "abis" namespace:
ip netns delete abis
It will still be functional until the last shell running in the namespace exits.