-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
msg-sim
Linux implementation
#58
Comments
I've given a look at this and here are some of my thoughts/notes: On dummy interfacesIt's very easy to spin up a dummy interface on Linux and play with it, e.g. # Make sure that the dummy kernel module is loaded,
# which provides support for the creation of dummy network interfaces
sudo modprobe dummy
# `ip link` allows to configure network devices. We want
# to add a new one, called `dummy0` of type `dummy`
sudo ip link add dummy0 type dummy
# We configure it by assigning an IP address to it.
# We also need to specify the network device
sudo ip addr add 192.168.1.1/24 dev dummy0
# Verify the dummy interface is correctly configured using
ip addr show dummy0
# Now you should be able to ping it:
ping 192.168.1.1
# To remove it
sudo ip link delete dummy0 However adding delay or loss using On namespaces and local P2P networkWith In order to achieve a dummy-like interface with similar purposes using this technique we can spin up one veth on a separate namespace, and one veth on the host environment, like so: # create namespace ns1
sudo ip netns add ns1
# create veth devices linked together
sudo ip link add veth-host type veth peer name veth-ns1
# move veth-ns1 device to ns1 namespace
sudo ip link set veth-ns1 netns ns1
# associate ip addr to veth-host device and spin it up
sudo ip addr add 192.168.1.2/24 dev veth-host
sudo ip link set veth-host up
# same but from ns1 namespace
sudo ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth-ns1
sudo ip netns exec ns1 ip link set veth-ns1 up
# this should work
sudo ip netns exec ns1 ping 192.168.1.2
# this too
ping 192.168.1.1
# add latency etc to veth-ns1 from ns1 namespace
sudo ip netns exec ns1 tc qdisc add dev veth-ns1 root netem delay 3000ms loss 50%
# this should be slow
ping 192.168.1.1
# bonus: attach a toy web server in another terminal; should take a while to respond
sudo ip netns exec ns1 python3 -m http.server --bind 192.168.1.1 8000 In the same fashion, we can spin up a local p2p network where each veth device lives in a separate namespace, then we have to link them, assign IP addresses and adding network emulations as desired On the actual implementationI think a good strategy would be:
On root accessHere I think there is not much we can do, since modifying the network stack requires root access. I think it's better to ask for them instead of altering the user's system configuration (which would require root privileges anyway) and may feel hacky/sketchy. For example, both tylertreat/comcast and celestiaorg/bittwister require root access to run the binary. |
Great writeup, thanks for clarifying all the steps. Also agreed on the strategy! One question: when adding delay / bandwidth to a veth inside of a namespace, is it symmetrical or only one way? If it's one way, it will be different from how it works on MacOS over the loopback interface. Keep in mind that the API I've settled on for the simulator is by no means final, if you think you can improve on it or bump into any limitations, feel free to propose changes to it. Let's start with just single endpoint simulation and we can then expand it to P2P. |
It is asymmetrical/only one way! For instance, if I apply delay to the device |
Context
Since #54, we have an initial implementation for our network simulation crate for MacOS, but we're still missing one for Linux. The simulation crate allows us to start simulated endpoints in Rust tests that we can then use to emulate a real world environment. The MacOS one uses
dummynet
with someifconfig
commands and a hacky localhostalias
to configure a simulated endpoint. We want to do the same for Linux, but luckily Linux has some better tools for these types of things:ip
command: with theip
command, we can create network namespaces, virtual ethernet devices, dummy interfaces etc. I think dummy interfaces specifically will be most useful in the beginning (it's basically a separate localhost but with normal MTU for more accurate simulation).tc
command: thetc
(traffic-control) command can be used withnetem
(a kernel module) to shape traffic.Some inspiration:
Other notes:
CAP_NET_ADMIN
capability allows us to do this stuff without root but I don't think it's useful when running tests. And granting capabilities also require root.veth
or virtual ethernet devices as well.The text was updated successfully, but these errors were encountered: