Tue Oct 11 13:59:31 2016 UTC ()
Implement RFC 5227 2.4 Ongoing Conflict Detection and Address Defence.

If ip_dad_count is 0, then the conflict is just logged and the address
is not marked as duplicated.


(roy)
diff -r1.229 -r1.230 src/sys/netinet/if_arp.c
diff -r1.87 -r1.88 src/sys/netinet/in_var.h

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

--- src/sys/netinet/if_arp.c 2016/10/11 12:32:30 1.229
+++ src/sys/netinet/if_arp.c 2016/10/11 13:59:30 1.230
@@ -1,2075 +1,2068 @@ @@ -1,2075 +1,2068 @@
1/* $NetBSD: if_arp.c,v 1.229 2016/10/11 12:32:30 roy Exp $ */ 1/* $NetBSD: if_arp.c,v 1.230 2016/10/11 13:59:30 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.229 2016/10/11 12:32:30 roy Exp $"); 71__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.230 2016/10/11 13:59:30 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 "arp.h" 80#include "arp.h"
81#include "bridge.h" 81#include "bridge.h"
82 82
83#include <sys/param.h> 83#include <sys/param.h>
84#include <sys/systm.h> 84#include <sys/systm.h>
85#include <sys/callout.h> 85#include <sys/callout.h>
86#include <sys/malloc.h> 86#include <sys/malloc.h>
87#include <sys/mbuf.h> 87#include <sys/mbuf.h>
88#include <sys/socket.h> 88#include <sys/socket.h>
89#include <sys/time.h> 89#include <sys/time.h>
90#include <sys/timetc.h> 90#include <sys/timetc.h>
91#include <sys/kernel.h> 91#include <sys/kernel.h>
92#include <sys/errno.h> 92#include <sys/errno.h>
93#include <sys/ioctl.h> 93#include <sys/ioctl.h>
94#include <sys/syslog.h> 94#include <sys/syslog.h>
95#include <sys/proc.h> 95#include <sys/proc.h>
96#include <sys/protosw.h> 96#include <sys/protosw.h>
97#include <sys/domain.h> 97#include <sys/domain.h>
98#include <sys/sysctl.h> 98#include <sys/sysctl.h>
99#include <sys/socketvar.h> 99#include <sys/socketvar.h>
100#include <sys/percpu.h> 100#include <sys/percpu.h>
101#include <sys/cprng.h> 101#include <sys/cprng.h>
102#include <sys/kmem.h> 102#include <sys/kmem.h>
103 103
104#include <net/ethertypes.h> 104#include <net/ethertypes.h>
105#include <net/if.h> 105#include <net/if.h>
106#include <net/if_dl.h> 106#include <net/if_dl.h>
107#include <net/if_token.h> 107#include <net/if_token.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/net_osdep.h> 111#include <net/net_osdep.h>
112#include <net/route.h> 112#include <net/route.h>
113#include <net/net_stats.h> 113#include <net/net_stats.h>
114 114
115#include <netinet/in.h> 115#include <netinet/in.h>
116#include <netinet/in_systm.h> 116#include <netinet/in_systm.h>
117#include <netinet/in_var.h> 117#include <netinet/in_var.h>
118#include <netinet/ip.h> 118#include <netinet/ip.h>
119#include <netinet/if_inarp.h> 119#include <netinet/if_inarp.h>
120 120
121#include "arcnet.h" 121#include "arcnet.h"
122#if NARCNET > 0 122#if NARCNET > 0
123#include <net/if_arc.h> 123#include <net/if_arc.h>
124#endif 124#endif
125#include "fddi.h" 125#include "fddi.h"
126#if NFDDI > 0 126#if NFDDI > 0
127#include <net/if_fddi.h> 127#include <net/if_fddi.h>
128#endif 128#endif
129#include "token.h" 129#include "token.h"
130#include "carp.h" 130#include "carp.h"
131#if NCARP > 0 131#if NCARP > 0
132#include <netinet/ip_carp.h> 132#include <netinet/ip_carp.h>
133#endif 133#endif
134 134
135#define SIN(s) ((struct sockaddr_in *)s) 135#define SIN(s) ((struct sockaddr_in *)s)
136#define SRP(s) ((struct sockaddr_inarp *)s) 136#define SRP(s) ((struct sockaddr_inarp *)s)
137 137
138/* 138/*
139 * ARP trailer negotiation. Trailer protocol is not IP specific, 139 * ARP trailer negotiation. Trailer protocol is not IP specific,
140 * but ARP request/response use IP addresses. 140 * but ARP request/response use IP addresses.
141 */ 141 */
142#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL 142#define ETHERTYPE_IPTRAILERS ETHERTYPE_TRAIL
143 143
144/* timer values */ 144/* timer values */
145static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ 145static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */
146static int arpt_down = 20; /* once declared down, don't send for 20 secs */ 146static int arpt_down = 20; /* once declared down, don't send for 20 secs */
147static int arp_maxhold = 1; /* number of packets to hold per ARP entry */ 147static int arp_maxhold = 1; /* number of packets to hold per ARP entry */
148#define rt_expire rt_rmx.rmx_expire 148#define rt_expire rt_rmx.rmx_expire
149#define rt_pksent rt_rmx.rmx_pksent 149#define rt_pksent rt_rmx.rmx_pksent
150 150
151int ip_dad_count = PROBE_NUM; 151int ip_dad_count = PROBE_NUM;
152#ifdef ARP_DEBUG 152#ifdef ARP_DEBUG
153int arp_debug = 1; 153int arp_debug = 1;
154#else 154#else
155int arp_debug = 0; 155int arp_debug = 0;
156#endif 156#endif
157 157
158static void arp_init(void); 158static void arp_init(void);
159 159
160static void arprequest(struct ifnet *, 160static void arprequest(struct ifnet *,
161 const struct in_addr *, const struct in_addr *, 161 const struct in_addr *, const struct in_addr *,
162 const u_int8_t *); 162 const u_int8_t *);
163static void arpannounce1(struct ifaddr *); 163static void arpannounce1(struct ifaddr *);
164static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *, 164static struct sockaddr *arp_setgate(struct rtentry *, struct sockaddr *,
165 const struct sockaddr *); 165 const struct sockaddr *);
166static void arptimer(void *); 166static void arptimer(void *);
167static void arp_settimer(struct llentry *, int); 167static void arp_settimer(struct llentry *, int);
168static struct llentry *arplookup(struct ifnet *, struct mbuf *, 168static struct llentry *arplookup(struct ifnet *, struct mbuf *,
169 const struct in_addr *, const struct sockaddr *, int); 169 const struct in_addr *, const struct sockaddr *, int);
170static struct llentry *arpcreate(struct ifnet *, struct mbuf *, 170static struct llentry *arpcreate(struct ifnet *, struct mbuf *,
171 const struct in_addr *, const struct sockaddr *, int); 171 const struct in_addr *, const struct sockaddr *, int);
172static void in_arpinput(struct mbuf *); 172static void in_arpinput(struct mbuf *);
173static void in_revarpinput(struct mbuf *); 173static void in_revarpinput(struct mbuf *);
174static void revarprequest(struct ifnet *); 174static void revarprequest(struct ifnet *);
175 175
176static void arp_drainstub(void); 176static void arp_drainstub(void);
177 177
178static void arp_dad_timer(struct ifaddr *); 178static void arp_dad_timer(struct ifaddr *);
179static void arp_dad_start(struct ifaddr *); 179static void arp_dad_start(struct ifaddr *);
180static void arp_dad_stop(struct ifaddr *); 180static void arp_dad_stop(struct ifaddr *);
181static void arp_dad_duplicated(struct ifaddr *); 181static void arp_dad_duplicated(struct ifaddr *, const char *);
182 182
183static void arp_init_llentry(struct ifnet *, struct llentry *); 183static void arp_init_llentry(struct ifnet *, struct llentry *);
184#if NTOKEN > 0 184#if NTOKEN > 0
185static void arp_free_llentry_tokenring(struct llentry *); 185static void arp_free_llentry_tokenring(struct llentry *);
186#endif 186#endif
187 187
188struct ifqueue arpintrq = { 188struct ifqueue arpintrq = {
189 .ifq_head = NULL, 189 .ifq_head = NULL,
190 .ifq_tail = NULL, 190 .ifq_tail = NULL,
191 .ifq_len = 0, 191 .ifq_len = 0,
192 .ifq_maxlen = 50, 192 .ifq_maxlen = 50,
193 .ifq_drops = 0, 193 .ifq_drops = 0,
194}; 194};
195static int arp_maxtries = 5; 195static int arp_maxtries = 5;
196static int useloopback = 1; /* use loopback interface for local traffic */ 196static int useloopback = 1; /* use loopback interface for local traffic */
197 197
198static percpu_t *arpstat_percpu; 198static percpu_t *arpstat_percpu;
199 199
200#define ARP_STAT_GETREF() _NET_STAT_GETREF(arpstat_percpu) 200#define ARP_STAT_GETREF() _NET_STAT_GETREF(arpstat_percpu)
201#define ARP_STAT_PUTREF() _NET_STAT_PUTREF(arpstat_percpu) 201#define ARP_STAT_PUTREF() _NET_STAT_PUTREF(arpstat_percpu)
202 202
203#define ARP_STATINC(x) _NET_STATINC(arpstat_percpu, x) 203#define ARP_STATINC(x) _NET_STATINC(arpstat_percpu, x)
204#define ARP_STATADD(x, v) _NET_STATADD(arpstat_percpu, x, v) 204#define ARP_STATADD(x, v) _NET_STATADD(arpstat_percpu, x, v)
205 205
206/* revarp state */ 206/* revarp state */
207static struct in_addr myip, srv_ip; 207static struct in_addr myip, srv_ip;
208static int myip_initialized = 0; 208static int myip_initialized = 0;
209static int revarp_in_progress = 0; 209static int revarp_in_progress = 0;
210static struct ifnet *myip_ifp = NULL; 210static struct ifnet *myip_ifp = NULL;
211 211
212static int arp_drainwanted; 212static int arp_drainwanted;
213 213
214static int log_movements = 1; 214static int log_movements = 1;
215static int log_permanent_modify = 1; 215static int log_permanent_modify = 1;
216static int log_wrong_iface = 1; 216static int log_wrong_iface = 1;
217static int log_unknown_network = 1; 217static int log_unknown_network = 1;
218 218
219/* 219/*
220 * this should be elsewhere. 220 * this should be elsewhere.
221 */ 221 */
222 222
223static char * 223static char *
224lla_snprintf(u_int8_t *, int); 224lla_snprintf(u_int8_t *, int);
225 225
226static char * 226static char *
227lla_snprintf(u_int8_t *adrp, int len) 227lla_snprintf(u_int8_t *adrp, int len)
228{ 228{
229#define NUMBUFS 3 229#define NUMBUFS 3
230 static char buf[NUMBUFS][16*3]; 230 static char buf[NUMBUFS][16*3];
231 static int bnum = 0; 231 static int bnum = 0;
232 232
233 int i; 233 int i;
234 char *p; 234 char *p;
235 235
236 p = buf[bnum]; 236 p = buf[bnum];
237 237
238 *p++ = hexdigits[(*adrp)>>4]; 238 *p++ = hexdigits[(*adrp)>>4];
239 *p++ = hexdigits[(*adrp++)&0xf]; 239 *p++ = hexdigits[(*adrp++)&0xf];
240 240
241 for (i=1; i<len && i<16; i++) { 241 for (i=1; i<len && i<16; i++) {
242 *p++ = ':'; 242 *p++ = ':';
243 *p++ = hexdigits[(*adrp)>>4]; 243 *p++ = hexdigits[(*adrp)>>4];
244 *p++ = hexdigits[(*adrp++)&0xf]; 244 *p++ = hexdigits[(*adrp++)&0xf];
245 } 245 }
246 246
247 *p = 0; 247 *p = 0;
248 p = buf[bnum]; 248 p = buf[bnum];
249 bnum = (bnum + 1) % NUMBUFS; 249 bnum = (bnum + 1) % NUMBUFS;
250 return p; 250 return p;
251} 251}
252 252
253DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */ 253DOMAIN_DEFINE(arpdomain); /* forward declare and add to link set */
254 254
255static void 255static void
256arp_fasttimo(void) 256arp_fasttimo(void)
257{ 257{
258 if (arp_drainwanted) { 258 if (arp_drainwanted) {
259 arp_drain(); 259 arp_drain();
260 arp_drainwanted = 0; 260 arp_drainwanted = 0;
261 } 261 }
262} 262}
263 263
264const struct protosw arpsw[] = { 264const struct protosw arpsw[] = {
265 { .pr_type = 0, 265 { .pr_type = 0,
266 .pr_domain = &arpdomain, 266 .pr_domain = &arpdomain,
267 .pr_protocol = 0, 267 .pr_protocol = 0,
268 .pr_flags = 0, 268 .pr_flags = 0,
269 .pr_input = 0, 269 .pr_input = 0,
270 .pr_ctlinput = 0, 270 .pr_ctlinput = 0,
271 .pr_ctloutput = 0, 271 .pr_ctloutput = 0,
272 .pr_usrreqs = 0, 272 .pr_usrreqs = 0,
273 .pr_init = arp_init, 273 .pr_init = arp_init,
274 .pr_fasttimo = arp_fasttimo, 274 .pr_fasttimo = arp_fasttimo,
275 .pr_slowtimo = 0, 275 .pr_slowtimo = 0,
276 .pr_drain = arp_drainstub, 276 .pr_drain = arp_drainstub,
277 } 277 }
278}; 278};
279 279
280struct domain arpdomain = { 280struct domain arpdomain = {
281 .dom_family = PF_ARP, 281 .dom_family = PF_ARP,
282 .dom_name = "arp", 282 .dom_name = "arp",
283 .dom_protosw = arpsw, 283 .dom_protosw = arpsw,
284 .dom_protoswNPROTOSW = &arpsw[__arraycount(arpsw)], 284 .dom_protoswNPROTOSW = &arpsw[__arraycount(arpsw)],
285}; 285};
286 286
287static void sysctl_net_inet_arp_setup(struct sysctllog **); 287static void sysctl_net_inet_arp_setup(struct sysctllog **);
288 288
289void 289void
290arp_init(void) 290arp_init(void)
291{ 291{
292 292
293 sysctl_net_inet_arp_setup(NULL); 293 sysctl_net_inet_arp_setup(NULL);
294 arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS); 294 arpstat_percpu = percpu_alloc(sizeof(uint64_t) * ARP_NSTATS);
295 IFQ_LOCK_INIT(&arpintrq); 295 IFQ_LOCK_INIT(&arpintrq);
296} 296}
297 297
298static void 298static void
299arp_drainstub(void) 299arp_drainstub(void)
300{ 300{
301 arp_drainwanted = 1; 301 arp_drainwanted = 1;
302} 302}
303 303
304/* 304/*
305 * ARP protocol drain routine. Called when memory is in short supply. 305 * ARP protocol drain routine. Called when memory is in short supply.
306 * Called at splvm(); don't acquire softnet_lock as can be called from 306 * Called at splvm(); don't acquire softnet_lock as can be called from
307 * hardware interrupt handlers. 307 * hardware interrupt handlers.
308 */ 308 */
309void 309void
310arp_drain(void) 310arp_drain(void)
311{ 311{
312 312
313 lltable_drain(AF_INET); 313 lltable_drain(AF_INET);
314} 314}
315 315
316static void 316static void
317arptimer(void *arg) 317arptimer(void *arg)
318{ 318{
319 struct llentry *lle = arg; 319 struct llentry *lle = arg;
320 struct ifnet *ifp; 320 struct ifnet *ifp;
321 321
322 if (lle == NULL) 322 if (lle == NULL)
323 return; 323 return;
324 324
325 if (lle->la_flags & LLE_STATIC) 325 if (lle->la_flags & LLE_STATIC)
326 return; 326 return;
327 327
328 LLE_WLOCK(lle); 328 LLE_WLOCK(lle);
329 if (callout_pending(&lle->la_timer)) { 329 if (callout_pending(&lle->la_timer)) {
330 /* 330 /*
331 * Here we are a bit odd here in the treatment of 331 * Here we are a bit odd here in the treatment of
332 * active/pending. If the pending bit is set, it got 332 * active/pending. If the pending bit is set, it got
333 * rescheduled before I ran. The active 333 * rescheduled before I ran. The active
334 * bit we ignore, since if it was stopped 334 * bit we ignore, since if it was stopped
335 * in ll_tablefree() and was currently running 335 * in ll_tablefree() and was currently running
336 * it would have return 0 so the code would 336 * it would have return 0 so the code would
337 * not have deleted it since the callout could 337 * not have deleted it since the callout could
338 * not be stopped so we want to go through 338 * not be stopped so we want to go through
339 * with the delete here now. If the callout 339 * with the delete here now. If the callout
340 * was restarted, the pending bit will be back on and 340 * was restarted, the pending bit will be back on and
341 * we just want to bail since the callout_reset would 341 * we just want to bail since the callout_reset would
342 * return 1 and our reference would have been removed 342 * return 1 and our reference would have been removed
343 * by arpresolve() below. 343 * by arpresolve() below.
344 */ 344 */
345 LLE_WUNLOCK(lle); 345 LLE_WUNLOCK(lle);
346 return; 346 return;
347 } 347 }
348 ifp = lle->lle_tbl->llt_ifp; 348 ifp = lle->lle_tbl->llt_ifp;
349 349
350 callout_stop(&lle->la_timer); 350 callout_stop(&lle->la_timer);
351 351
352 /* XXX: LOR avoidance. We still have ref on lle. */ 352 /* XXX: LOR avoidance. We still have ref on lle. */
353 LLE_WUNLOCK(lle); 353 LLE_WUNLOCK(lle);
354 354
355 IF_AFDATA_LOCK(ifp); 355 IF_AFDATA_LOCK(ifp);
356 LLE_WLOCK(lle); 356 LLE_WLOCK(lle);
357 357
358 /* Guard against race with other llentry_free(). */ 358 /* Guard against race with other llentry_free(). */
359 if (lle->la_flags & LLE_LINKED) { 359 if (lle->la_flags & LLE_LINKED) {
360 size_t pkts_dropped; 360 size_t pkts_dropped;
361 361
362 LLE_REMREF(lle); 362 LLE_REMREF(lle);
363 pkts_dropped = llentry_free(lle); 363 pkts_dropped = llentry_free(lle);
364 ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped); 364 ARP_STATADD(ARP_STAT_DFRDROPPED, pkts_dropped);
365 ARP_STATADD(ARP_STAT_DFRTOTAL, pkts_dropped); 365 ARP_STATADD(ARP_STAT_DFRTOTAL, pkts_dropped);
366 } else { 366 } else {
367 LLE_FREE_LOCKED(lle); 367 LLE_FREE_LOCKED(lle);
368 } 368 }
369 369
370 IF_AFDATA_UNLOCK(ifp); 370 IF_AFDATA_UNLOCK(ifp);
371} 371}
372 372
373static void 373static void
374arp_settimer(struct llentry *la, int sec) 374arp_settimer(struct llentry *la, int sec)
375{ 375{
376 376
377 LLE_WLOCK_ASSERT(la); 377 LLE_WLOCK_ASSERT(la);
378 LLE_ADDREF(la); 378 LLE_ADDREF(la);
379 callout_reset(&la->la_timer, hz * sec, arptimer, la); 379 callout_reset(&la->la_timer, hz * sec, arptimer, la);
380} 380}
381 381
382/* 382/*
383 * We set the gateway for RTF_CLONING routes to a "prototype" 383 * We set the gateway for RTF_CLONING routes to a "prototype"
384 * link-layer sockaddr whose interface type (if_type) and interface 384 * link-layer sockaddr whose interface type (if_type) and interface
385 * index (if_index) fields are prepared. 385 * index (if_index) fields are prepared.
386 */ 386 */
387static struct sockaddr * 387static struct sockaddr *
388arp_setgate(struct rtentry *rt, struct sockaddr *gate, 388arp_setgate(struct rtentry *rt, struct sockaddr *gate,
389 const struct sockaddr *netmask) 389 const struct sockaddr *netmask)
390{ 390{
391 const struct ifnet *ifp = rt->rt_ifp; 391 const struct ifnet *ifp = rt->rt_ifp;
392 uint8_t namelen = strlen(ifp->if_xname); 392 uint8_t namelen = strlen(ifp->if_xname);
393 uint8_t addrlen = ifp->if_addrlen; 393 uint8_t addrlen = ifp->if_addrlen;
394 394
395 /* 395 /*
396 * XXX: If this is a manually added route to interface 396 * XXX: If this is a manually added route to interface
397 * such as older version of routed or gated might provide, 397 * such as older version of routed or gated might provide,
398 * restore cloning bit. 398 * restore cloning bit.
399 */ 399 */
400 if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL && 400 if ((rt->rt_flags & RTF_HOST) == 0 && netmask != NULL &&
401 satocsin(netmask)->sin_addr.s_addr != 0xffffffff) 401 satocsin(netmask)->sin_addr.s_addr != 0xffffffff)
402 rt->rt_flags |= RTF_CONNECTED; 402 rt->rt_flags |= RTF_CONNECTED;
403 403
404 if ((rt->rt_flags & (RTF_CONNECTED | RTF_LOCAL))) { 404 if ((rt->rt_flags & (RTF_CONNECTED | RTF_LOCAL))) {
405 union { 405 union {
406 struct sockaddr sa; 406 struct sockaddr sa;
407 struct sockaddr_storage ss; 407 struct sockaddr_storage ss;
408 struct sockaddr_dl sdl; 408 struct sockaddr_dl sdl;
409 } u; 409 } u;
410 /* 410 /*
411 * Case 1: This route should come from a route to iface. 411 * Case 1: This route should come from a route to iface.
412 */ 412 */
413 sockaddr_dl_init(&u.sdl, sizeof(u.ss), 413 sockaddr_dl_init(&u.sdl, sizeof(u.ss),
414 ifp->if_index, ifp->if_type, NULL, namelen, NULL, addrlen); 414 ifp->if_index, ifp->if_type, NULL, namelen, NULL, addrlen);
415 rt_setgate(rt, &u.sa); 415 rt_setgate(rt, &u.sa);
416 gate = rt->rt_gateway; 416 gate = rt->rt_gateway;
417 } 417 }
418 return gate; 418 return gate;
419} 419}
420 420
421static void 421static void
422arp_init_llentry(struct ifnet *ifp, struct llentry *lle) 422arp_init_llentry(struct ifnet *ifp, struct llentry *lle)
423{ 423{
424 424
425 switch (ifp->if_type) { 425 switch (ifp->if_type) {
426#if NTOKEN > 0 426#if NTOKEN > 0
427 case IFT_ISO88025: 427 case IFT_ISO88025:
428 lle->la_opaque = kmem_intr_alloc(sizeof(struct token_rif), 428 lle->la_opaque = kmem_intr_alloc(sizeof(struct token_rif),
429 KM_NOSLEEP); 429 KM_NOSLEEP);
430 lle->lle_ll_free = arp_free_llentry_tokenring; 430 lle->lle_ll_free = arp_free_llentry_tokenring;
431 break; 431 break;
432#endif 432#endif
433 } 433 }
434} 434}
435 435
436#if NTOKEN > 0 436#if NTOKEN > 0
437static void 437static void
438arp_free_llentry_tokenring(struct llentry *lle) 438arp_free_llentry_tokenring(struct llentry *lle)
439{ 439{
440 440
441 kmem_intr_free(lle->la_opaque, sizeof(struct token_rif)); 441 kmem_intr_free(lle->la_opaque, sizeof(struct token_rif));
442} 442}
443#endif 443#endif
444 444
445/* 445/*
446 * Parallel to llc_rtrequest. 446 * Parallel to llc_rtrequest.
447 */ 447 */
448void 448void
449arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info) 449arp_rtrequest(int req, struct rtentry *rt, const struct rt_addrinfo *info)
450{ 450{
451 struct sockaddr *gate = rt->rt_gateway; 451 struct sockaddr *gate = rt->rt_gateway;
452 struct in_ifaddr *ia; 452 struct in_ifaddr *ia;
453 struct ifaddr *ifa; 453 struct ifaddr *ifa;
454 struct ifnet *ifp = rt->rt_ifp; 454 struct ifnet *ifp = rt->rt_ifp;
455 int bound; 455 int bound;
456 int s; 456 int s;
457 457
458 if (req == RTM_LLINFO_UPD) { 458 if (req == RTM_LLINFO_UPD) {
459 if ((ifa = info->rti_ifa) != NULL) 459 if ((ifa = info->rti_ifa) != NULL)
460 arpannounce1(ifa); 460 arpannounce1(ifa);
461 return; 461 return;
462 } 462 }
463 463
464 if ((rt->rt_flags & RTF_GATEWAY) != 0) { 464 if ((rt->rt_flags & RTF_GATEWAY) != 0) {
465 if (req != RTM_ADD) 465 if (req != RTM_ADD)
466 return; 466 return;
467 467
468 /* 468 /*
469 * linklayers with particular link MTU limitation. 469 * linklayers with particular link MTU limitation.
470 */ 470 */
471 switch(ifp->if_type) { 471 switch(ifp->if_type) {
472#if NFDDI > 0 472#if NFDDI > 0
473 case IFT_FDDI: 473 case IFT_FDDI:
474 if (ifp->if_mtu > FDDIIPMTU) 474 if (ifp->if_mtu > FDDIIPMTU)
475 rt->rt_rmx.rmx_mtu = FDDIIPMTU; 475 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
476 break; 476 break;
477#endif 477#endif
478#if NARCNET > 0 478#if NARCNET > 0
479 case IFT_ARCNET: 479 case IFT_ARCNET:
480 { 480 {
481 int arcipifmtu; 481 int arcipifmtu;
482 482
483 if (ifp->if_flags & IFF_LINK0) 483 if (ifp->if_flags & IFF_LINK0)
484 arcipifmtu = arc_ipmtu; 484 arcipifmtu = arc_ipmtu;
485 else 485 else
486 arcipifmtu = ARCMTU; 486 arcipifmtu = ARCMTU;
487 if (ifp->if_mtu > arcipifmtu) 487 if (ifp->if_mtu > arcipifmtu)
488 rt->rt_rmx.rmx_mtu = arcipifmtu; 488 rt->rt_rmx.rmx_mtu = arcipifmtu;
489 break; 489 break;
490 } 490 }
491#endif 491#endif
492 } 492 }
493 return; 493 return;
494 } 494 }
495 495
496 switch (req) { 496 switch (req) {
497 case RTM_SETGATE: 497 case RTM_SETGATE:
498 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]); 498 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
499 break; 499 break;
500 case RTM_ADD: 500 case RTM_ADD:
501 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]); 501 gate = arp_setgate(rt, gate, info->rti_info[RTAX_NETMASK]);
502 if (gate == NULL) { 502 if (gate == NULL) {
503 log(LOG_ERR, "%s: arp_setgate failed\n", __func__); 503 log(LOG_ERR, "%s: arp_setgate failed\n", __func__);
504 break; 504 break;
505 } 505 }
506 if ((rt->rt_flags & RTF_CONNECTED) || 506 if ((rt->rt_flags & RTF_CONNECTED) ||
507 (rt->rt_flags & RTF_LOCAL)) { 507 (rt->rt_flags & RTF_LOCAL)) {
508 /* 508 /*
509 * Give this route an expiration time, even though 509 * Give this route an expiration time, even though
510 * it's a "permanent" route, so that routes cloned 510 * it's a "permanent" route, so that routes cloned
511 * from it do not need their expiration time set. 511 * from it do not need their expiration time set.
512 */ 512 */
513 KASSERT(time_uptime != 0); 513 KASSERT(time_uptime != 0);
514 rt->rt_expire = time_uptime; 514 rt->rt_expire = time_uptime;
515 /* 515 /*
516 * linklayers with particular link MTU limitation. 516 * linklayers with particular link MTU limitation.
517 */ 517 */
518 switch (ifp->if_type) { 518 switch (ifp->if_type) {
519#if NFDDI > 0 519#if NFDDI > 0
520 case IFT_FDDI: 520 case IFT_FDDI:
521 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 && 521 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
522 (rt->rt_rmx.rmx_mtu > FDDIIPMTU || 522 (rt->rt_rmx.rmx_mtu > FDDIIPMTU ||
523 (rt->rt_rmx.rmx_mtu == 0 && 523 (rt->rt_rmx.rmx_mtu == 0 &&
524 ifp->if_mtu > FDDIIPMTU))) 524 ifp->if_mtu > FDDIIPMTU)))
525 rt->rt_rmx.rmx_mtu = FDDIIPMTU; 525 rt->rt_rmx.rmx_mtu = FDDIIPMTU;
526 break; 526 break;
527#endif 527#endif
528#if NARCNET > 0 528#if NARCNET > 0
529 case IFT_ARCNET: 529 case IFT_ARCNET:
530 { 530 {
531 int arcipifmtu; 531 int arcipifmtu;
532 if (ifp->if_flags & IFF_LINK0) 532 if (ifp->if_flags & IFF_LINK0)
533 arcipifmtu = arc_ipmtu; 533 arcipifmtu = arc_ipmtu;
534 else 534 else
535 arcipifmtu = ARCMTU; 535 arcipifmtu = ARCMTU;
536 536
537 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 && 537 if ((rt->rt_rmx.rmx_locks & RTV_MTU) == 0 &&
538 (rt->rt_rmx.rmx_mtu > arcipifmtu || 538 (rt->rt_rmx.rmx_mtu > arcipifmtu ||
539 (rt->rt_rmx.rmx_mtu == 0 && 539 (rt->rt_rmx.rmx_mtu == 0 &&
540 ifp->if_mtu > arcipifmtu))) 540 ifp->if_mtu > arcipifmtu)))
541 rt->rt_rmx.rmx_mtu = arcipifmtu; 541 rt->rt_rmx.rmx_mtu = arcipifmtu;
542 break; 542 break;
543 } 543 }
544#endif 544#endif
545 } 545 }
546 if (rt->rt_flags & RTF_CONNECTED) 546 if (rt->rt_flags & RTF_CONNECTED)
547 break; 547 break;
548 } 548 }
549 549
550 bound = curlwp_bind(); 550 bound = curlwp_bind();
551 /* Announce a new entry if requested. */ 551 /* Announce a new entry if requested. */
552 if (rt->rt_flags & RTF_ANNOUNCE) { 552 if (rt->rt_flags & RTF_ANNOUNCE) {
553 struct psref psref; 553 struct psref psref;
554 ia = in_get_ia_on_iface_psref( 554 ia = in_get_ia_on_iface_psref(
555 satocsin(rt_getkey(rt))->sin_addr, ifp, &psref); 555 satocsin(rt_getkey(rt))->sin_addr, ifp, &psref);
556 if (ia != NULL) { 556 if (ia != NULL) {
557 arpannounce(ifp, &ia->ia_ifa, 557 arpannounce(ifp, &ia->ia_ifa,
558 CLLADDR(satocsdl(gate))); 558 CLLADDR(satocsdl(gate)));
559 ia4_release(ia, &psref); 559 ia4_release(ia, &psref);
560 } 560 }
561 } 561 }
562 562
563 if (gate->sa_family != AF_LINK || 563 if (gate->sa_family != AF_LINK ||
564 gate->sa_len < sockaddr_dl_measure(0, ifp->if_addrlen)) { 564 gate->sa_len < sockaddr_dl_measure(0, ifp->if_addrlen)) {
565 log(LOG_DEBUG, "%s: bad gateway value\n", __func__); 565 log(LOG_DEBUG, "%s: bad gateway value\n", __func__);
566 goto out; 566 goto out;
567 } 567 }
568 568
569 satosdl(gate)->sdl_type = ifp->if_type; 569 satosdl(gate)->sdl_type = ifp->if_type;
570 satosdl(gate)->sdl_index = ifp->if_index; 570 satosdl(gate)->sdl_index = ifp->if_index;
571 571
572 /* If the route is for a broadcast address mark it as such. 572 /* If the route is for a broadcast address mark it as such.
573 * This way we can avoid an expensive call to in_broadcast() 573 * This way we can avoid an expensive call to in_broadcast()
574 * in ip_output() most of the time (because the route passed 574 * in ip_output() most of the time (because the route passed
575 * to ip_output() is almost always a host route). */ 575 * to ip_output() is almost always a host route). */
576 if (rt->rt_flags & RTF_HOST && 576 if (rt->rt_flags & RTF_HOST &&
577 !(rt->rt_flags & RTF_BROADCAST) && 577 !(rt->rt_flags & RTF_BROADCAST) &&
578 in_broadcast(satocsin(rt_getkey(rt))->sin_addr, rt->rt_ifp)) 578 in_broadcast(satocsin(rt_getkey(rt))->sin_addr, rt->rt_ifp))
579 rt->rt_flags |= RTF_BROADCAST; 579 rt->rt_flags |= RTF_BROADCAST;
580 /* There is little point in resolving the broadcast address */ 580 /* There is little point in resolving the broadcast address */
581 if (rt->rt_flags & RTF_BROADCAST) 581 if (rt->rt_flags & RTF_BROADCAST)
582 goto out; 582 goto out;
583 583
584 /* 584 /*
585 * When called from rt_ifa_addlocal, we cannot depend on that 585 * When called from rt_ifa_addlocal, we cannot depend on that
586 * the address (rt_getkey(rt)) exits in the address list of the 586 * the address (rt_getkey(rt)) exits in the address list of the
587 * interface. So check RTF_LOCAL instead. 587 * interface. So check RTF_LOCAL instead.
588 */ 588 */
589 if (rt->rt_flags & RTF_LOCAL) { 589 if (rt->rt_flags & RTF_LOCAL) {
590 rt->rt_expire = 0; 590 rt->rt_expire = 0;
591 if (useloopback) { 591 if (useloopback) {
592 rt->rt_ifp = lo0ifp; 592 rt->rt_ifp = lo0ifp;
593 rt->rt_rmx.rmx_mtu = 0; 593 rt->rt_rmx.rmx_mtu = 0;
594 } 594 }
595 goto out; 595 goto out;
596 } 596 }
597 597
598 s = pserialize_read_enter(); 598 s = pserialize_read_enter();
599 ia = in_get_ia_on_iface(satocsin(rt_getkey(rt))->sin_addr, ifp); 599 ia = in_get_ia_on_iface(satocsin(rt_getkey(rt))->sin_addr, ifp);
600 if (ia == NULL) { 600 if (ia == NULL) {
601 pserialize_read_exit(s); 601 pserialize_read_exit(s);
602 goto out; 602 goto out;
603 } 603 }
604 604
605 rt->rt_expire = 0; 605 rt->rt_expire = 0;
606 if (useloopback) { 606 if (useloopback) {
607 rt->rt_ifp = lo0ifp; 607 rt->rt_ifp = lo0ifp;
608 rt->rt_rmx.rmx_mtu = 0; 608 rt->rt_rmx.rmx_mtu = 0;
609 } 609 }
610 rt->rt_flags |= RTF_LOCAL; 610 rt->rt_flags |= RTF_LOCAL;
611 /* 611 /*
612 * make sure to set rt->rt_ifa to the interface 612 * make sure to set rt->rt_ifa to the interface
613 * address we are using, otherwise we will have trouble 613 * address we are using, otherwise we will have trouble
614 * with source address selection. 614 * with source address selection.
615 */ 615 */
616 ifa = &ia->ia_ifa; 616 ifa = &ia->ia_ifa;
617 if (ifa != rt->rt_ifa) 617 if (ifa != rt->rt_ifa)
618 /* Assume it doesn't sleep */ 618 /* Assume it doesn't sleep */
619 rt_replace_ifa(rt, ifa); 619 rt_replace_ifa(rt, ifa);
620 pserialize_read_exit(s); 620 pserialize_read_exit(s);
621 out: 621 out:
622 curlwp_bindx(bound); 622 curlwp_bindx(bound);
623 break; 623 break;
624 } 624 }
625} 625}
626 626
627/* 627/*
628 * Broadcast an ARP request. Caller specifies: 628 * Broadcast an ARP request. Caller specifies:
629 * - arp header source ip address 629 * - arp header source ip address
630 * - arp header target ip address 630 * - arp header target ip address
631 * - arp header source ethernet address 631 * - arp header source ethernet address
632 */ 632 */
633static void 633static void
634arprequest(struct ifnet *ifp, 634arprequest(struct ifnet *ifp,
635 const struct in_addr *sip, const struct in_addr *tip, 635 const struct in_addr *sip, const struct in_addr *tip,
636 const u_int8_t *enaddr) 636 const u_int8_t *enaddr)
637{ 637{
638 struct mbuf *m; 638 struct mbuf *m;
639 struct arphdr *ah; 639 struct arphdr *ah;
640 struct sockaddr sa; 640 struct sockaddr sa;
641 uint64_t *arps; 641 uint64_t *arps;
642 642
643 KASSERT(sip != NULL); 643 KASSERT(sip != NULL);
644 KASSERT(tip != NULL); 644 KASSERT(tip != NULL);
645 KASSERT(enaddr != NULL); 645 KASSERT(enaddr != NULL);
646 646
647 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 647 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
648 return; 648 return;
649 MCLAIM(m, &arpdomain.dom_mowner); 649 MCLAIM(m, &arpdomain.dom_mowner);
650 switch (ifp->if_type) { 650 switch (ifp->if_type) {
651 case IFT_IEEE1394: 651 case IFT_IEEE1394:
652 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 652 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
653 ifp->if_addrlen; 653 ifp->if_addrlen;
654 break; 654 break;
655 default: 655 default:
656 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) + 656 m->m_len = sizeof(*ah) + 2 * sizeof(struct in_addr) +
657 2 * ifp->if_addrlen; 657 2 * ifp->if_addrlen;
658 break; 658 break;
659 } 659 }
660 m->m_pkthdr.len = m->m_len; 660 m->m_pkthdr.len = m->m_len;
661 MH_ALIGN(m, m->m_len); 661 MH_ALIGN(m, m->m_len);
662 ah = mtod(m, struct arphdr *); 662 ah = mtod(m, struct arphdr *);
663 memset(ah, 0, m->m_len); 663 memset(ah, 0, m->m_len);
664 switch (ifp->if_type) { 664 switch (ifp->if_type) {
665 case IFT_IEEE1394: /* RFC2734 */ 665 case IFT_IEEE1394: /* RFC2734 */
666 /* fill it now for ar_tpa computation */ 666 /* fill it now for ar_tpa computation */
667 ah->ar_hrd = htons(ARPHRD_IEEE1394); 667 ah->ar_hrd = htons(ARPHRD_IEEE1394);
668 break; 668 break;
669 default: 669 default:
670 /* ifp->if_output will fill ar_hrd */ 670 /* ifp->if_output will fill ar_hrd */
671 break; 671 break;
672 } 672 }
673 ah->ar_pro = htons(ETHERTYPE_IP); 673 ah->ar_pro = htons(ETHERTYPE_IP);
674 ah->ar_hln = ifp->if_addrlen; /* hardware address length */ 674 ah->ar_hln = ifp->if_addrlen; /* hardware address length */
675 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 675 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
676 ah->ar_op = htons(ARPOP_REQUEST); 676 ah->ar_op = htons(ARPOP_REQUEST);
677 memcpy(ar_sha(ah), enaddr, ah->ar_hln); 677 memcpy(ar_sha(ah), enaddr, ah->ar_hln);
678 memcpy(ar_spa(ah), sip, ah->ar_pln); 678 memcpy(ar_spa(ah), sip, ah->ar_pln);
679 memcpy(ar_tpa(ah), tip, ah->ar_pln); 679 memcpy(ar_tpa(ah), tip, ah->ar_pln);
680 sa.sa_family = AF_ARP; 680 sa.sa_family = AF_ARP;
681 sa.sa_len = 2; 681 sa.sa_len = 2;
682 m->m_flags |= M_BCAST; 682 m->m_flags |= M_BCAST;
683 arps = ARP_STAT_GETREF(); 683 arps = ARP_STAT_GETREF();
684 arps[ARP_STAT_SNDTOTAL]++; 684 arps[ARP_STAT_SNDTOTAL]++;
685 arps[ARP_STAT_SENDREQUEST]++; 685 arps[ARP_STAT_SENDREQUEST]++;
686 ARP_STAT_PUTREF(); 686 ARP_STAT_PUTREF();
687 if_output_lock(ifp, ifp, m, &sa, NULL); 687 if_output_lock(ifp, ifp, m, &sa, NULL);
688} 688}
689 689
690void 690void
691arpannounce(struct ifnet *ifp, struct ifaddr *ifa, const uint8_t *enaddr) 691arpannounce(struct ifnet *ifp, struct ifaddr *ifa, const uint8_t *enaddr)
692{ 692{
693 struct in_ifaddr *ia = ifatoia(ifa); 693 struct in_ifaddr *ia = ifatoia(ifa);
694 struct in_addr *ip = &IA_SIN(ifa)->sin_addr; 694 struct in_addr *ip = &IA_SIN(ifa)->sin_addr;
695 695
696 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) { 696 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) {
697 arplog(LOG_DEBUG, "%s not ready\n", in_fmtaddr(*ip)); 697 arplog(LOG_DEBUG, "%s not ready\n", in_fmtaddr(*ip));
698 return; 698 return;
699 } 699 }
700 arprequest(ifp, ip, ip, enaddr); 700 arprequest(ifp, ip, ip, enaddr);
701} 701}
702 702
703static void 703static void
704arpannounce1(struct ifaddr *ifa) 704arpannounce1(struct ifaddr *ifa)
705{ 705{
706 706
707 arpannounce(ifa->ifa_ifp, ifa, CLLADDR(ifa->ifa_ifp->if_sadl)); 707 arpannounce(ifa->ifa_ifp, ifa, CLLADDR(ifa->ifa_ifp->if_sadl));
708} 708}
709 709
710/* 710/*
711 * Resolve an IP address into an ethernet address. If success, 711 * Resolve an IP address into an ethernet address. If success,
712 * desten is filled in. If there is no entry in arptab, 712 * desten is filled in. If there is no entry in arptab,
713 * set one up and broadcast a request for the IP address. 713 * set one up and broadcast a request for the IP address.
714 * Hold onto this mbuf and resend it once the address 714 * Hold onto this mbuf and resend it once the address
715 * is finally resolved. A return value of 0 indicates 715 * is finally resolved. A return value of 0 indicates
716 * that desten has been filled in and the packet should be sent 716 * that desten has been filled in and the packet should be sent
717 * normally; a return value of EWOULDBLOCK indicates that the packet has been 717 * normally; a return value of EWOULDBLOCK indicates that the packet has been
718 * held pending resolution. 718 * held pending resolution.
719 * Any other value indicates an error. 719 * Any other value indicates an error.
720 */ 720 */
721int 721int
722arpresolve(struct ifnet *ifp, const struct rtentry *rt, struct mbuf *m, 722arpresolve(struct ifnet *ifp, const struct rtentry *rt, struct mbuf *m,
723 const struct sockaddr *dst, void *desten, size_t destlen) 723 const struct sockaddr *dst, void *desten, size_t destlen)
724{ 724{
725 struct llentry *la; 725 struct llentry *la;
726 const char *create_lookup; 726 const char *create_lookup;
727 bool renew; 727 bool renew;
728 int error; 728 int error;
729 729
730 KASSERT(m != NULL); 730 KASSERT(m != NULL);
731 731
732 la = arplookup(ifp, m, NULL, dst, 0); 732 la = arplookup(ifp, m, NULL, dst, 0);
733 if (la == NULL) 733 if (la == NULL)
734 goto notfound; 734 goto notfound;
735 735
736 if ((la->la_flags & LLE_VALID) && 736 if ((la->la_flags & LLE_VALID) &&
737 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) { 737 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) {
738 KASSERT(destlen >= ifp->if_addrlen); 738 KASSERT(destlen >= ifp->if_addrlen);
739 memcpy(desten, &la->ll_addr, ifp->if_addrlen); 739 memcpy(desten, &la->ll_addr, ifp->if_addrlen);
740 LLE_RUNLOCK(la); 740 LLE_RUNLOCK(la);
741 return 0; 741 return 0;
742 } 742 }
743 743
744notfound: 744notfound:
745#ifdef IFF_STATICARP /* FreeBSD */ 745#ifdef IFF_STATICARP /* FreeBSD */
746#define _IFF_NOARP (IFF_NOARP | IFF_STATICARP) 746#define _IFF_NOARP (IFF_NOARP | IFF_STATICARP)
747#else 747#else
748#define _IFF_NOARP IFF_NOARP 748#define _IFF_NOARP IFF_NOARP
749#endif 749#endif
750 if (ifp->if_flags & _IFF_NOARP) { 750 if (ifp->if_flags & _IFF_NOARP) {
751 if (la != NULL) 751 if (la != NULL)
752 LLE_RUNLOCK(la); 752 LLE_RUNLOCK(la);
753 error = ENOTSUP; 753 error = ENOTSUP;
754 goto bad; 754 goto bad;
755 } 755 }
756#undef _IFF_NOARP 756#undef _IFF_NOARP
757 if (la == NULL) { 757 if (la == NULL) {
758 create_lookup = "create"; 758 create_lookup = "create";
759 IF_AFDATA_WLOCK(ifp); 759 IF_AFDATA_WLOCK(ifp);
760 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst); 760 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
761 IF_AFDATA_WUNLOCK(ifp); 761 IF_AFDATA_WUNLOCK(ifp);
762 if (la == NULL) 762 if (la == NULL)
763 ARP_STATINC(ARP_STAT_ALLOCFAIL); 763 ARP_STATINC(ARP_STAT_ALLOCFAIL);
764 else 764 else
765 arp_init_llentry(ifp, la); 765 arp_init_llentry(ifp, la);
766 } else if (LLE_TRY_UPGRADE(la) == 0) { 766 } else if (LLE_TRY_UPGRADE(la) == 0) {
767 create_lookup = "lookup"; 767 create_lookup = "lookup";
768 LLE_RUNLOCK(la); 768 LLE_RUNLOCK(la);
769 IF_AFDATA_RLOCK(ifp); 769 IF_AFDATA_RLOCK(ifp);
770 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst); 770 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
771 IF_AFDATA_RUNLOCK(ifp); 771 IF_AFDATA_RUNLOCK(ifp);
772 } 772 }
773 773
774 error = EINVAL; 774 error = EINVAL;
775 if (la == NULL) { 775 if (la == NULL) {
776 log(LOG_DEBUG, 776 log(LOG_DEBUG,
777 "%s: failed to %s llentry for %s on %s\n", 777 "%s: failed to %s llentry for %s on %s\n",
778 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr), 778 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr),
779 ifp->if_xname); 779 ifp->if_xname);
780 goto bad; 780 goto bad;
781 } 781 }
782 782
783 if ((la->la_flags & LLE_VALID) && 783 if ((la->la_flags & LLE_VALID) &&
784 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) 784 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime))
785 { 785 {
786 KASSERT(destlen >= ifp->if_addrlen); 786 KASSERT(destlen >= ifp->if_addrlen);
787 memcpy(desten, &la->ll_addr, ifp->if_addrlen); 787 memcpy(desten, &la->ll_addr, ifp->if_addrlen);
788 renew = false; 788 renew = false;
789 /* 789 /*
790 * If entry has an expiry time and it is approaching, 790 * If entry has an expiry time and it is approaching,
791 * see if we need to send an ARP request within this 791 * see if we need to send an ARP request within this
792 * arpt_down interval. 792 * arpt_down interval.
793 */ 793 */
794 if (!(la->la_flags & LLE_STATIC) && 794 if (!(la->la_flags & LLE_STATIC) &&
795 time_uptime + la->la_preempt > la->la_expire) 795 time_uptime + la->la_preempt > la->la_expire)
796 { 796 {
797 renew = true; 797 renew = true;
798 la->la_preempt--; 798 la->la_preempt--;
799 } 799 }
800 800
801 LLE_WUNLOCK(la); 801 LLE_WUNLOCK(la);
802 802
803 if (renew) { 803 if (renew) {
804 const u_int8_t *enaddr = 804 const u_int8_t *enaddr =
805#if NCARP > 0 805#if NCARP > 0
806 (ifp->if_type == IFT_CARP) ? 806 (ifp->if_type == IFT_CARP) ?
807 CLLADDR(ifp->if_sadl): 807 CLLADDR(ifp->if_sadl):
808#endif 808#endif
809 CLLADDR(ifp->if_sadl); 809 CLLADDR(ifp->if_sadl);
810 arprequest(ifp, 810 arprequest(ifp,
811 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 811 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
812 &satocsin(dst)->sin_addr, enaddr); 812 &satocsin(dst)->sin_addr, enaddr);
813 } 813 }
814 814
815 return 0; 815 return 0;
816 } 816 }
817 817
818 if (la->la_flags & LLE_STATIC) { /* should not happen! */ 818 if (la->la_flags & LLE_STATIC) { /* should not happen! */
819 LLE_RUNLOCK(la); 819 LLE_RUNLOCK(la);
820 log(LOG_DEBUG, "%s: ouch, empty static llinfo for %s\n", 820 log(LOG_DEBUG, "%s: ouch, empty static llinfo for %s\n",
821 __func__, inet_ntoa(satocsin(dst)->sin_addr)); 821 __func__, inet_ntoa(satocsin(dst)->sin_addr));
822 error = EINVAL; 822 error = EINVAL;
823 goto bad; 823 goto bad;
824 } 824 }
825 825
826 renew = (la->la_asked == 0 || la->la_expire != time_uptime); 826 renew = (la->la_asked == 0 || la->la_expire != time_uptime);
827 827
828 /* 828 /*
829 * There is an arptab entry, but no ethernet address 829 * There is an arptab entry, but no ethernet address
830 * response yet. Add the mbuf to the list, dropping 830 * response yet. Add the mbuf to the list, dropping
831 * the oldest packet if we have exceeded the system 831 * the oldest packet if we have exceeded the system
832 * setting. 832 * setting.
833 */ 833 */
834 LLE_WLOCK_ASSERT(la); 834 LLE_WLOCK_ASSERT(la);
835 if (la->la_numheld >= arp_maxhold) { 835 if (la->la_numheld >= arp_maxhold) {
836 if (la->la_hold != NULL) { 836 if (la->la_hold != NULL) {
837 struct mbuf *next = la->la_hold->m_nextpkt; 837 struct mbuf *next = la->la_hold->m_nextpkt;
838 m_freem(la->la_hold); 838 m_freem(la->la_hold);
839 la->la_hold = next; 839 la->la_hold = next;
840 la->la_numheld--; 840 la->la_numheld--;
841 ARP_STATINC(ARP_STAT_DFRDROPPED); 841 ARP_STATINC(ARP_STAT_DFRDROPPED);
842 ARP_STATINC(ARP_STAT_DFRTOTAL); 842 ARP_STATINC(ARP_STAT_DFRTOTAL);
843 } 843 }
844 } 844 }
845 if (la->la_hold != NULL) { 845 if (la->la_hold != NULL) {
846 struct mbuf *curr = la->la_hold; 846 struct mbuf *curr = la->la_hold;
847 while (curr->m_nextpkt != NULL) 847 while (curr->m_nextpkt != NULL)
848 curr = curr->m_nextpkt; 848 curr = curr->m_nextpkt;
849 curr->m_nextpkt = m; 849 curr->m_nextpkt = m;
850 } else 850 } else
851 la->la_hold = m; 851 la->la_hold = m;
852 la->la_numheld++; 852 la->la_numheld++;
853 if (!renew) 853 if (!renew)
854 LLE_DOWNGRADE(la); 854 LLE_DOWNGRADE(la);
855 855
856 /* 856 /*
857 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It 857 * Return EWOULDBLOCK if we have tried less than arp_maxtries. It
858 * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH 858 * will be masked by ether_output(). Return EHOSTDOWN/EHOSTUNREACH
859 * if we have already sent arp_maxtries ARP requests. Retransmit the 859 * if we have already sent arp_maxtries ARP requests. Retransmit the
860 * ARP request, but not faster than one request per second. 860 * ARP request, but not faster than one request per second.
861 */ 861 */
862 if (la->la_asked < arp_maxtries) 862 if (la->la_asked < arp_maxtries)
863 error = EWOULDBLOCK; /* First request. */ 863 error = EWOULDBLOCK; /* First request. */
864 else 864 else
865 error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ? 865 error = (rt != NULL && rt->rt_flags & RTF_GATEWAY) ?
866 EHOSTUNREACH : EHOSTDOWN; 866 EHOSTUNREACH : EHOSTDOWN;
867 867
868 if (renew) { 868 if (renew) {
869 const u_int8_t *enaddr = 869 const u_int8_t *enaddr =
870#if NCARP > 0 870#if NCARP > 0
871 (rt != NULL && rt->rt_ifp->if_type == IFT_CARP) ? 871 (rt != NULL && rt->rt_ifp->if_type == IFT_CARP) ?
872 CLLADDR(rt->rt_ifp->if_sadl): 872 CLLADDR(rt->rt_ifp->if_sadl):
873#endif 873#endif
874 CLLADDR(ifp->if_sadl); 874 CLLADDR(ifp->if_sadl);
875 la->la_expire = time_uptime; 875 la->la_expire = time_uptime;
876 arp_settimer(la, arpt_down); 876 arp_settimer(la, arpt_down);
877 la->la_asked++; 877 la->la_asked++;
878 LLE_WUNLOCK(la); 878 LLE_WUNLOCK(la);
879 879
880 if (rt != NULL) { 880 if (rt != NULL) {
881 arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 881 arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
882 &satocsin(dst)->sin_addr, enaddr); 882 &satocsin(dst)->sin_addr, enaddr);
883 } else { 883 } else {
884 struct sockaddr_in sin; 884 struct sockaddr_in sin;
885 struct rtentry *_rt; 885 struct rtentry *_rt;
886 886
887 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); 887 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0);
888 888
889 /* XXX */ 889 /* XXX */
890 _rt = rtalloc1((struct sockaddr *)&sin, 0); 890 _rt = rtalloc1((struct sockaddr *)&sin, 0);
891 if (_rt == NULL) 891 if (_rt == NULL)
892 goto bad; 892 goto bad;
893 arprequest(ifp, 893 arprequest(ifp,
894 &satocsin(_rt->rt_ifa->ifa_addr)->sin_addr, 894 &satocsin(_rt->rt_ifa->ifa_addr)->sin_addr,
895 &satocsin(dst)->sin_addr, enaddr); 895 &satocsin(dst)->sin_addr, enaddr);
896 rtfree(_rt); 896 rtfree(_rt);
897 } 897 }
898 return error; 898 return error;
899 } 899 }
900 900
901 LLE_RUNLOCK(la); 901 LLE_RUNLOCK(la);
902 return error; 902 return error;
903 903
904bad: 904bad:
905 m_freem(m); 905 m_freem(m);
906 return error; 906 return error;
907} 907}
908 908
909/* 909/*
910 * Common length and type checks are done here, 910 * Common length and type checks are done here,
911 * then the protocol-specific routine is called. 911 * then the protocol-specific routine is called.
912 */ 912 */
913void 913void
914arpintr(void) 914arpintr(void)
915{ 915{
916 struct mbuf *m; 916 struct mbuf *m;
917 struct arphdr *ar; 917 struct arphdr *ar;
918 int s; 918 int s;
919 int arplen; 919 int arplen;
920 920
921 mutex_enter(softnet_lock); 921 mutex_enter(softnet_lock);
922 KERNEL_LOCK(1, NULL); 922 KERNEL_LOCK(1, NULL);
923 for (;;) { 923 for (;;) {
924 struct ifnet *rcvif; 924 struct ifnet *rcvif;
925 925
926 IFQ_LOCK(&arpintrq); 926 IFQ_LOCK(&arpintrq);
927 IF_DEQUEUE(&arpintrq, m); 927 IF_DEQUEUE(&arpintrq, m);
928 IFQ_UNLOCK(&arpintrq); 928 IFQ_UNLOCK(&arpintrq);
929 if (m == NULL) 929 if (m == NULL)
930 goto out; 930 goto out;
931 if ((m->m_flags & M_PKTHDR) == 0) 931 if ((m->m_flags & M_PKTHDR) == 0)
932 panic("arpintr"); 932 panic("arpintr");
933 933
934 MCLAIM(m, &arpdomain.dom_mowner); 934 MCLAIM(m, &arpdomain.dom_mowner);
935 ARP_STATINC(ARP_STAT_RCVTOTAL); 935 ARP_STATINC(ARP_STAT_RCVTOTAL);
936 936
937 /* 937 /*
938 * First, make sure we have at least struct arphdr. 938 * First, make sure we have at least struct arphdr.
939 */ 939 */
940 if (m->m_len < sizeof(struct arphdr) || 940 if (m->m_len < sizeof(struct arphdr) ||
941 (ar = mtod(m, struct arphdr *)) == NULL) 941 (ar = mtod(m, struct arphdr *)) == NULL)
942 goto badlen; 942 goto badlen;
943 943
944 rcvif = m_get_rcvif(m, &s); 944 rcvif = m_get_rcvif(m, &s);
945 switch (rcvif->if_type) { 945 switch (rcvif->if_type) {
946 case IFT_IEEE1394: 946 case IFT_IEEE1394:
947 arplen = sizeof(struct arphdr) + 947 arplen = sizeof(struct arphdr) +
948 ar->ar_hln + 2 * ar->ar_pln; 948 ar->ar_hln + 2 * ar->ar_pln;
949 break; 949 break;
950 default: 950 default:
951 arplen = sizeof(struct arphdr) + 951 arplen = sizeof(struct arphdr) +
952 2 * ar->ar_hln + 2 * ar->ar_pln; 952 2 * ar->ar_hln + 2 * ar->ar_pln;
953 break; 953 break;
954 } 954 }
955 m_put_rcvif(rcvif, &s); 955 m_put_rcvif(rcvif, &s);
956 956
957 if (/* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */ 957 if (/* XXX ntohs(ar->ar_hrd) == ARPHRD_ETHER && */
958 m->m_len >= arplen) 958 m->m_len >= arplen)
959 switch (ntohs(ar->ar_pro)) { 959 switch (ntohs(ar->ar_pro)) {
960 case ETHERTYPE_IP: 960 case ETHERTYPE_IP:
961 case ETHERTYPE_IPTRAILERS: 961 case ETHERTYPE_IPTRAILERS:
962 in_arpinput(m); 962 in_arpinput(m);
963 continue; 963 continue;
964 default: 964 default:
965 ARP_STATINC(ARP_STAT_RCVBADPROTO); 965 ARP_STATINC(ARP_STAT_RCVBADPROTO);
966 } 966 }
967 else { 967 else {
968badlen: 968badlen:
969 ARP_STATINC(ARP_STAT_RCVBADLEN); 969 ARP_STATINC(ARP_STAT_RCVBADLEN);
970 } 970 }
971 m_freem(m); 971 m_freem(m);
972 } 972 }
973out: 973out:
974 KERNEL_UNLOCK_ONE(NULL); 974 KERNEL_UNLOCK_ONE(NULL);
975 mutex_exit(softnet_lock); 975 mutex_exit(softnet_lock);
976} 976}
977 977
978/* 978/*
979 * ARP for Internet protocols on 10 Mb/s Ethernet. 979 * ARP for Internet protocols on 10 Mb/s Ethernet.
980 * Algorithm is that given in RFC 826. 980 * Algorithm is that given in RFC 826.
981 * In addition, a sanity check is performed on the sender 981 * In addition, a sanity check is performed on the sender
982 * protocol address, to catch impersonators. 982 * protocol address, to catch impersonators.
983 * We no longer handle negotiations for use of trailer protocol: 983 * We no longer handle negotiations for use of trailer protocol:
984 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent 984 * Formerly, ARP replied for protocol type ETHERTYPE_TRAIL sent
985 * along with IP replies if we wanted trailers sent to us, 985 * along with IP replies if we wanted trailers sent to us,
986 * and also sent them in response to IP replies. 986 * and also sent them in response to IP replies.
987 * This allowed either end to announce the desire to receive 987 * This allowed either end to announce the desire to receive
988 * trailer packets. 988 * trailer packets.
989 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either, 989 * We no longer reply to requests for ETHERTYPE_TRAIL protocol either,
990 * but formerly didn't normally send requests. 990 * but formerly didn't normally send requests.
991 */ 991 */
992static void 992static void
993in_arpinput(struct mbuf *m) 993in_arpinput(struct mbuf *m)
994{ 994{
995 struct arphdr *ah; 995 struct arphdr *ah;
996 struct ifnet *ifp, *rcvif = NULL; 996 struct ifnet *ifp, *rcvif = NULL;
997 struct llentry *la = NULL; 997 struct llentry *la = NULL;
998 struct in_ifaddr *ia = NULL; 998 struct in_ifaddr *ia = NULL;
999#if NBRIDGE > 0 999#if NBRIDGE > 0
1000 struct in_ifaddr *bridge_ia = NULL; 1000 struct in_ifaddr *bridge_ia = NULL;
1001#endif 1001#endif
1002#if NCARP > 0 1002#if NCARP > 0
1003 u_int32_t count = 0, index = 0; 1003 u_int32_t count = 0, index = 0;
1004#endif 1004#endif
1005 struct sockaddr sa; 1005 struct sockaddr sa;
1006 struct in_addr isaddr, itaddr, myaddr; 1006 struct in_addr isaddr, itaddr, myaddr;
1007 int op; 1007 int op;
1008 void *tha; 1008 void *tha;
1009 uint64_t *arps; 1009 uint64_t *arps;
1010 struct psref psref, psref_ia; 1010 struct psref psref, psref_ia;
1011 int s; 1011 int s;
1012 1012
1013 if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT))) 1013 if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
1014 goto out; 1014 goto out;
1015 ah = mtod(m, struct arphdr *); 1015 ah = mtod(m, struct arphdr *);
1016 op = ntohs(ah->ar_op); 1016 op = ntohs(ah->ar_op);
1017 1017
1018 rcvif = ifp = m_get_rcvif_psref(m, &psref); 1018 rcvif = ifp = m_get_rcvif_psref(m, &psref);
1019 if (__predict_false(rcvif == NULL)) 1019 if (__predict_false(rcvif == NULL))
1020 goto drop; 1020 goto drop;
1021 /* 1021 /*
1022 * Fix up ah->ar_hrd if necessary, before using ar_tha() or 1022 * Fix up ah->ar_hrd if necessary, before using ar_tha() or
1023 * ar_tpa(). 1023 * ar_tpa().
1024 */ 1024 */
1025 switch (ifp->if_type) { 1025 switch (ifp->if_type) {
1026 case IFT_IEEE1394: 1026 case IFT_IEEE1394:
1027 if (ntohs(ah->ar_hrd) == ARPHRD_IEEE1394) 1027 if (ntohs(ah->ar_hrd) == ARPHRD_IEEE1394)
1028 ; 1028 ;
1029 else { 1029 else {
1030 /* XXX this is to make sure we compute ar_tha right */ 1030 /* XXX this is to make sure we compute ar_tha right */
1031 /* XXX check ar_hrd more strictly? */ 1031 /* XXX check ar_hrd more strictly? */
1032 ah->ar_hrd = htons(ARPHRD_IEEE1394); 1032 ah->ar_hrd = htons(ARPHRD_IEEE1394);
1033 } 1033 }
1034 break; 1034 break;
1035 default: 1035 default:
1036 /* XXX check ar_hrd? */ 1036 /* XXX check ar_hrd? */
1037 break; 1037 break;
1038 } 1038 }
1039 1039
1040 memcpy(&isaddr, ar_spa(ah), sizeof (isaddr)); 1040 memcpy(&isaddr, ar_spa(ah), sizeof (isaddr));
1041 memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr)); 1041 memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr));
1042 1042
1043 if (m->m_flags & (M_BCAST|M_MCAST)) 1043 if (m->m_flags & (M_BCAST|M_MCAST))
1044 ARP_STATINC(ARP_STAT_RCVMCAST); 1044 ARP_STATINC(ARP_STAT_RCVMCAST);
1045 1045
1046 1046
1047 /* 1047 /*
1048 * Search for a matching interface address 1048 * Search for a matching interface address
1049 * or any address on the interface to use 1049 * or any address on the interface to use
1050 * as a dummy address in the rest of this function 1050 * as a dummy address in the rest of this function
1051 */ 1051 */
1052 s = pserialize_read_enter(); 1052 s = pserialize_read_enter();
1053 IN_ADDRHASH_READER_FOREACH(ia, itaddr.s_addr) { 1053 IN_ADDRHASH_READER_FOREACH(ia, itaddr.s_addr) {
1054 if (!in_hosteq(ia->ia_addr.sin_addr, itaddr)) 1054 if (!in_hosteq(ia->ia_addr.sin_addr, itaddr))
1055 continue; 1055 continue;
1056#if NCARP > 0 1056#if NCARP > 0
1057 if (ia->ia_ifp->if_type == IFT_CARP && 1057 if (ia->ia_ifp->if_type == IFT_CARP &&
1058 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) == 1058 ((ia->ia_ifp->if_flags & (IFF_UP|IFF_RUNNING)) ==
1059 (IFF_UP|IFF_RUNNING))) { 1059 (IFF_UP|IFF_RUNNING))) {
1060 index++; 1060 index++;
1061 if (ia->ia_ifp == rcvif && 1061 if (ia->ia_ifp == rcvif &&
1062 carp_iamatch(ia, ar_sha(ah), 1062 carp_iamatch(ia, ar_sha(ah),
1063 &count, index)) { 1063 &count, index)) {
1064 break; 1064 break;
1065 } 1065 }
1066 } else 1066 } else
1067#endif 1067#endif
1068 if (ia->ia_ifp == rcvif) 1068 if (ia->ia_ifp == rcvif)
1069 break; 1069 break;
1070#if NBRIDGE > 0 1070#if NBRIDGE > 0
1071 /* 1071 /*
1072 * If the interface we received the packet on 1072 * If the interface we received the packet on
1073 * is part of a bridge, check to see if we need 1073 * is part of a bridge, check to see if we need
1074 * to "bridge" the packet to ourselves at this 1074 * to "bridge" the packet to ourselves at this
1075 * layer. Note we still prefer a perfect match, 1075 * layer. Note we still prefer a perfect match,
1076 * but allow this weaker match if necessary. 1076 * but allow this weaker match if necessary.
1077 */ 1077 */
1078 if (rcvif->if_bridge != NULL && 1078 if (rcvif->if_bridge != NULL &&
1079 rcvif->if_bridge == ia->ia_ifp->if_bridge) 1079 rcvif->if_bridge == ia->ia_ifp->if_bridge)
1080 bridge_ia = ia; 1080 bridge_ia = ia;
1081#endif /* NBRIDGE > 0 */ 1081#endif /* NBRIDGE > 0 */
1082 } 1082 }
1083 1083
1084#if NBRIDGE > 0 1084#if NBRIDGE > 0
1085 if (ia == NULL && bridge_ia != NULL) { 1085 if (ia == NULL && bridge_ia != NULL) {
1086 ia = bridge_ia; 1086 ia = bridge_ia;
1087 m_put_rcvif_psref(rcvif, &psref); 1087 m_put_rcvif_psref(rcvif, &psref);
1088 rcvif = NULL; 1088 rcvif = NULL;
1089 /* FIXME */ 1089 /* FIXME */
1090 ifp = bridge_ia->ia_ifp; 1090 ifp = bridge_ia->ia_ifp;
1091 } 1091 }
1092#endif 1092#endif
1093 if (ia != NULL) 1093 if (ia != NULL)
1094 ia4_acquire(ia, &psref_ia); 1094 ia4_acquire(ia, &psref_ia);
1095 pserialize_read_exit(s); 1095 pserialize_read_exit(s);
1096 1096
1097 if (ia == NULL) { 1097 if (ia == NULL) {
1098 ia = in_get_ia_on_iface_psref(isaddr, rcvif, &psref_ia); 1098 ia = in_get_ia_on_iface_psref(isaddr, rcvif, &psref_ia);
1099 if (ia == NULL) { 1099 if (ia == NULL) {
1100 ia = in_get_ia_from_ifp_psref(ifp, &psref_ia); 1100 ia = in_get_ia_from_ifp_psref(ifp, &psref_ia);
1101 if (ia == NULL) { 1101 if (ia == NULL) {
1102 ARP_STATINC(ARP_STAT_RCVNOINT); 1102 ARP_STATINC(ARP_STAT_RCVNOINT);
1103 goto out; 1103 goto out;
1104 } 1104 }
1105 } 1105 }
1106 } 1106 }
1107 1107
1108 myaddr = ia->ia_addr.sin_addr; 1108 myaddr = ia->ia_addr.sin_addr;
1109 1109
1110 /* XXX checks for bridge case? */ 1110 /* XXX checks for bridge case? */
1111 if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) { 1111 if (!memcmp(ar_sha(ah), CLLADDR(ifp->if_sadl), ifp->if_addrlen)) {
1112 ARP_STATINC(ARP_STAT_RCVLOCALSHA); 1112 ARP_STATINC(ARP_STAT_RCVLOCALSHA);
1113 goto out; /* it's from me, ignore it. */ 1113 goto out; /* it's from me, ignore it. */
1114 } 1114 }
1115 1115
1116 /* XXX checks for bridge case? */ 1116 /* XXX checks for bridge case? */
1117 if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) { 1117 if (!memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen)) {
1118 ARP_STATINC(ARP_STAT_RCVBCASTSHA); 1118 ARP_STATINC(ARP_STAT_RCVBCASTSHA);
1119 log(LOG_ERR, 1119 log(LOG_ERR,
1120 "%s: arp: link address is broadcast for IP address %s!\n", 1120 "%s: arp: link address is broadcast for IP address %s!\n",
1121 ifp->if_xname, in_fmtaddr(isaddr)); 1121 ifp->if_xname, in_fmtaddr(isaddr));
1122 goto out; 1122 goto out;
1123 } 1123 }
1124 1124
1125 /* 1125 /*
1126 * If the source IP address is zero, this is an RFC 5227 ARP probe 1126 * If the source IP address is zero, this is an RFC 5227 ARP probe
1127 */ 1127 */
1128 if (in_nullhost(isaddr)) 1128 if (in_nullhost(isaddr))
1129 ARP_STATINC(ARP_STAT_RCVZEROSPA); 1129 ARP_STATINC(ARP_STAT_RCVZEROSPA);
1130 else if (in_hosteq(isaddr, myaddr)) 1130 else if (in_hosteq(isaddr, myaddr))
1131 ARP_STATINC(ARP_STAT_RCVLOCALSPA); 1131 ARP_STATINC(ARP_STAT_RCVLOCALSPA);
1132 1132
1133 if (in_nullhost(itaddr)) 1133 if (in_nullhost(itaddr))
1134 ARP_STATINC(ARP_STAT_RCVZEROTPA); 1134 ARP_STATINC(ARP_STAT_RCVZEROTPA);
1135 1135
1136 /* DAD check, RFC 5227 2.1.1, Probe Details */ 1136 /* DAD check, RFC 5227 */
1137 if (in_hosteq(isaddr, myaddr) || 1137 if (in_hosteq(isaddr, myaddr) ||
1138 (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr))) 1138 (in_nullhost(isaddr) && in_hosteq(itaddr, myaddr)))
1139 { 1139 {
1140 /* If our address is tentative, mark it as duplicated */ 1140 arp_dad_duplicated((struct ifaddr *)ia,
1141 if (ia->ia4_flags & IN_IFF_TENTATIVE) 1141 lla_snprintf(ar_sha(ah), ah->ar_hln));
1142 arp_dad_duplicated((struct ifaddr *)ia); 1142 goto out;
1143 /* If our address is unuseable, don't reply */ 
1144 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) 
1145 goto out; 
1146 } 1143 }
1147 1144
1148 /* 1145 /*
1149 * If the target IP address is zero, ignore the packet. 1146 * If the target IP address is zero, ignore the packet.
1150 * This prevents the code below from tring to answer 1147 * This prevents the code below from tring to answer
1151 * when we are using IP address zero (booting). 1148 * when we are using IP address zero (booting).
1152 */ 1149 */
1153 if (in_nullhost(itaddr)) 1150 if (in_nullhost(itaddr))
1154 goto out; 1151 goto out;
1155 1152
1156 if (in_nullhost(isaddr)) 1153 if (in_nullhost(isaddr))
1157 goto reply; 1154 goto reply;
1158 1155
1159 if (in_hosteq(isaddr, myaddr)) { 
1160 log(LOG_ERR, 
1161 "duplicate IP address %s sent from link address %s\n", 
1162 in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln)); 
1163 itaddr = myaddr; 
1164 goto reply; 
1165 } 
1166 
1167 if (in_hosteq(itaddr, myaddr)) 1156 if (in_hosteq(itaddr, myaddr))
1168 la = arpcreate(ifp, m, &isaddr, NULL, 1); 1157 la = arpcreate(ifp, m, &isaddr, NULL, 1);
1169 else 1158 else
1170 la = arplookup(ifp, m, &isaddr, NULL, 1); 1159 la = arplookup(ifp, m, &isaddr, NULL, 1);
1171 if (la == NULL) 1160 if (la == NULL)
1172 goto reply; 1161 goto reply;
1173 1162
1174 if ((la->la_flags & LLE_VALID) && 1163 if ((la->la_flags & LLE_VALID) &&
1175 memcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) { 1164 memcmp(ar_sha(ah), &la->ll_addr, ifp->if_addrlen)) {
1176 if (la->la_flags & LLE_STATIC) { 1165 if (la->la_flags & LLE_STATIC) {
1177 ARP_STATINC(ARP_STAT_RCVOVERPERM); 1166 ARP_STATINC(ARP_STAT_RCVOVERPERM);
1178 if (!log_permanent_modify) 1167 if (!log_permanent_modify)
1179 goto out; 1168 goto out;
1180 log(LOG_INFO, 1169 log(LOG_INFO,
1181 "%s tried to overwrite permanent arp info" 1170 "%s tried to overwrite permanent arp info"
1182 " for %s\n", 1171 " for %s\n",
1183 lla_snprintf(ar_sha(ah), ah->ar_hln), 1172 lla_snprintf(ar_sha(ah), ah->ar_hln),
1184 in_fmtaddr(isaddr)); 1173 in_fmtaddr(isaddr));
1185 goto out; 1174 goto out;
1186 } else if (la->lle_tbl->llt_ifp != ifp) { 1175 } else if (la->lle_tbl->llt_ifp != ifp) {
1187 /* XXX should not happen? */ 1176 /* XXX should not happen? */
1188 ARP_STATINC(ARP_STAT_RCVOVERINT); 1177 ARP_STATINC(ARP_STAT_RCVOVERINT);
1189 if (!log_wrong_iface) 1178 if (!log_wrong_iface)
1190 goto out; 1179 goto out;
1191 log(LOG_INFO, 1180 log(LOG_INFO,
1192 "%s on %s tried to overwrite " 1181 "%s on %s tried to overwrite "
1193 "arp info for %s on %s\n", 1182 "arp info for %s on %s\n",
1194 lla_snprintf(ar_sha(ah), ah->ar_hln), 1183 lla_snprintf(ar_sha(ah), ah->ar_hln),
1195 ifp->if_xname, in_fmtaddr(isaddr), 1184 ifp->if_xname, in_fmtaddr(isaddr),
1196 la->lle_tbl->llt_ifp->if_xname); 1185 la->lle_tbl->llt_ifp->if_xname);
1197 goto out; 1186 goto out;
1198 } else { 1187 } else {
1199 ARP_STATINC(ARP_STAT_RCVOVER); 1188 ARP_STATINC(ARP_STAT_RCVOVER);
1200 if (log_movements) 1189 if (log_movements)
1201 log(LOG_INFO, "arp info overwritten " 1190 log(LOG_INFO, "arp info overwritten "
1202 "for %s by %s\n", 1191 "for %s by %s\n",
1203 in_fmtaddr(isaddr), 1192 in_fmtaddr(isaddr),
1204 lla_snprintf(ar_sha(ah), 1193 lla_snprintf(ar_sha(ah),
1205 ah->ar_hln)); 1194 ah->ar_hln));
1206 } 1195 }
1207 } 1196 }
1208 1197
1209 /* XXX llentry should have addrlen? */ 1198 /* XXX llentry should have addrlen? */
1210#if 0 1199#if 0
1211 /* 1200 /*
1212 * sanity check for the address length. 1201 * sanity check for the address length.
1213 * XXX this does not work for protocols with variable address 1202 * XXX this does not work for protocols with variable address
1214 * length. -is 1203 * length. -is
1215 */ 1204 */
1216 if (sdl->sdl_alen && sdl->sdl_alen != ah->ar_hln) { 1205 if (sdl->sdl_alen && sdl->sdl_alen != ah->ar_hln) {
1217 ARP_STATINC(ARP_STAT_RCVLENCHG); 1206 ARP_STATINC(ARP_STAT_RCVLENCHG);
1218 log(LOG_WARNING, 1207 log(LOG_WARNING,
1219 "arp from %s: new addr len %d, was %d\n", 1208 "arp from %s: new addr len %d, was %d\n",
1220 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen); 1209 in_fmtaddr(isaddr), ah->ar_hln, sdl->sdl_alen);
1221 } 1210 }
1222#endif 1211#endif
1223 1212
1224 if (ifp->if_addrlen != ah->ar_hln) { 1213 if (ifp->if_addrlen != ah->ar_hln) {
1225 ARP_STATINC(ARP_STAT_RCVBADLEN); 1214 ARP_STATINC(ARP_STAT_RCVBADLEN);
1226 log(LOG_WARNING, 1215 log(LOG_WARNING,
1227 "arp from %s: addr len: new %d, i/f %d (ignored)\n", 1216 "arp from %s: addr len: new %d, i/f %d (ignored)\n",
1228 in_fmtaddr(isaddr), ah->ar_hln, 1217 in_fmtaddr(isaddr), ah->ar_hln,
1229 ifp->if_addrlen); 1218 ifp->if_addrlen);
1230 goto reply; 1219 goto reply;
1231 } 1220 }
1232 1221
1233#if NTOKEN > 0 1222#if NTOKEN > 0
1234 /* 1223 /*
1235 * XXX uses m_data and assumes the complete answer including 1224 * XXX uses m_data and assumes the complete answer including
1236 * XXX token-ring headers is in the same buf 1225 * XXX token-ring headers is in the same buf
1237 */ 1226 */
1238 if (ifp->if_type == IFT_ISO88025) { 1227 if (ifp->if_type == IFT_ISO88025) {
1239 struct token_header *trh; 1228 struct token_header *trh;
1240 1229
1241 trh = (struct token_header *)M_TRHSTART(m); 1230 trh = (struct token_header *)M_TRHSTART(m);
1242 if (trh->token_shost[0] & TOKEN_RI_PRESENT) { 1231 if (trh->token_shost[0] & TOKEN_RI_PRESENT) {
1243 struct token_rif *rif; 1232 struct token_rif *rif;
1244 size_t riflen; 1233 size_t riflen;
1245 1234
1246 rif = TOKEN_RIF(trh); 1235 rif = TOKEN_RIF(trh);
1247 riflen = (ntohs(rif->tr_rcf) & 1236 riflen = (ntohs(rif->tr_rcf) &
1248 TOKEN_RCF_LEN_MASK) >> 8; 1237 TOKEN_RCF_LEN_MASK) >> 8;
1249 1238
1250 if (riflen > 2 && 1239 if (riflen > 2 &&
1251 riflen < sizeof(struct token_rif) && 1240 riflen < sizeof(struct token_rif) &&
1252 (riflen & 1) == 0) { 1241 (riflen & 1) == 0) {
1253 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION); 1242 rif->tr_rcf ^= htons(TOKEN_RCF_DIRECTION);
1254 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK); 1243 rif->tr_rcf &= htons(~TOKEN_RCF_BROADCAST_MASK);
1255 memcpy(TOKEN_RIF_LLE(la), rif, riflen); 1244 memcpy(TOKEN_RIF_LLE(la), rif, riflen);
1256 } 1245 }
1257 } 1246 }
1258 } 1247 }
1259#endif /* NTOKEN > 0 */ 1248#endif /* NTOKEN > 0 */
1260 1249
1261 KASSERT(sizeof(la->ll_addr) >= ifp->if_addrlen); 1250 KASSERT(sizeof(la->ll_addr) >= ifp->if_addrlen);
1262 (void)memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen); 1251 (void)memcpy(&la->ll_addr, ar_sha(ah), ifp->if_addrlen);
1263 la->la_flags |= LLE_VALID; 1252 la->la_flags |= LLE_VALID;
1264 if ((la->la_flags & LLE_STATIC) == 0) { 1253 if ((la->la_flags & LLE_STATIC) == 0) {
1265 la->la_expire = time_uptime + arpt_keep; 1254 la->la_expire = time_uptime + arpt_keep;
1266 arp_settimer(la, arpt_keep); 1255 arp_settimer(la, arpt_keep);
1267 } 1256 }
1268 la->la_asked = 0; 1257 la->la_asked = 0;
1269 /* rt->rt_flags &= ~RTF_REJECT; */ 1258 /* rt->rt_flags &= ~RTF_REJECT; */
1270 1259
1271 if (la->la_hold != NULL) { 1260 if (la->la_hold != NULL) {
1272 int n = la->la_numheld; 1261 int n = la->la_numheld;
1273 struct mbuf *m_hold, *m_hold_next; 1262 struct mbuf *m_hold, *m_hold_next;
1274 struct sockaddr_in sin; 1263 struct sockaddr_in sin;
1275 1264
1276 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0); 1265 sockaddr_in_init(&sin, &la->r_l3addr.addr4, 0);
1277 1266
1278 m_hold = la->la_hold; 1267 m_hold = la->la_hold;
1279 la->la_hold = NULL; 1268 la->la_hold = NULL;
1280 la->la_numheld = 0; 1269 la->la_numheld = 0;
1281 /* 1270 /*
1282 * We have to unlock here because if_output would call 1271 * We have to unlock here because if_output would call
1283 * arpresolve 1272 * arpresolve
1284 */ 1273 */
1285 LLE_WUNLOCK(la); 1274 LLE_WUNLOCK(la);
1286 ARP_STATADD(ARP_STAT_DFRSENT, n); 1275 ARP_STATADD(ARP_STAT_DFRSENT, n);
1287 ARP_STATADD(ARP_STAT_DFRTOTAL, n); 1276 ARP_STATADD(ARP_STAT_DFRTOTAL, n);
1288 for (; m_hold != NULL; m_hold = m_hold_next) { 1277 for (; m_hold != NULL; m_hold = m_hold_next) {
1289 m_hold_next = m_hold->m_nextpkt; 1278 m_hold_next = m_hold->m_nextpkt;
1290 m_hold->m_nextpkt = NULL; 1279 m_hold->m_nextpkt = NULL;
1291 if_output_lock(ifp, ifp, m_hold, sintosa(&sin), NULL); 1280 if_output_lock(ifp, ifp, m_hold, sintosa(&sin), NULL);
1292 } 1281 }
1293 } else 1282 } else
1294 LLE_WUNLOCK(la); 1283 LLE_WUNLOCK(la);
1295 la = NULL; 1284 la = NULL;
1296 1285
1297reply: 1286reply:
1298 if (la != NULL) { 1287 if (la != NULL) {
1299 LLE_WUNLOCK(la); 1288 LLE_WUNLOCK(la);
1300 la = NULL; 1289 la = NULL;
1301 } 1290 }
1302 if (op != ARPOP_REQUEST) { 1291 if (op != ARPOP_REQUEST) {
1303 if (op == ARPOP_REPLY) 1292 if (op == ARPOP_REPLY)
1304 ARP_STATINC(ARP_STAT_RCVREPLY); 1293 ARP_STATINC(ARP_STAT_RCVREPLY);
1305 goto out; 1294 goto out;
1306 } 1295 }
1307 ARP_STATINC(ARP_STAT_RCVREQUEST); 1296 ARP_STATINC(ARP_STAT_RCVREQUEST);
1308 if (in_hosteq(itaddr, myaddr)) { 1297 if (in_hosteq(itaddr, myaddr)) {
1309 /* If our address is unuseable, don't reply */ 1298 /* If our address is unuseable, don't reply */
1310 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) 1299 if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
1311 goto out; 1300 goto out;
1312 /* I am the target */ 1301 /* I am the target */
1313 tha = ar_tha(ah); 1302 tha = ar_tha(ah);
1314 if (tha) 1303 if (tha)
1315 memcpy(tha, ar_sha(ah), ah->ar_hln); 1304 memcpy(tha, ar_sha(ah), ah->ar_hln);
1316 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln); 1305 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln);
1317 } else { 1306 } else {
1318 /* Proxy ARP */ 1307 /* Proxy ARP */
1319 struct llentry *lle = NULL; 1308 struct llentry *lle = NULL;
1320 struct sockaddr_in sin; 1309 struct sockaddr_in sin;
1321#if NCARP > 0 1310#if NCARP > 0
1322 struct ifnet *_rcvif = m_get_rcvif(m, &s); 1311 struct ifnet *_rcvif = m_get_rcvif(m, &s);
1323 if (ifp->if_type == IFT_CARP && _rcvif->if_type != IFT_CARP) 1312 if (ifp->if_type == IFT_CARP && _rcvif->if_type != IFT_CARP)
1324 goto out; 1313 goto out;
1325 m_put_rcvif(_rcvif, &s); 1314 m_put_rcvif(_rcvif, &s);
1326#endif 1315#endif
1327 1316
1328 tha = ar_tha(ah); 1317 tha = ar_tha(ah);
1329 1318
1330 sockaddr_in_init(&sin, &itaddr, 0); 1319 sockaddr_in_init(&sin, &itaddr, 0);
1331 1320
1332 IF_AFDATA_RLOCK(ifp); 1321 IF_AFDATA_RLOCK(ifp);
1333 lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin); 1322 lle = lla_lookup(LLTABLE(ifp), 0, (struct sockaddr *)&sin);
1334 IF_AFDATA_RUNLOCK(ifp); 1323 IF_AFDATA_RUNLOCK(ifp);
1335 1324
1336 if ((lle != NULL) && (lle->la_flags & LLE_PUB)) { 1325 if ((lle != NULL) && (lle->la_flags & LLE_PUB)) {
1337 (void)memcpy(tha, ar_sha(ah), ah->ar_hln); 1326 (void)memcpy(tha, ar_sha(ah), ah->ar_hln);
1338 (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln); 1327 (void)memcpy(ar_sha(ah), &lle->ll_addr, ah->ar_hln);
1339 LLE_RUNLOCK(lle); 1328 LLE_RUNLOCK(lle);
1340 } else { 1329 } else {
1341 if (lle != NULL) 1330 if (lle != NULL)
1342 LLE_RUNLOCK(lle); 1331 LLE_RUNLOCK(lle);
1343 goto drop; 1332 goto drop;
1344 } 1333 }
1345 } 1334 }
1346 ia4_release(ia, &psref_ia); 1335 ia4_release(ia, &psref_ia);
1347 1336
1348 memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln); 1337 memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln);
1349 memcpy(ar_spa(ah), &itaddr, ah->ar_pln); 1338 memcpy(ar_spa(ah), &itaddr, ah->ar_pln);
1350 ah->ar_op = htons(ARPOP_REPLY); 1339 ah->ar_op = htons(ARPOP_REPLY);
1351 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */ 1340 ah->ar_pro = htons(ETHERTYPE_IP); /* let's be sure! */
1352 switch (ifp->if_type) { 1341 switch (ifp->if_type) {
1353 case IFT_IEEE1394: 1342 case IFT_IEEE1394:
1354 /* 1343 /*
1355 * ieee1394 arp reply is broadcast 1344 * ieee1394 arp reply is broadcast
1356 */ 1345 */
1357 m->m_flags &= ~M_MCAST; 1346 m->m_flags &= ~M_MCAST;
1358 m->m_flags |= M_BCAST; 1347 m->m_flags |= M_BCAST;
1359 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + ah->ar_hln; 1348 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + ah->ar_hln;
1360 break; 1349 break;
1361 default: 1350 default:
1362 m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */ 1351 m->m_flags &= ~(M_BCAST|M_MCAST); /* never reply by broadcast */
1363 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln); 1352 m->m_len = sizeof(*ah) + (2 * ah->ar_pln) + (2 * ah->ar_hln);
1364 break; 1353 break;
1365 } 1354 }
1366 m->m_pkthdr.len = m->m_len; 1355 m->m_pkthdr.len = m->m_len;
1367 sa.sa_family = AF_ARP; 1356 sa.sa_family = AF_ARP;
1368 sa.sa_len = 2; 1357 sa.sa_len = 2;
1369 arps = ARP_STAT_GETREF(); 1358 arps = ARP_STAT_GETREF();
1370 arps[ARP_STAT_SNDTOTAL]++; 1359 arps[ARP_STAT_SNDTOTAL]++;
1371 arps[ARP_STAT_SNDREPLY]++; 1360 arps[ARP_STAT_SNDREPLY]++;
1372 ARP_STAT_PUTREF(); 1361 ARP_STAT_PUTREF();
1373 if_output_lock(ifp, ifp, m, &sa, NULL); 1362 if_output_lock(ifp, ifp, m, &sa, NULL);
1374 if (rcvif != NULL) 1363 if (rcvif != NULL)
1375 m_put_rcvif_psref(rcvif, &psref); 1364 m_put_rcvif_psref(rcvif, &psref);
1376 return; 1365 return;
1377 1366
1378out: 1367out:
1379 if (la != NULL) 1368 if (la != NULL)
1380 LLE_WUNLOCK(la); 1369 LLE_WUNLOCK(la);
1381drop: 1370drop:
1382 if (ia != NULL) 1371 if (ia != NULL)
1383 ia4_release(ia, &psref_ia); 1372 ia4_release(ia, &psref_ia);
1384 if (rcvif != NULL) 1373 if (rcvif != NULL)
1385 m_put_rcvif_psref(rcvif, &psref); 1374 m_put_rcvif_psref(rcvif, &psref);
1386 m_freem(m); 1375 m_freem(m);
1387} 1376}
1388 1377
1389/* 1378/*
1390 * Lookup or a new address in arptab. 1379 * Lookup or a new address in arptab.
1391 */ 1380 */
1392static struct llentry * 1381static struct llentry *
1393arplookup(struct ifnet *ifp, struct mbuf *m, const struct in_addr *addr, 1382arplookup(struct ifnet *ifp, struct mbuf *m, const struct in_addr *addr,
1394 const struct sockaddr *sa, int wlock) 1383 const struct sockaddr *sa, int wlock)
1395{ 1384{
1396 struct sockaddr_in sin; 1385 struct sockaddr_in sin;
1397 struct llentry *la; 1386 struct llentry *la;
1398 int flags = wlock ? LLE_EXCLUSIVE : 0; 1387 int flags = wlock ? LLE_EXCLUSIVE : 0;
1399 1388
1400 1389
1401 if (sa == NULL) { 1390 if (sa == NULL) {
1402 KASSERT(addr != NULL); 1391 KASSERT(addr != NULL);
1403 sockaddr_in_init(&sin, addr, 0); 1392 sockaddr_in_init(&sin, addr, 0);
1404 sa = sintocsa(&sin); 1393 sa = sintocsa(&sin);
1405 } 1394 }
1406 1395
1407 IF_AFDATA_RLOCK(ifp); 1396 IF_AFDATA_RLOCK(ifp);
1408 la = lla_lookup(LLTABLE(ifp), flags, sa); 1397 la = lla_lookup(LLTABLE(ifp), flags, sa);
1409 IF_AFDATA_RUNLOCK(ifp); 1398 IF_AFDATA_RUNLOCK(ifp);
1410 1399
1411 return la; 1400 return la;
1412} 1401}
1413 1402
1414static struct llentry * 1403static struct llentry *
1415arpcreate(struct ifnet *ifp, struct mbuf *m, const struct in_addr *addr, 1404arpcreate(struct ifnet *ifp, struct mbuf *m, const struct in_addr *addr,
1416 const struct sockaddr *sa, int wlock) 1405 const struct sockaddr *sa, int wlock)
1417{ 1406{
1418 struct sockaddr_in sin; 1407 struct sockaddr_in sin;
1419 struct llentry *la; 1408 struct llentry *la;
1420 int flags = wlock ? LLE_EXCLUSIVE : 0; 1409 int flags = wlock ? LLE_EXCLUSIVE : 0;
1421 1410
1422 if (sa == NULL) { 1411 if (sa == NULL) {
1423 KASSERT(addr != NULL); 1412 KASSERT(addr != NULL);
1424 sockaddr_in_init(&sin, addr, 0); 1413 sockaddr_in_init(&sin, addr, 0);
1425 sa = sintocsa(&sin); 1414 sa = sintocsa(&sin);
1426 } 1415 }
1427 1416
1428 la = arplookup(ifp, m, addr, sa, wlock); 1417 la = arplookup(ifp, m, addr, sa, wlock);
1429 1418
1430 if (la == NULL) { 1419 if (la == NULL) {
1431 IF_AFDATA_WLOCK(ifp); 1420 IF_AFDATA_WLOCK(ifp);
1432 la = lla_create(LLTABLE(ifp), flags, sa); 1421 la = lla_create(LLTABLE(ifp), flags, sa);
1433 IF_AFDATA_WUNLOCK(ifp); 1422 IF_AFDATA_WUNLOCK(ifp);
1434 1423
1435 if (la != NULL) 1424 if (la != NULL)
1436 arp_init_llentry(ifp, la); 1425 arp_init_llentry(ifp, la);
1437 } 1426 }
1438 1427
1439 return la; 1428 return la;
1440} 1429}
1441 1430
1442int 1431int
1443arpioctl(u_long cmd, void *data) 1432arpioctl(u_long cmd, void *data)
1444{ 1433{
1445 1434
1446 return EOPNOTSUPP; 1435 return EOPNOTSUPP;
1447} 1436}
1448 1437
1449void 1438void
1450arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa) 1439arp_ifinit(struct ifnet *ifp, struct ifaddr *ifa)
1451{ 1440{
1452 struct in_addr *ip; 1441 struct in_addr *ip;
1453 struct in_ifaddr *ia = (struct in_ifaddr *)ifa; 1442 struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
1454 1443
1455 /* 1444 /*
1456 * Warn the user if another station has this IP address, 1445 * Warn the user if another station has this IP address,
1457 * but only if the interface IP address is not zero. 1446 * but only if the interface IP address is not zero.
1458 */ 1447 */
1459 ip = &IA_SIN(ifa)->sin_addr; 1448 ip = &IA_SIN(ifa)->sin_addr;
1460 if (!in_nullhost(*ip) && 1449 if (!in_nullhost(*ip) &&
1461 (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) == 0) { 1450 (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) == 0) {
1462 struct llentry *lle; 1451 struct llentry *lle;
1463 1452
1464 /* 1453 /*
1465 * interface address is considered static entry 1454 * interface address is considered static entry
1466 * because the output of the arp utility shows 1455 * because the output of the arp utility shows
1467 * that L2 entry as permanent 1456 * that L2 entry as permanent
1468 */ 1457 */
1469 IF_AFDATA_WLOCK(ifp); 1458 IF_AFDATA_WLOCK(ifp);
1470 lle = lla_create(LLTABLE(ifp), (LLE_IFADDR | LLE_STATIC), 1459 lle = lla_create(LLTABLE(ifp), (LLE_IFADDR | LLE_STATIC),
1471 (struct sockaddr *)IA_SIN(ifa)); 1460 (struct sockaddr *)IA_SIN(ifa));
1472 IF_AFDATA_WUNLOCK(ifp); 1461 IF_AFDATA_WUNLOCK(ifp);
1473 if (lle == NULL) 1462 if (lle == NULL)
1474 log(LOG_INFO, "%s: cannot create arp entry for" 1463 log(LOG_INFO, "%s: cannot create arp entry for"
1475 " interface address\n", __func__); 1464 " interface address\n", __func__);
1476 else { 1465 else {
1477 arp_init_llentry(ifp, lle); 1466 arp_init_llentry(ifp, lle);
1478 LLE_RUNLOCK(lle); 1467 LLE_RUNLOCK(lle);
1479 } 1468 }
1480 } 1469 }
1481 1470
1482 ifa->ifa_rtrequest = arp_rtrequest; 1471 ifa->ifa_rtrequest = arp_rtrequest;
1483 ifa->ifa_flags |= RTF_CONNECTED; 1472 ifa->ifa_flags |= RTF_CONNECTED;
1484 1473
1485 /* ARP will handle DAD for this address. */ 1474 /* ARP will handle DAD for this address. */
1486 if (in_nullhost(*ip)) { 1475 if (in_nullhost(*ip)) {
1487 if (ia->ia_dad_stop != NULL) /* safety */ 1476 if (ia->ia_dad_stop != NULL) /* safety */
1488 ia->ia_dad_stop(ifa); 1477 ia->ia_dad_stop(ifa);
1489 ia->ia_dad_start = NULL; 1478 ia->ia_dad_start = NULL;
1490 ia->ia_dad_stop = NULL; 1479 ia->ia_dad_stop = NULL;
1491 ia->ia4_flags &= ~IN_IFF_TENTATIVE; 1480 ia->ia4_flags &= ~IN_IFF_TENTATIVE;
1492 } else { 1481 } else {
1493 ia->ia_dad_start = arp_dad_start; 1482 ia->ia_dad_start = arp_dad_start;
1494 ia->ia_dad_stop = arp_dad_stop; 1483 ia->ia_dad_stop = arp_dad_stop;
1495 if (ia->ia4_flags & IN_IFF_TRYTENTATIVE) 1484 if (ia->ia4_flags & IN_IFF_TRYTENTATIVE)
1496 ia->ia4_flags |= IN_IFF_TENTATIVE; 1485 ia->ia4_flags |= IN_IFF_TENTATIVE;
1497 else 1486 else
1498 arpannounce1(ifa); 1487 arpannounce1(ifa);
1499 } 1488 }
1500} 1489}
1501 1490
1502TAILQ_HEAD(dadq_head, dadq); 1491TAILQ_HEAD(dadq_head, dadq);
1503struct dadq { 1492struct dadq {
1504 TAILQ_ENTRY(dadq) dad_list; 1493 TAILQ_ENTRY(dadq) dad_list;
1505 struct ifaddr *dad_ifa; 1494 struct ifaddr *dad_ifa;
1506 int dad_count; /* max ARP to send */ 1495 int dad_count; /* max ARP to send */
1507 int dad_arp_tcount; /* # of trials to send ARP */ 1496 int dad_arp_tcount; /* # of trials to send ARP */
1508 int dad_arp_ocount; /* ARP sent so far */ 1497 int dad_arp_ocount; /* ARP sent so far */
1509 int dad_arp_announce; /* max ARP announcements */ 1498 int dad_arp_announce; /* max ARP announcements */
1510 int dad_arp_acount; /* # of announcements */ 1499 int dad_arp_acount; /* # of announcements */
1511 struct callout dad_timer_ch; 1500 struct callout dad_timer_ch;
1512}; 1501};
1513MALLOC_JUSTDEFINE(M_IPARP, "ARP DAD", "ARP DAD Structure"); 1502MALLOC_JUSTDEFINE(M_IPARP, "ARP DAD", "ARP DAD Structure");
1514 1503
1515static struct dadq_head dadq; 1504static struct dadq_head dadq;
1516static int dad_init = 0; 1505static int dad_init = 0;
1517static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */ 1506static int dad_maxtry = 15; /* max # of *tries* to transmit DAD packet */
1518static kmutex_t arp_dad_lock; 1507static kmutex_t arp_dad_lock;
1519 1508
1520static struct dadq * 1509static struct dadq *
1521arp_dad_find(struct ifaddr *ifa) 1510arp_dad_find(struct ifaddr *ifa)
1522{ 1511{
1523 struct dadq *dp; 1512 struct dadq *dp;
1524 1513
1525 KASSERT(mutex_owned(&arp_dad_lock)); 1514 KASSERT(mutex_owned(&arp_dad_lock));
1526 1515
1527 TAILQ_FOREACH(dp, &dadq, dad_list) { 1516 TAILQ_FOREACH(dp, &dadq, dad_list) {
1528 if (dp->dad_ifa == ifa) 1517 if (dp->dad_ifa == ifa)
1529 return dp; 1518 return dp;
1530 } 1519 }
1531 return NULL; 1520 return NULL;
1532} 1521}
1533 1522
1534static void 1523static void
1535arp_dad_starttimer(struct dadq *dp, int ticks) 1524arp_dad_starttimer(struct dadq *dp, int ticks)
1536{ 1525{
1537 1526
1538 callout_reset(&dp->dad_timer_ch, ticks, 1527 callout_reset(&dp->dad_timer_ch, ticks,
1539 (void (*)(void *))arp_dad_timer, (void *)dp->dad_ifa); 1528 (void (*)(void *))arp_dad_timer, (void *)dp->dad_ifa);
1540} 1529}
1541 1530
1542static void 1531static void
1543arp_dad_stoptimer(struct dadq *dp) 1532arp_dad_stoptimer(struct dadq *dp)
1544{ 1533{
1545 1534
1546 callout_halt(&dp->dad_timer_ch, softnet_lock); 1535 callout_halt(&dp->dad_timer_ch, softnet_lock);
1547} 1536}
1548 1537
1549static void 1538static void
1550arp_dad_output(struct dadq *dp, struct ifaddr *ifa) 1539arp_dad_output(struct dadq *dp, struct ifaddr *ifa)
1551{ 1540{
1552 struct in_ifaddr *ia = (struct in_ifaddr *)ifa; 1541 struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
1553 struct ifnet *ifp = ifa->ifa_ifp; 1542 struct ifnet *ifp = ifa->ifa_ifp;
1554 struct in_addr sip; 1543 struct in_addr sip;
1555 1544
1556 dp->dad_arp_tcount++; 1545 dp->dad_arp_tcount++;
1557 if ((ifp->if_flags & IFF_UP) == 0) 1546 if ((ifp->if_flags & IFF_UP) == 0)
1558 return; 1547 return;
1559 if ((ifp->if_flags & IFF_RUNNING) == 0) 1548 if ((ifp->if_flags & IFF_RUNNING) == 0)
1560 return; 1549 return;
1561 1550
1562 dp->dad_arp_tcount = 0; 1551 dp->dad_arp_tcount = 0;
1563 dp->dad_arp_ocount++; 1552 dp->dad_arp_ocount++;
1564 1553
1565 memset(&sip, 0, sizeof(sip)); 1554 memset(&sip, 0, sizeof(sip));
1566 arprequest(ifa->ifa_ifp, &sip, &ia->ia_addr.sin_addr, 1555 arprequest(ifa->ifa_ifp, &sip, &ia->ia_addr.sin_addr,
1567 CLLADDR(ifa->ifa_ifp->if_sadl)); 1556 CLLADDR(ifa->ifa_ifp->if_sadl));
1568} 1557}
1569 1558
1570/* 1559/*
1571 * Start Duplicate Address Detection (DAD) for specified interface address. 1560 * Start Duplicate Address Detection (DAD) for specified interface address.
1572 */ 1561 */
1573static void 1562static void
1574arp_dad_start(struct ifaddr *ifa) 1563arp_dad_start(struct ifaddr *ifa)
1575{ 1564{
1576 struct in_ifaddr *ia = (struct in_ifaddr *)ifa; 1565 struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
1577 struct dadq *dp; 1566 struct dadq *dp;
1578 1567
1579 if (!dad_init) { 1568 if (!dad_init) {
1580 TAILQ_INIT(&dadq); 1569 TAILQ_INIT(&dadq);
1581 mutex_init(&arp_dad_lock, MUTEX_DEFAULT, IPL_NONE); 1570 mutex_init(&arp_dad_lock, MUTEX_DEFAULT, IPL_NONE);
1582 dad_init++; 1571 dad_init++;
1583 } 1572 }
1584 1573
1585 /* 1574 /*
1586 * If we don't need DAD, don't do it. 1575 * If we don't need DAD, don't do it.
1587 * - DAD is disabled (ip_dad_count == 0) 1576 * - DAD is disabled (ip_dad_count == 0)
1588 */ 1577 */
1589 if (!(ia->ia4_flags & IN_IFF_TENTATIVE)) { 1578 if (!(ia->ia4_flags & IN_IFF_TENTATIVE)) {
1590 log(LOG_DEBUG, 1579 log(LOG_DEBUG,
1591 "%s: called with non-tentative address %s(%s)\n", __func__, 1580 "%s: called with non-tentative address %s(%s)\n", __func__,
1592 in_fmtaddr(ia->ia_addr.sin_addr), 1581 in_fmtaddr(ia->ia_addr.sin_addr),
1593 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1582 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1594 return; 1583 return;
1595 } 1584 }
1596 if (!ip_dad_count) { 1585 if (!ip_dad_count) {
1597 ia->ia4_flags &= ~IN_IFF_TENTATIVE; 1586 ia->ia4_flags &= ~IN_IFF_TENTATIVE;
1598 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); 1587 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
1599 arpannounce1(ifa); 1588 arpannounce1(ifa);
1600 return; 1589 return;
1601 } 1590 }
1602 KASSERT(ifa->ifa_ifp != NULL); 1591 KASSERT(ifa->ifa_ifp != NULL);
1603 if (!(ifa->ifa_ifp->if_flags & IFF_UP)) 1592 if (!(ifa->ifa_ifp->if_flags & IFF_UP))
1604 return; 1593 return;
1605 1594
1606 mutex_enter(&arp_dad_lock); 1595 mutex_enter(&arp_dad_lock);
1607 if (arp_dad_find(ifa) != NULL) { 1596 if (arp_dad_find(ifa) != NULL) {
1608 mutex_exit(&arp_dad_lock); 1597 mutex_exit(&arp_dad_lock);
1609 /* DAD already in progress */ 1598 /* DAD already in progress */
1610 return; 1599 return;
1611 } 1600 }
1612 1601
1613 dp = malloc(sizeof(*dp), M_IPARP, M_NOWAIT); 1602 dp = malloc(sizeof(*dp), M_IPARP, M_NOWAIT);
1614 if (dp == NULL) { 1603 if (dp == NULL) {
1615 mutex_exit(&arp_dad_lock); 1604 mutex_exit(&arp_dad_lock);
1616 log(LOG_ERR, "%s: memory allocation failed for %s(%s)\n", 1605 log(LOG_ERR, "%s: memory allocation failed for %s(%s)\n",
1617 __func__, in_fmtaddr(ia->ia_addr.sin_addr), 1606 __func__, in_fmtaddr(ia->ia_addr.sin_addr),
1618 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1607 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1619 return; 1608 return;
1620 } 1609 }
1621 memset(dp, 0, sizeof(*dp)); 1610 memset(dp, 0, sizeof(*dp));
1622 callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE); 1611 callout_init(&dp->dad_timer_ch, CALLOUT_MPSAFE);
1623 1612
1624 /* 1613 /*
1625 * Send ARP packet for DAD, ip_dad_count times. 1614 * Send ARP packet for DAD, ip_dad_count times.
1626 * Note that we must delay the first transmission. 1615 * Note that we must delay the first transmission.
1627 */ 1616 */
1628 dp->dad_ifa = ifa; 1617 dp->dad_ifa = ifa;
1629 ifaref(ifa); /* just for safety */ 1618 ifaref(ifa); /* just for safety */
1630 dp->dad_count = ip_dad_count; 1619 dp->dad_count = ip_dad_count;
1631 dp->dad_arp_announce = 0; /* Will be set when starting to announce */ 1620 dp->dad_arp_announce = 0; /* Will be set when starting to announce */
1632 dp->dad_arp_acount = dp->dad_arp_ocount = dp->dad_arp_tcount = 0; 1621 dp->dad_arp_acount = dp->dad_arp_ocount = dp->dad_arp_tcount = 0;
1633 TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list); 1622 TAILQ_INSERT_TAIL(&dadq, (struct dadq *)dp, dad_list);
1634 1623
1635 arplog(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp), 1624 arplog(LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
1636 in_fmtaddr(ia->ia_addr.sin_addr)); 1625 in_fmtaddr(ia->ia_addr.sin_addr));
1637 1626
1638 arp_dad_starttimer(dp, cprng_fast32() % (PROBE_WAIT * hz)); 1627 arp_dad_starttimer(dp, cprng_fast32() % (PROBE_WAIT * hz));
1639 1628
1640 mutex_exit(&arp_dad_lock); 1629 mutex_exit(&arp_dad_lock);
1641} 1630}
1642 1631
1643/* 1632/*
1644 * terminate DAD unconditionally. used for address removals. 1633 * terminate DAD unconditionally. used for address removals.
1645 */ 1634 */
1646static void 1635static void
1647arp_dad_stop(struct ifaddr *ifa) 1636arp_dad_stop(struct ifaddr *ifa)
1648{ 1637{
1649 struct dadq *dp; 1638 struct dadq *dp;
1650 1639
1651 if (!dad_init) 1640 if (!dad_init)
1652 return; 1641 return;
1653 1642
1654 mutex_enter(&arp_dad_lock); 1643 mutex_enter(&arp_dad_lock);
1655 dp = arp_dad_find(ifa); 1644 dp = arp_dad_find(ifa);
1656 if (dp == NULL) { 1645 if (dp == NULL) {
1657 mutex_exit(&arp_dad_lock); 1646 mutex_exit(&arp_dad_lock);
1658 /* DAD wasn't started yet */ 1647 /* DAD wasn't started yet */
1659 return; 1648 return;
1660 } 1649 }
1661 1650
1662 /* Prevent the timer from running anymore. */ 1651 /* Prevent the timer from running anymore. */
1663 TAILQ_REMOVE(&dadq, dp, dad_list); 1652 TAILQ_REMOVE(&dadq, dp, dad_list);
1664 mutex_exit(&arp_dad_lock); 1653 mutex_exit(&arp_dad_lock);
1665 1654
1666 arp_dad_stoptimer(dp); 1655 arp_dad_stoptimer(dp);
1667 1656
1668 free(dp, M_IPARP); 1657 free(dp, M_IPARP);
1669 dp = NULL; 1658 dp = NULL;
1670 ifafree(ifa); 1659 ifafree(ifa);
1671} 1660}
1672 1661
1673static void 1662static void
1674arp_dad_timer(struct ifaddr *ifa) 1663arp_dad_timer(struct ifaddr *ifa)
1675{ 1664{
1676 struct in_ifaddr *ia = (struct in_ifaddr *)ifa; 1665 struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
1677 struct dadq *dp; 1666 struct dadq *dp;
1678 1667
1679 mutex_enter(softnet_lock); 1668 mutex_enter(softnet_lock);
1680 KERNEL_LOCK(1, NULL); 1669 KERNEL_LOCK(1, NULL);
1681 mutex_enter(&arp_dad_lock); 1670 mutex_enter(&arp_dad_lock);
1682 1671
1683 /* Sanity check */ 1672 /* Sanity check */
1684 if (ia == NULL) { 1673 if (ia == NULL) {
1685 log(LOG_ERR, "%s: called with null parameter\n", __func__); 1674 log(LOG_ERR, "%s: called with null parameter\n", __func__);
1686 goto done; 1675 goto done;
1687 } 1676 }
1688 dp = arp_dad_find(ifa); 1677 dp = arp_dad_find(ifa);
1689 if (dp == NULL) { 1678 if (dp == NULL) {
1690 /* DAD seems to be stopping, so do nothing. */ 1679 /* DAD seems to be stopping, so do nothing. */
1691 goto done; 1680 goto done;
1692 } 1681 }
1693 if (ia->ia4_flags & IN_IFF_DUPLICATED) { 1682 if (ia->ia4_flags & IN_IFF_DUPLICATED) {
1694 log(LOG_ERR, "%s: called with duplicate address %s(%s)\n", 1683 log(LOG_ERR, "%s: called with duplicate address %s(%s)\n",
1695 __func__, in_fmtaddr(ia->ia_addr.sin_addr), 1684 __func__, in_fmtaddr(ia->ia_addr.sin_addr),
1696 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1685 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1697 goto done; 1686 goto done;
1698 } 1687 }
1699 if ((ia->ia4_flags & IN_IFF_TENTATIVE) == 0 && dp->dad_arp_acount == 0) 1688 if ((ia->ia4_flags & IN_IFF_TENTATIVE) == 0 && dp->dad_arp_acount == 0)
1700 { 1689 {
1701 log(LOG_ERR, "%s: called with non-tentative address %s(%s)\n", 1690 log(LOG_ERR, "%s: called with non-tentative address %s(%s)\n",
1702 __func__, in_fmtaddr(ia->ia_addr.sin_addr), 1691 __func__, in_fmtaddr(ia->ia_addr.sin_addr),
1703 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???"); 1692 ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1704 goto done; 1693 goto done;
1705 } 1694 }
1706 1695
1707 /* timeouted with IFF_{RUNNING,UP} check */ 1696 /* timeouted with IFF_{RUNNING,UP} check */
1708 if (dp->dad_arp_tcount > dad_maxtry) { 1697 if (dp->dad_arp_tcount > dad_maxtry) {
1709 arplog(LOG_INFO, "%s: could not run DAD, driver problem?\n", 1698 arplog(LOG_INFO, "%s: could not run DAD, driver problem?\n",
1710 if_name(ifa->ifa_ifp)); 1699 if_name(ifa->ifa_ifp));
1711 1700
1712 TAILQ_REMOVE(&dadq, dp, dad_list); 1701 TAILQ_REMOVE(&dadq, dp, dad_list);
1713 free(dp, M_IPARP); 1702 free(dp, M_IPARP);
1714 dp = NULL; 1703 dp = NULL;
1715 ifafree(ifa); 1704 ifafree(ifa);
1716 goto done; 1705 goto done;
1717 } 1706 }
1718 1707
1719 /* Need more checks? */ 1708 /* Need more checks? */
1720 if (dp->dad_arp_ocount < dp->dad_count) { 1709 if (dp->dad_arp_ocount < dp->dad_count) {
1721 int adelay; 1710 int adelay;
1722 1711
1723 /* 1712 /*
1724 * We have more ARP to go. Send ARP packet for DAD. 1713 * We have more ARP to go. Send ARP packet for DAD.
1725 */ 1714 */
1726 arp_dad_output(dp, ifa); 1715 arp_dad_output(dp, ifa);
1727 if (dp->dad_arp_ocount < dp->dad_count) 1716 if (dp->dad_arp_ocount < dp->dad_count)
1728 adelay = (PROBE_MIN * hz) + 1717 adelay = (PROBE_MIN * hz) +
1729 (cprng_fast32() % 1718 (cprng_fast32() %
1730 ((PROBE_MAX * hz) - (PROBE_MIN * hz))); 1719 ((PROBE_MAX * hz) - (PROBE_MIN * hz)));
1731 else 1720 else
1732 adelay = ANNOUNCE_WAIT * hz; 1721 adelay = ANNOUNCE_WAIT * hz;
1733 arp_dad_starttimer(dp, adelay); 1722 arp_dad_starttimer(dp, adelay);
1734 goto done; 1723 goto done;
1735 } else if (dp->dad_arp_acount == 0) { 1724 } else if (dp->dad_arp_acount == 0) {
1736 /* 1725 /*
1737 * We are done with DAD. 1726 * We are done with DAD.
1738 * No duplicate address found. 1727 * No duplicate address found.
1739 */ 1728 */
1740 ia->ia4_flags &= ~IN_IFF_TENTATIVE; 1729 ia->ia4_flags &= ~IN_IFF_TENTATIVE;
1741 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); 1730 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
1742 arplog(LOG_DEBUG, 1731 arplog(LOG_DEBUG,
1743 "%s: DAD complete for %s - no duplicates found\n", 1732 "%s: DAD complete for %s - no duplicates found\n",
1744 if_name(ifa->ifa_ifp), 1733 if_name(ifa->ifa_ifp),
1745 in_fmtaddr(ia->ia_addr.sin_addr)); 1734 in_fmtaddr(ia->ia_addr.sin_addr));
1746 dp->dad_arp_announce = ANNOUNCE_NUM; 1735 dp->dad_arp_announce = ANNOUNCE_NUM;
1747 goto announce; 1736 goto announce;
1748 } else if (dp->dad_arp_acount < dp->dad_arp_announce) { 1737 } else if (dp->dad_arp_acount < dp->dad_arp_announce) {
1749announce: 1738announce:
1750 /* 1739 /*
1751 * Announce the address. 1740 * Announce the address.
1752 */ 1741 */
1753 arpannounce1(ifa); 1742 arpannounce1(ifa);
1754 dp->dad_arp_acount++; 1743 dp->dad_arp_acount++;
1755 if (dp->dad_arp_acount < dp->dad_arp_announce) { 1744 if (dp->dad_arp_acount < dp->dad_arp_announce) {
1756 arp_dad_starttimer(dp, ANNOUNCE_INTERVAL * hz); 1745 arp_dad_starttimer(dp, ANNOUNCE_INTERVAL * hz);
1757 goto done; 1746 goto done;
1758 } 1747 }
1759 arplog(LOG_DEBUG, 1748 arplog(LOG_DEBUG,
1760 "%s: ARP announcement complete for %s\n", 1749 "%s: ARP announcement complete for %s\n",
1761 if_name(ifa->ifa_ifp), 1750 if_name(ifa->ifa_ifp),
1762 in_fmtaddr(ia->ia_addr.sin_addr)); 1751 in_fmtaddr(ia->ia_addr.sin_addr));
1763 } 1752 }
1764 1753
1765 TAILQ_REMOVE(&dadq, dp, dad_list); 1754 TAILQ_REMOVE(&dadq, dp, dad_list);
1766 free(dp, M_IPARP); 1755 free(dp, M_IPARP);
1767 dp = NULL; 1756 dp = NULL;
1768 ifafree(ifa); 1757 ifafree(ifa);
1769 1758
1770done: 1759done:
1771 mutex_exit(&arp_dad_lock); 1760 mutex_exit(&arp_dad_lock);
1772 KERNEL_UNLOCK_ONE(NULL); 1761 KERNEL_UNLOCK_ONE(NULL);
1773 mutex_exit(softnet_lock); 1762 mutex_exit(softnet_lock);
1774} 1763}
1775 1764
1776static void 1765static void
1777arp_dad_duplicated(struct ifaddr *ifa) 1766arp_dad_duplicated(struct ifaddr *ifa, const char *sha)
1778{ 1767{
1779 struct in_ifaddr *ia = (struct in_ifaddr *)ifa; 1768 struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
1780 struct ifnet *ifp; 1769 struct ifnet *ifp = ifa->ifa_ifp;
1781 struct dadq *dp; 1770 const char *iastr = in_fmtaddr(ia->ia_addr.sin_addr);
1782 1771
1783 mutex_enter(&arp_dad_lock); 1772 if (ia->ia4_flags & (IN_IFF_TENTATIVE|IN_IFF_DUPLICATED)) {
1784 dp = arp_dad_find(ifa); 1773 log(LOG_ERR,
1785 if (dp == NULL) { 1774 "%s: DAD duplicate address %s from %s\n",
1786 mutex_exit(&arp_dad_lock); 1775 if_name(ifp), iastr, sha);
1787 /* DAD seems to be stopping, so do nothing. */ 1776 } else if (ia->ia_dad_defended == 0 ||
 1777 ia->ia_dad_defended < time_uptime - DEFEND_INTERVAL) {
 1778 ia->ia_dad_defended = time_uptime;
 1779 arpannounce1(ifa);
 1780 log(LOG_ERR,
 1781 "%s: DAD defended address %s from %s\n",
 1782 if_name(ifp), iastr, sha);
1788 return; 1783 return;
 1784 } else {
 1785 /* If DAD is disabled, just report the duplicate. */
 1786 if (ip_dad_count == 0) {
 1787 log(LOG_ERR,
 1788 "%s: DAD ignoring duplicate address %s from %s\n",
 1789 if_name(ifp), iastr, sha);
 1790 return;
 1791 }
 1792 log(LOG_ERR,
 1793 "%s: DAD defence failed for %s from %s\n",
 1794 if_name(ifp), iastr, sha);
1789 } 1795 }
1790 1796
1791 ifp = ifa->ifa_ifp; 1797 arp_dad_stop(ifa);
1792 log(LOG_ERR, 
1793 "%s: DAD detected duplicate IPv4 address %s: ARP out=%d\n", 
1794 if_name(ifp), in_fmtaddr(ia->ia_addr.sin_addr), 
1795 dp->dad_arp_ocount); 
1796 1798
1797 ia->ia4_flags &= ~IN_IFF_TENTATIVE; 1799 ia->ia4_flags &= ~IN_IFF_TENTATIVE;
1798 ia->ia4_flags |= IN_IFF_DUPLICATED; 1800 if ((ia->ia4_flags & IN_IFF_DUPLICATED) == 0) {
1799 1801 ia->ia4_flags |= IN_IFF_DUPLICATED;
1800 /* We are done with DAD, with duplicated address found. (failure) */ 1802 /* Inform the routing socket of the duplicate address */
1801 arp_dad_stoptimer(dp); 1803 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
1802 1804 }
1803 /* Inform the routing socket that DAD has completed */ 
1804 rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); 
1805 
1806 TAILQ_REMOVE(&dadq, dp, dad_list); 
1807 mutex_exit(&arp_dad_lock); 
1808 
1809 free(dp, M_IPARP); 
1810 dp = NULL; 
1811 ifafree(ifa); 
1812} 1805}
1813 1806
1814/* 1807/*
1815 * Called from 10 Mb/s Ethernet interrupt handlers 1808 * Called from 10 Mb/s Ethernet interrupt handlers
1816 * when ether packet type ETHERTYPE_REVARP 1809 * when ether packet type ETHERTYPE_REVARP
1817 * is received. Common length and type checks are done here, 1810 * is received. Common length and type checks are done here,
1818 * then the protocol-specific routine is called. 1811 * then the protocol-specific routine is called.
1819 */ 1812 */
1820void 1813void
1821revarpinput(struct mbuf *m) 1814revarpinput(struct mbuf *m)
1822{ 1815{
1823 struct arphdr *ar; 1816 struct arphdr *ar;
1824 1817
1825 if (m->m_len < sizeof(struct arphdr)) 1818 if (m->m_len < sizeof(struct arphdr))
1826 goto out; 1819 goto out;
1827 ar = mtod(m, struct arphdr *); 1820 ar = mtod(m, struct arphdr *);
1828#if 0 /* XXX I don't think we need this... and it will prevent other LL */ 1821#if 0 /* XXX I don't think we need this... and it will prevent other LL */
1829 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER) 1822 if (ntohs(ar->ar_hrd) != ARPHRD_ETHER)
1830 goto out; 1823 goto out;
1831#endif 1824#endif
1832 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln)) 1825 if (m->m_len < sizeof(struct arphdr) + 2 * (ar->ar_hln + ar->ar_pln))
1833 goto out; 1826 goto out;
1834 switch (ntohs(ar->ar_pro)) { 1827 switch (ntohs(ar->ar_pro)) {
1835 case ETHERTYPE_IP: 1828 case ETHERTYPE_IP:
1836 case ETHERTYPE_IPTRAILERS: 1829 case ETHERTYPE_IPTRAILERS:
1837 in_revarpinput(m); 1830 in_revarpinput(m);
1838 return; 1831 return;
1839 1832
1840 default: 1833 default:
1841 break; 1834 break;
1842 } 1835 }
1843out: 1836out:
1844 m_freem(m); 1837 m_freem(m);
1845} 1838}
1846 1839
1847/* 1840/*
1848 * RARP for Internet protocols on 10 Mb/s Ethernet. 1841 * RARP for Internet protocols on 10 Mb/s Ethernet.
1849 * Algorithm is that given in RFC 903. 1842 * Algorithm is that given in RFC 903.
1850 * We are only using for bootstrap purposes to get an ip address for one of 1843 * We are only using for bootstrap purposes to get an ip address for one of
1851 * our interfaces. Thus we support no user-interface. 1844 * our interfaces. Thus we support no user-interface.
1852 * 1845 *
1853 * Since the contents of the RARP reply are specific to the interface that 1846 * Since the contents of the RARP reply are specific to the interface that
1854 * sent the request, this code must ensure that they are properly associated. 1847 * sent the request, this code must ensure that they are properly associated.
1855 * 1848 *
1856 * Note: also supports ARP via RARP packets, per the RFC. 1849 * Note: also supports ARP via RARP packets, per the RFC.
1857 */ 1850 */
1858void 1851void
1859in_revarpinput(struct mbuf *m) 1852in_revarpinput(struct mbuf *m)
1860{ 1853{
1861 struct arphdr *ah; 1854 struct arphdr *ah;
1862 void *tha; 1855 void *tha;
1863 int op; 1856 int op;
1864 struct ifnet *rcvif; 1857 struct ifnet *rcvif;
1865 int s; 1858 int s;
1866 1859
1867 ah = mtod(m, struct arphdr *); 1860 ah = mtod(m, struct arphdr *);
1868 op = ntohs(ah->ar_op); 1861 op = ntohs(ah->ar_op);
1869 1862
1870 rcvif = m_get_rcvif(m, &s); 1863 rcvif = m_get_rcvif(m, &s);
1871 switch (rcvif->if_type) { 1864 switch (rcvif->if_type) {
1872 case IFT_IEEE1394: 1865 case IFT_IEEE1394:
1873 /* ARP without target hardware address is not supported */ 1866 /* ARP without target hardware address is not supported */
1874 goto out; 1867 goto out;
1875 default: 1868 default:
1876 break; 1869 break;
1877 } 1870 }
1878 1871
1879 switch (op) { 1872 switch (op) {
1880 case ARPOP_REQUEST: 1873 case ARPOP_REQUEST:
1881 case ARPOP_REPLY: /* per RFC */ 1874 case ARPOP_REPLY: /* per RFC */
1882 m_put_rcvif(rcvif, &s); 1875 m_put_rcvif(rcvif, &s);
1883 in_arpinput(m); 1876 in_arpinput(m);
1884 return; 1877 return;
1885 case ARPOP_REVREPLY: 1878 case ARPOP_REVREPLY:
1886 break; 1879 break;
1887 case ARPOP_REVREQUEST: /* handled by rarpd(8) */ 1880 case ARPOP_REVREQUEST: /* handled by rarpd(8) */
1888 default: 1881 default:
1889 goto out; 1882 goto out;
1890 } 1883 }
1891 if (!revarp_in_progress) 1884 if (!revarp_in_progress)
1892 goto out; 1885 goto out;
1893 if (rcvif != myip_ifp) /* !same interface */ 1886 if (rcvif != myip_ifp) /* !same interface */
1894 goto out; 1887 goto out;
1895 if (myip_initialized) 1888 if (myip_initialized)
1896 goto wake; 1889 goto wake;
1897 tha = ar_tha(ah); 1890 tha = ar_tha(ah);
1898 if (tha == NULL) 1891 if (tha == NULL)
1899 goto out; 1892 goto out;
1900 if (memcmp(tha, CLLADDR(rcvif->if_sadl), rcvif->if_sadl->sdl_alen)) 1893 if (memcmp(tha, CLLADDR(rcvif->if_sadl), rcvif->if_sadl->sdl_alen))
1901 goto out; 1894 goto out;
1902 memcpy(&srv_ip, ar_spa(ah), sizeof(srv_ip)); 1895 memcpy(&srv_ip, ar_spa(ah), sizeof(srv_ip));
1903 memcpy(&myip, ar_tpa(ah), sizeof(myip)); 1896 memcpy(&myip, ar_tpa(ah), sizeof(myip));
1904 myip_initialized = 1; 1897 myip_initialized = 1;
1905wake: /* Do wakeup every time in case it was missed. */ 1898wake: /* Do wakeup every time in case it was missed. */
1906 wakeup((void *)&myip); 1899 wakeup((void *)&myip);
1907 1900
1908out: 1901out:
1909 m_put_rcvif(rcvif, &s); 1902 m_put_rcvif(rcvif, &s);
1910 m_freem(m); 1903 m_freem(m);
1911} 1904}
1912 1905
1913/* 1906/*
1914 * Send a RARP request for the ip address of the specified interface. 1907 * Send a RARP request for the ip address of the specified interface.
1915 * The request should be RFC 903-compliant. 1908 * The request should be RFC 903-compliant.
1916 */ 1909 */
1917static void 1910static void
1918revarprequest(struct ifnet *ifp) 1911revarprequest(struct ifnet *ifp)
1919{ 1912{
1920 struct sockaddr sa; 1913 struct sockaddr sa;
1921 struct mbuf *m; 1914 struct mbuf *m;
1922 struct arphdr *ah; 1915 struct arphdr *ah;
1923 void *tha; 1916 void *tha;
1924 1917
1925 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) 1918 if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
1926 return; 1919 return;
1927 MCLAIM(m, &arpdomain.dom_mowner); 1920 MCLAIM(m, &arpdomain.dom_mowner);
1928 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) + 1921 m->m_len = sizeof(*ah) + 2*sizeof(struct in_addr) +
1929 2*ifp->if_addrlen; 1922 2*ifp->if_addrlen;
1930 m->m_pkthdr.len = m->m_len; 1923 m->m_pkthdr.len = m->m_len;
1931 MH_ALIGN(m, m->m_len); 1924 MH_ALIGN(m, m->m_len);
1932 ah = mtod(m, struct arphdr *); 1925 ah = mtod(m, struct arphdr *);
1933 memset(ah, 0, m->m_len); 1926 memset(ah, 0, m->m_len);
1934 ah->ar_pro = htons(ETHERTYPE_IP); 1927 ah->ar_pro = htons(ETHERTYPE_IP);
1935 ah->ar_hln = ifp->if_addrlen; /* hardware address length */ 1928 ah->ar_hln = ifp->if_addrlen; /* hardware address length */
1936 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */ 1929 ah->ar_pln = sizeof(struct in_addr); /* protocol address length */
1937 ah->ar_op = htons(ARPOP_REVREQUEST); 1930 ah->ar_op = htons(ARPOP_REVREQUEST);
1938 1931
1939 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln); 1932 memcpy(ar_sha(ah), CLLADDR(ifp->if_sadl), ah->ar_hln);
1940 tha = ar_tha(ah); 1933 tha = ar_tha(ah);
1941 if (tha == NULL) { 1934 if (tha == NULL) {
1942 m_free(m); 1935 m_free(m);
1943 return; 1936 return;
1944 } 1937 }
1945 memcpy(tha, CLLADDR(ifp->if_sadl), ah->ar_hln); 1938 memcpy(tha, CLLADDR(ifp->if_sadl), ah->ar_hln);
1946 1939
1947 sa.sa_family = AF_ARP; 1940 sa.sa_family = AF_ARP;
1948 sa.sa_len = 2; 1941 sa.sa_len = 2;
1949 m->m_flags |= M_BCAST; 1942 m->m_flags |= M_BCAST;
1950 1943
1951 if_output_lock(ifp, ifp, m, &sa, NULL); 1944 if_output_lock(ifp, ifp, m, &sa, NULL);
1952} 1945}
1953 1946
1954/* 1947/*
1955 * RARP for the ip address of the specified interface, but also 1948 * RARP for the ip address of the specified interface, but also
1956 * save the ip address of the server that sent the answer. 1949 * save the ip address of the server that sent the answer.
1957 * Timeout if no response is received. 1950 * Timeout if no response is received.
1958 */ 1951 */
1959int 1952int
1960revarpwhoarewe(struct ifnet *ifp, struct in_addr *serv_in, 1953revarpwhoarewe(struct ifnet *ifp, struct in_addr *serv_in,
1961 struct in_addr *clnt_in) 1954 struct in_addr *clnt_in)
1962{ 1955{
1963 int result, count = 20; 1956 int result, count = 20;
1964 1957
1965 myip_initialized = 0; 1958 myip_initialized = 0;
1966 myip_ifp = ifp; 1959 myip_ifp = ifp;
1967 1960
1968 revarp_in_progress = 1; 1961 revarp_in_progress = 1;
1969 while (count--) { 1962 while (count--) {
1970 revarprequest(ifp); 1963 revarprequest(ifp);
1971 result = tsleep((void *)&myip, PSOCK, "revarp", hz/2); 1964 result = tsleep((void *)&myip, PSOCK, "revarp", hz/2);
1972 if (result != EWOULDBLOCK) 1965 if (result != EWOULDBLOCK)
1973 break; 1966 break;
1974 } 1967 }
1975 revarp_in_progress = 0; 1968 revarp_in_progress = 0;
1976 1969
1977 if (!myip_initialized) 1970 if (!myip_initialized)
1978 return ENETUNREACH; 1971 return ENETUNREACH;
1979 1972
1980 memcpy(serv_in, &srv_ip, sizeof(*serv_in)); 1973 memcpy(serv_in, &srv_ip, sizeof(*serv_in));
1981 memcpy(clnt_in, &myip, sizeof(*clnt_in)); 1974 memcpy(clnt_in, &myip, sizeof(*clnt_in));
1982 return 0; 1975 return 0;
1983} 1976}
1984 1977
1985void 1978void
1986arp_stat_add(int type, uint64_t count) 1979arp_stat_add(int type, uint64_t count)
1987{ 1980{
1988 ARP_STATADD(type, count); 1981 ARP_STATADD(type, count);
1989} 1982}
1990 1983
1991static int 1984static int
1992sysctl_net_inet_arp_stats(SYSCTLFN_ARGS) 1985sysctl_net_inet_arp_stats(SYSCTLFN_ARGS)
1993{ 1986{
1994 1987
1995 return NETSTAT_SYSCTL(arpstat_percpu, ARP_NSTATS); 1988 return NETSTAT_SYSCTL(arpstat_percpu, ARP_NSTATS);
1996} 1989}
1997 1990
1998static void 1991static void
1999sysctl_net_inet_arp_setup(struct sysctllog **clog) 1992sysctl_net_inet_arp_setup(struct sysctllog **clog)
2000{ 1993{
2001 const struct sysctlnode *node; 1994 const struct sysctlnode *node;
2002 1995
2003 sysctl_createv(clog, 0, NULL, NULL, 1996 sysctl_createv(clog, 0, NULL, NULL,
2004 CTLFLAG_PERMANENT, 1997 CTLFLAG_PERMANENT,
2005 CTLTYPE_NODE, "inet", NULL, 1998 CTLTYPE_NODE, "inet", NULL,
2006 NULL, 0, NULL, 0, 1999 NULL, 0, NULL, 0,
2007 CTL_NET, PF_INET, CTL_EOL); 2000 CTL_NET, PF_INET, CTL_EOL);
2008 sysctl_createv(clog, 0, NULL, &node, 2001 sysctl_createv(clog, 0, NULL, &node,
2009 CTLFLAG_PERMANENT, 2002 CTLFLAG_PERMANENT,
2010 CTLTYPE_NODE, "arp", 2003 CTLTYPE_NODE, "arp",
2011 SYSCTL_DESCR("Address Resolution Protocol"), 2004 SYSCTL_DESCR("Address Resolution Protocol"),
2012 NULL, 0, NULL, 0, 2005 NULL, 0, NULL, 0,
2013 CTL_NET, PF_INET, CTL_CREATE, CTL_EOL); 2006 CTL_NET, PF_INET, CTL_CREATE, CTL_EOL);
2014 2007
2015 sysctl_createv(clog, 0, NULL, NULL, 2008 sysctl_createv(clog, 0, NULL, NULL,
2016 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2009 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2017 CTLTYPE_INT, "keep", 2010 CTLTYPE_INT, "keep",
2018 SYSCTL_DESCR("Valid ARP entry lifetime in seconds"), 2011 SYSCTL_DESCR("Valid ARP entry lifetime in seconds"),
2019 NULL, 0, &arpt_keep, 0, 2012 NULL, 0, &arpt_keep, 0,
2020 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2013 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2021 2014
2022 sysctl_createv(clog, 0, NULL, NULL, 2015 sysctl_createv(clog, 0, NULL, NULL,
2023 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2016 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2024 CTLTYPE_INT, "down", 2017 CTLTYPE_INT, "down",
2025 SYSCTL_DESCR("Failed ARP entry lifetime in seconds"), 2018 SYSCTL_DESCR("Failed ARP entry lifetime in seconds"),
2026 NULL, 0, &arpt_down, 0, 2019 NULL, 0, &arpt_down, 0,
2027 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2020 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2028 2021
2029 sysctl_createv(clog, 0, NULL, NULL, 2022 sysctl_createv(clog, 0, NULL, NULL,
2030 CTLFLAG_PERMANENT, 2023 CTLFLAG_PERMANENT,
2031 CTLTYPE_STRUCT, "stats", 2024 CTLTYPE_STRUCT, "stats",
2032 SYSCTL_DESCR("ARP statistics"), 2025 SYSCTL_DESCR("ARP statistics"),
2033 sysctl_net_inet_arp_stats, 0, NULL, 0, 2026 sysctl_net_inet_arp_stats, 0, NULL, 0,
2034 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2027 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2035 2028
2036 sysctl_createv(clog, 0, NULL, NULL, 2029 sysctl_createv(clog, 0, NULL, NULL,
2037 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2030 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2038 CTLTYPE_INT, "log_movements", 2031 CTLTYPE_INT, "log_movements",
2039 SYSCTL_DESCR("log ARP replies from MACs different than" 2032 SYSCTL_DESCR("log ARP replies from MACs different than"
2040 " the one in the cache"), 2033 " the one in the cache"),
2041 NULL, 0, &log_movements, 0, 2034 NULL, 0, &log_movements, 0,
2042 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2035 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2043 2036
2044 sysctl_createv(clog, 0, NULL, NULL, 2037 sysctl_createv(clog, 0, NULL, NULL,
2045 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2038 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2046 CTLTYPE_INT, "log_permanent_modify", 2039 CTLTYPE_INT, "log_permanent_modify",
2047 SYSCTL_DESCR("log ARP replies from MACs different than" 2040 SYSCTL_DESCR("log ARP replies from MACs different than"
2048 " the one in the permanent arp entry"), 2041 " the one in the permanent arp entry"),
2049 NULL, 0, &log_permanent_modify, 0, 2042 NULL, 0, &log_permanent_modify, 0,
2050 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2043 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2051 2044
2052 sysctl_createv(clog, 0, NULL, NULL, 2045 sysctl_createv(clog, 0, NULL, NULL,
2053 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2046 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2054 CTLTYPE_INT, "log_wrong_iface", 2047 CTLTYPE_INT, "log_wrong_iface",
2055 SYSCTL_DESCR("log ARP packets arriving on the wrong" 2048 SYSCTL_DESCR("log ARP packets arriving on the wrong"
2056 " interface"), 2049 " interface"),
2057 NULL, 0, &log_wrong_iface, 0, 2050 NULL, 0, &log_wrong_iface, 0,
2058 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2051 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2059 2052
2060 sysctl_createv(clog, 0, NULL, NULL, 2053 sysctl_createv(clog, 0, NULL, NULL,
2061 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2054 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2062 CTLTYPE_INT, "log_unknown_network", 2055 CTLTYPE_INT, "log_unknown_network",
2063 SYSCTL_DESCR("log ARP packets from non-local network"), 2056 SYSCTL_DESCR("log ARP packets from non-local network"),
2064 NULL, 0, &log_unknown_network, 0, 2057 NULL, 0, &log_unknown_network, 0,
2065 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2058 CTL_NET,PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2066 2059
2067 sysctl_createv(clog, 0, NULL, NULL, 2060 sysctl_createv(clog, 0, NULL, NULL,
2068 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 2061 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
2069 CTLTYPE_INT, "debug", 2062 CTLTYPE_INT, "debug",
2070 SYSCTL_DESCR("Enable ARP DAD debug output"), 2063 SYSCTL_DESCR("Enable ARP DAD debug output"),
2071 NULL, 0, &arp_debug, 0, 2064 NULL, 0, &arp_debug, 0,
2072 CTL_NET, PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL); 2065 CTL_NET, PF_INET, node->sysctl_num, CTL_CREATE, CTL_EOL);
2073} 2066}
2074 2067
2075#endif /* INET */ 2068#endif /* INET */

cvs diff -r1.87 -r1.88 src/sys/netinet/in_var.h (switch to unified diff)

--- src/sys/netinet/in_var.h 2016/09/29 15:18:18 1.87
+++ src/sys/netinet/in_var.h 2016/10/11 13:59:30 1.88
@@ -1,477 +1,478 @@ @@ -1,477 +1,478 @@
1/* $NetBSD: in_var.h,v 1.87 2016/09/29 15:18:18 roy Exp $ */ 1/* $NetBSD: in_var.h,v 1.88 2016/10/11 13:59:30 roy Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998 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) 1985, 1986, 1993 34 * Copyright (c) 1985, 1986, 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 * @(#)in_var.h 8.2 (Berkeley) 1/9/95 61 * @(#)in_var.h 8.2 (Berkeley) 1/9/95
62 */ 62 */
63 63
64#ifndef _NETINET_IN_VAR_H_ 64#ifndef _NETINET_IN_VAR_H_
65#define _NETINET_IN_VAR_H_ 65#define _NETINET_IN_VAR_H_
66 66
67#include <sys/queue.h> 67#include <sys/queue.h>
68 68
69#define IN_IFF_TENTATIVE 0x01 /* tentative address */ 69#define IN_IFF_TENTATIVE 0x01 /* tentative address */
70#define IN_IFF_DUPLICATED 0x02 /* DAD detected duplicate */ 70#define IN_IFF_DUPLICATED 0x02 /* DAD detected duplicate */
71#define IN_IFF_DETACHED 0x04 /* may be detached from the link */ 71#define IN_IFF_DETACHED 0x04 /* may be detached from the link */
72#define IN_IFF_TRYTENTATIVE 0x08 /* intent to try DAD */ 72#define IN_IFF_TRYTENTATIVE 0x08 /* intent to try DAD */
73 73
74#define IN_IFFBITS \ 74#define IN_IFFBITS \
75 "\020\1TENTATIVE\2DUPLICATED\3DETACHED\4TRYTENTATIVE" 75 "\020\1TENTATIVE\2DUPLICATED\3DETACHED\4TRYTENTATIVE"
76 76
77/* do not input/output */ 77/* do not input/output */
78#define IN_IFF_NOTREADY \ 78#define IN_IFF_NOTREADY \
79 (IN_IFF_TRYTENTATIVE | IN_IFF_TENTATIVE | IN_IFF_DUPLICATED) 79 (IN_IFF_TRYTENTATIVE | IN_IFF_TENTATIVE | IN_IFF_DUPLICATED)
80 80
81/* 81/*
82 * Interface address, Internet version. One of these structures 82 * Interface address, Internet version. One of these structures
83 * is allocated for each interface with an Internet address. 83 * is allocated for each interface with an Internet address.
84 * The ifaddr structure contains the protocol-independent part 84 * The ifaddr structure contains the protocol-independent part
85 * of the structure and is assumed to be first. 85 * of the structure and is assumed to be first.
86 */ 86 */
87struct in_ifaddr { 87struct in_ifaddr {
88 struct ifaddr ia_ifa; /* protocol-independent info */ 88 struct ifaddr ia_ifa; /* protocol-independent info */
89#define ia_ifp ia_ifa.ifa_ifp 89#define ia_ifp ia_ifa.ifa_ifp
90#define ia_flags ia_ifa.ifa_flags 90#define ia_flags ia_ifa.ifa_flags
91 /* ia_{,sub}net{,mask} in host order */ 91 /* ia_{,sub}net{,mask} in host order */
92 u_int32_t ia_net; /* network number of interface */ 92 u_int32_t ia_net; /* network number of interface */
93 u_int32_t ia_netmask; /* mask of net part */ 93 u_int32_t ia_netmask; /* mask of net part */
94 u_int32_t ia_subnet; /* subnet number, including net */ 94 u_int32_t ia_subnet; /* subnet number, including net */
95 u_int32_t ia_subnetmask; /* mask of subnet part */ 95 u_int32_t ia_subnetmask; /* mask of subnet part */
96 struct in_addr ia_netbroadcast; /* to recognize net broadcasts */ 96 struct in_addr ia_netbroadcast; /* to recognize net broadcasts */
97 LIST_ENTRY(in_ifaddr) ia_hash; /* entry in bucket of inet addresses */ 97 LIST_ENTRY(in_ifaddr) ia_hash; /* entry in bucket of inet addresses */
98 TAILQ_ENTRY(in_ifaddr) ia_list; /* list of internet addresses */ 98 TAILQ_ENTRY(in_ifaddr) ia_list; /* list of internet addresses */
99 struct sockaddr_in ia_addr; /* reserve space for interface name */ 99 struct sockaddr_in ia_addr; /* reserve space for interface name */
100 struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */ 100 struct sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
101#define ia_broadaddr ia_dstaddr 101#define ia_broadaddr ia_dstaddr
102 struct sockaddr_in ia_sockmask; /* reserve space for general netmask */ 102 struct sockaddr_in ia_sockmask; /* reserve space for general netmask */
103 LIST_HEAD(, in_multi) ia_multiaddrs; /* list of multicast addresses */ 103 LIST_HEAD(, in_multi) ia_multiaddrs; /* list of multicast addresses */
104 struct in_multi *ia_allhosts; /* multicast address record for 104 struct in_multi *ia_allhosts; /* multicast address record for
105 the allhosts multicast group */ 105 the allhosts multicast group */
106 uint16_t ia_idsalt; /* ip_id salt for this ia */ 106 uint16_t ia_idsalt; /* ip_id salt for this ia */
107 int ia4_flags; /* address flags */ 107 int ia4_flags; /* address flags */
108 void (*ia_dad_start) (struct ifaddr *); /* DAD start function */ 108 void (*ia_dad_start) (struct ifaddr *); /* DAD start function */
109 void (*ia_dad_stop) (struct ifaddr *); /* DAD stop function */ 109 void (*ia_dad_stop) (struct ifaddr *); /* DAD stop function */
 110 time_t ia_dad_defended; /* last time of DAD defence */
110 111
111#ifdef _KERNEL 112#ifdef _KERNEL
112 struct pslist_entry ia_hash_pslist_entry; 113 struct pslist_entry ia_hash_pslist_entry;
113 struct pslist_entry ia_pslist_entry; 114 struct pslist_entry ia_pslist_entry;
114#endif 115#endif
115}; 116};
116 117
117#ifdef _KERNEL 118#ifdef _KERNEL
118static inline void 119static inline void
119ia4_acquire(struct in_ifaddr *ia, struct psref *psref) 120ia4_acquire(struct in_ifaddr *ia, struct psref *psref)
120{ 121{
121 122
122 KASSERT(ia != NULL); 123 KASSERT(ia != NULL);
123 ifa_acquire(&ia->ia_ifa, psref); 124 ifa_acquire(&ia->ia_ifa, psref);
124} 125}
125 126
126static inline void 127static inline void
127ia4_release(struct in_ifaddr *ia, struct psref *psref) 128ia4_release(struct in_ifaddr *ia, struct psref *psref)
128{ 129{
129 130
130 if (ia == NULL) 131 if (ia == NULL)
131 return; 132 return;
132 ifa_release(&ia->ia_ifa, psref); 133 ifa_release(&ia->ia_ifa, psref);
133} 134}
134#endif 135#endif
135 136
136struct in_aliasreq { 137struct in_aliasreq {
137 char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */ 138 char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
138 struct sockaddr_in ifra_addr; 139 struct sockaddr_in ifra_addr;
139 struct sockaddr_in ifra_dstaddr; 140 struct sockaddr_in ifra_dstaddr;
140#define ifra_broadaddr ifra_dstaddr 141#define ifra_broadaddr ifra_dstaddr
141 struct sockaddr_in ifra_mask; 142 struct sockaddr_in ifra_mask;
142}; 143};
143 144
144/* 145/*
145 * Given a pointer to an in_ifaddr (ifaddr), 146 * Given a pointer to an in_ifaddr (ifaddr),
146 * return a pointer to the addr as a sockaddr_in. 147 * return a pointer to the addr as a sockaddr_in.
147 */ 148 */
148#define IA_SIN(ia) (&(((struct in_ifaddr *)(ia))->ia_addr)) 149#define IA_SIN(ia) (&(((struct in_ifaddr *)(ia))->ia_addr))
149 150
150#define iatoifa(ia) (struct ifaddr *)(ia) 151#define iatoifa(ia) (struct ifaddr *)(ia)
151 152
152#ifdef _KERNEL 153#ifdef _KERNEL
153 154
154/* Note: 61, 127, 251, 509, 1021, 2039 are good. */ 155/* Note: 61, 127, 251, 509, 1021, 2039 are good. */
155#ifndef IN_IFADDR_HASH_SIZE 156#ifndef IN_IFADDR_HASH_SIZE
156#define IN_IFADDR_HASH_SIZE 509 157#define IN_IFADDR_HASH_SIZE 509
157#endif 158#endif
158 159
159/* 160/*
160 * This is a bit unconventional, and wastes a little bit of space, but 161 * This is a bit unconventional, and wastes a little bit of space, but
161 * because we want a very even hash function we don't use & in_ifaddrhash 162 * because we want a very even hash function we don't use & in_ifaddrhash
162 * here, but rather % the hash size, which should obviously be prime. 163 * here, but rather % the hash size, which should obviously be prime.
163 */ 164 */
164 165
165#define IN_IFADDR_HASH(x) in_ifaddrhashtbl[(u_long)(x) % IN_IFADDR_HASH_SIZE] 166#define IN_IFADDR_HASH(x) in_ifaddrhashtbl[(u_long)(x) % IN_IFADDR_HASH_SIZE]
166 167
167LIST_HEAD(in_ifaddrhashhead, in_ifaddr); /* Type of the hash head */ 168LIST_HEAD(in_ifaddrhashhead, in_ifaddr); /* Type of the hash head */
168TAILQ_HEAD(in_ifaddrhead, in_ifaddr); /* Type of the list head */ 169TAILQ_HEAD(in_ifaddrhead, in_ifaddr); /* Type of the list head */
169 170
170extern u_long in_ifaddrhash; /* size of hash table - 1 */ 171extern u_long in_ifaddrhash; /* size of hash table - 1 */
171extern struct in_ifaddrhashhead *in_ifaddrhashtbl; /* Hash table head */ 172extern struct in_ifaddrhashhead *in_ifaddrhashtbl; /* Hash table head */
172extern struct in_ifaddrhead in_ifaddrhead; /* List head (in ip_input) */ 173extern struct in_ifaddrhead in_ifaddrhead; /* List head (in ip_input) */
173 174
174extern struct pslist_head *in_ifaddrhashtbl_pslist; 175extern struct pslist_head *in_ifaddrhashtbl_pslist;
175extern u_long in_ifaddrhash_pslist; 176extern u_long in_ifaddrhash_pslist;
176extern struct pslist_head in_ifaddrhead_pslist; 177extern struct pslist_head in_ifaddrhead_pslist;
177 178
178#define IN_IFADDR_HASH_PSLIST(x) \ 179#define IN_IFADDR_HASH_PSLIST(x) \
179 in_ifaddrhashtbl_pslist[(u_long)(x) % IN_IFADDR_HASH_SIZE] 180 in_ifaddrhashtbl_pslist[(u_long)(x) % IN_IFADDR_HASH_SIZE]
180 181
181#define IN_ADDRHASH_READER_FOREACH(__ia, __addr) \ 182#define IN_ADDRHASH_READER_FOREACH(__ia, __addr) \
182 PSLIST_READER_FOREACH((__ia), &IN_IFADDR_HASH_PSLIST(__addr), \ 183 PSLIST_READER_FOREACH((__ia), &IN_IFADDR_HASH_PSLIST(__addr), \
183 struct in_ifaddr, ia_hash_pslist_entry) 184 struct in_ifaddr, ia_hash_pslist_entry)
184#define IN_ADDRHASH_WRITER_INSERT_HEAD(__ia) \ 185#define IN_ADDRHASH_WRITER_INSERT_HEAD(__ia) \
185 PSLIST_WRITER_INSERT_HEAD( \ 186 PSLIST_WRITER_INSERT_HEAD( \
186 &IN_IFADDR_HASH_PSLIST((__ia)->ia_addr.sin_addr.s_addr), \ 187 &IN_IFADDR_HASH_PSLIST((__ia)->ia_addr.sin_addr.s_addr), \
187 (__ia), ia_hash_pslist_entry) 188 (__ia), ia_hash_pslist_entry)
188#define IN_ADDRHASH_WRITER_REMOVE(__ia) \ 189#define IN_ADDRHASH_WRITER_REMOVE(__ia) \
189 PSLIST_WRITER_REMOVE((__ia), ia_hash_pslist_entry) 190 PSLIST_WRITER_REMOVE((__ia), ia_hash_pslist_entry)
190#define IN_ADDRHASH_ENTRY_INIT(__ia) \ 191#define IN_ADDRHASH_ENTRY_INIT(__ia) \
191 PSLIST_ENTRY_INIT((__ia), ia_hash_pslist_entry); 192 PSLIST_ENTRY_INIT((__ia), ia_hash_pslist_entry);
192#define IN_ADDRHASH_ENTRY_DESTROY(__ia) \ 193#define IN_ADDRHASH_ENTRY_DESTROY(__ia) \
193 PSLIST_ENTRY_DESTROY((__ia), ia_hash_pslist_entry); 194 PSLIST_ENTRY_DESTROY((__ia), ia_hash_pslist_entry);
194#define IN_ADDRHASH_READER_NEXT(__ia) \ 195#define IN_ADDRHASH_READER_NEXT(__ia) \
195 PSLIST_READER_NEXT((__ia), struct in_ifaddr, ia_hash_pslist_entry) 196 PSLIST_READER_NEXT((__ia), struct in_ifaddr, ia_hash_pslist_entry)
196 197
197#define IN_ADDRLIST_ENTRY_INIT(__ia) \ 198#define IN_ADDRLIST_ENTRY_INIT(__ia) \
198 PSLIST_ENTRY_INIT((__ia), ia_pslist_entry) 199 PSLIST_ENTRY_INIT((__ia), ia_pslist_entry)
199#define IN_ADDRLIST_ENTRY_DESTROY(__ia) \ 200#define IN_ADDRLIST_ENTRY_DESTROY(__ia) \
200 PSLIST_ENTRY_DESTROY((__ia), ia_pslist_entry); 201 PSLIST_ENTRY_DESTROY((__ia), ia_pslist_entry);
201#define IN_ADDRLIST_READER_EMPTY() \ 202#define IN_ADDRLIST_READER_EMPTY() \
202 (PSLIST_READER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \ 203 (PSLIST_READER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
203 ia_pslist_entry) == NULL) 204 ia_pslist_entry) == NULL)
204#define IN_ADDRLIST_READER_FIRST() \ 205#define IN_ADDRLIST_READER_FIRST() \
205 PSLIST_READER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \ 206 PSLIST_READER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
206 ia_pslist_entry) 207 ia_pslist_entry)
207#define IN_ADDRLIST_READER_NEXT(__ia) \ 208#define IN_ADDRLIST_READER_NEXT(__ia) \
208 PSLIST_READER_NEXT((__ia), struct in_ifaddr, ia_pslist_entry) 209 PSLIST_READER_NEXT((__ia), struct in_ifaddr, ia_pslist_entry)
209#define IN_ADDRLIST_READER_FOREACH(__ia) \ 210#define IN_ADDRLIST_READER_FOREACH(__ia) \
210 PSLIST_READER_FOREACH((__ia), &in_ifaddrhead_pslist, \ 211 PSLIST_READER_FOREACH((__ia), &in_ifaddrhead_pslist, \
211 struct in_ifaddr, ia_pslist_entry) 212 struct in_ifaddr, ia_pslist_entry)
212#define IN_ADDRLIST_WRITER_INSERT_HEAD(__ia) \ 213#define IN_ADDRLIST_WRITER_INSERT_HEAD(__ia) \
213 PSLIST_WRITER_INSERT_HEAD(&in_ifaddrhead_pslist, (__ia), \ 214 PSLIST_WRITER_INSERT_HEAD(&in_ifaddrhead_pslist, (__ia), \
214 ia_pslist_entry) 215 ia_pslist_entry)
215#define IN_ADDRLIST_WRITER_REMOVE(__ia) \ 216#define IN_ADDRLIST_WRITER_REMOVE(__ia) \
216 PSLIST_WRITER_REMOVE((__ia), ia_pslist_entry) 217 PSLIST_WRITER_REMOVE((__ia), ia_pslist_entry)
217#define IN_ADDRLIST_WRITER_FOREACH(__ia) \ 218#define IN_ADDRLIST_WRITER_FOREACH(__ia) \
218 PSLIST_WRITER_FOREACH((__ia), &in_ifaddrhead_pslist, \ 219 PSLIST_WRITER_FOREACH((__ia), &in_ifaddrhead_pslist, \
219 struct in_ifaddr, ia_pslist_entry) 220 struct in_ifaddr, ia_pslist_entry)
220#define IN_ADDRLIST_WRITER_FIRST() \ 221#define IN_ADDRLIST_WRITER_FIRST() \
221 PSLIST_WRITER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \ 222 PSLIST_WRITER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
222 ia_pslist_entry) 223 ia_pslist_entry)
223#define IN_ADDRLIST_WRITER_NEXT(__ia) \ 224#define IN_ADDRLIST_WRITER_NEXT(__ia) \
224 PSLIST_WRITER_NEXT((__ia), struct in_ifaddr, ia_pslist_entry) 225 PSLIST_WRITER_NEXT((__ia), struct in_ifaddr, ia_pslist_entry)
225#define IN_ADDRLIST_WRITER_INSERT_AFTER(__ia, __new) \ 226#define IN_ADDRLIST_WRITER_INSERT_AFTER(__ia, __new) \
226 PSLIST_WRITER_INSERT_AFTER((__ia), (__new), ia_pslist_entry) 227 PSLIST_WRITER_INSERT_AFTER((__ia), (__new), ia_pslist_entry)
227#define IN_ADDRLIST_WRITER_EMPTY() \ 228#define IN_ADDRLIST_WRITER_EMPTY() \
228 (PSLIST_WRITER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \ 229 (PSLIST_WRITER_FIRST(&in_ifaddrhead_pslist, struct in_ifaddr, \
229 ia_pslist_entry) == NULL) 230 ia_pslist_entry) == NULL)
230#define IN_ADDRLIST_WRITER_INSERT_TAIL(__new) \ 231#define IN_ADDRLIST_WRITER_INSERT_TAIL(__new) \
231 do { \ 232 do { \
232 if (IN_ADDRLIST_WRITER_EMPTY()) { \ 233 if (IN_ADDRLIST_WRITER_EMPTY()) { \
233 IN_ADDRLIST_WRITER_INSERT_HEAD((__new)); \ 234 IN_ADDRLIST_WRITER_INSERT_HEAD((__new)); \
234 } else { \ 235 } else { \
235 struct in_ifaddr *__ia; \ 236 struct in_ifaddr *__ia; \
236 IN_ADDRLIST_WRITER_FOREACH(__ia) { \ 237 IN_ADDRLIST_WRITER_FOREACH(__ia) { \
237 if (IN_ADDRLIST_WRITER_NEXT(__ia) == NULL) { \ 238 if (IN_ADDRLIST_WRITER_NEXT(__ia) == NULL) { \
238 IN_ADDRLIST_WRITER_INSERT_AFTER(__ia,\ 239 IN_ADDRLIST_WRITER_INSERT_AFTER(__ia,\
239 (__new)); \ 240 (__new)); \
240 break; \ 241 break; \
241 } \ 242 } \
242 } \ 243 } \
243 } \ 244 } \
244 } while (0) 245 } while (0)
245 246
246extern const int inetctlerrmap[]; 247extern const int inetctlerrmap[];
247 248
248/* 249/*
249 * Find whether an internet address (in_addr) belongs to one 250 * Find whether an internet address (in_addr) belongs to one
250 * of our interfaces (in_ifaddr). NULL if the address isn't ours. 251 * of our interfaces (in_ifaddr). NULL if the address isn't ours.
251 */ 252 */
252static inline struct in_ifaddr * 253static inline struct in_ifaddr *
253in_get_ia(struct in_addr addr) 254in_get_ia(struct in_addr addr)
254{ 255{
255 struct in_ifaddr *ia; 256 struct in_ifaddr *ia;
256 257
257 IN_ADDRHASH_READER_FOREACH(ia, addr.s_addr) { 258 IN_ADDRHASH_READER_FOREACH(ia, addr.s_addr) {
258 if (in_hosteq(ia->ia_addr.sin_addr, addr)) 259 if (in_hosteq(ia->ia_addr.sin_addr, addr))
259 break; 260 break;
260 } 261 }
261 262
262 return ia; 263 return ia;
263} 264}
264 265
265static inline struct in_ifaddr * 266static inline struct in_ifaddr *
266in_get_ia_psref(struct in_addr addr, struct psref *psref) 267in_get_ia_psref(struct in_addr addr, struct psref *psref)
267{ 268{
268 struct in_ifaddr *ia; 269 struct in_ifaddr *ia;
269 int s; 270 int s;
270 271
271 s = pserialize_read_enter(); 272 s = pserialize_read_enter();
272 ia = in_get_ia(addr); 273 ia = in_get_ia(addr);
273 if (ia != NULL) 274 if (ia != NULL)
274 ia4_acquire(ia, psref); 275 ia4_acquire(ia, psref);
275 pserialize_read_exit(s); 276 pserialize_read_exit(s);
276 277
277 return ia; 278 return ia;
278} 279}
279 280
280/* 281/*
281 * Find whether an internet address (in_addr) belongs to a specified 282 * Find whether an internet address (in_addr) belongs to a specified
282 * interface. NULL if the address isn't ours. 283 * interface. NULL if the address isn't ours.
283 */ 284 */
284static inline struct in_ifaddr * 285static inline struct in_ifaddr *
285in_get_ia_on_iface(struct in_addr addr, struct ifnet *ifp) 286in_get_ia_on_iface(struct in_addr addr, struct ifnet *ifp)
286{ 287{
287 struct in_ifaddr *ia; 288 struct in_ifaddr *ia;
288 289
289 IN_ADDRHASH_READER_FOREACH(ia, addr.s_addr) { 290 IN_ADDRHASH_READER_FOREACH(ia, addr.s_addr) {
290 if (in_hosteq(ia->ia_addr.sin_addr, addr) && 291 if (in_hosteq(ia->ia_addr.sin_addr, addr) &&
291 ia->ia_ifp == ifp) 292 ia->ia_ifp == ifp)
292 break; 293 break;
293 } 294 }
294 295
295 return ia; 296 return ia;
296} 297}
297 298
298static inline struct in_ifaddr * 299static inline struct in_ifaddr *
299in_get_ia_on_iface_psref(struct in_addr addr, struct ifnet *ifp, struct psref *psref) 300in_get_ia_on_iface_psref(struct in_addr addr, struct ifnet *ifp, struct psref *psref)
300{ 301{
301 struct in_ifaddr *ia; 302 struct in_ifaddr *ia;
302 int s; 303 int s;
303 304
304 s = pserialize_read_enter(); 305 s = pserialize_read_enter();
305 ia = in_get_ia_on_iface(addr, ifp); 306 ia = in_get_ia_on_iface(addr, ifp);
306 if (ia != NULL) 307 if (ia != NULL)
307 ia4_acquire(ia, psref); 308 ia4_acquire(ia, psref);
308 pserialize_read_exit(s); 309 pserialize_read_exit(s);
309 310
310 return ia; 311 return ia;
311} 312}
312 313
313/* 314/*
314 * Find an internet address structure (in_ifaddr) corresponding 315 * Find an internet address structure (in_ifaddr) corresponding
315 * to a given interface (ifnet structure). 316 * to a given interface (ifnet structure).
316 */ 317 */
317static inline struct in_ifaddr * 318static inline struct in_ifaddr *
318in_get_ia_from_ifp(struct ifnet *ifp) 319in_get_ia_from_ifp(struct ifnet *ifp)
319{ 320{
320 struct ifaddr *ifa; 321 struct ifaddr *ifa;
321 322
322 IFADDR_READER_FOREACH(ifa, ifp) { 323 IFADDR_READER_FOREACH(ifa, ifp) {
323 if (ifa->ifa_addr->sa_family == AF_INET) 324 if (ifa->ifa_addr->sa_family == AF_INET)
324 break; 325 break;
325 } 326 }
326 327
327 return ifatoia(ifa); 328 return ifatoia(ifa);
328} 329}
329 330
330static inline struct in_ifaddr * 331static inline struct in_ifaddr *
331in_get_ia_from_ifp_psref(struct ifnet *ifp, struct psref *psref) 332in_get_ia_from_ifp_psref(struct ifnet *ifp, struct psref *psref)
332{ 333{
333 struct in_ifaddr *ia; 334 struct in_ifaddr *ia;
334 int s; 335 int s;
335 336
336 s = pserialize_read_enter(); 337 s = pserialize_read_enter();
337 ia = in_get_ia_from_ifp(ifp); 338 ia = in_get_ia_from_ifp(ifp);
338 if (ia != NULL) 339 if (ia != NULL)
339 ia4_acquire(ia, psref); 340 ia4_acquire(ia, psref);
340 pserialize_read_exit(s); 341 pserialize_read_exit(s);
341 342
342 return ia; 343 return ia;
343} 344}
344 345
345#include <netinet/in_selsrc.h> 346#include <netinet/in_selsrc.h>
346/* 347/*
347 * IPv4 per-interface state. 348 * IPv4 per-interface state.
348 */ 349 */
349struct in_ifinfo { 350struct in_ifinfo {
350 struct lltable *ii_llt; /* ARP state */ 351 struct lltable *ii_llt; /* ARP state */
351 struct in_ifsysctl *ii_selsrc; 352 struct in_ifsysctl *ii_selsrc;
352}; 353};
353 354
354#endif /* _KERNEL */ 355#endif /* _KERNEL */
355 356
356/* 357/*
357 * Internet multicast address structure. There is one of these for each IP 358 * Internet multicast address structure. There is one of these for each IP
358 * multicast group to which this host belongs on a given network interface. 359 * multicast group to which this host belongs on a given network interface.
359 * They are kept in a linked list, rooted in the interface's in_ifaddr 360 * They are kept in a linked list, rooted in the interface's in_ifaddr
360 * structure. 361 * structure.
361 */ 362 */
362struct router_info; 363struct router_info;
363 364
364struct in_multi { 365struct in_multi {
365 LIST_ENTRY(in_multi) inm_list; /* list of multicast addresses */ 366 LIST_ENTRY(in_multi) inm_list; /* list of multicast addresses */
366 struct router_info *inm_rti; /* router version info */ 367 struct router_info *inm_rti; /* router version info */
367 struct ifnet *inm_ifp; /* back pointer to ifnet */ 368 struct ifnet *inm_ifp; /* back pointer to ifnet */
368 struct in_addr inm_addr; /* IP multicast address */ 369 struct in_addr inm_addr; /* IP multicast address */
369 u_int inm_refcount; /* no. membership claims by sockets */ 370 u_int inm_refcount; /* no. membership claims by sockets */
370 u_int inm_timer; /* IGMP membership report timer */ 371 u_int inm_timer; /* IGMP membership report timer */
371 u_int inm_state; /* state of membership */ 372 u_int inm_state; /* state of membership */
372}; 373};
373 374
374#ifdef _KERNEL 375#ifdef _KERNEL
375 376
376#include <net/pktqueue.h> 377#include <net/pktqueue.h>
377 378
378extern pktqueue_t *ip_pktq; 379extern pktqueue_t *ip_pktq;
379 380
380extern int ip_dad_count; /* Duplicate Address Detection probes */ 381extern int ip_dad_count; /* Duplicate Address Detection probes */
381#if defined(INET) && NARP > 0 382#if defined(INET) && NARP > 0
382extern int arp_debug; 383extern int arp_debug;
383#define arplog(level, fmt, args...) \ 384#define arplog(level, fmt, args...) \
384 do { if (arp_debug) log(level, "%s: " fmt, __func__, ##args);} while (0) 385 do { if (arp_debug) log(level, "%s: " fmt, __func__, ##args);} while (0)
385#else 386#else
386#define arplog(level, fmt, args...) 387#define arplog(level, fmt, args...)
387#endif 388#endif
388 389
389/* 390/*
390 * Structure used by functions below to remember position when stepping 391 * Structure used by functions below to remember position when stepping
391 * through all of the in_multi records. 392 * through all of the in_multi records.
392 */ 393 */
393struct in_multistep { 394struct in_multistep {
394 int i_n; 395 int i_n;
395 struct in_multi *i_inm; 396 struct in_multi *i_inm;
396}; 397};
397 398
398bool in_multi_group(struct in_addr, struct ifnet *, int); 399bool in_multi_group(struct in_addr, struct ifnet *, int);
399struct in_multi *in_first_multi(struct in_multistep *); 400struct in_multi *in_first_multi(struct in_multistep *);
400struct in_multi *in_next_multi(struct in_multistep *); 401struct in_multi *in_next_multi(struct in_multistep *);
401struct in_multi *in_lookup_multi(struct in_addr, struct ifnet *); 402struct in_multi *in_lookup_multi(struct in_addr, struct ifnet *);
402struct in_multi *in_addmulti(struct in_addr *, struct ifnet *); 403struct in_multi *in_addmulti(struct in_addr *, struct ifnet *);
403void in_delmulti(struct in_multi *); 404void in_delmulti(struct in_multi *);
404 405
405void in_multi_lock(int); 406void in_multi_lock(int);
406void in_multi_unlock(void); 407void in_multi_unlock(void);
407int in_multi_lock_held(void); 408int in_multi_lock_held(void);
408 409
409struct ifaddr; 410struct ifaddr;
410 411
411int in_ifinit(struct ifnet *, struct in_ifaddr *, 412int in_ifinit(struct ifnet *, struct in_ifaddr *,
412 const struct sockaddr_in *, const struct sockaddr_in *, int); 413 const struct sockaddr_in *, const struct sockaddr_in *, int);
413void in_savemkludge(struct in_ifaddr *); 414void in_savemkludge(struct in_ifaddr *);
414void in_restoremkludge(struct in_ifaddr *, struct ifnet *); 415void in_restoremkludge(struct in_ifaddr *, struct ifnet *);
415void in_purgemkludge(struct ifnet *); 416void in_purgemkludge(struct ifnet *);
416void in_setmaxmtu(void); 417void in_setmaxmtu(void);
417const char *in_fmtaddr(struct in_addr); 418const char *in_fmtaddr(struct in_addr);
418int in_control(struct socket *, u_long, void *, struct ifnet *); 419int in_control(struct socket *, u_long, void *, struct ifnet *);
419void in_purgeaddr(struct ifaddr *); 420void in_purgeaddr(struct ifaddr *);
420void in_purgeif(struct ifnet *); 421void in_purgeif(struct ifnet *);
421int ipflow_fastforward(struct mbuf *); 422int ipflow_fastforward(struct mbuf *);
422 423
423struct ipid_state; 424struct ipid_state;
424typedef struct ipid_state ipid_state_t; 425typedef struct ipid_state ipid_state_t;
425 426
426ipid_state_t * ip_id_init(void); 427ipid_state_t * ip_id_init(void);
427void ip_id_fini(ipid_state_t *); 428void ip_id_fini(ipid_state_t *);
428uint16_t ip_randomid(ipid_state_t *, uint16_t); 429uint16_t ip_randomid(ipid_state_t *, uint16_t);
429 430
430extern ipid_state_t * ip_ids; 431extern ipid_state_t * ip_ids;
431extern uint16_t ip_id; 432extern uint16_t ip_id;
432extern int ip_do_randomid; 433extern int ip_do_randomid;
433 434
434/* 435/*
435 * ip_newid_range: "allocate" num contiguous IP IDs. 436 * ip_newid_range: "allocate" num contiguous IP IDs.
436 * 437 *
437 * => Return the first ID. 438 * => Return the first ID.
438 */ 439 */
439static __inline uint16_t 440static __inline uint16_t
440ip_newid_range(const struct in_ifaddr *ia, u_int num) 441ip_newid_range(const struct in_ifaddr *ia, u_int num)
441{ 442{
442 uint16_t id; 443 uint16_t id;
443 444
444 if (ip_do_randomid) { 445 if (ip_do_randomid) {
445 /* XXX ignore num */ 446 /* XXX ignore num */
446 return ip_randomid(ip_ids, ia ? ia->ia_idsalt : 0); 447 return ip_randomid(ip_ids, ia ? ia->ia_idsalt : 0);
447 } 448 }
448 449
449 /* Never allow an IP ID of 0 (detect wrap). */ 450 /* Never allow an IP ID of 0 (detect wrap). */
450 if ((uint16_t)(ip_id + num) < ip_id) { 451 if ((uint16_t)(ip_id + num) < ip_id) {
451 ip_id = 1; 452 ip_id = 1;
452 } 453 }
453 id = htons(ip_id); 454 id = htons(ip_id);
454 ip_id += num; 455 ip_id += num;
455 return id; 456 return id;
456} 457}
457 458
458static __inline uint16_t 459static __inline uint16_t
459ip_newid(const struct in_ifaddr *ia) 460ip_newid(const struct in_ifaddr *ia)
460{ 461{
461 462
462 return ip_newid_range(ia, 1); 463 return ip_newid_range(ia, 1);
463} 464}
464 465
465#ifdef SYSCTLFN_PROTO 466#ifdef SYSCTLFN_PROTO
466int sysctl_inpcblist(SYSCTLFN_PROTO); 467int sysctl_inpcblist(SYSCTLFN_PROTO);
467#endif 468#endif
468 469
469#define LLTABLE(ifp) \ 470#define LLTABLE(ifp) \
470 ((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt 471 ((struct in_ifinfo *)(ifp)->if_afdata[AF_INET])->ii_llt
471 472
472#endif /* !_KERNEL */ 473#endif /* !_KERNEL */
473 474
474/* INET6 stuff */ 475/* INET6 stuff */
475#include <netinet6/in6_var.h> 476#include <netinet6/in6_var.h>
476 477
477#endif /* !_NETINET_IN_VAR_H_ */ 478#endif /* !_NETINET_IN_VAR_H_ */