1c398230bSWarner Losh /*- 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 * 4. Neither the name of the University nor the names of its contributors 1419ff91c6SGarrett Wollman * may be used to endorse or promote products derived from this software 1519ff91c6SGarrett Wollman * without specific prior written permission. 1619ff91c6SGarrett Wollman * 1719ff91c6SGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1819ff91c6SGarrett Wollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1919ff91c6SGarrett Wollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2019ff91c6SGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2119ff91c6SGarrett Wollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2219ff91c6SGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2319ff91c6SGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2419ff91c6SGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2519ff91c6SGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2619ff91c6SGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2719ff91c6SGarrett Wollman * SUCH DAMAGE. 2819ff91c6SGarrett Wollman * 2919ff91c6SGarrett Wollman * From: @(#)if.h 8.1 (Berkeley) 6/10/93 30c3aac50fSPeter Wemm * $FreeBSD$ 3119ff91c6SGarrett Wollman */ 3219ff91c6SGarrett Wollman 3319ff91c6SGarrett Wollman #ifndef _NET_IF_VAR_H_ 3419ff91c6SGarrett Wollman #define _NET_IF_VAR_H_ 3519ff91c6SGarrett Wollman 3619ff91c6SGarrett Wollman /* 3719ff91c6SGarrett Wollman * Structures defining a network interface, providing a packet 3819ff91c6SGarrett Wollman * transport mechanism (ala level 0 of the PUP protocols). 3919ff91c6SGarrett Wollman * 4019ff91c6SGarrett Wollman * Each interface accepts output datagrams of a specified maximum 4119ff91c6SGarrett Wollman * length, and provides higher level routines with input datagrams 4219ff91c6SGarrett Wollman * received from its medium. 4319ff91c6SGarrett Wollman * 4419ff91c6SGarrett Wollman * Output occurs when the routine if_output is called, with three parameters: 4519ff91c6SGarrett Wollman * (*ifp->if_output)(ifp, m, dst, rt) 4619ff91c6SGarrett Wollman * Here m is the mbuf chain to be sent and dst is the destination address. 4719ff91c6SGarrett Wollman * The output routine encapsulates the supplied datagram if necessary, 4819ff91c6SGarrett Wollman * and then transmits it on its medium. 4919ff91c6SGarrett Wollman * 5019ff91c6SGarrett Wollman * On input, each interface unwraps the data received by it, and either 519d5abbddSJens Schweikhardt * places it on the input queue of an internetwork datagram routine 5219ff91c6SGarrett Wollman * and posts the associated software interrupt, or passes the datagram to a raw 5319ff91c6SGarrett Wollman * packet input routine. 5419ff91c6SGarrett Wollman * 5519ff91c6SGarrett Wollman * Routines exist for locating interfaces by their addresses 569d5abbddSJens Schweikhardt * or for locating an interface on a certain network, as well as more general 5719ff91c6SGarrett Wollman * routing and gateway routines maintaining information used to locate 5819ff91c6SGarrett Wollman * interfaces. These routines live in the files if.c and route.c 5919ff91c6SGarrett Wollman */ 6019ff91c6SGarrett Wollman 6119ff91c6SGarrett Wollman #ifdef __STDC__ 6219ff91c6SGarrett Wollman /* 6319ff91c6SGarrett Wollman * Forward structure declarations for function prototypes [sic]. 6419ff91c6SGarrett Wollman */ 6519ff91c6SGarrett Wollman struct mbuf; 66b40ce416SJulian Elischer struct thread; 6719ff91c6SGarrett Wollman struct rtentry; 688071913dSRuslan Ermilov struct rt_addrinfo; 6919ff91c6SGarrett Wollman struct socket; 7019ff91c6SGarrett Wollman struct ether_header; 71a9771948SGleb Smirnoff struct carp_if; 7219ff91c6SGarrett Wollman #endif 7319ff91c6SGarrett Wollman 7419ff91c6SGarrett Wollman #include <sys/queue.h> /* get TAILQ macros */ 7519ff91c6SGarrett Wollman 769ba20c31SJonathan Lemon #ifdef _KERNEL 77df5e1987SJonathan Lemon #include <sys/mbuf.h> 7825a4adceSMax Laier #include <sys/eventhandler.h> 799ba20c31SJonathan Lemon #endif /* _KERNEL */ 80f34fa851SJohn Baldwin #include <sys/lock.h> /* XXX */ 81f34fa851SJohn Baldwin #include <sys/mutex.h> /* XXX */ 82f9132cebSJonathan Lemon #include <sys/event.h> /* XXX */ 83af5e59bfSRobert Watson #include <sys/_task.h> 84df5e1987SJonathan Lemon 859bf40edeSBrooks Davis #define IF_DUNIT_NONE -1 869bf40edeSBrooks Davis 8702b199f1SMax Laier #include <altq/if_altq.h> 8802b199f1SMax Laier 89e3975643SJake Burkholder TAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ 90e3975643SJake Burkholder TAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ 91e3975643SJake Burkholder TAILQ_HEAD(ifprefixhead, ifprefix); 926817526dSPoul-Henning Kamp TAILQ_HEAD(ifmultihead, ifmultiaddr); 9319ff91c6SGarrett Wollman 9419ff91c6SGarrett Wollman /* 9519ff91c6SGarrett Wollman * Structure defining a queue for a network interface. 9619ff91c6SGarrett Wollman */ 9719ff91c6SGarrett Wollman struct ifqueue { 9819ff91c6SGarrett Wollman struct mbuf *ifq_head; 9919ff91c6SGarrett Wollman struct mbuf *ifq_tail; 10019ff91c6SGarrett Wollman int ifq_len; 10119ff91c6SGarrett Wollman int ifq_maxlen; 10219ff91c6SGarrett Wollman int ifq_drops; 103df5e1987SJonathan Lemon struct mtx ifq_mtx; 10419ff91c6SGarrett Wollman }; 10519ff91c6SGarrett Wollman 10619ff91c6SGarrett Wollman /* 10719ff91c6SGarrett Wollman * Structure defining a network interface. 10819ff91c6SGarrett Wollman * 10919ff91c6SGarrett Wollman * (Would like to call this struct ``if'', but C isn't PL/1.) 11019ff91c6SGarrett Wollman */ 1118ec410b5SMatt Jacob 11219ff91c6SGarrett Wollman struct ifnet { 11319ff91c6SGarrett Wollman void *if_softc; /* pointer to driver state */ 114fc74a9f9SBrooks Davis void *if_l2com; /* pointer to protocol bits */ 115e3975643SJake Burkholder TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ 1169bf40edeSBrooks Davis char if_xname[IFNAMSIZ]; /* external name (name + unit) */ 1179bf40edeSBrooks Davis const char *if_dname; /* driver name */ 1189bf40edeSBrooks Davis int if_dunit; /* unit or IF_DUNIT_NONE */ 11919ff91c6SGarrett Wollman struct ifaddrhead if_addrhead; /* linked list of addresses per if */ 120621b79c4SLuigi Rizzo /* 121621b79c4SLuigi Rizzo * if_addrhead is the list of all addresses associated to 122d65d2351SLuigi Rizzo * an interface. 123d65d2351SLuigi Rizzo * Some code in the kernel assumes that first element 124d65d2351SLuigi Rizzo * of the list has type AF_LINK, and contains sockaddr_dl 125d65d2351SLuigi Rizzo * addresses which store the link-level address and the name 126621b79c4SLuigi Rizzo * of the interface. 127d65d2351SLuigi Rizzo * However, access to the AF_LINK address through this 128d65d2351SLuigi Rizzo * field is deprecated. Use ifaddr_byindex() instead. 129621b79c4SLuigi Rizzo */ 130ad3b9257SJohn-Mark Gurney struct knlist if_klist; /* events attached to this if */ 13119ff91c6SGarrett Wollman int if_pcount; /* number of promiscuous listeners */ 1323a84d72aSGleb Smirnoff struct carp_if *if_carp; /* carp interface structure */ 13319ff91c6SGarrett Wollman struct bpf_if *if_bpf; /* packet filter structure */ 13419ff91c6SGarrett Wollman u_short if_index; /* numeric abbreviation for this if */ 13519ff91c6SGarrett Wollman short if_timer; /* time 'til if_watchdog called */ 13676cfd300SSam Leffler u_short if_nvlans; /* number of active vlans */ 13762f76486SMaxim Sobolev int if_flags; /* up/down, broadcast, etc. */ 138016da741SJonathan Lemon int if_capabilities; /* interface capabilities */ 139016da741SJonathan Lemon int if_capenable; /* enabled features */ 14019ff91c6SGarrett Wollman void *if_linkmib; /* link-type-specific MIB data */ 14119ff91c6SGarrett Wollman size_t if_linkmiblen; /* length of above data */ 14219ff91c6SGarrett Wollman struct if_data if_data; 1431158dfb7SGarrett Wollman struct ifmultihead if_multiaddrs; /* multicast addresses configured */ 1441158dfb7SGarrett Wollman int if_amcount; /* number of all-multicast requests */ 14519ff91c6SGarrett Wollman /* procedure handles */ 14619ff91c6SGarrett Wollman int (*if_output) /* output routine (enqueue) */ 147929ddbbbSAlfred Perlstein (struct ifnet *, struct mbuf *, struct sockaddr *, 148929ddbbbSAlfred Perlstein struct rtentry *); 14976cfd300SSam Leffler void (*if_input) /* input routine (from h/w driver) */ 15076cfd300SSam Leffler (struct ifnet *, struct mbuf *); 15119ff91c6SGarrett Wollman void (*if_start) /* initiate output routine */ 152929ddbbbSAlfred Perlstein (struct ifnet *); 15319ff91c6SGarrett Wollman int (*if_ioctl) /* ioctl routine */ 154929ddbbbSAlfred Perlstein (struct ifnet *, u_long, caddr_t); 15519ff91c6SGarrett Wollman void (*if_watchdog) /* timer routine */ 156929ddbbbSAlfred Perlstein (struct ifnet *); 15719ff91c6SGarrett Wollman void (*if_init) /* Init routine */ 158929ddbbbSAlfred Perlstein (void *); 1591158dfb7SGarrett Wollman int (*if_resolvemulti) /* validate/resolve multicast */ 160929ddbbbSAlfred Perlstein (struct ifnet *, struct sockaddr **, struct sockaddr *); 161b4d4574aSRobert Watson void *if_spare1; /* spare pointer 1 */ 162b4d4574aSRobert Watson void *if_spare2; /* spare pointer 2 */ 163b4d4574aSRobert Watson void *if_spare3; /* spare pointer 3 */ 164638ccea0SRobert Watson int if_drv_flags; /* driver-managed status flags */ 165b4d4574aSRobert Watson u_int if_spare_flags2; /* spare flags 2 */ 16602b199f1SMax Laier struct ifaltq if_snd; /* output queue (includes altq) */ 1672ab763ecSWarner Losh const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ 168f7c5baa1SLuigi Rizzo 1698f867517SAndrew Thompson void *if_bridge; /* bridge glue */ 1708f867517SAndrew Thompson 171f7c5baa1SLuigi Rizzo struct lltable *lltables; /* list of L3-L2 resolution tables */ 172f7c5baa1SLuigi Rizzo 173eca8a663SRobert Watson struct label *if_label; /* interface MAC label */ 17431b1bfe1SHajimu UMEMOTO 175f7c5baa1SLuigi Rizzo /* these are only used by IPv6 */ 176f7c5baa1SLuigi Rizzo struct ifprefixhead if_prefixhead; /* list of prefixes per if */ 17731b1bfe1SHajimu UMEMOTO void *if_afdata[AF_MAX]; 178234a35c7SHajimu UMEMOTO int if_afdata_initialized; 179234a35c7SHajimu UMEMOTO struct mtx if_afdata_mtx; 180af5e59bfSRobert Watson struct task if_starttask; /* task for IFF_NEEDSGIANT */ 18168a3482fSGleb Smirnoff struct task if_linktask; /* task for link change events */ 182de6073aaSRobert Watson struct mtx if_addr_mtx; /* mutex to protect address lists */ 18319ff91c6SGarrett Wollman }; 184df5e1987SJonathan Lemon 185929ddbbbSAlfred Perlstein typedef void if_init_f_t(void *); 18619ff91c6SGarrett Wollman 187212b6d52SLuigi Rizzo /* 188212b6d52SLuigi Rizzo * XXX These aliases are terribly dangerous because they could apply 189212b6d52SLuigi Rizzo * to anything. 190212b6d52SLuigi Rizzo */ 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 197127d7b2dSAndre Oppermann #define if_link_state if_data.ifi_link_state 19819ff91c6SGarrett Wollman #define if_baudrate if_data.ifi_baudrate 199db4f9cc7SJonathan Lemon #define if_hwassist if_data.ifi_hwassist 20019ff91c6SGarrett Wollman #define if_ipackets if_data.ifi_ipackets 20119ff91c6SGarrett Wollman #define if_ierrors if_data.ifi_ierrors 20219ff91c6SGarrett Wollman #define if_opackets if_data.ifi_opackets 20319ff91c6SGarrett Wollman #define if_oerrors if_data.ifi_oerrors 20419ff91c6SGarrett Wollman #define if_collisions if_data.ifi_collisions 20519ff91c6SGarrett Wollman #define if_ibytes if_data.ifi_ibytes 20619ff91c6SGarrett Wollman #define if_obytes if_data.ifi_obytes 20719ff91c6SGarrett Wollman #define if_imcasts if_data.ifi_imcasts 20819ff91c6SGarrett Wollman #define if_omcasts if_data.ifi_omcasts 20919ff91c6SGarrett Wollman #define if_iqdrops if_data.ifi_iqdrops 21019ff91c6SGarrett Wollman #define if_noproto if_data.ifi_noproto 21119ff91c6SGarrett Wollman #define if_lastchange if_data.ifi_lastchange 21219ff91c6SGarrett Wollman #define if_recvquota if_data.ifi_recvquota 21319ff91c6SGarrett Wollman #define if_xmitquota if_data.ifi_xmitquota 2142f27e151SJohn-Mark Gurney #define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL) 21519ff91c6SGarrett Wollman 21682cd038dSYoshinobu Inoue /* for compatibility with other BSDs */ 21782cd038dSYoshinobu Inoue #define if_addrlist if_addrhead 21882cd038dSYoshinobu Inoue #define if_list if_link 21982cd038dSYoshinobu Inoue 22019ff91c6SGarrett Wollman /* 221de6073aaSRobert Watson * Locks for address lists on the network interface. 222de6073aaSRobert Watson */ 223de6073aaSRobert Watson #define IF_ADDR_LOCK_INIT(if) mtx_init(&(if)->if_addr_mtx, \ 224de6073aaSRobert Watson "if_addr_mtx", NULL, MTX_DEF) 225de6073aaSRobert Watson #define IF_ADDR_LOCK_DESTROY(if) mtx_destroy(&(if)->if_addr_mtx) 226de6073aaSRobert Watson #define IF_ADDR_LOCK(if) mtx_lock(&(if)->if_addr_mtx) 227de6073aaSRobert Watson #define IF_ADDR_UNLOCK(if) mtx_unlock(&(if)->if_addr_mtx) 228de6073aaSRobert Watson #define IF_ADDR_LOCK_ASSERT(if) mtx_assert(&(if)->if_addr_mtx, MA_OWNED) 229de6073aaSRobert Watson 230de6073aaSRobert Watson /* 23119ff91c6SGarrett Wollman * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) 23219ff91c6SGarrett Wollman * are queues of messages stored on ifqueue structures 23319ff91c6SGarrett Wollman * (defined above). Entries are added to and deleted from these structures 23419ff91c6SGarrett Wollman * by these macros, which should be called with ipl raised to splimp(). 23519ff91c6SGarrett Wollman */ 2369ed346baSBosko Milekic #define IF_LOCK(ifq) mtx_lock(&(ifq)->ifq_mtx) 2379ed346baSBosko Milekic #define IF_UNLOCK(ifq) mtx_unlock(&(ifq)->ifq_mtx) 23802b199f1SMax Laier #define IF_LOCK_ASSERT(ifq) mtx_assert(&(ifq)->ifq_mtx, MA_OWNED) 239df5e1987SJonathan Lemon #define _IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 240df5e1987SJonathan Lemon #define _IF_DROP(ifq) ((ifq)->ifq_drops++) 241df5e1987SJonathan Lemon #define _IF_QLEN(ifq) ((ifq)->ifq_len) 242df5e1987SJonathan Lemon 243df5e1987SJonathan Lemon #define _IF_ENQUEUE(ifq, m) do { \ 244df5e1987SJonathan Lemon (m)->m_nextpkt = NULL; \ 245df5e1987SJonathan Lemon if ((ifq)->ifq_tail == NULL) \ 24619ff91c6SGarrett Wollman (ifq)->ifq_head = m; \ 24719ff91c6SGarrett Wollman else \ 24819ff91c6SGarrett Wollman (ifq)->ifq_tail->m_nextpkt = m; \ 24919ff91c6SGarrett Wollman (ifq)->ifq_tail = m; \ 25019ff91c6SGarrett Wollman (ifq)->ifq_len++; \ 251df5e1987SJonathan Lemon } while (0) 252df5e1987SJonathan Lemon 253df5e1987SJonathan Lemon #define IF_ENQUEUE(ifq, m) do { \ 254df5e1987SJonathan Lemon IF_LOCK(ifq); \ 255df5e1987SJonathan Lemon _IF_ENQUEUE(ifq, m); \ 256df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 257df5e1987SJonathan Lemon } while (0) 258df5e1987SJonathan Lemon 259df5e1987SJonathan Lemon #define _IF_PREPEND(ifq, m) do { \ 26019ff91c6SGarrett Wollman (m)->m_nextpkt = (ifq)->ifq_head; \ 261df5e1987SJonathan Lemon if ((ifq)->ifq_tail == NULL) \ 26219ff91c6SGarrett Wollman (ifq)->ifq_tail = (m); \ 26319ff91c6SGarrett Wollman (ifq)->ifq_head = (m); \ 26419ff91c6SGarrett Wollman (ifq)->ifq_len++; \ 265df5e1987SJonathan Lemon } while (0) 266df5e1987SJonathan Lemon 267df5e1987SJonathan Lemon #define IF_PREPEND(ifq, m) do { \ 268df5e1987SJonathan Lemon IF_LOCK(ifq); \ 269df5e1987SJonathan Lemon _IF_PREPEND(ifq, m); \ 270df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 271df5e1987SJonathan Lemon } while (0) 272df5e1987SJonathan Lemon 273df5e1987SJonathan Lemon #define _IF_DEQUEUE(ifq, m) do { \ 27419ff91c6SGarrett Wollman (m) = (ifq)->ifq_head; \ 27519ff91c6SGarrett Wollman if (m) { \ 2762f27e151SJohn-Mark Gurney if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \ 277df5e1987SJonathan Lemon (ifq)->ifq_tail = NULL; \ 278df5e1987SJonathan Lemon (m)->m_nextpkt = NULL; \ 27919ff91c6SGarrett Wollman (ifq)->ifq_len--; \ 28019ff91c6SGarrett Wollman } \ 281df5e1987SJonathan Lemon } while (0) 282df5e1987SJonathan Lemon 283df5e1987SJonathan Lemon #define IF_DEQUEUE(ifq, m) do { \ 284df5e1987SJonathan Lemon IF_LOCK(ifq); \ 285df5e1987SJonathan Lemon _IF_DEQUEUE(ifq, m); \ 286df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 287df5e1987SJonathan Lemon } while (0) 288df5e1987SJonathan Lemon 28902b199f1SMax Laier #define _IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) 29002b199f1SMax Laier #define IF_POLL(ifq, m) _IF_POLL(ifq, m) 29102b199f1SMax Laier 29202b199f1SMax Laier #define _IF_DRAIN(ifq) do { \ 293df5e1987SJonathan Lemon struct mbuf *m; \ 294df5e1987SJonathan Lemon for (;;) { \ 295df5e1987SJonathan Lemon _IF_DEQUEUE(ifq, m); \ 296df5e1987SJonathan Lemon if (m == NULL) \ 297df5e1987SJonathan Lemon break; \ 298df5e1987SJonathan Lemon m_freem(m); \ 299df5e1987SJonathan Lemon } \ 30002b199f1SMax Laier } while (0) 30102b199f1SMax Laier 30202b199f1SMax Laier #define IF_DRAIN(ifq) do { \ 30302b199f1SMax Laier IF_LOCK(ifq); \ 30402b199f1SMax Laier _IF_DRAIN(ifq); \ 305df5e1987SJonathan Lemon IF_UNLOCK(ifq); \ 306df5e1987SJonathan Lemon } while(0) 30719ff91c6SGarrett Wollman 308664a31e4SPeter Wemm #ifdef _KERNEL 30925a4adceSMax Laier /* interface address change event */ 31025a4adceSMax Laier typedef void (*ifaddr_event_handler_t)(void *, struct ifnet *); 31125a4adceSMax Laier EVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t); 31225a4adceSMax Laier /* new interface arrival event */ 31325a4adceSMax Laier typedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *); 31425a4adceSMax Laier EVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t); 31525a4adceSMax Laier /* interface departure event */ 31625a4adceSMax Laier typedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *); 31725a4adceSMax Laier EVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t); 31825a4adceSMax Laier 319234a35c7SHajimu UMEMOTO #define IF_AFDATA_LOCK_INIT(ifp) \ 320234a35c7SHajimu UMEMOTO mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF) 321234a35c7SHajimu UMEMOTO #define IF_AFDATA_LOCK(ifp) mtx_lock(&(ifp)->if_afdata_mtx) 322234a35c7SHajimu UMEMOTO #define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_mtx) 323234a35c7SHajimu UMEMOTO #define IF_AFDATA_UNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_mtx) 324234a35c7SHajimu UMEMOTO #define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_mtx) 325234a35c7SHajimu UMEMOTO 32631302ebfSRobert Watson #define IFF_LOCKGIANT(ifp) do { \ 32731302ebfSRobert Watson if ((ifp)->if_flags & IFF_NEEDSGIANT) \ 32831302ebfSRobert Watson mtx_lock(&Giant); \ 32931302ebfSRobert Watson } while (0) 33031302ebfSRobert Watson 33131302ebfSRobert Watson #define IFF_UNLOCKGIANT(ifp) do { \ 33231302ebfSRobert Watson if ((ifp)->if_flags & IFF_NEEDSGIANT) \ 33331302ebfSRobert Watson mtx_unlock(&Giant); \ 33431302ebfSRobert Watson } while (0) 33531302ebfSRobert Watson 3360b762445SRobert Watson int if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, 3370b762445SRobert Watson int adjust); 33802b199f1SMax Laier #define IF_HANDOFF(ifq, m, ifp) \ 33902b199f1SMax Laier if_handoff((struct ifqueue *)ifq, m, ifp, 0) 34002b199f1SMax Laier #define IF_HANDOFF_ADJ(ifq, m, ifp, adj) \ 34102b199f1SMax Laier if_handoff((struct ifqueue *)ifq, m, ifp, adj) 34219ff91c6SGarrett Wollman 343af5e59bfSRobert Watson void if_start(struct ifnet *); 344af5e59bfSRobert Watson 34502b199f1SMax Laier #define IFQ_ENQUEUE(ifq, m, err) \ 34602b199f1SMax Laier do { \ 34702b199f1SMax Laier IF_LOCK(ifq); \ 34802b199f1SMax Laier if (ALTQ_IS_ENABLED(ifq)) \ 34902b199f1SMax Laier ALTQ_ENQUEUE(ifq, m, NULL, err); \ 35002b199f1SMax Laier else { \ 35102b199f1SMax Laier if (_IF_QFULL(ifq)) { \ 35202b199f1SMax Laier m_freem(m); \ 35302b199f1SMax Laier (err) = ENOBUFS; \ 35402b199f1SMax Laier } else { \ 35502b199f1SMax Laier _IF_ENQUEUE(ifq, m); \ 35602b199f1SMax Laier (err) = 0; \ 35702b199f1SMax Laier } \ 35802b199f1SMax Laier } \ 35902b199f1SMax Laier if (err) \ 36002b199f1SMax Laier (ifq)->ifq_drops++; \ 36102b199f1SMax Laier IF_UNLOCK(ifq); \ 36202b199f1SMax Laier } while (0) 36302b199f1SMax Laier 36402b199f1SMax Laier #define IFQ_DEQUEUE_NOLOCK(ifq, m) \ 36502b199f1SMax Laier do { \ 36602b199f1SMax Laier if (TBR_IS_ENABLED(ifq)) \ 3674cb655c0SMax Laier (m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE); \ 36802b199f1SMax Laier else if (ALTQ_IS_ENABLED(ifq)) \ 36902b199f1SMax Laier ALTQ_DEQUEUE(ifq, m); \ 37002b199f1SMax Laier else \ 37102b199f1SMax Laier _IF_DEQUEUE(ifq, m); \ 37202b199f1SMax Laier } while (0) 37302b199f1SMax Laier 37402b199f1SMax Laier #define IFQ_DEQUEUE(ifq, m) \ 37502b199f1SMax Laier do { \ 37602b199f1SMax Laier IF_LOCK(ifq); \ 37702b199f1SMax Laier IFQ_DEQUEUE_NOLOCK(ifq, m); \ 37802b199f1SMax Laier IF_UNLOCK(ifq); \ 37902b199f1SMax Laier } while (0) 38002b199f1SMax Laier 38102b199f1SMax Laier #define IFQ_POLL_NOLOCK(ifq, m) \ 38202b199f1SMax Laier do { \ 38302b199f1SMax Laier if (TBR_IS_ENABLED(ifq)) \ 3844cb655c0SMax Laier (m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL); \ 38502b199f1SMax Laier else if (ALTQ_IS_ENABLED(ifq)) \ 38602b199f1SMax Laier ALTQ_POLL(ifq, m); \ 38702b199f1SMax Laier else \ 38802b199f1SMax Laier _IF_POLL(ifq, m); \ 38902b199f1SMax Laier } while (0) 39002b199f1SMax Laier 39102b199f1SMax Laier #define IFQ_POLL(ifq, m) \ 39202b199f1SMax Laier do { \ 39302b199f1SMax Laier IF_LOCK(ifq); \ 39402b199f1SMax Laier IFQ_POLL_NOLOCK(ifq, m); \ 39502b199f1SMax Laier IF_UNLOCK(ifq); \ 39602b199f1SMax Laier } while (0) 39702b199f1SMax Laier 39802b199f1SMax Laier #define IFQ_PURGE_NOLOCK(ifq) \ 39902b199f1SMax Laier do { \ 40002b199f1SMax Laier if (ALTQ_IS_ENABLED(ifq)) { \ 40102b199f1SMax Laier ALTQ_PURGE(ifq); \ 40202b199f1SMax Laier } else \ 40302b199f1SMax Laier _IF_DRAIN(ifq); \ 40402b199f1SMax Laier } while (0) 40502b199f1SMax Laier 40602b199f1SMax Laier #define IFQ_PURGE(ifq) \ 40702b199f1SMax Laier do { \ 40802b199f1SMax Laier IF_LOCK(ifq); \ 40902b199f1SMax Laier IFQ_PURGE_NOLOCK(ifq); \ 41002b199f1SMax Laier IF_UNLOCK(ifq); \ 41102b199f1SMax Laier } while (0) 41202b199f1SMax Laier 41302b199f1SMax Laier #define IFQ_SET_READY(ifq) \ 41402b199f1SMax Laier do { ((ifq)->altq_flags |= ALTQF_READY); } while (0) 41502b199f1SMax Laier 41602b199f1SMax Laier #define IFQ_LOCK(ifq) IF_LOCK(ifq) 41702b199f1SMax Laier #define IFQ_UNLOCK(ifq) IF_UNLOCK(ifq) 41802b199f1SMax Laier #define IFQ_LOCK_ASSERT(ifq) IF_LOCK_ASSERT(ifq) 41902b199f1SMax Laier #define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) 42002b199f1SMax Laier #define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) 42102b199f1SMax Laier #define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) 42202b199f1SMax Laier #define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) 42302b199f1SMax Laier #define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) 42402b199f1SMax Laier 42502b199f1SMax Laier #define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ 42602b199f1SMax Laier do { \ 42702b199f1SMax Laier int len; \ 42802b199f1SMax Laier short mflags; \ 42902b199f1SMax Laier \ 43002b199f1SMax Laier len = (m)->m_pkthdr.len; \ 43102b199f1SMax Laier mflags = (m)->m_flags; \ 43202b199f1SMax Laier IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \ 43302b199f1SMax Laier if ((err) == 0) { \ 43402b199f1SMax Laier (ifp)->if_obytes += len + (adj); \ 43502b199f1SMax Laier if (mflags & M_MCAST) \ 43602b199f1SMax Laier (ifp)->if_omcasts++; \ 43702b199f1SMax Laier if (((ifp)->if_flags & IFF_OACTIVE) == 0) \ 438af5e59bfSRobert Watson if_start(ifp); \ 43902b199f1SMax Laier } \ 44002b199f1SMax Laier } while (0) 44102b199f1SMax Laier 44202b199f1SMax Laier #define IFQ_HANDOFF(ifp, m, err) \ 44362d7f46eSMax Laier IFQ_HANDOFF_ADJ(ifp, m, 0, err) 44402b199f1SMax Laier 44502b199f1SMax Laier #define IFQ_DRV_DEQUEUE(ifq, m) \ 44602b199f1SMax Laier do { \ 44702b199f1SMax Laier (m) = (ifq)->ifq_drv_head; \ 44802b199f1SMax Laier if (m) { \ 44902b199f1SMax Laier if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL) \ 45002b199f1SMax Laier (ifq)->ifq_drv_tail = NULL; \ 45102b199f1SMax Laier (m)->m_nextpkt = NULL; \ 45202b199f1SMax Laier (ifq)->ifq_drv_len--; \ 45302b199f1SMax Laier } else { \ 45402b199f1SMax Laier IFQ_LOCK(ifq); \ 45502b199f1SMax Laier IFQ_DEQUEUE_NOLOCK(ifq, m); \ 45602b199f1SMax Laier while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) { \ 45702b199f1SMax Laier struct mbuf *m0; \ 45802b199f1SMax Laier IFQ_DEQUEUE_NOLOCK(ifq, m0); \ 45902b199f1SMax Laier if (m0 == NULL) \ 46002b199f1SMax Laier break; \ 46102b199f1SMax Laier m0->m_nextpkt = NULL; \ 46202b199f1SMax Laier if ((ifq)->ifq_drv_tail == NULL) \ 46302b199f1SMax Laier (ifq)->ifq_drv_head = m0; \ 46402b199f1SMax Laier else \ 46502b199f1SMax Laier (ifq)->ifq_drv_tail->m_nextpkt = m0; \ 46602b199f1SMax Laier (ifq)->ifq_drv_tail = m0; \ 46702b199f1SMax Laier (ifq)->ifq_drv_len++; \ 46802b199f1SMax Laier } \ 46902b199f1SMax Laier IFQ_UNLOCK(ifq); \ 47002b199f1SMax Laier } \ 47102b199f1SMax Laier } while (0) 47202b199f1SMax Laier 47302b199f1SMax Laier #define IFQ_DRV_PREPEND(ifq, m) \ 47402b199f1SMax Laier do { \ 47502b199f1SMax Laier (m)->m_nextpkt = (ifq)->ifq_drv_head; \ 476bfe46415SMax Laier if ((ifq)->ifq_drv_tail == NULL) \ 477bfe46415SMax Laier (ifq)->ifq_drv_tail = (m); \ 47802b199f1SMax Laier (ifq)->ifq_drv_head = (m); \ 47902b199f1SMax Laier (ifq)->ifq_drv_len++; \ 48002b199f1SMax Laier } while (0) 48102b199f1SMax Laier 48202b199f1SMax Laier #define IFQ_DRV_IS_EMPTY(ifq) \ 48302b199f1SMax Laier (((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0)) 48402b199f1SMax Laier 48502b199f1SMax Laier #define IFQ_DRV_PURGE(ifq) \ 48602b199f1SMax Laier do { \ 487bfe46415SMax Laier struct mbuf *m, *n = (ifq)->ifq_drv_head; \ 488bfe46415SMax Laier while((m = n) != NULL) { \ 489bfe46415SMax Laier n = m->m_nextpkt; \ 49002b199f1SMax Laier m_freem(m); \ 49102b199f1SMax Laier } \ 49202b199f1SMax Laier (ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL; \ 49302b199f1SMax Laier (ifq)->ifq_drv_len = 0; \ 49402b199f1SMax Laier IFQ_PURGE(ifq); \ 49502b199f1SMax Laier } while (0) 496aab3beeeSBrian Somers 497aab3beeeSBrian Somers /* 498aab3beeeSBrian Somers * 72 was chosen below because it is the size of a TCP/IP 499aab3beeeSBrian Somers * header (40) + the minimum mss (32). 500aab3beeeSBrian Somers */ 501aab3beeeSBrian Somers #define IF_MINMTU 72 502aab3beeeSBrian Somers #define IF_MAXMTU 65535 503aab3beeeSBrian Somers 504664a31e4SPeter Wemm #endif /* _KERNEL */ 50519ff91c6SGarrett Wollman 50619ff91c6SGarrett Wollman /* 50719ff91c6SGarrett Wollman * The ifaddr structure contains information about one address 50819ff91c6SGarrett Wollman * of an interface. They are maintained by the different address families, 50919ff91c6SGarrett Wollman * are allocated and attached when an address is set, and are linked 51019ff91c6SGarrett Wollman * together so all addresses for an interface can be located. 511621b79c4SLuigi Rizzo * 512621b79c4SLuigi Rizzo * NOTE: a 'struct ifaddr' is always at the beginning of a larger 513621b79c4SLuigi Rizzo * chunk of malloc'ed memory, where we store the three addresses 514621b79c4SLuigi Rizzo * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here. 51519ff91c6SGarrett Wollman */ 51619ff91c6SGarrett Wollman struct ifaddr { 51719ff91c6SGarrett Wollman struct sockaddr *ifa_addr; /* address of interface */ 51819ff91c6SGarrett Wollman struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ 51919ff91c6SGarrett Wollman #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 52019ff91c6SGarrett Wollman struct sockaddr *ifa_netmask; /* used to determine subnet */ 5215da9f8faSJosef Karthauser struct if_data if_data; /* not all members are meaningful */ 52219ff91c6SGarrett Wollman struct ifnet *ifa_ifp; /* back-pointer to interface */ 523e3975643SJake Burkholder TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ 52419ff91c6SGarrett Wollman void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ 525929ddbbbSAlfred Perlstein (int, struct rtentry *, struct rt_addrinfo *); 52619ff91c6SGarrett Wollman u_short ifa_flags; /* mostly rt_flags for cloning */ 527e3c1388bSPierre Beyssac u_int ifa_refcnt; /* references to this structure */ 52819ff91c6SGarrett Wollman int ifa_metric; /* cost of going out this interface */ 5297ed8f465SJulian Elischer int (*ifa_claim_addr) /* check if an addr goes to this if */ 530929ddbbbSAlfred Perlstein (struct ifaddr *, struct sockaddr *); 53119fc74fbSJeffrey Hsu struct mtx ifa_mtx; 53219ff91c6SGarrett Wollman }; 53319ff91c6SGarrett Wollman #define IFA_ROUTE RTF_UP /* route installed */ 53419ff91c6SGarrett Wollman 53582cd038dSYoshinobu Inoue /* for compatibility with other BSDs */ 53682cd038dSYoshinobu Inoue #define ifa_list ifa_link 53782cd038dSYoshinobu Inoue 53819fc74fbSJeffrey Hsu #define IFA_LOCK_INIT(ifa) \ 53919fc74fbSJeffrey Hsu mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF) 54019fc74fbSJeffrey Hsu #define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) 54119fc74fbSJeffrey Hsu #define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) 54219fc74fbSJeffrey Hsu #define IFA_DESTROY(ifa) mtx_destroy(&(ifa)->ifa_mtx) 54319fc74fbSJeffrey Hsu 5441158dfb7SGarrett Wollman /* 54576429de4SYoshinobu Inoue * The prefix structure contains information about one prefix 54676429de4SYoshinobu Inoue * of an interface. They are maintained by the different address families, 547d64ada50SJens Schweikhardt * are allocated and attached when a prefix or an address is set, 54882cd038dSYoshinobu Inoue * and are linked together so all prefixes for an interface can be located. 54976429de4SYoshinobu Inoue */ 55076429de4SYoshinobu Inoue struct ifprefix { 55176429de4SYoshinobu Inoue struct sockaddr *ifpr_prefix; /* prefix of interface */ 55276429de4SYoshinobu Inoue struct ifnet *ifpr_ifp; /* back-pointer to interface */ 553e3975643SJake Burkholder TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */ 55476429de4SYoshinobu Inoue u_char ifpr_plen; /* prefix length in bits */ 55576429de4SYoshinobu Inoue u_char ifpr_type; /* protocol dependent prefix type */ 55676429de4SYoshinobu Inoue }; 55776429de4SYoshinobu Inoue 55876429de4SYoshinobu Inoue /* 5591158dfb7SGarrett Wollman * Multicast address structure. This is analogous to the ifaddr 5601158dfb7SGarrett Wollman * structure except that it keeps track of multicast addresses. 5611158dfb7SGarrett Wollman * Also, the reference count here is a count of requests for this 5621158dfb7SGarrett Wollman * address, not a count of pointers to this structure. 5631158dfb7SGarrett Wollman */ 5641158dfb7SGarrett Wollman struct ifmultiaddr { 5656817526dSPoul-Henning Kamp TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ 566373f88edSGarrett Wollman struct sockaddr *ifma_addr; /* address this membership is for */ 567373f88edSGarrett Wollman struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ 568373f88edSGarrett Wollman struct ifnet *ifma_ifp; /* back-pointer to interface */ 569373f88edSGarrett Wollman u_int ifma_refcount; /* reference count */ 570373f88edSGarrett Wollman void *ifma_protospec; /* protocol-specific state, if any */ 5711158dfb7SGarrett Wollman }; 5721158dfb7SGarrett Wollman 573664a31e4SPeter Wemm #ifdef _KERNEL 57419ff91c6SGarrett Wollman #define IFAFREE(ifa) \ 575dfd5dee1SPeter Wemm do { \ 57619fc74fbSJeffrey Hsu IFA_LOCK(ifa); \ 57768eec1f8SJeffrey Hsu KASSERT((ifa)->ifa_refcnt > 0, \ 57868eec1f8SJeffrey Hsu ("ifa %p !(ifa_refcnt > 0)", ifa)); \ 57968eec1f8SJeffrey Hsu if (--(ifa)->ifa_refcnt == 0) { \ 58019fc74fbSJeffrey Hsu IFA_DESTROY(ifa); \ 58119fc74fbSJeffrey Hsu free(ifa, M_IFADDR); \ 58268eec1f8SJeffrey Hsu } else \ 58319fc74fbSJeffrey Hsu IFA_UNLOCK(ifa); \ 58419fc74fbSJeffrey Hsu } while (0) 58519fc74fbSJeffrey Hsu 58619fc74fbSJeffrey Hsu #define IFAREF(ifa) \ 58719fc74fbSJeffrey Hsu do { \ 58819fc74fbSJeffrey Hsu IFA_LOCK(ifa); \ 58919fc74fbSJeffrey Hsu ++(ifa)->ifa_refcnt; \ 59019fc74fbSJeffrey Hsu IFA_UNLOCK(ifa); \ 591dfd5dee1SPeter Wemm } while (0) 59219ff91c6SGarrett Wollman 593b30a244cSJeffrey Hsu extern struct mtx ifnet_lock; 594c919b1e2SJeffrey Hsu #define IFNET_LOCK_INIT() \ 595c919b1e2SJeffrey Hsu mtx_init(&ifnet_lock, "ifnet", NULL, MTX_DEF | MTX_RECURSE) 596b30a244cSJeffrey Hsu #define IFNET_WLOCK() mtx_lock(&ifnet_lock) 597b30a244cSJeffrey Hsu #define IFNET_WUNLOCK() mtx_unlock(&ifnet_lock) 598b30a244cSJeffrey Hsu #define IFNET_RLOCK() IFNET_WLOCK() 599b30a244cSJeffrey Hsu #define IFNET_RUNLOCK() IFNET_WUNLOCK() 600b30a244cSJeffrey Hsu 601f9132cebSJonathan Lemon struct ifindex_entry { 602f9132cebSJonathan Lemon struct ifnet *ife_ifnet; 603f9132cebSJonathan Lemon struct ifaddr *ife_ifnet_addr; 60489c9c53dSPoul-Henning Kamp struct cdev *ife_dev; 605f9132cebSJonathan Lemon }; 606f9132cebSJonathan Lemon 607f9132cebSJonathan Lemon #define ifnet_byindex(idx) ifindex_table[(idx)].ife_ifnet 608d65d2351SLuigi Rizzo /* 609d65d2351SLuigi Rizzo * Given the index, ifaddr_byindex() returns the one and only 610d65d2351SLuigi Rizzo * link-level ifaddr for the interface. You are not supposed to use 611d65d2351SLuigi Rizzo * it to traverse the list of addresses associated to the interface. 612d65d2351SLuigi Rizzo */ 613f9132cebSJonathan Lemon #define ifaddr_byindex(idx) ifindex_table[(idx)].ife_ifnet_addr 614f9132cebSJonathan Lemon #define ifdev_byindex(idx) ifindex_table[(idx)].ife_dev 615f9132cebSJonathan Lemon 61619ff91c6SGarrett Wollman extern struct ifnethead ifnet; 617f9132cebSJonathan Lemon extern struct ifindex_entry *ifindex_table; 61819ff91c6SGarrett Wollman extern int ifqmaxlen; 61990d9802fSPeter Wemm extern struct ifnet *loif; /* first loopback interface */ 62019ff91c6SGarrett Wollman extern int if_index; 62119ff91c6SGarrett Wollman 622929ddbbbSAlfred Perlstein int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); 623929ddbbbSAlfred Perlstein int if_allmulti(struct ifnet *, int); 624fc74a9f9SBrooks Davis struct ifnet* if_alloc(u_char); 625929ddbbbSAlfred Perlstein void if_attach(struct ifnet *); 626929ddbbbSAlfred Perlstein int if_delmulti(struct ifnet *, struct sockaddr *); 627929ddbbbSAlfred Perlstein void if_detach(struct ifnet *); 62845778b37SPeter Edwards void if_purgeaddrs(struct ifnet *); 629929ddbbbSAlfred Perlstein void if_down(struct ifnet *); 630fc74a9f9SBrooks Davis void if_free(struct ifnet *); 631fc74a9f9SBrooks Davis void if_free_type(struct ifnet *, u_char); 6329bf40edeSBrooks Davis void if_initname(struct ifnet *, const char *, int); 63394f5c9cfSSam Leffler void if_link_state_change(struct ifnet *, int); 634fa882e87SBrooks Davis int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); 635929ddbbbSAlfred Perlstein int if_setlladdr(struct ifnet *, const u_char *, int); 636929ddbbbSAlfred Perlstein void if_up(struct ifnet *); 637929ddbbbSAlfred Perlstein /*void ifinit(void);*/ /* declared in systm.h for main() */ 638929ddbbbSAlfred Perlstein int ifioctl(struct socket *, u_long, caddr_t, struct thread *); 639929ddbbbSAlfred Perlstein int ifpromisc(struct ifnet *, int); 640929ddbbbSAlfred Perlstein struct ifnet *ifunit(const char *); 64119ff91c6SGarrett Wollman 642929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithaddr(struct sockaddr *); 643929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); 644929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithnet(struct sockaddr *); 645929ddbbbSAlfred Perlstein struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); 646929ddbbbSAlfred Perlstein struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); 64719ff91c6SGarrett Wollman 648929ddbbbSAlfred Perlstein struct ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *); 649929ddbbbSAlfred Perlstein int if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); 650373f88edSGarrett Wollman 651fc74a9f9SBrooks Davis typedef void *if_com_alloc_t(u_char type, struct ifnet *ifp); 652fc74a9f9SBrooks Davis typedef void if_com_free_t(void *com, u_char type); 653fc74a9f9SBrooks Davis void if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f); 654fc74a9f9SBrooks Davis void if_deregister_com_alloc(u_char type); 655fc74a9f9SBrooks Davis 656322dcb8dSMax Khon #define IF_LLADDR(ifp) \ 657322dcb8dSMax Khon LLADDR((struct sockaddr_dl *) ifaddr_byindex((ifp)->if_index)->ifa_addr) 658322dcb8dSMax Khon 659e4fc250cSLuigi Rizzo #ifdef DEVICE_POLLING 660e4fc250cSLuigi Rizzo enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS, POLL_DEREGISTER }; 661e4fc250cSLuigi Rizzo 662929ddbbbSAlfred Perlstein typedef void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); 663929ddbbbSAlfred Perlstein int ether_poll_register(poll_handler_t *h, struct ifnet *ifp); 664929ddbbbSAlfred Perlstein int ether_poll_deregister(struct ifnet *ifp); 665e4fc250cSLuigi Rizzo #endif /* DEVICE_POLLING */ 666e4fc250cSLuigi Rizzo 667664a31e4SPeter Wemm #endif /* _KERNEL */ 66819ff91c6SGarrett Wollman 66919ff91c6SGarrett Wollman #endif /* !_NET_IF_VAR_H_ */ 670