From: vivek Date: Fri, 20 Nov 2015 18:34:50 +0000 (-0800) Subject: Zebra: Handle IPv6 address status during initialization X-Git-Tag: frr-2.0-rc1~1190 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=6a3b3531684a61f8500f6bfc595d649da2296c38;p=mirror%2Ffrr.git Zebra: Handle IPv6 address status during initialization At init time, Zebra queries the kernel for all interfaces. At this time, an IPv6 address may exist on an interface but IPv6 DAD has not completed, or it could be that DAD has failed. Zebra should examine the flags on the address and act accordingly. Otherwise, it may end up with addresses and routes which are not actually valid in the kernel, and this may lead to, for example, BGP attempting neighbor connections on an interface on which the source IPv6 address is not yet valid. Signed-off-by: Vivek Venkatraman Reviewed-by: Dinesh Dutt Ticket: CM-7176 Reviewed By: CCR-3815 Testing Done: Verify failed test (needs temporary test change) Note: Imported from 2.5-br patch zebra-handle-ipv6-addr-status.patch. --- diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 183dc6e057..88fac53310 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -575,8 +575,9 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h, if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */ { char buf[BUFSIZ]; - zlog_debug ("netlink_interface_addr %s %s vrf %u:", - lookup (nlmsg_str, h->nlmsg_type), ifp->name, vrf_id); + zlog_debug ("netlink_interface_addr %s %s vrf %u flags 0x%x:", + lookup (nlmsg_str, h->nlmsg_type), ifp->name, + vrf_id, ifa->ifa_flags); if (tb[IFA_LOCAL]) zlog_debug (" IFA_LOCAL %s/%d", inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]), @@ -654,9 +655,15 @@ netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h, if (ifa->ifa_family == AF_INET6) { if (h->nlmsg_type == RTM_NEWADDR) - connected_add_ipv6 (ifp, flags, - (struct in6_addr *) addr, ifa->ifa_prefixlen, - (struct in6_addr *) broad, label); + { + /* Only consider valid addresses; we'll not get a notification from + * the kernel till IPv6 DAD has completed, but at init time, Quagga + * does query for and will receive all addresses. + */ + if (!(ifa->ifa_flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE))) + connected_add_ipv6 (ifp, flags, (struct in6_addr *) addr, + ifa->ifa_prefixlen, (struct in6_addr *) broad, label); + } else connected_delete_ipv6 (ifp, (struct in6_addr *) addr, ifa->ifa_prefixlen,