Module Name: src Committed By: martin Date: Thu Sep 5 08:28:06 UTC 2019
Modified Files: src/sys/net [netbsd-9]: rtsock.c src/sys/netinet6 [netbsd-9]: nd6.c nd6_nbr.c Log Message: Pull up following revision(s) (requested by roy in ticket #168): sys/net/rtsock.c: revision 1.252 sys/netinet6/nd6_nbr.c: revision 1.168 - 1.172 sys/netinet6/nd6.c: revision 1.262 inet6: Send RTM_MISS when we fail to resolve an address. Takes the same approach as when adding a new address - we no longer announce the new lladdr right away but we announce the result. This will either be RTM_ADD or RTM_MISS. RTM_DELETE is only sent if we have a lladdr assigned OR gc'ed. This results in less messages via route(4) and tells us when a new lladdr has been added (RTM_ADD), changed (RTM_CHANGE), deleted (RTM_DELETED) or has failed to been resolved (RTM_MISS). The latter case can be interpreted as unreachable. inet6: change rt_announce and llchange to bool in nd6_na_input() more bool To generate a diff of this commit: cvs rdiff -u -r1.250.2.1 -r1.250.2.2 src/sys/net/rtsock.c cvs rdiff -u -r1.256.2.4 -r1.256.2.5 src/sys/netinet6/nd6.c cvs rdiff -u -r1.166.2.1 -r1.166.2.2 src/sys/netinet6/nd6_nbr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.250.2.1 src/sys/net/rtsock.c:1.250.2.2 --- src/sys/net/rtsock.c:1.250.2.1 Mon Aug 26 13:42:36 2019 +++ src/sys/net/rtsock.c Thu Sep 5 08:28:05 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.250.2.1 2019/08/26 13:42:36 martin Exp $ */ +/* $NetBSD: rtsock.c,v 1.250.2.2 2019/09/05 08:28:05 martin Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.250.2.1 2019/08/26 13:42:36 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.250.2.2 2019/09/05 08:28:05 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -152,21 +152,21 @@ rt_clonedmsg(int type, const struct sock /* Mimic flags exactly */ #define RTF_LLINFO 0x400 #define RTF_CLONED 0x2000 - int flags = RTF_HOST | RTF_DONE | RTF_LLINFO | RTF_CLONED; + int flags = RTF_DONE; union { struct sockaddr sa; struct sockaddr_storage ss; struct sockaddr_dl sdl; } u; - uint8_t namelen = strlen(ifp->if_xname); - uint8_t addrlen = ifp->if_addrlen; - if (type != RTM_DELETE) + if (type != RTM_MISS) + flags |= RTF_HOST | RTF_CLONED | RTF_LLINFO; + if (type == RTM_ADD || type == RTM_CHANGE) flags |= RTF_UP; memset(&info, 0, sizeof(info)); info.rti_info[RTAX_DST] = dst; sockaddr_dl_init(&u.sdl, sizeof(u.ss), ifp->if_index, ifp->if_type, - NULL, namelen, lladdr, addrlen); + NULL, 0, lladdr, ifp->if_addrlen); info.rti_info[RTAX_GATEWAY] = &u.sa; rt_missmsg(type, &info, flags, 0); Index: src/sys/netinet6/nd6.c diff -u src/sys/netinet6/nd6.c:1.256.2.4 src/sys/netinet6/nd6.c:1.256.2.5 --- src/sys/netinet6/nd6.c:1.256.2.4 Sun Sep 1 14:06:22 2019 +++ src/sys/netinet6/nd6.c Thu Sep 5 08:28:06 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6.c,v 1.256.2.4 2019/09/01 14:06:22 martin Exp $ */ +/* $NetBSD: nd6.c,v 1.256.2.5 2019/09/05 08:28:06 martin Exp $ */ /* $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.256.2.4 2019/09/01 14:06:22 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.256.2.5 2019/09/05 08:28:06 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -461,6 +461,8 @@ nd6_llinfo_timer(void *arg) struct nd_ifinfo *ndi = NULL; bool send_ns = false; const struct in6_addr *daddr6 = NULL; + const struct in6_addr *taddr6 = &ln->r_l3addr.addr6; + struct sockaddr_in6 sin6; SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE(); @@ -472,7 +474,6 @@ nd6_llinfo_timer(void *arg) goto out; } - ifp = ln->lle_tbl->llt_ifp; KASSERT(ifp != NULL); @@ -483,29 +484,33 @@ nd6_llinfo_timer(void *arg) if (ln->ln_asked < nd6_mmaxtries) { ln->ln_asked++; send_ns = true; - } else { - struct mbuf *m = ln->ln_hold; - if (m) { - struct mbuf *m0; + break; + } - /* - * assuming every packet in ln_hold has - * the same IP header - */ - m0 = m->m_nextpkt; - m->m_nextpkt = NULL; - ln->ln_hold = m0; - clear_llinfo_pqueue(ln); - } - LLE_REMREF(ln); - nd6_free(ln, 0); - ln = NULL; - if (m != NULL) { - icmp6_error2(m, ICMP6_DST_UNREACH, - ICMP6_DST_UNREACH_ADDR, 0, ifp); - } + if (ln->ln_hold) { + struct mbuf *m = ln->ln_hold, *m0; + + /* + * assuming every packet in ln_hold has + * the same IP header + */ + m0 = m->m_nextpkt; + m->m_nextpkt = NULL; + ln->ln_hold = m0; + clear_llinfo_pqueue(ln); + + icmp6_error2(m, ICMP6_DST_UNREACH, + ICMP6_DST_UNREACH_ADDR, 0, ifp); } + + sockaddr_in6_init(&sin6, taddr6, 0, 0, 0); + rt_clonedmsg(RTM_MISS, sin6tosa(&sin6), NULL, ifp); + + LLE_REMREF(ln); + nd6_free(ln, 0); + ln = NULL; break; + case ND6_LLINFO_REACHABLE: if (!ND6_LLINFO_PERMANENT(ln)) { ln->ln_state = ND6_LLINFO_STALE; @@ -550,7 +555,6 @@ nd6_llinfo_timer(void *arg) if (send_ns) { struct in6_addr src, *psrc; - const struct in6_addr *taddr6 = &ln->r_l3addr.addr6; nd6_llinfo_settimer(ln, ndi->retrans * hz / 1000); psrc = nd6_llinfo_get_holdsrc(ln, &src); @@ -1191,8 +1195,6 @@ nd6_free(struct llentry *ln, int gc) { struct ifnet *ifp; struct in6_addr *in6; - struct sockaddr_in6 sin6; - const char *lladdr; KASSERT(ln != NULL); LLE_WLOCK_ASSERT(ln); @@ -1282,9 +1284,15 @@ nd6_free(struct llentry *ln, int gc) LLE_WLOCK(ln); } - sockaddr_in6_init(&sin6, in6, 0, 0, 0); - lladdr = ln->la_flags & LLE_VALID ? (const char *)&ln->ll_addr : NULL; - rt_clonedmsg(RTM_DELETE, sin6tosa(&sin6), lladdr, ifp); + if (ln->la_flags & LLE_VALID || gc) { + struct sockaddr_in6 sin6; + const char *lladdr; + + sockaddr_in6_init(&sin6, in6, 0, 0, 0); + lladdr = ln->la_flags & LLE_VALID ? + (const char *)&ln->ll_addr : NULL; + rt_clonedmsg(RTM_DELETE, sin6tosa(&sin6), lladdr, ifp); + } /* * Save to unlock. We still hold an extra reference and will not @@ -2218,7 +2226,7 @@ nd6_cache_lladdr( break; } - if (do_update) { + if (do_update && lladdr != NULL) { struct sockaddr_in6 sin6; sockaddr_in6_init(&sin6, from, 0, 0, 0); @@ -2334,7 +2342,6 @@ nd6_resolve(struct ifnet *ifp, const str /* Slow path */ ln = nd6_lookup(&dst->sin6_addr, ifp, true); if (ln == NULL && nd6_is_addr_neighbor(dst, ifp)) { - struct sockaddr_in6 sin6; /* * Since nd6_is_addr_neighbor() internally calls nd6_lookup(), * the condition below is not very efficient. But we believe @@ -2350,11 +2357,6 @@ nd6_resolve(struct ifnet *ifp, const str m_freem(m); return ENOBUFS; } - - sockaddr_in6_init(&sin6, &ln->r_l3addr.addr6, 0, 0, 0); - if (rt != NULL) - rt_clonedmsg(RTM_ADD, sin6tosa(&sin6), NULL, ifp); - created = true; } @@ -2439,12 +2441,9 @@ nd6_resolve(struct ifnet *ifp, const str nd6_llinfo_settimer(ln, ND_IFINFO(ifp)->retrans * hz / 1000); psrc = nd6_llinfo_get_holdsrc(ln, &src); LLE_WUNLOCK(ln); - ln = NULL; nd6_ns_output(ifp, NULL, &dst->sin6_addr, psrc, NULL); - } else { - /* We did the lookup so we need to do the unlock here. */ + } else LLE_WUNLOCK(ln); - } if (created) nd6_gc_neighbors(LLTABLE6(ifp), &dst->sin6_addr); Index: src/sys/netinet6/nd6_nbr.c diff -u src/sys/netinet6/nd6_nbr.c:1.166.2.1 src/sys/netinet6/nd6_nbr.c:1.166.2.2 --- src/sys/netinet6/nd6_nbr.c:1.166.2.1 Mon Aug 26 13:42:36 2019 +++ src/sys/netinet6/nd6_nbr.c Thu Sep 5 08:28:06 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6_nbr.c,v 1.166.2.1 2019/08/26 13:42:36 martin Exp $ */ +/* $NetBSD: nd6_nbr.c,v 1.166.2.2 2019/09/05 08:28:06 martin Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.166.2.1 2019/08/26 13:42:36 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.166.2.2 2019/09/05 08:28:06 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -605,13 +605,13 @@ nd6_na_input(struct mbuf *m, int off, in int is_router; int is_solicited; int is_override; + int rt_cmd; char *lladdr = NULL; int lladdrlen = 0; struct ifaddr *ifa; struct llentry *ln = NULL; union nd_opts ndopts; struct sockaddr_in6 ssin6; - int rt_announce; bool checklink = false; struct psref psref; struct psref psref_ia; @@ -735,7 +735,7 @@ nd6_na_input(struct mbuf *m, int off, in if (ln == NULL) goto freeit; - rt_announce = 0; + rt_cmd = 0; if (ln->ln_state == ND6_LLINFO_INCOMPLETE) { /* * If the link-layer has address, and no lladdr option came, @@ -749,7 +749,7 @@ nd6_na_input(struct mbuf *m, int off, in */ memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen); ln->la_flags |= LLE_VALID; - rt_announce = 1; + rt_cmd = RTM_ADD; if (is_solicited) { ln->ln_state = ND6_LLINFO_REACHABLE; ln->ln_byhint = 0; @@ -770,22 +770,24 @@ nd6_na_input(struct mbuf *m, int off, in checklink = true; } } else { - int llchange; + bool llchange; /* * Check if the link-layer address has changed or not. */ if (lladdr == NULL) - llchange = 0; + llchange = false; else { if (ln->la_flags & LLE_VALID) { if (memcmp(lladdr, &ln->ll_addr, ifp->if_addrlen)) - llchange = rt_announce = 1; + llchange = true; else - llchange = 0; + llchange = false; } else - llchange = rt_announce = 1; + llchange = true; } + if (llchange) + rt_cmd = RTM_CHANGE; /* * This is VERY complex. Look at it with care. @@ -854,10 +856,8 @@ nd6_na_input(struct mbuf *m, int off, in * Remove the sender from the Default Router List and * update the Destination Cache entries. */ + const struct in6_addr *in6 = &ln->r_l3addr.addr6; struct nd_defrouter *dr; - const struct in6_addr *in6; - - in6 = &ln->r_l3addr.addr6; ND6_WLOCK(); dr = nd6_defrouter_lookup(in6, ln->lle_tbl->llt_ifp); @@ -884,11 +884,12 @@ nd6_na_input(struct mbuf *m, int off, in ln->ln_asked = 0; nd6_llinfo_release_pkts(ln, ifp); - if (rt_announce) { + if (rt_cmd != 0) { struct sockaddr_in6 sin6; - sockaddr_in6_init(&sin6, &taddr6, 0, 0, 0); - rt_clonedmsg(RTM_CHANGE, sin6tosa(&sin6), lladdr, ifp); + sockaddr_in6_init(&sin6, &ln->r_l3addr.addr6, 0, 0, 0); + rt_clonedmsg(rt_cmd, sin6tosa(&sin6), + (char *)&ln->ll_addr, ln->lle_tbl->llt_ifp); } freeit: