if_var.h revision 224151
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: head/sys/net/if_var.h 224151 2011-07-17 21:15:20Z bz $
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)
251148640Srwatson#define	IF_ADDR_LOCK(if)	mtx_lock(&(if)->if_addr_mtx)
252148640Srwatson#define	IF_ADDR_UNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
253148640Srwatson#define	IF_ADDR_LOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
254148640Srwatson
255148640Srwatson/*
256195020Srwatson * Function variations on locking macros intended to be used by loadable
257195020Srwatson * kernel modules in order to divorce them from the internals of address list
258195020Srwatson * locking.
259195020Srwatson */
260195020Srwatsonvoid	if_addr_rlock(struct ifnet *ifp);	/* if_addrhead */
261195020Srwatsonvoid	if_addr_runlock(struct ifnet *ifp);	/* if_addrhead */
262195020Srwatsonvoid	if_maddr_rlock(struct ifnet *ifp);	/* if_multiaddrs */
263195020Srwatsonvoid	if_maddr_runlock(struct ifnet *ifp);	/* if_multiaddrs */
264195020Srwatson
265195020Srwatson/*
26621259Swollman * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
26721259Swollman * are queues of messages stored on ifqueue structures
26821259Swollman * (defined above).  Entries are added to and deleted from these structures
26921259Swollman * by these macros, which should be called with ipl raised to splimp().
27021259Swollman */
27172200Sbmilekic#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
27272200Sbmilekic#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
273130416Smlaier#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
27469152Sjlemon#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
27569152Sjlemon#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
27669152Sjlemon#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
27721259Swollman
27869152Sjlemon#define	_IF_ENQUEUE(ifq, m) do { 				\
27969152Sjlemon	(m)->m_nextpkt = NULL;					\
28069152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
28169152Sjlemon		(ifq)->ifq_head = m; 				\
28269152Sjlemon	else 							\
28369152Sjlemon		(ifq)->ifq_tail->m_nextpkt = m; 		\
28469152Sjlemon	(ifq)->ifq_tail = m; 					\
28569152Sjlemon	(ifq)->ifq_len++; 					\
28669152Sjlemon} while (0)
28769152Sjlemon
28869152Sjlemon#define IF_ENQUEUE(ifq, m) do {					\
28969152Sjlemon	IF_LOCK(ifq); 						\
29069152Sjlemon	_IF_ENQUEUE(ifq, m); 					\
29169152Sjlemon	IF_UNLOCK(ifq); 					\
29269152Sjlemon} while (0)
29369152Sjlemon
29469152Sjlemon#define	_IF_PREPEND(ifq, m) do {				\
29569152Sjlemon	(m)->m_nextpkt = (ifq)->ifq_head; 			\
29669152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
29769152Sjlemon		(ifq)->ifq_tail = (m); 				\
29869152Sjlemon	(ifq)->ifq_head = (m); 					\
29969152Sjlemon	(ifq)->ifq_len++; 					\
30069152Sjlemon} while (0)
30169152Sjlemon
30269152Sjlemon#define IF_PREPEND(ifq, m) do {		 			\
30369152Sjlemon	IF_LOCK(ifq); 						\
30469152Sjlemon	_IF_PREPEND(ifq, m); 					\
30569152Sjlemon	IF_UNLOCK(ifq); 					\
30669152Sjlemon} while (0)
30769152Sjlemon
30869152Sjlemon#define	_IF_DEQUEUE(ifq, m) do { 				\
30969152Sjlemon	(m) = (ifq)->ifq_head; 					\
31069152Sjlemon	if (m) { 						\
311136950Sjmg		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
31269152Sjlemon			(ifq)->ifq_tail = NULL; 		\
31369152Sjlemon		(m)->m_nextpkt = NULL; 				\
31469152Sjlemon		(ifq)->ifq_len--; 				\
31569152Sjlemon	} 							\
31669152Sjlemon} while (0)
31769152Sjlemon
31869152Sjlemon#define IF_DEQUEUE(ifq, m) do { 				\
31969152Sjlemon	IF_LOCK(ifq); 						\
32069152Sjlemon	_IF_DEQUEUE(ifq, m); 					\
32169152Sjlemon	IF_UNLOCK(ifq); 					\
32269152Sjlemon} while (0)
32369152Sjlemon
324130416Smlaier#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
325130416Smlaier#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
326130416Smlaier
327130416Smlaier#define _IF_DRAIN(ifq) do { 					\
32869152Sjlemon	struct mbuf *m; 					\
32969152Sjlemon	for (;;) { 						\
33069152Sjlemon		_IF_DEQUEUE(ifq, m); 				\
33169152Sjlemon		if (m == NULL) 					\
33269152Sjlemon			break; 					\
33369152Sjlemon		m_freem(m); 					\
33469152Sjlemon	} 							\
33569152Sjlemon} while (0)
33669152Sjlemon
337130416Smlaier#define IF_DRAIN(ifq) do {					\
338130416Smlaier	IF_LOCK(ifq);						\
339130416Smlaier	_IF_DRAIN(ifq);						\
340130416Smlaier	IF_UNLOCK(ifq);						\
341130416Smlaier} while(0)
342130416Smlaier
34355205Speter#ifdef _KERNEL
344202588Sthompsa/* interface link layer address change event */
345202588Sthompsatypedef void (*iflladdr_event_handler_t)(void *, struct ifnet *);
346202588SthompsaEVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t);
347126264Smlaier/* interface address change event */
348126264Smlaiertypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
349126264SmlaierEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
350126264Smlaier/* new interface arrival event */
351126264Smlaiertypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
352126264SmlaierEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
353126264Smlaier/* interface departure event */
354126264Smlaiertypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
355126264SmlaierEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
356219819Sjeff/* Interface link state change event */
357219819Sjefftypedef void (*ifnet_link_event_handler_t)(void *, struct ifnet *, int);
358219819SjeffEVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t);
359126264Smlaier
360159781Smlaier/*
361159781Smlaier * interface groups
362159781Smlaier */
363159781Smlaierstruct ifg_group {
364159781Smlaier	char				 ifg_group[IFNAMSIZ];
365159781Smlaier	u_int				 ifg_refcnt;
366159781Smlaier	void				*ifg_pf_kif;
367159781Smlaier	TAILQ_HEAD(, ifg_member)	 ifg_members;
368159781Smlaier	TAILQ_ENTRY(ifg_group)		 ifg_next;
369159781Smlaier};
370159781Smlaier
371159781Smlaierstruct ifg_member {
372159781Smlaier	TAILQ_ENTRY(ifg_member)	 ifgm_next;
373159781Smlaier	struct ifnet		*ifgm_ifp;
374159781Smlaier};
375159781Smlaier
376159781Smlaierstruct ifg_list {
377159781Smlaier	struct ifg_group	*ifgl_group;
378159781Smlaier	TAILQ_ENTRY(ifg_list)	 ifgl_next;
379159781Smlaier};
380159781Smlaier
381159781Smlaier/* group attach event */
382159781Smlaiertypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
383159781SmlaierEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
384159781Smlaier/* group detach event */
385159781Smlaiertypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
386159781SmlaierEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
387159781Smlaier/* group change event */
388159781Smlaiertypedef void (*group_change_event_handler_t)(void *, const char *);
389159781SmlaierEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
390159781Smlaier
391121470Sume#define	IF_AFDATA_LOCK_INIT(ifp)	\
392186199Skmacy	rw_init(&(ifp)->if_afdata_lock, "if_afdata")
393121470Sume
394186199Skmacy#define	IF_AFDATA_WLOCK(ifp)	rw_wlock(&(ifp)->if_afdata_lock)
395186199Skmacy#define	IF_AFDATA_RLOCK(ifp)	rw_rlock(&(ifp)->if_afdata_lock)
396186199Skmacy#define	IF_AFDATA_WUNLOCK(ifp)	rw_wunlock(&(ifp)->if_afdata_lock)
397186199Skmacy#define	IF_AFDATA_RUNLOCK(ifp)	rw_runlock(&(ifp)->if_afdata_lock)
398186199Skmacy#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
399186199Skmacy#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
400186199Skmacy#define	IF_AFDATA_TRYLOCK(ifp)	rw_try_wlock(&(ifp)->if_afdata_lock)
401186199Skmacy#define	IF_AFDATA_DESTROY(ifp)	rw_destroy(&(ifp)->if_afdata_lock)
402186119Sqingli
403186199Skmacy#define	IF_AFDATA_LOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
404186199Skmacy#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
405186199Skmacy
406137065Srwatsonint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
407137065Srwatson	    int adjust);
408130416Smlaier#define	IF_HANDOFF(ifq, m, ifp)			\
409130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
410130416Smlaier#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
411130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
41221259Swollman
413132712Srwatsonvoid	if_start(struct ifnet *);
414132712Srwatson
415130416Smlaier#define	IFQ_ENQUEUE(ifq, m, err)					\
416130416Smlaierdo {									\
417130416Smlaier	IF_LOCK(ifq);							\
418130416Smlaier	if (ALTQ_IS_ENABLED(ifq))					\
419130416Smlaier		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
420130416Smlaier	else {								\
421130416Smlaier		if (_IF_QFULL(ifq)) {					\
422130416Smlaier			m_freem(m);					\
423130416Smlaier			(err) = ENOBUFS;				\
424130416Smlaier		} else {						\
425130416Smlaier			_IF_ENQUEUE(ifq, m);				\
426130416Smlaier			(err) = 0;					\
427130416Smlaier		}							\
428130416Smlaier	}								\
429130416Smlaier	if (err)							\
430130416Smlaier		(ifq)->ifq_drops++;					\
431130416Smlaier	IF_UNLOCK(ifq);							\
432130416Smlaier} while (0)
43321259Swollman
434130416Smlaier#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
435130416Smlaierdo {									\
436130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
437130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
438130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
439130416Smlaier		ALTQ_DEQUEUE(ifq, m);					\
440130416Smlaier	else								\
441130416Smlaier		_IF_DEQUEUE(ifq, m);					\
442130416Smlaier} while (0)
443130416Smlaier
444130416Smlaier#define	IFQ_DEQUEUE(ifq, m)						\
445130416Smlaierdo {									\
446130416Smlaier	IF_LOCK(ifq);							\
447130416Smlaier	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
448130416Smlaier	IF_UNLOCK(ifq);							\
449130416Smlaier} while (0)
450130416Smlaier
451130416Smlaier#define	IFQ_POLL_NOLOCK(ifq, m)						\
452130416Smlaierdo {									\
453130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
454130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
455130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
456130416Smlaier		ALTQ_POLL(ifq, m);					\
457130416Smlaier	else								\
458130416Smlaier		_IF_POLL(ifq, m);					\
459130416Smlaier} while (0)
460130416Smlaier
461130416Smlaier#define	IFQ_POLL(ifq, m)						\
462130416Smlaierdo {									\
463130416Smlaier	IF_LOCK(ifq);							\
464130416Smlaier	IFQ_POLL_NOLOCK(ifq, m);					\
465130416Smlaier	IF_UNLOCK(ifq);							\
466130416Smlaier} while (0)
467130416Smlaier
468130416Smlaier#define	IFQ_PURGE_NOLOCK(ifq)						\
469130416Smlaierdo {									\
470130416Smlaier	if (ALTQ_IS_ENABLED(ifq)) {					\
471130416Smlaier		ALTQ_PURGE(ifq);					\
472130416Smlaier	} else								\
473130416Smlaier		_IF_DRAIN(ifq);						\
474130416Smlaier} while (0)
475130416Smlaier
476130416Smlaier#define	IFQ_PURGE(ifq)							\
477130416Smlaierdo {									\
478130416Smlaier	IF_LOCK(ifq);							\
479130416Smlaier	IFQ_PURGE_NOLOCK(ifq);						\
480130416Smlaier	IF_UNLOCK(ifq);							\
481130416Smlaier} while (0)
482130416Smlaier
483130416Smlaier#define	IFQ_SET_READY(ifq)						\
484130416Smlaier	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
485130416Smlaier
486130416Smlaier#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
487130416Smlaier#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
488130416Smlaier#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
489130416Smlaier#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
490130416Smlaier#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
491130416Smlaier#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
492130416Smlaier#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
493130416Smlaier#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
494130416Smlaier
495148886Srwatson/*
496148886Srwatson * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
497148886Srwatson * the handoff logic, as that flag is locked by the device driver.
498148886Srwatson */
499130416Smlaier#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
500130416Smlaierdo {									\
501130416Smlaier	int len;							\
502130416Smlaier	short mflags;							\
503130416Smlaier									\
504130416Smlaier	len = (m)->m_pkthdr.len;					\
505130416Smlaier	mflags = (m)->m_flags;						\
506130416Smlaier	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
507130416Smlaier	if ((err) == 0) {						\
508130416Smlaier		(ifp)->if_obytes += len + (adj);			\
509130416Smlaier		if (mflags & M_MCAST)					\
510130416Smlaier			(ifp)->if_omcasts++;				\
511148886Srwatson		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
512132712Srwatson			if_start(ifp);					\
513130416Smlaier	}								\
514130416Smlaier} while (0)
515130416Smlaier
516130416Smlaier#define	IFQ_HANDOFF(ifp, m, err)					\
517130512Smlaier	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
518130416Smlaier
519130416Smlaier#define	IFQ_DRV_DEQUEUE(ifq, m)						\
520130416Smlaierdo {									\
521130416Smlaier	(m) = (ifq)->ifq_drv_head;					\
522130416Smlaier	if (m) {							\
523130416Smlaier		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
524130416Smlaier			(ifq)->ifq_drv_tail = NULL;			\
525130416Smlaier		(m)->m_nextpkt = NULL;					\
526130416Smlaier		(ifq)->ifq_drv_len--;					\
527130416Smlaier	} else {							\
528130416Smlaier		IFQ_LOCK(ifq);						\
529130416Smlaier		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
530130416Smlaier		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
531130416Smlaier			struct mbuf *m0;				\
532130416Smlaier			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
533130416Smlaier			if (m0 == NULL)					\
534130416Smlaier				break;					\
535130416Smlaier			m0->m_nextpkt = NULL;				\
536130416Smlaier			if ((ifq)->ifq_drv_tail == NULL)		\
537130416Smlaier				(ifq)->ifq_drv_head = m0;		\
538130416Smlaier			else						\
539130416Smlaier				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
540130416Smlaier			(ifq)->ifq_drv_tail = m0;			\
541130416Smlaier			(ifq)->ifq_drv_len++;				\
542130416Smlaier		}							\
543130416Smlaier		IFQ_UNLOCK(ifq);					\
544130416Smlaier	}								\
545130416Smlaier} while (0)
546130416Smlaier
547130416Smlaier#define	IFQ_DRV_PREPEND(ifq, m)						\
548130416Smlaierdo {									\
549130416Smlaier	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
550132152Smlaier	if ((ifq)->ifq_drv_tail == NULL)				\
551132152Smlaier		(ifq)->ifq_drv_tail = (m);				\
552130416Smlaier	(ifq)->ifq_drv_head = (m);					\
553130416Smlaier	(ifq)->ifq_drv_len++;						\
554130416Smlaier} while (0)
555130416Smlaier
556130416Smlaier#define	IFQ_DRV_IS_EMPTY(ifq)						\
557130416Smlaier	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
558130416Smlaier
559130416Smlaier#define	IFQ_DRV_PURGE(ifq)						\
560130416Smlaierdo {									\
561132152Smlaier	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
562132152Smlaier	while((m = n) != NULL) {					\
563132152Smlaier		n = m->m_nextpkt;					\
564130416Smlaier		m_freem(m);						\
565130416Smlaier	}								\
566130416Smlaier	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
567130416Smlaier	(ifq)->ifq_drv_len = 0;						\
568130416Smlaier	IFQ_PURGE(ifq);							\
569130416Smlaier} while (0)
570130416Smlaier
571186207Skmacy#ifdef _KERNEL
572186213Skmacystatic __inline void
573186213Skmacydrbr_stats_update(struct ifnet *ifp, int len, int mflags)
574186213Skmacy{
575193848Skmacy#ifndef NO_SLOW_STATS
576186213Skmacy	ifp->if_obytes += len;
577186213Skmacy	if (mflags & M_MCAST)
578186213Skmacy		ifp->if_omcasts++;
579193848Skmacy#endif
580186213Skmacy}
581186213Skmacy
582186207Skmacystatic __inline int
583186213Skmacydrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
584186207Skmacy{
585186207Skmacy	int error = 0;
586186213Skmacy	int len = m->m_pkthdr.len;
587186213Skmacy	int mflags = m->m_flags;
588186207Skmacy
589191033Skmacy#ifdef ALTQ
590191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
591191033Skmacy		IFQ_ENQUEUE(&ifp->if_snd, m, error);
592191033Skmacy		return (error);
593191033Skmacy	}
594191033Skmacy#endif
595193848Skmacy	if ((error = buf_ring_enqueue_bytes(br, m, len)) == ENOBUFS) {
596186207Skmacy		br->br_drops++;
597186207Skmacy		m_freem(m);
598186213Skmacy	} else
599186213Skmacy		drbr_stats_update(ifp, len, mflags);
600186213Skmacy
601186207Skmacy	return (error);
602186207Skmacy}
603186207Skmacy
604186207Skmacystatic __inline void
605194518Skmacydrbr_flush(struct ifnet *ifp, struct buf_ring *br)
606186207Skmacy{
607186207Skmacy	struct mbuf *m;
608186207Skmacy
609194518Skmacy#ifdef ALTQ
610203834Smlaier	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
611203834Smlaier		IFQ_PURGE(&ifp->if_snd);
612194518Skmacy#endif
613186207Skmacy	while ((m = buf_ring_dequeue_sc(br)) != NULL)
614186207Skmacy		m_freem(m);
615194518Skmacy}
616186207Skmacy
617194518Skmacystatic __inline void
618194518Skmacydrbr_free(struct buf_ring *br, struct malloc_type *type)
619194518Skmacy{
620194518Skmacy
621194518Skmacy	drbr_flush(NULL, br);
622186207Skmacy	buf_ring_free(br, type);
623186207Skmacy}
624191033Skmacy
625191033Skmacystatic __inline struct mbuf *
626191033Skmacydrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
627191033Skmacy{
628191033Skmacy#ifdef ALTQ
629191033Skmacy	struct mbuf *m;
630191033Skmacy
631191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
632203834Smlaier		IFQ_DEQUEUE(&ifp->if_snd, m);
633191033Skmacy		return (m);
634191033Skmacy	}
635186207Skmacy#endif
636191033Skmacy	return (buf_ring_dequeue_sc(br));
637191033Skmacy}
638186207Skmacy
639193848Skmacystatic __inline struct mbuf *
640193848Skmacydrbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
641193848Skmacy    int (*func) (struct mbuf *, void *), void *arg)
642193848Skmacy{
643193848Skmacy	struct mbuf *m;
644193848Skmacy#ifdef ALTQ
645203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
646203834Smlaier		IFQ_LOCK(&ifp->if_snd);
647203834Smlaier		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
648203834Smlaier		if (m != NULL && func(m, arg) == 0) {
649203834Smlaier			IFQ_UNLOCK(&ifp->if_snd);
650203834Smlaier			return (NULL);
651203834Smlaier		}
652205197Smlaier		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
653203834Smlaier		IFQ_UNLOCK(&ifp->if_snd);
654193848Skmacy		return (m);
655193848Skmacy	}
656193848Skmacy#endif
657193848Skmacy	m = buf_ring_peek(br);
658193848Skmacy	if (m == NULL || func(m, arg) == 0)
659193848Skmacy		return (NULL);
660193848Skmacy
661193848Skmacy	return (buf_ring_dequeue_sc(br));
662193848Skmacy}
663193848Skmacy
664191033Skmacystatic __inline int
665191033Skmacydrbr_empty(struct ifnet *ifp, struct buf_ring *br)
666191033Skmacy{
667191033Skmacy#ifdef ALTQ
668191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
669203834Smlaier		return (IFQ_IS_EMPTY(&ifp->if_snd));
670191033Skmacy#endif
671191033Skmacy	return (buf_ring_empty(br));
672191033Skmacy}
673193848Skmacy
674193848Skmacystatic __inline int
675203834Smlaierdrbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
676203834Smlaier{
677203834Smlaier#ifdef ALTQ
678203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd))
679203834Smlaier		return (1);
680203834Smlaier#endif
681203834Smlaier	return (!buf_ring_empty(br));
682203834Smlaier}
683203834Smlaier
684203834Smlaierstatic __inline int
685193848Skmacydrbr_inuse(struct ifnet *ifp, struct buf_ring *br)
686193848Skmacy{
687193848Skmacy#ifdef ALTQ
688193848Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
689193848Skmacy		return (ifp->if_snd.ifq_len);
690191033Skmacy#endif
691193848Skmacy	return (buf_ring_count(br));
692193848Skmacy}
693193848Skmacy#endif
69449459Sbrian/*
69549459Sbrian * 72 was chosen below because it is the size of a TCP/IP
69649459Sbrian * header (40) + the minimum mss (32).
69749459Sbrian */
69849459Sbrian#define	IF_MINMTU	72
69949459Sbrian#define	IF_MAXMTU	65535
70049459Sbrian
70155205Speter#endif /* _KERNEL */
70221259Swollman
70321259Swollman/*
70421259Swollman * The ifaddr structure contains information about one address
70521259Swollman * of an interface.  They are maintained by the different address families,
70621259Swollman * are allocated and attached when an address is set, and are linked
70721259Swollman * together so all addresses for an interface can be located.
708128291Sluigi *
709128291Sluigi * NOTE: a 'struct ifaddr' is always at the beginning of a larger
710128291Sluigi * chunk of malloc'ed memory, where we store the three addresses
711128291Sluigi * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
71221259Swollman */
71321259Swollmanstruct ifaddr {
71421259Swollman	struct	sockaddr *ifa_addr;	/* address of interface */
71521259Swollman	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
71621259Swollman#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
71721259Swollman	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
71867334Sjoe	struct	if_data if_data;	/* not all members are meaningful */
71921259Swollman	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
72060938Sjake	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
72121259Swollman	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
72292725Salfred		(int, struct rtentry *, struct rt_addrinfo *);
72321259Swollman	u_short	ifa_flags;		/* mostly rt_flags for cloning */
72447254Spb	u_int	ifa_refcnt;		/* references to this structure */
72521259Swollman	int	ifa_metric;		/* cost of going out this interface */
72628845Sjulian	int (*ifa_claim_addr)		/* check if an addr goes to this if */
72792725Salfred		(struct ifaddr *, struct sockaddr *);
728108033Shsu	struct mtx ifa_mtx;
72921259Swollman};
73021259Swollman#define	IFA_ROUTE	RTF_UP		/* route installed */
731201282Sqingli#define IFA_RTSELF	RTF_HOST	/* loopback route to self installed */
73221259Swollman
73353541Sshin/* for compatibility with other BSDs */
73453541Sshin#define	ifa_list	ifa_link
73553541Sshin
736194602Srwatson#ifdef _KERNEL
737108033Shsu#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
738108033Shsu#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
739108033Shsu
740194602Srwatsonvoid	ifa_free(struct ifaddr *ifa);
741194602Srwatsonvoid	ifa_init(struct ifaddr *ifa);
742194602Srwatsonvoid	ifa_ref(struct ifaddr *ifa);
743194602Srwatson#endif
744194602Srwatson
74521404Swollman/*
74652904Sshin * The prefix structure contains information about one prefix
74752904Sshin * of an interface.  They are maintained by the different address families,
748108470Sschweikh * are allocated and attached when a prefix or an address is set,
74953541Sshin * and are linked together so all prefixes for an interface can be located.
75052904Sshin */
75152904Sshinstruct ifprefix {
75252904Sshin	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
75352904Sshin	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
75460938Sjake	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
75552904Sshin	u_char	ifpr_plen;		/* prefix length in bits */
75652904Sshin	u_char	ifpr_type;		/* protocol dependent prefix type */
75752904Sshin};
75852904Sshin
75952904Sshin/*
76021404Swollman * Multicast address structure.  This is analogous to the ifaddr
76121404Swollman * structure except that it keeps track of multicast addresses.
76221404Swollman */
76321404Swollmanstruct ifmultiaddr {
76472084Sphk	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
76521434Swollman	struct	sockaddr *ifma_addr; 	/* address this membership is for */
76621434Swollman	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
76721434Swollman	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
76821434Swollman	u_int	ifma_refcount;		/* reference count */
76921434Swollman	void	*ifma_protospec;	/* protocol-specific state, if any */
770167729Sbms	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
77121404Swollman};
77221404Swollman
77355205Speter#ifdef _KERNEL
77421259Swollman
775196481Srwatsonextern	struct rwlock ifnet_rwlock;
776196481Srwatsonextern	struct sx ifnet_sxlock;
777108172Shsu
778196481Srwatson#define	IFNET_LOCK_INIT() do {						\
779196481Srwatson	rw_init_flags(&ifnet_rwlock, "ifnet_rw",  RW_RECURSE);		\
780196481Srwatson	sx_init_flags(&ifnet_sxlock, "ifnet_sx",  SX_RECURSE);		\
781196481Srwatson} while(0)
782196481Srwatson
783196481Srwatson#define	IFNET_WLOCK() do {						\
784196481Srwatson	sx_xlock(&ifnet_sxlock);					\
785196481Srwatson	rw_wlock(&ifnet_rwlock);					\
786196481Srwatson} while (0)
787196481Srwatson
788196481Srwatson#define	IFNET_WUNLOCK() do {						\
789196481Srwatson	rw_wunlock(&ifnet_rwlock);					\
790196481Srwatson	sx_xunlock(&ifnet_sxlock);					\
791196481Srwatson} while (0)
792196481Srwatson
793191367Srwatson/*
794196481Srwatson * To assert the ifnet lock, you must know not only whether it's for read or
795196481Srwatson * write, but also whether it was acquired with sleep support or not.
796196481Srwatson */
797196481Srwatson#define	IFNET_RLOCK_ASSERT()		sx_assert(&ifnet_sxlock, SA_SLOCKED)
798196481Srwatson#define	IFNET_RLOCK_NOSLEEP_ASSERT()	rw_assert(&ifnet_rwlock, RA_RLOCKED)
799196481Srwatson#define	IFNET_WLOCK_ASSERT() do {					\
800196481Srwatson	sx_assert(&ifnet_sxlock, SA_XLOCKED);				\
801196481Srwatson	rw_assert(&ifnet_rwlock, RA_WLOCKED);				\
802196481Srwatson} while (0)
803196481Srwatson
804196481Srwatson#define	IFNET_RLOCK()		sx_slock(&ifnet_sxlock)
805196481Srwatson#define	IFNET_RLOCK_NOSLEEP()	rw_rlock(&ifnet_rwlock)
806196481Srwatson#define	IFNET_RUNLOCK()		sx_sunlock(&ifnet_sxlock)
807196481Srwatson#define	IFNET_RUNLOCK_NOSLEEP()	rw_runlock(&ifnet_rwlock)
808196481Srwatson
809196481Srwatson/*
810191367Srwatson * Look up an ifnet given its index; the _ref variant also acquires a
811191367Srwatson * reference that must be freed using if_rele().  It is almost always a bug
812191367Srwatson * to call ifnet_byindex() instead if ifnet_byindex_ref().
813191367Srwatson */
814180042Srwatsonstruct ifnet	*ifnet_byindex(u_short idx);
815191816Szecstruct ifnet	*ifnet_byindex_locked(u_short idx);
816191367Srwatsonstruct ifnet	*ifnet_byindex_ref(u_short idx);
817181892Skmacy
818128315Sluigi/*
819128315Sluigi * Given the index, ifaddr_byindex() returns the one and only
820128315Sluigi * link-level ifaddr for the interface. You are not supposed to use
821128315Sluigi * it to traverse the list of addresses associated to the interface.
822128315Sluigi */
823180042Srwatsonstruct ifaddr	*ifaddr_byindex(u_short idx);
82483130Sjlemon
825195699SrwatsonVNET_DECLARE(struct ifnethead, ifnet);
826195699SrwatsonVNET_DECLARE(struct ifgrouphead, ifg_head);
827195699SrwatsonVNET_DECLARE(int, if_index);
828195699SrwatsonVNET_DECLARE(struct ifnet *, loif);	/* first loopback interface */
829195914SqingliVNET_DECLARE(int, useloopback);
830195699Srwatson
831195727Srwatson#define	V_ifnet		VNET(ifnet)
832195727Srwatson#define	V_ifg_head	VNET(ifg_head)
833195727Srwatson#define	V_if_index	VNET(if_index)
834195727Srwatson#define	V_loif		VNET(loif)
835195914Sqingli#define	V_useloopback	VNET(useloopback)
836195699Srwatson
837186048Sbzextern	int ifqmaxlen;
83821259Swollman
839159781Smlaierint	if_addgroup(struct ifnet *, const char *);
840159781Smlaierint	if_delgroup(struct ifnet *, const char *);
84192725Salfredint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
84292725Salfredint	if_allmulti(struct ifnet *, int);
843147256Sbrooksstruct	ifnet* if_alloc(u_char);
84492725Salfredvoid	if_attach(struct ifnet *);
845191418Srwatsonvoid	if_dead(struct ifnet *);
84692725Salfredint	if_delmulti(struct ifnet *, struct sockaddr *);
847167729Sbmsvoid	if_delmulti_ifma(struct ifmultiaddr *);
84892725Salfredvoid	if_detach(struct ifnet *);
849192605Szecvoid	if_vmove(struct ifnet *, struct vnet *);
850146620Speadarvoid	if_purgeaddrs(struct ifnet *);
851202935Ssyrinxvoid	if_delallmulti(struct ifnet *);
85292725Salfredvoid	if_down(struct ifnet *);
853167732Sbmsstruct ifmultiaddr *
854167732Sbms	if_findmulti(struct ifnet *, struct sockaddr *);
855147256Sbrooksvoid	if_free(struct ifnet *);
856147256Sbrooksvoid	if_free_type(struct ifnet *, u_char);
857121816Sbrooksvoid	if_initname(struct ifnet *, const char *, int);
858138542Ssamvoid	if_link_state_change(struct ifnet *, int);
859103900Sbrooksint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
860191161Skmacyvoid	if_qflush(struct ifnet *);
861191367Srwatsonvoid	if_ref(struct ifnet *);
862191367Srwatsonvoid	if_rele(struct ifnet *);
86392725Salfredint	if_setlladdr(struct ifnet *, const u_char *, int);
86492725Salfredvoid	if_up(struct ifnet *);
86592725Salfredint	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
86692725Salfredint	ifpromisc(struct ifnet *, int);
86792725Salfredstruct	ifnet *ifunit(const char *);
868191423Srwatsonstruct	ifnet *ifunit_ref(const char *);
86921259Swollman
870194259Ssamvoid	ifq_init(struct ifaltq *, struct ifnet *ifp);
871194259Ssamvoid	ifq_delete(struct ifaltq *);
872185162Skmacy
873197227Sqingliint	ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
874197227Sqingliint	ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
875197227Sqingli
87692725Salfredstruct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
877194622Srwatsonint		ifa_ifwithaddr_check(struct sockaddr *);
878162068Sandrestruct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
87992725Salfredstruct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
880208553Sqinglistruct	ifaddr *ifa_ifwithnet(struct sockaddr *, int);
88192725Salfredstruct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
882178888Sjulianstruct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
883178888Sjulian
88492725Salfredstruct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
88521259Swollman
88692725Salfredint	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
88721434Swollman
888147256Sbrookstypedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
889147256Sbrookstypedef	void if_com_free_t(void *com, u_char type);
890147256Sbrooksvoid	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
891147256Sbrooksvoid	if_deregister_com_alloc(u_char type);
892147256Sbrooks
89384931Sfjoe#define IF_LLADDR(ifp)							\
894152315Sru    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
89584931Sfjoe
89687902Sluigi#ifdef DEVICE_POLLING
897150789Sglebiusenum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
89887902Sluigi
899193096Sattiliotypedef	int poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
90092725Salfredint    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
90192725Salfredint    ether_poll_deregister(struct ifnet *ifp);
90287902Sluigi#endif /* DEVICE_POLLING */
90387902Sluigi
90455205Speter#endif /* _KERNEL */
90521259Swollman
90621259Swollman#endif /* !_NET_IF_VAR_H_ */
907