ifq.h revision 191816
118334Speter/*-
2169689Skan * Copyright (c) 1982, 1986, 1989, 1993
3169689Skan *	The Regents of the University of California.  All rights reserved.
4169689Skan *
518334Speter * Redistribution and use in source and binary forms, with or without
690075Sobrien * modification, are permitted provided that the following conditions
718334Speter * are met:
890075Sobrien * 1. Redistributions of source code must retain the above copyright
990075Sobrien *    notice, this list of conditions and the following disclaimer.
1090075Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1190075Sobrien *    notice, this list of conditions and the following disclaimer in the
1218334Speter *    documentation and/or other materials provided with the distribution.
1390075Sobrien * 4. Neither the name of the University nor the names of its contributors
1490075Sobrien *    may be used to endorse or promote products derived from this software
1590075Sobrien *    without specific prior written permission.
1690075Sobrien *
1718334Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1818334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1990075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20169689Skan * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21169689Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2218334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2318334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2418334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2518334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2618334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27169689Skan * SUCH DAMAGE.
2818334Speter *
2918334Speter *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3050397Sobrien * $FreeBSD: head/sys/net/if_var.h 191816 2009-05-05 10:56:12Z zec $
31132718Skan */
32132718Skan
3390075Sobrien#ifndef	_NET_IF_VAR_H_
3418334Speter#define	_NET_IF_VAR_H_
35169689Skan
3618334Speter/*
3790075Sobrien * Structures defining a network interface, providing a packet
3818334Speter * transport mechanism (ala level 0 of the PUP protocols).
3918334Speter *
4050397Sobrien * Each interface accepts output datagrams of a specified maximum
4150397Sobrien * length, and provides higher level routines with input datagrams
4252284Sobrien * received from its medium.
4390075Sobrien *
4490075Sobrien * Output occurs when the routine if_output is called, with three parameters:
45169689Skan *	(*ifp->if_output)(ifp, m, dst, rt)
46169689Skan * Here m is the mbuf chain to be sent and dst is the destination address.
47169689Skan * The output routine encapsulates the supplied datagram if necessary,
4818334Speter * and then transmits it on its medium.
49169689Skan *
50169689Skan * On input, each interface unwraps the data received by it, and either
51169689Skan * places it on the input queue of an internetwork datagram routine
52169689Skan * and posts the associated software interrupt, or passes the datagram to a raw
53169689Skan * packet input routine.
54169689Skan *
55169689Skan * Routines exist for locating interfaces by their addresses
56169689Skan * or for locating an interface on a certain network, as well as more general
57169689Skan * routing and gateway routines maintaining information used to locate
58169689Skan * interfaces.  These routines live in the files if.c and route.c
59169689Skan */
60169689Skan
61169689Skan#ifdef __STDC__
62169689Skan/*
63169689Skan * Forward structure declarations for function prototypes [sic].
64169689Skan */
65169689Skanstruct	mbuf;
66169689Skanstruct	thread;
67169689Skanstruct	rtentry;
68169689Skanstruct	rt_addrinfo;
69169689Skanstruct	socket;
70169689Skanstruct	ether_header;
7118334Speterstruct	carp_if;
7218334Speterstruct  ifvlantrunk;
7318334Speterstruct	route;
7418334Speter#endif
75132718Skan
76132718Skan#include <sys/queue.h>		/* get TAILQ macros */
7790075Sobrien
78169689Skan#ifdef _KERNEL
79132718Skan#include <sys/mbuf.h>
80169689Skan#include <sys/eventhandler.h>
81169689Skan#include <sys/buf_ring.h>
82169689Skan#endif /* _KERNEL */
83169689Skan#include <sys/lock.h>		/* XXX */
84132718Skan#include <sys/mutex.h>		/* XXX */
85132718Skan#include <sys/rwlock.h>		/* XXX */
86132718Skan#include <sys/event.h>		/* XXX */
87132718Skan#include <sys/_task.h>
88169689Skan
89132718Skan#define	IF_DUNIT_NONE	-1
90132718Skan
91132718Skan#include <altq/if_altq.h>
92132718Skan
93132718SkanTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
94132718SkanTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
95132718SkanTAILQ_HEAD(ifprefixhead, ifprefix);
96169689SkanTAILQ_HEAD(ifmultihead, ifmultiaddr);
97169689SkanTAILQ_HEAD(ifgrouphead, ifg_group);
98132718Skan
99132718Skan/*
100132718Skan * Structure defining a queue for a network interface.
101132718Skan */
102132718Skanstruct	ifqueue {
103132718Skan	struct	mbuf *ifq_head;
104132718Skan	struct	mbuf *ifq_tail;
105169689Skan	int	ifq_len;
106169689Skan	int	ifq_maxlen;
107169689Skan	int	ifq_drops;
108169689Skan	struct	mtx ifq_mtx;
109169689Skan};
11018334Speter
111169689Skan/*
112169689Skan * Structure defining a network interface.
113169689Skan *
114169689Skan * (Would like to call this struct ``if'', but C isn't PL/1.)
115169689Skan */
116169689Skan
117169689Skanstruct ifnet {
118169689Skan	void	*if_softc;		/* pointer to driver state */
119169689Skan	void	*if_l2com;		/* pointer to protocol bits */
120169689Skan	struct vnet *if_vnet;		/* pointer to network stack instance */
121169689Skan	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
122169689Skan	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
123169689Skan	const char *if_dname;		/* driver name */
124169689Skan	int	if_dunit;		/* unit or IF_DUNIT_NONE */
125169689Skan	u_int	if_refcount;		/* reference count */
126169689Skan	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
127169689Skan		/*
128169689Skan		 * if_addrhead is the list of all addresses associated to
129169689Skan		 * an interface.
130169689Skan		 * Some code in the kernel assumes that first element
131169689Skan		 * of the list has type AF_LINK, and contains sockaddr_dl
132169689Skan		 * addresses which store the link-level address and the name
133169689Skan		 * of the interface.
134169689Skan		 * However, access to the AF_LINK address through this
135169689Skan		 * field is deprecated. Use if_addr or ifaddr_byindex() instead.
136169689Skan		 */
137169689Skan	struct	knlist if_klist;	/* events attached to this if */
138169689Skan	int	if_pcount;		/* number of promiscuous listeners */
139169689Skan	struct	carp_if *if_carp;	/* carp interface structure */
140169689Skan	struct	bpf_if *if_bpf;		/* packet filter structure */
14118334Speter	u_short	if_index;		/* numeric abbreviation for this if  */
14218334Speter	short	if_timer;		/* time 'til if_watchdog called */
14318334Speter	struct  ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */
14418334Speter	int	if_flags;		/* up/down, broadcast, etc. */
145132718Skan	int	if_capabilities;	/* interface features & capabilities */
14618334Speter	int	if_capenable;		/* enabled features & capabilities */
14718334Speter	void	*if_linkmib;		/* link-type-specific MIB data */
14818334Speter	size_t	if_linkmiblen;		/* length of above data */
14990075Sobrien	struct	if_data if_data;
15052284Sobrien	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
15152284Sobrien	int	if_amcount;		/* number of all-multicast requests */
15218334Speter/* procedure handles */
15390075Sobrien	int	(*if_output)		/* output routine (enqueue) */
15418334Speter		(struct ifnet *, struct mbuf *, struct sockaddr *,
15518334Speter		     struct route *);
156117395Skan	void	(*if_input)		/* input routine (from h/w driver) */
15718334Speter		(struct ifnet *, struct mbuf *);
15818334Speter	void	(*if_start)		/* initiate output routine */
15918334Speter		(struct ifnet *);
16018334Speter	int	(*if_ioctl)		/* ioctl routine */
16118334Speter		(struct ifnet *, u_long, caddr_t);
16218334Speter	void	(*if_watchdog)		/* timer routine */
16318334Speter		(struct ifnet *);
16418334Speter	void	(*if_init)		/* Init routine */
165132718Skan		(void *);
16618334Speter	int	(*if_resolvemulti)	/* validate/resolve multicast */
16752284Sobrien		(struct ifnet *, struct sockaddr **, struct sockaddr *);
16818334Speter	void	(*if_qflush)		/* flush any queues */
16918334Speter		(struct ifnet *);
17018334Speter	int	(*if_transmit)		/* initiate output routine */
17118334Speter		(struct ifnet *, struct mbuf *);
17218334Speter	struct	ifaddr	*if_addr;	/* pointer to link-level address */
17318334Speter	void	*if_llsoftc;		/* link layer softc */
17418334Speter	int	if_drv_flags;		/* driver-managed status flags */
175169689Skan	struct  ifaltq if_snd;		/* output queue (includes altq) */
17618334Speter	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
17718334Speter
17818334Speter	void	*if_bridge;		/* bridge glue */
17918334Speter
18018334Speter	struct	label *if_label;	/* interface MAC label */
18118334Speter
18218334Speter	/* these are only used by IPv6 */
18318334Speter	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
18452284Sobrien	void	*if_afdata[AF_MAX];
18518334Speter	int	if_afdata_initialized;
18618334Speter	struct	rwlock if_afdata_lock;
18718334Speter	struct	task if_linktask;	/* task for link change events */
18852284Sobrien	struct	mtx if_addr_mtx;	/* mutex to protect address lists */
18918334Speter
19018334Speter	LIST_ENTRY(ifnet) if_clones;	/* interfaces of a cloner */
19118334Speter	TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
19252284Sobrien					/* protected by if_addr_mtx */
19318334Speter	void	*if_pf_kif;
19418334Speter	void	*if_lagg;		/* lagg glue */
19518334Speter	u_char	 if_alloctype;		/* if_type at time of allocation */
19618334Speter
19718334Speter	/*
19818334Speter	 * Spare fields are added so that we can modify sensitive data
19918334Speter	 * structures without changing the kernel binary interface, and must
20018334Speter	 * be used with care where binary compatibility is required.
20118334Speter	 */
20296263Sobrien	char	 if_cspare[3];
20396263Sobrien	void	*if_pspare[8];
20496263Sobrien	int	if_ispare[4];
20596263Sobrien};
20696263Sobrien
20718334Spetertypedef void if_init_f_t(void *);
20818334Speter
20918334Speter/*
21018334Speter * XXX These aliases are terribly dangerous because they could apply
21118334Speter * to anything.
21218334Speter */
21318334Speter#define	if_mtu		if_data.ifi_mtu
214169689Skan#define	if_type		if_data.ifi_type
21518334Speter#define if_physical	if_data.ifi_physical
21618334Speter#define	if_addrlen	if_data.ifi_addrlen
21718334Speter#define	if_hdrlen	if_data.ifi_hdrlen
218169689Skan#define	if_metric	if_data.ifi_metric
219169689Skan#define	if_link_state	if_data.ifi_link_state
22018334Speter#define	if_baudrate	if_data.ifi_baudrate
22118334Speter#define	if_hwassist	if_data.ifi_hwassist
222169689Skan#define	if_ipackets	if_data.ifi_ipackets
22318334Speter#define	if_ierrors	if_data.ifi_ierrors
22418334Speter#define	if_opackets	if_data.ifi_opackets
22518334Speter#define	if_oerrors	if_data.ifi_oerrors
226117395Skan#define	if_collisions	if_data.ifi_collisions
227117395Skan#define	if_ibytes	if_data.ifi_ibytes
228117395Skan#define	if_obytes	if_data.ifi_obytes
229117395Skan#define	if_imcasts	if_data.ifi_imcasts
230132718Skan#define	if_omcasts	if_data.ifi_omcasts
231117395Skan#define	if_iqdrops	if_data.ifi_iqdrops
232117395Skan#define	if_noproto	if_data.ifi_noproto
233117395Skan#define	if_lastchange	if_data.ifi_lastchange
234117395Skan#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL)
235117395Skan
236117395Skan/* for compatibility with other BSDs */
237117395Skan#define	if_addrlist	if_addrhead
238169689Skan#define	if_list		if_link
239169689Skan#define	if_name(ifp)	((ifp)->if_xname)
240169689Skan
241117395Skan/*
242117395Skan * Locks for address lists on the network interface.
243117395Skan */
244117395Skan#define	IF_ADDR_LOCK_INIT(if)	mtx_init(&(if)->if_addr_mtx,		\
245117395Skan				    "if_addr_mtx", NULL, MTX_DEF)
246117395Skan#define	IF_ADDR_LOCK_DESTROY(if)	mtx_destroy(&(if)->if_addr_mtx)
24718334Speter#define	IF_ADDR_LOCK(if)	mtx_lock(&(if)->if_addr_mtx)
24818334Speter#define	IF_ADDR_UNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
24918334Speter#define	IF_ADDR_LOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
25018334Speter
251132718Skan/*
25218334Speter * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
253132718Skan * are queues of messages stored on ifqueue structures
25452750Sobrien * (defined above).  Entries are added to and deleted from these structures
25518334Speter * by these macros, which should be called with ipl raised to splimp().
256169689Skan */
257169689Skan#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
258169689Skan#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
259169689Skan#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
260169689Skan#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
261169689Skan#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
262169689Skan#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
263169689Skan
264169689Skan#define	_IF_ENQUEUE(ifq, m) do { 				\
265169689Skan	(m)->m_nextpkt = NULL;					\
266169689Skan	if ((ifq)->ifq_tail == NULL) 				\
26718334Speter		(ifq)->ifq_head = m; 				\
268169689Skan	else 							\
26918334Speter		(ifq)->ifq_tail->m_nextpkt = m; 		\
270169689Skan	(ifq)->ifq_tail = m; 					\
271169689Skan	(ifq)->ifq_len++; 					\
272169689Skan} while (0)
27318334Speter
27418334Speter#define IF_ENQUEUE(ifq, m) do {					\
275169689Skan	IF_LOCK(ifq); 						\
27618334Speter	_IF_ENQUEUE(ifq, m); 					\
27790075Sobrien	IF_UNLOCK(ifq); 					\
27890075Sobrien} while (0)
27918334Speter
28018334Speter#define	_IF_PREPEND(ifq, m) do {				\
28118334Speter	(m)->m_nextpkt = (ifq)->ifq_head; 			\
28218334Speter	if ((ifq)->ifq_tail == NULL) 				\
28318334Speter		(ifq)->ifq_tail = (m); 				\
28418334Speter	(ifq)->ifq_head = (m); 					\
28518334Speter	(ifq)->ifq_len++; 					\
28618334Speter} while (0)
28718334Speter
28818334Speter#define IF_PREPEND(ifq, m) do {		 			\
28918334Speter	IF_LOCK(ifq); 						\
29018334Speter	_IF_PREPEND(ifq, m); 					\
291169689Skan	IF_UNLOCK(ifq); 					\
292169689Skan} while (0)
293169689Skan
29450397Sobrien#define	_IF_DEQUEUE(ifq, m) do { 				\
295169689Skan	(m) = (ifq)->ifq_head; 					\
29618334Speter	if (m) { 						\
297169689Skan		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
298169689Skan			(ifq)->ifq_tail = NULL; 		\
299169689Skan		(m)->m_nextpkt = NULL; 				\
300169689Skan		(ifq)->ifq_len--; 				\
30118334Speter	} 							\
302169689Skan} while (0)
303169689Skan
304169689Skan#define IF_DEQUEUE(ifq, m) do { 				\
305169689Skan	IF_LOCK(ifq); 						\
30618334Speter	_IF_DEQUEUE(ifq, m); 					\
307169689Skan	IF_UNLOCK(ifq); 					\
30818334Speter} while (0)
30918334Speter
31018334Speter#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
31118334Speter#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
312169689Skan
31318334Speter#define _IF_DRAIN(ifq) do { 					\
31452284Sobrien	struct mbuf *m; 					\
31552284Sobrien	for (;;) { 						\
316169689Skan		_IF_DEQUEUE(ifq, m); 				\
317169689Skan		if (m == NULL) 					\
318169689Skan			break; 					\
319169689Skan		m_freem(m); 					\
32018334Speter	} 							\
32118334Speter} while (0)
32218334Speter
32318334Speter#define IF_DRAIN(ifq) do {					\
324169689Skan	IF_LOCK(ifq);						\
325169689Skan	_IF_DRAIN(ifq);						\
326169689Skan	IF_UNLOCK(ifq);						\
327169689Skan} while(0)
328169689Skan
329169689Skan#ifdef _KERNEL
330169689Skan/* interface address change event */
331169689Skantypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
332169689SkanEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
333169689Skan/* new interface arrival event */
334169689Skantypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
335169689SkanEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
336169689Skan/* interface departure event */
337169689Skantypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
338169689SkanEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
339169689Skan
340169689Skan/*
341169689Skan * interface groups
342169689Skan */
343169689Skanstruct ifg_group {
344169689Skan	char				 ifg_group[IFNAMSIZ];
345169689Skan	u_int				 ifg_refcnt;
346169689Skan	void				*ifg_pf_kif;
34718334Speter	TAILQ_HEAD(, ifg_member)	 ifg_members;
348169689Skan	TAILQ_ENTRY(ifg_group)		 ifg_next;
349169689Skan};
35018334Speter
351169689Skanstruct ifg_member {
352169689Skan	TAILQ_ENTRY(ifg_member)	 ifgm_next;
35318334Speter	struct ifnet		*ifgm_ifp;
354169689Skan};
355169689Skan
356169689Skanstruct ifg_list {
357169689Skan	struct ifg_group	*ifgl_group;
358169689Skan	TAILQ_ENTRY(ifg_list)	 ifgl_next;
359169689Skan};
360169689Skan
361169689Skan/* group attach event */
362169689Skantypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
363169689SkanEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
364169689Skan/* group detach event */
365169689Skantypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
366169689SkanEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
367169689Skan/* group change event */
368169689Skantypedef void (*group_change_event_handler_t)(void *, const char *);
369169689SkanEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
370169689Skan
371169689Skan#define	IF_AFDATA_LOCK_INIT(ifp)	\
372169689Skan	rw_init(&(ifp)->if_afdata_lock, "if_afdata")
373169689Skan
374169689Skan#define	IF_AFDATA_WLOCK(ifp)	rw_wlock(&(ifp)->if_afdata_lock)
37518334Speter#define	IF_AFDATA_RLOCK(ifp)	rw_rlock(&(ifp)->if_afdata_lock)
37618334Speter#define	IF_AFDATA_WUNLOCK(ifp)	rw_wunlock(&(ifp)->if_afdata_lock)
37718334Speter#define	IF_AFDATA_RUNLOCK(ifp)	rw_runlock(&(ifp)->if_afdata_lock)
378169689Skan#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
379169689Skan#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
380169689Skan#define	IF_AFDATA_TRYLOCK(ifp)	rw_try_wlock(&(ifp)->if_afdata_lock)
381169689Skan#define	IF_AFDATA_DESTROY(ifp)	rw_destroy(&(ifp)->if_afdata_lock)
382169689Skan
383169689Skan#define	IF_AFDATA_LOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
384169689Skan#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
385169689Skan
386169689Skanint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
387169689Skan	    int adjust);
388169689Skan#define	IF_HANDOFF(ifq, m, ifp)			\
389169689Skan	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
390169689Skan#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
39118334Speter	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
39218334Speter
39318334Spetervoid	if_start(struct ifnet *);
39418334Speter
395169689Skan#define	IFQ_ENQUEUE(ifq, m, err)					\
39618334Speterdo {									\
39718334Speter	IF_LOCK(ifq);							\
39818334Speter	if (ALTQ_IS_ENABLED(ifq))					\
39918334Speter		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
40018334Speter	else {								\
40118334Speter		if (_IF_QFULL(ifq)) {					\
40218334Speter			m_freem(m);					\
403169689Skan			(err) = ENOBUFS;				\
40418334Speter		} else {						\
405169689Skan			_IF_ENQUEUE(ifq, m);				\
40618334Speter			(err) = 0;					\
40718334Speter		}							\
40818334Speter	}								\
40918334Speter	if (err)							\
41018334Speter		(ifq)->ifq_drops++;					\
411169689Skan	IF_UNLOCK(ifq);							\
412169689Skan} while (0)
413169689Skan
41418334Speter#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
41518334Speterdo {									\
41618334Speter	if (TBR_IS_ENABLED(ifq))					\
41718334Speter		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
418169689Skan	else if (ALTQ_IS_ENABLED(ifq))					\
419169689Skan		ALTQ_DEQUEUE(ifq, m);					\
42018334Speter	else								\
42118334Speter		_IF_DEQUEUE(ifq, m);					\
42218334Speter} while (0)
42318334Speter
424169689Skan#define	IFQ_DEQUEUE(ifq, m)						\
425169689Skando {									\
426169689Skan	IF_LOCK(ifq);							\
42718334Speter	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
42818334Speter	IF_UNLOCK(ifq);							\
42918334Speter} while (0)
43018334Speter
43118334Speter#define	IFQ_POLL_NOLOCK(ifq, m)						\
43218334Speterdo {									\
43318334Speter	if (TBR_IS_ENABLED(ifq))					\
43418334Speter		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
43518334Speter	else if (ALTQ_IS_ENABLED(ifq))					\
43618334Speter		ALTQ_POLL(ifq, m);					\
43718334Speter	else								\
43818334Speter		_IF_POLL(ifq, m);					\
43918334Speter} while (0)
44018334Speter
44118334Speter#define	IFQ_POLL(ifq, m)						\
44218334Speterdo {									\
44318334Speter	IF_LOCK(ifq);							\
44418334Speter	IFQ_POLL_NOLOCK(ifq, m);					\
44518334Speter	IF_UNLOCK(ifq);							\
44618334Speter} while (0)
44718334Speter
44818334Speter#define	IFQ_PURGE_NOLOCK(ifq)						\
44918334Speterdo {									\
45018334Speter	if (ALTQ_IS_ENABLED(ifq)) {					\
451132718Skan		ALTQ_PURGE(ifq);					\
45218334Speter	} else								\
45318334Speter		_IF_DRAIN(ifq);						\
45418334Speter} while (0)
45518334Speter
45618334Speter#define	IFQ_PURGE(ifq)							\
45718334Speterdo {									\
45818334Speter	IF_LOCK(ifq);							\
459169689Skan	IFQ_PURGE_NOLOCK(ifq);						\
460169689Skan	IF_UNLOCK(ifq);							\
461169689Skan} while (0)
462169689Skan
46318334Speter#define	IFQ_SET_READY(ifq)						\
46418334Speter	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
465169689Skan
466169689Skan#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
467169689Skan#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
468169689Skan#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
469169689Skan#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
470169689Skan#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
471169689Skan#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
472169689Skan#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
473169689Skan#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
474169689Skan
475169689Skan/*
476169689Skan * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
477169689Skan * the handoff logic, as that flag is locked by the device driver.
478169689Skan */
47918334Speter#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
48018334Speterdo {									\
48118334Speter	int len;							\
48218334Speter	short mflags;							\
48318334Speter									\
484169689Skan	len = (m)->m_pkthdr.len;					\
485169689Skan	mflags = (m)->m_flags;						\
486169689Skan	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
487169689Skan	if ((err) == 0) {						\
48818334Speter		(ifp)->if_obytes += len + (adj);			\
48918334Speter		if (mflags & M_MCAST)					\
490169689Skan			(ifp)->if_omcasts++;				\
491169689Skan		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
492169689Skan			if_start(ifp);					\
493169689Skan	}								\
494169689Skan} while (0)
495169689Skan
496169689Skan#define	IFQ_HANDOFF(ifp, m, err)					\
497169689Skan	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
498169689Skan
499169689Skan#define	IFQ_DRV_DEQUEUE(ifq, m)						\
500169689Skando {									\
501169689Skan	(m) = (ifq)->ifq_drv_head;					\
502169689Skan	if (m) {							\
503169689Skan		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
50418334Speter			(ifq)->ifq_drv_tail = NULL;			\
505169689Skan		(m)->m_nextpkt = NULL;					\
50618334Speter		(ifq)->ifq_drv_len--;					\
50718334Speter	} else {							\
50818334Speter		IFQ_LOCK(ifq);						\
509169689Skan		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
51018334Speter		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
511169689Skan			struct mbuf *m0;				\
51250397Sobrien			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
51318334Speter			if (m0 == NULL)					\
51418334Speter				break;					\
51518334Speter			m0->m_nextpkt = NULL;				\
51618334Speter			if ((ifq)->ifq_drv_tail == NULL)		\
51718334Speter				(ifq)->ifq_drv_head = m0;		\
51818334Speter			else						\
51918334Speter				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
520169689Skan			(ifq)->ifq_drv_tail = m0;			\
521169689Skan			(ifq)->ifq_drv_len++;				\
522169689Skan		}							\
523169689Skan		IFQ_UNLOCK(ifq);					\
524169689Skan	}								\
525169689Skan} while (0)
526169689Skan
527169689Skan#define	IFQ_DRV_PREPEND(ifq, m)						\
528169689Skando {									\
529169689Skan	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
530169689Skan	if ((ifq)->ifq_drv_tail == NULL)				\
531169689Skan		(ifq)->ifq_drv_tail = (m);				\
532169689Skan	(ifq)->ifq_drv_head = (m);					\
533169689Skan	(ifq)->ifq_drv_len++;						\
534169689Skan} while (0)
535169689Skan
536169689Skan#define	IFQ_DRV_IS_EMPTY(ifq)						\
537169689Skan	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
538169689Skan
539169689Skan#define	IFQ_DRV_PURGE(ifq)						\
540169689Skando {									\
541169689Skan	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
542169689Skan	while((m = n) != NULL) {					\
543169689Skan		n = m->m_nextpkt;					\
544169689Skan		m_freem(m);						\
545169689Skan	}								\
546169689Skan	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
547169689Skan	(ifq)->ifq_drv_len = 0;						\
548169689Skan	IFQ_PURGE(ifq);							\
549169689Skan} while (0)
550169689Skan
551169689Skan#ifdef _KERNEL
552169689Skanstatic __inline void
553169689Skandrbr_stats_update(struct ifnet *ifp, int len, int mflags)
554169689Skan{
555169689Skan
556169689Skan	ifp->if_obytes += len;
557169689Skan	if (mflags & M_MCAST)
558169689Skan		ifp->if_omcasts++;
559169689Skan}
560169689Skan
561169689Skanstatic __inline int
562169689Skandrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
563169689Skan{
564169689Skan	int error = 0;
565169689Skan	int len = m->m_pkthdr.len;
566169689Skan	int mflags = m->m_flags;
567169689Skan
568169689Skan#ifdef ALTQ
569169689Skan	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
570169689Skan		IFQ_ENQUEUE(&ifp->if_snd, m, error);
571169689Skan		return (error);
572169689Skan	}
573169689Skan#endif
574169689Skan	if ((error = buf_ring_enqueue(br, m)) == ENOBUFS) {
575169689Skan		br->br_drops++;
576169689Skan		_IF_DROP(&ifp->if_snd);
577169689Skan		m_freem(m);
578169689Skan	} else
579169689Skan		drbr_stats_update(ifp, len, mflags);
580169689Skan
581169689Skan	return (error);
582169689Skan}
583169689Skan
584169689Skanstatic __inline void
585169689Skandrbr_free(struct buf_ring *br, struct malloc_type *type)
586169689Skan{
587169689Skan	struct mbuf *m;
588169689Skan
589169689Skan	while ((m = buf_ring_dequeue_sc(br)) != NULL)
590169689Skan		m_freem(m);
591169689Skan
592169689Skan	buf_ring_free(br, type);
593169689Skan}
594169689Skan
595169689Skanstatic __inline struct mbuf *
596169689Skandrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
597169689Skan{
598169689Skan#ifdef ALTQ
599169689Skan	struct mbuf *m;
600169689Skan
601169689Skan	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
602169689Skan		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
603169689Skan		return (m);
604169689Skan	}
605169689Skan#endif
606169689Skan	return (buf_ring_dequeue_sc(br));
607169689Skan}
608169689Skan
609169689Skanstatic __inline int
610169689Skandrbr_empty(struct ifnet *ifp, struct buf_ring *br)
611169689Skan{
612169689Skan#ifdef ALTQ
613169689Skan	if (ALTQ_IS_ENABLED(&ifp->if_snd))
614169689Skan		return (IFQ_DRV_IS_EMPTY(&ifp->if_snd));
615169689Skan#endif
616169689Skan	return (buf_ring_empty(br));
617169689Skan}
618169689Skan#endif
619169689Skan/*
620169689Skan * 72 was chosen below because it is the size of a TCP/IP
621169689Skan * header (40) + the minimum mss (32).
622169689Skan */
623169689Skan#define	IF_MINMTU	72
624169689Skan#define	IF_MAXMTU	65535
625169689Skan
626169689Skan#endif /* _KERNEL */
627169689Skan
628169689Skan/*
629169689Skan * The ifaddr structure contains information about one address
630169689Skan * of an interface.  They are maintained by the different address families,
631169689Skan * are allocated and attached when an address is set, and are linked
632169689Skan * together so all addresses for an interface can be located.
633169689Skan *
634169689Skan * NOTE: a 'struct ifaddr' is always at the beginning of a larger
635169689Skan * chunk of malloc'ed memory, where we store the three addresses
636169689Skan * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
637169689Skan */
638169689Skanstruct ifaddr {
639169689Skan	struct	sockaddr *ifa_addr;	/* address of interface */
640169689Skan	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
641169689Skan#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
642169689Skan	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
643169689Skan	struct	if_data if_data;	/* not all members are meaningful */
644169689Skan	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
645169689Skan	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
646169689Skan	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
647169689Skan		(int, struct rtentry *, struct rt_addrinfo *);
648169689Skan	u_short	ifa_flags;		/* mostly rt_flags for cloning */
649169689Skan	u_int	ifa_refcnt;		/* references to this structure */
650169689Skan	int	ifa_metric;		/* cost of going out this interface */
651169689Skan	int (*ifa_claim_addr)		/* check if an addr goes to this if */
652169689Skan		(struct ifaddr *, struct sockaddr *);
653169689Skan	struct mtx ifa_mtx;
654169689Skan};
655169689Skan#define	IFA_ROUTE	RTF_UP		/* route installed */
656169689Skan
657169689Skan/* for compatibility with other BSDs */
658169689Skan#define	ifa_list	ifa_link
659169689Skan
660169689Skan#define	IFA_LOCK_INIT(ifa)	\
661169689Skan    mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF)
662169689Skan#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
663169689Skan#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
664169689Skan#define	IFA_DESTROY(ifa)	mtx_destroy(&(ifa)->ifa_mtx)
665169689Skan
666169689Skan/*
667169689Skan * The prefix structure contains information about one prefix
668169689Skan * of an interface.  They are maintained by the different address families,
669169689Skan * are allocated and attached when a prefix or an address is set,
670169689Skan * and are linked together so all prefixes for an interface can be located.
671169689Skan */
672169689Skanstruct ifprefix {
673169689Skan	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
674169689Skan	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
675169689Skan	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
676169689Skan	u_char	ifpr_plen;		/* prefix length in bits */
677169689Skan	u_char	ifpr_type;		/* protocol dependent prefix type */
678169689Skan};
679169689Skan
680169689Skan/*
681169689Skan * Multicast address structure.  This is analogous to the ifaddr
682169689Skan * structure except that it keeps track of multicast addresses.
683169689Skan */
684169689Skanstruct ifmultiaddr {
685169689Skan	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
686169689Skan	struct	sockaddr *ifma_addr; 	/* address this membership is for */
687169689Skan	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
688169689Skan	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
689169689Skan	u_int	ifma_refcount;		/* reference count */
690169689Skan	void	*ifma_protospec;	/* protocol-specific state, if any */
691169689Skan	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
692169689Skan};
693169689Skan
694169689Skan#ifdef _KERNEL
695169689Skan#define	IFAFREE(ifa)					\
696169689Skan	do {						\
697169689Skan		IFA_LOCK(ifa);				\
698169689Skan		KASSERT((ifa)->ifa_refcnt > 0,		\
699169689Skan		    ("ifa %p !(ifa_refcnt > 0)", ifa));	\
700169689Skan		if (--(ifa)->ifa_refcnt == 0) {		\
701169689Skan			IFA_DESTROY(ifa);		\
702169689Skan			free(ifa, M_IFADDR);		\
703169689Skan		} else 					\
704169689Skan			IFA_UNLOCK(ifa);		\
705169689Skan	} while (0)
706169689Skan
707169689Skan#define IFAREF(ifa)					\
708169689Skan	do {						\
709169689Skan		IFA_LOCK(ifa);				\
710169689Skan		++(ifa)->ifa_refcnt;			\
711169689Skan		IFA_UNLOCK(ifa);			\
712169689Skan	} while (0)
713169689Skan
714169689Skanextern	struct rwlock ifnet_lock;
715169689Skan#define	IFNET_LOCK_INIT() \
716169689Skan   rw_init_flags(&ifnet_lock, "ifnet",  RW_RECURSE)
717169689Skan#define	IFNET_WLOCK()		rw_wlock(&ifnet_lock)
718169689Skan#define	IFNET_WUNLOCK()		rw_wunlock(&ifnet_lock)
719169689Skan#define	IFNET_WLOCK_ASSERT()	rw_assert(&ifnet_lock, RA_LOCKED)
720169689Skan#define	IFNET_RLOCK()		rw_rlock(&ifnet_lock)
721169689Skan#define	IFNET_RUNLOCK()		rw_runlock(&ifnet_lock)
722169689Skan
723169689Skanstruct ifindex_entry {
724169689Skan	struct	ifnet *ife_ifnet;
725169689Skan	struct cdev *ife_dev;
726169689Skan};
727169689Skan
728169689Skan/*
729169689Skan * Look up an ifnet given its index; the _ref variant also acquires a
730169689Skan * reference that must be freed using if_rele().  It is almost always a bug
731169689Skan * to call ifnet_byindex() instead if ifnet_byindex_ref().
732169689Skan */
733169689Skanstruct ifnet	*ifnet_byindex(u_short idx);
734169689Skanstruct ifnet	*ifnet_byindex_locked(u_short idx);
735169689Skanstruct ifnet	*ifnet_byindex_ref(u_short idx);
73618334Spetervoid ifnet_setbyindex(u_short idx, struct ifnet *ifp);
737169689Skan
738169689Skan/*
739169689Skan * Given the index, ifaddr_byindex() returns the one and only
740169689Skan * link-level ifaddr for the interface. You are not supposed to use
741169689Skan * it to traverse the list of addresses associated to the interface.
742169689Skan */
743169689Skanstruct ifaddr	*ifaddr_byindex(u_short idx);
744169689Skanstruct cdev	*ifdev_byindex(u_short idx);
745169689Skan
746169689Skan#ifdef VIMAGE_GLOBALS
747169689Skanextern	struct ifnethead ifnet;
748169689Skanextern	struct ifnet *loif;	/* first loopback interface */
749169689Skanextern	int if_index;
750169689Skan#endif
751169689Skanextern	int ifqmaxlen;
752169689Skan
753169689Skanint	if_addgroup(struct ifnet *, const char *);
754169689Skanint	if_delgroup(struct ifnet *, const char *);
755169689Skanint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
756169689Skanint	if_allmulti(struct ifnet *, int);
757169689Skanstruct	ifnet* if_alloc(u_char);
758169689Skanvoid	if_attach(struct ifnet *);
759169689Skanvoid	if_dead(struct ifnet *);
760169689Skanvoid	if_grow(void);
761169689Skanint	if_delmulti(struct ifnet *, struct sockaddr *);
762169689Skanvoid	if_delmulti_ifma(struct ifmultiaddr *);
763169689Skanvoid	if_detach(struct ifnet *);
76418334Spetervoid	if_purgeaddrs(struct ifnet *);
76518334Spetervoid	if_purgemaddrs(struct ifnet *);
76618334Spetervoid	if_down(struct ifnet *);
76718334Speterstruct ifmultiaddr *
76818334Speter	if_findmulti(struct ifnet *, struct sockaddr *);
769169689Skanvoid	if_free(struct ifnet *);
77018334Spetervoid	if_free_type(struct ifnet *, u_char);
771169689Skanvoid	if_initname(struct ifnet *, const char *, int);
772169689Skanvoid	if_link_state_change(struct ifnet *, int);
773169689Skanint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
774169689Skanvoid	if_qflush(struct ifnet *);
775169689Skanvoid	if_ref(struct ifnet *);
776169689Skanvoid	if_rele(struct ifnet *);
777169689Skanint	if_setlladdr(struct ifnet *, const u_char *, int);
778169689Skanvoid	if_up(struct ifnet *);
779169689Skan/*void	ifinit(void);*/ /* declared in systm.h for main() */
780169689Skanint	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
781169689Skanint	ifpromisc(struct ifnet *, int);
782169689Skanstruct	ifnet *ifunit(const char *);
783169689Skanstruct	ifnet *ifunit_ref(const char *);
784169689Skan
785169689Skanvoid	ifq_attach(struct ifaltq *, struct ifnet *ifp);
786169689Skanvoid	ifq_detach(struct ifaltq *);
787169689Skan
78890075Sobrienstruct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
78990075Sobrienstruct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
79018334Speterstruct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
79118334Speterstruct	ifaddr *ifa_ifwithnet(struct sockaddr *);
79218334Speterstruct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
79318334Speterstruct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
79450397Sobrien
79550397Sobrienstruct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
79618334Speter
79718334Speterint	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
79890075Sobrien
79990075Sobrientypedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
80090075Sobrientypedef	void if_com_free_t(void *com, u_char type);
801169689Skanvoid	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
802169689Skanvoid	if_deregister_com_alloc(u_char type);
80390075Sobrien
80490075Sobrien#define IF_LLADDR(ifp)							\
805169689Skan    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
806169689Skan
80790075Sobrien#ifdef DEVICE_POLLING
808169689Skanenum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
809132718Skan
810132718Skantypedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
811132718Skanint    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
81218334Speterint    ether_poll_deregister(struct ifnet *ifp);
813132718Skan#endif /* DEVICE_POLLING */
814169689Skan
815132718Skan#endif /* _KERNEL */
816169689Skan
81718334Speter#endif /* !_NET_IF_VAR_H_ */
81818334Speter