if_var.h revision 231157
1139823Simp/*-
221259Swollman * Copyright (c) 1982, 1986, 1989, 1993
321259Swollman *	The Regents of the University of California.  All rights reserved.
421259Swollman *
521259Swollman * Redistribution and use in source and binary forms, with or without
621259Swollman * modification, are permitted provided that the following conditions
721259Swollman * are met:
821259Swollman * 1. Redistributions of source code must retain the above copyright
921259Swollman *    notice, this list of conditions and the following disclaimer.
1021259Swollman * 2. Redistributions in binary form must reproduce the above copyright
1121259Swollman *    notice, this list of conditions and the following disclaimer in the
1221259Swollman *    documentation and/or other materials provided with the distribution.
1321259Swollman * 4. Neither the name of the University nor the names of its contributors
1421259Swollman *    may be used to endorse or promote products derived from this software
1521259Swollman *    without specific prior written permission.
1621259Swollman *
1721259Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1821259Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1921259Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2021259Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2121259Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2221259Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2321259Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2421259Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2521259Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2621259Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2721259Swollman * SUCH DAMAGE.
2821259Swollman *
2921259Swollman *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3050477Speter * $FreeBSD: stable/9/sys/net/if_var.h 231157 2012-02-07 19:55:58Z jhb $
3121259Swollman */
3221259Swollman
3321259Swollman#ifndef	_NET_IF_VAR_H_
3421259Swollman#define	_NET_IF_VAR_H_
3521259Swollman
3621259Swollman/*
3721259Swollman * Structures defining a network interface, providing a packet
3821259Swollman * transport mechanism (ala level 0 of the PUP protocols).
3921259Swollman *
4021259Swollman * Each interface accepts output datagrams of a specified maximum
4121259Swollman * length, and provides higher level routines with input datagrams
4221259Swollman * received from its medium.
4321259Swollman *
4421259Swollman * Output occurs when the routine if_output is called, with three parameters:
4521259Swollman *	(*ifp->if_output)(ifp, m, dst, rt)
4621259Swollman * Here m is the mbuf chain to be sent and dst is the destination address.
4721259Swollman * The output routine encapsulates the supplied datagram if necessary,
4821259Swollman * and then transmits it on its medium.
4921259Swollman *
5021259Swollman * On input, each interface unwraps the data received by it, and either
51108533Sschweikh * places it on the input queue of an internetwork datagram routine
5221259Swollman * and posts the associated software interrupt, or passes the datagram to a raw
5321259Swollman * packet input routine.
5421259Swollman *
5521259Swollman * Routines exist for locating interfaces by their addresses
56108533Sschweikh * or for locating an interface on a certain network, as well as more general
5721259Swollman * routing and gateway routines maintaining information used to locate
5821259Swollman * interfaces.  These routines live in the files if.c and route.c
5921259Swollman */
6021259Swollman
6121259Swollman#ifdef __STDC__
6221259Swollman/*
6321259Swollman * Forward structure declarations for function prototypes [sic].
6421259Swollman */
6521259Swollmanstruct	mbuf;
6683366Sjulianstruct	thread;
6721259Swollmanstruct	rtentry;
6885074Srustruct	rt_addrinfo;
6921259Swollmanstruct	socket;
7021259Swollmanstruct	ether_header;
71142215Sglebiusstruct	carp_if;
72155051Sglebiusstruct  ifvlantrunk;
73191148Skmacystruct	route;
74193731Szecstruct	vnet;
7521259Swollman#endif
7621259Swollman
7721259Swollman#include <sys/queue.h>		/* get TAILQ macros */
7821259Swollman
7969224Sjlemon#ifdef _KERNEL
8069152Sjlemon#include <sys/mbuf.h>
81126264Smlaier#include <sys/eventhandler.h>
82186207Skmacy#include <sys/buf_ring.h>
83195699Srwatson#include <net/vnet.h>
8469224Sjlemon#endif /* _KERNEL */
8574914Sjhb#include <sys/lock.h>		/* XXX */
8674914Sjhb#include <sys/mutex.h>		/* XXX */
87186199Skmacy#include <sys/rwlock.h>		/* XXX */
88196481Srwatson#include <sys/sx.h>		/* XXX */
8983130Sjlemon#include <sys/event.h>		/* XXX */
90132712Srwatson#include <sys/_task.h>
9169152Sjlemon
92121816Sbrooks#define	IF_DUNIT_NONE	-1
93121816Sbrooks
94130416Smlaier#include <altq/if_altq.h>
95130416Smlaier
9660938SjakeTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
9760938SjakeTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
9860938SjakeTAILQ_HEAD(ifprefixhead, ifprefix);
9972084SphkTAILQ_HEAD(ifmultihead, ifmultiaddr);
100159781SmlaierTAILQ_HEAD(ifgrouphead, ifg_group);
10121259Swollman
10221259Swollman/*
10321259Swollman * Structure defining a queue for a network interface.
10421259Swollman */
10521259Swollmanstruct	ifqueue {
10621259Swollman	struct	mbuf *ifq_head;
10721259Swollman	struct	mbuf *ifq_tail;
10821259Swollman	int	ifq_len;
10921259Swollman	int	ifq_maxlen;
11021259Swollman	int	ifq_drops;
11169152Sjlemon	struct	mtx ifq_mtx;
11221259Swollman};
11321259Swollman
11421259Swollman/*
11521259Swollman * Structure defining a network interface.
11621259Swollman *
11721259Swollman * (Would like to call this struct ``if'', but C isn't PL/1.)
11821259Swollman */
11984380Smjacob
12021259Swollmanstruct ifnet {
12121259Swollman	void	*if_softc;		/* pointer to driver state */
122147256Sbrooks	void	*if_l2com;		/* pointer to protocol bits */
123191688Szec	struct vnet *if_vnet;		/* pointer to network stack instance */
12460938Sjake	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
125121816Sbrooks	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
126121816Sbrooks	const char *if_dname;		/* driver name */
127121816Sbrooks	int	if_dunit;		/* unit or IF_DUNIT_NONE */
128191367Srwatson	u_int	if_refcount;		/* reference count */
12921259Swollman	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
130128291Sluigi		/*
131128291Sluigi		 * if_addrhead is the list of all addresses associated to
132128315Sluigi		 * an interface.
133128315Sluigi		 * Some code in the kernel assumes that first element
134128315Sluigi		 * of the list has type AF_LINK, and contains sockaddr_dl
135128315Sluigi		 * addresses which store the link-level address and the name
136128291Sluigi		 * of the interface.
137128315Sluigi		 * However, access to the AF_LINK address through this
138152315Sru		 * field is deprecated. Use if_addr or ifaddr_byindex() instead.
139128291Sluigi		 */
14083130Sjlemon	int	if_pcount;		/* number of promiscuous listeners */
141142901Sglebius	struct	carp_if *if_carp;	/* carp interface structure */
14221259Swollman	struct	bpf_if *if_bpf;		/* packet filter structure */
14321259Swollman	u_short	if_index;		/* numeric abbreviation for this if  */
144199975Sjhb	short	if_index_reserved;	/* spare space to grow if_index */
145155051Sglebius	struct  ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */
146102052Ssobomax	int	if_flags;		/* up/down, broadcast, etc. */
147162070Sandre	int	if_capabilities;	/* interface features & capabilities */
148162070Sandre	int	if_capenable;		/* enabled features & capabilities */
14921259Swollman	void	*if_linkmib;		/* link-type-specific MIB data */
15021259Swollman	size_t	if_linkmiblen;		/* length of above data */
15121259Swollman	struct	if_data if_data;
15221404Swollman	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
15321404Swollman	int	if_amcount;		/* number of all-multicast requests */
15421259Swollman/* procedure handles */
15521259Swollman	int	(*if_output)		/* output routine (enqueue) */
15692725Salfred		(struct ifnet *, struct mbuf *, struct sockaddr *,
157191148Skmacy		     struct route *);
158106931Ssam	void	(*if_input)		/* input routine (from h/w driver) */
159106931Ssam		(struct ifnet *, struct mbuf *);
16021259Swollman	void	(*if_start)		/* initiate output routine */
16192725Salfred		(struct ifnet *);
16221259Swollman	int	(*if_ioctl)		/* ioctl routine */
16392725Salfred		(struct ifnet *, u_long, caddr_t);
16421259Swollman	void	(*if_init)		/* Init routine */
16592725Salfred		(void *);
16621404Swollman	int	(*if_resolvemulti)	/* validate/resolve multicast */
16792725Salfred		(struct ifnet *, struct sockaddr **, struct sockaddr *);
168189230Srwatson	void	(*if_qflush)		/* flush any queues */
169189230Srwatson		(struct ifnet *);
170189230Srwatson	int	(*if_transmit)		/* initiate output routine */
171189230Srwatson		(struct ifnet *, struct mbuf *);
172193731Szec	void	(*if_reassign)		/* reassign to vnet routine */
173193731Szec		(struct ifnet *, struct vnet *, char *);
174193731Szec	struct	vnet *if_home_vnet;	/* where this ifnet originates from */
175152315Sru	struct	ifaddr	*if_addr;	/* pointer to link-level address */
176174388Skmacy	void	*if_llsoftc;		/* link layer softc */
177148265Srwatson	int	if_drv_flags;		/* driver-managed status flags */
178130416Smlaier	struct  ifaltq if_snd;		/* output queue (includes altq) */
179123220Simp	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
180127828Sluigi
181146986Sthompsa	void	*if_bridge;		/* bridge glue */
182146986Sthompsa
183122524Srwatson	struct	label *if_label;	/* interface MAC label */
184121161Sume
185127828Sluigi	/* these are only used by IPv6 */
186127828Sluigi	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
187121161Sume	void	*if_afdata[AF_MAX];
188121470Sume	int	if_afdata_initialized;
189186199Skmacy	struct	rwlock if_afdata_lock;
190145320Sglebius	struct	task if_linktask;	/* task for link change events */
191148640Srwatson	struct	mtx if_addr_mtx;	/* mutex to protect address lists */
192186119Sqingli
193152209Sthompsa	LIST_ENTRY(ifnet) if_clones;	/* interfaces of a cloner */
194159781Smlaier	TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
195159781Smlaier					/* protected by if_addr_mtx */
196159781Smlaier	void	*if_pf_kif;
197168793Sthompsa	void	*if_lagg;		/* lagg glue */
198224151Sbz	char	*if_description;	/* interface description */
199224151Sbz	u_int	if_fib;			/* interface FIB */
200223739Sbz	u_char	if_alloctype;		/* if_type at time of allocation */
201189230Srwatson
202189230Srwatson	/*
203189230Srwatson	 * Spare fields are added so that we can modify sensitive data
204189230Srwatson	 * structures without changing the kernel binary interface, and must
205189230Srwatson	 * be used with care where binary compatibility is required.
206189230Srwatson	 */
207223739Sbz	char	if_cspare[3];
208189230Srwatson	int	if_ispare[4];
209224151Sbz	void	*if_pspare[8];		/* 1 netmap, 7 TDB */
21021259Swollman};
21169152Sjlemon
21292725Salfredtypedef void if_init_f_t(void *);
21321259Swollman
214128376Sluigi/*
215128376Sluigi * XXX These aliases are terribly dangerous because they could apply
216128376Sluigi * to anything.
217128376Sluigi */
21821259Swollman#define	if_mtu		if_data.ifi_mtu
21921259Swollman#define	if_type		if_data.ifi_type
22021259Swollman#define if_physical	if_data.ifi_physical
22121259Swollman#define	if_addrlen	if_data.ifi_addrlen
22221259Swollman#define	if_hdrlen	if_data.ifi_hdrlen
22321259Swollman#define	if_metric	if_data.ifi_metric
224128871Sandre#define	if_link_state	if_data.ifi_link_state
22521259Swollman#define	if_baudrate	if_data.ifi_baudrate
22658698Sjlemon#define	if_hwassist	if_data.ifi_hwassist
22721259Swollman#define	if_ipackets	if_data.ifi_ipackets
22821259Swollman#define	if_ierrors	if_data.ifi_ierrors
22921259Swollman#define	if_opackets	if_data.ifi_opackets
23021259Swollman#define	if_oerrors	if_data.ifi_oerrors
23121259Swollman#define	if_collisions	if_data.ifi_collisions
23221259Swollman#define	if_ibytes	if_data.ifi_ibytes
23321259Swollman#define	if_obytes	if_data.ifi_obytes
23421259Swollman#define	if_imcasts	if_data.ifi_imcasts
23521259Swollman#define	if_omcasts	if_data.ifi_omcasts
23621259Swollman#define	if_iqdrops	if_data.ifi_iqdrops
23721259Swollman#define	if_noproto	if_data.ifi_noproto
23821259Swollman#define	if_lastchange	if_data.ifi_lastchange
23921259Swollman
24053541Sshin/* for compatibility with other BSDs */
24153541Sshin#define	if_addrlist	if_addrhead
24253541Sshin#define	if_list		if_link
243160981Sbrooks#define	if_name(ifp)	((ifp)->if_xname)
24453541Sshin
24521259Swollman/*
246148640Srwatson * Locks for address lists on the network interface.
247148640Srwatson */
248148640Srwatson#define	IF_ADDR_LOCK_INIT(if)	mtx_init(&(if)->if_addr_mtx,		\
249148640Srwatson				    "if_addr_mtx", NULL, MTX_DEF)
250148640Srwatson#define	IF_ADDR_LOCK_DESTROY(if)	mtx_destroy(&(if)->if_addr_mtx)
251231157Sjhb#define	IF_ADDR_WLOCK(if)	mtx_lock(&(if)->if_addr_mtx)
252231157Sjhb#define	IF_ADDR_WUNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
253231157Sjhb#define	IF_ADDR_RLOCK(if)	mtx_lock(&(if)->if_addr_mtx)
254231157Sjhb#define	IF_ADDR_RUNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
255148640Srwatson#define	IF_ADDR_LOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
256231157Sjhb#define	IF_ADDR_WLOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
257231157Sjhb/* XXX: Compat. */
258231157Sjhb#define	IF_ADDR_LOCK(if)	IF_ADDR_WLOCK(if)
259231157Sjhb#define	IF_ADDR_UNLOCK(if)	IF_ADDR_WUNLOCK(if)
260148640Srwatson
261148640Srwatson/*
262195020Srwatson * Function variations on locking macros intended to be used by loadable
263195020Srwatson * kernel modules in order to divorce them from the internals of address list
264195020Srwatson * locking.
265195020Srwatson */
266195020Srwatsonvoid	if_addr_rlock(struct ifnet *ifp);	/* if_addrhead */
267195020Srwatsonvoid	if_addr_runlock(struct ifnet *ifp);	/* if_addrhead */
268195020Srwatsonvoid	if_maddr_rlock(struct ifnet *ifp);	/* if_multiaddrs */
269195020Srwatsonvoid	if_maddr_runlock(struct ifnet *ifp);	/* if_multiaddrs */
270195020Srwatson
271195020Srwatson/*
27221259Swollman * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
27321259Swollman * are queues of messages stored on ifqueue structures
27421259Swollman * (defined above).  Entries are added to and deleted from these structures
27521259Swollman * by these macros, which should be called with ipl raised to splimp().
27621259Swollman */
27772200Sbmilekic#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
27872200Sbmilekic#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
279130416Smlaier#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
28069152Sjlemon#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
28169152Sjlemon#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
28269152Sjlemon#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
28321259Swollman
28469152Sjlemon#define	_IF_ENQUEUE(ifq, m) do { 				\
28569152Sjlemon	(m)->m_nextpkt = NULL;					\
28669152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
28769152Sjlemon		(ifq)->ifq_head = m; 				\
28869152Sjlemon	else 							\
28969152Sjlemon		(ifq)->ifq_tail->m_nextpkt = m; 		\
29069152Sjlemon	(ifq)->ifq_tail = m; 					\
29169152Sjlemon	(ifq)->ifq_len++; 					\
29269152Sjlemon} while (0)
29369152Sjlemon
29469152Sjlemon#define IF_ENQUEUE(ifq, m) do {					\
29569152Sjlemon	IF_LOCK(ifq); 						\
29669152Sjlemon	_IF_ENQUEUE(ifq, m); 					\
29769152Sjlemon	IF_UNLOCK(ifq); 					\
29869152Sjlemon} while (0)
29969152Sjlemon
30069152Sjlemon#define	_IF_PREPEND(ifq, m) do {				\
30169152Sjlemon	(m)->m_nextpkt = (ifq)->ifq_head; 			\
30269152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
30369152Sjlemon		(ifq)->ifq_tail = (m); 				\
30469152Sjlemon	(ifq)->ifq_head = (m); 					\
30569152Sjlemon	(ifq)->ifq_len++; 					\
30669152Sjlemon} while (0)
30769152Sjlemon
30869152Sjlemon#define IF_PREPEND(ifq, m) do {		 			\
30969152Sjlemon	IF_LOCK(ifq); 						\
31069152Sjlemon	_IF_PREPEND(ifq, m); 					\
31169152Sjlemon	IF_UNLOCK(ifq); 					\
31269152Sjlemon} while (0)
31369152Sjlemon
31469152Sjlemon#define	_IF_DEQUEUE(ifq, m) do { 				\
31569152Sjlemon	(m) = (ifq)->ifq_head; 					\
31669152Sjlemon	if (m) { 						\
317136950Sjmg		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
31869152Sjlemon			(ifq)->ifq_tail = NULL; 		\
31969152Sjlemon		(m)->m_nextpkt = NULL; 				\
32069152Sjlemon		(ifq)->ifq_len--; 				\
32169152Sjlemon	} 							\
32269152Sjlemon} while (0)
32369152Sjlemon
32469152Sjlemon#define IF_DEQUEUE(ifq, m) do { 				\
32569152Sjlemon	IF_LOCK(ifq); 						\
32669152Sjlemon	_IF_DEQUEUE(ifq, m); 					\
32769152Sjlemon	IF_UNLOCK(ifq); 					\
32869152Sjlemon} while (0)
32969152Sjlemon
330229690Sglebius#define	_IF_DEQUEUE_ALL(ifq, m) do {				\
331229690Sglebius	(m) = (ifq)->ifq_head;					\
332229690Sglebius	(ifq)->ifq_head = (ifq)->ifq_tail = NULL;		\
333229690Sglebius	(ifq)->ifq_len = 0;					\
334229690Sglebius} while (0)
335229690Sglebius
336229690Sglebius#define	IF_DEQUEUE_ALL(ifq, m) do {				\
337229690Sglebius	IF_LOCK(ifq); 						\
338229690Sglebius	_IF_DEQUEUE_ALL(ifq, m);				\
339229690Sglebius	IF_UNLOCK(ifq); 					\
340229690Sglebius} while (0)
341229690Sglebius
342130416Smlaier#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
343130416Smlaier#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
344130416Smlaier
345130416Smlaier#define _IF_DRAIN(ifq) do { 					\
34669152Sjlemon	struct mbuf *m; 					\
34769152Sjlemon	for (;;) { 						\
34869152Sjlemon		_IF_DEQUEUE(ifq, m); 				\
34969152Sjlemon		if (m == NULL) 					\
35069152Sjlemon			break; 					\
35169152Sjlemon		m_freem(m); 					\
35269152Sjlemon	} 							\
35369152Sjlemon} while (0)
35469152Sjlemon
355130416Smlaier#define IF_DRAIN(ifq) do {					\
356130416Smlaier	IF_LOCK(ifq);						\
357130416Smlaier	_IF_DRAIN(ifq);						\
358130416Smlaier	IF_UNLOCK(ifq);						\
359130416Smlaier} while(0)
360130416Smlaier
36155205Speter#ifdef _KERNEL
362202588Sthompsa/* interface link layer address change event */
363202588Sthompsatypedef void (*iflladdr_event_handler_t)(void *, struct ifnet *);
364202588SthompsaEVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t);
365126264Smlaier/* interface address change event */
366126264Smlaiertypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
367126264SmlaierEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
368126264Smlaier/* new interface arrival event */
369126264Smlaiertypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
370126264SmlaierEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
371126264Smlaier/* interface departure event */
372126264Smlaiertypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
373126264SmlaierEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
374219819Sjeff/* Interface link state change event */
375219819Sjefftypedef void (*ifnet_link_event_handler_t)(void *, struct ifnet *, int);
376219819SjeffEVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t);
377126264Smlaier
378159781Smlaier/*
379159781Smlaier * interface groups
380159781Smlaier */
381159781Smlaierstruct ifg_group {
382159781Smlaier	char				 ifg_group[IFNAMSIZ];
383159781Smlaier	u_int				 ifg_refcnt;
384159781Smlaier	void				*ifg_pf_kif;
385159781Smlaier	TAILQ_HEAD(, ifg_member)	 ifg_members;
386159781Smlaier	TAILQ_ENTRY(ifg_group)		 ifg_next;
387159781Smlaier};
388159781Smlaier
389159781Smlaierstruct ifg_member {
390159781Smlaier	TAILQ_ENTRY(ifg_member)	 ifgm_next;
391159781Smlaier	struct ifnet		*ifgm_ifp;
392159781Smlaier};
393159781Smlaier
394159781Smlaierstruct ifg_list {
395159781Smlaier	struct ifg_group	*ifgl_group;
396159781Smlaier	TAILQ_ENTRY(ifg_list)	 ifgl_next;
397159781Smlaier};
398159781Smlaier
399159781Smlaier/* group attach event */
400159781Smlaiertypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
401159781SmlaierEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
402159781Smlaier/* group detach event */
403159781Smlaiertypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
404159781SmlaierEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
405159781Smlaier/* group change event */
406159781Smlaiertypedef void (*group_change_event_handler_t)(void *, const char *);
407159781SmlaierEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
408159781Smlaier
409121470Sume#define	IF_AFDATA_LOCK_INIT(ifp)	\
410186199Skmacy	rw_init(&(ifp)->if_afdata_lock, "if_afdata")
411121470Sume
412186199Skmacy#define	IF_AFDATA_WLOCK(ifp)	rw_wlock(&(ifp)->if_afdata_lock)
413186199Skmacy#define	IF_AFDATA_RLOCK(ifp)	rw_rlock(&(ifp)->if_afdata_lock)
414186199Skmacy#define	IF_AFDATA_WUNLOCK(ifp)	rw_wunlock(&(ifp)->if_afdata_lock)
415186199Skmacy#define	IF_AFDATA_RUNLOCK(ifp)	rw_runlock(&(ifp)->if_afdata_lock)
416186199Skmacy#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
417186199Skmacy#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
418186199Skmacy#define	IF_AFDATA_TRYLOCK(ifp)	rw_try_wlock(&(ifp)->if_afdata_lock)
419186199Skmacy#define	IF_AFDATA_DESTROY(ifp)	rw_destroy(&(ifp)->if_afdata_lock)
420186119Sqingli
421186199Skmacy#define	IF_AFDATA_LOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
422186199Skmacy#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
423186199Skmacy
424137065Srwatsonint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
425137065Srwatson	    int adjust);
426130416Smlaier#define	IF_HANDOFF(ifq, m, ifp)			\
427130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
428130416Smlaier#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
429130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
43021259Swollman
431132712Srwatsonvoid	if_start(struct ifnet *);
432132712Srwatson
433130416Smlaier#define	IFQ_ENQUEUE(ifq, m, err)					\
434130416Smlaierdo {									\
435130416Smlaier	IF_LOCK(ifq);							\
436130416Smlaier	if (ALTQ_IS_ENABLED(ifq))					\
437130416Smlaier		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
438130416Smlaier	else {								\
439130416Smlaier		if (_IF_QFULL(ifq)) {					\
440130416Smlaier			m_freem(m);					\
441130416Smlaier			(err) = ENOBUFS;				\
442130416Smlaier		} else {						\
443130416Smlaier			_IF_ENQUEUE(ifq, m);				\
444130416Smlaier			(err) = 0;					\
445130416Smlaier		}							\
446130416Smlaier	}								\
447130416Smlaier	if (err)							\
448130416Smlaier		(ifq)->ifq_drops++;					\
449130416Smlaier	IF_UNLOCK(ifq);							\
450130416Smlaier} while (0)
45121259Swollman
452130416Smlaier#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
453130416Smlaierdo {									\
454130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
455130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
456130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
457130416Smlaier		ALTQ_DEQUEUE(ifq, m);					\
458130416Smlaier	else								\
459130416Smlaier		_IF_DEQUEUE(ifq, m);					\
460130416Smlaier} while (0)
461130416Smlaier
462130416Smlaier#define	IFQ_DEQUEUE(ifq, m)						\
463130416Smlaierdo {									\
464130416Smlaier	IF_LOCK(ifq);							\
465130416Smlaier	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
466130416Smlaier	IF_UNLOCK(ifq);							\
467130416Smlaier} while (0)
468130416Smlaier
469130416Smlaier#define	IFQ_POLL_NOLOCK(ifq, m)						\
470130416Smlaierdo {									\
471130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
472130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
473130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
474130416Smlaier		ALTQ_POLL(ifq, m);					\
475130416Smlaier	else								\
476130416Smlaier		_IF_POLL(ifq, m);					\
477130416Smlaier} while (0)
478130416Smlaier
479130416Smlaier#define	IFQ_POLL(ifq, m)						\
480130416Smlaierdo {									\
481130416Smlaier	IF_LOCK(ifq);							\
482130416Smlaier	IFQ_POLL_NOLOCK(ifq, m);					\
483130416Smlaier	IF_UNLOCK(ifq);							\
484130416Smlaier} while (0)
485130416Smlaier
486130416Smlaier#define	IFQ_PURGE_NOLOCK(ifq)						\
487130416Smlaierdo {									\
488130416Smlaier	if (ALTQ_IS_ENABLED(ifq)) {					\
489130416Smlaier		ALTQ_PURGE(ifq);					\
490130416Smlaier	} else								\
491130416Smlaier		_IF_DRAIN(ifq);						\
492130416Smlaier} while (0)
493130416Smlaier
494130416Smlaier#define	IFQ_PURGE(ifq)							\
495130416Smlaierdo {									\
496130416Smlaier	IF_LOCK(ifq);							\
497130416Smlaier	IFQ_PURGE_NOLOCK(ifq);						\
498130416Smlaier	IF_UNLOCK(ifq);							\
499130416Smlaier} while (0)
500130416Smlaier
501130416Smlaier#define	IFQ_SET_READY(ifq)						\
502130416Smlaier	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
503130416Smlaier
504130416Smlaier#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
505130416Smlaier#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
506130416Smlaier#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
507130416Smlaier#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
508130416Smlaier#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
509130416Smlaier#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
510130416Smlaier#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
511130416Smlaier#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
512130416Smlaier
513148886Srwatson/*
514148886Srwatson * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
515148886Srwatson * the handoff logic, as that flag is locked by the device driver.
516148886Srwatson */
517130416Smlaier#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
518130416Smlaierdo {									\
519130416Smlaier	int len;							\
520130416Smlaier	short mflags;							\
521130416Smlaier									\
522130416Smlaier	len = (m)->m_pkthdr.len;					\
523130416Smlaier	mflags = (m)->m_flags;						\
524130416Smlaier	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
525130416Smlaier	if ((err) == 0) {						\
526130416Smlaier		(ifp)->if_obytes += len + (adj);			\
527130416Smlaier		if (mflags & M_MCAST)					\
528130416Smlaier			(ifp)->if_omcasts++;				\
529148886Srwatson		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
530132712Srwatson			if_start(ifp);					\
531130416Smlaier	}								\
532130416Smlaier} while (0)
533130416Smlaier
534130416Smlaier#define	IFQ_HANDOFF(ifp, m, err)					\
535130512Smlaier	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
536130416Smlaier
537130416Smlaier#define	IFQ_DRV_DEQUEUE(ifq, m)						\
538130416Smlaierdo {									\
539130416Smlaier	(m) = (ifq)->ifq_drv_head;					\
540130416Smlaier	if (m) {							\
541130416Smlaier		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
542130416Smlaier			(ifq)->ifq_drv_tail = NULL;			\
543130416Smlaier		(m)->m_nextpkt = NULL;					\
544130416Smlaier		(ifq)->ifq_drv_len--;					\
545130416Smlaier	} else {							\
546130416Smlaier		IFQ_LOCK(ifq);						\
547130416Smlaier		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
548130416Smlaier		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
549130416Smlaier			struct mbuf *m0;				\
550130416Smlaier			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
551130416Smlaier			if (m0 == NULL)					\
552130416Smlaier				break;					\
553130416Smlaier			m0->m_nextpkt = NULL;				\
554130416Smlaier			if ((ifq)->ifq_drv_tail == NULL)		\
555130416Smlaier				(ifq)->ifq_drv_head = m0;		\
556130416Smlaier			else						\
557130416Smlaier				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
558130416Smlaier			(ifq)->ifq_drv_tail = m0;			\
559130416Smlaier			(ifq)->ifq_drv_len++;				\
560130416Smlaier		}							\
561130416Smlaier		IFQ_UNLOCK(ifq);					\
562130416Smlaier	}								\
563130416Smlaier} while (0)
564130416Smlaier
565130416Smlaier#define	IFQ_DRV_PREPEND(ifq, m)						\
566130416Smlaierdo {									\
567130416Smlaier	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
568132152Smlaier	if ((ifq)->ifq_drv_tail == NULL)				\
569132152Smlaier		(ifq)->ifq_drv_tail = (m);				\
570130416Smlaier	(ifq)->ifq_drv_head = (m);					\
571130416Smlaier	(ifq)->ifq_drv_len++;						\
572130416Smlaier} while (0)
573130416Smlaier
574130416Smlaier#define	IFQ_DRV_IS_EMPTY(ifq)						\
575130416Smlaier	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
576130416Smlaier
577130416Smlaier#define	IFQ_DRV_PURGE(ifq)						\
578130416Smlaierdo {									\
579132152Smlaier	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
580132152Smlaier	while((m = n) != NULL) {					\
581132152Smlaier		n = m->m_nextpkt;					\
582130416Smlaier		m_freem(m);						\
583130416Smlaier	}								\
584130416Smlaier	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
585130416Smlaier	(ifq)->ifq_drv_len = 0;						\
586130416Smlaier	IFQ_PURGE(ifq);							\
587130416Smlaier} while (0)
588130416Smlaier
589186207Skmacy#ifdef _KERNEL
590186213Skmacystatic __inline void
591186213Skmacydrbr_stats_update(struct ifnet *ifp, int len, int mflags)
592186213Skmacy{
593193848Skmacy#ifndef NO_SLOW_STATS
594186213Skmacy	ifp->if_obytes += len;
595186213Skmacy	if (mflags & M_MCAST)
596186213Skmacy		ifp->if_omcasts++;
597193848Skmacy#endif
598186213Skmacy}
599186213Skmacy
600186207Skmacystatic __inline int
601186213Skmacydrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
602186207Skmacy{
603186207Skmacy	int error = 0;
604186213Skmacy	int len = m->m_pkthdr.len;
605186213Skmacy	int mflags = m->m_flags;
606186207Skmacy
607191033Skmacy#ifdef ALTQ
608191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
609191033Skmacy		IFQ_ENQUEUE(&ifp->if_snd, m, error);
610191033Skmacy		return (error);
611191033Skmacy	}
612191033Skmacy#endif
613193848Skmacy	if ((error = buf_ring_enqueue_bytes(br, m, len)) == ENOBUFS) {
614186207Skmacy		br->br_drops++;
615186207Skmacy		m_freem(m);
616186213Skmacy	} else
617186213Skmacy		drbr_stats_update(ifp, len, mflags);
618186213Skmacy
619186207Skmacy	return (error);
620186207Skmacy}
621186207Skmacy
622186207Skmacystatic __inline void
623194518Skmacydrbr_flush(struct ifnet *ifp, struct buf_ring *br)
624186207Skmacy{
625186207Skmacy	struct mbuf *m;
626186207Skmacy
627194518Skmacy#ifdef ALTQ
628203834Smlaier	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
629203834Smlaier		IFQ_PURGE(&ifp->if_snd);
630194518Skmacy#endif
631186207Skmacy	while ((m = buf_ring_dequeue_sc(br)) != NULL)
632186207Skmacy		m_freem(m);
633194518Skmacy}
634186207Skmacy
635194518Skmacystatic __inline void
636194518Skmacydrbr_free(struct buf_ring *br, struct malloc_type *type)
637194518Skmacy{
638194518Skmacy
639194518Skmacy	drbr_flush(NULL, br);
640186207Skmacy	buf_ring_free(br, type);
641186207Skmacy}
642191033Skmacy
643191033Skmacystatic __inline struct mbuf *
644191033Skmacydrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
645191033Skmacy{
646191033Skmacy#ifdef ALTQ
647191033Skmacy	struct mbuf *m;
648191033Skmacy
649191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
650203834Smlaier		IFQ_DEQUEUE(&ifp->if_snd, m);
651191033Skmacy		return (m);
652191033Skmacy	}
653186207Skmacy#endif
654191033Skmacy	return (buf_ring_dequeue_sc(br));
655191033Skmacy}
656186207Skmacy
657193848Skmacystatic __inline struct mbuf *
658193848Skmacydrbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
659193848Skmacy    int (*func) (struct mbuf *, void *), void *arg)
660193848Skmacy{
661193848Skmacy	struct mbuf *m;
662193848Skmacy#ifdef ALTQ
663203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
664203834Smlaier		IFQ_LOCK(&ifp->if_snd);
665203834Smlaier		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
666203834Smlaier		if (m != NULL && func(m, arg) == 0) {
667203834Smlaier			IFQ_UNLOCK(&ifp->if_snd);
668203834Smlaier			return (NULL);
669203834Smlaier		}
670205197Smlaier		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
671203834Smlaier		IFQ_UNLOCK(&ifp->if_snd);
672193848Skmacy		return (m);
673193848Skmacy	}
674193848Skmacy#endif
675193848Skmacy	m = buf_ring_peek(br);
676193848Skmacy	if (m == NULL || func(m, arg) == 0)
677193848Skmacy		return (NULL);
678193848Skmacy
679193848Skmacy	return (buf_ring_dequeue_sc(br));
680193848Skmacy}
681193848Skmacy
682191033Skmacystatic __inline int
683191033Skmacydrbr_empty(struct ifnet *ifp, struct buf_ring *br)
684191033Skmacy{
685191033Skmacy#ifdef ALTQ
686191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
687203834Smlaier		return (IFQ_IS_EMPTY(&ifp->if_snd));
688191033Skmacy#endif
689191033Skmacy	return (buf_ring_empty(br));
690191033Skmacy}
691193848Skmacy
692193848Skmacystatic __inline int
693203834Smlaierdrbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
694203834Smlaier{
695203834Smlaier#ifdef ALTQ
696203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd))
697203834Smlaier		return (1);
698203834Smlaier#endif
699203834Smlaier	return (!buf_ring_empty(br));
700203834Smlaier}
701203834Smlaier
702203834Smlaierstatic __inline int
703193848Skmacydrbr_inuse(struct ifnet *ifp, struct buf_ring *br)
704193848Skmacy{
705193848Skmacy#ifdef ALTQ
706193848Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
707193848Skmacy		return (ifp->if_snd.ifq_len);
708191033Skmacy#endif
709193848Skmacy	return (buf_ring_count(br));
710193848Skmacy}
711193848Skmacy#endif
71249459Sbrian/*
71349459Sbrian * 72 was chosen below because it is the size of a TCP/IP
71449459Sbrian * header (40) + the minimum mss (32).
71549459Sbrian */
71649459Sbrian#define	IF_MINMTU	72
71749459Sbrian#define	IF_MAXMTU	65535
71849459Sbrian
71955205Speter#endif /* _KERNEL */
72021259Swollman
72121259Swollman/*
72221259Swollman * The ifaddr structure contains information about one address
72321259Swollman * of an interface.  They are maintained by the different address families,
72421259Swollman * are allocated and attached when an address is set, and are linked
72521259Swollman * together so all addresses for an interface can be located.
726128291Sluigi *
727128291Sluigi * NOTE: a 'struct ifaddr' is always at the beginning of a larger
728128291Sluigi * chunk of malloc'ed memory, where we store the three addresses
729128291Sluigi * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
73021259Swollman */
73121259Swollmanstruct ifaddr {
73221259Swollman	struct	sockaddr *ifa_addr;	/* address of interface */
73321259Swollman	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
73421259Swollman#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
73521259Swollman	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
73667334Sjoe	struct	if_data if_data;	/* not all members are meaningful */
73721259Swollman	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
73860938Sjake	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
73921259Swollman	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
74092725Salfred		(int, struct rtentry *, struct rt_addrinfo *);
74121259Swollman	u_short	ifa_flags;		/* mostly rt_flags for cloning */
74247254Spb	u_int	ifa_refcnt;		/* references to this structure */
74321259Swollman	int	ifa_metric;		/* cost of going out this interface */
74428845Sjulian	int (*ifa_claim_addr)		/* check if an addr goes to this if */
74592725Salfred		(struct ifaddr *, struct sockaddr *);
746108033Shsu	struct mtx ifa_mtx;
74721259Swollman};
74821259Swollman#define	IFA_ROUTE	RTF_UP		/* route installed */
749201282Sqingli#define IFA_RTSELF	RTF_HOST	/* loopback route to self installed */
75021259Swollman
75153541Sshin/* for compatibility with other BSDs */
75253541Sshin#define	ifa_list	ifa_link
75353541Sshin
754194602Srwatson#ifdef _KERNEL
755108033Shsu#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
756108033Shsu#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
757108033Shsu
758194602Srwatsonvoid	ifa_free(struct ifaddr *ifa);
759194602Srwatsonvoid	ifa_init(struct ifaddr *ifa);
760194602Srwatsonvoid	ifa_ref(struct ifaddr *ifa);
761194602Srwatson#endif
762194602Srwatson
76321404Swollman/*
76452904Sshin * The prefix structure contains information about one prefix
76552904Sshin * of an interface.  They are maintained by the different address families,
766108470Sschweikh * are allocated and attached when a prefix or an address is set,
76753541Sshin * and are linked together so all prefixes for an interface can be located.
76852904Sshin */
76952904Sshinstruct ifprefix {
77052904Sshin	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
77152904Sshin	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
77260938Sjake	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
77352904Sshin	u_char	ifpr_plen;		/* prefix length in bits */
77452904Sshin	u_char	ifpr_type;		/* protocol dependent prefix type */
77552904Sshin};
77652904Sshin
77752904Sshin/*
77821404Swollman * Multicast address structure.  This is analogous to the ifaddr
77921404Swollman * structure except that it keeps track of multicast addresses.
78021404Swollman */
78121404Swollmanstruct ifmultiaddr {
78272084Sphk	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
78321434Swollman	struct	sockaddr *ifma_addr; 	/* address this membership is for */
78421434Swollman	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
78521434Swollman	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
78621434Swollman	u_int	ifma_refcount;		/* reference count */
78721434Swollman	void	*ifma_protospec;	/* protocol-specific state, if any */
788167729Sbms	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
78921404Swollman};
79021404Swollman
79155205Speter#ifdef _KERNEL
79221259Swollman
793196481Srwatsonextern	struct rwlock ifnet_rwlock;
794196481Srwatsonextern	struct sx ifnet_sxlock;
795108172Shsu
796196481Srwatson#define	IFNET_LOCK_INIT() do {						\
797196481Srwatson	rw_init_flags(&ifnet_rwlock, "ifnet_rw",  RW_RECURSE);		\
798196481Srwatson	sx_init_flags(&ifnet_sxlock, "ifnet_sx",  SX_RECURSE);		\
799196481Srwatson} while(0)
800196481Srwatson
801196481Srwatson#define	IFNET_WLOCK() do {						\
802196481Srwatson	sx_xlock(&ifnet_sxlock);					\
803196481Srwatson	rw_wlock(&ifnet_rwlock);					\
804196481Srwatson} while (0)
805196481Srwatson
806196481Srwatson#define	IFNET_WUNLOCK() do {						\
807196481Srwatson	rw_wunlock(&ifnet_rwlock);					\
808196481Srwatson	sx_xunlock(&ifnet_sxlock);					\
809196481Srwatson} while (0)
810196481Srwatson
811191367Srwatson/*
812196481Srwatson * To assert the ifnet lock, you must know not only whether it's for read or
813196481Srwatson * write, but also whether it was acquired with sleep support or not.
814196481Srwatson */
815196481Srwatson#define	IFNET_RLOCK_ASSERT()		sx_assert(&ifnet_sxlock, SA_SLOCKED)
816196481Srwatson#define	IFNET_RLOCK_NOSLEEP_ASSERT()	rw_assert(&ifnet_rwlock, RA_RLOCKED)
817196481Srwatson#define	IFNET_WLOCK_ASSERT() do {					\
818196481Srwatson	sx_assert(&ifnet_sxlock, SA_XLOCKED);				\
819196481Srwatson	rw_assert(&ifnet_rwlock, RA_WLOCKED);				\
820196481Srwatson} while (0)
821196481Srwatson
822196481Srwatson#define	IFNET_RLOCK()		sx_slock(&ifnet_sxlock)
823196481Srwatson#define	IFNET_RLOCK_NOSLEEP()	rw_rlock(&ifnet_rwlock)
824196481Srwatson#define	IFNET_RUNLOCK()		sx_sunlock(&ifnet_sxlock)
825196481Srwatson#define	IFNET_RUNLOCK_NOSLEEP()	rw_runlock(&ifnet_rwlock)
826196481Srwatson
827196481Srwatson/*
828191367Srwatson * Look up an ifnet given its index; the _ref variant also acquires a
829191367Srwatson * reference that must be freed using if_rele().  It is almost always a bug
830191367Srwatson * to call ifnet_byindex() instead if ifnet_byindex_ref().
831191367Srwatson */
832180042Srwatsonstruct ifnet	*ifnet_byindex(u_short idx);
833191816Szecstruct ifnet	*ifnet_byindex_locked(u_short idx);
834191367Srwatsonstruct ifnet	*ifnet_byindex_ref(u_short idx);
835181892Skmacy
836128315Sluigi/*
837128315Sluigi * Given the index, ifaddr_byindex() returns the one and only
838128315Sluigi * link-level ifaddr for the interface. You are not supposed to use
839128315Sluigi * it to traverse the list of addresses associated to the interface.
840128315Sluigi */
841180042Srwatsonstruct ifaddr	*ifaddr_byindex(u_short idx);
84283130Sjlemon
843195699SrwatsonVNET_DECLARE(struct ifnethead, ifnet);
844195699SrwatsonVNET_DECLARE(struct ifgrouphead, ifg_head);
845195699SrwatsonVNET_DECLARE(int, if_index);
846195699SrwatsonVNET_DECLARE(struct ifnet *, loif);	/* first loopback interface */
847195914SqingliVNET_DECLARE(int, useloopback);
848195699Srwatson
849195727Srwatson#define	V_ifnet		VNET(ifnet)
850195727Srwatson#define	V_ifg_head	VNET(ifg_head)
851195727Srwatson#define	V_if_index	VNET(if_index)
852195727Srwatson#define	V_loif		VNET(loif)
853195914Sqingli#define	V_useloopback	VNET(useloopback)
854195699Srwatson
855186048Sbzextern	int ifqmaxlen;
85621259Swollman
857159781Smlaierint	if_addgroup(struct ifnet *, const char *);
858159781Smlaierint	if_delgroup(struct ifnet *, const char *);
85992725Salfredint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
86092725Salfredint	if_allmulti(struct ifnet *, int);
861147256Sbrooksstruct	ifnet* if_alloc(u_char);
86292725Salfredvoid	if_attach(struct ifnet *);
863191418Srwatsonvoid	if_dead(struct ifnet *);
86492725Salfredint	if_delmulti(struct ifnet *, struct sockaddr *);
865167729Sbmsvoid	if_delmulti_ifma(struct ifmultiaddr *);
86692725Salfredvoid	if_detach(struct ifnet *);
867192605Szecvoid	if_vmove(struct ifnet *, struct vnet *);
868146620Speadarvoid	if_purgeaddrs(struct ifnet *);
869202935Ssyrinxvoid	if_delallmulti(struct ifnet *);
87092725Salfredvoid	if_down(struct ifnet *);
871167732Sbmsstruct ifmultiaddr *
872167732Sbms	if_findmulti(struct ifnet *, struct sockaddr *);
873147256Sbrooksvoid	if_free(struct ifnet *);
874147256Sbrooksvoid	if_free_type(struct ifnet *, u_char);
875121816Sbrooksvoid	if_initname(struct ifnet *, const char *, int);
876138542Ssamvoid	if_link_state_change(struct ifnet *, int);
877103900Sbrooksint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
878191161Skmacyvoid	if_qflush(struct ifnet *);
879191367Srwatsonvoid	if_ref(struct ifnet *);
880191367Srwatsonvoid	if_rele(struct ifnet *);
88192725Salfredint	if_setlladdr(struct ifnet *, const u_char *, int);
88292725Salfredvoid	if_up(struct ifnet *);
88392725Salfredint	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
88492725Salfredint	ifpromisc(struct ifnet *, int);
88592725Salfredstruct	ifnet *ifunit(const char *);
886191423Srwatsonstruct	ifnet *ifunit_ref(const char *);
88721259Swollman
888194259Ssamvoid	ifq_init(struct ifaltq *, struct ifnet *ifp);
889194259Ssamvoid	ifq_delete(struct ifaltq *);
890185162Skmacy
891197227Sqingliint	ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
892197227Sqingliint	ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
893197227Sqingli
89492725Salfredstruct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
895194622Srwatsonint		ifa_ifwithaddr_check(struct sockaddr *);
896162068Sandrestruct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
89792725Salfredstruct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
898208553Sqinglistruct	ifaddr *ifa_ifwithnet(struct sockaddr *, int);
89992725Salfredstruct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
900178888Sjulianstruct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
901178888Sjulian
90292725Salfredstruct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
90321259Swollman
90492725Salfredint	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
90521434Swollman
906147256Sbrookstypedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
907147256Sbrookstypedef	void if_com_free_t(void *com, u_char type);
908147256Sbrooksvoid	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
909147256Sbrooksvoid	if_deregister_com_alloc(u_char type);
910147256Sbrooks
91184931Sfjoe#define IF_LLADDR(ifp)							\
912152315Sru    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
91384931Sfjoe
91487902Sluigi#ifdef DEVICE_POLLING
915150789Sglebiusenum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
91687902Sluigi
917193096Sattiliotypedef	int poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
91892725Salfredint    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
91992725Salfredint    ether_poll_deregister(struct ifnet *ifp);
92087902Sluigi#endif /* DEVICE_POLLING */
92187902Sluigi
92255205Speter#endif /* _KERNEL */
92321259Swollman
92421259Swollman#endif /* !_NET_IF_VAR_H_ */
925