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)
* 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);
struct nd_router_advert *radvert;
char addr_str[INET6_ADDRSTRLEN];
struct zebra_if *zif;
- struct prefix p;
zif = ifp->info;
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;
}
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)))
{
}
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)
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 *);