if_var.h revision 21404
162587Sitojun/*
262587Sitojun * Copyright (c) 1982, 1986, 1989, 1993
362587Sitojun *	The Regents of the University of California.  All rights reserved.
453541Sshin *
553541Sshin * Redistribution and use in source and binary forms, with or without
653541Sshin * modification, are permitted provided that the following conditions
753541Sshin * are met:
853541Sshin * 1. Redistributions of source code must retain the above copyright
953541Sshin *    notice, this list of conditions and the following disclaimer.
1053541Sshin * 2. Redistributions in binary form must reproduce the above copyright
1153541Sshin *    notice, this list of conditions and the following disclaimer in the
1253541Sshin *    documentation and/or other materials provided with the distribution.
1353541Sshin * 3. All advertising materials mentioning features or use of this software
1453541Sshin *    must display the following acknowledgement:
1553541Sshin *	This product includes software developed by the University of
1653541Sshin *	California, Berkeley and its contributors.
1753541Sshin * 4. Neither the name of the University nor the names of its contributors
1853541Sshin *    may be used to endorse or promote products derived from this software
1953541Sshin *    without specific prior written permission.
2053541Sshin *
2153541Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2253541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2353541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2453541Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2553541Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2653541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2753541Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2853541Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2953541Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3053541Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3153541Sshin * SUCH DAMAGE.
3253541Sshin *
3353541Sshin *	From: @(#)if.h	8.1 (Berkeley) 6/10/93
3453541Sshin *	$Id: if_var.h,v 1.1 1997/01/03 19:50:26 wollman Exp $
3553541Sshin */
3653541Sshin
3753541Sshin#ifndef	_NET_IF_VAR_H_
3853541Sshin#define	_NET_IF_VAR_H_
3953541Sshin
4053541Sshin/*
4153541Sshin * Structures defining a network interface, providing a packet
4253541Sshin * transport mechanism (ala level 0 of the PUP protocols).
4353541Sshin *
4453541Sshin * Each interface accepts output datagrams of a specified maximum
4553541Sshin * length, and provides higher level routines with input datagrams
4653541Sshin * received from its medium.
4753541Sshin *
4853541Sshin * Output occurs when the routine if_output is called, with three parameters:
4953541Sshin *	(*ifp->if_output)(ifp, m, dst, rt)
5053541Sshin * Here m is the mbuf chain to be sent and dst is the destination address.
5153541Sshin * The output routine encapsulates the supplied datagram if necessary,
5253541Sshin * and then transmits it on its medium.
5353541Sshin *
5453541Sshin * On input, each interface unwraps the data received by it, and either
5553541Sshin * places it on the input queue of a internetwork datagram routine
5653541Sshin * and posts the associated software interrupt, or passes the datagram to a raw
5753541Sshin * packet input routine.
5853541Sshin *
5953541Sshin * Routines exist for locating interfaces by their addresses
6053541Sshin * or for locating a interface on a certain network, as well as more general
6153541Sshin * routing and gateway routines maintaining information used to locate
6253541Sshin * interfaces.  These routines live in the files if.c and route.c
6353541Sshin */
6453541Sshin
6553541Sshin#ifdef __STDC__
6653541Sshin/*
6753541Sshin * Forward structure declarations for function prototypes [sic].
6862587Sitojun */
6962587Sitojunstruct	mbuf;
7062587Sitojunstruct	proc;
7155009Sshinstruct	rtentry;
7264060Sdarrenrstruct	socket;
7353541Sshinstruct	ether_header;
7453541Sshin#endif
7553541Sshin
7653541Sshin#include <sys/queue.h>		/* get TAILQ macros */
7753541Sshin
7853541SshinTAILQ_HEAD(ifnethead, ifnet);	/* we use TAILQs so that the order of */
7953541SshinTAILQ_HEAD(ifaddrhead, ifaddr);	/* instantiation is preserved in the list */
8053541SshinLIST_HEAD(ifmultihead, ifmultiaddr);
8153541Sshin
8253541Sshin/*
8353541Sshin * Structure defining a queue for a network interface.
8453541Sshin */
8553541Sshinstruct	ifqueue {
8653541Sshin	struct	mbuf *ifq_head;
8764060Sdarrenr	struct	mbuf *ifq_tail;
8864060Sdarrenr	int	ifq_len;
8964060Sdarrenr	int	ifq_maxlen;
9053541Sshin	int	ifq_drops;
9153541Sshin};
9253541Sshin
9362587Sitojun/*
9462587Sitojun * Structure defining a network interface.
9562587Sitojun *
9653541Sshin * (Would like to call this struct ``if'', but C isn't PL/1.)
9753541Sshin */
9853541Sshinstruct ifnet {
9953541Sshin	void	*if_softc;		/* pointer to driver state */
10053541Sshin	char	*if_name;		/* name, e.g. ``en'' or ``lo'' */
10162587Sitojun	TAILQ_ENTRY(ifnet) if_link; 	/* all struct ifnets are chained */
10253541Sshin	struct	ifaddrhead if_addrhead;	/* linked list of addresses per if */
10362587Sitojun        int	if_pcount;		/* number of promiscuous listeners */
10453541Sshin	struct	bpf_if *if_bpf;		/* packet filter structure */
10553541Sshin	u_short	if_index;		/* numeric abbreviation for this if  */
10653541Sshin	short	if_unit;		/* sub-unit for lower level driver */
10753541Sshin	short	if_timer;		/* time 'til if_watchdog called */
10853541Sshin	short	if_flags;		/* up/down, broadcast, etc. */
10953541Sshin	int	if_ipending;		/* interrupts pending */
11053541Sshin	void	*if_linkmib;		/* link-type-specific MIB data */
11153541Sshin	size_t	if_linkmiblen;		/* length of above data */
11253541Sshin	struct	if_data if_data;
11364558Sume	struct	ifmultihead if_multiaddrs; /* multicast addresses configured */
11464558Sume	int	if_amcount;		/* number of all-multicast requests */
11553541Sshin/* procedure handles */
11653541Sshin	int	(*if_output)		/* output routine (enqueue) */
11753541Sshin		__P((struct ifnet *, struct mbuf *, struct sockaddr *,
11862587Sitojun		     struct rtentry *));
11962587Sitojun	void	(*if_start)		/* initiate output routine */
12062587Sitojun		__P((struct ifnet *));
12162587Sitojun	int	(*if_done)		/* output complete routine */
12262587Sitojun		__P((struct ifnet *));	/* (XXX not used; fake prototype) */
12353541Sshin	int	(*if_ioctl)		/* ioctl routine */
12453541Sshin		__P((struct ifnet *, int, caddr_t));
12562587Sitojun	void	(*if_watchdog)		/* timer routine */
12653541Sshin		__P((struct ifnet *));
12762587Sitojun	int	(*if_poll_recv)		/* polled receive routine */
12862587Sitojun		__P((struct ifnet *, int *));
12962587Sitojun	int	(*if_poll_xmit)		/* polled transmit routine */
13062587Sitojun		__P((struct ifnet *, int *));
13153541Sshin	void	(*if_poll_intren)	/* polled interrupt reenable routine */
13262587Sitojun		__P((struct ifnet *));
13362587Sitojun	void	(*if_poll_slowinput)	/* input routine for slow devices */
13453541Sshin		__P((struct ifnet *, struct mbuf *));
13564558Sume	void	(*if_init)		/* Init routine */
13664558Sume		__P((void *));
13764558Sume	int	(*if_resolvemulti)	/* validate/resolve multicast */
13853541Sshin		__P((struct ifnet *, struct sockaddr **, struct sockaddr *));
13953541Sshin	struct	ifqueue if_snd;		/* output queue */
14053541Sshin	struct	ifqueue *if_poll_slowq;	/* input queue for slow devices */
14153541Sshin};
14253541Sshintypedef void if_init_f_t __P((void *));
14353541Sshin
14453541Sshin#define	if_mtu		if_data.ifi_mtu
14553541Sshin#define	if_type		if_data.ifi_type
14653541Sshin#define if_physical	if_data.ifi_physical
14753541Sshin#define	if_addrlen	if_data.ifi_addrlen
14853541Sshin#define	if_hdrlen	if_data.ifi_hdrlen
14953541Sshin#define	if_metric	if_data.ifi_metric
15053541Sshin#define	if_baudrate	if_data.ifi_baudrate
15153541Sshin#define	if_ipackets	if_data.ifi_ipackets
15253541Sshin#define	if_ierrors	if_data.ifi_ierrors
15353541Sshin#define	if_opackets	if_data.ifi_opackets
15453541Sshin#define	if_oerrors	if_data.ifi_oerrors
15562587Sitojun#define	if_collisions	if_data.ifi_collisions
15653541Sshin#define	if_ibytes	if_data.ifi_ibytes
15753541Sshin#define	if_obytes	if_data.ifi_obytes
15853541Sshin#define	if_imcasts	if_data.ifi_imcasts
15953541Sshin#define	if_omcasts	if_data.ifi_omcasts
16053541Sshin#define	if_iqdrops	if_data.ifi_iqdrops
16153541Sshin#define	if_noproto	if_data.ifi_noproto
16253541Sshin#define	if_lastchange	if_data.ifi_lastchange
16353541Sshin#define if_recvquota	if_data.ifi_recvquota
16453541Sshin#define	if_xmitquota	if_data.ifi_xmitquota
16553541Sshin#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0)
16653541Sshin
16753541Sshin/*
16853541Sshin * Bit values in if_ipending
16964060Sdarrenr */
17064060Sdarrenr#define	IFI_RECV	1	/* I want to receive */
17164060Sdarrenr#define	IFI_XMIT	2	/* I want to transmit */
17264060Sdarrenr
17364060Sdarrenr/*
17453541Sshin * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
17553541Sshin * are queues of messages stored on ifqueue structures
17653541Sshin * (defined above).  Entries are added to and deleted from these structures
17753541Sshin * by these macros, which should be called with ipl raised to splimp().
17853541Sshin */
17953541Sshin#define	IF_QFULL(ifq)		((ifq)->ifq_len >= (ifq)->ifq_maxlen)
18062587Sitojun#define	IF_DROP(ifq)		((ifq)->ifq_drops++)
18162587Sitojun#define	IF_ENQUEUE(ifq, m) { \
18253541Sshin	(m)->m_nextpkt = 0; \
18353541Sshin	if ((ifq)->ifq_tail == 0) \
18453541Sshin		(ifq)->ifq_head = m; \
18562587Sitojun	else \
18662587Sitojun		(ifq)->ifq_tail->m_nextpkt = m; \
18753541Sshin	(ifq)->ifq_tail = m; \
18853541Sshin	(ifq)->ifq_len++; \
18953541Sshin}
19053541Sshin#define	IF_PREPEND(ifq, m) { \
19153541Sshin	(m)->m_nextpkt = (ifq)->ifq_head; \
19253541Sshin	if ((ifq)->ifq_tail == 0) \
19353541Sshin		(ifq)->ifq_tail = (m); \
19462587Sitojun	(ifq)->ifq_head = (m); \
19562587Sitojun	(ifq)->ifq_len++; \
19653541Sshin}
19762587Sitojun#define	IF_DEQUEUE(ifq, m) { \
19853541Sshin	(m) = (ifq)->ifq_head; \
19953541Sshin	if (m) { \
20053541Sshin		if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \
20153541Sshin			(ifq)->ifq_tail = 0; \
20253541Sshin		(m)->m_nextpkt = 0; \
20353541Sshin		(ifq)->ifq_len--; \
20453541Sshin	} \
20553541Sshin}
20653541Sshin
20753541Sshin#ifdef KERNEL
20853541Sshin#define	IF_ENQ_DROP(ifq, m)	if_enq_drop(ifq, m)
20953541Sshin
21053541Sshin#if defined(__GNUC__) && defined(MT_HEADER)
21153541Sshinstatic inline int
21253541Sshinif_queue_drop(struct ifqueue *ifq, struct mbuf *m)
21353541Sshin{
21453541Sshin	IF_DROP(ifq);
21553541Sshin	return 0;
21653541Sshin}
21753541Sshin
21862587Sitojunstatic inline int
21953541Sshinif_enq_drop(struct ifqueue *ifq, struct mbuf *m)
22053541Sshin{
22153541Sshin	if (IF_QFULL(ifq) &&
22253541Sshin	    !if_queue_drop(ifq, m))
22353541Sshin		return 0;
22453541Sshin	IF_ENQUEUE(ifq, m);
22553541Sshin	return 1;
22653541Sshin}
22753541Sshin#else
22853541Sshin
22953541Sshin#ifdef MT_HEADER
23062587Sitojunint	if_enq_drop __P((struct ifqueue *, struct mbuf *));
23153541Sshin#endif
23253541Sshin
23353541Sshin#endif
23453541Sshin#endif /* KERNEL */
23553541Sshin
23653541Sshin/*
23753541Sshin * The ifaddr structure contains information about one address
23853541Sshin * of an interface.  They are maintained by the different address families,
23953541Sshin * are allocated and attached when an address is set, and are linked
24062587Sitojun * together so all addresses for an interface can be located.
24162587Sitojun */
24262587Sitojunstruct ifaddr {
24353541Sshin	struct	sockaddr *ifa_addr;	/* address of interface */
24453541Sshin	struct	sockaddr *ifa_dstaddr;	/* other end of p-to-p link */
24553541Sshin#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
24653541Sshin	struct	sockaddr *ifa_netmask;	/* used to determine subnet */
24753541Sshin	struct	ifnet *ifa_ifp;		/* back-pointer to interface */
24853541Sshin	TAILQ_ENTRY(ifaddr) ifa_link;	/* queue macro glue */
24953541Sshin	void	(*ifa_rtrequest)	/* check or clean routes (+ or -)'d */
25053541Sshin		__P((int, struct rtentry *, struct sockaddr *));
25153541Sshin	u_short	ifa_flags;		/* mostly rt_flags for cloning */
25253541Sshin	short	ifa_refcnt;		/* references to this structure */
25353541Sshin	int	ifa_metric;		/* cost of going out this interface */
25453541Sshin#ifdef notdef
25553541Sshin	struct	rtentry *ifa_rt;	/* XXXX for ROUTETOIF ????? */
25653541Sshin#endif
25753541Sshin};
25853541Sshin#define	IFA_ROUTE	RTF_UP		/* route installed */
25953541Sshin
26053541Sshin/*
26153541Sshin * Multicast address structure.  This is analogous to the ifaddr
26253541Sshin * structure except that it keeps track of multicast addresses.
26353541Sshin * Also, the reference count here is a count of requests for this
26453541Sshin * address, not a count of pointers to this structure.
26553541Sshin */
26653541Sshinstruct ifmultiaddr {
26753541Sshin	LIST_ENTRY(ifmultiaddr) ifma_link;
26853541Sshin	struct	sockaddr *ifma_addr;
26953541Sshin	struct	sockaddr *ifma_lladdr;
27053541Sshin	struct	ifnet *ifma_ifp;
27153541Sshin	u_int	ifma_refcount;
27253541Sshin};
27353541Sshin
27453541Sshin#ifdef KERNEL
27553541Sshin#define	IFAFREE(ifa) \
27653541Sshin	if ((ifa)->ifa_refcnt <= 0) \
27753541Sshin		ifafree(ifa); \
27853541Sshin	else \
27953541Sshin		(ifa)->ifa_refcnt--;
28053541Sshin
28153541Sshinextern	struct ifnethead ifnet;
28253541Sshinextern	int ifqmaxlen;
28353541Sshinextern	struct ifnet loif[];
28453541Sshinextern	int if_index;
28553541Sshinextern	struct ifaddr **ifnet_addrs;
28653541Sshin
28753541Sshinvoid	ether_ifattach __P((struct ifnet *));
28853541Sshinvoid	ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *));
28953541Sshinint	ether_output __P((struct ifnet *,
29053541Sshin	   struct mbuf *, struct sockaddr *, struct rtentry *));
29153541Sshinint	ether_ioctl __P((struct ifnet *, int, caddr_t));
29253541Sshin
29353541Sshinint	if_addmulti __P((struct ifnet *, struct sockaddr *));
29453541Sshinint	if_allmulti __P((struct ifnet *, int));
29553541Sshinvoid	if_attach __P((struct ifnet *));
29653541Sshinint	if_delmulti __P((struct ifnet *, struct sockaddr *));
29753541Sshinvoid	if_down __P((struct ifnet *));
29853541Sshinvoid	if_up __P((struct ifnet *));
29953541Sshin#ifdef vax
30053541Sshinvoid	ifubareset __P((int));
30153541Sshin#endif
30253541Sshin/*void	ifinit __P((void));*/ /* declared in systm.h for main() */
30353541Sshinint	ifioctl __P((struct socket *, int, caddr_t, struct proc *));
30453541Sshinint	ifpromisc __P((struct ifnet *, int));
30553541Sshinstruct	ifnet *ifunit __P((char *));
30653541Sshin
30753541Sshinint	if_poll_recv_slow __P((struct ifnet *ifp, int *quotap));
30853541Sshinvoid	if_poll_xmit_slow __P((struct ifnet *ifp, int *quotap));
30953541Sshinvoid	if_poll_throttle __P((void));
31053541Sshinvoid	if_poll_unthrottle __P((void *));
31153541Sshinvoid	if_poll_init __P((void));
31253541Sshinvoid	if_poll __P((void));
31353541Sshin
31453541Sshinstruct	ifaddr *ifa_ifwithaddr __P((struct sockaddr *));
31553541Sshinstruct	ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *));
31653541Sshinstruct	ifaddr *ifa_ifwithnet __P((struct sockaddr *));
31753541Sshinstruct	ifaddr *ifa_ifwithroute __P((int, struct sockaddr *,
31853541Sshin					struct sockaddr *));
31953541Sshinstruct	ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *));
32053541Sshinvoid	ifafree __P((struct ifaddr *));
32153541Sshin
32253541Sshinint	looutput __P((struct ifnet *,
32353541Sshin	   struct mbuf *, struct sockaddr *, struct rtentry *));
32453541Sshin#endif /* KERNEL */
32553541Sshin
32653541Sshin
32753541Sshin#endif /* !_NET_IF_VAR_H_ */
32853541Sshin