Module Name: src Committed By: roy Date: Sun Sep 1 22:09:02 UTC 2019
Modified Files: src/sys/netinet: if_arp.c Log Message: inet: 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 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. To generate a diff of this commit: cvs rdiff -u -r1.286 -r1.287 src/sys/netinet/if_arp.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/netinet/if_arp.c diff -u src/sys/netinet/if_arp.c:1.286 src/sys/netinet/if_arp.c:1.287 --- src/sys/netinet/if_arp.c:1.286 Fri Aug 30 18:52:00 2019 +++ src/sys/netinet/if_arp.c Sun Sep 1 22:09:02 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.286 2019/08/30 18:52:00 roy Exp $ */ +/* $NetBSD: if_arp.c,v 1.287 2019/09/01 22:09:02 roy Exp $ */ /* * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.286 2019/08/30 18:52:00 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.287 2019/09/01 22:09:02 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -315,6 +315,17 @@ arptimer(void *arg) if (lle->la_flags & LLE_LINKED) { size_t pkts_dropped; + if (lle->la_flags & LLE_VALID) { + struct in_addr *in; + struct sockaddr_in sin; + const char *lladdr; + + in = &lle->r_l3addr.addr4; + sockaddr_in_init(&sin, in, 0); + lladdr = (const char *)&lle->ll_addr; + rt_clonedmsg(RTM_DELETE, sintosa(&sin), lladdr, ifp); + } + LLE_REMREF(lle); pkts_dropped = llentry_free(lle); ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped); @@ -745,14 +756,8 @@ notfound: rt_unref(_rt); if (la == NULL) ARP_STATINC(ARP_STAT_ALLOCFAIL); - else { - struct sockaddr_in sin; - + else arp_init_llentry(ifp, la); - sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); - if (rt != NULL) - rt_clonedmsg(RTM_ADD, sintosa(&sin), NULL, ifp); - } } else if (LLE_TRY_UPGRADE(la) == 0) { create_lookup = "lookup"; LLE_RUNLOCK(la); @@ -852,9 +857,16 @@ notfound: if (renew) { const uint8_t *enaddr = CLLADDR(ifp->if_sadl); + struct sockaddr_in sin; + la->la_expire = time_uptime; arp_settimer(la, arpt_down); la->la_asked++; + + sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); + if (error != EWOULDBLOCK) + rt_clonedmsg(RTM_MISS, sintosa(&sin), NULL, ifp); + LLE_WUNLOCK(la); if (rt != NULL) { @@ -862,11 +874,8 @@ notfound: &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, &satocsin(dst)->sin_addr, enaddr); } else { - struct sockaddr_in sin; struct rtentry *_rt; - sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); - /* XXX */ _rt = rtalloc1((struct sockaddr *)&sin, 0); if (_rt == NULL) @@ -1007,7 +1016,7 @@ in_arpinput(struct mbuf *m) #endif struct sockaddr sa; struct in_addr isaddr, itaddr, myaddr; - int op; + int op, rt_cmd; void *tha; uint64_t *arps; struct psref psref, psref_ia; @@ -1217,7 +1226,9 @@ in_arpinput(struct mbuf *m) "for %s by %s\n", IN_PRINT(ipbuf, &isaddr), llastr); } - } + rt_cmd = RTM_CHANGE; + } else + rt_cmd = la->la_flags & LLE_VALID ? 0 : RTM_ADD; KASSERT(ifp->if_sadl->sdl_alen == ifp->if_addrlen); @@ -1259,6 +1270,13 @@ in_arpinput(struct mbuf *m) la->la_asked = 0; /* rt->rt_flags &= ~RTF_REJECT; */ + if (rt_cmd != 0) { + struct sockaddr_in sin; + + sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); + rt_clonedmsg(rt_cmd, sintosa(&sin), ar_sha(ah), ifp); + } + if (la->la_hold != NULL) { int n = la->la_numheld; struct mbuf *m_hold, *m_hold_next;