xref: /freebsd/sys/net/if_var.h (revision de6073aa)
1c398230bSWarner Losh /*-
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  * 4. Neither the name of the University nor the names of its contributors
1419ff91c6SGarrett Wollman  *    may be used to endorse or promote products derived from this software
1519ff91c6SGarrett Wollman  *    without specific prior written permission.
1619ff91c6SGarrett Wollman  *
1719ff91c6SGarrett Wollman  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1819ff91c6SGarrett Wollman  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1919ff91c6SGarrett Wollman  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2019ff91c6SGarrett Wollman  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2119ff91c6SGarrett Wollman  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2219ff91c6SGarrett Wollman  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2319ff91c6SGarrett Wollman  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2419ff91c6SGarrett Wollman  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2519ff91c6SGarrett Wollman  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2619ff91c6SGarrett Wollman  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2719ff91c6SGarrett Wollman  * SUCH DAMAGE.
2819ff91c6SGarrett Wollman  *
2919ff91c6SGarrett Wollman  *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
30c3aac50fSPeter Wemm  * $FreeBSD$
3119ff91c6SGarrett Wollman  */
3219ff91c6SGarrett Wollman 
3319ff91c6SGarrett Wollman #ifndef	_NET_IF_VAR_H_
3419ff91c6SGarrett Wollman #define	_NET_IF_VAR_H_
3519ff91c6SGarrett Wollman 
3619ff91c6SGarrett Wollman /*
3719ff91c6SGarrett Wollman  * Structures defining a network interface, providing a packet
3819ff91c6SGarrett Wollman  * transport mechanism (ala level 0 of the PUP protocols).
3919ff91c6SGarrett Wollman  *
4019ff91c6SGarrett Wollman  * Each interface accepts output datagrams of a specified maximum
4119ff91c6SGarrett Wollman  * length, and provides higher level routines with input datagrams
4219ff91c6SGarrett Wollman  * received from its medium.
4319ff91c6SGarrett Wollman  *
4419ff91c6SGarrett Wollman  * Output occurs when the routine if_output is called, with three parameters:
4519ff91c6SGarrett Wollman  *	(*ifp->if_output)(ifp, m, dst, rt)
4619ff91c6SGarrett Wollman  * Here m is the mbuf chain to be sent and dst is the destination address.
4719ff91c6SGarrett Wollman  * The output routine encapsulates the supplied datagram if necessary,
4819ff91c6SGarrett Wollman  * and then transmits it on its medium.
4919ff91c6SGarrett Wollman  *
5019ff91c6SGarrett Wollman  * On input, each interface unwraps the data received by it, and either
519d5abbddSJens Schweikhardt  * places it on the input queue of an internetwork datagram routine
5219ff91c6SGarrett Wollman  * and posts the associated software interrupt, or passes the datagram to a raw
5319ff91c6SGarrett Wollman  * packet input routine.
5419ff91c6SGarrett Wollman  *
5519ff91c6SGarrett Wollman  * Routines exist for locating interfaces by their addresses
569d5abbddSJens Schweikhardt  * or for locating an interface on a certain network, as well as more general
5719ff91c6SGarrett Wollman  * routing and gateway routines maintaining information used to locate
5819ff91c6SGarrett Wollman  * interfaces.  These routines live in the files if.c and route.c
5919ff91c6SGarrett Wollman  */
6019ff91c6SGarrett Wollman 
6119ff91c6SGarrett Wollman #ifdef __STDC__
6219ff91c6SGarrett Wollman /*
6319ff91c6SGarrett Wollman  * Forward structure declarations for function prototypes [sic].
6419ff91c6SGarrett Wollman  */
6519ff91c6SGarrett Wollman struct	mbuf;
66b40ce416SJulian Elischer struct	thread;
6719ff91c6SGarrett Wollman struct	rtentry;
688071913dSRuslan Ermilov struct	rt_addrinfo;
6919ff91c6SGarrett Wollman struct	socket;
7019ff91c6SGarrett Wollman struct	ether_header;
71a9771948SGleb Smirnoff struct	carp_if;
7219ff91c6SGarrett Wollman #endif
7319ff91c6SGarrett Wollman 
7419ff91c6SGarrett Wollman #include <sys/queue.h>		/* get TAILQ macros */
7519ff91c6SGarrett Wollman 
769ba20c31SJonathan Lemon #ifdef _KERNEL
77df5e1987SJonathan Lemon #include <sys/mbuf.h>
7825a4adceSMax Laier #include <sys/eventhandler.h>
799ba20c31SJonathan Lemon #endif /* _KERNEL */
80f34fa851SJohn Baldwin #include <sys/lock.h>		/* XXX */
81f34fa851SJohn Baldwin #include <sys/mutex.h>		/* XXX */
82f9132cebSJonathan Lemon #include <sys/event.h>		/* XXX */
83af5e59bfSRobert Watson #include <sys/_task.h>
84df5e1987SJonathan Lemon 
859bf40edeSBrooks Davis #define	IF_DUNIT_NONE	-1
869bf40edeSBrooks Davis 
8702b199f1SMax Laier #include <altq/if_altq.h>
8802b199f1SMax Laier 
89e3975643SJake Burkholder TAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
90e3975643SJake Burkholder TAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
91e3975643SJake Burkholder TAILQ_HEAD(ifprefixhead, ifprefix);
926817526dSPoul-Henning Kamp TAILQ_HEAD(ifmultihead, ifmultiaddr);
9319ff91c6SGarrett Wollman 
9419ff91c6SGarrett Wollman /*
9519ff91c6SGarrett Wollman  * Structure defining a queue for a network interface.
9619ff91c6SGarrett Wollman  */
9719ff91c6SGarrett Wollman struct	ifqueue {
9819ff91c6SGarrett Wollman 	struct	mbuf *ifq_head;
9919ff91c6SGarrett Wollman 	struct	mbuf *ifq_tail;
10019ff91c6SGarrett Wollman 	int	ifq_len;
10119ff91c6SGarrett Wollman 	int	ifq_maxlen;
10219ff91c6SGarrett Wollman 	int	ifq_drops;
103df5e1987SJonathan Lemon 	struct	mtx ifq_mtx;
10419ff91c6SGarrett Wollman };
10519ff91c6SGarrett Wollman 
10619ff91c6SGarrett Wollman /*
10719ff91c6SGarrett Wollman  * Structure defining a network interface.
10819ff91c6SGarrett Wollman  *
10919ff91c6SGarrett Wollman  * (Would like to call this struct ``if'', but C isn't PL/1.)
11019ff91c6SGarrett Wollman  */
1118ec410b5SMatt Jacob 
11219ff91c6SGarrett Wollman struct ifnet {
11319ff91c6SGarrett Wollman 	void	*if_softc;		/* pointer to driver state */
114fc74a9f9SBrooks Davis 	void	*if_l2com;		/* pointer to protocol bits */
115e3975643SJake Burkholder 	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
1169bf40edeSBrooks Davis 	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
1179bf40edeSBrooks Davis 	const char *if_dname;		/* driver name */
1189bf40edeSBrooks Davis 	int	if_dunit;		/* unit or IF_DUNIT_NONE */
11919ff91c6SGarrett Wollman 	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
120621b79c4SLuigi Rizzo 		/*
121621b79c4SLuigi Rizzo 		 * if_addrhead is the list of all addresses associated to
122d65d2351SLuigi Rizzo 		 * an interface.
123d65d2351SLuigi Rizzo 		 * Some code in the kernel assumes that first element
124d65d2351SLuigi Rizzo 		 * of the list has type AF_LINK, and contains sockaddr_dl
125d65d2351SLuigi Rizzo 		 * addresses which store the link-level address and the name
126621b79c4SLuigi Rizzo 		 * of the interface.
127d65d2351SLuigi Rizzo 		 * However, access to the AF_LINK address through this
128d65d2351SLuigi Rizzo 		 * field is deprecated. Use ifaddr_byindex() instead.
129621b79c4SLuigi Rizzo 		 */
130ad3b9257SJohn-Mark Gurney 	struct	knlist if_klist;	/* events attached to this if */
13119ff91c6SGarrett Wollman 	int	if_pcount;		/* number of promiscuous listeners */
1323a84d72aSGleb Smirnoff 	struct	carp_if *if_carp;	/* carp interface structure */
13319ff91c6SGarrett Wollman 	struct	bpf_if *if_bpf;		/* packet filter structure */
13419ff91c6SGarrett Wollman 	u_short	if_index;		/* numeric abbreviation for this if  */
13519ff91c6SGarrett Wollman 	short	if_timer;		/* time 'til if_watchdog called */
13676cfd300SSam Leffler 	u_short	if_nvlans;		/* number of active vlans */
13762f76486SMaxim Sobolev 	int	if_flags;		/* up/down, broadcast, etc. */
138016da741SJonathan Lemon 	int	if_capabilities;	/* interface capabilities */
139016da741SJonathan Lemon 	int	if_capenable;		/* enabled features */
14019ff91c6SGarrett Wollman 	void	*if_linkmib;		/* link-type-specific MIB data */
14119ff91c6SGarrett Wollman 	size_t	if_linkmiblen;		/* length of above data */
14219ff91c6SGarrett Wollman 	struct	if_data if_data;
1431158dfb7SGarrett Wollman 	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
1441158dfb7SGarrett Wollman 	int	if_amcount;		/* number of all-multicast requests */
14519ff91c6SGarrett Wollman /* procedure handles */
14619ff91c6SGarrett Wollman 	int	(*if_output)		/* output routine (enqueue) */
147929ddbbbSAlfred Perlstein 		(struct ifnet *, struct mbuf *, struct sockaddr *,
148929ddbbbSAlfred Perlstein 		     struct rtentry *);
14976cfd300SSam Leffler 	void	(*if_input)		/* input routine (from h/w driver) */
15076cfd300SSam Leffler 		(struct ifnet *, struct mbuf *);
15119ff91c6SGarrett Wollman 	void	(*if_start)		/* initiate output routine */
152929ddbbbSAlfred Perlstein 		(struct ifnet *);
15319ff91c6SGarrett Wollman 	int	(*if_ioctl)		/* ioctl routine */
154929ddbbbSAlfred Perlstein 		(struct ifnet *, u_long, caddr_t);
15519ff91c6SGarrett Wollman 	void	(*if_watchdog)		/* timer routine */
156929ddbbbSAlfred Perlstein 		(struct ifnet *);
15719ff91c6SGarrett Wollman 	void	(*if_init)		/* Init routine */
158929ddbbbSAlfred Perlstein 		(void *);
1591158dfb7SGarrett Wollman 	int	(*if_resolvemulti)	/* validate/resolve multicast */
160929ddbbbSAlfred Perlstein 		(struct ifnet *, struct sockaddr **, struct sockaddr *);
161b4d4574aSRobert Watson 	void	*if_spare1;		/* spare pointer 1 */
162b4d4574aSRobert Watson 	void	*if_spare2;		/* spare pointer 2 */
163b4d4574aSRobert Watson 	void	*if_spare3;		/* spare pointer 3 */
164638ccea0SRobert Watson 	int	if_drv_flags;		/* driver-managed status flags */
165b4d4574aSRobert Watson 	u_int	if_spare_flags2;	/* spare flags 2 */
16602b199f1SMax Laier 	struct  ifaltq if_snd;		/* output queue (includes altq) */
1672ab763ecSWarner Losh 	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
168f7c5baa1SLuigi Rizzo 
1698f867517SAndrew Thompson 	void	*if_bridge;		/* bridge glue */
1708f867517SAndrew Thompson 
171f7c5baa1SLuigi Rizzo 	struct	lltable *lltables;	/* list of L3-L2 resolution tables */
172f7c5baa1SLuigi Rizzo 
173eca8a663SRobert Watson 	struct	label *if_label;	/* interface MAC label */
17431b1bfe1SHajimu UMEMOTO 
175f7c5baa1SLuigi Rizzo 	/* these are only used by IPv6 */
176f7c5baa1SLuigi Rizzo 	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
17731b1bfe1SHajimu UMEMOTO 	void	*if_afdata[AF_MAX];
178234a35c7SHajimu UMEMOTO 	int	if_afdata_initialized;
179234a35c7SHajimu UMEMOTO 	struct	mtx if_afdata_mtx;
180af5e59bfSRobert Watson 	struct	task if_starttask;	/* task for IFF_NEEDSGIANT */
18168a3482fSGleb Smirnoff 	struct	task if_linktask;	/* task for link change events */
182de6073aaSRobert Watson 	struct	mtx if_addr_mtx;	/* mutex to protect address lists */
18319ff91c6SGarrett Wollman };
184df5e1987SJonathan Lemon 
185929ddbbbSAlfred Perlstein typedef void if_init_f_t(void *);
18619ff91c6SGarrett Wollman 
187212b6d52SLuigi Rizzo /*
188212b6d52SLuigi Rizzo  * XXX These aliases are terribly dangerous because they could apply
189212b6d52SLuigi Rizzo  * to anything.
190212b6d52SLuigi Rizzo  */
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
197127d7b2dSAndre Oppermann #define	if_link_state	if_data.ifi_link_state
19819ff91c6SGarrett Wollman #define	if_baudrate	if_data.ifi_baudrate
199db4f9cc7SJonathan Lemon #define	if_hwassist	if_data.ifi_hwassist
20019ff91c6SGarrett Wollman #define	if_ipackets	if_data.ifi_ipackets
20119ff91c6SGarrett Wollman #define	if_ierrors	if_data.ifi_ierrors
20219ff91c6SGarrett Wollman #define	if_opackets	if_data.ifi_opackets
20319ff91c6SGarrett Wollman #define	if_oerrors	if_data.ifi_oerrors
20419ff91c6SGarrett Wollman #define	if_collisions	if_data.ifi_collisions
20519ff91c6SGarrett Wollman #define	if_ibytes	if_data.ifi_ibytes
20619ff91c6SGarrett Wollman #define	if_obytes	if_data.ifi_obytes
20719ff91c6SGarrett Wollman #define	if_imcasts	if_data.ifi_imcasts
20819ff91c6SGarrett Wollman #define	if_omcasts	if_data.ifi_omcasts
20919ff91c6SGarrett Wollman #define	if_iqdrops	if_data.ifi_iqdrops
21019ff91c6SGarrett Wollman #define	if_noproto	if_data.ifi_noproto
21119ff91c6SGarrett Wollman #define	if_lastchange	if_data.ifi_lastchange
21219ff91c6SGarrett Wollman #define if_recvquota	if_data.ifi_recvquota
21319ff91c6SGarrett Wollman #define	if_xmitquota	if_data.ifi_xmitquota
2142f27e151SJohn-Mark Gurney #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL)
21519ff91c6SGarrett Wollman 
21682cd038dSYoshinobu Inoue /* for compatibility with other BSDs */
21782cd038dSYoshinobu Inoue #define	if_addrlist	if_addrhead
21882cd038dSYoshinobu Inoue #define	if_list		if_link
21982cd038dSYoshinobu Inoue 
22019ff91c6SGarrett Wollman /*
221de6073aaSRobert Watson  * Locks for address lists on the network interface.
222de6073aaSRobert Watson  */
223de6073aaSRobert Watson #define	IF_ADDR_LOCK_INIT(if)	mtx_init(&(if)->if_addr_mtx,		\
224de6073aaSRobert Watson 				    "if_addr_mtx", NULL, MTX_DEF)
225de6073aaSRobert Watson #define	IF_ADDR_LOCK_DESTROY(if)	mtx_destroy(&(if)->if_addr_mtx)
226de6073aaSRobert Watson #define	IF_ADDR_LOCK(if)	mtx_lock(&(if)->if_addr_mtx)
227de6073aaSRobert Watson #define	IF_ADDR_UNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
228de6073aaSRobert Watson #define	IF_ADDR_LOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
229de6073aaSRobert Watson 
230de6073aaSRobert Watson /*
23119ff91c6SGarrett Wollman  * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
23219ff91c6SGarrett Wollman  * are queues of messages stored on ifqueue structures
23319ff91c6SGarrett Wollman  * (defined above).  Entries are added to and deleted from these structures
23419ff91c6SGarrett Wollman  * by these macros, which should be called with ipl raised to splimp().
23519ff91c6SGarrett Wollman  */
2369ed346baSBosko Milekic #define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
2379ed346baSBosko Milekic #define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
23802b199f1SMax Laier #define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
239df5e1987SJonathan Lemon #define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
240df5e1987SJonathan Lemon #define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
241df5e1987SJonathan Lemon #define	_IF_QLEN(ifq)		((ifq)->ifq_len)
242df5e1987SJonathan Lemon 
243df5e1987SJonathan Lemon #define	_IF_ENQUEUE(ifq, m) do { 				\
244df5e1987SJonathan Lemon 	(m)->m_nextpkt = NULL;					\
245df5e1987SJonathan Lemon 	if ((ifq)->ifq_tail == NULL) 				\
24619ff91c6SGarrett Wollman 		(ifq)->ifq_head = m; 				\
24719ff91c6SGarrett Wollman 	else 							\
24819ff91c6SGarrett Wollman 		(ifq)->ifq_tail->m_nextpkt = m; 		\
24919ff91c6SGarrett Wollman 	(ifq)->ifq_tail = m; 					\
25019ff91c6SGarrett Wollman 	(ifq)->ifq_len++; 					\
251df5e1987SJonathan Lemon } while (0)
252df5e1987SJonathan Lemon 
253df5e1987SJonathan Lemon #define IF_ENQUEUE(ifq, m) do {					\
254df5e1987SJonathan Lemon 	IF_LOCK(ifq); 						\
255df5e1987SJonathan Lemon 	_IF_ENQUEUE(ifq, m); 					\
256df5e1987SJonathan Lemon 	IF_UNLOCK(ifq); 					\
257df5e1987SJonathan Lemon } while (0)
258df5e1987SJonathan Lemon 
259df5e1987SJonathan Lemon #define	_IF_PREPEND(ifq, m) do {				\
26019ff91c6SGarrett Wollman 	(m)->m_nextpkt = (ifq)->ifq_head; 			\
261df5e1987SJonathan Lemon 	if ((ifq)->ifq_tail == NULL) 				\
26219ff91c6SGarrett Wollman 		(ifq)->ifq_tail = (m); 				\
26319ff91c6SGarrett Wollman 	(ifq)->ifq_head = (m); 					\
26419ff91c6SGarrett Wollman 	(ifq)->ifq_len++; 					\
265df5e1987SJonathan Lemon } while (0)
266df5e1987SJonathan Lemon 
267df5e1987SJonathan Lemon #define IF_PREPEND(ifq, m) do {		 			\
268df5e1987SJonathan Lemon 	IF_LOCK(ifq); 						\
269df5e1987SJonathan Lemon 	_IF_PREPEND(ifq, m); 					\
270df5e1987SJonathan Lemon 	IF_UNLOCK(ifq); 					\
271df5e1987SJonathan Lemon } while (0)
272df5e1987SJonathan Lemon 
273df5e1987SJonathan Lemon #define	_IF_DEQUEUE(ifq, m) do { 				\
27419ff91c6SGarrett Wollman 	(m) = (ifq)->ifq_head; 					\
27519ff91c6SGarrett Wollman 	if (m) { 						\
2762f27e151SJohn-Mark Gurney 		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
277df5e1987SJonathan Lemon 			(ifq)->ifq_tail = NULL; 		\
278df5e1987SJonathan Lemon 		(m)->m_nextpkt = NULL; 				\
27919ff91c6SGarrett Wollman 		(ifq)->ifq_len--; 				\
28019ff91c6SGarrett Wollman 	} 							\
281df5e1987SJonathan Lemon } while (0)
282df5e1987SJonathan Lemon 
283df5e1987SJonathan Lemon #define IF_DEQUEUE(ifq, m) do { 				\
284df5e1987SJonathan Lemon 	IF_LOCK(ifq); 						\
285df5e1987SJonathan Lemon 	_IF_DEQUEUE(ifq, m); 					\
286df5e1987SJonathan Lemon 	IF_UNLOCK(ifq); 					\
287df5e1987SJonathan Lemon } while (0)
288df5e1987SJonathan Lemon 
28902b199f1SMax Laier #define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
29002b199f1SMax Laier #define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
29102b199f1SMax Laier 
29202b199f1SMax Laier #define _IF_DRAIN(ifq) do { 					\
293df5e1987SJonathan Lemon 	struct mbuf *m; 					\
294df5e1987SJonathan Lemon 	for (;;) { 						\
295df5e1987SJonathan Lemon 		_IF_DEQUEUE(ifq, m); 				\
296df5e1987SJonathan Lemon 		if (m == NULL) 					\
297df5e1987SJonathan Lemon 			break; 					\
298df5e1987SJonathan Lemon 		m_freem(m); 					\
299df5e1987SJonathan Lemon 	} 							\
30002b199f1SMax Laier } while (0)
30102b199f1SMax Laier 
30202b199f1SMax Laier #define IF_DRAIN(ifq) do {					\
30302b199f1SMax Laier 	IF_LOCK(ifq);						\
30402b199f1SMax Laier 	_IF_DRAIN(ifq);						\
305df5e1987SJonathan Lemon 	IF_UNLOCK(ifq);						\
306df5e1987SJonathan Lemon } while(0)
30719ff91c6SGarrett Wollman 
308664a31e4SPeter Wemm #ifdef _KERNEL
30925a4adceSMax Laier /* interface address change event */
31025a4adceSMax Laier typedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
31125a4adceSMax Laier EVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
31225a4adceSMax Laier /* new interface arrival event */
31325a4adceSMax Laier typedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
31425a4adceSMax Laier EVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
31525a4adceSMax Laier /* interface departure event */
31625a4adceSMax Laier typedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
31725a4adceSMax Laier EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
31825a4adceSMax Laier 
319234a35c7SHajimu UMEMOTO #define	IF_AFDATA_LOCK_INIT(ifp)	\
320234a35c7SHajimu UMEMOTO     mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF)
321234a35c7SHajimu UMEMOTO #define	IF_AFDATA_LOCK(ifp)	mtx_lock(&(ifp)->if_afdata_mtx)
322234a35c7SHajimu UMEMOTO #define	IF_AFDATA_TRYLOCK(ifp)	mtx_trylock(&(ifp)->if_afdata_mtx)
323234a35c7SHajimu UMEMOTO #define	IF_AFDATA_UNLOCK(ifp)	mtx_unlock(&(ifp)->if_afdata_mtx)
324234a35c7SHajimu UMEMOTO #define	IF_AFDATA_DESTROY(ifp)	mtx_destroy(&(ifp)->if_afdata_mtx)
325234a35c7SHajimu UMEMOTO 
32631302ebfSRobert Watson #define	IFF_LOCKGIANT(ifp) do {						\
32731302ebfSRobert Watson 	if ((ifp)->if_flags & IFF_NEEDSGIANT)				\
32831302ebfSRobert Watson 		mtx_lock(&Giant);					\
32931302ebfSRobert Watson } while (0)
33031302ebfSRobert Watson 
33131302ebfSRobert Watson #define	IFF_UNLOCKGIANT(ifp) do {					\
33231302ebfSRobert Watson 	if ((ifp)->if_flags & IFF_NEEDSGIANT)				\
33331302ebfSRobert Watson 		mtx_unlock(&Giant);					\
33431302ebfSRobert Watson } while (0)
33531302ebfSRobert Watson 
3360b762445SRobert Watson int	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
3370b762445SRobert Watson 	    int adjust);
33802b199f1SMax Laier #define	IF_HANDOFF(ifq, m, ifp)			\
33902b199f1SMax Laier 	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
34002b199f1SMax Laier #define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
34102b199f1SMax Laier 	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
34219ff91c6SGarrett Wollman 
343af5e59bfSRobert Watson void	if_start(struct ifnet *);
344af5e59bfSRobert Watson 
34502b199f1SMax Laier #define	IFQ_ENQUEUE(ifq, m, err)					\
34602b199f1SMax Laier do {									\
34702b199f1SMax Laier 	IF_LOCK(ifq);							\
34802b199f1SMax Laier 	if (ALTQ_IS_ENABLED(ifq))					\
34902b199f1SMax Laier 		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
35002b199f1SMax Laier 	else {								\
35102b199f1SMax Laier 		if (_IF_QFULL(ifq)) {					\
35202b199f1SMax Laier 			m_freem(m);					\
35302b199f1SMax Laier 			(err) = ENOBUFS;				\
35402b199f1SMax Laier 		} else {						\
35502b199f1SMax Laier 			_IF_ENQUEUE(ifq, m);				\
35602b199f1SMax Laier 			(err) = 0;					\
35702b199f1SMax Laier 		}							\
35802b199f1SMax Laier 	}								\
35902b199f1SMax Laier 	if (err)							\
36002b199f1SMax Laier 		(ifq)->ifq_drops++;					\
36102b199f1SMax Laier 	IF_UNLOCK(ifq);							\
36202b199f1SMax Laier } while (0)
36302b199f1SMax Laier 
36402b199f1SMax Laier #define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
36502b199f1SMax Laier do {									\
36602b199f1SMax Laier 	if (TBR_IS_ENABLED(ifq))					\
3674cb655c0SMax Laier 		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
36802b199f1SMax Laier 	else if (ALTQ_IS_ENABLED(ifq))					\
36902b199f1SMax Laier 		ALTQ_DEQUEUE(ifq, m);					\
37002b199f1SMax Laier 	else								\
37102b199f1SMax Laier 		_IF_DEQUEUE(ifq, m);					\
37202b199f1SMax Laier } while (0)
37302b199f1SMax Laier 
37402b199f1SMax Laier #define	IFQ_DEQUEUE(ifq, m)						\
37502b199f1SMax Laier do {									\
37602b199f1SMax Laier 	IF_LOCK(ifq);							\
37702b199f1SMax Laier 	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
37802b199f1SMax Laier 	IF_UNLOCK(ifq);							\
37902b199f1SMax Laier } while (0)
38002b199f1SMax Laier 
38102b199f1SMax Laier #define	IFQ_POLL_NOLOCK(ifq, m)						\
38202b199f1SMax Laier do {									\
38302b199f1SMax Laier 	if (TBR_IS_ENABLED(ifq))					\
3844cb655c0SMax Laier 		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
38502b199f1SMax Laier 	else if (ALTQ_IS_ENABLED(ifq))					\
38602b199f1SMax Laier 		ALTQ_POLL(ifq, m);					\
38702b199f1SMax Laier 	else								\
38802b199f1SMax Laier 		_IF_POLL(ifq, m);					\
38902b199f1SMax Laier } while (0)
39002b199f1SMax Laier 
39102b199f1SMax Laier #define	IFQ_POLL(ifq, m)						\
39202b199f1SMax Laier do {									\
39302b199f1SMax Laier 	IF_LOCK(ifq);							\
39402b199f1SMax Laier 	IFQ_POLL_NOLOCK(ifq, m);					\
39502b199f1SMax Laier 	IF_UNLOCK(ifq);							\
39602b199f1SMax Laier } while (0)
39702b199f1SMax Laier 
39802b199f1SMax Laier #define	IFQ_PURGE_NOLOCK(ifq)						\
39902b199f1SMax Laier do {									\
40002b199f1SMax Laier 	if (ALTQ_IS_ENABLED(ifq)) {					\
40102b199f1SMax Laier 		ALTQ_PURGE(ifq);					\
40202b199f1SMax Laier 	} else								\
40302b199f1SMax Laier 		_IF_DRAIN(ifq);						\
40402b199f1SMax Laier } while (0)
40502b199f1SMax Laier 
40602b199f1SMax Laier #define	IFQ_PURGE(ifq)							\
40702b199f1SMax Laier do {									\
40802b199f1SMax Laier 	IF_LOCK(ifq);							\
40902b199f1SMax Laier 	IFQ_PURGE_NOLOCK(ifq);						\
41002b199f1SMax Laier 	IF_UNLOCK(ifq);							\
41102b199f1SMax Laier } while (0)
41202b199f1SMax Laier 
41302b199f1SMax Laier #define	IFQ_SET_READY(ifq)						\
41402b199f1SMax Laier 	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
41502b199f1SMax Laier 
41602b199f1SMax Laier #define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
41702b199f1SMax Laier #define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
41802b199f1SMax Laier #define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
41902b199f1SMax Laier #define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
42002b199f1SMax Laier #define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
42102b199f1SMax Laier #define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
42202b199f1SMax Laier #define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
42302b199f1SMax Laier #define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
42402b199f1SMax Laier 
42502b199f1SMax Laier #define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
42602b199f1SMax Laier do {									\
42702b199f1SMax Laier 	int len;							\
42802b199f1SMax Laier 	short mflags;							\
42902b199f1SMax Laier 									\
43002b199f1SMax Laier 	len = (m)->m_pkthdr.len;					\
43102b199f1SMax Laier 	mflags = (m)->m_flags;						\
43202b199f1SMax Laier 	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
43302b199f1SMax Laier 	if ((err) == 0) {						\
43402b199f1SMax Laier 		(ifp)->if_obytes += len + (adj);			\
43502b199f1SMax Laier 		if (mflags & M_MCAST)					\
43602b199f1SMax Laier 			(ifp)->if_omcasts++;				\
43702b199f1SMax Laier 		if (((ifp)->if_flags & IFF_OACTIVE) == 0)		\
438af5e59bfSRobert Watson 			if_start(ifp);					\
43902b199f1SMax Laier 	}								\
44002b199f1SMax Laier } while (0)
44102b199f1SMax Laier 
44202b199f1SMax Laier #define	IFQ_HANDOFF(ifp, m, err)					\
44362d7f46eSMax Laier 	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
44402b199f1SMax Laier 
44502b199f1SMax Laier #define	IFQ_DRV_DEQUEUE(ifq, m)						\
44602b199f1SMax Laier do {									\
44702b199f1SMax Laier 	(m) = (ifq)->ifq_drv_head;					\
44802b199f1SMax Laier 	if (m) {							\
44902b199f1SMax Laier 		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
45002b199f1SMax Laier 			(ifq)->ifq_drv_tail = NULL;			\
45102b199f1SMax Laier 		(m)->m_nextpkt = NULL;					\
45202b199f1SMax Laier 		(ifq)->ifq_drv_len--;					\
45302b199f1SMax Laier 	} else {							\
45402b199f1SMax Laier 		IFQ_LOCK(ifq);						\
45502b199f1SMax Laier 		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
45602b199f1SMax Laier 		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
45702b199f1SMax Laier 			struct mbuf *m0;				\
45802b199f1SMax Laier 			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
45902b199f1SMax Laier 			if (m0 == NULL)					\
46002b199f1SMax Laier 				break;					\
46102b199f1SMax Laier 			m0->m_nextpkt = NULL;				\
46202b199f1SMax Laier 			if ((ifq)->ifq_drv_tail == NULL)		\
46302b199f1SMax Laier 				(ifq)->ifq_drv_head = m0;		\
46402b199f1SMax Laier 			else						\
46502b199f1SMax Laier 				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
46602b199f1SMax Laier 			(ifq)->ifq_drv_tail = m0;			\
46702b199f1SMax Laier 			(ifq)->ifq_drv_len++;				\
46802b199f1SMax Laier 		}							\
46902b199f1SMax Laier 		IFQ_UNLOCK(ifq);					\
47002b199f1SMax Laier 	}								\
47102b199f1SMax Laier } while (0)
47202b199f1SMax Laier 
47302b199f1SMax Laier #define	IFQ_DRV_PREPEND(ifq, m)						\
47402b199f1SMax Laier do {									\
47502b199f1SMax Laier 	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
476bfe46415SMax Laier 	if ((ifq)->ifq_drv_tail == NULL)				\
477bfe46415SMax Laier 		(ifq)->ifq_drv_tail = (m);				\
47802b199f1SMax Laier 	(ifq)->ifq_drv_head = (m);					\
47902b199f1SMax Laier 	(ifq)->ifq_drv_len++;						\
48002b199f1SMax Laier } while (0)
48102b199f1SMax Laier 
48202b199f1SMax Laier #define	IFQ_DRV_IS_EMPTY(ifq)						\
48302b199f1SMax Laier 	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
48402b199f1SMax Laier 
48502b199f1SMax Laier #define	IFQ_DRV_PURGE(ifq)						\
48602b199f1SMax Laier do {									\
487bfe46415SMax Laier 	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
488bfe46415SMax Laier 	while((m = n) != NULL) {					\
489bfe46415SMax Laier 		n = m->m_nextpkt;					\
49002b199f1SMax Laier 		m_freem(m);						\
49102b199f1SMax Laier 	}								\
49202b199f1SMax Laier 	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
49302b199f1SMax Laier 	(ifq)->ifq_drv_len = 0;						\
49402b199f1SMax Laier 	IFQ_PURGE(ifq);							\
49502b199f1SMax Laier } while (0)
496aab3beeeSBrian Somers 
497aab3beeeSBrian Somers /*
498aab3beeeSBrian Somers  * 72 was chosen below because it is the size of a TCP/IP
499aab3beeeSBrian Somers  * header (40) + the minimum mss (32).
500aab3beeeSBrian Somers  */
501aab3beeeSBrian Somers #define	IF_MINMTU	72
502aab3beeeSBrian Somers #define	IF_MAXMTU	65535
503aab3beeeSBrian Somers 
504664a31e4SPeter Wemm #endif /* _KERNEL */
50519ff91c6SGarrett Wollman 
50619ff91c6SGarrett Wollman /*
50719ff91c6SGarrett Wollman  * The ifaddr structure contains information about one address
50819ff91c6SGarrett Wollman  * of an interface.  They are maintained by the different address families,
50919ff91c6SGarrett Wollman  * are allocated and attached when an address is set, and are linked
51019ff91c6SGarrett Wollman  * together so all addresses for an interface can be located.
511621b79c4SLuigi Rizzo  *
512621b79c4SLuigi Rizzo  * NOTE: a 'struct ifaddr' is always at the beginning of a larger
513621b79c4SLuigi Rizzo  * chunk of malloc'ed memory, where we store the three addresses
514621b79c4SLuigi Rizzo  * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
51519ff91c6SGarrett Wollman  */
51619ff91c6SGarrett Wollman struct ifaddr {
51719ff91c6SGarrett Wollman 	struct	sockaddr *ifa_addr;	/* address of interface */
51819ff91c6SGarrett Wollman 	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
51919ff91c6SGarrett Wollman #define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
52019ff91c6SGarrett Wollman 	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
5215da9f8faSJosef Karthauser 	struct	if_data if_data;	/* not all members are meaningful */
52219ff91c6SGarrett Wollman 	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
523e3975643SJake Burkholder 	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
52419ff91c6SGarrett Wollman 	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
525929ddbbbSAlfred Perlstein 		(int, struct rtentry *, struct rt_addrinfo *);
52619ff91c6SGarrett Wollman 	u_short	ifa_flags;		/* mostly rt_flags for cloning */
527e3c1388bSPierre Beyssac 	u_int	ifa_refcnt;		/* references to this structure */
52819ff91c6SGarrett Wollman 	int	ifa_metric;		/* cost of going out this interface */
5297ed8f465SJulian Elischer 	int (*ifa_claim_addr)		/* check if an addr goes to this if */
530929ddbbbSAlfred Perlstein 		(struct ifaddr *, struct sockaddr *);
53119fc74fbSJeffrey Hsu 	struct mtx ifa_mtx;
53219ff91c6SGarrett Wollman };
53319ff91c6SGarrett Wollman #define	IFA_ROUTE	RTF_UP		/* route installed */
53419ff91c6SGarrett Wollman 
53582cd038dSYoshinobu Inoue /* for compatibility with other BSDs */
53682cd038dSYoshinobu Inoue #define	ifa_list	ifa_link
53782cd038dSYoshinobu Inoue 
53819fc74fbSJeffrey Hsu #define	IFA_LOCK_INIT(ifa)	\
53919fc74fbSJeffrey Hsu     mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF)
54019fc74fbSJeffrey Hsu #define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
54119fc74fbSJeffrey Hsu #define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
54219fc74fbSJeffrey Hsu #define	IFA_DESTROY(ifa)	mtx_destroy(&(ifa)->ifa_mtx)
54319fc74fbSJeffrey Hsu 
5441158dfb7SGarrett Wollman /*
54576429de4SYoshinobu Inoue  * The prefix structure contains information about one prefix
54676429de4SYoshinobu Inoue  * of an interface.  They are maintained by the different address families,
547d64ada50SJens Schweikhardt  * are allocated and attached when a prefix or an address is set,
54882cd038dSYoshinobu Inoue  * and are linked together so all prefixes for an interface can be located.
54976429de4SYoshinobu Inoue  */
55076429de4SYoshinobu Inoue struct ifprefix {
55176429de4SYoshinobu Inoue 	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
55276429de4SYoshinobu Inoue 	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
553e3975643SJake Burkholder 	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
55476429de4SYoshinobu Inoue 	u_char	ifpr_plen;		/* prefix length in bits */
55576429de4SYoshinobu Inoue 	u_char	ifpr_type;		/* protocol dependent prefix type */
55676429de4SYoshinobu Inoue };
55776429de4SYoshinobu Inoue 
55876429de4SYoshinobu Inoue /*
5591158dfb7SGarrett Wollman  * Multicast address structure.  This is analogous to the ifaddr
5601158dfb7SGarrett Wollman  * structure except that it keeps track of multicast addresses.
5611158dfb7SGarrett Wollman  * Also, the reference count here is a count of requests for this
5621158dfb7SGarrett Wollman  * address, not a count of pointers to this structure.
5631158dfb7SGarrett Wollman  */
5641158dfb7SGarrett Wollman struct ifmultiaddr {
5656817526dSPoul-Henning Kamp 	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
566373f88edSGarrett Wollman 	struct	sockaddr *ifma_addr; 	/* address this membership is for */
567373f88edSGarrett Wollman 	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
568373f88edSGarrett Wollman 	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
569373f88edSGarrett Wollman 	u_int	ifma_refcount;		/* reference count */
570373f88edSGarrett Wollman 	void	*ifma_protospec;	/* protocol-specific state, if any */
5711158dfb7SGarrett Wollman };
5721158dfb7SGarrett Wollman 
573664a31e4SPeter Wemm #ifdef _KERNEL
57419ff91c6SGarrett Wollman #define	IFAFREE(ifa)					\
575dfd5dee1SPeter Wemm 	do {						\
57619fc74fbSJeffrey Hsu 		IFA_LOCK(ifa);				\
57768eec1f8SJeffrey Hsu 		KASSERT((ifa)->ifa_refcnt > 0,		\
57868eec1f8SJeffrey Hsu 		    ("ifa %p !(ifa_refcnt > 0)", ifa));	\
57968eec1f8SJeffrey Hsu 		if (--(ifa)->ifa_refcnt == 0) {		\
58019fc74fbSJeffrey Hsu 			IFA_DESTROY(ifa);		\
58119fc74fbSJeffrey Hsu 			free(ifa, M_IFADDR);		\
58268eec1f8SJeffrey Hsu 		} else 					\
58319fc74fbSJeffrey Hsu 			IFA_UNLOCK(ifa);		\
58419fc74fbSJeffrey Hsu 	} while (0)
58519fc74fbSJeffrey Hsu 
58619fc74fbSJeffrey Hsu #define IFAREF(ifa)					\
58719fc74fbSJeffrey Hsu 	do {						\
58819fc74fbSJeffrey Hsu 		IFA_LOCK(ifa);				\
58919fc74fbSJeffrey Hsu 		++(ifa)->ifa_refcnt;			\
59019fc74fbSJeffrey Hsu 		IFA_UNLOCK(ifa);			\
591dfd5dee1SPeter Wemm 	} while (0)
59219ff91c6SGarrett Wollman 
593b30a244cSJeffrey Hsu extern	struct mtx ifnet_lock;
594c919b1e2SJeffrey Hsu #define	IFNET_LOCK_INIT() \
595c919b1e2SJeffrey Hsu     mtx_init(&ifnet_lock, "ifnet", NULL, MTX_DEF | MTX_RECURSE)
596b30a244cSJeffrey Hsu #define	IFNET_WLOCK()		mtx_lock(&ifnet_lock)
597b30a244cSJeffrey Hsu #define	IFNET_WUNLOCK()		mtx_unlock(&ifnet_lock)
598b30a244cSJeffrey Hsu #define	IFNET_RLOCK()		IFNET_WLOCK()
599b30a244cSJeffrey Hsu #define	IFNET_RUNLOCK()		IFNET_WUNLOCK()
600b30a244cSJeffrey Hsu 
601f9132cebSJonathan Lemon struct ifindex_entry {
602f9132cebSJonathan Lemon 	struct	ifnet *ife_ifnet;
603f9132cebSJonathan Lemon 	struct	ifaddr *ife_ifnet_addr;
60489c9c53dSPoul-Henning Kamp 	struct cdev *ife_dev;
605f9132cebSJonathan Lemon };
606f9132cebSJonathan Lemon 
607f9132cebSJonathan Lemon #define ifnet_byindex(idx)	ifindex_table[(idx)].ife_ifnet
608d65d2351SLuigi Rizzo /*
609d65d2351SLuigi Rizzo  * Given the index, ifaddr_byindex() returns the one and only
610d65d2351SLuigi Rizzo  * link-level ifaddr for the interface. You are not supposed to use
611d65d2351SLuigi Rizzo  * it to traverse the list of addresses associated to the interface.
612d65d2351SLuigi Rizzo  */
613f9132cebSJonathan Lemon #define ifaddr_byindex(idx)	ifindex_table[(idx)].ife_ifnet_addr
614f9132cebSJonathan Lemon #define ifdev_byindex(idx)	ifindex_table[(idx)].ife_dev
615f9132cebSJonathan Lemon 
61619ff91c6SGarrett Wollman extern	struct ifnethead ifnet;
617f9132cebSJonathan Lemon extern	struct ifindex_entry *ifindex_table;
61819ff91c6SGarrett Wollman extern	int ifqmaxlen;
61990d9802fSPeter Wemm extern	struct ifnet *loif;	/* first loopback interface */
62019ff91c6SGarrett Wollman extern	int if_index;
62119ff91c6SGarrett Wollman 
622929ddbbbSAlfred Perlstein int	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
623929ddbbbSAlfred Perlstein int	if_allmulti(struct ifnet *, int);
624fc74a9f9SBrooks Davis struct	ifnet* if_alloc(u_char);
625929ddbbbSAlfred Perlstein void	if_attach(struct ifnet *);
626929ddbbbSAlfred Perlstein int	if_delmulti(struct ifnet *, struct sockaddr *);
627929ddbbbSAlfred Perlstein void	if_detach(struct ifnet *);
62845778b37SPeter Edwards void	if_purgeaddrs(struct ifnet *);
629929ddbbbSAlfred Perlstein void	if_down(struct ifnet *);
630fc74a9f9SBrooks Davis void	if_free(struct ifnet *);
631fc74a9f9SBrooks Davis void	if_free_type(struct ifnet *, u_char);
6329bf40edeSBrooks Davis void	if_initname(struct ifnet *, const char *, int);
63394f5c9cfSSam Leffler void	if_link_state_change(struct ifnet *, int);
634fa882e87SBrooks Davis int	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
635929ddbbbSAlfred Perlstein int	if_setlladdr(struct ifnet *, const u_char *, int);
636929ddbbbSAlfred Perlstein void	if_up(struct ifnet *);
637929ddbbbSAlfred Perlstein /*void	ifinit(void);*/ /* declared in systm.h for main() */
638929ddbbbSAlfred Perlstein int	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
639929ddbbbSAlfred Perlstein int	ifpromisc(struct ifnet *, int);
640929ddbbbSAlfred Perlstein struct	ifnet *ifunit(const char *);
64119ff91c6SGarrett Wollman 
642929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
643929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
644929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithnet(struct sockaddr *);
645929ddbbbSAlfred Perlstein struct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
646929ddbbbSAlfred Perlstein struct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
64719ff91c6SGarrett Wollman 
648929ddbbbSAlfred Perlstein struct	ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *);
649929ddbbbSAlfred Perlstein int	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
650373f88edSGarrett Wollman 
651fc74a9f9SBrooks Davis typedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
652fc74a9f9SBrooks Davis typedef	void if_com_free_t(void *com, u_char type);
653fc74a9f9SBrooks Davis void	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
654fc74a9f9SBrooks Davis void	if_deregister_com_alloc(u_char type);
655fc74a9f9SBrooks Davis 
656322dcb8dSMax Khon #define IF_LLADDR(ifp)							\
657322dcb8dSMax Khon     LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr)
658322dcb8dSMax Khon 
659e4fc250cSLuigi Rizzo #ifdef DEVICE_POLLING
660e4fc250cSLuigi Rizzo enum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS, POLL_DEREGISTER };
661e4fc250cSLuigi Rizzo 
662929ddbbbSAlfred Perlstein typedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
663929ddbbbSAlfred Perlstein int    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
664929ddbbbSAlfred Perlstein int    ether_poll_deregister(struct ifnet *ifp);
665e4fc250cSLuigi Rizzo #endif /* DEVICE_POLLING */
666e4fc250cSLuigi Rizzo 
667664a31e4SPeter Wemm #endif /* _KERNEL */
66819ff91c6SGarrett Wollman 
66919ff91c6SGarrett Wollman #endif /* !_NET_IF_VAR_H_ */
670