xref: /haiku/src/libs/compat/freebsd_network/if.c (revision 4c8e85b316c35a9161f5a1c50ad70bc91c83a76f)
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 	switch (command) {
850 		case SIOCSIFMTU:
851 			if (ifr->ifr_mtu > ETHERMTU)
852 				return EINVAL;
853 			else
854 				;
855 			// need to fix our ifreq to work with C...
856 			// ifp->ifr_mtu = ifr->ifr_mtu;
857 			break;
858 
859 		default:
860 			return EINVAL;
861 	}
862 
863 	return 0;
864 }
865 
866 
867 /*
868  * Initialization, destruction and refcounting functions for ifaddrs.
869  */
870 struct ifaddr *
871 ifa_alloc(size_t size, int flags)
872 {
873 	struct ifaddr *ifa;
874 
875 	KASSERT(size >= sizeof(struct ifaddr),
876 	    ("%s: invalid size %zu", __func__, size));
877 
878 	ifa = _kernel_malloc(size, M_ZERO | flags);
879 	if (ifa == NULL)
880 		return (NULL);
881 
882 	//refcount_init(&ifa->ifa_refcnt, 1);
883 
884 	return (ifa);
885 
886 fail:
887 	/* free(NULL) is okay */
888 	free(ifa);
889 
890 	return (NULL);
891 }
892 
893 void
894 ifa_ref(struct ifaddr *ifa)
895 {
896 	//refcount_acquire(&ifa->ifa_refcnt);
897 }
898 
899 void
900 ifa_free(struct ifaddr *ifa)
901 {
902 
903 	//if (refcount_release(&ifa->ifa_refcnt)) {
904 	//	free(ifa);
905 	//}
906 }
907 
908 void
909 if_inc_counter(struct ifnet *ifp, ift_counter cnt, int64_t inc)
910 {
911 	switch (cnt) {
912 		case IFCOUNTER_IPACKETS:
913 			atomic_add64((int64 *)&ifp->if_ipackets, inc);
914 			break;
915 		case IFCOUNTER_IERRORS:
916 			atomic_add64((int64 *)&ifp->if_ierrors, inc);
917 			break;
918 		case IFCOUNTER_OPACKETS:
919 			atomic_add64((int64 *)&ifp->if_opackets, inc);
920 			break;
921 		case IFCOUNTER_OERRORS:
922 			atomic_add64((int64 *)&ifp->if_oerrors, inc);
923 			break;
924 		case IFCOUNTER_COLLISIONS:
925 			atomic_add64((int64 *)&ifp->if_collisions, inc);
926 			break;
927 		case IFCOUNTER_IBYTES:
928 			atomic_add64((int64 *)&ifp->if_ibytes, inc);
929 			break;
930 		case IFCOUNTER_OBYTES:
931 			atomic_add64((int64 *)&ifp->if_obytes, inc);
932 			break;
933 		case IFCOUNTER_IMCASTS:
934 			atomic_add64((int64 *)&ifp->if_imcasts, inc);
935 			break;
936 		case IFCOUNTER_OMCASTS:
937 			atomic_add64((int64 *)&ifp->if_omcasts, inc);
938 			break;
939 		case IFCOUNTER_IQDROPS:
940 			atomic_add64((int64 *)&ifp->if_iqdrops, inc);
941 			break;
942 		case IFCOUNTER_OQDROPS:
943 			atomic_add64((int64 *)&ifp->if_oqdrops, inc);
944 			break;
945 		case IFCOUNTER_NOPROTO:
946 			atomic_add64((int64 *)&ifp->if_noproto, inc);
947 			break;
948 		case IFCOUNTERS:
949 			KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
950 	}
951 }
952 
953 
954 /* API for driver access to network stack owned ifnet.*/
955 uint64_t
956 if_setbaudrate(struct ifnet *ifp, uint64_t baudrate)
957 {
958 	uint64_t oldbrate;
959 
960 	oldbrate = ifp->if_baudrate;
961 	ifp->if_baudrate = baudrate;
962 	return (oldbrate);
963 }
964 
965 uint64_t
966 if_getbaudrate(if_t ifp)
967 {
968 
969 	return (((struct ifnet *)ifp)->if_baudrate);
970 }
971 
972 int
973 if_setcapabilities(if_t ifp, int capabilities)
974 {
975 	((struct ifnet *)ifp)->if_capabilities = capabilities;
976 	return (0);
977 }
978 
979 int
980 if_setcapabilitiesbit(if_t ifp, int setbit, int clearbit)
981 {
982 	((struct ifnet *)ifp)->if_capabilities |= setbit;
983 	((struct ifnet *)ifp)->if_capabilities &= ~clearbit;
984 
985 	return (0);
986 }
987 
988 int
989 if_getcapabilities(if_t ifp)
990 {
991 	return ((struct ifnet *)ifp)->if_capabilities;
992 }
993 
994 int
995 if_setcapenable(if_t ifp, int capabilities)
996 {
997 	((struct ifnet *)ifp)->if_capenable = capabilities;
998 	return (0);
999 }
1000 
1001 int
1002 if_setcapenablebit(if_t ifp, int setcap, int clearcap)
1003 {
1004 	if(setcap)
1005 		((struct ifnet *)ifp)->if_capenable |= setcap;
1006 	if(clearcap)
1007 		((struct ifnet *)ifp)->if_capenable &= ~clearcap;
1008 
1009 	return (0);
1010 }
1011 
1012 const char *
1013 if_getdname(if_t ifp)
1014 {
1015 	return ((struct ifnet *)ifp)->if_dname;
1016 }
1017 
1018 int
1019 if_togglecapenable(if_t ifp, int togglecap)
1020 {
1021 	((struct ifnet *)ifp)->if_capenable ^= togglecap;
1022 	return (0);
1023 }
1024 
1025 int
1026 if_getcapenable(if_t ifp)
1027 {
1028 	return ((struct ifnet *)ifp)->if_capenable;
1029 }
1030 
1031 /*
1032  * This is largely undesirable because it ties ifnet to a device, but does
1033  * provide flexiblity for an embedded product vendor. Should be used with
1034  * the understanding that it violates the interface boundaries, and should be
1035  * a last resort only.
1036  */
1037 int
1038 if_setdev(if_t ifp, void *dev)
1039 {
1040 	return (0);
1041 }
1042 
1043 int
1044 if_setdrvflagbits(if_t ifp, int set_flags, int clear_flags)
1045 {
1046 	((struct ifnet *)ifp)->if_drv_flags |= set_flags;
1047 	((struct ifnet *)ifp)->if_drv_flags &= ~clear_flags;
1048 
1049 	return (0);
1050 }
1051 
1052 int
1053 if_getdrvflags(if_t ifp)
1054 {
1055 	if ((struct ifnet *)ifp == NULL)
1056 		return 0;
1057 	return ((struct ifnet *)ifp)->if_drv_flags;
1058 }
1059 
1060 int
1061 if_setdrvflags(if_t ifp, int flags)
1062 {
1063 	((struct ifnet *)ifp)->if_drv_flags = flags;
1064 	return (0);
1065 }
1066 
1067 
1068 int
1069 if_setflags(if_t ifp, int flags)
1070 {
1071 	((struct ifnet *)ifp)->if_flags = flags;
1072 	return (0);
1073 }
1074 
1075 int
1076 if_setflagbits(if_t ifp, int set, int clear)
1077 {
1078 	((struct ifnet *)ifp)->if_flags |= set;
1079 	((struct ifnet *)ifp)->if_flags &= ~clear;
1080 
1081 	return (0);
1082 }
1083 
1084 int
1085 if_getflags(if_t ifp)
1086 {
1087 	return ((struct ifnet *)ifp)->if_flags;
1088 }
1089 
1090 int
1091 if_clearhwassist(if_t ifp)
1092 {
1093 	((struct ifnet *)ifp)->if_hwassist = 0;
1094 	return (0);
1095 }
1096 
1097 int
1098 if_sethwassistbits(if_t ifp, int toset, int toclear)
1099 {
1100 	((struct ifnet *)ifp)->if_hwassist |= toset;
1101 	((struct ifnet *)ifp)->if_hwassist &= ~toclear;
1102 
1103 	return (0);
1104 }
1105 
1106 int
1107 if_sethwassist(if_t ifp, int hwassist_bit)
1108 {
1109 	((struct ifnet *)ifp)->if_hwassist = hwassist_bit;
1110 	return (0);
1111 }
1112 
1113 int
1114 if_gethwassist(if_t ifp)
1115 {
1116 	return ((struct ifnet *)ifp)->if_hwassist;
1117 }
1118 
1119 int
1120 if_setmtu(if_t ifp, int mtu)
1121 {
1122 	((struct ifnet *)ifp)->if_mtu = mtu;
1123 	return (0);
1124 }
1125 
1126 int
1127 if_getmtu(if_t ifp)
1128 {
1129 	return ((struct ifnet *)ifp)->if_mtu;
1130 }
1131 
1132 int
1133 if_setsoftc(if_t ifp, void *softc)
1134 {
1135 	((struct ifnet *)ifp)->if_softc = softc;
1136 	return (0);
1137 }
1138 
1139 void *
1140 if_getsoftc(if_t ifp)
1141 {
1142 	return ((struct ifnet *)ifp)->if_softc;
1143 }
1144 
1145 void
1146 if_setrcvif(struct mbuf *m, if_t ifp)
1147 {
1148 	m->m_pkthdr.rcvif = (struct ifnet *)ifp;
1149 }
1150 
1151 void
1152 if_setvtag(struct mbuf *m, uint16_t tag)
1153 {
1154 	m->m_pkthdr.ether_vtag = tag;
1155 }
1156 
1157 uint16_t
1158 if_getvtag(struct mbuf *m)
1159 {
1160 
1161 	return (m->m_pkthdr.ether_vtag);
1162 }
1163 
1164 int
1165 if_sendq_empty(if_t ifp)
1166 {
1167 	return IFQ_DRV_IS_EMPTY(&((struct ifnet *)ifp)->if_snd);
1168 }
1169 
1170 int
1171 if_getamcount(if_t ifp)
1172 {
1173 	return ((struct ifnet *)ifp)->if_amcount;
1174 }
1175 
1176 
1177 int
1178 if_setsendqready(if_t ifp)
1179 {
1180 	IFQ_SET_READY(&((struct ifnet *)ifp)->if_snd);
1181 	return (0);
1182 }
1183 
1184 int
1185 if_setsendqlen(if_t ifp, int tx_desc_count)
1186 {
1187 	IFQ_SET_MAXLEN(&((struct ifnet *)ifp)->if_snd, tx_desc_count);
1188 	((struct ifnet *)ifp)->if_snd.ifq_drv_maxlen = tx_desc_count;
1189 
1190 	return (0);
1191 }
1192 
1193 int
1194 if_vlantrunkinuse(if_t ifp)
1195 {
1196 	return ((struct ifnet *)ifp)->if_vlantrunk != NULL?1:0;
1197 }
1198 
1199 int
1200 if_input(if_t ifp, struct mbuf* sendmp)
1201 {
1202 	(*((struct ifnet *)ifp)->if_input)((struct ifnet *)ifp, sendmp);
1203 	return (0);
1204 
1205 }
1206 
1207 /* XXX */
1208 #ifndef ETH_ADDR_LEN
1209 #define ETH_ADDR_LEN 6
1210 #endif
1211 
1212 int
1213 if_setupmultiaddr(if_t ifp, void *mta, int *cnt, int max)
1214 {
1215 	struct ifmultiaddr *ifma;
1216 	uint8_t *lmta = (uint8_t *)mta;
1217 	int mcnt = 0;
1218 
1219 	TAILQ_FOREACH(ifma, &((struct ifnet *)ifp)->if_multiaddrs, ifma_link) {
1220 		if (ifma->ifma_addr->sa_family != AF_LINK)
1221 			continue;
1222 
1223 		if (mcnt == max)
1224 			break;
1225 
1226 		bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1227 		    &lmta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN);
1228 		mcnt++;
1229 	}
1230 	*cnt = mcnt;
1231 
1232 	return (0);
1233 }
1234 
1235 int
1236 if_multiaddr_array(if_t ifp, void *mta, int *cnt, int max)
1237 {
1238 	int error;
1239 
1240 	if_maddr_rlock(ifp);
1241 	error = if_setupmultiaddr(ifp, mta, cnt, max);
1242 	if_maddr_runlock(ifp);
1243 	return (error);
1244 }
1245 
1246 int
1247 if_multiaddr_count(if_t ifp, int max)
1248 {
1249 	struct ifmultiaddr *ifma;
1250 	int count;
1251 
1252 	count = 0;
1253 	if_maddr_rlock(ifp);
1254 	TAILQ_FOREACH(ifma, &((struct ifnet *)ifp)->if_multiaddrs, ifma_link) {
1255 		if (ifma->ifma_addr->sa_family != AF_LINK)
1256 			continue;
1257 		count++;
1258 		if (count == max)
1259 			break;
1260 	}
1261 	if_maddr_runlock(ifp);
1262 	return (count);
1263 }
1264 
1265 u_int
1266 if_llmaddr_count(if_t ifp)
1267 {
1268 	struct ifmultiaddr *ifma;
1269 	int count;
1270 
1271 	count = 0;
1272 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1273 		if (ifma->ifma_addr->sa_family == AF_LINK)
1274 			count++;
1275 	}
1276 
1277 	return (count);
1278 }
1279 
1280 u_int
1281 if_foreach_llmaddr(if_t ifp, iflladdr_cb_t cb, void *cb_arg)
1282 {
1283 	struct ifmultiaddr *ifma;
1284 	u_int count;
1285 
1286 	count = 0;
1287 	TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
1288 		if (ifma->ifma_addr->sa_family != AF_LINK)
1289 			continue;
1290 		count += (*cb)(cb_arg, (struct sockaddr_dl *)ifma->ifma_addr,
1291 			count);
1292 	}
1293 
1294 	return (count);
1295 }
1296 
1297 struct mbuf *
1298 if_dequeue(if_t ifp)
1299 {
1300 	struct mbuf *m;
1301 	IFQ_DRV_DEQUEUE(&((struct ifnet *)ifp)->if_snd, m);
1302 
1303 	return (m);
1304 }
1305 
1306 int
1307 if_sendq_prepend(if_t ifp, struct mbuf *m)
1308 {
1309 	IFQ_DRV_PREPEND(&((struct ifnet *)ifp)->if_snd, m);
1310 	return (0);
1311 }
1312 
1313 int
1314 if_setifheaderlen(if_t ifp, int len)
1315 {
1316 	((struct ifnet *)ifp)->if_hdrlen = len;
1317 	return (0);
1318 }
1319 
1320 caddr_t
1321 if_getlladdr(if_t ifp)
1322 {
1323 	return (IF_LLADDR((struct ifnet *)ifp));
1324 }
1325 
1326 void *
1327 if_gethandle(u_char type)
1328 {
1329 	return (if_alloc(type));
1330 }
1331 
1332 void
1333 if_bpfmtap(if_t ifh, struct mbuf *m)
1334 {
1335 	struct ifnet *ifp = (struct ifnet *)ifh;
1336 
1337 	BPF_MTAP(ifp, m);
1338 }
1339 
1340 void
1341 if_etherbpfmtap(if_t ifh, struct mbuf *m)
1342 {
1343 	struct ifnet *ifp = (struct ifnet *)ifh;
1344 
1345 	ETHER_BPF_MTAP(ifp, m);
1346 }
1347 
1348 void
1349 if_vlancap(if_t ifh)
1350 {
1351 	struct ifnet *ifp = (struct ifnet *)ifh;
1352 	VLAN_CAPABILITIES(ifp);
1353 }
1354 
1355 void
1356 if_setinitfn(if_t ifp, void (*init_fn)(void *))
1357 {
1358 	((struct ifnet *)ifp)->if_init = init_fn;
1359 }
1360 
1361 void
1362 if_setioctlfn(if_t ifp, int (*ioctl_fn)(if_t, u_long, caddr_t))
1363 {
1364 	((struct ifnet *)ifp)->if_ioctl = (void *)ioctl_fn;
1365 }
1366 
1367 void
1368 if_setstartfn(if_t ifp, void (*start_fn)(if_t))
1369 {
1370 	((struct ifnet *)ifp)->if_start = (void *)start_fn;
1371 }
1372 
1373 void
1374 if_settransmitfn(if_t ifp, if_transmit_fn_t start_fn)
1375 {
1376 	((struct ifnet *)ifp)->if_transmit = start_fn;
1377 }
1378 
1379 void if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn)
1380 {
1381 	((struct ifnet *)ifp)->if_qflush = flush_fn;
1382 }
1383 
1384 void
1385 if_setgetcounterfn(if_t ifp, if_get_counter_t fn)
1386 {
1387 
1388 	ifp->if_get_counter = fn;
1389 }
1390 
1391