Skip to content

Commit c866e48

Browse files
committed
chore(sim,linux): docs, ci updated with sudo
1 parent 4798eed commit c866e48

File tree

2 files changed

+93
-26
lines changed

2 files changed

+93
-26
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ jobs:
1919
with:
2020
cache-on-failure: true
2121
- name: cargo test
22-
run: cargo test --all
22+
run: sudo HOME=$HOME $(which cargo) test --all
2323
- name: cargo test all features
24-
run: cargo test --all --all-features
24+
run: sudo HOME=$HOME $(which cargo) test --all --all-features
2525

2626
cargo-lint:
2727
runs-on: ubuntu-latest

msg-sim/README.md

Lines changed: 91 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,132 @@
11
# `msg-sim`
22

33
## Overview
4+
45
This crate provides functionality to simulate real-world network conditions
56
locally to and from a specific endpoint for testing and benchmarking purposes.
67
It only works on MacOS and Linux.
78

89
## Implementation
910

1011
### MacOS
12+
1113
On MacOS, we use a combination of the `pfctl` and `dnctl` tools.
12-
[`pfctl`](https://man.freebsd.org/cgi/man.cgi?query=pfctl&apropos=0&sektion=8&manpath=FreeBSD+14.0-RELEASE+and+Ports&arch=default&format=html) is a tool to manage the packet filter device. [`dnctl`](https://man.freebsd.org/cgi/man.cgi?query=dnctl&sektion=8&format=html) can manage
13-
the [dummynet](http://info.iet.unipi.it/~luigi/papers/20100304-ccr.pdf) traffic shaper.
14+
[`pfctl`](https://man.freebsd.org/cgi/man.cgi?query=pfctl&apropos=0&sektion=8&manpath=FreeBSD+14.0-RELEASE+and+Ports&arch=default&format=html)
15+
is a tool to manage the packet filter device.
16+
[`dnctl`](https://man.freebsd.org/cgi/man.cgi?query=dnctl&sektion=8&format=html)
17+
can manage the
18+
[dummynet](http://info.iet.unipi.it/~luigi/papers/20100304-ccr.pdf) traffic
19+
shaper.
1420

1521
The general flow is as follows:
1622

17-
* Create a dummynet pipe with `dnctl` and configure it with `bw`, `delay`, `plr`
23+
- Create a dummynet pipe with `dnctl` and configure it with `bw`, `delay`,
24+
`plr`
1825

1926
Example:
20-
```bash
21-
sudo dnctl pipe 1 config bw 10Kbit/s delay 50 plr 0.1
22-
```
2327

24-
* Create a loopback alias with `ifconfig` to simulate a different endpoint and
25-
set the MTU to the usual value (1500)
28+
`bash sudo dnctl pipe 1 config bw 10Kbit/s delay 50 plr 0.1 `
29+
30+
- Create a loopback alias with `ifconfig` to simulate a different endpoint and
31+
set the MTU to the usual value (1500)
2632

2733
Example:
28-
```bash
29-
sudo ifconfig lo0 alias 127.0.0.3 up
30-
sudo ifconfig lo0 mtu 1500
31-
```
3234

33-
* Use `pfctl` to create a rule to match traffic and send it through the pipe
35+
`bash sudo ifconfig lo0 alias 127.0.0.3 up sudo ifconfig lo0 mtu 1500 `
36+
37+
- Use `pfctl` to create a rule to match traffic and send it through the pipe
3438

3539
Example:
40+
3641
```bash
3742
# Create an anchor (a named container for rules, close to a namespace)
38-
(cat /etc/pf.conf && echo "dummynet-anchor \"msg-sim\"" && \
39-
echo "anchor \"msg-sim\"") | sudo pfctl -f -
4043

41-
# Create a rule to match traffic from any to the alias and send it through the pipe
42-
echo 'dummynet in from any to 127.0.0.3 pipe 1' | sudo pfctl -a msg-sim -f -
44+
(cat /etc/pf.conf && echo "dummynet-anchor \"msg-sim\"" && \ echo "anchor \"msg-sim\"") | sudo pfctl -f -
45+
46+
# Create a rule to match traffic from any to the alias and send it through the
47+
48+
pipe echo 'dummynet in from any to 127.0.0.3 pipe 1' | sudo pfctl -a msg-sim -f
4349

4450
# Enable the packet filter
51+
4552
sudo pfctl -E
4653
```
4754

48-
* Remove the rules and the pipe
55+
- Remove the rules and the pipe
56+
4957
```bash
5058
# Apply the default configuration
59+
5160
sudo pfctl -f /etc/pf.conf
61+
5262
# Disable the packet filter
63+
5364
sudo pfctl -d
65+
5466
# Remove the alias & reset the MTU
55-
sudo ifconfig lo0 -alias 127.0.0.3
56-
sudo ifconfig lo0 mtu 16384
57-
# Remove the dummynet pipes
58-
sudo dnctl pipe delete 1
67+
68+
sudo ifconfig lo0 -alias 127.0.0.3 sudo ifconfig lo0 mtu 16384
69+
70+
# Remove the dummynet
71+
72+
pipes sudo dnctl pipe delete 1
5973
```
6074

6175
### Questions
62-
- Do we need to create 2 pipes to simulate a bidirectional link? MAN page seems to say so.
76+
77+
- Do we need to create 2 pipes to simulate a bidirectional link? MAN page seems
78+
to say so.
6379

6480
### Linux
65-
On Linux, we use dummy interfaces and `tc` with `netem` to simulate and shape traffic.
81+
82+
On Linux, we leverage network namespaces to simulate different networking
83+
conditions, leveraging the `tc` and `netem` command to shape traffic.
84+
85+
On each namespace, we create a veth pair, with one end in the default namespace,
86+
and then we configure the veth devices as needed.
87+
88+
The general flow is as follows:
89+
90+
- Create a network namespace with `ip netns add`
91+
- Add a veth pair to the namespace with `ip link add`
92+
- Set the veth pair up with `ip link set`
93+
- Set the IP address of the veth pair in the namespace with `ip netns exec`
94+
- Set the network emulation parameters with `tc qdisc add dev` both in the host and
95+
the namespaced environment
96+
97+
Example:
98+
99+
```bash
100+
# create namespace ns1
101+
sudo ip netns add ns1
102+
# create veth devices linked together
103+
sudo ip link add veth-host type veth peer name veth-ns1
104+
# move veth-ns1 device to ns1 namespace
105+
sudo ip link set veth-ns1 netns ns1
106+
107+
# associate ip addr to veth-host device and spin it up
108+
sudo ip addr add 192.168.1.2/24 dev veth-host
109+
sudo ip link set veth-host up
110+
111+
# same but from ns1 namespace
112+
sudo ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth-ns1
113+
sudo ip netns exec ns1 ip link set veth-ns1 up
114+
115+
# add latency etc to veth-ns1 from ns1 namespace
116+
sudo ip netns exec ns1 tc qdisc add dev veth-ns1 root netem delay 3000ms loss 50%
117+
118+
# this should be slow
119+
ping 192.168.1.1
120+
```
121+
122+
#### How to run tests
123+
124+
Given that the tests require root privileges to modify the networking stack,
125+
you can run them with the following command:
126+
127+
```bash
128+
sudo HOME=$HOME $(which cargo) test # add your arguments here
129+
```
130+
131+
We need to provide the `$HOME` environment variable to `sudo` to ensure that
132+
it can find the Rust toolchain, and then we also need to provide the path of `cargo`.

0 commit comments

Comments
 (0)