[PATCH v7 00/13] Introduce multiple addresses and late binding
This series adds handling of multiple addresses into a unified address array, so that a guest can see the same addresses on his own interface. o All addresses are stored as union inany_addr o User configured addresses are marked with a USER flag. o Host provided addresses are marked with a HOST flag. o Link local addresses are also marked with a LINKLOCAL flag. o Addresses the guest is actually using are marked with an OBSERVED flag. o Addresses eligible for DHCP assignments are marked with an DHCP flag. o Addresses eligible for DHCPv6 advertisement are marked with an DHCPV6 flag. o Addresses eligible for NDP advertisement are marked with an NDP flag. v2: - Added the earlier standalone CIDR commit to the head of the series. - Replaced the guest namespace interface subscriptions with just an address observation feature, so that it works with both PASTA and PASST. - Unified 'no_copy_addrs' and 'copy_addrs' code paths, as suggested by David G. - Multiple other changes, also based on feedback from David. - Removed the host interface subscription patches, -for now. I intend to re-add them once this series is applied. - Outstanding question: When do we add an IPv4 link local address to the guest? Only in local/opaque mode? Only when explicitly requested? Always? v3: - Unified the IPv4 and IPv6 arrays into one array - Changed prefix_len to always be in IPv6/IpV4 mapped format - Updated migration protocol to v3, handling multiple addresses - Many other smaller changes, based on feedback from the PASST team v4: - Numerous changes based on feedback - Added several new commits, mostly broken out of the pre-existing ones. v5: - Re-introduced multiple OBSERVED addresses. This actually turned out to be cleaner and with more predictable behaviour than allowing only one. - Included the DHCP and NDP patches from previous versions, improved and updated according to feedback from the team. - Likewise re-included the host-side netlink commit to support late binding. v6: - Skipped late binding commit for now. - Added commit for using a single print buffer in conf_print - Added commit for reading and adding all addresses from template interface. - Added commit for refactoring pasta_ns_conf(). - Added separate address flags for DHCP, DHCPv6, and NDP, so that those are easy to recognize for their respective functions. - Split DHCP and DHCPv6 address selection into separate commits. - Updated migration protocol to v3 for multi-address support. - Numerous other smaller changes, both after feedback from David G. and issues I have identified myself. v7: - Replaced commit #1 with one that fixes a return address issue with DHCPv6 - Modified for_each_addr() macro to take 4 arguments - Many more fixes and changes based on feedback and own findings. Jon Maloy (13): dhcpv6: Fix reply destination to match client's source address passt, pasta: Introduce unified multi-address data structures fwd: Unify guest accessibility checks with unified address array arp: Check all configured addresses in ARP filtering conf: Allow multiple -a/--address options per address family netlink, conf: Read all addresses from template interface at startup netlink, pasta: refactor function pasta_ns_conf() conf, pasta: Track observed guest IPv4 addresses in unified address array conf, pasta: Track observed guest IPv6 addresses in unified address array migrate: Update protocol to v3 for multi-address support dhcp: Select address for DHCP distribution dhcpv6: Select addresses for DHCPv6 distribution ndp: Support advertising multiple prefixes in Router Advertisements arp.c | 20 +++- conf.c | 200 ++++++++++++++++++++--------------- dhcp.c | 22 ++-- dhcpv6.c | 115 +++++++++++--------- dhcpv6.h | 2 +- fwd.c | 305 ++++++++++++++++++++++++++++++++++++++++-------------- fwd.h | 8 ++ inany.h | 44 ++++++++ ip.h | 2 + migrate.c | 240 ++++++++++++++++++++++++++++++++++++++++-- ndp.c | 131 ++++++++++++++++------- netlink.c | 70 +++++++------ netlink.h | 7 +- passt.1 | 7 +- passt.h | 78 +++++++++++--- pasta.c | 224 ++++++++++++++++++++------------------- tap.c | 37 ++----- tap.h | 2 - 18 files changed, 1054 insertions(+), 460 deletions(-) -- 2.52.0
tap_ip6_daddr() selects the reply destination based on our source
address type (link-local), so it always returns addr_ll_seen. But if
the client sent from a global address, we would reply to an address
different from what the client is expecting. Since RFC 8415 allows
clients to use global addresses for DHCPv6, we now correct this, and
always respond to the address the client was using.
We also remove a redundant addr_ll_seen assignment, since this is
already done by tap.c when processing IPv6 packets.
Signed-off-by: Jon Maloy
We replace the fwd_guest_accessible4() and fwd_guest_accessible6()
functions with a unified fwd_guest_accessible() function that handles
both address families. With the unified address array, we can check
all configured addresses in a single pass using for_each_addr() with
family filter AF_UNSPEC.
Signed-off-by: Jon Maloy
As a preparation for handling multiple addresses, we update ignore_arp()
to check against all addresses in the unified addrs[] array using the
for_each_addr() macro.
Signed-off-by: Jon Maloy
Add nl_addr_get_all() to read all addresses from the template interface
into c->addrs[] array, rather than just selecting the "best" one.
This allows multi-address configurations where the template interface
has multiple IPv4 or IPv6 addresses assigned to it, all of which
will now be copied to the guest namespace when using --config-net.
For IPv6, the function also captures the link-local address into
c->ip6.our_tap_ll as a side effect.
Update conf_ip4() and conf_ip6() to use nl_addr_get_all() when no
user-specified addresses are present.
Signed-off-by: Jon Maloy
Allow specifying multiple addresses per family with -a/--address.
The first address of each family is used for DHCP/DHCPv6 assignment.
Signed-off-by: Jon Maloy
We remove the addr_seen field in struct ip4_ctx and replace it by
setting a new CONF_ADDR_OBSERVED flag in the corresponding entry
in the unified address array.
The observed IPv4 address is always added at or moved to position 0,
increasing chances for a fast lookup.
Signed-off-by: Jon Maloy
After the previous changes in this series it becomes possible
to simplify the pasta_ns_conf() function.
We extract address and route configuration into helper functions
pasta_conf_addrs() and pasta_conf_routes(), reducing nesting
and improving readability.
To allow pasta_conf_addrs() to handle both address families
uniformly, we change nl_addr_set() to take a union inany_addr pointer
instead of void pointer, moving the address family handling into
the function itself.
We also fix a bug where the IPv6 code path incorrectly wrote to
req.set.a4.rta_l.rta_type instead of req.set.a6.rta_l.rta_type.
Signed-off-by: Jon Maloy
We remove the addr_seen and addr_ll_seen fields in struct ip6_ctx
and replace them by setting CONF_ADDR_OBSERVED and CONF_ADDR_LINKLOCAL
flags in the corresponding entry in the unified address array.
The observed IPv6 address is always added/moved to position 0
in the array, improving chances for fast lookup.
The separate check against addr_seen in fwd_guest_accessible() can now
be removed because the observed address is now in the unified array,
and the existing for_each_addr() loop already checks against all
addresses, including this one.
This completes the unification of address storage for both IPv4 and
IPv6, enabling future support for multiple guest addresses per family.
Signed-off-by: Jon Maloy
We introduce a CONF_ADDR_DHCP flag to mark if an added address is
eligible for DHCP advertisement. By doing this once and for all
in the fwd_set_addr() function, the DHCP code only needs to check
for this flag to know that all criteria for advertisement are
fulfilled. Hence, we update the code in dhcp.c correspondingly.
We also let the conf_print() function use this flag to determine
and print the selected address.
Signed-off-by: Jon Maloy
We update the migration protocol to version 3 to support distributing
multiple addresses from the unified address array. The new protocol
migrates all address entries in the array, along with their prefix
lengths and flags, and leaves it to the receiver to filter which
ones he wants to apply.
Signed-off-by: Jon Maloy
We introduce a CONF_ADDR_DHCPV6 flag to mark if an added address is
eligible for DHCP advertisement. By doing this once and for all
in the fwd_set_addr() function, the DHCPv6 code only needs to check
for this flag to know that all criteria for advertisement are fulfilled.
We update the code in dhcpv6.c both to use the new flag and to make
it possible to send multiple addresses in a single reply message,
per RFC 8415.
We also let the conf_print() function use this flag to identify and
print the eligible addresses.
Signed-off-by: Jon Maloy
We extend NDP to advertise all suitable IPv6 prefixes in Router
Advertisements, per RFC 4861. Observed and link-local addresses,
plus addresses with a prefix length != 64, are excluded.
Signed-off-by: Jon Maloy
participants (1)
-
Jon Maloy