Skip to content

F #-: VRouter: IPv6 support (Forwarding, VRRP, DNS) - #417

Open
netaviator wants to merge 3 commits into
OpenNebula:masterfrom
netaviator:pr/vrouter-ipv6-support
Open

netaviator wants to merge 3 commits into
OpenNebula:masterfrom
netaviator:pr/vrouter-ipv6-support

Conversation

@netaviator

Copy link
Copy Markdown

Add IPv6 support to the VRouter: a router that holds IPv6 virtual IPs has to forward IPv6 as well, and the DNS resolver has to answer on them.

IPv6 forwarding. New Router6 module, opt-in with ONEAPP_VNF_ROUTER6_ENABLED (default NO). It is modelled on Router4 and writes /etc/sysctl.d/98-Router6.conf on start. Linux forwards IPv6 only when net.ipv6.conf.all.forwarding is 1, and once it is on the router forwards between all interfaces, so the management NICs are kept from being routers themselves. accept_ra=2 is written first on every NIC, because the global switch would turn off router advertisements on NICs that use SLAAC. The Failover service now starts Router6 on the VRRP master.

IPv6 virtual IPs via VRRP. IPv6 VIPs next to the IPv4 ones, from ETH_VROUTER_IP6 and ONEAPP_VROUTER_ETH_VIP. An address given by both is listed once. A VIP without a prefix length gets /64. A malformed IPv6 VIP is skipped with an error that names the attribute. Keepalived needs one instance per address family, so a second instance _6 joins the same sync group. IPv6 VIPs are installed with preferred_lft 0, so the kernel does not pick the VIP as the source address of the router's own traffic.

DNS: The resolver also serves the IPv6 addresses of the NICs. A NIC with IPv6 gets one explicit interface line per address (with ip-freebind), so a VIP that is not on the standby yet does not break unbound and no address is bound twice.

Two parts that belong together: a router that holds IPv6 VIPs has to
forward IPv6 as well.

IPv6 forwarding: new Router6 module
Router4 enables IPv4 forwarding on the routed NICs; nothing does it for
IPv6. Add the counterpart as an opt-in service (ONEAPP_VNF_ROUTER6_ENABLED,
default NO), modelled on Router4: an OpenRC service that writes
/etc/sysctl.d/98-Router6.conf on start and switches everything off on stop.
Unlike IPv4, Linux forwards IPv6 only when net.ipv6.conf.all.forwarding is
1: writing the per-interface switches does not turn the router on, and
once the global switch is on the router forwards between ALL interfaces.
So the global switch is set and only the management NICs are kept from
being routers themselves. accept_ra=2 is written first on every NIC,
because setting all.forwarding=1 turns router advertisement acceptance off
on the interfaces that have accept_ra=1 (a NIC configured by SLAAC would
lose its address). There is no IPv6 filtering or NAT66 in the appliance;
that is why the default is NO.

IPv6 virtual IPs via VRRP
Allow IPv6 VIPs next to the IPv4 ones. They come from the OpenNebula
floating IPv6 (ETH<n>_VROUTER_IP6) and from ONEAPP_VROUTER_ETH<n>_VIP<m>;
an address given by both is listed once and the explicit value wins.

* An IPv6 VIP without a prefix length gets /64 (ETH<n>_MASK and the IPv4
  range guesses do not apply). A prefix length of 0 becomes /128, like /32
  for IPv4. When the prefix length of an IPv4 VIP has to be guessed, a
  warning is logged once per NIC and address.
* A malformed IPv6 VIP is skipped with an error that names the attribute
  (at most 40 characters of the value are logged) instead of breaking
  keepalived.conf or the rest of the VIPs.
* VRRP: keepalived needs one instance per address family, so a second
  instance <NIC>_6 joins the same vrrp_sync_group as the IPv4 one (no
  authentication on it: it is not allowed for IPv6). A NIC group with
  IPv6 VIPs only gets just that instance. The Failover module reacts to
  the group event only, so nothing changes there.
* IPv6 VIPs are installed with preferred_lft 0. Otherwise the kernel picks
  the VIP as the source address of the router's own IPv6 traffic (measured
  on the VRRP master), and sessions to a peer that only knows the node
  address never came up. The VIP stays on the NIC and is still answered for.
* Addresses are compared in the form "ip -j addr" prints (compressed,
  lower case), so the readiness check does not fail on notation.

Tests: the Router6 module, the VIP detection and the generated
keepalived.conf, and IPv6 examples for the HAProxy and LVS configuration
(both are address family generic; frontends bind to the VIPs).

Signed-off-by: Jan Gilla <jgilla@level66.network>
The failover service starts the routing services on the VRRP master from
its SERVICES table, which had no entry for one-router6. With
ONEAPP_VNF_ROUTER6_ENABLED=YES the service was installed but never
started, so the IPv6 forwarding settings were never written.

Signed-off-by: Jan Gilla <jgilla@level66.network>
Serve DNS on IPv6 addresses of the NICs. NICs with IPv6 get one explicit
interface line per address (no NIC name, ip-freebind), so VIPs that are not
yet present on the BACKUP do not break unbound and addresses are not bound
twice. do-ip6 and freebind follow the final bind list.

Signed-off-by: Jan Gilla <jgilla@level66.network>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant