ifq.h revision 186048
190075Sobrien/*- 290075Sobrien * Copyright (c) 1982, 1986, 1989, 1993 3169689Skan * The Regents of the University of California. All rights reserved. 4169689Skan * 590075Sobrien * Redistribution and use in source and binary forms, with or without 690075Sobrien * modification, are permitted provided that the following conditions 790075Sobrien * 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 1290075Sobrien * 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 * 1790075Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1890075Sobrien * 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 2290075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2390075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24132718Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2590075Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2690075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2790075Sobrien * SUCH DAMAGE. 2890075Sobrien * 2990075Sobrien * From: @(#)if.h 8.1 (Berkeley) 6/10/93 3090075Sobrien * $FreeBSD: head/sys/net/if_var.h 186048 2008-12-13 19:13:03Z bz $ 3190075Sobrien */ 3290075Sobrien 3390075Sobrien#ifndef _NET_IF_VAR_H_ 3490075Sobrien#define _NET_IF_VAR_H_ 3590075Sobrien 3690075Sobrien/* 3790075Sobrien * Structures defining a network interface, providing a packet 3890075Sobrien * transport mechanism (ala level 0 of the PUP protocols). 3990075Sobrien * 4090075Sobrien * Each interface accepts output datagrams of a specified maximum 4190075Sobrien * length, and provides higher level routines with input datagrams 42117395Skan * received from its medium. 43132718Skan * 44132718Skan * Output occurs when the routine if_output is called, with three parameters: 45132718Skan * (*ifp->if_output)(ifp, m, dst, rt) 46132718Skan * Here m is the mbuf chain to be sent and dst is the destination address. 4790075Sobrien * The output routine encapsulates the supplied datagram if necessary, 4890075Sobrien * and then transmits it on its medium. 4990075Sobrien * 5090075Sobrien * On input, each interface unwraps the data received by it, and either 51132718Skan * places it on the input queue of an internetwork datagram routine 52132718Skan * and posts the associated software interrupt, or passes the datagram to a raw 5390075Sobrien * packet input routine. 5490075Sobrien * 5590075Sobrien * Routines exist for locating interfaces by their addresses 5690075Sobrien * or for locating an interface on a certain network, as well as more general 5790075Sobrien * routing and gateway routines maintaining information used to locate 5890075Sobrien * interfaces. These routines live in the files if.c and route.c 5990075Sobrien */ 6090075Sobrien 6190075Sobrien#ifdef __STDC__ 6290075Sobrien/* 6390075Sobrien * Forward structure declarations for function prototypes [sic]. 64169689Skan */ 65169689Skanstruct mbuf; 66169689Skanstruct thread; 67169689Skanstruct rtentry; 68132718Skanstruct rt_addrinfo; 6990075Sobrienstruct socket; 7090075Sobrienstruct ether_header; 7190075Sobrienstruct carp_if; 72169689Skanstruct ifvlantrunk; 7390075Sobrien#endif 74132718Skan 75132718Skan#include <sys/queue.h> /* get TAILQ macros */ 7690075Sobrien 77169689Skan#ifdef _KERNEL 78169689Skan#include <sys/mbuf.h> 7990075Sobrien#include <sys/eventhandler.h> 8090075Sobrien#endif /* _KERNEL */ 8190075Sobrien#include <sys/lock.h> /* XXX */ 82132718Skan#include <sys/mutex.h> /* XXX */ 8390075Sobrien#include <sys/event.h> /* XXX */ 84169689Skan#include <sys/_task.h> 85169689Skan 8690075Sobrien#define IF_DUNIT_NONE -1 87169689Skan 88169689Skan#include <altq/if_altq.h> 89169689Skan 90169689SkanTAILQ_HEAD(ifnethead, ifnet); /* we use TAILQs so that the order of */ 91169689SkanTAILQ_HEAD(ifaddrhead, ifaddr); /* instantiation is preserved in the list */ 92169689SkanTAILQ_HEAD(ifprefixhead, ifprefix); 9390075SobrienTAILQ_HEAD(ifmultihead, ifmultiaddr); 9490075SobrienTAILQ_HEAD(ifgrouphead, ifg_group); 9590075Sobrien 9690075Sobrien/* 9790075Sobrien * Structure defining a queue for a network interface. 9890075Sobrien */ 99169689Skanstruct ifqueue { 10090075Sobrien struct mbuf *ifq_head; 10190075Sobrien struct mbuf *ifq_tail; 102169689Skan int ifq_len; 10390075Sobrien int ifq_maxlen; 10490075Sobrien int ifq_drops; 10590075Sobrien struct mtx ifq_mtx; 10690075Sobrien}; 10790075Sobrien 108132718Skan/* 10990075Sobrien * Structure defining a network interface. 110117395Skan * 11190075Sobrien * (Would like to call this struct ``if'', but C isn't PL/1.) 112169689Skan */ 11390075Sobrien 114117395Skanstruct ifnet { 11590075Sobrien void *if_softc; /* pointer to driver state */ 116169689Skan void *if_l2com; /* pointer to protocol bits */ 117169689Skan TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ 118169689Skan char if_xname[IFNAMSIZ]; /* external name (name + unit) */ 119169689Skan const char *if_dname; /* driver name */ 12090075Sobrien int if_dunit; /* unit or IF_DUNIT_NONE */ 12190075Sobrien struct ifaddrhead if_addrhead; /* linked list of addresses per if */ 122169689Skan /* 123169689Skan * if_addrhead is the list of all addresses associated to 124169689Skan * an interface. 125169689Skan * Some code in the kernel assumes that first element 12690075Sobrien * of the list has type AF_LINK, and contains sockaddr_dl 127169689Skan * addresses which store the link-level address and the name 12890075Sobrien * of the interface. 12990075Sobrien * However, access to the AF_LINK address through this 13090075Sobrien * field is deprecated. Use if_addr or ifaddr_byindex() instead. 13190075Sobrien */ 13290075Sobrien struct knlist if_klist; /* events attached to this if */ 133132718Skan int if_pcount; /* number of promiscuous listeners */ 13490075Sobrien struct carp_if *if_carp; /* carp interface structure */ 13590075Sobrien struct bpf_if *if_bpf; /* packet filter structure */ 136169689Skan u_short if_index; /* numeric abbreviation for this if */ 13790075Sobrien short if_timer; /* time 'til if_watchdog called */ 13890075Sobrien struct ifvlantrunk *if_vlantrunk; /* pointer to 802.1q data */ 13990075Sobrien int if_flags; /* up/down, broadcast, etc. */ 140117395Skan int if_capabilities; /* interface features & capabilities */ 141117395Skan int if_capenable; /* enabled features & capabilities */ 142132718Skan void *if_linkmib; /* link-type-specific MIB data */ 143117395Skan size_t if_linkmiblen; /* length of above data */ 144117395Skan struct if_data if_data; 145117395Skan struct ifmultihead if_multiaddrs; /* multicast addresses configured */ 146117395Skan int if_amcount; /* number of all-multicast requests */ 147117395Skan/* procedure handles */ 148117395Skan int (*if_output) /* output routine (enqueue) */ 14990075Sobrien (struct ifnet *, struct mbuf *, struct sockaddr *, 150117395Skan struct rtentry *); 15190075Sobrien void (*if_input) /* input routine (from h/w driver) */ 152132718Skan (struct ifnet *, struct mbuf *); 15396263Sobrien void (*if_start) /* initiate output routine */ 154117395Skan (struct ifnet *); 155117395Skan int (*if_ioctl) /* ioctl routine */ 156169689Skan (struct ifnet *, u_long, caddr_t); 157169689Skan void (*if_watchdog) /* timer routine */ 158117395Skan (struct ifnet *); 159117395Skan void (*if_init) /* Init routine */ 160117395Skan (void *); 161117395Skan int (*if_resolvemulti) /* validate/resolve multicast */ 162132718Skan (struct ifnet *, struct sockaddr **, struct sockaddr *); 163117395Skan struct ifaddr *if_addr; /* pointer to link-level address */ 164117395Skan void *if_llsoftc; /* link layer softc */ 165117395Skan int if_drv_flags; /* driver-managed status flags */ 166132718Skan u_int if_spare_flags2; /* spare flags 2 */ 167169689Skan struct ifaltq if_snd; /* output queue (includes altq) */ 168169689Skan const u_int8_t *if_broadcastaddr; /* linklevel broadcast bytestring */ 169169689Skan 170169689Skan void *if_bridge; /* bridge glue */ 171169689Skan 172117395Skan struct lltable *lltables; /* list of L3-L2 resolution tables */ 173169689Skan 174117395Skan struct label *if_label; /* interface MAC label */ 175117395Skan 176117395Skan /* these are only used by IPv6 */ 177117395Skan struct ifprefixhead if_prefixhead; /* list of prefixes per if */ 178169689Skan void *if_afdata[AF_MAX]; 179117395Skan int if_afdata_initialized; 180169689Skan struct mtx if_afdata_mtx; 181169689Skan struct task if_starttask; /* task for IFF_NEEDSGIANT */ 182169689Skan struct task if_linktask; /* task for link change events */ 183117395Skan struct mtx if_addr_mtx; /* mutex to protect address lists */ 184117395Skan LIST_ENTRY(ifnet) if_clones; /* interfaces of a cloner */ 185117395Skan TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ 186117395Skan /* protected by if_addr_mtx */ 187117395Skan void *if_pf_kif; 188117395Skan void *if_lagg; /* lagg glue */ 189132718Skan void *if_pspare[8]; /* multiq/TOE 3; vimage 3; general use 4 */ 190117395Skan void (*if_qflush) /* flush any queues */ 191117395Skan (struct ifnet *); 192169689Skan int (*if_transmit) /* initiate output routine */ 193117395Skan (struct ifnet *, struct mbuf *); 194169689Skan int if_ispare[2]; /* general use 2 */ 195169689Skan}; 196169689Skan 197169689Skantypedef void if_init_f_t(void *); 198169689Skan 19996263Sobrien/* 200117395Skan * XXX These aliases are terribly dangerous because they could apply 201169689Skan * to anything. 202169689Skan */ 203169689Skan#define if_mtu if_data.ifi_mtu 204169689Skan#define if_type if_data.ifi_type 205169689Skan#define if_physical if_data.ifi_physical 206169689Skan#define if_addrlen if_data.ifi_addrlen 207169689Skan#define if_hdrlen if_data.ifi_hdrlen 208169689Skan#define if_metric if_data.ifi_metric 209169689Skan#define if_link_state if_data.ifi_link_state 210169689Skan#define if_baudrate if_data.ifi_baudrate 211169689Skan#define if_hwassist if_data.ifi_hwassist 212169689Skan#define if_ipackets if_data.ifi_ipackets 213169689Skan#define if_ierrors if_data.ifi_ierrors 214169689Skan#define if_opackets if_data.ifi_opackets 215169689Skan#define if_oerrors if_data.ifi_oerrors 216169689Skan#define if_collisions if_data.ifi_collisions 217169689Skan#define if_ibytes if_data.ifi_ibytes 218169689Skan#define if_obytes if_data.ifi_obytes 219169689Skan#define if_imcasts if_data.ifi_imcasts 220169689Skan#define if_omcasts if_data.ifi_omcasts 221169689Skan#define if_iqdrops if_data.ifi_iqdrops 222169689Skan#define if_noproto if_data.ifi_noproto 223169689Skan#define if_lastchange if_data.ifi_lastchange 224169689Skan#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)NULL) 225169689Skan 226169689Skan/* for compatibility with other BSDs */ 227169689Skan#define if_addrlist if_addrhead 228169689Skan#define if_list if_link 229169689Skan#define if_name(ifp) ((ifp)->if_xname) 230169689Skan 231169689Skan/* 232169689Skan * Locks for address lists on the network interface. 233169689Skan */ 234169689Skan#define IF_ADDR_LOCK_INIT(if) mtx_init(&(if)->if_addr_mtx, \ 235169689Skan "if_addr_mtx", NULL, MTX_DEF) 236169689Skan#define IF_ADDR_LOCK_DESTROY(if) mtx_destroy(&(if)->if_addr_mtx) 237169689Skan#define IF_ADDR_LOCK(if) mtx_lock(&(if)->if_addr_mtx) 238169689Skan#define IF_ADDR_UNLOCK(if) mtx_unlock(&(if)->if_addr_mtx) 239169689Skan#define IF_ADDR_LOCK_ASSERT(if) mtx_assert(&(if)->if_addr_mtx, MA_OWNED) 240169689Skan 241169689Skan/* 242169689Skan * Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq) 243169689Skan * are queues of messages stored on ifqueue structures 244169689Skan * (defined above). Entries are added to and deleted from these structures 245169689Skan * by these macros, which should be called with ipl raised to splimp(). 246169689Skan */ 247169689Skan#define IF_LOCK(ifq) mtx_lock(&(ifq)->ifq_mtx) 248169689Skan#define IF_UNLOCK(ifq) mtx_unlock(&(ifq)->ifq_mtx) 249169689Skan#define IF_LOCK_ASSERT(ifq) mtx_assert(&(ifq)->ifq_mtx, MA_OWNED) 250169689Skan#define _IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 251169689Skan#define _IF_DROP(ifq) ((ifq)->ifq_drops++) 252169689Skan#define _IF_QLEN(ifq) ((ifq)->ifq_len) 253169689Skan 254169689Skan#define _IF_ENQUEUE(ifq, m) do { \ 255169689Skan (m)->m_nextpkt = NULL; \ 256169689Skan if ((ifq)->ifq_tail == NULL) \ 257169689Skan (ifq)->ifq_head = m; \ 258117395Skan else \ 259117395Skan (ifq)->ifq_tail->m_nextpkt = m; \ 260117395Skan (ifq)->ifq_tail = m; \ 26196263Sobrien (ifq)->ifq_len++; \ 262117395Skan} while (0) 263132718Skan 26490075Sobrien#define IF_ENQUEUE(ifq, m) do { \ 265117395Skan IF_LOCK(ifq); \ 266169689Skan _IF_ENQUEUE(ifq, m); \ 267117395Skan IF_UNLOCK(ifq); \ 26890075Sobrien} while (0) 269117395Skan 270117395Skan#define _IF_PREPEND(ifq, m) do { \ 271117395Skan (m)->m_nextpkt = (ifq)->ifq_head; \ 27296263Sobrien if ((ifq)->ifq_tail == NULL) \ 273169689Skan (ifq)->ifq_tail = (m); \ 274169689Skan (ifq)->ifq_head = (m); \ 275117395Skan (ifq)->ifq_len++; \ 276169689Skan} while (0) 277169689Skan 278117395Skan#define IF_PREPEND(ifq, m) do { \ 27990075Sobrien IF_LOCK(ifq); \ 280132718Skan _IF_PREPEND(ifq, m); \ 28190075Sobrien IF_UNLOCK(ifq); \ 28290075Sobrien} while (0) 28390075Sobrien 28490075Sobrien#define _IF_DEQUEUE(ifq, m) do { \ 285169689Skan (m) = (ifq)->ifq_head; \ 28690075Sobrien if (m) { \ 287169689Skan if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \ 288169689Skan (ifq)->ifq_tail = NULL; \ 289169689Skan (m)->m_nextpkt = NULL; \ 290169689Skan (ifq)->ifq_len--; \ 29190075Sobrien } \ 292169689Skan} while (0) 293169689Skan 294169689Skan#define IF_DEQUEUE(ifq, m) do { \ 295169689Skan IF_LOCK(ifq); \ 296169689Skan _IF_DEQUEUE(ifq, m); \ 297169689Skan IF_UNLOCK(ifq); \ 298169689Skan} while (0) 299169689Skan 30090075Sobrien#define _IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) 301169689Skan#define IF_POLL(ifq, m) _IF_POLL(ifq, m) 302169689Skan 303169689Skan#define _IF_DRAIN(ifq) do { \ 30490075Sobrien struct mbuf *m; \ 305169689Skan for (;;) { \ 306169689Skan _IF_DEQUEUE(ifq, m); \ 30790075Sobrien if (m == NULL) \ 30890075Sobrien break; \ 309169689Skan m_freem(m); \ 31090075Sobrien } \ 31190075Sobrien} while (0) 31290075Sobrien 31390075Sobrien#define IF_DRAIN(ifq) do { \ 31490075Sobrien IF_LOCK(ifq); \ 31590075Sobrien _IF_DRAIN(ifq); \ 316132718Skan IF_UNLOCK(ifq); \ 31790075Sobrien} while(0) 318169689Skan 319169689Skan#ifdef _KERNEL 320169689Skan/* interface address change event */ 321169689Skantypedef void (*ifaddr_event_handler_t)(void *, struct ifnet *); 322169689SkanEVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t); 323169689Skan/* new interface arrival event */ 324169689Skantypedef void (*ifnet_arrival_event_handler_t)(void *, struct ifnet *); 325169689SkanEVENTHANDLER_DECLARE(ifnet_arrival_event, ifnet_arrival_event_handler_t); 326169689Skan/* interface departure event */ 327169689Skantypedef void (*ifnet_departure_event_handler_t)(void *, struct ifnet *); 32890075SobrienEVENTHANDLER_DECLARE(ifnet_departure_event, ifnet_departure_event_handler_t); 32990075Sobrien 33090075Sobrien/* 33190075Sobrien * interface groups 33290075Sobrien */ 33390075Sobrienstruct ifg_group { 334132718Skan char ifg_group[IFNAMSIZ]; 33590075Sobrien u_int ifg_refcnt; 33690075Sobrien void *ifg_pf_kif; 33790075Sobrien TAILQ_HEAD(, ifg_member) ifg_members; 33890075Sobrien TAILQ_ENTRY(ifg_group) ifg_next; 33990075Sobrien}; 34090075Sobrien 34190075Sobrienstruct ifg_member { 34290075Sobrien TAILQ_ENTRY(ifg_member) ifgm_next; 34390075Sobrien struct ifnet *ifgm_ifp; 34490075Sobrien}; 34590075Sobrien 346132718Skanstruct ifg_list { 34790075Sobrien struct ifg_group *ifgl_group; 348169689Skan TAILQ_ENTRY(ifg_list) ifgl_next; 349169689Skan}; 35090075Sobrien 351169689Skan/* group attach event */ 352169689Skantypedef void (*group_attach_event_handler_t)(void *, struct ifg_group *); 35390075SobrienEVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t); 35490075Sobrien/* group detach event */ 35590075Sobrientypedef void (*group_detach_event_handler_t)(void *, struct ifg_group *); 35690075SobrienEVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t); 35790075Sobrien/* group change event */ 35890075Sobrientypedef void (*group_change_event_handler_t)(void *, const char *); 35990075SobrienEVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t); 360132718Skan 36190075Sobrien#define IF_AFDATA_LOCK_INIT(ifp) \ 362169689Skan mtx_init(&(ifp)->if_afdata_mtx, "if_afdata", NULL, MTX_DEF) 36390075Sobrien#define IF_AFDATA_LOCK(ifp) mtx_lock(&(ifp)->if_afdata_mtx) 364169689Skan#define IF_AFDATA_TRYLOCK(ifp) mtx_trylock(&(ifp)->if_afdata_mtx) 36590075Sobrien#define IF_AFDATA_UNLOCK(ifp) mtx_unlock(&(ifp)->if_afdata_mtx) 366169689Skan#define IF_AFDATA_DESTROY(ifp) mtx_destroy(&(ifp)->if_afdata_mtx) 367169689Skan 36890075Sobrien#define IFF_LOCKGIANT(ifp) do { \ 369169689Skan if ((ifp)->if_flags & IFF_NEEDSGIANT) \ 370169689Skan mtx_lock(&Giant); \ 371169689Skan} while (0) 37290075Sobrien 37390075Sobrien#define IFF_UNLOCKGIANT(ifp) do { \ 37490075Sobrien if ((ifp)->if_flags & IFF_NEEDSGIANT) \ 37590075Sobrien mtx_unlock(&Giant); \ 37690075Sobrien} while (0) 377132718Skan 37890075Sobrienint if_handoff(struct ifqueue *ifq, struct mbuf *m, struct ifnet *ifp, 37990075Sobrien int adjust); 38090075Sobrien#define IF_HANDOFF(ifq, m, ifp) \ 381169689Skan if_handoff((struct ifqueue *)ifq, m, ifp, 0) 382169689Skan#define IF_HANDOFF_ADJ(ifq, m, ifp, adj) \ 38390075Sobrien if_handoff((struct ifqueue *)ifq, m, ifp, adj) 38490075Sobrien 38590075Sobrienvoid if_start(struct ifnet *); 386117395Skan 387117395Skan#define IFQ_ENQUEUE(ifq, m, err) \ 38890075Sobriendo { \ 38990075Sobrien IF_LOCK(ifq); \ 39090075Sobrien if (ALTQ_IS_ENABLED(ifq)) \ 39190075Sobrien ALTQ_ENQUEUE(ifq, m, NULL, err); \ 39290075Sobrien else { \ 39390075Sobrien if (_IF_QFULL(ifq)) { \ 39490075Sobrien m_freem(m); \ 39590075Sobrien (err) = ENOBUFS; \ 39690075Sobrien } else { \ 39790075Sobrien _IF_ENQUEUE(ifq, m); \ 39890075Sobrien (err) = 0; \ 39990075Sobrien } \ 40090075Sobrien } \ 401132718Skan if (err) \ 40290075Sobrien (ifq)->ifq_drops++; \ 403169689Skan IF_UNLOCK(ifq); \ 40490075Sobrien} while (0) 405169689Skan 40690075Sobrien#define IFQ_DEQUEUE_NOLOCK(ifq, m) \ 40790075Sobriendo { \ 408169689Skan if (TBR_IS_ENABLED(ifq)) \ 40990075Sobrien (m) = tbr_dequeue_ptr(ifq, ALTDQ_REMOVE); \ 410117395Skan else if (ALTQ_IS_ENABLED(ifq)) \ 411169689Skan ALTQ_DEQUEUE(ifq, m); \ 412117395Skan else \ 413132718Skan _IF_DEQUEUE(ifq, m); \ 414117395Skan} while (0) 415117395Skan 416117395Skan#define IFQ_DEQUEUE(ifq, m) \ 417117395Skando { \ 418169689Skan IF_LOCK(ifq); \ 419169689Skan IFQ_DEQUEUE_NOLOCK(ifq, m); \ 420117395Skan IF_UNLOCK(ifq); \ 42190075Sobrien} while (0) 422169689Skan 423169689Skan#define IFQ_POLL_NOLOCK(ifq, m) \ 424169689Skando { \ 425169689Skan if (TBR_IS_ENABLED(ifq)) \ 426169689Skan (m) = tbr_dequeue_ptr(ifq, ALTDQ_POLL); \ 42790075Sobrien else if (ALTQ_IS_ENABLED(ifq)) \ 428169689Skan ALTQ_POLL(ifq, m); \ 42990075Sobrien else \ 430169689Skan _IF_POLL(ifq, m); \ 431169689Skan} while (0) 432169689Skan 433169689Skan#define IFQ_POLL(ifq, m) \ 43490075Sobriendo { \ 435169689Skan IF_LOCK(ifq); \ 436169689Skan IFQ_POLL_NOLOCK(ifq, m); \ 43790075Sobrien IF_UNLOCK(ifq); \ 438169689Skan} while (0) 439169689Skan 440169689Skan#define IFQ_PURGE_NOLOCK(ifq) \ 441169689Skando { \ 442169689Skan if (ALTQ_IS_ENABLED(ifq)) { \ 443169689Skan ALTQ_PURGE(ifq); \ 444169689Skan } else \ 445169689Skan _IF_DRAIN(ifq); \ 446169689Skan} while (0) 447169689Skan 448169689Skan#define IFQ_PURGE(ifq) \ 449169689Skando { \ 450169689Skan IF_LOCK(ifq); \ 451169689Skan IFQ_PURGE_NOLOCK(ifq); \ 452169689Skan IF_UNLOCK(ifq); \ 453169689Skan} while (0) 454169689Skan 455169689Skan#define IFQ_SET_READY(ifq) \ 456169689Skan do { ((ifq)->altq_flags |= ALTQF_READY); } while (0) 457169689Skan 458169689Skan#define IFQ_LOCK(ifq) IF_LOCK(ifq) 459169689Skan#define IFQ_UNLOCK(ifq) IF_UNLOCK(ifq) 460169689Skan#define IFQ_LOCK_ASSERT(ifq) IF_LOCK_ASSERT(ifq) 461169689Skan#define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) 462169689Skan#define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) 463169689Skan#define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) 464169689Skan#define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) 465169689Skan#define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) 466169689Skan 467169689Skan/* 468169689Skan * The IFF_DRV_OACTIVE test should really occur in the device driver, not in 469169689Skan * the handoff logic, as that flag is locked by the device driver. 470169689Skan */ 471169689Skan#define IFQ_HANDOFF_ADJ(ifp, m, adj, err) \ 472169689Skando { \ 473169689Skan int len; \ 474169689Skan short mflags; \ 475169689Skan \ 476169689Skan len = (m)->m_pkthdr.len; \ 477169689Skan mflags = (m)->m_flags; \ 478169689Skan IFQ_ENQUEUE(&(ifp)->if_snd, m, err); \ 479169689Skan if ((err) == 0) { \ 480169689Skan (ifp)->if_obytes += len + (adj); \ 481169689Skan if (mflags & M_MCAST) \ 48290075Sobrien (ifp)->if_omcasts++; \ 483169689Skan if (((ifp)->if_drv_flags & IFF_DRV_OACTIVE) == 0) \ 48490075Sobrien if_start(ifp); \ 485169689Skan } \ 486169689Skan} while (0) 487169689Skan 488169689Skan#define IFQ_HANDOFF(ifp, m, err) \ 489169689Skan IFQ_HANDOFF_ADJ(ifp, m, 0, err) 490169689Skan 49190075Sobrien#define IFQ_DRV_DEQUEUE(ifq, m) \ 492117395Skando { \ 493117395Skan (m) = (ifq)->ifq_drv_head; \ 494117395Skan if (m) { \ 495117395Skan if (((ifq)->ifq_drv_head = (m)->m_nextpkt) == NULL) \ 496117395Skan (ifq)->ifq_drv_tail = NULL; \ 497117395Skan (m)->m_nextpkt = NULL; \ 49890075Sobrien (ifq)->ifq_drv_len--; \ 499169689Skan } else { \ 500169689Skan IFQ_LOCK(ifq); \ 50190075Sobrien IFQ_DEQUEUE_NOLOCK(ifq, m); \ 502169689Skan while ((ifq)->ifq_drv_len < (ifq)->ifq_drv_maxlen) { \ 50390075Sobrien struct mbuf *m0; \ 504169689Skan IFQ_DEQUEUE_NOLOCK(ifq, m0); \ 505169689Skan if (m0 == NULL) \ 506169689Skan break; \ 507169689Skan m0->m_nextpkt = NULL; \ 50890075Sobrien if ((ifq)->ifq_drv_tail == NULL) \ 509169689Skan (ifq)->ifq_drv_head = m0; \ 51090075Sobrien else \ 511169689Skan (ifq)->ifq_drv_tail->m_nextpkt = m0; \ 512169689Skan (ifq)->ifq_drv_tail = m0; \ 513169689Skan (ifq)->ifq_drv_len++; \ 514169689Skan } \ 515169689Skan IFQ_UNLOCK(ifq); \ 516169689Skan } \ 517169689Skan} while (0) 518169689Skan 51990075Sobrien#define IFQ_DRV_PREPEND(ifq, m) \ 520169689Skando { \ 521169689Skan (m)->m_nextpkt = (ifq)->ifq_drv_head; \ 522169689Skan if ((ifq)->ifq_drv_tail == NULL) \ 523169689Skan (ifq)->ifq_drv_tail = (m); \ 524169689Skan (ifq)->ifq_drv_head = (m); \ 525169689Skan (ifq)->ifq_drv_len++; \ 52690075Sobrien} while (0) 527169689Skan 528169689Skan#define IFQ_DRV_IS_EMPTY(ifq) \ 529117395Skan (((ifq)->ifq_drv_len == 0) && ((ifq)->ifq_len == 0)) 530169689Skan 531169689Skan#define IFQ_DRV_PURGE(ifq) \ 532169689Skando { \ 533169689Skan struct mbuf *m, *n = (ifq)->ifq_drv_head; \ 534169689Skan while((m = n) != NULL) { \ 535169689Skan n = m->m_nextpkt; \ 536169689Skan m_freem(m); \ 537169689Skan } \ 538169689Skan (ifq)->ifq_drv_head = (ifq)->ifq_drv_tail = NULL; \ 539169689Skan (ifq)->ifq_drv_len = 0; \ 540169689Skan IFQ_PURGE(ifq); \ 541169689Skan} while (0) 542169689Skan 543169689Skan/* 544169689Skan * 72 was chosen below because it is the size of a TCP/IP 545169689Skan * header (40) + the minimum mss (32). 546169689Skan */ 547169689Skan#define IF_MINMTU 72 548169689Skan#define IF_MAXMTU 65535 549169689Skan 550169689Skan#endif /* _KERNEL */ 551169689Skan 552169689Skan/* 553169689Skan * The ifaddr structure contains information about one address 554169689Skan * of an interface. They are maintained by the different address families, 555169689Skan * are allocated and attached when an address is set, and are linked 556169689Skan * together so all addresses for an interface can be located. 557169689Skan * 558169689Skan * NOTE: a 'struct ifaddr' is always at the beginning of a larger 559169689Skan * chunk of malloc'ed memory, where we store the three addresses 560169689Skan * (ifa_addr, ifa_dstaddr and ifa_netmask) referenced here. 561169689Skan */ 562169689Skanstruct ifaddr { 563169689Skan struct sockaddr *ifa_addr; /* address of interface */ 564169689Skan struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ 565169689Skan#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 566169689Skan struct sockaddr *ifa_netmask; /* used to determine subnet */ 567169689Skan struct if_data if_data; /* not all members are meaningful */ 568169689Skan struct ifnet *ifa_ifp; /* back-pointer to interface */ 569169689Skan TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ 570169689Skan void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ 571169689Skan (int, struct rtentry *, struct rt_addrinfo *); 572169689Skan u_short ifa_flags; /* mostly rt_flags for cloning */ 573169689Skan u_int ifa_refcnt; /* references to this structure */ 574169689Skan int ifa_metric; /* cost of going out this interface */ 575169689Skan int (*ifa_claim_addr) /* check if an addr goes to this if */ 576169689Skan (struct ifaddr *, struct sockaddr *); 577169689Skan struct mtx ifa_mtx; 578169689Skan}; 579169689Skan#define IFA_ROUTE RTF_UP /* route installed */ 580169689Skan 581169689Skan/* for compatibility with other BSDs */ 582169689Skan#define ifa_list ifa_link 58390075Sobrien 58490075Sobrien#define IFA_LOCK_INIT(ifa) \ 585169689Skan mtx_init(&(ifa)->ifa_mtx, "ifaddr", NULL, MTX_DEF) 586169689Skan#define IFA_LOCK(ifa) mtx_lock(&(ifa)->ifa_mtx) 587169689Skan#define IFA_UNLOCK(ifa) mtx_unlock(&(ifa)->ifa_mtx) 588169689Skan#define IFA_DESTROY(ifa) mtx_destroy(&(ifa)->ifa_mtx) 589169689Skan 590169689Skan/* 591169689Skan * The prefix structure contains information about one prefix 59290075Sobrien * of an interface. They are maintained by the different address families, 59390075Sobrien * are allocated and attached when a prefix or an address is set, 59490075Sobrien * and are linked together so all prefixes for an interface can be located. 59590075Sobrien */ 596132718Skanstruct ifprefix { 59790075Sobrien struct sockaddr *ifpr_prefix; /* prefix of interface */ 598169689Skan struct ifnet *ifpr_ifp; /* back-pointer to interface */ 59990075Sobrien TAILQ_ENTRY(ifprefix) ifpr_list; /* queue macro glue */ 60090075Sobrien u_char ifpr_plen; /* prefix length in bits */ 60190075Sobrien u_char ifpr_type; /* protocol dependent prefix type */ 602132718Skan}; 60390075Sobrien 60490075Sobrien/* 60590075Sobrien * Multicast address structure. This is analogous to the ifaddr 60690075Sobrien * structure except that it keeps track of multicast addresses. 60790075Sobrien */ 60890075Sobrienstruct ifmultiaddr { 60990075Sobrien TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ 61090075Sobrien struct sockaddr *ifma_addr; /* address this membership is for */ 61190075Sobrien struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ 61290075Sobrien struct ifnet *ifma_ifp; /* back-pointer to interface */ 61390075Sobrien u_int ifma_refcount; /* reference count */ 61490075Sobrien void *ifma_protospec; /* protocol-specific state, if any */ 61590075Sobrien struct ifmultiaddr *ifma_llifma; /* pointer to ifma for ifma_lladdr */ 61690075Sobrien}; 61790075Sobrien 61890075Sobrien#ifdef _KERNEL 61990075Sobrien#define IFAFREE(ifa) \ 62090075Sobrien do { \ 62190075Sobrien IFA_LOCK(ifa); \ 62290075Sobrien KASSERT((ifa)->ifa_refcnt > 0, \ 62390075Sobrien ("ifa %p !(ifa_refcnt > 0)", ifa)); \ 624132718Skan if (--(ifa)->ifa_refcnt == 0) { \ 625132718Skan IFA_DESTROY(ifa); \ 626169689Skan free(ifa, M_IFADDR); \ 627169689Skan } else \ 628132718Skan IFA_UNLOCK(ifa); \ 62990075Sobrien } while (0) 63090075Sobrien 63190075Sobrien#define IFAREF(ifa) \ 63290075Sobrien do { \ 63390075Sobrien IFA_LOCK(ifa); \ 63490075Sobrien ++(ifa)->ifa_refcnt; \ 63590075Sobrien IFA_UNLOCK(ifa); \ 63690075Sobrien } while (0) 63790075Sobrien 63890075Sobrienextern struct mtx ifnet_lock; 63990075Sobrien#define IFNET_LOCK_INIT() \ 64090075Sobrien mtx_init(&ifnet_lock, "ifnet", NULL, MTX_DEF | MTX_RECURSE) 64190075Sobrien#define IFNET_WLOCK() mtx_lock(&ifnet_lock) 64290075Sobrien#define IFNET_WUNLOCK() mtx_unlock(&ifnet_lock) 64390075Sobrien#define IFNET_WLOCK_ASSERT() mtx_assert(&ifnet_lock, MA_OWNED) 64490075Sobrien#define IFNET_RLOCK() IFNET_WLOCK() 64590075Sobrien#define IFNET_RUNLOCK() IFNET_WUNLOCK() 64690075Sobrien 64790075Sobrienstruct ifindex_entry { 64890075Sobrien struct ifnet *ife_ifnet; 64990075Sobrien struct cdev *ife_dev; 65090075Sobrien}; 65190075Sobrien 65290075Sobrienstruct ifnet *ifnet_byindex(u_short idx); 65390075Sobrien 65490075Sobrien/* 65590075Sobrien * Given the index, ifaddr_byindex() returns the one and only 65690075Sobrien * link-level ifaddr for the interface. You are not supposed to use 65790075Sobrien * it to traverse the list of addresses associated to the interface. 658117395Skan */ 65990075Sobrienstruct ifaddr *ifaddr_byindex(u_short idx); 66090075Sobrienstruct cdev *ifdev_byindex(u_short idx); 66190075Sobrien 662132718Skan#ifdef VIMAGE_GLOBALS 66390075Sobrienextern struct ifnethead ifnet; 66490075Sobrienextern struct ifnet *loif; /* first loopback interface */ 665169689Skanextern int if_index; 66690075Sobrien#endif 66790075Sobrienextern int ifqmaxlen; 66890075Sobrien 66990075Sobrienint if_addgroup(struct ifnet *, const char *); 67090075Sobrienint if_delgroup(struct ifnet *, const char *); 67190075Sobrienint if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); 67290075Sobrienint if_allmulti(struct ifnet *, int); 67390075Sobrienstruct ifnet* if_alloc(u_char); 674132718Skanvoid if_attach(struct ifnet *); 67590075Sobrienint if_delmulti(struct ifnet *, struct sockaddr *); 67690075Sobrienvoid if_delmulti_ifma(struct ifmultiaddr *); 67790075Sobrienvoid if_detach(struct ifnet *); 67890075Sobrienvoid if_purgeaddrs(struct ifnet *); 67990075Sobrienvoid if_purgemaddrs(struct ifnet *); 68090075Sobrienvoid if_down(struct ifnet *); 68190075Sobrienstruct ifmultiaddr * 68290075Sobrien if_findmulti(struct ifnet *, struct sockaddr *); 683169689Skanvoid if_free(struct ifnet *); 684169689Skanvoid if_free_type(struct ifnet *, u_char); 685169689Skanvoid if_initname(struct ifnet *, const char *, int); 68690075Sobrienvoid if_link_state_change(struct ifnet *, int); 687132718Skanint if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); 68890075Sobrienint if_setlladdr(struct ifnet *, const u_char *, int); 68990075Sobrienvoid if_up(struct ifnet *); 690117395Skan/*void ifinit(void);*/ /* declared in systm.h for main() */ 69190075Sobrienint ifioctl(struct socket *, u_long, caddr_t, struct thread *); 692117395Skanint ifpromisc(struct ifnet *, int); 693117395Skanstruct ifnet *ifunit(const char *); 69490075Sobrien 69590075Sobrienvoid ifq_attach(struct ifaltq *, struct ifnet *ifp); 69690075Sobrienvoid ifq_detach(struct ifaltq *); 69790075Sobrien 69890075Sobrienstruct ifaddr *ifa_ifwithaddr(struct sockaddr *); 69990075Sobrienstruct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *); 700132718Skanstruct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); 70190075Sobrienstruct ifaddr *ifa_ifwithnet(struct sockaddr *); 702117395Skanstruct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); 70390075Sobrienstruct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int); 704117395Skan 705117395Skanstruct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); 70690075Sobrien 70790075Sobrienint if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); 70890075Sobrien 70990075Sobrientypedef void *if_com_alloc_t(u_char type, struct ifnet *ifp); 71090075Sobrientypedef void if_com_free_t(void *com, u_char type); 71190075Sobrienvoid if_register_com_alloc(u_char type, if_com_alloc_t *a, if_com_free_t *f); 712132718Skanvoid if_deregister_com_alloc(u_char type); 71390075Sobrien 714169689Skan#define IF_LLADDR(ifp) \ 71590075Sobrien LLADDR((struct sockaddr_dl *)((ifp)->if_addr->ifa_addr)) 71690075Sobrien 71790075Sobrien#ifdef DEVICE_POLLING 71890075Sobrienenum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS }; 71990075Sobrien 72090075Sobrientypedef void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); 721117395Skanint ether_poll_register(poll_handler_t *h, struct ifnet *ifp); 72290075Sobrienint ether_poll_deregister(struct ifnet *ifp); 72390075Sobrien#endif /* DEVICE_POLLING */ 72490075Sobrien 725132718Skan#endif /* _KERNEL */ 72690075Sobrien 72790075Sobrien#endif /* !_NET_IF_VAR_H_ */ 728169689Skan