Module Name: src Committed By: roy Date: Mon Apr 29 16:12:30 UTC 2019
Modified Files: src/sys/compat/common: rtsock_50.c src/sys/compat/net: route.h src/sys/kern: compat_stub.c src/sys/net: route.h rtsock_shared.c src/sys/netinet: if_arp.c src/sys/netinet6: nd6_nbr.c src/sys/sys: compat_stub.h Log Message: Introduce rt_addrmsg_src which adds RTA_AUTHOR to the message. Use this when we notify userland of a duplicate address and set RTA_AUTHOR to the hardware address of the sender. While here, match the logging diagnostic of INET6 to the simpler one of INET so it's consistent. To generate a diff of this commit: cvs rdiff -u -r1.12 -r1.13 src/sys/compat/common/rtsock_50.c cvs rdiff -u -r1.3 -r1.4 src/sys/compat/net/route.h cvs rdiff -u -r1.10 -r1.11 src/sys/kern/compat_stub.c cvs rdiff -u -r1.122 -r1.123 src/sys/net/route.h cvs rdiff -u -r1.7 -r1.8 src/sys/net/rtsock_shared.c cvs rdiff -u -r1.281 -r1.282 src/sys/netinet/if_arp.c cvs rdiff -u -r1.165 -r1.166 src/sys/netinet6/nd6_nbr.c cvs rdiff -u -r1.14 -r1.15 src/sys/sys/compat_stub.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/compat/common/rtsock_50.c diff -u src/sys/compat/common/rtsock_50.c:1.12 src/sys/compat/common/rtsock_50.c:1.13 --- src/sys/compat/common/rtsock_50.c:1.12 Mon Apr 29 11:57:22 2019 +++ src/sys/compat/common/rtsock_50.c Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock_50.c,v 1.12 2019/04/29 11:57:22 roy Exp $ */ +/* $NetBSD: rtsock_50.c,v 1.13 2019/04/29 16:12:30 roy Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock_50.c,v 1.12 2019/04/29 11:57:22 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock_50.c,v 1.13 2019/04/29 16:12:30 roy Exp $"); #define COMPAT_RTSOCK /* Use the COMPATNAME/COMPATCALL macros and the * various other compat definitions - see @@ -162,6 +162,8 @@ rtsock_50_init(void) MODULE_HOOK_SET(rtsock_rt_ifmsg_50_hook, "rts_50", compat_50_rt_ifmsg); MODULE_HOOK_SET(rtsock_rt_addrmsg_rt_50_hook, "rts_50", compat_50_rt_addrmsg_rt); + MODULE_HOOK_SET(rtsock_rt_addrmsg_src_50_hook, "rts_50", + compat_50_rt_addrmsg_src); MODULE_HOOK_SET(rtsock_rt_addrmsg_50_hook, "rts_50", compat_50_rt_addrmsg); MODULE_HOOK_SET(rtsock_rt_ifannouncemsg_50_hook, "rts_50", @@ -181,6 +183,7 @@ rtsock_50_fini(void) MODULE_HOOK_UNSET(rtsock_rt_missmsg_50_hook); MODULE_HOOK_UNSET(rtsock_rt_ifmsg_50_hook); MODULE_HOOK_UNSET(rtsock_rt_addrmsg_rt_50_hook); + MODULE_HOOK_UNSET(rtsock_rt_addrmsg_src_50_hook); MODULE_HOOK_UNSET(rtsock_rt_addrmsg_50_hook); MODULE_HOOK_UNSET(rtsock_rt_ifannouncemsg_50_hook); MODULE_HOOK_UNSET(rtsock_rt_ieee80211msg_50_hook); Index: src/sys/compat/net/route.h diff -u src/sys/compat/net/route.h:1.3 src/sys/compat/net/route.h:1.4 --- src/sys/compat/net/route.h:1.3 Mon Apr 29 11:57:22 2019 +++ src/sys/compat/net/route.h Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: route.h,v 1.3 2019/04/29 11:57:22 roy Exp $ */ +/* $NetBSD: route.h,v 1.4 2019/04/29 16:12:30 roy Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -88,6 +88,7 @@ void compat_50_rt_missmsg(int, const str struct mbuf * compat_50_rt_msg1(int, struct rt_addrinfo *, void *, int); void compat_50_rt_addrmsg_rt(int, struct ifaddr *, int, struct rtentry *); +void compat_50_rt_addrmsg_src(int, struct ifaddr *, const struct sockaddr *); void compat_50_rt_addrmsg(int, struct ifaddr *); void compat_70_rt_newaddrmsg1(int, struct ifaddr *); #endif Index: src/sys/kern/compat_stub.c diff -u src/sys/kern/compat_stub.c:1.10 src/sys/kern/compat_stub.c:1.11 --- src/sys/kern/compat_stub.c:1.10 Mon Apr 29 11:57:22 2019 +++ src/sys/kern/compat_stub.c Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: compat_stub.c,v 1.10 2019/04/29 11:57:22 roy Exp $ */ +/* $NetBSD: compat_stub.c,v 1.11 2019/04/29 16:12:30 roy Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -204,6 +204,7 @@ struct rtsock_rt_missmsg_50_hook_t rtsoc struct rtsock_rt_ifmsg_50_hook_t rtsock_rt_ifmsg_50_hook; struct rtsock_rt_ifannouncemsg_50_hook_t rtsock_rt_ifannouncemsg_50_hook; struct rtsock_rt_addrmsg_rt_50_hook_t rtsock_rt_addrmsg_rt_50_hook; +struct rtsock_rt_addrmsg_src_50_hook_t rtsock_rt_addrmsg_src_50_hook; struct rtsock_rt_addrmsg_50_hook_t rtsock_rt_addrmsg_50_hook; struct rtsock_rt_ieee80211msg_50_hook_t rtsock_rt_ieee80211msg_50_hook; Index: src/sys/net/route.h diff -u src/sys/net/route.h:1.122 src/sys/net/route.h:1.123 --- src/sys/net/route.h:1.122 Mon Apr 29 11:57:22 2019 +++ src/sys/net/route.h Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: route.h,v 1.122 2019/04/29 11:57:22 roy Exp $ */ +/* $NetBSD: route.h,v 1.123 2019/04/29 16:12:30 roy Exp $ */ /* * Copyright (c) 1980, 1986, 1993 @@ -516,6 +516,7 @@ struct mbuf * rt_msg1(int, struct rt_addrinfo *, void *, int); int rt_msg3(int, struct rt_addrinfo *, void *, struct rt_walkarg *, int *); void rt_addrmsg(int, struct ifaddr *); +void rt_addrmsg_src(int, struct ifaddr *, const struct sockaddr *); void rt_addrmsg_rt(int, struct ifaddr *, int, struct rtentry *); void route_enqueue(struct mbuf *, int); Index: src/sys/net/rtsock_shared.c diff -u src/sys/net/rtsock_shared.c:1.7 src/sys/net/rtsock_shared.c:1.8 --- src/sys/net/rtsock_shared.c:1.7 Mon Apr 29 11:57:22 2019 +++ src/sys/net/rtsock_shared.c Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock_shared.c,v 1.7 2019/04/29 11:57:22 roy Exp $ */ +/* $NetBSD: rtsock_shared.c,v 1.8 2019/04/29 16:12:30 roy Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.7 2019/04/29 11:57:22 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.8 2019/04/29 16:12:30 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1364,9 +1364,9 @@ COMPATNAME(rt_ifmsg)(struct ifnet *ifp) * be unnecessary as the routing socket will automatically generate * copies of it. */ -void -COMPATNAME(rt_addrmsg_rt)(int cmd, struct ifaddr *ifa, int error, - struct rtentry *rt) +static void +COMPATNAME(rt_addrmsg0)(int cmd, struct ifaddr *ifa, int error, + struct rtentry *rt, const struct sockaddr *src) { #define cmdpass(__cmd, __pass) (((__cmd) << 2) | (__pass)) struct rt_addrinfo info; @@ -1428,6 +1428,7 @@ COMPATNAME(rt_addrmsg_rt)(int cmd, struc info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr; info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; info.rti_info[RTAX_BRD] = ifa->ifa_dstaddr; + info.rti_info[RTAX_AUTHOR] = src; memset(&ifam, 0, sizeof(ifam)); ifam.ifam_index = ifp->if_index; ifam.ifam_metric = ifa->ifa_metric; @@ -1473,7 +1474,23 @@ void COMPATNAME(rt_addrmsg)(int cmd, struct ifaddr *ifa) { - COMPATNAME(rt_addrmsg_rt)(cmd, ifa, 0, NULL); + COMPATNAME(rt_addrmsg0)(cmd, ifa, 0, NULL, NULL); +} + +void +COMPATNAME(rt_addrmsg_rt)(int cmd, struct ifaddr *ifa, int error, + struct rtentry *rt) +{ + + COMPATNAME(rt_addrmsg0)(cmd, ifa, error, rt, NULL); +} + +void +COMPATNAME(rt_addrmsg_src)(int cmd, struct ifaddr *ifa, + const struct sockaddr *src) +{ + + COMPATNAME(rt_addrmsg0)(cmd, ifa, 0, NULL, src); } static struct mbuf * Index: src/sys/netinet/if_arp.c diff -u src/sys/netinet/if_arp.c:1.281 src/sys/netinet/if_arp.c:1.282 --- src/sys/netinet/if_arp.c:1.281 Mon Apr 29 16:05:46 2019 +++ src/sys/netinet/if_arp.c Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.281 2019/04/29 16:05:46 roy Exp $ */ +/* $NetBSD: if_arp.c,v 1.282 2019/04/29 16:12:30 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.281 2019/04/29 16:05:46 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.282 2019/04/29 16:12:30 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -176,7 +176,7 @@ struct dadq; static void arp_dad_timer(struct dadq *); static void arp_dad_start(struct ifaddr *); static void arp_dad_stop(struct ifaddr *); -static void arp_dad_duplicated(struct ifaddr *, const char *); +static void arp_dad_duplicated(struct ifaddr *, const struct sockaddr_dl *); static void arp_init_llentry(struct ifnet *, struct llentry *); #if NTOKEN > 0 @@ -1005,7 +1005,6 @@ in_arpinput(struct mbuf *m) uint64_t *arps; struct psref psref, psref_ia; int s; - char llabuf[LLA_ADDRSTRLEN], *llastr; char ipbuf[INET_ADDRSTRLEN]; bool do_dad; @@ -1149,9 +1148,12 @@ in_arpinput(struct mbuf *m) (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr) && m->m_flags & M_BCAST))) { - llastr = lla_snprintf(llabuf, sizeof(llabuf), - ar_sha(ah), ah->ar_hln); - arp_dad_duplicated((struct ifaddr *)ia, llastr); + struct sockaddr_dl sdl, *sdlp; + + sdlp = sockaddr_dl_init(&sdl, sizeof(sdl), + ifp->if_index, ifp->if_type, + NULL, 0, ar_sha(ah), ah->ar_hln); + arp_dad_duplicated((struct ifaddr *)ia, sdlp); goto out; } @@ -1176,6 +1178,8 @@ in_arpinput(struct mbuf *m) if ((la->la_flags & LLE_VALID) && memcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) { + char llabuf[LLA_ADDRSTRLEN], *llastr; + llastr = lla_snprintf(llabuf, sizeof(llabuf), ar_sha(ah), ah->ar_hln); @@ -1753,38 +1757,43 @@ done: } static void -arp_dad_duplicated(struct ifaddr *ifa, const char *sha) +arp_dad_duplicated(struct ifaddr *ifa, const struct sockaddr_dl *from) { struct in_ifaddr *ia = (struct in_ifaddr *)ifa; struct ifnet *ifp = ifa->ifa_ifp; - char ipbuf[INET_ADDRSTRLEN]; - const char *iastr; + char ipbuf[INET_ADDRSTRLEN], llabuf[LLA_ADDRSTRLEN]; + const char *iastr, *llastr; iastr = IN_PRINT(ipbuf, &ia->ia_addr.sin_addr); + if (__predict_false(from == NULL)) + llastr = NULL; + else + llastr = lla_snprintf(llabuf, sizeof(llabuf), + CLLADDR(from), from->sdl_alen); if (ia->ia4_flags & (IN_IFF_TENTATIVE|IN_IFF_DUPLICATED)) { log(LOG_ERR, "%s: DAD duplicate address %s from %s\n", - if_name(ifp), iastr, sha); + if_name(ifp), iastr, llastr); } else if (ia->ia_dad_defended == 0 || ia->ia_dad_defended < time_uptime - DEFEND_INTERVAL) { ia->ia_dad_defended = time_uptime; arpannounce1(ifa); log(LOG_ERR, "%s: DAD defended address %s from %s\n", - if_name(ifp), iastr, sha); + if_name(ifp), iastr, llastr); return; } else { /* If DAD is disabled, just report the duplicate. */ if (!ip_dad_enabled()) { log(LOG_ERR, "%s: DAD ignoring duplicate address %s from %s\n", - if_name(ifp), iastr, sha); + if_name(ifp), iastr, llastr); return; } log(LOG_ERR, "%s: DAD defence failed for %s from %s\n", - if_name(ifp), iastr, sha); + if_name(ifp), iastr, llastr); } arp_dad_stop(ifa); @@ -1793,7 +1802,7 @@ arp_dad_duplicated(struct ifaddr *ifa, c if ((ia->ia4_flags & IN_IFF_DUPLICATED) == 0) { ia->ia4_flags |= IN_IFF_DUPLICATED; /* Inform the routing socket of the duplicate address */ - rt_addrmsg(RTM_NEWADDR, ifa); + rt_addrmsg_src(RTM_NEWADDR, ifa, (const struct sockaddr *)from); } } Index: src/sys/netinet6/nd6_nbr.c diff -u src/sys/netinet6/nd6_nbr.c:1.165 src/sys/netinet6/nd6_nbr.c:1.166 --- src/sys/netinet6/nd6_nbr.c:1.165 Mon Apr 29 11:57:22 2019 +++ src/sys/netinet6/nd6_nbr.c Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: nd6_nbr.c,v 1.165 2019/04/29 11:57:22 roy Exp $ */ +/* $NetBSD: nd6_nbr.c,v 1.166 2019/04/29 16:12:30 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.165 2019/04/29 11:57:22 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.166 2019/04/29 16:12:30 roy Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -82,8 +82,10 @@ static void nd6_dad_starttimer(struct da static void nd6_dad_destroytimer(struct dadq *); static void nd6_dad_timer(struct dadq *); static void nd6_dad_ns_output(struct dadq *, struct ifaddr *); -static void nd6_dad_input(struct ifaddr *, struct nd_opt_nonce *); -static void nd6_dad_duplicated(struct ifaddr *, struct dadq *); +static void nd6_dad_input(struct ifaddr *, struct nd_opt_nonce *, + const struct sockaddr_dl *); +static void nd6_dad_duplicated(struct ifaddr *, struct dadq *, + const struct sockaddr_dl *); static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ @@ -305,8 +307,17 @@ nd6_ns_input(struct mbuf *m, int off, in * If not, the packet is for addess resolution; * silently ignore it. */ - if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) - nd6_dad_input(ifa, ndopts.nd_opts_nonce); + if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) { + struct sockaddr_dl sdl, *sdlp; + + if (lladdr != NULL) + sdlp = sockaddr_dl_init(&sdl, sizeof(sdl), + ifp->if_index, ifp->if_type, + NULL, 0, lladdr, lladdrlen); + else + sdlp = NULL; + nd6_dad_input(ifa, ndopts.nd_opts_nonce, sdlp); + } goto freeit; } @@ -687,9 +698,17 @@ nd6_na_input(struct mbuf *m, int off, in * Otherwise, process as defined in RFC 2461. */ if (ifa) { - if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE) - nd6_dad_input(ifa, NULL); - else + if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE) { + struct sockaddr_dl sdl, *sdlp; + + if (lladdr != NULL) + sdlp = sockaddr_dl_init(&sdl, sizeof(sdl), + ifp->if_index, ifp->if_type, + NULL, 0, lladdr, lladdrlen); + else + sdlp = NULL; + nd6_dad_input(ifa, NULL, sdlp); + } else log(LOG_ERR, "nd6_na_input: duplicate IP6 address %s\n", IN6_PRINT(ip6buf, &taddr6)); @@ -1400,34 +1419,33 @@ done: } static void -nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp) +nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp, + const struct sockaddr_dl *from) { struct in6_ifaddr *ia; struct ifnet *ifp; - char ip6buf[INET6_ADDRSTRLEN]; + char ip6buf[INET6_ADDRSTRLEN], llabuf[LLA_ADDRSTRLEN], *llastr; KASSERT(mutex_owned(&nd6_dad_lock)); KASSERT(ifa != NULL); ifp = ifa->ifa_ifp; ia = (struct in6_ifaddr *)ifa; -#if 0 - log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: " - "NS in/out/loopback=%d/%d\n", - if_name(ifp), IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), - dp->dad_ns_ocount, dp->dad_ns_lcount) -#endif ia->ia6_flags &= ~IN6_IFF_TENTATIVE; ia->ia6_flags |= IN6_IFF_DUPLICATED; - log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n", - if_name(ifp), IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr)); - log(LOG_ERR, "%s: manual intervention required\n", - if_name(ifp)); + if (__predict_false(from == NULL)) + llastr = NULL; + else + llastr = lla_snprintf(llabuf, sizeof(llabuf), + CLLADDR(from), from->sdl_alen); + + log(LOG_ERR, "%s: DAD duplicate address %s from %s\n", + if_name(ifp), IN6_PRINT(ip6buf, &ia->ia_addr.sin6_addr), llastr); /* Inform the routing socket that DAD has completed */ - rt_addrmsg(RTM_NEWADDR, ifa); + rt_addrmsg_src(RTM_NEWADDR, ifa, (const struct sockaddr *)from); /* * If the address is a link-local address formed from an interface @@ -1492,7 +1510,8 @@ nd6_dad_ns_output(struct dadq *dp, struc } static void -nd6_dad_input(struct ifaddr *ifa, struct nd_opt_nonce *nonce) +nd6_dad_input(struct ifaddr *ifa, struct nd_opt_nonce *nonce, + const struct sockaddr_dl *from) { struct dadq *dp; bool found_nonce = false; @@ -1502,7 +1521,7 @@ nd6_dad_input(struct ifaddr *ifa, struct mutex_enter(&nd6_dad_lock); dp = nd6_dad_find(ifa, nonce, &found_nonce); if (!found_nonce) { - nd6_dad_duplicated(ifa, dp); + nd6_dad_duplicated(ifa, dp, from); if (dp != NULL) nd6_dad_stoptimer(dp); } Index: src/sys/sys/compat_stub.h diff -u src/sys/sys/compat_stub.h:1.14 src/sys/sys/compat_stub.h:1.15 --- src/sys/sys/compat_stub.h:1.14 Mon Apr 29 11:57:22 2019 +++ src/sys/sys/compat_stub.h Mon Apr 29 16:12:30 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: compat_stub.h,v 1.14 2019/04/29 11:57:22 roy Exp $ */ +/* $NetBSD: compat_stub.h,v 1.15 2019/04/29 16:12:30 roy Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -34,6 +34,7 @@ #include <sys/module_hook.h> #include <sys/param.h> +#include <sys/socket.h> /* * NOTE: If you make changes here, please remember to update the @@ -262,6 +263,8 @@ MODULE_HOOK(rtsock_rt_missmsg_50_hook, v MODULE_HOOK(rtsock_rt_ifmsg_50_hook, void, (struct ifnet *)); MODULE_HOOK(rtsock_rt_addrmsg_rt_50_hook, void, (int, struct ifaddr *, int, struct rtentry *)); +MODULE_HOOK(rtsock_rt_addrmsg_src_50_hook, void, + (int, struct ifaddr *, const struct sockaddr *)); MODULE_HOOK(rtsock_rt_addrmsg_50_hook, void, (int, struct ifaddr *)); MODULE_HOOK(rtsock_rt_ifannouncemsg_50_hook, void, (struct ifnet *, int)); MODULE_HOOK(rtsock_rt_ieee80211msg_50_hook, void,