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