xref: /haiku/src/libs/compat/freebsd_network/if.c (revision a5c0d1a80e18f50987966fda2005210092d7671b)
1 /*
2  * Copyright 2009, Colin Günther, coling@gmx.de.
3  * Copyright 2007-2009, Axel Dörfler, axeld@pinc-software.de.
4  * Copyright 2007, Hugo Santos. All Rights Reserved.
5  * Copyright 2004, Marcus Overhagen. All Rights Reserved.
6  *
7  * Distributed under the terms of the MIT License.
8  */
9 
10 
11 #include "device.h"
12 
13 #include <stdio.h>
14 #include <net/if_types.h>
15 #include <sys/sockio.h>
16 
17 #include <compat/sys/bus.h>
18 #include <compat/sys/kernel.h>
19 #include <compat/sys/taskqueue.h>
20 
21 #include <compat/net/bpf.h>
22 #include <compat/net/ethernet.h>
23 #include <compat/net/if.h>
24 #include <compat/net/if_arp.h>
25 #include <compat/net/if_media.h>
26 #include <compat/net/if_var.h>
27 #include <compat/net/if_vlan_var.h>
28 #include <compat/sys/malloc.h>
29 
30 
31 
32 int ifqmaxlen = IFQ_MAXLEN;
33 
34 static void	if_input_default(struct ifnet *, struct mbuf *);
35 static int	if_requestencap_default(struct ifnet *, struct if_encap_req *);
36 
37 
38 
39 #define IFNET_HOLD (void *)(uintptr_t)(-1)
40 
41 
42 static void
43 insert_into_device_name_list(struct ifnet * ifp)
44 {
45 	int i;
46 	for (i = 0; i < MAX_DEVICES; i++) {
47 		if (gDeviceNameList[i] == NULL) {
48 			gDeviceNameList[i] = ifp->device_name;
49 			return;
50 		}
51 	}
52 
53 	panic("too many devices");
54 }
55 
56 
57 static void
58 remove_from_device_name_list(struct ifnet * ifp)
59 {
60 	int i;
61 	for (i = 0; i < MAX_DEVICES; i++) {
62 		if (ifp->device_name == gDeviceNameList[i]) {
63 			int last;
64 			for (last = i + 1; last < MAX_DEVICES; last++) {
65 				if (gDeviceNameList[last] == NULL)
66 					break;
67 			}
68 			last--;
69 
70 			if (i == last)
71 				gDeviceNameList[i] = NULL;
72 			else {
73 				// switch positions with the last entry
74 				gDeviceNameList[i] = gDeviceNameList[last];
75 				gDeviceNameList[last] = NULL;
76 			}
77 			break;
78 		}
79 	}
80 }
81 
82 
83 struct ifnet *
84 ifnet_byindex(u_short idx)
85 {
86 	struct ifnet *ifp;
87 
88 	IFNET_RLOCK_NOSLEEP();
89 	ifp = ifnet_byindex_locked(idx);
90 	IFNET_RUNLOCK_NOSLEEP();
91 
92 	return (ifp);
93 }
94 
95 
96 struct ifnet *
97 ifnet_byindex_locked(u_short idx)
98 {
99 	struct ifnet *ifp;
100 
101 	ifp = gDevices[idx];
102 
103 	return (ifp);
104 }
105 
106 
107 static void
108 ifnet_setbyindex_locked(u_short idx, struct ifnet *ifp)
109 {
110 	gDevices[idx] = ifp;
111 }
112 
113 
114 static void
115 ifnet_setbyindex(u_short idx, struct ifnet *ifp)
116 {
117 	IFNET_WLOCK();
118 	ifnet_setbyindex_locked(idx, ifp);
119 	IFNET_WUNLOCK();
120 }
121 
122 
123 static int
124 ifindex_alloc_locked(u_short *idxp)
125 {
126 	u_short index;
127 
128 	for (index = 0; index < MAX_DEVICES; index++) {
129 		if (gDevices[index] == NULL) {
130 			break;
131 		}
132 	}
133 
134 	if (index == MAX_DEVICES)
135 		return ENOSPC;
136 
137 	gDeviceCount++;
138 	*idxp = index;
139 
140 	return ENOERR;
141 }
142 
143 
144 static void
145 ifindex_free_locked(u_short idx)
146 {
147 	gDevices[idx] = NULL;
148 	gDeviceCount--;
149 }
150 
151 
152 struct ifnet *
153 if_alloc(u_char type)
154 {
155 	char semName[64];
156 	u_short index;
157 
158 	struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
159 	if (ifp == NULL)
160 		return NULL;
161 
162 	snprintf(semName, sizeof(semName), "%s receive", gDriverName);
163 
164 	ifp->receive_sem = create_sem(0, semName);
165 	if (ifp->receive_sem < B_OK)
166 		goto err1;
167 
168 	switch (type) {
169 		case IFT_ETHER:
170 		{
171 			ifp->if_l2com = _kernel_malloc(sizeof(struct arpcom), M_ZERO);
172 			if (ifp->if_l2com == NULL)
173 				goto err2;
174 			IFP2AC(ifp)->ac_ifp = ifp;
175 			break;
176 		}
177 	}
178 
179 	ifp->link_state_sem = -1;
180 	ifp->open_count = 0;
181 	ifp->flags = 0;
182 	ifp->if_type = type;
183 	ifq_init(&ifp->receive_queue, semName);
184 
185 	ifp->scan_done_sem = -1;
186 		// WLAN specific, doesn't hurt when initilized for other devices
187 
188 	// Search for the first free device slot, and use that one
189 	IFNET_WLOCK();
190 	if (ifindex_alloc_locked(&index) != ENOERR) {
191 		IFNET_WUNLOCK();
192 		panic("too many devices");
193 		goto err3;
194 	}
195 	ifnet_setbyindex_locked(index, IFNET_HOLD);
196 	IFNET_WUNLOCK();
197 
198 	ifp->if_index = index;
199 	ifnet_setbyindex(ifp->if_index, ifp);
200 
201 	IF_ADDR_LOCK_INIT(ifp);
202 	return ifp;
203 
204 err3:
205 	switch (type) {
206 		case IFT_ETHER:
207 			_kernel_free(ifp->if_l2com);
208 			break;
209 	}
210 
211 err2:
212 	delete_sem(ifp->receive_sem);
213 
214 err1:
215 	_kernel_free(ifp);
216 	return NULL;
217 }
218 
219 
220 void
221 if_free(struct ifnet *ifp)
222 {
223 	// IEEE80211 devices won't be in this list,
224 	// so don't try to remove them.
225 	if (ifp->if_type == IFT_ETHER)
226 		remove_from_device_name_list(ifp);
227 
228 	IFNET_WLOCK();
229 	ifindex_free_locked(ifp->if_index);
230 	IFNET_WUNLOCK();
231 
232 	IF_ADDR_LOCK_DESTROY(ifp);
233 	switch (ifp->if_type) {
234 		case IFT_ETHER:
235 			_kernel_free(ifp->if_l2com);
236 			break;
237 	}
238 
239 	delete_sem(ifp->receive_sem);
240 	ifq_uninit(&ifp->receive_queue);
241 
242 	_kernel_free(ifp);
243 }
244 
245 
246 void
247 if_initname(struct ifnet *ifp, const char *name, int unit)
248 {
249 	dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit);
250 
251 	if (name == NULL || name[0] == '\0')
252 		panic("interface goes unnamed");
253 
254 	ifp->if_dname = name;
255 	ifp->if_dunit = unit;
256 
257 	strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
258 
259 	snprintf(ifp->device_name, sizeof(ifp->device_name), "net/%s/%i",
260 		gDriverName, ifp->if_index);
261 
262 	driver_printf("%s: /dev/%s\n", gDriverName, ifp->device_name);
263 	insert_into_device_name_list(ifp);
264 
265 	ifp->root_device = find_root_device(unit);
266 }
267 
268 
269 void
270 ifq_init(struct ifqueue *ifq, const char *name)
271 {
272 	ifq->ifq_head = NULL;
273 	ifq->ifq_tail = NULL;
274 	ifq->ifq_len = 0;
275 	ifq->ifq_maxlen = IFQ_MAXLEN;
276 	ifq->ifq_drops = 0;
277 
278 	mtx_init(&ifq->ifq_mtx, name, NULL, MTX_DEF);
279 }
280 
281 
282 void
283 ifq_uninit(struct ifqueue *ifq)
284 {
285 	mtx_destroy(&ifq->ifq_mtx);
286 }
287 
288 
289 static int
290 if_transmit(struct ifnet *ifp, struct mbuf *m)
291 {
292 	int error;
293 
294 	IFQ_HANDOFF(ifp, m, error);
295 	return (error);
296 }
297 
298 
299 static void
300 if_input_default(struct ifnet *ifp __unused, struct mbuf *m)
301 {
302 
303 	m_freem(m);
304 }
305 
306 
307 /*
308  * Flush an interface queue.
309  */
310 void
311 if_qflush(struct ifnet *ifp)
312 {
313 	struct mbuf *m, *n;
314 	struct ifaltq *ifq;
315 
316 	ifq = &ifp->if_snd;
317 	IFQ_LOCK(ifq);
318 #ifdef ALTQ
319 	if (ALTQ_IS_ENABLED(ifq))
320 		ALTQ_PURGE(ifq);
321 #endif
322 	n = ifq->ifq_head;
323 	while ((m = n) != NULL) {
324 		n = m->m_nextpkt;
325 		m_freem(m);
326 	}
327 	ifq->ifq_head = 0;
328 	ifq->ifq_tail = 0;
329 	ifq->ifq_len = 0;
330 	IFQ_UNLOCK(ifq);
331 }
332 
333 
334 void
335 if_attach(struct ifnet *ifp)
336 {
337 	unsigned socksize, ifasize;
338 	int namelen, masklen;
339 	struct sockaddr_dl *sdl;
340 	struct ifaddr *ifa;
341 
342 	TAILQ_INIT(&ifp->if_addrhead);
343 	TAILQ_INIT(&ifp->if_prefixhead);
344 	TAILQ_INIT(&ifp->if_multiaddrs);
345 
346 	IF_ADDR_LOCK_INIT(ifp);
347 
348 	ifp->if_lladdr.sdl_family = AF_LINK;
349 
350 	ifq_init((struct ifqueue *) &ifp->if_snd, ifp->if_xname);
351 
352 	if (ifp->if_transmit == NULL) {
353 		ifp->if_transmit = if_transmit;
354 		ifp->if_qflush = if_qflush;
355 	}
356 	if (ifp->if_input == NULL)
357 		ifp->if_input = if_input_default;
358 
359 	if (ifp->if_requestencap == NULL)
360 		ifp->if_requestencap = if_requestencap_default;
361 
362 	/*
363 	 * Create a Link Level name for this device.
364 	 */
365 	namelen = strlen(ifp->if_xname);
366 	/*
367 	 * Always save enough space for any possiable name so we
368 	 * can do a rename in place later.
369 	 */
370 	masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + IFNAMSIZ;
371 	socksize = masklen + ifp->if_addrlen;
372 	if (socksize < sizeof(*sdl))
373 		socksize = sizeof(*sdl);
374 	socksize = roundup2(socksize, sizeof(long));
375 	ifasize = sizeof(*ifa) + 2 * socksize;
376 	ifa = ifa_alloc(ifasize, M_WAITOK);
377 	sdl = (struct sockaddr_dl *)(ifa + 1);
378 	sdl->sdl_len = socksize;
379 	sdl->sdl_family = AF_LINK;
380 	bcopy(ifp->if_xname, sdl->sdl_data, namelen);
381 	sdl->sdl_nlen = namelen;
382 	sdl->sdl_index = ifp->if_index;
383 	sdl->sdl_type = ifp->if_type;
384 	ifp->if_addr = ifa;
385 	ifa->ifa_ifp = ifp;
386 	//ifa->ifa_rtrequest = link_rtrequest;
387 	ifa->ifa_addr = (struct sockaddr *)sdl;
388 	sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
389 	ifa->ifa_netmask = (struct sockaddr *)sdl;
390 	sdl->sdl_len = masklen;
391 	while (namelen != 0)
392 		sdl->sdl_data[--namelen] = 0xff;
393 	dprintf("if_attach %p\n", ifa->ifa_addr);
394 }
395 
396 
397 void
398 if_detach(struct ifnet *ifp)
399 {
400 	if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE))
401 		taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
402 
403 	IF_ADDR_LOCK_DESTROY(ifp);
404 	ifq_uninit((struct ifqueue *) &ifp->if_snd);
405 }
406 
407 
408 void
409 if_start(struct ifnet *ifp)
410 {
411 #ifdef IFF_NEEDSGIANT
412 	if (ifp->if_flags & IFF_NEEDSGIANT)
413 	panic("freebsd compat.: unsupported giant requirement");
414 #endif
415 	ifp->if_start(ifp);
416 }
417 
418 
419 int
420 if_printf(struct ifnet *ifp, const char *format, ...)
421 {
422 	char buf[256];
423 	va_list vl;
424 	va_start(vl, format);
425 	vsnprintf(buf, sizeof(buf), format, vl);
426 	va_end(vl);
427 
428 	dprintf("[%s] %s", ifp->device_name, buf);
429 	return 0;
430 }
431 
432 
433 /*
434  * Compat function for handling basic encapsulation requests.
435  * Not converted stacks (FDDI, IB, ..) supports traditional
436  * output model: ARP (and other similar L2 protocols) are handled
437  * inside output routine, arpresolve/nd6_resolve() returns MAC
438  * address instead of full prepend.
439  *
440  * This function creates calculated header==MAC for IPv4/IPv6 and
441  * returns EAFNOSUPPORT (which is then handled in ARP code) for other
442  * address families.
443  */
444 static int
445 if_requestencap_default(struct ifnet *ifp, struct if_encap_req *req)
446 {
447 
448 	if (req->rtype != IFENCAP_LL)
449 		return (EOPNOTSUPP);
450 
451 	if (req->bufsize < req->lladdr_len)
452 		return (ENOMEM);
453 
454 	switch (req->family) {
455 	case AF_INET:
456 	case AF_INET6:
457 		break;
458 	default:
459 		return (EAFNOSUPPORT);
460 	}
461 
462 	/* Copy lladdr to storage as is */
463 	memmove(req->buf, req->lladdr, req->lladdr_len);
464 	req->bufsize = req->lladdr_len;
465 	req->lladdr_off = 0;
466 
467 	return (0);
468 }
469 
470 
471 void
472 if_link_state_change(struct ifnet *ifp, int linkState)
473 {
474 	if (ifp->if_link_state == linkState)
475 		return;
476 
477 	ifp->if_link_state = linkState;
478 	release_sem_etc(ifp->link_state_sem, 1, B_DO_NOT_RESCHEDULE);
479 }
480 
481 static struct ifmultiaddr *
482 if_findmulti(struct ifnet *ifp, struct sockaddr *_address)
483 {
484 	struct sockaddr_dl *address = (struct sockaddr_dl *) _address;
485 	struct ifmultiaddr *ifma;
486 
487 	TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link) {
488 		if (memcmp(LLADDR(address),
489 			LLADDR((struct sockaddr_dl *)ifma->ifma_addr), ETHER_ADDR_LEN) == 0)
490 			return ifma;
491 	}
492 
493 	return NULL;
494 }
495 
496 
497 /*
498  * if_freemulti: free ifmultiaddr structure and possibly attached related
499  * addresses.  The caller is responsible for implementing reference
500  * counting, notifying the driver, handling routing messages, and releasing
501  * any dependent link layer state.
502  */
503 static void
504 if_freemulti(struct ifmultiaddr *ifma)
505 {
506 
507 	KASSERT(ifma->ifma_refcount == 0, ("if_freemulti: refcount %d",
508 	    ifma->ifma_refcount));
509 	KASSERT(ifma->ifma_protospec == NULL,
510 	    ("if_freemulti: protospec not NULL"));
511 
512 	if (ifma->ifma_lladdr != NULL)
513 		free(ifma->ifma_lladdr);
514 
515 	// Haiku note: We use a field in the ifmultiaddr struct (ifma_addr_storage)
516 	// to store the address and let ifma_addr point to that. We therefore do not
517 	// free it here, as it will be freed as part of freeing the if_multiaddr.
518 	//free(ifma->ifma_addr);
519 
520 	free(ifma);
521 }
522 
523 
524 static struct ifmultiaddr *
525 _if_addmulti(struct ifnet *ifp, struct sockaddr *address)
526 {
527 	struct ifmultiaddr *addr = if_findmulti(ifp, address);
528 
529 	if (addr != NULL) {
530 		addr->ifma_refcount++;
531 		return addr;
532 	}
533 
534 	addr = (struct ifmultiaddr *) malloc(sizeof(struct ifmultiaddr));
535 	if (addr == NULL)
536 		return NULL;
537 
538 	addr->ifma_lladdr = NULL;
539 	addr->ifma_ifp = ifp;
540 	addr->ifma_protospec = NULL;
541 
542 	memcpy(&addr->ifma_addr_storage, address, sizeof(struct sockaddr_dl));
543 	addr->ifma_addr = (struct sockaddr *) &addr->ifma_addr_storage;
544 
545 	addr->ifma_refcount = 1;
546 
547 	TAILQ_INSERT_HEAD(&ifp->if_multiaddrs, addr, ifma_link);
548 
549 	return addr;
550 }
551 
552 
553 int
554 if_addmulti(struct ifnet *ifp, struct sockaddr *address,
555 	struct ifmultiaddr **out)
556 {
557 	struct ifmultiaddr *result;
558 	int refcount = 0;
559 
560 	IF_ADDR_LOCK(ifp);
561 	result = _if_addmulti(ifp, address);
562 	if (result)
563 		refcount = result->ifma_refcount;
564 	IF_ADDR_UNLOCK(ifp);
565 
566 	if (result == NULL)
567 		return ENOBUFS;
568 
569 	if (refcount == 1 && ifp->if_ioctl != NULL)
570 		ifp->if_ioctl(ifp, SIOCADDMULTI, NULL);
571 
572 	if (out)
573 		(*out) = result;
574 
575 	return 0;
576 }
577 
578 
579 static int
580 if_delmulti_locked(struct ifnet *ifp, struct ifmultiaddr *ifma, int detaching)
581 {
582 	struct ifmultiaddr *ll_ifma;
583 
584 	if (ifp != NULL && ifma->ifma_ifp != NULL) {
585 		KASSERT(ifma->ifma_ifp == ifp,
586 		    ("%s: inconsistent ifp %p", __func__, ifp));
587 		IF_ADDR_LOCK_ASSERT(ifp);
588 	}
589 
590 	ifp = ifma->ifma_ifp;
591 
592 	/*
593 	 * If the ifnet is detaching, null out references to ifnet,
594 	 * so that upper protocol layers will notice, and not attempt
595 	 * to obtain locks for an ifnet which no longer exists. The
596 	 * routing socket announcement must happen before the ifnet
597 	 * instance is detached from the system.
598 	 */
599 	if (detaching) {
600 #ifdef DIAGNOSTIC
601 		printf("%s: detaching ifnet instance %p\n", __func__, ifp);
602 #endif
603 		/*
604 		 * ifp may already be nulled out if we are being reentered
605 		 * to delete the ll_ifma.
606 		 */
607 		if (ifp != NULL) {
608 #ifndef __HAIKU__
609 			rt_newmaddrmsg(RTM_DELMADDR, ifma);
610 #endif
611 			ifma->ifma_ifp = NULL;
612 		}
613 	}
614 
615 	if (--ifma->ifma_refcount > 0)
616 		return 0;
617 
618 #ifndef __HAIKU__
619 	/*
620 	 * If this ifma is a network-layer ifma, a link-layer ifma may
621 	 * have been associated with it. Release it first if so.
622 	 */
623 	ll_ifma = ifma->ifma_llifma;
624 	if (ll_ifma != NULL) {
625 		KASSERT(ifma->ifma_lladdr != NULL,
626 		    ("%s: llifma w/o lladdr", __func__));
627 		if (detaching)
628 			ll_ifma->ifma_ifp = NULL;	/* XXX */
629 		if (--ll_ifma->ifma_refcount == 0) {
630 			if (ifp != NULL) {
631 				TAILQ_REMOVE(&ifp->if_multiaddrs, ll_ifma,
632 				    ifma_link);
633 			}
634 			if_freemulti(ll_ifma);
635 		}
636 	}
637 #endif
638 
639 	if (ifp != NULL)
640 		TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
641 
642 	if_freemulti(ifma);
643 
644 	/*
645 	 * The last reference to this instance of struct ifmultiaddr
646 	 * was released; the hardware should be notified of this change.
647 	 */
648 	return 1;
649 }
650 
651 
652 /*
653  * Delete all multicast group membership for an interface.
654  * Should be used to quickly flush all multicast filters.
655  */
656 void
657 if_delallmulti(struct ifnet *ifp)
658 {
659 	struct ifmultiaddr *ifma;
660 	struct ifmultiaddr *next;
661 
662 	IF_ADDR_LOCK(ifp);
663 	TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
664 		if_delmulti_locked(ifp, ifma, 0);
665 	IF_ADDR_UNLOCK(ifp);
666 }
667 
668 
669 static void
670 if_delete_multiaddr(struct ifnet *ifp, struct ifmultiaddr *ifma)
671 {
672 	TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
673 	free(ifma);
674 }
675 
676 
677 int
678 if_delmulti(struct ifnet *ifp, struct sockaddr *sa)
679 {
680 	struct ifmultiaddr *ifma;
681 	int lastref;
682 #if 0 /* def INVARIANTS */
683 	struct ifnet *oifp;
684 
685 	IFNET_RLOCK_NOSLEEP();
686 	TAILQ_FOREACH(oifp, &V_ifnet, if_link)
687 		if (ifp == oifp)
688 			break;
689 	if (ifp != oifp)
690 		ifp = NULL;
691 	IFNET_RUNLOCK_NOSLEEP();
692 
693 	KASSERT(ifp != NULL, ("%s: ifnet went away", __func__));
694 #endif
695 	if (ifp == NULL)
696 		return (ENOENT);
697 
698 	IF_ADDR_LOCK(ifp);
699 	lastref = 0;
700 	ifma = if_findmulti(ifp, sa);
701 	if (ifma != NULL)
702 		lastref = if_delmulti_locked(ifp, ifma, 0);
703 	IF_ADDR_UNLOCK(ifp);
704 
705 	if (ifma == NULL)
706 		return (ENOENT);
707 
708 	if (lastref && ifp->if_ioctl != NULL) {
709 		(void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0);
710 	}
711 
712 	return (0);
713 }
714 
715 
716 void
717 if_purgemaddrs(struct ifnet *ifp)
718 {
719 	struct ifmultiaddr *ifma;
720 	struct ifmultiaddr *next;
721 
722 	IF_ADDR_LOCK(ifp);
723 	TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
724 		if_delmulti_locked(ifp, ifma, 1);
725 	IF_ADDR_UNLOCK(ifp);
726 }
727 
728 /*
729  * Return counter values from counter(9)s stored in ifnet.
730  */
731 uint64_t
732 if_get_counter_default(struct ifnet *ifp, ift_counter cnt)
733 {
734 
735 	KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
736 
737 	switch (cnt) {
738 		case IFCOUNTER_IPACKETS:
739 			return atomic_get64((int64 *)&ifp->if_ipackets);
740 		case IFCOUNTER_IERRORS:
741 			return atomic_get64((int64 *)&ifp->if_ierrors);
742 		case IFCOUNTER_OPACKETS:
743 			return atomic_get64((int64 *)&ifp->if_opackets);
744 		case IFCOUNTER_OERRORS:
745 			return atomic_get64((int64 *)&ifp->if_oerrors);
746 		case IFCOUNTER_COLLISIONS:
747 			return atomic_get64((int64 *)&ifp->if_collisions);
748 		case IFCOUNTER_IBYTES:
749 			return atomic_get64((int64 *)&ifp->if_ibytes);
750 		case IFCOUNTER_OBYTES:
751 			return atomic_get64((int64 *)&ifp->if_obytes);
752 		case IFCOUNTER_IMCASTS:
753 			return atomic_get64((int64 *)&ifp->if_imcasts);
754 		case IFCOUNTER_OMCASTS:
755 			return atomic_get64((int64 *)&ifp->if_omcasts);
756 		case IFCOUNTER_IQDROPS:
757 			return atomic_get64((int64 *)&ifp->if_iqdrops);
758 		case IFCOUNTER_OQDROPS:
759 			return atomic_get64((int64 *)&ifp->if_oqdrops);
760 		case IFCOUNTER_NOPROTO:
761 			return atomic_get64((int64 *)&ifp->if_noproto);
762 		case IFCOUNTERS:
763 			KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
764 	}
765 	return 0;
766 }
767 
768 void
769 if_addr_rlock(struct ifnet *ifp)
770 {
771 	IF_ADDR_LOCK(ifp);
772 }
773 
774 
775 void
776 if_addr_runlock(struct ifnet *ifp)
777 {
778 	IF_ADDR_UNLOCK(ifp);
779 }
780 
781 
782 void
783 if_maddr_rlock(struct ifnet *ifp)
784 {
785 	IF_ADDR_LOCK(ifp);
786 }
787 
788 
789 void
790 if_maddr_runlock(struct ifnet *ifp)
791 {
792 	IF_ADDR_UNLOCK(ifp);
793 }
794 
795 
796 int
797 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
798 	struct route *ro)
799 {
800 	int error = 0;
801 	IFQ_HANDOFF(ifp, m, error);
802 	return error;
803 }
804 
805 
806 static void ether_input(struct ifnet *ifp, struct mbuf *m)
807 {
808 	IF_ENQUEUE(&ifp->receive_queue, m);
809 	release_sem_etc(ifp->receive_sem, 1, B_DO_NOT_RESCHEDULE);
810 }
811 
812 
813 void
814 ether_ifattach(struct ifnet *ifp, const uint8_t *lla)
815 {
816 	struct ifaddr *ifa;
817 	struct sockaddr_dl *sdl;
818 
819 	ifp->if_addrlen = ETHER_ADDR_LEN;
820 	ifp->if_hdrlen = ETHER_HDR_LEN;
821 	if_attach(ifp);
822 	ifp->if_mtu = ETHERMTU;
823 	ifp->if_output = ether_output;
824 	ifp->if_input = ether_input;
825 	ifp->if_resolvemulti = NULL; // done in the stack
826 	ifp->if_get_counter = NULL;
827 	ifp->if_broadcastaddr = etherbroadcastaddr;
828 
829 	ifa = ifp->if_addr;
830 	sdl = (struct sockaddr_dl *)ifa->ifa_addr;
831 	sdl->sdl_type = IFT_ETHER;
832 	sdl->sdl_alen = ifp->if_addrlen;
833 	bcopy(lla, LLADDR(sdl), ifp->if_addrlen);
834 }
835 
836 
837 void
838 ether_ifdetach(struct ifnet *ifp)
839 {
840 	if_detach(ifp);
841 }
842 
843 
844 int
845 ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
846 {
847 	struct ifreq *ifr = (struct ifreq *) data;
848 
849 	//dprintf("ether_ioctl: received %d\n", command);
850 
851 	switch (command) {
852 		case SIOCSIFMTU:
853 			if (ifr->ifr_mtu > ETHERMTU_JUMBO)
854 				return EINVAL;
855 			ifp->if_mtu = ifr->ifr_mtu;
856 			break;
857 
858 		default:
859 			return EINVAL;
860 	}
861 
862 	return 0;
863 }
864 
865 
866 /*
867  * Initialization, destruction and refcounting functions for ifaddrs.
868  */
869 struct ifaddr *
870 ifa_alloc(size_t size, int flags)
871 {
872 	struct ifaddr *ifa;
873 
874 	KASSERT(size >= sizeof(struct ifaddr),
875 	    ("%s: invalid size %zu", __func__, size));
876 
877 	ifa = _kernel_malloc(size, M_ZERO | flags);
878 	if (ifa == NULL)
879 		return (NULL);
880 
881 	//refcount_init(&ifa->ifa_refcnt, 1);
882 
883 	return (ifa);
884 
885 fail:
886 	/* free(NULL) is okay */
887 	free(ifa);
888 
889 	return (NULL);
890 }
891 
892 void
893 ifa_ref(struct ifaddr *ifa)
894 {
895 	//refcount_acquire(&ifa->ifa_refcnt);
896 }
897 
898 void
899 ifa_free(struct ifaddr *ifa)
900 {
901 
902 	//if (refcount_release(&ifa->ifa_refcnt)) {
903 	//	free(ifa);
904 	//}
905 }
906 
907 void
908 if_inc_counter(struct ifnet *ifp, ift_counter cnt, int64_t inc)
909 {
910 	switch (cnt) {
911 		case IFCOUNTER_IPACKETS:
912 			atomic_add64((int64 *)&ifp->if_ipackets, inc);
913 			break;
914 		case IFCOUNTER_IERRORS:
915 			atomic_add64((int64 *)&ifp->if_ierrors, inc);
916 			break;
917 		case IFCOUNTER_OPACKETS:
918 			atomic_add64((int64 *)&ifp->if_opackets, inc);
919 			break;
920 		case IFCOUNTER_OERRORS:
921 			atomic_add64((int64 *)&ifp->if_oerrors, inc);
922 			break;
923 		case IFCOUNTER_COLLISIONS:
924 			atomic_add64((int64 *)&ifp->if_collisions, inc);
925 			break;
926 		case IFCOUNTER_IBYTES:
927 			atomic_add64((int64 *)&ifp->if_ibytes, inc);
928 			break;
929 		case IFCOUNTER_OBYTES:
930 			atomic_add64((int64 *)&ifp->if_obytes, inc);
931 			break;
932 		case IFCOUNTER_IMCASTS:
933 			atomic_add64((int64 *)&ifp->if_imcasts, inc);
934 			break;
935 		case IFCOUNTER_OMCASTS:
936 			atomic_add64((int64 *)&ifp->if_omcasts, inc);
937 			break;
938 		case IFCOUNTER_IQDROPS:
939 			atomic_add64((int64 *)&ifp->if_iqdrops, inc);
940 			break;
941 		case IFCOUNTER_OQDROPS:
942 			atomic_add64((int64 *)&ifp->if_oqdrops, inc);
943 			break;
944 		case IFCOUNTER_NOPROTO:
945 			atomic_add64((int64 *)&ifp->if_noproto, inc);
946 			break;
947 		case IFCOUNTERS:
948 			KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
949 	}
950 }
951 
952 
953 /* API for driver access to network stack owned ifnet.*/
954 uint64_t
955 if_setbaudrate(struct ifnet *ifp, uint64_t baudrate)
956 {
957 	uint64_t oldbrate;
958 
959 	oldbrate = ifp->if_baudrate;
960 	ifp->if_baudrate = baudrate;
961 	return (oldbrate);
962 }
963 
964 uint64_t
965 if_getbaudrate(if_t ifp)
966 {
967 
968 	return (((struct ifnet *)ifp)->if_baudrate);
969 }
970 
971 int
972 if_setcapabilities(if_t ifp, int capabilities)
973 {
974 	((struct ifnet *)ifp)->if_capabilities = capabilities;
975 	return (0);
976 }
977 
978 int
979 if_setcapabilitiesbit(if_t ifp, int setbit, int clearbit)
980 {
981 	((struct ifnet *)ifp)->if_capabilities |= setbit;
982 	((struct ifnet *)ifp)->if_capabilities &= ~clearbit;
983 
984 	return (0);
985 }
986 
987 int
988 if_getcapabilities(if_t ifp)
989 {
990 	return ((struct ifnet *)ifp)->if_capabilities;
991 }
992 
993 int
994 if_setcapenable(if_t ifp, int capabilities)
995 {
996 	((struct ifnet *)ifp)->if_capenable = capabilities;
997 	return (0);
998 }
999 
1000 int
1001 if_setcapenablebit(if_t ifp, int setcap, int clearcap)
1002 {
1003 	if(setcap)
1004 		((struct ifnet *)ifp)->if_capenable |= setcap;
1005 	if(clearcap)
1006 		((struct ifnet *)ifp)->if_capenable &= ~clearcap;
1007 
1008 	return (0);
1009 }
1010 
1011 const char *
1012 if_getdname(if_t ifp)
1013 {
1014 	return ((struct ifnet *)ifp)->if_dname;
1015 }
1016 
1017 int
1018 if_togglecapenable(if_t ifp, int togglecap)
1019 {
1020 	((struct ifnet *)ifp)->if_capenable ^= togglecap;
1021 	return (0);
1022 }
1023 
1024 int
1025 if_getcapenable(if_t ifp)
1026 {
1027 	return ((struct ifnet *)ifp)->if_capenable;
1028 }
1029 
1030 /*
1031  * This is largely undesirable because it ties ifnet to a device, but does
1032  * provide flexiblity for an embedded product vendor. Should be used with
1033  * the understanding that it violates the interface boundaries, and should be
1034  * a last resort only.
1035  */
1036 int
1037 if_setdev(if_t ifp, void *dev)
1038 {
1039 	return (0);
1040 }
1041 
1042 int
1043 if_setdrvflagbits(if_t ifp, int set_flags, int clear_flags)
1044 {
1045 	((struct ifnet *)ifp)->if_drv_flags |= set_flags;
1046 	((struct ifnet *)ifp)->if_drv_flags &= ~clear_flags;
1047 
1048 	return (0);
1049 }
1050 
1051 int
1052 if_getdrvflags(if_t ifp)
1053 {
1054 	if ((struct ifnet *)ifp == NULL)
1055 		return 0;
1056 	return ((struct ifnet *)ifp)->if_drv_flags;
1057 }
1058 
1059 int
1060 if_setdrvflags(if_t ifp, int flags)
1061 {
1062 	((struct ifnet *)ifp)->if_drv_flags = flags;
1063 	return (0);
1064 }
1065 
1066 
1067 int
1068 if_setflags(if_t ifp, int flags)
1069 {
1070 	((struct ifnet *)ifp)->if_flags = flags;
1071 	return (0);
1072 }
1073 
1074 int
1075 if_setflagbits(if_t ifp, int set, int clear)
1076 {
1077 	((struct ifnet *)ifp)->if_flags |= set;
1078 	((struct ifnet *)ifp)->if_flags &= ~clear;
1079 
1080 	return (0);
1081 }
1082 
1083 int
1084 if_getflags(if_t ifp)
1085 {
1086 	return ((struct ifnet *)ifp)->if_flags;
1087 }
1088 
1089 int
1090 if_clearhwassist(if_t ifp)
1091 {
1092 	((struct ifnet *)ifp)->if_hwassist = 0;
1093 	return (0);
1094 }
1095 
1096 int
1097 if_sethwassistbits(if_t ifp, int toset, int toclear)
1098 {
1099 	((struct ifnet *)ifp)->if_hwassist |= toset;
1100 	((struct ifnet *)ifp)->if_hwassist &= ~toclear;
1101 
1102 	return (0);
1103 }
1104 
1105 int
1106 if_sethwassist(if_t ifp, int hwassist_bit)
1107 {
1108 	((struct ifnet *)ifp)->if_hwassist = hwassist_bit;
1109 	return (0);
1110 }
1111 
1112 int
1113 if_gethwassist(if_t ifp)
1114 {
1115 	return ((struct ifnet *)ifp)->if_hwassist;
1116 }
1117 
1118 int
1119 if_setmtu(if_t ifp, int mtu)
1120 {
1121 	((struct ifnet *)ifp)->if_mtu = mtu;
1122 	return (0);
1123 }
1124 
1125 int
1126 if_getmtu(if_t ifp)
1127 {
1128 	return ((struct ifnet *)ifp)->if_mtu;
1129 }
1130 
1131 int
1132 if_setsoftc(if_t ifp, void *softc)
1133 {
1134 	((struct ifnet *)ifp)->if_softc = softc;
1135 	return (0);
1136 }
1137 
1138 void *
1139 if_getsoftc(if_t ifp)
1140 {
1141 	return ((struct ifnet *)ifp)->if_softc;
1142 }
1143 
1144 void
1145 if_setrcvif(struct mbuf *m, if_t ifp)
1146 {
1147 	m->m_pkthdr.rcvif = (struct ifnet *)ifp;
1148 }
1149 
1150 void
1151 if_setvtag(struct mbuf *m, uint16_t tag)
1152 {
1153 	m->m_pkthdr.ether_vtag = tag;
1154 }
1155 
1156 uint16_t
1157 if_getvtag(struct mbuf *m)
1158 {
1159 
1160 	return (m->m_pkthdr.ether_vtag);
1161 }
1162 
1163 int
1164 if_sendq_empty(if_t ifp)
1165 {
1166 	return IFQ_DRV_IS_EMPTY(&((struct ifnet *)ifp)->if_snd);
1167 }
1168 
1169 int
1170 if_getamcount(if_t ifp)
1171 {
1172 	return ((struct ifnet *)ifp)->if_amcount;
1173 }
1174 
1175 
1176 int
1177 if_setsendqready(if_t ifp)
1178 {
1179 	IFQ_SET_READY(&((struct ifnet *)ifp)->if_snd);
1180 	return (0);
1181 }
1182 
1183 int
1184 if_setsendqlen(if_t ifp, int tx_desc_count)
1185 {
1186 	IFQ_SET_MAXLEN(&((struct ifnet *)ifp)->if_snd, tx_desc_count);
1187 	((struct ifnet *)ifp)->if_snd.ifq_drv_maxlen = tx_desc_count;
1188 
1189 	return (0);
1190 }
1191 
1192 int
1193 if_vlantrunkinuse(if_t ifp)
1194 {
1195 	return ((struct ifnet *)ifp)->if_vlantrunk != NULL?1:0;
1196 }
1197 
1198 int
1199 if_input(if_t ifp, struct mbuf* sendmp)
1200 {
1201 	(*((struct ifnet *)ifp)->if_input)((struct ifnet *)ifp, sendmp);
1202 	return (0);
1203 
1204 }
1205 
1206 /* XXX */
1207 #ifndef ETH_ADDR_LEN
1208 #define ETH_ADDR_LEN 6
1209 #endif
1210 
1211 int
1212 if_setupmultiaddr(if_t ifp, void *mta, int *cnt, int max)
1213 {
1214 	struct ifmultiaddr *ifma;
1215 	uint8_t *lmta = (uint8_t *)mta;
1216 	int mcnt = 0;
1217 
1218 	TAILQ_FOREACH(ifma, &((struct ifnet *)ifp)->if_multiaddrs, ifma_link) {
1219 		if (ifma->ifma_addr->sa_family != AF_LINK)
1220 			continue;
1221 
1222 		if (mcnt == max)
1223 			break;
1224 
1225 		bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1226 		    &lmta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN);
1227 		mcnt++;
1228 	}
1229 	*cnt = mcnt;
1230 
1231 	return (0);
1232 }
1233 
1234 int
1235 if_multiaddr_array(if_t ifp, void *mta, int *cnt, int max)
1236 {
1237 	int error;
1238 
1239 	if_maddr_rlock(ifp);
1240 	error = if_setupmultiaddr(ifp, mta, cnt, max);
1241 	if_maddr_runlock(ifp);
1242 	return (error);
1243 }
1244 
1245 int
1246 if_multiaddr_count(if_t ifp, int max)
1247 {
1248 	struct ifmultiaddr *ifma;
1249 	int count;
1250 
1251 	count = 0;
1252 	if_maddr_rlock(ifp);
1253 	TAILQ_FOREACH(ifma, &((struct ifnet *)ifp)->if_multiaddrs, ifma_link) {
1254 		if (ifma->ifma_addr->sa_family != AF_LINK)
1255 			continue;
1256 		count++;
1257 		if (count == max)
1258 			break;
1259 	}
1260 	if_maddr_runlock(ifp);
1261 	return (count);
1262 }
1263 
1264 u_int
1265 if_llmaddr_count(if_t ifp)
1266 {
1267 	struct ifmultiaddr *ifma;
1268 	int count;
1269 
1270 	count = 0;
1271 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1272 		if (ifma->ifma_addr->sa_family == AF_LINK)
1273 			count++;
1274 	}
1275 
1276 	return (count);
1277 }
1278 
1279 u_int
1280 if_foreach_llmaddr(if_t ifp, iflladdr_cb_t cb, void *cb_arg)
1281 {
1282 	struct ifmultiaddr *ifma;
1283 	u_int count;
1284 
1285 	count = 0;
1286 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1287 		if (ifma->ifma_addr->sa_family != AF_LINK)
1288 			continue;
1289 		count += (*cb)(cb_arg, (struct sockaddr_dl *)ifma->ifma_addr,
1290 			count);
1291 	}
1292 
1293 	return (count);
1294 }
1295 
1296 struct mbuf *
1297 if_dequeue(if_t ifp)
1298 {
1299 	struct mbuf *m;
1300 	IFQ_DRV_DEQUEUE(&((struct ifnet *)ifp)->if_snd, m);
1301 
1302 	return (m);
1303 }
1304 
1305 int
1306 if_sendq_prepend(if_t ifp, struct mbuf *m)
1307 {
1308 	IFQ_DRV_PREPEND(&((struct ifnet *)ifp)->if_snd, m);
1309 	return (0);
1310 }
1311 
1312 int
1313 if_setifheaderlen(if_t ifp, int len)
1314 {
1315 	((struct ifnet *)ifp)->if_hdrlen = len;
1316 	return (0);
1317 }
1318 
1319 caddr_t
1320 if_getlladdr(if_t ifp)
1321 {
1322 	return (IF_LLADDR((struct ifnet *)ifp));
1323 }
1324 
1325 void *
1326 if_gethandle(u_char type)
1327 {
1328 	return (if_alloc(type));
1329 }
1330 
1331 void
1332 if_bpfmtap(if_t ifh, struct mbuf *m)
1333 {
1334 	struct ifnet *ifp = (struct ifnet *)ifh;
1335 
1336 	BPF_MTAP(ifp, m);
1337 }
1338 
1339 void
1340 if_etherbpfmtap(if_t ifh, struct mbuf *m)
1341 {
1342 	struct ifnet *ifp = (struct ifnet *)ifh;
1343 
1344 	ETHER_BPF_MTAP(ifp, m);
1345 }
1346 
1347 void
1348 if_vlancap(if_t ifh)
1349 {
1350 	struct ifnet *ifp = (struct ifnet *)ifh;
1351 	VLAN_CAPABILITIES(ifp);
1352 }
1353 
1354 void
1355 if_setinitfn(if_t ifp, void (*init_fn)(void *))
1356 {
1357 	((struct ifnet *)ifp)->if_init = init_fn;
1358 }
1359 
1360 void
1361 if_setioctlfn(if_t ifp, int (*ioctl_fn)(if_t, u_long, caddr_t))
1362 {
1363 	((struct ifnet *)ifp)->if_ioctl = (void *)ioctl_fn;
1364 }
1365 
1366 void
1367 if_setstartfn(if_t ifp, void (*start_fn)(if_t))
1368 {
1369 	((struct ifnet *)ifp)->if_start = (void *)start_fn;
1370 }
1371 
1372 void
1373 if_settransmitfn(if_t ifp, if_transmit_fn_t start_fn)
1374 {
1375 	((struct ifnet *)ifp)->if_transmit = start_fn;
1376 }
1377 
1378 void if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn)
1379 {
1380 	((struct ifnet *)ifp)->if_qflush = flush_fn;
1381 }
1382 
1383 void
1384 if_setgetcounterfn(if_t ifp, if_get_counter_t fn)
1385 {
1386 
1387 	ifp->if_get_counter = fn;
1388 }
1389 
1390