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$
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];
208252781Sandre	u_int	if_hw_tsomax;		/* tso burst length limit, the minmum
209252781Sandre					 * is (IP_MAXPACKET / 8).
210252781Sandre					 * XXXAO: Have to find a better place
211252781Sandre					 * for it eventually. */
212252781Sandre	int	if_ispare[3];
213224151Sbz	void	*if_pspare[8];		/* 1 netmap, 7 TDB */
21421259Swollman};
21569152Sjlemon
21692725Salfredtypedef void if_init_f_t(void *);
21721259Swollman
218128376Sluigi/*
219128376Sluigi * XXX These aliases are terribly dangerous because they could apply
220128376Sluigi * to anything.
221128376Sluigi */
22221259Swollman#define	if_mtu		if_data.ifi_mtu
22321259Swollman#define	if_type		if_data.ifi_type
22421259Swollman#define if_physical	if_data.ifi_physical
22521259Swollman#define	if_addrlen	if_data.ifi_addrlen
22621259Swollman#define	if_hdrlen	if_data.ifi_hdrlen
22721259Swollman#define	if_metric	if_data.ifi_metric
228128871Sandre#define	if_link_state	if_data.ifi_link_state
22921259Swollman#define	if_baudrate	if_data.ifi_baudrate
23058698Sjlemon#define	if_hwassist	if_data.ifi_hwassist
23121259Swollman#define	if_ipackets	if_data.ifi_ipackets
23221259Swollman#define	if_ierrors	if_data.ifi_ierrors
23321259Swollman#define	if_opackets	if_data.ifi_opackets
23421259Swollman#define	if_oerrors	if_data.ifi_oerrors
23521259Swollman#define	if_collisions	if_data.ifi_collisions
23621259Swollman#define	if_ibytes	if_data.ifi_ibytes
23721259Swollman#define	if_obytes	if_data.ifi_obytes
23821259Swollman#define	if_imcasts	if_data.ifi_imcasts
23921259Swollman#define	if_omcasts	if_data.ifi_omcasts
24021259Swollman#define	if_iqdrops	if_data.ifi_iqdrops
24121259Swollman#define	if_noproto	if_data.ifi_noproto
24221259Swollman#define	if_lastchange	if_data.ifi_lastchange
24321259Swollman
24453541Sshin/* for compatibility with other BSDs */
24553541Sshin#define	if_addrlist	if_addrhead
24653541Sshin#define	if_list		if_link
247160981Sbrooks#define	if_name(ifp)	((ifp)->if_xname)
24853541Sshin
24921259Swollman/*
250148640Srwatson * Locks for address lists on the network interface.
251148640Srwatson */
252148640Srwatson#define	IF_ADDR_LOCK_INIT(if)	mtx_init(&(if)->if_addr_mtx,		\
253148640Srwatson				    "if_addr_mtx", NULL, MTX_DEF)
254148640Srwatson#define	IF_ADDR_LOCK_DESTROY(if)	mtx_destroy(&(if)->if_addr_mtx)
255231157Sjhb#define	IF_ADDR_WLOCK(if)	mtx_lock(&(if)->if_addr_mtx)
256231157Sjhb#define	IF_ADDR_WUNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
257231157Sjhb#define	IF_ADDR_RLOCK(if)	mtx_lock(&(if)->if_addr_mtx)
258231157Sjhb#define	IF_ADDR_RUNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
259148640Srwatson#define	IF_ADDR_LOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
260231157Sjhb#define	IF_ADDR_WLOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
261231157Sjhb/* XXX: Compat. */
262231157Sjhb#define	IF_ADDR_LOCK(if)	IF_ADDR_WLOCK(if)
263231157Sjhb#define	IF_ADDR_UNLOCK(if)	IF_ADDR_WUNLOCK(if)
264148640Srwatson
265148640Srwatson/*
266195020Srwatson * Function variations on locking macros intended to be used by loadable
267195020Srwatson * kernel modules in order to divorce them from the internals of address list
268195020Srwatson * locking.
269195020Srwatson */
270195020Srwatsonvoid	if_addr_rlock(struct ifnet *ifp);	/* if_addrhead */
271195020Srwatsonvoid	if_addr_runlock(struct ifnet *ifp);	/* if_addrhead */
272195020Srwatsonvoid	if_maddr_rlock(struct ifnet *ifp);	/* if_multiaddrs */
273195020Srwatsonvoid	if_maddr_runlock(struct ifnet *ifp);	/* if_multiaddrs */
274195020Srwatson
275195020Srwatson/*
27621259Swollman * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
27721259Swollman * are queues of messages stored on ifqueue structures
27821259Swollman * (defined above).  Entries are added to and deleted from these structures
27921259Swollman * by these macros, which should be called with ipl raised to splimp().
28021259Swollman */
28172200Sbmilekic#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
28272200Sbmilekic#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
283130416Smlaier#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
28469152Sjlemon#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
28569152Sjlemon#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
28669152Sjlemon#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
28721259Swollman
28869152Sjlemon#define	_IF_ENQUEUE(ifq, m) do { 				\
28969152Sjlemon	(m)->m_nextpkt = NULL;					\
29069152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
29169152Sjlemon		(ifq)->ifq_head = m; 				\
29269152Sjlemon	else 							\
29369152Sjlemon		(ifq)->ifq_tail->m_nextpkt = m; 		\
29469152Sjlemon	(ifq)->ifq_tail = m; 					\
29569152Sjlemon	(ifq)->ifq_len++; 					\
29669152Sjlemon} while (0)
29769152Sjlemon
29869152Sjlemon#define IF_ENQUEUE(ifq, m) do {					\
29969152Sjlemon	IF_LOCK(ifq); 						\
30069152Sjlemon	_IF_ENQUEUE(ifq, m); 					\
30169152Sjlemon	IF_UNLOCK(ifq); 					\
30269152Sjlemon} while (0)
30369152Sjlemon
30469152Sjlemon#define	_IF_PREPEND(ifq, m) do {				\
30569152Sjlemon	(m)->m_nextpkt = (ifq)->ifq_head; 			\
30669152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
30769152Sjlemon		(ifq)->ifq_tail = (m); 				\
30869152Sjlemon	(ifq)->ifq_head = (m); 					\
30969152Sjlemon	(ifq)->ifq_len++; 					\
31069152Sjlemon} while (0)
31169152Sjlemon
31269152Sjlemon#define IF_PREPEND(ifq, m) do {		 			\
31369152Sjlemon	IF_LOCK(ifq); 						\
31469152Sjlemon	_IF_PREPEND(ifq, m); 					\
31569152Sjlemon	IF_UNLOCK(ifq); 					\
31669152Sjlemon} while (0)
31769152Sjlemon
31869152Sjlemon#define	_IF_DEQUEUE(ifq, m) do { 				\
31969152Sjlemon	(m) = (ifq)->ifq_head; 					\
32069152Sjlemon	if (m) { 						\
321136950Sjmg		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
32269152Sjlemon			(ifq)->ifq_tail = NULL; 		\
32369152Sjlemon		(m)->m_nextpkt = NULL; 				\
32469152Sjlemon		(ifq)->ifq_len--; 				\
32569152Sjlemon	} 							\
32669152Sjlemon} while (0)
32769152Sjlemon
32869152Sjlemon#define IF_DEQUEUE(ifq, m) do { 				\
32969152Sjlemon	IF_LOCK(ifq); 						\
33069152Sjlemon	_IF_DEQUEUE(ifq, m); 					\
33169152Sjlemon	IF_UNLOCK(ifq); 					\
33269152Sjlemon} while (0)
33369152Sjlemon
334229690Sglebius#define	_IF_DEQUEUE_ALL(ifq, m) do {				\
335229690Sglebius	(m) = (ifq)->ifq_head;					\
336229690Sglebius	(ifq)->ifq_head = (ifq)->ifq_tail = NULL;		\
337229690Sglebius	(ifq)->ifq_len = 0;					\
338229690Sglebius} while (0)
339229690Sglebius
340229690Sglebius#define	IF_DEQUEUE_ALL(ifq, m) do {				\
341229690Sglebius	IF_LOCK(ifq); 						\
342229690Sglebius	_IF_DEQUEUE_ALL(ifq, m);				\
343229690Sglebius	IF_UNLOCK(ifq); 					\
344229690Sglebius} while (0)
345229690Sglebius
346130416Smlaier#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
347130416Smlaier#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
348130416Smlaier
349130416Smlaier#define _IF_DRAIN(ifq) do { 					\
35069152Sjlemon	struct mbuf *m; 					\
35169152Sjlemon	for (;;) { 						\
35269152Sjlemon		_IF_DEQUEUE(ifq, m); 				\
35369152Sjlemon		if (m == NULL) 					\
35469152Sjlemon			break; 					\
35569152Sjlemon		m_freem(m); 					\
35669152Sjlemon	} 							\
35769152Sjlemon} while (0)
35869152Sjlemon
359130416Smlaier#define IF_DRAIN(ifq) do {					\
360130416Smlaier	IF_LOCK(ifq);						\
361130416Smlaier	_IF_DRAIN(ifq);						\
362130416Smlaier	IF_UNLOCK(ifq);						\
363130416Smlaier} while(0)
364130416Smlaier
36555205Speter#ifdef _KERNEL
366202588Sthompsa/* interface link layer address change event */
367202588Sthompsatypedef void (*iflladdr_event_handler_t)(void *, struct ifnet *);
368202588SthompsaEVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t);
369126264Smlaier/* interface address change event */
370126264Smlaiertypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
371126264SmlaierEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
372126264Smlaier/* new interface arrival event */
373126264Smlaiertypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
374126264SmlaierEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
375126264Smlaier/* interface departure event */
376126264Smlaiertypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
377126264SmlaierEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
378219819Sjeff/* Interface link state change event */
379219819Sjefftypedef void (*ifnet_link_event_handler_t)(void *, struct ifnet *, int);
380219819SjeffEVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t);
381126264Smlaier
382159781Smlaier/*
383159781Smlaier * interface groups
384159781Smlaier */
385159781Smlaierstruct ifg_group {
386159781Smlaier	char				 ifg_group[IFNAMSIZ];
387159781Smlaier	u_int				 ifg_refcnt;
388159781Smlaier	void				*ifg_pf_kif;
389159781Smlaier	TAILQ_HEAD(, ifg_member)	 ifg_members;
390159781Smlaier	TAILQ_ENTRY(ifg_group)		 ifg_next;
391159781Smlaier};
392159781Smlaier
393159781Smlaierstruct ifg_member {
394159781Smlaier	TAILQ_ENTRY(ifg_member)	 ifgm_next;
395159781Smlaier	struct ifnet		*ifgm_ifp;
396159781Smlaier};
397159781Smlaier
398159781Smlaierstruct ifg_list {
399159781Smlaier	struct ifg_group	*ifgl_group;
400159781Smlaier	TAILQ_ENTRY(ifg_list)	 ifgl_next;
401159781Smlaier};
402159781Smlaier
403159781Smlaier/* group attach event */
404159781Smlaiertypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
405159781SmlaierEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
406159781Smlaier/* group detach event */
407159781Smlaiertypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
408159781SmlaierEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
409159781Smlaier/* group change event */
410159781Smlaiertypedef void (*group_change_event_handler_t)(void *, const char *);
411159781SmlaierEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
412159781Smlaier
413121470Sume#define	IF_AFDATA_LOCK_INIT(ifp)	\
414186199Skmacy	rw_init(&(ifp)->if_afdata_lock, "if_afdata")
415121470Sume
416186199Skmacy#define	IF_AFDATA_WLOCK(ifp)	rw_wlock(&(ifp)->if_afdata_lock)
417186199Skmacy#define	IF_AFDATA_RLOCK(ifp)	rw_rlock(&(ifp)->if_afdata_lock)
418186199Skmacy#define	IF_AFDATA_WUNLOCK(ifp)	rw_wunlock(&(ifp)->if_afdata_lock)
419186199Skmacy#define	IF_AFDATA_RUNLOCK(ifp)	rw_runlock(&(ifp)->if_afdata_lock)
420186199Skmacy#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
421186199Skmacy#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
422186199Skmacy#define	IF_AFDATA_TRYLOCK(ifp)	rw_try_wlock(&(ifp)->if_afdata_lock)
423186199Skmacy#define	IF_AFDATA_DESTROY(ifp)	rw_destroy(&(ifp)->if_afdata_lock)
424186119Sqingli
425186199Skmacy#define	IF_AFDATA_LOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
426240313Sglebius#define	IF_AFDATA_RLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_RLOCKED)
427240313Sglebius#define	IF_AFDATA_WLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_WLOCKED)
428186199Skmacy#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
429186199Skmacy
430137065Srwatsonint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
431137065Srwatson	    int adjust);
432130416Smlaier#define	IF_HANDOFF(ifq, m, ifp)			\
433130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
434130416Smlaier#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
435130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
43621259Swollman
437132712Srwatsonvoid	if_start(struct ifnet *);
438132712Srwatson
439130416Smlaier#define	IFQ_ENQUEUE(ifq, m, err)					\
440130416Smlaierdo {									\
441130416Smlaier	IF_LOCK(ifq);							\
442130416Smlaier	if (ALTQ_IS_ENABLED(ifq))					\
443130416Smlaier		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
444130416Smlaier	else {								\
445130416Smlaier		if (_IF_QFULL(ifq)) {					\
446130416Smlaier			m_freem(m);					\
447130416Smlaier			(err) = ENOBUFS;				\
448130416Smlaier		} else {						\
449130416Smlaier			_IF_ENQUEUE(ifq, m);				\
450130416Smlaier			(err) = 0;					\
451130416Smlaier		}							\
452130416Smlaier	}								\
453130416Smlaier	if (err)							\
454130416Smlaier		(ifq)->ifq_drops++;					\
455130416Smlaier	IF_UNLOCK(ifq);							\
456130416Smlaier} while (0)
45721259Swollman
458130416Smlaier#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
459130416Smlaierdo {									\
460130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
461130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
462130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
463130416Smlaier		ALTQ_DEQUEUE(ifq, m);					\
464130416Smlaier	else								\
465130416Smlaier		_IF_DEQUEUE(ifq, m);					\
466130416Smlaier} while (0)
467130416Smlaier
468130416Smlaier#define	IFQ_DEQUEUE(ifq, m)						\
469130416Smlaierdo {									\
470130416Smlaier	IF_LOCK(ifq);							\
471130416Smlaier	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
472130416Smlaier	IF_UNLOCK(ifq);							\
473130416Smlaier} while (0)
474130416Smlaier
475130416Smlaier#define	IFQ_POLL_NOLOCK(ifq, m)						\
476130416Smlaierdo {									\
477130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
478130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
479130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
480130416Smlaier		ALTQ_POLL(ifq, m);					\
481130416Smlaier	else								\
482130416Smlaier		_IF_POLL(ifq, m);					\
483130416Smlaier} while (0)
484130416Smlaier
485130416Smlaier#define	IFQ_POLL(ifq, m)						\
486130416Smlaierdo {									\
487130416Smlaier	IF_LOCK(ifq);							\
488130416Smlaier	IFQ_POLL_NOLOCK(ifq, m);					\
489130416Smlaier	IF_UNLOCK(ifq);							\
490130416Smlaier} while (0)
491130416Smlaier
492130416Smlaier#define	IFQ_PURGE_NOLOCK(ifq)						\
493130416Smlaierdo {									\
494130416Smlaier	if (ALTQ_IS_ENABLED(ifq)) {					\
495130416Smlaier		ALTQ_PURGE(ifq);					\
496130416Smlaier	} else								\
497130416Smlaier		_IF_DRAIN(ifq);						\
498130416Smlaier} while (0)
499130416Smlaier
500130416Smlaier#define	IFQ_PURGE(ifq)							\
501130416Smlaierdo {									\
502130416Smlaier	IF_LOCK(ifq);							\
503130416Smlaier	IFQ_PURGE_NOLOCK(ifq);						\
504130416Smlaier	IF_UNLOCK(ifq);							\
505130416Smlaier} while (0)
506130416Smlaier
507130416Smlaier#define	IFQ_SET_READY(ifq)						\
508130416Smlaier	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
509130416Smlaier
510130416Smlaier#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
511130416Smlaier#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
512130416Smlaier#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
513130416Smlaier#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
514130416Smlaier#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
515130416Smlaier#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
516130416Smlaier#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
517130416Smlaier#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
518130416Smlaier
519148886Srwatson/*
520148886Srwatson * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
521148886Srwatson * the handoff logic, as that flag is locked by the device driver.
522148886Srwatson */
523130416Smlaier#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
524130416Smlaierdo {									\
525130416Smlaier	int len;							\
526130416Smlaier	short mflags;							\
527130416Smlaier									\
528130416Smlaier	len = (m)->m_pkthdr.len;					\
529130416Smlaier	mflags = (m)->m_flags;						\
530130416Smlaier	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
531130416Smlaier	if ((err) == 0) {						\
532130416Smlaier		(ifp)->if_obytes += len + (adj);			\
533130416Smlaier		if (mflags & M_MCAST)					\
534130416Smlaier			(ifp)->if_omcasts++;				\
535148886Srwatson		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
536132712Srwatson			if_start(ifp);					\
537130416Smlaier	}								\
538130416Smlaier} while (0)
539130416Smlaier
540130416Smlaier#define	IFQ_HANDOFF(ifp, m, err)					\
541130512Smlaier	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
542130416Smlaier
543130416Smlaier#define	IFQ_DRV_DEQUEUE(ifq, m)						\
544130416Smlaierdo {									\
545130416Smlaier	(m) = (ifq)->ifq_drv_head;					\
546130416Smlaier	if (m) {							\
547130416Smlaier		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
548130416Smlaier			(ifq)->ifq_drv_tail = NULL;			\
549130416Smlaier		(m)->m_nextpkt = NULL;					\
550130416Smlaier		(ifq)->ifq_drv_len--;					\
551130416Smlaier	} else {							\
552130416Smlaier		IFQ_LOCK(ifq);						\
553130416Smlaier		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
554130416Smlaier		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
555130416Smlaier			struct mbuf *m0;				\
556130416Smlaier			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
557130416Smlaier			if (m0 == NULL)					\
558130416Smlaier				break;					\
559130416Smlaier			m0->m_nextpkt = NULL;				\
560130416Smlaier			if ((ifq)->ifq_drv_tail == NULL)		\
561130416Smlaier				(ifq)->ifq_drv_head = m0;		\
562130416Smlaier			else						\
563130416Smlaier				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
564130416Smlaier			(ifq)->ifq_drv_tail = m0;			\
565130416Smlaier			(ifq)->ifq_drv_len++;				\
566130416Smlaier		}							\
567130416Smlaier		IFQ_UNLOCK(ifq);					\
568130416Smlaier	}								\
569130416Smlaier} while (0)
570130416Smlaier
571130416Smlaier#define	IFQ_DRV_PREPEND(ifq, m)						\
572130416Smlaierdo {									\
573130416Smlaier	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
574132152Smlaier	if ((ifq)->ifq_drv_tail == NULL)				\
575132152Smlaier		(ifq)->ifq_drv_tail = (m);				\
576130416Smlaier	(ifq)->ifq_drv_head = (m);					\
577130416Smlaier	(ifq)->ifq_drv_len++;						\
578130416Smlaier} while (0)
579130416Smlaier
580130416Smlaier#define	IFQ_DRV_IS_EMPTY(ifq)						\
581130416Smlaier	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
582130416Smlaier
583130416Smlaier#define	IFQ_DRV_PURGE(ifq)						\
584130416Smlaierdo {									\
585132152Smlaier	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
586132152Smlaier	while((m = n) != NULL) {					\
587132152Smlaier		n = m->m_nextpkt;					\
588130416Smlaier		m_freem(m);						\
589130416Smlaier	}								\
590130416Smlaier	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
591130416Smlaier	(ifq)->ifq_drv_len = 0;						\
592130416Smlaier	IFQ_PURGE(ifq);							\
593130416Smlaier} while (0)
594130416Smlaier
595186207Skmacy#ifdef _KERNEL
596186207Skmacystatic __inline int
597186213Skmacydrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
598186207Skmacy{
599186207Skmacy	int error = 0;
600186207Skmacy
601191033Skmacy#ifdef ALTQ
602191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
603191033Skmacy		IFQ_ENQUEUE(&ifp->if_snd, m, error);
604191033Skmacy		return (error);
605191033Skmacy	}
606191033Skmacy#endif
607243440Sglebius	error = buf_ring_enqueue(br, m);
608243440Sglebius	if (error)
609186207Skmacy		m_freem(m);
610243440Sglebius
611186207Skmacy	return (error);
612186207Skmacy}
613186207Skmacy
614186207Skmacystatic __inline void
615248287Sjfvdrbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *new)
616248287Sjfv{
617248287Sjfv	/*
618248287Sjfv	 * The top of the list needs to be swapped
619248287Sjfv	 * for this one.
620248287Sjfv	 */
621248287Sjfv#ifdef ALTQ
622248287Sjfv	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
623248287Sjfv		/*
624248287Sjfv		 * Peek in altq case dequeued it
625248287Sjfv		 * so put it back.
626248287Sjfv		 */
627248287Sjfv		IFQ_DRV_PREPEND(&ifp->if_snd, new);
628248287Sjfv		return;
629248287Sjfv	}
630248287Sjfv#endif
631248287Sjfv	buf_ring_putback_sc(br, new);
632248287Sjfv}
633248287Sjfv
634248287Sjfvstatic __inline struct mbuf *
635248287Sjfvdrbr_peek(struct ifnet *ifp, struct buf_ring *br)
636248287Sjfv{
637248287Sjfv#ifdef ALTQ
638248287Sjfv	struct mbuf *m;
639248287Sjfv	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
640248287Sjfv		/*
641248287Sjfv		 * Pull it off like a dequeue
642248287Sjfv		 * since drbr_advance() does nothing
643248287Sjfv		 * for altq and drbr_putback() will
644248287Sjfv		 * use the old prepend function.
645248287Sjfv		 */
646248287Sjfv		IFQ_DEQUEUE(&ifp->if_snd, m);
647248287Sjfv		return (m);
648248287Sjfv	}
649248287Sjfv#endif
650248287Sjfv	return(buf_ring_peek(br));
651248287Sjfv}
652248287Sjfv
653248287Sjfvstatic __inline void
654194518Skmacydrbr_flush(struct ifnet *ifp, struct buf_ring *br)
655186207Skmacy{
656186207Skmacy	struct mbuf *m;
657186207Skmacy
658194518Skmacy#ifdef ALTQ
659203834Smlaier	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
660203834Smlaier		IFQ_PURGE(&ifp->if_snd);
661194518Skmacy#endif
662186207Skmacy	while ((m = buf_ring_dequeue_sc(br)) != NULL)
663186207Skmacy		m_freem(m);
664194518Skmacy}
665186207Skmacy
666194518Skmacystatic __inline void
667194518Skmacydrbr_free(struct buf_ring *br, struct malloc_type *type)
668194518Skmacy{
669194518Skmacy
670194518Skmacy	drbr_flush(NULL, br);
671186207Skmacy	buf_ring_free(br, type);
672186207Skmacy}
673191033Skmacy
674191033Skmacystatic __inline struct mbuf *
675191033Skmacydrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
676191033Skmacy{
677191033Skmacy#ifdef ALTQ
678191033Skmacy	struct mbuf *m;
679191033Skmacy
680248287Sjfv	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
681203834Smlaier		IFQ_DEQUEUE(&ifp->if_snd, m);
682191033Skmacy		return (m);
683191033Skmacy	}
684186207Skmacy#endif
685191033Skmacy	return (buf_ring_dequeue_sc(br));
686191033Skmacy}
687186207Skmacy
688248287Sjfvstatic __inline void
689248287Sjfvdrbr_advance(struct ifnet *ifp, struct buf_ring *br)
690248287Sjfv{
691248287Sjfv#ifdef ALTQ
692248287Sjfv	/* Nothing to do here since peek dequeues in altq case */
693248287Sjfv	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
694248287Sjfv		return;
695248287Sjfv#endif
696248287Sjfv	return (buf_ring_advance_sc(br));
697248287Sjfv}
698248287Sjfv
699248287Sjfv
700193848Skmacystatic __inline struct mbuf *
701193848Skmacydrbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
702193848Skmacy    int (*func) (struct mbuf *, void *), void *arg)
703193848Skmacy{
704193848Skmacy	struct mbuf *m;
705193848Skmacy#ifdef ALTQ
706203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
707203834Smlaier		IFQ_LOCK(&ifp->if_snd);
708203834Smlaier		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
709203834Smlaier		if (m != NULL && func(m, arg) == 0) {
710203834Smlaier			IFQ_UNLOCK(&ifp->if_snd);
711203834Smlaier			return (NULL);
712203834Smlaier		}
713205197Smlaier		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
714203834Smlaier		IFQ_UNLOCK(&ifp->if_snd);
715193848Skmacy		return (m);
716193848Skmacy	}
717193848Skmacy#endif
718193848Skmacy	m = buf_ring_peek(br);
719193848Skmacy	if (m == NULL || func(m, arg) == 0)
720193848Skmacy		return (NULL);
721193848Skmacy
722193848Skmacy	return (buf_ring_dequeue_sc(br));
723193848Skmacy}
724193848Skmacy
725191033Skmacystatic __inline int
726191033Skmacydrbr_empty(struct ifnet *ifp, struct buf_ring *br)
727191033Skmacy{
728191033Skmacy#ifdef ALTQ
729191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
730203834Smlaier		return (IFQ_IS_EMPTY(&ifp->if_snd));
731191033Skmacy#endif
732191033Skmacy	return (buf_ring_empty(br));
733191033Skmacy}
734193848Skmacy
735193848Skmacystatic __inline int
736203834Smlaierdrbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
737203834Smlaier{
738203834Smlaier#ifdef ALTQ
739203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd))
740203834Smlaier		return (1);
741203834Smlaier#endif
742203834Smlaier	return (!buf_ring_empty(br));
743203834Smlaier}
744203834Smlaier
745203834Smlaierstatic __inline int
746193848Skmacydrbr_inuse(struct ifnet *ifp, struct buf_ring *br)
747193848Skmacy{
748193848Skmacy#ifdef ALTQ
749193848Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
750193848Skmacy		return (ifp->if_snd.ifq_len);
751191033Skmacy#endif
752193848Skmacy	return (buf_ring_count(br));
753193848Skmacy}
754193848Skmacy#endif
75549459Sbrian/*
75649459Sbrian * 72 was chosen below because it is the size of a TCP/IP
75749459Sbrian * header (40) + the minimum mss (32).
75849459Sbrian */
75949459Sbrian#define	IF_MINMTU	72
76049459Sbrian#define	IF_MAXMTU	65535
76149459Sbrian
762252555Snp#define	TOEDEV(ifp)	((ifp)->if_llsoftc)
763252555Snp
76455205Speter#endif /* _KERNEL */
76521259Swollman
76621259Swollman/*
76721259Swollman * The ifaddr structure contains information about one address
76821259Swollman * of an interface.  They are maintained by the different address families,
76921259Swollman * are allocated and attached when an address is set, and are linked
77021259Swollman * together so all addresses for an interface can be located.
771128291Sluigi *
772128291Sluigi * NOTE: a 'struct ifaddr' is always at the beginning of a larger
773128291Sluigi * chunk of malloc'ed memory, where we store the three addresses
774128291Sluigi * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
77521259Swollman */
77621259Swollmanstruct ifaddr {
77721259Swollman	struct	sockaddr *ifa_addr;	/* address of interface */
77821259Swollman	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
77921259Swollman#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
78021259Swollman	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
78167334Sjoe	struct	if_data if_data;	/* not all members are meaningful */
78221259Swollman	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
78360938Sjake	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
78421259Swollman	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
78592725Salfred		(int, struct rtentry *, struct rt_addrinfo *);
78621259Swollman	u_short	ifa_flags;		/* mostly rt_flags for cloning */
78747254Spb	u_int	ifa_refcnt;		/* references to this structure */
78821259Swollman	int	ifa_metric;		/* cost of going out this interface */
78928845Sjulian	int (*ifa_claim_addr)		/* check if an addr goes to this if */
79092725Salfred		(struct ifaddr *, struct sockaddr *);
791108033Shsu	struct mtx ifa_mtx;
79221259Swollman};
79321259Swollman#define	IFA_ROUTE	RTF_UP		/* route installed */
794201282Sqingli#define IFA_RTSELF	RTF_HOST	/* loopback route to self installed */
79521259Swollman
79653541Sshin/* for compatibility with other BSDs */
79753541Sshin#define	ifa_list	ifa_link
79853541Sshin
799194602Srwatson#ifdef _KERNEL
800108033Shsu#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
801108033Shsu#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
802108033Shsu
803194602Srwatsonvoid	ifa_free(struct ifaddr *ifa);
804194602Srwatsonvoid	ifa_init(struct ifaddr *ifa);
805194602Srwatsonvoid	ifa_ref(struct ifaddr *ifa);
806194602Srwatson#endif
807194602Srwatson
80821404Swollman/*
80952904Sshin * The prefix structure contains information about one prefix
81052904Sshin * of an interface.  They are maintained by the different address families,
811108470Sschweikh * are allocated and attached when a prefix or an address is set,
81253541Sshin * and are linked together so all prefixes for an interface can be located.
81352904Sshin */
81452904Sshinstruct ifprefix {
81552904Sshin	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
81652904Sshin	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
81760938Sjake	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
81852904Sshin	u_char	ifpr_plen;		/* prefix length in bits */
81952904Sshin	u_char	ifpr_type;		/* protocol dependent prefix type */
82052904Sshin};
82152904Sshin
82252904Sshin/*
82321404Swollman * Multicast address structure.  This is analogous to the ifaddr
82421404Swollman * structure except that it keeps track of multicast addresses.
82521404Swollman */
82621404Swollmanstruct ifmultiaddr {
82772084Sphk	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
82821434Swollman	struct	sockaddr *ifma_addr; 	/* address this membership is for */
82921434Swollman	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
83021434Swollman	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
83121434Swollman	u_int	ifma_refcount;		/* reference count */
83221434Swollman	void	*ifma_protospec;	/* protocol-specific state, if any */
833167729Sbms	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
83421404Swollman};
83521404Swollman
83655205Speter#ifdef _KERNEL
83721259Swollman
838196481Srwatsonextern	struct rwlock ifnet_rwlock;
839196481Srwatsonextern	struct sx ifnet_sxlock;
840108172Shsu
841196481Srwatson#define	IFNET_LOCK_INIT() do {						\
842196481Srwatson	rw_init_flags(&ifnet_rwlock, "ifnet_rw",  RW_RECURSE);		\
843196481Srwatson	sx_init_flags(&ifnet_sxlock, "ifnet_sx",  SX_RECURSE);		\
844196481Srwatson} while(0)
845196481Srwatson
846196481Srwatson#define	IFNET_WLOCK() do {						\
847196481Srwatson	sx_xlock(&ifnet_sxlock);					\
848196481Srwatson	rw_wlock(&ifnet_rwlock);					\
849196481Srwatson} while (0)
850196481Srwatson
851196481Srwatson#define	IFNET_WUNLOCK() do {						\
852196481Srwatson	rw_wunlock(&ifnet_rwlock);					\
853196481Srwatson	sx_xunlock(&ifnet_sxlock);					\
854196481Srwatson} while (0)
855196481Srwatson
856191367Srwatson/*
857196481Srwatson * To assert the ifnet lock, you must know not only whether it's for read or
858196481Srwatson * write, but also whether it was acquired with sleep support or not.
859196481Srwatson */
860196481Srwatson#define	IFNET_RLOCK_ASSERT()		sx_assert(&ifnet_sxlock, SA_SLOCKED)
861196481Srwatson#define	IFNET_RLOCK_NOSLEEP_ASSERT()	rw_assert(&ifnet_rwlock, RA_RLOCKED)
862196481Srwatson#define	IFNET_WLOCK_ASSERT() do {					\
863196481Srwatson	sx_assert(&ifnet_sxlock, SA_XLOCKED);				\
864196481Srwatson	rw_assert(&ifnet_rwlock, RA_WLOCKED);				\
865196481Srwatson} while (0)
866196481Srwatson
867196481Srwatson#define	IFNET_RLOCK()		sx_slock(&ifnet_sxlock)
868196481Srwatson#define	IFNET_RLOCK_NOSLEEP()	rw_rlock(&ifnet_rwlock)
869196481Srwatson#define	IFNET_RUNLOCK()		sx_sunlock(&ifnet_sxlock)
870196481Srwatson#define	IFNET_RUNLOCK_NOSLEEP()	rw_runlock(&ifnet_rwlock)
871196481Srwatson
872196481Srwatson/*
873191367Srwatson * Look up an ifnet given its index; the _ref variant also acquires a
874191367Srwatson * reference that must be freed using if_rele().  It is almost always a bug
875191367Srwatson * to call ifnet_byindex() instead if ifnet_byindex_ref().
876191367Srwatson */
877180042Srwatsonstruct ifnet	*ifnet_byindex(u_short idx);
878191816Szecstruct ifnet	*ifnet_byindex_locked(u_short idx);
879191367Srwatsonstruct ifnet	*ifnet_byindex_ref(u_short idx);
880181892Skmacy
881128315Sluigi/*
882128315Sluigi * Given the index, ifaddr_byindex() returns the one and only
883128315Sluigi * link-level ifaddr for the interface. You are not supposed to use
884128315Sluigi * it to traverse the list of addresses associated to the interface.
885128315Sluigi */
886180042Srwatsonstruct ifaddr	*ifaddr_byindex(u_short idx);
88783130Sjlemon
888195699SrwatsonVNET_DECLARE(struct ifnethead, ifnet);
889195699SrwatsonVNET_DECLARE(struct ifgrouphead, ifg_head);
890195699SrwatsonVNET_DECLARE(int, if_index);
891195699SrwatsonVNET_DECLARE(struct ifnet *, loif);	/* first loopback interface */
892195914SqingliVNET_DECLARE(int, useloopback);
893195699Srwatson
894195727Srwatson#define	V_ifnet		VNET(ifnet)
895195727Srwatson#define	V_ifg_head	VNET(ifg_head)
896195727Srwatson#define	V_if_index	VNET(if_index)
897195727Srwatson#define	V_loif		VNET(loif)
898195914Sqingli#define	V_useloopback	VNET(useloopback)
899195699Srwatson
900186048Sbzextern	int ifqmaxlen;
90121259Swollman
902159781Smlaierint	if_addgroup(struct ifnet *, const char *);
903159781Smlaierint	if_delgroup(struct ifnet *, const char *);
90492725Salfredint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
90592725Salfredint	if_allmulti(struct ifnet *, int);
906147256Sbrooksstruct	ifnet* if_alloc(u_char);
90792725Salfredvoid	if_attach(struct ifnet *);
908191418Srwatsonvoid	if_dead(struct ifnet *);
90992725Salfredint	if_delmulti(struct ifnet *, struct sockaddr *);
910167729Sbmsvoid	if_delmulti_ifma(struct ifmultiaddr *);
91192725Salfredvoid	if_detach(struct ifnet *);
912192605Szecvoid	if_vmove(struct ifnet *, struct vnet *);
913146620Speadarvoid	if_purgeaddrs(struct ifnet *);
914202935Ssyrinxvoid	if_delallmulti(struct ifnet *);
91592725Salfredvoid	if_down(struct ifnet *);
916167732Sbmsstruct ifmultiaddr *
917167732Sbms	if_findmulti(struct ifnet *, struct sockaddr *);
918147256Sbrooksvoid	if_free(struct ifnet *);
919147256Sbrooksvoid	if_free_type(struct ifnet *, u_char);
920121816Sbrooksvoid	if_initname(struct ifnet *, const char *, int);
921138542Ssamvoid	if_link_state_change(struct ifnet *, int);
922103900Sbrooksint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
923191161Skmacyvoid	if_qflush(struct ifnet *);
924191367Srwatsonvoid	if_ref(struct ifnet *);
925191367Srwatsonvoid	if_rele(struct ifnet *);
92692725Salfredint	if_setlladdr(struct ifnet *, const u_char *, int);
92792725Salfredvoid	if_up(struct ifnet *);
92892725Salfredint	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
92992725Salfredint	ifpromisc(struct ifnet *, int);
93092725Salfredstruct	ifnet *ifunit(const char *);
931191423Srwatsonstruct	ifnet *ifunit_ref(const char *);
93221259Swollman
933194259Ssamvoid	ifq_init(struct ifaltq *, struct ifnet *ifp);
934194259Ssamvoid	ifq_delete(struct ifaltq *);
935185162Skmacy
936197227Sqingliint	ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
937197227Sqingliint	ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
938197227Sqingli
93992725Salfredstruct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
940194622Srwatsonint		ifa_ifwithaddr_check(struct sockaddr *);
941162068Sandrestruct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
94292725Salfredstruct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
943208553Sqinglistruct	ifaddr *ifa_ifwithnet(struct sockaddr *, int);
94492725Salfredstruct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
945178888Sjulianstruct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
946178888Sjulian
94792725Salfredstruct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
94821259Swollman
94992725Salfredint	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
95021434Swollman
951147256Sbrookstypedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
952147256Sbrookstypedef	void if_com_free_t(void *com, u_char type);
953147256Sbrooksvoid	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
954147256Sbrooksvoid	if_deregister_com_alloc(u_char type);
955147256Sbrooks
95684931Sfjoe#define IF_LLADDR(ifp)							\
957152315Sru    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
95884931Sfjoe
95987902Sluigi#ifdef DEVICE_POLLING
960150789Sglebiusenum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
96187902Sluigi
962193096Sattiliotypedef	int poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
96392725Salfredint    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
96492725Salfredint    ether_poll_deregister(struct ifnet *ifp);
96587902Sluigi#endif /* DEVICE_POLLING */
96687902Sluigi
96755205Speter#endif /* _KERNEL */
96821259Swollman
96921259Swollman#endif /* !_NET_IF_VAR_H_ */
970