1139823Simp/*-
221259Swollman * Copyright (c) 1982, 1986, 1989, 1993
321259Swollman *	The Regents of the University of California.  All rights reserved.
421259Swollman *
521259Swollman * Redistribution and use in source and binary forms, with or without
621259Swollman * modification, are permitted provided that the following conditions
721259Swollman * are met:
821259Swollman * 1. Redistributions of source code must retain the above copyright
921259Swollman *    notice, this list of conditions and the following disclaimer.
1021259Swollman * 2. Redistributions in binary form must reproduce the above copyright
1121259Swollman *    notice, this list of conditions and the following disclaimer in the
1221259Swollman *    documentation and/or other materials provided with the distribution.
1321259Swollman * 4. Neither the name of the University nor the names of its contributors
1421259Swollman *    may be used to endorse or promote products derived from this software
1521259Swollman *    without specific prior written permission.
1621259Swollman *
1721259Swollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1821259Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1921259Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2021259Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2121259Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2221259Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2321259Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2421259Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2521259Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2621259Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2721259Swollman * SUCH DAMAGE.
2821259Swollman *
2921259Swollman *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3050477Speter * $FreeBSD: stable/10/sys/net/if_var.h 318505 2017-05-18 23:41:34Z rpokala $
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;
72228571Sglebiusstruct	carp_softc;
73155051Sglebiusstruct  ifvlantrunk;
74191148Skmacystruct	route;
75193731Szecstruct	vnet;
7621259Swollman#endif
7721259Swollman
7821259Swollman#include <sys/queue.h>		/* get TAILQ macros */
7921259Swollman
8069224Sjlemon#ifdef _KERNEL
8169152Sjlemon#include <sys/mbuf.h>
82126264Smlaier#include <sys/eventhandler.h>
83186207Skmacy#include <sys/buf_ring.h>
84195699Srwatson#include <net/vnet.h>
8569224Sjlemon#endif /* _KERNEL */
8674914Sjhb#include <sys/lock.h>		/* XXX */
8774914Sjhb#include <sys/mutex.h>		/* XXX */
88186199Skmacy#include <sys/rwlock.h>		/* XXX */
89196481Srwatson#include <sys/sx.h>		/* XXX */
9083130Sjlemon#include <sys/event.h>		/* XXX */
91132712Srwatson#include <sys/_task.h>
9269152Sjlemon
93121816Sbrooks#define	IF_DUNIT_NONE	-1
94121816Sbrooks
95130416Smlaier#include <altq/if_altq.h>
96130416Smlaier
9760938SjakeTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
9860938SjakeTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
9972084SphkTAILQ_HEAD(ifmultihead, ifmultiaddr);
100159781SmlaierTAILQ_HEAD(ifgrouphead, ifg_group);
10121259Swollman
102240112Smelifaro#ifdef _KERNEL
103240099SmelifaroVNET_DECLARE(struct pfil_head, link_pfil_hook);	/* packet filter hooks */
104240099Smelifaro#define	V_link_pfil_hook	VNET(link_pfil_hook)
105240112Smelifaro#endif /* _KERNEL */
106240099Smelifaro
107276124Saetypedef enum {
108276124Sae	IFCOUNTER_IPACKETS = 0,
109276124Sae	IFCOUNTER_IERRORS,
110276124Sae	IFCOUNTER_OPACKETS,
111276124Sae	IFCOUNTER_OERRORS,
112276124Sae	IFCOUNTER_COLLISIONS,
113276124Sae	IFCOUNTER_IBYTES,
114276124Sae	IFCOUNTER_OBYTES,
115276124Sae	IFCOUNTER_IMCASTS,
116276124Sae	IFCOUNTER_OMCASTS,
117276124Sae	IFCOUNTER_IQDROPS,
118276124Sae	IFCOUNTER_OQDROPS,
119276124Sae	IFCOUNTER_NOPROTO,
120276124Sae	IFCOUNTERS /* Array size. */
121276124Sae} ift_counter;
122276124Sae
12321259Swollman/*
12421259Swollman * Structure defining a queue for a network interface.
12521259Swollman */
12621259Swollmanstruct	ifqueue {
12721259Swollman	struct	mbuf *ifq_head;
12821259Swollman	struct	mbuf *ifq_tail;
12921259Swollman	int	ifq_len;
13021259Swollman	int	ifq_maxlen;
13121259Swollman	int	ifq_drops;
13269152Sjlemon	struct	mtx ifq_mtx;
13321259Swollman};
13421259Swollman
135274043Shselaskystruct ifnet_hw_tsomax {
136274043Shselasky	u_int	tsomaxbytes;	/* TSO total burst length limit in bytes */
137274043Shselasky	u_int	tsomaxsegcount;	/* TSO maximum segment count */
138274043Shselasky	u_int	tsomaxsegsize;	/* TSO maximum segment size in bytes */
139274043Shselasky};
140274043Shselasky
14121259Swollman/*
14221259Swollman * Structure defining a network interface.
14321259Swollman *
14421259Swollman * (Would like to call this struct ``if'', but C isn't PL/1.)
14521259Swollman */
14684380Smjacob
14721259Swollmanstruct ifnet {
14821259Swollman	void	*if_softc;		/* pointer to driver state */
149147256Sbrooks	void	*if_l2com;		/* pointer to protocol bits */
150191688Szec	struct vnet *if_vnet;		/* pointer to network stack instance */
15160938Sjake	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
152121816Sbrooks	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
153121816Sbrooks	const char *if_dname;		/* driver name */
154121816Sbrooks	int	if_dunit;		/* unit or IF_DUNIT_NONE */
155191367Srwatson	u_int	if_refcount;		/* reference count */
15621259Swollman	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
157128291Sluigi		/*
158128291Sluigi		 * if_addrhead is the list of all addresses associated to
159128315Sluigi		 * an interface.
160128315Sluigi		 * Some code in the kernel assumes that first element
161128315Sluigi		 * of the list has type AF_LINK, and contains sockaddr_dl
162128315Sluigi		 * addresses which store the link-level address and the name
163128291Sluigi		 * of the interface.
164128315Sluigi		 * However, access to the AF_LINK address through this
165152315Sru		 * field is deprecated. Use if_addr or ifaddr_byindex() instead.
166128291Sluigi		 */
16783130Sjlemon	int	if_pcount;		/* number of promiscuous listeners */
168142901Sglebius	struct	carp_if *if_carp;	/* carp interface structure */
16921259Swollman	struct	bpf_if *if_bpf;		/* packet filter structure */
17021259Swollman	u_short	if_index;		/* numeric abbreviation for this if  */
171199975Sjhb	short	if_index_reserved;	/* spare space to grow if_index */
172155051Sglebius	struct  ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */
173102052Ssobomax	int	if_flags;		/* up/down, broadcast, etc. */
174162070Sandre	int	if_capabilities;	/* interface features & capabilities */
175162070Sandre	int	if_capenable;		/* enabled features & capabilities */
17621259Swollman	void	*if_linkmib;		/* link-type-specific MIB data */
17721259Swollman	size_t	if_linkmiblen;		/* length of above data */
17821259Swollman	struct	if_data if_data;
17921404Swollman	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
18021404Swollman	int	if_amcount;		/* number of all-multicast requests */
18121259Swollman/* procedure handles */
18221259Swollman	int	(*if_output)		/* output routine (enqueue) */
183249925Sglebius		(struct ifnet *, struct mbuf *, const struct sockaddr *,
184191148Skmacy		     struct route *);
185106931Ssam	void	(*if_input)		/* input routine (from h/w driver) */
186106931Ssam		(struct ifnet *, struct mbuf *);
18721259Swollman	void	(*if_start)		/* initiate output routine */
18892725Salfred		(struct ifnet *);
18921259Swollman	int	(*if_ioctl)		/* ioctl routine */
19092725Salfred		(struct ifnet *, u_long, caddr_t);
19121259Swollman	void	(*if_init)		/* Init routine */
19292725Salfred		(void *);
19321404Swollman	int	(*if_resolvemulti)	/* validate/resolve multicast */
19492725Salfred		(struct ifnet *, struct sockaddr **, struct sockaddr *);
195189230Srwatson	void	(*if_qflush)		/* flush any queues */
196189230Srwatson		(struct ifnet *);
197189230Srwatson	int	(*if_transmit)		/* initiate output routine */
198189230Srwatson		(struct ifnet *, struct mbuf *);
199193731Szec	void	(*if_reassign)		/* reassign to vnet routine */
200193731Szec		(struct ifnet *, struct vnet *, char *);
201193731Szec	struct	vnet *if_home_vnet;	/* where this ifnet originates from */
202152315Sru	struct	ifaddr	*if_addr;	/* pointer to link-level address */
203174388Skmacy	void	*if_llsoftc;		/* link layer softc */
204148265Srwatson	int	if_drv_flags;		/* driver-managed status flags */
205130416Smlaier	struct  ifaltq if_snd;		/* output queue (includes altq) */
206123220Simp	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
207127828Sluigi
208146986Sthompsa	void	*if_bridge;		/* bridge glue */
209146986Sthompsa
210122524Srwatson	struct	label *if_label;	/* interface MAC label */
211121161Sume
212127828Sluigi	/* these are only used by IPv6 */
213231229Spluknet	void	*if_unused[2];
214121161Sume	void	*if_afdata[AF_MAX];
215121470Sume	int	if_afdata_initialized;
216250300Sandre	struct	rwlock if_afdata_lock;
217145320Sglebius	struct	task if_linktask;	/* task for link change events */
218250300Sandre	struct	rwlock if_addr_lock;	/* lock to protect address lists */
219186119Sqingli
220152209Sthompsa	LIST_ENTRY(ifnet) if_clones;	/* interfaces of a cloner */
221159781Smlaier	TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
222229873Sjhb					/* protected by if_addr_lock */
223159781Smlaier	void	*if_pf_kif;
224168793Sthompsa	void	*if_lagg;		/* lagg glue */
225224151Sbz	char	*if_description;	/* interface description */
226224151Sbz	u_int	if_fib;			/* interface FIB */
227223739Sbz	u_char	if_alloctype;		/* if_type at time of allocation */
228189230Srwatson
229274704Shselasky	/*
230274704Shselasky	 * Network adapter TSO limits:
231274704Shselasky	 * ===========================
232274704Shselasky	 *
233274704Shselasky	 * If the "if_hw_tsomax" field is zero the maximum segment
234274704Shselasky	 * length limit does not apply. If the "if_hw_tsomaxsegcount"
235274704Shselasky	 * or the "if_hw_tsomaxsegsize" field is zero the TSO segment
236274704Shselasky	 * count limit does not apply. If all three fields are zero,
237274704Shselasky	 * there is no TSO limit.
238274704Shselasky	 *
239289020Shselasky	 * NOTE: The TSO limits should reflect the values used in the
240289020Shselasky	 * BUSDMA tag a network adapter is using to load a mbuf chain
241289020Shselasky	 * for transmission. The TCP/IP network stack will subtract
242289020Shselasky	 * space for all linklevel and protocol level headers and
243289020Shselasky	 * ensure that the full mbuf chain passed to the network
244289020Shselasky	 * adapter fits within the given limits.
245274704Shselasky	 */
246274704Shselasky	u_int	if_hw_tsomax;
247251296Sandre
248189230Srwatson	/*
249189230Srwatson	 * Spare fields are added so that we can modify sensitive data
250189230Srwatson	 * structures without changing the kernel binary interface, and must
251189230Srwatson	 * be used with care where binary compatibility is required.
252189230Srwatson	 */
253223739Sbz	char	if_cspare[3];
254274043Shselasky	int	if_ispare[2];
255274043Shselasky
256274043Shselasky	/*
257274043Shselasky	 * TSO fields for segment limits. If a field is zero below,
258274043Shselasky	 * there is no limit:
259274043Shselasky	 */
260274043Shselasky	u_int	if_hw_tsomaxsegcount;	/* TSO maximum segment count */
261274043Shselasky	u_int	if_hw_tsomaxsegsize;	/* TSO maximum segment size in bytes */
262318505Srpokala	void	*if_pspare[7];		/* 1 netmap, 6 TDB */
263318505Srpokala	void	*if_hw_addr;		/* hardware link-level address */
26421259Swollman};
26569152Sjlemon
26692725Salfredtypedef void if_init_f_t(void *);
26721259Swollman
268128376Sluigi/*
269128376Sluigi * XXX These aliases are terribly dangerous because they could apply
270128376Sluigi * to anything.
271128376Sluigi */
27221259Swollman#define	if_mtu		if_data.ifi_mtu
27321259Swollman#define	if_type		if_data.ifi_type
27421259Swollman#define if_physical	if_data.ifi_physical
27521259Swollman#define	if_addrlen	if_data.ifi_addrlen
27621259Swollman#define	if_hdrlen	if_data.ifi_hdrlen
27721259Swollman#define	if_metric	if_data.ifi_metric
278128871Sandre#define	if_link_state	if_data.ifi_link_state
27921259Swollman#define	if_baudrate	if_data.ifi_baudrate
280241616Semax#define	if_baudrate_pf	if_data.ifi_baudrate_pf
28158698Sjlemon#define	if_hwassist	if_data.ifi_hwassist
28221259Swollman#define	if_ipackets	if_data.ifi_ipackets
28321259Swollman#define	if_ierrors	if_data.ifi_ierrors
28421259Swollman#define	if_opackets	if_data.ifi_opackets
28521259Swollman#define	if_oerrors	if_data.ifi_oerrors
28621259Swollman#define	if_collisions	if_data.ifi_collisions
28721259Swollman#define	if_ibytes	if_data.ifi_ibytes
28821259Swollman#define	if_obytes	if_data.ifi_obytes
28921259Swollman#define	if_imcasts	if_data.ifi_imcasts
29021259Swollman#define	if_omcasts	if_data.ifi_omcasts
29121259Swollman#define	if_iqdrops	if_data.ifi_iqdrops
29221259Swollman#define	if_noproto	if_data.ifi_noproto
29321259Swollman#define	if_lastchange	if_data.ifi_lastchange
29421259Swollman
29553541Sshin/* for compatibility with other BSDs */
29653541Sshin#define	if_addrlist	if_addrhead
29753541Sshin#define	if_list		if_link
298160981Sbrooks#define	if_name(ifp)	((ifp)->if_xname)
29953541Sshin
30021259Swollman/*
301148640Srwatson * Locks for address lists on the network interface.
302148640Srwatson */
303229873Sjhb#define	IF_ADDR_LOCK_INIT(if)	rw_init(&(if)->if_addr_lock, "if_addr_lock")
304229873Sjhb#define	IF_ADDR_LOCK_DESTROY(if)	rw_destroy(&(if)->if_addr_lock)
305229873Sjhb#define	IF_ADDR_WLOCK(if)	rw_wlock(&(if)->if_addr_lock)
306229873Sjhb#define	IF_ADDR_WUNLOCK(if)	rw_wunlock(&(if)->if_addr_lock)
307229873Sjhb#define	IF_ADDR_RLOCK(if)	rw_rlock(&(if)->if_addr_lock)
308229873Sjhb#define	IF_ADDR_RUNLOCK(if)	rw_runlock(&(if)->if_addr_lock)
309229873Sjhb#define	IF_ADDR_LOCK_ASSERT(if)	rw_assert(&(if)->if_addr_lock, RA_LOCKED)
310229873Sjhb#define	IF_ADDR_WLOCK_ASSERT(if) rw_assert(&(if)->if_addr_lock, RA_WLOCKED)
311148640Srwatson
312148640Srwatson/*
313195020Srwatson * Function variations on locking macros intended to be used by loadable
314195020Srwatson * kernel modules in order to divorce them from the internals of address list
315195020Srwatson * locking.
316195020Srwatson */
317195020Srwatsonvoid	if_addr_rlock(struct ifnet *ifp);	/* if_addrhead */
318195020Srwatsonvoid	if_addr_runlock(struct ifnet *ifp);	/* if_addrhead */
319195020Srwatsonvoid	if_maddr_rlock(struct ifnet *ifp);	/* if_multiaddrs */
320195020Srwatsonvoid	if_maddr_runlock(struct ifnet *ifp);	/* if_multiaddrs */
321195020Srwatson
322195020Srwatson/*
32321259Swollman * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
32421259Swollman * are queues of messages stored on ifqueue structures
32521259Swollman * (defined above).  Entries are added to and deleted from these structures
326241686Sandre * by these macros.
32721259Swollman */
32872200Sbmilekic#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
32972200Sbmilekic#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
330130416Smlaier#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
33169152Sjlemon#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
33269152Sjlemon#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
33369152Sjlemon#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
33421259Swollman
33569152Sjlemon#define	_IF_ENQUEUE(ifq, m) do { 				\
33669152Sjlemon	(m)->m_nextpkt = NULL;					\
33769152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
33869152Sjlemon		(ifq)->ifq_head = m; 				\
33969152Sjlemon	else 							\
34069152Sjlemon		(ifq)->ifq_tail->m_nextpkt = m; 		\
34169152Sjlemon	(ifq)->ifq_tail = m; 					\
34269152Sjlemon	(ifq)->ifq_len++; 					\
34369152Sjlemon} while (0)
34469152Sjlemon
34569152Sjlemon#define IF_ENQUEUE(ifq, m) do {					\
34669152Sjlemon	IF_LOCK(ifq); 						\
34769152Sjlemon	_IF_ENQUEUE(ifq, m); 					\
34869152Sjlemon	IF_UNLOCK(ifq); 					\
34969152Sjlemon} while (0)
35069152Sjlemon
35169152Sjlemon#define	_IF_PREPEND(ifq, m) do {				\
35269152Sjlemon	(m)->m_nextpkt = (ifq)->ifq_head; 			\
35369152Sjlemon	if ((ifq)->ifq_tail == NULL) 				\
35469152Sjlemon		(ifq)->ifq_tail = (m); 				\
35569152Sjlemon	(ifq)->ifq_head = (m); 					\
35669152Sjlemon	(ifq)->ifq_len++; 					\
35769152Sjlemon} while (0)
35869152Sjlemon
35969152Sjlemon#define IF_PREPEND(ifq, m) do {		 			\
36069152Sjlemon	IF_LOCK(ifq); 						\
36169152Sjlemon	_IF_PREPEND(ifq, m); 					\
36269152Sjlemon	IF_UNLOCK(ifq); 					\
36369152Sjlemon} while (0)
36469152Sjlemon
36569152Sjlemon#define	_IF_DEQUEUE(ifq, m) do { 				\
36669152Sjlemon	(m) = (ifq)->ifq_head; 					\
36769152Sjlemon	if (m) { 						\
368136950Sjmg		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
36969152Sjlemon			(ifq)->ifq_tail = NULL; 		\
37069152Sjlemon		(m)->m_nextpkt = NULL; 				\
37169152Sjlemon		(ifq)->ifq_len--; 				\
37269152Sjlemon	} 							\
37369152Sjlemon} while (0)
37469152Sjlemon
37569152Sjlemon#define IF_DEQUEUE(ifq, m) do { 				\
37669152Sjlemon	IF_LOCK(ifq); 						\
37769152Sjlemon	_IF_DEQUEUE(ifq, m); 					\
37869152Sjlemon	IF_UNLOCK(ifq); 					\
37969152Sjlemon} while (0)
38069152Sjlemon
381226830Sglebius#define	_IF_DEQUEUE_ALL(ifq, m) do {				\
382226830Sglebius	(m) = (ifq)->ifq_head;					\
383226830Sglebius	(ifq)->ifq_head = (ifq)->ifq_tail = NULL;		\
384226830Sglebius	(ifq)->ifq_len = 0;					\
385226830Sglebius} while (0)
386226830Sglebius
387226830Sglebius#define	IF_DEQUEUE_ALL(ifq, m) do {				\
388226830Sglebius	IF_LOCK(ifq); 						\
389226830Sglebius	_IF_DEQUEUE_ALL(ifq, m);				\
390226830Sglebius	IF_UNLOCK(ifq); 					\
391226830Sglebius} while (0)
392226830Sglebius
393130416Smlaier#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
394130416Smlaier#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
395130416Smlaier
396130416Smlaier#define _IF_DRAIN(ifq) do { 					\
39769152Sjlemon	struct mbuf *m; 					\
39869152Sjlemon	for (;;) { 						\
39969152Sjlemon		_IF_DEQUEUE(ifq, m); 				\
40069152Sjlemon		if (m == NULL) 					\
40169152Sjlemon			break; 					\
40269152Sjlemon		m_freem(m); 					\
40369152Sjlemon	} 							\
40469152Sjlemon} while (0)
40569152Sjlemon
406130416Smlaier#define IF_DRAIN(ifq) do {					\
407130416Smlaier	IF_LOCK(ifq);						\
408130416Smlaier	_IF_DRAIN(ifq);						\
409130416Smlaier	IF_UNLOCK(ifq);						\
410130416Smlaier} while(0)
411130416Smlaier
41255205Speter#ifdef _KERNEL
413202588Sthompsa/* interface link layer address change event */
414202588Sthompsatypedef void (*iflladdr_event_handler_t)(void *, struct ifnet *);
415202588SthompsaEVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t);
416126264Smlaier/* interface address change event */
417126264Smlaiertypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
418126264SmlaierEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
419126264Smlaier/* new interface arrival event */
420126264Smlaiertypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
421126264SmlaierEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
422126264Smlaier/* interface departure event */
423126264Smlaiertypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
424126264SmlaierEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
425219819Sjeff/* Interface link state change event */
426219819Sjefftypedef void (*ifnet_link_event_handler_t)(void *, struct ifnet *, int);
427219819SjeffEVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t);
428314122Sdexuan/* Interface up/down event */
429314122Sdexuan#define IFNET_EVENT_UP		0
430314122Sdexuan#define IFNET_EVENT_DOWN	1
431314122Sdexuantypedef void (*ifnet_event_fn)(void *, struct ifnet *ifp, int event);
432314122SdexuanEVENTHANDLER_DECLARE(ifnet_event, ifnet_event_fn);
433126264Smlaier
434159781Smlaier/*
435159781Smlaier * interface groups
436159781Smlaier */
437159781Smlaierstruct ifg_group {
438159781Smlaier	char				 ifg_group[IFNAMSIZ];
439159781Smlaier	u_int				 ifg_refcnt;
440159781Smlaier	void				*ifg_pf_kif;
441159781Smlaier	TAILQ_HEAD(, ifg_member)	 ifg_members;
442159781Smlaier	TAILQ_ENTRY(ifg_group)		 ifg_next;
443159781Smlaier};
444159781Smlaier
445159781Smlaierstruct ifg_member {
446159781Smlaier	TAILQ_ENTRY(ifg_member)	 ifgm_next;
447159781Smlaier	struct ifnet		*ifgm_ifp;
448159781Smlaier};
449159781Smlaier
450159781Smlaierstruct ifg_list {
451159781Smlaier	struct ifg_group	*ifgl_group;
452159781Smlaier	TAILQ_ENTRY(ifg_list)	 ifgl_next;
453159781Smlaier};
454159781Smlaier
455159781Smlaier/* group attach event */
456159781Smlaiertypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
457159781SmlaierEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
458159781Smlaier/* group detach event */
459159781Smlaiertypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
460159781SmlaierEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
461159781Smlaier/* group change event */
462159781Smlaiertypedef void (*group_change_event_handler_t)(void *, const char *);
463159781SmlaierEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
464159781Smlaier
465121470Sume#define	IF_AFDATA_LOCK_INIT(ifp)	\
466186199Skmacy	rw_init(&(ifp)->if_afdata_lock, "if_afdata")
467121470Sume
468186199Skmacy#define	IF_AFDATA_WLOCK(ifp)	rw_wlock(&(ifp)->if_afdata_lock)
469186199Skmacy#define	IF_AFDATA_RLOCK(ifp)	rw_rlock(&(ifp)->if_afdata_lock)
470186199Skmacy#define	IF_AFDATA_WUNLOCK(ifp)	rw_wunlock(&(ifp)->if_afdata_lock)
471186199Skmacy#define	IF_AFDATA_RUNLOCK(ifp)	rw_runlock(&(ifp)->if_afdata_lock)
472186199Skmacy#define	IF_AFDATA_LOCK(ifp)	IF_AFDATA_WLOCK(ifp)
473186199Skmacy#define	IF_AFDATA_UNLOCK(ifp)	IF_AFDATA_WUNLOCK(ifp)
474186199Skmacy#define	IF_AFDATA_TRYLOCK(ifp)	rw_try_wlock(&(ifp)->if_afdata_lock)
475186199Skmacy#define	IF_AFDATA_DESTROY(ifp)	rw_destroy(&(ifp)->if_afdata_lock)
476186119Sqingli
477186199Skmacy#define	IF_AFDATA_LOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED)
478238990Sglebius#define	IF_AFDATA_RLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_RLOCKED)
479238990Sglebius#define	IF_AFDATA_WLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_WLOCKED)
480186199Skmacy#define	IF_AFDATA_UNLOCK_ASSERT(ifp)	rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED)
481186199Skmacy
482137065Srwatsonint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
483137065Srwatson	    int adjust);
484130416Smlaier#define	IF_HANDOFF(ifq, m, ifp)			\
485130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
486130416Smlaier#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
487130416Smlaier	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
48821259Swollman
489132712Srwatsonvoid	if_start(struct ifnet *);
490132712Srwatson
491130416Smlaier#define	IFQ_ENQUEUE(ifq, m, err)					\
492130416Smlaierdo {									\
493130416Smlaier	IF_LOCK(ifq);							\
494130416Smlaier	if (ALTQ_IS_ENABLED(ifq))					\
495130416Smlaier		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
496130416Smlaier	else {								\
497130416Smlaier		if (_IF_QFULL(ifq)) {					\
498130416Smlaier			m_freem(m);					\
499130416Smlaier			(err) = ENOBUFS;				\
500130416Smlaier		} else {						\
501130416Smlaier			_IF_ENQUEUE(ifq, m);				\
502130416Smlaier			(err) = 0;					\
503130416Smlaier		}							\
504130416Smlaier	}								\
505130416Smlaier	if (err)							\
506130416Smlaier		(ifq)->ifq_drops++;					\
507130416Smlaier	IF_UNLOCK(ifq);							\
508130416Smlaier} while (0)
50921259Swollman
510130416Smlaier#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
511130416Smlaierdo {									\
512130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
513130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
514130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
515130416Smlaier		ALTQ_DEQUEUE(ifq, m);					\
516130416Smlaier	else								\
517130416Smlaier		_IF_DEQUEUE(ifq, m);					\
518130416Smlaier} while (0)
519130416Smlaier
520130416Smlaier#define	IFQ_DEQUEUE(ifq, m)						\
521130416Smlaierdo {									\
522130416Smlaier	IF_LOCK(ifq);							\
523130416Smlaier	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
524130416Smlaier	IF_UNLOCK(ifq);							\
525130416Smlaier} while (0)
526130416Smlaier
527130416Smlaier#define	IFQ_POLL_NOLOCK(ifq, m)						\
528130416Smlaierdo {									\
529130416Smlaier	if (TBR_IS_ENABLED(ifq))					\
530130508Smlaier		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
531130416Smlaier	else if (ALTQ_IS_ENABLED(ifq))					\
532130416Smlaier		ALTQ_POLL(ifq, m);					\
533130416Smlaier	else								\
534130416Smlaier		_IF_POLL(ifq, m);					\
535130416Smlaier} while (0)
536130416Smlaier
537130416Smlaier#define	IFQ_POLL(ifq, m)						\
538130416Smlaierdo {									\
539130416Smlaier	IF_LOCK(ifq);							\
540130416Smlaier	IFQ_POLL_NOLOCK(ifq, m);					\
541130416Smlaier	IF_UNLOCK(ifq);							\
542130416Smlaier} while (0)
543130416Smlaier
544130416Smlaier#define	IFQ_PURGE_NOLOCK(ifq)						\
545130416Smlaierdo {									\
546130416Smlaier	if (ALTQ_IS_ENABLED(ifq)) {					\
547130416Smlaier		ALTQ_PURGE(ifq);					\
548130416Smlaier	} else								\
549130416Smlaier		_IF_DRAIN(ifq);						\
550130416Smlaier} while (0)
551130416Smlaier
552130416Smlaier#define	IFQ_PURGE(ifq)							\
553130416Smlaierdo {									\
554130416Smlaier	IF_LOCK(ifq);							\
555130416Smlaier	IFQ_PURGE_NOLOCK(ifq);						\
556130416Smlaier	IF_UNLOCK(ifq);							\
557130416Smlaier} while (0)
558130416Smlaier
559130416Smlaier#define	IFQ_SET_READY(ifq)						\
560130416Smlaier	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
561130416Smlaier
562130416Smlaier#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
563130416Smlaier#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
564130416Smlaier#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
565130416Smlaier#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
566130416Smlaier#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
567130416Smlaier#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
568130416Smlaier#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
569130416Smlaier#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
570130416Smlaier
571148886Srwatson/*
572148886Srwatson * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
573148886Srwatson * the handoff logic, as that flag is locked by the device driver.
574148886Srwatson */
575130416Smlaier#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
576130416Smlaierdo {									\
577130416Smlaier	int len;							\
578130416Smlaier	short mflags;							\
579130416Smlaier									\
580130416Smlaier	len = (m)->m_pkthdr.len;					\
581130416Smlaier	mflags = (m)->m_flags;						\
582130416Smlaier	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
583130416Smlaier	if ((err) == 0) {						\
584130416Smlaier		(ifp)->if_obytes += len + (adj);			\
585130416Smlaier		if (mflags & M_MCAST)					\
586130416Smlaier			(ifp)->if_omcasts++;				\
587148886Srwatson		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
588132712Srwatson			if_start(ifp);					\
589130416Smlaier	}								\
590130416Smlaier} while (0)
591130416Smlaier
592130416Smlaier#define	IFQ_HANDOFF(ifp, m, err)					\
593130512Smlaier	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
594130416Smlaier
595130416Smlaier#define	IFQ_DRV_DEQUEUE(ifq, m)						\
596130416Smlaierdo {									\
597130416Smlaier	(m) = (ifq)->ifq_drv_head;					\
598130416Smlaier	if (m) {							\
599130416Smlaier		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
600130416Smlaier			(ifq)->ifq_drv_tail = NULL;			\
601130416Smlaier		(m)->m_nextpkt = NULL;					\
602130416Smlaier		(ifq)->ifq_drv_len--;					\
603130416Smlaier	} else {							\
604130416Smlaier		IFQ_LOCK(ifq);						\
605130416Smlaier		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
606130416Smlaier		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
607130416Smlaier			struct mbuf *m0;				\
608130416Smlaier			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
609130416Smlaier			if (m0 == NULL)					\
610130416Smlaier				break;					\
611130416Smlaier			m0->m_nextpkt = NULL;				\
612130416Smlaier			if ((ifq)->ifq_drv_tail == NULL)		\
613130416Smlaier				(ifq)->ifq_drv_head = m0;		\
614130416Smlaier			else						\
615130416Smlaier				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
616130416Smlaier			(ifq)->ifq_drv_tail = m0;			\
617130416Smlaier			(ifq)->ifq_drv_len++;				\
618130416Smlaier		}							\
619130416Smlaier		IFQ_UNLOCK(ifq);					\
620130416Smlaier	}								\
621130416Smlaier} while (0)
622130416Smlaier
623130416Smlaier#define	IFQ_DRV_PREPEND(ifq, m)						\
624130416Smlaierdo {									\
625130416Smlaier	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
626132152Smlaier	if ((ifq)->ifq_drv_tail == NULL)				\
627132152Smlaier		(ifq)->ifq_drv_tail = (m);				\
628130416Smlaier	(ifq)->ifq_drv_head = (m);					\
629130416Smlaier	(ifq)->ifq_drv_len++;						\
630130416Smlaier} while (0)
631130416Smlaier
632130416Smlaier#define	IFQ_DRV_IS_EMPTY(ifq)						\
633130416Smlaier	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
634130416Smlaier
635130416Smlaier#define	IFQ_DRV_PURGE(ifq)						\
636130416Smlaierdo {									\
637132152Smlaier	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
638132152Smlaier	while((m = n) != NULL) {					\
639132152Smlaier		n = m->m_nextpkt;					\
640130416Smlaier		m_freem(m);						\
641130416Smlaier	}								\
642130416Smlaier	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
643130416Smlaier	(ifq)->ifq_drv_len = 0;						\
644130416Smlaier	IFQ_PURGE(ifq);							\
645130416Smlaier} while (0)
646130416Smlaier
647186207Skmacy#ifdef _KERNEL
648241646Semaxstatic __inline void
649241646Semaxif_initbaudrate(struct ifnet *ifp, uintmax_t baud)
650241646Semax{
651241646Semax
652241646Semax	ifp->if_baudrate_pf = 0;
653241646Semax	while (baud > (u_long)(~0UL)) {
654241646Semax		baud /= 10;
655241646Semax		ifp->if_baudrate_pf++;
656241646Semax	}
657241646Semax	ifp->if_baudrate = baud;
658241646Semax}
659241646Semax
660186207Skmacystatic __inline int
661186213Skmacydrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m)
662186207Skmacy{
663186207Skmacy	int error = 0;
664186207Skmacy
665191033Skmacy#ifdef ALTQ
666191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
667191033Skmacy		IFQ_ENQUEUE(&ifp->if_snd, m, error);
668191033Skmacy		return (error);
669191033Skmacy	}
670191033Skmacy#endif
671241037Sglebius	error = buf_ring_enqueue(br, m);
672241037Sglebius	if (error)
673186207Skmacy		m_freem(m);
674241037Sglebius
675186207Skmacy	return (error);
676186207Skmacy}
677186207Skmacy
678186207Skmacystatic __inline void
679246482Srrsdrbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *new)
680246482Srrs{
681246482Srrs	/*
682246482Srrs	 * The top of the list needs to be swapped
683246482Srrs	 * for this one.
684246482Srrs	 */
685246482Srrs#ifdef ALTQ
686246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
687246482Srrs		/*
688246482Srrs		 * Peek in altq case dequeued it
689246482Srrs		 * so put it back.
690246482Srrs		 */
691246482Srrs		IFQ_DRV_PREPEND(&ifp->if_snd, new);
692246482Srrs		return;
693246482Srrs	}
694246482Srrs#endif
695246482Srrs	buf_ring_putback_sc(br, new);
696246482Srrs}
697246482Srrs
698246482Srrsstatic __inline struct mbuf *
699246482Srrsdrbr_peek(struct ifnet *ifp, struct buf_ring *br)
700246482Srrs{
701246482Srrs#ifdef ALTQ
702246482Srrs	struct mbuf *m;
703246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
704246482Srrs		/*
705246482Srrs		 * Pull it off like a dequeue
706246482Srrs		 * since drbr_advance() does nothing
707246482Srrs		 * for altq and drbr_putback() will
708246482Srrs		 * use the old prepend function.
709246482Srrs		 */
710246482Srrs		IFQ_DEQUEUE(&ifp->if_snd, m);
711246482Srrs		return (m);
712246482Srrs	}
713246482Srrs#endif
714301913Ssephe	return(buf_ring_peek_clear_sc(br));
715246482Srrs}
716246482Srrs
717246482Srrsstatic __inline void
718194518Skmacydrbr_flush(struct ifnet *ifp, struct buf_ring *br)
719186207Skmacy{
720186207Skmacy	struct mbuf *m;
721186207Skmacy
722194518Skmacy#ifdef ALTQ
723203834Smlaier	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
724203834Smlaier		IFQ_PURGE(&ifp->if_snd);
725194518Skmacy#endif
726186207Skmacy	while ((m = buf_ring_dequeue_sc(br)) != NULL)
727186207Skmacy		m_freem(m);
728194518Skmacy}
729186207Skmacy
730194518Skmacystatic __inline void
731194518Skmacydrbr_free(struct buf_ring *br, struct malloc_type *type)
732194518Skmacy{
733194518Skmacy
734194518Skmacy	drbr_flush(NULL, br);
735186207Skmacy	buf_ring_free(br, type);
736186207Skmacy}
737191033Skmacy
738191033Skmacystatic __inline struct mbuf *
739191033Skmacydrbr_dequeue(struct ifnet *ifp, struct buf_ring *br)
740191033Skmacy{
741191033Skmacy#ifdef ALTQ
742191033Skmacy	struct mbuf *m;
743191033Skmacy
744246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) {
745203834Smlaier		IFQ_DEQUEUE(&ifp->if_snd, m);
746191033Skmacy		return (m);
747191033Skmacy	}
748186207Skmacy#endif
749191033Skmacy	return (buf_ring_dequeue_sc(br));
750191033Skmacy}
751186207Skmacy
752246482Srrsstatic __inline void
753246482Srrsdrbr_advance(struct ifnet *ifp, struct buf_ring *br)
754246482Srrs{
755246482Srrs#ifdef ALTQ
756246482Srrs	/* Nothing to do here since peek dequeues in altq case */
757246482Srrs	if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd))
758246482Srrs		return;
759246482Srrs#endif
760246482Srrs	return (buf_ring_advance_sc(br));
761246482Srrs}
762246482Srrs
763246482Srrs
764193848Skmacystatic __inline struct mbuf *
765193848Skmacydrbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br,
766193848Skmacy    int (*func) (struct mbuf *, void *), void *arg)
767193848Skmacy{
768193848Skmacy	struct mbuf *m;
769193848Skmacy#ifdef ALTQ
770203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
771203834Smlaier		IFQ_LOCK(&ifp->if_snd);
772203834Smlaier		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
773203834Smlaier		if (m != NULL && func(m, arg) == 0) {
774203834Smlaier			IFQ_UNLOCK(&ifp->if_snd);
775203834Smlaier			return (NULL);
776203834Smlaier		}
777205197Smlaier		IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m);
778203834Smlaier		IFQ_UNLOCK(&ifp->if_snd);
779193848Skmacy		return (m);
780193848Skmacy	}
781193848Skmacy#endif
782193848Skmacy	m = buf_ring_peek(br);
783193848Skmacy	if (m == NULL || func(m, arg) == 0)
784193848Skmacy		return (NULL);
785193848Skmacy
786193848Skmacy	return (buf_ring_dequeue_sc(br));
787193848Skmacy}
788193848Skmacy
789191033Skmacystatic __inline int
790191033Skmacydrbr_empty(struct ifnet *ifp, struct buf_ring *br)
791191033Skmacy{
792191033Skmacy#ifdef ALTQ
793191033Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
794203834Smlaier		return (IFQ_IS_EMPTY(&ifp->if_snd));
795191033Skmacy#endif
796191033Skmacy	return (buf_ring_empty(br));
797191033Skmacy}
798193848Skmacy
799193848Skmacystatic __inline int
800203834Smlaierdrbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br)
801203834Smlaier{
802203834Smlaier#ifdef ALTQ
803203834Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd))
804203834Smlaier		return (1);
805203834Smlaier#endif
806203834Smlaier	return (!buf_ring_empty(br));
807203834Smlaier}
808203834Smlaier
809203834Smlaierstatic __inline int
810193848Skmacydrbr_inuse(struct ifnet *ifp, struct buf_ring *br)
811193848Skmacy{
812193848Skmacy#ifdef ALTQ
813193848Skmacy	if (ALTQ_IS_ENABLED(&ifp->if_snd))
814193848Skmacy		return (ifp->if_snd.ifq_len);
815191033Skmacy#endif
816193848Skmacy	return (buf_ring_count(br));
817193848Skmacy}
818193848Skmacy#endif
81949459Sbrian/*
82049459Sbrian * 72 was chosen below because it is the size of a TCP/IP
82149459Sbrian * header (40) + the minimum mss (32).
82249459Sbrian */
82349459Sbrian#define	IF_MINMTU	72
82449459Sbrian#define	IF_MAXMTU	65535
82549459Sbrian
826237263Snp#define	TOEDEV(ifp)	((ifp)->if_llsoftc)
827237263Snp
82855205Speter#endif /* _KERNEL */
82921259Swollman
83021259Swollman/*
83121259Swollman * The ifaddr structure contains information about one address
83221259Swollman * of an interface.  They are maintained by the different address families,
83321259Swollman * are allocated and attached when an address is set, and are linked
83421259Swollman * together so all addresses for an interface can be located.
835128291Sluigi *
836128291Sluigi * NOTE: a 'struct ifaddr' is always at the beginning of a larger
837128291Sluigi * chunk of malloc'ed memory, where we store the three addresses
838128291Sluigi * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
83921259Swollman */
84021259Swollmanstruct ifaddr {
84121259Swollman	struct	sockaddr *ifa_addr;	/* address of interface */
84221259Swollman	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
84321259Swollman#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
84421259Swollman	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
84567334Sjoe	struct	if_data if_data;	/* not all members are meaningful */
84621259Swollman	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
847228571Sglebius	struct	carp_softc *ifa_carp;	/* pointer to CARP data */
84860938Sjake	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
84921259Swollman	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
85092725Salfred		(int, struct rtentry *, struct rt_addrinfo *);
85121259Swollman	u_short	ifa_flags;		/* mostly rt_flags for cloning */
85247254Spb	u_int	ifa_refcnt;		/* references to this structure */
85321259Swollman	int	ifa_metric;		/* cost of going out this interface */
85428845Sjulian	int (*ifa_claim_addr)		/* check if an addr goes to this if */
85592725Salfred		(struct ifaddr *, struct sockaddr *);
856108033Shsu	struct mtx ifa_mtx;
85721259Swollman};
85821259Swollman#define	IFA_ROUTE	RTF_UP		/* route installed */
859201282Sqingli#define IFA_RTSELF	RTF_HOST	/* loopback route to self installed */
86021259Swollman
86153541Sshin/* for compatibility with other BSDs */
86253541Sshin#define	ifa_list	ifa_link
86353541Sshin
864194602Srwatson#ifdef _KERNEL
865108033Shsu#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
866108033Shsu#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
867108033Shsu
868194602Srwatsonvoid	ifa_free(struct ifaddr *ifa);
869194602Srwatsonvoid	ifa_init(struct ifaddr *ifa);
870194602Srwatsonvoid	ifa_ref(struct ifaddr *ifa);
871194602Srwatson#endif
872194602Srwatson
87321404Swollman/*
87421404Swollman * Multicast address structure.  This is analogous to the ifaddr
87521404Swollman * structure except that it keeps track of multicast addresses.
87621404Swollman */
87721404Swollmanstruct ifmultiaddr {
87872084Sphk	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
87921434Swollman	struct	sockaddr *ifma_addr; 	/* address this membership is for */
88021434Swollman	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
88121434Swollman	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
88221434Swollman	u_int	ifma_refcount;		/* reference count */
88321434Swollman	void	*ifma_protospec;	/* protocol-specific state, if any */
884167729Sbms	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
88521404Swollman};
88621404Swollman
88755205Speter#ifdef _KERNEL
88821259Swollman
889250300Sandreextern	struct rwlock ifnet_rwlock;
890196481Srwatsonextern	struct sx ifnet_sxlock;
891108172Shsu
892196481Srwatson#define	IFNET_LOCK_INIT() do {						\
893196481Srwatson	rw_init_flags(&ifnet_rwlock, "ifnet_rw",  RW_RECURSE);		\
894196481Srwatson	sx_init_flags(&ifnet_sxlock, "ifnet_sx",  SX_RECURSE);		\
895196481Srwatson} while(0)
896196481Srwatson
897196481Srwatson#define	IFNET_WLOCK() do {						\
898196481Srwatson	sx_xlock(&ifnet_sxlock);					\
899196481Srwatson	rw_wlock(&ifnet_rwlock);					\
900196481Srwatson} while (0)
901196481Srwatson
902196481Srwatson#define	IFNET_WUNLOCK() do {						\
903196481Srwatson	rw_wunlock(&ifnet_rwlock);					\
904196481Srwatson	sx_xunlock(&ifnet_sxlock);					\
905196481Srwatson} while (0)
906196481Srwatson
907191367Srwatson/*
908196481Srwatson * To assert the ifnet lock, you must know not only whether it's for read or
909196481Srwatson * write, but also whether it was acquired with sleep support or not.
910196481Srwatson */
911196481Srwatson#define	IFNET_RLOCK_ASSERT()		sx_assert(&ifnet_sxlock, SA_SLOCKED)
912196481Srwatson#define	IFNET_RLOCK_NOSLEEP_ASSERT()	rw_assert(&ifnet_rwlock, RA_RLOCKED)
913196481Srwatson#define	IFNET_WLOCK_ASSERT() do {					\
914196481Srwatson	sx_assert(&ifnet_sxlock, SA_XLOCKED);				\
915196481Srwatson	rw_assert(&ifnet_rwlock, RA_WLOCKED);				\
916196481Srwatson} while (0)
917196481Srwatson
918196481Srwatson#define	IFNET_RLOCK()		sx_slock(&ifnet_sxlock)
919196481Srwatson#define	IFNET_RLOCK_NOSLEEP()	rw_rlock(&ifnet_rwlock)
920196481Srwatson#define	IFNET_RUNLOCK()		sx_sunlock(&ifnet_sxlock)
921196481Srwatson#define	IFNET_RUNLOCK_NOSLEEP()	rw_runlock(&ifnet_rwlock)
922196481Srwatson
923196481Srwatson/*
924191367Srwatson * Look up an ifnet given its index; the _ref variant also acquires a
925191367Srwatson * reference that must be freed using if_rele().  It is almost always a bug
926191367Srwatson * to call ifnet_byindex() instead if ifnet_byindex_ref().
927191367Srwatson */
928180042Srwatsonstruct ifnet	*ifnet_byindex(u_short idx);
929191816Szecstruct ifnet	*ifnet_byindex_locked(u_short idx);
930191367Srwatsonstruct ifnet	*ifnet_byindex_ref(u_short idx);
931181892Skmacy
932128315Sluigi/*
933128315Sluigi * Given the index, ifaddr_byindex() returns the one and only
934128315Sluigi * link-level ifaddr for the interface. You are not supposed to use
935128315Sluigi * it to traverse the list of addresses associated to the interface.
936128315Sluigi */
937180042Srwatsonstruct ifaddr	*ifaddr_byindex(u_short idx);
93883130Sjlemon
939195699SrwatsonVNET_DECLARE(struct ifnethead, ifnet);
940195699SrwatsonVNET_DECLARE(struct ifgrouphead, ifg_head);
941195699SrwatsonVNET_DECLARE(int, if_index);
942195699SrwatsonVNET_DECLARE(struct ifnet *, loif);	/* first loopback interface */
943195914SqingliVNET_DECLARE(int, useloopback);
944195699Srwatson
945195727Srwatson#define	V_ifnet		VNET(ifnet)
946195727Srwatson#define	V_ifg_head	VNET(ifg_head)
947195727Srwatson#define	V_if_index	VNET(if_index)
948195727Srwatson#define	V_loif		VNET(loif)
949195914Sqingli#define	V_useloopback	VNET(useloopback)
950195699Srwatson
951186048Sbzextern	int ifqmaxlen;
95221259Swollman
953159781Smlaierint	if_addgroup(struct ifnet *, const char *);
954159781Smlaierint	if_delgroup(struct ifnet *, const char *);
95592725Salfredint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
95692725Salfredint	if_allmulti(struct ifnet *, int);
957147256Sbrooksstruct	ifnet* if_alloc(u_char);
95892725Salfredvoid	if_attach(struct ifnet *);
959191418Srwatsonvoid	if_dead(struct ifnet *);
96092725Salfredint	if_delmulti(struct ifnet *, struct sockaddr *);
961167729Sbmsvoid	if_delmulti_ifma(struct ifmultiaddr *);
96292725Salfredvoid	if_detach(struct ifnet *);
963192605Szecvoid	if_vmove(struct ifnet *, struct vnet *);
964146620Speadarvoid	if_purgeaddrs(struct ifnet *);
965202935Ssyrinxvoid	if_delallmulti(struct ifnet *);
96692725Salfredvoid	if_down(struct ifnet *);
967167732Sbmsstruct ifmultiaddr *
968167732Sbms	if_findmulti(struct ifnet *, struct sockaddr *);
969147256Sbrooksvoid	if_free(struct ifnet *);
970121816Sbrooksvoid	if_initname(struct ifnet *, const char *, int);
971138542Ssamvoid	if_link_state_change(struct ifnet *, int);
972103900Sbrooksint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
973191161Skmacyvoid	if_qflush(struct ifnet *);
974191367Srwatsonvoid	if_ref(struct ifnet *);
975191367Srwatsonvoid	if_rele(struct ifnet *);
97692725Salfredint	if_setlladdr(struct ifnet *, const u_char *, int);
977318430Srpokalaint	if_gethwaddr(struct ifnet *, struct ifreq *);
97892725Salfredvoid	if_up(struct ifnet *);
97992725Salfredint	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
98092725Salfredint	ifpromisc(struct ifnet *, int);
98192725Salfredstruct	ifnet *ifunit(const char *);
982191423Srwatsonstruct	ifnet *ifunit_ref(const char *);
98321259Swollman
984194259Ssamvoid	ifq_init(struct ifaltq *, struct ifnet *ifp);
985194259Ssamvoid	ifq_delete(struct ifaltq *);
986185162Skmacy
987197227Sqingliint	ifa_add_loopback_route(struct ifaddr *, struct sockaddr *);
988197227Sqingliint	ifa_del_loopback_route(struct ifaddr *, struct sockaddr *);
989197227Sqingli
99092725Salfredstruct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
991194622Srwatsonint		ifa_ifwithaddr_check(struct sockaddr *);
992162068Sandrestruct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
99392725Salfredstruct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
994267186Sasomersstruct	ifaddr *ifa_ifwithdstaddr_fib(struct sockaddr *, int);
995208553Sqinglistruct	ifaddr *ifa_ifwithnet(struct sockaddr *, int);
996267186Sasomersstruct	ifaddr *ifa_ifwithnet_fib(struct sockaddr *, int, int);
99792725Salfredstruct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
998178888Sjulianstruct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
99992725Salfredstruct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
1000246659Sglebiusint	ifa_preferred(struct ifaddr *, struct ifaddr *);
100121259Swollman
100292725Salfredint	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
100321434Swollman
1004147256Sbrookstypedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
1005147256Sbrookstypedef	void if_com_free_t(void *com, u_char type);
1006147256Sbrooksvoid	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
1007147256Sbrooksvoid	if_deregister_com_alloc(u_char type);
1008276124Saeuint64_t if_get_counter_default(struct ifnet *, ift_counter);
1009276124Saevoid	if_inc_counter(struct ifnet *, ift_counter, int64_t);
1010147256Sbrooks
101184931Sfjoe#define IF_LLADDR(ifp)							\
1012152315Sru    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
101384931Sfjoe
101487902Sluigi#ifdef DEVICE_POLLING
1015150789Sglebiusenum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
101687902Sluigi
1017193096Sattiliotypedef	int poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
101892725Salfredint    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
101992725Salfredint    ether_poll_deregister(struct ifnet *ifp);
102087902Sluigi#endif /* DEVICE_POLLING */
102187902Sluigi
1022274043Shselasky/* TSO */
1023274043Shselaskyvoid if_hw_tsomax_common(struct ifnet *, struct ifnet_hw_tsomax *);
1024274043Shselaskyint if_hw_tsomax_update(struct ifnet *, struct ifnet_hw_tsomax *);
1025274043Shselasky
102655205Speter#endif /* _KERNEL */
102721259Swollman
102821259Swollman#endif /* !_NET_IF_VAR_H_ */
1029