ifq.h revision 186048
190075Sobrien/*-
290075Sobrien * Copyright (c) 1982, 1986, 1989, 1993
3169689Skan *	The Regents of the University of California.  All rights reserved.
4169689Skan *
590075Sobrien * Redistribution and use in source and binary forms, with or without
690075Sobrien * modification, are permitted provided that the following conditions
790075Sobrien * are met:
890075Sobrien * 1. Redistributions of source code must retain the above copyright
990075Sobrien *    notice, this list of conditions and the following disclaimer.
1090075Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1190075Sobrien *    notice, this list of conditions and the following disclaimer in the
1290075Sobrien *    documentation and/or other materials provided with the distribution.
1390075Sobrien * 4. Neither the name of the University nor the names of its contributors
1490075Sobrien *    may be used to endorse or promote products derived from this software
1590075Sobrien *    without specific prior written permission.
1690075Sobrien *
1790075Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1890075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1990075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20169689Skan * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21169689Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2290075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2390075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24132718Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2590075Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2690075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2790075Sobrien * SUCH DAMAGE.
2890075Sobrien *
2990075Sobrien *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3090075Sobrien * $FreeBSD: head/sys/net/if_var.h 186048 2008-12-13 19:13:03Z bz $
3190075Sobrien */
3290075Sobrien
3390075Sobrien#ifndef	_NET_IF_VAR_H_
3490075Sobrien#define	_NET_IF_VAR_H_
3590075Sobrien
3690075Sobrien/*
3790075Sobrien * Structures defining a network interface, providing a packet
3890075Sobrien * transport mechanism (ala level 0 of the PUP protocols).
3990075Sobrien *
4090075Sobrien * Each interface accepts output datagrams of a specified maximum
4190075Sobrien * length, and provides higher level routines with input datagrams
42117395Skan * received from its medium.
43132718Skan *
44132718Skan * Output occurs when the routine if_output is called, with three parameters:
45132718Skan *	(*ifp->if_output)(ifp, m, dst, rt)
46132718Skan * Here m is the mbuf chain to be sent and dst is the destination address.
4790075Sobrien * The output routine encapsulates the supplied datagram if necessary,
4890075Sobrien * and then transmits it on its medium.
4990075Sobrien *
5090075Sobrien * On input, each interface unwraps the data received by it, and either
51132718Skan * places it on the input queue of an internetwork datagram routine
52132718Skan * and posts the associated software interrupt, or passes the datagram to a raw
5390075Sobrien * packet input routine.
5490075Sobrien *
5590075Sobrien * Routines exist for locating interfaces by their addresses
5690075Sobrien * or for locating an interface on a certain network, as well as more general
5790075Sobrien * routing and gateway routines maintaining information used to locate
5890075Sobrien * interfaces.  These routines live in the files if.c and route.c
5990075Sobrien */
6090075Sobrien
6190075Sobrien#ifdef __STDC__
6290075Sobrien/*
6390075Sobrien * Forward structure declarations for function prototypes [sic].
64169689Skan */
65169689Skanstruct	mbuf;
66169689Skanstruct	thread;
67169689Skanstruct	rtentry;
68132718Skanstruct	rt_addrinfo;
6990075Sobrienstruct	socket;
7090075Sobrienstruct	ether_header;
7190075Sobrienstruct	carp_if;
72169689Skanstruct  ifvlantrunk;
7390075Sobrien#endif
74132718Skan
75132718Skan#include <sys/queue.h>		/* get TAILQ macros */
7690075Sobrien
77169689Skan#ifdef _KERNEL
78169689Skan#include <sys/mbuf.h>
7990075Sobrien#include <sys/eventhandler.h>
8090075Sobrien#endif /* _KERNEL */
8190075Sobrien#include <sys/lock.h>		/* XXX */
82132718Skan#include <sys/mutex.h>		/* XXX */
8390075Sobrien#include <sys/event.h>		/* XXX */
84169689Skan#include <sys/_task.h>
85169689Skan
8690075Sobrien#define	IF_DUNIT_NONE	-1
87169689Skan
88169689Skan#include <altq/if_altq.h>
89169689Skan
90169689SkanTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
91169689SkanTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
92169689SkanTAILQ_HEAD(ifprefixhead, ifprefix);
9390075SobrienTAILQ_HEAD(ifmultihead, ifmultiaddr);
9490075SobrienTAILQ_HEAD(ifgrouphead, ifg_group);
9590075Sobrien
9690075Sobrien/*
9790075Sobrien * Structure defining a queue for a network interface.
9890075Sobrien */
99169689Skanstruct	ifqueue {
10090075Sobrien	struct	mbuf *ifq_head;
10190075Sobrien	struct	mbuf *ifq_tail;
102169689Skan	int	ifq_len;
10390075Sobrien	int	ifq_maxlen;
10490075Sobrien	int	ifq_drops;
10590075Sobrien	struct	mtx ifq_mtx;
10690075Sobrien};
10790075Sobrien
108132718Skan/*
10990075Sobrien * Structure defining a network interface.
110117395Skan *
11190075Sobrien * (Would like to call this struct ``if'', but C isn't PL/1.)
112169689Skan */
11390075Sobrien
114117395Skanstruct ifnet {
11590075Sobrien	void	*if_softc;		/* pointer to driver state */
116169689Skan	void	*if_l2com;		/* pointer to protocol bits */
117169689Skan	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
118169689Skan	char	if_xname[IFNAMSIZ];	/* external name (name + unit) */
119169689Skan	const char *if_dname;		/* driver name */
12090075Sobrien	int	if_dunit;		/* unit or IF_DUNIT_NONE */
12190075Sobrien	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
122169689Skan		/*
123169689Skan		 * if_addrhead is the list of all addresses associated to
124169689Skan		 * an interface.
125169689Skan		 * Some code in the kernel assumes that first element
12690075Sobrien		 * of the list has type AF_LINK, and contains sockaddr_dl
127169689Skan		 * addresses which store the link-level address and the name
12890075Sobrien		 * of the interface.
12990075Sobrien		 * However, access to the AF_LINK address through this
13090075Sobrien		 * field is deprecated. Use if_addr or ifaddr_byindex() instead.
13190075Sobrien		 */
13290075Sobrien	struct	knlist if_klist;	/* events attached to this if */
133132718Skan	int	if_pcount;		/* number of promiscuous listeners */
13490075Sobrien	struct	carp_if *if_carp;	/* carp interface structure */
13590075Sobrien	struct	bpf_if *if_bpf;		/* packet filter structure */
136169689Skan	u_short	if_index;		/* numeric abbreviation for this if  */
13790075Sobrien	short	if_timer;		/* time 'til if_watchdog called */
13890075Sobrien	struct  ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */
13990075Sobrien	int	if_flags;		/* up/down, broadcast, etc. */
140117395Skan	int	if_capabilities;	/* interface features & capabilities */
141117395Skan	int	if_capenable;		/* enabled features & capabilities */
142132718Skan	void	*if_linkmib;		/* link-type-specific MIB data */
143117395Skan	size_t	if_linkmiblen;		/* length of above data */
144117395Skan	struct	if_data if_data;
145117395Skan	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
146117395Skan	int	if_amcount;		/* number of all-multicast requests */
147117395Skan/* procedure handles */
148117395Skan	int	(*if_output)		/* output routine (enqueue) */
14990075Sobrien		(struct ifnet *, struct mbuf *, struct sockaddr *,
150117395Skan		     struct rtentry *);
15190075Sobrien	void	(*if_input)		/* input routine (from h/w driver) */
152132718Skan		(struct ifnet *, struct mbuf *);
15396263Sobrien	void	(*if_start)		/* initiate output routine */
154117395Skan		(struct ifnet *);
155117395Skan	int	(*if_ioctl)		/* ioctl routine */
156169689Skan		(struct ifnet *, u_long, caddr_t);
157169689Skan	void	(*if_watchdog)		/* timer routine */
158117395Skan		(struct ifnet *);
159117395Skan	void	(*if_init)		/* Init routine */
160117395Skan		(void *);
161117395Skan	int	(*if_resolvemulti)	/* validate/resolve multicast */
162132718Skan		(struct ifnet *, struct sockaddr **, struct sockaddr *);
163117395Skan	struct	ifaddr	*if_addr;	/* pointer to link-level address */
164117395Skan	void	*if_llsoftc;		/* link layer softc */
165117395Skan	int	if_drv_flags;		/* driver-managed status flags */
166132718Skan	u_int	if_spare_flags2;	/* spare flags 2 */
167169689Skan	struct  ifaltq if_snd;		/* output queue (includes altq) */
168169689Skan	const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */
169169689Skan
170169689Skan	void	*if_bridge;		/* bridge glue */
171169689Skan
172117395Skan	struct	lltable *lltables;	/* list of L3-L2 resolution tables */
173169689Skan
174117395Skan	struct	label *if_label;	/* interface MAC label */
175117395Skan
176117395Skan	/* these are only used by IPv6 */
177117395Skan	struct	ifprefixhead if_prefixhead; /* list of prefixes per if */
178169689Skan	void	*if_afdata[AF_MAX];
179117395Skan	int	if_afdata_initialized;
180169689Skan	struct	mtx if_afdata_mtx;
181169689Skan	struct	task if_starttask;	/* task for IFF_NEEDSGIANT */
182169689Skan	struct	task if_linktask;	/* task for link change events */
183117395Skan	struct	mtx if_addr_mtx;	/* mutex to protect address lists */
184117395Skan	LIST_ENTRY(ifnet) if_clones;	/* interfaces of a cloner */
185117395Skan	TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */
186117395Skan					/* protected by if_addr_mtx */
187117395Skan	void	*if_pf_kif;
188117395Skan	void	*if_lagg;		/* lagg glue */
189132718Skan	void	*if_pspare[8];		/* multiq/TOE 3; vimage 3; general use 4 */
190117395Skan	void	(*if_qflush)	/* flush any queues */
191117395Skan		(struct ifnet *);
192169689Skan	int	(*if_transmit)	/* initiate output routine */
193117395Skan		(struct ifnet *, struct mbuf *);
194169689Skan	int	if_ispare[2];		/* general use 2 */
195169689Skan};
196169689Skan
197169689Skantypedef void if_init_f_t(void *);
198169689Skan
19996263Sobrien/*
200117395Skan * XXX These aliases are terribly dangerous because they could apply
201169689Skan * to anything.
202169689Skan */
203169689Skan#define	if_mtu		if_data.ifi_mtu
204169689Skan#define	if_type		if_data.ifi_type
205169689Skan#define if_physical	if_data.ifi_physical
206169689Skan#define	if_addrlen	if_data.ifi_addrlen
207169689Skan#define	if_hdrlen	if_data.ifi_hdrlen
208169689Skan#define	if_metric	if_data.ifi_metric
209169689Skan#define	if_link_state	if_data.ifi_link_state
210169689Skan#define	if_baudrate	if_data.ifi_baudrate
211169689Skan#define	if_hwassist	if_data.ifi_hwassist
212169689Skan#define	if_ipackets	if_data.ifi_ipackets
213169689Skan#define	if_ierrors	if_data.ifi_ierrors
214169689Skan#define	if_opackets	if_data.ifi_opackets
215169689Skan#define	if_oerrors	if_data.ifi_oerrors
216169689Skan#define	if_collisions	if_data.ifi_collisions
217169689Skan#define	if_ibytes	if_data.ifi_ibytes
218169689Skan#define	if_obytes	if_data.ifi_obytes
219169689Skan#define	if_imcasts	if_data.ifi_imcasts
220169689Skan#define	if_omcasts	if_data.ifi_omcasts
221169689Skan#define	if_iqdrops	if_data.ifi_iqdrops
222169689Skan#define	if_noproto	if_data.ifi_noproto
223169689Skan#define	if_lastchange	if_data.ifi_lastchange
224169689Skan#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL)
225169689Skan
226169689Skan/* for compatibility with other BSDs */
227169689Skan#define	if_addrlist	if_addrhead
228169689Skan#define	if_list		if_link
229169689Skan#define	if_name(ifp)	((ifp)->if_xname)
230169689Skan
231169689Skan/*
232169689Skan * Locks for address lists on the network interface.
233169689Skan */
234169689Skan#define	IF_ADDR_LOCK_INIT(if)	mtx_init(&(if)->if_addr_mtx,		\
235169689Skan				    "if_addr_mtx", NULL, MTX_DEF)
236169689Skan#define	IF_ADDR_LOCK_DESTROY(if)	mtx_destroy(&(if)->if_addr_mtx)
237169689Skan#define	IF_ADDR_LOCK(if)	mtx_lock(&(if)->if_addr_mtx)
238169689Skan#define	IF_ADDR_UNLOCK(if)	mtx_unlock(&(if)->if_addr_mtx)
239169689Skan#define	IF_ADDR_LOCK_ASSERT(if)	mtx_assert(&(if)->if_addr_mtx, MA_OWNED)
240169689Skan
241169689Skan/*
242169689Skan * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
243169689Skan * are queues of messages stored on ifqueue structures
244169689Skan * (defined above).  Entries are added to and deleted from these structures
245169689Skan * by these macros, which should be called with ipl raised to splimp().
246169689Skan */
247169689Skan#define IF_LOCK(ifq)		mtx_lock(&(ifq)->ifq_mtx)
248169689Skan#define IF_UNLOCK(ifq)		mtx_unlock(&(ifq)->ifq_mtx)
249169689Skan#define	IF_LOCK_ASSERT(ifq)	mtx_assert(&(ifq)->ifq_mtx, MA_OWNED)
250169689Skan#define	_IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
251169689Skan#define	_IF_DROP(ifq)		((ifq)->ifq_drops++)
252169689Skan#define	_IF_QLEN(ifq)		((ifq)->ifq_len)
253169689Skan
254169689Skan#define	_IF_ENQUEUE(ifq, m) do { 				\
255169689Skan	(m)->m_nextpkt = NULL;					\
256169689Skan	if ((ifq)->ifq_tail == NULL) 				\
257169689Skan		(ifq)->ifq_head = m; 				\
258117395Skan	else 							\
259117395Skan		(ifq)->ifq_tail->m_nextpkt = m; 		\
260117395Skan	(ifq)->ifq_tail = m; 					\
26196263Sobrien	(ifq)->ifq_len++; 					\
262117395Skan} while (0)
263132718Skan
26490075Sobrien#define IF_ENQUEUE(ifq, m) do {					\
265117395Skan	IF_LOCK(ifq); 						\
266169689Skan	_IF_ENQUEUE(ifq, m); 					\
267117395Skan	IF_UNLOCK(ifq); 					\
26890075Sobrien} while (0)
269117395Skan
270117395Skan#define	_IF_PREPEND(ifq, m) do {				\
271117395Skan	(m)->m_nextpkt = (ifq)->ifq_head; 			\
27296263Sobrien	if ((ifq)->ifq_tail == NULL) 				\
273169689Skan		(ifq)->ifq_tail = (m); 				\
274169689Skan	(ifq)->ifq_head = (m); 					\
275117395Skan	(ifq)->ifq_len++; 					\
276169689Skan} while (0)
277169689Skan
278117395Skan#define IF_PREPEND(ifq, m) do {		 			\
27990075Sobrien	IF_LOCK(ifq); 						\
280132718Skan	_IF_PREPEND(ifq, m); 					\
28190075Sobrien	IF_UNLOCK(ifq); 					\
28290075Sobrien} while (0)
28390075Sobrien
28490075Sobrien#define	_IF_DEQUEUE(ifq, m) do { 				\
285169689Skan	(m) = (ifq)->ifq_head; 					\
28690075Sobrien	if (m) { 						\
287169689Skan		if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL)	\
288169689Skan			(ifq)->ifq_tail = NULL; 		\
289169689Skan		(m)->m_nextpkt = NULL; 				\
290169689Skan		(ifq)->ifq_len--; 				\
29190075Sobrien	} 							\
292169689Skan} while (0)
293169689Skan
294169689Skan#define IF_DEQUEUE(ifq, m) do { 				\
295169689Skan	IF_LOCK(ifq); 						\
296169689Skan	_IF_DEQUEUE(ifq, m); 					\
297169689Skan	IF_UNLOCK(ifq); 					\
298169689Skan} while (0)
299169689Skan
30090075Sobrien#define	_IF_POLL(ifq, m)	((m) = (ifq)->ifq_head)
301169689Skan#define	IF_POLL(ifq, m)		_IF_POLL(ifq, m)
302169689Skan
303169689Skan#define _IF_DRAIN(ifq) do { 					\
30490075Sobrien	struct mbuf *m; 					\
305169689Skan	for (;;) { 						\
306169689Skan		_IF_DEQUEUE(ifq, m); 				\
30790075Sobrien		if (m == NULL) 					\
30890075Sobrien			break; 					\
309169689Skan		m_freem(m); 					\
31090075Sobrien	} 							\
31190075Sobrien} while (0)
31290075Sobrien
31390075Sobrien#define IF_DRAIN(ifq) do {					\
31490075Sobrien	IF_LOCK(ifq);						\
31590075Sobrien	_IF_DRAIN(ifq);						\
316132718Skan	IF_UNLOCK(ifq);						\
31790075Sobrien} while(0)
318169689Skan
319169689Skan#ifdef _KERNEL
320169689Skan/* interface address change event */
321169689Skantypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *);
322169689SkanEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t);
323169689Skan/* new interface arrival event */
324169689Skantypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *);
325169689SkanEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t);
326169689Skan/* interface departure event */
327169689Skantypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *);
32890075SobrienEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t);
32990075Sobrien
33090075Sobrien/*
33190075Sobrien * interface groups
33290075Sobrien */
33390075Sobrienstruct ifg_group {
334132718Skan	char				 ifg_group[IFNAMSIZ];
33590075Sobrien	u_int				 ifg_refcnt;
33690075Sobrien	void				*ifg_pf_kif;
33790075Sobrien	TAILQ_HEAD(, ifg_member)	 ifg_members;
33890075Sobrien	TAILQ_ENTRY(ifg_group)		 ifg_next;
33990075Sobrien};
34090075Sobrien
34190075Sobrienstruct ifg_member {
34290075Sobrien	TAILQ_ENTRY(ifg_member)	 ifgm_next;
34390075Sobrien	struct ifnet		*ifgm_ifp;
34490075Sobrien};
34590075Sobrien
346132718Skanstruct ifg_list {
34790075Sobrien	struct ifg_group	*ifgl_group;
348169689Skan	TAILQ_ENTRY(ifg_list)	 ifgl_next;
349169689Skan};
35090075Sobrien
351169689Skan/* group attach event */
352169689Skantypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *);
35390075SobrienEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t);
35490075Sobrien/* group detach event */
35590075Sobrientypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *);
35690075SobrienEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t);
35790075Sobrien/* group change event */
35890075Sobrientypedef void (*group_change_event_handler_t)(void *, const char *);
35990075SobrienEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t);
360132718Skan
36190075Sobrien#define	IF_AFDATA_LOCK_INIT(ifp)	\
362169689Skan    mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF)
36390075Sobrien#define	IF_AFDATA_LOCK(ifp)	mtx_lock(&(ifp)->if_afdata_mtx)
364169689Skan#define	IF_AFDATA_TRYLOCK(ifp)	mtx_trylock(&(ifp)->if_afdata_mtx)
36590075Sobrien#define	IF_AFDATA_UNLOCK(ifp)	mtx_unlock(&(ifp)->if_afdata_mtx)
366169689Skan#define	IF_AFDATA_DESTROY(ifp)	mtx_destroy(&(ifp)->if_afdata_mtx)
367169689Skan
36890075Sobrien#define	IFF_LOCKGIANT(ifp) do {						\
369169689Skan	if ((ifp)->if_flags & IFF_NEEDSGIANT)				\
370169689Skan		mtx_lock(&Giant);					\
371169689Skan} while (0)
37290075Sobrien
37390075Sobrien#define	IFF_UNLOCKGIANT(ifp) do {					\
37490075Sobrien	if ((ifp)->if_flags & IFF_NEEDSGIANT)				\
37590075Sobrien		mtx_unlock(&Giant);					\
37690075Sobrien} while (0)
377132718Skan
37890075Sobrienint	if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp,
37990075Sobrien	    int adjust);
38090075Sobrien#define	IF_HANDOFF(ifq, m, ifp)			\
381169689Skan	if_handoff((struct ifqueue *)ifq, m, ifp, 0)
382169689Skan#define	IF_HANDOFF_ADJ(ifq, m, ifp, adj)	\
38390075Sobrien	if_handoff((struct ifqueue *)ifq, m, ifp, adj)
38490075Sobrien
38590075Sobrienvoid	if_start(struct ifnet *);
386117395Skan
387117395Skan#define	IFQ_ENQUEUE(ifq, m, err)					\
38890075Sobriendo {									\
38990075Sobrien	IF_LOCK(ifq);							\
39090075Sobrien	if (ALTQ_IS_ENABLED(ifq))					\
39190075Sobrien		ALTQ_ENQUEUE(ifq, m, NULL, err);			\
39290075Sobrien	else {								\
39390075Sobrien		if (_IF_QFULL(ifq)) {					\
39490075Sobrien			m_freem(m);					\
39590075Sobrien			(err) = ENOBUFS;				\
39690075Sobrien		} else {						\
39790075Sobrien			_IF_ENQUEUE(ifq, m);				\
39890075Sobrien			(err) = 0;					\
39990075Sobrien		}							\
40090075Sobrien	}								\
401132718Skan	if (err)							\
40290075Sobrien		(ifq)->ifq_drops++;					\
403169689Skan	IF_UNLOCK(ifq);							\
40490075Sobrien} while (0)
405169689Skan
40690075Sobrien#define	IFQ_DEQUEUE_NOLOCK(ifq, m)					\
40790075Sobriendo {									\
408169689Skan	if (TBR_IS_ENABLED(ifq))					\
40990075Sobrien		(m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE);		\
410117395Skan	else if (ALTQ_IS_ENABLED(ifq))					\
411169689Skan		ALTQ_DEQUEUE(ifq, m);					\
412117395Skan	else								\
413132718Skan		_IF_DEQUEUE(ifq, m);					\
414117395Skan} while (0)
415117395Skan
416117395Skan#define	IFQ_DEQUEUE(ifq, m)						\
417117395Skando {									\
418169689Skan	IF_LOCK(ifq);							\
419169689Skan	IFQ_DEQUEUE_NOLOCK(ifq, m);					\
420117395Skan	IF_UNLOCK(ifq);							\
42190075Sobrien} while (0)
422169689Skan
423169689Skan#define	IFQ_POLL_NOLOCK(ifq, m)						\
424169689Skando {									\
425169689Skan	if (TBR_IS_ENABLED(ifq))					\
426169689Skan		(m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL);			\
42790075Sobrien	else if (ALTQ_IS_ENABLED(ifq))					\
428169689Skan		ALTQ_POLL(ifq, m);					\
42990075Sobrien	else								\
430169689Skan		_IF_POLL(ifq, m);					\
431169689Skan} while (0)
432169689Skan
433169689Skan#define	IFQ_POLL(ifq, m)						\
43490075Sobriendo {									\
435169689Skan	IF_LOCK(ifq);							\
436169689Skan	IFQ_POLL_NOLOCK(ifq, m);					\
43790075Sobrien	IF_UNLOCK(ifq);							\
438169689Skan} while (0)
439169689Skan
440169689Skan#define	IFQ_PURGE_NOLOCK(ifq)						\
441169689Skando {									\
442169689Skan	if (ALTQ_IS_ENABLED(ifq)) {					\
443169689Skan		ALTQ_PURGE(ifq);					\
444169689Skan	} else								\
445169689Skan		_IF_DRAIN(ifq);						\
446169689Skan} while (0)
447169689Skan
448169689Skan#define	IFQ_PURGE(ifq)							\
449169689Skando {									\
450169689Skan	IF_LOCK(ifq);							\
451169689Skan	IFQ_PURGE_NOLOCK(ifq);						\
452169689Skan	IF_UNLOCK(ifq);							\
453169689Skan} while (0)
454169689Skan
455169689Skan#define	IFQ_SET_READY(ifq)						\
456169689Skan	do { ((ifq)->altq_flags |= ALTQF_READY); } while (0)
457169689Skan
458169689Skan#define	IFQ_LOCK(ifq)			IF_LOCK(ifq)
459169689Skan#define	IFQ_UNLOCK(ifq)			IF_UNLOCK(ifq)
460169689Skan#define	IFQ_LOCK_ASSERT(ifq)		IF_LOCK_ASSERT(ifq)
461169689Skan#define	IFQ_IS_EMPTY(ifq)		((ifq)->ifq_len == 0)
462169689Skan#define	IFQ_INC_LEN(ifq)		((ifq)->ifq_len++)
463169689Skan#define	IFQ_DEC_LEN(ifq)		(--(ifq)->ifq_len)
464169689Skan#define	IFQ_INC_DROPS(ifq)		((ifq)->ifq_drops++)
465169689Skan#define	IFQ_SET_MAXLEN(ifq, len)	((ifq)->ifq_maxlen = (len))
466169689Skan
467169689Skan/*
468169689Skan * The IFF_DRV_OACTIVE test should really occur in the device driver, not in
469169689Skan * the handoff logic, as that flag is locked by the device driver.
470169689Skan */
471169689Skan#define	IFQ_HANDOFF_ADJ(ifp, m, adj, err)				\
472169689Skando {									\
473169689Skan	int len;							\
474169689Skan	short mflags;							\
475169689Skan									\
476169689Skan	len = (m)->m_pkthdr.len;					\
477169689Skan	mflags = (m)->m_flags;						\
478169689Skan	IFQ_ENQUEUE(&(ifp)->if_snd, m, err);				\
479169689Skan	if ((err) == 0) {						\
480169689Skan		(ifp)->if_obytes += len + (adj);			\
481169689Skan		if (mflags & M_MCAST)					\
48290075Sobrien			(ifp)->if_omcasts++;				\
483169689Skan		if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0)	\
48490075Sobrien			if_start(ifp);					\
485169689Skan	}								\
486169689Skan} while (0)
487169689Skan
488169689Skan#define	IFQ_HANDOFF(ifp, m, err)					\
489169689Skan	IFQ_HANDOFF_ADJ(ifp, m, 0, err)
490169689Skan
49190075Sobrien#define	IFQ_DRV_DEQUEUE(ifq, m)						\
492117395Skando {									\
493117395Skan	(m) = (ifq)->ifq_drv_head;					\
494117395Skan	if (m) {							\
495117395Skan		if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL)	\
496117395Skan			(ifq)->ifq_drv_tail = NULL;			\
497117395Skan		(m)->m_nextpkt = NULL;					\
49890075Sobrien		(ifq)->ifq_drv_len--;					\
499169689Skan	} else {							\
500169689Skan		IFQ_LOCK(ifq);						\
50190075Sobrien		IFQ_DEQUEUE_NOLOCK(ifq, m);				\
502169689Skan		while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) {	\
50390075Sobrien			struct mbuf *m0;				\
504169689Skan			IFQ_DEQUEUE_NOLOCK(ifq, m0);			\
505169689Skan			if (m0 == NULL)					\
506169689Skan				break;					\
507169689Skan			m0->m_nextpkt = NULL;				\
50890075Sobrien			if ((ifq)->ifq_drv_tail == NULL)		\
509169689Skan				(ifq)->ifq_drv_head = m0;		\
51090075Sobrien			else						\
511169689Skan				(ifq)->ifq_drv_tail->m_nextpkt = m0;	\
512169689Skan			(ifq)->ifq_drv_tail = m0;			\
513169689Skan			(ifq)->ifq_drv_len++;				\
514169689Skan		}							\
515169689Skan		IFQ_UNLOCK(ifq);					\
516169689Skan	}								\
517169689Skan} while (0)
518169689Skan
51990075Sobrien#define	IFQ_DRV_PREPEND(ifq, m)						\
520169689Skando {									\
521169689Skan	(m)->m_nextpkt = (ifq)->ifq_drv_head;				\
522169689Skan	if ((ifq)->ifq_drv_tail == NULL)				\
523169689Skan		(ifq)->ifq_drv_tail = (m);				\
524169689Skan	(ifq)->ifq_drv_head = (m);					\
525169689Skan	(ifq)->ifq_drv_len++;						\
52690075Sobrien} while (0)
527169689Skan
528169689Skan#define	IFQ_DRV_IS_EMPTY(ifq)						\
529117395Skan	(((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0))
530169689Skan
531169689Skan#define	IFQ_DRV_PURGE(ifq)						\
532169689Skando {									\
533169689Skan	struct mbuf *m, *n = (ifq)->ifq_drv_head;			\
534169689Skan	while((m = n) != NULL) {					\
535169689Skan		n = m->m_nextpkt;					\
536169689Skan		m_freem(m);						\
537169689Skan	}								\
538169689Skan	(ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL;		\
539169689Skan	(ifq)->ifq_drv_len = 0;						\
540169689Skan	IFQ_PURGE(ifq);							\
541169689Skan} while (0)
542169689Skan
543169689Skan/*
544169689Skan * 72 was chosen below because it is the size of a TCP/IP
545169689Skan * header (40) + the minimum mss (32).
546169689Skan */
547169689Skan#define	IF_MINMTU	72
548169689Skan#define	IF_MAXMTU	65535
549169689Skan
550169689Skan#endif /* _KERNEL */
551169689Skan
552169689Skan/*
553169689Skan * The ifaddr structure contains information about one address
554169689Skan * of an interface.  They are maintained by the different address families,
555169689Skan * are allocated and attached when an address is set, and are linked
556169689Skan * together so all addresses for an interface can be located.
557169689Skan *
558169689Skan * NOTE: a 'struct ifaddr' is always at the beginning of a larger
559169689Skan * chunk of malloc'ed memory, where we store the three addresses
560169689Skan * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here.
561169689Skan */
562169689Skanstruct ifaddr {
563169689Skan	struct	sockaddr *ifa_addr;	/* address of interface */
564169689Skan	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
565169689Skan#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
566169689Skan	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
567169689Skan	struct	if_data if_data;	/* not all members are meaningful */
568169689Skan	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
569169689Skan	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
570169689Skan	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
571169689Skan		(int, struct rtentry *, struct rt_addrinfo *);
572169689Skan	u_short	ifa_flags;		/* mostly rt_flags for cloning */
573169689Skan	u_int	ifa_refcnt;		/* references to this structure */
574169689Skan	int	ifa_metric;		/* cost of going out this interface */
575169689Skan	int (*ifa_claim_addr)		/* check if an addr goes to this if */
576169689Skan		(struct ifaddr *, struct sockaddr *);
577169689Skan	struct mtx ifa_mtx;
578169689Skan};
579169689Skan#define	IFA_ROUTE	RTF_UP		/* route installed */
580169689Skan
581169689Skan/* for compatibility with other BSDs */
582169689Skan#define	ifa_list	ifa_link
58390075Sobrien
58490075Sobrien#define	IFA_LOCK_INIT(ifa)	\
585169689Skan    mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF)
586169689Skan#define	IFA_LOCK(ifa)		mtx_lock(&(ifa)->ifa_mtx)
587169689Skan#define	IFA_UNLOCK(ifa)		mtx_unlock(&(ifa)->ifa_mtx)
588169689Skan#define	IFA_DESTROY(ifa)	mtx_destroy(&(ifa)->ifa_mtx)
589169689Skan
590169689Skan/*
591169689Skan * The prefix structure contains information about one prefix
59290075Sobrien * of an interface.  They are maintained by the different address families,
59390075Sobrien * are allocated and attached when a prefix or an address is set,
59490075Sobrien * and are linked together so all prefixes for an interface can be located.
59590075Sobrien */
596132718Skanstruct ifprefix {
59790075Sobrien	struct	sockaddr *ifpr_prefix;	/* prefix of interface */
598169689Skan	struct	ifnet *ifpr_ifp;	/* back-pointer to interface */
59990075Sobrien	TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */
60090075Sobrien	u_char	ifpr_plen;		/* prefix length in bits */
60190075Sobrien	u_char	ifpr_type;		/* protocol dependent prefix type */
602132718Skan};
60390075Sobrien
60490075Sobrien/*
60590075Sobrien * Multicast address structure.  This is analogous to the ifaddr
60690075Sobrien * structure except that it keeps track of multicast addresses.
60790075Sobrien */
60890075Sobrienstruct ifmultiaddr {
60990075Sobrien	TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */
61090075Sobrien	struct	sockaddr *ifma_addr; 	/* address this membership is for */
61190075Sobrien	struct	sockaddr *ifma_lladdr;	/* link-layer translation, if any */
61290075Sobrien	struct	ifnet *ifma_ifp;	/* back-pointer to interface */
61390075Sobrien	u_int	ifma_refcount;		/* reference count */
61490075Sobrien	void	*ifma_protospec;	/* protocol-specific state, if any */
61590075Sobrien	struct	ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */
61690075Sobrien};
61790075Sobrien
61890075Sobrien#ifdef _KERNEL
61990075Sobrien#define	IFAFREE(ifa)					\
62090075Sobrien	do {						\
62190075Sobrien		IFA_LOCK(ifa);				\
62290075Sobrien		KASSERT((ifa)->ifa_refcnt > 0,		\
62390075Sobrien		    ("ifa %p !(ifa_refcnt > 0)", ifa));	\
624132718Skan		if (--(ifa)->ifa_refcnt == 0) {		\
625132718Skan			IFA_DESTROY(ifa);		\
626169689Skan			free(ifa, M_IFADDR);		\
627169689Skan		} else 					\
628132718Skan			IFA_UNLOCK(ifa);		\
62990075Sobrien	} while (0)
63090075Sobrien
63190075Sobrien#define IFAREF(ifa)					\
63290075Sobrien	do {						\
63390075Sobrien		IFA_LOCK(ifa);				\
63490075Sobrien		++(ifa)->ifa_refcnt;			\
63590075Sobrien		IFA_UNLOCK(ifa);			\
63690075Sobrien	} while (0)
63790075Sobrien
63890075Sobrienextern	struct mtx ifnet_lock;
63990075Sobrien#define	IFNET_LOCK_INIT() \
64090075Sobrien    mtx_init(&ifnet_lock, "ifnet", NULL, MTX_DEF | MTX_RECURSE)
64190075Sobrien#define	IFNET_WLOCK()		mtx_lock(&ifnet_lock)
64290075Sobrien#define	IFNET_WUNLOCK()		mtx_unlock(&ifnet_lock)
64390075Sobrien#define	IFNET_WLOCK_ASSERT()	mtx_assert(&ifnet_lock, MA_OWNED)
64490075Sobrien#define	IFNET_RLOCK()		IFNET_WLOCK()
64590075Sobrien#define	IFNET_RUNLOCK()		IFNET_WUNLOCK()
64690075Sobrien
64790075Sobrienstruct ifindex_entry {
64890075Sobrien	struct	ifnet *ife_ifnet;
64990075Sobrien	struct cdev *ife_dev;
65090075Sobrien};
65190075Sobrien
65290075Sobrienstruct ifnet	*ifnet_byindex(u_short idx);
65390075Sobrien
65490075Sobrien/*
65590075Sobrien * Given the index, ifaddr_byindex() returns the one and only
65690075Sobrien * link-level ifaddr for the interface. You are not supposed to use
65790075Sobrien * it to traverse the list of addresses associated to the interface.
658117395Skan */
65990075Sobrienstruct ifaddr	*ifaddr_byindex(u_short idx);
66090075Sobrienstruct cdev	*ifdev_byindex(u_short idx);
66190075Sobrien
662132718Skan#ifdef VIMAGE_GLOBALS
66390075Sobrienextern	struct ifnethead ifnet;
66490075Sobrienextern	struct ifnet *loif;	/* first loopback interface */
665169689Skanextern	int if_index;
66690075Sobrien#endif
66790075Sobrienextern	int ifqmaxlen;
66890075Sobrien
66990075Sobrienint	if_addgroup(struct ifnet *, const char *);
67090075Sobrienint	if_delgroup(struct ifnet *, const char *);
67190075Sobrienint	if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **);
67290075Sobrienint	if_allmulti(struct ifnet *, int);
67390075Sobrienstruct	ifnet* if_alloc(u_char);
674132718Skanvoid	if_attach(struct ifnet *);
67590075Sobrienint	if_delmulti(struct ifnet *, struct sockaddr *);
67690075Sobrienvoid	if_delmulti_ifma(struct ifmultiaddr *);
67790075Sobrienvoid	if_detach(struct ifnet *);
67890075Sobrienvoid	if_purgeaddrs(struct ifnet *);
67990075Sobrienvoid	if_purgemaddrs(struct ifnet *);
68090075Sobrienvoid	if_down(struct ifnet *);
68190075Sobrienstruct ifmultiaddr *
68290075Sobrien	if_findmulti(struct ifnet *, struct sockaddr *);
683169689Skanvoid	if_free(struct ifnet *);
684169689Skanvoid	if_free_type(struct ifnet *, u_char);
685169689Skanvoid	if_initname(struct ifnet *, const char *, int);
68690075Sobrienvoid	if_link_state_change(struct ifnet *, int);
687132718Skanint	if_printf(struct ifnet *, const char *, ...) __printflike(2, 3);
68890075Sobrienint	if_setlladdr(struct ifnet *, const u_char *, int);
68990075Sobrienvoid	if_up(struct ifnet *);
690117395Skan/*void	ifinit(void);*/ /* declared in systm.h for main() */
69190075Sobrienint	ifioctl(struct socket *, u_long, caddr_t, struct thread *);
692117395Skanint	ifpromisc(struct ifnet *, int);
693117395Skanstruct	ifnet *ifunit(const char *);
69490075Sobrien
69590075Sobrienvoid	ifq_attach(struct ifaltq *, struct ifnet *ifp);
69690075Sobrienvoid	ifq_detach(struct ifaltq *);
69790075Sobrien
69890075Sobrienstruct	ifaddr *ifa_ifwithaddr(struct sockaddr *);
69990075Sobrienstruct	ifaddr *ifa_ifwithbroadaddr(struct sockaddr *);
700132718Skanstruct	ifaddr *ifa_ifwithdstaddr(struct sockaddr *);
70190075Sobrienstruct	ifaddr *ifa_ifwithnet(struct sockaddr *);
702117395Skanstruct	ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *);
70390075Sobrienstruct	ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int);
704117395Skan
705117395Skanstruct	ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *);
70690075Sobrien
70790075Sobrienint	if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen);
70890075Sobrien
70990075Sobrientypedef	void *if_com_alloc_t(u_char type, struct ifnet *ifp);
71090075Sobrientypedef	void if_com_free_t(void *com, u_char type);
71190075Sobrienvoid	if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f);
712132718Skanvoid	if_deregister_com_alloc(u_char type);
71390075Sobrien
714169689Skan#define IF_LLADDR(ifp)							\
71590075Sobrien    LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr))
71690075Sobrien
71790075Sobrien#ifdef DEVICE_POLLING
71890075Sobrienenum poll_cmd {	POLL_ONLY, POLL_AND_CHECK_STATUS };
71990075Sobrien
72090075Sobrientypedef	void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count);
721117395Skanint    ether_poll_register(poll_handler_t *h, struct ifnet *ifp);
72290075Sobrienint    ether_poll_deregister(struct ifnet *ifp);
72390075Sobrien#endif /* DEVICE_POLLING */
72490075Sobrien
725132718Skan#endif /* _KERNEL */
72690075Sobrien
72790075Sobrien#endif /* !_NET_IF_VAR_H_ */
728169689Skan