ifq.h revision 256521
133965Sjdp/*- 278828Sobrien * Copyright (c) 1982, 1986, 1989, 1993 3218822Sdim * The Regents of the University of California. All rights reserved. 433965Sjdp * 533965Sjdp * Redistribution and use in source and binary forms, with or without 633965Sjdp * modification, are permitted provided that the following conditions 733965Sjdp * are met: 833965Sjdp * 1. Redistributions of source code must retain the above copyright 933965Sjdp * notice, this list of conditions and the following disclaimer. 1033965Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1133965Sjdp * notice, this list of conditions and the following disclaimer in the 1233965Sjdp * documentation and/or other materials provided with the distribution. 1333965Sjdp * 4. Neither the name of the University nor the names of its contributors 1433965Sjdp * may be used to endorse or promote products derived from this software 1533965Sjdp * without specific prior written permission. 1633965Sjdp * 1733965Sjdp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1833965Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1933965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20218822Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21218822Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2233965Sjdp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2333965Sjdp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2433965Sjdp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2533965Sjdp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2633965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2733965Sjdp * SUCH DAMAGE. 2833965Sjdp * 29218822Sdim * From: @(#)if.h 8.1 (Berkeley) 6/10/93 30218822Sdim * $FreeBSD: head/sys/net/if_var.h 256521 2013-10-15 10:41:22Z glebius $ 31218822Sdim */ 32218822Sdim 33218822Sdim#ifndef _NET_IF_VAR_H_ 34218822Sdim#define _NET_IF_VAR_H_ 35218822Sdim 3633965Sjdp/* 3733965Sjdp * Structures defining a network interface, providing a packet 3833965Sjdp * transport mechanism (ala level 0 of the PUP protocols). 3933965Sjdp * 4033965Sjdp * Each interface accepts output datagrams of a specified maximum 41218822Sdim * length, and provides higher level routines with input datagrams 42218822Sdim * received from its medium. 43218822Sdim * 4477298Sobrien * Output occurs when the routine if_output is called, with three parameters: 4577298Sobrien * (*ifp->if_output)(ifp, m, dst, rt) 4677298Sobrien * Here m is the mbuf chain to be sent and dst is the destination address. 4777298Sobrien * The output routine encapsulates the supplied datagram if necessary, 4889857Sobrien * and then transmits it on its medium. 4989857Sobrien * 5089857Sobrien * On input, each interface unwraps the data received by it, and either 51218822Sdim * places it on the input queue of an internetwork datagram routine 52218822Sdim * and posts the associated software interrupt, or passes the datagram to a raw 53218822Sdim * packet input routine. 54218822Sdim * 5589857Sobrien * Routines exist for locating interfaces by their addresses 5689857Sobrien * or for locating an interface on a certain network, as well as more general 5789857Sobrien * routing and gateway routines maintaining information used to locate 5889857Sobrien * interfaces. These routines live in the files if.c and route.c 5989857Sobrien */ 6089857Sobrien 6189857Sobrien#ifdef __STDC__ 6289857Sobrien/* 6389857Sobrien * Forward structure declarations for function prototypes [sic]. 6489857Sobrien */ 6589857Sobrienstruct mbuf; 6633965Sjdpstruct thread; 67218822Sdimstruct rtentry; 6833965Sjdpstruct rt_addrinfo; 6933965Sjdpstruct socket; 70218822Sdimstruct ether_header; 71218822Sdimstruct carp_if; 7233965Sjdpstruct carp_softc; 7333965Sjdpstruct ifvlantrunk; 7433965Sjdpstruct route; 75218822Sdimstruct vnet; 7633965Sjdp#endif 77218822Sdim 7833965Sjdp#include <sys/queue.h> /* get TAILQ macros */ 7933965Sjdp 8033965Sjdp#ifdef _KERNEL 8133965Sjdp#include <sys/mbuf.h> 82218822Sdim#include <sys/eventhandler.h> 8333965Sjdp#include <sys/buf_ring.h> 8433965Sjdp#include <net/vnet.h> 8533965Sjdp#endif /* _KERNEL */ 8633965Sjdp#include <sys/lock.h> /* XXX */ 8733965Sjdp#include <sys/mutex.h> /* XXX */ 8833965Sjdp#include <sys/rwlock.h> /* XXX */ 8933965Sjdp#include <sys/sx.h> /* XXX */ 9033965Sjdp#include <sys/event.h> /* XXX */ 9133965Sjdp#include <sys/_task.h> 92218822Sdim 9333965Sjdp#define IF_DUNIT_NONE -1 9433965Sjdp 9533965Sjdp#include <altq/if_altq.h> 9633965Sjdp 97218822SdimTAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ 98218822SdimTAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ 9933965SjdpTAILQ_HEAD(ifmultihead, ifmultiaddr); 10033965SjdpTAILQ_HEAD(ifgrouphead, ifg_group); 10133965Sjdp 10233965Sjdp#ifdef _KERNEL 10333965SjdpVNET_DECLARE(struct pfil_head, link_pfil_hook); /* packet filter hooks */ 10433965Sjdp#define V_link_pfil_hook VNET(link_pfil_hook) 10533965Sjdp#endif /* _KERNEL */ 106218822Sdim 10733965Sjdp/* 10833965Sjdp * Structure defining a queue for a network interface. 10933965Sjdp */ 11033965Sjdpstruct ifqueue { 111218822Sdim struct mbuf *ifq_head; 11233965Sjdp struct mbuf *ifq_tail; 11333965Sjdp int ifq_len; 11433965Sjdp int ifq_maxlen; 11533965Sjdp int ifq_drops; 11633965Sjdp struct mtx ifq_mtx; 117218822Sdim}; 11833965Sjdp 11933965Sjdp/* 12033965Sjdp * Structure defining a network interface. 12133965Sjdp * 122218822Sdim * (Would like to call this struct ``if'', but C isn't PL/1.) 12333965Sjdp */ 12433965Sjdp 12533965Sjdpstruct ifnet { 12633965Sjdp void *if_softc; /* pointer to driver state */ 12733965Sjdp void *if_l2com; /* pointer to protocol bits */ 128218822Sdim struct vnet *if_vnet; /* pointer to network stack instance */ 12933965Sjdp TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ 13033965Sjdp char if_xname[IFNAMSIZ]; /* external name (name + unit) */ 13133965Sjdp const char *if_dname; /* driver name */ 13233965Sjdp int if_dunit; /* unit or IF_DUNIT_NONE */ 133218822Sdim u_int if_refcount; /* reference count */ 134218822Sdim struct ifaddrhead if_addrhead; /* linked list of addresses per if */ 13533965Sjdp /* 13633965Sjdp * if_addrhead is the list of all addresses associated to 13733965Sjdp * an interface. 138218822Sdim * Some code in the kernel assumes that first element 13933965Sjdp * of the list has type AF_LINK, and contains sockaddr_dl 14033965Sjdp * addresses which store the link-level address and the name 14133965Sjdp * of the interface. 14233965Sjdp * However, access to the AF_LINK address through this 14333965Sjdp * field is deprecated. Use if_addr or ifaddr_byindex() instead. 144218822Sdim */ 14533965Sjdp int if_pcount; /* number of promiscuous listeners */ 14633965Sjdp struct carp_if *if_carp; /* carp interface structure */ 14733965Sjdp struct bpf_if *if_bpf; /* packet filter structure */ 14833965Sjdp u_short if_index; /* numeric abbreviation for this if */ 14933965Sjdp short if_index_reserved; /* spare space to grow if_index */ 15033965Sjdp struct ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */ 15133965Sjdp int if_flags; /* up/down, broadcast, etc. */ 15233965Sjdp int if_capabilities; /* interface features & capabilities */ 15333965Sjdp int if_capenable; /* enabled features & capabilities */ 15433965Sjdp void *if_linkmib; /* link-type-specific MIB data */ 155218822Sdim size_t if_linkmiblen; /* length of above data */ 15633965Sjdp struct if_data if_data; 15733965Sjdp struct ifmultihead if_multiaddrs; /* multicast addresses configured */ 15833965Sjdp int if_amcount; /* number of all-multicast requests */ 15933965Sjdp/* procedure handles */ 16038889Sjdp int (*if_output) /* output routine (enqueue) */ 16138889Sjdp (struct ifnet *, struct mbuf *, const struct sockaddr *, 16233965Sjdp struct route *); 16338889Sjdp void (*if_input) /* input routine (from h/w driver) */ 164218822Sdim (struct ifnet *, struct mbuf *); 16538889Sjdp void (*if_start) /* initiate output routine */ 16638889Sjdp (struct ifnet *); 16738889Sjdp int (*if_ioctl) /* ioctl routine */ 16838889Sjdp (struct ifnet *, u_long, caddr_t); 16938889Sjdp void (*if_init) /* Init routine */ 17038889Sjdp (void *); 17133965Sjdp int (*if_resolvemulti) /* validate/resolve multicast */ 17233965Sjdp (struct ifnet *, struct sockaddr **, struct sockaddr *); 173218822Sdim void (*if_qflush) /* flush any queues */ 17433965Sjdp (struct ifnet *); 17533965Sjdp int (*if_transmit) /* initiate output routine */ 17633965Sjdp (struct ifnet *, struct mbuf *); 177218822Sdim void (*if_reassign) /* reassign to vnet routine */ 17833965Sjdp (struct ifnet *, struct vnet *, char *); 17933965Sjdp struct vnet *if_home_vnet; /* where this ifnet originates from */ 180218822Sdim struct ifaddr *if_addr; /* pointer to link-level address */ 18133965Sjdp void *if_llsoftc; /* link layer softc */ 18233965Sjdp int if_drv_flags; /* driver-managed status flags */ 183104834Sobrien struct ifaltq if_snd; /* output queue (includes altq) */ 184218822Sdim const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ 185218822Sdim 18633965Sjdp void *if_bridge; /* bridge glue */ 18733965Sjdp 18833965Sjdp struct label *if_label; /* interface MAC label */ 18933965Sjdp 19033965Sjdp /* these are only used by IPv6 */ 19133965Sjdp void *if_unused[2]; 19233965Sjdp void *if_afdata[AF_MAX]; 193218822Sdim int if_afdata_initialized; 19433965Sjdp struct rwlock if_afdata_lock; 19533965Sjdp struct task if_linktask; /* task for link change events */ 19633965Sjdp struct rwlock if_addr_lock; /* lock to protect address lists */ 19760484Sobrien 19860484Sobrien LIST_ENTRY(ifnet) if_clones; /* interfaces of a cloner */ 19933965Sjdp TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ 20033965Sjdp /* protected by if_addr_lock */ 20133965Sjdp void *if_pf_kif; 20233965Sjdp void *if_lagg; /* lagg glue */ 20333965Sjdp char *if_description; /* interface description */ 204218822Sdim u_int if_fib; /* interface FIB */ 20533965Sjdp u_char if_alloctype; /* if_type at time of allocation */ 20633965Sjdp 20733965Sjdp u_int if_hw_tsomax; /* tso burst length limit, the minimum 20860484Sobrien * is (IP_MAXPACKET / 8). 20960484Sobrien * XXXAO: Have to find a better place 21033965Sjdp * for it eventually. */ 21133965Sjdp 21233965Sjdp /* 21333965Sjdp * Spare fields are added so that we can modify sensitive data 21433965Sjdp * structures without changing the kernel binary interface, and must 215218822Sdim * be used with care where binary compatibility is required. 21633965Sjdp */ 21760484Sobrien char if_cspare[3]; 21833965Sjdp int if_ispare[4]; 21933965Sjdp void *if_pspare[8]; /* 1 netmap, 7 TDB */ 22033965Sjdp}; 221218822Sdim 22233965Sjdptypedef void if_init_f_t(void *); 22360484Sobrien 22433965Sjdp/* 22533965Sjdp * XXX These aliases are terribly dangerous because they could apply 22633965Sjdp * to anything. 22733965Sjdp */ 228218822Sdim#define if_mtu if_data.ifi_mtu 22933965Sjdp#define if_type if_data.ifi_type 23060484Sobrien#define if_physical if_data.ifi_physical 23133965Sjdp#define if_addrlen if_data.ifi_addrlen 23233965Sjdp#define if_hdrlen if_data.ifi_hdrlen 23333965Sjdp#define if_metric if_data.ifi_metric 234218822Sdim#define if_link_state if_data.ifi_link_state 23533965Sjdp#define if_baudrate if_data.ifi_baudrate 23660484Sobrien#define if_baudrate_pf if_data.ifi_baudrate_pf 23733965Sjdp#define if_hwassist if_data.ifi_hwassist 23833965Sjdp#define if_ipackets if_data.ifi_ipackets 23933965Sjdp#define if_ierrors if_data.ifi_ierrors 24077298Sobrien#define if_opackets if_data.ifi_opackets 24133965Sjdp#define if_oerrors if_data.ifi_oerrors 242218822Sdim#define if_collisions if_data.ifi_collisions 243218822Sdim#define if_ibytes if_data.ifi_ibytes 24433965Sjdp#define if_obytes if_data.ifi_obytes 24533965Sjdp#define if_imcasts if_data.ifi_imcasts 24633965Sjdp#define if_omcasts if_data.ifi_omcasts 24733965Sjdp#define if_iqdrops if_data.ifi_iqdrops 24833965Sjdp#define if_noproto if_data.ifi_noproto 249218822Sdim#define if_lastchange if_data.ifi_lastchange 250218822Sdim 25133965Sjdp/* for compatibility with other BSDs */ 25233965Sjdp#define if_addrlist if_addrhead 253218822Sdim#define if_list if_link 254218822Sdim#define if_name(ifp) ((ifp)->if_xname) 255218822Sdim 256218822Sdim/* 25733965Sjdp * Locks for address lists on the network interface. 25877298Sobrien */ 25933965Sjdp#define IF_ADDR_LOCK_INIT(if) rw_init(&(if)->if_addr_lock, "if_addr_lock") 26033965Sjdp#define IF_ADDR_LOCK_DESTROY(if) rw_destroy(&(if)->if_addr_lock) 26133965Sjdp#define IF_ADDR_WLOCK(if) rw_wlock(&(if)->if_addr_lock) 26233965Sjdp#define IF_ADDR_WUNLOCK(if) rw_wunlock(&(if)->if_addr_lock) 263218822Sdim#define IF_ADDR_RLOCK(if) rw_rlock(&(if)->if_addr_lock) 26433965Sjdp#define IF_ADDR_RUNLOCK(if) rw_runlock(&(if)->if_addr_lock) 26533965Sjdp#define IF_ADDR_LOCK_ASSERT(if) rw_assert(&(if)->if_addr_lock, RA_LOCKED) 26633965Sjdp#define IF_ADDR_WLOCK_ASSERT(if) rw_assert(&(if)->if_addr_lock, RA_WLOCKED) 26760484Sobrien 26860484Sobrien/* 26933965Sjdp * Function variations on locking macros intended to be used by loadable 27033965Sjdp * kernel modules in order to divorce them from the internals of address list 27133965Sjdp * locking. 27233965Sjdp */ 27333965Sjdpvoid if_addr_rlock(struct ifnet *ifp); /* if_addrhead */ 27460484Sobrienvoid if_addr_runlock(struct ifnet *ifp); /* if_addrhead */ 27533965Sjdpvoid if_maddr_rlock(struct ifnet *ifp); /* if_multiaddrs */ 27633965Sjdpvoid if_maddr_runlock(struct ifnet *ifp); /* if_multiaddrs */ 27733965Sjdp 27833965Sjdp/* 279218822Sdim * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) 28033965Sjdp * are queues of messages stored on ifqueue structures 281218822Sdim * (defined above). Entries are added to and deleted from these structures 28233965Sjdp * by these macros. 28333965Sjdp */ 28433965Sjdp#define IF_LOCK(ifq) mtx_lock(&(ifq)->ifq_mtx) 285218822Sdim#define IF_UNLOCK(ifq) mtx_unlock(&(ifq)->ifq_mtx) 28633965Sjdp#define IF_LOCK_ASSERT(ifq) mtx_assert(&(ifq)->ifq_mtx, MA_OWNED) 28733965Sjdp#define _IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 28833965Sjdp#define _IF_DROP(ifq) ((ifq)->ifq_drops++) 28933965Sjdp#define _IF_QLEN(ifq) ((ifq)->ifq_len) 290218822Sdim 29133965Sjdp#define _IF_ENQUEUE(ifq, m) do { \ 29233965Sjdp (m)->m_nextpkt = NULL; \ 293218822Sdim if ((ifq)->ifq_tail == NULL) \ 29433965Sjdp (ifq)->ifq_head = m; \ 295218822Sdim else \ 296218822Sdim (ifq)->ifq_tail->m_nextpkt = m; \ 29733965Sjdp (ifq)->ifq_tail = m; \ 29833965Sjdp (ifq)->ifq_len++; \ 29933965Sjdp} while (0) 30033965Sjdp 30133965Sjdp#define IF_ENQUEUE(ifq, m) do { \ 30233965Sjdp IF_LOCK(ifq); \ 30333965Sjdp _IF_ENQUEUE(ifq, m); \ 30433965Sjdp IF_UNLOCK(ifq); \ 30533965Sjdp} while (0) 30633965Sjdp 30733965Sjdp#define _IF_PREPEND(ifq, m) do { \ 30833965Sjdp (m)->m_nextpkt = (ifq)->ifq_head; \ 30933965Sjdp if ((ifq)->ifq_tail == NULL) \ 31033965Sjdp (ifq)->ifq_tail = (m); \ 31133965Sjdp (ifq)->ifq_head = (m); \ 31233965Sjdp (ifq)->ifq_len++; \ 313218822Sdim} while (0) 31433965Sjdp 31560484Sobrien#define IF_PREPEND(ifq, m) do { \ 316218822Sdim IF_LOCK(ifq); \ 31777298Sobrien _IF_PREPEND(ifq, m); \ 31860484Sobrien IF_UNLOCK(ifq); \ 31960484Sobrien} while (0) 32033965Sjdp 32133965Sjdp#define _IF_DEQUEUE(ifq, m) do { \ 32233965Sjdp (m) = (ifq)->ifq_head; \ 32333965Sjdp if (m) { \ 32433965Sjdp if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \ 32533965Sjdp (ifq)->ifq_tail = NULL; \ 32633965Sjdp (m)->m_nextpkt = NULL; \ 32777298Sobrien (ifq)->ifq_len--; \ 32860484Sobrien } \ 32933965Sjdp} while (0) 33033965Sjdp 33133965Sjdp#define IF_DEQUEUE(ifq, m) do { \ 332218822Sdim IF_LOCK(ifq); \ 333218822Sdim _IF_DEQUEUE(ifq, m); \ 334218822Sdim IF_UNLOCK(ifq); \ 335218822Sdim} while (0) 336218822Sdim 337218822Sdim#define _IF_DEQUEUE_ALL(ifq, m) do { \ 338218822Sdim (m) = (ifq)->ifq_head; \ 339218822Sdim (ifq)->ifq_head = (ifq)->ifq_tail = NULL; \ 340218822Sdim (ifq)->ifq_len = 0; \ 341218822Sdim} while (0) 342218822Sdim 343218822Sdim#define IF_DEQUEUE_ALL(ifq, m) do { \ 34433965Sjdp IF_LOCK(ifq); \ 345218822Sdim _IF_DEQUEUE_ALL(ifq, m); \ 34633965Sjdp IF_UNLOCK(ifq); \ 34733965Sjdp} while (0) 34833965Sjdp 349218822Sdim#define _IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) 35033965Sjdp#define IF_POLL(ifq, m) _IF_POLL(ifq, m) 35133965Sjdp 35233965Sjdp#define _IF_DRAIN(ifq) do { \ 353218822Sdim struct mbuf *m; \ 35433965Sjdp for (;;) { \ 355218822Sdim _IF_DEQUEUE(ifq, m); \ 356218822Sdim if (m == NULL) \ 35733965Sjdp break; \ 358218822Sdim m_freem(m); \ 35978828Sobrien } \ 36078828Sobrien} while (0) 361218822Sdim 36278828Sobrien#define IF_DRAIN(ifq) do { \ 36377298Sobrien IF_LOCK(ifq); \ 36460484Sobrien _IF_DRAIN(ifq); \ 36560484Sobrien IF_UNLOCK(ifq); \ 36660484Sobrien} while(0) 36760484Sobrien 36860484Sobrien#ifdef _KERNEL 36978828Sobrien/* interface link layer address change event */ 37033965Sjdptypedef void (*iflladdr_event_handler_t)(void *, struct ifnet *); 37133965SjdpEVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t); 37233965Sjdp/* interface address change event */ 37333965Sjdptypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *); 37433965SjdpEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t); 37533965Sjdp/* new interface arrival event */ 37633965Sjdptypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *); 37733965SjdpEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t); 37833965Sjdp/* interface departure event */ 379218822Sdimtypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *); 38033965SjdpEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t); 38133965Sjdp/* Interface link state change event */ 38233965Sjdptypedef void (*ifnet_link_event_handler_t)(void *, struct ifnet *, int); 38360484SobrienEVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t); 38460484Sobrien 38533965Sjdp/* 38633965Sjdp * interface groups 38733965Sjdp */ 38833965Sjdpstruct ifg_group { 38933965Sjdp char ifg_group[IFNAMSIZ]; 39033965Sjdp u_int ifg_refcnt; 39133965Sjdp void *ifg_pf_kif; 392218822Sdim TAILQ_HEAD(, ifg_member) ifg_members; 39333965Sjdp TAILQ_ENTRY(ifg_group) ifg_next; 39433965Sjdp}; 39533965Sjdp 39633965Sjdpstruct ifg_member { 39733965Sjdp TAILQ_ENTRY(ifg_member) ifgm_next; 39860484Sobrien struct ifnet *ifgm_ifp; 39933965Sjdp}; 40033965Sjdp 40133965Sjdpstruct ifg_list { 40233965Sjdp struct ifg_group *ifgl_group; 40333965Sjdp TAILQ_ENTRY(ifg_list) ifgl_next; 40433965Sjdp}; 40589857Sobrien 40689857Sobrien/* group attach event */ 40789857Sobrientypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *); 40833965SjdpEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t); 40989857Sobrien/* group detach event */ 41089857Sobrientypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *); 41133965SjdpEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t); 41233965Sjdp/* group change event */ 41333965Sjdptypedef void (*group_change_event_handler_t)(void *, const char *); 41433965SjdpEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t); 41533965Sjdp 41633965Sjdp#define IF_AFDATA_LOCK_INIT(ifp) \ 41733965Sjdp rw_init(&(ifp)->if_afdata_lock, "if_afdata") 41833965Sjdp 41933965Sjdp#define IF_AFDATA_WLOCK(ifp) rw_wlock(&(ifp)->if_afdata_lock) 42033965Sjdp#define IF_AFDATA_RLOCK(ifp) rw_rlock(&(ifp)->if_afdata_lock) 42133965Sjdp#define IF_AFDATA_WUNLOCK(ifp) rw_wunlock(&(ifp)->if_afdata_lock) 42233965Sjdp#define IF_AFDATA_RUNLOCK(ifp) rw_runlock(&(ifp)->if_afdata_lock) 42333965Sjdp#define IF_AFDATA_LOCK(ifp) IF_AFDATA_WLOCK(ifp) 42433965Sjdp#define IF_AFDATA_UNLOCK(ifp) IF_AFDATA_WUNLOCK(ifp) 42533965Sjdp#define IF_AFDATA_TRYLOCK(ifp) rw_try_wlock(&(ifp)->if_afdata_lock) 42633965Sjdp#define IF_AFDATA_DESTROY(ifp) rw_destroy(&(ifp)->if_afdata_lock) 42733965Sjdp 42860484Sobrien#define IF_AFDATA_LOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_LOCKED) 42960484Sobrien#define IF_AFDATA_RLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_RLOCKED) 43060484Sobrien#define IF_AFDATA_WLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_WLOCKED) 43160484Sobrien#define IF_AFDATA_UNLOCK_ASSERT(ifp) rw_assert(&(ifp)->if_afdata_lock, RA_UNLOCKED) 432218822Sdim 43360484Sobrienint if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, 43460484Sobrien int adjust); 43560484Sobrien#define IF_HANDOFF(ifq, m, ifp) \ 43660484Sobrien if_handoff((struct ifqueue *)ifq, m, ifp, 0) 43760484Sobrien#define IF_HANDOFF_ADJ(ifq, m, ifp, adj) \ 43860484Sobrien if_handoff((struct ifqueue *)ifq, m, ifp, adj) 43960484Sobrien 44060484Sobrienvoid if_start(struct ifnet *); 44160484Sobrien 44260484Sobrien#define IFQ_ENQUEUE(ifq, m, err) \ 44360484Sobriendo { \ 44460484Sobrien IF_LOCK(ifq); \ 44560484Sobrien if (ALTQ_IS_ENABLED(ifq)) \ 44660484Sobrien ALTQ_ENQUEUE(ifq, m, NULL, err); \ 44760484Sobrien else { \ 44860484Sobrien if (_IF_QFULL(ifq)) { \ 44960484Sobrien m_freem(m); \ 45060484Sobrien (err) = ENOBUFS; \ 45160484Sobrien } else { \ 45260484Sobrien _IF_ENQUEUE(ifq, m); \ 45360484Sobrien (err) = 0; \ 45460484Sobrien } \ 45560484Sobrien } \ 45660484Sobrien if (err) \ 45760484Sobrien (ifq)->ifq_drops++; \ 45860484Sobrien IF_UNLOCK(ifq); \ 45960484Sobrien} while (0) 46060484Sobrien 46160484Sobrien#define IFQ_DEQUEUE_NOLOCK(ifq, m) \ 46260484Sobriendo { \ 46360484Sobrien if (TBR_IS_ENABLED(ifq)) \ 46460484Sobrien (m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE); \ 465104834Sobrien else if (ALTQ_IS_ENABLED(ifq)) \ 46660484Sobrien ALTQ_DEQUEUE(ifq, m); \ 46760484Sobrien else \ 46860484Sobrien _IF_DEQUEUE(ifq, m); \ 46960484Sobrien} while (0) 47060484Sobrien 47160484Sobrien#define IFQ_DEQUEUE(ifq, m) \ 47260484Sobriendo { \ 47360484Sobrien IF_LOCK(ifq); \ 47460484Sobrien IFQ_DEQUEUE_NOLOCK(ifq, m); \ 47560484Sobrien IF_UNLOCK(ifq); \ 47660484Sobrien} while (0) 47760484Sobrien 47860484Sobrien#define IFQ_POLL_NOLOCK(ifq, m) \ 479218822Sdimdo { \ 48060484Sobrien if (TBR_IS_ENABLED(ifq)) \ 48160484Sobrien (m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL); \ 48260484Sobrien else if (ALTQ_IS_ENABLED(ifq)) \ 48360484Sobrien ALTQ_POLL(ifq, m); \ 48460484Sobrien else \ 48560484Sobrien _IF_POLL(ifq, m); \ 48660484Sobrien} while (0) 48760484Sobrien 48860484Sobrien#define IFQ_POLL(ifq, m) \ 48960484Sobriendo { \ 49060484Sobrien IF_LOCK(ifq); \ 49160484Sobrien IFQ_POLL_NOLOCK(ifq, m); \ 49260484Sobrien IF_UNLOCK(ifq); \ 49360484Sobrien} while (0) 49460484Sobrien 49560484Sobrien#define IFQ_PURGE_NOLOCK(ifq) \ 49660484Sobriendo { \ 49760484Sobrien if (ALTQ_IS_ENABLED(ifq)) { \ 49860484Sobrien ALTQ_PURGE(ifq); \ 49960484Sobrien } else \ 50060484Sobrien _IF_DRAIN(ifq); \ 50160484Sobrien} while (0) 50260484Sobrien 50360484Sobrien#define IFQ_PURGE(ifq) \ 504218822Sdimdo { \ 50533965Sjdp IF_LOCK(ifq); \ 506218822Sdim IFQ_PURGE_NOLOCK(ifq); \ 507218822Sdim IF_UNLOCK(ifq); \ 508218822Sdim} while (0) 509218822Sdim 510218822Sdim#define IFQ_SET_READY(ifq) \ 511218822Sdim do { ((ifq)->altq_flags |= ALTQF_READY); } while (0) 512218822Sdim 51333965Sjdp#define IFQ_LOCK(ifq) IF_LOCK(ifq) 51433965Sjdp#define IFQ_UNLOCK(ifq) IF_UNLOCK(ifq) 515218822Sdim#define IFQ_LOCK_ASSERT(ifq) IF_LOCK_ASSERT(ifq) 516218822Sdim#define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) 51733965Sjdp#define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) 51833965Sjdp#define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) 519218822Sdim#define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) 52033965Sjdp#define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) 521218822Sdim 522218822Sdim/* 523218822Sdim * The IFF_DRV_OACTIVE test should really occur in the device driver, not in 52433965Sjdp * the handoff logic, as that flag is locked by the device driver. 52533965Sjdp */ 52633965Sjdp#define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ 52733965Sjdpdo { \ 52860484Sobrien int len; \ 52933965Sjdp short mflags; \ 53033965Sjdp \ 531218822Sdim len = (m)->m_pkthdr.len; \ 53233965Sjdp mflags = (m)->m_flags; \ 53333965Sjdp IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \ 53433965Sjdp if ((err) == 0) { \ 53533965Sjdp (ifp)->if_obytes += len + (adj); \ 53633965Sjdp if (mflags & M_MCAST) \ 53733965Sjdp (ifp)->if_omcasts++; \ 53833965Sjdp if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0) \ 53933965Sjdp if_start(ifp); \ 54033965Sjdp } \ 54133965Sjdp} while (0) 54233965Sjdp 54333965Sjdp#define IFQ_HANDOFF(ifp, m, err) \ 544218822Sdim IFQ_HANDOFF_ADJ(ifp, m, 0, err) 54533965Sjdp 54660484Sobrien#define IFQ_DRV_DEQUEUE(ifq, m) \ 54733965Sjdpdo { \ 54833965Sjdp (m) = (ifq)->ifq_drv_head; \ 54933965Sjdp if (m) { \ 55033965Sjdp if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL) \ 55133965Sjdp (ifq)->ifq_drv_tail = NULL; \ 55233965Sjdp (m)->m_nextpkt = NULL; \ 55333965Sjdp (ifq)->ifq_drv_len--; \ 55433965Sjdp } else { \ 55533965Sjdp IFQ_LOCK(ifq); \ 55633965Sjdp IFQ_DEQUEUE_NOLOCK(ifq, m); \ 55733965Sjdp while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) { \ 55833965Sjdp struct mbuf *m0; \ 55933965Sjdp IFQ_DEQUEUE_NOLOCK(ifq, m0); \ 560218822Sdim if (m0 == NULL) \ 56133965Sjdp break; \ 56277298Sobrien m0->m_nextpkt = NULL; \ 56360484Sobrien if ((ifq)->ifq_drv_tail == NULL) \ 56433965Sjdp (ifq)->ifq_drv_head = m0; \ 56533965Sjdp else \ 56633965Sjdp (ifq)->ifq_drv_tail->m_nextpkt = m0; \ 56760484Sobrien (ifq)->ifq_drv_tail = m0; \ 56833965Sjdp (ifq)->ifq_drv_len++; \ 56933965Sjdp } \ 570218822Sdim IFQ_UNLOCK(ifq); \ 57133965Sjdp } \ 57277298Sobrien} while (0) 57333965Sjdp 57433965Sjdp#define IFQ_DRV_PREPEND(ifq, m) \ 57533965Sjdpdo { \ 57633965Sjdp (m)->m_nextpkt = (ifq)->ifq_drv_head; \ 57733965Sjdp if ((ifq)->ifq_drv_tail == NULL) \ 57833965Sjdp (ifq)->ifq_drv_tail = (m); \ 579218822Sdim (ifq)->ifq_drv_head = (m); \ 58033965Sjdp (ifq)->ifq_drv_len++; \ 58133965Sjdp} while (0) 58233965Sjdp 58333965Sjdp#define IFQ_DRV_IS_EMPTY(ifq) \ 58433965Sjdp (((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0)) 58533965Sjdp 58633965Sjdp#define IFQ_DRV_PURGE(ifq) \ 58777298Sobriendo { \ 588218822Sdim struct mbuf *m, *n = (ifq)->ifq_drv_head; \ 58933965Sjdp while((m = n) != NULL) { \ 590218822Sdim n = m->m_nextpkt; \ 591218822Sdim m_freem(m); \ 59233965Sjdp } \ 59333965Sjdp (ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL; \ 594104834Sobrien (ifq)->ifq_drv_len = 0; \ 595218822Sdim IFQ_PURGE(ifq); \ 59633965Sjdp} while (0) 59733965Sjdp 59860484Sobrien#ifdef _KERNEL 59960484Sobrienstatic __inline void 600104834Sobrienif_initbaudrate(struct ifnet *ifp, uintmax_t baud) 60160484Sobrien{ 60260484Sobrien 60377298Sobrien ifp->if_baudrate_pf = 0; 60460484Sobrien while (baud > (u_long)(~0UL)) { 60560484Sobrien baud /= 10; 60660484Sobrien ifp->if_baudrate_pf++; 60760484Sobrien } 60860484Sobrien ifp->if_baudrate = baud; 60960484Sobrien} 61060484Sobrien 61160484Sobrienstatic __inline int 61277298Sobriendrbr_enqueue(struct ifnet *ifp, struct buf_ring *br, struct mbuf *m) 61360484Sobrien{ 61460484Sobrien int error = 0; 61560484Sobrien 61660484Sobrien#ifdef ALTQ 61777298Sobrien if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 61860484Sobrien IFQ_ENQUEUE(&ifp->if_snd, m, error); 61960484Sobrien return (error); 62060484Sobrien } 62160484Sobrien#endif 62260484Sobrien error = buf_ring_enqueue(br, m); 62333965Sjdp if (error) 62433965Sjdp m_freem(m); 62533965Sjdp 62633965Sjdp return (error); 62733965Sjdp} 62833965Sjdp 62933965Sjdpstatic __inline void 63033965Sjdpdrbr_putback(struct ifnet *ifp, struct buf_ring *br, struct mbuf *new) 63133965Sjdp{ 63233965Sjdp /* 63333965Sjdp * The top of the list needs to be swapped 63433965Sjdp * for this one. 63577298Sobrien */ 63677298Sobrien#ifdef ALTQ 63777298Sobrien if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { 63877298Sobrien /* 63977298Sobrien * Peek in altq case dequeued it 64077298Sobrien * so put it back. 64177298Sobrien */ 64277298Sobrien IFQ_DRV_PREPEND(&ifp->if_snd, new); 64377298Sobrien return; 64477298Sobrien } 64577298Sobrien#endif 64677298Sobrien buf_ring_putback_sc(br, new); 64777298Sobrien} 64877298Sobrien 64977298Sobrienstatic __inline struct mbuf * 65077298Sobriendrbr_peek(struct ifnet *ifp, struct buf_ring *br) 65177298Sobrien{ 65277298Sobrien#ifdef ALTQ 65377298Sobrien struct mbuf *m; 65477298Sobrien if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { 65577298Sobrien /* 65677298Sobrien * Pull it off like a dequeue 65777298Sobrien * since drbr_advance() does nothing 65877298Sobrien * for altq and drbr_putback() will 65977298Sobrien * use the old prepend function. 66077298Sobrien */ 66177298Sobrien IFQ_DEQUEUE(&ifp->if_snd, m); 66277298Sobrien return (m); 66377298Sobrien } 66477298Sobrien#endif 66577298Sobrien return(buf_ring_peek(br)); 66633965Sjdp} 66733965Sjdp 66833965Sjdpstatic __inline void 66933965Sjdpdrbr_flush(struct ifnet *ifp, struct buf_ring *br) 67077298Sobrien{ 67133965Sjdp struct mbuf *m; 67233965Sjdp 67333965Sjdp#ifdef ALTQ 67433965Sjdp if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) 67533965Sjdp IFQ_PURGE(&ifp->if_snd); 67633965Sjdp#endif 67777298Sobrien while ((m = buf_ring_dequeue_sc(br)) != NULL) 67833965Sjdp m_freem(m); 67933965Sjdp} 68060484Sobrien 68160484Sobrienstatic __inline void 68260484Sobriendrbr_free(struct buf_ring *br, struct malloc_type *type) 68360484Sobrien{ 68433965Sjdp 68533965Sjdp drbr_flush(NULL, br); 686218822Sdim buf_ring_free(br, type); 68733965Sjdp} 68833965Sjdp 68960484Sobrienstatic __inline struct mbuf * 69033965Sjdpdrbr_dequeue(struct ifnet *ifp, struct buf_ring *br) 69133965Sjdp{ 69233965Sjdp#ifdef ALTQ 69360484Sobrien struct mbuf *m; 69433965Sjdp 69533965Sjdp if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) { 696218822Sdim IFQ_DEQUEUE(&ifp->if_snd, m); 69733965Sjdp return (m); 69833965Sjdp } 69933965Sjdp#endif 70060484Sobrien return (buf_ring_dequeue_sc(br)); 70160484Sobrien} 70260484Sobrien 70360484Sobrienstatic __inline void 70433965Sjdpdrbr_advance(struct ifnet *ifp, struct buf_ring *br) 70533965Sjdp{ 70633965Sjdp#ifdef ALTQ 70733965Sjdp /* Nothing to do here since peek dequeues in altq case */ 70833965Sjdp if (ifp != NULL && ALTQ_IS_ENABLED(&ifp->if_snd)) 70933965Sjdp return; 71033965Sjdp#endif 71177298Sobrien return (buf_ring_advance_sc(br)); 71233965Sjdp} 71333965Sjdp 71433965Sjdp 71577298Sobrienstatic __inline struct mbuf * 71633965Sjdpdrbr_dequeue_cond(struct ifnet *ifp, struct buf_ring *br, 71733965Sjdp int (*func) (struct mbuf *, void *), void *arg) 71860484Sobrien{ 719218822Sdim struct mbuf *m; 720218822Sdim#ifdef ALTQ 721218822Sdim if (ALTQ_IS_ENABLED(&ifp->if_snd)) { 72233965Sjdp IFQ_LOCK(&ifp->if_snd); 72333965Sjdp IFQ_POLL_NOLOCK(&ifp->if_snd, m); 72460484Sobrien if (m != NULL && func(m, arg) == 0) { 725218822Sdim IFQ_UNLOCK(&ifp->if_snd); 72660484Sobrien return (NULL); 72733965Sjdp } 72860484Sobrien IFQ_DEQUEUE_NOLOCK(&ifp->if_snd, m); 72933965Sjdp IFQ_UNLOCK(&ifp->if_snd); 730104834Sobrien return (m); 73160484Sobrien } 73260484Sobrien#endif 73360484Sobrien m = buf_ring_peek(br); 734104834Sobrien if (m == NULL || func(m, arg) == 0) 73533965Sjdp return (NULL); 73633965Sjdp 73733965Sjdp return (buf_ring_dequeue_sc(br)); 73833965Sjdp} 73933965Sjdp 74033965Sjdpstatic __inline int 74133965Sjdpdrbr_empty(struct ifnet *ifp, struct buf_ring *br) 742218822Sdim{ 74333965Sjdp#ifdef ALTQ 74433965Sjdp if (ALTQ_IS_ENABLED(&ifp->if_snd)) 74577298Sobrien return (IFQ_IS_EMPTY(&ifp->if_snd)); 74633965Sjdp#endif 74733965Sjdp return (buf_ring_empty(br)); 74833965Sjdp} 74933965Sjdp 75033965Sjdpstatic __inline int 75133965Sjdpdrbr_needs_enqueue(struct ifnet *ifp, struct buf_ring *br) 75233965Sjdp{ 75333965Sjdp#ifdef ALTQ 75433965Sjdp if (ALTQ_IS_ENABLED(&ifp->if_snd)) 75533965Sjdp return (1); 75633965Sjdp#endif 75733965Sjdp return (!buf_ring_empty(br)); 75877298Sobrien} 759218822Sdim 76033965Sjdpstatic __inline int 76133965Sjdpdrbr_inuse(struct ifnet *ifp, struct buf_ring *br) 76233965Sjdp{ 76333965Sjdp#ifdef ALTQ 76433965Sjdp if (ALTQ_IS_ENABLED(&ifp->if_snd)) 76533965Sjdp return (ifp->if_snd.ifq_len); 76633965Sjdp#endif 76733965Sjdp return (buf_ring_count(br)); 76833965Sjdp} 76933965Sjdp#endif 77033965Sjdp/* 77133965Sjdp * 72 was chosen below because it is the size of a TCP/IP 772218822Sdim * header (40) + the minimum mss (32). 77333965Sjdp */ 77433965Sjdp#define IF_MINMTU 72 77533965Sjdp#define IF_MAXMTU 65535 77633965Sjdp 77733965Sjdp#define TOEDEV(ifp) ((ifp)->if_llsoftc) 77833965Sjdp 77933965Sjdp#endif /* _KERNEL */ 78033965Sjdp 78133965Sjdp/* 78233965Sjdp * The ifaddr structure contains information about one address 78333965Sjdp * of an interface. They are maintained by the different address families, 78433965Sjdp * are allocated and attached when an address is set, and are linked 785218822Sdim * together so all addresses for an interface can be located. 786218822Sdim * 787218822Sdim * NOTE: a 'struct ifaddr' is always at the beginning of a larger 78833965Sjdp * chunk of malloc'ed memory, where we store the three addresses 789218822Sdim * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here. 790218822Sdim */ 79133965Sjdp#if defined(_KERNEL) || defined(_WANT_IFADDR) 79233965Sjdpstruct ifaddr { 79333965Sjdp struct sockaddr *ifa_addr; /* address of interface */ 79433965Sjdp struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ 79533965Sjdp#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 796218822Sdim struct sockaddr *ifa_netmask; /* used to determine subnet */ 79733965Sjdp struct if_data if_data; /* not all members are meaningful */ 79833965Sjdp struct ifnet *ifa_ifp; /* back-pointer to interface */ 79933965Sjdp struct carp_softc *ifa_carp; /* pointer to CARP data */ 80033965Sjdp TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ 80133965Sjdp void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ 80260484Sobrien (int, struct rtentry *, struct rt_addrinfo *); 80333965Sjdp u_short ifa_flags; /* mostly rt_flags for cloning */ 80433965Sjdp u_int ifa_refcnt; /* references to this structure */ 805218822Sdim int ifa_metric; /* cost of going out this interface */ 80633965Sjdp int (*ifa_claim_addr) /* check if an addr goes to this if */ 80733965Sjdp (struct ifaddr *, struct sockaddr *); 80833965Sjdp}; 80933965Sjdp#endif 81033965Sjdp 81133965Sjdp#define IFA_ROUTE RTF_UP /* route installed */ 81233965Sjdp#define IFA_RTSELF RTF_HOST /* loopback route to self installed */ 81333965Sjdp 81433965Sjdp/* for compatibility with other BSDs */ 81533965Sjdp#define ifa_list ifa_link 81633965Sjdp 81733965Sjdp#ifdef _KERNEL 81833965Sjdpstruct ifaddr * ifa_alloc(size_t size, int flags); 81933965Sjdpvoid ifa_free(struct ifaddr *ifa); 82033965Sjdpvoid ifa_ref(struct ifaddr *ifa); 82133965Sjdp#endif 82260484Sobrien 823218822Sdim/* 82433965Sjdp * Multicast address structure. This is analogous to the ifaddr 82533965Sjdp * structure except that it keeps track of multicast addresses. 82633965Sjdp */ 82733965Sjdpstruct ifmultiaddr { 82833965Sjdp TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ 82933965Sjdp struct sockaddr *ifma_addr; /* address this membership is for */ 83033965Sjdp struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ 83133965Sjdp struct ifnet *ifma_ifp; /* back-pointer to interface */ 83233965Sjdp u_int ifma_refcount; /* reference count */ 83333965Sjdp void *ifma_protospec; /* protocol-specific state, if any */ 83433965Sjdp struct ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */ 835218822Sdim}; 83633965Sjdp 83733965Sjdp#ifdef _KERNEL 83833965Sjdp 83933965Sjdpextern struct rwlock ifnet_rwlock; 84033965Sjdpextern struct sx ifnet_sxlock; 84133965Sjdp 84233965Sjdp#define IFNET_LOCK_INIT() do { \ 84333965Sjdp rw_init_flags(&ifnet_rwlock, "ifnet_rw", RW_RECURSE); \ 84433965Sjdp sx_init_flags(&ifnet_sxlock, "ifnet_sx", SX_RECURSE); \ 84533965Sjdp} while(0) 84633965Sjdp 847218822Sdim#define IFNET_WLOCK() do { \ 84833965Sjdp sx_xlock(&ifnet_sxlock); \ 84933965Sjdp rw_wlock(&ifnet_rwlock); \ 85033965Sjdp} while (0) 85160484Sobrien 85233965Sjdp#define IFNET_WUNLOCK() do { \ 85333965Sjdp rw_wunlock(&ifnet_rwlock); \ 85433965Sjdp sx_xunlock(&ifnet_sxlock); \ 85533965Sjdp} while (0) 856218822Sdim 85733965Sjdp/* 85833965Sjdp * To assert the ifnet lock, you must know not only whether it's for read or 85933965Sjdp * write, but also whether it was acquired with sleep support or not. 86033965Sjdp */ 86160484Sobrien#define IFNET_RLOCK_ASSERT() sx_assert(&ifnet_sxlock, SA_SLOCKED) 86233965Sjdp#define IFNET_RLOCK_NOSLEEP_ASSERT() rw_assert(&ifnet_rwlock, RA_RLOCKED) 86333965Sjdp#define IFNET_WLOCK_ASSERT() do { \ 86433965Sjdp sx_assert(&ifnet_sxlock, SA_XLOCKED); \ 86533965Sjdp rw_assert(&ifnet_rwlock, RA_WLOCKED); \ 86633965Sjdp} while (0) 867218822Sdim 86833965Sjdp#define IFNET_RLOCK() sx_slock(&ifnet_sxlock) 86933965Sjdp#define IFNET_RLOCK_NOSLEEP() rw_rlock(&ifnet_rwlock) 87033965Sjdp#define IFNET_RUNLOCK() sx_sunlock(&ifnet_sxlock) 87160484Sobrien#define IFNET_RUNLOCK_NOSLEEP() rw_runlock(&ifnet_rwlock) 87233965Sjdp 87333965Sjdp/* 874218822Sdim * Look up an ifnet given its index; the _ref variant also acquires a 87533965Sjdp * reference that must be freed using if_rele(). It is almost always a bug 87633965Sjdp * to call ifnet_byindex() instead if ifnet_byindex_ref(). 87733965Sjdp */ 87833965Sjdpstruct ifnet *ifnet_byindex(u_short idx); 87933965Sjdpstruct ifnet *ifnet_byindex_locked(u_short idx); 88033965Sjdpstruct ifnet *ifnet_byindex_ref(u_short idx); 88133965Sjdp 882218822Sdim/* 88333965Sjdp * Given the index, ifaddr_byindex() returns the one and only 88433965Sjdp * link-level ifaddr for the interface. You are not supposed to use 88533965Sjdp * it to traverse the list of addresses associated to the interface. 88660484Sobrien */ 88733965Sjdpstruct ifaddr *ifaddr_byindex(u_short idx); 88833965Sjdp 889218822SdimVNET_DECLARE(struct ifnethead, ifnet); 89033965SjdpVNET_DECLARE(struct ifgrouphead, ifg_head); 89133965SjdpVNET_DECLARE(int, if_index); 89233965SjdpVNET_DECLARE(struct ifnet *, loif); /* first loopback interface */ 89333965SjdpVNET_DECLARE(int, useloopback); 89433965Sjdp 89533965Sjdp#define V_ifnet VNET(ifnet) 896218822Sdim#define V_ifg_head VNET(ifg_head) 89733965Sjdp#define V_if_index VNET(if_index) 89833965Sjdp#define V_loif VNET(loif) 89933965Sjdp#define V_useloopback VNET(useloopback) 90033965Sjdp 90133965Sjdpextern int ifqmaxlen; 90233965Sjdp 90360484Sobrienint if_addgroup(struct ifnet *, const char *); 90433965Sjdpint if_delgroup(struct ifnet *, const char *); 90533965Sjdpint if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); 90633965Sjdpint if_allmulti(struct ifnet *, int); 90733965Sjdpstruct ifnet* if_alloc(u_char); 90833965Sjdpvoid if_attach(struct ifnet *); 90933965Sjdpvoid if_dead(struct ifnet *); 91033965Sjdpint if_delmulti(struct ifnet *, struct sockaddr *); 91133965Sjdpvoid if_delmulti_ifma(struct ifmultiaddr *); 91233965Sjdpvoid if_detach(struct ifnet *); 91333965Sjdpvoid if_vmove(struct ifnet *, struct vnet *); 91433965Sjdpvoid if_purgeaddrs(struct ifnet *); 91533965Sjdpvoid if_delallmulti(struct ifnet *); 91633965Sjdpvoid if_down(struct ifnet *); 91777298Sobrienstruct ifmultiaddr * 91833965Sjdp if_findmulti(struct ifnet *, struct sockaddr *); 91933965Sjdpvoid if_free(struct ifnet *); 92033965Sjdpvoid if_initname(struct ifnet *, const char *, int); 921218822Sdimvoid if_link_state_change(struct ifnet *, int); 92233965Sjdpint if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); 92333965Sjdpvoid if_qflush(struct ifnet *); 92433965Sjdpvoid if_ref(struct ifnet *); 92533965Sjdpvoid if_rele(struct ifnet *); 92633965Sjdpint if_setlladdr(struct ifnet *, const u_char *, int); 92733965Sjdpvoid if_up(struct ifnet *); 92833965Sjdpint ifioctl(struct socket *, u_long, caddr_t, struct thread *); 92933965Sjdpint ifpromisc(struct ifnet *, int); 930218822Sdimstruct ifnet *ifunit(const char *); 93133965Sjdpstruct ifnet *ifunit_ref(const char *); 93233965Sjdp 93333965Sjdpvoid ifq_init(struct ifaltq *, struct ifnet *ifp); 93460484Sobrienvoid ifq_delete(struct ifaltq *); 93533965Sjdp 93633965Sjdpint ifa_add_loopback_route(struct ifaddr *, struct sockaddr *); 937218822Sdimint ifa_del_loopback_route(struct ifaddr *, struct sockaddr *); 93833965Sjdp 93933965Sjdpstruct ifaddr *ifa_ifwithaddr(struct sockaddr *); 94033965Sjdpint ifa_ifwithaddr_check(struct sockaddr *); 94133965Sjdpstruct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *); 94233965Sjdpstruct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); 943218822Sdimstruct ifaddr *ifa_ifwithnet(struct sockaddr *, int); 94433965Sjdpstruct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); 94533965Sjdpstruct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int); 94633965Sjdpstruct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); 94733965Sjdpint ifa_preferred(struct ifaddr *, struct ifaddr *); 94833965Sjdp 949218822Sdimint if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); 95033965Sjdp 95133965Sjdptypedef void *if_com_alloc_t(u_char type, struct ifnet *ifp); 95233965Sjdptypedef void if_com_free_t(void *com, u_char type); 95360484Sobrienvoid if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f); 95433965Sjdpvoid if_deregister_com_alloc(u_char type); 95533965Sjdp 956218822Sdim#define IF_LLADDR(ifp) \ 95733965Sjdp LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr)) 95833965Sjdp 95933965Sjdp#ifdef DEVICE_POLLING 96033965Sjdpenum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS }; 96133965Sjdp 96233965Sjdptypedef int poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); 96333965Sjdpint ether_poll_register(poll_handler_t *h, struct ifnet *ifp); 96433965Sjdpint ether_poll_deregister(struct ifnet *ifp); 96533965Sjdp#endif /* DEVICE_POLLING */ 966218822Sdim 96733965Sjdp#endif /* _KERNEL */ 968218822Sdim 96960484Sobrien#endif /* !_NET_IF_VAR_H_ */ 97033965Sjdp