[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] RFC: Supporting IPv6 on libvirt virtual networks



There are a couple of bugzilla records open requesting IPv6 support on
libvirt's virtual networks:

https://bugzilla.redhat.com/show_bug.cgi?id=514749
https://bugzilla.redhat.com/show_bug.cgi?id=586124

This is a first cut at describing what that support will look
like. Please send any comments/criticisms/suggestions you may have.

Changes to network XML
----------------------

1) The <ip> element of the network xml will be expanded in the following ways:

a) <ip> can now appear multiple times (although I think only one of
   these can/should be allowed to have a <dhcp> element). The bridge
   interface (eg virbr0) will be configured with all given ips.

b) The address attribute can now be either an ipv4 dotted quad, or an
   ipv6 address, eg "2001:db8:1::10" (the schema will allow either in
   any case, but the parser will validate that it is appropriate for
   the given family - see (b))

b) new attributes:

   family="ipv4|ipv6".

     Optional. It will default to ipv4 if not specified.

   prefix="<some number>"

     Optional. This is used to specify how many significant bits are
     in the ipv6 address. This will also be usable for ipv4, but the
     parser will make sure that only one of netmask or prefix is given
     for an ipv4 address (since netmasks generally aren't specified as
     such in IPv6, the netmask attribute will not be allowed if family
     is ipv6).

2) New subelements of <ip>

   If we want to avoid requiring the admin to login to the hosts to
   configure radvd for advertising addresses, the ipv6 version of <ip>
   is going to need radvd config information. The list of options is
   rather long, and I don't see how we could assume a hardcoded
   default for any of them, so if we're going to have an <radvd>
   subelement, it's going to need a *lot* of attributes/subelements of
   its own:

     http://linux.die.net/man/5/radvd.conf

For this reason, I think we can at least initially *not* include all this config,
   and not attempt to run radvd ourselves.

   However, we can't merely ignore radvd, since our bridges don't
   exist at the time radvd is started by the system, and even if
   you've put the proper config in the static radvd.conf file, it
   can't be recognized until the interface exists, and the method of
   informing radvd that it needs to re-scan the conf file to find new
   interfaces is to send it a SIGHUP.

   So, I'm thinking we can add an <radvd/> subelement to IP that, for
   now, will have no attributes and no subelements. If the ip/radvd
   subelement exists, libvirt will send radvd a SIGHUP when the
   network is brought up, and again if it is brought down.

Here is the example from formatnetwork.html on libvirt.org, updated with examples of
the changes I'm proposing:

<network>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.100" end="192.168.122.254" />
<host mac="00:16:3e:77:e2:ed" name="foo.example.com" ip="192.168.122.10" />
<host mac="00:16:3e:3e:a9:1a" name="bar.example.com" ip="192.168.122.11" />
</dhcp>
</ip>
<ip family="ipv4" address="192.168.125.1" prefix="24">
<ip family="ipv6" address="2001:db8:1::10" prefix="128"/>
<ip family="ipv6" address="2001:4978:2ac::1" prefix="48">
<radvd/>
</ip>
</network>

The original ipv4 address example remains unchanged, but notice that
we can also give a 2nd ipv4 address, and can use "prefix" instead of
"netmask" if we want.

The example configs the bridge with two ipv6 addresses, so guests
connected to the bridge can be on either of these networks or both. In
addition, radvd will be SIGHUPed when the network is brought up, so if
it is configured properly, it will begin giving out addresses on the
network via IPv6 autoconf (presumably on the 2001:4978:2ac::/28
network, although that's completely dependent on the radvd config.


NB: As previously discussed, we are making the assumptions that

 1) nobody will want to use dhcp6 (although it's available, autoconf
    via radvd is the more accepted method of automatically getting an
    address).

 2) any tftp booting required can be done with the IPv4 facilities
    already in place (ie, if that is needed, the guests will use both
    IPv4 and IPv6). Likewise for any other configuration required that
    isn't covered by ipv6 autoconf.

 3) radvd configuration is outside the scope of libvirt, although
    libvirt can give it a kick now and then.

Configuring the IP addresses of the bridge
------------------------------------------

Currently, libvirt uses the SIOCSIFADDR ioctl to set the (single) ipv4
address of the bridge. This ioctl does not support IPv6. In order to
configure and IPv6 address (or more than one IPv4 address) we will
need to use netlink (ie libnl).

Unfortunately, libnl isn't available on all Linux platforms (libvirt's
virtual networks are only available on Linux), for example RHEL5 has
libnl, but it's an older version that is API-incompatible with the
version used by libvirt.

libvirt already uses libnl directly for macvtap support, and
indirectly for netcf (the iface-* commands), but both of those are
conditionally compiled. In order to continue supporting older
platforms, all this IPv6 stuff will need to be optional, and
conditional on the presence of the right libnl version. If libnl is
available, the default will be --with-ipv6, otherwise, the default
will be --without-ipv6.

Also, src/network/bridge_driver.c:networkDisableIPV6, which tweaks
some kernel tunables to disallow adding IPv6 addresses to a bridge, is
currently called for all networks' bridges when they are brought
up. This will of course now be called only if the network has no IPv6
config.


iptables/ip6tables
------------------

The ip6tables rules setup for the bridge will be similar to those we
already setup for ipv4. See Bug 586124 for a short script that creates
a workable set of rules.

"mode=nat" anomoly
------------------

libvirt's virtual networks have three modes: isolated, routed, and
nat. If mode=isolated or mode=routed, IPv6 and IPv4 will be handled
the same. However, since there is no NAT for IPv6, if you specify
mode='nat' on a network, and give it an IPv6 address, the IPv6 traffic
will be routed, while IPv4 traffic will be NATed. (Since there is a
single mode attribute for the entire network, it will not be possible
to specify isolated IPv6 and routed/nat IPv4, or isolated IPv4 and
routed IPv6).


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]