HaikuDepot: notify work status from main window
[haiku.git] / src / libs / compat / freebsd11_network / if.c
blob723f0dc4e2853da2158fb1a759e1cacda7a347b8
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.
7 * Distributed under the terms of the MIT License.
8 */
11 #include "device.h"
13 #include <stdio.h>
14 #include <net/if_types.h>
15 #include <sys/sockio.h>
17 #include <compat/sys/bus.h>
18 #include <compat/sys/kernel.h>
19 #include <compat/sys/taskqueue.h>
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>
32 int ifqmaxlen = IFQ_MAXLEN;
34 static void if_input_default(struct ifnet *, struct mbuf *);
35 static int if_requestencap_default(struct ifnet *, struct if_encap_req *);
39 #define IFNET_HOLD (void *)(uintptr_t)(-1)
42 static void
43 insert_into_device_name_list(struct ifnet * ifp)
45 int i;
46 for (i = 0; i < MAX_DEVICES; i++) {
47 if (gDeviceNameList[i] == NULL) {
48 gDeviceNameList[i] = ifp->device_name;
49 return;
53 panic("too many devices");
57 static void
58 remove_from_device_name_list(struct ifnet * ifp)
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;
68 last--;
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;
77 break;
83 struct ifnet *
84 ifnet_byindex(u_short idx)
86 struct ifnet *ifp;
88 IFNET_RLOCK_NOSLEEP();
89 ifp = ifnet_byindex_locked(idx);
90 IFNET_RUNLOCK_NOSLEEP();
92 return (ifp);
96 struct ifnet *
97 ifnet_byindex_locked(u_short idx)
99 struct ifnet *ifp;
101 ifp = gDevices[idx];
103 return (ifp);
107 static void
108 ifnet_setbyindex_locked(u_short idx, struct ifnet *ifp)
110 gDevices[idx] = ifp;
114 static void
115 ifnet_setbyindex(u_short idx, struct ifnet *ifp)
117 IFNET_WLOCK();
118 ifnet_setbyindex_locked(idx, ifp);
119 IFNET_WUNLOCK();
123 static int
124 ifindex_alloc_locked(u_short *idxp)
126 u_short index;
128 for (index = 0; index < MAX_DEVICES; index++) {
129 if (gDevices[index] == NULL) {
130 break;
134 if (index == MAX_DEVICES)
135 return ENOSPC;
137 gDeviceCount++;
138 *idxp = index;
140 return ENOERR;
144 static void
145 ifindex_free_locked(u_short idx)
147 gDevices[idx] = NULL;
148 gDeviceCount--;
152 struct ifnet *
153 if_alloc(u_char type)
155 char semName[64];
156 u_short index;
158 struct ifnet *ifp = _kernel_malloc(sizeof(struct ifnet), M_ZERO);
159 if (ifp == NULL)
160 return NULL;
162 snprintf(semName, sizeof(semName), "%s receive", gDriverName);
164 ifp->receive_sem = create_sem(0, semName);
165 if (ifp->receive_sem < B_OK)
166 goto err1;
168 switch (type) {
169 case IFT_ETHER:
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;
177 case IFT_IEEE80211:
179 if (wlan_if_l2com_alloc(ifp) != B_OK)
180 goto err2;
181 break;
185 ifp->link_state_sem = -1;
186 ifp->open_count = 0;
187 ifp->flags = 0;
188 ifp->if_type = type;
189 ifq_init(&ifp->receive_queue, semName);
191 ifp->scan_done_sem = -1;
192 // WLAN specific, doesn't hurt when initilized for other devices
194 // Search for the first free device slot, and use that one
195 IFNET_WLOCK();
196 if (ifindex_alloc_locked(&index) != ENOERR) {
197 IFNET_WUNLOCK();
198 panic("too many devices");
199 goto err3;
201 ifnet_setbyindex_locked(index, IFNET_HOLD);
202 IFNET_WUNLOCK();
204 ifp->if_index = index;
205 ifnet_setbyindex(ifp->if_index, ifp);
207 IF_ADDR_LOCK_INIT(ifp);
208 return ifp;
210 err3:
211 switch (type) {
212 case IFT_ETHER:
213 case IFT_IEEE80211:
214 _kernel_free(ifp->if_l2com);
215 break;
218 err2:
219 delete_sem(ifp->receive_sem);
221 err1:
222 _kernel_free(ifp);
223 return NULL;
227 void
228 if_free(struct ifnet *ifp)
230 // IEEE80211 devices won't be in this list,
231 // so don't try to remove them.
232 if (ifp->if_type == IFT_ETHER)
233 remove_from_device_name_list(ifp);
235 IFNET_WLOCK();
236 ifindex_free_locked(ifp->if_index);
237 IFNET_WUNLOCK();
239 IF_ADDR_LOCK_DESTROY(ifp);
240 switch (ifp->if_type) {
241 case IFT_ETHER:
242 case IFT_IEEE80211:
243 _kernel_free(ifp->if_l2com);
244 break;
247 delete_sem(ifp->receive_sem);
248 ifq_uninit(&ifp->receive_queue);
250 _kernel_free(ifp);
254 void
255 if_initname(struct ifnet *ifp, const char *name, int unit)
257 dprintf("if_initname(%p, %s, %d)\n", ifp, name, unit);
259 if (name == NULL || name[0] == '\0')
260 panic("interface goes unnamed");
262 ifp->if_dname = name;
263 ifp->if_dunit = unit;
265 strlcpy(ifp->if_xname, name, sizeof(ifp->if_xname));
267 snprintf(ifp->device_name, sizeof(ifp->device_name), "net/%s/%i",
268 gDriverName, ifp->if_index);
270 driver_printf("%s: /dev/%s\n", gDriverName, ifp->device_name);
272 // For wlan devices we only want to see the cloned wlan device
273 // in the list.
274 // Remember: For each wlan device, there is a base device of type
275 // IFT_IEEE80211. On top of that a clone device is created of
276 // type IFT_ETHER.
277 // Haiku shall only see the cloned device as it is the one
278 // FreeBSD 8 uses for wireless i/o, too.
279 if (ifp->if_type == IFT_ETHER)
280 insert_into_device_name_list(ifp);
282 ifp->root_device = find_root_device(unit);
286 void
287 ifq_init(struct ifqueue *ifq, const char *name)
289 ifq->ifq_head = NULL;
290 ifq->ifq_tail = NULL;
291 ifq->ifq_len = 0;
292 ifq->ifq_maxlen = IFQ_MAXLEN;
293 ifq->ifq_drops = 0;
295 mtx_init(&ifq->ifq_mtx, name, NULL, MTX_DEF);
299 void
300 ifq_uninit(struct ifqueue *ifq)
302 mtx_destroy(&ifq->ifq_mtx);
306 static int
307 if_transmit(struct ifnet *ifp, struct mbuf *m)
309 int error;
311 IFQ_HANDOFF(ifp, m, error);
312 return (error);
316 static void
317 if_input_default(struct ifnet *ifp __unused, struct mbuf *m)
320 m_freem(m);
325 * Flush an interface queue.
327 void
328 if_qflush(struct ifnet *ifp)
330 struct mbuf *m, *n;
331 struct ifaltq *ifq;
333 ifq = &ifp->if_snd;
334 IFQ_LOCK(ifq);
335 #ifdef ALTQ
336 if (ALTQ_IS_ENABLED(ifq))
337 ALTQ_PURGE(ifq);
338 #endif
339 n = ifq->ifq_head;
340 while ((m = n) != NULL) {
341 n = m->m_nextpkt;
342 m_freem(m);
344 ifq->ifq_head = 0;
345 ifq->ifq_tail = 0;
346 ifq->ifq_len = 0;
347 IFQ_UNLOCK(ifq);
351 void
352 if_attach(struct ifnet *ifp)
354 unsigned socksize, ifasize;
355 int namelen, masklen;
356 struct sockaddr_dl *sdl;
357 struct ifaddr *ifa;
359 TAILQ_INIT(&ifp->if_addrhead);
360 TAILQ_INIT(&ifp->if_prefixhead);
361 TAILQ_INIT(&ifp->if_multiaddrs);
363 IF_ADDR_LOCK_INIT(ifp);
365 ifp->if_lladdr.sdl_family = AF_LINK;
367 ifq_init((struct ifqueue *) &ifp->if_snd, ifp->if_xname);
369 if (ifp->if_transmit == NULL) {
370 ifp->if_transmit = if_transmit;
371 ifp->if_qflush = if_qflush;
373 if (ifp->if_input == NULL)
374 ifp->if_input = if_input_default;
376 if (ifp->if_requestencap == NULL)
377 ifp->if_requestencap = if_requestencap_default;
380 * Create a Link Level name for this device.
382 namelen = strlen(ifp->if_xname);
384 * Always save enough space for any possiable name so we
385 * can do a rename in place later.
387 masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + IFNAMSIZ;
388 socksize = masklen + ifp->if_addrlen;
389 if (socksize < sizeof(*sdl))
390 socksize = sizeof(*sdl);
391 socksize = roundup2(socksize, sizeof(long));
392 ifasize = sizeof(*ifa) + 2 * socksize;
393 ifa = ifa_alloc(ifasize, M_WAITOK);
394 sdl = (struct sockaddr_dl *)(ifa + 1);
395 sdl->sdl_len = socksize;
396 sdl->sdl_family = AF_LINK;
397 bcopy(ifp->if_xname, sdl->sdl_data, namelen);
398 sdl->sdl_nlen = namelen;
399 sdl->sdl_index = ifp->if_index;
400 sdl->sdl_type = ifp->if_type;
401 ifp->if_addr = ifa;
402 ifa->ifa_ifp = ifp;
403 //ifa->ifa_rtrequest = link_rtrequest;
404 ifa->ifa_addr = (struct sockaddr *)sdl;
405 sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
406 ifa->ifa_netmask = (struct sockaddr *)sdl;
407 sdl->sdl_len = masklen;
408 while (namelen != 0)
409 sdl->sdl_data[--namelen] = 0xff;
410 dprintf("if_attach %p\n", ifa->ifa_addr);
414 void
415 if_detach(struct ifnet *ifp)
417 if (HAIKU_DRIVER_REQUIRES(FBSD_SWI_TASKQUEUE))
418 taskqueue_drain(taskqueue_swi, &ifp->if_linktask);
420 IF_ADDR_LOCK_DESTROY(ifp);
421 ifq_uninit((struct ifqueue *) &ifp->if_snd);
425 void
426 if_start(struct ifnet *ifp)
428 #ifdef IFF_NEEDSGIANT
429 if (ifp->if_flags & IFF_NEEDSGIANT)
430 panic("freebsd compat.: unsupported giant requirement");
431 #endif
432 ifp->if_start(ifp);
437 if_printf(struct ifnet *ifp, const char *format, ...)
439 char buf[256];
440 va_list vl;
441 va_start(vl, format);
442 vsnprintf(buf, sizeof(buf), format, vl);
443 va_end(vl);
445 dprintf("[%s] %s", ifp->device_name, buf);
446 return 0;
451 * Compat function for handling basic encapsulation requests.
452 * Not converted stacks (FDDI, IB, ..) supports traditional
453 * output model: ARP (and other similar L2 protocols) are handled
454 * inside output routine, arpresolve/nd6_resolve() returns MAC
455 * address instead of full prepend.
457 * This function creates calculated header==MAC for IPv4/IPv6 and
458 * returns EAFNOSUPPORT (which is then handled in ARP code) for other
459 * address families.
461 static int
462 if_requestencap_default(struct ifnet *ifp, struct if_encap_req *req)
465 if (req->rtype != IFENCAP_LL)
466 return (EOPNOTSUPP);
468 if (req->bufsize < req->lladdr_len)
469 return (ENOMEM);
471 switch (req->family) {
472 case AF_INET:
473 case AF_INET6:
474 break;
475 default:
476 return (EAFNOSUPPORT);
479 /* Copy lladdr to storage as is */
480 memmove(req->buf, req->lladdr, req->lladdr_len);
481 req->bufsize = req->lladdr_len;
482 req->lladdr_off = 0;
484 return (0);
488 void
489 if_link_state_change(struct ifnet *ifp, int linkState)
491 if (ifp->if_link_state == linkState)
492 return;
494 ifp->if_link_state = linkState;
495 release_sem_etc(ifp->link_state_sem, 1, B_DO_NOT_RESCHEDULE);
498 static struct ifmultiaddr *
499 if_findmulti(struct ifnet *ifp, struct sockaddr *_address)
501 struct sockaddr_dl *address = (struct sockaddr_dl *) _address;
502 struct ifmultiaddr *ifma;
504 TAILQ_FOREACH (ifma, &ifp->if_multiaddrs, ifma_link) {
505 if (memcmp(LLADDR(address),
506 LLADDR((struct sockaddr_dl *)ifma->ifma_addr), ETHER_ADDR_LEN) == 0)
507 return ifma;
510 return NULL;
515 * if_freemulti: free ifmultiaddr structure and possibly attached related
516 * addresses. The caller is responsible for implementing reference
517 * counting, notifying the driver, handling routing messages, and releasing
518 * any dependent link layer state.
520 static void
521 if_freemulti(struct ifmultiaddr *ifma)
524 KASSERT(ifma->ifma_refcount == 0, ("if_freemulti: refcount %d",
525 ifma->ifma_refcount));
526 KASSERT(ifma->ifma_protospec == NULL,
527 ("if_freemulti: protospec not NULL"));
529 if (ifma->ifma_lladdr != NULL)
530 free(ifma->ifma_lladdr);
532 // Haiku note: We use a field in the ifmultiaddr struct (ifma_addr_storage)
533 // to store the address and let ifma_addr point to that. We therefore do not
534 // free it here, as it will be freed as part of freeing the if_multiaddr.
535 //free(ifma->ifma_addr);
537 free(ifma);
541 static struct ifmultiaddr *
542 _if_addmulti(struct ifnet *ifp, struct sockaddr *address)
544 struct ifmultiaddr *addr = if_findmulti(ifp, address);
546 if (addr != NULL) {
547 addr->ifma_refcount++;
548 return addr;
551 addr = (struct ifmultiaddr *) malloc(sizeof(struct ifmultiaddr));
552 if (addr == NULL)
553 return NULL;
555 addr->ifma_lladdr = NULL;
556 addr->ifma_ifp = ifp;
557 addr->ifma_protospec = NULL;
559 memcpy(&addr->ifma_addr_storage, address, sizeof(struct sockaddr_dl));
560 addr->ifma_addr = (struct sockaddr *) &addr->ifma_addr_storage;
562 addr->ifma_refcount = 1;
564 TAILQ_INSERT_HEAD(&ifp->if_multiaddrs, addr, ifma_link);
566 return addr;
571 if_addmulti(struct ifnet *ifp, struct sockaddr *address,
572 struct ifmultiaddr **out)
574 struct ifmultiaddr *result;
575 int refcount = 0;
577 IF_ADDR_LOCK(ifp);
578 result = _if_addmulti(ifp, address);
579 if (result)
580 refcount = result->ifma_refcount;
581 IF_ADDR_UNLOCK(ifp);
583 if (result == NULL)
584 return ENOBUFS;
586 if (refcount == 1 && ifp->if_ioctl != NULL)
587 ifp->if_ioctl(ifp, SIOCADDMULTI, NULL);
589 if (out)
590 (*out) = result;
592 return 0;
596 static int
597 if_delmulti_locked(struct ifnet *ifp, struct ifmultiaddr *ifma, int detaching)
599 struct ifmultiaddr *ll_ifma;
601 if (ifp != NULL && ifma->ifma_ifp != NULL) {
602 KASSERT(ifma->ifma_ifp == ifp,
603 ("%s: inconsistent ifp %p", __func__, ifp));
604 IF_ADDR_LOCK_ASSERT(ifp);
607 ifp = ifma->ifma_ifp;
610 * If the ifnet is detaching, null out references to ifnet,
611 * so that upper protocol layers will notice, and not attempt
612 * to obtain locks for an ifnet which no longer exists. The
613 * routing socket announcement must happen before the ifnet
614 * instance is detached from the system.
616 if (detaching) {
617 #ifdef DIAGNOSTIC
618 printf("%s: detaching ifnet instance %p\n", __func__, ifp);
619 #endif
621 * ifp may already be nulled out if we are being reentered
622 * to delete the ll_ifma.
624 if (ifp != NULL) {
625 #ifndef __HAIKU__
626 rt_newmaddrmsg(RTM_DELMADDR, ifma);
627 #endif
628 ifma->ifma_ifp = NULL;
632 if (--ifma->ifma_refcount > 0)
633 return 0;
635 #ifndef __HAIKU__
637 * If this ifma is a network-layer ifma, a link-layer ifma may
638 * have been associated with it. Release it first if so.
640 ll_ifma = ifma->ifma_llifma;
641 if (ll_ifma != NULL) {
642 KASSERT(ifma->ifma_lladdr != NULL,
643 ("%s: llifma w/o lladdr", __func__));
644 if (detaching)
645 ll_ifma->ifma_ifp = NULL; /* XXX */
646 if (--ll_ifma->ifma_refcount == 0) {
647 if (ifp != NULL) {
648 TAILQ_REMOVE(&ifp->if_multiaddrs, ll_ifma,
649 ifma_link);
651 if_freemulti(ll_ifma);
654 #endif
656 if (ifp != NULL)
657 TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
659 if_freemulti(ifma);
662 * The last reference to this instance of struct ifmultiaddr
663 * was released; the hardware should be notified of this change.
665 return 1;
670 * Delete all multicast group membership for an interface.
671 * Should be used to quickly flush all multicast filters.
673 void
674 if_delallmulti(struct ifnet *ifp)
676 struct ifmultiaddr *ifma;
677 struct ifmultiaddr *next;
679 IF_ADDR_LOCK(ifp);
680 TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
681 if_delmulti_locked(ifp, ifma, 0);
682 IF_ADDR_UNLOCK(ifp);
686 static void
687 if_delete_multiaddr(struct ifnet *ifp, struct ifmultiaddr *ifma)
689 TAILQ_REMOVE(&ifp->if_multiaddrs, ifma, ifma_link);
690 free(ifma);
695 if_delmulti(struct ifnet *ifp, struct sockaddr *sa)
697 struct ifmultiaddr *ifma;
698 int lastref;
699 #ifdef INVARIANTS
700 struct ifnet *oifp;
702 IFNET_RLOCK_NOSLEEP();
703 TAILQ_FOREACH(oifp, &V_ifnet, if_link)
704 if (ifp == oifp)
705 break;
706 if (ifp != oifp)
707 ifp = NULL;
708 IFNET_RUNLOCK_NOSLEEP();
710 KASSERT(ifp != NULL, ("%s: ifnet went away", __func__));
711 #endif
712 if (ifp == NULL)
713 return (ENOENT);
715 IF_ADDR_LOCK(ifp);
716 lastref = 0;
717 ifma = if_findmulti(ifp, sa);
718 if (ifma != NULL)
719 lastref = if_delmulti_locked(ifp, ifma, 0);
720 IF_ADDR_UNLOCK(ifp);
722 if (ifma == NULL)
723 return (ENOENT);
725 if (lastref && ifp->if_ioctl != NULL) {
726 (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, 0);
729 return (0);
733 void
734 if_purgemaddrs(struct ifnet *ifp)
736 struct ifmultiaddr *ifma;
737 struct ifmultiaddr *next;
739 IF_ADDR_LOCK(ifp);
740 TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
741 if_delmulti_locked(ifp, ifma, 1);
742 IF_ADDR_UNLOCK(ifp);
746 * Return counter values from counter(9)s stored in ifnet.
748 uint64_t
749 if_get_counter_default(struct ifnet *ifp, ift_counter cnt)
752 KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
754 switch (cnt) {
755 case IFCOUNTER_IPACKETS:
756 return atomic_get64((int64 *)&ifp->if_ipackets);
757 case IFCOUNTER_IERRORS:
758 return atomic_get64((int64 *)&ifp->if_ierrors);
759 case IFCOUNTER_OPACKETS:
760 return atomic_get64((int64 *)&ifp->if_opackets);
761 case IFCOUNTER_OERRORS:
762 return atomic_get64((int64 *)&ifp->if_oerrors);
763 case IFCOUNTER_COLLISIONS:
764 return atomic_get64((int64 *)&ifp->if_collisions);
765 case IFCOUNTER_IBYTES:
766 return atomic_get64((int64 *)&ifp->if_ibytes);
767 case IFCOUNTER_OBYTES:
768 return atomic_get64((int64 *)&ifp->if_obytes);
769 case IFCOUNTER_IMCASTS:
770 return atomic_get64((int64 *)&ifp->if_imcasts);
771 case IFCOUNTER_OMCASTS:
772 return atomic_get64((int64 *)&ifp->if_omcasts);
773 case IFCOUNTER_IQDROPS:
774 return atomic_get64((int64 *)&ifp->if_iqdrops);
775 case IFCOUNTER_OQDROPS:
776 return atomic_get64((int64 *)&ifp->if_oqdrops);
777 case IFCOUNTER_NOPROTO:
778 return atomic_get64((int64 *)&ifp->if_noproto);
779 case IFCOUNTERS:
780 KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
782 return 0;
785 void
786 if_addr_rlock(struct ifnet *ifp)
788 IF_ADDR_LOCK(ifp);
792 void
793 if_addr_runlock(struct ifnet *ifp)
795 IF_ADDR_UNLOCK(ifp);
799 void
800 if_maddr_rlock(struct ifnet *ifp)
802 IF_ADDR_LOCK(ifp);
806 void
807 if_maddr_runlock(struct ifnet *ifp)
809 IF_ADDR_UNLOCK(ifp);
814 ether_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
815 struct route *ro)
817 int error = 0;
818 IFQ_HANDOFF(ifp, m, error);
819 return error;
823 static void ether_input(struct ifnet *ifp, struct mbuf *m)
825 IF_ENQUEUE(&ifp->receive_queue, m);
826 release_sem_etc(ifp->receive_sem, 1, B_DO_NOT_RESCHEDULE);
830 void
831 ether_ifattach(struct ifnet *ifp, const uint8_t *lla)
833 struct ifaddr *ifa;
834 struct sockaddr_dl *sdl;
836 ifp->if_addrlen = ETHER_ADDR_LEN;
837 ifp->if_hdrlen = ETHER_HDR_LEN;
838 if_attach(ifp);
839 ifp->if_mtu = ETHERMTU;
840 ifp->if_output = ether_output;
841 ifp->if_input = ether_input;
842 ifp->if_resolvemulti = NULL; // done in the stack
843 ifp->if_broadcastaddr = etherbroadcastaddr;
845 ifa = ifp->if_addr;
846 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
847 sdl->sdl_type = IFT_ETHER;
848 sdl->sdl_alen = ifp->if_addrlen;
849 bcopy(lla, LLADDR(sdl), ifp->if_addrlen);
853 void
854 ether_ifdetach(struct ifnet *ifp)
856 if_detach(ifp);
861 ether_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
863 struct ifreq *ifr = (struct ifreq *) data;
865 switch (command) {
866 case SIOCSIFMTU:
867 if (ifr->ifr_mtu > ETHERMTU)
868 return EINVAL;
869 else
871 // need to fix our ifreq to work with C...
872 // ifp->ifr_mtu = ifr->ifr_mtu;
873 break;
875 default:
876 return EINVAL;
879 return 0;
884 * Initialization, destruction and refcounting functions for ifaddrs.
886 struct ifaddr *
887 ifa_alloc(size_t size, int flags)
889 struct ifaddr *ifa;
891 KASSERT(size >= sizeof(struct ifaddr),
892 ("%s: invalid size %zu", __func__, size));
894 ifa = _kernel_malloc(size, M_ZERO | flags);
895 if (ifa == NULL)
896 return (NULL);
898 //refcount_init(&ifa->ifa_refcnt, 1);
900 return (ifa);
902 fail:
903 /* free(NULL) is okay */
904 free(ifa);
906 return (NULL);
909 void
910 ifa_ref(struct ifaddr *ifa)
912 //refcount_acquire(&ifa->ifa_refcnt);
915 void
916 ifa_free(struct ifaddr *ifa)
919 //if (refcount_release(&ifa->ifa_refcnt)) {
920 // free(ifa);
924 void
925 if_inc_counter(struct ifnet *ifp, ift_counter cnt, int64_t inc)
927 switch (cnt) {
928 case IFCOUNTER_IPACKETS:
929 atomic_add64((int64 *)&ifp->if_ipackets, inc);
930 break;
931 case IFCOUNTER_IERRORS:
932 atomic_add64((int64 *)&ifp->if_ierrors, inc);
933 break;
934 case IFCOUNTER_OPACKETS:
935 atomic_add64((int64 *)&ifp->if_opackets, inc);
936 break;
937 case IFCOUNTER_OERRORS:
938 atomic_add64((int64 *)&ifp->if_oerrors, inc);
939 break;
940 case IFCOUNTER_COLLISIONS:
941 atomic_add64((int64 *)&ifp->if_collisions, inc);
942 break;
943 case IFCOUNTER_IBYTES:
944 atomic_add64((int64 *)&ifp->if_ibytes, inc);
945 break;
946 case IFCOUNTER_OBYTES:
947 atomic_add64((int64 *)&ifp->if_obytes, inc);
948 break;
949 case IFCOUNTER_IMCASTS:
950 atomic_add64((int64 *)&ifp->if_imcasts, inc);
951 break;
952 case IFCOUNTER_OMCASTS:
953 atomic_add64((int64 *)&ifp->if_omcasts, inc);
954 break;
955 case IFCOUNTER_IQDROPS:
956 atomic_add64((int64 *)&ifp->if_iqdrops, inc);
957 break;
958 case IFCOUNTER_OQDROPS:
959 atomic_add64((int64 *)&ifp->if_oqdrops, inc);
960 break;
961 case IFCOUNTER_NOPROTO:
962 atomic_add64((int64 *)&ifp->if_noproto, inc);
963 break;
964 case IFCOUNTERS:
965 KASSERT(cnt < IFCOUNTERS, ("%s: invalid cnt %d", __func__, cnt));
970 /* API for driver access to network stack owned ifnet.*/
971 uint64_t
972 if_setbaudrate(struct ifnet *ifp, uint64_t baudrate)
974 uint64_t oldbrate;
976 oldbrate = ifp->if_baudrate;
977 ifp->if_baudrate = baudrate;
978 return (oldbrate);
981 uint64_t
982 if_getbaudrate(if_t ifp)
985 return (((struct ifnet *)ifp)->if_baudrate);
989 if_setcapabilities(if_t ifp, int capabilities)
991 ((struct ifnet *)ifp)->if_capabilities = capabilities;
992 return (0);
996 if_setcapabilitiesbit(if_t ifp, int setbit, int clearbit)
998 ((struct ifnet *)ifp)->if_capabilities |= setbit;
999 ((struct ifnet *)ifp)->if_capabilities &= ~clearbit;
1001 return (0);
1005 if_getcapabilities(if_t ifp)
1007 return ((struct ifnet *)ifp)->if_capabilities;
1010 int
1011 if_setcapenable(if_t ifp, int capabilities)
1013 ((struct ifnet *)ifp)->if_capenable = capabilities;
1014 return (0);
1018 if_setcapenablebit(if_t ifp, int setcap, int clearcap)
1020 if(setcap)
1021 ((struct ifnet *)ifp)->if_capenable |= setcap;
1022 if(clearcap)
1023 ((struct ifnet *)ifp)->if_capenable &= ~clearcap;
1025 return (0);
1028 const char *
1029 if_getdname(if_t ifp)
1031 return ((struct ifnet *)ifp)->if_dname;
1035 if_togglecapenable(if_t ifp, int togglecap)
1037 ((struct ifnet *)ifp)->if_capenable ^= togglecap;
1038 return (0);
1042 if_getcapenable(if_t ifp)
1044 return ((struct ifnet *)ifp)->if_capenable;
1048 * This is largely undesirable because it ties ifnet to a device, but does
1049 * provide flexiblity for an embedded product vendor. Should be used with
1050 * the understanding that it violates the interface boundaries, and should be
1051 * a last resort only.
1054 if_setdev(if_t ifp, void *dev)
1056 return (0);
1060 if_setdrvflagbits(if_t ifp, int set_flags, int clear_flags)
1062 ((struct ifnet *)ifp)->if_drv_flags |= set_flags;
1063 ((struct ifnet *)ifp)->if_drv_flags &= ~clear_flags;
1065 return (0);
1069 if_getdrvflags(if_t ifp)
1071 return ((struct ifnet *)ifp)->if_drv_flags;
1075 if_setdrvflags(if_t ifp, int flags)
1077 ((struct ifnet *)ifp)->if_drv_flags = flags;
1078 return (0);
1083 if_setflags(if_t ifp, int flags)
1085 ((struct ifnet *)ifp)->if_flags = flags;
1086 return (0);
1090 if_setflagbits(if_t ifp, int set, int clear)
1092 ((struct ifnet *)ifp)->if_flags |= set;
1093 ((struct ifnet *)ifp)->if_flags &= ~clear;
1095 return (0);
1099 if_getflags(if_t ifp)
1101 return ((struct ifnet *)ifp)->if_flags;
1105 if_clearhwassist(if_t ifp)
1107 ((struct ifnet *)ifp)->if_hwassist = 0;
1108 return (0);
1112 if_sethwassistbits(if_t ifp, int toset, int toclear)
1114 ((struct ifnet *)ifp)->if_hwassist |= toset;
1115 ((struct ifnet *)ifp)->if_hwassist &= ~toclear;
1117 return (0);
1121 if_sethwassist(if_t ifp, int hwassist_bit)
1123 ((struct ifnet *)ifp)->if_hwassist = hwassist_bit;
1124 return (0);
1128 if_gethwassist(if_t ifp)
1130 return ((struct ifnet *)ifp)->if_hwassist;
1134 if_setmtu(if_t ifp, int mtu)
1136 ((struct ifnet *)ifp)->if_mtu = mtu;
1137 return (0);
1141 if_getmtu(if_t ifp)
1143 return ((struct ifnet *)ifp)->if_mtu;
1147 if_setsoftc(if_t ifp, void *softc)
1149 ((struct ifnet *)ifp)->if_softc = softc;
1150 return (0);
1153 void *
1154 if_getsoftc(if_t ifp)
1156 return ((struct ifnet *)ifp)->if_softc;
1159 void
1160 if_setrcvif(struct mbuf *m, if_t ifp)
1162 m->m_pkthdr.rcvif = (struct ifnet *)ifp;
1165 void
1166 if_setvtag(struct mbuf *m, uint16_t tag)
1168 m->m_pkthdr.ether_vtag = tag;
1171 uint16_t
1172 if_getvtag(struct mbuf *m)
1175 return (m->m_pkthdr.ether_vtag);
1179 if_sendq_empty(if_t ifp)
1181 return IFQ_DRV_IS_EMPTY(&((struct ifnet *)ifp)->if_snd);
1185 if_getamcount(if_t ifp)
1187 return ((struct ifnet *)ifp)->if_amcount;
1192 if_setsendqready(if_t ifp)
1194 IFQ_SET_READY(&((struct ifnet *)ifp)->if_snd);
1195 return (0);
1199 if_setsendqlen(if_t ifp, int tx_desc_count)
1201 IFQ_SET_MAXLEN(&((struct ifnet *)ifp)->if_snd, tx_desc_count);
1202 ((struct ifnet *)ifp)->if_snd.ifq_drv_maxlen = tx_desc_count;
1204 return (0);
1208 if_vlantrunkinuse(if_t ifp)
1210 return ((struct ifnet *)ifp)->if_vlantrunk != NULL?1:0;
1214 if_input(if_t ifp, struct mbuf* sendmp)
1216 (*((struct ifnet *)ifp)->if_input)((struct ifnet *)ifp, sendmp);
1217 return (0);
1221 /* XXX */
1222 #ifndef ETH_ADDR_LEN
1223 #define ETH_ADDR_LEN 6
1224 #endif
1227 if_setupmultiaddr(if_t ifp, void *mta, int *cnt, int max)
1229 struct ifmultiaddr *ifma;
1230 uint8_t *lmta = (uint8_t *)mta;
1231 int mcnt = 0;
1233 TAILQ_FOREACH(ifma, &((struct ifnet *)ifp)->if_multiaddrs, ifma_link) {
1234 if (ifma->ifma_addr->sa_family != AF_LINK)
1235 continue;
1237 if (mcnt == max)
1238 break;
1240 bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
1241 &lmta[mcnt * ETH_ADDR_LEN], ETH_ADDR_LEN);
1242 mcnt++;
1244 *cnt = mcnt;
1246 return (0);
1250 if_multiaddr_array(if_t ifp, void *mta, int *cnt, int max)
1252 int error;
1254 if_maddr_rlock(ifp);
1255 error = if_setupmultiaddr(ifp, mta, cnt, max);
1256 if_maddr_runlock(ifp);
1257 return (error);
1261 if_multiaddr_count(if_t ifp, int max)
1263 struct ifmultiaddr *ifma;
1264 int count;
1266 count = 0;
1267 if_maddr_rlock(ifp);
1268 TAILQ_FOREACH(ifma, &((struct ifnet *)ifp)->if_multiaddrs, ifma_link) {
1269 if (ifma->ifma_addr->sa_family != AF_LINK)
1270 continue;
1271 count++;
1272 if (count == max)
1273 break;
1275 if_maddr_runlock(ifp);
1276 return (count);
1279 struct mbuf *
1280 if_dequeue(if_t ifp)
1282 struct mbuf *m;
1283 IFQ_DRV_DEQUEUE(&((struct ifnet *)ifp)->if_snd, m);
1285 return (m);
1289 if_sendq_prepend(if_t ifp, struct mbuf *m)
1291 IFQ_DRV_PREPEND(&((struct ifnet *)ifp)->if_snd, m);
1292 return (0);
1296 if_setifheaderlen(if_t ifp, int len)
1298 ((struct ifnet *)ifp)->if_hdrlen = len;
1299 return (0);
1302 caddr_t
1303 if_getlladdr(if_t ifp)
1305 return (IF_LLADDR((struct ifnet *)ifp));
1308 void *
1309 if_gethandle(u_char type)
1311 return (if_alloc(type));
1314 void
1315 if_bpfmtap(if_t ifh, struct mbuf *m)
1317 struct ifnet *ifp = (struct ifnet *)ifh;
1319 BPF_MTAP(ifp, m);
1322 void
1323 if_etherbpfmtap(if_t ifh, struct mbuf *m)
1325 struct ifnet *ifp = (struct ifnet *)ifh;
1327 ETHER_BPF_MTAP(ifp, m);
1330 void
1331 if_vlancap(if_t ifh)
1333 struct ifnet *ifp = (struct ifnet *)ifh;
1334 VLAN_CAPABILITIES(ifp);
1337 void
1338 if_setinitfn(if_t ifp, void (*init_fn)(void *))
1340 ((struct ifnet *)ifp)->if_init = init_fn;
1343 void
1344 if_setioctlfn(if_t ifp, int (*ioctl_fn)(if_t, u_long, caddr_t))
1346 ((struct ifnet *)ifp)->if_ioctl = (void *)ioctl_fn;
1349 void
1350 if_setstartfn(if_t ifp, void (*start_fn)(if_t))
1352 ((struct ifnet *)ifp)->if_start = (void *)start_fn;
1355 void
1356 if_settransmitfn(if_t ifp, if_transmit_fn_t start_fn)
1358 ((struct ifnet *)ifp)->if_transmit = start_fn;
1361 void if_setqflushfn(if_t ifp, if_qflush_fn_t flush_fn)
1363 ((struct ifnet *)ifp)->if_qflush = flush_fn;
1366 void
1367 if_setgetcounterfn(if_t ifp, if_get_counter_t fn)
1370 ifp->if_get_counter = fn;