Hello guys!

I got into problem with installing IPv6 default gateway on centos7 guest while running dhcpv6.

=== Scheme ===

Guest has two network interfaces.

eth0 is connected to Host-Only network over virbr0. This network has dhcpv6 set up.

[root@s143 ~]# virsh net-dumpxml Host-Only
<network connections='1'>
  <name>Host-Only</name>
  <uuid>11aa4e6a-9014-4dae-86b9-b13159896efe</uuid>
  <bridge name='virbr0' stp='off' delay='0'/>
  <mac address='52:54:00:1e:17:49'/>
  <ip family='ipv4' address='10.37.130.2' prefix='24'>
    <dhcp>
      <range start='10.37.130.1' end='10.37.130.254'/>
    </dhcp>
  </ip>
  <ip family='ipv6' address='fdb2:2c26:f4e4::1' prefix='64'>
    <dhcp>
      <range start='fdb2:2c26:f4e4::' end='fdb2:2c26:f4e4::ffff'/>
    </dhcp>
  </ip>
</network>


eth1 is connected to Bridged network over br0 bridge on host enp4s0 interface.

[root@s143 ~]# virsh net-dumpxml Bridged
<network connections='1'>
  <name>Bridged</name>
  <uuid>1ffa16f9-6a52-4710-9b58-52b8463cdece</uuid>
  <forward mode='bridge'/>
  <bridge name='br0'/>
</network>


[root@s143 ~]# virsh iface-dumpxml br0
<interface type='bridge' name='br0'>
  <protocol family='ipv4'>
    <ip address='10.94.1.161' prefix='16'/>
  </protocol>
  <protocol family='ipv6'>
    <ip address='2001:aaad::a5e:a28E' prefix='64'/>
    <ip address='fe80::be5f:f4ff:fe44:2cbb' prefix='64'/>
  </protocol>
  <bridge>
    <interface type='ethernet' name='vme42460d71'>
      <link state='unknown'/>
      <mac address='fe:1c:42:46:0d:71'/>
    </interface>
    <interface type='ethernet' name='enp4s0'>
      <link speed='1000' state='up'/>
      <mac address='bc:5f:f4:44:2c:bb'/>
    </interface>
  </bridge>
</interface>


=== Problem ===

Now I want to set ipv6 address 2001:aaad::a5e:a28F to guest eth1 (bridged to host)
and install a default route
ip -6 route add default via 2001:aaad::a5e:a290 dev eth1 // metric 1024

So I want all the IPv6 traffic w/o route to go into eth1, then through host bridge to gateway (same for host and guest).

The problem is that I see following in my guest:

// the metric changes somehow, but this does not matter.
default via fe80::5054:ff:fe1e:1749 dev eth0  proto static  metric 100  pref medium
default via 2001:aaad::a5e:a290 dev eth1  metric 1024  pref medium


And the first (via link-local) route is preferred on routing.

[root@s143 ~]# ip -6 address show dev virbr0
6: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
    inet6 fdb2:2c26:f4e4::1/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::5054:ff:fe1e:1749/64 scope link
       valid_lft forever preferred_lft forever


The problem is:
guest:/ # radvdump
#
# radvd configuration generated by radvdump 2.11
# based on Router Advertisement from fe80::5054:ff:fe1e:1749
# received by interface eth0
#

interface eth0
{
    AdvSendAdvert on;
    # Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
    AdvManagedFlag on;
    AdvOtherConfigFlag on;
    AdvReachableTime 0;
    AdvRetransTimer 0;
    AdvCurHopLimit 64;
    AdvDefaultLifetime 1800; <----------------
    AdvHomeAgentFlag off;
    AdvDefaultPreference medium;
    AdvLinkMTU 1500;
    AdvSourceLLAddress on;

    prefix fdb2:2c26:f4e4::/64
    {
        AdvValidLifetime 3600;
        AdvPreferredLifetime 3600;
        AdvOnLink on;
        AdvAutonomous off;
        AdvRouterAddr off;
    }; # End of prefix definition


    RDNSS fe80::5054:ff:fe1e:1749
    {
        AdvRDNSSLifetime 3600;
    }; # End of RDNSS definition

}; # End of interface definition


So, dnsmasq includes its link-local address into RA and
announces itself as default gateway valid for 30min.
Guest sees this RA and installs a route in accordance.

As a result, the default gateway requested by user is overridden and thus not used.
We cannot just disable RA since we still need IPv6 address on guest eth0 (dhcp6 part of functionality).

=== Possible solutions ===

I see two possible solutions.
1) Tinker with routes.
As I said, the metric of installed RA routes may change and it's difficult to override them for sure (maybe with metric 0 or 1?)
Moreover, this may confuse user and requires specific knowledge (IPv6, RA, etc.).

2) Forbid guest to learn default route from RA
sysctl -w net.ipv6.conf.eth0.accept_ra_defrtr=0
- This should be made for all virbr-based networks.
- This may confuse user as well.

3) Forbid dnsmasq to announce virbr0 link-local address as default gateway.
This can be made with
adding 'ra-param=*,0,0' to /var/lib/libvirt/dnsmasq/Host-Only.conf
// interface=* (any), interval=0 (default), router_lifetime=0 (I am NOT you gateway, Luke).
// tested on dnsmasq-2.75-3.fc22 but should work from 2.67
 now the RA looks as following:

linux-bnqo:/ # radvdump
#
# radvd configuration generated by radvdump 2.11
# based on Router Advertisement from fe80::5054:ff:fe1e:1749
# received by interface eth0
#

interface eth0
{
    AdvSendAdvert on;
    # Note: {Min,Max}RtrAdvInterval cannot be obtained with radvdump
    AdvManagedFlag on;
    AdvOtherConfigFlag on;
    AdvReachableTime 0;
    AdvRetransTimer 0;
    AdvCurHopLimit 64;
    AdvDefaultLifetime 0;
    AdvHomeAgentFlag off;
    AdvDefaultPreference medium;
    AdvLinkMTU 1500;
    AdvSourceLLAddress on;

    prefix fdb2:2c26:f4e4::/64
    {
        AdvValidLifetime 3600;
        AdvPreferredLifetime 3600;
        AdvOnLink on;
        AdvAutonomous off;
        AdvRouterAddr off;
    }; # End of prefix definition


    RDNSS fe80::5054:ff:fe1e:1749
    {
        AdvRDNSSLifetime 3600;
    }; # End of RDNSS definition

}; # End of interface definition


=== Conclusion ====

Please correct me if my setup itself is wrong and causes problems.
Maybe there are another solutions possible, w/o modifying libvirt/guest?
Would you accept patches related to 3rd solution?

Looking forward to your replies.
Thanks in advance!
-- 
Your sincerely,
Maxim Perevedentsev