1/* $OpenBSD: if_var.h,v 1.148 2026/03/22 23:14:00 bluhm 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#ifdef _KERNEL
40
41#include <sys/queue.h>
42#include <sys/mbuf.h>
43#include <sys/smr.h>
44#include <sys/refcnt.h>
45#include <sys/task.h>
46#include <sys/timeout.h>
47
48#include <net/ifq.h>
49#include <net/route.h>
50
51/*
52 * Structures defining a network interface, providing a packet
53 * transport mechanism (ala level 0 of the PUP protocols).
54 *
55 * Each interface accepts output datagrams of a specified maximum
56 * length, and provides higher level routines with input datagrams
57 * received from its medium.
58 *
59 * Output occurs when the routine if_output is called, with four parameters:
60 * (*ifp->if_output)(ifp, m, dst, rt)
61 * Here m is the mbuf chain to be sent and dst is the destination address.
62 * The output routine encapsulates the supplied datagram if necessary,
63 * and then transmits it on its medium.
64 *
65 * On input, each interface unwraps the data received by it, and either
66 * places it on the input queue of an internetwork datagram routine
67 * and posts the associated software interrupt, or passes the datagram to a raw
68 * packet input routine.
69 *
70 * Routines exist for locating interfaces by their addresses
71 * or for locating an interface on a certain network, as well as more general
72 * routing and gateway routines maintaining information used to locate
73 * interfaces. These routines live in the files if.c and route.c
74 */
75
76/*
77 * Locks used to protect struct members in this file:
78 * I immutable after creation
79 * d protection left to the driver
80 * c only used in ioctl or routing socket contexts (kernel lock)
81 * K kernel lock
82 * N net lock
83 * T if_tmplist_lock
84 * m interface multicast rwlock if_maddrlock
85 *
86 * For SRP related structures that allow lock-free reads, the write lock
87 * is indicated below.
88 */
89
90struct rtentry;
91struct ifnet;
92struct task;
93struct cpumem;
94
95struct netstack {
96 struct mbuf_list ns_input;
97 struct mbuf_list ns_proto;
98
99 struct route ns_route;
100 struct mbuf_list ns_tcp_ml;
101 struct mbuf_list ns_tcp6_ml;
102};
103
104/*
105 * Structure describing a `cloning' interface.
106 */
107struct if_clone {
108 LIST_ENTRY(if_clone) ifc_list; /* [I] on list of cloners */
109 const char *ifc_name; /* name of device, e.g. `gif' */
110 size_t ifc_namelen; /* length of name */
111
112 int (*ifc_create)(struct if_clone *, int);
113 int (*ifc_destroy)(struct ifnet *);
114};
115
116#define IF_CLONE_INITIALIZER(name, create, destroy) \
117{ \
118 .ifc_list = { NULL, NULL }, \
119 .ifc_name = name, \
120 .ifc_namelen = sizeof(name) - 1, \
121 .ifc_create = create, \
122 .ifc_destroy = destroy, \
123}
124
125enum if_counters {
126 ifc_ipackets, /* packets received on interface */
127 ifc_ierrors, /* input errors on interface */
128 ifc_opackets, /* packets sent on interface */
129 ifc_oerrors, /* output errors on interface */
130 ifc_collisions, /* collisions on csma interfaces */
131 ifc_ibytes, /* total number of octets received */
132 ifc_obytes, /* total number of octets sent */
133 ifc_imcasts, /* packets received via multicast */
134 ifc_omcasts, /* packets sent via multicast */
135 ifc_iqdrops, /* dropped on input, this interface */
136 ifc_oqdrops, /* dropped on output, this interface */
137 ifc_noproto, /* destined for unsupported protocol */
138
139 ifc_ncounters
140};
141
142/*
143 * Structure defining a queue for a network interface.
144 *
145 * (Would like to call this struct ``if'', but C isn't PL/1.)
146 */
147TAILQ_HEAD(ifnet_head, ifnet); /* the actual queue head */
148struct carp_softc;
149SMR_LIST_HEAD(carp_iflist, carp_softc);
150
151struct ifnet { /* and the entries */
152 void *if_softc; /* [I] lower-level data for this if */
153 struct refcnt if_refcnt;
154 TAILQ_ENTRY(ifnet) if_list; /* [NK] all struct ifnets are chained */
155 TAILQ_ENTRY(ifnet) if_tmplist; /* [T] temporary list */
156 TAILQ_HEAD(, ifaddr) if_addrlist; /* [N] list of addresses per if */
157 TAILQ_HEAD(, ifmaddr) if_maddrlist; /* [m] list of multicast records */
158 TAILQ_HEAD(, ifg_list) if_groups; /* [N] list of groups per if */
159 struct rwlock if_maddrlock;
160 struct task_list if_addrhooks; /* [I] address change callbacks */
161 struct task_list if_linkstatehooks; /* [I] link change callbacks*/
162 struct task_list if_detachhooks; /* [I] detach callbacks */
163 /* [I] check or clean routes (+ or -)'d */
164 void (*if_rtrequest)(struct ifnet *, int, struct rtentry *);
165 char if_xname[IFNAMSIZ]; /* [I] external name (name + unit) */
166 int if_pcount; /* [N] # of promiscuous listeners */
167 unsigned int if_bridgeidx; /* [K] used by bridge ports */
168 caddr_t if_bpf; /* packet filter structure */
169 caddr_t if_mcast; /* used by multicast code */
170 caddr_t if_mcast6; /* used by IPv6 multicast code */
171 caddr_t if_pf_kif; /* pf interface abstraction */
172 union {
173 /* carp if list (used by IFT_ETHER) */
174 struct carp_iflist carp_s;
175
176 /* index of carpdev (used by IFT_CARP) */
177 unsigned int carp_idx;
178 } if_carp_ptr;
179#define if_carp if_carp_ptr.carp_s
180#define if_carpdevidx if_carp_ptr.carp_idx
181 unsigned int if_index; /* [I] unique index for this if */
182 short if_timer; /* time 'til if_watchdog called */
183 unsigned short if_flags; /* [N] up/down, broadcast, etc. */
184 int if_xflags; /* [N] extra softnet flags */
185
186 /* Stats and other data about if. Should be in sync with if_data. */
187 u_char if_type;
188 u_char if_addrlen;
189 u_char if_hdrlen;
190 u_char if_link_state;
191 uint32_t if_mtu;
192 uint32_t if_metric;
193 uint64_t if_baudrate;
194 uint32_t if_capabilities;
195 uint32_t if_rdomain;
196 struct timeval if_lastchange; /* [c] last op. state change */
197 uint64_t if_data_counters[ifc_ncounters];
198
199 struct cpumem *if_counters; /* per cpu stats */
200 uint32_t if_hardmtu; /* [d] maximum MTU device supports */
201 char if_description[IFDESCRSIZE]; /* [c] interface description */
202 u_short if_rtlabelid; /* [c] next route label */
203 uint8_t if_priority; /* [c] route priority offset */
204 uint8_t if_llprio; /* [N] link layer priority */
205 struct timeout if_slowtimo; /* [I] watchdog timeout */
206 struct task if_watchdogtask; /* [I] watchdog task */
207 struct task if_linkstatetask; /* [I] task to do route updates */
208
209 /* procedure handles */
210 void (*if_input)(struct ifnet *, struct mbuf *, struct netstack *);
211 int (*if_bpf_mtap)(caddr_t, const struct mbuf *, u_int);
212 int (*if_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
213 struct rtentry *); /* output routine (enqueue) */
214 /* link level output function */
215 int (*if_ll_output)(struct ifnet *, struct mbuf *,
216 struct sockaddr *, struct rtentry *);
217 int (*if_enqueue)(struct ifnet *, struct mbuf *);
218 void (*if_start)(struct ifnet *); /* initiate output */
219 int (*if_ioctl)(struct ifnet *, u_long, caddr_t); /* ioctl hook */
220 void (*if_watchdog)(struct ifnet *); /* timer routine */
221 int (*if_wol)(struct ifnet *, int); /* WoL routine **/
222
223 /* queues */
224 struct ifqueue if_snd; /* transmit queue */
225 struct ifqueue **if_ifqs; /* [I] pointer to an array of sndqs */
226 void (*if_qstart)(struct ifqueue *);
227 unsigned int if_nifqs; /* [I] number of output queues */
228 unsigned int if_txmit; /* [c] txmitigation amount */
229
230 struct ifiqueue if_rcv; /* rx/input queue */
231 struct ifiqueue **if_iqs; /* [I] pointer to the array of iqs */
232 unsigned int if_niqs; /* [I] number of input queues */
233
234 struct sockaddr_dl *if_sadl; /* [N] pointer to our sockaddr_dl */
235
236 struct nd_ifinfo *if_nd; /* [I] IPv6 Neighbor Discovery info */
237};
238
239#define if_ipackets if_data_counters[ifc_ipackets]
240#define if_ierrors if_data_counters[ifc_ierrors]
241#define if_opackets if_data_counters[ifc_opackets]
242#define if_oerrors if_data_counters[ifc_oerrors]
243#define if_collisions if_data_counters[ifc_collisions]
244#define if_ibytes if_data_counters[ifc_ibytes]
245#define if_obytes if_data_counters[ifc_obytes]
246#define if_imcasts if_data_counters[ifc_imcasts]
247#define if_omcasts if_data_counters[ifc_omcasts]
248#define if_iqdrops if_data_counters[ifc_iqdrops]
249#define if_oqdrops if_data_counters[ifc_oqdrops]
250#define if_noproto if_data_counters[ifc_noproto]
251
252/*
253 * The ifaddr structure contains information about one address
254 * of an interface. They are maintained by the different address families,
255 * are allocated and attached when an address is set, and are linked
256 * together so all addresses for an interface can be located.
257 */
258struct ifaddr {
259 struct sockaddr *ifa_addr; /* address of interface */
260 struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */
261#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
262 struct sockaddr *ifa_netmask; /* used to determine subnet */
263 struct ifnet *ifa_ifp; /* back-pointer to interface */
264 TAILQ_ENTRY(ifaddr) ifa_list; /* [N] list of addresses for
265 interface */
266 TAILQ_ENTRY(ifaddr) ifa_tmplist;/* [T] temporary list */
267 u_int ifa_flags; /* interface flags, see below */
268 struct refcnt ifa_refcnt; /* number of `rt_ifa` references */
269 int ifa_metric; /* cost of going out this interface */
270};
271
272#define IFA_ROUTE 0x01 /* Auto-magically installed route */
273
274/*
275 * Interface multicast address.
276 */
277struct ifmaddr {
278 TAILQ_ENTRY(ifmaddr) ifma_list; /* [m] Per-interface list */
279 struct sockaddr *ifma_addr; /* [I] Protocol address */
280 struct refcnt ifma_refcnt; /* Count of references */
281 unsigned int ifma_ifidx; /* [I] Index of the interface */
282};
283
284/*
285 * interface groups
286 */
287
288struct ifg_group {
289 char ifg_group[IFNAMSIZ]; /* [I] group name */
290 u_int ifg_refcnt; /* [N] group reference count */
291 caddr_t ifg_pf_kif; /* [I] pf interface group */
292 int ifg_carp_demoted; /* [K] carp demotion counter */
293 TAILQ_HEAD(, ifg_member) ifg_members; /* [N] list of members per group */
294 TAILQ_ENTRY(ifg_group) ifg_next; /* [N] all groups are chained */
295
296 struct refcnt ifg_tmprefcnt;
297 TAILQ_ENTRY(ifg_group) ifg_tmplist; /* [T] temporary list */
298};
299
300struct ifg_member {
301 TAILQ_ENTRY(ifg_member) ifgm_next; /* [N] all members are chained */
302 struct ifnet *ifgm_ifp; /* [I] member interface */
303};
304
305struct ifg_list {
306 struct ifg_group *ifgl_group; /* [I] interface group */
307 TAILQ_ENTRY(ifg_list) ifgl_next; /* [N] all groups are chained */
308};
309
310#define IFNET_SLOWTIMO 1 /* granularity is 1 second */
311
312#define IF_TXMIT_MIN 1
313#define IF_TXMIT_DEFAULT 16
314
315/* default interface priorities */
316#define IF_WIRED_DEFAULT_PRIORITY 0
317#define IF_WIRELESS_DEFAULT_PRIORITY 4
318#define IF_WWAN_DEFAULT_PRIORITY 6
319#define IF_CARP_DEFAULT_PRIORITY 15
320
321/*
322 * Network stack input queues.
323 */
324struct niqueue {
325 struct mbuf_queue ni_q;
326 u_int ni_isr;
327};
328
329#define NIQUEUE_INITIALIZER(_len, _isr) \
330 { MBUF_QUEUE_INITIALIZER((_len), IPL_NET), (_isr) }
331
332int niq_enqueue(struct niqueue *, struct mbuf *);
333
334#define niq_dequeue(_q) mq_dequeue(&(_q)->ni_q)
335#define niq_delist(_q, _ml) mq_delist(&(_q)->ni_q, (_ml))
336#define niq_len(_q) mq_len(&(_q)->ni_q)
337#define niq_drops(_q) mq_drops(&(_q)->ni_q)
338#define sysctl_niq(_n, _l, _op, _olp, _np, _nl, _niq) \
339 sysctl_mq((_n), (_l), (_op), (_olp), (_np), (_nl), &(_niq)->ni_q)
340
341extern struct rwlock if_tmplist_lock;
342extern struct ifnet_head ifnetlist;
343
344void if_start(struct ifnet *);
345int if_enqueue(struct ifnet *, struct mbuf *);
346int if_enqueue_ifq(struct ifnet *, struct mbuf *);
347void if_input(struct ifnet *, struct mbuf_list *);
348void if_vinput(struct ifnet *, struct mbuf *, struct netstack *);
349void if_input_process(struct ifnet *, struct mbuf_list *, unsigned int);
350void if_input_proto(struct ifnet *, struct mbuf *,
351 void (*)(struct ifnet *, struct mbuf *, struct netstack *),
352 struct netstack *);
353int if_input_local(struct ifnet *, struct mbuf *, sa_family_t,
354 struct netstack *);
355int if_output_ml(struct ifnet *, struct mbuf_list *,
356 struct sockaddr *, struct rtentry *);
357int if_output_mq(struct ifnet *, struct mbuf_queue *, unsigned int *,
358 struct sockaddr *, struct rtentry *);
359int if_output_tso(struct ifnet *, struct mbuf **, struct sockaddr *,
360 struct rtentry *, u_int);
361int if_output_local(struct ifnet *, struct mbuf *, sa_family_t);
362void if_rtrequest_dummy(struct ifnet *, int, struct rtentry *);
363void p2p_rtrequest(struct ifnet *, int, struct rtentry *);
364void p2p_input(struct ifnet *, struct mbuf *, struct netstack *);
365int p2p_bpf_mtap(caddr_t, const struct mbuf *, u_int);
366
367/* this is a helper for if_input_process and similar functions */
368static inline void
369if_input_process_proto(struct ifnet *ifp, struct mbuf *m, struct netstack *ns)
370{
371 void (*input)(struct ifnet *, struct mbuf *, struct netstack *);
372 input = m->m_pkthdr.ph_cookie;
373 (*input)(ifp, m, ns);
374}
375
376struct ifaddr *ifa_ifwithaddr(const struct sockaddr *, u_int);
377struct ifaddr *ifa_ifwithdstaddr(const struct sockaddr *, u_int);
378struct ifaddr *ifaof_ifpforaddr(const struct sockaddr *, struct ifnet *);
379struct ifaddr *ifaref(struct ifaddr *);
380void ifafree(struct ifaddr *);
381
382int if_isconnected(const struct ifnet *, unsigned int);
383
384void if_clone_attach(struct if_clone *);
385
386int if_clone_create(const char *, int);
387int if_clone_destroy(const char *);
388
389struct if_clone *
390 if_clone_lookup(const char *, int *);
391
392void ifa_add(struct ifnet *, struct ifaddr *);
393void ifa_del(struct ifnet *, struct ifaddr *);
394void ifa_update_broadaddr(struct ifnet *, struct ifaddr *,
395 struct sockaddr *);
396
397void if_addrhook_add(struct ifnet *, struct task *);
398void if_addrhook_del(struct ifnet *, struct task *);
399void if_addrhooks_run(struct ifnet *);
400void if_linkstatehook_add(struct ifnet *, struct task *);
401void if_linkstatehook_del(struct ifnet *, struct task *);
402void if_detachhook_add(struct ifnet *, struct task *);
403void if_detachhook_del(struct ifnet *, struct task *);
404
405void if_rxr_livelocked(struct if_rxring *);
406void if_rxr_init(struct if_rxring *, u_int, u_int);
407u_int if_rxr_get(struct if_rxring *, u_int);
408
409#define if_rxr_put(_r, _c) do { (_r)->rxr_alive -= (_c); } while (0)
410#define if_rxr_needrefill(_r) ((_r)->rxr_alive < (_r)->rxr_lwm)
411#define if_rxr_inuse(_r) ((_r)->rxr_alive)
412#define if_rxr_cwm(_r) ((_r)->rxr_cwm)
413
414int if_rxr_info_ioctl(struct if_rxrinfo *, u_int, struct if_rxring_info *);
415int if_rxr_ioctl(struct if_rxrinfo *, const char *, u_int,
416 struct if_rxring *);
417
418void if_counters_alloc(struct ifnet *);
419void if_counters_free(struct ifnet *);
420
421int if_txhprio_l2_check(int);
422int if_txhprio_l3_check(int);
423int if_rxhprio_l2_check(int);
424int if_rxhprio_l3_check(int);
425
426#endif /* _KERNEL */
427
428#endif /* _NET_IF_VAR_H_ */