ifq.h revision 50477
18871Srgrimes/* 21558Srgrimes * Copyright (c) 1982, 1986, 1989, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30114589Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 3223675Speter * 33114589Sobrien * From: @(#)if.h 8.1 (Berkeley) 6/10/93 3441477Sjulian * $FreeBSD: head/sys/net/if_var.h 50477 1999-08-28 01:08:13Z peter $ 35114589Sobrien */ 36114589Sobrien 371558Srgrimes#ifndef _NET_IF_VAR_H_ 381558Srgrimes#define _NET_IF_VAR_H_ 3962668Smckusick 4074556Smckusick/* 4123675Speter * Structures defining a network interface, providing a packet 421558Srgrimes * transport mechanism (ala level 0 of the PUP protocols). 431558Srgrimes * 441558Srgrimes * Each interface accepts output datagrams of a specified maximum 4523675Speter * length, and provides higher level routines with input datagrams 4623675Speter * received from its medium. 47103949Smike * 48101037Smux * Output occurs when the routine if_output is called, with three parameters: 491558Srgrimes * (*ifp->if_output)(ifp, m, dst, rt) 5023675Speter * Here m is the mbuf chain to be sent and dst is the destination address. 511558Srgrimes * The output routine encapsulates the supplied datagram if necessary, 521558Srgrimes * and then transmits it on its medium. 5398542Smckusick * 5498542Smckusick * On input, each interface unwraps the data received by it, and either 5541474Sjulian * places it on the input queue of a internetwork datagram routine 561558Srgrimes * and posts the associated software interrupt, or passes the datagram to a raw 57188110Smckusick * packet input routine. 587585Sbde * 597585Sbde * Routines exist for locating interfaces by their addresses 6092839Simp * or for locating a interface on a certain network, as well as more general 611558Srgrimes * routing and gateway routines maintaining information used to locate 6241474Sjulian * interfaces. These routines live in the files if.c and route.c 631558Srgrimes */ 64249788Smckusick 65249788Smckusick#ifdef __STDC__ 66188110Smckusick/* 6798542Smckusick * Forward structure declarations for function prototypes [sic]. 6898542Smckusick */ 69188110Smckusickstruct mbuf; 701558Srgrimesstruct proc; 711558Srgrimesstruct rtentry; 72102231Strhodesstruct socket; 731558Srgrimesstruct ether_header; 741558Srgrimes#endif 751558Srgrimes 761558Srgrimes#include <sys/queue.h> /* get TAILQ macros */ 771558Srgrimes 781558SrgrimesTAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ 791558SrgrimesTAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ 801558SrgrimesLIST_HEAD(ifmultihead, ifmultiaddr); 811558Srgrimes 821558Srgrimes/* 8369800Stomsoft * Structure defining a queue for a network interface. 8469800Stomsoft */ 8569800Stomsoftstruct ifqueue { 8669800Stomsoft struct mbuf *ifq_head; 8769800Stomsoft struct mbuf *ifq_tail; 881558Srgrimes int ifq_len; 891558Srgrimes int ifq_maxlen; 901558Srgrimes int ifq_drops; 9123675Speter}; 921558Srgrimes 931558Srgrimes/* 941558Srgrimes * Structure defining a network interface. 9541474Sjulian * 9641474Sjulian * (Would like to call this struct ``if'', but C isn't PL/1.) 97249788Smckusick */ 98249788Smckusickstruct ifnet { 99188110Smckusick void *if_softc; /* pointer to driver state */ 100249788Smckusick char *if_name; /* name, e.g. ``en'' or ``lo'' */ 101188110Smckusick TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ 102188110Smckusick struct ifaddrhead if_addrhead; /* linked list of addresses per if */ 103249788Smckusick int if_pcount; /* number of promiscuous listeners */ 104201708Smckusick struct bpf_if *if_bpf; /* packet filter structure */ 105201708Smckusick u_short if_index; /* numeric abbreviation for this if */ 106201708Smckusick short if_unit; /* sub-unit for lower level driver */ 107201708Smckusick short if_timer; /* time 'til if_watchdog called */ 108201708Smckusick short if_flags; /* up/down, broadcast, etc. */ 109176575Sdelphij int if_ipending; /* interrupts pending */ 110201708Smckusick void *if_linkmib; /* link-type-specific MIB data */ 111201708Smckusick size_t if_linkmiblen; /* length of above data */ 11298542Smckusick struct if_data if_data; 113201708Smckusick struct ifmultihead if_multiaddrs; /* multicast addresses configured */ 11470050Siedowse int if_amcount; /* number of all-multicast requests */ 11570050Siedowse/* procedure handles */ 11670050Siedowse int (*if_output) /* output routine (enqueue) */ 11770050Siedowse __P((struct ifnet *, struct mbuf *, struct sockaddr *, 11870050Siedowse struct rtentry *)); 11970050Siedowse void (*if_start) /* initiate output routine */ 120126345Sscottl __P((struct ifnet *)); 121126345Sscottl int (*if_done) /* output complete routine */ 122126345Sscottl __P((struct ifnet *)); /* (XXX not used; fake prototype) */ 123126345Sscottl int (*if_ioctl) /* ioctl routine */ 124126345Sscottl __P((struct ifnet *, u_long, caddr_t)); 12541474Sjulian void (*if_watchdog) /* timer routine */ 12641474Sjulian __P((struct ifnet *)); 12741474Sjulian int (*if_poll_recv) /* polled receive routine */ 12841474Sjulian __P((struct ifnet *, int *)); 12941474Sjulian int (*if_poll_xmit) /* polled transmit routine */ 13041474Sjulian __P((struct ifnet *, int *)); 13141474Sjulian void (*if_poll_intren) /* polled interrupt reenable routine */ 132188110Smckusick __P((struct ifnet *)); 133249788Smckusick void (*if_poll_slowinput) /* input routine for slow devices */ 134103949Smike __P((struct ifnet *, struct mbuf *)); 13541474Sjulian void (*if_init) /* Init routine */ 13641474Sjulian __P((void *)); 137103949Smike int (*if_resolvemulti) /* validate/resolve multicast */ 13841474Sjulian __P((struct ifnet *, struct sockaddr **, struct sockaddr *)); 13941474Sjulian struct ifqueue if_snd; /* output queue */ 14041474Sjulian struct ifqueue *if_poll_slowq; /* input queue for slow devices */ 14141474Sjulian}; 14241474Sjuliantypedef void if_init_f_t __P((void *)); 14341474Sjulian 14441474Sjulian#define if_mtu if_data.ifi_mtu 14541474Sjulian#define if_type if_data.ifi_type 14641474Sjulian#define if_physical if_data.ifi_physical 14741474Sjulian#define if_addrlen if_data.ifi_addrlen 14841474Sjulian#define if_hdrlen if_data.ifi_hdrlen 14941474Sjulian#define if_metric if_data.ifi_metric 15041474Sjulian#define if_baudrate if_data.ifi_baudrate 15141474Sjulian#define if_ipackets if_data.ifi_ipackets 15241474Sjulian#define if_ierrors if_data.ifi_ierrors 15341474Sjulian#define if_opackets if_data.ifi_opackets 15441474Sjulian#define if_oerrors if_data.ifi_oerrors 155249788Smckusick#define if_collisions if_data.ifi_collisions 15641474Sjulian#define if_ibytes if_data.ifi_ibytes 157125036Scperciva#define if_obytes if_data.ifi_obytes 15841474Sjulian#define if_imcasts if_data.ifi_imcasts 15941474Sjulian#define if_omcasts if_data.ifi_omcasts 16041474Sjulian#define if_iqdrops if_data.ifi_iqdrops 16141474Sjulian#define if_noproto if_data.ifi_noproto 16241474Sjulian#define if_lastchange if_data.ifi_lastchange 16341474Sjulian#define if_recvquota if_data.ifi_recvquota 16441474Sjulian#define if_xmitquota if_data.ifi_xmitquota 165188110Smckusick#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0) 1661558Srgrimes 16741474Sjulian/* 168188110Smckusick * Bit values in if_ipending 169188110Smckusick */ 170188110Smckusick#define IFI_RECV 1 /* I want to receive */ 171188110Smckusick#define IFI_XMIT 2 /* I want to transmit */ 172188110Smckusick 173188110Smckusick/* 174188110Smckusick * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) 175249788Smckusick * are queues of messages stored on ifqueue structures 176188110Smckusick * (defined above). Entries are added to and deleted from these structures 1771558Srgrimes * by these macros, which should be called with ipl raised to splimp(). 178188110Smckusick */ 179188110Smckusick#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 180188110Smckusick#define IF_DROP(ifq) ((ifq)->ifq_drops++) 181188110Smckusick#define IF_ENQUEUE(ifq, m) { \ 182188110Smckusick (m)->m_nextpkt = 0; \ 183188110Smckusick if ((ifq)->ifq_tail == 0) \ 184188110Smckusick (ifq)->ifq_head = m; \ 185188110Smckusick else \ 186188110Smckusick (ifq)->ifq_tail->m_nextpkt = m; \ 187249788Smckusick (ifq)->ifq_tail = m; \ 188249788Smckusick (ifq)->ifq_len++; \ 189249788Smckusick} 190188110Smckusick#define IF_PREPEND(ifq, m) { \ 191249788Smckusick (m)->m_nextpkt = (ifq)->ifq_head; \ 192188110Smckusick if ((ifq)->ifq_tail == 0) \ 193249788Smckusick (ifq)->ifq_tail = (m); \ 194188110Smckusick (ifq)->ifq_head = (m); \ 195249788Smckusick (ifq)->ifq_len++; \ 196249788Smckusick} 197188110Smckusick#define IF_DEQUEUE(ifq, m) { \ 198188110Smckusick (m) = (ifq)->ifq_head; \ 199188110Smckusick if (m) { \ 20041474Sjulian if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \ 201188110Smckusick (ifq)->ifq_tail = 0; \ 202188110Smckusick (m)->m_nextpkt = 0; \ 203188110Smckusick (ifq)->ifq_len--; \ 204188110Smckusick } \ 205249788Smckusick} 206188110Smckusick 207249788Smckusick#ifdef KERNEL 208188110Smckusick#define IF_ENQ_DROP(ifq, m) if_enq_drop(ifq, m) 209249788Smckusick 210188110Smckusick#if defined(__GNUC__) && defined(MT_HEADER) 21141474Sjulianstatic __inline int 21241474Sjulianif_queue_drop(struct ifqueue *ifq, struct mbuf *m) 21341474Sjulian{ 21441474Sjulian IF_DROP(ifq); 21541474Sjulian return 0; 21641474Sjulian} 217188110Smckusick 218188110Smckusickstatic __inline int 21941474Sjulianif_enq_drop(struct ifqueue *ifq, struct mbuf *m) 22041474Sjulian{ 22141474Sjulian if (IF_QFULL(ifq) && 22241474Sjulian !if_queue_drop(ifq, m)) 22341474Sjulian return 0; 22441474Sjulian IF_ENQUEUE(ifq, m); 225249788Smckusick return 1; 22641474Sjulian} 227125036Scperciva#else 22841474Sjulian 22941474Sjulian#ifdef MT_HEADER 23041474Sjulianint if_enq_drop __P((struct ifqueue *, struct mbuf *)); 23141474Sjulian#endif 2321558Srgrimes 2331558Srgrimes#endif 2341558Srgrimes 2351558Srgrimes/* 236188110Smckusick * 72 was chosen below because it is the size of a TCP/IP 237188110Smckusick * header (40) + the minimum mss (32). 2381558Srgrimes */ 23998542Smckusick#define IF_MINMTU 72 24098542Smckusick#define IF_MAXMTU 65535 24198542Smckusick 2421558Srgrimes#endif /* KERNEL */ 243103885Smckusick 2441558Srgrimes/* 245188110Smckusick * The ifaddr structure contains information about one address 246188110Smckusick * of an interface. They are maintained by the different address families, 24798542Smckusick * are allocated and attached when an address is set, and are linked 2481558Srgrimes * together so all addresses for an interface can be located. 24998542Smckusick */ 25098542Smckusickstruct ifaddr { 25198542Smckusick struct sockaddr *ifa_addr; /* address of interface */ 25298542Smckusick struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ 25398542Smckusick#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 25498542Smckusick struct sockaddr *ifa_netmask; /* used to determine subnet */ 25598542Smckusick struct ifnet *ifa_ifp; /* back-pointer to interface */ 25698542Smckusick TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ 25798542Smckusick void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ 25898542Smckusick __P((int, struct rtentry *, struct sockaddr *)); 25998542Smckusick u_short ifa_flags; /* mostly rt_flags for cloning */ 26098542Smckusick u_int ifa_refcnt; /* references to this structure */ 26186514Siedowse int ifa_metric; /* cost of going out this interface */ 26286514Siedowse#ifdef notdef 2631558Srgrimes struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */ 2641558Srgrimes#endif 2651558Srgrimes int (*ifa_claim_addr) /* check if an addr goes to this if */ 2661558Srgrimes __P((struct ifaddr *, struct sockaddr *)); 2671558Srgrimes 2681558Srgrimes}; 26941474Sjulian#define IFA_ROUTE RTF_UP /* route installed */ 270188110Smckusick 2711558Srgrimes/* 2721558Srgrimes * Multicast address structure. This is analogous to the ifaddr 27371884Siedowse * structure except that it keeps track of multicast addresses. 27498888Siedowse * Also, the reference count here is a count of requests for this 27598888Siedowse * address, not a count of pointers to this structure. 27698888Siedowse */ 27798888Siedowsestruct ifmultiaddr { 27898542Smckusick LIST_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ 27998542Smckusick struct sockaddr *ifma_addr; /* address this membership is for */ 28098542Smckusick struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ 2811558Srgrimes struct ifnet *ifma_ifp; /* back-pointer to interface */ 282101037Smux u_int ifma_refcount; /* reference count */ 2831558Srgrimes void *ifma_protospec; /* protocol-specific state, if any */ 2841558Srgrimes}; 2851558Srgrimes 2861558Srgrimes#ifdef KERNEL 287134589Sscottl#define IFAFREE(ifa) \ 288134589Sscottl do { \ 2891558Srgrimes if ((ifa)->ifa_refcnt <= 0) \ 2901558Srgrimes ifafree(ifa); \ 29163003Smckusick else \ 29298542Smckusick (ifa)->ifa_refcnt--; \ 29363003Smckusick } while (0) 294101037Smux 295101037Smuxextern struct ifnethead ifnet; 29663003Smckusickextern int ifqmaxlen; 29763003Smckusickextern struct ifnet loif[]; 29898542Smckusickextern int if_index; 29998542Smckusickextern struct ifaddr **ifnet_addrs; 30072525Stegge 30172525Steggevoid ether_ifattach __P((struct ifnet *)); 30272525Steggevoid ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *)); 30372525Steggeint ether_output __P((struct ifnet *, 30498542Smckusick struct mbuf *, struct sockaddr *, struct rtentry *)); 3051558Srgrimesint ether_ioctl __P((struct ifnet *, int, caddr_t)); 3061558Srgrimes 307101037Smuxint if_addmulti __P((struct ifnet *, struct sockaddr *, 308101037Smux struct ifmultiaddr **)); 3091558Srgrimesint if_allmulti __P((struct ifnet *, int)); 3101558Srgrimesvoid if_attach __P((struct ifnet *)); 3111558Srgrimesint if_delmulti __P((struct ifnet *, struct sockaddr *)); 3121558Srgrimesvoid if_detach __P((struct ifnet *)); 3131558Srgrimesvoid if_down __P((struct ifnet *)); 3141558Srgrimesvoid if_route __P((struct ifnet *, int flag, int fam)); 3151558Srgrimesvoid if_unroute __P((struct ifnet *, int flag, int fam)); 3161558Srgrimesvoid if_up __P((struct ifnet *)); 3171558Srgrimes/*void ifinit __P((void));*/ /* declared in systm.h for main() */ 31898542Smckusickint ifioctl __P((struct socket *, u_long, caddr_t, struct proc *)); 31998542Smckusickint ifpromisc __P((struct ifnet *, int)); 32098542Smckusickstruct ifnet *ifunit __P((char *)); 32198542Smckusick 32298542Smckusickint if_poll_recv_slow __P((struct ifnet *ifp, int *quotap)); 32398542Smckusickvoid if_poll_xmit_slow __P((struct ifnet *ifp, int *quotap)); 32498542Smckusickvoid if_poll_throttle __P((void)); 3251558Srgrimesvoid if_poll_unthrottle __P((void *)); 3261558Srgrimesvoid if_poll_init __P((void)); 3271558Srgrimesvoid if_poll __P((void)); 3281558Srgrimes 3291558Srgrimesstruct ifaddr *ifa_ifwithaddr __P((struct sockaddr *)); 3301558Srgrimesstruct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *)); 3311558Srgrimesstruct ifaddr *ifa_ifwithnet __P((struct sockaddr *)); 3321558Srgrimesstruct ifaddr *ifa_ifwithroute __P((int, struct sockaddr *, 33398879Siedowse struct sockaddr *)); 33498542Smckusickstruct ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *)); 3351558Srgrimesvoid ifafree __P((struct ifaddr *)); 336101037Smux 337101037Smuxstruct ifmultiaddr *ifmaof_ifpforaddr __P((struct sockaddr *, 3381558Srgrimes struct ifnet *)); 3391558Srgrimesint if_simloop __P((struct ifnet *ifp, struct mbuf *m, 3401558Srgrimes struct sockaddr *dst, int hlen)); 3411558Srgrimes 3421558Srgrimes#endif /* KERNEL */ 34398542Smckusick 3441558Srgrimes 345101037Smux#endif /* !_NET_IF_VAR_H_ */ 346101037Smux