diff options
author | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-03-08 19:30:03 +0100 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-05-17 02:27:08 +0200 |
commit | 1760ce424b642c8ac9e7d4db72f9346533da1f98 (patch) | |
tree | 9cd6e18609e9d15eddbc0eff10b855d0c9e0023f /vrrpd/vrrp.c | |
parent | Revert "vrrpd: protodown mvlans when shutting down" (diff) | |
download | frr-1760ce424b642c8ac9e7d4db72f9346533da1f98.tar.xz frr-1760ce424b642c8ac9e7d4db72f9346533da1f98.zip |
vrrpd: allow OS to choose VRRP IPv6 src address
Under IPv6, Linux will look at our destination address and select the
source address with the smallest scope that covers the destination. For
the VRRP multicast address ff02::12, Linux will always select a link
local address.
We can take advantage of this behavior to avoid a subtle and complicated
class of bugs caused by Zebra's semantics around inoperative interfaces.
As far as Zebra is concerned, an inoperative interface has no addresses
assigned to it. This is a real bummer for VRRP because it's quite
possible that the IPv6 VRRP macvlan device is down when we attach to it,
and we would really like to be able to know in advance which address we
will be transmitting IPv6 advertisements from without having to bring an
interface up to convince Zebra to tell us its address list.
In the future, though, it would be better to be explicit about selecting
the link local we want. This will require adding the ability to Zebra to
read and send us address information for inoperative interfaces.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'vrrpd/vrrp.c')
-rw-r--r-- | vrrpd/vrrp.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c index cba078a6c..6262cd692 100644 --- a/vrrpd/vrrp.c +++ b/vrrpd/vrrp.c @@ -315,10 +315,10 @@ void vrrp_check_start(struct vrrp_vrouter *vr) #if 0 /* Macvlan interface must be admin up */ start = start && CHECK_FLAG(r->mvl_ifp->flags, IFF_UP); -#endif /* Macvlan interface must have a link local */ start = start && connected_get_linklocal(r->mvl_ifp); whynot = (!start && !whynot) ? "No link local address configured" : NULL; +#endif /* Macvlan interface must have a v6 IP besides the link local */ start = start && (r->mvl_ifp->connected->count >= 2); whynot = (!start && !whynot) ? "No Virtual IP address configured" : NULL; @@ -1125,6 +1125,13 @@ static int vrrp_socket(struct vrrp_router *r) VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM "Set %s as outgoing multicast interface", r->vr->vrid, family2str(r->family), r->mvl_ifp->name); + + /* Select and bind source address */ + if (vrrp_bind_to_primary_connected(r) < 0) { + failed = true; + goto done; + } + } else if (r->family == AF_INET6) { /* Always transmit IPv6 packets with hop limit set to 255 */ ret = setsockopt_ipv6_multicast_hops(r->sock_tx, 255); @@ -1227,12 +1234,6 @@ static int vrrp_socket(struct vrrp_router *r) r->vr->vrid, family2str(r->family), r->mvl_ifp->name); } - /* Bind Tx socket to link-local address */ - if (vrrp_bind_to_primary_connected(r) < 0) { - failed = true; - goto done; - } - done: ret = 0; if (failed) { |