? arch/amd64/compile/GENERIC.MP Index: arch/amd64/conf/GENERIC =================================================================== RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v retrieving revision 1.445 diff -u -p -r1.445 GENERIC --- arch/amd64/conf/GENERIC 28 Aug 2017 19:32:53 -0000 1.445 +++ arch/amd64/conf/GENERIC 22 Sep 2017 03:24:19 -0000 @@ -13,6 +13,8 @@ machine amd64 include "../../../conf/GENERIC" maxusers 80 # estimated number of users +makeoptions DEBUG="-g" + option USER_PCICONF # user-space PCI configuration #option VM86 # Virtual 8086 emulation @@ -122,7 +124,7 @@ uguru0 at isa? disable port 0xe0 # ABIT aps0 at isa? port 0x1600 # ThinkPad Active Protection System asmc0 at isa? port 0x300 # Apple SMC -piixpm* at pci? # Intel PIIX PM +piixpm* at pci? disable # Intel PIIX PM iic* at piixpm? ichiic* at pci? # Intel ICH SMBus controller iic* at ichiic? Index: arch/amd64/conf/Makefile.amd64 =================================================================== RCS file: /cvs/src/sys/arch/amd64/conf/Makefile.amd64,v retrieving revision 1.93 diff -u -p -r1.93 Makefile.amd64 --- arch/amd64/conf/Makefile.amd64 12 Sep 2017 08:23:42 -0000 1.93 +++ arch/amd64/conf/Makefile.amd64 22 Sep 2017 03:24:19 -0000 @@ -8,6 +8,9 @@ # DEBUG is set to -g by config if debugging is requested (config -g). # PROF is set to -pg by config if profiling is requested (config -p). +COMPILER_VERSION=gcc +CC=gcc + .include SIZE?= size Index: conf/GENERIC =================================================================== RCS file: /cvs/src/sys/conf/GENERIC,v retrieving revision 1.246 diff -u -p -r1.246 GENERIC --- conf/GENERIC 11 Aug 2017 20:50:15 -0000 1.246 +++ conf/GENERIC 22 Sep 2017 03:24:19 -0000 @@ -3,6 +3,8 @@ # Machine-independent option; used by all architectures for their # GENERIC kernel +option MSGBUFSIZE="64*NBPG" + option DDB # in-kernel debugger #option DDBPROF # ddb(4) based profiling #option DDB_SAFE_CONSOLE # allow break into ddb during boot Index: dev/pci/if_myxreg.h =================================================================== RCS file: /cvs/src/sys/dev/pci/if_myxreg.h,v retrieving revision 1.9 diff -u -p -r1.9 if_myxreg.h --- dev/pci/if_myxreg.h 31 Oct 2016 01:38:57 -0000 1.9 +++ dev/pci/if_myxreg.h 22 Sep 2017 03:24:19 -0000 @@ -31,7 +31,7 @@ #define MYX_NRXDESC 256 #define MYX_NTXDESC_MIN 2 -#define MYX_IRQCOALDELAY 60 +#define MYX_IRQCOALDELAY 120 #define MYX_IRQDEASSERTWAIT 1 #define MYXALIGN_CMD 64 Index: kern/kern_exit.c =================================================================== RCS file: /cvs/src/sys/kern/kern_exit.c,v retrieving revision 1.161 diff -u -p -r1.161 kern_exit.c --- kern/kern_exit.c 29 Aug 2017 02:51:27 -0000 1.161 +++ kern/kern_exit.c 22 Sep 2017 03:24:19 -0000 @@ -417,6 +417,8 @@ reaper(void) { struct proc *p; + sched_peg_curproc(&cpu_info_primary); + KERNEL_UNLOCK(); SCHED_ASSERT_UNLOCKED(); Index: net/art.c =================================================================== RCS file: /cvs/src/sys/net/art.c,v retrieving revision 1.27 diff -u -p -r1.27 art.c --- net/art.c 28 Feb 2017 09:50:13 -0000 1.27 +++ net/art.c 22 Sep 2017 03:24:19 -0000 @@ -116,7 +116,7 @@ art_init(void) * Per routing table initialization API function. */ struct art_root * -art_alloc(unsigned int rtableid, unsigned int alen, unsigned int off) +art_alloc(unsigned int alen, unsigned int off) { struct art_root *ar; int i; @@ -146,7 +146,6 @@ art_alloc(unsigned int rtableid, unsigne } ar->ar_off = off; - ar->ar_rtableid = rtableid; rw_init(&ar->ar_lock, "art"); return (ar); @@ -931,11 +930,27 @@ art_get(void *dst, uint8_t plen) an->an_plen = plen; SRPL_INIT(&an->an_rtlist); + refcnt_init(&an->an_refcnt); + + return (an); +} + +struct art_node * +art_take(struct art_node *an) +{ + refcnt_take(&an->an_refcnt); return (an); } void +art_rele(struct art_node *an) +{ + if (refcnt_rele(&an->an_refcnt)) + pool_put(&an_pool, an); +} + +void art_put(struct art_node *an) { KASSERT(SRPL_EMPTY_LOCKED(&an->an_rtlist)); @@ -963,7 +978,7 @@ art_gc(void *null) srp_finalize(an, "artnfini"); - pool_put(&an_pool, an); + art_rele(an); an = next; } Index: net/art.h =================================================================== RCS file: /cvs/src/sys/net/art.h,v retrieving revision 1.17 diff -u -p -r1.17 art.h --- net/art.h 28 Feb 2017 09:50:13 -0000 1.17 +++ net/art.h 22 Sep 2017 03:24:19 -0000 @@ -20,6 +20,7 @@ #define _NET_ART_H_ #include +#include #define ART_MAXLVL 32 /* We currently use 32 levels for IPv6. */ @@ -33,9 +34,11 @@ struct art_root { uint8_t ar_nlvl; /* Number of levels */ uint8_t ar_alen; /* Address length in bits */ uint8_t ar_off; /* Offset of the key in bytes */ - unsigned int ar_rtableid; /* ID of this routing table */ }; +#define art_enter(_ar) rw_enter_write(&(_ar)->ar_lock) +#define art_leave(_ar) rw_exit_write(&(_ar)->ar_lock) + /* * Forward declaration needed for the list of mpath routes * attached to a single ART node. @@ -50,13 +53,14 @@ struct art_node { SRPL_HEAD(, rtentry) an__rtlist; /* Route related to this node */ struct art_node *an__gc; /* Entry on GC list */ } an_pointer; + struct refcnt an_refcnt; uint8_t an_plen; /* Prefix length */ }; #define an_rtlist an_pointer.an__rtlist #define an_gc an_pointer.an__gc void art_init(void); -struct art_root *art_alloc(unsigned int, unsigned int, unsigned int); +struct art_root *art_alloc(unsigned int, unsigned int); struct art_node *art_insert(struct art_root *, struct art_node *, void *, int); struct art_node *art_delete(struct art_root *, struct art_node *, void *, @@ -68,6 +72,8 @@ int art_walk(struct art_root *, int (*)(struct art_node *, void *), void *); struct art_node *art_get(void *, uint8_t); +struct art_node *art_take(struct art_node *); +void art_rele(struct art_node *); void art_put(struct art_node *); #endif /* _NET_ART_H_ */ Index: net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.1042 diff -u -p -r1.1042 pf.c --- net/pf.c 14 Aug 2017 15:58:16 -0000 1.1042 +++ net/pf.c 22 Sep 2017 03:24:19 -0000 @@ -7091,7 +7091,8 @@ pf_ouraddr(struct mbuf *m) return (1); /* If we have linked state keys it is certainly forwarded. */ - if (sk->reverse != NULL) + if (sk->reverse != NULL && + !ISSET(m->m_flags, M_MCAST|M_BCAST)) return (0); } Index: net/route.c =================================================================== RCS file: /cvs/src/sys/net/route.c,v retrieving revision 1.367 diff -u -p -r1.367 route.c --- net/route.c 5 Sep 2017 10:56:04 -0000 1.367 +++ net/route.c 22 Sep 2017 03:24:19 -0000 @@ -159,6 +159,7 @@ int rtflushclone1(struct rtentry *, void void rtflushclone(unsigned int, struct rtentry *); int rt_ifa_purge_walker(struct rtentry *, void *, unsigned int); struct rtentry *rt_match(struct sockaddr *, uint32_t *, int, unsigned int); +struct rtentry *rt_clone(struct rtentry *, struct sockaddr *, unsigned int); struct sockaddr *rt_plentosa(sa_family_t, int, struct sockaddr_in6 *); #ifdef DDB @@ -228,44 +229,53 @@ rtisvalid(struct rtentry *rt) struct rtentry * rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid) { - struct rtentry *rt0, *rt = NULL; - int error = 0; + struct rtentry *rt = NULL; NET_ASSERT_LOCKED(); rt = rtable_match(tableid, dst, src); - if (rt != NULL) { - if ((rt->rt_flags & RTF_CLONING) && ISSET(flags, RT_RESOLVE)) { - struct rt_addrinfo info; - - rt0 = rt; - - memset(&info, 0, sizeof(info)); - info.rti_info[RTAX_DST] = dst; - - KERNEL_LOCK(); - /* - * The priority of cloned route should be different - * to avoid conflict with /32 cloning routes. - * - * It should also be higher to let the ARP layer find - * cloned routes instead of the cloning one. - */ - error = rtrequest(RTM_RESOLVE, &info, - rt->rt_priority - 1, &rt, tableid); - if (error) { - rtm_miss(RTM_MISS, &info, 0, RTP_NONE, 0, - error, tableid); - } else { - /* Inform listeners of the new route */ - rtm_send(rt, RTM_ADD, 0, tableid); - rtfree(rt0); - } - KERNEL_UNLOCK(); - } - rt->rt_use++; - } else + if (rt == NULL) { rtstat_inc(rts_unreach); + return (NULL); + } + + if (ISSET(rt->rt_flags, RTF_CLONING) && ISSET(flags, RT_RESOLVE)) + rt = rt_clone(rt, dst, tableid); + + rt->rt_use++; + return (rt); +} + +struct rtentry * +rt_clone(struct rtentry *rt, struct sockaddr *dst, unsigned int rtableid) +{ + struct rt_addrinfo info; + struct rtentry *rt0; + int error = 0; + + rt0 = rt; + + memset(&info, 0, sizeof(info)); + info.rti_info[RTAX_DST] = dst; + + KERNEL_LOCK(); + /* + * The priority of cloned route should be different + * to avoid conflict with /32 cloning routes. + * + * It should also be higher to let the ARP layer find + * cloned routes instead of the cloning one. + */ + error = rtrequest(RTM_RESOLVE, &info, + rt->rt_priority - 1, &rt, rtableid); + if (error) { + rtm_miss(RTM_MISS, &info, 0, RTP_NONE, 0, error, rtableid); + } else { + /* Inform listeners of the new route */ + rtm_send(rt, RTM_ADD, 0, rtableid); + rtfree(rt0); + } + KERNEL_UNLOCK(); return (rt); } @@ -371,21 +381,57 @@ rtalloc(struct sockaddr *dst, int flags, int rt_setgwroute(struct rtentry *rt, u_int rtableid) { - struct rtentry *nhrt; + struct rtentry *prt, *nhrt, *nhrt0; NET_ASSERT_LOCKED(); KASSERT(ISSET(rt->rt_flags, RTF_GATEWAY)); /* If we cannot find a valid next hop bail. */ - nhrt = rt_match(rt->rt_gateway, NULL, RT_RESOLVE, rtable_l2(rtableid)); - if (nhrt == NULL) + nhrt0 = rt_match(rt->rt_gateway, NULL, RT_RESOLVE, rtable_l2(rtableid)); + if (nhrt0 == NULL) return (ENOENT); - /* Next hop entry must be on the same interface. */ - if (nhrt->rt_ifidx != rt->rt_ifidx) { - rtfree(nhrt); - return (EHOSTUNREACH); + rtref(nhrt0); + nhrt = nhrt0; + + while (ISSET(nhrt->rt_flags, RTF_LLINFO)) { + if (nhrt->rt_ifidx == rt->rt_ifidx) { + rtfree(nhrt0); + goto llinfo; + } + + nhrt = rtable_iterate(nhrt); + if (nhrt == NULL) + break; + } + rtfree(nhrt); + + if (ISSET(nhrt0->rt_flags, RTF_LLINFO)) { + /* + * We found a L2 entry, so we might have multiple + * RTF_CLONING routes for the same subnet. Try to + * pick the correct one. + */ + prt = rtable_first(nhrt0->rt_parent); + rtfree(nhrt0); + for (;;) { + if (prt == NULL) + return (EHOSTUNREACH); + + if (prt->rt_ifidx == rt->rt_ifidx) + break; + + prt = rtable_iterate(prt); + } + + /* We found a non-cloning MPATH route, we're done. */ + if (!ISSET(prt->rt_flags, RTF_CLONING)) { + rtfree(prt); + return (EHOSTUNREACH); + } + + nhrt = rt_clone(prt, rt->rt_gateway, rtable_l2(rtableid)); } /* @@ -397,6 +443,7 @@ rt_setgwroute(struct rtentry *rt, u_int return (ENETUNREACH); } +llinfo: /* Next hop is valid so remove possible old cache. */ rt_putgwroute(rt); KASSERT(rt->rt_gwroute == NULL); @@ -446,10 +493,11 @@ rt_putgwroute(struct rtentry *rt) rt->rt_gwroute = NULL; } -void +struct rtentry * rtref(struct rtentry *rt) { atomic_inc_int(&rt->rt_refcnt); + return (rt); } void @@ -462,6 +510,7 @@ rtfree(struct rtentry *rt) refcnt = (int)atomic_dec_int_nv(&rt->rt_refcnt); if (refcnt <= 0) { + KASSERT(rt->rt_node == NULL); KASSERT(!ISSET(rt->rt_flags, RTF_UP)); KASSERT(!RT_ROOT(rt)); atomic_dec_int(&rttrash); @@ -531,7 +580,7 @@ rtredirect(struct sockaddr *dst, struct rtfree(rt); rt = NULL; - rt = rtable_lookup(rdomain, dst, NULL, NULL, RTP_ANY); + rt = rtable_match(rdomain, dst, NULL); /* * If the redirect isn't from our current router for this dst, * it's either old or wrong. If it redirects us to ourselves, Index: net/route.h =================================================================== RCS file: /cvs/src/sys/net/route.h,v retrieving revision 1.167 diff -u -p -r1.167 route.h --- net/route.h 2 Aug 2017 08:38:28 -0000 1.167 +++ net/route.h 22 Sep 2017 03:24:19 -0000 @@ -83,6 +83,8 @@ struct rt_metrics { #include #include +struct art_node; + /* * We distinguish between routes to hosts and routes to networks, * preferring the former if available. For each route we infer @@ -96,6 +98,7 @@ struct rtentry { #if !defined(_KERNEL) && !defined(ART) struct radix_node rt_nodes[2]; /* tree glue, and other values */ #else + struct art_node *rt_node; struct sockaddr *rt_dest; /* destination */ SRPL_ENTRY(rtentry) rt_next; /* Next multipath entry to our dst. */ #endif @@ -443,7 +446,7 @@ int rtisvalid(struct rtentry *); int rt_hash(struct rtentry *, struct sockaddr *, uint32_t *); struct rtentry *rtalloc_mpath(struct sockaddr *, uint32_t *, u_int); struct rtentry *rtalloc(struct sockaddr *, int, unsigned int); -void rtref(struct rtentry *); +struct rtentry *rtref(struct rtentry *); void rtfree(struct rtentry *); int rt_ifa_add(struct ifaddr *, int, struct sockaddr *); Index: net/rtable.c =================================================================== RCS file: /cvs/src/sys/net/rtable.c,v retrieving revision 1.63 diff -u -p -r1.63 rtable.c --- net/rtable.c 5 Sep 2017 11:15:39 -0000 1.63 +++ net/rtable.c 22 Sep 2017 03:24:19 -0000 @@ -259,6 +259,28 @@ rtable_get(unsigned int rtableid, sa_fam return (tbl); } +void * +rtable_enter(unsigned int rtableid, sa_family_t af) +{ + struct art_root *ar; + + ar = rtable_get(rtableid, af); + if (ar == NULL) + return (NULL); + + art_enter(ar); + + return (ar); +} + +void +rtable_leave(void *rtable) +{ + struct art_root *ar = rtable; + + art_leave(ar); +} + int rtable_exists(unsigned int rtableid) { @@ -345,7 +367,7 @@ rtable_init_backend(unsigned int keylen) void * rtable_alloc(unsigned int rtableid, unsigned int alen, unsigned int off) { - return (art_alloc(rtableid, alen, off)); + return (art_alloc(alen, off)); } struct rtentry * @@ -497,7 +519,7 @@ rtable_insert(unsigned int rtableid, str return (EINVAL); rtref(rt); /* guarantee rtfree won't do anything during insert */ - rw_enter_write(&ar->ar_lock); + art_enter(ar); /* Do not permit exactly the same dst/mask/gw pair. */ an = art_lookup(ar, addr, plen, &sr); @@ -531,6 +553,7 @@ rtable_insert(unsigned int rtableid, str rt->rt_flags &= ~RTF_MPATH; rt->rt_dest = dst; rt->rt_plen = plen; + rt->rt_node = art_take(an); SRPL_INSERT_HEAD_LOCKED(&rt_rc, &an->an_rtlist, rt, rt_next); prev = art_insert(ar, an, addr, plen); @@ -538,6 +561,7 @@ rtable_insert(unsigned int rtableid, str SRPL_REMOVE_LOCKED(&rt_rc, &an->an_rtlist, rt, rtentry, rt_next); rt->rt_flags = rt_flags; + art_rele(rt->rt_node); art_put(an); if (prev == NULL) { @@ -570,10 +594,11 @@ rtable_insert(unsigned int rtableid, str } /* Put newly inserted entry at the right place. */ + rt->rt_node = art_take(an); rtable_mpath_insert(an, rt); } leave: - rw_exit_write(&ar->ar_lock); + art_leave(ar); rtfree(rt); return (error); } @@ -599,7 +624,7 @@ rtable_delete(unsigned int rtableid, str plen = rtable_satoplen(dst->sa_family, mask); rtref(rt); /* guarantee rtfree won't do anything under ar_lock */ - rw_enter_write(&ar->ar_lock); + art_enter(ar); an = art_lookup(ar, addr, plen, &sr); srp_leave(&sr); /* an can't go away while we have the lock */ @@ -609,6 +634,9 @@ rtable_delete(unsigned int rtableid, str goto leave; } + art_rele(rt->rt_node); + rt->rt_node = NULL; + /* * If other multipath route entries are still attached to * this ART node we only have to unlink it. @@ -636,7 +664,7 @@ rtable_delete(unsigned int rtableid, str art_put(an); leave: - rw_exit_write(&ar->ar_lock); + art_leave(ar); rtfree(rt); return (error); @@ -704,6 +732,22 @@ rtable_iterate(struct rtentry *rt0) return (rt); } +struct rtentry * +rtable_first(struct rtentry *rtn) +{ + struct art_node *an; + struct rtentry *rt; + struct srp_ref sr; + + an = rtn->rt_node; + rt = SRPL_FIRST(&sr, &an->an_rtlist); + if (rt != NULL) + rtref(rt); + SRPL_LEAVE(&sr); + + return (rt); +} + int rtable_mpath_capable(unsigned int rtableid, sa_family_t af) { @@ -728,7 +772,7 @@ rtable_mpath_reprio(unsigned int rtablei addr = satoaddr(ar, dst); plen = rtable_satoplen(dst->sa_family, mask); - rw_enter_write(&ar->ar_lock); + art_enter(ar); an = art_lookup(ar, addr, plen, &sr); srp_leave(&sr); /* an can't go away while we have the lock */ @@ -753,7 +797,7 @@ rtable_mpath_reprio(unsigned int rtablei rtfree(rt); error = EAGAIN; } - rw_exit_write(&ar->ar_lock); + art_leave(ar); return (error); } Index: net/rtable.h =================================================================== RCS file: /cvs/src/sys/net/rtable.h,v retrieving revision 1.20 diff -u -p -r1.20 rtable.h --- net/rtable.h 2 Aug 2017 08:38:28 -0000 1.20 +++ net/rtable.h 22 Sep 2017 03:24:19 -0000 @@ -54,9 +54,13 @@ unsigned int rtable_l2(unsigned int); unsigned int rtable_loindex(unsigned int); void rtable_l2set(unsigned int, unsigned int, unsigned int); +void *rtable_enter(unsigned int, sa_family_t); +void rtable_leave(void *); + struct rtentry *rtable_lookup(unsigned int, struct sockaddr *, struct sockaddr *, struct sockaddr *, uint8_t); struct rtentry *rtable_match(unsigned int, struct sockaddr *, uint32_t *); +struct rtentry *rtable_first(struct rtentry *); struct rtentry *rtable_iterate(struct rtentry *); int rtable_insert(unsigned int, struct sockaddr *, struct sockaddr *, struct sockaddr *, uint8_t, Index: netinet/if_ether.c =================================================================== RCS file: /cvs/src/sys/netinet/if_ether.c,v retrieving revision 1.231 diff -u -p -r1.231 if_ether.c --- netinet/if_ether.c 11 Aug 2017 21:24:19 -0000 1.231 +++ netinet/if_ether.c 22 Sep 2017 03:24:19 -0000 @@ -484,7 +484,7 @@ in_arpinput(struct ifnet *ifp, struct mb struct sockaddr_in sin; struct in_addr isaddr, itaddr; char addr[INET_ADDRSTRLEN]; - int op, target = 0; + int op, resolve = 0; unsigned int rdomain; rdomain = rtable_l2(m->m_pkthdr.ph_rtableid); @@ -496,9 +496,6 @@ in_arpinput(struct ifnet *ifp, struct mb memcpy(&itaddr, ea->arp_tpa, sizeof(itaddr)); memcpy(&isaddr, ea->arp_spa, sizeof(isaddr)); - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; if (ETHER_IS_MULTICAST(&ea->arp_sha[0]) && !memcmp(ea->arp_sha, etherbroadcastaddr, sizeof(ea->arp_sha))) { @@ -512,44 +509,67 @@ in_arpinput(struct ifnet *ifp, struct mb goto out; /* it's from me, ignore it. */ /* Check target against our interface addresses. */ + memset(&sin, 0, sizeof(sin)); + sin.sin_len = sizeof(sin); + sin.sin_family = AF_INET; sin.sin_addr = itaddr; rt = rtalloc(sintosa(&sin), 0, rdomain); - if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) && - rt->rt_ifidx == ifp->if_index) - target = 1; + while (rtisvalid(rt)) { + if (ISSET(rt->rt_flags, RTF_LOCAL) && + rt->rt_ifidx == ifp->if_index) { + resolve = RT_RESOLVE; + break; + } + + rt = rtable_iterate(rt); + } rtfree(rt); rt = NULL; -#if NCARP > 0 - if (target && op == ARPOP_REQUEST && ifp->if_type == IFT_CARP && +#if 0 && NCARP > 0 + if (resolve && op == ARPOP_REQUEST && ifp->if_type == IFT_CARP && !carp_iamatch(ifp)) goto out; #endif /* Do we have an ARP cache for the sender? Create if we are target. */ - rt = arplookup(&isaddr, target, 0, rdomain); + + sin.sin_addr = isaddr; + for (rt = rtalloc(sintosa(&sin), resolve, rdomain); + rtisvalid(rt); rt = rtable_iterate(rt)) { + if (rt->rt_ifidx != ifp->if_index) + continue; + + if (!ISSET(rt->rt_flags, RTF_GATEWAY) && + ISSET(rt->rt_flags, RTF_LLINFO) && + rt->rt_gateway->sa_family == AF_LINK) + break; + } /* Check sender against our interface addresses. */ - if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL) && - rt->rt_ifidx == ifp->if_index && isaddr.s_addr != INADDR_ANY) { - inet_ntop(AF_INET, &isaddr, addr, sizeof(addr)); - log(LOG_ERR, "duplicate IP address %s sent from ethernet " - "address %s\n", addr, ether_sprintf(ea->arp_sha)); - itaddr = isaddr; - } else if (rt != NULL) { - int error; - - KERNEL_LOCK(); - error = arpcache(ifp, ea, rt); - KERNEL_UNLOCK(); - if (error) - goto out; + if (rt != NULL) { + if (ISSET(rt->rt_flags, RTF_LOCAL) && + isaddr.s_addr != INADDR_ANY) { + inet_ntop(AF_INET, &isaddr, addr, sizeof(addr)); + log(LOG_ERR, "duplicate IP address %s sent from " + "ethernet address %s\n", addr, + ether_sprintf(ea->arp_sha)); + itaddr = isaddr; + } else { + int error; + + KERNEL_LOCK(); + error = arpcache(ifp, ea, rt); + KERNEL_UNLOCK(); + if (error) + goto out; + } } if (op == ARPOP_REQUEST) { uint8_t *eaddr; - if (target) { + if (resolve) { /* We already have all info for the reply */ eaddr = LLADDR(ifp->if_sadl); } else { Index: netinet/ip_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.322 diff -u -p -r1.322 ip_input.c --- netinet/ip_input.c 7 Sep 2017 10:54:49 -0000 1.322 +++ netinet/ip_input.c 22 Sep 2017 03:24:19 -0000 @@ -806,6 +806,17 @@ in_ouraddr(struct mbuf *m, struct ifnet match = 1; break; } + + if (ip_directedbcast || + !ISSET(ifp->if_flags, IFF_BROADCAST) || + ifa->ifa_broadaddr == NULL) + continue; + + if (ip->ip_dst.s_addr == + ifatoia(ifa)->ia_broadaddr.sin_addr.s_addr) { + match = 1; + break; + } } } Index: sys/socketvar.h =================================================================== RCS file: /cvs/src/sys/sys/socketvar.h,v retrieving revision 1.76 diff -u -p -r1.76 socketvar.h --- sys/socketvar.h 1 Sep 2017 15:05:31 -0000 1.76 +++ sys/socketvar.h 22 Sep 2017 03:24:19 -0000 @@ -114,7 +114,7 @@ struct socket { short sb_flags; /* flags, see below */ u_short sb_timeo; /* timeout for read/write */ } so_rcv, so_snd; -#define SB_MAX (2*1024*1024) /* default for max chars in sockbuf */ +#define SB_MAX (4*1024*1024) /* default for max chars in sockbuf */ #define SB_LOCK 0x01 /* lock on data queue */ #define SB_WANT 0x02 /* someone is waiting to lock */ #define SB_WAIT 0x04 /* someone is waiting for data/space */