Wed Jan 25 03:04:22 2017 UTC ()
fix locking against myself in module autoload; module autoload calls
if_clone_attach which takes the lock again.


(christos)
diff -r1.374 -r1.375 src/sys/net/if.c

cvs diff -r1.374 -r1.375 src/sys/net/if.c (switch to unified diff)

--- src/sys/net/if.c 2017/01/24 07:58:58 1.374
+++ src/sys/net/if.c 2017/01/25 03:04:21 1.375
@@ -1,2622 +1,2627 @@ @@ -1,2622 +1,2627 @@
1/* $NetBSD: if.c,v 1.374 2017/01/24 07:58:58 ozaki-r Exp $ */ 1/* $NetBSD: if.c,v 1.375 2017/01/25 03:04:21 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999, 2000, 2001, 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 William Studenmund and Jason R. Thorpe. 8 * by William Studenmund and Jason R. Thorpe.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 33 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
34 * All rights reserved. 34 * All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the project nor the names of its contributors 44 * 3. Neither the name of the project nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 */ 59 */
60 60
61/* 61/*
62 * Copyright (c) 1980, 1986, 1993 62 * Copyright (c) 1980, 1986, 1993
63 * The Regents of the University of California. All rights reserved. 63 * The Regents of the University of California. All rights reserved.
64 * 64 *
65 * Redistribution and use in source and binary forms, with or without 65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions 66 * modification, are permitted provided that the following conditions
67 * are met: 67 * are met:
68 * 1. Redistributions of source code must retain the above copyright 68 * 1. Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer. 69 * notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright 70 * 2. Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in the 71 * notice, this list of conditions and the following disclaimer in the
72 * documentation and/or other materials provided with the distribution. 72 * documentation and/or other materials provided with the distribution.
73 * 3. Neither the name of the University nor the names of its contributors 73 * 3. Neither the name of the University nor the names of its contributors
74 * may be used to endorse or promote products derived from this software 74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission. 75 * without specific prior written permission.
76 * 76 *
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
87 * SUCH DAMAGE. 87 * SUCH DAMAGE.
88 * 88 *
89 * @(#)if.c 8.5 (Berkeley) 1/9/95 89 * @(#)if.c 8.5 (Berkeley) 1/9/95
90 */ 90 */
91 91
92#include <sys/cdefs.h> 92#include <sys/cdefs.h>
93__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.374 2017/01/24 07:58:58 ozaki-r Exp $"); 93__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.375 2017/01/25 03:04:21 christos Exp $");
94 94
95#if defined(_KERNEL_OPT) 95#if defined(_KERNEL_OPT)
96#include "opt_inet.h" 96#include "opt_inet.h"
97#include "opt_ipsec.h" 97#include "opt_ipsec.h"
98 98
99#include "opt_atalk.h" 99#include "opt_atalk.h"
100#include "opt_natm.h" 100#include "opt_natm.h"
101#include "opt_wlan.h" 101#include "opt_wlan.h"
102#include "opt_net_mpsafe.h" 102#include "opt_net_mpsafe.h"
103#endif 103#endif
104 104
105#include <sys/param.h> 105#include <sys/param.h>
106#include <sys/mbuf.h> 106#include <sys/mbuf.h>
107#include <sys/systm.h> 107#include <sys/systm.h>
108#include <sys/callout.h> 108#include <sys/callout.h>
109#include <sys/proc.h> 109#include <sys/proc.h>
110#include <sys/socket.h> 110#include <sys/socket.h>
111#include <sys/socketvar.h> 111#include <sys/socketvar.h>
112#include <sys/domain.h> 112#include <sys/domain.h>
113#include <sys/protosw.h> 113#include <sys/protosw.h>
114#include <sys/kernel.h> 114#include <sys/kernel.h>
115#include <sys/ioctl.h> 115#include <sys/ioctl.h>
116#include <sys/sysctl.h> 116#include <sys/sysctl.h>
117#include <sys/syslog.h> 117#include <sys/syslog.h>
118#include <sys/kauth.h> 118#include <sys/kauth.h>
119#include <sys/kmem.h> 119#include <sys/kmem.h>
120#include <sys/xcall.h> 120#include <sys/xcall.h>
121#include <sys/cpu.h> 121#include <sys/cpu.h>
122#include <sys/intr.h> 122#include <sys/intr.h>
123 123
124#include <net/if.h> 124#include <net/if.h>
125#include <net/if_dl.h> 125#include <net/if_dl.h>
126#include <net/if_ether.h> 126#include <net/if_ether.h>
127#include <net/if_media.h> 127#include <net/if_media.h>
128#include <net80211/ieee80211.h> 128#include <net80211/ieee80211.h>
129#include <net80211/ieee80211_ioctl.h> 129#include <net80211/ieee80211_ioctl.h>
130#include <net/if_types.h> 130#include <net/if_types.h>
131#include <net/route.h> 131#include <net/route.h>
132#include <net/netisr.h> 132#include <net/netisr.h>
133#include <sys/module.h> 133#include <sys/module.h>
134#ifdef NETATALK 134#ifdef NETATALK
135#include <netatalk/at_extern.h> 135#include <netatalk/at_extern.h>
136#include <netatalk/at.h> 136#include <netatalk/at.h>
137#endif 137#endif
138#include <net/pfil.h> 138#include <net/pfil.h>
139#include <netinet/in.h> 139#include <netinet/in.h>
140#include <netinet/in_var.h> 140#include <netinet/in_var.h>
141#ifndef IPSEC 141#ifndef IPSEC
142#include <netinet/ip_encap.h> 142#include <netinet/ip_encap.h>
143#endif 143#endif
144#include <net/bpf.h> 144#include <net/bpf.h>
145 145
146#ifdef INET6 146#ifdef INET6
147#include <netinet6/in6_var.h> 147#include <netinet6/in6_var.h>
148#include <netinet6/nd6.h> 148#include <netinet6/nd6.h>
149#endif 149#endif
150 150
151#include "ether.h" 151#include "ether.h"
152#include "fddi.h" 152#include "fddi.h"
153#include "token.h" 153#include "token.h"
154 154
155#include "carp.h" 155#include "carp.h"
156#if NCARP > 0 156#if NCARP > 0
157#include <netinet/ip_carp.h> 157#include <netinet/ip_carp.h>
158#endif 158#endif
159 159
160#include <compat/sys/sockio.h> 160#include <compat/sys/sockio.h>
161#include <compat/sys/socket.h> 161#include <compat/sys/socket.h>
162 162
163MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address"); 163MALLOC_DEFINE(M_IFADDR, "ifaddr", "interface address");
164MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address"); 164MALLOC_DEFINE(M_IFMADDR, "ether_multi", "link-level multicast address");
165 165
166/* 166/*
167 * Global list of interfaces. 167 * Global list of interfaces.
168 */ 168 */
169/* DEPRECATED. Remove it once kvm(3) users disappeared */ 169/* DEPRECATED. Remove it once kvm(3) users disappeared */
170struct ifnet_head ifnet_list; 170struct ifnet_head ifnet_list;
171 171
172struct pslist_head ifnet_pslist; 172struct pslist_head ifnet_pslist;
173static ifnet_t ** ifindex2ifnet = NULL; 173static ifnet_t ** ifindex2ifnet = NULL;
174static u_int if_index = 1; 174static u_int if_index = 1;
175static size_t if_indexlim = 0; 175static size_t if_indexlim = 0;
176static uint64_t index_gen; 176static uint64_t index_gen;
177/* Mutex to protect the above objects. */ 177/* Mutex to protect the above objects. */
178kmutex_t ifnet_mtx __cacheline_aligned; 178kmutex_t ifnet_mtx __cacheline_aligned;
179struct psref_class *ifnet_psref_class __read_mostly; 179struct psref_class *ifnet_psref_class __read_mostly;
180static pserialize_t ifnet_psz; 180static pserialize_t ifnet_psz;
181 181
182static kmutex_t if_clone_mtx; 182static kmutex_t if_clone_mtx;
183 183
184struct ifnet *lo0ifp; 184struct ifnet *lo0ifp;
185int ifqmaxlen = IFQ_MAXLEN; 185int ifqmaxlen = IFQ_MAXLEN;
186 186
187struct psref_class *ifa_psref_class __read_mostly; 187struct psref_class *ifa_psref_class __read_mostly;
188 188
189static int if_delroute_matcher(struct rtentry *, void *); 189static int if_delroute_matcher(struct rtentry *, void *);
190 190
191static struct if_clone *if_clone_lookup(const char *, int *); 191static struct if_clone *if_clone_lookup(const char *, int *);
192 192
193static LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); 193static LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners);
194static int if_cloners_count; 194static int if_cloners_count;
195 195
196/* Packet filtering hook for interfaces. */ 196/* Packet filtering hook for interfaces. */
197pfil_head_t * if_pfil __read_mostly; 197pfil_head_t * if_pfil __read_mostly;
198 198
199static kauth_listener_t if_listener; 199static kauth_listener_t if_listener;
200 200
201static int doifioctl(struct socket *, u_long, void *, struct lwp *); 201static int doifioctl(struct socket *, u_long, void *, struct lwp *);
202static void if_detach_queues(struct ifnet *, struct ifqueue *); 202static void if_detach_queues(struct ifnet *, struct ifqueue *);
203static void sysctl_sndq_setup(struct sysctllog **, const char *, 203static void sysctl_sndq_setup(struct sysctllog **, const char *,
204 struct ifaltq *); 204 struct ifaltq *);
205static void if_slowtimo(void *); 205static void if_slowtimo(void *);
206static void if_free_sadl(struct ifnet *); 206static void if_free_sadl(struct ifnet *);
207static void if_attachdomain1(struct ifnet *); 207static void if_attachdomain1(struct ifnet *);
208static int ifconf(u_long, void *); 208static int ifconf(u_long, void *);
209static int if_transmit(struct ifnet *, struct mbuf *); 209static int if_transmit(struct ifnet *, struct mbuf *);
210static int if_clone_create(const char *); 210static int if_clone_create(const char *);
211static int if_clone_destroy(const char *); 211static int if_clone_destroy(const char *);
212static void if_link_state_change_si(void *); 212static void if_link_state_change_si(void *);
213 213
214struct if_percpuq { 214struct if_percpuq {
215 struct ifnet *ipq_ifp; 215 struct ifnet *ipq_ifp;
216 void *ipq_si; 216 void *ipq_si;
217 struct percpu *ipq_ifqs; /* struct ifqueue */ 217 struct percpu *ipq_ifqs; /* struct ifqueue */
218}; 218};
219 219
220static struct mbuf *if_percpuq_dequeue(struct if_percpuq *); 220static struct mbuf *if_percpuq_dequeue(struct if_percpuq *);
221 221
222static void if_percpuq_drops(void *, void *, struct cpu_info *); 222static void if_percpuq_drops(void *, void *, struct cpu_info *);
223static int sysctl_percpuq_drops_handler(SYSCTLFN_PROTO); 223static int sysctl_percpuq_drops_handler(SYSCTLFN_PROTO);
224static void sysctl_percpuq_setup(struct sysctllog **, const char *, 224static void sysctl_percpuq_setup(struct sysctllog **, const char *,
225 struct if_percpuq *); 225 struct if_percpuq *);
226 226
227struct if_deferred_start { 227struct if_deferred_start {
228 struct ifnet *ids_ifp; 228 struct ifnet *ids_ifp;
229 void (*ids_if_start)(struct ifnet *); 229 void (*ids_if_start)(struct ifnet *);
230 void *ids_si; 230 void *ids_si;
231}; 231};
232 232
233static void if_deferred_start_softint(void *); 233static void if_deferred_start_softint(void *);
234static void if_deferred_start_common(struct ifnet *); 234static void if_deferred_start_common(struct ifnet *);
235static void if_deferred_start_destroy(struct ifnet *); 235static void if_deferred_start_destroy(struct ifnet *);
236 236
237#if defined(INET) || defined(INET6) 237#if defined(INET) || defined(INET6)
238static void sysctl_net_pktq_setup(struct sysctllog **, int); 238static void sysctl_net_pktq_setup(struct sysctllog **, int);
239#endif 239#endif
240 240
241static void if_sysctl_setup(struct sysctllog **); 241static void if_sysctl_setup(struct sysctllog **);
242 242
243/* 243/*
244 * Pointer to stub or real compat_cvtcmd() depending on presence of 244 * Pointer to stub or real compat_cvtcmd() depending on presence of
245 * the compat module 245 * the compat module
246 */ 246 */
247u_long stub_compat_cvtcmd(u_long); 247u_long stub_compat_cvtcmd(u_long);
248u_long (*vec_compat_cvtcmd)(u_long) = stub_compat_cvtcmd; 248u_long (*vec_compat_cvtcmd)(u_long) = stub_compat_cvtcmd;
249 249
250/* Similarly, pointer to compat_ifioctl() if it is present */ 250/* Similarly, pointer to compat_ifioctl() if it is present */
251 251
252int (*vec_compat_ifioctl)(struct socket *, u_long, u_long, void *, 252int (*vec_compat_ifioctl)(struct socket *, u_long, u_long, void *,
253 struct lwp *) = NULL; 253 struct lwp *) = NULL;
254 254
255/* The stub version of compat_cvtcmd() */ 255/* The stub version of compat_cvtcmd() */
256u_long stub_compat_cvtcmd(u_long cmd) 256u_long stub_compat_cvtcmd(u_long cmd)
257{ 257{
258 258
259 return cmd; 259 return cmd;
260} 260}
261 261
262static int 262static int
263if_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 263if_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
264 void *arg0, void *arg1, void *arg2, void *arg3) 264 void *arg0, void *arg1, void *arg2, void *arg3)
265{ 265{
266 int result; 266 int result;
267 enum kauth_network_req req; 267 enum kauth_network_req req;
268 268
269 result = KAUTH_RESULT_DEFER; 269 result = KAUTH_RESULT_DEFER;
270 req = (enum kauth_network_req)arg1; 270 req = (enum kauth_network_req)arg1;
271 271
272 if (action != KAUTH_NETWORK_INTERFACE) 272 if (action != KAUTH_NETWORK_INTERFACE)
273 return result; 273 return result;
274 274
275 if ((req == KAUTH_REQ_NETWORK_INTERFACE_GET) || 275 if ((req == KAUTH_REQ_NETWORK_INTERFACE_GET) ||
276 (req == KAUTH_REQ_NETWORK_INTERFACE_SET)) 276 (req == KAUTH_REQ_NETWORK_INTERFACE_SET))
277 result = KAUTH_RESULT_ALLOW; 277 result = KAUTH_RESULT_ALLOW;
278 278
279 return result; 279 return result;
280} 280}
281 281
282/* 282/*
283 * Network interface utility routines. 283 * Network interface utility routines.
284 * 284 *
285 * Routines with ifa_ifwith* names take sockaddr *'s as 285 * Routines with ifa_ifwith* names take sockaddr *'s as
286 * parameters. 286 * parameters.
287 */ 287 */
288void 288void
289ifinit(void) 289ifinit(void)
290{ 290{
291 291
292 if_sysctl_setup(NULL); 292 if_sysctl_setup(NULL);
293 293
294#if (defined(INET) || defined(INET6)) && !defined(IPSEC) 294#if (defined(INET) || defined(INET6)) && !defined(IPSEC)
295 encapinit(); 295 encapinit();
296#endif 296#endif
297 297
298 if_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK, 298 if_listener = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
299 if_listener_cb, NULL); 299 if_listener_cb, NULL);
300 300
301 /* interfaces are available, inform socket code */ 301 /* interfaces are available, inform socket code */
302 ifioctl = doifioctl; 302 ifioctl = doifioctl;
303} 303}
304 304
305/* 305/*
306 * XXX Initialization before configure(). 306 * XXX Initialization before configure().
307 * XXX hack to get pfil_add_hook working in autoconf. 307 * XXX hack to get pfil_add_hook working in autoconf.
308 */ 308 */
309void 309void
310ifinit1(void) 310ifinit1(void)
311{ 311{
312 mutex_init(&if_clone_mtx, MUTEX_DEFAULT, IPL_NONE); 312 mutex_init(&if_clone_mtx, MUTEX_DEFAULT, IPL_NONE);
313 313
314 TAILQ_INIT(&ifnet_list); 314 TAILQ_INIT(&ifnet_list);
315 mutex_init(&ifnet_mtx, MUTEX_DEFAULT, IPL_NONE); 315 mutex_init(&ifnet_mtx, MUTEX_DEFAULT, IPL_NONE);
316 ifnet_psz = pserialize_create(); 316 ifnet_psz = pserialize_create();
317 ifnet_psref_class = psref_class_create("ifnet", IPL_SOFTNET); 317 ifnet_psref_class = psref_class_create("ifnet", IPL_SOFTNET);
318 ifa_psref_class = psref_class_create("ifa", IPL_SOFTNET); 318 ifa_psref_class = psref_class_create("ifa", IPL_SOFTNET);
319 PSLIST_INIT(&ifnet_pslist); 319 PSLIST_INIT(&ifnet_pslist);
320 320
321 if_indexlim = 8; 321 if_indexlim = 8;
322 322
323 if_pfil = pfil_head_create(PFIL_TYPE_IFNET, NULL); 323 if_pfil = pfil_head_create(PFIL_TYPE_IFNET, NULL);
324 KASSERT(if_pfil != NULL); 324 KASSERT(if_pfil != NULL);
325 325
326#if NETHER > 0 || NFDDI > 0 || defined(NETATALK) || NTOKEN > 0 || defined(WLAN) 326#if NETHER > 0 || NFDDI > 0 || defined(NETATALK) || NTOKEN > 0 || defined(WLAN)
327 etherinit(); 327 etherinit();
328#endif 328#endif
329} 329}
330 330
331ifnet_t * 331ifnet_t *
332if_alloc(u_char type) 332if_alloc(u_char type)
333{ 333{
334 return kmem_zalloc(sizeof(ifnet_t), KM_SLEEP); 334 return kmem_zalloc(sizeof(ifnet_t), KM_SLEEP);
335} 335}
336 336
337void 337void
338if_free(ifnet_t *ifp) 338if_free(ifnet_t *ifp)
339{ 339{
340 kmem_free(ifp, sizeof(ifnet_t)); 340 kmem_free(ifp, sizeof(ifnet_t));
341} 341}
342 342
343void 343void
344if_initname(struct ifnet *ifp, const char *name, int unit) 344if_initname(struct ifnet *ifp, const char *name, int unit)
345{ 345{
346 (void)snprintf(ifp->if_xname, sizeof(ifp->if_xname), 346 (void)snprintf(ifp->if_xname, sizeof(ifp->if_xname),
347 "%s%d", name, unit); 347 "%s%d", name, unit);
348} 348}
349 349
350/* 350/*
351 * Null routines used while an interface is going away. These routines 351 * Null routines used while an interface is going away. These routines
352 * just return an error. 352 * just return an error.
353 */ 353 */
354 354
355int 355int
356if_nulloutput(struct ifnet *ifp, struct mbuf *m, 356if_nulloutput(struct ifnet *ifp, struct mbuf *m,
357 const struct sockaddr *so, const struct rtentry *rt) 357 const struct sockaddr *so, const struct rtentry *rt)
358{ 358{
359 359
360 return ENXIO; 360 return ENXIO;
361} 361}
362 362
363void 363void
364if_nullinput(struct ifnet *ifp, struct mbuf *m) 364if_nullinput(struct ifnet *ifp, struct mbuf *m)
365{ 365{
366 366
367 /* Nothing. */ 367 /* Nothing. */
368} 368}
369 369
370void 370void
371if_nullstart(struct ifnet *ifp) 371if_nullstart(struct ifnet *ifp)
372{ 372{
373 373
374 /* Nothing. */ 374 /* Nothing. */
375} 375}
376 376
377int 377int
378if_nulltransmit(struct ifnet *ifp, struct mbuf *m) 378if_nulltransmit(struct ifnet *ifp, struct mbuf *m)
379{ 379{
380 380
381 return ENXIO; 381 return ENXIO;
382} 382}
383 383
384int 384int
385if_nullioctl(struct ifnet *ifp, u_long cmd, void *data) 385if_nullioctl(struct ifnet *ifp, u_long cmd, void *data)
386{ 386{
387 387
388 return ENXIO; 388 return ENXIO;
389} 389}
390 390
391int 391int
392if_nullinit(struct ifnet *ifp) 392if_nullinit(struct ifnet *ifp)
393{ 393{
394 394
395 return ENXIO; 395 return ENXIO;
396} 396}
397 397
398void 398void
399if_nullstop(struct ifnet *ifp, int disable) 399if_nullstop(struct ifnet *ifp, int disable)
400{ 400{
401 401
402 /* Nothing. */ 402 /* Nothing. */
403} 403}
404 404
405void 405void
406if_nullslowtimo(struct ifnet *ifp) 406if_nullslowtimo(struct ifnet *ifp)
407{ 407{
408 408
409 /* Nothing. */ 409 /* Nothing. */
410} 410}
411 411
412void 412void
413if_nulldrain(struct ifnet *ifp) 413if_nulldrain(struct ifnet *ifp)
414{ 414{
415 415
416 /* Nothing. */ 416 /* Nothing. */
417} 417}
418 418
419void 419void
420if_set_sadl(struct ifnet *ifp, const void *lla, u_char addrlen, bool factory) 420if_set_sadl(struct ifnet *ifp, const void *lla, u_char addrlen, bool factory)
421{ 421{
422 struct ifaddr *ifa; 422 struct ifaddr *ifa;
423 struct sockaddr_dl *sdl; 423 struct sockaddr_dl *sdl;
424 424
425 ifp->if_addrlen = addrlen; 425 ifp->if_addrlen = addrlen;
426 if_alloc_sadl(ifp); 426 if_alloc_sadl(ifp);
427 ifa = ifp->if_dl; 427 ifa = ifp->if_dl;
428 sdl = satosdl(ifa->ifa_addr); 428 sdl = satosdl(ifa->ifa_addr);
429 429
430 (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lla, ifp->if_addrlen); 430 (void)sockaddr_dl_setaddr(sdl, sdl->sdl_len, lla, ifp->if_addrlen);
431 if (factory) { 431 if (factory) {
432 ifp->if_hwdl = ifp->if_dl; 432 ifp->if_hwdl = ifp->if_dl;
433 ifaref(ifp->if_hwdl); 433 ifaref(ifp->if_hwdl);
434 } 434 }
435 /* TBD routing socket */ 435 /* TBD routing socket */
436} 436}
437 437
438struct ifaddr * 438struct ifaddr *
439if_dl_create(const struct ifnet *ifp, const struct sockaddr_dl **sdlp) 439if_dl_create(const struct ifnet *ifp, const struct sockaddr_dl **sdlp)
440{ 440{
441 unsigned socksize, ifasize; 441 unsigned socksize, ifasize;
442 int addrlen, namelen; 442 int addrlen, namelen;
443 struct sockaddr_dl *mask, *sdl; 443 struct sockaddr_dl *mask, *sdl;
444 struct ifaddr *ifa; 444 struct ifaddr *ifa;
445 445
446 namelen = strlen(ifp->if_xname); 446 namelen = strlen(ifp->if_xname);
447 addrlen = ifp->if_addrlen; 447 addrlen = ifp->if_addrlen;
448 socksize = roundup(sockaddr_dl_measure(namelen, addrlen), sizeof(long)); 448 socksize = roundup(sockaddr_dl_measure(namelen, addrlen), sizeof(long));
449 ifasize = sizeof(*ifa) + 2 * socksize; 449 ifasize = sizeof(*ifa) + 2 * socksize;
450 ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK|M_ZERO); 450 ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK|M_ZERO);
451 451
452 sdl = (struct sockaddr_dl *)(ifa + 1); 452 sdl = (struct sockaddr_dl *)(ifa + 1);
453 mask = (struct sockaddr_dl *)(socksize + (char *)sdl); 453 mask = (struct sockaddr_dl *)(socksize + (char *)sdl);
454 454
455 sockaddr_dl_init(sdl, socksize, ifp->if_index, ifp->if_type, 455 sockaddr_dl_init(sdl, socksize, ifp->if_index, ifp->if_type,
456 ifp->if_xname, namelen, NULL, addrlen); 456 ifp->if_xname, namelen, NULL, addrlen);
457 mask->sdl_len = sockaddr_dl_measure(namelen, 0); 457 mask->sdl_len = sockaddr_dl_measure(namelen, 0);
458 memset(&mask->sdl_data[0], 0xff, namelen); 458 memset(&mask->sdl_data[0], 0xff, namelen);
459 ifa->ifa_rtrequest = link_rtrequest; 459 ifa->ifa_rtrequest = link_rtrequest;
460 ifa->ifa_addr = (struct sockaddr *)sdl; 460 ifa->ifa_addr = (struct sockaddr *)sdl;
461 ifa->ifa_netmask = (struct sockaddr *)mask; 461 ifa->ifa_netmask = (struct sockaddr *)mask;
462 ifa_psref_init(ifa); 462 ifa_psref_init(ifa);
463 463
464 *sdlp = sdl; 464 *sdlp = sdl;
465 465
466 return ifa; 466 return ifa;
467} 467}
468 468
469static void 469static void
470if_sadl_setrefs(struct ifnet *ifp, struct ifaddr *ifa) 470if_sadl_setrefs(struct ifnet *ifp, struct ifaddr *ifa)
471{ 471{
472 const struct sockaddr_dl *sdl; 472 const struct sockaddr_dl *sdl;
473 473
474 ifp->if_dl = ifa; 474 ifp->if_dl = ifa;
475 ifaref(ifa); 475 ifaref(ifa);
476 sdl = satosdl(ifa->ifa_addr); 476 sdl = satosdl(ifa->ifa_addr);
477 ifp->if_sadl = sdl; 477 ifp->if_sadl = sdl;
478} 478}
479 479
480/* 480/*
481 * Allocate the link level name for the specified interface. This 481 * Allocate the link level name for the specified interface. This
482 * is an attachment helper. It must be called after ifp->if_addrlen 482 * is an attachment helper. It must be called after ifp->if_addrlen
483 * is initialized, which may not be the case when if_attach() is 483 * is initialized, which may not be the case when if_attach() is
484 * called. 484 * called.
485 */ 485 */
486void 486void
487if_alloc_sadl(struct ifnet *ifp) 487if_alloc_sadl(struct ifnet *ifp)
488{ 488{
489 struct ifaddr *ifa; 489 struct ifaddr *ifa;
490 const struct sockaddr_dl *sdl; 490 const struct sockaddr_dl *sdl;
491 491
492 /* 492 /*
493 * If the interface already has a link name, release it 493 * If the interface already has a link name, release it
494 * now. This is useful for interfaces that can change 494 * now. This is useful for interfaces that can change
495 * link types, and thus switch link names often. 495 * link types, and thus switch link names often.
496 */ 496 */
497 if (ifp->if_sadl != NULL) 497 if (ifp->if_sadl != NULL)
498 if_free_sadl(ifp); 498 if_free_sadl(ifp);
499 499
500 ifa = if_dl_create(ifp, &sdl); 500 ifa = if_dl_create(ifp, &sdl);
501 501
502 ifa_insert(ifp, ifa); 502 ifa_insert(ifp, ifa);
503 if_sadl_setrefs(ifp, ifa); 503 if_sadl_setrefs(ifp, ifa);
504} 504}
505 505
506static void 506static void
507if_deactivate_sadl(struct ifnet *ifp) 507if_deactivate_sadl(struct ifnet *ifp)
508{ 508{
509 struct ifaddr *ifa; 509 struct ifaddr *ifa;
510 510
511 KASSERT(ifp->if_dl != NULL); 511 KASSERT(ifp->if_dl != NULL);
512 512
513 ifa = ifp->if_dl; 513 ifa = ifp->if_dl;
514 514
515 ifp->if_sadl = NULL; 515 ifp->if_sadl = NULL;
516 516
517 ifp->if_dl = NULL; 517 ifp->if_dl = NULL;
518 ifafree(ifa); 518 ifafree(ifa);
519} 519}
520 520
521void 521void
522if_activate_sadl(struct ifnet *ifp, struct ifaddr *ifa0, 522if_activate_sadl(struct ifnet *ifp, struct ifaddr *ifa0,
523 const struct sockaddr_dl *sdl) 523 const struct sockaddr_dl *sdl)
524{ 524{
525 int s, ss; 525 int s, ss;
526 struct ifaddr *ifa; 526 struct ifaddr *ifa;
527 int bound = curlwp_bind(); 527 int bound = curlwp_bind();
528 528
529 s = splsoftnet(); 529 s = splsoftnet();
530 530
531 if_deactivate_sadl(ifp); 531 if_deactivate_sadl(ifp);
532 532
533 if_sadl_setrefs(ifp, ifa0); 533 if_sadl_setrefs(ifp, ifa0);
534 534
535 ss = pserialize_read_enter(); 535 ss = pserialize_read_enter();
536 IFADDR_READER_FOREACH(ifa, ifp) { 536 IFADDR_READER_FOREACH(ifa, ifp) {
537 struct psref psref; 537 struct psref psref;
538 ifa_acquire(ifa, &psref); 538 ifa_acquire(ifa, &psref);
539 pserialize_read_exit(ss); 539 pserialize_read_exit(ss);
540 540
541 rtinit(ifa, RTM_LLINFO_UPD, 0); 541 rtinit(ifa, RTM_LLINFO_UPD, 0);
542 542
543 ss = pserialize_read_enter(); 543 ss = pserialize_read_enter();
544 ifa_release(ifa, &psref); 544 ifa_release(ifa, &psref);
545 } 545 }
546 pserialize_read_exit(ss); 546 pserialize_read_exit(ss);
547 547
548 splx(s); 548 splx(s);
549 curlwp_bindx(bound); 549 curlwp_bindx(bound);
550} 550}
551 551
552/* 552/*
553 * Free the link level name for the specified interface. This is 553 * Free the link level name for the specified interface. This is
554 * a detach helper. This is called from if_detach(). 554 * a detach helper. This is called from if_detach().
555 */ 555 */
556static void 556static void
557if_free_sadl(struct ifnet *ifp) 557if_free_sadl(struct ifnet *ifp)
558{ 558{
559 struct ifaddr *ifa; 559 struct ifaddr *ifa;
560 int s; 560 int s;
561 561
562 ifa = ifp->if_dl; 562 ifa = ifp->if_dl;
563 if (ifa == NULL) { 563 if (ifa == NULL) {
564 KASSERT(ifp->if_sadl == NULL); 564 KASSERT(ifp->if_sadl == NULL);
565 return; 565 return;
566 } 566 }
567 567
568 KASSERT(ifp->if_sadl != NULL); 568 KASSERT(ifp->if_sadl != NULL);
569 569
570 s = splsoftnet(); 570 s = splsoftnet();
571 rtinit(ifa, RTM_DELETE, 0); 571 rtinit(ifa, RTM_DELETE, 0);
572 ifa_remove(ifp, ifa); 572 ifa_remove(ifp, ifa);
573 if_deactivate_sadl(ifp); 573 if_deactivate_sadl(ifp);
574 if (ifp->if_hwdl == ifa) { 574 if (ifp->if_hwdl == ifa) {
575 ifafree(ifa); 575 ifafree(ifa);
576 ifp->if_hwdl = NULL; 576 ifp->if_hwdl = NULL;
577 } 577 }
578 splx(s); 578 splx(s);
579} 579}
580 580
581static void 581static void
582if_getindex(ifnet_t *ifp) 582if_getindex(ifnet_t *ifp)
583{ 583{
584 bool hitlimit = false; 584 bool hitlimit = false;
585 585
586 ifp->if_index_gen = index_gen++; 586 ifp->if_index_gen = index_gen++;
587 587
588 ifp->if_index = if_index; 588 ifp->if_index = if_index;
589 if (ifindex2ifnet == NULL) { 589 if (ifindex2ifnet == NULL) {
590 if_index++; 590 if_index++;
591 goto skip; 591 goto skip;
592 } 592 }
593 while (if_byindex(ifp->if_index)) { 593 while (if_byindex(ifp->if_index)) {
594 /* 594 /*
595 * If we hit USHRT_MAX, we skip back to 0 since 595 * If we hit USHRT_MAX, we skip back to 0 since
596 * there are a number of places where the value 596 * there are a number of places where the value
597 * of if_index or if_index itself is compared 597 * of if_index or if_index itself is compared
598 * to or stored in an unsigned short. By 598 * to or stored in an unsigned short. By
599 * jumping back, we won't botch those assignments 599 * jumping back, we won't botch those assignments
600 * or comparisons. 600 * or comparisons.
601 */ 601 */
602 if (++if_index == 0) { 602 if (++if_index == 0) {
603 if_index = 1; 603 if_index = 1;
604 } else if (if_index == USHRT_MAX) { 604 } else if (if_index == USHRT_MAX) {
605 /* 605 /*
606 * However, if we have to jump back to 606 * However, if we have to jump back to
607 * zero *twice* without finding an empty 607 * zero *twice* without finding an empty
608 * slot in ifindex2ifnet[], then there 608 * slot in ifindex2ifnet[], then there
609 * there are too many (>65535) interfaces. 609 * there are too many (>65535) interfaces.
610 */ 610 */
611 if (hitlimit) { 611 if (hitlimit) {
612 panic("too many interfaces"); 612 panic("too many interfaces");
613 } 613 }
614 hitlimit = true; 614 hitlimit = true;
615 if_index = 1; 615 if_index = 1;
616 } 616 }
617 ifp->if_index = if_index; 617 ifp->if_index = if_index;
618 } 618 }
619skip: 619skip:
620 /* 620 /*
621 * ifindex2ifnet is indexed by if_index. Since if_index will 621 * ifindex2ifnet is indexed by if_index. Since if_index will
622 * grow dynamically, it should grow too. 622 * grow dynamically, it should grow too.
623 */ 623 */
624 if (ifindex2ifnet == NULL || ifp->if_index >= if_indexlim) { 624 if (ifindex2ifnet == NULL || ifp->if_index >= if_indexlim) {
625 size_t m, n, oldlim; 625 size_t m, n, oldlim;
626 void *q; 626 void *q;
627 627
628 oldlim = if_indexlim; 628 oldlim = if_indexlim;
629 while (ifp->if_index >= if_indexlim) 629 while (ifp->if_index >= if_indexlim)
630 if_indexlim <<= 1; 630 if_indexlim <<= 1;
631 631
632 /* grow ifindex2ifnet */ 632 /* grow ifindex2ifnet */
633 m = oldlim * sizeof(struct ifnet *); 633 m = oldlim * sizeof(struct ifnet *);
634 n = if_indexlim * sizeof(struct ifnet *); 634 n = if_indexlim * sizeof(struct ifnet *);
635 q = malloc(n, M_IFADDR, M_WAITOK|M_ZERO); 635 q = malloc(n, M_IFADDR, M_WAITOK|M_ZERO);
636 if (ifindex2ifnet != NULL) { 636 if (ifindex2ifnet != NULL) {
637 memcpy(q, ifindex2ifnet, m); 637 memcpy(q, ifindex2ifnet, m);
638 free(ifindex2ifnet, M_IFADDR); 638 free(ifindex2ifnet, M_IFADDR);
639 } 639 }
640 ifindex2ifnet = (struct ifnet **)q; 640 ifindex2ifnet = (struct ifnet **)q;
641 } 641 }
642 ifindex2ifnet[ifp->if_index] = ifp; 642 ifindex2ifnet[ifp->if_index] = ifp;
643} 643}
644 644
645/* 645/*
646 * Initialize an interface and assign an index for it. 646 * Initialize an interface and assign an index for it.
647 * 647 *
648 * It must be called prior to a device specific attach routine 648 * It must be called prior to a device specific attach routine
649 * (e.g., ether_ifattach and ieee80211_ifattach) or if_alloc_sadl, 649 * (e.g., ether_ifattach and ieee80211_ifattach) or if_alloc_sadl,
650 * and be followed by if_register: 650 * and be followed by if_register:
651 * 651 *
652 * if_initialize(ifp); 652 * if_initialize(ifp);
653 * ether_ifattach(ifp, enaddr); 653 * ether_ifattach(ifp, enaddr);
654 * if_register(ifp); 654 * if_register(ifp);
655 */ 655 */
656void 656void
657if_initialize(ifnet_t *ifp) 657if_initialize(ifnet_t *ifp)
658{ 658{
659 KASSERT(if_indexlim > 0); 659 KASSERT(if_indexlim > 0);
660 TAILQ_INIT(&ifp->if_addrlist); 660 TAILQ_INIT(&ifp->if_addrlist);
661 661
662 /* 662 /*
663 * Link level name is allocated later by a separate call to 663 * Link level name is allocated later by a separate call to
664 * if_alloc_sadl(). 664 * if_alloc_sadl().
665 */ 665 */
666 666
667 if (ifp->if_snd.ifq_maxlen == 0) 667 if (ifp->if_snd.ifq_maxlen == 0)
668 ifp->if_snd.ifq_maxlen = ifqmaxlen; 668 ifp->if_snd.ifq_maxlen = ifqmaxlen;
669 669
670 ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */ 670 ifp->if_broadcastaddr = 0; /* reliably crash if used uninitialized */
671 671
672 ifp->if_link_state = LINK_STATE_UNKNOWN; 672 ifp->if_link_state = LINK_STATE_UNKNOWN;
673 ifp->if_link_queue = -1; /* all bits set, see link_state_change() */ 673 ifp->if_link_queue = -1; /* all bits set, see link_state_change() */
674 674
675 ifp->if_capenable = 0; 675 ifp->if_capenable = 0;
676 ifp->if_csum_flags_tx = 0; 676 ifp->if_csum_flags_tx = 0;
677 ifp->if_csum_flags_rx = 0; 677 ifp->if_csum_flags_rx = 0;
678 678
679#ifdef ALTQ 679#ifdef ALTQ
680 ifp->if_snd.altq_type = 0; 680 ifp->if_snd.altq_type = 0;
681 ifp->if_snd.altq_disc = NULL; 681 ifp->if_snd.altq_disc = NULL;
682 ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE; 682 ifp->if_snd.altq_flags &= ALTQF_CANTCHANGE;
683 ifp->if_snd.altq_tbr = NULL; 683 ifp->if_snd.altq_tbr = NULL;
684 ifp->if_snd.altq_ifp = ifp; 684 ifp->if_snd.altq_ifp = ifp;
685#endif 685#endif
686 686
687 IFQ_LOCK_INIT(&ifp->if_snd); 687 IFQ_LOCK_INIT(&ifp->if_snd);
688 688
689 ifp->if_pfil = pfil_head_create(PFIL_TYPE_IFNET, ifp); 689 ifp->if_pfil = pfil_head_create(PFIL_TYPE_IFNET, ifp);
690 pfil_run_ifhooks(if_pfil, PFIL_IFNET_ATTACH, ifp); 690 pfil_run_ifhooks(if_pfil, PFIL_IFNET_ATTACH, ifp);
691 691
692 IF_AFDATA_LOCK_INIT(ifp); 692 IF_AFDATA_LOCK_INIT(ifp);
693 693
694 if (if_is_link_state_changeable(ifp)) { 694 if (if_is_link_state_changeable(ifp)) {
695 ifp->if_link_si = softint_establish(SOFTINT_NET, 695 ifp->if_link_si = softint_establish(SOFTINT_NET,
696 if_link_state_change_si, ifp); 696 if_link_state_change_si, ifp);
697 if (ifp->if_link_si == NULL) 697 if (ifp->if_link_si == NULL)
698 panic("%s: softint_establish() failed", __func__); 698 panic("%s: softint_establish() failed", __func__);
699 } 699 }
700 700
701 PSLIST_ENTRY_INIT(ifp, if_pslist_entry); 701 PSLIST_ENTRY_INIT(ifp, if_pslist_entry);
702 PSLIST_INIT(&ifp->if_addr_pslist); 702 PSLIST_INIT(&ifp->if_addr_pslist);
703 psref_target_init(&ifp->if_psref, ifnet_psref_class); 703 psref_target_init(&ifp->if_psref, ifnet_psref_class);
704 ifp->if_ioctl_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 704 ifp->if_ioctl_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
705 705
706 IFNET_LOCK(); 706 IFNET_LOCK();
707 if_getindex(ifp); 707 if_getindex(ifp);
708 IFNET_UNLOCK(); 708 IFNET_UNLOCK();
709} 709}
710 710
711/* 711/*
712 * Register an interface to the list of "active" interfaces. 712 * Register an interface to the list of "active" interfaces.
713 */ 713 */
714void 714void
715if_register(ifnet_t *ifp) 715if_register(ifnet_t *ifp)
716{ 716{
717 /* 717 /*
718 * If the driver has not supplied its own if_ioctl, then 718 * If the driver has not supplied its own if_ioctl, then
719 * supply the default. 719 * supply the default.
720 */ 720 */
721 if (ifp->if_ioctl == NULL) 721 if (ifp->if_ioctl == NULL)
722 ifp->if_ioctl = ifioctl_common; 722 ifp->if_ioctl = ifioctl_common;
723 723
724 sysctl_sndq_setup(&ifp->if_sysctl_log, ifp->if_xname, &ifp->if_snd); 724 sysctl_sndq_setup(&ifp->if_sysctl_log, ifp->if_xname, &ifp->if_snd);
725 725
726 if (!STAILQ_EMPTY(&domains)) 726 if (!STAILQ_EMPTY(&domains))
727 if_attachdomain1(ifp); 727 if_attachdomain1(ifp);
728 728
729 /* Announce the interface. */ 729 /* Announce the interface. */
730 rt_ifannouncemsg(ifp, IFAN_ARRIVAL); 730 rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
731 731
732 if (ifp->if_slowtimo != NULL) { 732 if (ifp->if_slowtimo != NULL) {
733 ifp->if_slowtimo_ch = 733 ifp->if_slowtimo_ch =
734 kmem_zalloc(sizeof(*ifp->if_slowtimo_ch), KM_SLEEP); 734 kmem_zalloc(sizeof(*ifp->if_slowtimo_ch), KM_SLEEP);
735 callout_init(ifp->if_slowtimo_ch, 0); 735 callout_init(ifp->if_slowtimo_ch, 0);
736 callout_setfunc(ifp->if_slowtimo_ch, if_slowtimo, ifp); 736 callout_setfunc(ifp->if_slowtimo_ch, if_slowtimo, ifp);
737 if_slowtimo(ifp); 737 if_slowtimo(ifp);
738 } 738 }
739 739
740 if (ifp->if_transmit == NULL || ifp->if_transmit == if_nulltransmit) 740 if (ifp->if_transmit == NULL || ifp->if_transmit == if_nulltransmit)
741 ifp->if_transmit = if_transmit; 741 ifp->if_transmit = if_transmit;
742 742
743 IFNET_LOCK(); 743 IFNET_LOCK();
744 TAILQ_INSERT_TAIL(&ifnet_list, ifp, if_list); 744 TAILQ_INSERT_TAIL(&ifnet_list, ifp, if_list);
745 IFNET_WRITER_INSERT_TAIL(ifp); 745 IFNET_WRITER_INSERT_TAIL(ifp);
746 IFNET_UNLOCK(); 746 IFNET_UNLOCK();
747} 747}
748 748
749/* 749/*
750 * The if_percpuq framework 750 * The if_percpuq framework
751 * 751 *
752 * It allows network device drivers to execute the network stack 752 * It allows network device drivers to execute the network stack
753 * in softint (so called softint-based if_input). It utilizes 753 * in softint (so called softint-based if_input). It utilizes
754 * softint and percpu ifqueue. It doesn't distribute any packets 754 * softint and percpu ifqueue. It doesn't distribute any packets
755 * between CPUs, unlike pktqueue(9). 755 * between CPUs, unlike pktqueue(9).
756 * 756 *
757 * Currently we support two options for device drivers to apply the framework: 757 * Currently we support two options for device drivers to apply the framework:
758 * - Use it implicitly with less changes 758 * - Use it implicitly with less changes
759 * - If you use if_attach in driver's _attach function and if_input in 759 * - If you use if_attach in driver's _attach function and if_input in
760 * driver's Rx interrupt handler, a packet is queued and a softint handles 760 * driver's Rx interrupt handler, a packet is queued and a softint handles
761 * the packet implicitly 761 * the packet implicitly
762 * - Use it explicitly in each driver (recommended) 762 * - Use it explicitly in each driver (recommended)
763 * - You can use if_percpuq_* directly in your driver 763 * - You can use if_percpuq_* directly in your driver
764 * - In this case, you need to allocate struct if_percpuq in driver's softc 764 * - In this case, you need to allocate struct if_percpuq in driver's softc
765 * - See wm(4) as a reference implementation 765 * - See wm(4) as a reference implementation
766 */ 766 */
767 767
768static void 768static void
769if_percpuq_softint(void *arg) 769if_percpuq_softint(void *arg)
770{ 770{
771 struct if_percpuq *ipq = arg; 771 struct if_percpuq *ipq = arg;
772 struct ifnet *ifp = ipq->ipq_ifp; 772 struct ifnet *ifp = ipq->ipq_ifp;
773 struct mbuf *m; 773 struct mbuf *m;
774 774
775 while ((m = if_percpuq_dequeue(ipq)) != NULL) { 775 while ((m = if_percpuq_dequeue(ipq)) != NULL) {
776 ifp->if_ipackets++; 776 ifp->if_ipackets++;
777#ifndef NET_MPSAFE 777#ifndef NET_MPSAFE
778 KERNEL_LOCK(1, NULL); 778 KERNEL_LOCK(1, NULL);
779#endif 779#endif
780 bpf_mtap(ifp, m); 780 bpf_mtap(ifp, m);
781#ifndef NET_MPSAFE 781#ifndef NET_MPSAFE
782 KERNEL_UNLOCK_ONE(NULL); 782 KERNEL_UNLOCK_ONE(NULL);
783#endif 783#endif
784 784
785 ifp->_if_input(ifp, m); 785 ifp->_if_input(ifp, m);
786 } 786 }
787} 787}
788 788
789static void 789static void
790if_percpuq_init_ifq(void *p, void *arg __unused, struct cpu_info *ci __unused) 790if_percpuq_init_ifq(void *p, void *arg __unused, struct cpu_info *ci __unused)
791{ 791{
792 struct ifqueue *const ifq = p; 792 struct ifqueue *const ifq = p;
793 793
794 memset(ifq, 0, sizeof(*ifq)); 794 memset(ifq, 0, sizeof(*ifq));
795 ifq->ifq_maxlen = IFQ_MAXLEN; 795 ifq->ifq_maxlen = IFQ_MAXLEN;
796} 796}
797 797
798struct if_percpuq * 798struct if_percpuq *
799if_percpuq_create(struct ifnet *ifp) 799if_percpuq_create(struct ifnet *ifp)
800{ 800{
801 struct if_percpuq *ipq; 801 struct if_percpuq *ipq;
802 802
803 ipq = kmem_zalloc(sizeof(*ipq), KM_SLEEP); 803 ipq = kmem_zalloc(sizeof(*ipq), KM_SLEEP);
804 if (ipq == NULL) 804 if (ipq == NULL)
805 panic("kmem_zalloc failed"); 805 panic("kmem_zalloc failed");
806 806
807 ipq->ipq_ifp = ifp; 807 ipq->ipq_ifp = ifp;
808 ipq->ipq_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, 808 ipq->ipq_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE,
809 if_percpuq_softint, ipq); 809 if_percpuq_softint, ipq);
810 ipq->ipq_ifqs = percpu_alloc(sizeof(struct ifqueue)); 810 ipq->ipq_ifqs = percpu_alloc(sizeof(struct ifqueue));
811 percpu_foreach(ipq->ipq_ifqs, &if_percpuq_init_ifq, NULL); 811 percpu_foreach(ipq->ipq_ifqs, &if_percpuq_init_ifq, NULL);
812 812
813 sysctl_percpuq_setup(&ifp->if_sysctl_log, ifp->if_xname, ipq); 813 sysctl_percpuq_setup(&ifp->if_sysctl_log, ifp->if_xname, ipq);
814 814
815 return ipq; 815 return ipq;
816} 816}
817 817
818static struct mbuf * 818static struct mbuf *
819if_percpuq_dequeue(struct if_percpuq *ipq) 819if_percpuq_dequeue(struct if_percpuq *ipq)
820{ 820{
821 struct mbuf *m; 821 struct mbuf *m;
822 struct ifqueue *ifq; 822 struct ifqueue *ifq;
823 int s; 823 int s;
824 824
825 s = splnet(); 825 s = splnet();
826 ifq = percpu_getref(ipq->ipq_ifqs); 826 ifq = percpu_getref(ipq->ipq_ifqs);
827 IF_DEQUEUE(ifq, m); 827 IF_DEQUEUE(ifq, m);
828 percpu_putref(ipq->ipq_ifqs); 828 percpu_putref(ipq->ipq_ifqs);
829 splx(s); 829 splx(s);
830 830
831 return m; 831 return m;
832} 832}
833 833
834static void 834static void
835if_percpuq_purge_ifq(void *p, void *arg __unused, struct cpu_info *ci __unused) 835if_percpuq_purge_ifq(void *p, void *arg __unused, struct cpu_info *ci __unused)
836{ 836{
837 struct ifqueue *const ifq = p; 837 struct ifqueue *const ifq = p;
838 838
839 IF_PURGE(ifq); 839 IF_PURGE(ifq);
840} 840}
841 841
842void 842void
843if_percpuq_destroy(struct if_percpuq *ipq) 843if_percpuq_destroy(struct if_percpuq *ipq)
844{ 844{
845 845
846 /* if_detach may already destroy it */ 846 /* if_detach may already destroy it */
847 if (ipq == NULL) 847 if (ipq == NULL)
848 return; 848 return;
849 849
850 softint_disestablish(ipq->ipq_si); 850 softint_disestablish(ipq->ipq_si);
851 percpu_foreach(ipq->ipq_ifqs, &if_percpuq_purge_ifq, NULL); 851 percpu_foreach(ipq->ipq_ifqs, &if_percpuq_purge_ifq, NULL);
852 percpu_free(ipq->ipq_ifqs, sizeof(struct ifqueue)); 852 percpu_free(ipq->ipq_ifqs, sizeof(struct ifqueue));
853 kmem_free(ipq, sizeof(*ipq)); 853 kmem_free(ipq, sizeof(*ipq));
854} 854}
855 855
856void 856void
857if_percpuq_enqueue(struct if_percpuq *ipq, struct mbuf *m) 857if_percpuq_enqueue(struct if_percpuq *ipq, struct mbuf *m)
858{ 858{
859 struct ifqueue *ifq; 859 struct ifqueue *ifq;
860 int s; 860 int s;
861 861
862 KASSERT(ipq != NULL); 862 KASSERT(ipq != NULL);
863 863
864 s = splnet(); 864 s = splnet();
865 ifq = percpu_getref(ipq->ipq_ifqs); 865 ifq = percpu_getref(ipq->ipq_ifqs);
866 if (IF_QFULL(ifq)) { 866 if (IF_QFULL(ifq)) {
867 IF_DROP(ifq); 867 IF_DROP(ifq);
868 percpu_putref(ipq->ipq_ifqs); 868 percpu_putref(ipq->ipq_ifqs);
869 m_freem(m); 869 m_freem(m);
870 goto out; 870 goto out;
871 } 871 }
872 IF_ENQUEUE(ifq, m); 872 IF_ENQUEUE(ifq, m);
873 percpu_putref(ipq->ipq_ifqs); 873 percpu_putref(ipq->ipq_ifqs);
874 874
875 softint_schedule(ipq->ipq_si); 875 softint_schedule(ipq->ipq_si);
876out: 876out:
877 splx(s); 877 splx(s);
878} 878}
879 879
880static void 880static void
881if_percpuq_drops(void *p, void *arg, struct cpu_info *ci __unused) 881if_percpuq_drops(void *p, void *arg, struct cpu_info *ci __unused)
882{ 882{
883 struct ifqueue *const ifq = p; 883 struct ifqueue *const ifq = p;
884 int *sum = arg; 884 int *sum = arg;
885 885
886 *sum += ifq->ifq_drops; 886 *sum += ifq->ifq_drops;
887} 887}
888 888
889static int 889static int
890sysctl_percpuq_drops_handler(SYSCTLFN_ARGS) 890sysctl_percpuq_drops_handler(SYSCTLFN_ARGS)
891{ 891{
892 struct sysctlnode node; 892 struct sysctlnode node;
893 struct if_percpuq *ipq; 893 struct if_percpuq *ipq;
894 int sum = 0; 894 int sum = 0;
895 int error; 895 int error;
896 896
897 node = *rnode; 897 node = *rnode;
898 ipq = node.sysctl_data; 898 ipq = node.sysctl_data;
899 899
900 percpu_foreach(ipq->ipq_ifqs, if_percpuq_drops, &sum); 900 percpu_foreach(ipq->ipq_ifqs, if_percpuq_drops, &sum);
901 901
902 node.sysctl_data = &sum; 902 node.sysctl_data = &sum;
903 error = sysctl_lookup(SYSCTLFN_CALL(&node)); 903 error = sysctl_lookup(SYSCTLFN_CALL(&node));
904 if (error != 0 || newp == NULL) 904 if (error != 0 || newp == NULL)
905 return error; 905 return error;
906 906
907 return 0; 907 return 0;
908} 908}
909 909
910static void 910static void
911sysctl_percpuq_setup(struct sysctllog **clog, const char* ifname, 911sysctl_percpuq_setup(struct sysctllog **clog, const char* ifname,
912 struct if_percpuq *ipq) 912 struct if_percpuq *ipq)
913{ 913{
914 const struct sysctlnode *cnode, *rnode; 914 const struct sysctlnode *cnode, *rnode;
915 915
916 if (sysctl_createv(clog, 0, NULL, &rnode, 916 if (sysctl_createv(clog, 0, NULL, &rnode,
917 CTLFLAG_PERMANENT, 917 CTLFLAG_PERMANENT,
918 CTLTYPE_NODE, "interfaces", 918 CTLTYPE_NODE, "interfaces",
919 SYSCTL_DESCR("Per-interface controls"), 919 SYSCTL_DESCR("Per-interface controls"),
920 NULL, 0, NULL, 0, 920 NULL, 0, NULL, 0,
921 CTL_NET, CTL_CREATE, CTL_EOL) != 0) 921 CTL_NET, CTL_CREATE, CTL_EOL) != 0)
922 goto bad; 922 goto bad;
923 923
924 if (sysctl_createv(clog, 0, &rnode, &rnode, 924 if (sysctl_createv(clog, 0, &rnode, &rnode,
925 CTLFLAG_PERMANENT, 925 CTLFLAG_PERMANENT,
926 CTLTYPE_NODE, ifname, 926 CTLTYPE_NODE, ifname,
927 SYSCTL_DESCR("Interface controls"), 927 SYSCTL_DESCR("Interface controls"),
928 NULL, 0, NULL, 0, 928 NULL, 0, NULL, 0,
929 CTL_CREATE, CTL_EOL) != 0) 929 CTL_CREATE, CTL_EOL) != 0)
930 goto bad; 930 goto bad;
931 931
932 if (sysctl_createv(clog, 0, &rnode, &rnode, 932 if (sysctl_createv(clog, 0, &rnode, &rnode,
933 CTLFLAG_PERMANENT, 933 CTLFLAG_PERMANENT,
934 CTLTYPE_NODE, "rcvq", 934 CTLTYPE_NODE, "rcvq",
935 SYSCTL_DESCR("Interface input queue controls"), 935 SYSCTL_DESCR("Interface input queue controls"),
936 NULL, 0, NULL, 0, 936 NULL, 0, NULL, 0,
937 CTL_CREATE, CTL_EOL) != 0) 937 CTL_CREATE, CTL_EOL) != 0)
938 goto bad; 938 goto bad;
939 939
940#ifdef NOTYET 940#ifdef NOTYET
941 /* XXX Should show each per-CPU queue length? */ 941 /* XXX Should show each per-CPU queue length? */
942 if (sysctl_createv(clog, 0, &rnode, &rnode, 942 if (sysctl_createv(clog, 0, &rnode, &rnode,
943 CTLFLAG_PERMANENT, 943 CTLFLAG_PERMANENT,
944 CTLTYPE_INT, "len", 944 CTLTYPE_INT, "len",
945 SYSCTL_DESCR("Current input queue length"), 945 SYSCTL_DESCR("Current input queue length"),
946 sysctl_percpuq_len, 0, NULL, 0, 946 sysctl_percpuq_len, 0, NULL, 0,
947 CTL_CREATE, CTL_EOL) != 0) 947 CTL_CREATE, CTL_EOL) != 0)
948 goto bad; 948 goto bad;
949 949
950 if (sysctl_createv(clog, 0, &rnode, &cnode, 950 if (sysctl_createv(clog, 0, &rnode, &cnode,
951 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 951 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
952 CTLTYPE_INT, "maxlen", 952 CTLTYPE_INT, "maxlen",
953 SYSCTL_DESCR("Maximum allowed input queue length"), 953 SYSCTL_DESCR("Maximum allowed input queue length"),
954 sysctl_percpuq_maxlen_handler, 0, (void *)ipq, 0, 954 sysctl_percpuq_maxlen_handler, 0, (void *)ipq, 0,
955 CTL_CREATE, CTL_EOL) != 0) 955 CTL_CREATE, CTL_EOL) != 0)
956 goto bad; 956 goto bad;
957#endif 957#endif
958 958
959 if (sysctl_createv(clog, 0, &rnode, &cnode, 959 if (sysctl_createv(clog, 0, &rnode, &cnode,
960 CTLFLAG_PERMANENT, 960 CTLFLAG_PERMANENT,
961 CTLTYPE_INT, "drops", 961 CTLTYPE_INT, "drops",
962 SYSCTL_DESCR("Total packets dropped due to full input queue"), 962 SYSCTL_DESCR("Total packets dropped due to full input queue"),
963 sysctl_percpuq_drops_handler, 0, (void *)ipq, 0, 963 sysctl_percpuq_drops_handler, 0, (void *)ipq, 0,
964 CTL_CREATE, CTL_EOL) != 0) 964 CTL_CREATE, CTL_EOL) != 0)
965 goto bad; 965 goto bad;
966 966
967 return; 967 return;
968bad: 968bad:
969 printf("%s: could not attach sysctl nodes\n", ifname); 969 printf("%s: could not attach sysctl nodes\n", ifname);
970 return; 970 return;
971} 971}
972 972
973/* 973/*
974 * The deferred if_start framework 974 * The deferred if_start framework
975 * 975 *
976 * The common APIs to defer if_start to softint when if_start is requested 976 * The common APIs to defer if_start to softint when if_start is requested
977 * from a device driver running in hardware interrupt context. 977 * from a device driver running in hardware interrupt context.
978 */ 978 */
979/* 979/*
980 * Call ifp->if_start (or equivalent) in a dedicated softint for 980 * Call ifp->if_start (or equivalent) in a dedicated softint for
981 * deferred if_start. 981 * deferred if_start.
982 */ 982 */
983static void 983static void
984if_deferred_start_softint(void *arg) 984if_deferred_start_softint(void *arg)
985{ 985{
986 struct if_deferred_start *ids = arg; 986 struct if_deferred_start *ids = arg;
987 struct ifnet *ifp = ids->ids_ifp; 987 struct ifnet *ifp = ids->ids_ifp;
988 988
989 ids->ids_if_start(ifp); 989 ids->ids_if_start(ifp);
990} 990}
991 991
992/* 992/*
993 * The default callback function for deferred if_start. 993 * The default callback function for deferred if_start.
994 */ 994 */
995static void 995static void
996if_deferred_start_common(struct ifnet *ifp) 996if_deferred_start_common(struct ifnet *ifp)
997{ 997{
998 998
999 if_start_lock(ifp); 999 if_start_lock(ifp);
1000} 1000}
1001 1001
1002static inline bool 1002static inline bool
1003if_snd_is_used(struct ifnet *ifp) 1003if_snd_is_used(struct ifnet *ifp)
1004{ 1004{
1005 1005
1006 return ifp->if_transmit == NULL || ifp->if_transmit == if_nulltransmit || 1006 return ifp->if_transmit == NULL || ifp->if_transmit == if_nulltransmit ||
1007 ALTQ_IS_ENABLED(&ifp->if_snd); 1007 ALTQ_IS_ENABLED(&ifp->if_snd);
1008} 1008}
1009 1009
1010/* 1010/*
1011 * Schedule deferred if_start. 1011 * Schedule deferred if_start.
1012 */ 1012 */
1013void 1013void
1014if_schedule_deferred_start(struct ifnet *ifp) 1014if_schedule_deferred_start(struct ifnet *ifp)
1015{ 1015{
1016 1016
1017 KASSERT(ifp->if_deferred_start != NULL); 1017 KASSERT(ifp->if_deferred_start != NULL);
1018 1018
1019 if (if_snd_is_used(ifp) && IFQ_IS_EMPTY(&ifp->if_snd)) 1019 if (if_snd_is_used(ifp) && IFQ_IS_EMPTY(&ifp->if_snd))
1020 return; 1020 return;
1021 1021
1022 softint_schedule(ifp->if_deferred_start->ids_si); 1022 softint_schedule(ifp->if_deferred_start->ids_si);
1023} 1023}
1024 1024
1025/* 1025/*
1026 * Create an instance of deferred if_start. A driver should call the function 1026 * Create an instance of deferred if_start. A driver should call the function
1027 * only if the driver needs deferred if_start. Drivers can setup their own 1027 * only if the driver needs deferred if_start. Drivers can setup their own
1028 * deferred if_start function via 2nd argument. 1028 * deferred if_start function via 2nd argument.
1029 */ 1029 */
1030void 1030void
1031if_deferred_start_init(struct ifnet *ifp, void (*func)(struct ifnet *)) 1031if_deferred_start_init(struct ifnet *ifp, void (*func)(struct ifnet *))
1032{ 1032{
1033 struct if_deferred_start *ids; 1033 struct if_deferred_start *ids;
1034 1034
1035 ids = kmem_zalloc(sizeof(*ids), KM_SLEEP); 1035 ids = kmem_zalloc(sizeof(*ids), KM_SLEEP);
1036 if (ids == NULL) 1036 if (ids == NULL)
1037 panic("kmem_zalloc failed"); 1037 panic("kmem_zalloc failed");
1038 1038
1039 ids->ids_ifp = ifp; 1039 ids->ids_ifp = ifp;
1040 ids->ids_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE, 1040 ids->ids_si = softint_establish(SOFTINT_NET|SOFTINT_MPSAFE,
1041 if_deferred_start_softint, ids); 1041 if_deferred_start_softint, ids);
1042 if (func != NULL) 1042 if (func != NULL)
1043 ids->ids_if_start = func; 1043 ids->ids_if_start = func;
1044 else 1044 else
1045 ids->ids_if_start = if_deferred_start_common; 1045 ids->ids_if_start = if_deferred_start_common;
1046 1046
1047 ifp->if_deferred_start = ids; 1047 ifp->if_deferred_start = ids;
1048} 1048}
1049 1049
1050static void 1050static void
1051if_deferred_start_destroy(struct ifnet *ifp) 1051if_deferred_start_destroy(struct ifnet *ifp)
1052{ 1052{
1053 1053
1054 if (ifp->if_deferred_start == NULL) 1054 if (ifp->if_deferred_start == NULL)
1055 return; 1055 return;
1056 1056
1057 softint_disestablish(ifp->if_deferred_start->ids_si); 1057 softint_disestablish(ifp->if_deferred_start->ids_si);
1058 kmem_free(ifp->if_deferred_start, sizeof(*ifp->if_deferred_start)); 1058 kmem_free(ifp->if_deferred_start, sizeof(*ifp->if_deferred_start));
1059 ifp->if_deferred_start = NULL; 1059 ifp->if_deferred_start = NULL;
1060} 1060}
1061 1061
1062/* 1062/*
1063 * The common interface input routine that is called by device drivers, 1063 * The common interface input routine that is called by device drivers,
1064 * which should be used only when the driver's rx handler already runs 1064 * which should be used only when the driver's rx handler already runs
1065 * in softint. 1065 * in softint.
1066 */ 1066 */
1067void 1067void
1068if_input(struct ifnet *ifp, struct mbuf *m) 1068if_input(struct ifnet *ifp, struct mbuf *m)
1069{ 1069{
1070 1070
1071 KASSERT(ifp->if_percpuq == NULL); 1071 KASSERT(ifp->if_percpuq == NULL);
1072 KASSERT(!cpu_intr_p()); 1072 KASSERT(!cpu_intr_p());
1073 1073
1074 ifp->if_ipackets++; 1074 ifp->if_ipackets++;
1075#ifndef NET_MPSAFE 1075#ifndef NET_MPSAFE
1076 KERNEL_LOCK(1, NULL); 1076 KERNEL_LOCK(1, NULL);
1077#endif 1077#endif
1078 bpf_mtap(ifp, m); 1078 bpf_mtap(ifp, m);
1079#ifndef NET_MPSAFE 1079#ifndef NET_MPSAFE
1080 KERNEL_UNLOCK_ONE(NULL); 1080 KERNEL_UNLOCK_ONE(NULL);
1081#endif 1081#endif
1082 1082
1083 ifp->_if_input(ifp, m); 1083 ifp->_if_input(ifp, m);
1084} 1084}
1085 1085
1086/* 1086/*
1087 * DEPRECATED. Use if_initialize and if_register instead. 1087 * DEPRECATED. Use if_initialize and if_register instead.
1088 * See the above comment of if_initialize. 1088 * See the above comment of if_initialize.
1089 * 1089 *
1090 * Note that it implicitly enables if_percpuq to make drivers easy to 1090 * Note that it implicitly enables if_percpuq to make drivers easy to
1091 * migrate softint-based if_input without much changes. If you don't 1091 * migrate softint-based if_input without much changes. If you don't
1092 * want to enable it, use if_initialize instead. 1092 * want to enable it, use if_initialize instead.
1093 */ 1093 */
1094void 1094void
1095if_attach(ifnet_t *ifp) 1095if_attach(ifnet_t *ifp)
1096{ 1096{
1097 1097
1098 if_initialize(ifp); 1098 if_initialize(ifp);
1099 ifp->if_percpuq = if_percpuq_create(ifp); 1099 ifp->if_percpuq = if_percpuq_create(ifp);
1100 if_register(ifp); 1100 if_register(ifp);
1101} 1101}
1102 1102
1103void 1103void
1104if_attachdomain(void) 1104if_attachdomain(void)
1105{ 1105{
1106 struct ifnet *ifp; 1106 struct ifnet *ifp;
1107 int s; 1107 int s;
1108 int bound = curlwp_bind(); 1108 int bound = curlwp_bind();
1109 1109
1110 s = pserialize_read_enter(); 1110 s = pserialize_read_enter();
1111 IFNET_READER_FOREACH(ifp) { 1111 IFNET_READER_FOREACH(ifp) {
1112 struct psref psref; 1112 struct psref psref;
1113 psref_acquire(&psref, &ifp->if_psref, ifnet_psref_class); 1113 psref_acquire(&psref, &ifp->if_psref, ifnet_psref_class);
1114 pserialize_read_exit(s); 1114 pserialize_read_exit(s);
1115 if_attachdomain1(ifp); 1115 if_attachdomain1(ifp);
1116 s = pserialize_read_enter(); 1116 s = pserialize_read_enter();
1117 psref_release(&psref, &ifp->if_psref, ifnet_psref_class); 1117 psref_release(&psref, &ifp->if_psref, ifnet_psref_class);
1118 } 1118 }
1119 pserialize_read_exit(s); 1119 pserialize_read_exit(s);
1120 curlwp_bindx(bound); 1120 curlwp_bindx(bound);
1121} 1121}
1122 1122
1123static void 1123static void
1124if_attachdomain1(struct ifnet *ifp) 1124if_attachdomain1(struct ifnet *ifp)
1125{ 1125{
1126 struct domain *dp; 1126 struct domain *dp;
1127 int s; 1127 int s;
1128 1128
1129 s = splsoftnet(); 1129 s = splsoftnet();
1130 1130
1131 /* address family dependent data region */ 1131 /* address family dependent data region */
1132 memset(ifp->if_afdata, 0, sizeof(ifp->if_afdata)); 1132 memset(ifp->if_afdata, 0, sizeof(ifp->if_afdata));
1133 DOMAIN_FOREACH(dp) { 1133 DOMAIN_FOREACH(dp) {
1134 if (dp->dom_ifattach != NULL) 1134 if (dp->dom_ifattach != NULL)
1135 ifp->if_afdata[dp->dom_family] = 1135 ifp->if_afdata[dp->dom_family] =
1136 (*dp->dom_ifattach)(ifp); 1136 (*dp->dom_ifattach)(ifp);
1137 } 1137 }
1138 1138
1139 splx(s); 1139 splx(s);
1140} 1140}
1141 1141
1142/* 1142/*
1143 * Deactivate an interface. This points all of the procedure 1143 * Deactivate an interface. This points all of the procedure
1144 * handles at error stubs. May be called from interrupt context. 1144 * handles at error stubs. May be called from interrupt context.
1145 */ 1145 */
1146void 1146void
1147if_deactivate(struct ifnet *ifp) 1147if_deactivate(struct ifnet *ifp)
1148{ 1148{
1149 int s; 1149 int s;
1150 1150
1151 s = splsoftnet(); 1151 s = splsoftnet();
1152 1152
1153 ifp->if_output = if_nulloutput; 1153 ifp->if_output = if_nulloutput;
1154 ifp->_if_input = if_nullinput; 1154 ifp->_if_input = if_nullinput;
1155 ifp->if_start = if_nullstart; 1155 ifp->if_start = if_nullstart;
1156 ifp->if_transmit = if_nulltransmit; 1156 ifp->if_transmit = if_nulltransmit;
1157 ifp->if_ioctl = if_nullioctl; 1157 ifp->if_ioctl = if_nullioctl;
1158 ifp->if_init = if_nullinit; 1158 ifp->if_init = if_nullinit;
1159 ifp->if_stop = if_nullstop; 1159 ifp->if_stop = if_nullstop;
1160 ifp->if_slowtimo = if_nullslowtimo; 1160 ifp->if_slowtimo = if_nullslowtimo;
1161 ifp->if_drain = if_nulldrain; 1161 ifp->if_drain = if_nulldrain;
1162 1162
1163 /* No more packets may be enqueued. */ 1163 /* No more packets may be enqueued. */
1164 ifp->if_snd.ifq_maxlen = 0; 1164 ifp->if_snd.ifq_maxlen = 0;
1165 1165
1166 splx(s); 1166 splx(s);
1167} 1167}
1168 1168
1169bool 1169bool
1170if_is_deactivated(const struct ifnet *ifp) 1170if_is_deactivated(const struct ifnet *ifp)
1171{ 1171{
1172 1172
1173 return ifp->if_output == if_nulloutput; 1173 return ifp->if_output == if_nulloutput;
1174} 1174}
1175 1175
1176void 1176void
1177if_purgeaddrs(struct ifnet *ifp, int family, void (*purgeaddr)(struct ifaddr *)) 1177if_purgeaddrs(struct ifnet *ifp, int family, void (*purgeaddr)(struct ifaddr *))
1178{ 1178{
1179 struct ifaddr *ifa, *nifa; 1179 struct ifaddr *ifa, *nifa;
1180 int s; 1180 int s;
1181 1181
1182 s = pserialize_read_enter(); 1182 s = pserialize_read_enter();
1183 for (ifa = IFADDR_READER_FIRST(ifp); ifa; ifa = nifa) { 1183 for (ifa = IFADDR_READER_FIRST(ifp); ifa; ifa = nifa) {
1184 nifa = IFADDR_READER_NEXT(ifa); 1184 nifa = IFADDR_READER_NEXT(ifa);
1185 if (ifa->ifa_addr->sa_family != family) 1185 if (ifa->ifa_addr->sa_family != family)
1186 continue; 1186 continue;
1187 pserialize_read_exit(s); 1187 pserialize_read_exit(s);
1188 1188
1189 (*purgeaddr)(ifa); 1189 (*purgeaddr)(ifa);
1190 1190
1191 s = pserialize_read_enter(); 1191 s = pserialize_read_enter();
1192 } 1192 }
1193 pserialize_read_exit(s); 1193 pserialize_read_exit(s);
1194} 1194}
1195 1195
1196#ifdef IFAREF_DEBUG 1196#ifdef IFAREF_DEBUG
1197static struct ifaddr **ifa_list; 1197static struct ifaddr **ifa_list;
1198static int ifa_list_size; 1198static int ifa_list_size;
1199 1199
1200/* Depends on only one if_attach runs at once */ 1200/* Depends on only one if_attach runs at once */
1201static void 1201static void
1202if_build_ifa_list(struct ifnet *ifp) 1202if_build_ifa_list(struct ifnet *ifp)
1203{ 1203{
1204 struct ifaddr *ifa; 1204 struct ifaddr *ifa;
1205 int i; 1205 int i;
1206 1206
1207 KASSERT(ifa_list == NULL); 1207 KASSERT(ifa_list == NULL);
1208 KASSERT(ifa_list_size == 0); 1208 KASSERT(ifa_list_size == 0);
1209 1209
1210 IFADDR_READER_FOREACH(ifa, ifp) 1210 IFADDR_READER_FOREACH(ifa, ifp)
1211 ifa_list_size++; 1211 ifa_list_size++;
1212 1212
1213 ifa_list = kmem_alloc(sizeof(*ifa) * ifa_list_size, KM_SLEEP); 1213 ifa_list = kmem_alloc(sizeof(*ifa) * ifa_list_size, KM_SLEEP);
1214 if (ifa_list == NULL) 1214 if (ifa_list == NULL)
1215 return; 1215 return;
1216 1216
1217 i = 0; 1217 i = 0;
1218 IFADDR_READER_FOREACH(ifa, ifp) { 1218 IFADDR_READER_FOREACH(ifa, ifp) {
1219 ifa_list[i++] = ifa; 1219 ifa_list[i++] = ifa;
1220 ifaref(ifa); 1220 ifaref(ifa);
1221 } 1221 }
1222} 1222}
1223 1223
1224static void 1224static void
1225if_check_and_free_ifa_list(struct ifnet *ifp) 1225if_check_and_free_ifa_list(struct ifnet *ifp)
1226{ 1226{
1227 int i; 1227 int i;
1228 struct ifaddr *ifa; 1228 struct ifaddr *ifa;
1229 1229
1230 if (ifa_list == NULL) 1230 if (ifa_list == NULL)
1231 return; 1231 return;
1232 1232
1233 for (i = 0; i < ifa_list_size; i++) { 1233 for (i = 0; i < ifa_list_size; i++) {
1234 char buf[64]; 1234 char buf[64];
1235 1235
1236 ifa = ifa_list[i]; 1236 ifa = ifa_list[i];
1237 sockaddr_format(ifa->ifa_addr, buf, sizeof(buf)); 1237 sockaddr_format(ifa->ifa_addr, buf, sizeof(buf));
1238 if (ifa->ifa_refcnt > 1) { 1238 if (ifa->ifa_refcnt > 1) {
1239 log(LOG_WARNING, 1239 log(LOG_WARNING,
1240 "ifa(%s) still referenced (refcnt=%d)\n", 1240 "ifa(%s) still referenced (refcnt=%d)\n",
1241 buf, ifa->ifa_refcnt - 1); 1241 buf, ifa->ifa_refcnt - 1);
1242 } else 1242 } else
1243 log(LOG_DEBUG, 1243 log(LOG_DEBUG,
1244 "ifa(%s) not referenced (refcnt=%d)\n", 1244 "ifa(%s) not referenced (refcnt=%d)\n",
1245 buf, ifa->ifa_refcnt - 1); 1245 buf, ifa->ifa_refcnt - 1);
1246 ifafree(ifa); 1246 ifafree(ifa);
1247 } 1247 }
1248 1248
1249 kmem_free(ifa_list, sizeof(*ifa) * ifa_list_size); 1249 kmem_free(ifa_list, sizeof(*ifa) * ifa_list_size);
1250 ifa_list = NULL; 1250 ifa_list = NULL;
1251 ifa_list_size = 0; 1251 ifa_list_size = 0;
1252} 1252}
1253#endif 1253#endif
1254 1254
1255/* 1255/*
1256 * Detach an interface from the list of "active" interfaces, 1256 * Detach an interface from the list of "active" interfaces,
1257 * freeing any resources as we go along. 1257 * freeing any resources as we go along.
1258 * 1258 *
1259 * NOTE: This routine must be called with a valid thread context, 1259 * NOTE: This routine must be called with a valid thread context,
1260 * as it may block. 1260 * as it may block.
1261 */ 1261 */
1262void 1262void
1263if_detach(struct ifnet *ifp) 1263if_detach(struct ifnet *ifp)
1264{ 1264{
1265 struct socket so; 1265 struct socket so;
1266 struct ifaddr *ifa; 1266 struct ifaddr *ifa;
1267#ifdef IFAREF_DEBUG 1267#ifdef IFAREF_DEBUG
1268 struct ifaddr *last_ifa = NULL; 1268 struct ifaddr *last_ifa = NULL;
1269#endif 1269#endif
1270 struct domain *dp; 1270 struct domain *dp;
1271 const struct protosw *pr; 1271 const struct protosw *pr;
1272 int s, i, family, purged; 1272 int s, i, family, purged;
1273 uint64_t xc; 1273 uint64_t xc;
1274 1274
1275#ifdef IFAREF_DEBUG 1275#ifdef IFAREF_DEBUG
1276 if_build_ifa_list(ifp); 1276 if_build_ifa_list(ifp);
1277#endif 1277#endif
1278 /* 1278 /*
1279 * XXX It's kind of lame that we have to have the 1279 * XXX It's kind of lame that we have to have the
1280 * XXX socket structure... 1280 * XXX socket structure...
1281 */ 1281 */
1282 memset(&so, 0, sizeof(so)); 1282 memset(&so, 0, sizeof(so));
1283 1283
1284 s = splnet(); 1284 s = splnet();
1285 1285
1286 sysctl_teardown(&ifp->if_sysctl_log); 1286 sysctl_teardown(&ifp->if_sysctl_log);
1287 mutex_enter(ifp->if_ioctl_lock); 1287 mutex_enter(ifp->if_ioctl_lock);
1288 if_deactivate(ifp); 1288 if_deactivate(ifp);
1289 mutex_exit(ifp->if_ioctl_lock); 1289 mutex_exit(ifp->if_ioctl_lock);
1290 1290
1291 IFNET_LOCK(); 1291 IFNET_LOCK();
1292 ifindex2ifnet[ifp->if_index] = NULL; 1292 ifindex2ifnet[ifp->if_index] = NULL;
1293 TAILQ_REMOVE(&ifnet_list, ifp, if_list); 1293 TAILQ_REMOVE(&ifnet_list, ifp, if_list);
1294 IFNET_WRITER_REMOVE(ifp); 1294 IFNET_WRITER_REMOVE(ifp);
1295 pserialize_perform(ifnet_psz); 1295 pserialize_perform(ifnet_psz);
1296 IFNET_UNLOCK(); 1296 IFNET_UNLOCK();
1297 1297
1298 /* Wait for all readers to drain before freeing. */ 1298 /* Wait for all readers to drain before freeing. */
1299 psref_target_destroy(&ifp->if_psref, ifnet_psref_class); 1299 psref_target_destroy(&ifp->if_psref, ifnet_psref_class);
1300 PSLIST_ENTRY_DESTROY(ifp, if_pslist_entry); 1300 PSLIST_ENTRY_DESTROY(ifp, if_pslist_entry);
1301 1301
1302 mutex_obj_free(ifp->if_ioctl_lock); 1302 mutex_obj_free(ifp->if_ioctl_lock);
1303 ifp->if_ioctl_lock = NULL; 1303 ifp->if_ioctl_lock = NULL;
1304 1304
1305 if (ifp->if_slowtimo != NULL && ifp->if_slowtimo_ch != NULL) { 1305 if (ifp->if_slowtimo != NULL && ifp->if_slowtimo_ch != NULL) {
1306 ifp->if_slowtimo = NULL; 1306 ifp->if_slowtimo = NULL;
1307 callout_halt(ifp->if_slowtimo_ch, NULL); 1307 callout_halt(ifp->if_slowtimo_ch, NULL);
1308 callout_destroy(ifp->if_slowtimo_ch); 1308 callout_destroy(ifp->if_slowtimo_ch);
1309 kmem_free(ifp->if_slowtimo_ch, sizeof(*ifp->if_slowtimo_ch)); 1309 kmem_free(ifp->if_slowtimo_ch, sizeof(*ifp->if_slowtimo_ch));
1310 } 1310 }
1311 if_deferred_start_destroy(ifp); 1311 if_deferred_start_destroy(ifp);
1312 1312
1313 /* 1313 /*
1314 * Do an if_down() to give protocols a chance to do something. 1314 * Do an if_down() to give protocols a chance to do something.
1315 */ 1315 */
1316 if_down(ifp); 1316 if_down(ifp);
1317 1317
1318#ifdef ALTQ 1318#ifdef ALTQ
1319 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 1319 if (ALTQ_IS_ENABLED(&ifp->if_snd))
1320 altq_disable(&ifp->if_snd); 1320 altq_disable(&ifp->if_snd);
1321 if (ALTQ_IS_ATTACHED(&ifp->if_snd)) 1321 if (ALTQ_IS_ATTACHED(&ifp->if_snd))
1322 altq_detach(&ifp->if_snd); 1322 altq_detach(&ifp->if_snd);
1323#endif 1323#endif
1324 1324
1325 mutex_obj_free(ifp->if_snd.ifq_lock); 1325 mutex_obj_free(ifp->if_snd.ifq_lock);
1326 1326
1327#if NCARP > 0 1327#if NCARP > 0
1328 /* Remove the interface from any carp group it is a part of. */ 1328 /* Remove the interface from any carp group it is a part of. */
1329 if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP) 1329 if (ifp->if_carp != NULL && ifp->if_type != IFT_CARP)
1330 carp_ifdetach(ifp); 1330 carp_ifdetach(ifp);
1331#endif 1331#endif
1332 1332
1333 /* 1333 /*
1334 * Rip all the addresses off the interface. This should make 1334 * Rip all the addresses off the interface. This should make
1335 * all of the routes go away. 1335 * all of the routes go away.
1336 * 1336 *
1337 * pr_usrreq calls can remove an arbitrary number of ifaddrs 1337 * pr_usrreq calls can remove an arbitrary number of ifaddrs
1338 * from the list, including our "cursor", ifa. For safety, 1338 * from the list, including our "cursor", ifa. For safety,
1339 * and to honor the TAILQ abstraction, I just restart the 1339 * and to honor the TAILQ abstraction, I just restart the
1340 * loop after each removal. Note that the loop will exit 1340 * loop after each removal. Note that the loop will exit
1341 * when all of the remaining ifaddrs belong to the AF_LINK 1341 * when all of the remaining ifaddrs belong to the AF_LINK
1342 * family. I am counting on the historical fact that at 1342 * family. I am counting on the historical fact that at
1343 * least one pr_usrreq in each address domain removes at 1343 * least one pr_usrreq in each address domain removes at
1344 * least one ifaddr. 1344 * least one ifaddr.
1345 */ 1345 */
1346again: 1346again:
1347 /* 1347 /*
1348 * At this point, no other one tries to remove ifa in the list, 1348 * At this point, no other one tries to remove ifa in the list,
1349 * so we don't need to take a lock or psref. 1349 * so we don't need to take a lock or psref.
1350 */ 1350 */
1351 IFADDR_READER_FOREACH(ifa, ifp) { 1351 IFADDR_READER_FOREACH(ifa, ifp) {
1352 family = ifa->ifa_addr->sa_family; 1352 family = ifa->ifa_addr->sa_family;
1353#ifdef IFAREF_DEBUG 1353#ifdef IFAREF_DEBUG
1354 printf("if_detach: ifaddr %p, family %d, refcnt %d\n", 1354 printf("if_detach: ifaddr %p, family %d, refcnt %d\n",
1355 ifa, family, ifa->ifa_refcnt); 1355 ifa, family, ifa->ifa_refcnt);
1356 if (last_ifa != NULL && ifa == last_ifa) 1356 if (last_ifa != NULL && ifa == last_ifa)
1357 panic("if_detach: loop detected"); 1357 panic("if_detach: loop detected");
1358 last_ifa = ifa; 1358 last_ifa = ifa;
1359#endif 1359#endif
1360 if (family == AF_LINK) 1360 if (family == AF_LINK)
1361 continue; 1361 continue;
1362 dp = pffinddomain(family); 1362 dp = pffinddomain(family);
1363#ifdef DIAGNOSTIC 1363#ifdef DIAGNOSTIC
1364 if (dp == NULL) 1364 if (dp == NULL)
1365 panic("if_detach: no domain for AF %d", 1365 panic("if_detach: no domain for AF %d",
1366 family); 1366 family);
1367#endif 1367#endif
1368 /* 1368 /*
1369 * XXX These PURGEIF calls are redundant with the 1369 * XXX These PURGEIF calls are redundant with the
1370 * purge-all-families calls below, but are left in for 1370 * purge-all-families calls below, but are left in for
1371 * now both to make a smaller change, and to avoid 1371 * now both to make a smaller change, and to avoid
1372 * unplanned interactions with clearing of 1372 * unplanned interactions with clearing of
1373 * ifp->if_addrlist. 1373 * ifp->if_addrlist.
1374 */ 1374 */
1375 purged = 0; 1375 purged = 0;
1376 for (pr = dp->dom_protosw; 1376 for (pr = dp->dom_protosw;
1377 pr < dp->dom_protoswNPROTOSW; pr++) { 1377 pr < dp->dom_protoswNPROTOSW; pr++) {
1378 so.so_proto = pr; 1378 so.so_proto = pr;
1379 if (pr->pr_usrreqs) { 1379 if (pr->pr_usrreqs) {
1380 (void) (*pr->pr_usrreqs->pr_purgeif)(&so, ifp); 1380 (void) (*pr->pr_usrreqs->pr_purgeif)(&so, ifp);
1381 purged = 1; 1381 purged = 1;
1382 } 1382 }
1383 } 1383 }
1384 if (purged == 0) { 1384 if (purged == 0) {
1385 /* 1385 /*
1386 * XXX What's really the best thing to do 1386 * XXX What's really the best thing to do
1387 * XXX here? --thorpej@NetBSD.org 1387 * XXX here? --thorpej@NetBSD.org
1388 */ 1388 */
1389 printf("if_detach: WARNING: AF %d not purged\n", 1389 printf("if_detach: WARNING: AF %d not purged\n",
1390 family); 1390 family);
1391 ifa_remove(ifp, ifa); 1391 ifa_remove(ifp, ifa);
1392 } 1392 }
1393 goto again; 1393 goto again;
1394 } 1394 }
1395 1395
1396 if_free_sadl(ifp); 1396 if_free_sadl(ifp);
1397 1397
1398 /* Delete stray routes from the routing table. */ 1398 /* Delete stray routes from the routing table. */
1399 for (i = 0; i <= AF_MAX; i++) 1399 for (i = 0; i <= AF_MAX; i++)
1400 rt_delete_matched_entries(i, if_delroute_matcher, ifp); 1400 rt_delete_matched_entries(i, if_delroute_matcher, ifp);
1401 1401
1402 DOMAIN_FOREACH(dp) { 1402 DOMAIN_FOREACH(dp) {
1403 if (dp->dom_ifdetach != NULL && ifp->if_afdata[dp->dom_family]) 1403 if (dp->dom_ifdetach != NULL && ifp->if_afdata[dp->dom_family])
1404 { 1404 {
1405 void *p = ifp->if_afdata[dp->dom_family]; 1405 void *p = ifp->if_afdata[dp->dom_family];
1406 if (p) { 1406 if (p) {
1407 ifp->if_afdata[dp->dom_family] = NULL; 1407 ifp->if_afdata[dp->dom_family] = NULL;
1408 (*dp->dom_ifdetach)(ifp, p); 1408 (*dp->dom_ifdetach)(ifp, p);
1409 } 1409 }
1410 } 1410 }
1411 1411
1412 /* 1412 /*
1413 * One would expect multicast memberships (INET and 1413 * One would expect multicast memberships (INET and
1414 * INET6) on UDP sockets to be purged by the PURGEIF 1414 * INET6) on UDP sockets to be purged by the PURGEIF
1415 * calls above, but if all addresses were removed from 1415 * calls above, but if all addresses were removed from
1416 * the interface prior to destruction, the calls will 1416 * the interface prior to destruction, the calls will
1417 * not be made (e.g. ppp, for which pppd(8) generally 1417 * not be made (e.g. ppp, for which pppd(8) generally
1418 * removes addresses before destroying the interface). 1418 * removes addresses before destroying the interface).
1419 * Because there is no invariant that multicast 1419 * Because there is no invariant that multicast
1420 * memberships only exist for interfaces with IPv4 1420 * memberships only exist for interfaces with IPv4
1421 * addresses, we must call PURGEIF regardless of 1421 * addresses, we must call PURGEIF regardless of
1422 * addresses. (Protocols which might store ifnet 1422 * addresses. (Protocols which might store ifnet
1423 * pointers are marked with PR_PURGEIF.) 1423 * pointers are marked with PR_PURGEIF.)
1424 */ 1424 */
1425 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) { 1425 for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
1426 so.so_proto = pr; 1426 so.so_proto = pr;
1427 if (pr->pr_usrreqs && pr->pr_flags & PR_PURGEIF) 1427 if (pr->pr_usrreqs && pr->pr_flags & PR_PURGEIF)
1428 (void)(*pr->pr_usrreqs->pr_purgeif)(&so, ifp); 1428 (void)(*pr->pr_usrreqs->pr_purgeif)(&so, ifp);
1429 } 1429 }
1430 } 1430 }
1431 1431
1432 pfil_run_ifhooks(if_pfil, PFIL_IFNET_DETACH, ifp); 1432 pfil_run_ifhooks(if_pfil, PFIL_IFNET_DETACH, ifp);
1433 (void)pfil_head_destroy(ifp->if_pfil); 1433 (void)pfil_head_destroy(ifp->if_pfil);
1434 1434
1435 /* Announce that the interface is gone. */ 1435 /* Announce that the interface is gone. */
1436 rt_ifannouncemsg(ifp, IFAN_DEPARTURE); 1436 rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
1437 1437
1438 IF_AFDATA_LOCK_DESTROY(ifp); 1438 IF_AFDATA_LOCK_DESTROY(ifp);
1439 1439
1440 if (if_is_link_state_changeable(ifp)) { 1440 if (if_is_link_state_changeable(ifp)) {
1441 softint_disestablish(ifp->if_link_si); 1441 softint_disestablish(ifp->if_link_si);
1442 ifp->if_link_si = NULL; 1442 ifp->if_link_si = NULL;
1443 } 1443 }
1444 1444
1445 /* 1445 /*
1446 * remove packets that came from ifp, from software interrupt queues. 1446 * remove packets that came from ifp, from software interrupt queues.
1447 */ 1447 */
1448 DOMAIN_FOREACH(dp) { 1448 DOMAIN_FOREACH(dp) {
1449 for (i = 0; i < __arraycount(dp->dom_ifqueues); i++) { 1449 for (i = 0; i < __arraycount(dp->dom_ifqueues); i++) {
1450 struct ifqueue *iq = dp->dom_ifqueues[i]; 1450 struct ifqueue *iq = dp->dom_ifqueues[i];
1451 if (iq == NULL) 1451 if (iq == NULL)
1452 break; 1452 break;
1453 dp->dom_ifqueues[i] = NULL; 1453 dp->dom_ifqueues[i] = NULL;
1454 if_detach_queues(ifp, iq); 1454 if_detach_queues(ifp, iq);
1455 } 1455 }
1456 } 1456 }
1457 1457
1458 /* 1458 /*
1459 * IP queues have to be processed separately: net-queue barrier 1459 * IP queues have to be processed separately: net-queue barrier
1460 * ensures that the packets are dequeued while a cross-call will 1460 * ensures that the packets are dequeued while a cross-call will
1461 * ensure that the interrupts have completed. FIXME: not quite.. 1461 * ensure that the interrupts have completed. FIXME: not quite..
1462 */ 1462 */
1463#ifdef INET 1463#ifdef INET
1464 pktq_barrier(ip_pktq); 1464 pktq_barrier(ip_pktq);
1465#endif 1465#endif
1466#ifdef INET6 1466#ifdef INET6
1467 if (in6_present) 1467 if (in6_present)
1468 pktq_barrier(ip6_pktq); 1468 pktq_barrier(ip6_pktq);
1469#endif 1469#endif
1470 xc = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL); 1470 xc = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
1471 xc_wait(xc); 1471 xc_wait(xc);
1472 1472
1473 if (ifp->if_percpuq != NULL) { 1473 if (ifp->if_percpuq != NULL) {
1474 if_percpuq_destroy(ifp->if_percpuq); 1474 if_percpuq_destroy(ifp->if_percpuq);
1475 ifp->if_percpuq = NULL; 1475 ifp->if_percpuq = NULL;
1476 } 1476 }
1477 1477
1478 splx(s); 1478 splx(s);
1479 1479
1480#ifdef IFAREF_DEBUG 1480#ifdef IFAREF_DEBUG
1481 if_check_and_free_ifa_list(ifp); 1481 if_check_and_free_ifa_list(ifp);
1482#endif 1482#endif
1483} 1483}
1484 1484
1485static void 1485static void
1486if_detach_queues(struct ifnet *ifp, struct ifqueue *q) 1486if_detach_queues(struct ifnet *ifp, struct ifqueue *q)
1487{ 1487{
1488 struct mbuf *m, *prev, *next; 1488 struct mbuf *m, *prev, *next;
1489 1489
1490 prev = NULL; 1490 prev = NULL;
1491 for (m = q->ifq_head; m != NULL; m = next) { 1491 for (m = q->ifq_head; m != NULL; m = next) {
1492 KASSERT((m->m_flags & M_PKTHDR) != 0); 1492 KASSERT((m->m_flags & M_PKTHDR) != 0);
1493 1493
1494 next = m->m_nextpkt; 1494 next = m->m_nextpkt;
1495 if (m->m_pkthdr.rcvif_index != ifp->if_index) { 1495 if (m->m_pkthdr.rcvif_index != ifp->if_index) {
1496 prev = m; 1496 prev = m;
1497 continue; 1497 continue;
1498 } 1498 }
1499 1499
1500 if (prev != NULL) 1500 if (prev != NULL)
1501 prev->m_nextpkt = m->m_nextpkt; 1501 prev->m_nextpkt = m->m_nextpkt;
1502 else 1502 else
1503 q->ifq_head = m->m_nextpkt; 1503 q->ifq_head = m->m_nextpkt;
1504 if (q->ifq_tail == m) 1504 if (q->ifq_tail == m)
1505 q->ifq_tail = prev; 1505 q->ifq_tail = prev;
1506 q->ifq_len--; 1506 q->ifq_len--;
1507 1507
1508 m->m_nextpkt = NULL; 1508 m->m_nextpkt = NULL;
1509 m_freem(m); 1509 m_freem(m);
1510 IF_DROP(q); 1510 IF_DROP(q);
1511 } 1511 }
1512} 1512}
1513 1513
1514/* 1514/*
1515 * Callback for a radix tree walk to delete all references to an 1515 * Callback for a radix tree walk to delete all references to an
1516 * ifnet. 1516 * ifnet.
1517 */ 1517 */
1518static int 1518static int
1519if_delroute_matcher(struct rtentry *rt, void *v) 1519if_delroute_matcher(struct rtentry *rt, void *v)
1520{ 1520{
1521 struct ifnet *ifp = (struct ifnet *)v; 1521 struct ifnet *ifp = (struct ifnet *)v;
1522 1522
1523 if (rt->rt_ifp == ifp) 1523 if (rt->rt_ifp == ifp)
1524 return 1; 1524 return 1;
1525 else 1525 else
1526 return 0; 1526 return 0;
1527} 1527}
1528 1528
1529/* 1529/*
1530 * Create a clone network interface. 1530 * Create a clone network interface.
1531 */ 1531 */
1532static int 1532static int
1533if_clone_create(const char *name) 1533if_clone_create(const char *name)
1534{ 1534{
1535 struct if_clone *ifc; 1535 struct if_clone *ifc;
1536 int unit; 1536 int unit;
1537 struct ifnet *ifp; 1537 struct ifnet *ifp;
1538 struct psref psref; 1538 struct psref psref;
1539 1539
1540 KASSERT(mutex_owned(&if_clone_mtx)); 1540 KASSERT(mutex_owned(&if_clone_mtx));
1541 1541
1542 ifc = if_clone_lookup(name, &unit); 1542 ifc = if_clone_lookup(name, &unit);
1543 if (ifc == NULL) 1543 if (ifc == NULL)
1544 return EINVAL; 1544 return EINVAL;
1545 1545
1546 ifp = if_get(name, &psref); 1546 ifp = if_get(name, &psref);
1547 if (ifp != NULL) { 1547 if (ifp != NULL) {
1548 if_put(ifp, &psref); 1548 if_put(ifp, &psref);
1549 return EEXIST; 1549 return EEXIST;
1550 } 1550 }
1551 1551
1552 return (*ifc->ifc_create)(ifc, unit); 1552 return (*ifc->ifc_create)(ifc, unit);
1553} 1553}
1554 1554
1555/* 1555/*
1556 * Destroy a clone network interface. 1556 * Destroy a clone network interface.
1557 */ 1557 */
1558static int 1558static int
1559if_clone_destroy(const char *name) 1559if_clone_destroy(const char *name)
1560{ 1560{
1561 struct if_clone *ifc; 1561 struct if_clone *ifc;
1562 struct ifnet *ifp; 1562 struct ifnet *ifp;
1563 struct psref psref; 1563 struct psref psref;
1564 1564
1565 KASSERT(mutex_owned(&if_clone_mtx)); 1565 KASSERT(mutex_owned(&if_clone_mtx));
1566 1566
1567 ifc = if_clone_lookup(name, NULL); 1567 ifc = if_clone_lookup(name, NULL);
1568 if (ifc == NULL) 1568 if (ifc == NULL)
1569 return EINVAL; 1569 return EINVAL;
1570 1570
1571 if (ifc->ifc_destroy == NULL) 1571 if (ifc->ifc_destroy == NULL)
1572 return EOPNOTSUPP; 1572 return EOPNOTSUPP;
1573 1573
1574 ifp = if_get(name, &psref); 1574 ifp = if_get(name, &psref);
1575 if (ifp == NULL) 1575 if (ifp == NULL)
1576 return ENXIO; 1576 return ENXIO;
1577 1577
1578 /* We have to disable ioctls here */ 1578 /* We have to disable ioctls here */
1579 mutex_enter(ifp->if_ioctl_lock); 1579 mutex_enter(ifp->if_ioctl_lock);
1580 ifp->if_ioctl = if_nullioctl; 1580 ifp->if_ioctl = if_nullioctl;
1581 mutex_exit(ifp->if_ioctl_lock); 1581 mutex_exit(ifp->if_ioctl_lock);
1582 1582
1583 /* 1583 /*
1584 * We cannot call ifc_destroy with holding ifp. 1584 * We cannot call ifc_destroy with holding ifp.
1585 * Releasing ifp here is safe thanks to if_clone_mtx. 1585 * Releasing ifp here is safe thanks to if_clone_mtx.
1586 */ 1586 */
1587 if_put(ifp, &psref); 1587 if_put(ifp, &psref);
1588 1588
1589 return (*ifc->ifc_destroy)(ifp); 1589 return (*ifc->ifc_destroy)(ifp);
1590} 1590}
1591 1591
1592/* 1592/*
1593 * Look up a network interface cloner. 1593 * Look up a network interface cloner.
1594 */ 1594 */
1595static struct if_clone * 1595static struct if_clone *
1596if_clone_lookup(const char *name, int *unitp) 1596if_clone_lookup(const char *name, int *unitp)
1597{ 1597{
1598 struct if_clone *ifc; 1598 struct if_clone *ifc;
1599 const char *cp; 1599 const char *cp;
1600 char *dp, ifname[IFNAMSIZ + 3]; 1600 char *dp, ifname[IFNAMSIZ + 3];
1601 int unit; 1601 int unit;
1602 1602
1603 KASSERT(mutex_owned(&if_clone_mtx)); 1603 KASSERT(mutex_owned(&if_clone_mtx));
1604 1604
1605 strcpy(ifname, "if_"); 1605 strcpy(ifname, "if_");
1606 /* separate interface name from unit */ 1606 /* separate interface name from unit */
1607 for (dp = ifname + 3, cp = name; cp - name < IFNAMSIZ && 1607 for (dp = ifname + 3, cp = name; cp - name < IFNAMSIZ &&
1608 *cp && (*cp < '0' || *cp > '9');) 1608 *cp && (*cp < '0' || *cp > '9');)
1609 *dp++ = *cp++; 1609 *dp++ = *cp++;
1610 1610
1611 if (cp == name || cp - name == IFNAMSIZ || !*cp) 1611 if (cp == name || cp - name == IFNAMSIZ || !*cp)
1612 return NULL; /* No name or unit number */ 1612 return NULL; /* No name or unit number */
1613 *dp++ = '\0'; 1613 *dp++ = '\0';
1614 1614
1615again: 1615again:
1616 LIST_FOREACH(ifc, &if_cloners, ifc_list) { 1616 LIST_FOREACH(ifc, &if_cloners, ifc_list) {
1617 if (strcmp(ifname + 3, ifc->ifc_name) == 0) 1617 if (strcmp(ifname + 3, ifc->ifc_name) == 0)
1618 break; 1618 break;
1619 } 1619 }
1620 1620
1621 if (ifc == NULL) { 1621 if (ifc == NULL) {
1622 if (*ifname == '\0' || 1622 int error;
1623 module_autoload(ifname, MODULE_CLASS_DRIVER)) 1623 if (*ifname == '\0')
 1624 return NULL;
 1625 mutex_exit(&if_clone_mtx);
 1626 error = module_autoload(ifname, MODULE_CLASS_DRIVER);
 1627 mutex_enter(&if_clone_mtx);
 1628 if (error)
1624 return NULL; 1629 return NULL;
1625 *ifname = '\0'; 1630 *ifname = '\0';
1626 goto again; 1631 goto again;
1627 } 1632 }
1628 1633
1629 unit = 0; 1634 unit = 0;
1630 while (cp - name < IFNAMSIZ && *cp) { 1635 while (cp - name < IFNAMSIZ && *cp) {
1631 if (*cp < '0' || *cp > '9' || unit >= INT_MAX / 10) { 1636 if (*cp < '0' || *cp > '9' || unit >= INT_MAX / 10) {
1632 /* Bogus unit number. */ 1637 /* Bogus unit number. */
1633 return NULL; 1638 return NULL;
1634 } 1639 }
1635 unit = (unit * 10) + (*cp++ - '0'); 1640 unit = (unit * 10) + (*cp++ - '0');
1636 } 1641 }
1637 1642
1638 if (unitp != NULL) 1643 if (unitp != NULL)
1639 *unitp = unit; 1644 *unitp = unit;
1640 return ifc; 1645 return ifc;
1641} 1646}
1642 1647
1643/* 1648/*
1644 * Register a network interface cloner. 1649 * Register a network interface cloner.
1645 */ 1650 */
1646void 1651void
1647if_clone_attach(struct if_clone *ifc) 1652if_clone_attach(struct if_clone *ifc)
1648{ 1653{
1649 1654
1650 mutex_enter(&if_clone_mtx); 1655 mutex_enter(&if_clone_mtx);
1651 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); 1656 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
1652 if_cloners_count++; 1657 if_cloners_count++;
1653 mutex_exit(&if_clone_mtx); 1658 mutex_exit(&if_clone_mtx);
1654} 1659}
1655 1660
1656/* 1661/*
1657 * Unregister a network interface cloner. 1662 * Unregister a network interface cloner.
1658 */ 1663 */
1659void 1664void
1660if_clone_detach(struct if_clone *ifc) 1665if_clone_detach(struct if_clone *ifc)
1661{ 1666{
1662 1667
1663 KASSERT(mutex_owned(&if_clone_mtx)); 1668 KASSERT(mutex_owned(&if_clone_mtx));
1664 LIST_REMOVE(ifc, ifc_list); 1669 LIST_REMOVE(ifc, ifc_list);
1665 if_cloners_count--; 1670 if_cloners_count--;
1666} 1671}
1667 1672
1668/* 1673/*
1669 * Provide list of interface cloners to userspace. 1674 * Provide list of interface cloners to userspace.
1670 */ 1675 */
1671int 1676int
1672if_clone_list(int buf_count, char *buffer, int *total) 1677if_clone_list(int buf_count, char *buffer, int *total)
1673{ 1678{
1674 char outbuf[IFNAMSIZ], *dst; 1679 char outbuf[IFNAMSIZ], *dst;
1675 struct if_clone *ifc; 1680 struct if_clone *ifc;
1676 int count, error = 0; 1681 int count, error = 0;
1677 1682
1678 mutex_enter(&if_clone_mtx); 1683 mutex_enter(&if_clone_mtx);
1679 *total = if_cloners_count; 1684 *total = if_cloners_count;
1680 if ((dst = buffer) == NULL) { 1685 if ((dst = buffer) == NULL) {
1681 /* Just asking how many there are. */ 1686 /* Just asking how many there are. */
1682 goto out; 1687 goto out;
1683 } 1688 }
1684 1689
1685 if (buf_count < 0) { 1690 if (buf_count < 0) {
1686 error = EINVAL; 1691 error = EINVAL;
1687 goto out; 1692 goto out;
1688 } 1693 }
1689 1694
1690 count = (if_cloners_count < buf_count) ? 1695 count = (if_cloners_count < buf_count) ?
1691 if_cloners_count : buf_count; 1696 if_cloners_count : buf_count;
1692 1697
1693 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0; 1698 for (ifc = LIST_FIRST(&if_cloners); ifc != NULL && count != 0;
1694 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) { 1699 ifc = LIST_NEXT(ifc, ifc_list), count--, dst += IFNAMSIZ) {
1695 (void)strncpy(outbuf, ifc->ifc_name, sizeof(outbuf)); 1700 (void)strncpy(outbuf, ifc->ifc_name, sizeof(outbuf));
1696 if (outbuf[sizeof(outbuf) - 1] != '\0') { 1701 if (outbuf[sizeof(outbuf) - 1] != '\0') {
1697 error = ENAMETOOLONG; 1702 error = ENAMETOOLONG;
1698 goto out; 1703 goto out;
1699 } 1704 }
1700 error = copyout(outbuf, dst, sizeof(outbuf)); 1705 error = copyout(outbuf, dst, sizeof(outbuf));
1701 if (error != 0) 1706 if (error != 0)
1702 break; 1707 break;
1703 } 1708 }
1704 1709
1705out: 1710out:
1706 mutex_exit(&if_clone_mtx); 1711 mutex_exit(&if_clone_mtx);
1707 return error; 1712 return error;
1708} 1713}
1709 1714
1710void 1715void
1711ifa_psref_init(struct ifaddr *ifa) 1716ifa_psref_init(struct ifaddr *ifa)
1712{ 1717{
1713 1718
1714 psref_target_init(&ifa->ifa_psref, ifa_psref_class); 1719 psref_target_init(&ifa->ifa_psref, ifa_psref_class);
1715} 1720}
1716 1721
1717void 1722void
1718ifaref(struct ifaddr *ifa) 1723ifaref(struct ifaddr *ifa)
1719{ 1724{
1720 KASSERT(!ISSET(ifa->ifa_flags, IFA_DESTROYING)); 1725 KASSERT(!ISSET(ifa->ifa_flags, IFA_DESTROYING));
1721 ifa->ifa_refcnt++; 1726 ifa->ifa_refcnt++;
1722} 1727}
1723 1728
1724void 1729void
1725ifafree(struct ifaddr *ifa) 1730ifafree(struct ifaddr *ifa)
1726{ 1731{
1727 KASSERT(ifa != NULL); 1732 KASSERT(ifa != NULL);
1728 KASSERT(ifa->ifa_refcnt > 0); 1733 KASSERT(ifa->ifa_refcnt > 0);
1729 1734
1730 if (--ifa->ifa_refcnt == 0) { 1735 if (--ifa->ifa_refcnt == 0) {
1731 free(ifa, M_IFADDR); 1736 free(ifa, M_IFADDR);
1732 } 1737 }
1733} 1738}
1734 1739
1735bool 1740bool
1736ifa_is_destroying(struct ifaddr *ifa) 1741ifa_is_destroying(struct ifaddr *ifa)
1737{ 1742{
1738 1743
1739 return ISSET(ifa->ifa_flags, IFA_DESTROYING); 1744 return ISSET(ifa->ifa_flags, IFA_DESTROYING);
1740} 1745}
1741 1746
1742void 1747void
1743ifa_insert(struct ifnet *ifp, struct ifaddr *ifa) 1748ifa_insert(struct ifnet *ifp, struct ifaddr *ifa)
1744{ 1749{
1745 1750
1746 ifa->ifa_ifp = ifp; 1751 ifa->ifa_ifp = ifp;
1747 1752
1748 IFNET_LOCK(); 1753 IFNET_LOCK();
1749 TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list); 1754 TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list);
1750 IFADDR_ENTRY_INIT(ifa); 1755 IFADDR_ENTRY_INIT(ifa);
1751 IFADDR_WRITER_INSERT_TAIL(ifp, ifa); 1756 IFADDR_WRITER_INSERT_TAIL(ifp, ifa);
1752 IFNET_UNLOCK(); 1757 IFNET_UNLOCK();
1753 1758
1754 ifaref(ifa); 1759 ifaref(ifa);
1755} 1760}
1756 1761
1757void 1762void
1758ifa_remove(struct ifnet *ifp, struct ifaddr *ifa) 1763ifa_remove(struct ifnet *ifp, struct ifaddr *ifa)
1759{ 1764{
1760 1765
1761 KASSERT(ifa->ifa_ifp == ifp); 1766 KASSERT(ifa->ifa_ifp == ifp);
1762 1767
1763 IFNET_LOCK(); 1768 IFNET_LOCK();
1764 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list); 1769 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
1765 IFADDR_WRITER_REMOVE(ifa); 1770 IFADDR_WRITER_REMOVE(ifa);
1766#ifdef NET_MPSAFE 1771#ifdef NET_MPSAFE
1767 pserialize_perform(ifnet_psz); 1772 pserialize_perform(ifnet_psz);
1768#endif 1773#endif
1769 IFNET_UNLOCK(); 1774 IFNET_UNLOCK();
1770 1775
1771#ifdef NET_MPSAFE 1776#ifdef NET_MPSAFE
1772 psref_target_destroy(&ifa->ifa_psref, ifa_psref_class); 1777 psref_target_destroy(&ifa->ifa_psref, ifa_psref_class);
1773#endif 1778#endif
1774 IFADDR_ENTRY_DESTROY(ifa); 1779 IFADDR_ENTRY_DESTROY(ifa);
1775 ifafree(ifa); 1780 ifafree(ifa);
1776} 1781}
1777 1782
1778void 1783void
1779ifa_acquire(struct ifaddr *ifa, struct psref *psref) 1784ifa_acquire(struct ifaddr *ifa, struct psref *psref)
1780{ 1785{
1781 1786
1782 psref_acquire(psref, &ifa->ifa_psref, ifa_psref_class); 1787 psref_acquire(psref, &ifa->ifa_psref, ifa_psref_class);
1783} 1788}
1784 1789
1785void 1790void
1786ifa_release(struct ifaddr *ifa, struct psref *psref) 1791ifa_release(struct ifaddr *ifa, struct psref *psref)
1787{ 1792{
1788 1793
1789 if (ifa == NULL) 1794 if (ifa == NULL)
1790 return; 1795 return;
1791 1796
1792 psref_release(psref, &ifa->ifa_psref, ifa_psref_class); 1797 psref_release(psref, &ifa->ifa_psref, ifa_psref_class);
1793} 1798}
1794 1799
1795bool 1800bool
1796ifa_held(struct ifaddr *ifa) 1801ifa_held(struct ifaddr *ifa)
1797{ 1802{
1798 1803
1799 return psref_held(&ifa->ifa_psref, ifa_psref_class); 1804 return psref_held(&ifa->ifa_psref, ifa_psref_class);
1800} 1805}
1801 1806
1802static inline int 1807static inline int
1803equal(const struct sockaddr *sa1, const struct sockaddr *sa2) 1808equal(const struct sockaddr *sa1, const struct sockaddr *sa2)
1804{ 1809{
1805 return sockaddr_cmp(sa1, sa2) == 0; 1810 return sockaddr_cmp(sa1, sa2) == 0;
1806} 1811}
1807 1812
1808/* 1813/*
1809 * Locate an interface based on a complete address. 1814 * Locate an interface based on a complete address.
1810 */ 1815 */
1811/*ARGSUSED*/ 1816/*ARGSUSED*/
1812struct ifaddr * 1817struct ifaddr *
1813ifa_ifwithaddr(const struct sockaddr *addr) 1818ifa_ifwithaddr(const struct sockaddr *addr)
1814{ 1819{
1815 struct ifnet *ifp; 1820 struct ifnet *ifp;
1816 struct ifaddr *ifa; 1821 struct ifaddr *ifa;
1817 1822
1818 IFNET_READER_FOREACH(ifp) { 1823 IFNET_READER_FOREACH(ifp) {
1819 if (if_is_deactivated(ifp)) 1824 if (if_is_deactivated(ifp))
1820 continue; 1825 continue;
1821 IFADDR_READER_FOREACH(ifa, ifp) { 1826 IFADDR_READER_FOREACH(ifa, ifp) {
1822 if (ifa->ifa_addr->sa_family != addr->sa_family) 1827 if (ifa->ifa_addr->sa_family != addr->sa_family)
1823 continue; 1828 continue;
1824 if (equal(addr, ifa->ifa_addr)) 1829 if (equal(addr, ifa->ifa_addr))
1825 return ifa; 1830 return ifa;
1826 if ((ifp->if_flags & IFF_BROADCAST) && 1831 if ((ifp->if_flags & IFF_BROADCAST) &&
1827 ifa->ifa_broadaddr && 1832 ifa->ifa_broadaddr &&
1828 /* IP6 doesn't have broadcast */ 1833 /* IP6 doesn't have broadcast */
1829 ifa->ifa_broadaddr->sa_len != 0 && 1834 ifa->ifa_broadaddr->sa_len != 0 &&
1830 equal(ifa->ifa_broadaddr, addr)) 1835 equal(ifa->ifa_broadaddr, addr))
1831 return ifa; 1836 return ifa;
1832 } 1837 }
1833 } 1838 }
1834 return NULL; 1839 return NULL;
1835} 1840}
1836 1841
1837struct ifaddr * 1842struct ifaddr *
1838ifa_ifwithaddr_psref(const struct sockaddr *addr, struct psref *psref) 1843ifa_ifwithaddr_psref(const struct sockaddr *addr, struct psref *psref)
1839{ 1844{
1840 struct ifaddr *ifa; 1845 struct ifaddr *ifa;
1841 int s = pserialize_read_enter(); 1846 int s = pserialize_read_enter();
1842 1847
1843 ifa = ifa_ifwithaddr(addr); 1848 ifa = ifa_ifwithaddr(addr);
1844 if (ifa != NULL) 1849 if (ifa != NULL)
1845 ifa_acquire(ifa, psref); 1850 ifa_acquire(ifa, psref);
1846 pserialize_read_exit(s); 1851 pserialize_read_exit(s);
1847 1852
1848 return ifa; 1853 return ifa;
1849} 1854}
1850 1855
1851/* 1856/*
1852 * Locate the point to point interface with a given destination address. 1857 * Locate the point to point interface with a given destination address.
1853 */ 1858 */
1854/*ARGSUSED*/ 1859/*ARGSUSED*/
1855struct ifaddr * 1860struct ifaddr *
1856ifa_ifwithdstaddr(const struct sockaddr *addr) 1861ifa_ifwithdstaddr(const struct sockaddr *addr)
1857{ 1862{
1858 struct ifnet *ifp; 1863 struct ifnet *ifp;
1859 struct ifaddr *ifa; 1864 struct ifaddr *ifa;
1860 1865
1861 IFNET_READER_FOREACH(ifp) { 1866 IFNET_READER_FOREACH(ifp) {
1862 if (if_is_deactivated(ifp)) 1867 if (if_is_deactivated(ifp))
1863 continue; 1868 continue;
1864 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) 1869 if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
1865 continue; 1870 continue;
1866 IFADDR_READER_FOREACH(ifa, ifp) { 1871 IFADDR_READER_FOREACH(ifa, ifp) {
1867 if (ifa->ifa_addr->sa_family != addr->sa_family || 1872 if (ifa->ifa_addr->sa_family != addr->sa_family ||
1868 ifa->ifa_dstaddr == NULL) 1873 ifa->ifa_dstaddr == NULL)
1869 continue; 1874 continue;
1870 if (equal(addr, ifa->ifa_dstaddr)) 1875 if (equal(addr, ifa->ifa_dstaddr))
1871 return ifa; 1876 return ifa;
1872 } 1877 }
1873 } 1878 }
1874 1879
1875 return NULL; 1880 return NULL;
1876} 1881}
1877 1882
1878struct ifaddr * 1883struct ifaddr *
1879ifa_ifwithdstaddr_psref(const struct sockaddr *addr, struct psref *psref) 1884ifa_ifwithdstaddr_psref(const struct sockaddr *addr, struct psref *psref)
1880{ 1885{
1881 struct ifaddr *ifa; 1886 struct ifaddr *ifa;
1882 int s; 1887 int s;
1883 1888
1884 s = pserialize_read_enter(); 1889 s = pserialize_read_enter();
1885 ifa = ifa_ifwithdstaddr(addr); 1890 ifa = ifa_ifwithdstaddr(addr);
1886 if (ifa != NULL) 1891 if (ifa != NULL)
1887 ifa_acquire(ifa, psref); 1892 ifa_acquire(ifa, psref);
1888 pserialize_read_exit(s); 1893 pserialize_read_exit(s);
1889 1894
1890 return ifa; 1895 return ifa;
1891} 1896}
1892 1897
1893/* 1898/*
1894 * Find an interface on a specific network. If many, choice 1899 * Find an interface on a specific network. If many, choice
1895 * is most specific found. 1900 * is most specific found.
1896 */ 1901 */
1897struct ifaddr * 1902struct ifaddr *
1898ifa_ifwithnet(const struct sockaddr *addr) 1903ifa_ifwithnet(const struct sockaddr *addr)
1899{ 1904{
1900 struct ifnet *ifp; 1905 struct ifnet *ifp;
1901 struct ifaddr *ifa, *ifa_maybe = NULL; 1906 struct ifaddr *ifa, *ifa_maybe = NULL;
1902 const struct sockaddr_dl *sdl; 1907 const struct sockaddr_dl *sdl;
1903 u_int af = addr->sa_family; 1908 u_int af = addr->sa_family;
1904 const char *addr_data = addr->sa_data, *cplim; 1909 const char *addr_data = addr->sa_data, *cplim;
1905 1910
1906 if (af == AF_LINK) { 1911 if (af == AF_LINK) {
1907 sdl = satocsdl(addr); 1912 sdl = satocsdl(addr);
1908 if (sdl->sdl_index && sdl->sdl_index < if_indexlim && 1913 if (sdl->sdl_index && sdl->sdl_index < if_indexlim &&
1909 ifindex2ifnet[sdl->sdl_index] && 1914 ifindex2ifnet[sdl->sdl_index] &&
1910 !if_is_deactivated(ifindex2ifnet[sdl->sdl_index])) { 1915 !if_is_deactivated(ifindex2ifnet[sdl->sdl_index])) {
1911 return ifindex2ifnet[sdl->sdl_index]->if_dl; 1916 return ifindex2ifnet[sdl->sdl_index]->if_dl;
1912 } 1917 }
1913 } 1918 }
1914#ifdef NETATALK 1919#ifdef NETATALK
1915 if (af == AF_APPLETALK) { 1920 if (af == AF_APPLETALK) {
1916 const struct sockaddr_at *sat, *sat2; 1921 const struct sockaddr_at *sat, *sat2;
1917 sat = (const struct sockaddr_at *)addr; 1922 sat = (const struct sockaddr_at *)addr;
1918 IFNET_READER_FOREACH(ifp) { 1923 IFNET_READER_FOREACH(ifp) {
1919 if (if_is_deactivated(ifp)) 1924 if (if_is_deactivated(ifp))
1920 continue; 1925 continue;
1921 ifa = at_ifawithnet((const struct sockaddr_at *)addr, ifp); 1926 ifa = at_ifawithnet((const struct sockaddr_at *)addr, ifp);
1922 if (ifa == NULL) 1927 if (ifa == NULL)
1923 continue; 1928 continue;
1924 sat2 = (struct sockaddr_at *)ifa->ifa_addr; 1929 sat2 = (struct sockaddr_at *)ifa->ifa_addr;
1925 if (sat2->sat_addr.s_net == sat->sat_addr.s_net) 1930 if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
1926 return ifa; /* exact match */ 1931 return ifa; /* exact match */
1927 if (ifa_maybe == NULL) { 1932 if (ifa_maybe == NULL) {
1928 /* else keep the if with the right range */ 1933 /* else keep the if with the right range */
1929 ifa_maybe = ifa; 1934 ifa_maybe = ifa;
1930 } 1935 }
1931 } 1936 }
1932 return ifa_maybe; 1937 return ifa_maybe;
1933 } 1938 }
1934#endif 1939#endif
1935 IFNET_READER_FOREACH(ifp) { 1940 IFNET_READER_FOREACH(ifp) {
1936 if (if_is_deactivated(ifp)) 1941 if (if_is_deactivated(ifp))
1937 continue; 1942 continue;
1938 IFADDR_READER_FOREACH(ifa, ifp) { 1943 IFADDR_READER_FOREACH(ifa, ifp) {
1939 const char *cp, *cp2, *cp3; 1944 const char *cp, *cp2, *cp3;
1940 1945
1941 if (ifa->ifa_addr->sa_family != af || 1946 if (ifa->ifa_addr->sa_family != af ||
1942 ifa->ifa_netmask == NULL) 1947 ifa->ifa_netmask == NULL)
1943 next: continue; 1948 next: continue;
1944 cp = addr_data; 1949 cp = addr_data;
1945 cp2 = ifa->ifa_addr->sa_data; 1950 cp2 = ifa->ifa_addr->sa_data;
1946 cp3 = ifa->ifa_netmask->sa_data; 1951 cp3 = ifa->ifa_netmask->sa_data;
1947 cplim = (const char *)ifa->ifa_netmask + 1952 cplim = (const char *)ifa->ifa_netmask +
1948 ifa->ifa_netmask->sa_len; 1953 ifa->ifa_netmask->sa_len;
1949 while (cp3 < cplim) { 1954 while (cp3 < cplim) {
1950 if ((*cp++ ^ *cp2++) & *cp3++) { 1955 if ((*cp++ ^ *cp2++) & *cp3++) {
1951 /* want to continue for() loop */ 1956 /* want to continue for() loop */
1952 goto next; 1957 goto next;
1953 } 1958 }
1954 } 1959 }
1955 if (ifa_maybe == NULL || 1960 if (ifa_maybe == NULL ||
1956 rt_refines(ifa->ifa_netmask, 1961 rt_refines(ifa->ifa_netmask,
1957 ifa_maybe->ifa_netmask)) 1962 ifa_maybe->ifa_netmask))
1958 ifa_maybe = ifa; 1963 ifa_maybe = ifa;
1959 } 1964 }
1960 } 1965 }
1961 return ifa_maybe; 1966 return ifa_maybe;
1962} 1967}
1963 1968
1964struct ifaddr * 1969struct ifaddr *
1965ifa_ifwithnet_psref(const struct sockaddr *addr, struct psref *psref) 1970ifa_ifwithnet_psref(const struct sockaddr *addr, struct psref *psref)
1966{ 1971{
1967 struct ifaddr *ifa; 1972 struct ifaddr *ifa;
1968 int s; 1973 int s;
1969 1974
1970 s = pserialize_read_enter(); 1975 s = pserialize_read_enter();
1971 ifa = ifa_ifwithnet(addr); 1976 ifa = ifa_ifwithnet(addr);
1972 if (ifa != NULL) 1977 if (ifa != NULL)
1973 ifa_acquire(ifa, psref); 1978 ifa_acquire(ifa, psref);
1974 pserialize_read_exit(s); 1979 pserialize_read_exit(s);
1975 1980
1976 return ifa; 1981 return ifa;
1977} 1982}
1978 1983
1979/* 1984/*
1980 * Find the interface of the addresss. 1985 * Find the interface of the addresss.
1981 */ 1986 */
1982struct ifaddr * 1987struct ifaddr *
1983ifa_ifwithladdr(const struct sockaddr *addr) 1988ifa_ifwithladdr(const struct sockaddr *addr)
1984{ 1989{
1985 struct ifaddr *ia; 1990 struct ifaddr *ia;
1986 1991
1987 if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) || 1992 if ((ia = ifa_ifwithaddr(addr)) || (ia = ifa_ifwithdstaddr(addr)) ||
1988 (ia = ifa_ifwithnet(addr))) 1993 (ia = ifa_ifwithnet(addr)))
1989 return ia; 1994 return ia;
1990 return NULL; 1995 return NULL;
1991} 1996}
1992 1997
1993struct ifaddr * 1998struct ifaddr *
1994ifa_ifwithladdr_psref(const struct sockaddr *addr, struct psref *psref) 1999ifa_ifwithladdr_psref(const struct sockaddr *addr, struct psref *psref)
1995{ 2000{
1996 struct ifaddr *ifa; 2001 struct ifaddr *ifa;
1997 int s; 2002 int s;
1998 2003
1999 s = pserialize_read_enter(); 2004 s = pserialize_read_enter();
2000 ifa = ifa_ifwithladdr(addr); 2005 ifa = ifa_ifwithladdr(addr);
2001 if (ifa != NULL) 2006 if (ifa != NULL)
2002 ifa_acquire(ifa, psref); 2007 ifa_acquire(ifa, psref);
2003 pserialize_read_exit(s); 2008 pserialize_read_exit(s);
2004 2009
2005 return ifa; 2010 return ifa;
2006} 2011}
2007 2012
2008/* 2013/*
2009 * Find an interface using a specific address family 2014 * Find an interface using a specific address family
2010 */ 2015 */
2011struct ifaddr * 2016struct ifaddr *
2012ifa_ifwithaf(int af) 2017ifa_ifwithaf(int af)
2013{ 2018{
2014 struct ifnet *ifp; 2019 struct ifnet *ifp;
2015 struct ifaddr *ifa = NULL; 2020 struct ifaddr *ifa = NULL;
2016 int s; 2021 int s;
2017 2022
2018 s = pserialize_read_enter(); 2023 s = pserialize_read_enter();
2019 IFNET_READER_FOREACH(ifp) { 2024 IFNET_READER_FOREACH(ifp) {
2020 if (if_is_deactivated(ifp)) 2025 if (if_is_deactivated(ifp))
2021 continue; 2026 continue;
2022 IFADDR_READER_FOREACH(ifa, ifp) { 2027 IFADDR_READER_FOREACH(ifa, ifp) {
2023 if (ifa->ifa_addr->sa_family == af) 2028 if (ifa->ifa_addr->sa_family == af)
2024 goto out; 2029 goto out;
2025 } 2030 }
2026 } 2031 }
2027out: 2032out:
2028 pserialize_read_exit(s); 2033 pserialize_read_exit(s);
2029 return ifa; 2034 return ifa;
2030} 2035}
2031 2036
2032/* 2037/*
2033 * Find an interface address specific to an interface best matching 2038 * Find an interface address specific to an interface best matching
2034 * a given address. 2039 * a given address.
2035 */ 2040 */
2036struct ifaddr * 2041struct ifaddr *
2037ifaof_ifpforaddr(const struct sockaddr *addr, struct ifnet *ifp) 2042ifaof_ifpforaddr(const struct sockaddr *addr, struct ifnet *ifp)
2038{ 2043{
2039 struct ifaddr *ifa; 2044 struct ifaddr *ifa;
2040 const char *cp, *cp2, *cp3; 2045 const char *cp, *cp2, *cp3;
2041 const char *cplim; 2046 const char *cplim;
2042 struct ifaddr *ifa_maybe = 0; 2047 struct ifaddr *ifa_maybe = 0;
2043 u_int af = addr->sa_family; 2048 u_int af = addr->sa_family;
2044 2049
2045 if (if_is_deactivated(ifp)) 2050 if (if_is_deactivated(ifp))
2046 return NULL; 2051 return NULL;
2047 2052
2048 if (af >= AF_MAX) 2053 if (af >= AF_MAX)
2049 return NULL; 2054 return NULL;
2050 2055
2051 IFADDR_READER_FOREACH(ifa, ifp) { 2056 IFADDR_READER_FOREACH(ifa, ifp) {
2052 if (ifa->ifa_addr->sa_family != af) 2057 if (ifa->ifa_addr->sa_family != af)
2053 continue; 2058 continue;
2054 ifa_maybe = ifa; 2059 ifa_maybe = ifa;
2055 if (ifa->ifa_netmask == NULL) { 2060 if (ifa->ifa_netmask == NULL) {
2056 if (equal(addr, ifa->ifa_addr) || 2061 if (equal(addr, ifa->ifa_addr) ||
2057 (ifa->ifa_dstaddr && 2062 (ifa->ifa_dstaddr &&
2058 equal(addr, ifa->ifa_dstaddr))) 2063 equal(addr, ifa->ifa_dstaddr)))
2059 return ifa; 2064 return ifa;
2060 continue; 2065 continue;
2061 } 2066 }
2062 cp = addr->sa_data; 2067 cp = addr->sa_data;
2063 cp2 = ifa->ifa_addr->sa_data; 2068 cp2 = ifa->ifa_addr->sa_data;
2064 cp3 = ifa->ifa_netmask->sa_data; 2069 cp3 = ifa->ifa_netmask->sa_data;
2065 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask; 2070 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
2066 for (; cp3 < cplim; cp3++) { 2071 for (; cp3 < cplim; cp3++) {
2067 if ((*cp++ ^ *cp2++) & *cp3) 2072 if ((*cp++ ^ *cp2++) & *cp3)
2068 break; 2073 break;
2069 } 2074 }
2070 if (cp3 == cplim) 2075 if (cp3 == cplim)
2071 return ifa; 2076 return ifa;
2072 } 2077 }
2073 return ifa_maybe; 2078 return ifa_maybe;
2074} 2079}
2075 2080
2076struct ifaddr * 2081struct ifaddr *
2077ifaof_ifpforaddr_psref(const struct sockaddr *addr, struct ifnet *ifp, 2082ifaof_ifpforaddr_psref(const struct sockaddr *addr, struct ifnet *ifp,
2078 struct psref *psref) 2083 struct psref *psref)
2079{ 2084{
2080 struct ifaddr *ifa; 2085 struct ifaddr *ifa;
2081 int s; 2086 int s;
2082 2087
2083 s = pserialize_read_enter(); 2088 s = pserialize_read_enter();
2084 ifa = ifaof_ifpforaddr(addr, ifp); 2089 ifa = ifaof_ifpforaddr(addr, ifp);
2085 if (ifa != NULL) 2090 if (ifa != NULL)
2086 ifa_acquire(ifa, psref); 2091 ifa_acquire(ifa, psref);
2087 pserialize_read_exit(s); 2092 pserialize_read_exit(s);
2088 2093
2089 return ifa; 2094 return ifa;
2090} 2095}
2091 2096
2092/* 2097/*
2093 * Default action when installing a route with a Link Level gateway. 2098 * Default action when installing a route with a Link Level gateway.
2094 * Lookup an appropriate real ifa to point to. 2099 * Lookup an appropriate real ifa to point to.
2095 * This should be moved to /sys/net/link.c eventually. 2100 * This should be moved to /sys/net/link.c eventually.
2096 */ 2101 */
2097void 2102void
2098link_rtrequest(int cmd, struct rtentry *rt, const struct rt_addrinfo *info) 2103link_rtrequest(int cmd, struct rtentry *rt, const struct rt_addrinfo *info)
2099{ 2104{
2100 struct ifaddr *ifa; 2105 struct ifaddr *ifa;
2101 const struct sockaddr *dst; 2106 const struct sockaddr *dst;
2102 struct ifnet *ifp; 2107 struct ifnet *ifp;
2103 struct psref psref; 2108 struct psref psref;
2104 2109
2105 if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL || 2110 if (cmd != RTM_ADD || (ifa = rt->rt_ifa) == NULL ||
2106 (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL) 2111 (ifp = ifa->ifa_ifp) == NULL || (dst = rt_getkey(rt)) == NULL)
2107 return; 2112 return;
2108 if ((ifa = ifaof_ifpforaddr_psref(dst, ifp, &psref)) != NULL) { 2113 if ((ifa = ifaof_ifpforaddr_psref(dst, ifp, &psref)) != NULL) {
2109 rt_replace_ifa(rt, ifa); 2114 rt_replace_ifa(rt, ifa);
2110 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest) 2115 if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
2111 ifa->ifa_rtrequest(cmd, rt, info); 2116 ifa->ifa_rtrequest(cmd, rt, info);
2112 ifa_release(ifa, &psref); 2117 ifa_release(ifa, &psref);
2113 } 2118 }
2114} 2119}
2115 2120
2116/* 2121/*
2117 * bitmask macros to manage a densely packed link_state change queue. 2122 * bitmask macros to manage a densely packed link_state change queue.
2118 * Because we need to store LINK_STATE_UNKNOWN(0), LINK_STATE_DOWN(1) and 2123 * Because we need to store LINK_STATE_UNKNOWN(0), LINK_STATE_DOWN(1) and
2119 * LINK_STATE_UP(2) we need 2 bits for each state change. 2124 * LINK_STATE_UP(2) we need 2 bits for each state change.
2120 * As a state change to store is 0, treat all bits set as an unset item. 2125 * As a state change to store is 0, treat all bits set as an unset item.
2121 */ 2126 */
2122#define LQ_ITEM_BITS 2 2127#define LQ_ITEM_BITS 2
2123#define LQ_ITEM_MASK ((1 << LQ_ITEM_BITS) - 1) 2128#define LQ_ITEM_MASK ((1 << LQ_ITEM_BITS) - 1)
2124#define LQ_MASK(i) (LQ_ITEM_MASK << (i) * LQ_ITEM_BITS) 2129#define LQ_MASK(i) (LQ_ITEM_MASK << (i) * LQ_ITEM_BITS)
2125#define LINK_STATE_UNSET LQ_ITEM_MASK 2130#define LINK_STATE_UNSET LQ_ITEM_MASK
2126#define LQ_ITEM(q, i) (((q) & LQ_MASK((i))) >> (i) * LQ_ITEM_BITS) 2131#define LQ_ITEM(q, i) (((q) & LQ_MASK((i))) >> (i) * LQ_ITEM_BITS)
2127#define LQ_STORE(q, i, v) \ 2132#define LQ_STORE(q, i, v) \
2128 do { \ 2133 do { \
2129 (q) &= ~LQ_MASK((i)); \ 2134 (q) &= ~LQ_MASK((i)); \
2130 (q) |= (v) << (i) * LQ_ITEM_BITS; \ 2135 (q) |= (v) << (i) * LQ_ITEM_BITS; \
2131 } while (0 /* CONSTCOND */) 2136 } while (0 /* CONSTCOND */)
2132#define LQ_MAX(q) ((sizeof((q)) * NBBY) / LQ_ITEM_BITS) 2137#define LQ_MAX(q) ((sizeof((q)) * NBBY) / LQ_ITEM_BITS)
2133#define LQ_POP(q, v) \ 2138#define LQ_POP(q, v) \
2134 do { \ 2139 do { \
2135 (v) = LQ_ITEM((q), 0); \ 2140 (v) = LQ_ITEM((q), 0); \
2136 (q) >>= LQ_ITEM_BITS; \ 2141 (q) >>= LQ_ITEM_BITS; \
2137 (q) |= LINK_STATE_UNSET << (LQ_MAX((q)) - 1) * LQ_ITEM_BITS; \ 2142 (q) |= LINK_STATE_UNSET << (LQ_MAX((q)) - 1) * LQ_ITEM_BITS; \
2138 } while (0 /* CONSTCOND */) 2143 } while (0 /* CONSTCOND */)
2139#define LQ_PUSH(q, v) \ 2144#define LQ_PUSH(q, v) \
2140 do { \ 2145 do { \
2141 (q) >>= LQ_ITEM_BITS; \ 2146 (q) >>= LQ_ITEM_BITS; \
2142 (q) |= (v) << (LQ_MAX((q)) - 1) * LQ_ITEM_BITS; \ 2147 (q) |= (v) << (LQ_MAX((q)) - 1) * LQ_ITEM_BITS; \
2143 } while (0 /* CONSTCOND */) 2148 } while (0 /* CONSTCOND */)
2144#define LQ_FIND_UNSET(q, i) \ 2149#define LQ_FIND_UNSET(q, i) \
2145 for ((i) = 0; i < LQ_MAX((q)); (i)++) { \ 2150 for ((i) = 0; i < LQ_MAX((q)); (i)++) { \
2146 if (LQ_ITEM((q), (i)) == LINK_STATE_UNSET) \ 2151 if (LQ_ITEM((q), (i)) == LINK_STATE_UNSET) \
2147 break; \ 2152 break; \
2148 } 2153 }
2149/* 2154/*
2150 * Handle a change in the interface link state and 2155 * Handle a change in the interface link state and
2151 * queue notifications. 2156 * queue notifications.
2152 */ 2157 */
2153void 2158void
2154if_link_state_change(struct ifnet *ifp, int link_state) 2159if_link_state_change(struct ifnet *ifp, int link_state)
2155{ 2160{
2156 int s, idx; 2161 int s, idx;
2157 2162
2158 KASSERTMSG(if_is_link_state_changeable(ifp), 2163 KASSERTMSG(if_is_link_state_changeable(ifp),
2159 "%s: IFEF_NO_LINK_STATE_CHANGE must not be set, but if_extflags=0x%x", 2164 "%s: IFEF_NO_LINK_STATE_CHANGE must not be set, but if_extflags=0x%x",
2160 ifp->if_xname, ifp->if_extflags); 2165 ifp->if_xname, ifp->if_extflags);
2161 2166
2162 /* Ensure change is to a valid state */ 2167 /* Ensure change is to a valid state */
2163 switch (link_state) { 2168 switch (link_state) {
2164 case LINK_STATE_UNKNOWN: /* FALLTHROUGH */ 2169 case LINK_STATE_UNKNOWN: /* FALLTHROUGH */
2165 case LINK_STATE_DOWN: /* FALLTHROUGH */ 2170 case LINK_STATE_DOWN: /* FALLTHROUGH */
2166 case LINK_STATE_UP: 2171 case LINK_STATE_UP:
2167 break; 2172 break;
2168 default: 2173 default:
2169#ifdef DEBUG 2174#ifdef DEBUG
2170 printf("%s: invalid link state %d\n", 2175 printf("%s: invalid link state %d\n",
2171 ifp->if_xname, link_state); 2176 ifp->if_xname, link_state);
2172#endif 2177#endif
2173 return; 2178 return;
2174 } 2179 }
2175 2180
2176 s = splnet(); 2181 s = splnet();
2177 2182
2178 /* Find the last unset event in the queue. */ 2183 /* Find the last unset event in the queue. */
2179 LQ_FIND_UNSET(ifp->if_link_queue, idx); 2184 LQ_FIND_UNSET(ifp->if_link_queue, idx);
2180 2185
2181 /* 2186 /*
2182 * Ensure link_state doesn't match the last event in the queue. 2187 * Ensure link_state doesn't match the last event in the queue.
2183 * ifp->if_link_state is not checked and set here because 2188 * ifp->if_link_state is not checked and set here because
2184 * that would present an inconsistent picture to the system. 2189 * that would present an inconsistent picture to the system.
2185 */ 2190 */
2186 if (idx != 0 && 2191 if (idx != 0 &&
2187 LQ_ITEM(ifp->if_link_queue, idx - 1) == (uint8_t)link_state) 2192 LQ_ITEM(ifp->if_link_queue, idx - 1) == (uint8_t)link_state)
2188 goto out; 2193 goto out;
2189 2194
2190 /* Handle queue overflow. */ 2195 /* Handle queue overflow. */
2191 if (idx == LQ_MAX(ifp->if_link_queue)) { 2196 if (idx == LQ_MAX(ifp->if_link_queue)) {
2192 uint8_t lost; 2197 uint8_t lost;
2193 2198
2194 /* 2199 /*
2195 * The DOWN state must be protected from being pushed off 2200 * The DOWN state must be protected from being pushed off
2196 * the queue to ensure that userland will always be 2201 * the queue to ensure that userland will always be
2197 * in a sane state. 2202 * in a sane state.
2198 * Because DOWN is protected, there is no need to protect 2203 * Because DOWN is protected, there is no need to protect
2199 * UNKNOWN. 2204 * UNKNOWN.
2200 * It should be invalid to change from any other state to 2205 * It should be invalid to change from any other state to
2201 * UNKNOWN anyway ... 2206 * UNKNOWN anyway ...
2202 */ 2207 */
2203 lost = LQ_ITEM(ifp->if_link_queue, 0); 2208 lost = LQ_ITEM(ifp->if_link_queue, 0);
2204 LQ_PUSH(ifp->if_link_queue, (uint8_t)link_state); 2209 LQ_PUSH(ifp->if_link_queue, (uint8_t)link_state);
2205 if (lost == LINK_STATE_DOWN) { 2210 if (lost == LINK_STATE_DOWN) {
2206 lost = LQ_ITEM(ifp->if_link_queue, 0); 2211 lost = LQ_ITEM(ifp->if_link_queue, 0);
2207 LQ_STORE(ifp->if_link_queue, 0, LINK_STATE_DOWN); 2212 LQ_STORE(ifp->if_link_queue, 0, LINK_STATE_DOWN);
2208 } 2213 }
2209 printf("%s: lost link state change %s\n", 2214 printf("%s: lost link state change %s\n",
2210 ifp->if_xname, 2215 ifp->if_xname,
2211 lost == LINK_STATE_UP ? "UP" : 2216 lost == LINK_STATE_UP ? "UP" :
2212 lost == LINK_STATE_DOWN ? "DOWN" : 2217 lost == LINK_STATE_DOWN ? "DOWN" :
2213 "UNKNOWN"); 2218 "UNKNOWN");
2214 } else 2219 } else
2215 LQ_STORE(ifp->if_link_queue, idx, (uint8_t)link_state); 2220 LQ_STORE(ifp->if_link_queue, idx, (uint8_t)link_state);
2216 2221
2217 softint_schedule(ifp->if_link_si); 2222 softint_schedule(ifp->if_link_si);
2218 2223
2219out: 2224out:
2220 splx(s); 2225 splx(s);
2221} 2226}
2222 2227
2223/* 2228/*
2224 * Handle interface link state change notifications. 2229 * Handle interface link state change notifications.
2225 * Must be called at splnet(). 2230 * Must be called at splnet().
2226 */ 2231 */
2227static void 2232static void
2228if_link_state_change0(struct ifnet *ifp, int link_state) 2233if_link_state_change0(struct ifnet *ifp, int link_state)
2229{ 2234{
2230 struct domain *dp; 2235 struct domain *dp;
2231 2236
2232 /* Ensure the change is still valid. */ 2237 /* Ensure the change is still valid. */
2233 if (ifp->if_link_state == link_state) 2238 if (ifp->if_link_state == link_state)
2234 return; 2239 return;
2235 2240
2236#ifdef DEBUG 2241#ifdef DEBUG
2237 log(LOG_DEBUG, "%s: link state %s (was %s)\n", ifp->if_xname, 2242 log(LOG_DEBUG, "%s: link state %s (was %s)\n", ifp->if_xname,
2238 link_state == LINK_STATE_UP ? "UP" : 2243 link_state == LINK_STATE_UP ? "UP" :
2239 link_state == LINK_STATE_DOWN ? "DOWN" : 2244 link_state == LINK_STATE_DOWN ? "DOWN" :
2240 "UNKNOWN", 2245 "UNKNOWN",
2241 ifp->if_link_state == LINK_STATE_UP ? "UP" : 2246 ifp->if_link_state == LINK_STATE_UP ? "UP" :
2242 ifp->if_link_state == LINK_STATE_DOWN ? "DOWN" : 2247 ifp->if_link_state == LINK_STATE_DOWN ? "DOWN" :
2243 "UNKNOWN"); 2248 "UNKNOWN");
2244#endif 2249#endif
2245 2250
2246 /* 2251 /*
2247 * When going from UNKNOWN to UP, we need to mark existing 2252 * When going from UNKNOWN to UP, we need to mark existing
2248 * addresses as tentative and restart DAD as we may have 2253 * addresses as tentative and restart DAD as we may have
2249 * erroneously not found a duplicate. 2254 * erroneously not found a duplicate.
2250 * 2255 *
2251 * This needs to happen before rt_ifmsg to avoid a race where 2256 * This needs to happen before rt_ifmsg to avoid a race where
2252 * listeners would have an address and expect it to work right 2257 * listeners would have an address and expect it to work right
2253 * away. 2258 * away.
2254 */ 2259 */
2255 if (link_state == LINK_STATE_UP && 2260 if (link_state == LINK_STATE_UP &&
2256 ifp->if_link_state == LINK_STATE_UNKNOWN) 2261 ifp->if_link_state == LINK_STATE_UNKNOWN)
2257 { 2262 {
2258 DOMAIN_FOREACH(dp) { 2263 DOMAIN_FOREACH(dp) {
2259 if (dp->dom_if_link_state_change != NULL) 2264 if (dp->dom_if_link_state_change != NULL)
2260 dp->dom_if_link_state_change(ifp, 2265 dp->dom_if_link_state_change(ifp,
2261 LINK_STATE_DOWN); 2266 LINK_STATE_DOWN);
2262 } 2267 }
2263 } 2268 }
2264 2269
2265 ifp->if_link_state = link_state; 2270 ifp->if_link_state = link_state;
2266 2271
2267 /* Notify that the link state has changed. */ 2272 /* Notify that the link state has changed. */
2268 rt_ifmsg(ifp); 2273 rt_ifmsg(ifp);
2269 2274
2270#if NCARP > 0 2275#if NCARP > 0
2271 if (ifp->if_carp) 2276 if (ifp->if_carp)
2272 carp_carpdev_state(ifp); 2277 carp_carpdev_state(ifp);
2273#endif 2278#endif
2274 2279
2275 DOMAIN_FOREACH(dp) { 2280 DOMAIN_FOREACH(dp) {
2276 if (dp->dom_if_link_state_change != NULL) 2281 if (dp->dom_if_link_state_change != NULL)
2277 dp->dom_if_link_state_change(ifp, link_state); 2282 dp->dom_if_link_state_change(ifp, link_state);
2278 } 2283 }
2279} 2284}
2280 2285
2281/* 2286/*
2282 * Process the interface link state change queue. 2287 * Process the interface link state change queue.
2283 */ 2288 */
2284static void 2289static void
2285if_link_state_change_si(void *arg) 2290if_link_state_change_si(void *arg)
2286{ 2291{
2287 struct ifnet *ifp = arg; 2292 struct ifnet *ifp = arg;
2288 int s; 2293 int s;
2289 uint8_t state; 2294 uint8_t state;
2290 2295
2291#ifndef NET_MPSAFE 2296#ifndef NET_MPSAFE
2292 mutex_enter(softnet_lock); 2297 mutex_enter(softnet_lock);
2293 KERNEL_LOCK(1, NULL); 2298 KERNEL_LOCK(1, NULL);
2294#endif 2299#endif
2295 s = splnet(); 2300 s = splnet();
2296 2301
2297 /* Pop a link state change from the queue and process it. */ 2302 /* Pop a link state change from the queue and process it. */
2298 LQ_POP(ifp->if_link_queue, state); 2303 LQ_POP(ifp->if_link_queue, state);
2299 if_link_state_change0(ifp, state); 2304 if_link_state_change0(ifp, state);
2300 2305
2301 /* If there is a link state change to come, schedule it. */ 2306 /* If there is a link state change to come, schedule it. */
2302 if (LQ_ITEM(ifp->if_link_queue, 0) != LINK_STATE_UNSET) 2307 if (LQ_ITEM(ifp->if_link_queue, 0) != LINK_STATE_UNSET)
2303 softint_schedule(ifp->if_link_si); 2308 softint_schedule(ifp->if_link_si);
2304 2309
2305 splx(s); 2310 splx(s);
2306#ifndef NET_MPSAFE 2311#ifndef NET_MPSAFE
2307 KERNEL_UNLOCK_ONE(NULL); 2312 KERNEL_UNLOCK_ONE(NULL);
2308 mutex_exit(softnet_lock); 2313 mutex_exit(softnet_lock);
2309#endif 2314#endif
2310} 2315}
2311 2316
2312/* 2317/*
2313 * Default action when installing a local route on a point-to-point 2318 * Default action when installing a local route on a point-to-point
2314 * interface. 2319 * interface.
2315 */ 2320 */
2316void 2321void
2317p2p_rtrequest(int req, struct rtentry *rt, 2322p2p_rtrequest(int req, struct rtentry *rt,
2318 __unused const struct rt_addrinfo *info) 2323 __unused const struct rt_addrinfo *info)
2319{ 2324{
2320 struct ifnet *ifp = rt->rt_ifp; 2325 struct ifnet *ifp = rt->rt_ifp;
2321 struct ifaddr *ifa, *lo0ifa; 2326 struct ifaddr *ifa, *lo0ifa;
2322 int s = pserialize_read_enter(); 2327 int s = pserialize_read_enter();
2323 2328
2324 switch (req) { 2329 switch (req) {
2325 case RTM_ADD: 2330 case RTM_ADD:
2326 if ((rt->rt_flags & RTF_LOCAL) == 0) 2331 if ((rt->rt_flags & RTF_LOCAL) == 0)
2327 break; 2332 break;
2328 2333
2329 rt->rt_ifp = lo0ifp; 2334 rt->rt_ifp = lo0ifp;
2330 2335
2331 IFADDR_READER_FOREACH(ifa, ifp) { 2336 IFADDR_READER_FOREACH(ifa, ifp) {
2332 if (equal(rt_getkey(rt), ifa->ifa_addr)) 2337 if (equal(rt_getkey(rt), ifa->ifa_addr))
2333 break; 2338 break;
2334 } 2339 }
2335 if (ifa == NULL) 2340 if (ifa == NULL)
2336 break; 2341 break;
2337 2342
2338 /* 2343 /*
2339 * Ensure lo0 has an address of the same family. 2344 * Ensure lo0 has an address of the same family.
2340 */ 2345 */
2341 IFADDR_READER_FOREACH(lo0ifa, lo0ifp) { 2346 IFADDR_READER_FOREACH(lo0ifa, lo0ifp) {
2342 if (lo0ifa->ifa_addr->sa_family == 2347 if (lo0ifa->ifa_addr->sa_family ==
2343 ifa->ifa_addr->sa_family) 2348 ifa->ifa_addr->sa_family)
2344 break; 2349 break;
2345 } 2350 }
2346 if (lo0ifa == NULL) 2351 if (lo0ifa == NULL)
2347 break; 2352 break;
2348 2353
2349 /* 2354 /*
2350 * Make sure to set rt->rt_ifa to the interface 2355 * Make sure to set rt->rt_ifa to the interface
2351 * address we are using, otherwise we will have trouble 2356 * address we are using, otherwise we will have trouble
2352 * with source address selection. 2357 * with source address selection.
2353 */ 2358 */
2354 if (ifa != rt->rt_ifa) 2359 if (ifa != rt->rt_ifa)
2355 rt_replace_ifa(rt, ifa); 2360 rt_replace_ifa(rt, ifa);
2356 break; 2361 break;
2357 case RTM_DELETE: 2362 case RTM_DELETE:
2358 default: 2363 default:
2359 break; 2364 break;
2360 } 2365 }
2361 pserialize_read_exit(s); 2366 pserialize_read_exit(s);
2362} 2367}
2363 2368
2364/* 2369/*
2365 * Mark an interface down and notify protocols of 2370 * Mark an interface down and notify protocols of
2366 * the transition. 2371 * the transition.
2367 * NOTE: must be called at splsoftnet or equivalent. 2372 * NOTE: must be called at splsoftnet or equivalent.
2368 */ 2373 */
2369void 2374void
2370if_down(struct ifnet *ifp) 2375if_down(struct ifnet *ifp)
2371{ 2376{
2372 struct ifaddr *ifa; 2377 struct ifaddr *ifa;
2373 struct domain *dp; 2378 struct domain *dp;
2374 int s, bound; 2379 int s, bound;
2375 struct psref psref; 2380 struct psref psref;
2376 2381
2377 ifp->if_flags &= ~IFF_UP; 2382 ifp->if_flags &= ~IFF_UP;
2378 nanotime(&ifp->if_lastchange); 2383 nanotime(&ifp->if_lastchange);
2379 2384
2380 bound = curlwp_bind(); 2385 bound = curlwp_bind();
2381 s = pserialize_read_enter(); 2386 s = pserialize_read_enter();
2382 IFADDR_READER_FOREACH(ifa, ifp) { 2387 IFADDR_READER_FOREACH(ifa, ifp) {
2383 ifa_acquire(ifa, &psref); 2388 ifa_acquire(ifa, &psref);
2384 pserialize_read_exit(s); 2389 pserialize_read_exit(s);
2385 2390
2386 pfctlinput(PRC_IFDOWN, ifa->ifa_addr); 2391 pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
2387 2392
2388 s = pserialize_read_enter(); 2393 s = pserialize_read_enter();
2389 ifa_release(ifa, &psref); 2394 ifa_release(ifa, &psref);
2390 } 2395 }
2391 pserialize_read_exit(s); 2396 pserialize_read_exit(s);
2392 curlwp_bindx(bound); 2397 curlwp_bindx(bound);
2393 2398
2394 IFQ_PURGE(&ifp->if_snd); 2399 IFQ_PURGE(&ifp->if_snd);
2395#if NCARP > 0 2400#if NCARP > 0
2396 if (ifp->if_carp) 2401 if (ifp->if_carp)
2397 carp_carpdev_state(ifp); 2402 carp_carpdev_state(ifp);
2398#endif 2403#endif
2399 rt_ifmsg(ifp); 2404 rt_ifmsg(ifp);
2400 DOMAIN_FOREACH(dp) { 2405 DOMAIN_FOREACH(dp) {
2401 if (dp->dom_if_down) 2406 if (dp->dom_if_down)
2402 dp->dom_if_down(ifp); 2407 dp->dom_if_down(ifp);
2403 } 2408 }
2404} 2409}
2405 2410
2406/* 2411/*
2407 * Mark an interface up and notify protocols of 2412 * Mark an interface up and notify protocols of
2408 * the transition. 2413 * the transition.
2409 * NOTE: must be called at splsoftnet or equivalent. 2414 * NOTE: must be called at splsoftnet or equivalent.
2410 */ 2415 */
2411void 2416void
2412if_up(struct ifnet *ifp) 2417if_up(struct ifnet *ifp)
2413{ 2418{
2414#ifdef notyet 2419#ifdef notyet
2415 struct ifaddr *ifa; 2420 struct ifaddr *ifa;
2416#endif 2421#endif
2417 struct domain *dp; 2422 struct domain *dp;
2418 2423
2419 ifp->if_flags |= IFF_UP; 2424 ifp->if_flags |= IFF_UP;
2420 nanotime(&ifp->if_lastchange); 2425 nanotime(&ifp->if_lastchange);
2421#ifdef notyet 2426#ifdef notyet
2422 /* this has no effect on IP, and will kill all ISO connections XXX */ 2427 /* this has no effect on IP, and will kill all ISO connections XXX */
2423 IFADDR_READER_FOREACH(ifa, ifp) 2428 IFADDR_READER_FOREACH(ifa, ifp)
2424 pfctlinput(PRC_IFUP, ifa->ifa_addr); 2429 pfctlinput(PRC_IFUP, ifa->ifa_addr);
2425#endif 2430#endif
2426#if NCARP > 0 2431#if NCARP > 0
2427 if (ifp->if_carp) 2432 if (ifp->if_carp)
2428 carp_carpdev_state(ifp); 2433 carp_carpdev_state(ifp);
2429#endif 2434#endif
2430 rt_ifmsg(ifp); 2435 rt_ifmsg(ifp);
2431 DOMAIN_FOREACH(dp) { 2436 DOMAIN_FOREACH(dp) {
2432 if (dp->dom_if_up) 2437 if (dp->dom_if_up)
2433 dp->dom_if_up(ifp); 2438 dp->dom_if_up(ifp);
2434 } 2439 }
2435} 2440}
2436 2441
2437/* 2442/*
2438 * Handle interface slowtimo timer routine. Called 2443 * Handle interface slowtimo timer routine. Called
2439 * from softclock, we decrement timer (if set) and 2444 * from softclock, we decrement timer (if set) and
2440 * call the appropriate interface routine on expiration. 2445 * call the appropriate interface routine on expiration.
2441 */ 2446 */
2442static void 2447static void
2443if_slowtimo(void *arg) 2448if_slowtimo(void *arg)
2444{ 2449{
2445 void (*slowtimo)(struct ifnet *); 2450 void (*slowtimo)(struct ifnet *);
2446 struct ifnet *ifp = arg; 2451 struct ifnet *ifp = arg;
2447 int s; 2452 int s;
2448 2453
2449 slowtimo = ifp->if_slowtimo; 2454 slowtimo = ifp->if_slowtimo;
2450 if (__predict_false(slowtimo == NULL)) 2455 if (__predict_false(slowtimo == NULL))
2451 return; 2456 return;
2452 2457
2453 s = splnet(); 2458 s = splnet();
2454 if (ifp->if_timer != 0 && --ifp->if_timer == 0) 2459 if (ifp->if_timer != 0 && --ifp->if_timer == 0)
2455 (*slowtimo)(ifp); 2460 (*slowtimo)(ifp);
2456 2461
2457 splx(s); 2462 splx(s);
2458 2463
2459 if (__predict_true(ifp->if_slowtimo != NULL)) 2464 if (__predict_true(ifp->if_slowtimo != NULL))
2460 callout_schedule(ifp->if_slowtimo_ch, hz / IFNET_SLOWHZ); 2465 callout_schedule(ifp->if_slowtimo_ch, hz / IFNET_SLOWHZ);
2461} 2466}
2462 2467
2463/* 2468/*
2464 * Set/clear promiscuous mode on interface ifp based on the truth value 2469 * Set/clear promiscuous mode on interface ifp based on the truth value
2465 * of pswitch. The calls are reference counted so that only the first 2470 * of pswitch. The calls are reference counted so that only the first
2466 * "on" request actually has an effect, as does the final "off" request. 2471 * "on" request actually has an effect, as does the final "off" request.
2467 * Results are undefined if the "off" and "on" requests are not matched. 2472 * Results are undefined if the "off" and "on" requests are not matched.
2468 */ 2473 */
2469int 2474int
2470ifpromisc(struct ifnet *ifp, int pswitch) 2475ifpromisc(struct ifnet *ifp, int pswitch)
2471{ 2476{
2472 int pcount, ret; 2477 int pcount, ret;
2473 short nflags; 2478 short nflags;
2474 2479
2475 pcount = ifp->if_pcount; 2480 pcount = ifp->if_pcount;
2476 if (pswitch) { 2481 if (pswitch) {
2477 /* 2482 /*
2478 * Allow the device to be "placed" into promiscuous 2483 * Allow the device to be "placed" into promiscuous
2479 * mode even if it is not configured up. It will 2484 * mode even if it is not configured up. It will
2480 * consult IFF_PROMISC when it is brought up. 2485 * consult IFF_PROMISC when it is brought up.
2481 */ 2486 */
2482 if (ifp->if_pcount++ != 0) 2487 if (ifp->if_pcount++ != 0)
2483 return 0; 2488 return 0;
2484 nflags = ifp->if_flags | IFF_PROMISC; 2489 nflags = ifp->if_flags | IFF_PROMISC;
2485 } else { 2490 } else {
2486 if (--ifp->if_pcount > 0) 2491 if (--ifp->if_pcount > 0)
2487 return 0; 2492 return 0;
2488 nflags = ifp->if_flags & ~IFF_PROMISC; 2493 nflags = ifp->if_flags & ~IFF_PROMISC;
2489 } 2494 }
2490 ret = if_flags_set(ifp, nflags); 2495 ret = if_flags_set(ifp, nflags);
2491 /* Restore interface state if not successful. */ 2496 /* Restore interface state if not successful. */
2492 if (ret != 0) { 2497 if (ret != 0) {
2493 ifp->if_pcount = pcount; 2498 ifp->if_pcount = pcount;
2494 } 2499 }
2495 return ret; 2500 return ret;
2496} 2501}
2497 2502
2498/* 2503/*
2499 * Map interface name to 2504 * Map interface name to
2500 * interface structure pointer. 2505 * interface structure pointer.
2501 */ 2506 */
2502struct ifnet * 2507struct ifnet *
2503ifunit(const char *name) 2508ifunit(const char *name)
2504{ 2509{
2505 struct ifnet *ifp; 2510 struct ifnet *ifp;
2506 const char *cp = name; 2511 const char *cp = name;
2507 u_int unit = 0; 2512 u_int unit = 0;
2508 u_int i; 2513 u_int i;
2509 int s; 2514 int s;
2510 2515
2511 /* 2516 /*
2512 * If the entire name is a number, treat it as an ifindex. 2517 * If the entire name is a number, treat it as an ifindex.
2513 */ 2518 */
2514 for (i = 0; i < IFNAMSIZ && *cp >= '0' && *cp <= '9'; i++, cp++) { 2519 for (i = 0; i < IFNAMSIZ && *cp >= '0' && *cp <= '9'; i++, cp++) {
2515 unit = unit * 10 + (*cp - '0'); 2520 unit = unit * 10 + (*cp - '0');
2516 } 2521 }
2517 2522
2518 /* 2523 /*
2519 * If the number took all of the name, then it's a valid ifindex. 2524 * If the number took all of the name, then it's a valid ifindex.
2520 */ 2525 */
2521 if (i == IFNAMSIZ || (cp != name && *cp == '\0')) { 2526 if (i == IFNAMSIZ || (cp != name && *cp == '\0')) {
2522 if (unit >= if_indexlim) 2527 if (unit >= if_indexlim)
2523 return NULL; 2528 return NULL;
2524 ifp = ifindex2ifnet[unit]; 2529 ifp = ifindex2ifnet[unit];
2525 if (ifp == NULL || if_is_deactivated(ifp)) 2530 if (ifp == NULL || if_is_deactivated(ifp))
2526 return NULL; 2531 return NULL;
2527 return ifp; 2532 return ifp;
2528 } 2533 }
2529 2534
2530 ifp = NULL; 2535 ifp = NULL;
2531 s = pserialize_read_enter(); 2536 s = pserialize_read_enter();
2532 IFNET_READER_FOREACH(ifp) { 2537 IFNET_READER_FOREACH(ifp) {
2533 if (if_is_deactivated(ifp)) 2538 if (if_is_deactivated(ifp))
2534 continue; 2539 continue;
2535 if (strcmp(ifp->if_xname, name) == 0) 2540 if (strcmp(ifp->if_xname, name) == 0)
2536 goto out; 2541 goto out;
2537 } 2542 }
2538out: 2543out:
2539 pserialize_read_exit(s); 2544 pserialize_read_exit(s);
2540 return ifp; 2545 return ifp;
2541} 2546}
2542 2547
2543/* 2548/*
2544 * Get a reference of an ifnet object by an interface name. 2549 * Get a reference of an ifnet object by an interface name.
2545 * The returned reference is protected by psref(9). The caller 2550 * The returned reference is protected by psref(9). The caller
2546 * must release a returned reference by if_put after use. 2551 * must release a returned reference by if_put after use.
2547 */ 2552 */
2548struct ifnet * 2553struct ifnet *
2549if_get(const char *name, struct psref *psref) 2554if_get(const char *name, struct psref *psref)
2550{ 2555{
2551 struct ifnet *ifp; 2556 struct ifnet *ifp;
2552 const char *cp = name; 2557 const char *cp = name;
2553 u_int unit = 0; 2558 u_int unit = 0;
2554 u_int i; 2559 u_int i;
2555 int s; 2560 int s;
2556 2561
2557 /* 2562 /*
2558 * If the entire name is a number, treat it as an ifindex. 2563 * If the entire name is a number, treat it as an ifindex.
2559 */ 2564 */
2560 for (i = 0; i < IFNAMSIZ && *cp >= '0' && *cp <= '9'; i++, cp++) { 2565 for (i = 0; i < IFNAMSIZ && *cp >= '0' && *cp <= '9'; i++, cp++) {
2561 unit = unit * 10 + (*cp - '0'); 2566 unit = unit * 10 + (*cp - '0');
2562 } 2567 }
2563 2568
2564 /* 2569 /*
2565 * If the number took all of the name, then it's a valid ifindex. 2570 * If the number took all of the name, then it's a valid ifindex.
2566 */ 2571 */
2567 if (i == IFNAMSIZ || (cp != name && *cp == '\0')) { 2572 if (i == IFNAMSIZ || (cp != name && *cp == '\0')) {
2568 if (unit >= if_indexlim) 2573 if (unit >= if_indexlim)
2569 return NULL; 2574 return NULL;
2570 ifp = ifindex2ifnet[unit]; 2575 ifp = ifindex2ifnet[unit];
2571 if (ifp == NULL || if_is_deactivated(ifp)) 2576 if (ifp == NULL || if_is_deactivated(ifp))
2572 return NULL; 2577 return NULL;
2573 return ifp; 2578 return ifp;
2574 } 2579 }
2575 2580
2576 ifp = NULL; 2581 ifp = NULL;
2577 s = pserialize_read_enter(); 2582 s = pserialize_read_enter();
2578 IFNET_READER_FOREACH(ifp) { 2583 IFNET_READER_FOREACH(ifp) {
2579 if (if_is_deactivated(ifp)) 2584 if (if_is_deactivated(ifp))
2580 continue; 2585 continue;
2581 if (strcmp(ifp->if_xname, name) == 0) { 2586 if (strcmp(ifp->if_xname, name) == 0) {
2582 psref_acquire(psref, &ifp->if_psref, 2587 psref_acquire(psref, &ifp->if_psref,
2583 ifnet_psref_class); 2588 ifnet_psref_class);
2584 goto out; 2589 goto out;
2585 } 2590 }
2586 } 2591 }
2587out: 2592out:
2588 pserialize_read_exit(s); 2593 pserialize_read_exit(s);
2589 return ifp; 2594 return ifp;
2590} 2595}
2591 2596
2592/* 2597/*
2593 * Release a reference of an ifnet object given by if_get or 2598 * Release a reference of an ifnet object given by if_get or
2594 * if_get_byindex. 2599 * if_get_byindex.
2595 */ 2600 */
2596void 2601void
2597if_put(const struct ifnet *ifp, struct psref *psref) 2602if_put(const struct ifnet *ifp, struct psref *psref)
2598{ 2603{
2599 2604
2600 if (ifp == NULL) 2605 if (ifp == NULL)
2601 return; 2606 return;
2602 2607
2603 psref_release(psref, &ifp->if_psref, ifnet_psref_class); 2608 psref_release(psref, &ifp->if_psref, ifnet_psref_class);
2604} 2609}
2605 2610
2606ifnet_t * 2611ifnet_t *
2607if_byindex(u_int idx) 2612if_byindex(u_int idx)
2608{ 2613{
2609 ifnet_t *ifp; 2614 ifnet_t *ifp;
2610 2615
2611 ifp = (idx < if_indexlim) ? ifindex2ifnet[idx] : NULL; 2616 ifp = (idx < if_indexlim) ? ifindex2ifnet[idx] : NULL;
2612 if (ifp != NULL && if_is_deactivated(ifp)) 2617 if (ifp != NULL && if_is_deactivated(ifp))
2613 ifp = NULL; 2618 ifp = NULL;
2614 return ifp; 2619 return ifp;
2615} 2620}
2616 2621
2617/* 2622/*
2618 * Get a reference of an ifnet object by an interface index. 2623 * Get a reference of an ifnet object by an interface index.
2619 * The returned reference is protected by psref(9). The caller 2624 * The returned reference is protected by psref(9). The caller
2620 * must release a returned reference by if_put after use. 2625 * must release a returned reference by if_put after use.
2621 */ 2626 */
2622ifnet_t * 2627ifnet_t *