Page MenuHomeVyOS Platform

VRRP V3 backup router sending ND RA
Open, NormalPublicBUG

Description

When configuring VRRP using IPv6 virtual address in combination with router advertise only the master should send ND RA according to RFC 5798 6.4.2

To reproduce:
Router1:

vyos@vyos-vrrp1# run sh config commands
set high-availability vrrp group eth1-50 advertise-interval '1'
set high-availability vrrp group eth1-50 interface 'eth1'
set high-availability vrrp group eth1-50 priority '150'
set high-availability vrrp group eth1-50 virtual-address '10.1.1.50/24'
set high-availability vrrp group eth1-50 vrid '50'
set high-availability vrrp group eth1-51 interface 'eth1'
set high-availability vrrp group eth1-51 priority '150'
set high-availability vrrp group eth1-51 virtual-address '2001:4642:3a8e:fff0::100/64'
set high-availability vrrp group eth1-51 vrid '51'
set high-availability vrrp sync-group vyos-vrrp member 'eth1-50'
set interfaces ethernet eth0 address 'dhcp'
set interfaces ethernet eth0 duplex 'auto'
set interfaces ethernet eth0 hw-id '00:0c:29:32:59:cc'
set interfaces ethernet eth0 smp-affinity 'auto'
set interfaces ethernet eth0 speed 'auto'
set interfaces ethernet eth1 address '192.168.0.0/31'
set interfaces ethernet eth1 duplex 'auto'
set interfaces ethernet eth1 hw-id '00:0c:29:32:59:d6'
set interfaces ethernet eth1 ipv6 router-advert prefix 2001:4642:3a8e:fff0::/64
set interfaces ethernet eth1 smp-affinity 'auto'
set interfaces ethernet eth1 speed 'auto'

Router2:

vyos@vyos-vrrp2# run sh configuration commands
set high-availability vrrp group eth1-50 advertise-interval '1'
set high-availability vrrp group eth1-50 interface 'eth1'
set high-availability vrrp group eth1-50 priority '50'
set high-availability vrrp group eth1-50 virtual-address '10.1.1.50/24'
set high-availability vrrp group eth1-50 vrid '50'
set high-availability vrrp group eth1-51 interface 'eth1'
set high-availability vrrp group eth1-51 priority '50'
set high-availability vrrp group eth1-51 virtual-address '2001:4642:3a8e:fff0::100/64'
set high-availability vrrp group eth1-51 vrid '51'
set high-availability vrrp sync-group vyos-vrrp member 'eth1-50'
set interfaces ethernet eth0 address 'dhcp'
set interfaces ethernet eth0 duplex 'auto'
set interfaces ethernet eth0 hw-id '00:0c:29:d3:a5:45'
set interfaces ethernet eth0 smp-affinity 'auto'
set interfaces ethernet eth0 speed 'auto'
set interfaces ethernet eth1 address '192.168.0.1/31'
set interfaces ethernet eth1 duplex 'auto'
set interfaces ethernet eth1 hw-id '00:0c:29:d3:a5:4f'
set interfaces ethernet eth1 ipv6 router-advert prefix 2001:4642:3a8e:fff0::/64
set interfaces ethernet eth1 smp-affinity 'auto'
set interfaces ethernet eth1 speed 'auto'

Observ packets on network connected to eth1 using wireshark and see both routers sending router advertisement.

Details

Difficulty level
Hard (possibly days)
Version
VyOS 1.2.0-rolling+201809050337
Why the issue appeared?
Will be filled on close
Is it a breaking change?
Behavior change

Event Timeline

This will need to be implemented using transition scripts in keepalived to enable and disable radvd for the prefix.

In the meantime one work-around would be to set your primary with a priority of high and backup with a priority of medium allowing the hosts to select the gateway based on preference.

Would likely implement as an additional option e.g.

set high-availability vrrp group <x> enable-ipv6-ra-failover

Note: For automatic address configuration (as opposed to manual) the next-hop used will be the link-local address rather than the global address so VRRP for the global address will not impact next-hop on its own except for hosts which have manually configured the default gateway to be that address.

Having VRRP for IPv6 will be very helpful for failover scenarios which make use of static IP routes though (e.g. for outside interfaces in a firewall configuration).

Agree that getting radvd start-stop support tied into VRRP should be a priority for IPv6 support though.

In T840#19823, @c-po wrote:

Did you respond to the wrong task?

@rps seems to be the case. sorry for the noise

So I'm not sure this is a bug as much as a feature request. You CAN in fact accomplish what you're trying to do in VyOS 1.2 albeit manually using a transition script.

As a proof-of-concept you can create a transition script and reference it in your VRRP configuration for master, backup, and fault which will disable radvd for the specific interface using the CLI API:

#!/bin/bash

LOG_FILE=/tmp/vrrp-ipv6-transition.log

date  >> $LOG_FILE

STATE=$1
INTERFACE=$2
GROUP=$3


radvd_enable() {
    session_env=$(cli-shell-api getSessionEnv $PPID)
    eval $session_env
    cli-shell-api setupSession
    cli-shell-api inSession
    if [ $? -ne 0 ]; then
        echo "Error: Unable to obtain API session" >> $LOG_FILE
        exit 1
    fi
    /opt/vyatta/sbin/my_set interfaces ethernet $INTERFACE ipv6 router-advert send-advert true
    /opt/vyatta/sbin/my_commit
    cli-shell-api teardownSession
}

radvd_disable() {
    session_env=$(cli-shell-api getSessionEnv $PPID)
    eval $session_env
    cli-shell-api setupSession
    cli-shell-api inSession
    if [ $? -ne 0 ]; then
        echo "Error: Unable to obtain API session" >> $LOG_FILE
        exit 1
    fi
    /opt/vyatta/sbin/my_set interfaces ethernet $INTERFACE ipv6 router-advert send-advert false
    /opt/vyatta/sbin/my_commit
    cli-shell-api teardownSession
}


case $STATE in
    "master")
        echo "$INTERFACE has entered a MASTER state" >> $LOG_FILE
        radvd_enable
    ;;
    "backup")
        echo "$INTERFACE has entered a BACKUP state" >> $LOG_FILE
        radvd_disable
    ;;
    "fault")
        echo "$INTERFACE has entered a FAULT state" >> $LOG_FILE
        radvd_disable
    ;;
esac

I verified that this transition script will correctly transition IPv6 RA with VRRP with the following configuration:

set high-availability vrrp group <group> transition-script backup '/config/scripts/vrrp-ipv6-transition.script'
set high-availability vrrp group <group> transition-script fault '/config/scripts/vrrp-ipv6-transition.script'
set high-availability vrrp group <group> transition-script master '/config/scripts/vrrp-ipv6-transition.script'

Example RA configuration:

set interfaces ethernet eth2 ipv6 router-advert cur-hop-limit '64'
set interfaces ethernet eth2 ipv6 router-advert default-lifetime '300'
set interfaces ethernet eth2 ipv6 router-advert default-preference 'high'
set interfaces ethernet eth2 ipv6 router-advert link-mtu '0'
set interfaces ethernet eth2 ipv6 router-advert max-interval '30'
set interfaces ethernet eth2 ipv6 router-advert prefix fd02::/64 autonomous-flag 'true'
set interfaces ethernet eth2 ipv6 router-advert prefix fd02::/64 on-link-flag 'true'
set interfaces ethernet eth2 ipv6 router-advert prefix fd02::/64 preferred-lifetime '300'
set interfaces ethernet eth2 ipv6 router-advert prefix fd02::/64 valid-lifetime '900'
set interfaces ethernet eth2 ipv6 router-advert reachable-time '900000'
set interfaces ethernet eth2 ipv6 router-advert retrans-timer '0'
set interfaces ethernet eth2 ipv6 router-advert send-advert 'true'

I do agree that there should be a pre-canned way to do this.

I'm also not sure that radvd configuration is best kept in the interface now that VRRP configuration has been moved out (perhaps under protocols or services).

Thoughts?

I think the radvd should be made vrrp3 aware. In Juniper this looks like protocols router-advertisement interface <val> virtual-router-only: Send advertisemnets only for vrrp-inet6-group.

@rps I think this is a bug, because this behavior is not by design - it just to happen ;-) . You may call i a design bug.

Using a transition script is not a problem for me. If we could make the router to behave correctly out of the box it would be better. I just think the implementation should be based on a qualified choice. This make it easier to test, respond to requests about the feature and to document the feature.

I do agree that there should be a pre-canned way to do this.

I don't think we have any disagreement here @aopdal

syncer triaged this task as High priority.Sep 25 2018, 2:07 PM
syncer lowered the priority of this task from High to Normal.Nov 2 2018, 7:32 PM

Thanks @rherold! Good to know that radvd already supports link-local IPv6 selection!

Regarding standby router sending RAs, we also think it should be a nice option to link VRRP state (master, standby/fault) with router-advert sending (send-advert true/false).
We were already discussing this some months ago and even we now have some production systems with transition scripts:
https://phabricator.vyos.net/T448

@syncer, do you think is there a chance for this feature request to be added to Crux? Or not until Equuleus? Using transition scripts works but sometimes there is some kind of failure in these scripts and we find both routers (VRRP master and backup) sending RAs :-(

Thank you all!

To dust off this one...

Summary:

  • When using VRRP for IPv6 only the active router should perform router advertisements
  • This is defined in RFC 5798 section 6.4.2
  • The expected behavior is also that VRRP will handle failover of a link-local address, and that RAs will be sourced using the virtual address. For example, fe80::1.

Task 1: Upgrade radvd to 2.x

Currently VyOS does not allow for configuring the link-local address used to source RAs, this is defined by the AdvRASrcAddress option in radvd version 2 or later (we are on 1.9). This could be implemented as set interfaces ethernet <int> ipv6 router-advert use-source-address <addr>.

Task 2: Support user-defined link-local address

Currently you can add additional link-local addresses but you can not replace the default link-local address of an interface. For consistency it is common practice in VRRP or HSRP environments to define a VLAN-specific link-local address such as fe80::29:1 as a virtual link-local and fe80::29:2 , fe80::29:3 as the native link-local addresses for each router. This also comes into play when working around software issues which do not correctly distinguish network interface when multiple link-local addresses are in use and there is a uniqueness requirement for link-local addressing across VLANs.

Suggested configuration would be to add a set interfaces ethernet <int> ipv6 link-local configuration block, or a link-local flag following an IPv6 address.

Task 3: Add option for radvd to be enabled or disabled by keepalived

I suggest updating set interfaces ethernet <int> ipv6 router-advert send-advert 'true' to add a third option of high-availability-only alongside true and false and add a built-in VRRP transition script that takes effect before user-defined scrips which handles a reconfiguration and start-stop of radvd on state change.

Thoughts?

Hi @rps ,
Very good summary of what is needed. I think what you state fits perfectly in our (and most) uses cases. We need to sync RAs with VRRP state, and we would need to use a "virtual IP" like fe80::1 to be announced to neighbors as the default gateway.
So for me makes absolutely sense, thanks for your effort!
If you need any help defining/testing, just let me know!

zsdc changed Difficulty level from Unknown (require assessment) to Hard (possibly days).Mar 11 2021, 6:59 PM
zsdc set Is it a breaking change? to Behavior change.

Is it an actual task? If yes, can someone explain which configuration you expect from keepalived.conf or radvd.conf?
As I see PR 9aad6f was merged.

Hi @Viacheslav, I guess that, at least for our use cases, PR 9aad6f would allow the expected behavior.

From what I understand, if we could configure in VyOS the source address for the RAs, and set it to one of the VRRP virtual addresses, only the VRRP master would send the RAs, since the VRRP backup interface addresses would not intersect the configured RA source address.

Did I get it right?

Thanks!