FreeBSD/Linux Kernel Cross Reference
sys/net/if.c
1 /* $OpenBSD: if.c,v 1.683 2022/11/23 16:57:37 kn Exp $ */
2 /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
3
4 /*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33 /*
34 * Copyright (c) 1980, 1986, 1993
35 * The Regents of the University of California. All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)if.c 8.3 (Berkeley) 1/4/94
62 */
63
64 #include "bpfilter.h"
65 #include "bridge.h"
66 #include "carp.h"
67 #include "ether.h"
68 #include "pf.h"
69 #include "pfsync.h"
70 #include "ppp.h"
71 #include "pppoe.h"
72 #include "if_wg.h"
73
74 #include <sys/param.h>
75 #include <sys/systm.h>
76 #include <sys/mbuf.h>
77 #include <sys/socket.h>
78 #include <sys/socketvar.h>
79 #include <sys/timeout.h>
80 #include <sys/protosw.h>
81 #include <sys/kernel.h>
82 #include <sys/ioctl.h>
83 #include <sys/domain.h>
84 #include <sys/task.h>
85 #include <sys/atomic.h>
86 #include <sys/percpu.h>
87 #include <sys/proc.h>
88 #include <sys/stdint.h> /* uintptr_t */
89 #include <sys/rwlock.h>
90 #include <sys/smr.h>
91
92 #include <net/if.h>
93 #include <net/if_dl.h>
94 #include <net/if_types.h>
95 #include <net/route.h>
96 #include <net/netisr.h>
97
98 #include <netinet/in.h>
99 #include <netinet/if_ether.h>
100 #include <netinet/igmp.h>
101 #ifdef MROUTING
102 #include <netinet/ip_mroute.h>
103 #endif
104
105 #ifdef INET6
106 #include <netinet6/in6_var.h>
107 #include <netinet6/in6_ifattach.h>
108 #include <netinet6/nd6.h>
109 #include <netinet/ip6.h>
110 #include <netinet6/ip6_var.h>
111 #endif
112
113 #ifdef MPLS
114 #include <netmpls/mpls.h>
115 #endif
116
117 #if NBPFILTER > 0
118 #include <net/bpf.h>
119 #endif
120
121 #if NBRIDGE > 0
122 #include <net/if_bridge.h>
123 #endif
124
125 #if NCARP > 0
126 #include <netinet/ip_carp.h>
127 #endif
128
129 #if NPF > 0
130 #include <net/pfvar.h>
131 #endif
132
133 #include <sys/device.h>
134
135 void if_attachsetup(struct ifnet *);
136 void if_attach_common(struct ifnet *);
137 void if_remove(struct ifnet *);
138 int if_createrdomain(int, struct ifnet *);
139 int if_setrdomain(struct ifnet *, int);
140 void if_slowtimo(void *);
141
142 void if_detached_qstart(struct ifqueue *);
143 int if_detached_ioctl(struct ifnet *, u_long, caddr_t);
144
145 int ifioctl_get(u_long, caddr_t);
146 int ifconf(caddr_t);
147 static int
148 if_sffpage_check(const caddr_t);
149
150 int if_getgroup(caddr_t, struct ifnet *);
151 int if_getgroupmembers(caddr_t);
152 int if_getgroupattribs(caddr_t);
153 int if_setgroupattribs(caddr_t);
154 int if_getgrouplist(caddr_t);
155
156 void if_linkstate(struct ifnet *);
157 void if_linkstate_task(void *);
158
159 int if_clone_list(struct if_clonereq *);
160 struct if_clone *if_clone_lookup(const char *, int *);
161
162 int if_group_egress_build(void);
163
164 void if_watchdog_task(void *);
165
166 void if_netisr(void *);
167
168 #ifdef DDB
169 void ifa_print_all(void);
170 #endif
171
172 void if_qstart_compat(struct ifqueue *);
173
174 /*
175 * interface index map
176 *
177 * the kernel maintains a mapping of interface indexes to struct ifnet
178 * pointers.
179 *
180 * the map is an array of struct ifnet pointers prefixed by an if_map
181 * structure. the if_map structure stores the length of its array.
182 *
183 * as interfaces are attached to the system, the map is grown on demand
184 * up to USHRT_MAX entries.
185 *
186 * interface index 0 is reserved and represents no interface. this
187 * supports the use of the interface index as the scope for IPv6 link
188 * local addresses, where scope 0 means no scope has been specified.
189 * it also supports the use of interface index as the unique identifier
190 * for network interfaces in SNMP applications as per RFC2863. therefore
191 * if_get(0) returns NULL.
192 */
193
194 struct ifnet *if_ref(struct ifnet *);
195
196 /*
197 * struct if_idxmap
198 *
199 * infrastructure to manage updates and accesses to the current if_map.
200 *
201 * interface index 0 is special and represents "no interface", so we
202 * use the 0th slot in map to store the length of the array.
203 */
204
205 struct if_idxmap {
206 unsigned int serial;
207 unsigned int count;
208 struct ifnet **map; /* SMR protected */
209 struct rwlock lock;
210 unsigned char *usedidx; /* bitmap of indices in use */
211 };
212
213 struct if_idxmap_dtor {
214 struct smr_entry smr;
215 struct ifnet **map;
216 };
217
218 void if_idxmap_init(unsigned int);
219 void if_idxmap_free(void *);
220 void if_idxmap_alloc(struct ifnet *);
221 void if_idxmap_insert(struct ifnet *);
222 void if_idxmap_remove(struct ifnet *);
223
224 TAILQ_HEAD(, ifg_group) ifg_head =
225 TAILQ_HEAD_INITIALIZER(ifg_head); /* [N] list of interface groups */
226
227 LIST_HEAD(, if_clone) if_cloners =
228 LIST_HEAD_INITIALIZER(if_cloners); /* [I] list of clonable interfaces */
229 int if_cloners_count; /* [I] number of clonable interfaces */
230
231 struct rwlock if_cloners_lock = RWLOCK_INITIALIZER("clonelk");
232
233 /* hooks should only be added, deleted, and run from a process context */
234 struct mutex if_hooks_mtx = MUTEX_INITIALIZER(IPL_NONE);
235 void if_hooks_run(struct task_list *);
236
237 int ifq_congestion;
238
239 int netisr;
240
241 #define NET_TASKQ 4
242 struct taskq *nettqmp[NET_TASKQ];
243
244 struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL);
245
246 /*
247 * Serialize socket operations to ensure no new sleeping points
248 * are introduced in IP output paths.
249 */
250 struct rwlock netlock = RWLOCK_INITIALIZER("netlock");
251
252 /*
253 * Network interface utility routines.
254 */
255 void
256 ifinit(void)
257 {
258 unsigned int i;
259
260 /*
261 * most machines boot with 4 or 5 interfaces, so size the initial map
262 * to accommodate this
263 */
264 if_idxmap_init(8); /* 8 is a nice power of 2 for malloc */
265
266 for (i = 0; i < NET_TASKQ; i++) {
267 nettqmp[i] = taskq_create("softnet", 1, IPL_NET, TASKQ_MPSAFE);
268 if (nettqmp[i] == NULL)
269 panic("unable to create network taskq %d", i);
270 }
271 }
272
273 static struct if_idxmap if_idxmap;
274
275 struct ifnet_head ifnetlist = TAILQ_HEAD_INITIALIZER(ifnetlist);
276
277 static inline unsigned int
278 if_idxmap_limit(struct ifnet **if_map)
279 {
280 return ((uintptr_t)if_map[0]);
281 }
282
283 static inline size_t
284 if_idxmap_usedidx_size(unsigned int limit)
285 {
286 return (max(howmany(limit, NBBY), sizeof(struct if_idxmap_dtor)));
287 }
288
289 void
290 if_idxmap_init(unsigned int limit)
291 {
292 struct ifnet **if_map;
293
294 rw_init(&if_idxmap.lock, "idxmaplk");
295 if_idxmap.serial = 1; /* skip ifidx 0 */
296
297 if_map = mallocarray(limit, sizeof(*if_map), M_IFADDR,
298 M_WAITOK | M_ZERO);
299
300 if_map[0] = (struct ifnet *)(uintptr_t)limit;
301
302 if_idxmap.usedidx = malloc(if_idxmap_usedidx_size(limit),
303 M_IFADDR, M_WAITOK | M_ZERO);
304 setbit(if_idxmap.usedidx, 0); /* blacklist ifidx 0 */
305
306 /* this is called early so there's nothing to race with */
307 SMR_PTR_SET_LOCKED(&if_idxmap.map, if_map);
308 }
309
310 void
311 if_idxmap_alloc(struct ifnet *ifp)
312 {
313 struct ifnet **if_map;
314 unsigned int limit;
315 unsigned int index, i;
316
317 refcnt_init(&ifp->if_refcnt);
318
319 rw_enter_write(&if_idxmap.lock);
320
321 if (++if_idxmap.count >= USHRT_MAX)
322 panic("too many interfaces");
323
324 if_map = SMR_PTR_GET_LOCKED(&if_idxmap.map);
325 limit = if_idxmap_limit(if_map);
326
327 index = if_idxmap.serial++ & USHRT_MAX;
328
329 if (index >= limit) {
330 struct if_idxmap_dtor *dtor;
331 struct ifnet **oif_map;
332 unsigned int olimit;
333 unsigned char *nusedidx;
334
335 oif_map = if_map;
336 olimit = limit;
337
338 limit = olimit * 2;
339 if_map = mallocarray(limit, sizeof(*if_map), M_IFADDR,
340 M_WAITOK | M_ZERO);
341 if_map[0] = (struct ifnet *)(uintptr_t)limit;
342
343 for (i = 1; i < olimit; i++) {
344 struct ifnet *oifp = SMR_PTR_GET_LOCKED(&oif_map[i]);
345 if (oifp == NULL)
346 continue;
347
348 /*
349 * nif_map isn't visible yet, so don't need
350 * SMR_PTR_SET_LOCKED and its membar.
351 */
352 if_map[i] = if_ref(oifp);
353 }
354
355 nusedidx = malloc(if_idxmap_usedidx_size(limit),
356 M_IFADDR, M_WAITOK | M_ZERO);
357 memcpy(nusedidx, if_idxmap.usedidx, howmany(olimit, NBBY));
358
359 /* use the old usedidx bitmap as an smr_entry for the if_map */
360 dtor = (struct if_idxmap_dtor *)if_idxmap.usedidx;
361 if_idxmap.usedidx = nusedidx;
362
363 SMR_PTR_SET_LOCKED(&if_idxmap.map, if_map);
364
365 dtor->map = oif_map;
366 smr_init(&dtor->smr);
367 smr_call(&dtor->smr, if_idxmap_free, dtor);
368 }
369
370 /* pick the next free index */
371 for (i = 0; i < USHRT_MAX; i++) {
372 if (index != 0 && isclr(if_idxmap.usedidx, index))
373 break;
374
375 index = if_idxmap.serial++ & USHRT_MAX;
376 }
377 KASSERT(index != 0 && index < limit);
378 KASSERT(isclr(if_idxmap.usedidx, index));
379
380 setbit(if_idxmap.usedidx, index);
381 ifp->if_index = index;
382
383 rw_exit_write(&if_idxmap.lock);
384 }
385
386 void
387 if_idxmap_free(void *arg)
388 {
389 struct if_idxmap_dtor *dtor = arg;
390 struct ifnet **oif_map = dtor->map;
391 unsigned int olimit = if_idxmap_limit(oif_map);
392 unsigned int i;
393
394 for (i = 1; i < olimit; i++)
395 if_put(oif_map[i]);
396
397 free(oif_map, M_IFADDR, olimit * sizeof(*oif_map));
398 free(dtor, M_IFADDR, if_idxmap_usedidx_size(olimit));
399 }
400
401 void
402 if_idxmap_insert(struct ifnet *ifp)
403 {
404 struct ifnet **if_map;
405 unsigned int index = ifp->if_index;
406
407 rw_enter_write(&if_idxmap.lock);
408
409 if_map = SMR_PTR_GET_LOCKED(&if_idxmap.map);
410
411 KASSERTMSG(index != 0 && index < if_idxmap_limit(if_map),
412 "%s(%p) index %u vs limit %u", ifp->if_xname, ifp, index,
413 if_idxmap_limit(if_map));
414 KASSERT(SMR_PTR_GET_LOCKED(&if_map[index]) == NULL);
415 KASSERT(isset(if_idxmap.usedidx, index));
416
417 /* commit */
418 SMR_PTR_SET_LOCKED(&if_map[index], if_ref(ifp));
419
420 rw_exit_write(&if_idxmap.lock);
421 }
422
423 void
424 if_idxmap_remove(struct ifnet *ifp)
425 {
426 struct ifnet **if_map;
427 unsigned int index = ifp->if_index;
428
429 rw_enter_write(&if_idxmap.lock);
430
431 if_map = SMR_PTR_GET_LOCKED(&if_idxmap.map);
432
433 KASSERT(index != 0 && index < if_idxmap_limit(if_map));
434 KASSERT(SMR_PTR_GET_LOCKED(&if_map[index]) == ifp);
435 KASSERT(isset(if_idxmap.usedidx, index));
436
437 SMR_PTR_SET_LOCKED(&if_map[index], NULL);
438
439 if_idxmap.count--;
440 clrbit(if_idxmap.usedidx, index);
441 /* end of if_idxmap modifications */
442
443 rw_exit_write(&if_idxmap.lock);
444
445 smr_barrier();
446 if_put(ifp);
447 }
448
449 /*
450 * Attach an interface to the
451 * list of "active" interfaces.
452 */
453 void
454 if_attachsetup(struct ifnet *ifp)
455 {
456 unsigned long ifidx;
457
458 NET_ASSERT_LOCKED();
459
460 if_addgroup(ifp, IFG_ALL);
461
462 #ifdef INET6
463 nd6_ifattach(ifp);
464 #endif
465
466 #if NPF > 0
467 pfi_attach_ifnet(ifp);
468 #endif
469
470 timeout_set(&ifp->if_slowtimo, if_slowtimo, ifp);
471 if_slowtimo(ifp);
472
473 if_idxmap_insert(ifp);
474 KASSERT(if_get(0) == NULL);
475
476 ifidx = ifp->if_index;
477
478 task_set(&ifp->if_watchdogtask, if_watchdog_task, (void *)ifidx);
479 task_set(&ifp->if_linkstatetask, if_linkstate_task, (void *)ifidx);
480
481 /* Announce the interface. */
482 rtm_ifannounce(ifp, IFAN_ARRIVAL);
483 }
484
485 /*
486 * Allocate the link level name for the specified interface. This
487 * is an attachment helper. It must be called after ifp->if_addrlen
488 * is initialized, which may not be the case when if_attach() is
489 * called.
490 */
491 void
492 if_alloc_sadl(struct ifnet *ifp)
493 {
494 unsigned int socksize;
495 int namelen, masklen;
496 struct sockaddr_dl *sdl;
497
498 /*
499 * If the interface already has a link name, release it
500 * now. This is useful for interfaces that can change
501 * link types, and thus switch link names often.
502 */
503 if_free_sadl(ifp);
504
505 namelen = strlen(ifp->if_xname);
506 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
507 socksize = masklen + ifp->if_addrlen;
508 #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
509 if (socksize < sizeof(*sdl))
510 socksize = sizeof(*sdl);
511 socksize = ROUNDUP(socksize);
512 sdl = malloc(socksize, M_IFADDR, M_WAITOK|M_ZERO);
513 sdl->sdl_len = socksize;
514 sdl->sdl_family = AF_LINK;
515 bcopy(ifp->if_xname, sdl->sdl_data, namelen);
516 sdl->sdl_nlen = namelen;
517 sdl->sdl_alen = ifp->if_addrlen;
518 sdl->sdl_index = ifp->if_index;
519 sdl->sdl_type = ifp->if_type;
520 ifp->if_sadl = sdl;
521 }
522
523 /*
524 * Free the link level name for the specified interface. This is
525 * a detach helper. This is called from if_detach() or from
526 * link layer type specific detach functions.
527 */
528 void
529 if_free_sadl(struct ifnet *ifp)
530 {
531 if (ifp->if_sadl == NULL)
532 return;
533
534 free(ifp->if_sadl, M_IFADDR, ifp->if_sadl->sdl_len);
535 ifp->if_sadl = NULL;
536 }
537
538 void
539 if_attachhead(struct ifnet *ifp)
540 {
541 if_attach_common(ifp);
542 NET_LOCK();
543 TAILQ_INSERT_HEAD(&ifnetlist, ifp, if_list);
544 if_attachsetup(ifp);
545 NET_UNLOCK();
546 }
547
548 void
549 if_attach(struct ifnet *ifp)
550 {
551 if_attach_common(ifp);
552 NET_LOCK();
553 TAILQ_INSERT_TAIL(&ifnetlist, ifp, if_list);
554 if_attachsetup(ifp);
555 NET_UNLOCK();
556 }
557
558 void
559 if_attach_queues(struct ifnet *ifp, unsigned int nqs)
560 {
561 struct ifqueue **map;
562 struct ifqueue *ifq;
563 int i;
564
565 KASSERT(ifp->if_ifqs == ifp->if_snd.ifq_ifqs);
566 KASSERT(nqs != 0);
567
568 map = mallocarray(sizeof(*map), nqs, M_DEVBUF, M_WAITOK);
569
570 ifp->if_snd.ifq_softc = NULL;
571 map[0] = &ifp->if_snd;
572
573 for (i = 1; i < nqs; i++) {
574 ifq = malloc(sizeof(*ifq), M_DEVBUF, M_WAITOK|M_ZERO);
575 ifq_set_maxlen(ifq, ifp->if_snd.ifq_maxlen);
576 ifq_init(ifq, ifp, i);
577 map[i] = ifq;
578 }
579
580 ifp->if_ifqs = map;
581 ifp->if_nifqs = nqs;
582 }
583
584 void
585 if_attach_iqueues(struct ifnet *ifp, unsigned int niqs)
586 {
587 struct ifiqueue **map;
588 struct ifiqueue *ifiq;
589 unsigned int i;
590
591 KASSERT(niqs != 0);
592
593 map = mallocarray(niqs, sizeof(*map), M_DEVBUF, M_WAITOK);
594
595 ifp->if_rcv.ifiq_softc = NULL;
596 map[0] = &ifp->if_rcv;
597
598 for (i = 1; i < niqs; i++) {
599 ifiq = malloc(sizeof(*ifiq), M_DEVBUF, M_WAITOK|M_ZERO);
600 ifiq_init(ifiq, ifp, i);
601 map[i] = ifiq;
602 }
603
604 ifp->if_iqs = map;
605 ifp->if_niqs = niqs;
606 }
607
608 void
609 if_attach_common(struct ifnet *ifp)
610 {
611 KASSERT(ifp->if_ioctl != NULL);
612
613 TAILQ_INIT(&ifp->if_addrlist);
614 TAILQ_INIT(&ifp->if_maddrlist);
615 TAILQ_INIT(&ifp->if_groups);
616
617 if (!ISSET(ifp->if_xflags, IFXF_MPSAFE)) {
618 KASSERTMSG(ifp->if_qstart == NULL,
619 "%s: if_qstart set without MPSAFE set", ifp->if_xname);
620 ifp->if_qstart = if_qstart_compat;
621 } else {
622 KASSERTMSG(ifp->if_start == NULL,
623 "%s: if_start set with MPSAFE set", ifp->if_xname);
624 KASSERTMSG(ifp->if_qstart != NULL,
625 "%s: if_qstart not set with MPSAFE set", ifp->if_xname);
626 }
627
628 if_idxmap_alloc(ifp);
629
630 ifq_init(&ifp->if_snd, ifp, 0);
631
632 ifp->if_snd.ifq_ifqs[0] = &ifp->if_snd;
633 ifp->if_ifqs = ifp->if_snd.ifq_ifqs;
634 ifp->if_nifqs = 1;
635 if (ifp->if_txmit == 0)
636 ifp->if_txmit = IF_TXMIT_DEFAULT;
637
638 ifiq_init(&ifp->if_rcv, ifp, 0);
639
640 ifp->if_rcv.ifiq_ifiqs[0] = &ifp->if_rcv;
641 ifp->if_iqs = ifp->if_rcv.ifiq_ifiqs;
642 ifp->if_niqs = 1;
643
644 TAILQ_INIT(&ifp->if_addrhooks);
645 TAILQ_INIT(&ifp->if_linkstatehooks);
646 TAILQ_INIT(&ifp->if_detachhooks);
647
648 if (ifp->if_rtrequest == NULL)
649 ifp->if_rtrequest = if_rtrequest_dummy;
650 if (ifp->if_enqueue == NULL)
651 ifp->if_enqueue = if_enqueue_ifq;
652 #if NBPFILTER > 0
653 if (ifp->if_bpf_mtap == NULL)
654 ifp->if_bpf_mtap = bpf_mtap_ether;
655 #endif
656 ifp->if_llprio = IFQ_DEFPRIO;
657 }
658
659 void
660 if_attach_ifq(struct ifnet *ifp, const struct ifq_ops *newops, void *args)
661 {
662 /*
663 * only switch the ifq_ops on the first ifq on an interface.
664 *
665 * the only ifq_ops we provide priq and hfsc, and hfsc only
666 * works on a single ifq. because the code uses the ifq_ops
667 * on the first ifq (if_snd) to select a queue for an mbuf,
668 * by switching only the first one we change both the algorithm
669 * and force the routing of all new packets to it.
670 */
671 ifq_attach(&ifp->if_snd, newops, args);
672 }
673
674 void
675 if_start(struct ifnet *ifp)
676 {
677 KASSERT(ifp->if_qstart == if_qstart_compat);
678 if_qstart_compat(&ifp->if_snd);
679 }
680 void
681 if_qstart_compat(struct ifqueue *ifq)
682 {
683 struct ifnet *ifp = ifq->ifq_if;
684 int s;
685
686 /*
687 * the stack assumes that an interface can have multiple
688 * transmit rings, but a lot of drivers are still written
689 * so that interfaces and send rings have a 1:1 mapping.
690 * this provides compatibility between the stack and the older
691 * drivers by translating from the only queue they have
692 * (ifp->if_snd) back to the interface and calling if_start.
693 */
694
695 KERNEL_LOCK();
696 s = splnet();
697 (*ifp->if_start)(ifp);
698 splx(s);
699 KERNEL_UNLOCK();
700 }
701
702 int
703 if_enqueue(struct ifnet *ifp, struct mbuf *m)
704 {
705 CLR(m->m_pkthdr.csum_flags, M_TIMESTAMP);
706
707 #if NPF > 0
708 if (m->m_pkthdr.pf.delay > 0)
709 return (pf_delay_pkt(m, ifp->if_index));
710 #endif
711
712 #if NBRIDGE > 0
713 if (ifp->if_bridgeidx && (m->m_flags & M_PROTO1) == 0) {
714 int error;
715
716 error = bridge_enqueue(ifp, m);
717 return (error);
718 }
719 #endif
720
721 #if NPF > 0
722 pf_pkt_addr_changed(m);
723 #endif /* NPF > 0 */
724
725 return ((*ifp->if_enqueue)(ifp, m));
726 }
727
728 int
729 if_enqueue_ifq(struct ifnet *ifp, struct mbuf *m)
730 {
731 struct ifqueue *ifq = &ifp->if_snd;
732 int error;
733
734 if (ifp->if_nifqs > 1) {
735 unsigned int idx;
736
737 /*
738 * use the operations on the first ifq to pick which of
739 * the array gets this mbuf.
740 */
741
742 idx = ifq_idx(&ifp->if_snd, ifp->if_nifqs, m);
743 ifq = ifp->if_ifqs[idx];
744 }
745
746 error = ifq_enqueue(ifq, m);
747 if (error)
748 return (error);
749
750 ifq_start(ifq);
751
752 return (0);
753 }
754
755 void
756 if_input(struct ifnet *ifp, struct mbuf_list *ml)
757 {
758 ifiq_input(&ifp->if_rcv, ml);
759 }
760
761 int
762 if_input_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
763 {
764 int keepflags;
765
766 #if NBPFILTER > 0
767 /*
768 * Only send packets to bpf if they are destined to local
769 * addresses.
770 *
771 * if_input_local() is also called for SIMPLEX interfaces to
772 * duplicate packets for local use. But don't dup them to bpf.
773 */
774 if (ifp->if_flags & IFF_LOOPBACK) {
775 caddr_t if_bpf = ifp->if_bpf;
776
777 if (if_bpf)
778 bpf_mtap_af(if_bpf, af, m, BPF_DIRECTION_OUT);
779 }
780 #endif
781 keepflags = m->m_flags & (M_BCAST|M_MCAST);
782 m_resethdr(m);
783 m->m_flags |= M_LOOP | keepflags;
784 m->m_pkthdr.ph_ifidx = ifp->if_index;
785 m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
786
787 ifp->if_opackets++;
788 ifp->if_obytes += m->m_pkthdr.len;
789
790 ifp->if_ipackets++;
791 ifp->if_ibytes += m->m_pkthdr.len;
792
793 switch (af) {
794 case AF_INET:
795 ipv4_input(ifp, m);
796 break;
797 #ifdef INET6
798 case AF_INET6:
799 ipv6_input(ifp, m);
800 break;
801 #endif /* INET6 */
802 #ifdef MPLS
803 case AF_MPLS:
804 mpls_input(ifp, m);
805 break;
806 #endif /* MPLS */
807 default:
808 printf("%s: can't handle af%d\n", ifp->if_xname, af);
809 m_freem(m);
810 return (EAFNOSUPPORT);
811 }
812
813 return (0);
814 }
815
816 int
817 if_output_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
818 {
819 struct ifiqueue *ifiq;
820 unsigned int flow = 0;
821
822 m->m_pkthdr.ph_family = af;
823 m->m_pkthdr.ph_ifidx = ifp->if_index;
824 m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
825
826 if (ISSET(m->m_pkthdr.csum_flags, M_FLOWID))
827 flow = m->m_pkthdr.ph_flowid;
828
829 ifiq = ifp->if_iqs[flow % ifp->if_niqs];
830
831 return (ifiq_enqueue(ifiq, m) == 0 ? 0 : ENOBUFS);
832 }
833
834 void
835 if_input_process(struct ifnet *ifp, struct mbuf_list *ml)
836 {
837 struct mbuf *m;
838
839 if (ml_empty(ml))
840 return;
841
842 if (!ISSET(ifp->if_xflags, IFXF_CLONED))
843 enqueue_randomness(ml_len(ml) ^ (uintptr_t)MBUF_LIST_FIRST(ml));
844
845 /*
846 * We grab the shared netlock for packet processing in the softnet
847 * threads. Packets can regrab the exclusive lock via queues.
848 * ioctl, sysctl, and socket syscall may use shared lock if access is
849 * read only or MP safe. Usually they hold the exclusive net lock.
850 */
851
852 NET_LOCK_SHARED();
853 while ((m = ml_dequeue(ml)) != NULL)
854 (*ifp->if_input)(ifp, m);
855 NET_UNLOCK_SHARED();
856 }
857
858 void
859 if_vinput(struct ifnet *ifp, struct mbuf *m)
860 {
861 #if NBPFILTER > 0
862 caddr_t if_bpf;
863 #endif
864
865 m->m_pkthdr.ph_ifidx = ifp->if_index;
866 m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
867
868 counters_pkt(ifp->if_counters,
869 ifc_ipackets, ifc_ibytes, m->m_pkthdr.len);
870
871 #if NPF > 0
872 pf_pkt_addr_changed(m);
873 #endif
874
875 #if NBPFILTER > 0
876 if_bpf = ifp->if_bpf;
877 if (if_bpf) {
878 if ((*ifp->if_bpf_mtap)(if_bpf, m, BPF_DIRECTION_IN)) {
879 m_freem(m);
880 return;
881 }
882 }
883 #endif
884
885 if (__predict_true(!ISSET(ifp->if_xflags, IFXF_MONITOR)))
886 (*ifp->if_input)(ifp, m);
887 else
888 m_freem(m);
889 }
890
891 void
892 if_netisr(void *unused)
893 {
894 int n, t = 0;
895
896 NET_LOCK();
897
898 while ((n = netisr) != 0) {
899 /* Like sched_pause() but with a rwlock dance. */
900 if (curcpu()->ci_schedstate.spc_schedflags & SPCF_SHOULDYIELD) {
901 NET_UNLOCK();
902 yield();
903 NET_LOCK();
904 }
905
906 atomic_clearbits_int(&netisr, n);
907
908 #if NETHER > 0
909 if (n & (1 << NETISR_ARP)) {
910 KERNEL_LOCK();
911 arpintr();
912 KERNEL_UNLOCK();
913 }
914 #endif
915 if (n & (1 << NETISR_IP))
916 ipintr();
917 #ifdef INET6
918 if (n & (1 << NETISR_IPV6))
919 ip6intr();
920 #endif
921 #if NPPP > 0
922 if (n & (1 << NETISR_PPP)) {
923 KERNEL_LOCK();
924 pppintr();
925 KERNEL_UNLOCK();
926 }
927 #endif
928 #if NBRIDGE > 0
929 if (n & (1 << NETISR_BRIDGE))
930 bridgeintr();
931 #endif
932 #ifdef PIPEX
933 if (n & (1 << NETISR_PIPEX))
934 pipexintr();
935 #endif
936 #if NPPPOE > 0
937 if (n & (1 << NETISR_PPPOE)) {
938 KERNEL_LOCK();
939 pppoeintr();
940 KERNEL_UNLOCK();
941 }
942 #endif
943 t |= n;
944 }
945
946 #if NPFSYNC > 0
947 if (t & (1 << NETISR_PFSYNC)) {
948 KERNEL_LOCK();
949 pfsyncintr();
950 KERNEL_UNLOCK();
951 }
952 #endif
953
954 NET_UNLOCK();
955 }
956
957 void
958 if_hooks_run(struct task_list *hooks)
959 {
960 struct task *t, *nt;
961 struct task cursor = { .t_func = NULL };
962 void (*func)(void *);
963 void *arg;
964
965 mtx_enter(&if_hooks_mtx);
966 for (t = TAILQ_FIRST(hooks); t != NULL; t = nt) {
967 if (t->t_func == NULL) { /* skip cursors */
968 nt = TAILQ_NEXT(t, t_entry);
969 continue;
970 }
971 func = t->t_func;
972 arg = t->t_arg;
973
974 TAILQ_INSERT_AFTER(hooks, t, &cursor, t_entry);
975 mtx_leave(&if_hooks_mtx);
976
977 (*func)(arg);
978
979 mtx_enter(&if_hooks_mtx);
980 nt = TAILQ_NEXT(&cursor, t_entry); /* avoid _Q_INVALIDATE */
981 TAILQ_REMOVE(hooks, &cursor, t_entry);
982 }
983 mtx_leave(&if_hooks_mtx);
984 }
985
986 void
987 if_remove(struct ifnet *ifp)
988 {
989 /* Remove the interface from the list of all interfaces. */
990 NET_LOCK();
991 TAILQ_REMOVE(&ifnetlist, ifp, if_list);
992 NET_UNLOCK();
993
994 /* Remove the interface from the interface index map. */
995 if_idxmap_remove(ifp);
996
997 /* Sleep until the last reference is released. */
998 refcnt_finalize(&ifp->if_refcnt, "ifrm");
999 }
1000
1001 void
1002 if_deactivate(struct ifnet *ifp)
1003 {
1004 /*
1005 * Call detach hooks from head to tail. To make sure detach
1006 * hooks are executed in the reverse order they were added, all
1007 * the hooks have to be added to the head!
1008 */
1009
1010 NET_LOCK();
1011 if_hooks_run(&ifp->if_detachhooks);
1012 NET_UNLOCK();
1013 }
1014
1015 void
1016 if_detachhook_add(struct ifnet *ifp, struct task *t)
1017 {
1018 mtx_enter(&if_hooks_mtx);
1019 TAILQ_INSERT_HEAD(&ifp->if_detachhooks, t, t_entry);
1020 mtx_leave(&if_hooks_mtx);
1021 }
1022
1023 void
1024 if_detachhook_del(struct ifnet *ifp, struct task *t)
1025 {
1026 mtx_enter(&if_hooks_mtx);
1027 TAILQ_REMOVE(&ifp->if_detachhooks, t, t_entry);
1028 mtx_leave(&if_hooks_mtx);
1029 }
1030
1031 /*
1032 * Detach an interface from everything in the kernel. Also deallocate
1033 * private resources.
1034 */
1035 void
1036 if_detach(struct ifnet *ifp)
1037 {
1038 struct ifaddr *ifa;
1039 struct ifg_list *ifg;
1040 int i, s;
1041
1042 /* Undo pseudo-driver changes. */
1043 if_deactivate(ifp);
1044
1045 /* Other CPUs must not have a reference before we start destroying. */
1046 if_remove(ifp);
1047
1048 ifp->if_qstart = if_detached_qstart;
1049
1050 /* Wait until the start routines finished. */
1051 ifq_barrier(&ifp->if_snd);
1052 ifq_clr_oactive(&ifp->if_snd);
1053
1054 #if NBPFILTER > 0
1055 bpfdetach(ifp);
1056 #endif
1057
1058 NET_LOCK();
1059 s = splnet();
1060 ifp->if_ioctl = if_detached_ioctl;
1061 ifp->if_watchdog = NULL;
1062
1063 /* Remove the watchdog timeout & task */
1064 timeout_del(&ifp->if_slowtimo);
1065 task_del(net_tq(ifp->if_index), &ifp->if_watchdogtask);
1066
1067 /* Remove the link state task */
1068 task_del(net_tq(ifp->if_index), &ifp->if_linkstatetask);
1069
1070 rti_delete(ifp);
1071 #if NETHER > 0 && defined(NFSCLIENT)
1072 if (ifp->if_index == revarp_ifidx)
1073 revarp_ifidx = 0;
1074 #endif
1075 #ifdef MROUTING
1076 vif_delete(ifp);
1077 #endif
1078 in_ifdetach(ifp);
1079 #ifdef INET6
1080 in6_ifdetach(ifp);
1081 #endif
1082 #if NPF > 0
1083 pfi_detach_ifnet(ifp);
1084 #endif
1085
1086 while ((ifg = TAILQ_FIRST(&ifp->if_groups)) != NULL)
1087 if_delgroup(ifp, ifg->ifgl_group->ifg_group);
1088
1089 if_free_sadl(ifp);
1090
1091 /* We should not have any address left at this point. */
1092 if (!TAILQ_EMPTY(&ifp->if_addrlist)) {
1093 #ifdef DIAGNOSTIC
1094 printf("%s: address list non empty\n", ifp->if_xname);
1095 #endif
1096 while ((ifa = TAILQ_FIRST(&ifp->if_addrlist)) != NULL) {
1097 ifa_del(ifp, ifa);
1098 ifa->ifa_ifp = NULL;
1099 ifafree(ifa);
1100 }
1101 }
1102
1103 KASSERT(TAILQ_EMPTY(&ifp->if_addrhooks));
1104 KASSERT(TAILQ_EMPTY(&ifp->if_linkstatehooks));
1105 KASSERT(TAILQ_EMPTY(&ifp->if_detachhooks));
1106
1107 #ifdef INET6
1108 nd6_ifdetach(ifp);
1109 #endif
1110
1111 /* Announce that the interface is gone. */
1112 rtm_ifannounce(ifp, IFAN_DEPARTURE);
1113 splx(s);
1114 NET_UNLOCK();
1115
1116 if (ifp->if_counters != NULL)
1117 if_counters_free(ifp);
1118
1119 for (i = 0; i < ifp->if_nifqs; i++)
1120 ifq_destroy(ifp->if_ifqs[i]);
1121 if (ifp->if_ifqs != ifp->if_snd.ifq_ifqs) {
1122 for (i = 1; i < ifp->if_nifqs; i++) {
1123 free(ifp->if_ifqs[i], M_DEVBUF,
1124 sizeof(struct ifqueue));
1125 }
1126 free(ifp->if_ifqs, M_DEVBUF,
1127 sizeof(struct ifqueue *) * ifp->if_nifqs);
1128 }
1129
1130 for (i = 0; i < ifp->if_niqs; i++)
1131 ifiq_destroy(ifp->if_iqs[i]);
1132 if (ifp->if_iqs != ifp->if_rcv.ifiq_ifiqs) {
1133 for (i = 1; i < ifp->if_niqs; i++) {
1134 free(ifp->if_iqs[i], M_DEVBUF,
1135 sizeof(struct ifiqueue));
1136 }
1137 free(ifp->if_iqs, M_DEVBUF,
1138 sizeof(struct ifiqueue *) * ifp->if_niqs);
1139 }
1140 }
1141
1142 /*
1143 * Returns true if ``ifp0'' is connected to the interface with index ``ifidx''.
1144 */
1145 int
1146 if_isconnected(const struct ifnet *ifp0, unsigned int ifidx)
1147 {
1148 struct ifnet *ifp;
1149 int connected = 0;
1150
1151 ifp = if_get(ifidx);
1152 if (ifp == NULL)
1153 return (0);
1154
1155 if (ifp0->if_index == ifp->if_index)
1156 connected = 1;
1157
1158 #if NBRIDGE > 0
1159 if (ifp0->if_bridgeidx != 0 && ifp0->if_bridgeidx == ifp->if_bridgeidx)
1160 connected = 1;
1161 #endif
1162 #if NCARP > 0
1163 if ((ifp0->if_type == IFT_CARP &&
1164 ifp0->if_carpdevidx == ifp->if_index) ||
1165 (ifp->if_type == IFT_CARP && ifp->if_carpdevidx == ifp0->if_index))
1166 connected = 1;
1167 #endif
1168
1169 if_put(ifp);
1170 return (connected);
1171 }
1172
1173 /*
1174 * Create a clone network interface.
1175 */
1176 int
1177 if_clone_create(const char *name, int rdomain)
1178 {
1179 struct if_clone *ifc;
1180 struct ifnet *ifp;
1181 int unit, ret;
1182
1183 ifc = if_clone_lookup(name, &unit);
1184 if (ifc == NULL)
1185 return (EINVAL);
1186
1187 rw_enter_write(&if_cloners_lock);
1188
1189 if ((ifp = if_unit(name)) != NULL) {
1190 ret = EEXIST;
1191 goto unlock;
1192 }
1193
1194 ret = (*ifc->ifc_create)(ifc, unit);
1195
1196 if (ret != 0 || (ifp = if_unit(name)) == NULL)
1197 goto unlock;
1198
1199 NET_LOCK();
1200 if_addgroup(ifp, ifc->ifc_name);
1201 if (rdomain != 0)
1202 if_setrdomain(ifp, rdomain);
1203 NET_UNLOCK();
1204 unlock:
1205 rw_exit_write(&if_cloners_lock);
1206 if_put(ifp);
1207
1208 return (ret);
1209 }
1210
1211 /*
1212 * Destroy a clone network interface.
1213 */
1214 int
1215 if_clone_destroy(const char *name)
1216 {
1217 struct if_clone *ifc;
1218 struct ifnet *ifp;
1219 int ret;
1220
1221 ifc = if_clone_lookup(name, NULL);
1222 if (ifc == NULL)
1223 return (EINVAL);
1224
1225 if (ifc->ifc_destroy == NULL)
1226 return (EOPNOTSUPP);
1227
1228 rw_enter_write(&if_cloners_lock);
1229
1230 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
1231 if (strcmp(ifp->if_xname, name) == 0)
1232 break;
1233 }
1234 if (ifp == NULL) {
1235 rw_exit_write(&if_cloners_lock);
1236 return (ENXIO);
1237 }
1238
1239 NET_LOCK();
1240 if (ifp->if_flags & IFF_UP) {
1241 int s;
1242 s = splnet();
1243 if_down(ifp);
1244 splx(s);
1245 }
1246 NET_UNLOCK();
1247 ret = (*ifc->ifc_destroy)(ifp);
1248
1249 rw_exit_write(&if_cloners_lock);
1250
1251 return (ret);
1252 }
1253
1254 /*
1255 * Look up a network interface cloner.
1256 */
1257 struct if_clone *
1258 if_clone_lookup(const char *name, int *unitp)
1259 {
1260 struct if_clone *ifc;
1261 const char *cp;
1262 int unit;
1263
1264 /* separate interface name from unit */
1265 for (cp = name;
1266 cp - name < IFNAMSIZ && *cp && (*cp < '' || *cp > '9');
1267 cp++)
1268 continue;
1269
1270 if (cp == name || cp - name == IFNAMSIZ || !*cp)
1271 return (NULL); /* No name or unit number */
1272
1273 if (cp - name < IFNAMSIZ-1 && *cp == '' && cp[1] != '\0')
1274 return (NULL); /* unit number 0 padded */
1275
1276 LIST_FOREACH(ifc, &if_cloners, ifc_list) {
1277 if (strlen(ifc->ifc_name) == cp - name &&
1278 !strncmp(name, ifc->ifc_name, cp - name))
1279 break;
1280 }
1281
1282 if (ifc == NULL)
1283 return (NULL);
1284
1285 unit = 0;
1286 while (cp - name < IFNAMSIZ && *cp) {
1287 if (*cp < '' || *cp > '9' ||
1288 unit > (INT_MAX - (*cp - '')) / 10) {
1289 /* Bogus unit number. */
1290 return (NULL);
1291 }
1292 unit = (unit * 10) + (*cp++ - '');
1293 }
1294
1295 if (unitp != NULL)
1296 *unitp = unit;
1297 return (ifc);
1298 }
1299
1300 /*
1301 * Register a network interface cloner.
1302 */
1303 void
1304 if_clone_attach(struct if_clone *ifc)
1305 {
1306 /*
1307 * we are called at kernel boot by main(), when pseudo devices are
1308 * being attached. The main() is the only guy which may alter the
1309 * if_cloners. While system is running and main() is done with
1310 * initialization, the if_cloners becomes immutable.
1311 */
1312 KASSERT(pdevinit_done == 0);
1313 LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list);
1314 if_cloners_count++;
1315 }
1316
1317 /*
1318 * Provide list of interface cloners to userspace.
1319 */
1320 int
1321 if_clone_list(struct if_clonereq *ifcr)
1322 {
1323 char outbuf[IFNAMSIZ], *dst;
1324 struct if_clone *ifc;
1325 int count, error = 0;
1326
1327 if ((dst = ifcr->ifcr_buffer) == NULL) {
1328 /* Just asking how many there are. */
1329 ifcr->ifcr_total = if_cloners_count;
1330 return (0);
1331 }
1332
1333 if (ifcr->ifcr_count < 0)
1334 return (EINVAL);
1335
1336 ifcr->ifcr_total = if_cloners_count;
1337 count = MIN(if_cloners_count, ifcr->ifcr_count);
1338
1339 LIST_FOREACH(ifc, &if_cloners, ifc_list) {
1340 if (count == 0)
1341 break;
1342 bzero(outbuf, sizeof outbuf);
1343 strlcpy(outbuf, ifc->ifc_name, IFNAMSIZ);
1344 error = copyout(outbuf, dst, IFNAMSIZ);
1345 if (error)
1346 break;
1347 count--;
1348 dst += IFNAMSIZ;
1349 }
1350
1351 return (error);
1352 }
1353
1354 /*
1355 * set queue congestion marker
1356 */
1357 void
1358 if_congestion(void)
1359 {
1360 extern int ticks;
1361
1362 ifq_congestion = ticks;
1363 }
1364
1365 int
1366 if_congested(void)
1367 {
1368 extern int ticks;
1369 int diff;
1370
1371 diff = ticks - ifq_congestion;
1372 if (diff < 0) {
1373 ifq_congestion = ticks - hz;
1374 return (0);
1375 }
1376
1377 return (diff <= (hz / 100));
1378 }
1379
1380 #define equal(a1, a2) \
1381 (bcmp((caddr_t)(a1), (caddr_t)(a2), \
1382 (a1)->sa_len) == 0)
1383
1384 /*
1385 * Locate an interface based on a complete address.
1386 */
1387 struct ifaddr *
1388 ifa_ifwithaddr(struct sockaddr *addr, u_int rtableid)
1389 {
1390 struct ifnet *ifp;
1391 struct ifaddr *ifa;
1392 u_int rdomain;
1393
1394 rdomain = rtable_l2(rtableid);
1395 KERNEL_LOCK();
1396 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
1397 if (ifp->if_rdomain != rdomain)
1398 continue;
1399
1400 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1401 if (ifa->ifa_addr->sa_family != addr->sa_family)
1402 continue;
1403
1404 if (equal(addr, ifa->ifa_addr)) {
1405 KERNEL_UNLOCK();
1406 return (ifa);
1407 }
1408 }
1409 }
1410 KERNEL_UNLOCK();
1411 return (NULL);
1412 }
1413
1414 /*
1415 * Locate the point to point interface with a given destination address.
1416 */
1417 struct ifaddr *
1418 ifa_ifwithdstaddr(struct sockaddr *addr, u_int rdomain)
1419 {
1420 struct ifnet *ifp;
1421 struct ifaddr *ifa;
1422
1423 rdomain = rtable_l2(rdomain);
1424 KERNEL_LOCK();
1425 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
1426 if (ifp->if_rdomain != rdomain)
1427 continue;
1428 if (ifp->if_flags & IFF_POINTOPOINT) {
1429 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1430 if (ifa->ifa_addr->sa_family !=
1431 addr->sa_family || ifa->ifa_dstaddr == NULL)
1432 continue;
1433 if (equal(addr, ifa->ifa_dstaddr)) {
1434 KERNEL_UNLOCK();
1435 return (ifa);
1436 }
1437 }
1438 }
1439 }
1440 KERNEL_UNLOCK();
1441 return (NULL);
1442 }
1443
1444 /*
1445 * Find an interface address specific to an interface best matching
1446 * a given address.
1447 */
1448 struct ifaddr *
1449 ifaof_ifpforaddr(struct sockaddr *addr, struct ifnet *ifp)
1450 {
1451 struct ifaddr *ifa;
1452 char *cp, *cp2, *cp3;
1453 char *cplim;
1454 struct ifaddr *ifa_maybe = NULL;
1455 u_int af = addr->sa_family;
1456
1457 if (af >= AF_MAX)
1458 return (NULL);
1459 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1460 if (ifa->ifa_addr->sa_family != af)
1461 continue;
1462 if (ifa_maybe == NULL)
1463 ifa_maybe = ifa;
1464 if (ifa->ifa_netmask == 0 || ifp->if_flags & IFF_POINTOPOINT) {
1465 if (equal(addr, ifa->ifa_addr) ||
1466 (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
1467 return (ifa);
1468 continue;
1469 }
1470 cp = addr->sa_data;
1471 cp2 = ifa->ifa_addr->sa_data;
1472 cp3 = ifa->ifa_netmask->sa_data;
1473 cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
1474 for (; cp3 < cplim; cp3++)
1475 if ((*cp++ ^ *cp2++) & *cp3)
1476 break;
1477 if (cp3 == cplim)
1478 return (ifa);
1479 }
1480 return (ifa_maybe);
1481 }
1482
1483 void
1484 if_rtrequest_dummy(struct ifnet *ifp, int req, struct rtentry *rt)
1485 {
1486 }
1487
1488 /*
1489 * Default action when installing a local route on a point-to-point
1490 * interface.
1491 */
1492 void
1493 p2p_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
1494 {
1495 struct ifnet *lo0ifp;
1496 struct ifaddr *ifa, *lo0ifa;
1497
1498 switch (req) {
1499 case RTM_ADD:
1500 if (!ISSET(rt->rt_flags, RTF_LOCAL))
1501 break;
1502
1503 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1504 if (memcmp(rt_key(rt), ifa->ifa_addr,
1505 rt_key(rt)->sa_len) == 0)
1506 break;
1507 }
1508
1509 if (ifa == NULL)
1510 break;
1511
1512 KASSERT(ifa == rt->rt_ifa);
1513
1514 lo0ifp = if_get(rtable_loindex(ifp->if_rdomain));
1515 KASSERT(lo0ifp != NULL);
1516 TAILQ_FOREACH(lo0ifa, &lo0ifp->if_addrlist, ifa_list) {
1517 if (lo0ifa->ifa_addr->sa_family ==
1518 ifa->ifa_addr->sa_family)
1519 break;
1520 }
1521 if_put(lo0ifp);
1522
1523 if (lo0ifa == NULL)
1524 break;
1525
1526 rt->rt_flags &= ~RTF_LLINFO;
1527 break;
1528 case RTM_DELETE:
1529 case RTM_RESOLVE:
1530 default:
1531 break;
1532 }
1533 }
1534
1535 int
1536 p2p_bpf_mtap(caddr_t if_bpf, const struct mbuf *m, u_int dir)
1537 {
1538 #if NBPFILTER > 0
1539 return (bpf_mtap_af(if_bpf, m->m_pkthdr.ph_family, m, dir));
1540 #else
1541 return (0);
1542 #endif
1543 }
1544
1545 void
1546 p2p_input(struct ifnet *ifp, struct mbuf *m)
1547 {
1548 void (*input)(struct ifnet *, struct mbuf *);
1549
1550 switch (m->m_pkthdr.ph_family) {
1551 case AF_INET:
1552 input = ipv4_input;
1553 break;
1554 #ifdef INET6
1555 case AF_INET6:
1556 input = ipv6_input;
1557 break;
1558 #endif
1559 #ifdef MPLS
1560 case AF_MPLS:
1561 input = mpls_input;
1562 break;
1563 #endif
1564 default:
1565 m_freem(m);
1566 return;
1567 }
1568
1569 (*input)(ifp, m);
1570 }
1571
1572 /*
1573 * Bring down all interfaces
1574 */
1575 void
1576 if_downall(void)
1577 {
1578 struct ifreq ifrq; /* XXX only partly built */
1579 struct ifnet *ifp;
1580
1581 NET_LOCK();
1582 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
1583 if ((ifp->if_flags & IFF_UP) == 0)
1584 continue;
1585 if_down(ifp);
1586 ifrq.ifr_flags = ifp->if_flags;
1587 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
1588 }
1589 NET_UNLOCK();
1590 }
1591
1592 /*
1593 * Mark an interface down and notify protocols of
1594 * the transition.
1595 */
1596 void
1597 if_down(struct ifnet *ifp)
1598 {
1599 NET_ASSERT_LOCKED();
1600
1601 ifp->if_flags &= ~IFF_UP;
1602 getmicrotime(&ifp->if_lastchange);
1603 ifq_purge(&ifp->if_snd);
1604
1605 if_linkstate(ifp);
1606 }
1607
1608 /*
1609 * Mark an interface up and notify protocols of
1610 * the transition.
1611 */
1612 void
1613 if_up(struct ifnet *ifp)
1614 {
1615 NET_ASSERT_LOCKED();
1616
1617 ifp->if_flags |= IFF_UP;
1618 getmicrotime(&ifp->if_lastchange);
1619
1620 #ifdef INET6
1621 /* Userland expects the kernel to set ::1 on default lo(4). */
1622 if (ifp->if_index == rtable_loindex(ifp->if_rdomain))
1623 in6_ifattach(ifp);
1624 #endif
1625
1626 if_linkstate(ifp);
1627 }
1628
1629 /*
1630 * Notify userland, the routing table and hooks owner of
1631 * a link-state transition.
1632 */
1633 void
1634 if_linkstate_task(void *xifidx)
1635 {
1636 unsigned int ifidx = (unsigned long)xifidx;
1637 struct ifnet *ifp;
1638
1639 KERNEL_LOCK();
1640 NET_LOCK();
1641
1642 ifp = if_get(ifidx);
1643 if (ifp != NULL)
1644 if_linkstate(ifp);
1645 if_put(ifp);
1646
1647 NET_UNLOCK();
1648 KERNEL_UNLOCK();
1649 }
1650
1651 void
1652 if_linkstate(struct ifnet *ifp)
1653 {
1654 NET_ASSERT_LOCKED();
1655
1656 rtm_ifchg(ifp);
1657 rt_if_track(ifp);
1658
1659 if_hooks_run(&ifp->if_linkstatehooks);
1660 }
1661
1662 void
1663 if_linkstatehook_add(struct ifnet *ifp, struct task *t)
1664 {
1665 mtx_enter(&if_hooks_mtx);
1666 TAILQ_INSERT_HEAD(&ifp->if_linkstatehooks, t, t_entry);
1667 mtx_leave(&if_hooks_mtx);
1668 }
1669
1670 void
1671 if_linkstatehook_del(struct ifnet *ifp, struct task *t)
1672 {
1673 mtx_enter(&if_hooks_mtx);
1674 TAILQ_REMOVE(&ifp->if_linkstatehooks, t, t_entry);
1675 mtx_leave(&if_hooks_mtx);
1676 }
1677
1678 /*
1679 * Schedule a link state change task.
1680 */
1681 void
1682 if_link_state_change(struct ifnet *ifp)
1683 {
1684 task_add(net_tq(ifp->if_index), &ifp->if_linkstatetask);
1685 }
1686
1687 /*
1688 * Handle interface watchdog timer routine. Called
1689 * from softclock, we decrement timer (if set) and
1690 * call the appropriate interface routine on expiration.
1691 */
1692 void
1693 if_slowtimo(void *arg)
1694 {
1695 struct ifnet *ifp = arg;
1696 int s = splnet();
1697
1698 if (ifp->if_watchdog) {
1699 if (ifp->if_timer > 0 && --ifp->if_timer == 0)
1700 task_add(net_tq(ifp->if_index), &ifp->if_watchdogtask);
1701 timeout_add_sec(&ifp->if_slowtimo, IFNET_SLOWTIMO);
1702 }
1703 splx(s);
1704 }
1705
1706 void
1707 if_watchdog_task(void *xifidx)
1708 {
1709 unsigned int ifidx = (unsigned long)xifidx;
1710 struct ifnet *ifp;
1711 int s;
1712
1713 ifp = if_get(ifidx);
1714 if (ifp == NULL)
1715 return;
1716
1717 KERNEL_LOCK();
1718 s = splnet();
1719 if (ifp->if_watchdog)
1720 (*ifp->if_watchdog)(ifp);
1721 splx(s);
1722 KERNEL_UNLOCK();
1723
1724 if_put(ifp);
1725 }
1726
1727 /*
1728 * Map interface name to interface structure pointer.
1729 */
1730 struct ifnet *
1731 if_unit(const char *name)
1732 {
1733 struct ifnet *ifp;
1734
1735 KERNEL_ASSERT_LOCKED();
1736
1737 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
1738 if (strcmp(ifp->if_xname, name) == 0) {
1739 if_ref(ifp);
1740 return (ifp);
1741 }
1742 }
1743
1744 return (NULL);
1745 }
1746
1747 /*
1748 * Map interface index to interface structure pointer.
1749 */
1750 struct ifnet *
1751 if_get(unsigned int index)
1752 {
1753 struct ifnet **if_map;
1754 struct ifnet *ifp = NULL;
1755
1756 if (index == 0)
1757 return (NULL);
1758
1759 smr_read_enter();
1760 if_map = SMR_PTR_GET(&if_idxmap.map);
1761 if (index < if_idxmap_limit(if_map)) {
1762 ifp = SMR_PTR_GET(&if_map[index]);
1763 if (ifp != NULL) {
1764 KASSERT(ifp->if_index == index);
1765 if_ref(ifp);
1766 }
1767 }
1768 smr_read_leave();
1769
1770 return (ifp);
1771 }
1772
1773 struct ifnet *
1774 if_ref(struct ifnet *ifp)
1775 {
1776 refcnt_take(&ifp->if_refcnt);
1777
1778 return (ifp);
1779 }
1780
1781 void
1782 if_put(struct ifnet *ifp)
1783 {
1784 if (ifp == NULL)
1785 return;
1786
1787 refcnt_rele_wake(&ifp->if_refcnt);
1788 }
1789
1790 int
1791 if_setlladdr(struct ifnet *ifp, const uint8_t *lladdr)
1792 {
1793 if (ifp->if_sadl == NULL)
1794 return (EINVAL);
1795
1796 memcpy(((struct arpcom *)ifp)->ac_enaddr, lladdr, ETHER_ADDR_LEN);
1797 memcpy(LLADDR(ifp->if_sadl), lladdr, ETHER_ADDR_LEN);
1798
1799 return (0);
1800 }
1801
1802 int
1803 if_createrdomain(int rdomain, struct ifnet *ifp)
1804 {
1805 int error;
1806 struct ifnet *loifp;
1807 char loifname[IFNAMSIZ];
1808 unsigned int unit = rdomain;
1809
1810 if ((error = rtable_add(rdomain)) != 0)
1811 return (error);
1812 if (!rtable_empty(rdomain))
1813 return (EEXIST);
1814
1815 /* Create rdomain including its loopback if with unit == rdomain */
1816 snprintf(loifname, sizeof(loifname), "lo%u", unit);
1817 error = if_clone_create(loifname, 0);
1818 if ((loifp = if_unit(loifname)) == NULL)
1819 return (ENXIO);
1820 if (error && (ifp != loifp || error != EEXIST)) {
1821 if_put(loifp);
1822 return (error);
1823 }
1824
1825 rtable_l2set(rdomain, rdomain, loifp->if_index);
1826 loifp->if_rdomain = rdomain;
1827 if_put(loifp);
1828
1829 return (0);
1830 }
1831
1832 int
1833 if_setrdomain(struct ifnet *ifp, int rdomain)
1834 {
1835 struct ifreq ifr;
1836 int error, up = 0, s;
1837
1838 if (rdomain < 0 || rdomain > RT_TABLEID_MAX)
1839 return (EINVAL);
1840
1841 if (rdomain != ifp->if_rdomain &&
1842 (ifp->if_flags & IFF_LOOPBACK) &&
1843 (ifp->if_index == rtable_loindex(ifp->if_rdomain)))
1844 return (EPERM);
1845
1846 if (!rtable_exists(rdomain))
1847 return (ESRCH);
1848
1849 /* make sure that the routing table is a real rdomain */
1850 if (rdomain != rtable_l2(rdomain))
1851 return (EINVAL);
1852
1853 if (rdomain != ifp->if_rdomain) {
1854 s = splnet();
1855 /*
1856 * We are tearing down the world.
1857 * Take down the IF so:
1858 * 1. everything that cares gets a message
1859 * 2. the automagic IPv6 bits are recreated
1860 */
1861 if (ifp->if_flags & IFF_UP) {
1862 up = 1;
1863 if_down(ifp);
1864 }
1865 rti_delete(ifp);
1866 #ifdef MROUTING
1867 vif_delete(ifp);
1868 #endif
1869 in_ifdetach(ifp);
1870 #ifdef INET6
1871 in6_ifdetach(ifp);
1872 #endif
1873 splx(s);
1874 }
1875
1876 /* Let devices like enc(4) or mpe(4) know about the change */
1877 ifr.ifr_rdomainid = rdomain;
1878 if ((error = (*ifp->if_ioctl)(ifp, SIOCSIFRDOMAIN,
1879 (caddr_t)&ifr)) != ENOTTY)
1880 return (error);
1881 error = 0;
1882
1883 /* Add interface to the specified rdomain */
1884 ifp->if_rdomain = rdomain;
1885
1886 /* If we took down the IF, bring it back */
1887 if (up) {
1888 s = splnet();
1889 if_up(ifp);
1890 splx(s);
1891 }
1892
1893 return (0);
1894 }
1895
1896 /*
1897 * Interface ioctls.
1898 */
1899 int
1900 ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
1901 {
1902 struct ifnet *ifp;
1903 struct ifreq *ifr = (struct ifreq *)data;
1904 struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
1905 struct if_afreq *ifar = (struct if_afreq *)data;
1906 char ifdescrbuf[IFDESCRSIZE];
1907 char ifrtlabelbuf[RTLABEL_LEN];
1908 int s, error = 0, oif_xflags;
1909 size_t bytesdone;
1910 unsigned short oif_flags;
1911
1912 switch (cmd) {
1913 case SIOCIFCREATE:
1914 if ((error = suser(p)) != 0)
1915 return (error);
1916 KERNEL_LOCK();
1917 error = if_clone_create(ifr->ifr_name, 0);
1918 KERNEL_UNLOCK();
1919 return (error);
1920 case SIOCIFDESTROY:
1921 if ((error = suser(p)) != 0)
1922 return (error);
1923 KERNEL_LOCK();
1924 error = if_clone_destroy(ifr->ifr_name);
1925 KERNEL_UNLOCK();
1926 return (error);
1927 case SIOCSIFGATTR:
1928 if ((error = suser(p)) != 0)
1929 return (error);
1930 KERNEL_LOCK();
1931 NET_LOCK();
1932 error = if_setgroupattribs(data);
1933 NET_UNLOCK();
1934 KERNEL_UNLOCK();
1935 return (error);
1936 case SIOCGIFCONF:
1937 case SIOCIFGCLONERS:
1938 case SIOCGIFGMEMB:
1939 case SIOCGIFGATTR:
1940 case SIOCGIFGLIST:
1941 case SIOCGIFFLAGS:
1942 case SIOCGIFXFLAGS:
1943 case SIOCGIFMETRIC:
1944 case SIOCGIFMTU:
1945 case SIOCGIFHARDMTU:
1946 case SIOCGIFDATA:
1947 case SIOCGIFDESCR:
1948 case SIOCGIFRTLABEL:
1949 case SIOCGIFPRIORITY:
1950 case SIOCGIFRDOMAIN:
1951 case SIOCGIFGROUP:
1952 case SIOCGIFLLPRIO:
1953 error = ifioctl_get(cmd, data);
1954 return (error);
1955 }
1956
1957 KERNEL_LOCK();
1958
1959 ifp = if_unit(ifr->ifr_name);
1960 if (ifp == NULL) {
1961 KERNEL_UNLOCK();
1962 return (ENXIO);
1963 }
1964 oif_flags = ifp->if_flags;
1965 oif_xflags = ifp->if_xflags;
1966
1967 switch (cmd) {
1968 case SIOCIFAFATTACH:
1969 case SIOCIFAFDETACH:
1970 if ((error = suser(p)) != 0)
1971 break;
1972 NET_LOCK();
1973 switch (ifar->ifar_af) {
1974 case AF_INET:
1975 /* attach is a noop for AF_INET */
1976 if (cmd == SIOCIFAFDETACH)
1977 in_ifdetach(ifp);
1978 break;
1979 #ifdef INET6
1980 case AF_INET6:
1981 if (cmd == SIOCIFAFATTACH)
1982 error = in6_ifattach(ifp);
1983 else
1984 in6_ifdetach(ifp);
1985 break;
1986 #endif /* INET6 */
1987 default:
1988 error = EAFNOSUPPORT;
1989 }
1990 NET_UNLOCK();
1991 break;
1992
1993 case SIOCSIFXFLAGS:
1994 if ((error = suser(p)) != 0)
1995 break;
1996
1997 NET_LOCK();
1998 #ifdef INET6
1999 if ((ISSET(ifr->ifr_flags, IFXF_AUTOCONF6) ||
2000 ISSET(ifr->ifr_flags, IFXF_AUTOCONF6TEMP)) &&
2001 !ISSET(ifp->if_xflags, IFXF_AUTOCONF6) &&
2002 !ISSET(ifp->if_xflags, IFXF_AUTOCONF6TEMP)) {
2003 error = in6_ifattach(ifp);
2004 if (error != 0) {
2005 NET_UNLOCK();
2006 break;
2007 }
2008 }
2009
2010 if (ISSET(ifr->ifr_flags, IFXF_INET6_NOSOII) &&
2011 !ISSET(ifp->if_xflags, IFXF_INET6_NOSOII))
2012 ifp->if_xflags |= IFXF_INET6_NOSOII;
2013
2014 if (!ISSET(ifr->ifr_flags, IFXF_INET6_NOSOII) &&
2015 ISSET(ifp->if_xflags, IFXF_INET6_NOSOII))
2016 ifp->if_xflags &= ~IFXF_INET6_NOSOII;
2017
2018 #endif /* INET6 */
2019
2020 #ifdef MPLS
2021 if (ISSET(ifr->ifr_flags, IFXF_MPLS) &&
2022 !ISSET(ifp->if_xflags, IFXF_MPLS)) {
2023 s = splnet();
2024 ifp->if_xflags |= IFXF_MPLS;
2025 ifp->if_ll_output = ifp->if_output;
2026 ifp->if_output = mpls_output;
2027 splx(s);
2028 }
2029 if (ISSET(ifp->if_xflags, IFXF_MPLS) &&
2030 !ISSET(ifr->ifr_flags, IFXF_MPLS)) {
2031 s = splnet();
2032 ifp->if_xflags &= ~IFXF_MPLS;
2033 ifp->if_output = ifp->if_ll_output;
2034 ifp->if_ll_output = NULL;
2035 splx(s);
2036 }
2037 #endif /* MPLS */
2038
2039 #ifndef SMALL_KERNEL
2040 if (ifp->if_capabilities & IFCAP_WOL) {
2041 if (ISSET(ifr->ifr_flags, IFXF_WOL) &&
2042 !ISSET(ifp->if_xflags, IFXF_WOL)) {
2043 s = splnet();
2044 ifp->if_xflags |= IFXF_WOL;
2045 error = ifp->if_wol(ifp, 1);
2046 splx(s);
2047 }
2048 if (ISSET(ifp->if_xflags, IFXF_WOL) &&
2049 !ISSET(ifr->ifr_flags, IFXF_WOL)) {
2050 s = splnet();
2051 ifp->if_xflags &= ~IFXF_WOL;
2052 error = ifp->if_wol(ifp, 0);
2053 splx(s);
2054 }
2055 } else if (ISSET(ifr->ifr_flags, IFXF_WOL)) {
2056 ifr->ifr_flags &= ~IFXF_WOL;
2057 error = ENOTSUP;
2058 }
2059
2060 if (ISSET(ifp->if_capabilities, IFCAP_TSO) &&
2061 ISSET(ifr->ifr_flags, IFXF_TSO) !=
2062 ISSET(ifp->if_xflags, IFXF_TSO)) {
2063 struct ifreq ifrq;
2064
2065 s = splnet();
2066
2067 if (ISSET(ifr->ifr_flags, IFXF_TSO))
2068 ifp->if_xflags |= IFXF_TSO;
2069 else
2070 ifp->if_xflags &= ~IFXF_TSO;
2071
2072 NET_ASSERT_LOCKED(); /* for ioctl */
2073 KERNEL_ASSERT_LOCKED(); /* for if_flags */
2074
2075 if (ISSET(ifp->if_flags, IFF_UP)) {
2076 /* go down for a moment... */
2077 ifp->if_flags &= ~IFF_UP;
2078 ifrq.ifr_flags = ifp->if_flags;
2079 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
2080 (caddr_t)&ifrq);
2081
2082 /* ... and up again */
2083 ifp->if_flags |= IFF_UP;
2084 ifrq.ifr_flags = ifp->if_flags;
2085 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS,
2086 (caddr_t)&ifrq);
2087 }
2088
2089 splx(s);
2090 } else if (!ISSET(ifp->if_capabilities, IFCAP_TSO) &&
2091 ISSET(ifr->ifr_flags, IFXF_TSO)) {
2092 ifr->ifr_flags &= ~IFXF_TSO;
2093 error = ENOTSUP;
2094 }
2095 #endif
2096
2097 if (error == 0)
2098 ifp->if_xflags = (ifp->if_xflags & IFXF_CANTCHANGE) |
2099 (ifr->ifr_flags & ~IFXF_CANTCHANGE);
2100
2101 if (!ISSET(ifp->if_flags, IFF_UP) &&
2102 ((!ISSET(oif_xflags, IFXF_AUTOCONF4) &&
2103 ISSET(ifp->if_xflags, IFXF_AUTOCONF4)) ||
2104 (!ISSET(oif_xflags, IFXF_AUTOCONF6) &&
2105 ISSET(ifp->if_xflags, IFXF_AUTOCONF6)) ||
2106 (!ISSET(oif_xflags, IFXF_AUTOCONF6TEMP) &&
2107 ISSET(ifp->if_xflags, IFXF_AUTOCONF6TEMP)))) {
2108 ifr->ifr_flags = ifp->if_flags | IFF_UP;
2109 goto forceup;
2110 }
2111
2112 NET_UNLOCK();
2113 break;
2114
2115 case SIOCSIFFLAGS:
2116 if ((error = suser(p)) != 0)
2117 break;
2118
2119 NET_LOCK();
2120 forceup:
2121 ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
2122 (ifr->ifr_flags & ~IFF_CANTCHANGE);
2123 error = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, data);
2124 if (error != 0) {
2125 ifp->if_flags = oif_flags;
2126 if (cmd == SIOCSIFXFLAGS)
2127 ifp->if_xflags = oif_xflags;
2128 } else if (ISSET(oif_flags ^ ifp->if_flags, IFF_UP)) {
2129 s = splnet();
2130 if (ISSET(ifp->if_flags, IFF_UP))
2131 if_up(ifp);
2132 else
2133 if_down(ifp);
2134 splx(s);
2135 }
2136 NET_UNLOCK();
2137 break;
2138
2139 case SIOCSIFMETRIC:
2140 if ((error = suser(p)) != 0)
2141 break;
2142 NET_LOCK();
2143 ifp->if_metric = ifr->ifr_metric;
2144 NET_UNLOCK();
2145 break;
2146
2147 case SIOCSIFMTU:
2148 if ((error = suser(p)) != 0)
2149 break;
2150 NET_LOCK();
2151 error = (*ifp->if_ioctl)(ifp, cmd, data);
2152 NET_UNLOCK();
2153 if (error == 0)
2154 rtm_ifchg(ifp);
2155 break;
2156
2157 case SIOCSIFDESCR:
2158 if ((error = suser(p)) != 0)
2159 break;
2160 error = copyinstr(ifr->ifr_data, ifdescrbuf,
2161 IFDESCRSIZE, &bytesdone);
2162 if (error == 0) {
2163 (void)memset(ifp->if_description, 0, IFDESCRSIZE);
2164 strlcpy(ifp->if_description, ifdescrbuf, IFDESCRSIZE);
2165 }
2166 break;
2167
2168 case SIOCSIFRTLABEL:
2169 if ((error = suser(p)) != 0)
2170 break;
2171 error = copyinstr(ifr->ifr_data, ifrtlabelbuf,
2172 RTLABEL_LEN, &bytesdone);
2173 if (error == 0) {
2174 rtlabel_unref(ifp->if_rtlabelid);
2175 ifp->if_rtlabelid = rtlabel_name2id(ifrtlabelbuf);
2176 }
2177 break;
2178
2179 case SIOCSIFPRIORITY:
2180 if ((error = suser(p)) != 0)
2181 break;
2182 if (ifr->ifr_metric < 0 || ifr->ifr_metric > 15) {
2183 error = EINVAL;
2184 break;
2185 }
2186 ifp->if_priority = ifr->ifr_metric;
2187 break;
2188
2189 case SIOCSIFRDOMAIN:
2190 if ((error = suser(p)) != 0)
2191 break;
2192 error = if_createrdomain(ifr->ifr_rdomainid, ifp);
2193 if (!error || error == EEXIST) {
2194 NET_LOCK();
2195 error = if_setrdomain(ifp, ifr->ifr_rdomainid);
2196 NET_UNLOCK();
2197 }
2198 break;
2199
2200 case SIOCAIFGROUP:
2201 if ((error = suser(p)))
2202 break;
2203 NET_LOCK();
2204 error = if_addgroup(ifp, ifgr->ifgr_group);
2205 if (error == 0) {
2206 error = (*ifp->if_ioctl)(ifp, cmd, data);
2207 if (error == ENOTTY)
2208 error = 0;
2209 }
2210 NET_UNLOCK();
2211 break;
2212
2213 case SIOCDIFGROUP:
2214 if ((error = suser(p)))
2215 break;
2216 NET_LOCK();
2217 error = (*ifp->if_ioctl)(ifp, cmd, data);
2218 if (error == ENOTTY)
2219 error = 0;
2220 if (error == 0)
2221 error = if_delgroup(ifp, ifgr->ifgr_group);
2222 NET_UNLOCK();
2223 break;
2224
2225 case SIOCSIFLLADDR:
2226 if ((error = suser(p)))
2227 break;
2228 if ((ifp->if_sadl == NULL) ||
2229 (ifr->ifr_addr.sa_len != ETHER_ADDR_LEN) ||
2230 (ETHER_IS_MULTICAST(ifr->ifr_addr.sa_data))) {
2231 error = EINVAL;
2232 break;
2233 }
2234 NET_LOCK();
2235 switch (ifp->if_type) {
2236 case IFT_ETHER:
2237 case IFT_CARP:
2238 case IFT_XETHER:
2239 case IFT_ISO88025:
2240 error = (*ifp->if_ioctl)(ifp, cmd, data);
2241 if (error == ENOTTY)
2242 error = 0;
2243 if (error == 0)
2244 error = if_setlladdr(ifp,
2245 ifr->ifr_addr.sa_data);
2246 break;
2247 default:
2248 error = ENODEV;
2249 }
2250
2251 if (error == 0)
2252 ifnewlladdr(ifp);
2253 NET_UNLOCK();
2254 if (error == 0)
2255 rtm_ifchg(ifp);
2256 break;
2257
2258 case SIOCSIFLLPRIO:
2259 if ((error = suser(p)))
2260 break;
2261 if (ifr->ifr_llprio < IFQ_MINPRIO ||
2262 ifr->ifr_llprio > IFQ_MAXPRIO) {
2263 error = EINVAL;
2264 break;
2265 }
2266 NET_LOCK();
2267 ifp->if_llprio = ifr->ifr_llprio;
2268 NET_UNLOCK();
2269 break;
2270
2271 case SIOCGIFSFFPAGE:
2272 error = suser(p);
2273 if (error != 0)
2274 break;
2275
2276 error = if_sffpage_check(data);
2277 if (error != 0)
2278 break;
2279
2280 /* don't take NET_LOCK because i2c reads take a long time */
2281 error = ((*ifp->if_ioctl)(ifp, cmd, data));
2282 break;
2283
2284 case SIOCSIFMEDIA:
2285 if ((error = suser(p)) != 0)
2286 break;
2287 /* FALLTHROUGH */
2288 case SIOCGIFMEDIA:
2289 /* net lock is not needed */
2290 error = ((*ifp->if_ioctl)(ifp, cmd, data));
2291 break;
2292
2293 case SIOCSETKALIVE:
2294 case SIOCDIFPHYADDR:
2295 case SIOCSLIFPHYADDR:
2296 case SIOCSLIFPHYRTABLE:
2297 case SIOCSLIFPHYTTL:
2298 case SIOCSLIFPHYDF:
2299 case SIOCSLIFPHYECN:
2300 case SIOCADDMULTI:
2301 case SIOCDELMULTI:
2302 case SIOCSVNETID:
2303 case SIOCDVNETID:
2304 case SIOCSVNETFLOWID:
2305 case SIOCSTXHPRIO:
2306 case SIOCSRXHPRIO:
2307 case SIOCSIFPAIR:
2308 case SIOCSIFPARENT:
2309 case SIOCDIFPARENT:
2310 case SIOCSETMPWCFG:
2311 case SIOCSETLABEL:
2312 case SIOCDELLABEL:
2313 case SIOCSPWE3CTRLWORD:
2314 case SIOCSPWE3FAT:
2315 case SIOCSPWE3NEIGHBOR:
2316 case SIOCDPWE3NEIGHBOR:
2317 #if NBRIDGE > 0
2318 case SIOCBRDGADD:
2319 case SIOCBRDGDEL:
2320 case SIOCBRDGSIFFLGS:
2321 case SIOCBRDGSCACHE:
2322 case SIOCBRDGADDS:
2323 case SIOCBRDGDELS:
2324 case SIOCBRDGSADDR:
2325 case SIOCBRDGSTO:
2326 case SIOCBRDGDADDR:
2327 case SIOCBRDGFLUSH:
2328 case SIOCBRDGADDL:
2329 case SIOCBRDGSIFPROT:
2330 case SIOCBRDGARL:
2331 case SIOCBRDGFRL:
2332 case SIOCBRDGSPRI:
2333 case SIOCBRDGSHT:
2334 case SIOCBRDGSFD:
2335 case SIOCBRDGSMA:
2336 case SIOCBRDGSIFPRIO:
2337 case SIOCBRDGSIFCOST:
2338 case SIOCBRDGSTXHC:
2339 case SIOCBRDGSPROTO:
2340 #endif
2341 if ((error = suser(p)) != 0)
2342 break;
2343 /* FALLTHROUGH */
2344 default:
2345 error = pru_control(so, cmd, data, ifp);
2346 if (error != EOPNOTSUPP)
2347 break;
2348 switch (cmd) {
2349 case SIOCAIFADDR:
2350 case SIOCDIFADDR:
2351 case SIOCSIFADDR:
2352 case SIOCSIFNETMASK:
2353 case SIOCSIFDSTADDR:
2354 case SIOCSIFBRDADDR:
2355 #ifdef INET6
2356 case SIOCAIFADDR_IN6:
2357 case SIOCDIFADDR_IN6:
2358 #endif
2359 error = suser(p);
2360 break;
2361 default:
2362 error = 0;
2363 break;
2364 }
2365 if (error)
2366 break;
2367 NET_LOCK();
2368 error = ((*ifp->if_ioctl)(ifp, cmd, data));
2369 NET_UNLOCK();
2370 break;
2371 }
2372
2373 if (oif_flags != ifp->if_flags || oif_xflags != ifp->if_xflags) {
2374 /* if_up() and if_down() already sent an update, skip here */
2375 if (((oif_flags ^ ifp->if_flags) & IFF_UP) == 0)
2376 rtm_ifchg(ifp);
2377 }
2378
2379 if (((oif_flags ^ ifp->if_flags) & IFF_UP) != 0)
2380 getmicrotime(&ifp->if_lastchange);
2381
2382 KERNEL_UNLOCK();
2383
2384 if_put(ifp);
2385
2386 return (error);
2387 }
2388
2389 int
2390 ifioctl_get(u_long cmd, caddr_t data)
2391 {
2392 struct ifnet *ifp;
2393 struct ifreq *ifr = (struct ifreq *)data;
2394 char ifdescrbuf[IFDESCRSIZE];
2395 char ifrtlabelbuf[RTLABEL_LEN];
2396 int error = 0;
2397 size_t bytesdone;
2398 const char *label;
2399
2400 switch(cmd) {
2401 case SIOCGIFCONF:
2402 NET_LOCK_SHARED();
2403 error = ifconf(data);
2404 NET_UNLOCK_SHARED();
2405 return (error);
2406 case SIOCIFGCLONERS:
2407 error = if_clone_list((struct if_clonereq *)data);
2408 return (error);
2409 case SIOCGIFGMEMB:
2410 NET_LOCK_SHARED();
2411 error = if_getgroupmembers(data);
2412 NET_UNLOCK_SHARED();
2413 return (error);
2414 case SIOCGIFGATTR:
2415 NET_LOCK_SHARED();
2416 error = if_getgroupattribs(data);
2417 NET_UNLOCK_SHARED();
2418 return (error);
2419 case SIOCGIFGLIST:
2420 NET_LOCK_SHARED();
2421 error = if_getgrouplist(data);
2422 NET_UNLOCK_SHARED();
2423 return (error);
2424 }
2425
2426 KERNEL_LOCK();
2427
2428 ifp = if_unit(ifr->ifr_name);
2429 if (ifp == NULL) {
2430 KERNEL_UNLOCK();
2431 return (ENXIO);
2432 }
2433
2434 NET_LOCK_SHARED();
2435
2436 switch(cmd) {
2437 case SIOCGIFFLAGS:
2438 ifr->ifr_flags = ifp->if_flags;
2439 if (ifq_is_oactive(&ifp->if_snd))
2440 ifr->ifr_flags |= IFF_OACTIVE;
2441 break;
2442
2443 case SIOCGIFXFLAGS:
2444 ifr->ifr_flags = ifp->if_xflags & ~(IFXF_MPSAFE|IFXF_CLONED);
2445 break;
2446
2447 case SIOCGIFMETRIC:
2448 ifr->ifr_metric = ifp->if_metric;
2449 break;
2450
2451 case SIOCGIFMTU:
2452 ifr->ifr_mtu = ifp->if_mtu;
2453 break;
2454
2455 case SIOCGIFHARDMTU:
2456 ifr->ifr_hardmtu = ifp->if_hardmtu;
2457 break;
2458
2459 case SIOCGIFDATA: {
2460 struct if_data ifdata;
2461 if_getdata(ifp, &ifdata);
2462 error = copyout(&ifdata, ifr->ifr_data, sizeof(ifdata));
2463 break;
2464 }
2465
2466 case SIOCGIFDESCR:
2467 strlcpy(ifdescrbuf, ifp->if_description, IFDESCRSIZE);
2468 error = copyoutstr(ifdescrbuf, ifr->ifr_data, IFDESCRSIZE,
2469 &bytesdone);
2470 break;
2471
2472 case SIOCGIFRTLABEL:
2473 if (ifp->if_rtlabelid &&
2474 (label = rtlabel_id2name(ifp->if_rtlabelid)) != NULL) {
2475 strlcpy(ifrtlabelbuf, label, RTLABEL_LEN);
2476 error = copyoutstr(ifrtlabelbuf, ifr->ifr_data,
2477 RTLABEL_LEN, &bytesdone);
2478 } else
2479 error = ENOENT;
2480 break;
2481
2482 case SIOCGIFPRIORITY:
2483 ifr->ifr_metric = ifp->if_priority;
2484 break;
2485
2486 case SIOCGIFRDOMAIN:
2487 ifr->ifr_rdomainid = ifp->if_rdomain;
2488 break;
2489
2490 case SIOCGIFGROUP:
2491 error = if_getgroup(data, ifp);
2492 break;
2493
2494 case SIOCGIFLLPRIO:
2495 ifr->ifr_llprio = ifp->if_llprio;
2496 break;
2497
2498 default:
2499 panic("invalid ioctl %lu", cmd);
2500 }
2501
2502 NET_UNLOCK_SHARED();
2503
2504 KERNEL_UNLOCK();
2505
2506 if_put(ifp);
2507
2508 return (error);
2509 }
2510
2511 static int
2512 if_sffpage_check(const caddr_t data)
2513 {
2514 const struct if_sffpage *sff = (const struct if_sffpage *)data;
2515
2516 switch (sff->sff_addr) {
2517 case IFSFF_ADDR_EEPROM:
2518 case IFSFF_ADDR_DDM:
2519 break;
2520 default:
2521 return (EINVAL);
2522 }
2523
2524 return (0);
2525 }
2526
2527 int
2528 if_txhprio_l2_check(int hdrprio)
2529 {
2530 switch (hdrprio) {
2531 case IF_HDRPRIO_PACKET:
2532 return (0);
2533 default:
2534 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
2535 return (0);
2536 break;
2537 }
2538
2539 return (EINVAL);
2540 }
2541
2542 int
2543 if_txhprio_l3_check(int hdrprio)
2544 {
2545 switch (hdrprio) {
2546 case IF_HDRPRIO_PACKET:
2547 case IF_HDRPRIO_PAYLOAD:
2548 return (0);
2549 default:
2550 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
2551 return (0);
2552 break;
2553 }
2554
2555 return (EINVAL);
2556 }
2557
2558 int
2559 if_rxhprio_l2_check(int hdrprio)
2560 {
2561 switch (hdrprio) {
2562 case IF_HDRPRIO_PACKET:
2563 case IF_HDRPRIO_OUTER:
2564 return (0);
2565 default:
2566 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
2567 return (0);
2568 break;
2569 }
2570
2571 return (EINVAL);
2572 }
2573
2574 int
2575 if_rxhprio_l3_check(int hdrprio)
2576 {
2577 switch (hdrprio) {
2578 case IF_HDRPRIO_PACKET:
2579 case IF_HDRPRIO_PAYLOAD:
2580 case IF_HDRPRIO_OUTER:
2581 return (0);
2582 default:
2583 if (hdrprio >= IF_HDRPRIO_MIN && hdrprio <= IF_HDRPRIO_MAX)
2584 return (0);
2585 break;
2586 }
2587
2588 return (EINVAL);
2589 }
2590
2591 /*
2592 * Return interface configuration
2593 * of system. List may be used
2594 * in later ioctl's (above) to get
2595 * other information.
2596 */
2597 int
2598 ifconf(caddr_t data)
2599 {
2600 struct ifconf *ifc = (struct ifconf *)data;
2601 struct ifnet *ifp;
2602 struct ifaddr *ifa;
2603 struct ifreq ifr, *ifrp;
2604 int space = ifc->ifc_len, error = 0;
2605
2606 /* If ifc->ifc_len is 0, fill it in with the needed size and return. */
2607 if (space == 0) {
2608 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
2609 struct sockaddr *sa;
2610
2611 if (TAILQ_EMPTY(&ifp->if_addrlist))
2612 space += sizeof (ifr);
2613 else
2614 TAILQ_FOREACH(ifa,
2615 &ifp->if_addrlist, ifa_list) {
2616 sa = ifa->ifa_addr;
2617 if (sa->sa_len > sizeof(*sa))
2618 space += sa->sa_len -
2619 sizeof(*sa);
2620 space += sizeof(ifr);
2621 }
2622 }
2623 ifc->ifc_len = space;
2624 return (0);
2625 }
2626
2627 ifrp = ifc->ifc_req;
2628 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
2629 if (space < sizeof(ifr))
2630 break;
2631 bcopy(ifp->if_xname, ifr.ifr_name, IFNAMSIZ);
2632 if (TAILQ_EMPTY(&ifp->if_addrlist)) {
2633 bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
2634 error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
2635 sizeof(ifr));
2636 if (error)
2637 break;
2638 space -= sizeof (ifr), ifrp++;
2639 } else
2640 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
2641 struct sockaddr *sa = ifa->ifa_addr;
2642
2643 if (space < sizeof(ifr))
2644 break;
2645 if (sa->sa_len <= sizeof(*sa)) {
2646 ifr.ifr_addr = *sa;
2647 error = copyout((caddr_t)&ifr,
2648 (caddr_t)ifrp, sizeof (ifr));
2649 ifrp++;
2650 } else {
2651 space -= sa->sa_len - sizeof(*sa);
2652 if (space < sizeof (ifr))
2653 break;
2654 error = copyout((caddr_t)&ifr,
2655 (caddr_t)ifrp,
2656 sizeof(ifr.ifr_name));
2657 if (error == 0)
2658 error = copyout((caddr_t)sa,
2659 (caddr_t)&ifrp->ifr_addr,
2660 sa->sa_len);
2661 ifrp = (struct ifreq *)(sa->sa_len +
2662 (caddr_t)&ifrp->ifr_addr);
2663 }
2664 if (error)
2665 break;
2666 space -= sizeof (ifr);
2667 }
2668 }
2669 ifc->ifc_len -= space;
2670 return (error);
2671 }
2672
2673 void
2674 if_counters_alloc(struct ifnet *ifp)
2675 {
2676 KASSERT(ifp->if_counters == NULL);
2677
2678 ifp->if_counters = counters_alloc(ifc_ncounters);
2679 }
2680
2681 void
2682 if_counters_free(struct ifnet *ifp)
2683 {
2684 KASSERT(ifp->if_counters != NULL);
2685
2686 counters_free(ifp->if_counters, ifc_ncounters);
2687 ifp->if_counters = NULL;
2688 }
2689
2690 void
2691 if_getdata(struct ifnet *ifp, struct if_data *data)
2692 {
2693 unsigned int i;
2694
2695 *data = ifp->if_data;
2696
2697 if (ifp->if_counters != NULL) {
2698 uint64_t counters[ifc_ncounters];
2699
2700 counters_read(ifp->if_counters, counters, nitems(counters));
2701
2702 data->ifi_ipackets += counters[ifc_ipackets];
2703 data->ifi_ierrors += counters[ifc_ierrors];
2704 data->ifi_opackets += counters[ifc_opackets];
2705 data->ifi_oerrors += counters[ifc_oerrors];
2706 data->ifi_collisions += counters[ifc_collisions];
2707 data->ifi_ibytes += counters[ifc_ibytes];
2708 data->ifi_obytes += counters[ifc_obytes];
2709 data->ifi_imcasts += counters[ifc_imcasts];
2710 data->ifi_omcasts += counters[ifc_omcasts];
2711 data->ifi_iqdrops += counters[ifc_iqdrops];
2712 data->ifi_oqdrops += counters[ifc_oqdrops];
2713 data->ifi_noproto += counters[ifc_noproto];
2714 }
2715
2716 for (i = 0; i < ifp->if_nifqs; i++) {
2717 struct ifqueue *ifq = ifp->if_ifqs[i];
2718
2719 ifq_add_data(ifq, data);
2720 }
2721
2722 for (i = 0; i < ifp->if_niqs; i++) {
2723 struct ifiqueue *ifiq = ifp->if_iqs[i];
2724
2725 ifiq_add_data(ifiq, data);
2726 }
2727 }
2728
2729 /*
2730 * Dummy functions replaced in ifnet during detach (if protocols decide to
2731 * fiddle with the if during detach.
2732 */
2733 void
2734 if_detached_qstart(struct ifqueue *ifq)
2735 {
2736 ifq_purge(ifq);
2737 }
2738
2739 int
2740 if_detached_ioctl(struct ifnet *ifp, u_long a, caddr_t b)
2741 {
2742 return ENODEV;
2743 }
2744
2745 /*
2746 * Create interface group without members
2747 */
2748 struct ifg_group *
2749 if_creategroup(const char *groupname)
2750 {
2751 struct ifg_group *ifg;
2752
2753 if ((ifg = malloc(sizeof(*ifg), M_TEMP, M_NOWAIT)) == NULL)
2754 return (NULL);
2755
2756 strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group));
2757 ifg->ifg_refcnt = 1;
2758 ifg->ifg_carp_demoted = 0;
2759 TAILQ_INIT(&ifg->ifg_members);
2760 #if NPF > 0
2761 pfi_attach_ifgroup(ifg);
2762 #endif
2763 TAILQ_INSERT_TAIL(&ifg_head, ifg, ifg_next);
2764
2765 return (ifg);
2766 }
2767
2768 /*
2769 * Add a group to an interface
2770 */
2771 int
2772 if_addgroup(struct ifnet *ifp, const char *groupname)
2773 {
2774 struct ifg_list *ifgl;
2775 struct ifg_group *ifg = NULL;
2776 struct ifg_member *ifgm;
2777 size_t namelen;
2778
2779 namelen = strlen(groupname);
2780 if (namelen == 0 || namelen >= IFNAMSIZ ||
2781 (groupname[namelen - 1] >= '' && groupname[namelen - 1] <= '9'))
2782 return (EINVAL);
2783
2784 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
2785 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
2786 return (EEXIST);
2787
2788 if ((ifgl = malloc(sizeof(*ifgl), M_TEMP, M_NOWAIT)) == NULL)
2789 return (ENOMEM);
2790
2791 if ((ifgm = malloc(sizeof(*ifgm), M_TEMP, M_NOWAIT)) == NULL) {
2792 free(ifgl, M_TEMP, sizeof(*ifgl));
2793 return (ENOMEM);
2794 }
2795
2796 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
2797 if (!strcmp(ifg->ifg_group, groupname))
2798 break;
2799
2800 if (ifg == NULL) {
2801 ifg = if_creategroup(groupname);
2802 if (ifg == NULL) {
2803 free(ifgl, M_TEMP, sizeof(*ifgl));
2804 free(ifgm, M_TEMP, sizeof(*ifgm));
2805 return (ENOMEM);
2806 }
2807 } else
2808 ifg->ifg_refcnt++;
2809 KASSERT(ifg->ifg_refcnt != 0);
2810
2811 ifgl->ifgl_group = ifg;
2812 ifgm->ifgm_ifp = ifp;
2813
2814 TAILQ_INSERT_TAIL(&ifg->ifg_members, ifgm, ifgm_next);
2815 TAILQ_INSERT_TAIL(&ifp->if_groups, ifgl, ifgl_next);
2816
2817 #if NPF > 0
2818 pfi_group_addmember(groupname);
2819 #endif
2820
2821 return (0);
2822 }
2823
2824 /*
2825 * Remove a group from an interface
2826 */
2827 int
2828 if_delgroup(struct ifnet *ifp, const char *groupname)
2829 {
2830 struct ifg_list *ifgl;
2831 struct ifg_member *ifgm;
2832
2833 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
2834 if (!strcmp(ifgl->ifgl_group->ifg_group, groupname))
2835 break;
2836 if (ifgl == NULL)
2837 return (ENOENT);
2838
2839 TAILQ_REMOVE(&ifp->if_groups, ifgl, ifgl_next);
2840
2841 TAILQ_FOREACH(ifgm, &ifgl->ifgl_group->ifg_members, ifgm_next)
2842 if (ifgm->ifgm_ifp == ifp)
2843 break;
2844
2845 if (ifgm != NULL) {
2846 TAILQ_REMOVE(&ifgl->ifgl_group->ifg_members, ifgm, ifgm_next);
2847 free(ifgm, M_TEMP, sizeof(*ifgm));
2848 }
2849
2850 #if NPF > 0
2851 pfi_group_delmember(groupname);
2852 #endif
2853
2854 KASSERT(ifgl->ifgl_group->ifg_refcnt != 0);
2855 if (--ifgl->ifgl_group->ifg_refcnt == 0) {
2856 TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next);
2857 #if NPF > 0
2858 pfi_detach_ifgroup(ifgl->ifgl_group);
2859 #endif
2860 free(ifgl->ifgl_group, M_TEMP, sizeof(*ifgl->ifgl_group));
2861 }
2862
2863 free(ifgl, M_TEMP, sizeof(*ifgl));
2864
2865 return (0);
2866 }
2867
2868 /*
2869 * Stores all groups from an interface in memory pointed
2870 * to by data
2871 */
2872 int
2873 if_getgroup(caddr_t data, struct ifnet *ifp)
2874 {
2875 int len, error;
2876 struct ifg_list *ifgl;
2877 struct ifg_req ifgrq, *ifgp;
2878 struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
2879
2880 if (ifgr->ifgr_len == 0) {
2881 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next)
2882 ifgr->ifgr_len += sizeof(struct ifg_req);
2883 return (0);
2884 }
2885
2886 len = ifgr->ifgr_len;
2887 ifgp = ifgr->ifgr_groups;
2888 TAILQ_FOREACH(ifgl, &ifp->if_groups, ifgl_next) {
2889 if (len < sizeof(ifgrq))
2890 return (EINVAL);
2891 bzero(&ifgrq, sizeof ifgrq);
2892 strlcpy(ifgrq.ifgrq_group, ifgl->ifgl_group->ifg_group,
2893 sizeof(ifgrq.ifgrq_group));
2894 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
2895 sizeof(struct ifg_req))))
2896 return (error);
2897 len -= sizeof(ifgrq);
2898 ifgp++;
2899 }
2900
2901 return (0);
2902 }
2903
2904 /*
2905 * Stores all members of a group in memory pointed to by data
2906 */
2907 int
2908 if_getgroupmembers(caddr_t data)
2909 {
2910 struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
2911 struct ifg_group *ifg;
2912 struct ifg_member *ifgm;
2913 struct ifg_req ifgrq, *ifgp;
2914 int len, error;
2915
2916 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
2917 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
2918 break;
2919 if (ifg == NULL)
2920 return (ENOENT);
2921
2922 if (ifgr->ifgr_len == 0) {
2923 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
2924 ifgr->ifgr_len += sizeof(ifgrq);
2925 return (0);
2926 }
2927
2928 len = ifgr->ifgr_len;
2929 ifgp = ifgr->ifgr_groups;
2930 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next) {
2931 if (len < sizeof(ifgrq))
2932 return (EINVAL);
2933 bzero(&ifgrq, sizeof ifgrq);
2934 strlcpy(ifgrq.ifgrq_member, ifgm->ifgm_ifp->if_xname,
2935 sizeof(ifgrq.ifgrq_member));
2936 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
2937 sizeof(struct ifg_req))))
2938 return (error);
2939 len -= sizeof(ifgrq);
2940 ifgp++;
2941 }
2942
2943 return (0);
2944 }
2945
2946 int
2947 if_getgroupattribs(caddr_t data)
2948 {
2949 struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
2950 struct ifg_group *ifg;
2951
2952 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
2953 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
2954 break;
2955 if (ifg == NULL)
2956 return (ENOENT);
2957
2958 ifgr->ifgr_attrib.ifg_carp_demoted = ifg->ifg_carp_demoted;
2959
2960 return (0);
2961 }
2962
2963 int
2964 if_setgroupattribs(caddr_t data)
2965 {
2966 struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
2967 struct ifg_group *ifg;
2968 struct ifg_member *ifgm;
2969 int demote;
2970
2971 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
2972 if (!strcmp(ifg->ifg_group, ifgr->ifgr_name))
2973 break;
2974 if (ifg == NULL)
2975 return (ENOENT);
2976
2977 demote = ifgr->ifgr_attrib.ifg_carp_demoted;
2978 if (demote + ifg->ifg_carp_demoted > 0xff ||
2979 demote + ifg->ifg_carp_demoted < 0)
2980 return (EINVAL);
2981
2982 ifg->ifg_carp_demoted += demote;
2983
2984 TAILQ_FOREACH(ifgm, &ifg->ifg_members, ifgm_next)
2985 ifgm->ifgm_ifp->if_ioctl(ifgm->ifgm_ifp, SIOCSIFGATTR, data);
2986
2987 return (0);
2988 }
2989
2990 /*
2991 * Stores all groups in memory pointed to by data
2992 */
2993 int
2994 if_getgrouplist(caddr_t data)
2995 {
2996 struct ifgroupreq *ifgr = (struct ifgroupreq *)data;
2997 struct ifg_group *ifg;
2998 struct ifg_req ifgrq, *ifgp;
2999 int len, error;
3000
3001 if (ifgr->ifgr_len == 0) {
3002 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
3003 ifgr->ifgr_len += sizeof(ifgrq);
3004 return (0);
3005 }
3006
3007 len = ifgr->ifgr_len;
3008 ifgp = ifgr->ifgr_groups;
3009 TAILQ_FOREACH(ifg, &ifg_head, ifg_next) {
3010 if (len < sizeof(ifgrq))
3011 return (EINVAL);
3012 bzero(&ifgrq, sizeof ifgrq);
3013 strlcpy(ifgrq.ifgrq_group, ifg->ifg_group,
3014 sizeof(ifgrq.ifgrq_group));
3015 if ((error = copyout((caddr_t)&ifgrq, (caddr_t)ifgp,
3016 sizeof(struct ifg_req))))
3017 return (error);
3018 len -= sizeof(ifgrq);
3019 ifgp++;
3020 }
3021
3022 return (0);
3023 }
3024
3025 void
3026 if_group_routechange(struct sockaddr *dst, struct sockaddr *mask)
3027 {
3028 switch (dst->sa_family) {
3029 case AF_INET:
3030 if (satosin(dst)->sin_addr.s_addr == INADDR_ANY &&
3031 mask && (mask->sa_len == 0 ||
3032 satosin(mask)->sin_addr.s_addr == INADDR_ANY))
3033 if_group_egress_build();
3034 break;
3035 #ifdef INET6
3036 case AF_INET6:
3037 if (IN6_ARE_ADDR_EQUAL(&(satosin6(dst))->sin6_addr,
3038 &in6addr_any) && mask && (mask->sa_len == 0 ||
3039 IN6_ARE_ADDR_EQUAL(&(satosin6(mask))->sin6_addr,
3040 &in6addr_any)))
3041 if_group_egress_build();
3042 break;
3043 #endif
3044 }
3045 }
3046
3047 int
3048 if_group_egress_build(void)
3049 {
3050 struct ifnet *ifp;
3051 struct ifg_group *ifg;
3052 struct ifg_member *ifgm, *next;
3053 struct sockaddr_in sa_in;
3054 #ifdef INET6
3055 struct sockaddr_in6 sa_in6;
3056 #endif
3057 struct rtentry *rt;
3058
3059 TAILQ_FOREACH(ifg, &ifg_head, ifg_next)
3060 if (!strcmp(ifg->ifg_group, IFG_EGRESS))
3061 break;
3062
3063 if (ifg != NULL)
3064 TAILQ_FOREACH_SAFE(ifgm, &ifg->ifg_members, ifgm_next, next)
3065 if_delgroup(ifgm->ifgm_ifp, IFG_EGRESS);
3066
3067 bzero(&sa_in, sizeof(sa_in));
3068 sa_in.sin_len = sizeof(sa_in);
3069 sa_in.sin_family = AF_INET;
3070 rt = rtable_lookup(0, sintosa(&sa_in), sintosa(&sa_in), NULL, RTP_ANY);
3071 while (rt != NULL) {
3072 ifp = if_get(rt->rt_ifidx);
3073 if (ifp != NULL) {
3074 if_addgroup(ifp, IFG_EGRESS);
3075 if_put(ifp);
3076 }
3077 rt = rtable_iterate(rt);
3078 }
3079
3080 #ifdef INET6
3081 bcopy(&sa6_any, &sa_in6, sizeof(sa_in6));
3082 rt = rtable_lookup(0, sin6tosa(&sa_in6), sin6tosa(&sa_in6), NULL,
3083 RTP_ANY);
3084 while (rt != NULL) {
3085 ifp = if_get(rt->rt_ifidx);
3086 if (ifp != NULL) {
3087 if_addgroup(ifp, IFG_EGRESS);
3088 if_put(ifp);
3089 }
3090 rt = rtable_iterate(rt);
3091 }
3092 #endif /* INET6 */
3093
3094 return (0);
3095 }
3096
3097 /*
3098 * Set/clear promiscuous mode on interface ifp based on the truth value
3099 * of pswitch. The calls are reference counted so that only the first
3100 * "on" request actually has an effect, as does the final "off" request.
3101 * Results are undefined if the "off" and "on" requests are not matched.
3102 */
3103 int
3104 ifpromisc(struct ifnet *ifp, int pswitch)
3105 {
3106 struct ifreq ifr;
3107 unsigned short oif_flags;
3108 int oif_pcount, error;
3109
3110 NET_ASSERT_LOCKED(); /* modifying if_flags and if_pcount */
3111
3112 oif_flags = ifp->if_flags;
3113 oif_pcount = ifp->if_pcount;
3114 if (pswitch) {
3115 if (ifp->if_pcount++ != 0)
3116 return (0);
3117 ifp->if_flags |= IFF_PROMISC;
3118 } else {
3119 if (--ifp->if_pcount > 0)
3120 return (0);
3121 ifp->if_flags &= ~IFF_PROMISC;
3122 }
3123
3124 if ((ifp->if_flags & IFF_UP) == 0)
3125 return (0);
3126
3127 memset(&ifr, 0, sizeof(ifr));
3128 ifr.ifr_flags = ifp->if_flags;
3129 error = ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
3130 if (error) {
3131 ifp->if_flags = oif_flags;
3132 ifp->if_pcount = oif_pcount;
3133 }
3134
3135 return (error);
3136 }
3137
3138 void
3139 ifa_add(struct ifnet *ifp, struct ifaddr *ifa)
3140 {
3141 TAILQ_INSERT_TAIL(&ifp->if_addrlist, ifa, ifa_list);
3142 }
3143
3144 void
3145 ifa_del(struct ifnet *ifp, struct ifaddr *ifa)
3146 {
3147 TAILQ_REMOVE(&ifp->if_addrlist, ifa, ifa_list);
3148 }
3149
3150 void
3151 ifa_update_broadaddr(struct ifnet *ifp, struct ifaddr *ifa, struct sockaddr *sa)
3152 {
3153 if (ifa->ifa_broadaddr->sa_len != sa->sa_len)
3154 panic("ifa_update_broadaddr does not support dynamic length");
3155 bcopy(sa, ifa->ifa_broadaddr, sa->sa_len);
3156 }
3157
3158 #ifdef DDB
3159 /* debug function, can be called from ddb> */
3160 void
3161 ifa_print_all(void)
3162 {
3163 struct ifnet *ifp;
3164 struct ifaddr *ifa;
3165
3166 TAILQ_FOREACH(ifp, &ifnetlist, if_list) {
3167 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
3168 char addr[INET6_ADDRSTRLEN];
3169
3170 switch (ifa->ifa_addr->sa_family) {
3171 case AF_INET:
3172 printf("%s", inet_ntop(AF_INET,
3173 &satosin(ifa->ifa_addr)->sin_addr,
3174 addr, sizeof(addr)));
3175 break;
3176 #ifdef INET6
3177 case AF_INET6:
3178 printf("%s", inet_ntop(AF_INET6,
3179 &(satosin6(ifa->ifa_addr))->sin6_addr,
3180 addr, sizeof(addr)));
3181 break;
3182 #endif
3183 }
3184 printf(" on %s\n", ifp->if_xname);
3185 }
3186 }
3187 }
3188 #endif /* DDB */
3189
3190 void
3191 ifnewlladdr(struct ifnet *ifp)
3192 {
3193 #ifdef INET6
3194 struct ifaddr *ifa;
3195 #endif
3196 struct ifreq ifrq;
3197 short up;
3198
3199 NET_ASSERT_LOCKED(); /* for ioctl and in6 */
3200 KERNEL_ASSERT_LOCKED(); /* for if_flags */
3201
3202 up = ifp->if_flags & IFF_UP;
3203
3204 if (up) {
3205 /* go down for a moment... */
3206 ifp->if_flags &= ~IFF_UP;
3207 ifrq.ifr_flags = ifp->if_flags;
3208 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
3209 }
3210
3211 ifp->if_flags |= IFF_UP;
3212 ifrq.ifr_flags = ifp->if_flags;
3213 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
3214
3215 #ifdef INET6
3216 /*
3217 * Update the link-local address. Don't do it if we're
3218 * a router to avoid confusing hosts on the network.
3219 */
3220 if (!ip6_forwarding) {
3221 ifa = &in6ifa_ifpforlinklocal(ifp, 0)->ia_ifa;
3222 if (ifa) {
3223 in6_purgeaddr(ifa);
3224 if_hooks_run(&ifp->if_addrhooks);
3225 in6_ifattach(ifp);
3226 }
3227 }
3228 #endif
3229 if (!up) {
3230 /* go back down */
3231 ifp->if_flags &= ~IFF_UP;
3232 ifrq.ifr_flags = ifp->if_flags;
3233 (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifrq);
3234 }
3235 }
3236
3237 void
3238 if_addrhook_add(struct ifnet *ifp, struct task *t)
3239 {
3240 mtx_enter(&if_hooks_mtx);
3241 TAILQ_INSERT_TAIL(&ifp->if_addrhooks, t, t_entry);
3242 mtx_leave(&if_hooks_mtx);
3243 }
3244
3245 void
3246 if_addrhook_del(struct ifnet *ifp, struct task *t)
3247 {
3248 mtx_enter(&if_hooks_mtx);
3249 TAILQ_REMOVE(&ifp->if_addrhooks, t, t_entry);
3250 mtx_leave(&if_hooks_mtx);
3251 }
3252
3253 void
3254 if_addrhooks_run(struct ifnet *ifp)
3255 {
3256 if_hooks_run(&ifp->if_addrhooks);
3257 }
3258
3259 void
3260 if_rxr_init(struct if_rxring *rxr, u_int lwm, u_int hwm)
3261 {
3262 extern int ticks;
3263
3264 memset(rxr, 0, sizeof(*rxr));
3265
3266 rxr->rxr_adjusted = ticks;
3267 rxr->rxr_cwm = rxr->rxr_lwm = lwm;
3268 rxr->rxr_hwm = hwm;
3269 }
3270
3271 static inline void
3272 if_rxr_adjust_cwm(struct if_rxring *rxr)
3273 {
3274 extern int ticks;
3275
3276 if (rxr->rxr_alive >= rxr->rxr_lwm)
3277 return;
3278 else if (rxr->rxr_cwm < rxr->rxr_hwm)
3279 rxr->rxr_cwm++;
3280
3281 rxr->rxr_adjusted = ticks;
3282 }
3283
3284 void
3285 if_rxr_livelocked(struct if_rxring *rxr)
3286 {
3287 extern int ticks;
3288
3289 if (ticks - rxr->rxr_adjusted >= 1) {
3290 if (rxr->rxr_cwm > rxr->rxr_lwm)
3291 rxr->rxr_cwm--;
3292
3293 rxr->rxr_adjusted = ticks;
3294 }
3295 }
3296
3297 u_int
3298 if_rxr_get(struct if_rxring *rxr, u_int max)
3299 {
3300 extern int ticks;
3301 u_int diff;
3302
3303 if (ticks - rxr->rxr_adjusted >= 1) {
3304 /* we're free to try for an adjustment */
3305 if_rxr_adjust_cwm(rxr);
3306 }
3307
3308 if (rxr->rxr_alive >= rxr->rxr_cwm)
3309 return (0);
3310
3311 diff = min(rxr->rxr_cwm - rxr->rxr_alive, max);
3312 rxr->rxr_alive += diff;
3313
3314 return (diff);
3315 }
3316
3317 int
3318 if_rxr_info_ioctl(struct if_rxrinfo *uifri, u_int t, struct if_rxring_info *e)
3319 {
3320 struct if_rxrinfo kifri;
3321 int error;
3322 u_int n;
3323
3324 error = copyin(uifri, &kifri, sizeof(kifri));
3325 if (error)
3326 return (error);
3327
3328 n = min(t, kifri.ifri_total);
3329 kifri.ifri_total = t;
3330
3331 if (n > 0) {
3332 error = copyout(e, kifri.ifri_entries, sizeof(*e) * n);
3333 if (error)
3334 return (error);
3335 }
3336
3337 return (copyout(&kifri, uifri, sizeof(kifri)));
3338 }
3339
3340 int
3341 if_rxr_ioctl(struct if_rxrinfo *ifri, const char *name, u_int size,
3342 struct if_rxring *rxr)
3343 {
3344 struct if_rxring_info ifr;
3345
3346 memset(&ifr, 0, sizeof(ifr));
3347
3348 if (name != NULL)
3349 strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
3350
3351 ifr.ifr_size = size;
3352 ifr.ifr_info = *rxr;
3353
3354 return (if_rxr_info_ioctl(ifri, 1, &ifr));
3355 }
3356
3357 /*
3358 * Network stack input queues.
3359 */
3360
3361 void
3362 niq_init(struct niqueue *niq, u_int maxlen, u_int isr)
3363 {
3364 mq_init(&niq->ni_q, maxlen, IPL_NET);
3365 niq->ni_isr = isr;
3366 }
3367
3368 int
3369 niq_enqueue(struct niqueue *niq, struct mbuf *m)
3370 {
3371 int rv;
3372
3373 rv = mq_enqueue(&niq->ni_q, m);
3374 if (rv == 0)
3375 schednetisr(niq->ni_isr);
3376 else
3377 if_congestion();
3378
3379 return (rv);
3380 }
3381
3382 int
3383 niq_enlist(struct niqueue *niq, struct mbuf_list *ml)
3384 {
3385 int rv;
3386
3387 rv = mq_enlist(&niq->ni_q, ml);
3388 if (rv == 0)
3389 schednetisr(niq->ni_isr);
3390 else
3391 if_congestion();
3392
3393 return (rv);
3394 }
3395
3396 __dead void
3397 unhandled_af(int af)
3398 {
3399 panic("unhandled af %d", af);
3400 }
3401
3402 struct taskq *
3403 net_tq(unsigned int ifindex)
3404 {
3405 struct taskq *t = NULL;
3406 static int nettaskqs;
3407
3408 if (nettaskqs == 0)
3409 nettaskqs = min(NET_TASKQ, ncpus);
3410
3411 t = nettqmp[ifindex % nettaskqs];
3412
3413 return (t);
3414 }
Cache object: 87cefc890a38912d68c23b5e0bd921f3
|