1 /* $OpenBSD: if_var.h,v 1.12 2014/07/08 04:02:14 dlg Exp $ */ 2 /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 2012-2013 Henning Brauer <henning@openbsd.org> 6 * Copyright (c) 1982, 1986, 1989, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)if.h 8.1 (Berkeley) 6/10/93 34 */ 35 36 #ifndef _NET_IF_VAR_H_ 37 #define _NET_IF_VAR_H_ 38 39 #include <sys/queue.h> 40 #ifdef _KERNEL 41 #include <net/hfsc.h> 42 #endif 43 44 /* 45 * Structures defining a network interface, providing a packet 46 * transport mechanism (ala level 0 of the PUP protocols). 47 * 48 * Each interface accepts output datagrams of a specified maximum 49 * length, and provides higher level routines with input datagrams 50 * received from its medium. 51 * 52 * Output occurs when the routine if_output is called, with four parameters: 53 * (*ifp->if_output)(ifp, m, dst, rt) 54 * Here m is the mbuf chain to be sent and dst is the destination address. 55 * The output routine encapsulates the supplied datagram if necessary, 56 * and then transmits it on its medium. 57 * 58 * On input, each interface unwraps the data received by it, and either 59 * places it on the input queue of an internetwork datagram routine 60 * and posts the associated software interrupt, or passes the datagram to a raw 61 * packet input routine. 62 * 63 * Routines exist for locating interfaces by their addresses 64 * or for locating an interface on a certain network, as well as more general 65 * routing and gateway routines maintaining information used to locate 66 * interfaces. These routines live in the files if.c and route.c 67 */ 68 69 #include <sys/time.h> 70 71 struct mbuf; 72 struct proc; 73 struct rtentry; 74 struct socket; 75 struct ether_header; 76 struct arpcom; 77 struct rt_addrinfo; 78 struct ifnet; 79 struct hfsc_if; 80 81 /* 82 * Structure describing a `cloning' interface. 83 */ 84 struct if_clone { 85 LIST_ENTRY(if_clone) ifc_list; /* on list of cloners */ 86 const char *ifc_name; /* name of device, e.g. `gif' */ 87 size_t ifc_namelen; /* length of name */ 88 89 int (*ifc_create)(struct if_clone *, int); 90 int (*ifc_destroy)(struct ifnet *); 91 }; 92 93 #define IF_CLONE_INITIALIZER(name, create, destroy) \ 94 { { 0 }, name, sizeof(name) - 1, create, destroy } 95 96 /* 97 * Structure defining a queue for a network interface. 98 */ 99 struct ifqueue { 100 struct { 101 struct mbuf *head; 102 struct mbuf *tail; 103 } ifq_q[IFQ_NQUEUES]; 104 int ifq_len; 105 int ifq_maxlen; 106 int ifq_drops; 107 struct hfsc_if *ifq_hfsc; 108 struct timeout *ifq_congestion; 109 }; 110 111 /* 112 * Structure defining a queue for a network interface. 113 * 114 * (Would like to call this struct ``if'', but C isn't PL/1.) 115 */ 116 TAILQ_HEAD(ifnet_head, ifnet); /* the actual queue head */ 117 118 struct ifnet { /* and the entries */ 119 void *if_softc; /* lower-level data for this if */ 120 TAILQ_ENTRY(ifnet) if_list; /* all struct ifnets are chained */ 121 TAILQ_ENTRY(ifnet) if_txlist; /* list of ifnets ready to tx */ 122 TAILQ_HEAD(, ifaddr) if_addrlist; /* linked list of addresses per if */ 123 TAILQ_HEAD(, ifmaddr) if_maddrlist; /* list of multicast records */ 124 TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ 125 struct hook_desc_head *if_addrhooks; /* address change callbacks */ 126 struct hook_desc_head *if_linkstatehooks; /* link change callbacks */ 127 struct hook_desc_head *if_detachhooks; /* detach callbacks */ 128 char if_xname[IFNAMSIZ]; /* external name (name + unit) */ 129 int if_pcount; /* number of promiscuous listeners */ 130 caddr_t if_bpf; /* packet filter structure */ 131 caddr_t if_bridgeport; /* used by bridge ports */ 132 caddr_t if_tp; /* used by trunk ports */ 133 caddr_t if_pf_kif; /* pf interface abstraction */ 134 union { 135 caddr_t carp_s; /* carp structure (used by !carp ifs) */ 136 struct ifnet *carp_d; /* ptr to carpdev (used by carp ifs) */ 137 } if_carp_ptr; 138 #define if_carp if_carp_ptr.carp_s 139 #define if_carpdev if_carp_ptr.carp_d 140 u_short if_index; /* numeric abbreviation for this if */ 141 short if_timer; /* time 'til if_watchdog called */ 142 short if_flags; /* up/down, broadcast, etc. */ 143 int if_xflags; /* extra softnet flags */ 144 struct if_data if_data; /* stats and other data about if */ 145 u_int32_t if_hardmtu; /* maximum MTU device supports */ 146 u_int if_rdomain; /* routing instance */ 147 char if_description[IFDESCRSIZE]; /* interface description */ 148 u_short if_rtlabelid; /* next route label */ 149 u_int8_t if_priority; 150 151 /* procedure handles */ 152 /* output routine (enqueue) */ 153 int (*if_output)(struct ifnet *, struct mbuf *, struct sockaddr *, 154 struct rtentry *); 155 156 /* link level output function */ 157 int (*if_ll_output)(struct ifnet *, struct mbuf *, 158 struct sockaddr *, struct rtentry *); 159 /* initiate output routine */ 160 void (*if_start)(struct ifnet *); 161 /* ioctl routine */ 162 int (*if_ioctl)(struct ifnet *, u_long, caddr_t); 163 /* stop routine */ 164 int (*if_stop)(struct ifnet *, int); 165 /* timer routine */ 166 void (*if_watchdog)(struct ifnet *); 167 int (*if_wol)(struct ifnet *, int); 168 struct ifaddr *if_lladdr; /* pointer to link-level address */ 169 struct ifqueue if_snd; /* output queue */ 170 struct sockaddr_dl *if_sadl; /* pointer to our sockaddr_dl */ 171 172 void *if_afdata[AF_MAX]; 173 }; 174 #define if_mtu if_data.ifi_mtu 175 #define if_type if_data.ifi_type 176 #define if_addrlen if_data.ifi_addrlen 177 #define if_hdrlen if_data.ifi_hdrlen 178 #define if_metric if_data.ifi_metric 179 #define if_link_state if_data.ifi_link_state 180 #define if_baudrate if_data.ifi_baudrate 181 #define if_ipackets if_data.ifi_ipackets 182 #define if_ierrors if_data.ifi_ierrors 183 #define if_opackets if_data.ifi_opackets 184 #define if_oerrors if_data.ifi_oerrors 185 #define if_collisions if_data.ifi_collisions 186 #define if_ibytes if_data.ifi_ibytes 187 #define if_obytes if_data.ifi_obytes 188 #define if_imcasts if_data.ifi_imcasts 189 #define if_omcasts if_data.ifi_omcasts 190 #define if_iqdrops if_data.ifi_iqdrops 191 #define if_noproto if_data.ifi_noproto 192 #define if_lastchange if_data.ifi_lastchange 193 #define if_capabilities if_data.ifi_capabilities 194 195 #ifdef _KERNEL 196 /* 197 * Output queues (ifp->if_snd) and internetwork datagram level (pup level 1) 198 * input routines have queues of messages stored on ifqueue structures 199 * (defined above). Entries are added to and deleted from these structures 200 * by these macros, which should be called with ipl raised to splnet(). 201 */ 202 #define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) 203 #define IF_DROP(ifq) ((ifq)->ifq_drops++) 204 #define IF_ENQUEUE(ifq, m) \ 205 do { \ 206 (m)->m_nextpkt = NULL; \ 207 if ((ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail == NULL) \ 208 (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head = m; \ 209 else \ 210 (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail->m_nextpkt = m; \ 211 (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail = m; \ 212 (ifq)->ifq_len++; \ 213 } while (/* CONSTCOND */0) 214 #define IF_PREPEND(ifq, m) \ 215 do { \ 216 (m)->m_nextpkt = (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head; \ 217 if ((ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail == NULL) \ 218 (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].tail = (m); \ 219 (ifq)->ifq_q[(m)->m_pkthdr.pf.prio].head = (m); \ 220 (ifq)->ifq_len++; \ 221 } while (/* CONSTCOND */0) 222 223 #define IF_POLL(ifq, m) \ 224 do { \ 225 int if_dequeue_prio = IFQ_MAXPRIO; \ 226 do { \ 227 (m) = (ifq)->ifq_q[if_dequeue_prio].head; \ 228 } while (!(m) && --if_dequeue_prio >= 0); \ 229 } while (/* CONSTCOND */0) 230 231 #define IF_DEQUEUE(ifq, m) \ 232 do { \ 233 int if_dequeue_prio = IFQ_MAXPRIO; \ 234 do { \ 235 (m) = (ifq)->ifq_q[if_dequeue_prio].head; \ 236 if (m) { \ 237 if (((ifq)->ifq_q[if_dequeue_prio].head = \ 238 (m)->m_nextpkt) == NULL) \ 239 (ifq)->ifq_q[if_dequeue_prio].tail = NULL; \ 240 (m)->m_nextpkt = NULL; \ 241 (ifq)->ifq_len--; \ 242 } \ 243 } while (!(m) && --if_dequeue_prio >= 0); \ 244 } while (/* CONSTCOND */0) 245 246 #define IF_INPUT_ENQUEUE(ifq, m) \ 247 do { \ 248 if (IF_QFULL(ifq)) { \ 249 IF_DROP(ifq); \ 250 m_freem(m); \ 251 if (!(ifq)->ifq_congestion) \ 252 if_congestion(ifq); \ 253 } else \ 254 IF_ENQUEUE(ifq, m); \ 255 } while (/* CONSTCOND */0) 256 257 #define IF_PURGE(ifq) \ 258 do { \ 259 struct mbuf *__m0; \ 260 \ 261 for (;;) { \ 262 IF_DEQUEUE((ifq), __m0); \ 263 if (__m0 == NULL) \ 264 break; \ 265 else \ 266 m_freem(__m0); \ 267 } \ 268 } while (/* CONSTCOND */0) 269 #define IF_LEN(ifq) ((ifq)->ifq_len) 270 #define IF_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) 271 272 #define IFQ_MAXLEN 256 273 #define IFNET_SLOWHZ 1 /* granularity is 1 second */ 274 #endif 275 276 /* 277 * The ifaddr structure contains information about one address 278 * of an interface. They are maintained by the different address families, 279 * are allocated and attached when an address is set, and are linked 280 * together so all addresses for an interface can be located. 281 */ 282 struct ifaddr { 283 struct sockaddr *ifa_addr; /* address of interface */ 284 struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ 285 #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ 286 struct sockaddr *ifa_netmask; /* used to determine subnet */ 287 struct ifnet *ifa_ifp; /* back-pointer to interface */ 288 TAILQ_ENTRY(ifaddr) ifa_list; /* list of addresses for interface */ 289 /* check or clean routes (+ or -)'d */ 290 void (*ifa_rtrequest)(int, struct rtentry *); 291 u_int ifa_flags; /* interface flags, see below */ 292 u_int ifa_refcnt; /* number of `rt_ifa` references */ 293 int ifa_metric; /* cost of going out this interface */ 294 }; 295 296 #define IFA_ROUTE 0x01 /* Auto-magically installed route */ 297 298 /* 299 * Interface multicast address. 300 */ 301 struct ifmaddr { 302 struct sockaddr *ifma_addr; /* Protocol address */ 303 unsigned short ifma_ifidx; /* Index of the interface */ 304 unsigned int ifma_refcnt; /* Count of references */ 305 TAILQ_ENTRY(ifmaddr) ifma_list; /* Per-interface list */ 306 }; 307 308 /* 309 * interface groups 310 */ 311 312 struct ifg_group { 313 char ifg_group[IFNAMSIZ]; 314 u_int ifg_refcnt; 315 caddr_t ifg_pf_kif; 316 int ifg_carp_demoted; 317 TAILQ_HEAD(, ifg_member) ifg_members; 318 TAILQ_ENTRY(ifg_group) ifg_next; 319 }; 320 321 struct ifg_member { 322 TAILQ_ENTRY(ifg_member) ifgm_next; 323 struct ifnet *ifgm_ifp; 324 }; 325 326 struct ifg_list { 327 struct ifg_group *ifgl_group; 328 TAILQ_ENTRY(ifg_list) ifgl_next; 329 }; 330 331 #ifdef _KERNEL 332 /* XXX pattr unused */ 333 #define IFQ_ENQUEUE(ifq, m, pattr, err) \ 334 do { \ 335 if (HFSC_ENABLED(ifq)) \ 336 (err) = hfsc_enqueue(((struct ifqueue *)(ifq)), m); \ 337 else { \ 338 if (IF_QFULL((ifq))) { \ 339 m_freem((m)); \ 340 (err) = ENOBUFS; \ 341 } else { \ 342 IF_ENQUEUE((ifq), (m)); \ 343 (err) = 0; \ 344 } \ 345 } \ 346 if ((err)) \ 347 (ifq)->ifq_drops++; \ 348 } while (/* CONSTCOND */0) 349 350 #define IFQ_DEQUEUE(ifq, m) \ 351 do { \ 352 if (HFSC_ENABLED((ifq))) \ 353 (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 1); \ 354 else \ 355 IF_DEQUEUE((ifq), (m)); \ 356 } while (/* CONSTCOND */0) 357 358 #define IFQ_POLL(ifq, m) \ 359 do { \ 360 if (HFSC_ENABLED((ifq))) \ 361 (m) = hfsc_dequeue(((struct ifqueue *)(ifq)), 0); \ 362 else \ 363 IF_POLL((ifq), (m)); \ 364 } while (/* CONSTCOND */0) 365 366 #define IFQ_PURGE(ifq) \ 367 do { \ 368 if (HFSC_ENABLED((ifq))) \ 369 hfsc_purge(((struct ifqueue *)(ifq))); \ 370 else \ 371 IF_PURGE((ifq)); \ 372 } while (/* CONSTCOND */0) 373 374 #define IFQ_SET_READY(ifq) /* nothing */ 375 376 #define IFQ_LEN(ifq) IF_LEN(ifq) 377 #define IFQ_IS_EMPTY(ifq) ((ifq)->ifq_len == 0) 378 #define IFQ_INC_LEN(ifq) ((ifq)->ifq_len++) 379 #define IFQ_DEC_LEN(ifq) (--(ifq)->ifq_len) 380 #define IFQ_INC_DROPS(ifq) ((ifq)->ifq_drops++) 381 #define IFQ_SET_MAXLEN(ifq, len) ((ifq)->ifq_maxlen = (len)) 382 383 /* default interface priorities */ 384 #define IF_WIRED_DEFAULT_PRIORITY 0 385 #define IF_WIRELESS_DEFAULT_PRIORITY 4 386 387 extern struct ifnet_head ifnet; 388 extern struct ifnet *lo0ifp; 389 390 #define ether_input_mbuf(ifp, m) ether_input((ifp), NULL, (m)) 391 392 void ether_ifattach(struct ifnet *); 393 void ether_ifdetach(struct ifnet *); 394 int ether_ioctl(struct ifnet *, struct arpcom *, u_long, caddr_t); 395 void ether_input(struct ifnet *, struct ether_header *, struct mbuf *); 396 int ether_output(struct ifnet *, 397 struct mbuf *, struct sockaddr *, struct rtentry *); 398 char *ether_sprintf(u_char *); 399 400 void if_alloc_sadl(struct ifnet *); 401 void if_free_sadl(struct ifnet *); 402 void if_attach(struct ifnet *); 403 void if_attachdomain(void); 404 void if_attachtail(struct ifnet *); 405 void if_attachhead(struct ifnet *); 406 void if_detach(struct ifnet *); 407 void if_down(struct ifnet *); 408 void if_downall(void); 409 void if_link_state_change(struct ifnet *); 410 void if_slowtimo(void *); 411 void if_up(struct ifnet *); 412 int ifconf(u_long, caddr_t); 413 void ifinit(void); 414 int ifioctl(struct socket *, u_long, caddr_t, struct proc *); 415 int ifpromisc(struct ifnet *, int); 416 struct ifg_group *if_creategroup(const char *); 417 int if_addgroup(struct ifnet *, const char *); 418 int if_delgroup(struct ifnet *, const char *); 419 void if_group_routechange(struct sockaddr *, struct sockaddr *); 420 struct ifnet *ifunit(const char *); 421 struct ifnet *if_get(unsigned int); 422 void if_start(struct ifnet *); 423 void ifnewlladdr(struct ifnet *); 424 425 struct ifaddr *ifa_ifwithaddr(struct sockaddr *, u_int); 426 struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *, u_int); 427 struct ifaddr *ifa_ifwithnet(struct sockaddr *, u_int); 428 struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); 429 void ifafree(struct ifaddr *); 430 void link_rtrequest(int, struct rtentry *); 431 void p2p_rtrequest(int, struct rtentry *); 432 433 void if_clone_attach(struct if_clone *); 434 void if_clone_detach(struct if_clone *); 435 436 int if_clone_create(const char *); 437 int if_clone_destroy(const char *); 438 439 void if_congestion(struct ifqueue *); 440 int sysctl_ifq(int *, u_int, void *, size_t *, void *, size_t, 441 struct ifqueue *); 442 443 int loioctl(struct ifnet *, u_long, caddr_t); 444 void loopattach(int); 445 int looutput(struct ifnet *, 446 struct mbuf *, struct sockaddr *, struct rtentry *); 447 void lortrequest(int, struct rtentry *); 448 void ifa_add(struct ifnet *, struct ifaddr *); 449 void ifa_del(struct ifnet *, struct ifaddr *); 450 void ifa_update_broadaddr(struct ifnet *, struct ifaddr *, 451 struct sockaddr *); 452 453 void if_rxr_init(struct if_rxring *, u_int, u_int); 454 u_int if_rxr_get(struct if_rxring *, u_int); 455 456 #define if_rxr_put(_r, _c) do { (_r)->rxr_alive -= (_c); } while (0) 457 #define if_rxr_inuse(_r) ((_r)->rxr_alive) 458 459 int if_rxr_info_ioctl(struct if_rxrinfo *, u_int, struct if_rxring_info *); 460 int if_rxr_ioctl(struct if_rxrinfo *, const char *, u_int, 461 struct if_rxring *); 462 463 #endif /* _KERNEL */ 464 465 #endif /* _NET_IF_VAR_H_ */ 466