From 64ad908eb80c9b494454f0e4ac06e691a89fdb22 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Thu, 13 May 2021 20:13:24 +0000 Subject: spectrumPackages: use link-local router addresses There's no need for every interface on a router to have it's own unique IP. Using link-local addresses, we can assign every interface on a single router the same IP, and save the effort of adding/subtracting one all the time to infer the address of one side of a link from the other. This means that routers and clients are both only interested in what the IP of the client should be, since that's the only thing that is different between different links. So we change our MAC format to communicate the client IP to both sides. If we just made the whole NIC portion of the MAC the last three octets of an IP address like we did before, then both ends of the link would have the same MAC, so we still need to set a bit to encode whether a MAC is at the router side of the link or the client side. I've decided to simplify the implementation by using the most significant bit of the NIC part for that, and just declaring the rest of that octet to be reserved. This way, no calculation is required in the guests -- they just need to look at the last two octets. And we can still identify 65536 links in this scheme, which should be enough for anybody, right? Message-Id: <20210513201323.2087344-1-hi@alyssa.is> Reviewed-by: Cole Helbling --- .../linux/spectrum/testhost/default.nix | 25 ++++++++++------------ pkgs/os-specific/linux/spectrum/vm/app/default.nix | 15 +++++-------- pkgs/os-specific/linux/spectrum/vm/net/default.nix | 13 +++++------ 3 files changed, 23 insertions(+), 30 deletions(-) (limited to 'pkgs/os-specific') diff --git a/pkgs/os-specific/linux/spectrum/testhost/default.nix b/pkgs/os-specific/linux/spectrum/testhost/default.nix index 21c585f1490..de62f0add67 100644 --- a/pkgs/os-specific/linux/spectrum/testhost/default.nix +++ b/pkgs/os-specific/linux/spectrum/testhost/default.nix @@ -45,23 +45,20 @@ let if { ip link set br0 up } # Calculate the MACs for our TAP and the router's TAP. - backtick -in router_nic_dec { - expr ${toString sys-vms.app.vmID} * 2 + 64 * 256 * 256 - } - backtick -in client_nic_dec { - expr ${toString sys-vms.app.vmID} * 2 + 64 * 256 * 256 + 1 - } - multisubstitute { - importas -iu router_nic_dec router_nic_dec - importas -iu client_nic_dec client_nic_dec - } + # MAC address format, by octet: + # + # 0-3 Static OUI for Spectrum + # 4 Most significant bit is used to differentiate + # routers from clients. Other bits are reserved. + # 5-6 Last two octets of client's IP (in 100.64.0.0/16). + # backtick -i router_mac { - pipeline { printf %x $router_nic_dec } - sed s/^\\(..\\)\\(..\\)\\(..\\)$/0A:B3:EC:\\1:\\2:\\3/ + pipeline { printf %.4x ${toString sys-vms.app.vmID} } + sed s/^\\(..\\)\\(..\\)$/0A:B3:EC:80:\\1:\\2/ } backtick -i client_mac { - pipeline { printf %x $client_nic_dec } - sed s/^\\(..\\)\\(..\\)\\(..\\)$/0A:B3:EC:\\1:\\2:\\3/ + pipeline { printf %.4x ${toString sys-vms.app.vmID} } + sed s/^\\(..\\)\\(..\\)$/0A:B3:EC:00:\\1:\\2/ } multisubstitute { importas -iu router_mac router_mac diff --git a/pkgs/os-specific/linux/spectrum/vm/app/default.nix b/pkgs/os-specific/linux/spectrum/vm/app/default.nix index 65dbb51f5e1..f8ff480932c 100644 --- a/pkgs/os-specific/linux/spectrum/vm/app/default.nix +++ b/pkgs/os-specific/linux/spectrum/vm/app/default.nix @@ -28,20 +28,15 @@ runCommand "vm-app" rec { up = writeText "net-up" '' backtick -i LOCAL_IP { pipeline { ip -j link show eth0 } - pipeline { jq -r ".[0].address | split(\":\") | .[3:6] | \"0x\" + .[]" } - xargs printf "100.%d.%d.%d" + pipeline { jq -r ".[0].address | split(\":\") | .[4:6] | \"0x\" + .[]" } + xargs printf "100.64.%d.%d" } importas -iu LOCAL_IP LOCAL_IP - backtick -i REMOTE_IP { - jq -jn --arg localip $LOCAL_IP - "$localip | split(\".\") | .[3] |= tonumber - 1 | join(\".\")" - } - importas -iu REMOTE_IP REMOTE_IP - - if { ip address add ''${LOCAL_IP}/31 dev eth0 } + if { ip address add ''${LOCAL_IP}/32 dev eth0 } if { ip link set eth0 up } - ip route add default via $REMOTE_IP + if { ip route add 169.254.0.1 dev eth0 } + ip route add default via 169.254.0.1 dev eth0 ''; }; diff --git a/pkgs/os-specific/linux/spectrum/vm/net/default.nix b/pkgs/os-specific/linux/spectrum/vm/net/default.nix index 1deb7031caf..5921b62fcf7 100644 --- a/pkgs/os-specific/linux/spectrum/vm/net/default.nix +++ b/pkgs/os-specific/linux/spectrum/vm/net/default.nix @@ -54,15 +54,16 @@ runCommand "vm-net" rec { # Our IP is encoded in the NIC-specific portion of the # interface's MAC address. - backtick -i LOCAL_IP { + backtick -i CLIENT_IP { pipeline { ip -j link show $INTERFACE } - pipeline { jq -r ".[0].address | split(\":\") | .[3:6] | \"0x\" + .[]" } - xargs printf "100.%d.%d.%d" + pipeline { jq -r ".[0].address | split(\":\") | .[4:6] | \"0x\" + .[]" } + xargs printf "100.64.%d.%d" } - importas -iu LOCAL_IP LOCAL_IP + importas -iu CLIENT_IP CLIENT_IP - if { ip address add ''${LOCAL_IP}/31 dev $INTERFACE } - ip link set $INTERFACE up + if { ip address add 169.254.0.1/32 dev $INTERFACE } + if { ip link set $INTERFACE up } + ip route add $CLIENT_IP dev $INTERFACE } { -- cgit 1.4.1