Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys inet6: Send RTM_MISS when we fail to resolve an address.
details: https://anonhg.NetBSD.org/src/rev/800098ecd02a
branches: trunk
changeset: 965104:800098ecd02a
user: roy <roy%NetBSD.org@localhost>
date: Sun Sep 01 18:54:38 2019 +0000
description:
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.
diffstat:
sys/net/rtsock.c | 14 ++++----
sys/netinet6/nd6.c | 79 ++++++++++++++++++++++++-------------------------
sys/netinet6/nd6_nbr.c | 20 ++++++-----
3 files changed, 57 insertions(+), 56 deletions(-)
diffs (295 lines):
diff -r abbfb157cb43 -r 800098ecd02a sys/net/rtsock.c
--- a/sys/net/rtsock.c Sun Sep 01 18:51:27 2019 +0000
+++ b/sys/net/rtsock.c Sun Sep 01 18:54:38 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rtsock.c,v 1.251 2019/08/22 21:14:45 roy Exp $ */
+/* $NetBSD: rtsock.c,v 1.252 2019/09/01 18:54:38 roy 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.251 2019/08/22 21:14:45 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.252 2019/09/01 18:54:38 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -152,21 +152,21 @@
/* 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);
diff -r abbfb157cb43 -r 800098ecd02a sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c Sun Sep 01 18:51:27 2019 +0000
+++ b/sys/netinet6/nd6.c Sun Sep 01 18:54:38 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6.c,v 1.261 2019/08/31 01:49:45 roy Exp $ */
+/* $NetBSD: nd6.c,v 1.262 2019/09/01 18:54:38 roy 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.261 2019/08/31 01:49:45 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.262 2019/09/01 18:54:38 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -461,6 +461,8 @@
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 @@
goto out;
}
-
ifp = ln->lle_tbl->llt_ifp;
KASSERT(ifp != NULL);
@@ -483,29 +484,33 @@
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;
+ }
+
+ 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);
- }
- LLE_REMREF(ln);
- nd6_free(ln, 0);
- ln = NULL;
- if (m != NULL) {
- icmp6_error2(m, ICMP6_DST_UNREACH,
- ICMP6_DST_UNREACH_ADDR, 0, ifp);
- }
+ /*
+ * 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 @@
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 @@
{
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 @@
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 @@
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 @@
/* 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 @@
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_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);
diff -r abbfb157cb43 -r 800098ecd02a sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c Sun Sep 01 18:51:27 2019 +0000
+++ b/sys/netinet6/nd6_nbr.c Sun Sep 01 18:54:38 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: nd6_nbr.c,v 1.171 2019/08/30 08:40:25 roy Exp $ */
+/* $NetBSD: nd6_nbr.c,v 1.172 2019/09/01 18:54:38 roy 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.171 2019/08/30 08:40:25 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.172 2019/09/01 18:54:38 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -605,13 +605,13 @@
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;
- bool rt_announce;
bool checklink = false;
struct psref psref;
struct psref psref_ia;
@@ -735,7 +735,7 @@
if (ln == NULL)
goto freeit;
- rt_announce = false;
+ 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 @@
*/
memcpy(&ln->ll_addr, lladdr, ifp->if_addrlen);
ln->la_flags |= LLE_VALID;
- rt_announce = true;
+ rt_cmd = RTM_ADD;
if (is_solicited) {
ln->ln_state = ND6_LLINFO_REACHABLE;
ln->ln_byhint = 0;
@@ -780,12 +780,14 @@
else {
if (ln->la_flags & LLE_VALID) {
if (memcmp(lladdr, &ln->ll_addr, ifp->if_addrlen))
- llchange = rt_announce = true;
+ llchange = true;
else
llchange = false;
} else
- llchange = rt_announce = true;
+ llchange = true;
}
+ if (llchange)
+ rt_cmd = RTM_CHANGE;
/*
* This is VERY complex. Look at it with care.
@@ -882,11 +884,11 @@
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, &ln->r_l3addr.addr6, 0, 0, 0);
- rt_clonedmsg(RTM_CHANGE, sin6tosa(&sin6),
+ rt_clonedmsg(rt_cmd, sin6tosa(&sin6),
(char *)&ln->ll_addr, ln->lle_tbl->llt_ifp);
}
Home |
Main Index |
Thread Index |
Old Index