From: vivek Date: Fri, 13 May 2016 01:31:19 +0000 (-0700) Subject: Revert "Zebra: Update/fix router_lifetime in IPv6 RAs" X-Git-Tag: frr-2.0-rc1~918 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=6b9efc026fe0632d580672e3182e614aef935ac8;p=mirror%2Ffrr.git Revert "Zebra: Update/fix router_lifetime in IPv6 RAs" This reverts commit 690baa53592320dddee5c729f959150cc9a72699. Making the router lifetime in the IPv6 RAs as 0 by default would break BGP unnumbered when this version of Quagga goes up against a 2.5.x Quagga. This is because of a defect in the Quagga code that ignores any received RAs with a lifetime of 0. --- diff --git a/zebra/rtadv.c b/zebra/rtadv.c index d4d48988c7..02499a3557 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -189,14 +189,8 @@ rtadv_send_packet (int sock, struct interface *ifp) rtadv->nd_ra_curhoplimit = 64; /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */ -#if defined(HAVE_CUMULUS) - /* Uninitialized (default) lifetime means 0. */ - rtadv->nd_ra_flags_reserved = - zif->rtadv.AdvDefaultLifetime <= 0 ? 0 : zif->rtadv.DefaultPreference; -#else rtadv->nd_ra_flags_reserved = zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference; -#endif rtadv->nd_ra_flags_reserved <<= 3; if (zif->rtadv.AdvManagedFlag) @@ -213,15 +207,9 @@ rtadv_send_packet (int sock, struct interface *ifp) * value for this field. To prevent this, routers SHOULD keep * AdvDefaultLifetime in at least one second, even if the use of * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */ -#if defined(HAVE_CUMULUS) - /* Uninitialized (default) lifetime means 0. */ - pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ? - zif->rtadv.AdvDefaultLifetime : 0; -#else pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ? zif->rtadv.AdvDefaultLifetime : MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval); -#endif rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime); rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime); rtadv->nd_ra_retransmit = htonl (0); @@ -460,7 +448,6 @@ rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp, struct nd_router_advert *radvert; char addr_str[INET6_ADDRSTRLEN]; struct zebra_if *zif; - struct prefix p; zif = ifp->info; @@ -514,13 +501,15 @@ rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp, ifp->name, ifp->ifindex, addr_str); } - /* Create entry for neighbor if not known. */ - p.family = AF_INET6; - IPV6_ADDR_COPY (&p.u.prefix, &addr->sin6_addr); - p.prefixlen = IPV6_MAX_PREFIXLEN; + /* Currently supporting only P2P links, so any new RA source address is + considered as the replacement of the previously learnt Link-Local address. + As per the RFC, lifetime zero is to be considered a delete */ + if (ntohs(radvert->nd_ra_router_lifetime)) + nbr_connected_replacement_add_ipv6(ifp, &addr->sin6_addr, 128); + else + nbr_connected_delete_ipv6(ifp, &addr->sin6_addr, 128); - if (!nbr_connected_check(ifp, &p)) - nbr_connected_add_ipv6 (ifp, &addr->sin6_addr); + return; } diff --git a/zebra/zserv.c b/zebra/zserv.c index d6de0792e1..e9698a82a8 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -471,16 +471,21 @@ zsend_interface_vrf_update (struct zserv *client, struct interface *ifp, return zebra_server_send_message(client); } -/* Add new nbr connected IPv6 address */ +/* Add new nbr connected IPv6 address if none exists already, or replace the + existing one if an ifc entry is found on the interface. */ void -nbr_connected_add_ipv6 (struct interface *ifp, struct in6_addr *address) +nbr_connected_replacement_add_ipv6 (struct interface *ifp, struct in6_addr *address, + u_char prefixlen) { struct nbr_connected *ifc; struct prefix p; p.family = AF_INET6; IPV6_ADDR_COPY (&p.u.prefix, address); - p.prefixlen = IPV6_MAX_PREFIXLEN; + p.prefixlen = prefixlen; + + if (nbr_connected_check(ifp, &p)) + return; if (!(ifc = listnode_head(ifp->nbr_connected))) { @@ -499,14 +504,15 @@ nbr_connected_add_ipv6 (struct interface *ifp, struct in6_addr *address) } void -nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address) +nbr_connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address, + u_char prefixlen) { struct nbr_connected *ifc; struct prefix p; p.family = AF_INET6; IPV6_ADDR_COPY (&p.u.prefix, address); - p.prefixlen = IPV6_MAX_PREFIXLEN; + p.prefixlen = prefixlen; ifc = nbr_connected_check(ifp, &p); if (!ifc) diff --git a/zebra/zserv.h b/zebra/zserv.h index 16700ee523..7fde4adb5e 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -155,8 +155,9 @@ extern int zsend_interface_delete (struct zserv *, struct interface *); extern int zsend_interface_addresses (struct zserv *, struct interface *); extern int zsend_interface_address (int, struct zserv *, struct interface *, struct connected *); -extern void nbr_connected_add_ipv6 (struct interface *, struct in6_addr *); -extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *); +extern void nbr_connected_replacement_add_ipv6 (struct interface *, + struct in6_addr *, u_char); +extern void nbr_connected_delete_ipv6 (struct interface *, struct in6_addr *, u_char); extern int zsend_interface_update (int, struct zserv *, struct interface *); extern int zsend_redistribute_route (int, struct zserv *, struct prefix *, struct rib *);