Conversation
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a simple DHCP client to configure the eth0 interface. The implementation is a good start, but I've found several critical issues that need to be addressed. There are bugs in parsing IP addresses from the DHCP response due to incorrect byte order handling, which will lead to incorrect network configuration. Additionally, the DHCP option parsing logic has a security vulnerability that could lead to a buffer over-read when processing a malicious response. I've also identified a double-close bug in init.c and some other minor issues. Please see the detailed comments for suggestions on how to fix these problems.
e0c9001 to
52dc947
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a simple DHCP client to configure the eth0 interface at startup. The implementation is a good starting point, but I've identified a few areas for improvement regarding robustness and maintainability. Specifically, I've suggested changing how /etc/resolv.conf is handled to prevent duplicate entries, randomizing the DHCP transaction ID for better compliance with standards, and a long-term suggestion to refactor the manual DHCP packet construction to improve code clarity and reduce brittleness. The changes to the build system and the integration into the init process are correct.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a simple DHCP client to configure the eth0 network interface on startup. The implementation is well-structured, using netlink for network configuration and handling the basic DHCP discovery flow with rapid commit. My review focuses on improving robustness, maintainability, and clarity. Key suggestions include correcting error handling to prevent potential indefinite blocking, refactoring resource management to be more robust, and improving clarity by renaming misleadingly named functions, removing an unused macro, and correcting misleading comments.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a simple DHCP client to configure the eth0 network interface during initialization. The overall approach is sound, but I've identified a few areas for improvement, primarily related to error handling and a discrepancy between documented and actual behavior. Specifically, several function return values are not checked, which could mask network configuration failures. Additionally, the handling of /etc/resolv.conf truncates the file instead of appending as the documentation suggests. Addressing these points will make the DHCP client more robust and reliable.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a DHCP client to configure the eth0 interface. The implementation is a good start, using netlink for configuration and a simple DHCP discover/ack flow with rapid commit. I've found a few areas for improvement regarding error handling and API correctness. Specifically, there's a minor bug in an error message and an opportunity to improve API safety with const.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a simple DHCP client to configure the eth0 network interface during initialization. The implementation uses netlink sockets to configure the interface, address, and routes, and a UDP socket for DHCP communication. The changes are well-contained and the approach of using a temporary link-local address to avoid raw sockets is a good design choice.
My review identifies a few areas for improvement to enhance robustness, error handling, and code clarity. This includes a high-severity issue with a predictable DHCP transaction ID and several medium-severity issues related to error reporting, misleading comments, use of magic numbers, and unchecked return values from system calls. Overall, this is a valuable addition, and addressing these points will make the implementation more robust and maintainable.
| /* Option 53: DHCP Message Type = DISCOVER (1) */ | ||
| request.options[opt_offset++] = 53; | ||
| request.options[opt_offset++] = 1; | ||
| request.options[opt_offset++] = 1; | ||
|
|
||
| /* Option 80: Rapid Commit (RFC 4039) */ | ||
| request.options[opt_offset++] = 80; | ||
| request.options[opt_offset++] = 0; | ||
|
|
||
| /* Option 255: End of options */ | ||
| request.options[opt_offset++] = 0xff; |
There was a problem hiding this comment.
The code uses several magic numbers for DHCP options (e.g., 53, 80, 255) and their values. It would improve readability and maintainability to define these as named constants at the top of the file. For example:
#define DHCP_OPT_MESSAGE_TYPE 53
#define DHCP_OPT_MESSAGE_TYPE_DISCOVER 1
#define DHCP_OPT_RAPID_COMMIT 80
#define DHCP_OPT_END 255This principle should also be applied to the option codes used when parsing the DHCP response (e.g., options 1, 3, 6, 26).
There was a problem hiding this comment.
We're only using them once, and they're al properly documented. Moving them to constants makes it less readable. Nack.
There was a problem hiding this comment.
I mean it's a matter of preference but I'd say I'd prefer the constants too in most cases.
|
What's the reason to translate the DHCP implementation from Rust to C rather than to translate init.c to init.rs? Is it because of the TEE stuff? Could work in #590 help if this is the case? Or are there other reasons? |
Translating If we're to translate |
Personally I would too rather rewrite the init in Rust, but for 1.x branch it's safer to not touch it that much. Btw. instead of musl / glibc I would try going for no-libc and use direct syscalls using rustix crate bindings (we would also need an allocator crate implementation + json parser). |
|
Interesting results, vmnet-helper DHCP is significantly slower than gvproxy. Furthermore, with vmnet-helper, my VM didn't get any IP assigned (subnet is configured as I think the possibility of read-only root setups is another reason for having an option to disable the built-in DHCP. |
vmnet_{start,end}_address require address in the private IP range (RFC 1918), but I tried only 192.168/16. vmnet_network_configuration_create - the modern way to create vment network requires 192.168/16. If you use static addresses and do no need DHCP, there is a way to disable DHCP for vment but it is not available in vmnet-helper yet, but you can add it. For anylinuxfs use case, why not use multiple vms in the same subnet with --operation-mode=host and --enable-isolation? Creating many subnets will fail when you conflict with another application that created the same subnet before you. |
|
@nirs I already have a working setup with static addresses and /30 subnets which are picked dynamically from a predefined pool so that they don't conflict with any other IP ranges on the host interfaces. Haven't tried disabling vmnet DHCP, I just ignore it. I have considered your approach before but decided to use the smallest subnets separately. |
|
Haven't used host mode though because sometimes I need internet access too and don't want to manage multiple configuration profiles for mounting, bootstrapping VM images or installing packages. I think we're getting a little off topic here... but thanks! |
|
I'm going to introduce a change to gate this behavior behind an API call. |
1ad1d26 to
8fe2451
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a standalone DHCP client implementation in C to enable automatic IPv4 configuration for guest network interfaces. Key changes include the DHCP client logic, integration into the init process triggered by a new environment variable, and API updates in libkrun to support the DHCP client flag. The review feedback highlights several security and robustness concerns, such as missing validation for DHCP options and netlink messages, predictable transaction IDs, and an overly short receive timeout.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a standalone C-based DHCP client to libkrun, enabling automated IPv4 network configuration for guest interfaces. The implementation includes support for DHCP DISCOVER/REQUEST flows, MTU configuration, and DNS setup via /etc/resolv.conf. Integration is provided across TAP, unixstream, and unixgram backends, triggered by a new environment variable. Review feedback identifies a critical error handling gap when retrieving the interface MAC address, suggests safer macro definitions using parentheses, and notes that the function documentation for do_dhcp needs to be updated to accurately reflect the implementation.
init/dhcp.c
Outdated
| if (ioctl(sock, SIOCGIFHWADDR, &mac_ifr) == 0) { | ||
| memcpy(request.chaddr, mac_ifr.ifr_hwaddr.sa_data, 6); | ||
| } |
There was a problem hiding this comment.
If ioctl fails to get the MAC address, the DHCP request will be sent with an all-zero chaddr, which will likely be rejected by the DHCP server. This should be treated as a fatal error for the DHCP process.
if (ioctl(sock, SIOCGIFHWADDR, &mac_ifr) < 0) {
perror("ioctl(SIOCGIFHWADDR) failed");
goto cleanup;
}
memcpy(request.chaddr, mac_ifr.ifr_hwaddr.sa_data, 6);
include/libkrun.h
Outdated
| /* Send the VFKIT magic after establishing the connection, | ||
| as required by gvproxy in vfkit mode. */ | ||
| #define NET_FLAG_VFKIT 1 << 0 | ||
| #define NET_FLAG_DHCP_CLIENT 1 << 1 |
init/dhcp.h
Outdated
| * 1. Sets up a temporary link-local address (169.254.1.1/16) | ||
| * 2. Sends a DHCP DISCOVER message with Rapid Commit option | ||
| * 3. Waits up to 100ms for a DHCP ACK response | ||
| * 4. Parses the response and configures: | ||
| * - IPv4 address with appropriate prefix length | ||
| * - Default gateway route | ||
| * - DNS servers (overwriting /etc/resolv.conf) | ||
| * - Interface MTU | ||
| * 5. Cleans up temporary configuration |
There was a problem hiding this comment.
The description for do_dhcp seems to be out of sync with the implementation. For example, it mentions setting up a temporary link-local address, but this is not done in do_dhcp. Please update the comment to accurately reflect the function's behavior.
References
- Prioritize code readability and focused commits over micro-optimizations.
Sorry, I had some unexpected interruptions coming up. I still plan to review this, I'm now giving myself a harder deadline for this week. |
|
/gemini review |
Thank you @sbrivio-rh ! We're in kind on an stretch to release 1.18, so this one might go in before you review it. But that's fine, if you find anything we should change, we can put it into 1.18.1. |
There was a problem hiding this comment.
Code Review
This pull request implements an embedded DHCP client in the init process to automate IPv4 network configuration. It introduces the NET_FLAG_DHCP_CLIENT flag to enable this feature via the network configuration APIs. Key changes include the DHCP client implementation in init/dhcp.c, its integration into the init binary, and VMM updates to pass the configuration through the kernel command line. Reviewers identified a compilation error due to a missing semicolon and recommended stricter error handling when updating /etc/resolv.conf.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request implements an embedded DHCP client within the init process to automate IPv4 network configuration for guest VMs, controlled by a new NET_FLAG_DHCP_CLIENT flag. The review identified several issues in the DHCP implementation, including potential out-of-bounds reads during packet parsing, incorrect handling of the Server Identifier per RFC 2131, the use of a non-unique transaction ID (PID 1), and an overly aggressive 100ms timeout that could cause configuration failures.
If there's a eth0 interface present, and one of the interfaces has been configured with the newly introduced NET_FLAG_DHCP_CLIENT flag, the embedded dhcp client will try to obtain an address. For 2.x we should be more flexible and actually allow both dhcp and static IP configuration on specific interfaces (identified by their MAC addresses, since ifnames aren't deterministic), but this should be good enough for 1.x. Signed-off-by: Sergio Lopez <slp@redhat.com>
Replace the temporary link-local address (169.254.1.1) workaround with SO_BINDTODEVICE. The temp address caused the kernel to use 169.254.1.1 as the source IP in DHCP packets; gvproxy then tried to reply to that address and failed with "no route to host". With this change the source IP should be 0.0.0.0, which is what RFC 2131 requires for DHCPDISCOVER. Signed-off-by: Matej Hrica <mhrica@redhat.com>
When a server answers DHCPDISCOVER with DHCPOFFER instead of an immediate ACK, send DHCPREQUEST for the and wait for the final ACK. This makes DHCP work on macOS hosts when using gvproxy for networking. Signed-off-by: Matej Hrica <mhrica@redhat.com>
If there's a eth0 interface present, configure it with DHCP.