ifq.h revision 191816
118334Speter/*- 2169689Skan * Copyright (c) 1982, 1986, 1989, 1993 3169689Skan * The Regents of the University of California. All rights reserved. 4169689Skan * 518334Speter * Redistribution and use in source and binary forms, with or without 690075Sobrien * modification, are permitted provided that the following conditions 718334Speter * are met: 890075Sobrien * 1. Redistributions of source code must retain the above copyright 990075Sobrien * notice, this list of conditions and the following disclaimer. 1090075Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1190075Sobrien * notice, this list of conditions and the following disclaimer in the 1218334Speter * documentation and/or other materials provided with the distribution. 1390075Sobrien * 4. Neither the name of the University nor the names of its contributors 1490075Sobrien * may be used to endorse or promote products derived from this software 1590075Sobrien * without specific prior written permission. 1690075Sobrien * 1718334Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1818334Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1990075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20169689Skan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21169689Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2218334Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2318334Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2418334Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2518334Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2618334Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27169689Skan * SUCH DAMAGE. 2818334Speter * 2918334Speter * From: @(#)if.h 8.1 (Berkeley) 6/10/93 3050397Sobrien * $FreeBSD: head/sys/net/if_var.h 191816 2009-05-05 10:56:12Z zec $ 31132718Skan */ 32132718Skan 3390075Sobrien#ifndef _NET_IF_VAR_H_ 3418334Speter#define _NET_IF_VAR_H_ 35169689Skan 3618334Speter/* 3790075Sobrien * Structures defining a network interface, providing a packet 3818334Speter * transport mechanism (ala level 0 of the PUP protocols). 3918334Speter * 4050397Sobrien * Each interface accepts output datagrams of a specified maximum 4150397Sobrien * length, and provides higher level routines with input datagrams 4252284Sobrien * received from its medium. 4390075Sobrien * 4490075Sobrien * Output occurs when the routine if_output is called, with three parameters: 45169689Skan * (*ifp->if_output)(ifp, m, dst, rt) 46169689Skan * Here m is the mbuf chain to be sent and dst is the destination address. 47169689Skan * The output routine encapsulates the supplied datagram if necessary, 4818334Speter * and then transmits it on its medium. 49169689Skan * 50169689Skan * On input, each interface unwraps the data received by it, and either 51169689Skan * places it on the input queue of an internetwork datagram routine 52169689Skan * and posts the associated software interrupt, or passes the datagram to a raw 53169689Skan * packet input routine. 54169689Skan * 55169689Skan * Routines exist for locating interfaces by their addresses 56169689Skan * or for locating an interface on a certain network, as well as more general 57169689Skan * routing and gateway routines maintaining information used to locate 58169689Skan * interfaces. These routines live in the files if.c and route.c 59169689Skan */ 60169689Skan 61169689Skan#ifdef __STDC__ 62169689Skan/* 63169689Skan * Forward structure declarations for function prototypes [sic]. 64169689Skan */ 65169689Skanstruct mbuf; 66169689Skanstruct thread; 67169689Skanstruct rtentry; 68169689Skanstruct rt_addrinfo; 69169689Skanstruct socket; 70169689Skanstruct ether_header; 7118334Speterstruct carp_if; 7218334Speterstruct ifvlantrunk; 7318334Speterstruct route; 7418334Speter#endif 75132718Skan 76132718Skan#include <sys/queue.h> /* get TAILQ macros */ 7790075Sobrien 78169689Skan#ifdef _KERNEL 79132718Skan#include <sys/mbuf.h> 80169689Skan#include <sys/eventhandler.h> 81169689Skan#include <sys/buf_ring.h> 82169689Skan#endif /* _KERNEL */ 83169689Skan#include <sys/lock.h> /* XXX */ 84132718Skan#include <sys/mutex.h> /* XXX */ 85132718Skan#include <sys/rwlock.h> /* XXX */ 86132718Skan#include <sys/event.h> /* XXX */ 87132718Skan#include <sys/_task.h> 88169689Skan 89132718Skan#define IF_DUNIT_NONE -1 90132718Skan 91132718Skan#include <altq/if_altq.h> 92132718Skan 93132718SkanTAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ 94132718SkanTAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ 95132718SkanTAILQ_HEAD(ifprefixhead, ifprefix); 96169689SkanTAILQ_HEAD(ifmultihead, ifmultiaddr); 97169689SkanTAILQ_HEAD(ifgrouphead, ifg_group); 98132718Skan 99132718Skan/* 100132718Skan * Structure defining a queue for a network interface. 101132718Skan */ 102132718Skanstruct ifqueue { 103132718Skan struct mbuf *ifq_head; 104132718Skan struct mbuf *ifq_tail; 105169689Skan int ifq_len; 106169689Skan int ifq_maxlen; 107169689Skan int ifq_drops; 108169689Skan struct mtx ifq_mtx; 109169689Skan}; 11018334Speter 111169689Skan/* 112169689Skan * Structure defining a network interface. 113169689Skan * 114169689Skan * (Would like to call this struct ``if'', but C isn't PL/1.) 115169689Skan */ 116169689Skan 117169689Skanstruct ifnet { 118169689Skan void *if_softc; /* pointer to driver state */ 119169689Skan void *if_l2com; /* pointer to protocol bits */ 120169689Skan struct vnet *if_vnet; /* pointer to network stack instance */ 121169689Skan TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ 122169689Skan char if_xname[IFNAMSIZ]; /* external name (name + unit) */ 123169689Skan const char *if_dname; /* driver name */ 124169689Skan int if_dunit; /* unit or IF_DUNIT_NONE */ 125169689Skan u_int if_refcount; /* reference count */ 126169689Skan struct ifaddrhead if_addrhead; /* linked list of addresses per if */ 127169689Skan /* 128169689Skan * if_addrhead is the list of all addresses associated to 129169689Skan * an interface. 130169689Skan * Some code in the kernel assumes that first element 131169689Skan * of the list has type AF_LINK, and contains sockaddr_dl 132169689Skan * addresses which store the link-level address and the name 133169689Skan * of the interface. 134169689Skan * However, access to the AF_LINK address through this 135169689Skan * field is deprecated. Use if_addr or ifaddr_byindex() instead. 136169689Skan */ 137169689Skan struct knlist if_klist; /* events attached to this if */ 138169689Skan int if_pcount; /* number of promiscuous listeners */ 139169689Skan struct carp_if *if_carp; /* carp interface structure */ 140169689Skan struct bpf_if *if_bpf; /* packet filter structure */ 14118334Speter u_short if_index; /* numeric abbreviation for this if */ 14218334Speter short if_timer; /* time 'til if_watchdog called */ 14318334Speter struct ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */ 14418334Speter int if_flags; /* up/down, broadcast, etc. */ 145132718Skan int if_capabilities; /* interface features & capabilities */ 14618334Speter int if_capenable; /* enabled features & capabilities */ 14718334Speter void *if_linkmib; /* link-type-specific MIB data */ 14818334Speter size_t if_linkmiblen; /* length of above data */ 14990075Sobrien struct if_data if_data; 15052284Sobrien struct ifmultihead if_multiaddrs; /* multicast addresses configured */ 15152284Sobrien int if_amcount; /* number of all-multicast requests */ 15218334Speter/* procedure handles */ 15390075Sobrien int (*if_output) /* output routine (enqueue) */ 15418334Speter (struct ifnet *, struct mbuf *, struct sockaddr *, 15518334Speter struct route *); 156117395Skan void (*if_input) /* input routine (from h/w driver) */ 15718334Speter (struct ifnet *, struct mbuf *); 15818334Speter void (*if_start) /* initiate output routine */ 15918334Speter (struct ifnet *); 16018334Speter int (*if_ioctl) /* ioctl routine */ 16118334Speter (struct ifnet *, u_long, caddr_t); 16218334Speter void (*if_watchdog) /* timer routine */ 16318334Speter (struct ifnet *); 16418334Speter void (*if_init) /* Init routine */ 165132718Skan (void *); 16618334Speter int (*if_resolvemulti) /* validate/resolve multicast */ 16752284Sobrien (struct ifnet *, struct sockaddr **, struct sockaddr *); 16818334Speter void (*if_qflush) /* flush any queues */ 16918334Speter (struct ifnet *); 17018334Speter int (*if_transmit) /* initiate output routine */ 17118334Speter (struct ifnet *, struct mbuf *); 17218334Speter struct ifaddr *if_addr; /* pointer to link-level address */ 17318334Speter void *if_llsoftc; /* link layer softc */ 17418334Speter int if_drv_flags; /* driver-managed status flags */ 175169689Skan struct ifaltq if_snd; /* output queue (includes altq) */ 17618334Speter const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ 17718334Speter 17818334Speter void *if_bridge; /* bridge glue */ 17918334Speter 18018334Speter struct label *if_label; /* interface MAC label */ 18118334Speter 18218334Speter /* these are only used by IPv6 */ 18318334Speter struct ifprefixhead if_prefixhead; /* list of prefixes per if */ 18452284Sobrien void *if_afdata[AF_MAX]; 18518334Speter int if_afdata_initialized; 18618334Speter struct rwlock if_afdata_lock; 18718334Speter struct task if_linktask; /* task for link change events */ 18852284Sobrien struct mtx if_addr_mtx; /* mutex to protect address lists */ 18918334Speter 19018334Speter LIST_ENTRY(ifnet) if_clones; /* interfaces of a cloner */ 19118334Speter TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ 19252284Sobrien /* protected by if_addr_mtx */ 19318334Speter void *if_pf_kif; 19418334Speter void *if_lagg; /* lagg glue */ 19518334Speter u_char if_alloctype; /* if_type at time of allocation */ 19618334Speter 19718334Speter /* 19818334Speter * Spare fields are added so that we can modify sensitive data 19918334Speter * structures without changing the kernel binary interface, and must 20018334Speter * be used with care where binary compatibility is required. 20118334Speter */ 20296263Sobrien char if_cspare[3]; 20396263Sobrien void *if_pspare[8]; 20496263Sobrien int if_ispare[4]; 20596263Sobrien}; 20696263Sobrien 20718334Spetertypedef void if_init_f_t(void *); 20818334Speter 20918334Speter/* 21018334Speter * XXX These aliases are terribly dangerous because they could apply 21118334Speter * to anything. 21218334Speter */ 21318334Speter#define if_mtu if_data.ifi_mtu 214169689Skan#define if_type if_data.ifi_type 21518334Speter#define if_physical if_data.ifi_physical 21618334Speter#define if_addrlen if_data.ifi_addrlen 21718334Speter#define if_hdrlen if_data.ifi_hdrlen 218169689Skan#define if_metric if_data.ifi_metric 219169689Skan#define if_link_state if_data.ifi_link_state 22018334Speter#define if_baudrate if_data.ifi_baudrate 22118334Speter#define if_hwassist if_data.ifi_hwassist 222169689Skan#define if_ipackets if_data.ifi_ipackets 22318334Speter#define if_ierrors if_data.ifi_ierrors 22418334Speter#define if_opackets if_data.ifi_opackets 22518334Speter#define if_oerrors if_data.ifi_oerrors 226117395Skan#define if_collisions if_data.ifi_collisions 227117395Skan#define if_ibytes if_data.ifi_ibytes 228117395Skan#define if_obytes if_data.ifi_obytes 229117395Skan#define if_imcasts if_data.ifi_imcasts 230132718Skan#define if_omcasts if_data.ifi_omcasts 231117395Skan#define if_iqdrops if_data.ifi_iqdrops 232117395Skan#define if_noproto if_data.ifi_noproto 233117395Skan#define if_lastchange if_data.ifi_lastchange 234117395Skan#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL) 235117395Skan 236117395Skan/* for compatibility with other BSDs */ 237117395Skan#define if_addrlist if_addrhead 238169689Skan#define if_list if_link 239169689Skan#define if_name(ifp) ((ifp)->if_xname) 240169689Skan 241117395Skan/* 242117395Skan * Locks for address lists on the network interface. 243117395Skan */ 244117395Skan#define IF_ADDR_LOCK_INIT(if) mtx_init(&(if)->if_addr_mtx, \ 245117395Skan "if_addr_mtx", NULL, MTX_DEF) 246117395Skan#define IF_ADDR_LOCK_DESTROY(if) mtx_destroy(&(if)->if_addr_mtx) 24718334Speter#define IF_ADDR_LOCK(if) mtx_lock(&(if)->if_addr_mtx) 24818334Speter#define IF_ADDR_UNLOCK(if) mtx_unlock(&(if)->if_addr_mtx) 24918334Speter#define IF_ADDR_LOCK_ASSERT(if) mtx_assert(&(if)->if_addr_mtx, MA_OWNED) 25018334Speter 251132718Skan/* 25218334Speter * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) 253132718Skan * are queues of messages stored on ifqueue structures 25452750Sobrien * (defined above). Entries are added to and deleted from these structures 25518334Speter * by these macros, which should be called with ipl raised to splimp(). 256169689Skan */ 257169689Skan#define IF_LOCK(ifq) mtx_lock(&(ifq)->ifq_mtx) 258169689Skan#define IF_UNLOCK(ifq) mtx_unlock(&(ifq)->ifq_mtx) 259169689Skan#define IF_LOCK_ASSERT(ifq) mtx_assert(&(ifq)->ifq_mtx, MA_OWNED) 260169689Skan#define _IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 261169689Skan#define _IF_DROP(ifq) ((ifq)->ifq_drops++) 262169689Skan#define _IF_QLEN(ifq) ((ifq)->ifq_len) 263169689Skan 264169689Skan#define _IF_ENQUEUE(ifq, m) do { \ 265169689Skan (m)->m_nextpkt = NULL; \ 266169689Skan if ((ifq)->ifq_tail == NULL) \ 26718334Speter (ifq)->ifq_head = m; \ 268169689Skan else \ 26918334Speter (ifq)->ifq_tail->m_nextpkt = m; \ 270169689Skan (ifq)->ifq_tail = m; \ 271169689Skan (ifq)->ifq_len++; \ 272169689Skan} while (0) 27318334Speter 27418334Speter#define IF_ENQUEUE(ifq, m) do { \ 275169689Skan IF_LOCK(ifq); \ 27618334Speter _IF_ENQUEUE(ifq, m); \ 27790075Sobrien IF_UNLOCK(ifq); \ 27890075Sobrien} while (0) 27918334Speter 28018334Speter#define _IF_PREPEND(ifq, m) do { \ 28118334Speter (m)->m_nextpkt = (ifq)->ifq_head; \ 28218334Speter if ((ifq)->ifq_tail == NULL) \ 28318334Speter (ifq)->ifq_tail = (m); \ 28418334Speter (ifq)->ifq_head = (m); \ 28518334Speter (ifq)->ifq_len++; \ 28618334Speter} while (0) 28718334Speter 28818334Speter#define IF_PREPEND(ifq, m) do { \ 28918334Speter IF_LOCK(ifq); \ 29018334Speter _IF_PREPEND(ifq, m); \ 291169689Skan IF_UNLOCK(ifq); \ 292169689Skan} while (0) 293169689Skan 29450397Sobrien#define _IF_DEQUEUE(ifq, m) do { \ 295169689Skan (m) = (ifq)->ifq_head; \ 29618334Speter if (m) { \ 297169689Skan if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \ 298169689Skan (ifq)->ifq_tail = NULL; \ 299169689Skan (m)->m_nextpkt = NULL; \ 300169689Skan (ifq)->ifq_len--; \ 30118334Speter } \ 302169689Skan} while (0) 303169689Skan 304169689Skan#define IF_DEQUEUE(ifq, m) do { \ 305169689Skan IF_LOCK(ifq); \ 30618334Speter _IF_DEQUEUE(ifq, m); \ 307169689Skan IF_UNLOCK(ifq); \ 30818334Speter} while (0) 30918334Speter 31018334Speter#define _IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) 31118334Speter#define IF_POLL(ifq, m) _IF_POLL(ifq, m) 312169689Skan 31318334Speter#define _IF_DRAIN(ifq) do { \ 31452284Sobrien struct mbuf *m; \ 31552284Sobrien for (;;) { \ 316169689Skan _IF_DEQUEUE(ifq, m); \ 317169689Skan if (m == NULL) \ 318169689Skan break; \ 319169689Skan m_freem(m); \ 32018334Speter } \ 32118334Speter} while (0) 32218334Speter 32318334Speter#define IF_DRAIN(ifq) do { \ 324169689Skan IF_LOCK(ifq); \ 325169689Skan _IF_DRAIN(ifq); \ 326169689Skan IF_UNLOCK(ifq); \ 327169689Skan} while(0) 328169689Skan 329169689Skan#ifdef _KERNEL 330169689Skan/* interface address change event */ 331169689Skantypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *); 332169689SkanEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t); 333169689Skan/* new interface arrival event */ 334169689Skantypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *); 335169689SkanEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t); 336169689Skan/* interface departure event */ 337169689Skantypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *); 338169689SkanEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t); 339169689Skan 340169689Skan/* 341169689Skan * interface groups 342169689Skan */ 343169689Skanstruct ifg_group { 344169689Skan char ifg_group[IFNAMSIZ]; 345169689Skan u_int ifg_refcnt; 346169689Skan void *ifg_pf_kif; 34718334Speter TAILQ_HEAD(, ifg_member) ifg_members; 348169689Skan TAILQ_ENTRY(ifg_group) ifg_next; 349169689Skan}; 35018334Speter 351169689Skanstruct ifg_member { 352169689Skan TAILQ_ENTRY(ifg_member) ifgm_next; 35318334Speter struct ifnet *ifgm_ifp; 354169689Skan}; 355169689Skan 356169689Skanstruct ifg_list { 357169689Skan struct ifg_group *ifgl_group; 358169689Skan TAILQ_ENTRY(ifg_list) ifgl_next; 359169689Skan}; 360169689Skan 361169689Skan/* group attach event */ 362169689Skantypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *); 363169689SkanEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t); 364169689Skan/* group detach event */ 365169689Skantypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *); 366169689SkanEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t); 367169689Skan/* group change event */ 368169689Skantypedef void (*group_change_event_handler_t)(void *, const char *); 369169689SkanEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t); 370169689Skan 371169689Skan#define IF_AFDATA_LOCK_INIT(ifp) \ 372169689Skan rw_init(&(ifp)->if_afdata_lock, "if_afdata") 373169689Skan 374169689Skan#define IF_AFDATA_WLOCK(ifp) rw_wlock(&(ifp)->if_afdata_lock) 37518334Speter#define IF_AFDATA_RLOCK(ifp) rw_rlock(&(ifp)->if_afdata_lock) 37618334Speter#define IF_AFDATA_WUNLOCK(ifp) rw_wunlock(&(ifp)->if_afdata_lock) 37718334Speter#define IF_AFDATA_RUNLOCK(ifp) rw_runlock(&(ifp)->if_afdata_lock) 378169689Skan#define IF_AFDATA_LOCK(ifp) IF_AFDATA_WLOCK(ifp) 379169689Skan#define IF_AFDATA_UNLOCK(ifp) IF_AFDATA_WUNLOCK(ifp) 380169689Skan#define IF_AFDATA_TRYLOCK(ifp) rw_try_wlock(&(ifp)->if_afdata_lock) 381169689Skan#define IF_AFDATA_DESTROY(ifp) rw_destroy(&(ifp)->if_afdata_lock) 382169689Skan 383169689Skan#define IF_AFDATA_LOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED) 384169689Skan#define IF_AFDATA_UNLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED) 385169689Skan 386169689Skanint if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, 387169689Skan int adjust); 388169689Skan#define IF_HANDOFF(ifq, m, ifp) \ 389169689Skan if_handoff((struct ifqueue *)ifq, m, ifp, 0) 390169689Skan#define IF_HANDOFF_ADJ(ifq, m, ifp, adj) \ 39118334Speter if_handoff((struct ifqueue *)ifq, m, ifp, adj) 39218334Speter 39318334Spetervoid if_start(struct ifnet *); 39418334Speter 395169689Skan#define IFQ_ENQUEUE(ifq, m, err) \ 39618334Speterdo { \ 39718334Speter IF_LOCK(ifq); \ 39818334Speter if (ALTQ_IS_ENABLED(ifq)) \ 39918334Speter ALTQ_ENQUEUE(ifq, m, NULL, err); \ 40018334Speter else { \ 40118334Speter if (_IF_QFULL(ifq)) { \ 40218334Speter m_freem(m); \ 403169689Skan (err) = ENOBUFS; \ 40418334Speter } else { \ 405169689Skan _IF_ENQUEUE(ifq, m); \ 40618334Speter (err) = 0; \ 40718334Speter } \ 40818334Speter } \ 40918334Speter if (err) \ 41018334Speter (ifq)->ifq_drops++; \ 411169689Skan IF_UNLOCK(ifq); \ 412169689Skan} while (0) 413169689Skan 41418334Speter#define IFQ_DEQUEUE_NOLOCK(ifq, m) \ 41518334Speterdo { \ 41618334Speter if (TBR_IS_ENABLED(ifq)) \ 41718334Speter (m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE); \ 418169689Skan else if (ALTQ_IS_ENABLED(ifq)) \ 419169689Skan ALTQ_DEQUEUE(ifq, m); \ 42018334Speter else \ 42118334Speter _IF_DEQUEUE(ifq, m); \ 42218334Speter} while (0) 42318334Speter 424169689Skan#define IFQ_DEQUEUE(ifq, m) \ 425169689Skando { \ 426169689Skan IF_LOCK(ifq); \ 42718334Speter IFQ_DEQUEUE_NOLOCK(ifq, m); \ 42818334Speter IF_UNLOCK(ifq); \ 42918334Speter} while (0) 43018334Speter 43118334Speter#define IFQ_POLL_NOLOCK(ifq, m) \ 43218334Speterdo { \ 43318334Speter if (TBR_IS_ENABLED(ifq)) \ 43418334Speter (m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL); \ 43518334Speter else if (ALTQ_IS_ENABLED(ifq)) \ 43618334Speter ALTQ_POLL(ifq, m); \ 43718334Speter else \ 43818334Speter _IF_POLL(ifq, m); \ 43918334Speter} while (0) 44018334Speter 44118334Speter#define IFQ_POLL(ifq, m) \ 44218334Speterdo { \ 44318334Speter IF_LOCK(ifq); \ 44418334Speter IFQ_POLL_NOLOCK(ifq, m); \ 44518334Speter IF_UNLOCK(ifq); \ 44618334Speter} while (0) 44718334Speter 44818334Speter#define IFQ_PURGE_NOLOCK(ifq) \ 44918334Speterdo { \ 45018334Speter if (ALTQ_IS_ENABLED(ifq)) { \ 451132718Skan ALTQ_PURGE(ifq); \ 45218334Speter } else \ 45318334Speter _IF_DRAIN(ifq); \ 45418334Speter} while (0) 45518334Speter 45618334Speter#define IFQ_PURGE(ifq) \ 45718334Speterdo { \ 45818334Speter IF_LOCK(ifq); \ 459169689Skan IFQ_PURGE_NOLOCK(ifq); \ 460169689Skan IF_UNLOCK(ifq); \ 461169689Skan} while (0) 462169689Skan 46318334Speter#define IFQ_SET_READY(ifq) \ 46418334Speter do { ((ifq)->altq_flags |= ALTQF_READY); } while (0) 465169689Skan 466169689Skan#define IFQ_LOCK(ifq) IF_LOCK(ifq) 467169689Skan#define IFQ_UNLOCK(ifq) IF_UNLOCK(ifq) 468169689Skan#define IFQ_LOCK_ASSERT(ifq) IF_LOCK_ASSERT(ifq) 469169689Skan#define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) 470169689Skan#define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) 471169689Skan#define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) 472169689Skan#define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) 473169689Skan#define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) 474169689Skan 475169689Skan/* 476169689Skan * The IFF_DRV_OACTIVE test should really occur in the device driver, not in 477169689Skan * the handoff logic, as that flag is locked by the device driver. 478169689Skan */ 47918334Speter#define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ 48018334Speterdo { \ 48118334Speter int len; \ 48218334Speter short mflags; \ 48318334Speter \ 484169689Skan len = (m)->m_pkthdr.len; \ 485169689Skan mflags = (m)->m_flags; \ 486169689Skan IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \ 487169689Skan if ((err) == 0) { \ 48818334Speter (ifp)->if_obytes += len + (adj); \ 48918334Speter if (mflags & M_MCAST) \ 490169689Skan (ifp)->if_omcasts++; \ 491169689Skan if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0) \ 492169689Skan if_start(ifp); \ 493169689Skan } \ 494169689Skan} while (0) 495169689Skan 496169689Skan#define IFQ_HANDOFF(ifp, m, err) \ 497169689Skan IFQ_HANDOFF_ADJ(ifp, m, 0, err) 498169689Skan 499169689Skan#define IFQ_DRV_DEQUEUE(ifq, m) \ 500169689Skando { \ 501169689Skan (m) = (ifq)->ifq_drv_head; \ 502169689Skan if (m) { \ 503169689Skan if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL) \ 50418334Speter (ifq)->ifq_drv_tail = NULL; \ 505169689Skan (m)->m_nextpkt = NULL; \ 50618334Speter (ifq)->ifq_drv_len--; \ 50718334Speter } else { \ 50818334Speter IFQ_LOCK(ifq); \ 509169689Skan IFQ_DEQUEUE_NOLOCK(ifq, m); \ 51018334Speter while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) { \ 511169689Skan struct mbuf *m0; \ 51250397Sobrien IFQ_DEQUEUE_NOLOCK(ifq, m0); \ 51318334Speter if (m0 == NULL) \ 51418334Speter break; \ 51518334Speter m0->m_nextpkt = NULL; \ 51618334Speter if ((ifq)->ifq_drv_tail == NULL) \ 51718334Speter (ifq)->ifq_drv_head = m0; \ 51818334Speter else \ 51918334Speter (ifq)->ifq_drv_tail->m_nextpkt = m0; \ 520169689Skan (ifq)->ifq_drv_tail = m0; \ 521169689Skan (ifq)->ifq_drv_len++; \ 522169689Skan } \ 523169689Skan IFQ_UNLOCK(ifq); \ 524169689Skan } \ 525169689Skan} while (0) 526169689Skan 527169689Skan#define IFQ_DRV_PREPEND(ifq, m) \ 528169689Skando { \ 529169689Skan (m)->m_nextpkt = (ifq)->ifq_drv_head; \ 530169689Skan if ((ifq)->ifq_drv_tail == NULL) \ 531169689Skan (ifq)->ifq_drv_tail = (m); \ 532169689Skan (ifq)->ifq_drv_head = (m); \ 533169689Skan (ifq)->ifq_drv_len++; \ 534169689Skan} while (0) 535169689Skan 536169689Skan#define IFQ_DRV_IS_EMPTY(ifq) \ 537169689Skan (((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0)) 538169689Skan 539169689Skan#define IFQ_DRV_PURGE(ifq) \ 540169689Skando { \ 541169689Skan struct mbuf *m, *n = (ifq)->ifq_drv_head; \ 542169689Skan while((m = n) != NULL) { \ 543169689Skan n = m->m_nextpkt; \ 544169689Skan m_freem(m); \ 545169689Skan } \ 546169689Skan (ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL; \ 547169689Skan (ifq)->ifq_drv_len = 0; \ 548169689Skan IFQ_PURGE(ifq); \ 549169689Skan} while (0) 550169689Skan 551169689Skan#ifdef _KERNEL 552169689Skanstatic __inline void 553169689Skandrbr_stats_update(struct ifnet *ifp, int len, int mflags) 554169689Skan{ 555169689Skan 556169689Skan ifp->if_obytes += len; 557169689Skan if (mflags & M_MCAST) 558169689Skan ifp->if_omcasts++; 559169689Skan} 560169689Skan 561169689Skanstatic __inline int 562169689Skandrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m) 563169689Skan{ 564169689Skan int error = 0; 565169689Skan int len = m->m_pkthdr.len; 566169689Skan int mflags = m->m_flags; 567169689Skan 568169689Skan#ifdef ALTQ 569169689Skan if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 570169689Skan IFQ_ENQUEUE(&ifp->if_snd, m, error); 571169689Skan return (error); 572169689Skan } 573169689Skan#endif 574169689Skan if ((error = buf_ring_enqueue(br, m)) == ENOBUFS) { 575169689Skan br->br_drops++; 576169689Skan _IF_DROP(&ifp->if_snd); 577169689Skan m_freem(m); 578169689Skan } else 579169689Skan drbr_stats_update(ifp, len, mflags); 580169689Skan 581169689Skan return (error); 582169689Skan} 583169689Skan 584169689Skanstatic __inline void 585169689Skandrbr_free(struct buf_ring *br, struct malloc_type *type) 586169689Skan{ 587169689Skan struct mbuf *m; 588169689Skan 589169689Skan while ((m = buf_ring_dequeue_sc(br)) != NULL) 590169689Skan m_freem(m); 591169689Skan 592169689Skan buf_ring_free(br, type); 593169689Skan} 594169689Skan 595169689Skanstatic __inline struct mbuf * 596169689Skandrbr_dequeue(struct ifnet *ifp, struct buf_ring *br) 597169689Skan{ 598169689Skan#ifdef ALTQ 599169689Skan struct mbuf *m; 600169689Skan 601169689Skan if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 602169689Skan IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 603169689Skan return (m); 604169689Skan } 605169689Skan#endif 606169689Skan return (buf_ring_dequeue_sc(br)); 607169689Skan} 608169689Skan 609169689Skanstatic __inline int 610169689Skandrbr_empty(struct ifnet *ifp, struct buf_ring *br) 611169689Skan{ 612169689Skan#ifdef ALTQ 613169689Skan if (ALTQ_IS_ENABLED(&ifp->if_snd)) 614169689Skan return (IFQ_DRV_IS_EMPTY(&ifp->if_snd)); 615169689Skan#endif 616169689Skan return (buf_ring_empty(br)); 617169689Skan} 618169689Skan#endif 619169689Skan/* 620169689Skan * 72 was chosen below because it is the size of a TCP/IP 621169689Skan * header (40) + the minimum mss (32). 622169689Skan */ 623169689Skan#define IF_MINMTU 72 624169689Skan#define IF_MAXMTU 65535 625169689Skan 626169689Skan#endif /* _KERNEL */ 627169689Skan 628169689Skan/* 629169689Skan * The ifaddr structure contains information about one address 630169689Skan * of an interface. They are maintained by the different address families, 631169689Skan * are allocated and attached when an address is set, and are linked 632169689Skan * together so all addresses for an interface can be located. 633169689Skan * 634169689Skan * NOTE: a 'struct ifaddr' is always at the beginning of a larger 635169689Skan * chunk of malloc'ed memory, where we store the three addresses 636169689Skan * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here. 637169689Skan */ 638169689Skanstruct ifaddr { 639169689Skan struct sockaddr *ifa_addr; /* address of interface */ 640169689Skan struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ 641169689Skan#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 642169689Skan struct sockaddr *ifa_netmask; /* used to determine subnet */ 643169689Skan struct if_data if_data; /* not all members are meaningful */ 644169689Skan struct ifnet *ifa_ifp; /* back-pointer to interface */ 645169689Skan TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ 646169689Skan void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ 647169689Skan (int, struct rtentry *, struct rt_addrinfo *); 648169689Skan u_short ifa_flags; /* mostly rt_flags for cloning */ 649169689Skan u_int ifa_refcnt; /* references to this structure */ 650169689Skan int ifa_metric; /* cost of going out this interface */ 651169689Skan int (*ifa_claim_addr) /* check if an addr goes to this if */ 652169689Skan (struct ifaddr *, struct sockaddr *); 653169689Skan struct mtx ifa_mtx; 654169689Skan}; 655169689Skan#define IFA_ROUTE RTF_UP /* route installed */ 656169689Skan 657169689Skan/* for compatibility with other BSDs */ 658169689Skan#define ifa_list ifa_link 659169689Skan 660169689Skan#define IFA_LOCK_INIT(ifa) \ 661169689Skan mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF) 662169689Skan#define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) 663169689Skan#define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) 664169689Skan#define IFA_DESTROY(ifa) mtx_destroy(&(ifa)->ifa_mtx) 665169689Skan 666169689Skan/* 667169689Skan * The prefix structure contains information about one prefix 668169689Skan * of an interface. They are maintained by the different address families, 669169689Skan * are allocated and attached when a prefix or an address is set, 670169689Skan * and are linked together so all prefixes for an interface can be located. 671169689Skan */ 672169689Skanstruct ifprefix { 673169689Skan struct sockaddr *ifpr_prefix; /* prefix of interface */ 674169689Skan struct ifnet *ifpr_ifp; /* back-pointer to interface */ 675169689Skan TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */ 676169689Skan u_char ifpr_plen; /* prefix length in bits */ 677169689Skan u_char ifpr_type; /* protocol dependent prefix type */ 678169689Skan}; 679169689Skan 680169689Skan/* 681169689Skan * Multicast address structure. This is analogous to the ifaddr 682169689Skan * structure except that it keeps track of multicast addresses. 683169689Skan */ 684169689Skanstruct ifmultiaddr { 685169689Skan TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ 686169689Skan struct sockaddr *ifma_addr; /* address this membership is for */ 687169689Skan struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ 688169689Skan struct ifnet *ifma_ifp; /* back-pointer to interface */ 689169689Skan u_int ifma_refcount; /* reference count */ 690169689Skan void *ifma_protospec; /* protocol-specific state, if any */ 691169689Skan struct ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */ 692169689Skan}; 693169689Skan 694169689Skan#ifdef _KERNEL 695169689Skan#define IFAFREE(ifa) \ 696169689Skan do { \ 697169689Skan IFA_LOCK(ifa); \ 698169689Skan KASSERT((ifa)->ifa_refcnt > 0, \ 699169689Skan ("ifa %p !(ifa_refcnt > 0)", ifa)); \ 700169689Skan if (--(ifa)->ifa_refcnt == 0) { \ 701169689Skan IFA_DESTROY(ifa); \ 702169689Skan free(ifa, M_IFADDR); \ 703169689Skan } else \ 704169689Skan IFA_UNLOCK(ifa); \ 705169689Skan } while (0) 706169689Skan 707169689Skan#define IFAREF(ifa) \ 708169689Skan do { \ 709169689Skan IFA_LOCK(ifa); \ 710169689Skan ++(ifa)->ifa_refcnt; \ 711169689Skan IFA_UNLOCK(ifa); \ 712169689Skan } while (0) 713169689Skan 714169689Skanextern struct rwlock ifnet_lock; 715169689Skan#define IFNET_LOCK_INIT() \ 716169689Skan rw_init_flags(&ifnet_lock, "ifnet", RW_RECURSE) 717169689Skan#define IFNET_WLOCK() rw_wlock(&ifnet_lock) 718169689Skan#define IFNET_WUNLOCK() rw_wunlock(&ifnet_lock) 719169689Skan#define IFNET_WLOCK_ASSERT() rw_assert(&ifnet_lock, RA_LOCKED) 720169689Skan#define IFNET_RLOCK() rw_rlock(&ifnet_lock) 721169689Skan#define IFNET_RUNLOCK() rw_runlock(&ifnet_lock) 722169689Skan 723169689Skanstruct ifindex_entry { 724169689Skan struct ifnet *ife_ifnet; 725169689Skan struct cdev *ife_dev; 726169689Skan}; 727169689Skan 728169689Skan/* 729169689Skan * Look up an ifnet given its index; the _ref variant also acquires a 730169689Skan * reference that must be freed using if_rele(). It is almost always a bug 731169689Skan * to call ifnet_byindex() instead if ifnet_byindex_ref(). 732169689Skan */ 733169689Skanstruct ifnet *ifnet_byindex(u_short idx); 734169689Skanstruct ifnet *ifnet_byindex_locked(u_short idx); 735169689Skanstruct ifnet *ifnet_byindex_ref(u_short idx); 73618334Spetervoid ifnet_setbyindex(u_short idx, struct ifnet *ifp); 737169689Skan 738169689Skan/* 739169689Skan * Given the index, ifaddr_byindex() returns the one and only 740169689Skan * link-level ifaddr for the interface. You are not supposed to use 741169689Skan * it to traverse the list of addresses associated to the interface. 742169689Skan */ 743169689Skanstruct ifaddr *ifaddr_byindex(u_short idx); 744169689Skanstruct cdev *ifdev_byindex(u_short idx); 745169689Skan 746169689Skan#ifdef VIMAGE_GLOBALS 747169689Skanextern struct ifnethead ifnet; 748169689Skanextern struct ifnet *loif; /* first loopback interface */ 749169689Skanextern int if_index; 750169689Skan#endif 751169689Skanextern int ifqmaxlen; 752169689Skan 753169689Skanint if_addgroup(struct ifnet *, const char *); 754169689Skanint if_delgroup(struct ifnet *, const char *); 755169689Skanint if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); 756169689Skanint if_allmulti(struct ifnet *, int); 757169689Skanstruct ifnet* if_alloc(u_char); 758169689Skanvoid if_attach(struct ifnet *); 759169689Skanvoid if_dead(struct ifnet *); 760169689Skanvoid if_grow(void); 761169689Skanint if_delmulti(struct ifnet *, struct sockaddr *); 762169689Skanvoid if_delmulti_ifma(struct ifmultiaddr *); 763169689Skanvoid if_detach(struct ifnet *); 76418334Spetervoid if_purgeaddrs(struct ifnet *); 76518334Spetervoid if_purgemaddrs(struct ifnet *); 76618334Spetervoid if_down(struct ifnet *); 76718334Speterstruct ifmultiaddr * 76818334Speter if_findmulti(struct ifnet *, struct sockaddr *); 769169689Skanvoid if_free(struct ifnet *); 77018334Spetervoid if_free_type(struct ifnet *, u_char); 771169689Skanvoid if_initname(struct ifnet *, const char *, int); 772169689Skanvoid if_link_state_change(struct ifnet *, int); 773169689Skanint if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); 774169689Skanvoid if_qflush(struct ifnet *); 775169689Skanvoid if_ref(struct ifnet *); 776169689Skanvoid if_rele(struct ifnet *); 777169689Skanint if_setlladdr(struct ifnet *, const u_char *, int); 778169689Skanvoid if_up(struct ifnet *); 779169689Skan/*void ifinit(void);*/ /* declared in systm.h for main() */ 780169689Skanint ifioctl(struct socket *, u_long, caddr_t, struct thread *); 781169689Skanint ifpromisc(struct ifnet *, int); 782169689Skanstruct ifnet *ifunit(const char *); 783169689Skanstruct ifnet *ifunit_ref(const char *); 784169689Skan 785169689Skanvoid ifq_attach(struct ifaltq *, struct ifnet *ifp); 786169689Skanvoid ifq_detach(struct ifaltq *); 787169689Skan 78890075Sobrienstruct ifaddr *ifa_ifwithaddr(struct sockaddr *); 78990075Sobrienstruct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *); 79018334Speterstruct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); 79118334Speterstruct ifaddr *ifa_ifwithnet(struct sockaddr *); 79218334Speterstruct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); 79318334Speterstruct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int); 79450397Sobrien 79550397Sobrienstruct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); 79618334Speter 79718334Speterint if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); 79890075Sobrien 79990075Sobrientypedef void *if_com_alloc_t(u_char type, struct ifnet *ifp); 80090075Sobrientypedef void if_com_free_t(void *com, u_char type); 801169689Skanvoid if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f); 802169689Skanvoid if_deregister_com_alloc(u_char type); 80390075Sobrien 80490075Sobrien#define IF_LLADDR(ifp) \ 805169689Skan LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr)) 806169689Skan 80790075Sobrien#ifdef DEVICE_POLLING 808169689Skanenum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS }; 809132718Skan 810132718Skantypedef void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); 811132718Skanint ether_poll_register(poll_handler_t *h, struct ifnet *ifp); 81218334Speterint ether_poll_deregister(struct ifnet *ifp); 813132718Skan#endif /* DEVICE_POLLING */ 814169689Skan 815132718Skan#endif /* _KERNEL */ 816169689Skan 81718334Speter#endif /* !_NET_IF_VAR_H_ */ 81818334Speter