119ff91c6SGarrett Wollman /* 219ff91c6SGarrett Wollman * Copyright (c) 1982, 1986, 1989, 1993 319ff91c6SGarrett Wollman * The Regents of the University of California. All rights reserved. 419ff91c6SGarrett Wollman * 519ff91c6SGarrett Wollman * Redistribution and use in source and binary forms, with or without 619ff91c6SGarrett Wollman * modification, are permitted provided that the following conditions 719ff91c6SGarrett Wollman * are met: 819ff91c6SGarrett Wollman * 1. Redistributions of source code must retain the above copyright 919ff91c6SGarrett Wollman * notice, this list of conditions and the following disclaimer. 1019ff91c6SGarrett Wollman * 2. Redistributions in binary form must reproduce the above copyright 1119ff91c6SGarrett Wollman * notice, this list of conditions and the following disclaimer in the 1219ff91c6SGarrett Wollman * documentation and/or other materials provided with the distribution. 1319ff91c6SGarrett Wollman * 3. All advertising materials mentioning features or use of this software 1419ff91c6SGarrett Wollman * must display the following acknowledgement: 1519ff91c6SGarrett Wollman * This product includes software developed by the University of 1619ff91c6SGarrett Wollman * California, Berkeley and its contributors. 1719ff91c6SGarrett Wollman * 4. Neither the name of the University nor the names of its contributors 1819ff91c6SGarrett Wollman * may be used to endorse or promote products derived from this software 1919ff91c6SGarrett Wollman * without specific prior written permission. 2019ff91c6SGarrett Wollman * 2119ff91c6SGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2219ff91c6SGarrett Wollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2319ff91c6SGarrett Wollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2419ff91c6SGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2519ff91c6SGarrett Wollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2619ff91c6SGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2719ff91c6SGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2819ff91c6SGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2919ff91c6SGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3019ff91c6SGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3119ff91c6SGarrett Wollman * SUCH DAMAGE. 3219ff91c6SGarrett Wollman * 3319ff91c6SGarrett Wollman * From: @(#)if.h 8.1 (Berkeley) 6/10/93 34c3aac50fSPeter Wemm * $FreeBSD$ 3519ff91c6SGarrett Wollman */ 3619ff91c6SGarrett Wollman 3719ff91c6SGarrett Wollman #ifndef _NET_IF_VAR_H_ 3819ff91c6SGarrett Wollman #define _NET_IF_VAR_H_ 3919ff91c6SGarrett Wollman 4019ff91c6SGarrett Wollman /* 4119ff91c6SGarrett Wollman * Structures defining a network interface, providing a packet 4219ff91c6SGarrett Wollman * transport mechanism (ala level 0 of the PUP protocols). 4319ff91c6SGarrett Wollman * 4419ff91c6SGarrett Wollman * Each interface accepts output datagrams of a specified maximum 4519ff91c6SGarrett Wollman * length, and provides higher level routines with input datagrams 4619ff91c6SGarrett Wollman * received from its medium. 4719ff91c6SGarrett Wollman * 4819ff91c6SGarrett Wollman * Output occurs when the routine if_output is called, with three parameters: 4919ff91c6SGarrett Wollman * (*ifp->if_output)(ifp, m, dst, rt) 5019ff91c6SGarrett Wollman * Here m is the mbuf chain to be sent and dst is the destination address. 5119ff91c6SGarrett Wollman * The output routine encapsulates the supplied datagram if necessary, 5219ff91c6SGarrett Wollman * and then transmits it on its medium. 5319ff91c6SGarrett Wollman * 5419ff91c6SGarrett Wollman * On input, each interface unwraps the data received by it, and either 559d5abbddSJens Schweikhardt * places it on the input queue of an internetwork datagram routine 5619ff91c6SGarrett Wollman * and posts the associated software interrupt, or passes the datagram to a raw 5719ff91c6SGarrett Wollman * packet input routine. 5819ff91c6SGarrett Wollman * 5919ff91c6SGarrett Wollman * Routines exist for locating interfaces by their addresses 609d5abbddSJens Schweikhardt * or for locating an interface on a certain network, as well as more general 6119ff91c6SGarrett Wollman * routing and gateway routines maintaining information used to locate 6219ff91c6SGarrett Wollman * interfaces. These routines live in the files if.c and route.c 6319ff91c6SGarrett Wollman */ 6419ff91c6SGarrett Wollman 6519ff91c6SGarrett Wollman #ifdef __STDC__ 6619ff91c6SGarrett Wollman /* 6719ff91c6SGarrett Wollman * Forward structure declarations for function prototypes [sic]. 6819ff91c6SGarrett Wollman */ 6919ff91c6SGarrett Wollman struct mbuf; 70b40ce416SJulian Elischer struct thread; 7119ff91c6SGarrett Wollman struct rtentry; 728071913dSRuslan Ermilov struct rt_addrinfo; 7319ff91c6SGarrett Wollman struct socket; 7419ff91c6SGarrett Wollman struct ether_header; 7519ff91c6SGarrett Wollman #endif 7619ff91c6SGarrett Wollman 7719ff91c6SGarrett Wollman #include <sys/queue.h> /* get TAILQ macros */ 7819ff91c6SGarrett Wollman 799ba20c31SJonathan Lemon #ifdef _KERNEL 80df5e1987SJonathan Lemon #include <sys/mbuf.h> 819ba20c31SJonathan Lemon #endif /* _KERNEL */ 82f34fa851SJohn Baldwin #include <sys/lock.h> /* XXX */ 83f34fa851SJohn Baldwin #include <sys/mutex.h> /* XXX */ 84f9132cebSJonathan Lemon #include <sys/event.h> /* XXX */ 85df5e1987SJonathan Lemon 869bf40edeSBrooks Davis #define IF_DUNIT_NONE -1 879bf40edeSBrooks Davis 88e3975643SJake Burkholder TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ 89e3975643SJake Burkholder TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ 90e3975643SJake Burkholder TAILQ_HEAD(ifprefixhead, ifprefix); 916817526dSPoul-Henning Kamp TAILQ_HEAD(ifmultihead, ifmultiaddr); 9219ff91c6SGarrett Wollman 9319ff91c6SGarrett Wollman /* 9419ff91c6SGarrett Wollman * Structure defining a queue for a network interface. 9519ff91c6SGarrett Wollman */ 9619ff91c6SGarrett Wollman struct ifqueue { 9719ff91c6SGarrett Wollman struct mbuf *ifq_head; 9819ff91c6SGarrett Wollman struct mbuf *ifq_tail; 9919ff91c6SGarrett Wollman int ifq_len; 10019ff91c6SGarrett Wollman int ifq_maxlen; 10119ff91c6SGarrett Wollman int ifq_drops; 102df5e1987SJonathan Lemon struct mtx ifq_mtx; 10319ff91c6SGarrett Wollman }; 10419ff91c6SGarrett Wollman 10519ff91c6SGarrett Wollman /* 10619ff91c6SGarrett Wollman * Structure defining a network interface. 10719ff91c6SGarrett Wollman * 10819ff91c6SGarrett Wollman * (Would like to call this struct ``if'', but C isn't PL/1.) 10919ff91c6SGarrett Wollman */ 1108ec410b5SMatt Jacob 1118ec410b5SMatt Jacob /* 1128ec410b5SMatt Jacob * NB: For FreeBSD, it is assumed that each NIC driver's softc starts with 1138ec410b5SMatt Jacob * one of these structures, typically held within an arpcom structure. 114985fbf6bSLuigi Rizzo * 115985fbf6bSLuigi Rizzo * struct <foo>_softc { 116985fbf6bSLuigi Rizzo * struct arpcom { 117985fbf6bSLuigi Rizzo * struct ifnet ac_if; 118985fbf6bSLuigi Rizzo * ... 119985fbf6bSLuigi Rizzo * } <arpcom> ; 120985fbf6bSLuigi Rizzo * ... 121985fbf6bSLuigi Rizzo * }; 122985fbf6bSLuigi Rizzo * 123985fbf6bSLuigi Rizzo * The assumption is used in a number of places, including many 124985fbf6bSLuigi Rizzo * files in sys/net, device drivers, and sys/dev/mii.c:miibus_attach(). 125985fbf6bSLuigi Rizzo * 126985fbf6bSLuigi Rizzo * Unfortunately devices' softc are opaque, so we depend on this layout 127985fbf6bSLuigi Rizzo * to locate the struct ifnet from the softc in the generic code. 128985fbf6bSLuigi Rizzo * 1298ec410b5SMatt Jacob */ 13019ff91c6SGarrett Wollman struct ifnet { 13119ff91c6SGarrett Wollman void *if_softc; /* pointer to driver state */ 132e3975643SJake Burkholder TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ 1339bf40edeSBrooks Davis char if_xname[IFNAMSIZ]; /* external name (name + unit) */ 1349bf40edeSBrooks Davis const char *if_dname; /* driver name */ 1359bf40edeSBrooks Davis int if_dunit; /* unit or IF_DUNIT_NONE */ 13619ff91c6SGarrett Wollman struct ifaddrhead if_addrhead; /* linked list of addresses per if */ 137f9132cebSJonathan Lemon struct klist if_klist; /* events attached to this if */ 13819ff91c6SGarrett Wollman int if_pcount; /* number of promiscuous listeners */ 13919ff91c6SGarrett Wollman struct bpf_if *if_bpf; /* packet filter structure */ 14019ff91c6SGarrett Wollman u_short if_index; /* numeric abbreviation for this if */ 14119ff91c6SGarrett Wollman short if_timer; /* time 'til if_watchdog called */ 14276cfd300SSam Leffler u_short if_nvlans; /* number of active vlans */ 14362f76486SMaxim Sobolev int if_flags; /* up/down, broadcast, etc. */ 144016da741SJonathan Lemon int if_capabilities; /* interface capabilities */ 145016da741SJonathan Lemon int if_capenable; /* enabled features */ 14619ff91c6SGarrett Wollman int if_ipending; /* interrupts pending */ 14719ff91c6SGarrett Wollman void *if_linkmib; /* link-type-specific MIB data */ 14819ff91c6SGarrett Wollman size_t if_linkmiblen; /* length of above data */ 14919ff91c6SGarrett Wollman struct if_data if_data; 1501158dfb7SGarrett Wollman struct ifmultihead if_multiaddrs; /* multicast addresses configured */ 1511158dfb7SGarrett Wollman int if_amcount; /* number of all-multicast requests */ 15219ff91c6SGarrett Wollman /* procedure handles */ 15319ff91c6SGarrett Wollman int (*if_output) /* output routine (enqueue) */ 154929ddbbbSAlfred Perlstein (struct ifnet *, struct mbuf *, struct sockaddr *, 155929ddbbbSAlfred Perlstein struct rtentry *); 15676cfd300SSam Leffler void (*if_input) /* input routine (from h/w driver) */ 15776cfd300SSam Leffler (struct ifnet *, struct mbuf *); 15819ff91c6SGarrett Wollman void (*if_start) /* initiate output routine */ 159929ddbbbSAlfred Perlstein (struct ifnet *); 16019ff91c6SGarrett Wollman int (*if_done) /* output complete routine */ 161929ddbbbSAlfred Perlstein (struct ifnet *); /* (XXX not used; fake prototype) */ 16219ff91c6SGarrett Wollman int (*if_ioctl) /* ioctl routine */ 163929ddbbbSAlfred Perlstein (struct ifnet *, u_long, caddr_t); 16419ff91c6SGarrett Wollman void (*if_watchdog) /* timer routine */ 165929ddbbbSAlfred Perlstein (struct ifnet *); 16619ff91c6SGarrett Wollman int (*if_poll_recv) /* polled receive routine */ 167929ddbbbSAlfred Perlstein (struct ifnet *, int *); 16819ff91c6SGarrett Wollman int (*if_poll_xmit) /* polled transmit routine */ 169929ddbbbSAlfred Perlstein (struct ifnet *, int *); 17019ff91c6SGarrett Wollman void (*if_poll_intren) /* polled interrupt reenable routine */ 171929ddbbbSAlfred Perlstein (struct ifnet *); 17219ff91c6SGarrett Wollman void (*if_poll_slowinput) /* input routine for slow devices */ 173929ddbbbSAlfred Perlstein (struct ifnet *, struct mbuf *); 17419ff91c6SGarrett Wollman void (*if_init) /* Init routine */ 175929ddbbbSAlfred Perlstein (void *); 1761158dfb7SGarrett Wollman int (*if_resolvemulti) /* validate/resolve multicast */ 177929ddbbbSAlfred Perlstein (struct ifnet *, struct sockaddr **, struct sockaddr *); 17819ff91c6SGarrett Wollman struct ifqueue if_snd; /* output queue */ 17919ff91c6SGarrett Wollman struct ifqueue *if_poll_slowq; /* input queue for slow devices */ 18076429de4SYoshinobu Inoue struct ifprefixhead if_prefixhead; /* list of prefixes per if */ 181322dcb8dSMax Khon u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ 182eca8a663SRobert Watson struct label *if_label; /* interface MAC label */ 18331b1bfe1SHajimu UMEMOTO 18431b1bfe1SHajimu UMEMOTO void *if_afdata[AF_MAX]; 185234a35c7SHajimu UMEMOTO int if_afdata_initialized; 186234a35c7SHajimu UMEMOTO struct mtx if_afdata_mtx; 18719ff91c6SGarrett Wollman }; 188df5e1987SJonathan Lemon 189929ddbbbSAlfred Perlstein typedef void if_init_f_t(void *); 19019ff91c6SGarrett Wollman 19119ff91c6SGarrett Wollman #define if_mtu if_data.ifi_mtu 19219ff91c6SGarrett Wollman #define if_type if_data.ifi_type 19319ff91c6SGarrett Wollman #define if_physical if_data.ifi_physical 19419ff91c6SGarrett Wollman #define if_addrlen if_data.ifi_addrlen 19519ff91c6SGarrett Wollman #define if_hdrlen if_data.ifi_hdrlen 19619ff91c6SGarrett Wollman #define if_metric if_data.ifi_metric 19719ff91c6SGarrett Wollman #define if_baudrate if_data.ifi_baudrate 198db4f9cc7SJonathan Lemon #define if_hwassist if_data.ifi_hwassist 19919ff91c6SGarrett Wollman #define if_ipackets if_data.ifi_ipackets 20019ff91c6SGarrett Wollman #define if_ierrors if_data.ifi_ierrors 20119ff91c6SGarrett Wollman #define if_opackets if_data.ifi_opackets 20219ff91c6SGarrett Wollman #define if_oerrors if_data.ifi_oerrors 20319ff91c6SGarrett Wollman #define if_collisions if_data.ifi_collisions 20419ff91c6SGarrett Wollman #define if_ibytes if_data.ifi_ibytes 20519ff91c6SGarrett Wollman #define if_obytes if_data.ifi_obytes 20619ff91c6SGarrett Wollman #define if_imcasts if_data.ifi_imcasts 20719ff91c6SGarrett Wollman #define if_omcasts if_data.ifi_omcasts 20819ff91c6SGarrett Wollman #define if_iqdrops if_data.ifi_iqdrops 20919ff91c6SGarrett Wollman #define if_noproto if_data.ifi_noproto 21019ff91c6SGarrett Wollman #define if_lastchange if_data.ifi_lastchange 21119ff91c6SGarrett Wollman #define if_recvquota if_data.ifi_recvquota 21219ff91c6SGarrett Wollman #define if_xmitquota if_data.ifi_xmitquota 21319ff91c6SGarrett Wollman #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0) 21419ff91c6SGarrett Wollman 21582cd038dSYoshinobu Inoue /* for compatibility with other BSDs */ 21682cd038dSYoshinobu Inoue #define if_addrlist if_addrhead 21782cd038dSYoshinobu Inoue #define if_list if_link 21882cd038dSYoshinobu Inoue 21919ff91c6SGarrett Wollman /* 22019ff91c6SGarrett Wollman * Bit values in if_ipending 22119ff91c6SGarrett Wollman */ 22219ff91c6SGarrett Wollman #define IFI_RECV 1 /* I want to receive */ 22319ff91c6SGarrett Wollman #define IFI_XMIT 2 /* I want to transmit */ 22419ff91c6SGarrett Wollman 22519ff91c6SGarrett Wollman /* 22619ff91c6SGarrett Wollman * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) 22719ff91c6SGarrett Wollman * are queues of messages stored on ifqueue structures 22819ff91c6SGarrett Wollman * (defined above). Entries are added to and deleted from these structures 22919ff91c6SGarrett Wollman * by these macros, which should be called with ipl raised to splimp(). 23019ff91c6SGarrett Wollman */ 2319ed346baSBosko Milekic #define IF_LOCK(ifq) mtx_lock(&(ifq)->ifq_mtx) 2329ed346baSBosko Milekic #define IF_UNLOCK(ifq) mtx_unlock(&(ifq)->ifq_mtx) 233df5e1987SJonathan Lemon #define _IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 234df5e1987SJonathan Lemon #define _IF_DROP(ifq) ((ifq)->ifq_drops++) 235df5e1987SJonathan Lemon #define _IF_QLEN(ifq) ((ifq)->ifq_len) 236df5e1987SJonathan Lemon 237df5e1987SJonathan Lemon #define _IF_ENQUEUE(ifq, m) do { \ 238df5e1987SJonathan Lemon (m)->m_nextpkt = NULL; \ 239df5e1987SJonathan Lemon if ((ifq)->ifq_tail == NULL) \ 24019ff91c6SGarrett Wollman (ifq)->ifq_head = m; \ 24119ff91c6SGarrett Wollman else \ 24219ff91c6SGarrett Wollman (ifq)->ifq_tail->m_nextpkt = m; \ 24319ff91c6SGarrett Wollman (ifq)->ifq_tail = m; \ 24419ff91c6SGarrett Wollman (ifq)->ifq_len++; \ 245df5e1987SJonathan Lemon } while (0) 246df5e1987SJonathan Lemon 247df5e1987SJonathan Lemon #define IF_ENQUEUE(ifq, m) do { \ 248df5e1987SJonathan Lemon IF_LOCK(ifq); \ 249df5e1987SJonathan Lemon _IF_ENQUEUE(ifq, m); \ 250df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 251df5e1987SJonathan Lemon } while (0) 252df5e1987SJonathan Lemon 253df5e1987SJonathan Lemon #define _IF_PREPEND(ifq, m) do { \ 25419ff91c6SGarrett Wollman (m)->m_nextpkt = (ifq)->ifq_head; \ 255df5e1987SJonathan Lemon if ((ifq)->ifq_tail == NULL) \ 25619ff91c6SGarrett Wollman (ifq)->ifq_tail = (m); \ 25719ff91c6SGarrett Wollman (ifq)->ifq_head = (m); \ 25819ff91c6SGarrett Wollman (ifq)->ifq_len++; \ 259df5e1987SJonathan Lemon } while (0) 260df5e1987SJonathan Lemon 261df5e1987SJonathan Lemon #define IF_PREPEND(ifq, m) do { \ 262df5e1987SJonathan Lemon IF_LOCK(ifq); \ 263df5e1987SJonathan Lemon _IF_PREPEND(ifq, m); \ 264df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 265df5e1987SJonathan Lemon } while (0) 266df5e1987SJonathan Lemon 267df5e1987SJonathan Lemon #define _IF_DEQUEUE(ifq, m) do { \ 26819ff91c6SGarrett Wollman (m) = (ifq)->ifq_head; \ 26919ff91c6SGarrett Wollman if (m) { \ 27019ff91c6SGarrett Wollman if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \ 271df5e1987SJonathan Lemon (ifq)->ifq_tail = NULL; \ 272df5e1987SJonathan Lemon (m)->m_nextpkt = NULL; \ 27319ff91c6SGarrett Wollman (ifq)->ifq_len--; \ 27419ff91c6SGarrett Wollman } \ 275df5e1987SJonathan Lemon } while (0) 276df5e1987SJonathan Lemon 277df5e1987SJonathan Lemon #define IF_DEQUEUE(ifq, m) do { \ 278df5e1987SJonathan Lemon IF_LOCK(ifq); \ 279df5e1987SJonathan Lemon _IF_DEQUEUE(ifq, m); \ 280df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 281df5e1987SJonathan Lemon } while (0) 282df5e1987SJonathan Lemon 283df5e1987SJonathan Lemon #define IF_DRAIN(ifq) do { \ 284df5e1987SJonathan Lemon struct mbuf *m; \ 285df5e1987SJonathan Lemon IF_LOCK(ifq); \ 286df5e1987SJonathan Lemon for (;;) { \ 287df5e1987SJonathan Lemon _IF_DEQUEUE(ifq, m); \ 288df5e1987SJonathan Lemon if (m == NULL) \ 289df5e1987SJonathan Lemon break; \ 290df5e1987SJonathan Lemon m_freem(m); \ 291df5e1987SJonathan Lemon } \ 292df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 293df5e1987SJonathan Lemon } while (0) 29419ff91c6SGarrett Wollman 295664a31e4SPeter Wemm #ifdef _KERNEL 296234a35c7SHajimu UMEMOTO #define IF_AFDATA_LOCK_INIT(ifp) \ 297234a35c7SHajimu UMEMOTO mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF) 298234a35c7SHajimu UMEMOTO #define IF_AFDATA_LOCK(ifp) mtx_lock(&(ifp)->if_afdata_mtx) 299234a35c7SHajimu UMEMOTO #define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_mtx) 300234a35c7SHajimu UMEMOTO #define IF_AFDATA_UNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_mtx) 301234a35c7SHajimu UMEMOTO #define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_mtx) 302234a35c7SHajimu UMEMOTO 303df5e1987SJonathan Lemon #define IF_HANDOFF(ifq, m, ifp) if_handoff(ifq, m, ifp, 0) 304df5e1987SJonathan Lemon #define IF_HANDOFF_ADJ(ifq, m, ifp, adj) if_handoff(ifq, m, ifp, adj) 30519ff91c6SGarrett Wollman 306c1087c13SBruce Evans static __inline int 307df5e1987SJonathan Lemon if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, int adjust) 30819ff91c6SGarrett Wollman { 309df5e1987SJonathan Lemon int active = 0; 310df5e1987SJonathan Lemon 311df5e1987SJonathan Lemon IF_LOCK(ifq); 312df5e1987SJonathan Lemon if (_IF_QFULL(ifq)) { 313df5e1987SJonathan Lemon _IF_DROP(ifq); 314df5e1987SJonathan Lemon IF_UNLOCK(ifq); 315df5e1987SJonathan Lemon m_freem(m); 316df5e1987SJonathan Lemon return (0); 31719ff91c6SGarrett Wollman } 318df5e1987SJonathan Lemon if (ifp != NULL) { 319df5e1987SJonathan Lemon ifp->if_obytes += m->m_pkthdr.len + adjust; 320df5e1987SJonathan Lemon if (m->m_flags & M_MCAST) 321df5e1987SJonathan Lemon ifp->if_omcasts++; 322df5e1987SJonathan Lemon active = ifp->if_flags & IFF_OACTIVE; 323df5e1987SJonathan Lemon } 324df5e1987SJonathan Lemon _IF_ENQUEUE(ifq, m); 325df5e1987SJonathan Lemon IF_UNLOCK(ifq); 32699efe4f0SJohn Baldwin if (ifp != NULL && !active) 327df5e1987SJonathan Lemon (*ifp->if_start)(ifp); 328df5e1987SJonathan Lemon return (1); 329df5e1987SJonathan Lemon } 330aab3beeeSBrian Somers 331aab3beeeSBrian Somers /* 332aab3beeeSBrian Somers * 72 was chosen below because it is the size of a TCP/IP 333aab3beeeSBrian Somers * header (40) + the minimum mss (32). 334aab3beeeSBrian Somers */ 335aab3beeeSBrian Somers #define IF_MINMTU 72 336aab3beeeSBrian Somers #define IF_MAXMTU 65535 337aab3beeeSBrian Somers 338664a31e4SPeter Wemm #endif /* _KERNEL */ 33919ff91c6SGarrett Wollman 34019ff91c6SGarrett Wollman /* 34119ff91c6SGarrett Wollman * The ifaddr structure contains information about one address 34219ff91c6SGarrett Wollman * of an interface. They are maintained by the different address families, 34319ff91c6SGarrett Wollman * are allocated and attached when an address is set, and are linked 34419ff91c6SGarrett Wollman * together so all addresses for an interface can be located. 34519ff91c6SGarrett Wollman */ 34619ff91c6SGarrett Wollman struct ifaddr { 34719ff91c6SGarrett Wollman struct sockaddr *ifa_addr; /* address of interface */ 34819ff91c6SGarrett Wollman struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ 34919ff91c6SGarrett Wollman #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 35019ff91c6SGarrett Wollman struct sockaddr *ifa_netmask; /* used to determine subnet */ 3515da9f8faSJosef Karthauser struct if_data if_data; /* not all members are meaningful */ 35219ff91c6SGarrett Wollman struct ifnet *ifa_ifp; /* back-pointer to interface */ 353e3975643SJake Burkholder TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ 35419ff91c6SGarrett Wollman void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ 355929ddbbbSAlfred Perlstein (int, struct rtentry *, struct rt_addrinfo *); 35619ff91c6SGarrett Wollman u_short ifa_flags; /* mostly rt_flags for cloning */ 357e3c1388bSPierre Beyssac u_int ifa_refcnt; /* references to this structure */ 35819ff91c6SGarrett Wollman int ifa_metric; /* cost of going out this interface */ 35919ff91c6SGarrett Wollman #ifdef notdef 36019ff91c6SGarrett Wollman struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */ 36119ff91c6SGarrett Wollman #endif 3627ed8f465SJulian Elischer int (*ifa_claim_addr) /* check if an addr goes to this if */ 363929ddbbbSAlfred Perlstein (struct ifaddr *, struct sockaddr *); 36419fc74fbSJeffrey Hsu struct mtx ifa_mtx; 36519ff91c6SGarrett Wollman }; 36619ff91c6SGarrett Wollman #define IFA_ROUTE RTF_UP /* route installed */ 36719ff91c6SGarrett Wollman 36882cd038dSYoshinobu Inoue /* for compatibility with other BSDs */ 36982cd038dSYoshinobu Inoue #define ifa_list ifa_link 37082cd038dSYoshinobu Inoue 37119fc74fbSJeffrey Hsu #define IFA_LOCK_INIT(ifa) \ 37219fc74fbSJeffrey Hsu mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF) 37319fc74fbSJeffrey Hsu #define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) 37419fc74fbSJeffrey Hsu #define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) 37519fc74fbSJeffrey Hsu #define IFA_DESTROY(ifa) mtx_destroy(&(ifa)->ifa_mtx) 37619fc74fbSJeffrey Hsu 3771158dfb7SGarrett Wollman /* 37876429de4SYoshinobu Inoue * The prefix structure contains information about one prefix 37976429de4SYoshinobu Inoue * of an interface. They are maintained by the different address families, 380d64ada50SJens Schweikhardt * are allocated and attached when a prefix or an address is set, 38182cd038dSYoshinobu Inoue * and are linked together so all prefixes for an interface can be located. 38276429de4SYoshinobu Inoue */ 38376429de4SYoshinobu Inoue struct ifprefix { 38476429de4SYoshinobu Inoue struct sockaddr *ifpr_prefix; /* prefix of interface */ 38576429de4SYoshinobu Inoue struct ifnet *ifpr_ifp; /* back-pointer to interface */ 386e3975643SJake Burkholder TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */ 38776429de4SYoshinobu Inoue u_char ifpr_plen; /* prefix length in bits */ 38876429de4SYoshinobu Inoue u_char ifpr_type; /* protocol dependent prefix type */ 38976429de4SYoshinobu Inoue }; 39076429de4SYoshinobu Inoue 39176429de4SYoshinobu Inoue /* 3921158dfb7SGarrett Wollman * Multicast address structure. This is analogous to the ifaddr 3931158dfb7SGarrett Wollman * structure except that it keeps track of multicast addresses. 3941158dfb7SGarrett Wollman * Also, the reference count here is a count of requests for this 3951158dfb7SGarrett Wollman * address, not a count of pointers to this structure. 3961158dfb7SGarrett Wollman */ 3971158dfb7SGarrett Wollman struct ifmultiaddr { 3986817526dSPoul-Henning Kamp TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ 399373f88edSGarrett Wollman struct sockaddr *ifma_addr; /* address this membership is for */ 400373f88edSGarrett Wollman struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ 401373f88edSGarrett Wollman struct ifnet *ifma_ifp; /* back-pointer to interface */ 402373f88edSGarrett Wollman u_int ifma_refcount; /* reference count */ 403373f88edSGarrett Wollman void *ifma_protospec; /* protocol-specific state, if any */ 4041158dfb7SGarrett Wollman }; 4051158dfb7SGarrett Wollman 406664a31e4SPeter Wemm #ifdef _KERNEL 40719ff91c6SGarrett Wollman #define IFAFREE(ifa) \ 408dfd5dee1SPeter Wemm do { \ 40919fc74fbSJeffrey Hsu IFA_LOCK(ifa); \ 41068eec1f8SJeffrey Hsu KASSERT((ifa)->ifa_refcnt > 0, \ 41168eec1f8SJeffrey Hsu ("ifa %p !(ifa_refcnt > 0)", ifa)); \ 41268eec1f8SJeffrey Hsu if (--(ifa)->ifa_refcnt == 0) { \ 41319fc74fbSJeffrey Hsu IFA_DESTROY(ifa); \ 41419fc74fbSJeffrey Hsu free(ifa, M_IFADDR); \ 41568eec1f8SJeffrey Hsu } else \ 41619fc74fbSJeffrey Hsu IFA_UNLOCK(ifa); \ 41719fc74fbSJeffrey Hsu } while (0) 41819fc74fbSJeffrey Hsu 41919fc74fbSJeffrey Hsu #define IFAREF(ifa) \ 42019fc74fbSJeffrey Hsu do { \ 42119fc74fbSJeffrey Hsu IFA_LOCK(ifa); \ 42219fc74fbSJeffrey Hsu ++(ifa)->ifa_refcnt; \ 42319fc74fbSJeffrey Hsu IFA_UNLOCK(ifa); \ 424dfd5dee1SPeter Wemm } while (0) 42519ff91c6SGarrett Wollman 426b30a244cSJeffrey Hsu extern struct mtx ifnet_lock; 427c919b1e2SJeffrey Hsu #define IFNET_LOCK_INIT() \ 428c919b1e2SJeffrey Hsu mtx_init(&ifnet_lock, "ifnet", NULL, MTX_DEF | MTX_RECURSE) 429b30a244cSJeffrey Hsu #define IFNET_WLOCK() mtx_lock(&ifnet_lock) 430b30a244cSJeffrey Hsu #define IFNET_WUNLOCK() mtx_unlock(&ifnet_lock) 431b30a244cSJeffrey Hsu #define IFNET_RLOCK() IFNET_WLOCK() 432b30a244cSJeffrey Hsu #define IFNET_RUNLOCK() IFNET_WUNLOCK() 433b30a244cSJeffrey Hsu 434f9132cebSJonathan Lemon struct ifindex_entry { 435f9132cebSJonathan Lemon struct ifnet *ife_ifnet; 436f9132cebSJonathan Lemon struct ifaddr *ife_ifnet_addr; 437f9132cebSJonathan Lemon dev_t ife_dev; 438f9132cebSJonathan Lemon }; 439f9132cebSJonathan Lemon 440f9132cebSJonathan Lemon #define ifnet_byindex(idx) ifindex_table[(idx)].ife_ifnet 441f9132cebSJonathan Lemon #define ifaddr_byindex(idx) ifindex_table[(idx)].ife_ifnet_addr 442f9132cebSJonathan Lemon #define ifdev_byindex(idx) ifindex_table[(idx)].ife_dev 443f9132cebSJonathan Lemon 44419ff91c6SGarrett Wollman extern struct ifnethead ifnet; 445f9132cebSJonathan Lemon extern struct ifindex_entry *ifindex_table; 44619ff91c6SGarrett Wollman extern int ifqmaxlen; 44790d9802fSPeter Wemm extern struct ifnet *loif; /* first loopback interface */ 44819ff91c6SGarrett Wollman extern int if_index; 44919ff91c6SGarrett Wollman 450929ddbbbSAlfred Perlstein int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); 451929ddbbbSAlfred Perlstein int if_allmulti(struct ifnet *, int); 452929ddbbbSAlfred Perlstein void if_attach(struct ifnet *); 453929ddbbbSAlfred Perlstein int if_delmulti(struct ifnet *, struct sockaddr *); 454929ddbbbSAlfred Perlstein void if_detach(struct ifnet *); 455929ddbbbSAlfred Perlstein void if_down(struct ifnet *); 4569bf40edeSBrooks Davis void if_initname(struct ifnet *, const char *, int); 457fa882e87SBrooks Davis int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); 458929ddbbbSAlfred Perlstein void if_route(struct ifnet *, int flag, int fam); 459929ddbbbSAlfred Perlstein int if_setlladdr(struct ifnet *, const u_char *, int); 460929ddbbbSAlfred Perlstein void if_unroute(struct ifnet *, int flag, int fam); 461929ddbbbSAlfred Perlstein void if_up(struct ifnet *); 462929ddbbbSAlfred Perlstein /*void ifinit(void);*/ /* declared in systm.h for main() */ 463929ddbbbSAlfred Perlstein int ifioctl(struct socket *, u_long, caddr_t, struct thread *); 464929ddbbbSAlfred Perlstein int ifpromisc(struct ifnet *, int); 465929ddbbbSAlfred Perlstein struct ifnet *ifunit(const char *); 466929ddbbbSAlfred Perlstein struct ifnet *if_withname(struct sockaddr *); 46719ff91c6SGarrett Wollman 468929ddbbbSAlfred Perlstein int if_poll_recv_slow(struct ifnet *ifp, int *quotap); 469929ddbbbSAlfred Perlstein void if_poll_xmit_slow(struct ifnet *ifp, int *quotap); 470929ddbbbSAlfred Perlstein void if_poll_throttle(void); 471929ddbbbSAlfred Perlstein void if_poll_unthrottle(void *); 472929ddbbbSAlfred Perlstein void if_poll_init(void); 473929ddbbbSAlfred Perlstein void if_poll(void); 47419ff91c6SGarrett Wollman 475929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithaddr(struct sockaddr *); 476929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); 477929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithnet(struct sockaddr *); 478929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); 479929ddbbbSAlfred Perlstein struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); 48019ff91c6SGarrett Wollman 481929ddbbbSAlfred Perlstein struct ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *); 482929ddbbbSAlfred Perlstein int if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); 483373f88edSGarrett Wollman 484929ddbbbSAlfred Perlstein void if_clone_attach(struct if_clone *); 485929ddbbbSAlfred Perlstein void if_clone_detach(struct if_clone *); 48630aad87dSBrooks Davis 487929ddbbbSAlfred Perlstein int if_clone_create(char *, int); 488929ddbbbSAlfred Perlstein int if_clone_destroy(const char *); 48930aad87dSBrooks Davis 490322dcb8dSMax Khon #define IF_LLADDR(ifp) \ 491322dcb8dSMax Khon LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr) 492322dcb8dSMax Khon 493e4fc250cSLuigi Rizzo #ifdef DEVICE_POLLING 494e4fc250cSLuigi Rizzo enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS, POLL_DEREGISTER }; 495e4fc250cSLuigi Rizzo 496929ddbbbSAlfred Perlstein typedef void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); 497929ddbbbSAlfred Perlstein int ether_poll_register(poll_handler_t *h, struct ifnet *ifp); 498929ddbbbSAlfred Perlstein int ether_poll_deregister(struct ifnet *ifp); 499e4fc250cSLuigi Rizzo #endif /* DEVICE_POLLING */ 500e4fc250cSLuigi Rizzo 501664a31e4SPeter Wemm #endif /* _KERNEL */ 50219ff91c6SGarrett Wollman 50319ff91c6SGarrett Wollman #endif /* !_NET_IF_VAR_H_ */ 504