diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 2ca862a2a620..4d29da3994be 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.c,v 1.155 2014/12/03 01:32:11 christos Exp $ */ +/* $NetBSD: nd6.c,v 1.156 2014/12/16 11:42:27 roy Exp $ */ /* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.155 2014/12/03 01:32:11 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.156 2014/12/16 11:42:27 roy Exp $"); #include "bridge.h" #include "carp.h" @@ -1037,6 +1037,7 @@ nd6_free(struct rtentry *rt, int gc) struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo, *next; struct in6_addr in6 = satocsin6(rt_getkey(rt))->sin6_addr; struct nd_defrouter *dr; + struct rtentry *oldrt; /* * we used to have pfctlinput(PRC_HOSTDEAD) here. @@ -1129,7 +1130,15 @@ nd6_free(struct rtentry *rt, int gc) * caches, and disable the route entry not to be used in already * cached routes. */ - rtrequest(RTM_DELETE, rt_getkey(rt), NULL, rt_mask(rt), 0, NULL); + oldrt = NULL; + rtrequest(RTM_DELETE, rt_getkey(rt), NULL, rt_mask(rt), 0, &oldrt); + if (oldrt) { + nd6_rtmsg(RTM_DELETE, oldrt); /* tell user process */ + if (oldrt->rt_refcnt <= 0) { + oldrt->rt_refcnt++; + rtfree(oldrt); + } + } return next; } @@ -2059,6 +2068,9 @@ fail: break; } + if (do_update) + nd6_rtmsg(RTM_CHANGE, rt); /* tell user process */ + /* * When the link-layer address of a router changes, select the * best router again. In particular, when the neighbor entry is newly diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h index 6e7b6cb73e3f..875275ac2dd9 100644 --- a/sys/netinet6/nd6.h +++ b/sys/netinet6/nd6.h @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.h,v 1.60 2014/09/05 06:08:15 matt Exp $ */ +/* $NetBSD: nd6.h,v 1.61 2014/12/16 11:42:27 roy Exp $ */ /* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */ /* @@ -413,6 +413,7 @@ void nd6_option_init(void *, int, union nd_opts *); struct nd_opt_hdr *nd6_option(union nd_opts *); int nd6_options(union nd_opts *); struct rtentry *nd6_lookup(const struct in6_addr *, int, struct ifnet *); +void nd6_rtmsg(int, struct rtentry *); void nd6_setmtu(struct ifnet *); void nd6_llinfo_settimer(struct llinfo_nd6 *, long); void nd6_timer(void *); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 088686f47558..ea3d462750bc 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1,4 +1,4 @@ -/* $NetBSD: nd6_nbr.c,v 1.102 2014/10/12 20:05:50 roy Exp $ */ +/* $NetBSD: nd6_nbr.c,v 1.103 2014/12/16 11:42:27 roy Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.102 2014/10/12 20:05:50 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.103 2014/12/16 11:42:27 roy Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -567,6 +567,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) struct sockaddr_dl *sdl; union nd_opts ndopts; struct sockaddr_in6 ssin6; + int rt_announce; if (ip6->ip6_hlim != 255) { nd6log((LOG_ERR, @@ -669,6 +670,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) ((sdl = satosdl(rt->rt_gateway)) == NULL)) goto freeit; + rt_announce = 0; if (ln->ln_state == ND6_LLINFO_INCOMPLETE) { /* * If the link-layer has address, and no lladdr option came, @@ -682,6 +684,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) */ (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lladdr, ifp->if_addrlen); + rt_announce = 1; if (is_solicited) { ln->ln_state = ND6_LLINFO_REACHABLE; ln->ln_byhint = 0; @@ -712,11 +715,11 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) else { if (sdl->sdl_alen) { if (memcmp(lladdr, CLLADDR(sdl), ifp->if_addrlen)) - llchange = 1; + llchange = rt_announce = 1; else llchange = 0; } else - llchange = 1; + llchange = rt_announce = 1; } /* @@ -819,6 +822,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) rt->rt_flags &= ~RTF_REJECT; ln->ln_asked = 0; nd6_llinfo_release_pkts(ln, ifp, rt); + if (rt_announce) /* tell user process about any new lladdr */ + nd6_rtmsg(RTM_CHANGE, rt); freeit: m_freem(m); diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index d3696f6d983d..ce6ac1154959 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $NetBSD: nd6_rtr.c,v 1.94 2014/09/05 06:08:15 matt Exp $ */ +/* $NetBSD: nd6_rtr.c,v 1.95 2014/12/16 11:42:27 roy Exp $ */ /* $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.94 2014/09/05 06:08:15 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.95 2014/12/16 11:42:27 roy Exp $"); #include #include @@ -76,7 +76,6 @@ static void pfxrtr_del(struct nd_pfxrouter *); static struct nd_pfxrouter *find_pfxlist_reachable_router (struct nd_prefix *); static void defrouter_delreq(struct nd_defrouter *); -static void nd6_rtmsg(int, struct rtentry *); static int in6_init_prefix_ltimes(struct nd_prefix *); static void in6_init_address_ltimes(struct nd_prefix *, @@ -416,7 +415,7 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) */ /* tell the change to user processes watching the routing socket. */ -static void +void nd6_rtmsg(int cmd, struct rtentry *rt) { struct rt_addrinfo info;