Mon Mar 9 17:57:19 2020 UTC ()
arp: report RTM_MISS when removing an unresolved entry in the arp table

Otherwise we only get it when renewing and we've sent too many requests.
This mirrors INET6 behaviour.


(roy)
diff -r1.292 -r1.293 src/sys/netinet/if_arp.c

cvs diff -r1.292 -r1.293 src/sys/netinet/if_arp.c (switch to unified diff)

--- src/sys/netinet/if_arp.c 2020/01/23 17:27:35 1.292
+++ src/sys/netinet/if_arp.c 2020/03/09 17:57:19 1.293
@@ -1,1320 +1,1324 @@ @@ -1,1320 +1,1324 @@
1/* $NetBSD: if_arp.c,v 1.292 2020/01/23 17:27:35 roy Exp $ */ 1/* $NetBSD: if_arp.c,v 1.293 2020/03/09 17:57:19 roy Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Public Access Networks Corporation ("Panix"). It was developed under 8 * by Public Access Networks Corporation ("Panix"). It was developed under
9 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 9 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Copyright (c) 1982, 1986, 1988, 1993 34 * Copyright (c) 1982, 1986, 1988, 1993
35 * The Regents of the University of California. All rights reserved. 35 * The Regents of the University of California. All rights reserved.
36 * 36 *
37 * Redistribution and use in source and binary forms, with or without 37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions 38 * modification, are permitted provided that the following conditions
39 * are met: 39 * are met:
40 * 1. Redistributions of source code must retain the above copyright 40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer. 41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright 42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the 43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution. 44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors 45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software 46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission. 47 * without specific prior written permission.
48 * 48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 61 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94
62 */ 62 */
63 63
64/* 64/*
65 * Ethernet address resolution protocol. 65 * Ethernet address resolution protocol.
66 * TODO: 66 * TODO:
67 * add "inuse/lock" bit (or ref. count) along with valid bit 67 * add "inuse/lock" bit (or ref. count) along with valid bit
68 */ 68 */
69 69
70#include <sys/cdefs.h> 70#include <sys/cdefs.h>
71__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.292 2020/01/23 17:27:35 roy Exp $"); 71__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.293 2020/03/09 17:57:19 roy Exp $");
72 72
73#ifdef _KERNEL_OPT 73#ifdef _KERNEL_OPT
74#include "opt_ddb.h" 74#include "opt_ddb.h"
75#include "opt_inet.h" 75#include "opt_inet.h"
76#include "opt_net_mpsafe.h" 76#include "opt_net_mpsafe.h"
77#endif 77#endif
78 78
79#ifdef INET 79#ifdef INET
80 80
81#include "arp.h" 81#include "arp.h"
82#include "bridge.h" 82#include "bridge.h"
83 83
84#include <sys/param.h> 84#include <sys/param.h>
85#include <sys/systm.h> 85#include <sys/systm.h>
86#include <sys/callout.h> 86#include <sys/callout.h>
87#include <sys/kmem.h> 87#include <sys/kmem.h>
88#include <sys/mbuf.h> 88#include <sys/mbuf.h>
89#include <sys/socket.h> 89#include <sys/socket.h>
90#include <sys/time.h> 90#include <sys/time.h>
91#include <sys/timetc.h> 91#include <sys/timetc.h>
92#include <sys/kernel.h> 92#include <sys/kernel.h>
93#include <sys/errno.h> 93#include <sys/errno.h>
94#include <sys/ioctl.h> 94#include <sys/ioctl.h>
95#include <sys/syslog.h> 95#include <sys/syslog.h>
96#include <sys/proc.h> 96#include <sys/proc.h>
97#include <sys/protosw.h> 97#include <sys/protosw.h>
98#include <sys/domain.h> 98#include <sys/domain.h>
99#include <sys/sysctl.h> 99#include <sys/sysctl.h>
100#include <sys/socketvar.h> 100#include <sys/socketvar.h>
101#include <sys/percpu.h> 101#include <sys/percpu.h>
102#include <sys/cprng.h> 102#include <sys/cprng.h>
103#include <sys/kmem.h> 103#include <sys/kmem.h>
104 104
105#include <net/ethertypes.h> 105#include <net/ethertypes.h>
106#include <net/if.h> 106#include <net/if.h>
107#include <net/if_dl.h> 107#include <net/if_dl.h>
108#include <net/if_types.h> 108#include <net/if_types.h>
109#include <net/if_ether.h> 109#include <net/if_ether.h>
110#include <net/if_llatbl.h> 110#include <net/if_llatbl.h>
111#include <net/route.h> 111#include <net/route.h>
112#include <net/net_stats.h> 112#include <net/net_stats.h>
113 113
114#include <netinet/in.h> 114#include <netinet/in.h>
115#include <netinet/in_systm.h> 115#include <netinet/in_systm.h>
116#include <netinet/in_var.h> 116#include <netinet/in_var.h>
117#include <netinet/ip.h> 117#include <netinet/ip.h>
118#include <netinet/if_inarp.h> 118#include <netinet/if_inarp.h>
119 119
120#include "arcnet.h" 120#include "arcnet.h"
121#if NARCNET > 0 121#if NARCNET > 0
122#include <net/if_arc.h> 122#include <net/if_arc.h>
123#endif 123#endif
124#include "carp.h" 124#include "carp.h"
125#if NCARP > 0 125#if NCARP > 0
126#include <netinet/ip_carp.h> 126#include <netinet/ip_carp.h>
127#endif 127#endif
128 128
129/* 129/*
130 * ARP trailer negotiation. Trailer protocol is not IP specific, 130 * ARP trailer negotiation. Trailer protocol is not IP specific,
131 * but ARP request/response use IP addresses. 131 * but ARP request/response use IP addresses.
132 */ 132 */
133#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL 133#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
134 134
135/* timer values */ 135/* timer values */
136static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ 136static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
137static int arpt_down = 20; /* once declared down, don't send for 20 secs */ 137static int arpt_down = 20; /* once declared down, don't send for 20 secs */
138static int arp_maxhold = 1; /* number of packets to hold per ARP entry */ 138static int arp_maxhold = 1; /* number of packets to hold per ARP entry */
139#define rt_expire rt_rmx.rmx_expire 139#define rt_expire rt_rmx.rmx_expire
140#define rt_pksent rt_rmx.rmx_pksent 140#define rt_pksent rt_rmx.rmx_pksent
141 141
142int ip_dad_count = PROBE_NUM; 142int ip_dad_count = PROBE_NUM;
143#ifdef ARP_DEBUG 143#ifdef ARP_DEBUG
144int arp_debug = 1; 144int arp_debug = 1;
145#else 145#else
146int arp_debug = 0; 146int arp_debug = 0;
147#endif 147#endif
148 148
149static void arp_init(void); 149static void arp_init(void);
150static void arp_dad_init(void); 150static void arp_dad_init(void);
151 151
152static void arprequest(struct ifnet *, 152static void arprequest(struct ifnet *,
153 const struct in_addr *, const struct in_addr *, 153 const struct in_addr *, const struct in_addr *,
154 const uint8_t *); 154 const uint8_t *);
155static void arpannounce1(struct ifaddr *); 155static void arpannounce1(struct ifaddr *);
156static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *, 156static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
157 const struct sockaddr *); 157 const struct sockaddr *);
158static void arptimer(void *); 158static void arptimer(void *);
159static void arp_settimer(struct llentry *, int); 159static void arp_settimer(struct llentry *, int);
160static struct llentry *arplookup(struct ifnet *, 160static struct llentry *arplookup(struct ifnet *,
161 const struct in_addr *, const struct sockaddr *, int); 161 const struct in_addr *, const struct sockaddr *, int);
162static struct llentry *arpcreate(struct ifnet *, 162static struct llentry *arpcreate(struct ifnet *,
163 const struct in_addr *, const struct sockaddr *, int); 163 const struct in_addr *, const struct sockaddr *, int);
164static void in_arpinput(struct mbuf *); 164static void in_arpinput(struct mbuf *);
165static void in_revarpinput(struct mbuf *); 165static void in_revarpinput(struct mbuf *);
166static void revarprequest(struct ifnet *); 166static void revarprequest(struct ifnet *);
167 167
168static void arp_drainstub(void); 168static void arp_drainstub(void);
169 169
170struct dadq; 170struct dadq;
171static void arp_dad_timer(struct dadq *); 171static void arp_dad_timer(struct dadq *);
172static void arp_dad_start(struct ifaddr *); 172static void arp_dad_start(struct ifaddr *);
173static void arp_dad_stop(struct ifaddr *); 173static void arp_dad_stop(struct ifaddr *);
174static void arp_dad_duplicated(struct ifaddr *, const struct sockaddr_dl *); 174static void arp_dad_duplicated(struct ifaddr *, const struct sockaddr_dl *);
175 175
176static void arp_init_llentry(struct ifnet *, struct llentry *); 176static void arp_init_llentry(struct ifnet *, struct llentry *);
177 177
178struct ifqueue arpintrq = { 178struct ifqueue arpintrq = {
179 .ifq_head = NULL, 179 .ifq_head = NULL,
180 .ifq_tail = NULL, 180 .ifq_tail = NULL,
181 .ifq_len = 0, 181 .ifq_len = 0,
182 .ifq_maxlen = 50, 182 .ifq_maxlen = 50,
183 .ifq_drops = 0, 183 .ifq_drops = 0,
184}; 184};
185static int arp_maxtries = 5; 185static int arp_maxtries = 5;
186static int useloopback = 1; /* use loopback interface for local traffic */ 186static int useloopback = 1; /* use loopback interface for local traffic */
187 187
188static percpu_t *arpstat_percpu; 188static percpu_t *arpstat_percpu;
189 189
190#define ARP_STAT_GETREF() _NET_STAT_GETREF(arpstat_percpu) 190#define ARP_STAT_GETREF() _NET_STAT_GETREF(arpstat_percpu)
191#define ARP_STAT_PUTREF() _NET_STAT_PUTREF(arpstat_percpu) 191#define ARP_STAT_PUTREF() _NET_STAT_PUTREF(arpstat_percpu)
192 192
193#define ARP_STATINC(x) _NET_STATINC(arpstat_percpu, x) 193#define ARP_STATINC(x) _NET_STATINC(arpstat_percpu, x)
194#define ARP_STATADD(x, v) _NET_STATADD(arpstat_percpu, x, v) 194#define ARP_STATADD(x, v) _NET_STATADD(arpstat_percpu, x, v)
195 195
196/* revarp state */ 196/* revarp state */
197static struct in_addr myip, srv_ip; 197static struct in_addr myip, srv_ip;
198static int myip_initialized = 0; 198static int myip_initialized = 0;
199static int revarp_in_progress = 0; 199static int revarp_in_progress = 0;
200static struct ifnet *myip_ifp = NULL; 200static struct ifnet *myip_ifp = NULL;
201 201
202static int arp_drainwanted; 202static int arp_drainwanted;
203 203
204static int log_movements = 0; 204static int log_movements = 0;
205static int log_permanent_modify = 1; 205static int log_permanent_modify = 1;
206static int log_wrong_iface = 1; 206static int log_wrong_iface = 1;
207 207
208DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */ 208DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */
209 209
210static void 210static void
211arp_fasttimo(void) 211arp_fasttimo(void)
212{ 212{
213 if (arp_drainwanted) { 213 if (arp_drainwanted) {
214 arp_drain(); 214 arp_drain();
215 arp_drainwanted = 0; 215 arp_drainwanted = 0;
216 } 216 }
217} 217}
218 218
219static const struct protosw arpsw[] = { 219static const struct protosw arpsw[] = {
220 { 220 {
221 .pr_type = 0, 221 .pr_type = 0,
222 .pr_domain = &arpdomain, 222 .pr_domain = &arpdomain,
223 .pr_protocol = 0, 223 .pr_protocol = 0,
224 .pr_flags = 0, 224 .pr_flags = 0,
225 .pr_input = 0, 225 .pr_input = 0,
226 .pr_ctlinput = 0, 226 .pr_ctlinput = 0,
227 .pr_ctloutput = 0, 227 .pr_ctloutput = 0,
228 .pr_usrreqs = 0, 228 .pr_usrreqs = 0,
229 .pr_init = arp_init, 229 .pr_init = arp_init,
230 .pr_fasttimo = arp_fasttimo, 230 .pr_fasttimo = arp_fasttimo,
231 .pr_slowtimo = 0, 231 .pr_slowtimo = 0,
232 .pr_drain = arp_drainstub, 232 .pr_drain = arp_drainstub,
233 } 233 }
234}; 234};
235 235
236struct domain arpdomain = { 236struct domain arpdomain = {
237 .dom_family = PF_ARP, 237 .dom_family = PF_ARP,
238 .dom_name = "arp", 238 .dom_name = "arp",
239 .dom_protosw = arpsw, 239 .dom_protosw = arpsw,
240 .dom_protoswNPROTOSW = &arpsw[__arraycount(arpsw)], 240 .dom_protoswNPROTOSW = &arpsw[__arraycount(arpsw)],
241#ifdef MBUFTRACE 241#ifdef MBUFTRACE
242 .dom_mowner = MOWNER_INIT("internet", "arp"), 242 .dom_mowner = MOWNER_INIT("internet", "arp"),
243#endif 243#endif
244}; 244};
245 245
246static void sysctl_net_inet_arp_setup(struct sysctllog **); 246static void sysctl_net_inet_arp_setup(struct sysctllog **);
247 247
248void 248void
249arp_init(void) 249arp_init(void)
250{ 250{
251 251
252 sysctl_net_inet_arp_setup(NULL); 252 sysctl_net_inet_arp_setup(NULL);
253 arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS); 253 arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS);
254 IFQ_LOCK_INIT(&arpintrq); 254 IFQ_LOCK_INIT(&arpintrq);
255 255
256#ifdef MBUFTRACE 256#ifdef MBUFTRACE
257 MOWNER_ATTACH(&arpdomain.dom_mowner); 257 MOWNER_ATTACH(&arpdomain.dom_mowner);
258#endif 258#endif
259 259
260 arp_dad_init(); 260 arp_dad_init();
261} 261}
262 262
263static void 263static void
264arp_drainstub(void) 264arp_drainstub(void)
265{ 265{
266 arp_drainwanted = 1; 266 arp_drainwanted = 1;
267} 267}
268 268
269/* 269/*
270 * ARP protocol drain routine. Called when memory is in short supply. 270 * ARP protocol drain routine. Called when memory is in short supply.
271 * Called at splvm(); don't acquire softnet_lock as can be called from 271 * Called at splvm(); don't acquire softnet_lock as can be called from
272 * hardware interrupt handlers. 272 * hardware interrupt handlers.
273 */ 273 */
274void 274void
275arp_drain(void) 275arp_drain(void)
276{ 276{
277 277
278 lltable_drain(AF_INET); 278 lltable_drain(AF_INET);
279} 279}
280 280
281static void 281static void
282arptimer(void *arg) 282arptimer(void *arg)
283{ 283{
284 struct llentry *lle = arg; 284 struct llentry *lle = arg;
285 struct ifnet *ifp; 285 struct ifnet *ifp;
286 286
287 KASSERT((lle->la_flags & LLE_STATIC) == 0); 287 KASSERT((lle->la_flags & LLE_STATIC) == 0);
288 288
289 LLE_WLOCK(lle); 289 LLE_WLOCK(lle);
290 290
291 /* 291 /*
292 * This shortcut is required to avoid trying to touch ifp that may be 292 * This shortcut is required to avoid trying to touch ifp that may be
293 * being destroyed. 293 * being destroyed.
294 */ 294 */
295 if ((lle->la_flags & LLE_LINKED) == 0) { 295 if ((lle->la_flags & LLE_LINKED) == 0) {
296 LLE_FREE_LOCKED(lle); 296 LLE_FREE_LOCKED(lle);
297 return; 297 return;
298 } 298 }
299 299
300 ifp = lle->lle_tbl->llt_ifp; 300 ifp = lle->lle_tbl->llt_ifp;
301 301
302 /* XXX: LOR avoidance. We still have ref on lle. */ 302 /* XXX: LOR avoidance. We still have ref on lle. */
303 LLE_WUNLOCK(lle); 303 LLE_WUNLOCK(lle);
304 304
305 IF_AFDATA_LOCK(ifp); 305 IF_AFDATA_LOCK(ifp);
306 LLE_WLOCK(lle); 306 LLE_WLOCK(lle);
307 307
308 /* Guard against race with other llentry_free(). */ 308 /* Guard against race with other llentry_free(). */
309 if (lle->la_flags & LLE_LINKED) { 309 if (lle->la_flags & LLE_LINKED) {
 310 int rt_cmd;
 311 struct in_addr *in;
 312 struct sockaddr_in sin;
 313 const char *lladdr;
310 size_t pkts_dropped; 314 size_t pkts_dropped;
311 315
 316 in = &lle->r_l3addr.addr4;
 317 sockaddr_in_init(&sin, in, 0);
312 if (lle->la_flags & LLE_VALID) { 318 if (lle->la_flags & LLE_VALID) {
313 struct in_addr *in; 319 rt_cmd = RTM_DELETE;
314 struct sockaddr_in sin; 
315 const char *lladdr; 
316 
317 in = &lle->r_l3addr.addr4; 
318 sockaddr_in_init(&sin, in, 0); 
319 lladdr = (const char *)&lle->ll_addr; 320 lladdr = (const char *)&lle->ll_addr;
320 rt_clonedmsg(RTM_DELETE, sintosa(&sin), lladdr, ifp); 321 } else {
 322 rt_cmd = RTM_MISS;
 323 lladdr = NULL;
321 } 324 }
 325 rt_clonedmsg(rt_cmd, sintosa(&sin), lladdr, ifp);
322 326
323 LLE_REMREF(lle); 327 LLE_REMREF(lle);
324 pkts_dropped = llentry_free(lle); 328 pkts_dropped = llentry_free(lle);
325 ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped); 329 ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped);
326 ARP_STATADD(ARP_STAT_DFRTOTAL, pkts_dropped); 330 ARP_STATADD(ARP_STAT_DFRTOTAL, pkts_dropped);
327 } else { 331 } else {
328 LLE_FREE_LOCKED(lle); 332 LLE_FREE_LOCKED(lle);
329 } 333 }
330 334
331 IF_AFDATA_UNLOCK(ifp); 335 IF_AFDATA_UNLOCK(ifp);
332} 336}
333 337
334static void 338static void
335arp_settimer(struct llentry *la, int sec) 339arp_settimer(struct llentry *la, int sec)
336{ 340{
337 341
338 LLE_WLOCK_ASSERT(la); 342 LLE_WLOCK_ASSERT(la);
339 KASSERT((la->la_flags & LLE_STATIC) == 0); 343 KASSERT((la->la_flags & LLE_STATIC) == 0);
340 344
341 /* 345 /*
342 * We have to take care of a reference leak which occurs if 346 * We have to take care of a reference leak which occurs if
343 * callout_reset overwrites a pending callout schedule. Unfortunately 347 * callout_reset overwrites a pending callout schedule. Unfortunately
344 * we don't have a mean to know the overwrite, so we need to know it 348 * we don't have a mean to know the overwrite, so we need to know it
345 * using callout_stop. We need to call callout_pending first to exclude 349 * using callout_stop. We need to call callout_pending first to exclude
346 * the case that the callout has never been scheduled. 350 * the case that the callout has never been scheduled.
347 */ 351 */
348 if (callout_pending(&la->la_timer)) { 352 if (callout_pending(&la->la_timer)) {
349 bool expired = callout_stop(&la->la_timer); 353 bool expired = callout_stop(&la->la_timer);
350 if (!expired) 354 if (!expired)
351 /* A pending callout schedule is canceled. */ 355 /* A pending callout schedule is canceled. */
352 LLE_REMREF(la); 356 LLE_REMREF(la);
353 } 357 }
354 LLE_ADDREF(la); 358 LLE_ADDREF(la);
355 callout_reset(&la->la_timer, hz * sec, arptimer, la); 359 callout_reset(&la->la_timer, hz * sec, arptimer, la);
356} 360}
357 361
358/* 362/*
359 * We set the gateway for RTF_CLONING routes to a "prototype" 363 * We set the gateway for RTF_CLONING routes to a "prototype"
360 * link-layer sockaddr whose interface type (if_type) and interface 364 * link-layer sockaddr whose interface type (if_type) and interface
361 * index (if_index) fields are prepared. 365 * index (if_index) fields are prepared.
362 */ 366 */
363static struct sockaddr * 367static struct sockaddr *
364arp_setgate(struct rtentry *rt, struct sockaddr *gate, 368arp_setgate(struct rtentry *rt, struct sockaddr *gate,
365 const struct sockaddr *netmask) 369 const struct sockaddr *netmask)
366{ 370{
367 const struct ifnet *ifp = rt->rt_ifp; 371 const struct ifnet *ifp = rt->rt_ifp;
368 uint8_t namelen = strlen(ifp->if_xname); 372 uint8_t namelen = strlen(ifp->if_xname);
369 uint8_t addrlen = ifp->if_addrlen; 373 uint8_t addrlen = ifp->if_addrlen;
370 374
371 /* 375 /*
372 * XXX: If this is a manually added route to interface 376 * XXX: If this is a manually added route to interface
373 * such as older version of routed or gated might provide, 377 * such as older version of routed or gated might provide,
374 * restore cloning bit. 378 * restore cloning bit.
375 */ 379 */
376 if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL && 380 if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL &&
377 satocsin(netmask)->sin_addr.s_addr != 0xffffffff) 381 satocsin(netmask)->sin_addr.s_addr != 0xffffffff)
378 rt->rt_flags |= RTF_CONNECTED; 382 rt->rt_flags |= RTF_CONNECTED;
379 383
380 if ((rt->rt_flags & (RTF_CONNECTED | RTF_LOCAL))) { 384 if ((rt->rt_flags & (RTF_CONNECTED | RTF_LOCAL))) {
381 union { 385 union {
382 struct sockaddr sa; 386 struct sockaddr sa;
383 struct sockaddr_storage ss; 387 struct sockaddr_storage ss;
384 struct sockaddr_dl sdl; 388 struct sockaddr_dl sdl;
385 } u; 389 } u;
386 /* 390 /*
387 * Case 1: This route should come from a route to iface. 391 * Case 1: This route should come from a route to iface.
388 */ 392 */
389 sockaddr_dl_init(&u.sdl, sizeof(u.ss), 393 sockaddr_dl_init(&u.sdl, sizeof(u.ss),
390 ifp->if_index, ifp->if_type, NULL, namelen, NULL, addrlen); 394 ifp->if_index, ifp->if_type, NULL, namelen, NULL, addrlen);
391 rt_setgate(rt, &u.sa); 395 rt_setgate(rt, &u.sa);
392 gate = rt->rt_gateway; 396 gate = rt->rt_gateway;
393 } 397 }
394 return gate; 398 return gate;
395} 399}
396 400
397static void 401static void
398arp_init_llentry(struct ifnet *ifp, struct llentry *lle) 402arp_init_llentry(struct ifnet *ifp, struct llentry *lle)
399{ 403{
400 404
401 switch (ifp->if_type) { 405 switch (ifp->if_type) {
402 default: 406 default:
403 /* Nothing. */ 407 /* Nothing. */
404 break; 408 break;
405 } 409 }
406} 410}
407 411
408/* 412/*
409 * Parallel to llc_rtrequest. 413 * Parallel to llc_rtrequest.
410 */ 414 */
411void 415void
412arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info) 416arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
413{ 417{
414 struct sockaddr *gate = rt->rt_gateway; 418 struct sockaddr *gate = rt->rt_gateway;
415 struct in_ifaddr *ia; 419 struct in_ifaddr *ia;
416 struct ifaddr *ifa; 420 struct ifaddr *ifa;
417 struct ifnet *ifp = rt->rt_ifp; 421 struct ifnet *ifp = rt->rt_ifp;
418 int bound; 422 int bound;
419 int s; 423 int s;
420 424
421 if (req == RTM_LLINFO_UPD) { 425 if (req == RTM_LLINFO_UPD) {
422 if ((ifa = info->rti_ifa) != NULL) 426 if ((ifa = info->rti_ifa) != NULL)
423 arpannounce1(ifa); 427 arpannounce1(ifa);
424 return; 428 return;
425 } 429 }
426 430
427 if ((rt->rt_flags & RTF_GATEWAY) != 0) { 431 if ((rt->rt_flags & RTF_GATEWAY) != 0) {
428 if (req != RTM_ADD) 432 if (req != RTM_ADD)
429 return; 433 return;
430 434
431 /* 435 /*
432 * linklayers with particular link MTU limitation. 436 * linklayers with particular link MTU limitation.
433 */ 437 */
434 switch(ifp->if_type) { 438 switch(ifp->if_type) {
435#if NARCNET > 0 439#if NARCNET > 0
436 case IFT_ARCNET: 440 case IFT_ARCNET:
437 { 441 {
438 int arcipifmtu; 442 int arcipifmtu;
439 443
440 if (ifp->if_flags & IFF_LINK0) 444 if (ifp->if_flags & IFF_LINK0)
441 arcipifmtu = arc_ipmtu; 445 arcipifmtu = arc_ipmtu;
442 else 446 else
443 arcipifmtu = ARCMTU; 447 arcipifmtu = ARCMTU;
444 if (ifp->if_mtu > arcipifmtu) 448 if (ifp->if_mtu > arcipifmtu)
445 rt->rt_rmx.rmx_mtu = arcipifmtu; 449 rt->rt_rmx.rmx_mtu = arcipifmtu;
446 break; 450 break;
447 } 451 }
448#endif 452#endif
449 } 453 }
450 return; 454 return;
451 } 455 }
452 456
453 switch (req) { 457 switch (req) {
454 case RTM_SETGATE: 458 case RTM_SETGATE:
455 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]); 459 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
456 break; 460 break;
457 case RTM_ADD: 461 case RTM_ADD:
458 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]); 462 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
459 if (gate == NULL) { 463 if (gate == NULL) {
460 log(LOG_ERR, "%s: arp_setgate failed\n", __func__); 464 log(LOG_ERR, "%s: arp_setgate failed\n", __func__);
461 break; 465 break;
462 } 466 }
463 if ((rt->rt_flags & RTF_CONNECTED) || 467 if ((rt->rt_flags & RTF_CONNECTED) ||
464 (rt->rt_flags & RTF_LOCAL)) { 468 (rt->rt_flags & RTF_LOCAL)) {
465 /* 469 /*
466 * Give this route an expiration time, even though 470 * Give this route an expiration time, even though
467 * it's a "permanent" route, so that routes cloned 471 * it's a "permanent" route, so that routes cloned
468 * from it do not need their expiration time set. 472 * from it do not need their expiration time set.
469 */ 473 */
470 KASSERT(time_uptime != 0); 474 KASSERT(time_uptime != 0);
471 rt->rt_expire = time_uptime; 475 rt->rt_expire = time_uptime;
472 /* 476 /*
473 * linklayers with particular link MTU limitation. 477 * linklayers with particular link MTU limitation.
474 */ 478 */
475 switch (ifp->if_type) { 479 switch (ifp->if_type) {
476#if NARCNET > 0 480#if NARCNET > 0
477 case IFT_ARCNET: 481 case IFT_ARCNET:
478 { 482 {
479 int arcipifmtu; 483 int arcipifmtu;
480 if (ifp->if_flags & IFF_LINK0) 484 if (ifp->if_flags & IFF_LINK0)
481 arcipifmtu = arc_ipmtu; 485 arcipifmtu = arc_ipmtu;
482 else 486 else
483 arcipifmtu = ARCMTU; 487 arcipifmtu = ARCMTU;
484 488
485 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 && 489 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
486 (rt->rt_rmx.rmx_mtu > arcipifmtu || 490 (rt->rt_rmx.rmx_mtu > arcipifmtu ||
487 (rt->rt_rmx.rmx_mtu == 0 && 491 (rt->rt_rmx.rmx_mtu == 0 &&
488 ifp->if_mtu > arcipifmtu))) 492 ifp->if_mtu > arcipifmtu)))
489 rt->rt_rmx.rmx_mtu = arcipifmtu; 493 rt->rt_rmx.rmx_mtu = arcipifmtu;
490 break; 494 break;
491 } 495 }
492#endif 496#endif
493 } 497 }
494 if (rt->rt_flags & RTF_CONNECTED) 498 if (rt->rt_flags & RTF_CONNECTED)
495 break; 499 break;
496 } 500 }
497 501
498 bound = curlwp_bind(); 502 bound = curlwp_bind();
499 /* Announce a new entry if requested. */ 503 /* Announce a new entry if requested. */
500 if (rt->rt_flags & RTF_ANNOUNCE) { 504 if (rt->rt_flags & RTF_ANNOUNCE) {
501 struct psref psref; 505 struct psref psref;
502 ia = in_get_ia_on_iface_psref( 506 ia = in_get_ia_on_iface_psref(
503 satocsin(rt_getkey(rt))->sin_addr, ifp, &psref); 507 satocsin(rt_getkey(rt))->sin_addr, ifp, &psref);
504 if (ia != NULL) { 508 if (ia != NULL) {
505 arpannounce(ifp, &ia->ia_ifa, 509 arpannounce(ifp, &ia->ia_ifa,
506 CLLADDR(satocsdl(gate))); 510 CLLADDR(satocsdl(gate)));
507 ia4_release(ia, &psref); 511 ia4_release(ia, &psref);
508 } 512 }
509 } 513 }
510 514
511 if (gate->sa_family != AF_LINK || 515 if (gate->sa_family != AF_LINK ||
512 gate->sa_len < sockaddr_dl_measure(0, ifp->if_addrlen)) { 516 gate->sa_len < sockaddr_dl_measure(0, ifp->if_addrlen)) {
513 log(LOG_DEBUG, "%s: bad gateway value\n", __func__); 517 log(LOG_DEBUG, "%s: bad gateway value\n", __func__);
514 goto out; 518 goto out;
515 } 519 }
516 520
517 satosdl(gate)->sdl_type = ifp->if_type; 521 satosdl(gate)->sdl_type = ifp->if_type;
518 satosdl(gate)->sdl_index = ifp->if_index; 522 satosdl(gate)->sdl_index = ifp->if_index;
519 523
520 /* 524 /*
521 * If the route is for a broadcast address mark it as such. 525 * If the route is for a broadcast address mark it as such.
522 * This way we can avoid an expensive call to in_broadcast() 526 * This way we can avoid an expensive call to in_broadcast()
523 * in ip_output() most of the time (because the route passed 527 * in ip_output() most of the time (because the route passed
524 * to ip_output() is almost always a host route). 528 * to ip_output() is almost always a host route).
525 */ 529 */
526 if (rt->rt_flags & RTF_HOST && 530 if (rt->rt_flags & RTF_HOST &&
527 !(rt->rt_flags & RTF_BROADCAST) && 531 !(rt->rt_flags & RTF_BROADCAST) &&
528 in_broadcast(satocsin(rt_getkey(rt))->sin_addr, rt->rt_ifp)) 532 in_broadcast(satocsin(rt_getkey(rt))->sin_addr, rt->rt_ifp))
529 rt->rt_flags |= RTF_BROADCAST; 533 rt->rt_flags |= RTF_BROADCAST;
530 /* There is little point in resolving the broadcast address */ 534 /* There is little point in resolving the broadcast address */
531 if (rt->rt_flags & RTF_BROADCAST) 535 if (rt->rt_flags & RTF_BROADCAST)
532 goto out; 536 goto out;
533 537
534 /* 538 /*
535 * When called from rt_ifa_addlocal, we cannot depend on that 539 * When called from rt_ifa_addlocal, we cannot depend on that
536 * the address (rt_getkey(rt)) exits in the address list of the 540 * the address (rt_getkey(rt)) exits in the address list of the
537 * interface. So check RTF_LOCAL instead. 541 * interface. So check RTF_LOCAL instead.
538 */ 542 */
539 if (rt->rt_flags & RTF_LOCAL) { 543 if (rt->rt_flags & RTF_LOCAL) {
540 rt->rt_expire = 0; 544 rt->rt_expire = 0;
541 if (useloopback) { 545 if (useloopback) {
542 rt->rt_ifp = lo0ifp; 546 rt->rt_ifp = lo0ifp;
543 rt->rt_rmx.rmx_mtu = 0; 547 rt->rt_rmx.rmx_mtu = 0;
544 } 548 }
545 goto out; 549 goto out;
546 } 550 }
547 551
548 s = pserialize_read_enter(); 552 s = pserialize_read_enter();
549 ia = in_get_ia_on_iface(satocsin(rt_getkey(rt))->sin_addr, ifp); 553 ia = in_get_ia_on_iface(satocsin(rt_getkey(rt))->sin_addr, ifp);
550 if (ia == NULL) { 554 if (ia == NULL) {
551 pserialize_read_exit(s); 555 pserialize_read_exit(s);
552 goto out; 556 goto out;
553 } 557 }
554 558
555 rt->rt_expire = 0; 559 rt->rt_expire = 0;
556 if (useloopback) { 560 if (useloopback) {
557 rt->rt_ifp = lo0ifp; 561 rt->rt_ifp = lo0ifp;
558 rt->rt_rmx.rmx_mtu = 0; 562 rt->rt_rmx.rmx_mtu = 0;
559 } 563 }
560 rt->rt_flags |= RTF_LOCAL; 564 rt->rt_flags |= RTF_LOCAL;
561 565
562 if (ISSET(info->rti_flags, RTF_DONTCHANGEIFA)) { 566 if (ISSET(info->rti_flags, RTF_DONTCHANGEIFA)) {
563 pserialize_read_exit(s); 567 pserialize_read_exit(s);
564 goto out; 568 goto out;
565 } 569 }
566 /* 570 /*
567 * make sure to set rt->rt_ifa to the interface 571 * make sure to set rt->rt_ifa to the interface
568 * address we are using, otherwise we will have trouble 572 * address we are using, otherwise we will have trouble
569 * with source address selection. 573 * with source address selection.
570 */ 574 */
571 ifa = &ia->ia_ifa; 575 ifa = &ia->ia_ifa;
572 if (ifa != rt->rt_ifa) 576 if (ifa != rt->rt_ifa)
573 /* Assume it doesn't sleep */ 577 /* Assume it doesn't sleep */
574 rt_replace_ifa(rt, ifa); 578 rt_replace_ifa(rt, ifa);
575 pserialize_read_exit(s); 579 pserialize_read_exit(s);
576 out: 580 out:
577 curlwp_bindx(bound); 581 curlwp_bindx(bound);
578 break; 582 break;
579 } 583 }
580} 584}
581 585
582/* 586/*
583 * Broadcast an ARP request. Caller specifies: 587 * Broadcast an ARP request. Caller specifies:
584 * - arp header source ip address 588 * - arp header source ip address
585 * - arp header target ip address 589 * - arp header target ip address
586 * - arp header source ethernet address 590 * - arp header source ethernet address
587 */ 591 */
588static void 592static void
589arprequest(struct ifnet *ifp, 593arprequest(struct ifnet *ifp,
590 const struct in_addr *sip, const struct in_addr *tip, 594 const struct in_addr *sip, const struct in_addr *tip,
591 const uint8_t *enaddr) 595 const uint8_t *enaddr)
592{ 596{
593 struct mbuf *m; 597 struct mbuf *m;
594 struct arphdr *ah; 598 struct arphdr *ah;
595 struct sockaddr sa; 599 struct sockaddr sa;
596 uint64_t *arps; 600 uint64_t *arps;
597 601
598 KASSERT(sip != NULL); 602 KASSERT(sip != NULL);
599 KASSERT(tip != NULL); 603 KASSERT(tip != NULL);
600 KASSERT(enaddr != NULL); 604 KASSERT(enaddr != NULL);
601 605
602 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 606 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
603 return; 607 return;
604 MCLAIM(m, &arpdomain.dom_mowner); 608 MCLAIM(m, &arpdomain.dom_mowner);
605 switch (ifp->if_type) { 609 switch (ifp->if_type) {
606 case IFT_IEEE1394: 610 case IFT_IEEE1394:
607 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 611 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
608 ifp->if_addrlen; 612 ifp->if_addrlen;
609 break; 613 break;
610 default: 614 default:
611 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 615 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
612 2 * ifp->if_addrlen; 616 2 * ifp->if_addrlen;
613 break; 617 break;
614 } 618 }
615 m->m_pkthdr.len = m->m_len; 619 m->m_pkthdr.len = m->m_len;
616 m_align(m, m->m_len); 620 m_align(m, m->m_len);
617 ah = mtod(m, struct arphdr *); 621 ah = mtod(m, struct arphdr *);
618 memset(ah, 0, m->m_len); 622 memset(ah, 0, m->m_len);
619 switch (ifp->if_type) { 623 switch (ifp->if_type) {
620 case IFT_IEEE1394: /* RFC2734 */ 624 case IFT_IEEE1394: /* RFC2734 */
621 /* fill it now for ar_tpa computation */ 625 /* fill it now for ar_tpa computation */
622 ah->ar_hrd = htons(ARPHRD_IEEE1394); 626 ah->ar_hrd = htons(ARPHRD_IEEE1394);
623 break; 627 break;
624 default: 628 default:
625 /* ifp->if_output will fill ar_hrd */ 629 /* ifp->if_output will fill ar_hrd */
626 break; 630 break;
627 } 631 }
628 ah->ar_pro = htons(ETHERTYPE_IP); 632 ah->ar_pro = htons(ETHERTYPE_IP);
629 ah->ar_hln = ifp->if_addrlen; /* hardware address length */ 633 ah->ar_hln = ifp->if_addrlen; /* hardware address length */
630 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 634 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
631 ah->ar_op = htons(ARPOP_REQUEST); 635 ah->ar_op = htons(ARPOP_REQUEST);
632 memcpy(ar_sha(ah), enaddr, ah->ar_hln); 636 memcpy(ar_sha(ah), enaddr, ah->ar_hln);
633 memcpy(ar_spa(ah), sip, ah->ar_pln); 637 memcpy(ar_spa(ah), sip, ah->ar_pln);
634 memcpy(ar_tpa(ah), tip, ah->ar_pln); 638 memcpy(ar_tpa(ah), tip, ah->ar_pln);
635 sa.sa_family = AF_ARP; 639 sa.sa_family = AF_ARP;
636 sa.sa_len = 2; 640 sa.sa_len = 2;
637 m->m_flags |= M_BCAST; 641 m->m_flags |= M_BCAST;
638 arps = ARP_STAT_GETREF(); 642 arps = ARP_STAT_GETREF();
639 arps[ARP_STAT_SNDTOTAL]++; 643 arps[ARP_STAT_SNDTOTAL]++;
640 arps[ARP_STAT_SENDREQUEST]++; 644 arps[ARP_STAT_SENDREQUEST]++;
641 ARP_STAT_PUTREF(); 645 ARP_STAT_PUTREF();
642 if_output_lock(ifp, ifp, m, &sa, NULL); 646 if_output_lock(ifp, ifp, m, &sa, NULL);
643} 647}
644 648
645void 649void
646arpannounce(struct ifnet *ifp, struct ifaddr *ifa, const uint8_t *enaddr) 650arpannounce(struct ifnet *ifp, struct ifaddr *ifa, const uint8_t *enaddr)
647{ 651{
648 struct in_ifaddr *ia = ifatoia(ifa); 652 struct in_ifaddr *ia = ifatoia(ifa);
649 struct in_addr *ip = &IA_SIN(ifa)->sin_addr; 653 struct in_addr *ip = &IA_SIN(ifa)->sin_addr;
650 654
651 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) { 655 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) {
652 ARPLOG(LOG_DEBUG, "%s not ready\n", ARPLOGADDR(ip)); 656 ARPLOG(LOG_DEBUG, "%s not ready\n", ARPLOGADDR(ip));
653 return; 657 return;
654 } 658 }
655 arprequest(ifp, ip, ip, enaddr); 659 arprequest(ifp, ip, ip, enaddr);
656} 660}
657 661
658static void 662static void
659arpannounce1(struct ifaddr *ifa) 663arpannounce1(struct ifaddr *ifa)
660{ 664{
661 665
662 arpannounce(ifa->ifa_ifp, ifa, CLLADDR(ifa->ifa_ifp->if_sadl)); 666 arpannounce(ifa->ifa_ifp, ifa, CLLADDR(ifa->ifa_ifp->if_sadl));
663} 667}
664 668
665/* 669/*
666 * Resolve an IP address into an ethernet address. If success, desten is 670 * Resolve an IP address into an ethernet address. If success, desten is
667 * filled in. If there is no entry in arptab, set one up and broadcast a 671 * filled in. If there is no entry in arptab, set one up and broadcast a
668 * request for the IP address. Hold onto this mbuf and resend it once the 672 * request for the IP address. Hold onto this mbuf and resend it once the
669 * address is finally resolved. 673 * address is finally resolved.
670 * 674 *
671 * A return value of 0 indicates that desten has been filled in and the packet 675 * A return value of 0 indicates that desten has been filled in and the packet
672 * should be sent normally; a return value of EWOULDBLOCK indicates that the 676 * should be sent normally; a return value of EWOULDBLOCK indicates that the
673 * packet has been held pending resolution. Any other value indicates an 677 * packet has been held pending resolution. Any other value indicates an
674 * error. 678 * error.
675 */ 679 */
676int 680int
677arpresolve(struct ifnet *ifp, const struct rtentry *rt, struct mbuf *m, 681arpresolve(struct ifnet *ifp, const struct rtentry *rt, struct mbuf *m,
678 const struct sockaddr *dst, void *desten, size_t destlen) 682 const struct sockaddr *dst, void *desten, size_t destlen)
679{ 683{
680 struct llentry *la; 684 struct llentry *la;
681 const char *create_lookup; 685 const char *create_lookup;
682 bool renew; 686 bool renew;
683 int error; 687 int error;
684 struct ifnet *origifp = ifp; 688 struct ifnet *origifp = ifp;
685 689
686#if NCARP > 0 690#if NCARP > 0
687 if (rt != NULL && rt->rt_ifp->if_type == IFT_CARP) 691 if (rt != NULL && rt->rt_ifp->if_type == IFT_CARP)
688 ifp = rt->rt_ifp; 692 ifp = rt->rt_ifp;
689#endif 693#endif
690 694
691 KASSERT(m != NULL); 695 KASSERT(m != NULL);
692 696
693 la = arplookup(ifp, NULL, dst, 0); 697 la = arplookup(ifp, NULL, dst, 0);
694 if (la == NULL) 698 if (la == NULL)
695 goto notfound; 699 goto notfound;
696 700
697 if ((la->la_flags & LLE_VALID) && 701 if ((la->la_flags & LLE_VALID) &&
698 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) { 702 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) {
699 KASSERT(destlen >= ifp->if_addrlen); 703 KASSERT(destlen >= ifp->if_addrlen);
700 memcpy(desten, &la->ll_addr, ifp->if_addrlen); 704 memcpy(desten, &la->ll_addr, ifp->if_addrlen);
701 LLE_RUNLOCK(la); 705 LLE_RUNLOCK(la);
702 return 0; 706 return 0;
703 } 707 }
704 708
705notfound: 709notfound:
706 if (ifp->if_flags & IFF_NOARP) { 710 if (ifp->if_flags & IFF_NOARP) {
707 if (la != NULL) 711 if (la != NULL)
708 LLE_RUNLOCK(la); 712 LLE_RUNLOCK(la);
709 error = ENOTSUP; 713 error = ENOTSUP;
710 goto bad; 714 goto bad;
711 } 715 }
712 716
713 if (la == NULL) { 717 if (la == NULL) {
714 struct rtentry *_rt; 718 struct rtentry *_rt;
715 719
716 create_lookup = "create"; 720 create_lookup = "create";
717 _rt = rtalloc1(dst, 0); 721 _rt = rtalloc1(dst, 0);
718 IF_AFDATA_WLOCK(ifp); 722 IF_AFDATA_WLOCK(ifp);
719 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst, _rt); 723 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst, _rt);
720 IF_AFDATA_WUNLOCK(ifp); 724 IF_AFDATA_WUNLOCK(ifp);
721 if (_rt != NULL) 725 if (_rt != NULL)
722 rt_unref(_rt); 726 rt_unref(_rt);
723 if (la == NULL) 727 if (la == NULL)
724 ARP_STATINC(ARP_STAT_ALLOCFAIL); 728 ARP_STATINC(ARP_STAT_ALLOCFAIL);
725 else 729 else
726 arp_init_llentry(ifp, la); 730 arp_init_llentry(ifp, la);
727 } else if (LLE_TRY_UPGRADE(la) == 0) { 731 } else if (LLE_TRY_UPGRADE(la) == 0) {
728 create_lookup = "lookup"; 732 create_lookup = "lookup";
729 LLE_RUNLOCK(la); 733 LLE_RUNLOCK(la);
730 IF_AFDATA_RLOCK(ifp); 734 IF_AFDATA_RLOCK(ifp);
731 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst); 735 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
732 IF_AFDATA_RUNLOCK(ifp); 736 IF_AFDATA_RUNLOCK(ifp);
733 } 737 }
734 738
735 error = EINVAL; 739 error = EINVAL;
736 if (la == NULL) { 740 if (la == NULL) {
737 log(LOG_DEBUG, 741 log(LOG_DEBUG,
738 "%s: failed to %s llentry for %s on %s\n", 742 "%s: failed to %s llentry for %s on %s\n",
739 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr), 743 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr),
740 ifp->if_xname); 744 ifp->if_xname);
741 goto bad; 745 goto bad;
742 } 746 }
743 747
744 if ((la->la_flags & LLE_VALID) && 748 if ((la->la_flags & LLE_VALID) &&
745 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) 749 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime))
746 { 750 {
747 KASSERT(destlen >= ifp->if_addrlen); 751 KASSERT(destlen >= ifp->if_addrlen);
748 memcpy(desten, &la->ll_addr, ifp->if_addrlen); 752 memcpy(desten, &la->ll_addr, ifp->if_addrlen);
749 renew = false; 753 renew = false;
750 /* 754 /*
751 * If entry has an expiry time and it is approaching, 755 * If entry has an expiry time and it is approaching,
752 * see if we need to send an ARP request within this 756 * see if we need to send an ARP request within this
753 * arpt_down interval. 757 * arpt_down interval.
754 */ 758 */
755 if (!(la->la_flags & LLE_STATIC) && 759 if (!(la->la_flags & LLE_STATIC) &&
756 time_uptime + la->la_preempt > la->la_expire) 760 time_uptime + la->la_preempt > la->la_expire)
757 { 761 {
758 renew = true; 762 renew = true;
759 la->la_preempt--; 763 la->la_preempt--;
760 } 764 }
761 765
762 LLE_WUNLOCK(la); 766 LLE_WUNLOCK(la);
763 767
764 if (renew) { 768 if (renew) {
765 const uint8_t *enaddr = CLLADDR(ifp->if_sadl); 769 const uint8_t *enaddr = CLLADDR(ifp->if_sadl);
766 arprequest(origifp, 770 arprequest(origifp,
767 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 771 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
768 &satocsin(dst)->sin_addr, enaddr); 772 &satocsin(dst)->sin_addr, enaddr);
769 } 773 }
770 774
771 return 0; 775 return 0;
772 } 776 }
773 777
774 if (la->la_flags & LLE_STATIC) { /* should not happen! */ 778 if (la->la_flags & LLE_STATIC) { /* should not happen! */
775 LLE_RUNLOCK(la); 779 LLE_RUNLOCK(la);
776 log(LOG_DEBUG, "%s: ouch, empty static llinfo for %s\n", 780 log(LOG_DEBUG, "%s: ouch, empty static llinfo for %s\n",
777 __func__, inet_ntoa(satocsin(dst)->sin_addr)); 781 __func__, inet_ntoa(satocsin(dst)->sin_addr));
778 error = EINVAL; 782 error = EINVAL;
779 goto bad; 783 goto bad;
780 } 784 }
781 785
782 renew = (la->la_asked == 0 || la->la_expire != time_uptime); 786 renew = (la->la_asked == 0 || la->la_expire != time_uptime);
783 787
784 /* 788 /*
785 * There is an arptab entry, but no ethernet address 789 * There is an arptab entry, but no ethernet address
786 * response yet. Add the mbuf to the list, dropping 790 * response yet. Add the mbuf to the list, dropping
787 * the oldest packet if we have exceeded the system 791 * the oldest packet if we have exceeded the system
788 * setting. 792 * setting.
789 */ 793 */
790 LLE_WLOCK_ASSERT(la); 794 LLE_WLOCK_ASSERT(la);
791 if (la->la_numheld >= arp_maxhold) { 795 if (la->la_numheld >= arp_maxhold) {
792 if (la->la_hold != NULL) { 796 if (la->la_hold != NULL) {
793 struct mbuf *next = la->la_hold->m_nextpkt; 797 struct mbuf *next = la->la_hold->m_nextpkt;
794 m_freem(la->la_hold); 798 m_freem(la->la_hold);
795 la->la_hold = next; 799 la->la_hold = next;
796 la->la_numheld--; 800 la->la_numheld--;
797 ARP_STATINC(ARP_STAT_DFRDROPPED); 801 ARP_STATINC(ARP_STAT_DFRDROPPED);
798 ARP_STATINC(ARP_STAT_DFRTOTAL); 802 ARP_STATINC(ARP_STAT_DFRTOTAL);
799 } 803 }
800 } 804 }
801 if (la->la_hold != NULL) { 805 if (la->la_hold != NULL) {
802 struct mbuf *curr = la->la_hold; 806 struct mbuf *curr = la->la_hold;
803 while (curr->m_nextpkt != NULL) 807 while (curr->m_nextpkt != NULL)
804 curr = curr->m_nextpkt; 808 curr = curr->m_nextpkt;
805 curr->m_nextpkt = m; 809 curr->m_nextpkt = m;
806 } else 810 } else
807 la->la_hold = m; 811 la->la_hold = m;
808 la->la_numheld++; 812 la->la_numheld++;
809 if (!renew) 813 if (!renew)
810 LLE_DOWNGRADE(la); 814 LLE_DOWNGRADE(la);
811 815
812 /* 816 /*
813 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It 817 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It
814 * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH 818 * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH
815 * if we have already sent arp_maxtries ARP requests. Retransmit the 819 * if we have already sent arp_maxtries ARP requests. Retransmit the
816 * ARP request, but not faster than one request per second. 820 * ARP request, but not faster than one request per second.
817 */ 821 */
818 if (la->la_asked < arp_maxtries) 822 if (la->la_asked < arp_maxtries)
819 error = EWOULDBLOCK; /* First request. */ 823 error = EWOULDBLOCK; /* First request. */
820 else 824 else
821 error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ? 825 error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ?
822 EHOSTUNREACH : EHOSTDOWN; 826 EHOSTUNREACH : EHOSTDOWN;
823 827
824 if (renew) { 828 if (renew) {
825 const uint8_t *enaddr = CLLADDR(ifp->if_sadl); 829 const uint8_t *enaddr = CLLADDR(ifp->if_sadl);
826 struct sockaddr_in sin; 830 struct sockaddr_in sin;
827 831
828 la->la_expire = time_uptime; 832 la->la_expire = time_uptime;
829 arp_settimer(la, arpt_down); 833 arp_settimer(la, arpt_down);
830 la->la_asked++; 834 la->la_asked++;
831 835
832 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); 836 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0);
833 if (error != EWOULDBLOCK) 837 if (error != EWOULDBLOCK)
834 rt_clonedmsg(RTM_MISS, sintosa(&sin), NULL, ifp); 838 rt_clonedmsg(RTM_MISS, sintosa(&sin), NULL, ifp);
835 839
836 LLE_WUNLOCK(la); 840 LLE_WUNLOCK(la);
837 841
838 if (rt != NULL) { 842 if (rt != NULL) {
839 arprequest(origifp, 843 arprequest(origifp,
840 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 844 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
841 &satocsin(dst)->sin_addr, enaddr); 845 &satocsin(dst)->sin_addr, enaddr);
842 } else { 846 } else {
843 struct rtentry *_rt; 847 struct rtentry *_rt;
844 848
845 /* XXX */ 849 /* XXX */
846 _rt = rtalloc1((struct sockaddr *)&sin, 0); 850 _rt = rtalloc1((struct sockaddr *)&sin, 0);
847 if (_rt == NULL) 851 if (_rt == NULL)
848 goto bad; 852 goto bad;
849 arprequest(origifp, 853 arprequest(origifp,
850 &satocsin(_rt->rt_ifa->ifa_addr)->sin_addr, 854 &satocsin(_rt->rt_ifa->ifa_addr)->sin_addr,
851 &satocsin(dst)->sin_addr, enaddr); 855 &satocsin(dst)->sin_addr, enaddr);
852 rt_unref(_rt); 856 rt_unref(_rt);
853 } 857 }
854 return error; 858 return error;
855 } 859 }
856 860
857 LLE_RUNLOCK(la); 861 LLE_RUNLOCK(la);
858 return error; 862 return error;
859 863
860bad: 864bad:
861 m_freem(m); 865 m_freem(m);
862 return error; 866 return error;
863} 867}
864 868
865/* 869/*
866 * Common length and type checks are done here, 870 * Common length and type checks are done here,
867 * then the protocol-specific routine is called. 871 * then the protocol-specific routine is called.
868 */ 872 */
869void 873void
870arpintr(void) 874arpintr(void)
871{ 875{
872 struct mbuf *m; 876 struct mbuf *m;
873 struct arphdr *ar; 877 struct arphdr *ar;
874 int s; 878 int s;
875 int arplen; 879 int arplen;
876 880
877 SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE(); 881 SOFTNET_KERNEL_LOCK_UNLESS_NET_MPSAFE();
878 for (;;) { 882 for (;;) {
879 struct ifnet *rcvif; 883 struct ifnet *rcvif;
880 884
881 IFQ_LOCK(&arpintrq); 885 IFQ_LOCK(&arpintrq);
882 IF_DEQUEUE(&arpintrq, m); 886 IF_DEQUEUE(&arpintrq, m);
883 IFQ_UNLOCK(&arpintrq); 887 IFQ_UNLOCK(&arpintrq);
884 if (m == NULL) 888 if (m == NULL)
885 goto out; 889 goto out;
886 if ((m->m_flags & M_PKTHDR) == 0) 890 if ((m->m_flags & M_PKTHDR) == 0)
887 panic("arpintr"); 891 panic("arpintr");
888 892
889 MCLAIM(m, &arpdomain.dom_mowner); 893 MCLAIM(m, &arpdomain.dom_mowner);
890 ARP_STATINC(ARP_STAT_RCVTOTAL); 894 ARP_STATINC(ARP_STAT_RCVTOTAL);
891 895
892 arplen = sizeof(struct arphdr); 896 arplen = sizeof(struct arphdr);
893 if (m->m_len < arplen && (m = m_pullup(m, arplen)) == NULL) 897 if (m->m_len < arplen && (m = m_pullup(m, arplen)) == NULL)
894 goto badlen; 898 goto badlen;
895 ar = mtod(m, struct arphdr *); 899 ar = mtod(m, struct arphdr *);
896 900
897 rcvif = m_get_rcvif(m, &s); 901 rcvif = m_get_rcvif(m, &s);
898 if (__predict_false(rcvif == NULL)) { 902 if (__predict_false(rcvif == NULL)) {
899 ARP_STATINC(ARP_STAT_RCVNOINT); 903 ARP_STATINC(ARP_STAT_RCVNOINT);
900 goto free; 904 goto free;
901 } 905 }
902 906
903 /* 907 /*
904 * We don't want non-IEEE1394 ARP packets on IEEE1394 908 * We don't want non-IEEE1394 ARP packets on IEEE1394
905 * interfaces, and vice versa. Our life depends on that. 909 * interfaces, and vice versa. Our life depends on that.
906 */ 910 */
907 switch (rcvif->if_type) { 911 switch (rcvif->if_type) {
908 case IFT_IEEE1394: 912 case IFT_IEEE1394:
909 if (ntohs(ar->ar_hrd) != ARPHRD_IEEE1394) { 913 if (ntohs(ar->ar_hrd) != ARPHRD_IEEE1394) {
910 m_put_rcvif(rcvif, &s); 914 m_put_rcvif(rcvif, &s);
911 ARP_STATINC(ARP_STAT_RCVBADPROTO); 915 ARP_STATINC(ARP_STAT_RCVBADPROTO);
912 goto free; 916 goto free;
913 } 917 }
914 918
915 arplen = sizeof(struct arphdr) + 919 arplen = sizeof(struct arphdr) +
916 ar->ar_hln + 2 * ar->ar_pln; 920 ar->ar_hln + 2 * ar->ar_pln;
917 break; 921 break;
918 default: 922 default:
919 if (ntohs(ar->ar_hrd) == ARPHRD_IEEE1394) { 923 if (ntohs(ar->ar_hrd) == ARPHRD_IEEE1394) {
920 m_put_rcvif(rcvif, &s); 924 m_put_rcvif(rcvif, &s);
921 ARP_STATINC(ARP_STAT_RCVBADPROTO); 925 ARP_STATINC(ARP_STAT_RCVBADPROTO);
922 goto free; 926 goto free;
923 } 927 }
924 928
925 arplen = sizeof(struct arphdr) + 929 arplen = sizeof(struct arphdr) +
926 2 * ar->ar_hln + 2 * ar->ar_pln; 930 2 * ar->ar_hln + 2 * ar->ar_pln;
927 break; 931 break;
928 } 932 }
929 933
930 m_put_rcvif(rcvif, &s); 934 m_put_rcvif(rcvif, &s);
931 935
932 if (m->m_len < arplen && (m = m_pullup(m, arplen)) == NULL) 936 if (m->m_len < arplen && (m = m_pullup(m, arplen)) == NULL)
933 goto badlen; 937 goto badlen;
934 ar = mtod(m, struct arphdr *); 938 ar = mtod(m, struct arphdr *);
935 939
936 switch (ntohs(ar->ar_pro)) { 940 switch (ntohs(ar->ar_pro)) {
937 case ETHERTYPE_IP: 941 case ETHERTYPE_IP:
938 case ETHERTYPE_IPTRAILERS: 942 case ETHERTYPE_IPTRAILERS:
939 in_arpinput(m); 943 in_arpinput(m);
940 continue; 944 continue;
941 default: 945 default:
942 ARP_STATINC(ARP_STAT_RCVBADPROTO); 946 ARP_STATINC(ARP_STAT_RCVBADPROTO);
943 goto free; 947 goto free;
944 } 948 }
945 949
946badlen: 950badlen:
947 ARP_STATINC(ARP_STAT_RCVBADLEN); 951 ARP_STATINC(ARP_STAT_RCVBADLEN);
948free: 952free:
949 m_freem(m); 953 m_freem(m);
950 } 954 }
951 955
952out: 956out:
953 SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE(); 957 SOFTNET_KERNEL_UNLOCK_UNLESS_NET_MPSAFE();
954 return; /* XXX gcc */ 958 return; /* XXX gcc */
955} 959}
956 960
957/* 961/*
958 * ARP for Internet protocols on 10 Mb/s Ethernet. Algorithm is that given in 962 * ARP for Internet protocols on 10 Mb/s Ethernet. Algorithm is that given in
959 * RFC 826. In addition, a sanity check is performed on the sender protocol 963 * RFC 826. In addition, a sanity check is performed on the sender protocol
960 * address, to catch impersonators. 964 * address, to catch impersonators.
961 * 965 *
962 * We no longer handle negotiations for use of trailer protocol: formerly, ARP 966 * We no longer handle negotiations for use of trailer protocol: formerly, ARP
963 * replied for protocol type ETHERTYPE_TRAIL sent along with IP replies if we 967 * replied for protocol type ETHERTYPE_TRAIL sent along with IP replies if we
964 * wanted trailers sent to us, and also sent them in response to IP replies. 968 * wanted trailers sent to us, and also sent them in response to IP replies.
965 * This allowed either end to announce the desire to receive trailer packets. 969 * This allowed either end to announce the desire to receive trailer packets.
966 * 970 *
967 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, but 971 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, but
968 * formerly didn't normally send requests. 972 * formerly didn't normally send requests.
969 */ 973 */
970static void 974static void
971in_arpinput(struct mbuf *m) 975in_arpinput(struct mbuf *m)
972{ 976{
973 struct arphdr *ah; 977 struct arphdr *ah;
974 struct ifnet *ifp, *rcvif = NULL; 978 struct ifnet *ifp, *rcvif = NULL;
975 struct llentry *la = NULL; 979 struct llentry *la = NULL;
976 struct in_ifaddr *ia = NULL; 980 struct in_ifaddr *ia = NULL;
977#if NBRIDGE > 0 981#if NBRIDGE > 0
978 struct in_ifaddr *bridge_ia = NULL; 982 struct in_ifaddr *bridge_ia = NULL;
979#endif 983#endif
980#if NCARP > 0 984#if NCARP > 0
981 uint32_t count = 0, index = 0; 985 uint32_t count = 0, index = 0;
982#endif 986#endif
983 struct sockaddr sa; 987 struct sockaddr sa;
984 struct in_addr isaddr, itaddr, myaddr; 988 struct in_addr isaddr, itaddr, myaddr;
985 int op, rt_cmd; 989 int op, rt_cmd;
986 void *tha; 990 void *tha;
987 uint64_t *arps; 991 uint64_t *arps;
988 struct psref psref, psref_ia; 992 struct psref psref, psref_ia;
989 int s; 993 int s;
990 char ipbuf[INET_ADDRSTRLEN]; 994 char ipbuf[INET_ADDRSTRLEN];
991 bool find_source, do_dad; 995 bool find_source, do_dad;
992 996
993 if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT))) 997 if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
994 goto out; 998 goto out;
995 ah = mtod(m, struct arphdr *); 999 ah = mtod(m, struct arphdr *);
996 op = ntohs(ah->ar_op); 1000 op = ntohs(ah->ar_op);
997 1001
998 if (ah->ar_pln != sizeof(struct in_addr)) 1002 if (ah->ar_pln != sizeof(struct in_addr))
999 goto out; 1003 goto out;
1000 1004
1001 ifp = if_get_bylla(ar_sha(ah), ah->ar_hln, &psref); 1005 ifp = if_get_bylla(ar_sha(ah), ah->ar_hln, &psref);
1002 if (ifp) { 1006 if (ifp) {
1003 /* it's from me, ignore it. */ 1007 /* it's from me, ignore it. */
1004 if_put(ifp, &psref); 1008 if_put(ifp, &psref);
1005 ARP_STATINC(ARP_STAT_RCVLOCALSHA); 1009 ARP_STATINC(ARP_STAT_RCVLOCALSHA);
1006 goto out; 1010 goto out;
1007 } 1011 }
1008 1012
1009 rcvif = ifp = m_get_rcvif_psref(m, &psref); 1013 rcvif = ifp = m_get_rcvif_psref(m, &psref);
1010 if (__predict_false(rcvif == NULL)) 1014 if (__predict_false(rcvif == NULL))
1011 goto out; 1015 goto out;
1012 if (rcvif->if_flags & IFF_NOARP) 1016 if (rcvif->if_flags & IFF_NOARP)
1013 goto out; 1017 goto out;
1014 1018
1015 memcpy(&isaddr, ar_spa(ah), sizeof(isaddr)); 1019 memcpy(&isaddr, ar_spa(ah), sizeof(isaddr));
1016 memcpy(&itaddr, ar_tpa(ah), sizeof(itaddr)); 1020 memcpy(&itaddr, ar_tpa(ah), sizeof(itaddr));
1017 1021
1018 if (m->m_flags & (M_BCAST|M_MCAST)) 1022 if (m->m_flags & (M_BCAST|M_MCAST))
1019 ARP_STATINC(ARP_STAT_RCVMCAST); 1023 ARP_STATINC(ARP_STAT_RCVMCAST);
1020 1024
1021 /* 1025 /*
1022 * Search for a matching interface address 1026 * Search for a matching interface address
1023 * or any address on the interface to use 1027 * or any address on the interface to use
1024 * as a dummy address in the rest of this function. 1028 * as a dummy address in the rest of this function.
1025 * 1029 *
1026 * First try and find the source address for early 1030 * First try and find the source address for early
1027 * duplicate address detection. 1031 * duplicate address detection.
1028 */ 1032 */
1029 if (in_nullhost(isaddr)) { 1033 if (in_nullhost(isaddr)) {
1030 if (in_nullhost(itaddr)) /* very bogus ARP */ 1034 if (in_nullhost(itaddr)) /* very bogus ARP */
1031 goto out; 1035 goto out;
1032 find_source = false; 1036 find_source = false;
1033 myaddr = itaddr; 1037 myaddr = itaddr;
1034 } else { 1038 } else {
1035 find_source = true; 1039 find_source = true;
1036 myaddr = isaddr; 1040 myaddr = isaddr;
1037 } 1041 }
1038 s = pserialize_read_enter(); 1042 s = pserialize_read_enter();
1039again: 1043again:
1040 IN_ADDRHASH_READER_FOREACH(ia, myaddr.s_addr) { 1044 IN_ADDRHASH_READER_FOREACH(ia, myaddr.s_addr) {
1041 if (!in_hosteq(ia->ia_addr.sin_addr, myaddr)) 1045 if (!in_hosteq(ia->ia_addr.sin_addr, myaddr))
1042 continue; 1046 continue;
1043#if NCARP > 0 1047#if NCARP > 0
1044 if (ia->ia_ifp->if_type == IFT_CARP && 1048 if (ia->ia_ifp->if_type == IFT_CARP &&
1045 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) == 1049 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
1046 (IFF_UP|IFF_RUNNING))) { 1050 (IFF_UP|IFF_RUNNING))) {
1047 index++; 1051 index++;
1048 /* XXX: ar_hln? */ 1052 /* XXX: ar_hln? */
1049 if (ia->ia_ifp == rcvif && (ah->ar_hln >= 6) && 1053 if (ia->ia_ifp == rcvif && (ah->ar_hln >= 6) &&
1050 carp_iamatch(ia, ar_sha(ah), 1054 carp_iamatch(ia, ar_sha(ah),
1051 &count, index)) { 1055 &count, index)) {
1052 break; 1056 break;
1053 } 1057 }
1054 } else 1058 } else
1055#endif 1059#endif
1056 if (ia->ia_ifp == rcvif) 1060 if (ia->ia_ifp == rcvif)
1057 break; 1061 break;
1058#if NBRIDGE > 0 1062#if NBRIDGE > 0
1059 /* 1063 /*
1060 * If the interface we received the packet on 1064 * If the interface we received the packet on
1061 * is part of a bridge, check to see if we need 1065 * is part of a bridge, check to see if we need
1062 * to "bridge" the packet to ourselves at this 1066 * to "bridge" the packet to ourselves at this
1063 * layer. Note we still prefer a perfect match, 1067 * layer. Note we still prefer a perfect match,
1064 * but allow this weaker match if necessary. 1068 * but allow this weaker match if necessary.
1065 */ 1069 */
1066 if (rcvif->if_bridge != NULL && 1070 if (rcvif->if_bridge != NULL &&
1067 rcvif->if_bridge == ia->ia_ifp->if_bridge) 1071 rcvif->if_bridge == ia->ia_ifp->if_bridge)
1068 bridge_ia = ia; 1072 bridge_ia = ia;
1069#endif 1073#endif
1070 } 1074 }
1071 1075
1072#if NBRIDGE > 0 1076#if NBRIDGE > 0
1073 if (ia == NULL && bridge_ia != NULL) { 1077 if (ia == NULL && bridge_ia != NULL) {
1074 ia = bridge_ia; 1078 ia = bridge_ia;
1075 m_put_rcvif_psref(rcvif, &psref); 1079 m_put_rcvif_psref(rcvif, &psref);
1076 rcvif = NULL; 1080 rcvif = NULL;
1077 /* FIXME */ 1081 /* FIXME */
1078 ifp = bridge_ia->ia_ifp; 1082 ifp = bridge_ia->ia_ifp;
1079 } 1083 }
1080#endif 1084#endif
1081 1085
1082 /* If we failed to find the source address then find 1086 /* If we failed to find the source address then find
1083 * the target address. */ 1087 * the target address. */
1084 if (ia == NULL && find_source && !in_nullhost(itaddr)) { 1088 if (ia == NULL && find_source && !in_nullhost(itaddr)) {
1085 find_source = false; 1089 find_source = false;
1086 myaddr = itaddr; 1090 myaddr = itaddr;
1087 goto again; 1091 goto again;
1088 } 1092 }
1089 1093
1090 if (ia != NULL) 1094 if (ia != NULL)
1091 ia4_acquire(ia, &psref_ia); 1095 ia4_acquire(ia, &psref_ia);
1092 pserialize_read_exit(s); 1096 pserialize_read_exit(s);
1093 1097
1094 if (ah->ar_hln != ifp->if_addrlen) { 1098 if (ah->ar_hln != ifp->if_addrlen) {
1095 ARP_STATINC(ARP_STAT_RCVBADLEN); 1099 ARP_STATINC(ARP_STAT_RCVBADLEN);
1096 log(LOG_WARNING, 1100 log(LOG_WARNING,
1097 "arp from %s: addr len: new %d, i/f %d (ignored)\n", 1101 "arp from %s: addr len: new %d, i/f %d (ignored)\n",
1098 IN_PRINT(ipbuf, &isaddr), ah->ar_hln, ifp->if_addrlen); 1102 IN_PRINT(ipbuf, &isaddr), ah->ar_hln, ifp->if_addrlen);
1099 goto out; 1103 goto out;
1100 } 1104 }
1101 1105
1102 /* Only do DaD if we have a matching address. */ 1106 /* Only do DaD if we have a matching address. */
1103 do_dad = (ia != NULL); 1107 do_dad = (ia != NULL);
1104 1108
1105 if (ia == NULL) { 1109 if (ia == NULL) {
1106 ia = in_get_ia_on_iface_psref(isaddr, rcvif, &psref_ia); 1110 ia = in_get_ia_on_iface_psref(isaddr, rcvif, &psref_ia);
1107 if (ia == NULL) { 1111 if (ia == NULL) {
1108 ia = in_get_ia_from_ifp_psref(ifp, &psref_ia); 1112 ia = in_get_ia_from_ifp_psref(ifp, &psref_ia);
1109 if (ia == NULL) { 1113 if (ia == NULL) {
1110 ARP_STATINC(ARP_STAT_RCVNOINT); 1114 ARP_STATINC(ARP_STAT_RCVNOINT);
1111 goto out; 1115 goto out;
1112 } 1116 }
1113 } 1117 }
1114 } 1118 }
1115 1119
1116 myaddr = ia->ia_addr.sin_addr; 1120 myaddr = ia->ia_addr.sin_addr;
1117 1121
1118 /* XXX checks for bridge case? */ 1122 /* XXX checks for bridge case? */
1119 if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) { 1123 if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
1120 ARP_STATINC(ARP_STAT_RCVBCASTSHA); 1124 ARP_STATINC(ARP_STAT_RCVBCASTSHA);
1121 log(LOG_ERR, 1125 log(LOG_ERR,
1122 "%s: arp: link address is broadcast for IP address %s!\n", 1126 "%s: arp: link address is broadcast for IP address %s!\n",
1123 ifp->if_xname, IN_PRINT(ipbuf, &isaddr)); 1127 ifp->if_xname, IN_PRINT(ipbuf, &isaddr));
1124 goto out; 1128 goto out;
1125 } 1129 }
1126 1130
1127 /* 1131 /*
1128 * If the source IP address is zero, this is an RFC 5227 ARP probe 1132 * If the source IP address is zero, this is an RFC 5227 ARP probe
1129 */ 1133 */
1130 if (in_nullhost(isaddr)) 1134 if (in_nullhost(isaddr))
1131 ARP_STATINC(ARP_STAT_RCVZEROSPA); 1135 ARP_STATINC(ARP_STAT_RCVZEROSPA);
1132 else if (in_hosteq(isaddr, myaddr)) 1136 else if (in_hosteq(isaddr, myaddr))
1133 ARP_STATINC(ARP_STAT_RCVLOCALSPA); 1137 ARP_STATINC(ARP_STAT_RCVLOCALSPA);
1134 1138
1135 if (in_nullhost(itaddr)) 1139 if (in_nullhost(itaddr))
1136 ARP_STATINC(ARP_STAT_RCVZEROTPA); 1140 ARP_STATINC(ARP_STAT_RCVZEROTPA);
1137 1141
1138 /* 1142 /*
1139 * DAD check, RFC 5227. 1143 * DAD check, RFC 5227.
1140 * Collision on sender address is always a duplicate. 1144 * Collision on sender address is always a duplicate.
1141 * Collision on target address is only a duplicate 1145 * Collision on target address is only a duplicate
1142 * IF the sender address is the null host (ie a DAD probe) 1146 * IF the sender address is the null host (ie a DAD probe)
1143 * AND the message was broadcast 1147 * AND the message was broadcast
1144 * AND our address is either tentative or duplicated 1148 * AND our address is either tentative or duplicated
1145 * If it was unicast then it's a valid Unicast Poll from RFC 1122. 1149 * If it was unicast then it's a valid Unicast Poll from RFC 1122.
1146 */ 1150 */
1147 if (do_dad && 1151 if (do_dad &&
1148 (in_hosteq(isaddr, myaddr) || 1152 (in_hosteq(isaddr, myaddr) ||
1149 (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr) && 1153 (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr) &&
1150 m->m_flags & M_BCAST && 1154 m->m_flags & M_BCAST &&
1151 ia->ia4_flags & (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED)))) 1155 ia->ia4_flags & (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED))))
1152 { 1156 {
1153 struct sockaddr_dl sdl, *sdlp; 1157 struct sockaddr_dl sdl, *sdlp;
1154 1158
1155 sdlp = sockaddr_dl_init(&sdl, sizeof(sdl), 1159 sdlp = sockaddr_dl_init(&sdl, sizeof(sdl),
1156 ifp->if_index, ifp->if_type, 1160 ifp->if_index, ifp->if_type,
1157 NULL, 0, ar_sha(ah), ah->ar_hln); 1161 NULL, 0, ar_sha(ah), ah->ar_hln);
1158 arp_dad_duplicated((struct ifaddr *)ia, sdlp); 1162 arp_dad_duplicated((struct ifaddr *)ia, sdlp);
1159 goto out; 1163 goto out;
1160 } 1164 }
1161 1165
1162 /* 1166 /*
1163 * If the target IP address is zero, ignore the packet. 1167 * If the target IP address is zero, ignore the packet.
1164 * This prevents the code below from trying to answer 1168 * This prevents the code below from trying to answer
1165 * when we are using IP address zero (booting). 1169 * when we are using IP address zero (booting).
1166 */ 1170 */
1167 if (in_nullhost(itaddr)) 1171 if (in_nullhost(itaddr))
1168 goto out; 1172 goto out;
1169 1173
1170 if (in_nullhost(isaddr)) 1174 if (in_nullhost(isaddr))
1171 goto reply; 1175 goto reply;
1172 1176
1173 if (in_hosteq(itaddr, myaddr)) 1177 if (in_hosteq(itaddr, myaddr))
1174 la = arpcreate(ifp, &isaddr, NULL, 1); 1178 la = arpcreate(ifp, &isaddr, NULL, 1);
1175 else 1179 else
1176 la = arplookup(ifp, &isaddr, NULL, 1); 1180 la = arplookup(ifp, &isaddr, NULL, 1);
1177 if (la == NULL) 1181 if (la == NULL)
1178 goto reply; 1182 goto reply;
1179 1183
1180 if ((la->la_flags & LLE_VALID) && 1184 if ((la->la_flags & LLE_VALID) &&
1181 memcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) 1185 memcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen))
1182 { 1186 {
1183 char llabuf[LLA_ADDRSTRLEN], *llastr; 1187 char llabuf[LLA_ADDRSTRLEN], *llastr;
1184 1188
1185 llastr = lla_snprintf(llabuf, sizeof(llabuf), 1189 llastr = lla_snprintf(llabuf, sizeof(llabuf),
1186 ar_sha(ah), ah->ar_hln); 1190 ar_sha(ah), ah->ar_hln);
1187 1191
1188 if (la->la_flags & LLE_STATIC) { 1192 if (la->la_flags & LLE_STATIC) {
1189 ARP_STATINC(ARP_STAT_RCVOVERPERM); 1193 ARP_STATINC(ARP_STAT_RCVOVERPERM);
1190 if (!log_permanent_modify) 1194 if (!log_permanent_modify)
1191 goto out; 1195 goto out;
1192 log(LOG_INFO, 1196 log(LOG_INFO,
1193 "%s tried to overwrite permanent arp info" 1197 "%s tried to overwrite permanent arp info"
1194 " for %s\n", llastr, IN_PRINT(ipbuf, &isaddr)); 1198 " for %s\n", llastr, IN_PRINT(ipbuf, &isaddr));
1195 goto out; 1199 goto out;
1196 } else if (la->lle_tbl->llt_ifp != ifp) { 1200 } else if (la->lle_tbl->llt_ifp != ifp) {
1197 /* XXX should not happen? */ 1201 /* XXX should not happen? */
1198 ARP_STATINC(ARP_STAT_RCVOVERINT); 1202 ARP_STATINC(ARP_STAT_RCVOVERINT);
1199 if (!log_wrong_iface) 1203 if (!log_wrong_iface)
1200 goto out; 1204 goto out;
1201 log(LOG_INFO, 1205 log(LOG_INFO,
1202 "%s on %s tried to overwrite " 1206 "%s on %s tried to overwrite "
1203 "arp info for %s on %s\n", 1207 "arp info for %s on %s\n",
1204 llastr, 1208 llastr,
1205 ifp->if_xname, IN_PRINT(ipbuf, &isaddr), 1209 ifp->if_xname, IN_PRINT(ipbuf, &isaddr),
1206 la->lle_tbl->llt_ifp->if_xname); 1210 la->lle_tbl->llt_ifp->if_xname);
1207 goto out; 1211 goto out;
1208 } else { 1212 } else {
1209 ARP_STATINC(ARP_STAT_RCVOVER); 1213 ARP_STATINC(ARP_STAT_RCVOVER);
1210 if (log_movements) 1214 if (log_movements)
1211 log(LOG_INFO, "arp info overwritten " 1215 log(LOG_INFO, "arp info overwritten "
1212 "for %s by %s\n", 1216 "for %s by %s\n",
1213 IN_PRINT(ipbuf, &isaddr), llastr); 1217 IN_PRINT(ipbuf, &isaddr), llastr);
1214 } 1218 }
1215 rt_cmd = RTM_CHANGE; 1219 rt_cmd = RTM_CHANGE;
1216 } else 1220 } else
1217 rt_cmd = la->la_flags & LLE_VALID ? 0 : RTM_ADD; 1221 rt_cmd = la->la_flags & LLE_VALID ? 0 : RTM_ADD;
1218 1222
1219 KASSERT(ifp->if_sadl->sdl_alen == ifp->if_addrlen); 1223 KASSERT(ifp->if_sadl->sdl_alen == ifp->if_addrlen);
1220 1224
1221 KASSERT(sizeof(la->ll_addr) >= ifp->if_addrlen); 1225 KASSERT(sizeof(la->ll_addr) >= ifp->if_addrlen);
1222 memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen); 1226 memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
1223 la->la_flags |= LLE_VALID; 1227 la->la_flags |= LLE_VALID;
1224 if ((la->la_flags & LLE_STATIC) == 0) { 1228 if ((la->la_flags & LLE_STATIC) == 0) {
1225 la->la_expire = time_uptime + arpt_keep; 1229 la->la_expire = time_uptime + arpt_keep;
1226 arp_settimer(la, arpt_keep); 1230 arp_settimer(la, arpt_keep);
1227 } 1231 }
1228 la->la_asked = 0; 1232 la->la_asked = 0;
1229 /* rt->rt_flags &= ~RTF_REJECT; */ 1233 /* rt->rt_flags &= ~RTF_REJECT; */
1230 1234
1231 if (rt_cmd != 0) { 1235 if (rt_cmd != 0) {
1232 struct sockaddr_in sin; 1236 struct sockaddr_in sin;
1233 1237
1234 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); 1238 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0);
1235 rt_clonedmsg(rt_cmd, sintosa(&sin), ar_sha(ah), ifp); 1239 rt_clonedmsg(rt_cmd, sintosa(&sin), ar_sha(ah), ifp);
1236 } 1240 }
1237 1241
1238 if (la->la_hold != NULL) { 1242 if (la->la_hold != NULL) {
1239 int n = la->la_numheld; 1243 int n = la->la_numheld;
1240 struct mbuf *m_hold, *m_hold_next; 1244 struct mbuf *m_hold, *m_hold_next;
1241 struct sockaddr_in sin; 1245 struct sockaddr_in sin;
1242 1246
1243 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); 1247 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0);
1244 1248
1245 m_hold = la->la_hold; 1249 m_hold = la->la_hold;
1246 la->la_hold = NULL; 1250 la->la_hold = NULL;
1247 la->la_numheld = 0; 1251 la->la_numheld = 0;
1248 /* 1252 /*
1249 * We have to unlock here because if_output would call 1253 * We have to unlock here because if_output would call
1250 * arpresolve 1254 * arpresolve
1251 */ 1255 */
1252 LLE_WUNLOCK(la); 1256 LLE_WUNLOCK(la);
1253 ARP_STATADD(ARP_STAT_DFRSENT, n); 1257 ARP_STATADD(ARP_STAT_DFRSENT, n);
1254 ARP_STATADD(ARP_STAT_DFRTOTAL, n); 1258 ARP_STATADD(ARP_STAT_DFRTOTAL, n);
1255 for (; m_hold != NULL; m_hold = m_hold_next) { 1259 for (; m_hold != NULL; m_hold = m_hold_next) {
1256 m_hold_next = m_hold->m_nextpkt; 1260 m_hold_next = m_hold->m_nextpkt;
1257 m_hold->m_nextpkt = NULL; 1261 m_hold->m_nextpkt = NULL;
1258 if_output_lock(ifp, ifp, m_hold, sintosa(&sin), NULL); 1262 if_output_lock(ifp, ifp, m_hold, sintosa(&sin), NULL);
1259 } 1263 }
1260 } else 1264 } else
1261 LLE_WUNLOCK(la); 1265 LLE_WUNLOCK(la);
1262 la = NULL; 1266 la = NULL;
1263 1267
1264reply: 1268reply:
1265 if (la != NULL) { 1269 if (la != NULL) {
1266 LLE_WUNLOCK(la); 1270 LLE_WUNLOCK(la);
1267 la = NULL; 1271 la = NULL;
1268 } 1272 }
1269 if (op != ARPOP_REQUEST) { 1273 if (op != ARPOP_REQUEST) {
1270 if (op == ARPOP_REPLY) 1274 if (op == ARPOP_REPLY)
1271 ARP_STATINC(ARP_STAT_RCVREPLY); 1275 ARP_STATINC(ARP_STAT_RCVREPLY);
1272 goto out; 1276 goto out;
1273 } 1277 }
1274 ARP_STATINC(ARP_STAT_RCVREQUEST); 1278 ARP_STATINC(ARP_STAT_RCVREQUEST);
1275 if (in_hosteq(itaddr, myaddr)) { 1279 if (in_hosteq(itaddr, myaddr)) {
1276 /* If our address is unusable, don't reply */ 1280 /* If our address is unusable, don't reply */
1277 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) 1281 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
1278 goto out; 1282 goto out;
1279 /* I am the target */ 1283 /* I am the target */
1280 tha = ar_tha(ah); 1284 tha = ar_tha(ah);
1281 if (tha) 1285 if (tha)
1282 memcpy(tha, ar_sha(ah), ah->ar_hln); 1286 memcpy(tha, ar_sha(ah), ah->ar_hln);
1283 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln); 1287 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln);
1284 } else { 1288 } else {
1285 /* Proxy ARP */ 1289 /* Proxy ARP */
1286 struct llentry *lle = NULL; 1290 struct llentry *lle = NULL;
1287 struct sockaddr_in sin; 1291 struct sockaddr_in sin;
1288 1292
1289#if NCARP > 0 1293#if NCARP > 0
1290 if (ifp->if_type == IFT_CARP) { 1294 if (ifp->if_type == IFT_CARP) {
1291 struct ifnet *_rcvif = m_get_rcvif(m, &s); 1295 struct ifnet *_rcvif = m_get_rcvif(m, &s);
1292 int iftype = 0; 1296 int iftype = 0;
1293 if (__predict_true(_rcvif != NULL)) 1297 if (__predict_true(_rcvif != NULL))
1294 iftype = _rcvif->if_type; 1298 iftype = _rcvif->if_type;
1295 m_put_rcvif(_rcvif, &s); 1299 m_put_rcvif(_rcvif, &s);
1296 if (iftype != IFT_CARP) 1300 if (iftype != IFT_CARP)
1297 goto out; 1301 goto out;
1298 } 1302 }
1299#endif 1303#endif
1300 1304
1301 tha = ar_tha(ah); 1305 tha = ar_tha(ah);
1302 1306
1303 sockaddr_in_init(&sin, &itaddr, 0); 1307 sockaddr_in_init(&sin, &itaddr, 0);
1304 1308
1305 IF_AFDATA_RLOCK(ifp); 1309 IF_AFDATA_RLOCK(ifp);
1306 lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin); 1310 lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
1307 IF_AFDATA_RUNLOCK(ifp); 1311 IF_AFDATA_RUNLOCK(ifp);
1308 1312
1309 if ((lle != NULL) && (lle->la_flags & LLE_PUB)) { 1313 if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
1310 if (tha) 1314 if (tha)
1311 memcpy(tha, ar_sha(ah), ah->ar_hln); 1315 memcpy(tha, ar_sha(ah), ah->ar_hln);
1312 memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln); 1316 memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
1313 LLE_RUNLOCK(lle); 1317 LLE_RUNLOCK(lle);
1314 } else { 1318 } else {
1315 if (lle != NULL) 1319 if (lle != NULL)
1316 LLE_RUNLOCK(lle); 1320 LLE_RUNLOCK(lle);
1317 goto out; 1321 goto out;
1318 } 1322 }
1319 } 1323 }
1320 ia4_release(ia, &psref_ia); 1324 ia4_release(ia, &psref_ia);