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
This commit is contained in:
parent
e29561936c
commit
42272c05f6
|
@ -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 sockaddr *dst, const uint8_t *lladdr,
|
|||
/* 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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
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 struct rtentry *rt, struct mbuf *m,
|
|||
/* 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 struct rtentry *rt, struct mbuf *m,
|
|||
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 struct rtentry *rt, struct mbuf *m,
|
|||
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);
|
||||
|
|
|
@ -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, int icmp6len)
|
|||
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, int icmp6len)
|
|||
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, int icmp6len)
|
|||
*/
|
||||
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, int icmp6len)
|
|||
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, int icmp6len)
|
|||
* 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, int icmp6len)
|
|||
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:
|
||||
|
|
Loading…
Reference in New Issue