xref: /haiku/src/libs/compat/freebsd_network/fbsd_if.c (revision 7d36436b75aad721d1311dea29c75f6a3678c3e0)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2010 Bjoern A. Zeeb <bz@FreeBSD.org>
5  * Copyright (c) 1980, 1986, 1993
6  *	The Regents of the University of California.  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 University 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 REGENTS 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 REGENTS 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 #include <sys/epoch.h>
34 
35 #include <net/if.h>
36 #include <net/if_var.h>
37 #include <net/ethernet.h>
38 #include <net/if_vlan_var.h>
39 
40 /* API for driver access to network stack owned ifnet.*/
41 uint64_t
if_setbaudrate(struct ifnet * ifp,uint64_t baudrate)42 if_setbaudrate(struct ifnet *ifp, uint64_t baudrate)
43 {
44 	uint64_t oldbrate;
45 
46 	oldbrate = ifp->if_baudrate;
47 	ifp->if_baudrate = baudrate;
48 	return (oldbrate);
49 }
50 
51 uint64_t
if_getbaudrate(const if_t ifp)52 if_getbaudrate(const if_t ifp)
53 {
54 	return (ifp->if_baudrate);
55 }
56 
57 int
if_setcapabilities(if_t ifp,int capabilities)58 if_setcapabilities(if_t ifp, int capabilities)
59 {
60 	ifp->if_capabilities = capabilities;
61 	return (0);
62 }
63 
64 int
if_setcapabilitiesbit(if_t ifp,int setbit,int clearbit)65 if_setcapabilitiesbit(if_t ifp, int setbit, int clearbit)
66 {
67 	ifp->if_capabilities &= ~clearbit;
68 	ifp->if_capabilities |= setbit;
69 	return (0);
70 }
71 
72 int
if_getcapabilities(const if_t ifp)73 if_getcapabilities(const if_t ifp)
74 {
75 	return (ifp->if_capabilities);
76 }
77 
78 int
if_setcapenable(if_t ifp,int capabilities)79 if_setcapenable(if_t ifp, int capabilities)
80 {
81 	ifp->if_capenable = capabilities;
82 	return (0);
83 }
84 
85 int
if_setcapenablebit(if_t ifp,int setcap,int clearcap)86 if_setcapenablebit(if_t ifp, int setcap, int clearcap)
87 {
88 	ifp->if_capenable &= ~clearcap;
89 	ifp->if_capenable |= setcap;
90 	return (0);
91 }
92 
93 #if 0
94 int
95 if_setcapabilities2(if_t ifp, int capabilities)
96 {
97 	ifp->if_capabilities2 = capabilities;
98 	return (0);
99 }
100 
101 int
102 if_setcapabilities2bit(if_t ifp, int setbit, int clearbit)
103 {
104 	ifp->if_capabilities2 &= ~clearbit;
105 	ifp->if_capabilities2 |= setbit;
106 	return (0);
107 }
108 
109 int
110 if_getcapabilities2(const if_t ifp)
111 {
112 	return (ifp->if_capabilities2);
113 }
114 
115 int
116 if_setcapenable2(if_t ifp, int capabilities2)
117 {
118 	ifp->if_capenable2 = capabilities2;
119 	return (0);
120 }
121 
122 int
123 if_setcapenable2bit(if_t ifp, int setcap, int clearcap)
124 {
125 	ifp->if_capenable2 &= ~clearcap;
126 	ifp->if_capenable2 |= setcap;
127 	return (0);
128 }
129 #endif
130 
131 const char *
if_getdname(const if_t ifp)132 if_getdname(const if_t ifp)
133 {
134 	return (ifp->if_dname);
135 }
136 
137 void
if_setdname(if_t ifp,const char * dname)138 if_setdname(if_t ifp, const char *dname)
139 {
140 	ifp->if_dname = dname;
141 }
142 
143 const char *
if_name(if_t ifp)144 if_name(if_t ifp)
145 {
146 	return (ifp->if_xname);
147 }
148 
149 int
if_setname(if_t ifp,const char * name)150 if_setname(if_t ifp, const char *name)
151 {
152 	if (strlen(name) > sizeof(ifp->if_xname) - 1)
153 		return (ENAMETOOLONG);
154 	strcpy(ifp->if_xname, name);
155 
156 	return (0);
157 }
158 
159 int
if_togglecapenable(if_t ifp,int togglecap)160 if_togglecapenable(if_t ifp, int togglecap)
161 {
162 	ifp->if_capenable ^= togglecap;
163 	return (0);
164 }
165 
166 int
if_getcapenable(const if_t ifp)167 if_getcapenable(const if_t ifp)
168 {
169 	return (ifp->if_capenable);
170 }
171 
172 #if 0
173 int
174 if_togglecapenable2(if_t ifp, int togglecap)
175 {
176 	ifp->if_capenable2 ^= togglecap;
177 	return (0);
178 }
179 
180 int
181 if_getcapenable2(const if_t ifp)
182 {
183 	return (ifp->if_capenable2);
184 }
185 #endif
186 
187 int
if_getdunit(const if_t ifp)188 if_getdunit(const if_t ifp)
189 {
190 	return (ifp->if_dunit);
191 }
192 
193 int
if_getindex(const if_t ifp)194 if_getindex(const if_t ifp)
195 {
196 	return (ifp->if_index);
197 }
198 
199 #if 0
200 int
201 if_getidxgen(const if_t ifp)
202 {
203 	return (ifp->if_idxgen);
204 }
205 
206 const char *
207 if_getdescr(if_t ifp)
208 {
209 	return (ifp->if_description);
210 }
211 
212 void
213 if_setdescr(if_t ifp, char *descrbuf)
214 {
215 	sx_xlock(&ifdescr_sx);
216 	char *odescrbuf = ifp->if_description;
217 	ifp->if_description = descrbuf;
218 	sx_xunlock(&ifdescr_sx);
219 
220 	if_freedescr(odescrbuf);
221 }
222 
223 char *
224 if_allocdescr(size_t sz, int malloc_flag)
225 {
226 	malloc_flag &= (M_WAITOK | M_NOWAIT);
227 	return (malloc(sz, M_IFDESCR, M_ZERO | malloc_flag));
228 }
229 
230 void
231 if_freedescr(char *descrbuf)
232 {
233 	free(descrbuf, M_IFDESCR);
234 }
235 
236 int
237 if_getalloctype(const if_t ifp)
238 {
239 	return (ifp->if_alloctype);
240 }
241 
242 void
243 if_setlastchange(if_t ifp)
244 {
245 	getmicrotime(&ifp->if_lastchange);
246 }
247 #endif
248 
249 /*
250  * This is largely undesirable because it ties ifnet to a device, but does
251  * provide flexiblity for an embedded product vendor. Should be used with
252  * the understanding that it violates the interface boundaries, and should be
253  * a last resort only.
254  */
255 int
if_setdev(if_t ifp,void * dev)256 if_setdev(if_t ifp, void *dev)
257 {
258 	return (0);
259 }
260 
261 int
if_setdrvflagbits(if_t ifp,int set_flags,int clear_flags)262 if_setdrvflagbits(if_t ifp, int set_flags, int clear_flags)
263 {
264 	ifp->if_drv_flags &= ~clear_flags;
265 	ifp->if_drv_flags |= set_flags;
266 
267 	return (0);
268 }
269 
270 int
if_getdrvflags(const if_t ifp)271 if_getdrvflags(const if_t ifp)
272 {
273 	return (ifp->if_drv_flags);
274 }
275 
276 int
if_setdrvflags(if_t ifp,int flags)277 if_setdrvflags(if_t ifp, int flags)
278 {
279 	ifp->if_drv_flags = flags;
280 	return (0);
281 }
282 
283 int
if_setflags(if_t ifp,int flags)284 if_setflags(if_t ifp, int flags)
285 {
286 	ifp->if_flags = flags;
287 	return (0);
288 }
289 
290 int
if_setflagbits(if_t ifp,int set,int clear)291 if_setflagbits(if_t ifp, int set, int clear)
292 {
293 	ifp->if_flags &= ~clear;
294 	ifp->if_flags |= set;
295 	return (0);
296 }
297 
298 int
if_getflags(const if_t ifp)299 if_getflags(const if_t ifp)
300 {
301 	return (ifp->if_flags);
302 }
303 
304 int
if_clearhwassist(if_t ifp)305 if_clearhwassist(if_t ifp)
306 {
307 	ifp->if_hwassist = 0;
308 	return (0);
309 }
310 
311 int
if_sethwassistbits(if_t ifp,int toset,int toclear)312 if_sethwassistbits(if_t ifp, int toset, int toclear)
313 {
314 	ifp->if_hwassist &= ~toclear;
315 	ifp->if_hwassist |= toset;
316 
317 	return (0);
318 }
319 
320 int
if_sethwassist(if_t ifp,int hwassist_bit)321 if_sethwassist(if_t ifp, int hwassist_bit)
322 {
323 	ifp->if_hwassist = hwassist_bit;
324 	return (0);
325 }
326 
327 int
if_gethwassist(const if_t ifp)328 if_gethwassist(const if_t ifp)
329 {
330 	return (ifp->if_hwassist);
331 }
332 
333 int
if_togglehwassist(if_t ifp,int toggle_bits)334 if_togglehwassist(if_t ifp, int toggle_bits)
335 {
336 	ifp->if_hwassist ^= toggle_bits;
337 	return (0);
338 }
339 
340 int
if_setmtu(if_t ifp,int mtu)341 if_setmtu(if_t ifp, int mtu)
342 {
343 	ifp->if_mtu = mtu;
344 	return (0);
345 }
346 
347 #if 0
348 void
349 if_notifymtu(if_t ifp)
350 {
351 #ifdef INET6
352 	nd6_setmtu(ifp);
353 #endif
354 	rt_updatemtu(ifp);
355 }
356 #endif
357 
358 int
if_getmtu(const if_t ifp)359 if_getmtu(const if_t ifp)
360 {
361 	return (ifp->if_mtu);
362 }
363 
364 #if 0
365 int
366 if_getmtu_family(const if_t ifp, int family)
367 {
368 	struct domain *dp;
369 
370 	SLIST_FOREACH(dp, &domains, dom_next) {
371 		if (dp->dom_family == family && dp->dom_ifmtu != NULL)
372 			return (dp->dom_ifmtu(ifp));
373 	}
374 
375 	return (ifp->if_mtu);
376 }
377 #endif
378 
379 /*
380  * Methods for drivers to access interface unicast and multicast
381  * link level addresses.  Driver shall not know 'struct ifaddr' neither
382  * 'struct ifmultiaddr'.
383  */
384 u_int
if_lladdr_count(if_t ifp)385 if_lladdr_count(if_t ifp)
386 {
387 	struct epoch_tracker et;
388 	struct ifaddr *ifa;
389 	u_int count;
390 
391 	count = 0;
392 	NET_EPOCH_ENTER(et);
393 	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
394 		if (ifa->ifa_addr->sa_family == AF_LINK)
395 			count++;
396 	NET_EPOCH_EXIT(et);
397 
398 	return (count);
399 }
400 
401 #if 0
402 int
403 if_foreach(if_foreach_cb_t cb, void *cb_arg)
404 {
405 	if_t ifp;
406 	int error;
407 
408 	NET_EPOCH_ASSERT();
409 	MPASS(cb);
410 
411 	error = 0;
412 	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
413 		error = cb(ifp, cb_arg);
414 		if (error != 0)
415 			break;
416 	}
417 
418 	return (error);
419 }
420 
421 /*
422  * Iterates over the list of interfaces, permitting callback function @cb to sleep.
423  * Stops iteration if @cb returns non-zero error code.
424  * Returns the last error code from @cb.
425  * @match_cb: optional match callback limiting the iteration to only matched interfaces
426  * @match_arg: argument to pass to @match_cb
427  * @cb: iteration callback
428  * @cb_arg: argument to pass to @cb
429  */
430 int
431 if_foreach_sleep(if_foreach_match_t match_cb, void *match_arg, if_foreach_cb_t cb,
432 	void *cb_arg)
433 {
434 	int match_count = 0, array_size = 16; /* 128 bytes for malloc */
435 	struct ifnet **match_array = NULL;
436 	int error = 0;
437 
438 	MPASS(cb);
439 
440 	while (true) {
441 		struct ifnet **new_array;
442 		int new_size = array_size;
443 		struct epoch_tracker et;
444 		struct ifnet *ifp;
445 
446 		while (new_size < match_count)
447 			new_size *= 2;
448 		new_array = malloc(new_size * sizeof(void *), M_TEMP, M_WAITOK);
449 		if (match_array != NULL)
450 			memcpy(new_array, match_array, array_size * sizeof(void *));
451 		free(match_array, M_TEMP);
452 		match_array = new_array;
453 		array_size = new_size;
454 
455 		match_count = 0;
456 		NET_EPOCH_ENTER(et);
457 		CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
458 			if (match_cb != NULL && !match_cb(ifp, match_arg))
459 				continue;
460 			if (match_count < array_size) {
461 				if (if_try_ref(ifp))
462 					match_array[match_count++] = ifp;
463 			} else
464 				match_count++;
465 		}
466 		NET_EPOCH_EXIT(et);
467 
468 		if (match_count > array_size) {
469 			for (int i = 0; i < array_size; i++)
470 				if_rele(match_array[i]);
471 			continue;
472 		} else {
473 			for (int i = 0; i < match_count; i++) {
474 				if (error == 0)
475 					error = cb(match_array[i], cb_arg);
476 				if_rele(match_array[i]);
477 			}
478 			free(match_array, M_TEMP);
479 			break;
480 		}
481 	}
482 
483 	return (error);
484 }
485 
486 
487 /*
488  * Uses just 1 pointer of the 4 available in the public struct.
489  */
490 if_t
491 if_iter_start(struct if_iter *iter)
492 {
493 	if_t ifp;
494 
495 	NET_EPOCH_ASSERT();
496 
497 	bzero(iter, sizeof(*iter));
498 	ifp = CK_STAILQ_FIRST(&V_ifnet);
499 	if (ifp != NULL)
500 		iter->context[0] = CK_STAILQ_NEXT(ifp, if_link);
501 	else
502 		iter->context[0] = NULL;
503 	return (ifp);
504 }
505 
506 if_t
507 if_iter_next(struct if_iter *iter)
508 {
509 	if_t cur_ifp = iter->context[0];
510 
511 	if (cur_ifp != NULL)
512 		iter->context[0] = CK_STAILQ_NEXT(cur_ifp, if_link);
513 	return (cur_ifp);
514 }
515 
516 void
517 if_iter_finish(struct if_iter *iter)
518 {
519 	/* Nothing to do here for now. */
520 }
521 #endif
522 
523 u_int
if_foreach_lladdr(if_t ifp,iflladdr_cb_t cb,void * cb_arg)524 if_foreach_lladdr(if_t ifp, iflladdr_cb_t cb, void *cb_arg)
525 {
526 	struct epoch_tracker et;
527 	struct ifaddr *ifa;
528 	u_int count;
529 
530 	MPASS(cb);
531 
532 	count = 0;
533 	NET_EPOCH_ENTER(et);
534 	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
535 		if (ifa->ifa_addr->sa_family != AF_LINK)
536 			continue;
537 		count += (*cb)(cb_arg, (struct sockaddr_dl *)ifa->ifa_addr,
538 			count);
539 	}
540 	NET_EPOCH_EXIT(et);
541 
542 	return (count);
543 }
544 
545 u_int
if_llmaddr_count(if_t ifp)546 if_llmaddr_count(if_t ifp)
547 {
548 	struct epoch_tracker et;
549 	struct ifmultiaddr *ifma;
550 	int count;
551 
552 	count = 0;
553 	NET_EPOCH_ENTER(et);
554 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
555 		if (ifma->ifma_addr->sa_family == AF_LINK)
556 			count++;
557 	NET_EPOCH_EXIT(et);
558 
559 	return (count);
560 }
561 
562 bool
if_maddr_empty(if_t ifp)563 if_maddr_empty(if_t ifp)
564 {
565 
566 	return (TAILQ_EMPTY(&ifp->if_multiaddrs));
567 }
568 
569 u_int
if_foreach_llmaddr(if_t ifp,iflladdr_cb_t cb,void * cb_arg)570 if_foreach_llmaddr(if_t ifp, iflladdr_cb_t cb, void *cb_arg)
571 {
572 	struct epoch_tracker et;
573 	struct ifmultiaddr *ifma;
574 	u_int count;
575 
576 	MPASS(cb);
577 
578 	count = 0;
579 	NET_EPOCH_ENTER(et);
580 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
581 		if (ifma->ifma_addr->sa_family != AF_LINK)
582 			continue;
583 		count += (*cb)(cb_arg, (struct sockaddr_dl *)ifma->ifma_addr,
584 			count);
585 	}
586 	NET_EPOCH_EXIT(et);
587 
588 	return (count);
589 }
590 
591 #if 0
592 u_int
593 if_foreach_addr_type(if_t ifp, int type, if_addr_cb_t cb, void *cb_arg)
594 {
595 	struct epoch_tracker et;
596 	struct ifaddr *ifa;
597 	u_int count;
598 
599 	MPASS(cb);
600 
601 	count = 0;
602 	NET_EPOCH_ENTER(et);
603 	CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
604 		if (ifa->ifa_addr->sa_family != type)
605 			continue;
606 		count += (*cb)(cb_arg, ifa, count);
607 	}
608 	NET_EPOCH_EXIT(et);
609 
610 	return (count);
611 }
612 
613 struct ifaddr *
614 ifa_iter_start(if_t ifp, struct ifa_iter *iter)
615 {
616 	struct ifaddr *ifa;
617 
618 	NET_EPOCH_ASSERT();
619 
620 	bzero(iter, sizeof(*iter));
621 	ifa = CK_STAILQ_FIRST(&ifp->if_addrhead);
622 	if (ifa != NULL)
623 		iter->context[0] = CK_STAILQ_NEXT(ifa, ifa_link);
624 	else
625 		iter->context[0] = NULL;
626 	return (ifa);
627 }
628 
629 struct ifaddr *
630 ifa_iter_next(struct ifa_iter *iter)
631 {
632 	struct ifaddr *ifa = iter->context[0];
633 
634 	if (ifa != NULL)
635 		iter->context[0] = CK_STAILQ_NEXT(ifa, ifa_link);
636 	return (ifa);
637 }
638 
639 void
640 ifa_iter_finish(struct ifa_iter *iter)
641 {
642 	/* Nothing to do here for now. */
643 }
644 #endif
645 
646 int
if_setsoftc(if_t ifp,void * softc)647 if_setsoftc(if_t ifp, void *softc)
648 {
649 	ifp->if_softc = softc;
650 	return (0);
651 }
652 
653 void *
if_getsoftc(const if_t ifp)654 if_getsoftc(const if_t ifp)
655 {
656 	return (ifp->if_softc);
657 }
658 
659 void
if_setrcvif(struct mbuf * m,if_t ifp)660 if_setrcvif(struct mbuf *m, if_t ifp)
661 {
662 #if 0
663 	MPASS((m->m_pkthdr.csum_flags & CSUM_SND_TAG) == 0);
664 #endif
665 	m->m_pkthdr.rcvif = (struct ifnet *)ifp;
666 }
667 
668 void
if_setvtag(struct mbuf * m,uint16_t tag)669 if_setvtag(struct mbuf *m, uint16_t tag)
670 {
671 	m->m_pkthdr.ether_vtag = tag;
672 }
673 
674 uint16_t
if_getvtag(struct mbuf * m)675 if_getvtag(struct mbuf *m)
676 {
677 	return (m->m_pkthdr.ether_vtag);
678 }
679 
680 int
if_sendq_empty(if_t ifp)681 if_sendq_empty(if_t ifp)
682 {
683 	return (IFQ_DRV_IS_EMPTY(&ifp->if_snd));
684 }
685 
686 struct ifaddr *
if_getifaddr(const if_t ifp)687 if_getifaddr(const if_t ifp)
688 {
689 	return (ifp->if_addr);
690 }
691 
692 int
if_getamcount(const if_t ifp)693 if_getamcount(const if_t ifp)
694 {
695 	return (ifp->if_amcount);
696 }
697 
698 int
if_setsendqready(if_t ifp)699 if_setsendqready(if_t ifp)
700 {
701 	IFQ_SET_READY(&ifp->if_snd);
702 	return (0);
703 }
704 
705 int
if_setsendqlen(if_t ifp,int tx_desc_count)706 if_setsendqlen(if_t ifp, int tx_desc_count)
707 {
708 	IFQ_SET_MAXLEN(&ifp->if_snd, tx_desc_count);
709 	ifp->if_snd.ifq_drv_maxlen = tx_desc_count;
710 	return (0);
711 }
712 
713 #if 0
714 void
715 if_setnetmapadapter(if_t ifp, struct netmap_adapter *na)
716 {
717 	ifp->if_netmap = na;
718 }
719 
720 struct netmap_adapter *
721 if_getnetmapadapter(if_t ifp)
722 {
723 	return (ifp->if_netmap);
724 }
725 #endif
726 
727 int
if_vlantrunkinuse(if_t ifp)728 if_vlantrunkinuse(if_t ifp)
729 {
730 	return (ifp->if_vlantrunk != NULL);
731 }
732 
733 void
if_init(if_t ifp,void * ctx)734 if_init(if_t ifp, void *ctx)
735 {
736 	(*ifp->if_init)(ctx);
737 }
738 
739 void
if_input(if_t ifp,struct mbuf * sendmp)740 if_input(if_t ifp, struct mbuf* sendmp)
741 {
742 	(*ifp->if_input)(ifp, sendmp);
743 }
744 
745 int
if_transmit(if_t ifp,struct mbuf * m)746 if_transmit(if_t ifp, struct mbuf *m)
747 {
748 	return ((*ifp->if_transmit)(ifp, m));
749 }
750 
751 int
if_resolvemulti(if_t ifp,struct sockaddr ** srcs,struct sockaddr * dst)752 if_resolvemulti(if_t ifp, struct sockaddr **srcs, struct sockaddr *dst)
753 {
754 	if (ifp->if_resolvemulti == NULL)
755 		return (EOPNOTSUPP);
756 
757 	return (ifp->if_resolvemulti(ifp, srcs, dst));
758 }
759 
760 int
if_ioctl(if_t ifp,u_long cmd,void * data)761 if_ioctl(if_t ifp, u_long cmd, void *data)
762 {
763 	if (ifp->if_ioctl == NULL)
764 		return (EOPNOTSUPP);
765 
766 	return (ifp->if_ioctl(ifp, cmd, (caddr_t)data));
767 }
768 
769 struct mbuf *
if_dequeue(if_t ifp)770 if_dequeue(if_t ifp)
771 {
772 	struct mbuf *m;
773 
774 	IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
775 	return (m);
776 }
777 
778 int
if_sendq_prepend(if_t ifp,struct mbuf * m)779 if_sendq_prepend(if_t ifp, struct mbuf *m)
780 {
781 	IFQ_DRV_PREPEND(&ifp->if_snd, m);
782 	return (0);
783 }
784 
785 int
if_setifheaderlen(if_t ifp,int len)786 if_setifheaderlen(if_t ifp, int len)
787 {
788 	ifp->if_hdrlen = len;
789 	return (0);
790 }
791 
792 caddr_t
if_getlladdr(const if_t ifp)793 if_getlladdr(const if_t ifp)
794 {
795 	return (IF_LLADDR(ifp));
796 }
797 
798 void *
if_gethandle(u_char type)799 if_gethandle(u_char type)
800 {
801 	return (if_alloc(type));
802 }
803 
804 void
if_vlancap(if_t ifp)805 if_vlancap(if_t ifp)
806 {
807 	VLAN_CAPABILITIES(ifp);
808 }
809 
810 int
if_sethwtsomax(if_t ifp,u_int if_hw_tsomax)811 if_sethwtsomax(if_t ifp, u_int if_hw_tsomax)
812 {
813 	ifp->if_hw_tsomax = if_hw_tsomax;
814 		return (0);
815 }
816 
817 int
if_sethwtsomaxsegcount(if_t ifp,u_int if_hw_tsomaxsegcount)818 if_sethwtsomaxsegcount(if_t ifp, u_int if_hw_tsomaxsegcount)
819 {
820 	ifp->if_hw_tsomaxsegcount = if_hw_tsomaxsegcount;
821 		return (0);
822 }
823 
824 int
if_sethwtsomaxsegsize(if_t ifp,u_int if_hw_tsomaxsegsize)825 if_sethwtsomaxsegsize(if_t ifp, u_int if_hw_tsomaxsegsize)
826 {
827 	ifp->if_hw_tsomaxsegsize = if_hw_tsomaxsegsize;
828 		return (0);
829 }
830 
831 u_int
if_gethwtsomax(const if_t ifp)832 if_gethwtsomax(const if_t ifp)
833 {
834 	return (ifp->if_hw_tsomax);
835 }
836 
837 u_int
if_gethwtsomaxsegcount(const if_t ifp)838 if_gethwtsomaxsegcount(const if_t ifp)
839 {
840 	return (ifp->if_hw_tsomaxsegcount);
841 }
842 
843 u_int
if_gethwtsomaxsegsize(const if_t ifp)844 if_gethwtsomaxsegsize(const if_t ifp)
845 {
846 	return (ifp->if_hw_tsomaxsegsize);
847 }
848 
849 void
if_setinitfn(if_t ifp,if_init_fn_t init_fn)850 if_setinitfn(if_t ifp, if_init_fn_t init_fn)
851 {
852 	ifp->if_init = init_fn;
853 }
854 
855 #if 0
856 void
857 if_setinputfn(if_t ifp, if_input_fn_t input_fn)
858 {
859 	ifp->if_input = input_fn;
860 }
861 
862 if_input_fn_t
863 if_getinputfn(if_t ifp)
864 {
865 	return (ifp->if_input);
866 }
867 #endif
868 
869 void
if_setioctlfn(if_t ifp,if_ioctl_fn_t ioctl_fn)870 if_setioctlfn(if_t ifp, if_ioctl_fn_t ioctl_fn)
871 {
872 	ifp->if_ioctl = ioctl_fn;
873 }
874 
875 #if 0
876 void
877 if_setoutputfn(if_t ifp, if_output_fn_t output_fn)
878 {
879 	ifp->if_output = output_fn;
880 }
881 #endif
882 
883 void
if_setstartfn(if_t ifp,if_start_fn_t start_fn)884 if_setstartfn(if_t ifp, if_start_fn_t start_fn)
885 {
886 	ifp->if_start = start_fn;
887 }
888 
889 if_start_fn_t
if_getstartfn(if_t ifp)890 if_getstartfn(if_t ifp)
891 {
892 	return (ifp->if_start);
893 }
894 
895 void
if_settransmitfn(if_t ifp,if_transmit_fn_t start_fn)896 if_settransmitfn(if_t ifp, if_transmit_fn_t start_fn)
897 {
898 	ifp->if_transmit = start_fn;
899 }
900 
901 if_transmit_fn_t
if_gettransmitfn(if_t ifp)902 if_gettransmitfn(if_t ifp)
903 {
904 	return (ifp->if_transmit);
905 }
906 
907 void
if_setqflushfn(if_t ifp,if_qflush_fn_t flush_fn)908 if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn)
909 {
910 	ifp->if_qflush = flush_fn;
911 }
912 
913 #if 0
914 void
915 if_setsndtagallocfn(if_t ifp, if_snd_tag_alloc_t alloc_fn)
916 {
917 	ifp->if_snd_tag_alloc = alloc_fn;
918 }
919 
920 int
921 if_snd_tag_alloc(if_t ifp, union if_snd_tag_alloc_params *params,
922 	struct m_snd_tag **mstp)
923 {
924 	if (ifp->if_snd_tag_alloc == NULL)
925 		return (EOPNOTSUPP);
926 	return (ifp->if_snd_tag_alloc(ifp, params, mstp));
927 }
928 #endif
929 
930 void
if_setgetcounterfn(if_t ifp,if_get_counter_t fn)931 if_setgetcounterfn(if_t ifp, if_get_counter_t fn)
932 {
933 	ifp->if_get_counter = fn;
934 }
935 
936 #if 0
937 void
938 if_setreassignfn(if_t ifp, if_reassign_fn_t fn)
939 {
940 	ifp->if_reassign = fn;
941 }
942 
943 void
944 if_setratelimitqueryfn(if_t ifp, if_ratelimit_query_t fn)
945 {
946 	ifp->if_ratelimit_query = fn;
947 }
948 
949 void
950 if_setdebugnet_methods(if_t ifp, struct debugnet_methods *m)
951 {
952 	ifp->if_debugnet_methods = m;
953 }
954 #endif
955 
956 struct label *
if_getmaclabel(if_t ifp)957 if_getmaclabel(if_t ifp)
958 {
959 	return (ifp->if_label);
960 }
961 
962 void
if_setmaclabel(if_t ifp,struct label * label)963 if_setmaclabel(if_t ifp, struct label *label)
964 {
965 	ifp->if_label = label;
966 }
967 
968 int
if_gettype(if_t ifp)969 if_gettype(if_t ifp)
970 {
971 	return (ifp->if_type);
972 }
973 
974 #if 0
975 void *
976 if_getllsoftc(if_t ifp)
977 {
978 	return (ifp->if_llsoftc);
979 }
980 
981 void
982 if_setllsoftc(if_t ifp, void *llsoftc)
983 {
984 	ifp->if_llsoftc = llsoftc;
985 }
986 #endif
987 
988 int
if_getlinkstate(if_t ifp)989 if_getlinkstate(if_t ifp)
990 {
991 	return (ifp->if_link_state);
992 }
993 
994 const uint8_t *
if_getbroadcastaddr(if_t ifp)995 if_getbroadcastaddr(if_t ifp)
996 {
997 	return (ifp->if_broadcastaddr);
998 }
999 
1000 void
if_setbroadcastaddr(if_t ifp,const uint8_t * addr)1001 if_setbroadcastaddr(if_t ifp, const uint8_t *addr)
1002 {
1003 	ifp->if_broadcastaddr = addr;
1004 }
1005 
1006 #if 0
1007 int
1008 if_getnumadomain(if_t ifp)
1009 {
1010 	return (ifp->if_numa_domain);
1011 }
1012 #endif
1013 
1014 uint64_t
if_getcounter(if_t ifp,ift_counter counter)1015 if_getcounter(if_t ifp, ift_counter counter)
1016 {
1017 	return (ifp->if_get_counter(ifp, counter));
1018 }
1019 
1020 bool
if_altq_is_enabled(if_t ifp)1021 if_altq_is_enabled(if_t ifp)
1022 {
1023 	return (ALTQ_IS_ENABLED(&ifp->if_snd));
1024 }
1025 
1026 #if 0
1027 struct vnet *
1028 if_getvnet(if_t ifp)
1029 {
1030 	return (ifp->if_vnet);
1031 }
1032 #endif
1033 
1034 void *
if_getafdata(if_t ifp,int af)1035 if_getafdata(if_t ifp, int af)
1036 {
1037 	return (ifp->if_afdata[af]);
1038 }
1039 
1040 #if 0
1041 u_int
1042 if_getfib(if_t ifp)
1043 {
1044 	return (ifp->if_fib);
1045 }
1046 #endif
1047 
1048 uint8_t
if_getaddrlen(if_t ifp)1049 if_getaddrlen(if_t ifp)
1050 {
1051 	return (ifp->if_addrlen);
1052 }
1053 
1054 struct bpf_if *
if_getbpf(if_t ifp)1055 if_getbpf(if_t ifp)
1056 {
1057 	return (ifp->if_bpf);
1058 }
1059 
1060 struct ifvlantrunk *
if_getvlantrunk(if_t ifp)1061 if_getvlantrunk(if_t ifp)
1062 {
1063 	return (ifp->if_vlantrunk);
1064 }
1065 
1066 #if 0
1067 uint8_t
1068 if_getpcp(if_t ifp)
1069 {
1070 	return (ifp->if_pcp);
1071 }
1072 #endif
1073 
1074 void *
if_getl2com(if_t ifp)1075 if_getl2com(if_t ifp)
1076 {
1077 	return (ifp->if_l2com);
1078 }
1079