Project

General

Profile

Simulate Network Latency » History » Version 4

neels, 08/31/2021 12:16 PM

1 1 neels
h1. Simulate Network Latency
2
3
This describes how to virtually introduce network latency on a specific ethernet link,
4
based on the practical example of introducing latency on the Abis link (between BSC and BTS).
5
All of this on a single machine using the loopback interface.
6
7
{{graphviz_link()
8
digraph G {
9
  rankdir = LR;
10
11
  subgraph cluster_abis {
12
    label="namespace: abis";style=dotted
13 3 neels
    TRX [rank="min"]
14 1 neels
    BTS [rank="min"]
15
    abisin [label="link: abis-in\n10.9.8.2/24";shape=box]
16
  }
17
18
  subgraph cluster_root {
19
    label="namespace: root";style=dotted
20
    abisout [label="link: abis-out\n10.9.8.1/24";shape=box]
21
    BSC
22
    MSC
23
  }
24
25 3 neels
  TRX -> BTS -> abisin [dir=both]
26 1 neels
  abisin -> abisout [label="netem delay"]
27
  abisout -> abisin [label="netem delay"]
28
  abisout -> BSC -> MSC [dir=both]
29
}
30
31
}}
32
33 4 neels
h2. setup virtual ethernet link
34 1 neels
35
(Perform the following steps as root user)
36
37
create network namespace "abis",
38
create a virtual ethernet link "abis-in" <-> "abis-out"
39
and put "abis-in" in the new network namespace:
40
41
<pre>
42
ip netns add abis
43
ip link add abis-in type veth peer name abis-out
44
ip link set abis-in netns abis
45
</pre>
46
47
make up a new local IP subnet, here 10.9.8.0/24,
48
and give each link an address in that subnet.
49
First for "abis-out" in the root namespace:
50
51
<pre>
52
ip link set abis-out up
53
ip addr add 10.9.8.1/24 dev abis-out
54
</pre>
55
56
And for "abis-in" within the "abis" namespace,
57
first opening a shell in that namespace:
58
59
<pre>
60
ip netns exec abis bash
61
ip link set abis-in up
62
ip addr add 10.9.8.2/24 dev abis-in
63
</pre>
64
65 4 neels
h2. verify the link
66 1 neels
67
Any shell within the "abis" namespace should show only the "abis-in" and loopback links,
68
and the "abis-in" link should be in state UP:
69
70 2 neels
(I repeat the 'ip netns exec' step below just to clarify, of course it suffices to keep one shell within the "abis" namespace open)
71
72 1 neels
<pre>
73
# ip netns exec abis bash
74
# ip link
75
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
76
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
77
6: abis-in@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
78
    link/ether f6:c6:b5:47:46:4f brd ff:ff:ff:ff:ff:ff link-netnsid 0
79
80
# ip a
81
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
82
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
83
6: abis-in@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
84
    link/ether f6:c6:b5:47:46:4f brd ff:ff:ff:ff:ff:ff link-netnsid 0
85
    inet 10.9.8.2/24 scope global abis-in
86
       valid_lft forever preferred_lft forever
87
    inet6 fe80::f4c6:b5ff:fe47:464f/64 scope link 
88
       valid_lft forever preferred_lft forever
89
</pre>
90
91
A shell running in the "root" namespace should show the "abis-out" link
92
and any other links your machine may have configured:
93
94
<pre>
95
# ip link
96
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
97
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
98
[...]
99
5: abis-out@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc netem state UP mode DEFAULT group default qlen 1000
100
    link/ether be:49:d6:ef:35:38 brd ff:ff:ff:ff:ff:ff link-netns abis
101
102
# ip a
103
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
104
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
105
    inet 127.0.0.1/8 scope host lo
106
       valid_lft forever preferred_lft forever
107
    inet6 ::1/128 scope host 
108
       valid_lft forever preferred_lft forever
109
[...]
110
5: abis-out@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc netem state UP group default qlen 1000
111
    link/ether be:49:d6:ef:35:38 brd ff:ff:ff:ff:ff:ff link-netns abis
112
    inet 10.9.8.1/24 scope global abis-out
113
       valid_lft forever preferred_lft forever
114
    inet6 fe80::bc49:d6ff:feef:3538/64 scope link 
115
       valid_lft forever preferred_lft forever
116 2 neels
</pre>
117
118
A shell run within the "abis" namespace should be able to ping the "root" namespace:
119
120
<pre>
121
# ip netns exec abis bash
122
# ping 10.9.8.1
123
PING 10.9.8.1 (10.9.8.1) 56(84) bytes of data.
124
64 bytes from 10.9.8.1: icmp_seq=1 ttl=64 time=0.133 ms
125
64 bytes from 10.9.8.1: icmp_seq=2 ttl=64 time=0.059 ms
126
64 bytes from 10.9.8.1: icmp_seq=3 ttl=64 time=0.059 ms
127
64 bytes from 10.9.8.1: icmp_seq=4 ttl=64 time=0.058 ms
128
^C
129
</pre>
130
131
And a running in the "root" namespace should be able to ping into the "abis" namespace:
132
<pre>
133
# ping 10.9.8.2
134
PING 10.9.8.2 (10.9.8.2) 56(84) bytes of data.
135
64 bytes from 10.9.8.2: icmp_seq=1 ttl=64 time=0.133 ms
136
64 bytes from 10.9.8.2: icmp_seq=2 ttl=64 time=0.059 ms
137
64 bytes from 10.9.8.2: icmp_seq=3 ttl=64 time=0.059 ms
138
64 bytes from 10.9.8.2: icmp_seq=4 ttl=64 time=0.058 ms
139
^C
140
</pre>
141
142
h2. add latency
143
144
In a shell running in the "root" namespace, add a netem delay, for example:
145
146
<pre>
147
tc qdisc add dev abis-out root handle 1:0 netem delay 200ms 50ms 50%
148
</pre>
149
150
From here on, there is latency in *only one* direction on the virtual ethernet.
151
It already shows in the ping time on both sides, because ping always includes the entire roundtrip.
152
153
Also add similar latency in the other direction:
154
155
<pre>
156
ip netns exec abis bash
157
tc qdisc add dev abis-in root handle 1:0 netem delay 200ms 50ms 50%
158
</pre>
159
160
At this point there is latency in both directions between "abis-in" and "abis-out"
161
162 4 neels
h2. use the link
163 2 neels
164
In my specific example, I configure the BSC to listen for Abis on 10.9.8.1,
165
and I can now run my osmo-bts-trx and osmo-trx-uhd within the "abis" namespace:
166
167
<pre>
168
ip netns exec abis bash
169
osmo-trx-uhd -C osmo-trx.cfg
170
</pre>
171
172
In my specific case, I am running osmo-trx-uhd as root user above to be able to set realtime priority on the process.
173
osmo-bts-trx should run as my normal user, but first I need to enter the "abis" netns:
174
175
<pre>
176
ip netns exec abis bash
177
su - neels
178
osmo-bts-trx -c osmo-bts.cfg
179 1 neels
</pre>
Add picture from clipboard (Maximum size: 48.8 MB)