Wed Oct 14 11:17:57 2015 UTC ()
Save and clear the la route while we have a write lock


(roy)
diff -r1.187 -r1.188 src/sys/netinet/if_arp.c

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

--- src/sys/netinet/if_arp.c 2015/10/13 12:33:07 1.187
+++ src/sys/netinet/if_arp.c 2015/10/14 11:17:57 1.188
@@ -1,1356 +1,1358 @@ @@ -1,1356 +1,1358 @@
1/* $NetBSD: if_arp.c,v 1.187 2015/10/13 12:33:07 roy Exp $ */ 1/* $NetBSD: if_arp.c,v 1.188 2015/10/14 11:17:57 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.187 2015/10/13 12:33:07 roy Exp $"); 71__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.188 2015/10/14 11:17:57 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#endif 76#endif
77 77
78#ifdef INET 78#ifdef INET
79 79
80#include "bridge.h" 80#include "bridge.h"
81 81
82#include <sys/param.h> 82#include <sys/param.h>
83#include <sys/systm.h> 83#include <sys/systm.h>
84#include <sys/callout.h> 84#include <sys/callout.h>
85#include <sys/malloc.h> 85#include <sys/malloc.h>
86#include <sys/mbuf.h> 86#include <sys/mbuf.h>
87#include <sys/socket.h> 87#include <sys/socket.h>
88#include <sys/time.h> 88#include <sys/time.h>
89#include <sys/timetc.h> 89#include <sys/timetc.h>
90#include <sys/kernel.h> 90#include <sys/kernel.h>
91#include <sys/errno.h> 91#include <sys/errno.h>
92#include <sys/ioctl.h> 92#include <sys/ioctl.h>
93#include <sys/syslog.h> 93#include <sys/syslog.h>
94#include <sys/proc.h> 94#include <sys/proc.h>
95#include <sys/protosw.h> 95#include <sys/protosw.h>
96#include <sys/domain.h> 96#include <sys/domain.h>
97#include <sys/sysctl.h> 97#include <sys/sysctl.h>
98#include <sys/socketvar.h> 98#include <sys/socketvar.h>
99#include <sys/percpu.h> 99#include <sys/percpu.h>
100#include <sys/cprng.h> 100#include <sys/cprng.h>
101#include <sys/kmem.h> 101#include <sys/kmem.h>
102 102
103#include <net/ethertypes.h> 103#include <net/ethertypes.h>
104#include <net/if.h> 104#include <net/if.h>
105#include <net/if_dl.h> 105#include <net/if_dl.h>
106#include <net/if_token.h> 106#include <net/if_token.h>
107#include <net/if_types.h> 107#include <net/if_types.h>
108#include <net/if_ether.h> 108#include <net/if_ether.h>
109#include <net/if_llatbl.h> 109#include <net/if_llatbl.h>
110#include <net/net_osdep.h> 110#include <net/net_osdep.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 "fddi.h" 124#include "fddi.h"
125#if NFDDI > 0 125#if NFDDI > 0
126#include <net/if_fddi.h> 126#include <net/if_fddi.h>
127#endif 127#endif
128#include "token.h" 128#include "token.h"
129#include "carp.h" 129#include "carp.h"
130#if NCARP > 0 130#if NCARP > 0
131#include <netinet/ip_carp.h> 131#include <netinet/ip_carp.h>
132#endif 132#endif
133 133
134#define SIN(s) ((struct sockaddr_in *)s) 134#define SIN(s) ((struct sockaddr_in *)s)
135#define SRP(s) ((struct sockaddr_inarp *)s) 135#define SRP(s) ((struct sockaddr_inarp *)s)
136 136
137/* 137/*
138 * ARP trailer negotiation. Trailer protocol is not IP specific, 138 * ARP trailer negotiation. Trailer protocol is not IP specific,
139 * but ARP request/response use IP addresses. 139 * but ARP request/response use IP addresses.
140 */ 140 */
141#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL 141#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
142 142
143/* timer values */ 143/* timer values */
144static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ 144static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
145static int arpt_down = 20; /* once declared down, don't send for 20 secs */ 145static int arpt_down = 20; /* once declared down, don't send for 20 secs */
146static int arp_maxhold = 1; /* number of packets to hold per ARP entry */ 146static int arp_maxhold = 1; /* number of packets to hold per ARP entry */
147#define rt_expire rt_rmx.rmx_expire 147#define rt_expire rt_rmx.rmx_expire
148#define rt_pksent rt_rmx.rmx_pksent 148#define rt_pksent rt_rmx.rmx_pksent
149 149
150int ip_dad_count = PROBE_NUM; 150int ip_dad_count = PROBE_NUM;
151#ifdef ARP_DEBUG 151#ifdef ARP_DEBUG
152static int arp_debug = 1; 152static int arp_debug = 1;
153#else 153#else
154static int arp_debug = 0; 154static int arp_debug = 0;
155#endif 155#endif
156#define arplog(x) do { if (arp_debug) log x; } while (/*CONSTCOND*/ 0) 156#define arplog(x) do { if (arp_debug) log x; } while (/*CONSTCOND*/ 0)
157 157
158static void arp_init(void); 158static void arp_init(void);
159 159
160static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *, 160static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
161 const struct sockaddr *); 161 const struct sockaddr *);
162static void arptfree(struct rtentry *); 162static void arptfree(struct rtentry *);
163static void arptimer(void *); 163static void arptimer(void *);
164static struct llentry *arplookup(struct ifnet *, struct mbuf *, 164static struct llentry *arplookup(struct ifnet *, struct mbuf *,
165 const struct in_addr *, int, int, int, struct rtentry *); 165 const struct in_addr *, int, int, int, struct rtentry *);
166static void in_arpinput(struct mbuf *); 166static void in_arpinput(struct mbuf *);
167static void in_revarpinput(struct mbuf *); 167static void in_revarpinput(struct mbuf *);
168static void revarprequest(struct ifnet *); 168static void revarprequest(struct ifnet *);
169 169
170static void arp_drainstub(void); 170static void arp_drainstub(void);
171 171
172static void arp_dad_timer(struct ifaddr *); 172static void arp_dad_timer(struct ifaddr *);
173static void arp_dad_start(struct ifaddr *); 173static void arp_dad_start(struct ifaddr *);
174static void arp_dad_stop(struct ifaddr *); 174static void arp_dad_stop(struct ifaddr *);
175static void arp_dad_duplicated(struct ifaddr *); 175static void arp_dad_duplicated(struct ifaddr *);
176 176
177struct ifqueue arpintrq = { 177struct ifqueue arpintrq = {
178 .ifq_head = NULL, 178 .ifq_head = NULL,
179 .ifq_tail = NULL, 179 .ifq_tail = NULL,
180 .ifq_len = 0, 180 .ifq_len = 0,
181 .ifq_maxlen = 50, 181 .ifq_maxlen = 50,
182 .ifq_drops = 0, 182 .ifq_drops = 0,
183}; 183};
184static int arp_inuse, arp_allocated; 184static int arp_inuse, arp_allocated;
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
202#ifdef DDB 202#ifdef DDB
203static void db_print_sa(const struct sockaddr *); 203static void db_print_sa(const struct sockaddr *);
204static void db_print_ifa(struct ifaddr *); 204static void db_print_ifa(struct ifaddr *);
205static void db_print_llinfo(void *); 205static void db_print_llinfo(void *);
206static int db_show_rtentry(struct rtentry *, void *); 206static int db_show_rtentry(struct rtentry *, void *);
207#endif 207#endif
208 208
209static int arp_drainwanted; 209static int arp_drainwanted;
210 210
211static int log_movements = 1; 211static int log_movements = 1;
212static int log_permanent_modify = 1; 212static int log_permanent_modify = 1;
213static int log_wrong_iface = 1; 213static int log_wrong_iface = 1;
214static int log_unknown_network = 1; 214static int log_unknown_network = 1;
215 215
216/* 216/*
217 * this should be elsewhere. 217 * this should be elsewhere.
218 */ 218 */
219 219
220static char * 220static char *
221lla_snprintf(u_int8_t *, int); 221lla_snprintf(u_int8_t *, int);
222 222
223static char * 223static char *
224lla_snprintf(u_int8_t *adrp, int len) 224lla_snprintf(u_int8_t *adrp, int len)
225{ 225{
226#define NUMBUFS 3 226#define NUMBUFS 3
227 static char buf[NUMBUFS][16*3]; 227 static char buf[NUMBUFS][16*3];
228 static int bnum = 0; 228 static int bnum = 0;
229 229
230 int i; 230 int i;
231 char *p; 231 char *p;
232 232
233 p = buf[bnum]; 233 p = buf[bnum];
234 234
235 *p++ = hexdigits[(*adrp)>>4]; 235 *p++ = hexdigits[(*adrp)>>4];
236 *p++ = hexdigits[(*adrp++)&0xf]; 236 *p++ = hexdigits[(*adrp++)&0xf];
237 237
238 for (i=1; i<len && i<16; i++) { 238 for (i=1; i<len && i<16; i++) {
239 *p++ = ':'; 239 *p++ = ':';
240 *p++ = hexdigits[(*adrp)>>4]; 240 *p++ = hexdigits[(*adrp)>>4];
241 *p++ = hexdigits[(*adrp++)&0xf]; 241 *p++ = hexdigits[(*adrp++)&0xf];
242 } 242 }
243 243
244 *p = 0; 244 *p = 0;
245 p = buf[bnum]; 245 p = buf[bnum];
246 bnum = (bnum + 1) % NUMBUFS; 246 bnum = (bnum + 1) % NUMBUFS;
247 return p; 247 return p;
248} 248}
249 249
250DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */ 250DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */
251 251
252static void 252static void
253arp_fasttimo(void) 253arp_fasttimo(void)
254{ 254{
255 if (arp_drainwanted) { 255 if (arp_drainwanted) {
256 arp_drain(); 256 arp_drain();
257 arp_drainwanted = 0; 257 arp_drainwanted = 0;
258 } 258 }
259} 259}
260 260
261const struct protosw arpsw[] = { 261const struct protosw arpsw[] = {
262 { .pr_type = 0, 262 { .pr_type = 0,
263 .pr_domain = &arpdomain, 263 .pr_domain = &arpdomain,
264 .pr_protocol = 0, 264 .pr_protocol = 0,
265 .pr_flags = 0, 265 .pr_flags = 0,
266 .pr_input = 0, 266 .pr_input = 0,
267 .pr_output = 0, 267 .pr_output = 0,
268 .pr_ctlinput = 0, 268 .pr_ctlinput = 0,
269 .pr_ctloutput = 0, 269 .pr_ctloutput = 0,
270 .pr_usrreqs = 0, 270 .pr_usrreqs = 0,
271 .pr_init = arp_init, 271 .pr_init = arp_init,
272 .pr_fasttimo = arp_fasttimo, 272 .pr_fasttimo = arp_fasttimo,
273 .pr_slowtimo = 0, 273 .pr_slowtimo = 0,
274 .pr_drain = arp_drainstub, 274 .pr_drain = arp_drainstub,
275 } 275 }
276}; 276};
277 277
278struct domain arpdomain = { 278struct domain arpdomain = {
279 .dom_family = PF_ARP, 279 .dom_family = PF_ARP,
280 .dom_name = "arp", 280 .dom_name = "arp",
281 .dom_protosw = arpsw, 281 .dom_protosw = arpsw,
282 .dom_protoswNPROTOSW = &arpsw[__arraycount(arpsw)], 282 .dom_protoswNPROTOSW = &arpsw[__arraycount(arpsw)],
283}; 283};
284 284
285static void sysctl_net_inet_arp_setup(struct sysctllog **); 285static void sysctl_net_inet_arp_setup(struct sysctllog **);
286 286
287void 287void
288arp_init(void) 288arp_init(void)
289{ 289{
290 290
291 sysctl_net_inet_arp_setup(NULL); 291 sysctl_net_inet_arp_setup(NULL);
292 arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS); 292 arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS);
293} 293}
294 294
295static void 295static void
296arp_drainstub(void) 296arp_drainstub(void)
297{ 297{
298 arp_drainwanted = 1; 298 arp_drainwanted = 1;
299} 299}
300 300
301/* 301/*
302 * ARP protocol drain routine. Called when memory is in short supply. 302 * ARP protocol drain routine. Called when memory is in short supply.
303 * Called at splvm(); don't acquire softnet_lock as can be called from 303 * Called at splvm(); don't acquire softnet_lock as can be called from
304 * hardware interrupt handlers. 304 * hardware interrupt handlers.
305 */ 305 */
306void 306void
307arp_drain(void) 307arp_drain(void)
308{ 308{
309 309
310 lltable_drain(AF_INET); 310 lltable_drain(AF_INET);
311} 311}
312 312
313static void 313static void
314arptimer(void *arg) 314arptimer(void *arg)
315{ 315{
316 struct llentry *lle = arg; 316 struct llentry *lle = arg;
317 struct ifnet *ifp; 317 struct ifnet *ifp;
 318 struct rtentry *rt;
318 319
319 mutex_enter(softnet_lock); 320 mutex_enter(softnet_lock);
320 321
321 if (lle == NULL) 322 if (lle == NULL)
322 goto out; 323 goto out;
323 324
324 if (lle->la_flags & LLE_STATIC) 325 if (lle->la_flags & LLE_STATIC)
325 goto out; 326 goto out;
326 327
327 LLE_WLOCK(lle); 328 LLE_WLOCK(lle);
328 if (callout_pending(&lle->la_timer)) { 329 if (callout_pending(&lle->la_timer)) {
329 /* 330 /*
330 * Here we are a bit odd here in the treatment of 331 * Here we are a bit odd here in the treatment of
331 * active/pending. If the pending bit is set, it got 332 * active/pending. If the pending bit is set, it got
332 * rescheduled before I ran. The active 333 * rescheduled before I ran. The active
333 * bit we ignore, since if it was stopped 334 * bit we ignore, since if it was stopped
334 * in ll_tablefree() and was currently running 335 * in ll_tablefree() and was currently running
335 * it would have return 0 so the code would 336 * it would have return 0 so the code would
336 * not have deleted it since the callout could 337 * not have deleted it since the callout could
337 * not be stopped so we want to go through 338 * not be stopped so we want to go through
338 * with the delete here now. If the callout 339 * with the delete here now. If the callout
339 * was restarted, the pending bit will be back on and 340 * was restarted, the pending bit will be back on and
340 * we just want to bail since the callout_reset would 341 * we just want to bail since the callout_reset would
341 * return 1 and our reference would have been removed 342 * return 1 and our reference would have been removed
342 * by arpresolve() below. 343 * by arpresolve() below.
343 */ 344 */
344 LLE_WUNLOCK(lle); 345 LLE_WUNLOCK(lle);
345 goto out; 346 goto out;
346 } 347 }
347 ifp = lle->lle_tbl->llt_ifp; 348 ifp = lle->lle_tbl->llt_ifp;
 349 rt = lle->la_rt;
 350 lle->la_rt = NULL;
348 351
349 callout_stop(&lle->la_timer); 352 callout_stop(&lle->la_timer);
350 353
351 /* XXX: LOR avoidance. We still have ref on lle. */ 354 /* XXX: LOR avoidance. We still have ref on lle. */
352 LLE_WUNLOCK(lle); 355 LLE_WUNLOCK(lle);
353 356
354 if (lle->la_rt != NULL) { 357 if (rt != NULL) {
355 /* We have to call arptfree w/o IF_AFDATA_LOCK */ 358 /* We have to call arptfree w/o IF_AFDATA_LOCK */
356 arptfree(lle->la_rt); 359 arptfree(rt);
357 lle->la_rt = NULL; 
358 } 360 }
359 361
360 IF_AFDATA_LOCK(ifp); 362 IF_AFDATA_LOCK(ifp);
361 LLE_WLOCK(lle); 363 LLE_WLOCK(lle);
362 364
363 /* Guard against race with other llentry_free(). */ 365 /* Guard against race with other llentry_free(). */
364 if (lle->la_flags & LLE_LINKED) { 366 if (lle->la_flags & LLE_LINKED) {
365 size_t pkts_dropped; 367 size_t pkts_dropped;
366 368
367 LLE_REMREF(lle); 369 LLE_REMREF(lle);
368 pkts_dropped = llentry_free(lle); 370 pkts_dropped = llentry_free(lle);
369 ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped); 371 ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped);
370 } else { 372 } else {
371 LLE_FREE_LOCKED(lle); 373 LLE_FREE_LOCKED(lle);
372 } 374 }
373 375
374 IF_AFDATA_UNLOCK(ifp); 376 IF_AFDATA_UNLOCK(ifp);
375 377
376out: 378out:
377 mutex_exit(softnet_lock); 379 mutex_exit(softnet_lock);
378} 380}
379 381
380/* 382/*
381 * We set the gateway for RTF_CLONING routes to a "prototype" 383 * We set the gateway for RTF_CLONING routes to a "prototype"
382 * link-layer sockaddr whose interface type (if_type) and interface 384 * link-layer sockaddr whose interface type (if_type) and interface
383 * index (if_index) fields are prepared. 385 * index (if_index) fields are prepared.
384 */ 386 */
385static struct sockaddr * 387static struct sockaddr *
386arp_setgate(struct rtentry *rt, struct sockaddr *gate, 388arp_setgate(struct rtentry *rt, struct sockaddr *gate,
387 const struct sockaddr *netmask) 389 const struct sockaddr *netmask)
388{ 390{
389 const struct ifnet *ifp = rt->rt_ifp; 391 const struct ifnet *ifp = rt->rt_ifp;
390 uint8_t namelen = strlen(ifp->if_xname); 392 uint8_t namelen = strlen(ifp->if_xname);
391 uint8_t addrlen = ifp->if_addrlen; 393 uint8_t addrlen = ifp->if_addrlen;
392 394
393 /* 395 /*
394 * XXX: If this is a manually added route to interface 396 * XXX: If this is a manually added route to interface
395 * such as older version of routed or gated might provide, 397 * such as older version of routed or gated might provide,
396 * restore cloning bit. 398 * restore cloning bit.
397 */ 399 */
398 if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL && 400 if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL &&
399 satocsin(netmask)->sin_addr.s_addr != 0xffffffff) 401 satocsin(netmask)->sin_addr.s_addr != 0xffffffff)
400 rt->rt_flags |= RTF_CLONING; 402 rt->rt_flags |= RTF_CLONING;
401 if (rt->rt_flags & RTF_CLONING || 403 if (rt->rt_flags & RTF_CLONING ||
402 ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !rt->rt_llinfo)) 404 ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !rt->rt_llinfo))
403 { 405 {
404 union { 406 union {
405 struct sockaddr sa; 407 struct sockaddr sa;
406 struct sockaddr_storage ss; 408 struct sockaddr_storage ss;
407 struct sockaddr_dl sdl; 409 struct sockaddr_dl sdl;
408 } u; 410 } u;
409 /* 411 /*
410 * Case 1: This route should come from a route to iface. 412 * Case 1: This route should come from a route to iface.
411 */ 413 */
412 sockaddr_dl_init(&u.sdl, sizeof(u.ss), 414 sockaddr_dl_init(&u.sdl, sizeof(u.ss),
413 ifp->if_index, ifp->if_type, NULL, namelen, NULL, addrlen); 415 ifp->if_index, ifp->if_type, NULL, namelen, NULL, addrlen);
414 rt_setgate(rt, &u.sa); 416 rt_setgate(rt, &u.sa);
415 gate = rt->rt_gateway; 417 gate = rt->rt_gateway;
416 } 418 }
417 return gate; 419 return gate;
418} 420}
419 421
420/* 422/*
421 * Parallel to llc_rtrequest. 423 * Parallel to llc_rtrequest.
422 */ 424 */
423void 425void
424arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info) 426arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
425{ 427{
426 struct sockaddr *gate = rt->rt_gateway; 428 struct sockaddr *gate = rt->rt_gateway;
427 struct llentry *la = NULL; 429 struct llentry *la = NULL;
428 struct in_ifaddr *ia; 430 struct in_ifaddr *ia;
429 struct ifaddr *ifa; 431 struct ifaddr *ifa;
430 struct ifnet *ifp = rt->rt_ifp; 432 struct ifnet *ifp = rt->rt_ifp;
431 int flags = 0; 433 int flags = 0;
432 434
433 if (req == RTM_LLINFO_UPD) { 435 if (req == RTM_LLINFO_UPD) {
434 struct in_addr *in; 436 struct in_addr *in;
435 437
436 if ((ifa = info->rti_ifa) == NULL) 438 if ((ifa = info->rti_ifa) == NULL)
437 return; 439 return;
438 440
439 in = &ifatoia(ifa)->ia_addr.sin_addr; 441 in = &ifatoia(ifa)->ia_addr.sin_addr;
440 442
441 if (ifatoia(ifa)->ia4_flags & 443 if (ifatoia(ifa)->ia4_flags &
442 (IN_IFF_NOTREADY | IN_IFF_DETACHED)) 444 (IN_IFF_NOTREADY | IN_IFF_DETACHED))
443 { 445 {
444 arplog((LOG_DEBUG, "arp_request: %s not ready\n", 446 arplog((LOG_DEBUG, "arp_request: %s not ready\n",
445 in_fmtaddr(*in))); 447 in_fmtaddr(*in)));
446 return; 448 return;
447 } 449 }
448 450
449 arprequest(ifa->ifa_ifp, in, in, 451 arprequest(ifa->ifa_ifp, in, in,
450 CLLADDR(ifa->ifa_ifp->if_sadl)); 452 CLLADDR(ifa->ifa_ifp->if_sadl));
451 return; 453 return;
452 } 454 }
453 455
454 if ((rt->rt_flags & RTF_GATEWAY) != 0) { 456 if ((rt->rt_flags & RTF_GATEWAY) != 0) {
455 if (req != RTM_ADD) 457 if (req != RTM_ADD)
456 return; 458 return;
457 459
458 /* 460 /*
459 * linklayers with particular link MTU limitation. 461 * linklayers with particular link MTU limitation.
460 */ 462 */
461 switch(ifp->if_type) { 463 switch(ifp->if_type) {
462#if NFDDI > 0 464#if NFDDI > 0
463 case IFT_FDDI: 465 case IFT_FDDI:
464 if (ifp->if_mtu > FDDIIPMTU) 466 if (ifp->if_mtu > FDDIIPMTU)
465 rt->rt_rmx.rmx_mtu = FDDIIPMTU; 467 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
466 break; 468 break;
467#endif 469#endif
468#if NARCNET > 0 470#if NARCNET > 0
469 case IFT_ARCNET: 471 case IFT_ARCNET:
470 { 472 {
471 int arcipifmtu; 473 int arcipifmtu;
472 474
473 if (ifp->if_flags & IFF_LINK0) 475 if (ifp->if_flags & IFF_LINK0)
474 arcipifmtu = arc_ipmtu; 476 arcipifmtu = arc_ipmtu;
475 else 477 else
476 arcipifmtu = ARCMTU; 478 arcipifmtu = ARCMTU;
477 if (ifp->if_mtu > arcipifmtu) 479 if (ifp->if_mtu > arcipifmtu)
478 rt->rt_rmx.rmx_mtu = arcipifmtu; 480 rt->rt_rmx.rmx_mtu = arcipifmtu;
479 break; 481 break;
480 } 482 }
481#endif 483#endif
482 } 484 }
483 return; 485 return;
484 } 486 }
485 487
486 IF_AFDATA_RLOCK(ifp); 488 IF_AFDATA_RLOCK(ifp);
487 la = lla_lookup(LLTABLE(ifp), flags, rt_getkey(rt)); 489 la = lla_lookup(LLTABLE(ifp), flags, rt_getkey(rt));
488 IF_AFDATA_RUNLOCK(ifp); 490 IF_AFDATA_RUNLOCK(ifp);
489 491
490 switch (req) { 492 switch (req) {
491 case RTM_SETGATE: 493 case RTM_SETGATE:
492 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]); 494 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
493 break; 495 break;
494 case RTM_ADD: 496 case RTM_ADD:
495 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]); 497 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
496 if (rt->rt_flags & RTF_CLONING || 498 if (rt->rt_flags & RTF_CLONING ||
497 ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !la)) 499 ((rt->rt_flags & (RTF_LLINFO | RTF_LOCAL)) && !la))
498 { 500 {
499 /* 501 /*
500 * Give this route an expiration time, even though 502 * Give this route an expiration time, even though
501 * it's a "permanent" route, so that routes cloned 503 * it's a "permanent" route, so that routes cloned
502 * from it do not need their expiration time set. 504 * from it do not need their expiration time set.
503 */ 505 */
504 KASSERT(time_uptime != 0); 506 KASSERT(time_uptime != 0);
505 rt->rt_expire = time_uptime; 507 rt->rt_expire = time_uptime;
506 /* 508 /*
507 * linklayers with particular link MTU limitation. 509 * linklayers with particular link MTU limitation.
508 */ 510 */
509 switch (ifp->if_type) { 511 switch (ifp->if_type) {
510#if NFDDI > 0 512#if NFDDI > 0
511 case IFT_FDDI: 513 case IFT_FDDI:
512 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 && 514 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
513 (rt->rt_rmx.rmx_mtu > FDDIIPMTU || 515 (rt->rt_rmx.rmx_mtu > FDDIIPMTU ||
514 (rt->rt_rmx.rmx_mtu == 0 && 516 (rt->rt_rmx.rmx_mtu == 0 &&
515 ifp->if_mtu > FDDIIPMTU))) 517 ifp->if_mtu > FDDIIPMTU)))
516 rt->rt_rmx.rmx_mtu = FDDIIPMTU; 518 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
517 break; 519 break;
518#endif 520#endif
519#if NARCNET > 0 521#if NARCNET > 0
520 case IFT_ARCNET: 522 case IFT_ARCNET:
521 { 523 {
522 int arcipifmtu; 524 int arcipifmtu;
523 if (ifp->if_flags & IFF_LINK0) 525 if (ifp->if_flags & IFF_LINK0)
524 arcipifmtu = arc_ipmtu; 526 arcipifmtu = arc_ipmtu;
525 else 527 else
526 arcipifmtu = ARCMTU; 528 arcipifmtu = ARCMTU;
527 529
528 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 && 530 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
529 (rt->rt_rmx.rmx_mtu > arcipifmtu || 531 (rt->rt_rmx.rmx_mtu > arcipifmtu ||
530 (rt->rt_rmx.rmx_mtu == 0 && 532 (rt->rt_rmx.rmx_mtu == 0 &&
531 ifp->if_mtu > arcipifmtu))) 533 ifp->if_mtu > arcipifmtu)))
532 rt->rt_rmx.rmx_mtu = arcipifmtu; 534 rt->rt_rmx.rmx_mtu = arcipifmtu;
533 break; 535 break;
534 } 536 }
535#endif 537#endif
536 } 538 }
537 if (rt->rt_flags & RTF_CLONING) 539 if (rt->rt_flags & RTF_CLONING)
538 break; 540 break;
539 } 541 }
540 /* Announce a new entry if requested. */ 542 /* Announce a new entry if requested. */
541 if (rt->rt_flags & RTF_ANNOUNCE) { 543 if (rt->rt_flags & RTF_ANNOUNCE) {
542 INADDR_TO_IA(satocsin(rt_getkey(rt))->sin_addr, ia); 544 INADDR_TO_IA(satocsin(rt_getkey(rt))->sin_addr, ia);
543 while (ia && ia->ia_ifp != ifp) 545 while (ia && ia->ia_ifp != ifp)
544 NEXT_IA_WITH_SAME_ADDR(ia); 546 NEXT_IA_WITH_SAME_ADDR(ia);
545 if (ia == NULL || 547 if (ia == NULL ||
546 ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) 548 ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
547 ; 549 ;
548 else 550 else
549 arprequest(ifp, 551 arprequest(ifp,
550 &satocsin(rt_getkey(rt))->sin_addr, 552 &satocsin(rt_getkey(rt))->sin_addr,
551 &satocsin(rt_getkey(rt))->sin_addr, 553 &satocsin(rt_getkey(rt))->sin_addr,
552 CLLADDR(satocsdl(gate))); 554 CLLADDR(satocsdl(gate)));
553 } 555 }
554 /*FALLTHROUGH*/ 556 /*FALLTHROUGH*/
555 case RTM_RESOLVE: 557 case RTM_RESOLVE:
556 if (gate->sa_family != AF_LINK || 558 if (gate->sa_family != AF_LINK ||
557 gate->sa_len < sockaddr_dl_measure(0, ifp->if_addrlen)) { 559 gate->sa_len < sockaddr_dl_measure(0, ifp->if_addrlen)) {
558 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n"); 560 log(LOG_DEBUG, "arp_rtrequest: bad gateway value\n");
559 break; 561 break;
560 } 562 }
561 563
562 satosdl(gate)->sdl_type = ifp->if_type; 564 satosdl(gate)->sdl_type = ifp->if_type;
563 satosdl(gate)->sdl_index = ifp->if_index; 565 satosdl(gate)->sdl_index = ifp->if_index;
564 if (la != NULL) 566 if (la != NULL)
565 break; /* This happens on a route change */ 567 break; /* This happens on a route change */
566 568
567 /* If the route is for a broadcast address mark it as such. 569 /* If the route is for a broadcast address mark it as such.
568 * This way we can avoid an expensive call to in_broadcast() 570 * This way we can avoid an expensive call to in_broadcast()
569 * in ip_output() most of the time (because the route passed 571 * in ip_output() most of the time (because the route passed
570 * to ip_output() is almost always a host route). */ 572 * to ip_output() is almost always a host route). */
571 if (rt->rt_flags & RTF_HOST && 573 if (rt->rt_flags & RTF_HOST &&
572 !(rt->rt_flags & RTF_BROADCAST) && 574 !(rt->rt_flags & RTF_BROADCAST) &&
573 in_broadcast(satocsin(rt_getkey(rt))->sin_addr, rt->rt_ifp)) 575 in_broadcast(satocsin(rt_getkey(rt))->sin_addr, rt->rt_ifp))
574 rt->rt_flags |= RTF_BROADCAST; 576 rt->rt_flags |= RTF_BROADCAST;
575 /* There is little point in resolving the broadcast address */ 577 /* There is little point in resolving the broadcast address */
576 if (rt->rt_flags & RTF_BROADCAST) 578 if (rt->rt_flags & RTF_BROADCAST)
577 break; 579 break;
578 580
579 INADDR_TO_IA(satocsin(rt_getkey(rt))->sin_addr, ia); 581 INADDR_TO_IA(satocsin(rt_getkey(rt))->sin_addr, ia);
580 while (ia && ia->ia_ifp != ifp) 582 while (ia && ia->ia_ifp != ifp)
581 NEXT_IA_WITH_SAME_ADDR(ia); 583 NEXT_IA_WITH_SAME_ADDR(ia);
582 if (ia) { 584 if (ia) {
583 /* 585 /*
584 * This test used to be 586 * This test used to be
585 * if (lo0ifp->if_flags & IFF_UP) 587 * if (lo0ifp->if_flags & IFF_UP)
586 * It allowed local traffic to be forced through 588 * It allowed local traffic to be forced through
587 * the hardware by configuring the loopback down. 589 * the hardware by configuring the loopback down.
588 * However, it causes problems during network 590 * However, it causes problems during network
589 * configuration for boards that can't receive 591 * configuration for boards that can't receive
590 * packets they send. It is now necessary to clear 592 * packets they send. It is now necessary to clear
591 * "useloopback" and remove the route to force 593 * "useloopback" and remove the route to force
592 * traffic out to the hardware. 594 * traffic out to the hardware.
593 * 595 *
594 * In 4.4BSD, the above "if" statement checked 596 * In 4.4BSD, the above "if" statement checked
595 * rt->rt_ifa against rt_getkey(rt). It was changed 597 * rt->rt_ifa against rt_getkey(rt). It was changed
596 * to the current form so that we can provide a 598 * to the current form so that we can provide a
597 * better support for multiple IPv4 addresses on a 599 * better support for multiple IPv4 addresses on a
598 * interface. 600 * interface.
599 */ 601 */
600 rt->rt_expire = 0; 602 rt->rt_expire = 0;
601 if (sockaddr_dl_init(satosdl(gate), gate->sa_len, 603 if (sockaddr_dl_init(satosdl(gate), gate->sa_len,
602 ifp->if_index, ifp->if_type, NULL, 0, 604 ifp->if_index, ifp->if_type, NULL, 0,
603 CLLADDR(ifp->if_sadl), ifp->if_addrlen) == NULL) { 605 CLLADDR(ifp->if_sadl), ifp->if_addrlen) == NULL) {
604 panic("%s(%s): sockaddr_dl_init cannot fail", 606 panic("%s(%s): sockaddr_dl_init cannot fail",
605 __func__, ifp->if_xname); 607 __func__, ifp->if_xname);
606 } 608 }
607 if (useloopback) { 609 if (useloopback) {
608 ifp = rt->rt_ifp = lo0ifp; 610 ifp = rt->rt_ifp = lo0ifp;
609 rt->rt_rmx.rmx_mtu = 0; 611 rt->rt_rmx.rmx_mtu = 0;
610 } 612 }
611 rt->rt_flags |= RTF_LOCAL; 613 rt->rt_flags |= RTF_LOCAL;
612 /* 614 /*
613 * make sure to set rt->rt_ifa to the interface 615 * make sure to set rt->rt_ifa to the interface
614 * address we are using, otherwise we will have trouble 616 * address we are using, otherwise we will have trouble
615 * with source address selection. 617 * with source address selection.
616 */ 618 */
617 ifa = &ia->ia_ifa; 619 ifa = &ia->ia_ifa;
618 if (ifa != rt->rt_ifa) 620 if (ifa != rt->rt_ifa)
619 rt_replace_ifa(rt, ifa); 621 rt_replace_ifa(rt, ifa);
620 } 622 }
621 623
622 /* 624 /*
623 * Case 2: This route may come from cloning, or a manual route 625 * Case 2: This route may come from cloning, or a manual route
624 * add with a LL address. 626 * add with a LL address.
625 */ 627 */
626 flags = LLE_EXCLUSIVE; 628 flags = LLE_EXCLUSIVE;
627 if ((rt->rt_flags & RTF_CLONED) == 0) 629 if ((rt->rt_flags & RTF_CLONED) == 0)
628 flags |= LLE_IFADDR; 630 flags |= LLE_IFADDR;
629 631
630 IF_AFDATA_WLOCK(ifp); 632 IF_AFDATA_WLOCK(ifp);
631 la = lla_create(LLTABLE(ifp), flags, rt_getkey(rt)); 633 la = lla_create(LLTABLE(ifp), flags, rt_getkey(rt));
632 IF_AFDATA_WUNLOCK(ifp); 634 IF_AFDATA_WUNLOCK(ifp);
633 635
634 if (la == NULL) { 636 if (la == NULL) {
635 log(LOG_DEBUG, "%s: lla_create failed\n", 637 log(LOG_DEBUG, "%s: lla_create failed\n",
636 __func__); 638 __func__);
637 rt->rt_llinfo = NULL; 639 rt->rt_llinfo = NULL;
638 break; 640 break;
639 } 641 }
640 rt->rt_llinfo = la; 642 rt->rt_llinfo = la;
641 switch (ifp->if_type) { 643 switch (ifp->if_type) {
642#if NTOKEN > 0 644#if NTOKEN > 0
643 case IFT_ISO88025: 645 case IFT_ISO88025:
644 la->la_opaque = kmem_alloc(sizeof(struct token_rif), 646 la->la_opaque = kmem_alloc(sizeof(struct token_rif),
645 KM_SLEEP); 647 KM_SLEEP);
646 break; 648 break;
647#endif /* NTOKEN > 0 */ 649#endif /* NTOKEN > 0 */
648 default: 650 default:
649 break; 651 break;
650 } 652 }
651 la->la_rt = rt; 653 la->la_rt = rt;
652 rt->rt_refcnt++; 654 rt->rt_refcnt++;
653 rt->rt_flags |= RTF_LLINFO; 655 rt->rt_flags |= RTF_LLINFO;
654 arp_inuse++, arp_allocated++; 656 arp_inuse++, arp_allocated++;
655 657
656 LLE_WUNLOCK(la); 658 LLE_WUNLOCK(la);
657 la = NULL; 659 la = NULL;
658 660
659 break; 661 break;
660 662
661 case RTM_DELETE: 663 case RTM_DELETE:
662 if (la == NULL) 664 if (la == NULL)
663 break; 665 break;
664 arp_inuse--; 666 arp_inuse--;
665 rt->rt_llinfo = NULL; 667 rt->rt_llinfo = NULL;
666 rt->rt_flags &= ~RTF_LLINFO; 668 rt->rt_flags &= ~RTF_LLINFO;
667 669
668 LLE_RUNLOCK(la); 670 LLE_RUNLOCK(la);
669 671
670 flags |= LLE_EXCLUSIVE; 672 flags |= LLE_EXCLUSIVE;
671 IF_AFDATA_WLOCK(ifp); 673 IF_AFDATA_WLOCK(ifp);
672 674
673 la = lla_lookup(LLTABLE(ifp), flags, rt_getkey(rt)); 675 la = lla_lookup(LLTABLE(ifp), flags, rt_getkey(rt));
674 /* This shouldn't happen */ 676 /* This shouldn't happen */
675 if (la == NULL) { 677 if (la == NULL) {
676 IF_AFDATA_WUNLOCK(ifp); 678 IF_AFDATA_WUNLOCK(ifp);
677 break; 679 break;
678 } 680 }
679 681
680 if (la->la_opaque != NULL) { 682 if (la->la_opaque != NULL) {
681 switch (ifp->if_type) { 683 switch (ifp->if_type) {
682#if NTOKEN > 0 684#if NTOKEN > 0
683 case IFT_ISO88025: 685 case IFT_ISO88025:
684 kmem_free(la->la_opaque, 686 kmem_free(la->la_opaque,
685 sizeof(struct token_rif)); 687 sizeof(struct token_rif));
686 break; 688 break;
687#endif /* NTOKEN > 0 */ 689#endif /* NTOKEN > 0 */
688 default: 690 default:
689 break; 691 break;
690 } 692 }
691 } 693 }
692 694
693 if (la->la_rt != NULL) { 695 if (la->la_rt != NULL) {
694 /* 696 /*
695 * Don't rtfree (may actually free objects) here. 697 * Don't rtfree (may actually free objects) here.
696 * Leave it to rtrequest1. 698 * Leave it to rtrequest1.
697 */ 699 */
698 la->la_rt->rt_refcnt--; 700 la->la_rt->rt_refcnt--;
699 la->la_rt = NULL; 701 la->la_rt = NULL;
700 } 702 }
701 llentry_free(la); 703 llentry_free(la);
702 704
703 IF_AFDATA_WUNLOCK(ifp); 705 IF_AFDATA_WUNLOCK(ifp);
704 la = NULL; 706 la = NULL;
705 } 707 }
706 708
707 if (la != NULL) { 709 if (la != NULL) {
708 if (flags & LLE_EXCLUSIVE) 710 if (flags & LLE_EXCLUSIVE)
709 LLE_WUNLOCK(la); 711 LLE_WUNLOCK(la);
710 else 712 else
711 LLE_RUNLOCK(la); 713 LLE_RUNLOCK(la);
712 } 714 }
713} 715}
714 716
715/* 717/*
716 * Broadcast an ARP request. Caller specifies: 718 * Broadcast an ARP request. Caller specifies:
717 * - arp header source ip address 719 * - arp header source ip address
718 * - arp header target ip address 720 * - arp header target ip address
719 * - arp header source ethernet address 721 * - arp header source ethernet address
720 */ 722 */
721void 723void
722arprequest(struct ifnet *ifp, 724arprequest(struct ifnet *ifp,
723 const struct in_addr *sip, const struct in_addr *tip, 725 const struct in_addr *sip, const struct in_addr *tip,
724 const u_int8_t *enaddr) 726 const u_int8_t *enaddr)
725{ 727{
726 struct mbuf *m; 728 struct mbuf *m;
727 struct arphdr *ah; 729 struct arphdr *ah;
728 struct sockaddr sa; 730 struct sockaddr sa;
729 uint64_t *arps; 731 uint64_t *arps;
730 732
731 KASSERT(sip != NULL); 733 KASSERT(sip != NULL);
732 KASSERT(tip != NULL); 734 KASSERT(tip != NULL);
733 KASSERT(enaddr != NULL); 735 KASSERT(enaddr != NULL);
734 736
735 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 737 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
736 return; 738 return;
737 MCLAIM(m, &arpdomain.dom_mowner); 739 MCLAIM(m, &arpdomain.dom_mowner);
738 switch (ifp->if_type) { 740 switch (ifp->if_type) {
739 case IFT_IEEE1394: 741 case IFT_IEEE1394:
740 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 742 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
741 ifp->if_addrlen; 743 ifp->if_addrlen;
742 break; 744 break;
743 default: 745 default:
744 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 746 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
745 2 * ifp->if_addrlen; 747 2 * ifp->if_addrlen;
746 break; 748 break;
747 } 749 }
748 m->m_pkthdr.len = m->m_len; 750 m->m_pkthdr.len = m->m_len;
749 MH_ALIGN(m, m->m_len); 751 MH_ALIGN(m, m->m_len);
750 ah = mtod(m, struct arphdr *); 752 ah = mtod(m, struct arphdr *);
751 memset(ah, 0, m->m_len); 753 memset(ah, 0, m->m_len);
752 switch (ifp->if_type) { 754 switch (ifp->if_type) {
753 case IFT_IEEE1394: /* RFC2734 */ 755 case IFT_IEEE1394: /* RFC2734 */
754 /* fill it now for ar_tpa computation */ 756 /* fill it now for ar_tpa computation */
755 ah->ar_hrd = htons(ARPHRD_IEEE1394); 757 ah->ar_hrd = htons(ARPHRD_IEEE1394);
756 break; 758 break;
757 default: 759 default:
758 /* ifp->if_output will fill ar_hrd */ 760 /* ifp->if_output will fill ar_hrd */
759 break; 761 break;
760 } 762 }
761 ah->ar_pro = htons(ETHERTYPE_IP); 763 ah->ar_pro = htons(ETHERTYPE_IP);
762 ah->ar_hln = ifp->if_addrlen; /* hardware address length */ 764 ah->ar_hln = ifp->if_addrlen; /* hardware address length */
763 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 765 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
764 ah->ar_op = htons(ARPOP_REQUEST); 766 ah->ar_op = htons(ARPOP_REQUEST);
765 memcpy(ar_sha(ah), enaddr, ah->ar_hln); 767 memcpy(ar_sha(ah), enaddr, ah->ar_hln);
766 memcpy(ar_spa(ah), sip, ah->ar_pln); 768 memcpy(ar_spa(ah), sip, ah->ar_pln);
767 memcpy(ar_tpa(ah), tip, ah->ar_pln); 769 memcpy(ar_tpa(ah), tip, ah->ar_pln);
768 sa.sa_family = AF_ARP; 770 sa.sa_family = AF_ARP;
769 sa.sa_len = 2; 771 sa.sa_len = 2;
770 m->m_flags |= M_BCAST; 772 m->m_flags |= M_BCAST;
771 arps = ARP_STAT_GETREF(); 773 arps = ARP_STAT_GETREF();
772 arps[ARP_STAT_SNDTOTAL]++; 774 arps[ARP_STAT_SNDTOTAL]++;
773 arps[ARP_STAT_SENDREQUEST]++; 775 arps[ARP_STAT_SENDREQUEST]++;
774 ARP_STAT_PUTREF(); 776 ARP_STAT_PUTREF();
775 (*ifp->if_output)(ifp, m, &sa, NULL); 777 (*ifp->if_output)(ifp, m, &sa, NULL);
776} 778}
777 779
778/* 780/*
779 * Resolve an IP address into an ethernet address. If success, 781 * Resolve an IP address into an ethernet address. If success,
780 * desten is filled in. If there is no entry in arptab, 782 * desten is filled in. If there is no entry in arptab,
781 * set one up and broadcast a request for the IP address. 783 * set one up and broadcast a request for the IP address.
782 * Hold onto this mbuf and resend it once the address 784 * Hold onto this mbuf and resend it once the address
783 * is finally resolved. A return value of 0 indicates 785 * is finally resolved. A return value of 0 indicates
784 * that desten has been filled in and the packet should be sent 786 * that desten has been filled in and the packet should be sent
785 * normally; a return value of EWOULDBLOCK indicates that the packet has been 787 * normally; a return value of EWOULDBLOCK indicates that the packet has been
786 * held pending resolution. 788 * held pending resolution.
787 * Any other value indicates an error. 789 * Any other value indicates an error.
788 */ 790 */
789int 791int
790arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m, 792arpresolve(struct ifnet *ifp, struct rtentry *rt, struct mbuf *m,
791 const struct sockaddr *dst, u_char *desten) 793 const struct sockaddr *dst, u_char *desten)
792{ 794{
793 struct llentry *la; 795 struct llentry *la;
794 const struct sockaddr_dl *sdl; 796 const struct sockaddr_dl *sdl;
795 const char *create_lookup; 797 const char *create_lookup;
796 bool renew; 798 bool renew;
797 int error; 799 int error;
798 800
799 KASSERT(m != NULL); 801 KASSERT(m != NULL);
800 802
801 la = arplookup(ifp, m, &satocsin(dst)->sin_addr, 0, 0, 0, rt); 803 la = arplookup(ifp, m, &satocsin(dst)->sin_addr, 0, 0, 0, rt);
802 if (la == NULL || la->la_rt == NULL) 804 if (la == NULL || la->la_rt == NULL)
803 goto notfound; 805 goto notfound;
804 806
805 rt = la->la_rt; 807 rt = la->la_rt;
806 sdl = satocsdl(rt->rt_gateway); 808 sdl = satocsdl(rt->rt_gateway);
807 /* 809 /*
808 * Check the address family and length is valid, the address 810 * Check the address family and length is valid, the address
809 * is resolved; otherwise, try to resolve. 811 * is resolved; otherwise, try to resolve.
810 */ 812 */
811 if ((rt->rt_expire == 0 || rt->rt_expire > time_uptime) && 813 if ((rt->rt_expire == 0 || rt->rt_expire > time_uptime) &&
812 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) { 814 sdl->sdl_family == AF_LINK && sdl->sdl_alen != 0) {
813 memcpy(desten, CLLADDR(sdl), 815 memcpy(desten, CLLADDR(sdl),
814 min(sdl->sdl_alen, ifp->if_addrlen)); 816 min(sdl->sdl_alen, ifp->if_addrlen));
815 rt->rt_pksent = time_uptime; /* Time for last pkt sent */ 817 rt->rt_pksent = time_uptime; /* Time for last pkt sent */
816 LLE_RUNLOCK(la); 818 LLE_RUNLOCK(la);
817 return 0; 819 return 0;
818 } 820 }
819 821
820 /* 822 /*
821 * Re-send the ARP request when appropriate. 823 * Re-send the ARP request when appropriate.
822 */ 824 */
823#ifdef DIAGNOSTIC 825#ifdef DIAGNOSTIC
824 if (rt->rt_expire == 0) { 826 if (rt->rt_expire == 0) {
825 /* This should never happen. (Should it? -gwr) */ 827 /* This should never happen. (Should it? -gwr) */
826 printf("arpresolve: unresolved and rt_expire == 0\n"); 828 printf("arpresolve: unresolved and rt_expire == 0\n");
827 /* Set expiration time to now (expired). */ 829 /* Set expiration time to now (expired). */
828 rt->rt_expire = time_uptime; 830 rt->rt_expire = time_uptime;
829 } 831 }
830#endif 832#endif
831 833
832notfound: 834notfound:
833#ifdef IFF_STATICARP /* FreeBSD */ 835#ifdef IFF_STATICARP /* FreeBSD */
834#define _IFF_NOARP (IFF_NOARP | IFF_STATICARP) 836#define _IFF_NOARP (IFF_NOARP | IFF_STATICARP)
835#else 837#else
836#define _IFF_NOARP IFF_NOARP 838#define _IFF_NOARP IFF_NOARP
837#endif 839#endif
838 if (ifp->if_flags & _IFF_NOARP) { 840 if (ifp->if_flags & _IFF_NOARP) {
839 if (la != NULL) 841 if (la != NULL)
840 LLE_RUNLOCK(la); 842 LLE_RUNLOCK(la);
841 m_freem(m); 843 m_freem(m);
842 return ENOTSUP; 844 return ENOTSUP;
843 } 845 }
844#undef _IFF_NOARP 846#undef _IFF_NOARP
845 if (la == NULL) { 847 if (la == NULL) {
846 create_lookup = "create"; 848 create_lookup = "create";
847 IF_AFDATA_WLOCK(ifp); 849 IF_AFDATA_WLOCK(ifp);
848 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst); 850 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
849 IF_AFDATA_WUNLOCK(ifp); 851 IF_AFDATA_WUNLOCK(ifp);
850 if (la == NULL) 852 if (la == NULL)
851 ARP_STATINC(ARP_STAT_ALLOCFAIL); 853 ARP_STATINC(ARP_STAT_ALLOCFAIL);
852 } else if (LLE_TRY_UPGRADE(la) == 0) { 854 } else if (LLE_TRY_UPGRADE(la) == 0) {
853 create_lookup = "lookup"; 855 create_lookup = "lookup";
854 LLE_RUNLOCK(la); 856 LLE_RUNLOCK(la);
855 IF_AFDATA_RLOCK(ifp); 857 IF_AFDATA_RLOCK(ifp);
856 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst); 858 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
857 IF_AFDATA_RUNLOCK(ifp); 859 IF_AFDATA_RUNLOCK(ifp);
858 } 860 }
859 861
860 if (la == NULL) { 862 if (la == NULL) {
861 log(LOG_DEBUG, 863 log(LOG_DEBUG,
862 "%s: failed to %s llentry for %s on %s\n", 864 "%s: failed to %s llentry for %s on %s\n",
863 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr), 865 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr),
864 ifp->if_xname); 866 ifp->if_xname);
865 m_freem(m); 867 m_freem(m);
866 return EINVAL; 868 return EINVAL;
867 } 869 }
868 870
869 /* Just in case */ 871 /* Just in case */
870 if (la->la_rt == NULL) { 872 if (la->la_rt == NULL) {
871 LLE_WUNLOCK(la); 873 LLE_WUNLOCK(la);
872 log(LOG_DEBUG, 874 log(LOG_DEBUG,
873 "%s: valid llentry has no rtentry for %s on %s\n", 875 "%s: valid llentry has no rtentry for %s on %s\n",
874 __func__, inet_ntoa(satocsin(dst)->sin_addr), 876 __func__, inet_ntoa(satocsin(dst)->sin_addr),
875 ifp->if_xname); 877 ifp->if_xname);
876 m_freem(m); 878 m_freem(m);
877 return EINVAL; 879 return EINVAL;
878 } 880 }
879 rt = la->la_rt; 881 rt = la->la_rt;
880 882
881 if ((la->la_flags & LLE_VALID) && 883 if ((la->la_flags & LLE_VALID) &&
882 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) 884 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime))
883 { 885 {
884 sdl = satocsdl(rt->rt_gateway); 886 sdl = satocsdl(rt->rt_gateway);
885 memcpy(desten, CLLADDR(sdl), 887 memcpy(desten, CLLADDR(sdl),
886 min(sdl->sdl_alen, ifp->if_addrlen)); 888 min(sdl->sdl_alen, ifp->if_addrlen));
887 renew = false; 889 renew = false;
888 /* 890 /*
889 * If entry has an expiry time and it is approaching, 891 * If entry has an expiry time and it is approaching,
890 * see if we need to send an ARP request within this 892 * see if we need to send an ARP request within this
891 * arpt_down interval. 893 * arpt_down interval.
892 */ 894 */
893 if (!(la->la_flags & LLE_STATIC) && 895 if (!(la->la_flags & LLE_STATIC) &&
894 time_uptime + la->la_preempt > la->la_expire) 896 time_uptime + la->la_preempt > la->la_expire)
895 { 897 {
896 renew = true; 898 renew = true;
897 la->la_preempt--; 899 la->la_preempt--;
898 } 900 }
899 901
900 LLE_WUNLOCK(la); 902 LLE_WUNLOCK(la);
901 903
902 if (renew) { 904 if (renew) {
903 const u_int8_t *enaddr = 905 const u_int8_t *enaddr =
904#if NCARP > 0 906#if NCARP > 0
905 (rt->rt_ifp->if_type == IFT_CARP) ? 907 (rt->rt_ifp->if_type == IFT_CARP) ?
906 CLLADDR(rt->rt_ifp->if_sadl): 908 CLLADDR(rt->rt_ifp->if_sadl):
907#endif 909#endif
908 CLLADDR(ifp->if_sadl); 910 CLLADDR(ifp->if_sadl);
909 arprequest(ifp, 911 arprequest(ifp,
910 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 912 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
911 &satocsin(dst)->sin_addr, enaddr); 913 &satocsin(dst)->sin_addr, enaddr);
912 } 914 }
913 915
914 return 0; 916 return 0;
915 } 917 }
916 918
917 if (la->la_flags & LLE_STATIC) { /* should not happen! */ 919 if (la->la_flags & LLE_STATIC) { /* should not happen! */
918 log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n", 920 log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n",
919 inet_ntoa(satocsin(dst)->sin_addr)); 921 inet_ntoa(satocsin(dst)->sin_addr));
920 m_freem(m); 922 m_freem(m);
921 error = EINVAL; 923 error = EINVAL;
922 goto done; 924 goto done;
923 } 925 }
924 926
925 renew = (la->la_asked == 0 || la->la_expire != time_uptime); 927 renew = (la->la_asked == 0 || la->la_expire != time_uptime);
926 928
927 /* 929 /*
928 * There is an arptab entry, but no ethernet address 930 * There is an arptab entry, but no ethernet address
929 * response yet. Add the mbuf to the list, dropping 931 * response yet. Add the mbuf to the list, dropping
930 * the oldest packet if we have exceeded the system 932 * the oldest packet if we have exceeded the system
931 * setting. 933 * setting.
932 */ 934 */
933 LLE_WLOCK_ASSERT(la); 935 LLE_WLOCK_ASSERT(la);
934 if (la->la_numheld >= arp_maxhold) { 936 if (la->la_numheld >= arp_maxhold) {
935 if (la->la_hold != NULL) { 937 if (la->la_hold != NULL) {
936 struct mbuf *next = la->la_hold->m_nextpkt; 938 struct mbuf *next = la->la_hold->m_nextpkt;
937 m_freem(la->la_hold); 939 m_freem(la->la_hold);
938 la->la_hold = next; 940 la->la_hold = next;
939 la->la_numheld--; 941 la->la_numheld--;
940 ARP_STATINC(ARP_STAT_DFRDROPPED); 942 ARP_STATINC(ARP_STAT_DFRDROPPED);
941 } 943 }
942 } 944 }
943 if (la->la_hold != NULL) { 945 if (la->la_hold != NULL) {
944 struct mbuf *curr = la->la_hold; 946 struct mbuf *curr = la->la_hold;
945 while (curr->m_nextpkt != NULL) 947 while (curr->m_nextpkt != NULL)
946 curr = curr->m_nextpkt; 948 curr = curr->m_nextpkt;
947 curr->m_nextpkt = m; 949 curr->m_nextpkt = m;
948 } else 950 } else
949 la->la_hold = m; 951 la->la_hold = m;
950 la->la_numheld++; 952 la->la_numheld++;
951 if (!renew) 953 if (!renew)
952 LLE_DOWNGRADE(la); 954 LLE_DOWNGRADE(la);
953 955
954 /* 956 /*
955 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It 957 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It
956 * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH 958 * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH
957 * if we have already sent arp_maxtries ARP requests. Retransmit the 959 * if we have already sent arp_maxtries ARP requests. Retransmit the
958 * ARP request, but not faster than one request per second. 960 * ARP request, but not faster than one request per second.
959 */ 961 */
960 if (la->la_asked < arp_maxtries) 962 if (la->la_asked < arp_maxtries)
961 error = EWOULDBLOCK; /* First request. */ 963 error = EWOULDBLOCK; /* First request. */
962 else 964 else
963 error = (rt->rt_flags & RTF_GATEWAY) ? 965 error = (rt->rt_flags & RTF_GATEWAY) ?
964 EHOSTUNREACH : EHOSTDOWN; 966 EHOSTUNREACH : EHOSTDOWN;
965 967
966 if (renew) { 968 if (renew) {
967 const u_int8_t *enaddr = 969 const u_int8_t *enaddr =
968#if NCARP > 0 970#if NCARP > 0
969 (rt->rt_ifp->if_type == IFT_CARP) ? 971 (rt->rt_ifp->if_type == IFT_CARP) ?
970 CLLADDR(rt->rt_ifp->if_sadl): 972 CLLADDR(rt->rt_ifp->if_sadl):
971#endif 973#endif
972 CLLADDR(ifp->if_sadl); 974 CLLADDR(ifp->if_sadl);
973 LLE_ADDREF(la); 975 LLE_ADDREF(la);
974 la->la_expire = time_uptime; 976 la->la_expire = time_uptime;
975 callout_reset(&la->la_timer, hz * arpt_down, 977 callout_reset(&la->la_timer, hz * arpt_down,
976 arptimer, la); 978 arptimer, la);
977 la->la_asked++; 979 la->la_asked++;
978 LLE_WUNLOCK(la); 980 LLE_WUNLOCK(la);
979 981
980 arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 982 arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
981 &satocsin(dst)->sin_addr, enaddr); 983 &satocsin(dst)->sin_addr, enaddr);
982 return error; 984 return error;
983 } 985 }
984done: 986done:
985 LLE_RUNLOCK(la); 987 LLE_RUNLOCK(la);
986 988
987 return error; 989 return error;
988} 990}
989 991
990/* 992/*
991 * Common length and type checks are done here, 993 * Common length and type checks are done here,
992 * then the protocol-specific routine is called. 994 * then the protocol-specific routine is called.
993 */ 995 */
994void 996void
995arpintr(void) 997arpintr(void)
996{ 998{
997 struct mbuf *m; 999 struct mbuf *m;
998 struct arphdr *ar; 1000 struct arphdr *ar;
999 int s; 1001 int s;
1000 int arplen; 1002 int arplen;
1001 1003
1002 mutex_enter(softnet_lock); 1004 mutex_enter(softnet_lock);
1003 KERNEL_LOCK(1, NULL); 1005 KERNEL_LOCK(1, NULL);
1004 while (arpintrq.ifq_head) { 1006 while (arpintrq.ifq_head) {
1005 s = splnet(); 1007 s = splnet();
1006 IF_DEQUEUE(&arpintrq, m); 1008 IF_DEQUEUE(&arpintrq, m);
1007 splx(s); 1009 splx(s);
1008 if (m == NULL || (m->m_flags & M_PKTHDR) == 0) 1010 if (m == NULL || (m->m_flags & M_PKTHDR) == 0)
1009 panic("arpintr"); 1011 panic("arpintr");
1010 1012
1011 MCLAIM(m, &arpdomain.dom_mowner); 1013 MCLAIM(m, &arpdomain.dom_mowner);
1012 ARP_STATINC(ARP_STAT_RCVTOTAL); 1014 ARP_STATINC(ARP_STAT_RCVTOTAL);
1013 1015
1014 /* 1016 /*
1015 * First, make sure we have at least struct arphdr. 1017 * First, make sure we have at least struct arphdr.
1016 */ 1018 */
1017 if (m->m_len < sizeof(struct arphdr) || 1019 if (m->m_len < sizeof(struct arphdr) ||
1018 (ar = mtod(m, struct arphdr *)) == NULL) 1020 (ar = mtod(m, struct arphdr *)) == NULL)
1019 goto badlen; 1021 goto badlen;
1020 1022
1021 switch (m->m_pkthdr.rcvif->if_type) { 1023 switch (m->m_pkthdr.rcvif->if_type) {
1022 case IFT_IEEE1394: 1024 case IFT_IEEE1394:
1023 arplen = sizeof(struct arphdr) + 1025 arplen = sizeof(struct arphdr) +
1024 ar->ar_hln + 2 * ar->ar_pln; 1026 ar->ar_hln + 2 * ar->ar_pln;
1025 break; 1027 break;
1026 default: 1028 default:
1027 arplen = sizeof(struct arphdr) + 1029 arplen = sizeof(struct arphdr) +
1028 2 * ar->ar_hln + 2 * ar->ar_pln; 1030 2 * ar->ar_hln + 2 * ar->ar_pln;
1029 break; 1031 break;
1030 } 1032 }
1031 1033
1032 if (/* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */ 1034 if (/* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */
1033 m->m_len >= arplen) 1035 m->m_len >= arplen)
1034 switch (ntohs(ar->ar_pro)) { 1036 switch (ntohs(ar->ar_pro)) {
1035 case ETHERTYPE_IP: 1037 case ETHERTYPE_IP:
1036 case ETHERTYPE_IPTRAILERS: 1038 case ETHERTYPE_IPTRAILERS:
1037 in_arpinput(m); 1039 in_arpinput(m);
1038 continue; 1040 continue;
1039 default: 1041 default:
1040 ARP_STATINC(ARP_STAT_RCVBADPROTO); 1042 ARP_STATINC(ARP_STAT_RCVBADPROTO);
1041 } 1043 }
1042 else { 1044 else {
1043badlen: 1045badlen:
1044 ARP_STATINC(ARP_STAT_RCVBADLEN); 1046 ARP_STATINC(ARP_STAT_RCVBADLEN);
1045 } 1047 }
1046 m_freem(m); 1048 m_freem(m);
1047 } 1049 }
1048 KERNEL_UNLOCK_ONE(NULL); 1050 KERNEL_UNLOCK_ONE(NULL);
1049 mutex_exit(softnet_lock); 1051 mutex_exit(softnet_lock);
1050} 1052}
1051 1053
1052/* 1054/*
1053 * ARP for Internet protocols on 10 Mb/s Ethernet. 1055 * ARP for Internet protocols on 10 Mb/s Ethernet.
1054 * Algorithm is that given in RFC 826. 1056 * Algorithm is that given in RFC 826.
1055 * In addition, a sanity check is performed on the sender 1057 * In addition, a sanity check is performed on the sender
1056 * protocol address, to catch impersonators. 1058 * protocol address, to catch impersonators.
1057 * We no longer handle negotiations for use of trailer protocol: 1059 * We no longer handle negotiations for use of trailer protocol:
1058 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent 1060 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
1059 * along with IP replies if we wanted trailers sent to us, 1061 * along with IP replies if we wanted trailers sent to us,
1060 * and also sent them in response to IP replies. 1062 * and also sent them in response to IP replies.
1061 * This allowed either end to announce the desire to receive 1063 * This allowed either end to announce the desire to receive
1062 * trailer packets. 1064 * trailer packets.
1063 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, 1065 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
1064 * but formerly didn't normally send requests. 1066 * but formerly didn't normally send requests.
1065 */ 1067 */
1066static void 1068static void
1067in_arpinput(struct mbuf *m) 1069in_arpinput(struct mbuf *m)
1068{ 1070{
1069 struct arphdr *ah; 1071 struct arphdr *ah;
1070 struct ifnet *ifp = m->m_pkthdr.rcvif; 1072 struct ifnet *ifp = m->m_pkthdr.rcvif;
1071 struct llentry *la = NULL; 1073 struct llentry *la = NULL;
1072 struct rtentry *rt = NULL; 1074 struct rtentry *rt = NULL;
1073 struct in_ifaddr *ia; 1075 struct in_ifaddr *ia;
1074#if NBRIDGE > 0 1076#if NBRIDGE > 0
1075 struct in_ifaddr *bridge_ia = NULL; 1077 struct in_ifaddr *bridge_ia = NULL;
1076#endif 1078#endif
1077#if NCARP > 0 1079#if NCARP > 0
1078 u_int32_t count = 0, index = 0; 1080 u_int32_t count = 0, index = 0;
1079#endif 1081#endif
1080 struct sockaddr_dl *sdl = NULL; 1082 struct sockaddr_dl *sdl = NULL;
1081 struct sockaddr sa; 1083 struct sockaddr sa;
1082 struct in_addr isaddr, itaddr, myaddr; 1084 struct in_addr isaddr, itaddr, myaddr;
1083 int op; 1085 int op;
1084 void *tha; 1086 void *tha;
1085 uint64_t *arps; 1087 uint64_t *arps;
1086 1088
1087 if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT))) 1089 if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
1088 goto out; 1090 goto out;
1089 ah = mtod(m, struct arphdr *); 1091 ah = mtod(m, struct arphdr *);
1090 op = ntohs(ah->ar_op); 1092 op = ntohs(ah->ar_op);
1091 1093
1092 /* 1094 /*
1093 * Fix up ah->ar_hrd if necessary, before using ar_tha() or 1095 * Fix up ah->ar_hrd if necessary, before using ar_tha() or
1094 * ar_tpa(). 1096 * ar_tpa().
1095 */ 1097 */
1096 switch (ifp->if_type) { 1098 switch (ifp->if_type) {
1097 case IFT_IEEE1394: 1099 case IFT_IEEE1394:
1098 if (ntohs(ah->ar_hrd) == ARPHRD_IEEE1394) 1100 if (ntohs(ah->ar_hrd) == ARPHRD_IEEE1394)
1099 ; 1101 ;
1100 else { 1102 else {
1101 /* XXX this is to make sure we compute ar_tha right */ 1103 /* XXX this is to make sure we compute ar_tha right */
1102 /* XXX check ar_hrd more strictly? */ 1104 /* XXX check ar_hrd more strictly? */
1103 ah->ar_hrd = htons(ARPHRD_IEEE1394); 1105 ah->ar_hrd = htons(ARPHRD_IEEE1394);
1104 } 1106 }
1105 break; 1107 break;
1106 default: 1108 default:
1107 /* XXX check ar_hrd? */ 1109 /* XXX check ar_hrd? */
1108 break; 1110 break;
1109 } 1111 }
1110 1112
1111 memcpy(&isaddr, ar_spa(ah), sizeof (isaddr)); 1113 memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
1112 memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr)); 1114 memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
1113 1115
1114 if (m->m_flags & (M_BCAST|M_MCAST)) 1116 if (m->m_flags & (M_BCAST|M_MCAST))
1115 ARP_STATINC(ARP_STAT_RCVMCAST); 1117 ARP_STATINC(ARP_STAT_RCVMCAST);
1116 1118
1117 1119
1118 /* 1120 /*
1119 * Search for a matching interface address 1121 * Search for a matching interface address
1120 * or any address on the interface to use 1122 * or any address on the interface to use
1121 * as a dummy address in the rest of this function 1123 * as a dummy address in the rest of this function
1122 */ 1124 */
1123  1125
1124 INADDR_TO_IA(itaddr, ia); 1126 INADDR_TO_IA(itaddr, ia);
1125 while (ia != NULL) { 1127 while (ia != NULL) {
1126#if NCARP > 0 1128#if NCARP > 0
1127 if (ia->ia_ifp->if_type == IFT_CARP && 1129 if (ia->ia_ifp->if_type == IFT_CARP &&
1128 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) == 1130 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
1129 (IFF_UP|IFF_RUNNING))) { 1131 (IFF_UP|IFF_RUNNING))) {
1130 index++; 1132 index++;
1131 if (ia->ia_ifp == m->m_pkthdr.rcvif && 1133 if (ia->ia_ifp == m->m_pkthdr.rcvif &&
1132 carp_iamatch(ia, ar_sha(ah), 1134 carp_iamatch(ia, ar_sha(ah),
1133 &count, index)) { 1135 &count, index)) {
1134 break; 1136 break;
1135 } 1137 }
1136 } else 1138 } else
1137#endif 1139#endif
1138 if (ia->ia_ifp == m->m_pkthdr.rcvif) 1140 if (ia->ia_ifp == m->m_pkthdr.rcvif)
1139 break; 1141 break;
1140#if NBRIDGE > 0 1142#if NBRIDGE > 0
1141 /* 1143 /*
1142 * If the interface we received the packet on 1144 * If the interface we received the packet on
1143 * is part of a bridge, check to see if we need 1145 * is part of a bridge, check to see if we need
1144 * to "bridge" the packet to ourselves at this 1146 * to "bridge" the packet to ourselves at this
1145 * layer. Note we still prefer a perfect match, 1147 * layer. Note we still prefer a perfect match,
1146 * but allow this weaker match if necessary. 1148 * but allow this weaker match if necessary.
1147 */ 1149 */
1148 if (m->m_pkthdr.rcvif->if_bridge != NULL && 1150 if (m->m_pkthdr.rcvif->if_bridge != NULL &&
1149 m->m_pkthdr.rcvif->if_bridge == ia->ia_ifp->if_bridge) 1151 m->m_pkthdr.rcvif->if_bridge == ia->ia_ifp->if_bridge)
1150 bridge_ia = ia; 1152 bridge_ia = ia;
1151#endif /* NBRIDGE > 0 */ 1153#endif /* NBRIDGE > 0 */
1152 1154
1153 NEXT_IA_WITH_SAME_ADDR(ia); 1155 NEXT_IA_WITH_SAME_ADDR(ia);
1154 } 1156 }
1155 1157
1156#if NBRIDGE > 0 1158#if NBRIDGE > 0
1157 if (ia == NULL && bridge_ia != NULL) { 1159 if (ia == NULL && bridge_ia != NULL) {
1158 ia = bridge_ia; 1160 ia = bridge_ia;
1159 ifp = bridge_ia->ia_ifp; 1161 ifp = bridge_ia->ia_ifp;
1160 } 1162 }
1161#endif 1163#endif
1162 1164
1163 if (ia == NULL) { 1165 if (ia == NULL) {
1164 INADDR_TO_IA(isaddr, ia); 1166 INADDR_TO_IA(isaddr, ia);
1165 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif) 1167 while ((ia != NULL) && ia->ia_ifp != m->m_pkthdr.rcvif)
1166 NEXT_IA_WITH_SAME_ADDR(ia); 1168 NEXT_IA_WITH_SAME_ADDR(ia);
1167 1169
1168 if (ia == NULL) { 1170 if (ia == NULL) {
1169 IFP_TO_IA(ifp, ia); 1171 IFP_TO_IA(ifp, ia);
1170 if (ia == NULL) { 1172 if (ia == NULL) {
1171 ARP_STATINC(ARP_STAT_RCVNOINT); 1173 ARP_STATINC(ARP_STAT_RCVNOINT);
1172 goto out; 1174 goto out;
1173 } 1175 }
1174 } 1176 }
1175 } 1177 }
1176 1178
1177 myaddr = ia->ia_addr.sin_addr; 1179 myaddr = ia->ia_addr.sin_addr;
1178 1180
1179 /* XXX checks for bridge case? */ 1181 /* XXX checks for bridge case? */
1180 if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) { 1182 if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) {
1181 ARP_STATINC(ARP_STAT_RCVLOCALSHA); 1183 ARP_STATINC(ARP_STAT_RCVLOCALSHA);
1182 goto out; /* it's from me, ignore it. */ 1184 goto out; /* it's from me, ignore it. */
1183 } 1185 }
1184 1186
1185 /* XXX checks for bridge case? */ 1187 /* XXX checks for bridge case? */
1186 if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) { 1188 if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
1187 ARP_STATINC(ARP_STAT_RCVBCASTSHA); 1189 ARP_STATINC(ARP_STAT_RCVBCASTSHA);
1188 log(LOG_ERR, 1190 log(LOG_ERR,
1189 "%s: arp: link address is broadcast for IP address %s!\n", 1191 "%s: arp: link address is broadcast for IP address %s!\n",
1190 ifp->if_xname, in_fmtaddr(isaddr)); 1192 ifp->if_xname, in_fmtaddr(isaddr));
1191 goto out; 1193 goto out;
1192 } 1194 }
1193 1195
1194 /* 1196 /*
1195 * If the source IP address is zero, this is an RFC 5227 ARP probe 1197 * If the source IP address is zero, this is an RFC 5227 ARP probe
1196 */ 1198 */
1197 if (in_nullhost(isaddr)) 1199 if (in_nullhost(isaddr))
1198 ARP_STATINC(ARP_STAT_RCVZEROSPA); 1200 ARP_STATINC(ARP_STAT_RCVZEROSPA);
1199 else if (in_hosteq(isaddr, myaddr)) 1201 else if (in_hosteq(isaddr, myaddr))
1200 ARP_STATINC(ARP_STAT_RCVLOCALSPA); 1202 ARP_STATINC(ARP_STAT_RCVLOCALSPA);
1201 1203
1202 if (in_nullhost(itaddr)) 1204 if (in_nullhost(itaddr))
1203 ARP_STATINC(ARP_STAT_RCVZEROTPA); 1205 ARP_STATINC(ARP_STAT_RCVZEROTPA);
1204 1206
1205 /* DAD check, RFC 5227 2.1.1, Probe Details */ 1207 /* DAD check, RFC 5227 2.1.1, Probe Details */
1206 if (in_hosteq(isaddr, myaddr) || 1208 if (in_hosteq(isaddr, myaddr) ||
1207 (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr))) 1209 (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr)))
1208 { 1210 {
1209 /* If our address is tentative, mark it as duplicated */ 1211 /* If our address is tentative, mark it as duplicated */
1210 if (ia->ia4_flags & IN_IFF_TENTATIVE) 1212 if (ia->ia4_flags & IN_IFF_TENTATIVE)
1211 arp_dad_duplicated((struct ifaddr *)ia); 1213 arp_dad_duplicated((struct ifaddr *)ia);
1212 /* If our address is unuseable, don't reply */ 1214 /* If our address is unuseable, don't reply */
1213 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) 1215 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
1214 goto out; 1216 goto out;
1215 } 1217 }
1216 1218
1217 /* 1219 /*
1218 * If the target IP address is zero, ignore the packet. 1220 * If the target IP address is zero, ignore the packet.
1219 * This prevents the code below from tring to answer 1221 * This prevents the code below from tring to answer
1220 * when we are using IP address zero (booting). 1222 * when we are using IP address zero (booting).
1221 */ 1223 */
1222 if (in_nullhost(itaddr)) 1224 if (in_nullhost(itaddr))
1223 goto out; 1225 goto out;
1224 1226
1225 if (in_nullhost(isaddr)) 1227 if (in_nullhost(isaddr))
1226 goto reply; 1228 goto reply;
1227 1229
1228 if (in_hosteq(isaddr, myaddr)) { 1230 if (in_hosteq(isaddr, myaddr)) {
1229 log(LOG_ERR, 1231 log(LOG_ERR,
1230 "duplicate IP address %s sent from link address %s\n", 1232 "duplicate IP address %s sent from link address %s\n",
1231 in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln)); 1233 in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln));
1232 itaddr = myaddr; 1234 itaddr = myaddr;
1233 goto reply; 1235 goto reply;
1234 } 1236 }
1235 1237
1236 la = arplookup(ifp, m, &isaddr, in_hosteq(itaddr, myaddr), 0, 1, NULL); 1238 la = arplookup(ifp, m, &isaddr, in_hosteq(itaddr, myaddr), 0, 1, NULL);
1237 if (la != NULL) { 1239 if (la != NULL) {
1238 rt = la->la_rt; 1240 rt = la->la_rt;
1239 if (rt != NULL) 1241 if (rt != NULL)
1240 sdl = satosdl(rt->rt_gateway); 1242 sdl = satosdl(rt->rt_gateway);
1241 } 1243 }
1242 if (sdl != NULL) { 1244 if (sdl != NULL) {
1243 if (sdl->sdl_alen && 1245 if (sdl->sdl_alen &&
1244 memcmp(ar_sha(ah), CLLADDR(sdl), sdl->sdl_alen)) { 1246 memcmp(ar_sha(ah), CLLADDR(sdl), sdl->sdl_alen)) {
1245 if (rt->rt_flags & RTF_STATIC) { 1247 if (rt->rt_flags & RTF_STATIC) {
1246 ARP_STATINC(ARP_STAT_RCVOVERPERM); 1248 ARP_STATINC(ARP_STAT_RCVOVERPERM);
1247 if (!log_permanent_modify) 1249 if (!log_permanent_modify)
1248 goto out; 1250 goto out;
1249 log(LOG_INFO, 1251 log(LOG_INFO,
1250 "%s tried to overwrite permanent arp info" 1252 "%s tried to overwrite permanent arp info"
1251 " for %s\n", 1253 " for %s\n",
1252 lla_snprintf(ar_sha(ah), ah->ar_hln), 1254 lla_snprintf(ar_sha(ah), ah->ar_hln),
1253 in_fmtaddr(isaddr)); 1255 in_fmtaddr(isaddr));
1254 goto out; 1256 goto out;
1255 } else if (rt->rt_ifp != ifp) { 1257 } else if (rt->rt_ifp != ifp) {
1256 ARP_STATINC(ARP_STAT_RCVOVERINT); 1258 ARP_STATINC(ARP_STAT_RCVOVERINT);
1257 if (!log_wrong_iface) 1259 if (!log_wrong_iface)
1258 goto out; 1260 goto out;
1259 log(LOG_INFO, 1261 log(LOG_INFO,
1260 "%s on %s tried to overwrite " 1262 "%s on %s tried to overwrite "
1261 "arp info for %s on %s\n", 1263 "arp info for %s on %s\n",
1262 lla_snprintf(ar_sha(ah), ah->ar_hln), 1264 lla_snprintf(ar_sha(ah), ah->ar_hln),
1263 ifp->if_xname, in_fmtaddr(isaddr), 1265 ifp->if_xname, in_fmtaddr(isaddr),
1264 rt->rt_ifp->if_xname); 1266 rt->rt_ifp->if_xname);
1265 goto out; 1267 goto out;
1266 } else { 1268 } else {
1267 ARP_STATINC(ARP_STAT_RCVOVER); 1269 ARP_STATINC(ARP_STAT_RCVOVER);
1268 if (log_movements) 1270 if (log_movements)
1269 log(LOG_INFO, "arp info overwritten " 1271 log(LOG_INFO, "arp info overwritten "
1270 "for %s by %s\n", 1272 "for %s by %s\n",
1271 in_fmtaddr(isaddr), 1273 in_fmtaddr(isaddr),
1272 lla_snprintf(ar_sha(ah), 1274 lla_snprintf(ar_sha(ah),
1273 ah->ar_hln)); 1275 ah->ar_hln));
1274 } 1276 }
1275 } 1277 }
1276 /* 1278 /*
1277 * sanity check for the address length. 1279 * sanity check for the address length.
1278 * XXX this does not work for protocols with variable address 1280 * XXX this does not work for protocols with variable address
1279 * length. -is 1281 * length. -is
1280 */ 1282 */
1281 if (sdl->sdl_alen && 1283 if (sdl->sdl_alen &&
1282 sdl->sdl_alen != ah->ar_hln) { 1284 sdl->sdl_alen != ah->ar_hln) {
1283 ARP_STATINC(ARP_STAT_RCVLENCHG); 1285 ARP_STATINC(ARP_STAT_RCVLENCHG);
1284 log(LOG_WARNING, 1286 log(LOG_WARNING,
1285 "arp from %s: new addr len %d, was %d\n", 1287 "arp from %s: new addr len %d, was %d\n",
1286 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen); 1288 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen);
1287 } 1289 }
1288 if (ifp->if_addrlen != ah->ar_hln) { 1290 if (ifp->if_addrlen != ah->ar_hln) {
1289 ARP_STATINC(ARP_STAT_RCVBADLEN); 1291 ARP_STATINC(ARP_STAT_RCVBADLEN);
1290 log(LOG_WARNING, 1292 log(LOG_WARNING,
1291 "arp from %s: addr len: new %d, i/f %d (ignored)\n", 1293 "arp from %s: addr len: new %d, i/f %d (ignored)\n",
1292 in_fmtaddr(isaddr), ah->ar_hln, 1294 in_fmtaddr(isaddr), ah->ar_hln,
1293 ifp->if_addrlen); 1295 ifp->if_addrlen);
1294 goto reply; 1296 goto reply;
1295 } 1297 }
1296#if NTOKEN > 0 1298#if NTOKEN > 0
1297 /* 1299 /*
1298 * XXX uses m_data and assumes the complete answer including 1300 * XXX uses m_data and assumes the complete answer including
1299 * XXX token-ring headers is in the same buf 1301 * XXX token-ring headers is in the same buf
1300 */ 1302 */
1301 if (ifp->if_type == IFT_ISO88025) { 1303 if (ifp->if_type == IFT_ISO88025) {
1302 struct token_header *trh; 1304 struct token_header *trh;
1303 1305
1304 trh = (struct token_header *)M_TRHSTART(m); 1306 trh = (struct token_header *)M_TRHSTART(m);
1305 if (trh->token_shost[0] & TOKEN_RI_PRESENT) { 1307 if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
1306 struct token_rif *rif; 1308 struct token_rif *rif;
1307 size_t riflen; 1309 size_t riflen;
1308 1310
1309 rif = TOKEN_RIF(trh); 1311 rif = TOKEN_RIF(trh);
1310 riflen = (ntohs(rif->tr_rcf) & 1312 riflen = (ntohs(rif->tr_rcf) &
1311 TOKEN_RCF_LEN_MASK) >> 8; 1313 TOKEN_RCF_LEN_MASK) >> 8;
1312 1314
1313 if (riflen > 2 && 1315 if (riflen > 2 &&
1314 riflen < sizeof(struct token_rif) && 1316 riflen < sizeof(struct token_rif) &&
1315 (riflen & 1) == 0) { 1317 (riflen & 1) == 0) {
1316 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION); 1318 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION);
1317 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK); 1319 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK);
1318 memcpy(TOKEN_RIF(la), rif, riflen); 1320 memcpy(TOKEN_RIF(la), rif, riflen);
1319 } 1321 }
1320 } 1322 }
1321 } 1323 }
1322#endif /* NTOKEN > 0 */ 1324#endif /* NTOKEN > 0 */
1323 (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, ar_sha(ah), 1325 (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, ar_sha(ah),
1324 ah->ar_hln); 1326 ah->ar_hln);
1325 if (rt->rt_expire) { 1327 if (rt->rt_expire) {
1326 rt->rt_expire = time_uptime + arpt_keep; 1328 rt->rt_expire = time_uptime + arpt_keep;
1327 1329
1328 KASSERT((la->la_flags & LLE_STATIC) == 0); 1330 KASSERT((la->la_flags & LLE_STATIC) == 0);
1329 LLE_ADDREF(la); 1331 LLE_ADDREF(la);
1330 callout_reset(&la->la_timer, hz * arpt_keep, arptimer, la); 1332 callout_reset(&la->la_timer, hz * arpt_keep, arptimer, la);
1331 } 1333 }
1332 rt->rt_flags &= ~RTF_REJECT; 1334 rt->rt_flags &= ~RTF_REJECT;
1333 la->la_asked = 0; 1335 la->la_asked = 0;
1334 1336
1335 if (la->la_hold != NULL) { 1337 if (la->la_hold != NULL) {
1336 int n = la->la_numheld; 1338 int n = la->la_numheld;
1337 struct mbuf *m_hold, *m_hold_next; 1339 struct mbuf *m_hold, *m_hold_next;
1338 1340
1339 m_hold = la->la_hold; 1341 m_hold = la->la_hold;
1340 la->la_hold = NULL; 1342 la->la_hold = NULL;
1341 la->la_numheld = 0; 1343 la->la_numheld = 0;
1342 /* 1344 /*
1343 * We have to unlock here because if_output would call 1345 * We have to unlock here because if_output would call
1344 * arpresolve 1346 * arpresolve
1345 */ 1347 */
1346 LLE_WUNLOCK(la); 1348 LLE_WUNLOCK(la);
1347 ARP_STATADD(ARP_STAT_DFRSENT, n); 1349 ARP_STATADD(ARP_STAT_DFRSENT, n);
1348 for (; m_hold != NULL; m_hold = m_hold_next) { 1350 for (; m_hold != NULL; m_hold = m_hold_next) {
1349 m_hold_next = m_hold->m_nextpkt; 1351 m_hold_next = m_hold->m_nextpkt;
1350 m_hold->m_nextpkt = NULL; 1352 m_hold->m_nextpkt = NULL;
1351 (*ifp->if_output)(ifp, m_hold, rt_getkey(rt), rt); 1353 (*ifp->if_output)(ifp, m_hold, rt_getkey(rt), rt);
1352 } 1354 }
1353 } else 1355 } else
1354 LLE_WUNLOCK(la); 1356 LLE_WUNLOCK(la);
1355 la = NULL; 1357 la = NULL;
1356 } 1358 }