xref: /freebsd/sys/net/if_var.h (revision eca8a663)
119ff91c6SGarrett Wollman /*
219ff91c6SGarrett Wollman  * Copyright (c) 1982, 1986, 1989, 1993
319ff91c6SGarrett Wollman  *	The Regents of the University of California.  All rights reserved.
419ff91c6SGarrett Wollman  *
519ff91c6SGarrett Wollman  * Redistribution and use in source and binary forms, with or without
619ff91c6SGarrett Wollman  * modification, are permitted provided that the following conditions
719ff91c6SGarrett Wollman  * are met:
819ff91c6SGarrett Wollman  * 1. Redistributions of source code must retain the above copyright
919ff91c6SGarrett Wollman  *    notice, this list of conditions and the following disclaimer.
1019ff91c6SGarrett Wollman  * 2. Redistributions in binary form must reproduce the above copyright
1119ff91c6SGarrett Wollman  *    notice, this list of conditions and the following disclaimer in the
1219ff91c6SGarrett Wollman  *    documentation and/or other materials provided with the distribution.
1319ff91c6SGarrett Wollman  * 3. All advertising materials mentioning features or use of this software
1419ff91c6SGarrett Wollman  *    must display the following acknowledgement:
1519ff91c6SGarrett Wollman  *	This product includes software developed by the University of
1619ff91c6SGarrett Wollman  *	California, Berkeley and its contributors.
1719ff91c6SGarrett Wollman  * 4. Neither the name of the University nor the names of its contributors
1819ff91c6SGarrett Wollman  *    may be used to endorse or promote products derived from this software
1919ff91c6SGarrett Wollman  *    without specific prior written permission.
2019ff91c6SGarrett Wollman  *
2119ff91c6SGarrett Wollman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2219ff91c6SGarrett Wollman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2319ff91c6SGarrett Wollman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2419ff91c6SGarrett Wollman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2519ff91c6SGarrett Wollman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2619ff91c6SGarrett Wollman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2719ff91c6SGarrett Wollman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2819ff91c6SGarrett Wollman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2919ff91c6SGarrett Wollman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3019ff91c6SGarrett Wollman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3119ff91c6SGarrett Wollman  * SUCH DAMAGE.
3219ff91c6SGarrett Wollman  *
3319ff91c6SGarrett Wollman  *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
34c3aac50fSPeter Wemm  * $FreeBSD$
3519ff91c6SGarrett Wollman  */
3619ff91c6SGarrett Wollman 
3719ff91c6SGarrett Wollman #ifndef	_NET_IF_VAR_H_
3819ff91c6SGarrett Wollman #define	_NET_IF_VAR_H_
3919ff91c6SGarrett Wollman 
4019ff91c6SGarrett Wollman /*
4119ff91c6SGarrett Wollman  * Structures defining a network interface, providing a packet
4219ff91c6SGarrett Wollman  * transport mechanism (ala level 0 of the PUP protocols).
4319ff91c6SGarrett Wollman  *
4419ff91c6SGarrett Wollman  * Each interface accepts output datagrams of a specified maximum
4519ff91c6SGarrett Wollman  * length, and provides higher level routines with input datagrams
4619ff91c6SGarrett Wollman  * received from its medium.
4719ff91c6SGarrett Wollman  *
4819ff91c6SGarrett Wollman  * Output occurs when the routine if_output is called, with three parameters:
4919ff91c6SGarrett Wollman  *	(*ifp->if_output)(ifp, m, dst, rt)
5019ff91c6SGarrett Wollman  * Here m is the mbuf chain to be sent and dst is the destination address.
5119ff91c6SGarrett Wollman  * The output routine encapsulates the supplied datagram if necessary,
5219ff91c6SGarrett Wollman  * and then transmits it on its medium.
5319ff91c6SGarrett Wollman  *
5419ff91c6SGarrett Wollman  * On input, each interface unwraps the data received by it, and either
559d5abbddSJens Schweikhardt  * places it on the input queue of an internetwork datagram routine
5619ff91c6SGarrett Wollman  * and posts the associated software interrupt, or passes the datagram to a raw
5719ff91c6SGarrett Wollman  * packet input routine.
5819ff91c6SGarrett Wollman  *
5919ff91c6SGarrett Wollman  * Routines exist for locating interfaces by their addresses
609d5abbddSJens Schweikhardt  * or for locating an interface on a certain network, as well as more general
6119ff91c6SGarrett Wollman  * routing and gateway routines maintaining information used to locate
6219ff91c6SGarrett Wollman  * interfaces.  These routines live in the files if.c and route.c
6319ff91c6SGarrett Wollman  */
6419ff91c6SGarrett Wollman 
6519ff91c6SGarrett Wollman #ifdef __STDC__
6619ff91c6SGarrett Wollman /*
6719ff91c6SGarrett Wollman  * Forward structure declarations for function prototypes [sic].
6819ff91c6SGarrett Wollman  */
6919ff91c6SGarrett Wollman struct	mbuf;
70b40ce416SJulian Elischer struct	thread;
7119ff91c6SGarrett Wollman struct	rtentry;
728071913dSRuslan Ermilov struct	rt_addrinfo;
7319ff91c6SGarrett Wollman struct	socket;
7419ff91c6SGarrett Wollman struct	ether_header;
7519ff91c6SGarrett Wollman #endif
7619ff91c6SGarrett Wollman 
7719ff91c6SGarrett Wollman #include <sys/queue.h>		/* get TAILQ macros */
7819ff91c6SGarrett Wollman 
799ba20c31SJonathan Lemon #ifdef _KERNEL
80df5e1987SJonathan Lemon #include <sys/mbuf.h>
819ba20c31SJonathan Lemon #endif /* _KERNEL */
82f34fa851SJohn Baldwin #include <sys/lock.h>		/* XXX */
83f34fa851SJohn Baldwin #include <sys/mutex.h>		/* XXX */
84f9132cebSJonathan Lemon #include <sys/event.h>		/* XXX */
85df5e1987SJonathan Lemon 
869bf40edeSBrooks Davis #define	IF_DUNIT_NONE	-1
879bf40edeSBrooks Davis 
88e3975643SJake Burkholder TAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
89e3975643SJake Burkholder TAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
90e3975643SJake Burkholder TAILQ_HEAD(ifprefixhead, ifprefix);
916817526dSPoul-Henning Kamp TAILQ_HEAD(ifmultihead, ifmultiaddr);
9219ff91c6SGarrett Wollman 
9319ff91c6SGarrett Wollman /*
9419ff91c6SGarrett Wollman  * Structure defining a queue for a network interface.
9519ff91c6SGarrett Wollman  */
9619ff91c6SGarrett Wollman struct	ifqueue {
9719ff91c6SGarrett Wollman 	struct	mbuf *ifq_head;
9819ff91c6SGarrett Wollman 	struct	mbuf *ifq_tail;
9919ff91c6SGarrett Wollman 	int	ifq_len;
10019ff91c6SGarrett Wollman 	int	ifq_maxlen;
10119ff91c6SGarrett Wollman 	int	ifq_drops;
102df5e1987SJonathan Lemon 	struct	mtx ifq_mtx;
10319ff91c6SGarrett Wollman };
10419ff91c6SGarrett Wollman 
10519ff91c6SGarrett Wollman /*
10619ff91c6SGarrett Wollman  * Structure defining a network interface.
10719ff91c6SGarrett Wollman  *
10819ff91c6SGarrett Wollman  * (Would like to call this struct ``if'', but C isn't PL/1.)
10919ff91c6SGarrett Wollman  */
1108ec410b5SMatt Jacob 
1118ec410b5SMatt Jacob /*
1128ec410b5SMatt Jacob  * NB: For FreeBSD, it is assumed that each NIC driver's softc starts with
1138ec410b5SMatt Jacob  * one of these structures, typically held within an arpcom structure.
114985fbf6bSLuigi Rizzo  *
115985fbf6bSLuigi Rizzo  *	struct <foo>_softc {
116985fbf6bSLuigi Rizzo  *		struct arpcom {
117985fbf6bSLuigi Rizzo  *			struct  ifnet ac_if;
118985fbf6bSLuigi Rizzo  *			...
119985fbf6bSLuigi Rizzo  *		} <arpcom> ;
120985fbf6bSLuigi Rizzo  *		...
121985fbf6bSLuigi Rizzo  *	};
122985fbf6bSLuigi Rizzo  *
123985fbf6bSLuigi Rizzo  * The assumption is used in a number of places, including many
124985fbf6bSLuigi Rizzo  * files in sys/net, device drivers, and sys/dev/mii.c:miibus_attach().
125985fbf6bSLuigi Rizzo  *
126985fbf6bSLuigi Rizzo  * Unfortunately devices' softc are opaque, so we depend on this layout
127985fbf6bSLuigi Rizzo  * to locate the struct ifnet from the softc in the generic code.
128985fbf6bSLuigi Rizzo  *
1298ec410b5SMatt Jacob  */
13019ff91c6SGarrett Wollman struct ifnet {
13119ff91c6SGarrett Wollman 	void	*if_softc;		/* pointer to driver state */
132e3975643SJake Burkholder 	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
1339bf40edeSBrooks Davis 	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
1349bf40edeSBrooks Davis 	const char *if_dname;		/* driver name */
1359bf40edeSBrooks Davis 	int	if_dunit;		/* unit or IF_DUNIT_NONE */
13619ff91c6SGarrett Wollman 	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
137f9132cebSJonathan Lemon 	struct	klist if_klist;		/* events attached to this if */
13819ff91c6SGarrett Wollman 	int	if_pcount;		/* number of promiscuous listeners */
13919ff91c6SGarrett Wollman 	struct	bpf_if *if_bpf;		/* packet filter structure */
14019ff91c6SGarrett Wollman 	u_short	if_index;		/* numeric abbreviation for this if  */
14119ff91c6SGarrett Wollman 	short	if_timer;		/* time 'til if_watchdog called */
14276cfd300SSam Leffler 	u_short	if_nvlans;		/* number of active vlans */
14362f76486SMaxim Sobolev 	int	if_flags;		/* up/down, broadcast, etc. */
144016da741SJonathan Lemon 	int	if_capabilities;	/* interface capabilities */
145016da741SJonathan Lemon 	int	if_capenable;		/* enabled features */
14619ff91c6SGarrett Wollman 	int	if_ipending;		/* interrupts pending */
14719ff91c6SGarrett Wollman 	void	*if_linkmib;		/* link-type-specific MIB data */
14819ff91c6SGarrett Wollman 	size_t	if_linkmiblen;		/* length of above data */
14919ff91c6SGarrett Wollman 	struct	if_data if_data;
1501158dfb7SGarrett Wollman 	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
1511158dfb7SGarrett Wollman 	int	if_amcount;		/* number of all-multicast requests */
15219ff91c6SGarrett Wollman /* procedure handles */
15319ff91c6SGarrett Wollman 	int	(*if_output)		/* output routine (enqueue) */
154929ddbbbSAlfred Perlstein 		(struct ifnet *, struct mbuf *, struct sockaddr *,
155929ddbbbSAlfred Perlstein 		     struct rtentry *);
15676cfd300SSam Leffler 	void	(*if_input)		/* input routine (from h/w driver) */
15776cfd300SSam Leffler 		(struct ifnet *, struct mbuf *);
15819ff91c6SGarrett Wollman 	void	(*if_start)		/* initiate output routine */
159929ddbbbSAlfred Perlstein 		(struct ifnet *);
16019ff91c6SGarrett Wollman 	int	(*if_done)		/* output complete routine */
161929ddbbbSAlfred Perlstein 		(struct ifnet *);	/* (XXX not used; fake prototype) */
16219ff91c6SGarrett Wollman 	int	(*if_ioctl)		/* ioctl routine */
163929ddbbbSAlfred Perlstein 		(struct ifnet *, u_long, caddr_t);
16419ff91c6SGarrett Wollman 	void	(*if_watchdog)		/* timer routine */
165929ddbbbSAlfred Perlstein 		(struct ifnet *);
16619ff91c6SGarrett Wollman 	int	(*if_poll_recv)		/* polled receive routine */
167929ddbbbSAlfred Perlstein 		(struct ifnet *, int *);
16819ff91c6SGarrett Wollman 	int	(*if_poll_xmit)		/* polled transmit routine */
169929ddbbbSAlfred Perlstein 		(struct ifnet *, int *);
17019ff91c6SGarrett Wollman 	void	(*if_poll_intren)	/* polled interrupt reenable routine */
171929ddbbbSAlfred Perlstein 		(struct ifnet *);
17219ff91c6SGarrett Wollman 	void	(*if_poll_slowinput)	/* input routine for slow devices */
173929ddbbbSAlfred Perlstein 		(struct ifnet *, struct mbuf *);
17419ff91c6SGarrett Wollman 	void	(*if_init)		/* Init routine */
175929ddbbbSAlfred Perlstein 		(void *);
1761158dfb7SGarrett Wollman 	int	(*if_resolvemulti)	/* validate/resolve multicast */
177929ddbbbSAlfred Perlstein 		(struct ifnet *, struct sockaddr **, struct sockaddr *);
17819ff91c6SGarrett Wollman 	struct	ifqueue if_snd;		/* output queue */
17919ff91c6SGarrett Wollman 	struct	ifqueue *if_poll_slowq;	/* input queue for slow devices */
18076429de4SYoshinobu Inoue 	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
181322dcb8dSMax Khon 	u_int8_t *if_broadcastaddr;	/* linklevel broadcast bytestring */
182eca8a663SRobert Watson 	struct	label *if_label;	/* interface MAC label */
18331b1bfe1SHajimu UMEMOTO 
18431b1bfe1SHajimu UMEMOTO 	void	*if_afdata[AF_MAX];
185234a35c7SHajimu UMEMOTO 	int	if_afdata_initialized;
186234a35c7SHajimu UMEMOTO 	struct	mtx if_afdata_mtx;
18719ff91c6SGarrett Wollman };
188df5e1987SJonathan Lemon 
189929ddbbbSAlfred Perlstein typedef void if_init_f_t(void *);
19019ff91c6SGarrett Wollman 
19119ff91c6SGarrett Wollman #define	if_mtu		if_data.ifi_mtu
19219ff91c6SGarrett Wollman #define	if_type		if_data.ifi_type
19319ff91c6SGarrett Wollman #define if_physical	if_data.ifi_physical
19419ff91c6SGarrett Wollman #define	if_addrlen	if_data.ifi_addrlen
19519ff91c6SGarrett Wollman #define	if_hdrlen	if_data.ifi_hdrlen
19619ff91c6SGarrett Wollman #define	if_metric	if_data.ifi_metric
19719ff91c6SGarrett Wollman #define	if_baudrate	if_data.ifi_baudrate
198db4f9cc7SJonathan Lemon #define	if_hwassist	if_data.ifi_hwassist
19919ff91c6SGarrett Wollman #define	if_ipackets	if_data.ifi_ipackets
20019ff91c6SGarrett Wollman #define	if_ierrors	if_data.ifi_ierrors
20119ff91c6SGarrett Wollman #define	if_opackets	if_data.ifi_opackets
20219ff91c6SGarrett Wollman #define	if_oerrors	if_data.ifi_oerrors
20319ff91c6SGarrett Wollman #define	if_collisions	if_data.ifi_collisions
20419ff91c6SGarrett Wollman #define	if_ibytes	if_data.ifi_ibytes
20519ff91c6SGarrett Wollman #define	if_obytes	if_data.ifi_obytes
20619ff91c6SGarrett Wollman #define	if_imcasts	if_data.ifi_imcasts
20719ff91c6SGarrett Wollman #define	if_omcasts	if_data.ifi_omcasts
20819ff91c6SGarrett Wollman #define	if_iqdrops	if_data.ifi_iqdrops
20919ff91c6SGarrett Wollman #define	if_noproto	if_data.ifi_noproto
21019ff91c6SGarrett Wollman #define	if_lastchange	if_data.ifi_lastchange
21119ff91c6SGarrett Wollman #define if_recvquota	if_data.ifi_recvquota
21219ff91c6SGarrett Wollman #define	if_xmitquota	if_data.ifi_xmitquota
21319ff91c6SGarrett Wollman #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0)
21419ff91c6SGarrett Wollman 
21582cd038dSYoshinobu Inoue /* for compatibility with other BSDs */
21682cd038dSYoshinobu Inoue #define	if_addrlist	if_addrhead
21782cd038dSYoshinobu Inoue #define	if_list		if_link
21882cd038dSYoshinobu Inoue 
21919ff91c6SGarrett Wollman /*
22019ff91c6SGarrett Wollman  * Bit values in if_ipending
22119ff91c6SGarrett Wollman  */
22219ff91c6SGarrett Wollman #define	IFI_RECV	1	/* I want to receive */
22319ff91c6SGarrett Wollman #define	IFI_XMIT	2	/* I want to transmit */
22419ff91c6SGarrett Wollman 
22519ff91c6SGarrett Wollman /*
22619ff91c6SGarrett Wollman  * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
22719ff91c6SGarrett Wollman  * are queues of messages stored on ifqueue structures
22819ff91c6SGarrett Wollman  * (defined above).  Entries are added to and deleted from these structures
22919ff91c6SGarrett Wollman  * by these macros, which should be called with ipl raised to splimp().
23019ff91c6SGarrett Wollman  */
2319ed346baSBosko Milekic #define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
2329ed346baSBosko Milekic #define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
233df5e1987SJonathan Lemon #define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
234df5e1987SJonathan Lemon #define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
235df5e1987SJonathan Lemon #define	_IF_QLEN(ifq)		((ifq)->ifq_len)
236df5e1987SJonathan Lemon 
237df5e1987SJonathan Lemon #define	_IF_ENQUEUE(ifq, m) do { 				\
238df5e1987SJonathan Lemon 	(m)->m_nextpkt = NULL;					\
239df5e1987SJonathan Lemon 	if ((ifq)->ifq_tail == NULL) 				\
24019ff91c6SGarrett Wollman 		(ifq)->ifq_head = m; 				\
24119ff91c6SGarrett Wollman 	else 							\
24219ff91c6SGarrett Wollman 		(ifq)->ifq_tail->m_nextpkt = m; 		\
24319ff91c6SGarrett Wollman 	(ifq)->ifq_tail = m; 					\
24419ff91c6SGarrett Wollman 	(ifq)->ifq_len++; 					\
245df5e1987SJonathan Lemon } while (0)
246df5e1987SJonathan Lemon 
247df5e1987SJonathan Lemon #define IF_ENQUEUE(ifq, m) do {					\
248df5e1987SJonathan Lemon 	IF_LOCK(ifq); 						\
249df5e1987SJonathan Lemon 	_IF_ENQUEUE(ifq, m); 					\
250df5e1987SJonathan Lemon 	IF_UNLOCK(ifq); 					\
251df5e1987SJonathan Lemon } while (0)
252df5e1987SJonathan Lemon 
253df5e1987SJonathan Lemon #define	_IF_PREPEND(ifq, m) do {				\
25419ff91c6SGarrett Wollman 	(m)->m_nextpkt = (ifq)->ifq_head; 			\
255df5e1987SJonathan Lemon 	if ((ifq)->ifq_tail == NULL) 				\
25619ff91c6SGarrett Wollman 		(ifq)->ifq_tail = (m); 				\
25719ff91c6SGarrett Wollman 	(ifq)->ifq_head = (m); 					\
25819ff91c6SGarrett Wollman 	(ifq)->ifq_len++; 					\
259df5e1987SJonathan Lemon } while (0)
260df5e1987SJonathan Lemon 
261df5e1987SJonathan Lemon #define IF_PREPEND(ifq, m) do {		 			\
262df5e1987SJonathan Lemon 	IF_LOCK(ifq); 						\
263df5e1987SJonathan Lemon 	_IF_PREPEND(ifq, m); 					\
264df5e1987SJonathan Lemon 	IF_UNLOCK(ifq); 					\
265df5e1987SJonathan Lemon } while (0)
266df5e1987SJonathan Lemon 
267df5e1987SJonathan Lemon #define	_IF_DEQUEUE(ifq, m) do { 				\
26819ff91c6SGarrett Wollman 	(m) = (ifq)->ifq_head; 					\
26919ff91c6SGarrett Wollman 	if (m) { 						\
27019ff91c6SGarrett Wollman 		if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) 	\
271df5e1987SJonathan Lemon 			(ifq)->ifq_tail = NULL; 		\
272df5e1987SJonathan Lemon 		(m)->m_nextpkt = NULL; 				\
27319ff91c6SGarrett Wollman 		(ifq)->ifq_len--; 				\
27419ff91c6SGarrett Wollman 	} 							\
275df5e1987SJonathan Lemon } while (0)
276df5e1987SJonathan Lemon 
277df5e1987SJonathan Lemon #define IF_DEQUEUE(ifq, m) do { 				\
278df5e1987SJonathan Lemon 	IF_LOCK(ifq); 						\
279df5e1987SJonathan Lemon 	_IF_DEQUEUE(ifq, m); 					\
280df5e1987SJonathan Lemon 	IF_UNLOCK(ifq); 					\
281df5e1987SJonathan Lemon } while (0)
282df5e1987SJonathan Lemon 
283df5e1987SJonathan Lemon #define IF_DRAIN(ifq) do { 					\
284df5e1987SJonathan Lemon 	struct mbuf *m; 					\
285df5e1987SJonathan Lemon 	IF_LOCK(ifq); 						\
286df5e1987SJonathan Lemon 	for (;;) { 						\
287df5e1987SJonathan Lemon 		_IF_DEQUEUE(ifq, m); 				\
288df5e1987SJonathan Lemon 		if (m == NULL) 					\
289df5e1987SJonathan Lemon 			break; 					\
290df5e1987SJonathan Lemon 		m_freem(m); 					\
291df5e1987SJonathan Lemon 	} 							\
292df5e1987SJonathan Lemon 	IF_UNLOCK(ifq); 					\
293df5e1987SJonathan Lemon } while (0)
29419ff91c6SGarrett Wollman 
295664a31e4SPeter Wemm #ifdef _KERNEL
296234a35c7SHajimu UMEMOTO #define	IF_AFDATA_LOCK_INIT(ifp)	\
297234a35c7SHajimu UMEMOTO     mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF)
298234a35c7SHajimu UMEMOTO #define	IF_AFDATA_LOCK(ifp)	mtx_lock(&(ifp)->if_afdata_mtx)
299234a35c7SHajimu UMEMOTO #define	IF_AFDATA_TRYLOCK(ifp)	mtx_trylock(&(ifp)->if_afdata_mtx)
300234a35c7SHajimu UMEMOTO #define	IF_AFDATA_UNLOCK(ifp)	mtx_unlock(&(ifp)->if_afdata_mtx)
301234a35c7SHajimu UMEMOTO #define	IF_AFDATA_DESTROY(ifp)	mtx_destroy(&(ifp)->if_afdata_mtx)
302234a35c7SHajimu UMEMOTO 
303df5e1987SJonathan Lemon #define	IF_HANDOFF(ifq, m, ifp)			if_handoff(ifq, m, ifp, 0)
304df5e1987SJonathan Lemon #define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	if_handoff(ifq, m, ifp, adj)
30519ff91c6SGarrett Wollman 
306c1087c13SBruce Evans static __inline int
307df5e1987SJonathan Lemon if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust)
30819ff91c6SGarrett Wollman {
309df5e1987SJonathan Lemon 	int active = 0;
310df5e1987SJonathan Lemon 
311df5e1987SJonathan Lemon 	IF_LOCK(ifq);
312df5e1987SJonathan Lemon 	if (_IF_QFULL(ifq)) {
313df5e1987SJonathan Lemon 		_IF_DROP(ifq);
314df5e1987SJonathan Lemon 		IF_UNLOCK(ifq);
315df5e1987SJonathan Lemon 		m_freem(m);
316df5e1987SJonathan Lemon 		return (0);
31719ff91c6SGarrett Wollman 	}
318df5e1987SJonathan Lemon 	if (ifp != NULL) {
319df5e1987SJonathan Lemon 		ifp->if_obytes += m->m_pkthdr.len + adjust;
320df5e1987SJonathan Lemon 		if (m->m_flags & M_MCAST)
321df5e1987SJonathan Lemon 			ifp->if_omcasts++;
322df5e1987SJonathan Lemon 		active = ifp->if_flags & IFF_OACTIVE;
323df5e1987SJonathan Lemon 	}
324df5e1987SJonathan Lemon 	_IF_ENQUEUE(ifq, m);
325df5e1987SJonathan Lemon 	IF_UNLOCK(ifq);
32699efe4f0SJohn Baldwin 	if (ifp != NULL && !active)
327df5e1987SJonathan Lemon 		(*ifp->if_start)(ifp);
328df5e1987SJonathan Lemon 	return (1);
329df5e1987SJonathan Lemon }
330aab3beeeSBrian Somers 
331aab3beeeSBrian Somers /*
332aab3beeeSBrian Somers  * 72 was chosen below because it is the size of a TCP/IP
333aab3beeeSBrian Somers  * header (40) + the minimum mss (32).
334aab3beeeSBrian Somers  */
335aab3beeeSBrian Somers #define	IF_MINMTU	72
336aab3beeeSBrian Somers #define	IF_MAXMTU	65535
337aab3beeeSBrian Somers 
338664a31e4SPeter Wemm #endif /* _KERNEL */
33919ff91c6SGarrett Wollman 
34019ff91c6SGarrett Wollman /*
34119ff91c6SGarrett Wollman  * The ifaddr structure contains information about one address
34219ff91c6SGarrett Wollman  * of an interface.  They are maintained by the different address families,
34319ff91c6SGarrett Wollman  * are allocated and attached when an address is set, and are linked
34419ff91c6SGarrett Wollman  * together so all addresses for an interface can be located.
34519ff91c6SGarrett Wollman  */
34619ff91c6SGarrett Wollman struct ifaddr {
34719ff91c6SGarrett Wollman 	struct	sockaddr *ifa_addr;	/* address of interface */
34819ff91c6SGarrett Wollman 	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
34919ff91c6SGarrett Wollman #define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
35019ff91c6SGarrett Wollman 	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
3515da9f8faSJosef Karthauser 	struct	if_data if_data;	/* not all members are meaningful */
35219ff91c6SGarrett Wollman 	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
353e3975643SJake Burkholder 	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
35419ff91c6SGarrett Wollman 	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
355929ddbbbSAlfred Perlstein 		(int, struct rtentry *, struct rt_addrinfo *);
35619ff91c6SGarrett Wollman 	u_short	ifa_flags;		/* mostly rt_flags for cloning */
357e3c1388bSPierre Beyssac 	u_int	ifa_refcnt;		/* references to this structure */
35819ff91c6SGarrett Wollman 	int	ifa_metric;		/* cost of going out this interface */
35919ff91c6SGarrett Wollman #ifdef notdef
36019ff91c6SGarrett Wollman 	struct	rtentry *ifa_rt;	/* XXXX for ROUTETOIF ????? */
36119ff91c6SGarrett Wollman #endif
3627ed8f465SJulian Elischer 	int (*ifa_claim_addr)		/* check if an addr goes to this if */
363929ddbbbSAlfred Perlstein 		(struct ifaddr *, struct sockaddr *);
36419fc74fbSJeffrey Hsu 	struct mtx ifa_mtx;
36519ff91c6SGarrett Wollman };
36619ff91c6SGarrett Wollman #define	IFA_ROUTE	RTF_UP		/* route installed */
36719ff91c6SGarrett Wollman 
36882cd038dSYoshinobu Inoue /* for compatibility with other BSDs */
36982cd038dSYoshinobu Inoue #define	ifa_list	ifa_link
37082cd038dSYoshinobu Inoue 
37119fc74fbSJeffrey Hsu #define	IFA_LOCK_INIT(ifa)	\
37219fc74fbSJeffrey Hsu     mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF)
37319fc74fbSJeffrey Hsu #define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
37419fc74fbSJeffrey Hsu #define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
37519fc74fbSJeffrey Hsu #define	IFA_DESTROY(ifa)	mtx_destroy(&(ifa)->ifa_mtx)
37619fc74fbSJeffrey Hsu 
3771158dfb7SGarrett Wollman /*
37876429de4SYoshinobu Inoue  * The prefix structure contains information about one prefix
37976429de4SYoshinobu Inoue  * of an interface.  They are maintained by the different address families,
380d64ada50SJens Schweikhardt  * are allocated and attached when a prefix or an address is set,
38182cd038dSYoshinobu Inoue  * and are linked together so all prefixes for an interface can be located.
38276429de4SYoshinobu Inoue  */
38376429de4SYoshinobu Inoue struct ifprefix {
38476429de4SYoshinobu Inoue 	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
38576429de4SYoshinobu Inoue 	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
386e3975643SJake Burkholder 	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
38776429de4SYoshinobu Inoue 	u_char	ifpr_plen;		/* prefix length in bits */
38876429de4SYoshinobu Inoue 	u_char	ifpr_type;		/* protocol dependent prefix type */
38976429de4SYoshinobu Inoue };
39076429de4SYoshinobu Inoue 
39176429de4SYoshinobu Inoue /*
3921158dfb7SGarrett Wollman  * Multicast address structure.  This is analogous to the ifaddr
3931158dfb7SGarrett Wollman  * structure except that it keeps track of multicast addresses.
3941158dfb7SGarrett Wollman  * Also, the reference count here is a count of requests for this
3951158dfb7SGarrett Wollman  * address, not a count of pointers to this structure.
3961158dfb7SGarrett Wollman  */
3971158dfb7SGarrett Wollman struct ifmultiaddr {
3986817526dSPoul-Henning Kamp 	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
399373f88edSGarrett Wollman 	struct	sockaddr *ifma_addr; 	/* address this membership is for */
400373f88edSGarrett Wollman 	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
401373f88edSGarrett Wollman 	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
402373f88edSGarrett Wollman 	u_int	ifma_refcount;		/* reference count */
403373f88edSGarrett Wollman 	void	*ifma_protospec;	/* protocol-specific state, if any */
4041158dfb7SGarrett Wollman };
4051158dfb7SGarrett Wollman 
406664a31e4SPeter Wemm #ifdef _KERNEL
40719ff91c6SGarrett Wollman #define	IFAFREE(ifa)					\
408dfd5dee1SPeter Wemm 	do {						\
40919fc74fbSJeffrey Hsu 		IFA_LOCK(ifa);				\
41068eec1f8SJeffrey Hsu 		KASSERT((ifa)->ifa_refcnt > 0,		\
41168eec1f8SJeffrey Hsu 		    ("ifa %p !(ifa_refcnt > 0)", ifa));	\
41268eec1f8SJeffrey Hsu 		if (--(ifa)->ifa_refcnt == 0) {		\
41319fc74fbSJeffrey Hsu 			IFA_DESTROY(ifa);		\
41419fc74fbSJeffrey Hsu 			free(ifa, M_IFADDR);		\
41568eec1f8SJeffrey Hsu 		} else 					\
41619fc74fbSJeffrey Hsu 			IFA_UNLOCK(ifa);		\
41719fc74fbSJeffrey Hsu 	} while (0)
41819fc74fbSJeffrey Hsu 
41919fc74fbSJeffrey Hsu #define IFAREF(ifa)					\
42019fc74fbSJeffrey Hsu 	do {						\
42119fc74fbSJeffrey Hsu 		IFA_LOCK(ifa);				\
42219fc74fbSJeffrey Hsu 		++(ifa)->ifa_refcnt;			\
42319fc74fbSJeffrey Hsu 		IFA_UNLOCK(ifa);			\
424dfd5dee1SPeter Wemm 	} while (0)
42519ff91c6SGarrett Wollman 
426b30a244cSJeffrey Hsu extern	struct mtx ifnet_lock;
427c919b1e2SJeffrey Hsu #define	IFNET_LOCK_INIT() \
428c919b1e2SJeffrey Hsu     mtx_init(&ifnet_lock, "ifnet", NULL, MTX_DEF | MTX_RECURSE)
429b30a244cSJeffrey Hsu #define	IFNET_WLOCK()		mtx_lock(&ifnet_lock)
430b30a244cSJeffrey Hsu #define	IFNET_WUNLOCK()		mtx_unlock(&ifnet_lock)
431b30a244cSJeffrey Hsu #define	IFNET_RLOCK()		IFNET_WLOCK()
432b30a244cSJeffrey Hsu #define	IFNET_RUNLOCK()		IFNET_WUNLOCK()
433b30a244cSJeffrey Hsu 
434f9132cebSJonathan Lemon struct ifindex_entry {
435f9132cebSJonathan Lemon 	struct	ifnet *ife_ifnet;
436f9132cebSJonathan Lemon 	struct	ifaddr *ife_ifnet_addr;
437f9132cebSJonathan Lemon 	dev_t	ife_dev;
438f9132cebSJonathan Lemon };
439f9132cebSJonathan Lemon 
440f9132cebSJonathan Lemon #define ifnet_byindex(idx)	ifindex_table[(idx)].ife_ifnet
441f9132cebSJonathan Lemon #define ifaddr_byindex(idx)	ifindex_table[(idx)].ife_ifnet_addr
442f9132cebSJonathan Lemon #define ifdev_byindex(idx)	ifindex_table[(idx)].ife_dev
443f9132cebSJonathan Lemon 
44419ff91c6SGarrett Wollman extern	struct ifnethead ifnet;
445f9132cebSJonathan Lemon extern	struct ifindex_entry *ifindex_table;
44619ff91c6SGarrett Wollman extern	int ifqmaxlen;
44790d9802fSPeter Wemm extern	struct ifnet *loif;	/* first loopback interface */
44819ff91c6SGarrett Wollman extern	int if_index;
44919ff91c6SGarrett Wollman 
450929ddbbbSAlfred Perlstein int	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
451929ddbbbSAlfred Perlstein int	if_allmulti(struct ifnet *, int);
452929ddbbbSAlfred Perlstein void	if_attach(struct ifnet *);
453929ddbbbSAlfred Perlstein int	if_delmulti(struct ifnet *, struct sockaddr *);
454929ddbbbSAlfred Perlstein void	if_detach(struct ifnet *);
455929ddbbbSAlfred Perlstein void	if_down(struct ifnet *);
4569bf40edeSBrooks Davis void	if_initname(struct ifnet *, const char *, int);
457fa882e87SBrooks Davis int	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
458929ddbbbSAlfred Perlstein void	if_route(struct ifnet *, int flag, int fam);
459929ddbbbSAlfred Perlstein int	if_setlladdr(struct ifnet *, const u_char *, int);
460929ddbbbSAlfred Perlstein void	if_unroute(struct ifnet *, int flag, int fam);
461929ddbbbSAlfred Perlstein void	if_up(struct ifnet *);
462929ddbbbSAlfred Perlstein /*void	ifinit(void);*/ /* declared in systm.h for main() */
463929ddbbbSAlfred Perlstein int	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
464929ddbbbSAlfred Perlstein int	ifpromisc(struct ifnet *, int);
465929ddbbbSAlfred Perlstein struct	ifnet *ifunit(const char *);
466929ddbbbSAlfred Perlstein struct	ifnet *if_withname(struct sockaddr *);
46719ff91c6SGarrett Wollman 
468929ddbbbSAlfred Perlstein int	if_poll_recv_slow(struct ifnet *ifp, int *quotap);
469929ddbbbSAlfred Perlstein void	if_poll_xmit_slow(struct ifnet *ifp, int *quotap);
470929ddbbbSAlfred Perlstein void	if_poll_throttle(void);
471929ddbbbSAlfred Perlstein void	if_poll_unthrottle(void *);
472929ddbbbSAlfred Perlstein void	if_poll_init(void);
473929ddbbbSAlfred Perlstein void	if_poll(void);
47419ff91c6SGarrett Wollman 
475929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
476929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
477929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithnet(struct sockaddr *);
478929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
479929ddbbbSAlfred Perlstein struct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
48019ff91c6SGarrett Wollman 
481929ddbbbSAlfred Perlstein struct	ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *);
482929ddbbbSAlfred Perlstein int	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
483373f88edSGarrett Wollman 
484929ddbbbSAlfred Perlstein void	if_clone_attach(struct if_clone *);
485929ddbbbSAlfred Perlstein void	if_clone_detach(struct if_clone *);
48630aad87dSBrooks Davis 
487929ddbbbSAlfred Perlstein int	if_clone_create(char *, int);
488929ddbbbSAlfred Perlstein int	if_clone_destroy(const char *);
48930aad87dSBrooks Davis 
490322dcb8dSMax Khon #define IF_LLADDR(ifp)							\
491322dcb8dSMax Khon     LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr)
492322dcb8dSMax Khon 
493e4fc250cSLuigi Rizzo #ifdef DEVICE_POLLING
494e4fc250cSLuigi Rizzo enum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS, POLL_DEREGISTER };
495e4fc250cSLuigi Rizzo 
496929ddbbbSAlfred Perlstein typedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
497929ddbbbSAlfred Perlstein int    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
498929ddbbbSAlfred Perlstein int    ether_poll_deregister(struct ifnet *ifp);
499e4fc250cSLuigi Rizzo #endif /* DEVICE_POLLING */
500e4fc250cSLuigi Rizzo 
501664a31e4SPeter Wemm #endif /* _KERNEL */
50219ff91c6SGarrett Wollman 
50319ff91c6SGarrett Wollman #endif /* !_NET_IF_VAR_H_ */
504