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