-
Notifications
You must be signed in to change notification settings - Fork 113
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
Automatically enable requesting broadcast reply on ipvlan
#32
Comments
I don't see a reason why not. We would need a way to detect if the interface is ipvlan or not. We would also need to adjust the default IAID for the interface as well as the MAC address is shared. |
I'm having a hell of a time figuring ipvlans out myself, so I don't really know. How do you detect the other stuff? |
|
The ipvlan source is here if that helps any https://github.com/torvalds/linux/tree/master/drivers/net/ipvlan |
The specific info around whether broadcast via ipvlan is available might be in I thought the (non-portable) way of determining whether an interface supports broadcast generically was to do Bringing up an L2
While it has a |
You have a good point in that broadcast isn't available in all ipvlan modes IIUC, I forgot about that because I've only been using the L2 mode. The initial problem was that I wasn't able to get the DHCP replies at all over unicast; because you can't receive to IPs that aren't yours (IIUC). |
IFF_BROADCAST Valid broadcast address set. Doesn't mean that we need to set the broadcast bit in DHCP messages sadly. |
You can base new code on the netlink code to get the wireless SSID found here: |
I just want to make sure I understand your setup here, because your statement here is making me question whether this is solvable with DHCP broadcast replies. Disclaimer just to get the obvious out of the way: Help me replicate your setup, so that I can get a sense if this will work or not, can you share how your interfaces are configured? Also:
|
That is why we need to set the broadcast bit in the DHCP message we sent to instruct the server to broadcast the reply rather than unicasting it. We need to set the flag somewhere here for ipvlan interfaces: |
I was able to get that working with L2 mode, but with L3/L3S mode For example, I saw a container networking implementation a couple years ago that did stateful DHCP relaying between the container interfaces and external DHCP server by tracking DHCP XIDs or (where available)
Thanks for the pointer, that saved me a couple of |
Seems like some of these replies aren't needed anymore but here they are; It looks like I failed to mention (since I didn't see a need at the time) that I do in fact have a working DHCP setup when the broadcast flag is set. - by just passing I just figured it would be reasonable to detect ipvlan additionally to the other two cases, because unicast doesn't work with L2 mode ipvlan unless you already have the IP you're being assigned. (I don't understand how this works with other device either though...) I don't understand how ipvlan works , but I made a discovery yesterday (honestly, why isn't this stuff documented in the usual places as opposed to some obscure pdf somewhere?): https://people.netfilter.org/pablo/netdev0.1/slides/bandewar-IPvlan-presentation-Netdev01.pdf , that suggests that communication between the master device and slave device doesn't work at all, or at least only in one direction, which matches what I experienced with wireshark.
If you have any good suggestions how to work around this, that would be great, because I didn't understand the suggested workarounds yet, or they don't look very good. The document says macvlan has the same problem though?
Yes the packets are visible on the host interface. (IIUC - they were definitely visible somewhere, which is part of how I figured out that I needed this in the first place)
This is partially answered by the above, but also, I have no idea how to move packets around with iptables. If you have any recommended literature, I'd be happy to hear. It might help alleviate the "master can't talk to slave" problem. (I don't understand why they can "external" packets but not ones hitting the master interface from the same machine?) I did manually set a client ID, but I don't know if it's strictly needed (or if dhcpcd sets a unique one automatically). containernetworking/cni#17 (comment) brought the setting to my attention, and it makes sense, so I set it. That guy seems to have a clue about how this works.
I don't know how containers work internally, but it seems there are some basic features, which get combined into what ends up being called "containers". I use systemd-nspawn, because some infrastructure is already provided by my linux distro. I don't know any details but it seems thinner than stuff like docker, so probably pretty minimal. Any daemon or such, I would have to use in addition. Once you're limited to L3 stuff, I think you start using dhcp relay daemons? This whole project of mine came from trying to run a proxyDHCP (weird name for what it does?) server so I could run a PXE server in a container, and it works now :) I actually had a pretty hard time finding my way around tooling in the dhcp space. |
For L2
I'm looking for alternatives that will work for unicast DHCP OFFERs if you know the container hostnames/client-IDs (not IPs), or are willing to be stateful (DHCP XIDs) and can inject the DHCP replies you're seeing on the host interface into the ipvlan interfaces. That alternative would work across all types of The reason one might want to have unicast OFFERs where possible is that with broadcast, all neighboring containers and hosts in the broadcast domain would see the new container. Depending on one's threat model, that may not be desired. (For example, if you allow containers from different untrusted third parties on the same host, that could introduce crosstalk between parties that shouldn't exist.)
In the case of an
Excellent, then there is some hope we can forward them into the container somehow... :-D
It looks like we're reading more or less the same things. They're implementing more or less what I'm suggesting above with client IDs. If there were an iptables conntrack extension for DHCP, that would come in super useful here, since you could conntrack by DHCP XID or client ID across ipvlan interfaces, and everything would work out...seems like that's the missing piece for getting L3/L3S
Or iptables-/ebpf-based options with to forward DHCP packets into the ipvlan interfaces (from the host) based on DHCP client ID, etc.
For what it's worth, I also use systemd-nspawn or lxc, and prefer to avoid heavier container orchestration systems (e.g. Docker) because of their attack surface. You can replace my usage of "container" with "netns" everywhere above. |
I'm not sure I understood this correctly, and it complicates setup (but sounds like it makes it possible at all); a slave device could be added in the "host" environment next to the master device, and then routing done? Feels redundant with already having a master device.... Edit: Unless I'm confusing something with my existing setup again, that seems to work for communication between host(master-adjacent) and slave. Though half the point of all this containerization stuff is me trying to simplify the config of the host... |
It should be doable without another child interface, using netfilter/XDP/eBPF, or possibly even just a relay agent of some sort listening on the master interface and injecting packets into the Anyhow, a draft of the broadcast patch is available in #33. I'm still cleaning it up but it should be functional now, if you want to try it out. Note that you will need to explicitly set the IAID or client ID for Unfortunately, for properly namespaced I'm thinking about migrating to an approach that generically tracks "child" and "parent" interface relationships and enables broadcast + alternate default IAID when their MAC addresses are the same, but for now moving forward with ipvlan-specific code. |
If it detects ipvlan it could bail/leave a log message about needing an id set? |
A log message seems fair. However, if we're going to bail when the Also, thanks for the reminder, the current patch does not yet check if the interface is configured, and should probably only set |
Yeah on second though, I just realized it's kind of all-or-nothing, because if broadcast gets set automatically but the client ID isn't set, something weird could happen? So a sane default needs to be found, or you cant really do this automatically? Good luck. |
Linux ipvlan interfaces share a MAC address with their siblinds and parent physical interface. Before they are assigned an IP address, these virtual interfaces do not receive DHCP OFFER unicast messages because the ipvlan driver does not know to pass them to the virtual interface yet. This chicken-and-egg problem is resolved with two changes: - Set broadcast flag for an interface if it belongs to the ipvlan driver, as detected via SIOCETHTOOL ETHTOOL_GDRVINFO. (closes #32) A forthcoming patch will automatically modify the DHCP IAID for ipvlan interfaces so that they do not conflict with the parent (lower/physical) interface IAID. For now, dhcpcd will display a warning log message when conflicting IAID (same MAC address) interfaces are active. (A minor grammar correction is included free of charge.)
Linux ipvlan interfaces share a MAC address with their siblings and parent physical interface. Before they are assigned an IP address, these virtual interfaces do not receive DHCP OFFER unicast messages because the ipvlan driver does not know to pass them to the virtual interface yet by IP. This chicken-and-egg problem is resolved with two changes: In this patch, we set the broadcast flag for an interface if it belongs to the ipvlan driver, as detected via SIOCETHTOOL ETHTOOL_GDRVINFO. (closes #32) A forthcoming patch will automatically modify the DHCP IAID for ipvlan interfaces so that they do not conflict with the parent (lower/physical) interface IAID. For now, dhcpcd will display a warning log message when conflicting IAID (same MAC address) interfaces are active. (A minor grammar correction is included free of charge.)
If it's ipvlan then default the IAID to the interface name if 4 chars or less, otherwise index. |
I was playing around with hashing the network namespace + interface name, but I think you're right. Unfortunately, the likely outcome here will be that a very common setup will result in a conflict: Suppose you have two "containers" (network namespaces) with an ipvlan interface in each one named eth0, and a physical/lower interface named eth0 in the init netns (outside the "containers"). The IAIDs of the ipvlan interfaces will conflict in this case. This seems too much like magic that will surprise the user in unexpected ways, so I'll output a warning message when we see an ipvlan interface to the effect of strongly recommending that they set a custom IAID. |
I don't know what kind of things it's appropriate to do here, if you want to avoid conflicts wouldn't it be better to set a random suffix per boot and recommend setting an ID if the user wants stability? or is DHCP space exhaustion if you reboot a lot bad too? To generalize it a bit, you could instead save a seed in the file and then use that to derive further IDs unique to the host. |
Another option is to ignore the interface unless there is a configuration for it as we do for tap and bridge interfaces on Linux: Although we might want to be more noisy about it and adjust if_ignore (on if-bsd.c and if-sun.c as well as if-linux.c) to return an int (probably as a references argument rather than the returned value) which represents the log level for use in logmessage here: |
Brief update - haven't forgotten about this - going to implement your suggestions @rsmarples. |
The
dhcpcd.conf
manual states:Would it be possible to do this for
ipvlan
interfaces as well?Unicast packets don't make it through the device unless it's configured. I don't know if this can be worked around, but by design it only demuxes based on layer 3 data.
The text was updated successfully, but these errors were encountered: