-
Notifications
You must be signed in to change notification settings - Fork 23
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
guest/net: New implementation of network setup with SLAAC and own DHC… #111
base: main
Are you sure you want to change the base?
Conversation
Supersedes #64. Test passt static builds, along with RPMs and Debian packages (x86 only, sorry) at https://passt.top/builds/latest/x86_64/ |
ca7ea9c
to
e1eb9df
Compare
Hmm, I can't test this anymore after rebasing to latest upstream. I'm getting one of these two errors ("Failed to create the microVM" about 30% of the times, Failed to execute
With
or:
I reverted a few commits but I can't seem to get this to work anymore. |
Oh, okay, I didn't pull for a while. It works if I do:
...posting another version of that commit with two functions taken out of configure_network() now that I can test things. Those other issues I'm facing, I have no idea where to start debugging them... |
Fixed by #112
Fixed by updating libkrun. |
This is now supported by passt 2024_11_27.c0fbc7e, matching Fedora updates passt-0^20241127.gc0fbc7e-1.fc40, passt-0^20241127.gc0fbc7e-1.fc41, passt-0^20241127.gc0fbc7e-1.fc42, as well as Debian's passt-0.0~git20241127.c0fbc7e-1. |
Thanks a lot @sbrivio-rh , I really like this approach. A couple questions:
|
Ah, right, I thought So, yes, I should also configure
Oops, I didn't check. I'm not exactly the right person as I barely understand what a crate is (do I?) and I don't even use Fedora regularly, but yes, I can probably do that, it should be low effort. I found this abandoned Copr by the way, https://copr.fedorainfracloud.org/coprs/zurdo/i3status-rs-update/package/rust-neli/, it looks pretty easy. Let me give it a try, but if you know somebody else who could be interested... |
Naive question: if it's statically linked, does it really become a dependency? Or is it just a build dependency? Does that matter also if the crate is downloaded as needed...? |
It's just a build dependency. In Fedora, every crate you depend on must be independently packaged, and builds are done offline. Luckily, rust2rpm helps a lot with this. |
Oh, oops, I just had a look at https://src.fedoraproject.org/user/slp/projects... let me package that. :) |
p += l as usize; | ||
} | ||
|
||
let prefix_len : u8 = netmask.to_bits().leading_ones() as u8; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering why the bump to Rust 1.80, and this is the reason...
https://doc.rust-lang.org/stable/core/net/struct.Ipv4Addr.html#method.to_bits
(No action necessary here.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct :)
I just added support for nameservers over DHCP (option 6), omitting for the moment:
|
Oops, I just noticed the |
…P client The existing implementation has a couple of issues: - it doesn't support IPv6 or SLAAC - it relies on either dhclient(8) or dhcpcd(8), which need a significant amount of time to configure the network as they are rather generic DHCP clients - on top of this, dhcpcd, by default, unless --noarp is given, will spend five seconds ARP-probing the address it just received before configuring it Replace the IPv4 part with a minimalistic, 73-line DHCP client that just does what we need, using option 80 (Rapid Commit) to speed up the whole exchange. Add IPv6 support (including IPv4-only, and IPv6-only modes) relying on the kernel to perform SLAAC. Safely avoid DAD (we're the only node on the link) by disabling router solicitations, starting SLAAC, and re-enabling them once addresses are configured. Instead of merely triggering the network setup and proceeding, wait until everything is configured, so that connectivity is guaranteed to be ready before any further process runs in the guest, say: $ ./target/debug/muvm -- ping -c1 2a01:4f8:222:904::2 PING 2a01:4f8:222:904::2 (2a01:4f8:222:904::2) 56 data bytes 64 bytes from 2a01:4f8:222:904::2: icmp_seq=1 ttl=255 time=0.256 ms --- 2a01:4f8:222:904::2 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.256/0.256/0.256/0.000 ms The whole procedure now takes approximately 1.5 to 2 ms (for both IPv4 and IPv6), with the DHCP exchange and configuration taking somewhere around 300-500 µs out of that, instead of hundreds of milliseconds to seconds. Configure nameservers received via DHCP option 6 as well: passt already takes care care of translating DNS traffic directed to loopback addresses read from resolv.conf, so we can just write those to resolv.conf in the guest. At least for the moment being, for simplicity, omit handling of option 119 (domain search list), as I doubt it's going to be of much use for muvm. I'm not adding handling of the NDP RDNSS option (25, RFC 8106) either, for the moment, as it involves a second netlink socket subscribing to the RTNLGRP_ND_USEROPT group and listening to events while we receive the first router advertisement. The equivalent userspace tool would be rdnssd(8), which is not called before this change anyway. I would rather add it at a later time instead of making this patch explode. Matching support in passt for option 80 (RFC 4039) and for the DHCP "broadcast" flag (RFC 2131) needs at least passt 2024_11_27.c0fbc7e: https://archives.passt.top/passt-user/20241127142126.3c53066e@elisabeth/ Signed-off-by: Stefano Brivio <[email protected]>
Gosh, the reformatted version looks horrible, with 100 columns that don't fit pretty much anywhere and things wildly misaligned. Is |
let socket = UdpSocket::bind("0.0.0.0:68").expect("Failed to bind"); | ||
let mut buf = [0; 576 /* RFC 2131, Section 2 */ ]; | ||
|
||
const REQUEST: [u8; 300 /* From RFC 951: >= 60 B of options */ ] = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How would you initialise bytes after the sname
and file
fields, though? That is, the DHCP cookie and the options.
Besides, if you prefer a version with everything on its own line, a struct with #[repr(packed)]
could be used instead (at least up to the options... those would need a different description). This, for example, is how passt does it in C.
But my idea here was, given that we don't have to be flexible at all, to keep it in sixteen lines (because it's possible), so that you have an immediate overview of the whole thing without scrolling back and forth.
Package reviews: |
…P client
The existing implementation has a couple of issues:
it doesn't support IPv6 or SLAAC
it relies on either dhclient(8) or dhcpcd(8), which need a significant amount of time to configure the network as they are rather generic DHCP clients
on top of this, dhcpcd, by default, unless --noarp is given, will spend five seconds ARP-probing the address it just received before configuring it
Replace the IPv4 part with a minimalistic, 73-line DHCP client that just does what we need, using option 80 (Rapid Commit) to speed up the whole exchange.
Add IPv6 support (including IPv4-only, and IPv6-only modes) relying on the kernel to perform SLAAC. Safely avoid DAD (we're the only node on the link) by disabling router solicitations, starting SLAAC, and re-enabling them once addresses are configured.
Instead of merely triggering the network setup and proceeding, wait until everything is configured, so that connectivity is guaranteed to be ready before any further process runs in the guest, say:
$ ./target/debug/muvm -- ping -c1 2a01:4f8:222:904::2
PING 2a01:4f8:222:904::2 (2a01:4f8:222:904::2) 56 data bytes
64 bytes from 2a01:4f8:222:904::2: icmp_seq=1 ttl=255 time=0.256 ms
--- 2a01:4f8:222:904::2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.256/0.256/0.256/0.000 ms
The whole procedure now takes approximately 1.5 to 2 ms (for both IPv4 and IPv6), with the DHCP exchange and configuration taking somewhere around 300-500 µs out of that, instead of hundreds of milliseconds to seconds.
Matching support in passt for option 80 (RFC 4039) and for the DHCP "broadcast" flag (RFC 2131) needs this series:
https://archives.passt.top/passt-dev/[email protected]/
[I'll update this commit message once we have an upstream release with it]