if_var.h revision 191418
121495Sjmacd/*-
221495Sjmacd * Copyright (c) 1982, 1986, 1989, 1993
321495Sjmacd *	The Regents of the University of California.  All rights reserved.
421495Sjmacd *
521495Sjmacd * Redistribution and use in source and binary forms, with or without
621495Sjmacd * modification, are permitted provided that the following conditions
721495Sjmacd * are met:
821495Sjmacd * 1. Redistributions of source code must retain the above copyright
921495Sjmacd *    notice, this list of conditions and the following disclaimer.
1021495Sjmacd * 2. Redistributions in binary form must reproduce the above copyright
1121495Sjmacd *    notice, this list of conditions and the following disclaimer in the
1221495Sjmacd *    documentation and/or other materials provided with the distribution.
1321495Sjmacd * 4. Neither the name of the University nor the names of its contributors
1421495Sjmacd *    may be used to endorse or promote products derived from this software
1521495Sjmacd *    without specific prior written permission.
1621495Sjmacd *
1721495Sjmacd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1821495Sjmacd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1921495Sjmacd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2021495Sjmacd * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2121495Sjmacd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2221495Sjmacd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2321495Sjmacd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2421495Sjmacd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2521495Sjmacd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2621495Sjmacd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2721495Sjmacd * SUCH DAMAGE.
2821495Sjmacd *
2921495Sjmacd *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3021495Sjmacd * $FreeBSD: head/sys/net/if_var.h 191418 2009-04-23 11:51:53Z rwatson $
3121495Sjmacd */
3221495Sjmacd
3321495Sjmacd#ifndef	_NET_IF_VAR_H_
3421495Sjmacd#define	_NET_IF_VAR_H_
3521495Sjmacd
3621495Sjmacd/*
3721495Sjmacd * Structures defining a network interface, providing a packet
3821495Sjmacd * transport mechanism (ala level 0 of the PUP protocols).
3921495Sjmacd *
4021495Sjmacd * Each interface accepts output datagrams of a specified maximum
4121495Sjmacd * length, and provides higher level routines with input datagrams
4221495Sjmacd * received from its medium.
4321495Sjmacd *
4421495Sjmacd * Output occurs when the routine if_output is called, with three parameters:
4521495Sjmacd *	(*ifp->if_output)(ifp, m, dst, rt)
4621495Sjmacd * Here m is the mbuf chain to be sent and dst is the destination address.
4721495Sjmacd * The output routine encapsulates the supplied datagram if necessary,
4821495Sjmacd * and then transmits it on its medium.
4921495Sjmacd *
5021495Sjmacd * On input, each interface unwraps the data received by it, and either
5121495Sjmacd * places it on the input queue of an internetwork datagram routine
5221495Sjmacd * and posts the associated software interrupt, or passes the datagram to a raw
5321495Sjmacd * packet input routine.
5421495Sjmacd *
5521495Sjmacd * Routines exist for locating interfaces by their addresses
5621495Sjmacd * or for locating an interface on a certain network, as well as more general
5721495Sjmacd * routing and gateway routines maintaining information used to locate
5821495Sjmacd * interfaces.  These routines live in the files if.c and route.c
5921495Sjmacd */
6021495Sjmacd
6121495Sjmacd#ifdef __STDC__
6221495Sjmacd/*
6321495Sjmacd * Forward structure declarations for function prototypes [sic].
6421495Sjmacd */
6521495Sjmacdstruct	mbuf;
6621495Sjmacdstruct	thread;
6721495Sjmacdstruct	rtentry;
6821495Sjmacdstruct	rt_addrinfo;
6921495Sjmacdstruct	socket;
7021495Sjmacdstruct	ether_header;
7121495Sjmacdstruct	carp_if;
7221495Sjmacdstruct  ifvlantrunk;
7321495Sjmacdstruct	route;
7421495Sjmacd#endif
7521495Sjmacd
7621495Sjmacd#include <sys/queue.h>		/* get TAILQ macros */
7721495Sjmacd
7821495Sjmacd#ifdef _KERNEL
7921495Sjmacd#include <sys/mbuf.h>
8021495Sjmacd#include <sys/eventhandler.h>
8121495Sjmacd#include <sys/buf_ring.h>
8221495Sjmacd#endif /* _KERNEL */
8321495Sjmacd#include <sys/lock.h>		/* XXX */
8421495Sjmacd#include <sys/mutex.h>		/* XXX */
8521495Sjmacd#include <sys/rwlock.h>		/* XXX */
8621495Sjmacd#include <sys/event.h>		/* XXX */
8721495Sjmacd#include <sys/_task.h>
8821495Sjmacd
8921495Sjmacd#define	IF_DUNIT_NONE	-1
9021495Sjmacd
9121495Sjmacd#include <altq/if_altq.h>
9221495Sjmacd
9321495SjmacdTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
9421495SjmacdTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
9521495SjmacdTAILQ_HEAD(ifprefixhead, ifprefix);
9621495SjmacdTAILQ_HEAD(ifmultihead, ifmultiaddr);
9721495SjmacdTAILQ_HEAD(ifgrouphead, ifg_group);
9821495Sjmacd
9921495Sjmacd/*
10021495Sjmacd * Structure defining a queue for a network interface.
10121495Sjmacd */
10221495Sjmacdstruct	ifqueue {
10321495Sjmacd	struct	mbuf *ifq_head;
10421495Sjmacd	struct	mbuf *ifq_tail;
10521495Sjmacd	int	ifq_len;
10621495Sjmacd	int	ifq_maxlen;
10721495Sjmacd	int	ifq_drops;
10821495Sjmacd	struct	mtx ifq_mtx;
10921495Sjmacd};
11021495Sjmacd
11121495Sjmacd/*
11221495Sjmacd * Structure defining a network interface.
11321495Sjmacd *
11421495Sjmacd * (Would like to call this struct ``if'', but C isn't PL/1.)
11521495Sjmacd */
11621495Sjmacd
11721495Sjmacdstruct ifnet {
11821495Sjmacd	void	*if_softc;		/* pointer to driver state */
11921495Sjmacd	void	*if_l2com;		/* pointer to protocol bits */
12021495Sjmacd	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
12121495Sjmacd	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
12221495Sjmacd	const char *if_dname;		/* driver name */
12321495Sjmacd	int	if_dunit;		/* unit or IF_DUNIT_NONE */
12421495Sjmacd	u_int	if_refcount;		/* reference count */
12521495Sjmacd	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
12621495Sjmacd		/*
12721495Sjmacd		 * if_addrhead is the list of all addresses associated to
12821495Sjmacd		 * an interface.
12921495Sjmacd		 * Some code in the kernel assumes that first element
13021495Sjmacd		 * of the list has type AF_LINK, and contains sockaddr_dl
13121495Sjmacd		 * addresses which store the link-level address and the name
13221495Sjmacd		 * of the interface.
13321495Sjmacd		 * However, access to the AF_LINK address through this
13421495Sjmacd		 * field is deprecated. Use if_addr or ifaddr_byindex() instead.
13521495Sjmacd		 */
13621495Sjmacd	struct	knlist if_klist;	/* events attached to this if */
13721495Sjmacd	int	if_pcount;		/* number of promiscuous listeners */
13821495Sjmacd	struct	carp_if *if_carp;	/* carp interface structure */
13921495Sjmacd	struct	bpf_if *if_bpf;		/* packet filter structure */
14021495Sjmacd	u_short	if_index;		/* numeric abbreviation for this if  */
14121495Sjmacd	short	if_timer;		/* time 'til if_watchdog called */
14221495Sjmacd	struct  ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */
14321495Sjmacd	int	if_flags;		/* up/down, broadcast, etc. */
14421495Sjmacd	int	if_capabilities;	/* interface features & capabilities */
14521495Sjmacd	int	if_capenable;		/* enabled features & capabilities */
14621495Sjmacd	void	*if_linkmib;		/* link-type-specific MIB data */
14721495Sjmacd	size_t	if_linkmiblen;		/* length of above data */
14821495Sjmacd	struct	if_data if_data;
14921495Sjmacd	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
15021495Sjmacd	int	if_amcount;		/* number of all-multicast requests */
15121495Sjmacd/* procedure handles */
15221495Sjmacd	int	(*if_output)		/* output routine (enqueue) */
15321495Sjmacd		(struct ifnet *, struct mbuf *, struct sockaddr *,
15421495Sjmacd		     struct route *);
15521495Sjmacd	void	(*if_input)		/* input routine (from h/w driver) */
15621495Sjmacd		(struct ifnet *, struct mbuf *);
15721495Sjmacd	void	(*if_start)		/* initiate output routine */
15821495Sjmacd		(struct ifnet *);
15921495Sjmacd	int	(*if_ioctl)		/* ioctl routine */
16021495Sjmacd		(struct ifnet *, u_long, caddr_t);
16121495Sjmacd	void	(*if_watchdog)		/* timer routine */
16221495Sjmacd		(struct ifnet *);
16321495Sjmacd	void	(*if_init)		/* Init routine */
16421495Sjmacd		(void *);
16521495Sjmacd	int	(*if_resolvemulti)	/* validate/resolve multicast */
16621495Sjmacd		(struct ifnet *, struct sockaddr **, struct sockaddr *);
16721495Sjmacd	void	(*if_qflush)		/* flush any queues */
16821495Sjmacd		(struct ifnet *);
16921495Sjmacd	int	(*if_transmit)		/* initiate output routine */
17021495Sjmacd		(struct ifnet *, struct mbuf *);
17121495Sjmacd	struct	ifaddr	*if_addr;	/* pointer to link-level address */
17221495Sjmacd	void	*if_llsoftc;		/* link layer softc */
17321495Sjmacd	int	if_drv_flags;		/* driver-managed status flags */
17421495Sjmacd	struct  ifaltq if_snd;		/* output queue (includes altq) */
17521495Sjmacd	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
17621495Sjmacd
17721495Sjmacd	void	*if_bridge;		/* bridge glue */
17821495Sjmacd
17921495Sjmacd	struct	label *if_label;	/* interface MAC label */
18021495Sjmacd
18121495Sjmacd	/* these are only used by IPv6 */
18221495Sjmacd	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
18321495Sjmacd	void	*if_afdata[AF_MAX];
18421495Sjmacd	int	if_afdata_initialized;
18521495Sjmacd	struct	rwlock if_afdata_lock;
18621495Sjmacd	struct	task if_linktask;	/* task for link change events */
18721495Sjmacd	struct	mtx if_addr_mtx;	/* mutex to protect address lists */
18821495Sjmacd
18921495Sjmacd	LIST_ENTRY(ifnet) if_clones;	/* interfaces of a cloner */
19021495Sjmacd	TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
19121495Sjmacd					/* protected by if_addr_mtx */
19221495Sjmacd	void	*if_pf_kif;
19321495Sjmacd	void	*if_lagg;		/* lagg glue */
19421495Sjmacd	u_char	 if_alloctype;		/* if_type at time of allocation */
19521495Sjmacd
19621495Sjmacd	/*
19721495Sjmacd	 * Spare fields are added so that we can modify sensitive data
19821495Sjmacd	 * structures without changing the kernel binary interface, and must
19921495Sjmacd	 * be used with care where binary compatibility is required.
20021495Sjmacd	 */
20121495Sjmacd	char	 if_cspare[3];
20221495Sjmacd	void	*if_pspare[8];
20321495Sjmacd	int	if_ispare[4];
20421495Sjmacd};
20521495Sjmacd
20621495Sjmacdtypedef void if_init_f_t(void *);
20721495Sjmacd
20821495Sjmacd/*
20921495Sjmacd * XXX These aliases are terribly dangerous because they could apply
21021495Sjmacd * to anything.
21121495Sjmacd */
21221495Sjmacd#define	if_mtu		if_data.ifi_mtu
21321495Sjmacd#define	if_type		if_data.ifi_type
21421495Sjmacd#define if_physical	if_data.ifi_physical
21521495Sjmacd#define	if_addrlen	if_data.ifi_addrlen
21621495Sjmacd#define	if_hdrlen	if_data.ifi_hdrlen
21721495Sjmacd#define	if_metric	if_data.ifi_metric
21821495Sjmacd#define	if_link_state	if_data.ifi_link_state
21921495Sjmacd#define	if_baudrate	if_data.ifi_baudrate
22021495Sjmacd#define	if_hwassist	if_data.ifi_hwassist
22121495Sjmacd#define	if_ipackets	if_data.ifi_ipackets
22221495Sjmacd#define	if_ierrors	if_data.ifi_ierrors
22321495Sjmacd#define	if_opackets	if_data.ifi_opackets
22421495Sjmacd#define	if_oerrors	if_data.ifi_oerrors
22521495Sjmacd#define	if_collisions	if_data.ifi_collisions
22621495Sjmacd#define	if_ibytes	if_data.ifi_ibytes
22721495Sjmacd#define	if_obytes	if_data.ifi_obytes
22821495Sjmacd#define	if_imcasts	if_data.ifi_imcasts
22921495Sjmacd#define	if_omcasts	if_data.ifi_omcasts
23021495Sjmacd#define	if_iqdrops	if_data.ifi_iqdrops
23121495Sjmacd#define	if_noproto	if_data.ifi_noproto
23221495Sjmacd#define	if_lastchange	if_data.ifi_lastchange
23321495Sjmacd#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL)
23421495Sjmacd
23521495Sjmacd/* for compatibility with other BSDs */
23621495Sjmacd#define	if_addrlist	if_addrhead
23721495Sjmacd#define	if_list		if_link
23821495Sjmacd#define	if_name(ifp)	((ifp)->if_xname)
23921495Sjmacd
24021495Sjmacd/*
24121495Sjmacd * Locks for address lists on the network interface.
24221495Sjmacd */
24321495Sjmacd#define	IF_ADDR_LOCK_INIT(if)	mtx_init(&(if)->if_addr_mtx,		\
24421495Sjmacd				    "if_addr_mtx", NULL, MTX_DEF)
24521495Sjmacd#define	IF_ADDR_LOCK_DESTROY(if)	mtx_destroy(&(if)->if_addr_mtx)
24621495Sjmacd#define	IF_ADDR_LOCK(if)	mtx_lock(&(if)->if_addr_mtx)
24721495Sjmacd#define	IF_ADDR_UNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
24821495Sjmacd#define	IF_ADDR_LOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
24921495Sjmacd
25021495Sjmacd/*
25121495Sjmacd * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
25221495Sjmacd * are queues of messages stored on ifqueue structures
25321495Sjmacd * (defined above).  Entries are added to and deleted from these structures
25421495Sjmacd * by these macros, which should be called with ipl raised to splimp().
25521495Sjmacd */
25621495Sjmacd#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
25721495Sjmacd#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
25821495Sjmacd#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
25921495Sjmacd#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
26021495Sjmacd#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
26121495Sjmacd#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
26221495Sjmacd
26321495Sjmacd#define	_IF_ENQUEUE(ifq, m) do { 				\
26421495Sjmacd	(m)->m_nextpkt = NULL;					\
26521495Sjmacd	if ((ifq)->ifq_tail == NULL) 				\
26621495Sjmacd		(ifq)->ifq_head = m; 				\
26721495Sjmacd	else 							\
26821495Sjmacd		(ifq)->ifq_tail->m_nextpkt = m; 		\
26921495Sjmacd	(ifq)->ifq_tail = m; 					\
27021495Sjmacd	(ifq)->ifq_len++; 					\
27121495Sjmacd} while (0)
27221495Sjmacd
27321495Sjmacd#define IF_ENQUEUE(ifq, m) do {					\
27421495Sjmacd	IF_LOCK(ifq); 						\
27521495Sjmacd	_IF_ENQUEUE(ifq, m); 					\
27621495Sjmacd	IF_UNLOCK(ifq); 					\
27721495Sjmacd} while (0)
27821495Sjmacd
27921495Sjmacd#define	_IF_PREPEND(ifq, m) do {				\
28021495Sjmacd	(m)->m_nextpkt = (ifq)->ifq_head; 			\
28121495Sjmacd	if ((ifq)->ifq_tail == NULL) 				\
28221495Sjmacd		(ifq)->ifq_tail = (m); 				\
28321495Sjmacd	(ifq)->ifq_head = (m); 					\
28421495Sjmacd	(ifq)->ifq_len++; 					\
28521495Sjmacd} while (0)
28621495Sjmacd
28721495Sjmacd#define IF_PREPEND(ifq, m) do {		 			\
28821495Sjmacd	IF_LOCK(ifq); 						\
28921495Sjmacd	_IF_PREPEND(ifq, m); 					\
29021495Sjmacd	IF_UNLOCK(ifq); 					\
29121495Sjmacd} while (0)
29221495Sjmacd
29321495Sjmacd#define	_IF_DEQUEUE(ifq, m) do { 				\
29421495Sjmacd	(m) = (ifq)->ifq_head; 					\
29521495Sjmacd	if (m) { 						\
29621495Sjmacd		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
29721495Sjmacd			(ifq)->ifq_tail = NULL; 		\
29821495Sjmacd		(m)->m_nextpkt = NULL; 				\
29921495Sjmacd		(ifq)->ifq_len--; 				\
30021495Sjmacd	} 							\
30121495Sjmacd} while (0)
30221495Sjmacd
30321495Sjmacd#define IF_DEQUEUE(ifq, m) do { 				\
30421495Sjmacd	IF_LOCK(ifq); 						\
30521495Sjmacd	_IF_DEQUEUE(ifq, m); 					\
30621495Sjmacd	IF_UNLOCK(ifq); 					\
30721495Sjmacd} while (0)
30821495Sjmacd
30921495Sjmacd#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
31021495Sjmacd#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
31121495Sjmacd
31221495Sjmacd#define _IF_DRAIN(ifq) do { 					\
31321495Sjmacd	struct mbuf *m; 					\
31421495Sjmacd	for (;;) { 						\
31521495Sjmacd		_IF_DEQUEUE(ifq, m); 				\
31621495Sjmacd		if (m == NULL) 					\
31721495Sjmacd			break; 					\
31821495Sjmacd		m_freem(m); 					\
31921495Sjmacd	} 							\
32021495Sjmacd} while (0)
32121495Sjmacd
32221495Sjmacd#define IF_DRAIN(ifq) do {					\
32321495Sjmacd	IF_LOCK(ifq);						\
32421495Sjmacd	_IF_DRAIN(ifq);						\
32521495Sjmacd	IF_UNLOCK(ifq);						\
32621495Sjmacd} while(0)
32721495Sjmacd
32821495Sjmacd#ifdef _KERNEL
32921495Sjmacd/* interface address change event */
33021495Sjmacdtypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
33121495SjmacdEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
33221495Sjmacd/* new interface arrival event */
33321495Sjmacdtypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
33421495SjmacdEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
33521495Sjmacd/* interface departure event */
33621495Sjmacdtypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
33721495SjmacdEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
33821495Sjmacd
33921495Sjmacd/*
34021495Sjmacd * interface groups
34121495Sjmacd */
34221495Sjmacdstruct ifg_group {
34321495Sjmacd	char				 ifg_group[IFNAMSIZ];
34421495Sjmacd	u_int				 ifg_refcnt;
34521495Sjmacd	void				*ifg_pf_kif;
34621495Sjmacd	TAILQ_HEAD(, ifg_member)	 ifg_members;
34721495Sjmacd	TAILQ_ENTRY(ifg_group)		 ifg_next;
34821495Sjmacd};
34921495Sjmacd
35021495Sjmacdstruct ifg_member {
35121495Sjmacd	TAILQ_ENTRY(ifg_member)	 ifgm_next;
35221495Sjmacd	struct ifnet		*ifgm_ifp;
35321495Sjmacd};
35421495Sjmacd
35521495Sjmacdstruct ifg_list {
35621495Sjmacd	struct ifg_group	*ifgl_group;
35721495Sjmacd	TAILQ_ENTRY(ifg_list)	 ifgl_next;
35821495Sjmacd};
35921495Sjmacd
36021495Sjmacd/* group attach event */
36121495Sjmacdtypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
36221495SjmacdEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
36321495Sjmacd/* group detach event */
36421495Sjmacdtypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
36521495SjmacdEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
36621495Sjmacd/* group change event */
36721495Sjmacdtypedef void (*group_change_event_handler_t)(void *, const char *);
36821495SjmacdEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
36921495Sjmacd
37021495Sjmacd#define	IF_AFDATA_LOCK_INIT(ifp)	\
37121495Sjmacd	rw_init(&(ifp)->if_afdata_lock, "if_afdata")
37221495Sjmacd
37321495Sjmacd#define	IF_AFDATA_WLOCK(ifp)	rw_wlock(&(ifp)->if_afdata_lock)
37421495Sjmacd#define	IF_AFDATA_RLOCK(ifp)	rw_rlock(&(ifp)->if_afdata_lock)
37521495Sjmacd#define	IF_AFDATA_WUNLOCK(ifp)	rw_wunlock(&(ifp)->if_afdata_lock)
37621495Sjmacd#define	IF_AFDATA_RUNLOCK(ifp)	rw_runlock(&(ifp)->if_afdata_lock)
37721495Sjmacd#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
37821495Sjmacd#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
37921495Sjmacd#define	IF_AFDATA_TRYLOCK(ifp)	rw_try_wlock(&(ifp)->if_afdata_lock)
38021495Sjmacd#define	IF_AFDATA_DESTROY(ifp)	rw_destroy(&(ifp)->if_afdata_lock)
38121495Sjmacd
38221495Sjmacd#define	IF_AFDATA_LOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
38321495Sjmacd#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
38421495Sjmacd
38521495Sjmacdint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
38621495Sjmacd	    int adjust);
38721495Sjmacd#define	IF_HANDOFF(ifq, m, ifp)			\
38821495Sjmacd	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
38921495Sjmacd#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
39021495Sjmacd	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
39121495Sjmacd
39221495Sjmacdvoid	if_start(struct ifnet *);
39321495Sjmacd
39421495Sjmacd#define	IFQ_ENQUEUE(ifq, m, err)					\
39521495Sjmacddo {									\
39621495Sjmacd	IF_LOCK(ifq);							\
39721495Sjmacd	if (ALTQ_IS_ENABLED(ifq))					\
39821495Sjmacd		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
39921495Sjmacd	else {								\
40021495Sjmacd		if (_IF_QFULL(ifq)) {					\
40121495Sjmacd			m_freem(m);					\
40221495Sjmacd			(err) = ENOBUFS;				\
40321495Sjmacd		} else {						\
40421495Sjmacd			_IF_ENQUEUE(ifq, m);				\
40521495Sjmacd			(err) = 0;					\
40621495Sjmacd		}							\
40721495Sjmacd	}								\
40821495Sjmacd	if (err)							\
40921495Sjmacd		(ifq)->ifq_drops++;					\
41021495Sjmacd	IF_UNLOCK(ifq);							\
41121495Sjmacd} while (0)
41221495Sjmacd
41321495Sjmacd#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
41421495Sjmacddo {									\
41521495Sjmacd	if (TBR_IS_ENABLED(ifq))					\
41621495Sjmacd		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
41721495Sjmacd	else if (ALTQ_IS_ENABLED(ifq))					\
41821495Sjmacd		ALTQ_DEQUEUE(ifq, m);					\
41921495Sjmacd	else								\
42021495Sjmacd		_IF_DEQUEUE(ifq, m);					\
42121495Sjmacd} while (0)
42221495Sjmacd
42321495Sjmacd#define	IFQ_DEQUEUE(ifq, m)						\
42421495Sjmacddo {									\
42521495Sjmacd	IF_LOCK(ifq);							\
42621495Sjmacd	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
42721495Sjmacd	IF_UNLOCK(ifq);							\
42821495Sjmacd} while (0)
42921495Sjmacd
43021495Sjmacd#define	IFQ_POLL_NOLOCK(ifq, m)						\
43121495Sjmacddo {									\
43221495Sjmacd	if (TBR_IS_ENABLED(ifq))					\
43321495Sjmacd		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
43421495Sjmacd	else if (ALTQ_IS_ENABLED(ifq))					\
43521495Sjmacd		ALTQ_POLL(ifq, m);					\
43621495Sjmacd	else								\
43721495Sjmacd		_IF_POLL(ifq, m);					\
43821495Sjmacd} while (0)
43921495Sjmacd
44021495Sjmacd#define	IFQ_POLL(ifq, m)						\
44121495Sjmacddo {									\
44221495Sjmacd	IF_LOCK(ifq);							\
44321495Sjmacd	IFQ_POLL_NOLOCK(ifq, m);					\
44421495Sjmacd	IF_UNLOCK(ifq);							\
44521495Sjmacd} while (0)
44621495Sjmacd
44721495Sjmacd#define	IFQ_PURGE_NOLOCK(ifq)						\
44821495Sjmacddo {									\
44921495Sjmacd	if (ALTQ_IS_ENABLED(ifq)) {					\
45021495Sjmacd		ALTQ_PURGE(ifq);					\
45121495Sjmacd	} else								\
45221495Sjmacd		_IF_DRAIN(ifq);						\
45321495Sjmacd} while (0)
45421495Sjmacd
45521495Sjmacd#define	IFQ_PURGE(ifq)							\
45621495Sjmacddo {									\
45721495Sjmacd	IF_LOCK(ifq);							\
45821495Sjmacd	IFQ_PURGE_NOLOCK(ifq);						\
45921495Sjmacd	IF_UNLOCK(ifq);							\
46021495Sjmacd} while (0)
46121495Sjmacd
46221495Sjmacd#define	IFQ_SET_READY(ifq)						\
46321495Sjmacd	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
46421495Sjmacd
46521495Sjmacd#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
46621495Sjmacd#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
46721495Sjmacd#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
46821495Sjmacd#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
46921495Sjmacd#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
47021495Sjmacd#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
47121495Sjmacd#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
47221495Sjmacd#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
47321495Sjmacd
47421495Sjmacd/*
47521495Sjmacd * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
47621495Sjmacd * the handoff logic, as that flag is locked by the device driver.
47721495Sjmacd */
47821495Sjmacd#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
47921495Sjmacddo {									\
48021495Sjmacd	int len;							\
48121495Sjmacd	short mflags;							\
48221495Sjmacd									\
48321495Sjmacd	len = (m)->m_pkthdr.len;					\
48421495Sjmacd	mflags = (m)->m_flags;						\
48521495Sjmacd	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
48621495Sjmacd	if ((err) == 0) {						\
48721495Sjmacd		(ifp)->if_obytes += len + (adj);			\
48821495Sjmacd		if (mflags & M_MCAST)					\
48921495Sjmacd			(ifp)->if_omcasts++;				\
49021495Sjmacd		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
49121495Sjmacd			if_start(ifp);					\
49221495Sjmacd	}								\
49321495Sjmacd} while (0)
49421495Sjmacd
49521495Sjmacd#define	IFQ_HANDOFF(ifp, m, err)					\
49621495Sjmacd	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
49721495Sjmacd
49821495Sjmacd#define	IFQ_DRV_DEQUEUE(ifq, m)						\
49921495Sjmacddo {									\
50021495Sjmacd	(m) = (ifq)->ifq_drv_head;					\
50121495Sjmacd	if (m) {							\
50221495Sjmacd		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
50321495Sjmacd			(ifq)->ifq_drv_tail = NULL;			\
50421495Sjmacd		(m)->m_nextpkt = NULL;					\
50521495Sjmacd		(ifq)->ifq_drv_len--;					\
50621495Sjmacd	} else {							\
50721495Sjmacd		IFQ_LOCK(ifq);						\
50821495Sjmacd		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
50921495Sjmacd		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
51021495Sjmacd			struct mbuf *m0;				\
51121495Sjmacd			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
51221495Sjmacd			if (m0 == NULL)					\
51321495Sjmacd				break;					\
51421495Sjmacd			m0->m_nextpkt = NULL;				\
51521495Sjmacd			if ((ifq)->ifq_drv_tail == NULL)		\
51621495Sjmacd				(ifq)->ifq_drv_head = m0;		\
51721495Sjmacd			else						\
51821495Sjmacd				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
51921495Sjmacd			(ifq)->ifq_drv_tail = m0;			\
52021495Sjmacd			(ifq)->ifq_drv_len++;				\
52121495Sjmacd		}							\
52221495Sjmacd		IFQ_UNLOCK(ifq);					\
52321495Sjmacd	}								\
52421495Sjmacd} while (0)
52521495Sjmacd
52621495Sjmacd#define	IFQ_DRV_PREPEND(ifq, m)						\
52721495Sjmacddo {									\
52821495Sjmacd	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
52921495Sjmacd	if ((ifq)->ifq_drv_tail == NULL)				\
53021495Sjmacd		(ifq)->ifq_drv_tail = (m);				\
53121495Sjmacd	(ifq)->ifq_drv_head = (m);					\
53221495Sjmacd	(ifq)->ifq_drv_len++;						\
53321495Sjmacd} while (0)
53421495Sjmacd
53521495Sjmacd#define	IFQ_DRV_IS_EMPTY(ifq)						\
53621495Sjmacd	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
53721495Sjmacd
53821495Sjmacd#define	IFQ_DRV_PURGE(ifq)						\
53921495Sjmacddo {									\
54021495Sjmacd	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
54121495Sjmacd	while((m = n) != NULL) {					\
54221495Sjmacd		n = m->m_nextpkt;					\
54321495Sjmacd		m_freem(m);						\
54421495Sjmacd	}								\
54521495Sjmacd	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
54621495Sjmacd	(ifq)->ifq_drv_len = 0;						\
54721495Sjmacd	IFQ_PURGE(ifq);							\
54821495Sjmacd} while (0)
54921495Sjmacd
55021495Sjmacd#ifdef _KERNEL
55121495Sjmacdstatic __inline void
55221495Sjmacddrbr_stats_update(struct ifnet *ifp, int len, int mflags)
55321495Sjmacd{
55421495Sjmacd
55521495Sjmacd	ifp->if_obytes += len;
55621495Sjmacd	if (mflags & M_MCAST)
55721495Sjmacd		ifp->if_omcasts++;
55821495Sjmacd}
55921495Sjmacd
56021495Sjmacdstatic __inline int
56121495Sjmacddrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
56221495Sjmacd{
56321495Sjmacd	int error = 0;
56421495Sjmacd	int len = m->m_pkthdr.len;
56521495Sjmacd	int mflags = m->m_flags;
56621495Sjmacd
56721495Sjmacd#ifdef ALTQ
56821495Sjmacd	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
56921495Sjmacd		IFQ_ENQUEUE(&ifp->if_snd, m, error);
57021495Sjmacd		return (error);
57121495Sjmacd	}
57221495Sjmacd#endif
57321495Sjmacd	if ((error = buf_ring_enqueue(br, m)) == ENOBUFS) {
57421495Sjmacd		br->br_drops++;
57521495Sjmacd		_IF_DROP(&ifp->if_snd);
57621495Sjmacd		m_freem(m);
57721495Sjmacd	} else
57821495Sjmacd		drbr_stats_update(ifp, len, mflags);
57921495Sjmacd
58021495Sjmacd	return (error);
58121495Sjmacd}
58221495Sjmacd
58321495Sjmacdstatic __inline void
58421495Sjmacddrbr_free(struct buf_ring *br, struct malloc_type *type)
58521495Sjmacd{
58621495Sjmacd	struct mbuf *m;
58721495Sjmacd
58821495Sjmacd	while ((m = buf_ring_dequeue_sc(br)) != NULL)
58921495Sjmacd		m_freem(m);
59021495Sjmacd
59121495Sjmacd	buf_ring_free(br, type);
59221495Sjmacd}
59321495Sjmacd
59421495Sjmacdstatic __inline struct mbuf *
59521495Sjmacddrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
59621495Sjmacd{
59721495Sjmacd#ifdef ALTQ
59821495Sjmacd	struct mbuf *m;
59921495Sjmacd
60021495Sjmacd	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
60121495Sjmacd		IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
60221495Sjmacd		return (m);
60321495Sjmacd	}
60421495Sjmacd#endif
60521495Sjmacd	return (buf_ring_dequeue_sc(br));
60621495Sjmacd}
60721495Sjmacd
60821495Sjmacdstatic __inline int
60921495Sjmacddrbr_empty(struct ifnet *ifp, struct buf_ring *br)
61021495Sjmacd{
61121495Sjmacd#ifdef ALTQ
61221495Sjmacd	if (ALTQ_IS_ENABLED(&ifp->if_snd))
61321495Sjmacd		return (IFQ_DRV_IS_EMPTY(&ifp->if_snd));
61421495Sjmacd#endif
61521495Sjmacd	return (buf_ring_empty(br));
61621495Sjmacd}
61721495Sjmacd#endif
61821495Sjmacd/*
61921495Sjmacd * 72 was chosen below because it is the size of a TCP/IP
62021495Sjmacd * header (40) + the minimum mss (32).
62121495Sjmacd */
62221495Sjmacd#define	IF_MINMTU	72
62321495Sjmacd#define	IF_MAXMTU	65535
62421495Sjmacd
62521495Sjmacd#endif /* _KERNEL */
62621495Sjmacd
62721495Sjmacd/*
62821495Sjmacd * The ifaddr structure contains information about one address
62921495Sjmacd * of an interface.  They are maintained by the different address families,
63021495Sjmacd * are allocated and attached when an address is set, and are linked
63121495Sjmacd * together so all addresses for an interface can be located.
63221495Sjmacd *
63321495Sjmacd * NOTE: a 'struct ifaddr' is always at the beginning of a larger
63421495Sjmacd * chunk of malloc'ed memory, where we store the three addresses
63521495Sjmacd * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
63621495Sjmacd */
63721495Sjmacdstruct ifaddr {
63821495Sjmacd	struct	sockaddr *ifa_addr;	/* address of interface */
63921495Sjmacd	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
64021495Sjmacd#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
64121495Sjmacd	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
64221495Sjmacd	struct	if_data if_data;	/* not all members are meaningful */
64321495Sjmacd	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
64421495Sjmacd	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
64521495Sjmacd	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
64621495Sjmacd		(int, struct rtentry *, struct rt_addrinfo *);
64721495Sjmacd	u_short	ifa_flags;		/* mostly rt_flags for cloning */
64821495Sjmacd	u_int	ifa_refcnt;		/* references to this structure */
64921495Sjmacd	int	ifa_metric;		/* cost of going out this interface */
65021495Sjmacd	int (*ifa_claim_addr)		/* check if an addr goes to this if */
65121495Sjmacd		(struct ifaddr *, struct sockaddr *);
65221495Sjmacd	struct mtx ifa_mtx;
65321495Sjmacd};
65421495Sjmacd#define	IFA_ROUTE	RTF_UP		/* route installed */
65521495Sjmacd
65621495Sjmacd/* for compatibility with other BSDs */
65721495Sjmacd#define	ifa_list	ifa_link
65821495Sjmacd
65921495Sjmacd#define	IFA_LOCK_INIT(ifa)	\
66021495Sjmacd    mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF)
66121495Sjmacd#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
66221495Sjmacd#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
66321495Sjmacd#define	IFA_DESTROY(ifa)	mtx_destroy(&(ifa)->ifa_mtx)
66421495Sjmacd
66521495Sjmacd/*
66621495Sjmacd * The prefix structure contains information about one prefix
66721495Sjmacd * of an interface.  They are maintained by the different address families,
66821495Sjmacd * are allocated and attached when a prefix or an address is set,
66921495Sjmacd * and are linked together so all prefixes for an interface can be located.
67021495Sjmacd */
67121495Sjmacdstruct ifprefix {
67221495Sjmacd	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
67321495Sjmacd	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
67421495Sjmacd	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
67521495Sjmacd	u_char	ifpr_plen;		/* prefix length in bits */
67621495Sjmacd	u_char	ifpr_type;		/* protocol dependent prefix type */
67721495Sjmacd};
67821495Sjmacd
67921495Sjmacd/*
68021495Sjmacd * Multicast address structure.  This is analogous to the ifaddr
68121495Sjmacd * structure except that it keeps track of multicast addresses.
68221495Sjmacd */
68321495Sjmacdstruct ifmultiaddr {
68421495Sjmacd	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
68521495Sjmacd	struct	sockaddr *ifma_addr; 	/* address this membership is for */
68621495Sjmacd	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
68721495Sjmacd	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
68821495Sjmacd	u_int	ifma_refcount;		/* reference count */
68921495Sjmacd	void	*ifma_protospec;	/* protocol-specific state, if any */
69021495Sjmacd	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
69121495Sjmacd};
69221495Sjmacd
69321495Sjmacd#ifdef _KERNEL
69421495Sjmacd#define	IFAFREE(ifa)					\
69521495Sjmacd	do {						\
69621495Sjmacd		IFA_LOCK(ifa);				\
69721495Sjmacd		KASSERT((ifa)->ifa_refcnt > 0,		\
69821495Sjmacd		    ("ifa %p !(ifa_refcnt > 0)", ifa));	\
69921495Sjmacd		if (--(ifa)->ifa_refcnt == 0) {		\
70021495Sjmacd			IFA_DESTROY(ifa);		\
70121495Sjmacd			free(ifa, M_IFADDR);		\
70221495Sjmacd		} else 					\
70321495Sjmacd			IFA_UNLOCK(ifa);		\
70421495Sjmacd	} while (0)
70521495Sjmacd
70621495Sjmacd#define IFAREF(ifa)					\
70721495Sjmacd	do {						\
70821495Sjmacd		IFA_LOCK(ifa);				\
70921495Sjmacd		++(ifa)->ifa_refcnt;			\
71021495Sjmacd		IFA_UNLOCK(ifa);			\
71121495Sjmacd	} while (0)
71221495Sjmacd
71321495Sjmacdextern	struct rwlock ifnet_lock;
71421495Sjmacd#define	IFNET_LOCK_INIT() \
71521495Sjmacd   rw_init_flags(&ifnet_lock, "ifnet",  RW_RECURSE)
71621495Sjmacd#define	IFNET_WLOCK()		rw_wlock(&ifnet_lock)
71721495Sjmacd#define	IFNET_WUNLOCK()		rw_wunlock(&ifnet_lock)
71821495Sjmacd#define	IFNET_WLOCK_ASSERT()	rw_assert(&ifnet_lock, RA_LOCKED)
71921495Sjmacd#define	IFNET_RLOCK()		rw_rlock(&ifnet_lock)
72021495Sjmacd#define	IFNET_RUNLOCK()		rw_runlock(&ifnet_lock)
72121495Sjmacd
72221495Sjmacdstruct ifindex_entry {
72321495Sjmacd	struct	ifnet *ife_ifnet;
72421495Sjmacd	struct cdev *ife_dev;
72521495Sjmacd};
72621495Sjmacd
72721495Sjmacd/*
72821495Sjmacd * Look up an ifnet given its index; the _ref variant also acquires a
72921495Sjmacd * reference that must be freed using if_rele().  It is almost always a bug
73021495Sjmacd * to call ifnet_byindex() instead if ifnet_byindex_ref().
73121495Sjmacd */
73221495Sjmacdstruct ifnet	*ifnet_byindex(u_short idx);
73321495Sjmacdstruct ifnet	*ifnet_byindex_ref(u_short idx);
73421495Sjmacd
73521495Sjmacd/*
73621495Sjmacd * Given the index, ifaddr_byindex() returns the one and only
73721495Sjmacd * link-level ifaddr for the interface. You are not supposed to use
73821495Sjmacd * it to traverse the list of addresses associated to the interface.
73921495Sjmacd */
74021495Sjmacdstruct ifaddr	*ifaddr_byindex(u_short idx);
74121495Sjmacdstruct cdev	*ifdev_byindex(u_short idx);
74221495Sjmacd
74321495Sjmacd#ifdef VIMAGE_GLOBALS
74421495Sjmacdextern	struct ifnethead ifnet;
74521495Sjmacdextern	struct ifnet *loif;	/* first loopback interface */
74621495Sjmacdextern	int if_index;
74721495Sjmacd#endif
74821495Sjmacdextern	int ifqmaxlen;
74921495Sjmacd
75021495Sjmacdint	if_addgroup(struct ifnet *, const char *);
75121495Sjmacdint	if_delgroup(struct ifnet *, const char *);
75221495Sjmacdint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
75321495Sjmacdint	if_allmulti(struct ifnet *, int);
75421495Sjmacdstruct	ifnet* if_alloc(u_char);
75521495Sjmacdvoid	if_attach(struct ifnet *);
75621495Sjmacdvoid	if_dead(struct ifnet *);
75721495Sjmacdint	if_delmulti(struct ifnet *, struct sockaddr *);
75821495Sjmacdvoid	if_delmulti_ifma(struct ifmultiaddr *);
75921495Sjmacdvoid	if_detach(struct ifnet *);
76021495Sjmacdvoid	if_purgeaddrs(struct ifnet *);
76121495Sjmacdvoid	if_purgemaddrs(struct ifnet *);
76221495Sjmacdvoid	if_down(struct ifnet *);
76321495Sjmacdstruct ifmultiaddr *
76421495Sjmacd	if_findmulti(struct ifnet *, struct sockaddr *);
76521495Sjmacdvoid	if_free(struct ifnet *);
76621495Sjmacdvoid	if_free_type(struct ifnet *, u_char);
76721495Sjmacdvoid	if_initname(struct ifnet *, const char *, int);
76821495Sjmacdvoid	if_link_state_change(struct ifnet *, int);
76921495Sjmacdint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
77021495Sjmacdvoid	if_qflush(struct ifnet *);
77121495Sjmacdvoid	if_ref(struct ifnet *);
772void	if_rele(struct ifnet *);
773int	if_setlladdr(struct ifnet *, const u_char *, int);
774void	if_up(struct ifnet *);
775/*void	ifinit(void);*/ /* declared in systm.h for main() */
776int	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
777int	ifpromisc(struct ifnet *, int);
778struct	ifnet *ifunit(const char *);
779
780void	ifq_attach(struct ifaltq *, struct ifnet *ifp);
781void	ifq_detach(struct ifaltq *);
782
783struct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
784struct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
785struct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
786struct	ifaddr *ifa_ifwithnet(struct sockaddr *);
787struct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
788struct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
789
790struct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
791
792int	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
793
794typedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
795typedef	void if_com_free_t(void *com, u_char type);
796void	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
797void	if_deregister_com_alloc(u_char type);
798
799#define IF_LLADDR(ifp)							\
800    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
801
802#ifdef DEVICE_POLLING
803enum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
804
805typedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
806int    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
807int    ether_poll_deregister(struct ifnet *ifp);
808#endif /* DEVICE_POLLING */
809
810#endif /* _KERNEL */
811
812#endif /* !_NET_IF_VAR_H_ */
813