ifq.h revision 195699
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 195699 2009-07-14 22:48:30Z rwatson $
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 */
8883130Sjlemon#include <sys/event.h>		/* XXX */
89132712Srwatson#include <sys/_task.h>
9069152Sjlemon
91121816Sbrooks#define	IF_DUNIT_NONE	-1
92121816Sbrooks
93130416Smlaier#include <altq/if_altq.h>
94130416Smlaier
9560938SjakeTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
9660938SjakeTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
9760938SjakeTAILQ_HEAD(ifprefixhead, ifprefix);
9872084SphkTAILQ_HEAD(ifmultihead, ifmultiaddr);
99159781SmlaierTAILQ_HEAD(ifgrouphead, ifg_group);
10021259Swollman
10121259Swollman/*
10221259Swollman * Structure defining a queue for a network interface.
10321259Swollman */
10421259Swollmanstruct	ifqueue {
10521259Swollman	struct	mbuf *ifq_head;
10621259Swollman	struct	mbuf *ifq_tail;
10721259Swollman	int	ifq_len;
10821259Swollman	int	ifq_maxlen;
10921259Swollman	int	ifq_drops;
11069152Sjlemon	struct	mtx ifq_mtx;
11121259Swollman};
11221259Swollman
11321259Swollman/*
11421259Swollman * Structure defining a network interface.
11521259Swollman *
11621259Swollman * (Would like to call this struct ``if'', but C isn't PL/1.)
11721259Swollman */
11884380Smjacob
11921259Swollmanstruct ifnet {
12021259Swollman	void	*if_softc;		/* pointer to driver state */
121147256Sbrooks	void	*if_l2com;		/* pointer to protocol bits */
122191688Szec	struct vnet *if_vnet;		/* pointer to network stack instance */
12360938Sjake	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
124121816Sbrooks	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
125121816Sbrooks	const char *if_dname;		/* driver name */
126121816Sbrooks	int	if_dunit;		/* unit or IF_DUNIT_NONE */
127191367Srwatson	u_int	if_refcount;		/* reference count */
12821259Swollman	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
129128291Sluigi		/*
130128291Sluigi		 * if_addrhead is the list of all addresses associated to
131128315Sluigi		 * an interface.
132128315Sluigi		 * Some code in the kernel assumes that first element
133128315Sluigi		 * of the list has type AF_LINK, and contains sockaddr_dl
134128315Sluigi		 * addresses which store the link-level address and the name
135128291Sluigi		 * of the interface.
136128315Sluigi		 * However, access to the AF_LINK address through this
137152315Sru		 * field is deprecated. Use if_addr or ifaddr_byindex() instead.
138128291Sluigi		 */
13983130Sjlemon	int	if_pcount;		/* number of promiscuous listeners */
140142901Sglebius	struct	carp_if *if_carp;	/* carp interface structure */
14121259Swollman	struct	bpf_if *if_bpf;		/* packet filter structure */
14221259Swollman	u_short	if_index;		/* numeric abbreviation for this if  */
14321259Swollman	short	if_timer;		/* time 'til if_watchdog called */
144155051Sglebius	struct  ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */
145102052Ssobomax	int	if_flags;		/* up/down, broadcast, etc. */
146162070Sandre	int	if_capabilities;	/* interface features & capabilities */
147162070Sandre	int	if_capenable;		/* enabled features & capabilities */
14821259Swollman	void	*if_linkmib;		/* link-type-specific MIB data */
14921259Swollman	size_t	if_linkmiblen;		/* length of above data */
15021259Swollman	struct	if_data if_data;
15121404Swollman	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
15221404Swollman	int	if_amcount;		/* number of all-multicast requests */
15321259Swollman/* procedure handles */
15421259Swollman	int	(*if_output)		/* output routine (enqueue) */
15592725Salfred		(struct ifnet *, struct mbuf *, struct sockaddr *,
156191148Skmacy		     struct route *);
157106931Ssam	void	(*if_input)		/* input routine (from h/w driver) */
158106931Ssam		(struct ifnet *, struct mbuf *);
15921259Swollman	void	(*if_start)		/* initiate output routine */
16092725Salfred		(struct ifnet *);
16121259Swollman	int	(*if_ioctl)		/* ioctl routine */
16292725Salfred		(struct ifnet *, u_long, caddr_t);
16321259Swollman	void	(*if_watchdog)		/* timer routine */
16492725Salfred		(struct ifnet *);
16521259Swollman	void	(*if_init)		/* Init routine */
16692725Salfred		(void *);
16721404Swollman	int	(*if_resolvemulti)	/* validate/resolve multicast */
16892725Salfred		(struct ifnet *, struct sockaddr **, struct sockaddr *);
169189230Srwatson	void	(*if_qflush)		/* flush any queues */
170189230Srwatson		(struct ifnet *);
171189230Srwatson	int	(*if_transmit)		/* initiate output routine */
172189230Srwatson		(struct ifnet *, struct mbuf *);
173193731Szec	void	(*if_reassign)		/* reassign to vnet routine */
174193731Szec		(struct ifnet *, struct vnet *, char *);
175193731Szec	struct	vnet *if_home_vnet;	/* where this ifnet originates from */
176152315Sru	struct	ifaddr	*if_addr;	/* pointer to link-level address */
177174388Skmacy	void	*if_llsoftc;		/* link layer softc */
178148265Srwatson	int	if_drv_flags;		/* driver-managed status flags */
179130416Smlaier	struct  ifaltq if_snd;		/* output queue (includes altq) */
180123220Simp	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
181127828Sluigi
182146986Sthompsa	void	*if_bridge;		/* bridge glue */
183146986Sthompsa
184122524Srwatson	struct	label *if_label;	/* interface MAC label */
185121161Sume
186127828Sluigi	/* these are only used by IPv6 */
187127828Sluigi	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
188121161Sume	void	*if_afdata[AF_MAX];
189121470Sume	int	if_afdata_initialized;
190186199Skmacy	struct	rwlock if_afdata_lock;
191145320Sglebius	struct	task if_linktask;	/* task for link change events */
192148640Srwatson	struct	mtx if_addr_mtx;	/* mutex to protect address lists */
193186119Sqingli
194152209Sthompsa	LIST_ENTRY(ifnet) if_clones;	/* interfaces of a cloner */
195159781Smlaier	TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
196159781Smlaier					/* protected by if_addr_mtx */
197159781Smlaier	void	*if_pf_kif;
198168793Sthompsa	void	*if_lagg;		/* lagg glue */
199191367Srwatson	u_char	 if_alloctype;		/* if_type at time of allocation */
200189230Srwatson
201189230Srwatson	/*
202189230Srwatson	 * Spare fields are added so that we can modify sensitive data
203189230Srwatson	 * structures without changing the kernel binary interface, and must
204189230Srwatson	 * be used with care where binary compatibility is required.
205189230Srwatson	 */
206191367Srwatson	char	 if_cspare[3];
207189230Srwatson	void	*if_pspare[8];
208189230Srwatson	int	if_ispare[4];
20921259Swollman};
21069152Sjlemon
21192725Salfredtypedef void if_init_f_t(void *);
21221259Swollman
213128376Sluigi/*
214128376Sluigi * XXX These aliases are terribly dangerous because they could apply
215128376Sluigi * to anything.
216128376Sluigi */
21721259Swollman#define	if_mtu		if_data.ifi_mtu
21821259Swollman#define	if_type		if_data.ifi_type
21921259Swollman#define if_physical	if_data.ifi_physical
22021259Swollman#define	if_addrlen	if_data.ifi_addrlen
22121259Swollman#define	if_hdrlen	if_data.ifi_hdrlen
22221259Swollman#define	if_metric	if_data.ifi_metric
223128871Sandre#define	if_link_state	if_data.ifi_link_state
22421259Swollman#define	if_baudrate	if_data.ifi_baudrate
22558698Sjlemon#define	if_hwassist	if_data.ifi_hwassist
22621259Swollman#define	if_ipackets	if_data.ifi_ipackets
22721259Swollman#define	if_ierrors	if_data.ifi_ierrors
22821259Swollman#define	if_opackets	if_data.ifi_opackets
22921259Swollman#define	if_oerrors	if_data.ifi_oerrors
23021259Swollman#define	if_collisions	if_data.ifi_collisions
23121259Swollman#define	if_ibytes	if_data.ifi_ibytes
23221259Swollman#define	if_obytes	if_data.ifi_obytes
23321259Swollman#define	if_imcasts	if_data.ifi_imcasts
23421259Swollman#define	if_omcasts	if_data.ifi_omcasts
23521259Swollman#define	if_iqdrops	if_data.ifi_iqdrops
23621259Swollman#define	if_noproto	if_data.ifi_noproto
23721259Swollman#define	if_lastchange	if_data.ifi_lastchange
238136950Sjmg#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL)
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
344126264Smlaier/* interface address change event */
345126264Smlaiertypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
346126264SmlaierEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
347126264Smlaier/* new interface arrival event */
348126264Smlaiertypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
349126264SmlaierEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
350126264Smlaier/* interface departure event */
351126264Smlaiertypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
352126264SmlaierEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
353126264Smlaier
354159781Smlaier/*
355159781Smlaier * interface groups
356159781Smlaier */
357159781Smlaierstruct ifg_group {
358159781Smlaier	char				 ifg_group[IFNAMSIZ];
359159781Smlaier	u_int				 ifg_refcnt;
360159781Smlaier	void				*ifg_pf_kif;
361159781Smlaier	TAILQ_HEAD(, ifg_member)	 ifg_members;
362159781Smlaier	TAILQ_ENTRY(ifg_group)		 ifg_next;
363159781Smlaier};
364159781Smlaier
365159781Smlaierstruct ifg_member {
366159781Smlaier	TAILQ_ENTRY(ifg_member)	 ifgm_next;
367159781Smlaier	struct ifnet		*ifgm_ifp;
368159781Smlaier};
369159781Smlaier
370159781Smlaierstruct ifg_list {
371159781Smlaier	struct ifg_group	*ifgl_group;
372159781Smlaier	TAILQ_ENTRY(ifg_list)	 ifgl_next;
373159781Smlaier};
374159781Smlaier
375159781Smlaier/* group attach event */
376159781Smlaiertypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
377159781SmlaierEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
378159781Smlaier/* group detach event */
379159781Smlaiertypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
380159781SmlaierEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
381159781Smlaier/* group change event */
382159781Smlaiertypedef void (*group_change_event_handler_t)(void *, const char *);
383159781SmlaierEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
384159781Smlaier
385121470Sume#define	IF_AFDATA_LOCK_INIT(ifp)	\
386186199Skmacy	rw_init(&(ifp)->if_afdata_lock, "if_afdata")
387121470Sume
388186199Skmacy#define	IF_AFDATA_WLOCK(ifp)	rw_wlock(&(ifp)->if_afdata_lock)
389186199Skmacy#define	IF_AFDATA_RLOCK(ifp)	rw_rlock(&(ifp)->if_afdata_lock)
390186199Skmacy#define	IF_AFDATA_WUNLOCK(ifp)	rw_wunlock(&(ifp)->if_afdata_lock)
391186199Skmacy#define	IF_AFDATA_RUNLOCK(ifp)	rw_runlock(&(ifp)->if_afdata_lock)
392186199Skmacy#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
393186199Skmacy#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
394186199Skmacy#define	IF_AFDATA_TRYLOCK(ifp)	rw_try_wlock(&(ifp)->if_afdata_lock)
395186199Skmacy#define	IF_AFDATA_DESTROY(ifp)	rw_destroy(&(ifp)->if_afdata_lock)
396186119Sqingli
397186199Skmacy#define	IF_AFDATA_LOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
398186199Skmacy#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
399186199Skmacy
400137065Srwatsonint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
401137065Srwatson	    int adjust);
402130416Smlaier#define	IF_HANDOFF(ifq, m, ifp)			\
403130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
404130416Smlaier#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
405130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
40621259Swollman
407132712Srwatsonvoid	if_start(struct ifnet *);
408132712Srwatson
409130416Smlaier#define	IFQ_ENQUEUE(ifq, m, err)					\
410130416Smlaierdo {									\
411130416Smlaier	IF_LOCK(ifq);							\
412130416Smlaier	if (ALTQ_IS_ENABLED(ifq))					\
413130416Smlaier		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
414130416Smlaier	else {								\
415130416Smlaier		if (_IF_QFULL(ifq)) {					\
416130416Smlaier			m_freem(m);					\
417130416Smlaier			(err) = ENOBUFS;				\
418130416Smlaier		} else {						\
419130416Smlaier			_IF_ENQUEUE(ifq, m);				\
420130416Smlaier			(err) = 0;					\
421130416Smlaier		}							\
422130416Smlaier	}								\
423130416Smlaier	if (err)							\
424130416Smlaier		(ifq)->ifq_drops++;					\
425130416Smlaier	IF_UNLOCK(ifq);							\
426130416Smlaier} while (0)
42721259Swollman
428130416Smlaier#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
429130416Smlaierdo {									\
430130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
431130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
432130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
433130416Smlaier		ALTQ_DEQUEUE(ifq, m);					\
434130416Smlaier	else								\
435130416Smlaier		_IF_DEQUEUE(ifq, m);					\
436130416Smlaier} while (0)
437130416Smlaier
438130416Smlaier#define	IFQ_DEQUEUE(ifq, m)						\
439130416Smlaierdo {									\
440130416Smlaier	IF_LOCK(ifq);							\
441130416Smlaier	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
442130416Smlaier	IF_UNLOCK(ifq);							\
443130416Smlaier} while (0)
444130416Smlaier
445130416Smlaier#define	IFQ_POLL_NOLOCK(ifq, m)						\
446130416Smlaierdo {									\
447130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
448130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
449130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
450130416Smlaier		ALTQ_POLL(ifq, m);					\
451130416Smlaier	else								\
452130416Smlaier		_IF_POLL(ifq, m);					\
453130416Smlaier} while (0)
454130416Smlaier
455130416Smlaier#define	IFQ_POLL(ifq, m)						\
456130416Smlaierdo {									\
457130416Smlaier	IF_LOCK(ifq);							\
458130416Smlaier	IFQ_POLL_NOLOCK(ifq, m);					\
459130416Smlaier	IF_UNLOCK(ifq);							\
460130416Smlaier} while (0)
461130416Smlaier
462130416Smlaier#define	IFQ_PURGE_NOLOCK(ifq)						\
463130416Smlaierdo {									\
464130416Smlaier	if (ALTQ_IS_ENABLED(ifq)) {					\
465130416Smlaier		ALTQ_PURGE(ifq);					\
466130416Smlaier	} else								\
467130416Smlaier		_IF_DRAIN(ifq);						\
468130416Smlaier} while (0)
469130416Smlaier
470130416Smlaier#define	IFQ_PURGE(ifq)							\
471130416Smlaierdo {									\
472130416Smlaier	IF_LOCK(ifq);							\
473130416Smlaier	IFQ_PURGE_NOLOCK(ifq);						\
474130416Smlaier	IF_UNLOCK(ifq);							\
475130416Smlaier} while (0)
476130416Smlaier
477130416Smlaier#define	IFQ_SET_READY(ifq)						\
478130416Smlaier	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
479130416Smlaier
480130416Smlaier#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
481130416Smlaier#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
482130416Smlaier#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
483130416Smlaier#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
484130416Smlaier#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
485130416Smlaier#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
486130416Smlaier#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
487130416Smlaier#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
488130416Smlaier
489148886Srwatson/*
490148886Srwatson * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
491148886Srwatson * the handoff logic, as that flag is locked by the device driver.
492148886Srwatson */
493130416Smlaier#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
494130416Smlaierdo {									\
495130416Smlaier	int len;							\
496130416Smlaier	short mflags;							\
497130416Smlaier									\
498130416Smlaier	len = (m)->m_pkthdr.len;					\
499130416Smlaier	mflags = (m)->m_flags;						\
500130416Smlaier	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
501130416Smlaier	if ((err) == 0) {						\
502130416Smlaier		(ifp)->if_obytes += len + (adj);			\
503130416Smlaier		if (mflags & M_MCAST)					\
504130416Smlaier			(ifp)->if_omcasts++;				\
505148886Srwatson		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
506132712Srwatson			if_start(ifp);					\
507130416Smlaier	}								\
508130416Smlaier} while (0)
509130416Smlaier
510130416Smlaier#define	IFQ_HANDOFF(ifp, m, err)					\
511130512Smlaier	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
512130416Smlaier
513130416Smlaier#define	IFQ_DRV_DEQUEUE(ifq, m)						\
514130416Smlaierdo {									\
515130416Smlaier	(m) = (ifq)->ifq_drv_head;					\
516130416Smlaier	if (m) {							\
517130416Smlaier		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
518130416Smlaier			(ifq)->ifq_drv_tail = NULL;			\
519130416Smlaier		(m)->m_nextpkt = NULL;					\
520130416Smlaier		(ifq)->ifq_drv_len--;					\
521130416Smlaier	} else {							\
522130416Smlaier		IFQ_LOCK(ifq);						\
523130416Smlaier		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
524130416Smlaier		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
525130416Smlaier			struct mbuf *m0;				\
526130416Smlaier			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
527130416Smlaier			if (m0 == NULL)					\
528130416Smlaier				break;					\
529130416Smlaier			m0->m_nextpkt = NULL;				\
530130416Smlaier			if ((ifq)->ifq_drv_tail == NULL)		\
531130416Smlaier				(ifq)->ifq_drv_head = m0;		\
532130416Smlaier			else						\
533130416Smlaier				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
534130416Smlaier			(ifq)->ifq_drv_tail = m0;			\
535130416Smlaier			(ifq)->ifq_drv_len++;				\
536130416Smlaier		}							\
537130416Smlaier		IFQ_UNLOCK(ifq);					\
538130416Smlaier	}								\
539130416Smlaier} while (0)
540130416Smlaier
541130416Smlaier#define	IFQ_DRV_PREPEND(ifq, m)						\
542130416Smlaierdo {									\
543130416Smlaier	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
544132152Smlaier	if ((ifq)->ifq_drv_tail == NULL)				\
545132152Smlaier		(ifq)->ifq_drv_tail = (m);				\
546130416Smlaier	(ifq)->ifq_drv_head = (m);					\
547130416Smlaier	(ifq)->ifq_drv_len++;						\
548130416Smlaier} while (0)
549130416Smlaier
550130416Smlaier#define	IFQ_DRV_IS_EMPTY(ifq)						\
551130416Smlaier	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
552130416Smlaier
553130416Smlaier#define	IFQ_DRV_PURGE(ifq)						\
554130416Smlaierdo {									\
555132152Smlaier	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
556132152Smlaier	while((m = n) != NULL) {					\
557132152Smlaier		n = m->m_nextpkt;					\
558130416Smlaier		m_freem(m);						\
559130416Smlaier	}								\
560130416Smlaier	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
561130416Smlaier	(ifq)->ifq_drv_len = 0;						\
562130416Smlaier	IFQ_PURGE(ifq);							\
563130416Smlaier} while (0)
564130416Smlaier
565186207Skmacy#ifdef _KERNEL
566186213Skmacystatic __inline void
567186213Skmacydrbr_stats_update(struct ifnet *ifp, int len, int mflags)
568186213Skmacy{
569193848Skmacy#ifndef NO_SLOW_STATS
570186213Skmacy	ifp->if_obytes += len;
571186213Skmacy	if (mflags & M_MCAST)
572186213Skmacy		ifp->if_omcasts++;
573193848Skmacy#endif
574186213Skmacy}
575186213Skmacy
576186207Skmacystatic __inline int
577186213Skmacydrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
578186207Skmacy{
579186207Skmacy	int error = 0;
580186213Skmacy	int len = m->m_pkthdr.len;
581186213Skmacy	int mflags = m->m_flags;
582186207Skmacy
583191033Skmacy#ifdef ALTQ
584191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
585191033Skmacy		IFQ_ENQUEUE(&ifp->if_snd, m, error);
586191033Skmacy		return (error);
587191033Skmacy	}
588191033Skmacy#endif
589193848Skmacy	if ((error = buf_ring_enqueue_bytes(br, m, len)) == ENOBUFS) {
590186207Skmacy		br->br_drops++;
591186207Skmacy		m_freem(m);
592186213Skmacy	} else
593186213Skmacy		drbr_stats_update(ifp, len, mflags);
594186213Skmacy
595186207Skmacy	return (error);
596186207Skmacy}
597186207Skmacy
598186207Skmacystatic __inline void
599194518Skmacydrbr_flush(struct ifnet *ifp, struct buf_ring *br)
600186207Skmacy{
601186207Skmacy	struct mbuf *m;
602186207Skmacy
603194518Skmacy#ifdef ALTQ
604194518Skmacy	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
605194518Skmacy		while (!IFQ_IS_EMPTY(&ifp->if_snd)) {
606194518Skmacy			IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
607194518Skmacy			m_freem(m);
608194518Skmacy		}
609194518Skmacy	}
610194518Skmacy#endif
611186207Skmacy	while ((m = buf_ring_dequeue_sc(br)) != NULL)
612186207Skmacy		m_freem(m);
613194518Skmacy}
614186207Skmacy
615194518Skmacystatic __inline void
616194518Skmacydrbr_free(struct buf_ring *br, struct malloc_type *type)
617194518Skmacy{
618194518Skmacy
619194518Skmacy	drbr_flush(NULL, br);
620186207Skmacy	buf_ring_free(br, type);
621186207Skmacy}
622191033Skmacy
623191033Skmacystatic __inline struct mbuf *
624191033Skmacydrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
625191033Skmacy{
626191033Skmacy#ifdef ALTQ
627191033Skmacy	struct mbuf *m;
628191033Skmacy
629191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
630191033Skmacy		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
631191033Skmacy		return (m);
632191033Skmacy	}
633186207Skmacy#endif
634191033Skmacy	return (buf_ring_dequeue_sc(br));
635191033Skmacy}
636186207Skmacy
637193848Skmacystatic __inline struct mbuf *
638193848Skmacydrbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
639193848Skmacy    int (*func) (struct mbuf *, void *), void *arg)
640193848Skmacy{
641193848Skmacy	struct mbuf *m;
642193848Skmacy#ifdef ALTQ
643193848Skmacy	/*
644193848Skmacy	 * XXX need to evaluate / requeue
645193848Skmacy	 */
646193848Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
647193848Skmacy		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
648193848Skmacy		return (m);
649193848Skmacy	}
650193848Skmacy#endif
651193848Skmacy	m = buf_ring_peek(br);
652193848Skmacy	if (m == NULL || func(m, arg) == 0)
653193848Skmacy		return (NULL);
654193848Skmacy
655193848Skmacy	return (buf_ring_dequeue_sc(br));
656193848Skmacy}
657193848Skmacy
658191033Skmacystatic __inline int
659191033Skmacydrbr_empty(struct ifnet *ifp, struct buf_ring *br)
660191033Skmacy{
661191033Skmacy#ifdef ALTQ
662191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
663191033Skmacy		return (IFQ_DRV_IS_EMPTY(&ifp->if_snd));
664191033Skmacy#endif
665191033Skmacy	return (buf_ring_empty(br));
666191033Skmacy}
667193848Skmacy
668193848Skmacystatic __inline int
669193848Skmacydrbr_inuse(struct ifnet *ifp, struct buf_ring *br)
670193848Skmacy{
671193848Skmacy#ifdef ALTQ
672193848Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
673193848Skmacy		return (ifp->if_snd.ifq_len);
674191033Skmacy#endif
675193848Skmacy	return (buf_ring_count(br));
676193848Skmacy}
677193848Skmacy#endif
67849459Sbrian/*
67949459Sbrian * 72 was chosen below because it is the size of a TCP/IP
68049459Sbrian * header (40) + the minimum mss (32).
68149459Sbrian */
68249459Sbrian#define	IF_MINMTU	72
68349459Sbrian#define	IF_MAXMTU	65535
68449459Sbrian
68555205Speter#endif /* _KERNEL */
68621259Swollman
68721259Swollman/*
68821259Swollman * The ifaddr structure contains information about one address
68921259Swollman * of an interface.  They are maintained by the different address families,
69021259Swollman * are allocated and attached when an address is set, and are linked
69121259Swollman * together so all addresses for an interface can be located.
692128291Sluigi *
693128291Sluigi * NOTE: a 'struct ifaddr' is always at the beginning of a larger
694128291Sluigi * chunk of malloc'ed memory, where we store the three addresses
695128291Sluigi * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
69621259Swollman */
69721259Swollmanstruct ifaddr {
69821259Swollman	struct	sockaddr *ifa_addr;	/* address of interface */
69921259Swollman	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
70021259Swollman#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
70121259Swollman	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
70267334Sjoe	struct	if_data if_data;	/* not all members are meaningful */
70321259Swollman	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
70460938Sjake	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
70521259Swollman	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
70692725Salfred		(int, struct rtentry *, struct rt_addrinfo *);
70721259Swollman	u_short	ifa_flags;		/* mostly rt_flags for cloning */
70847254Spb	u_int	ifa_refcnt;		/* references to this structure */
70921259Swollman	int	ifa_metric;		/* cost of going out this interface */
71028845Sjulian	int (*ifa_claim_addr)		/* check if an addr goes to this if */
71192725Salfred		(struct ifaddr *, struct sockaddr *);
712108033Shsu	struct mtx ifa_mtx;
71321259Swollman};
71421259Swollman#define	IFA_ROUTE	RTF_UP		/* route installed */
71521259Swollman
71653541Sshin/* for compatibility with other BSDs */
71753541Sshin#define	ifa_list	ifa_link
71853541Sshin
719194602Srwatson#ifdef _KERNEL
720108033Shsu#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
721108033Shsu#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
722108033Shsu
723194602Srwatsonvoid	ifa_free(struct ifaddr *ifa);
724194602Srwatsonvoid	ifa_init(struct ifaddr *ifa);
725194602Srwatsonvoid	ifa_ref(struct ifaddr *ifa);
726194602Srwatson#endif
727194602Srwatson
72821404Swollman/*
72952904Sshin * The prefix structure contains information about one prefix
73052904Sshin * of an interface.  They are maintained by the different address families,
731108470Sschweikh * are allocated and attached when a prefix or an address is set,
73253541Sshin * and are linked together so all prefixes for an interface can be located.
73352904Sshin */
73452904Sshinstruct ifprefix {
73552904Sshin	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
73652904Sshin	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
73760938Sjake	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
73852904Sshin	u_char	ifpr_plen;		/* prefix length in bits */
73952904Sshin	u_char	ifpr_type;		/* protocol dependent prefix type */
74052904Sshin};
74152904Sshin
74252904Sshin/*
74321404Swollman * Multicast address structure.  This is analogous to the ifaddr
74421404Swollman * structure except that it keeps track of multicast addresses.
74521404Swollman */
74621404Swollmanstruct ifmultiaddr {
74772084Sphk	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
74821434Swollman	struct	sockaddr *ifma_addr; 	/* address this membership is for */
74921434Swollman	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
75021434Swollman	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
75121434Swollman	u_int	ifma_refcount;		/* reference count */
75221434Swollman	void	*ifma_protospec;	/* protocol-specific state, if any */
753167729Sbms	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
75421404Swollman};
75521404Swollman
75655205Speter#ifdef _KERNEL
75721259Swollman
758186199Skmacyextern	struct rwlock ifnet_lock;
759108298Shsu#define	IFNET_LOCK_INIT() \
760186199Skmacy   rw_init_flags(&ifnet_lock, "ifnet",  RW_RECURSE)
761186199Skmacy#define	IFNET_WLOCK()		rw_wlock(&ifnet_lock)
762186199Skmacy#define	IFNET_WUNLOCK()		rw_wunlock(&ifnet_lock)
763186199Skmacy#define	IFNET_WLOCK_ASSERT()	rw_assert(&ifnet_lock, RA_LOCKED)
764186199Skmacy#define	IFNET_RLOCK()		rw_rlock(&ifnet_lock)
765186199Skmacy#define	IFNET_RUNLOCK()		rw_runlock(&ifnet_lock)
766108172Shsu
767191367Srwatson/*
768191367Srwatson * Look up an ifnet given its index; the _ref variant also acquires a
769191367Srwatson * reference that must be freed using if_rele().  It is almost always a bug
770191367Srwatson * to call ifnet_byindex() instead if ifnet_byindex_ref().
771191367Srwatson */
772180042Srwatsonstruct ifnet	*ifnet_byindex(u_short idx);
773191816Szecstruct ifnet	*ifnet_byindex_locked(u_short idx);
774191367Srwatsonstruct ifnet	*ifnet_byindex_ref(u_short idx);
775181892Skmacy
776128315Sluigi/*
777128315Sluigi * Given the index, ifaddr_byindex() returns the one and only
778128315Sluigi * link-level ifaddr for the interface. You are not supposed to use
779128315Sluigi * it to traverse the list of addresses associated to the interface.
780128315Sluigi */
781180042Srwatsonstruct ifaddr	*ifaddr_byindex(u_short idx);
78283130Sjlemon
783195699SrwatsonVNET_DECLARE(struct ifnethead, ifnet);
784195699SrwatsonVNET_DECLARE(struct ifgrouphead, ifg_head);
785195699SrwatsonVNET_DECLARE(int, if_index);
786195699SrwatsonVNET_DECLARE(struct ifnet *, loif);	/* first loopback interface */
787195699Srwatson
788195699Srwatson#define	V_ifnet		VNET_GET(ifnet)
789195699Srwatson#define	V_ifg_head	VNET_GET(ifg_head)
790195699Srwatson#define	V_if_index	VNET_GET(if_index)
791195699Srwatson#define	V_loif		VNET_GET(loif)
792195699Srwatson
793186048Sbzextern	int ifqmaxlen;
79421259Swollman
795159781Smlaierint	if_addgroup(struct ifnet *, const char *);
796159781Smlaierint	if_delgroup(struct ifnet *, const char *);
79792725Salfredint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
79892725Salfredint	if_allmulti(struct ifnet *, int);
799147256Sbrooksstruct	ifnet* if_alloc(u_char);
80092725Salfredvoid	if_attach(struct ifnet *);
801191418Srwatsonvoid	if_dead(struct ifnet *);
802191816Szecvoid	if_grow(void);
80392725Salfredint	if_delmulti(struct ifnet *, struct sockaddr *);
804167729Sbmsvoid	if_delmulti_ifma(struct ifmultiaddr *);
80592725Salfredvoid	if_detach(struct ifnet *);
806192605Szecvoid	if_vmove(struct ifnet *, struct vnet *);
807146620Speadarvoid	if_purgeaddrs(struct ifnet *);
808177617Ssamvoid	if_purgemaddrs(struct ifnet *);
80992725Salfredvoid	if_down(struct ifnet *);
810167732Sbmsstruct ifmultiaddr *
811167732Sbms	if_findmulti(struct ifnet *, struct sockaddr *);
812147256Sbrooksvoid	if_free(struct ifnet *);
813147256Sbrooksvoid	if_free_type(struct ifnet *, u_char);
814121816Sbrooksvoid	if_initname(struct ifnet *, const char *, int);
815138542Ssamvoid	if_link_state_change(struct ifnet *, int);
816103900Sbrooksint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
817191161Skmacyvoid	if_qflush(struct ifnet *);
818191367Srwatsonvoid	if_ref(struct ifnet *);
819191367Srwatsonvoid	if_rele(struct ifnet *);
82092725Salfredint	if_setlladdr(struct ifnet *, const u_char *, int);
82192725Salfredvoid	if_up(struct ifnet *);
82292725Salfred/*void	ifinit(void);*/ /* declared in systm.h for main() */
82392725Salfredint	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
82492725Salfredint	ifpromisc(struct ifnet *, int);
82592725Salfredstruct	ifnet *ifunit(const char *);
826191423Srwatsonstruct	ifnet *ifunit_ref(const char *);
82721259Swollman
828194259Ssamvoid	ifq_init(struct ifaltq *, struct ifnet *ifp);
829194259Ssamvoid	ifq_delete(struct ifaltq *);
830185162Skmacy
83192725Salfredstruct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
832194622Srwatsonint		ifa_ifwithaddr_check(struct sockaddr *);
833162068Sandrestruct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
83492725Salfredstruct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
83592725Salfredstruct	ifaddr *ifa_ifwithnet(struct sockaddr *);
83692725Salfredstruct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
837178888Sjulianstruct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
838178888Sjulian
83992725Salfredstruct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
84021259Swollman
84192725Salfredint	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
84221434Swollman
843147256Sbrookstypedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
844147256Sbrookstypedef	void if_com_free_t(void *com, u_char type);
845147256Sbrooksvoid	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
846147256Sbrooksvoid	if_deregister_com_alloc(u_char type);
847147256Sbrooks
84884931Sfjoe#define IF_LLADDR(ifp)							\
849152315Sru    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
85084931Sfjoe
85187902Sluigi#ifdef DEVICE_POLLING
852150789Sglebiusenum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
85387902Sluigi
854193096Sattiliotypedef	int poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
85592725Salfredint    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
85692725Salfredint    ether_poll_deregister(struct ifnet *ifp);
85787902Sluigi#endif /* DEVICE_POLLING */
85887902Sluigi
85955205Speter#endif /* _KERNEL */
86021259Swollman
86121259Swollman#endif /* !_NET_IF_VAR_H_ */
862