Commit | Line | Data |
---|---|---|
984263bc MD |
1 | /* |
2 | * Copyright (c) 1982, 1986, 1989, 1993 | |
3 | * The Regents of the University of California. All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
2c64e990 | 13 | * 3. Neither the name of the University nor the names of its contributors |
984263bc MD |
14 | * may be used to endorse or promote products derived from this software |
15 | * without specific prior written permission. | |
16 | * | |
17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
27 | * SUCH DAMAGE. | |
28 | * | |
29 | * From: @(#)if.h 8.1 (Berkeley) 6/10/93 | |
30 | * $FreeBSD: src/sys/net/if_var.h,v 1.18.2.16 2003/04/15 18:11:19 fjoe Exp $ | |
31 | */ | |
32 | ||
33 | #ifndef _NET_IF_VAR_H_ | |
34 | #define _NET_IF_VAR_H_ | |
35 | ||
78195a76 MD |
36 | #ifndef _SYS_SERIALIZE_H_ |
37 | #include <sys/serialize.h> | |
38 | #endif | |
1bd40720 MD |
39 | #ifndef _NET_IF_H_ |
40 | #include <net/if.h> | |
41 | #endif | |
9683f229 MD |
42 | #ifndef _SYS_MUTEX_H_ |
43 | #include <sys/mutex.h> | |
44 | #endif | |
78195a76 | 45 | |
984263bc MD |
46 | /* |
47 | * Structures defining a network interface, providing a packet | |
48 | * transport mechanism (ala level 0 of the PUP protocols). | |
49 | * | |
50 | * Each interface accepts output datagrams of a specified maximum | |
51 | * length, and provides higher level routines with input datagrams | |
52 | * received from its medium. | |
53 | * | |
78195a76 | 54 | * Output occurs when the routine if_output is called, with four parameters: |
376a6a2a | 55 | * |
78195a76 | 56 | * ifp->if_output(ifp, m, dst, rt) |
376a6a2a | 57 | * |
984263bc MD |
58 | * Here m is the mbuf chain to be sent and dst is the destination address. |
59 | * The output routine encapsulates the supplied datagram if necessary, | |
60 | * and then transmits it on its medium. | |
61 | * | |
62 | * On input, each interface unwraps the data received by it, and either | |
63 | * places it on the input queue of a internetwork datagram routine | |
3013ac0e | 64 | * and posts the associated software interrupt, or passes the datagram to |
376a6a2a FF |
65 | * the routine if_input. It is called with four parameters: |
66 | * | |
67 | * ifp->if_input(ifp, m, pi, cpuid) | |
68 | * | |
69 | * Here m is the mbuf chain to be received. The input routine removes the | |
70 | * protocol dependent header if necessary. A driver may also call using | |
71 | * custom struct pktinfo reference pi and a cpuid to take advantage of | |
72 | * hardware supplied information. Otherwise, the defaults for pi and cpuid | |
73 | * are as follows: | |
74 | * | |
75 | * ifp->if_input(ifp, m, NULL, -1); | |
984263bc MD |
76 | * |
77 | * Routines exist for locating interfaces by their addresses | |
78 | * or for locating a interface on a certain network, as well as more general | |
79 | * routing and gateway routines maintaining information used to locate | |
80 | * interfaces. These routines live in the files if.c and route.c | |
81 | */ | |
82 | ||
984263bc MD |
83 | /* |
84 | * Forward structure declarations for function prototypes [sic]. | |
85 | */ | |
03d44125 | 86 | struct rtentry; /* ifa_rtrequest */ |
984263bc | 87 | struct socket; |
bd4539cc | 88 | struct ucred; |
78195a76 | 89 | struct lwkt_serialize; |
b2632176 SZ |
90 | struct ifaddr_container; |
91 | struct ifaddr; | |
2eb0d069 | 92 | struct pktinfo; |
b3a7093f | 93 | struct ifpoll_info; |
e1fcdad7 | 94 | struct ifdata_pcpu; |
984263bc MD |
95 | |
96 | #include <sys/queue.h> /* get TAILQ macros */ | |
97 | ||
4d723e5a JS |
98 | #include <net/altq/if_altq.h> |
99 | ||
984263bc | 100 | #ifdef _KERNEL |
f2bd8b67 | 101 | #include <sys/eventhandler.h> |
984263bc | 102 | #include <sys/mbuf.h> |
4986965b | 103 | #include <sys/thread2.h> |
984263bc MD |
104 | #endif /* _KERNEL */ |
105 | ||
1550dfd9 MD |
106 | #define IF_DUNIT_NONE -1 |
107 | ||
233c8570 AL |
108 | /* |
109 | * we use TAILQs so that the order of instantiation is preserved in | |
110 | * the list. | |
111 | */ | |
112 | TAILQ_HEAD(ifnethead, ifnet); | |
113 | TAILQ_HEAD(ifaddrhead, ifaddr_container); | |
441d34b2 | 114 | TAILQ_HEAD(ifmultihead, ifmultiaddr); |
233c8570 | 115 | TAILQ_HEAD(ifgrouphead, ifg_group); |
984263bc MD |
116 | |
117 | /* | |
bc26e110 | 118 | * Structure defining a mbuf queue. |
984263bc | 119 | */ |
bc26e110 | 120 | struct ifqueue { |
984263bc MD |
121 | struct mbuf *ifq_head; |
122 | struct mbuf *ifq_tail; | |
123 | int ifq_len; | |
124 | int ifq_maxlen; | |
125 | int ifq_drops; | |
126 | }; | |
127 | ||
2b71c8f1 | 128 | /* |
9b4bf5e3 SZ |
129 | * Note of IFPOLL_ENABLE |
130 | * 1) Any file(*.c) that depends on IFPOLL_ENABLE supports in this | |
131 | * file should include opt_ifpoll.h at its beginning. | |
132 | * 2) When struct changes, which are conditioned by IFPOLL_ENABLE, | |
2b71c8f1 | 133 | * are to be introduced, please keep the struct's size and layout |
9b4bf5e3 SZ |
134 | * same, no matter whether IFPOLL_ENABLE is defined or not. |
135 | * See ifnet.if_npoll and ifnet.if_npoll_unused for example. | |
2b71c8f1 SZ |
136 | */ |
137 | ||
bc26e110 SZ |
138 | /* |
139 | * Network serialize/deserialize types | |
140 | */ | |
a3dd34d2 | 141 | enum ifnet_serialize { |
bc26e110 | 142 | IFNET_SERIALIZE_ALL /* all serializers */ |
a3dd34d2 | 143 | }; |
a3dd34d2 | 144 | |
1afbcbac MD |
145 | #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) |
146 | ||
984263bc MD |
147 | /* |
148 | * Structure defining a network interface. | |
149 | * | |
150 | * (Would like to call this struct ``if'', but C isn't PL/1.) | |
151 | */ | |
152 | ||
153 | /* | |
bc26e110 SZ |
154 | * NB: For DragonFlyBSD, it is assumed that each NIC driver's softc starts |
155 | * with one of these structures, typically held within an arpcom structure. | |
156 | * | |
984263bc MD |
157 | * struct <foo>_softc { |
158 | * struct arpcom { | |
159 | * struct ifnet ac_if; | |
160 | * ... | |
161 | * } <arpcom> ; | |
b44c913f | 162 | * ... |
984263bc MD |
163 | * }; |
164 | * | |
165 | * The assumption is used in a number of places, including many | |
166 | * files in sys/net, device drivers, and sys/dev/mii.c:miibus_attach(). | |
bc26e110 | 167 | * |
984263bc MD |
168 | * Unfortunately devices' softc are opaque, so we depend on this layout |
169 | * to locate the struct ifnet from the softc in the generic code. | |
170 | * | |
bc26e110 SZ |
171 | * |
172 | * | |
173 | * MPSAFE NOTES: | |
78195a76 | 174 | * |
a3dd34d2 SZ |
175 | * ifnet is protected by calling if_serialize, if_tryserialize and |
176 | * if_deserialize serialize functions with the ifnet_serialize parameter. | |
bc26e110 SZ |
177 | * Callers of if_ioctl, if_watchdog, if_init, if_resolvemulti, and if_npoll |
178 | * should call the ifnet serialize functions with IFNET_SERIALIZE_ALL. | |
179 | * | |
180 | * if_snd subqueues are protected by its own serializers. Callers of | |
181 | * if_start should call ifsq_serialiize_hw(), ifsq_deserialize_hw() and | |
182 | * ifsq_tryserialize_hw() to properly serialize hardware for transmission. | |
183 | * | |
184 | * Caller of if_output MUST NOT serialize ifnet or if_snd by calling | |
185 | * the related serialize functions. | |
186 | * | |
2949c680 AL |
187 | * For better transmission performance, driver should setup if_snd subqueue |
188 | * owner's cpuid properly using ifsq_set_cpuid() (or ifq_set_cpuid(), if not | |
189 | * multiple transmit queue capable). Normally, the if_snd subqueue owner's | |
190 | * cpu is the one that processing the transmission interruption. And in | |
191 | * driver, direct call of if_start should be avoided, use ifsq_devstart() or | |
bc26e110 SZ |
192 | * ifsq_devstart_sched() instead (or if_devstart()/if_devstart_sched(), if |
193 | * not multiple transmit queue capable). | |
194 | * | |
195 | * | |
196 | * | |
197 | * STATISTICS: | |
198 | * | |
199 | * if_data is no longer used to hold per interface statistics, so DO NOT use | |
200 | * the old style ifp->if_ipackets++ to update statistics; instead IFNET_STAT_ | |
201 | * macros should be used. | |
202 | * | |
203 | * | |
a3dd34d2 | 204 | * |
bc26e110 | 205 | * SINGLE SERIALIZER MODE: |
a3dd34d2 | 206 | * |
bc26e110 SZ |
207 | * In this mode, driver MUST NOT setup if_serialize, if_deserialize, |
208 | * if_tryserialize or if_serialize_assert. Driver could supply its own | |
209 | * serializer to be used (through the type specific attach function, e.g. | |
210 | * ether_ifattach()) or it could depend on the default serializer. In this | |
211 | * mode if_serializer will be setup properly. | |
78195a76 MD |
212 | * |
213 | * If a device driver installs the same serializer for its interrupt | |
214 | * as for ifnet, then the driver only really needs to worry about further | |
bc26e110 SZ |
215 | * serialization in timeout based entry points and device_method_t entry |
216 | * points. All other entry points will already be serialized. | |
217 | * | |
218 | * | |
219 | * | |
220 | * MULTI SERIALIZERS MODE: | |
221 | * | |
222 | * In this mode, driver MUST setup if_serialize, if_deserialize, | |
223 | * if_tryserialize and if_serialize_assert. Driver MUST NOT supply its own | |
224 | * serializer to be used. In this mode, if_serializer will be left as NULL. | |
225 | * And driver MUST setup if_snd subqueues' hardware serailizer properly by | |
226 | * calling ifsq_set_hw_serialize(). | |
227 | * | |
228 | * | |
229 | * | |
230 | * MULTIPLE TRANSMIT QUEUES: | |
231 | * | |
232 | * This should be implemented in "MULTI SERIALIZERS MODE". Legacy if_watchdog | |
233 | * method SHOULD NOT be used. | |
234 | * | |
235 | * 1) Attach | |
236 | * | |
237 | * Before the type specific attach, e.g. ether_ifattach(), driver should | |
238 | * setup the transmit queue count and cpuid to subqueue mapping method | |
239 | * properly (assume QCOUNT is power of 2): | |
240 | * | |
241 | * ifq_set_subq_cnt(&ifp->if_snd, QCOUNT); | |
c807e2c7 SZ |
242 | * ifp->if_mapsubq = ifq_mapsubq_modulo; |
243 | * ifq_set_subq_divisor(&ifp->if_snd, QCOUNT); | |
bc26e110 SZ |
244 | * |
245 | * After the type specific attach, driver should setup the subqueues owner | |
246 | * cpu, serializer and watchdog properly: | |
247 | * | |
248 | * for (i = 0; i < QCOUNT, ++i) { | |
249 | * struct ifaltq_subque *ifsq = ifq_get_subq(&ifp->if_snd, i); | |
250 | * | |
251 | * ifsq_set_cpuid(ifsq, Q_CPUID); | |
252 | * ifsq_set_hw_serialize(ifsq, Q_SLIZE); | |
e2292763 | 253 | * ifsq_watchdog_init(Q_WDOG, ifsq, Q_WDOG_FUNC, IF_WDOG_FLAGS); |
bc26e110 SZ |
254 | * } |
255 | * | |
256 | * Q_CPUID, the cpu which handles the hardware transmit queue interrupt | |
257 | * Q_SLIZE, the serializer protects the hardware transmit queue | |
258 | * Q_WDOG, per hardware transmit queue watchdog handler, struct ifsubq_watchdog | |
259 | * Q_WDOG_FUNC, watchdog function, probably should reset hardware | |
e2292763 MD |
260 | * IF_WDOG_FLAGS, various IF_WDOG_* flags (typically 0) |
261 | * | |
262 | * The watchdog function is called on the 1->0 transition of wd_timer by | |
263 | * default. Flags modify thiis behavior: | |
264 | * IF_WDOG_ALLTICKS Issue callback on all wd_timer transitions | |
265 | * IF_WDOG_LASTTICK Issue callback on 2->1 and 1->0 | |
bc26e110 SZ |
266 | * |
267 | * 2) Stop | |
268 | * | |
269 | * Make sure per hardware transmit queue watchdog is stopped and oactive is | |
270 | * cleared: | |
271 | * | |
272 | * for (i = 0; i < QCOUNT, ++i) { | |
273 | * ifsq_clr_oactive(ifsq); | |
274 | * ifsq_watchdog_stop(Q_WDOG); | |
275 | * } | |
276 | * | |
277 | * 3) Initialize | |
278 | * | |
279 | * Make sure per hardware transmit queue watchdog is started and oactive is | |
280 | * cleared: | |
281 | * | |
282 | * for (i = 0; i < QCOUNT, ++i) { | |
283 | * ifsq_clr_oactive(ifsq); | |
284 | * ifsq_watchdog_start(Q_WDOG); | |
285 | * } | |
286 | * | |
287 | * 4) if_start | |
288 | * | |
289 | * if_start takes subqueue as parameter, so instead of using ifq_ functions | |
290 | * ifsq_ functions should be used. If device could not be programmed to | |
291 | * transmit when no media link is not up, MAKE SURE to purge the subqueue: | |
292 | * | |
293 | * if ((ifp->if_flags & IFF_RUNNING) == 0 || ifsq_is_oactive(ifsq)) | |
294 | * return; | |
295 | * if (NO_LINK) { | |
296 | * ifsq_purge(ifsq); | |
297 | * return; | |
298 | * } | |
299 | * for (;;) { | |
300 | * if (NO_FREE_DESC) { | |
301 | * ifsq_set_oactive(ifsq); | |
302 | * break; | |
303 | * } | |
6dadc833 | 304 | * m = ifsq_dequeue(ifsq); |
bc26e110 SZ |
305 | * if (m != NULL) |
306 | * DRIVER_ENCAP(m); | |
307 | * Q_WDOG.wd_timer = WDOG_TIMEOUT; | |
308 | * } | |
309 | * | |
310 | * 5) Transmission done, e.g. transmit queue interrupt processing | |
311 | * | |
312 | * Same as if_start, ifsq_ functions should be used: | |
313 | * | |
314 | * DRIVER_COLLECT_DESC(); | |
315 | * if (HAS_FREE_DESC) | |
316 | * ifsq_clr_oactive(ifsq); | |
317 | * if (NO_PENDING_DESC) | |
318 | * Q_WDOG.wd_timer = 0; | |
319 | * if (!ifsq_is_empty(ifsq)) | |
320 | * ifsq_devstart(ifsq); | |
984263bc MD |
321 | */ |
322 | struct ifnet { | |
323 | void *if_softc; /* pointer to driver state */ | |
30809119 | 324 | void *if_l2com; /* pointer to protocol bits */ |
f23061d4 | 325 | TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ |
2949c680 AL |
326 | char if_xname[IFNAMSIZ]; /* external name (name + unit); |
327 | * can be renamed (SIOCSIFNAME) */ | |
3e4a09e7 MD |
328 | const char *if_dname; /* driver name */ |
329 | int if_dunit; /* unit or IF_DUNIT_NONE */ | |
9433ab01 | 330 | void *if_vlantrunks; /* vlan trunks */ |
bc26e110 | 331 | struct ifaddrhead *if_addrheads; /* per-cpu per-if addresses */ |
984263bc | 332 | int if_pcount; /* number of promiscuous listeners */ |
5bd4422e | 333 | void *if_carp; /* carp interfaces */ |
984263bc MD |
334 | struct bpf_if *if_bpf; /* packet filter structure */ |
335 | u_short if_index; /* numeric abbreviation for this if */ | |
984263bc | 336 | short if_timer; /* time 'til if_watchdog called */ |
3e4a09e7 | 337 | int if_flags; /* up/down, broadcast, etc. */ |
34b4b6a2 JS |
338 | int if_capabilities; /* interface capabilities */ |
339 | int if_capenable; /* enabled features */ | |
984263bc MD |
340 | void *if_linkmib; /* link-type-specific MIB data */ |
341 | size_t if_linkmiblen; /* length of above data */ | |
bc26e110 | 342 | struct if_data if_data; /* NOTE: stats are in if_data_pcpu */ |
984263bc MD |
343 | struct ifmultihead if_multiaddrs; /* multicast addresses configured */ |
344 | int if_amcount; /* number of all-multicast requests */ | |
233c8570 AL |
345 | TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if; |
346 | * protected by 'ifgroup_lock' */ | |
347 | ||
348 | /* | |
349 | * procedure handlers | |
350 | */ | |
984263bc MD |
351 | int (*if_output) /* output routine (enqueue) */ |
352 | (struct ifnet *, struct mbuf *, struct sockaddr *, | |
353 | struct rtentry *); | |
3013ac0e | 354 | void (*if_input) /* input routine from hardware driver */ |
73029d08 FF |
355 | (struct ifnet *, struct mbuf *, |
356 | const struct pktinfo *pi, int cpuid); | |
984263bc | 357 | void (*if_start) /* initiate output routine */ |
f0a26983 | 358 | (struct ifnet *, struct ifaltq_subque *); |
984263bc | 359 | int (*if_ioctl) /* ioctl routine */ |
bd4539cc | 360 | (struct ifnet *, u_long, caddr_t, struct ucred *); |
984263bc MD |
361 | void (*if_watchdog) /* timer routine */ |
362 | (struct ifnet *); | |
bc26e110 | 363 | void (*if_init) /* init routine */ |
984263bc MD |
364 | (void *); |
365 | int (*if_resolvemulti) /* validate/resolve multicast */ | |
366 | (struct ifnet *, struct sockaddr **, struct sockaddr *); | |
f6994c54 | 367 | char *if_description; /* interface description */ |
bc26e110 | 368 | int (*if_mapsubq) /* cpuid to if_snd subqueue map */ |
2cc2f639 | 369 | (struct ifaltq *, int); |
9b4bf5e3 | 370 | int if_unused2; |
bc26e110 SZ |
371 | |
372 | /* | |
373 | * ifnet serialize functions | |
374 | */ | |
a3dd34d2 SZ |
375 | void (*if_serialize) |
376 | (struct ifnet *, enum ifnet_serialize); | |
377 | void (*if_deserialize) | |
378 | (struct ifnet *, enum ifnet_serialize); | |
379 | int (*if_tryserialize) | |
380 | (struct ifnet *, enum ifnet_serialize); | |
2c9effcf SZ |
381 | #ifdef INVARIANTS |
382 | void (*if_serialize_assert) | |
383 | (struct ifnet *, enum ifnet_serialize, boolean_t); | |
384 | #else | |
4aa0b844 | 385 | /* Place holder */ |
2c9effcf | 386 | void (*if_serialize_unused)(void); |
b3a7093f | 387 | #endif |
bc26e110 | 388 | |
b3a7093f | 389 | #ifdef IFPOLL_ENABLE |
bc26e110 | 390 | void (*if_npoll) /* polling config */ |
b3a7093f SZ |
391 | (struct ifnet *, struct ifpoll_info *); |
392 | #else | |
4aa0b844 | 393 | /* Place holder */ |
f994de37 | 394 | void (*if_npoll_unused)(void); |
2c9effcf | 395 | #endif |
e41e61d5 | 396 | int if_tsolen; /* max TSO length */ |
bc26e110 | 397 | struct ifaltq if_snd; /* output subqueues */ |
c401f0fd | 398 | const uint8_t *if_broadcastaddr; |
db37145f | 399 | void *if_bridge; /* bridge glue */ |
50b1e235 | 400 | void *if_lagg; /* lagg glue */ |
698ac46c | 401 | void *if_afdata[AF_MAX]; |
141697b6 | 402 | struct ifaddr *if_lladdr; |
bc26e110 SZ |
403 | |
404 | /* serializer, in single serializer mode */ | |
405 | struct lwkt_serialize *if_serializer; | |
406 | /* | |
407 | * default serializer, in single serializer mode, | |
408 | * if driver does not supply one | |
409 | */ | |
410 | struct lwkt_serialize if_default_serializer; | |
411 | ||
dfd3b18b | 412 | int if_unused4; |
bc26e110 SZ |
413 | struct ifdata_pcpu *if_data_pcpu; /* per-cpu stats */ |
414 | void *if_pf_kif; /* pf interface */ | |
ae6d2ace SZ |
415 | |
416 | /* | |
417 | * Mbuf clusters/jclusters limits should be increased | |
418 | * by if_nmbclusters/if_nmbjclusters. Mainly for mbuf | |
419 | * clusters/jclusters that could sit on the device | |
420 | * queues, e.g. reception queues, for quite some time. | |
421 | */ | |
422 | int if_nmbclusters; | |
423 | int if_nmbjclusters; | |
984263bc MD |
424 | }; |
425 | typedef void if_init_f_t (void *); | |
426 | ||
984263bc MD |
427 | #define if_mtu if_data.ifi_mtu |
428 | #define if_type if_data.ifi_type | |
7485684f | 429 | #define if_physical if_data.ifi_physical |
984263bc MD |
430 | #define if_addrlen if_data.ifi_addrlen |
431 | #define if_hdrlen if_data.ifi_hdrlen | |
432 | #define if_metric if_data.ifi_metric | |
6de83abe | 433 | #define if_link_state if_data.ifi_link_state |
984263bc MD |
434 | #define if_baudrate if_data.ifi_baudrate |
435 | #define if_hwassist if_data.ifi_hwassist | |
436 | #define if_ipackets if_data.ifi_ipackets | |
437 | #define if_ierrors if_data.ifi_ierrors | |
438 | #define if_opackets if_data.ifi_opackets | |
439 | #define if_oerrors if_data.ifi_oerrors | |
440 | #define if_collisions if_data.ifi_collisions | |
441 | #define if_ibytes if_data.ifi_ibytes | |
442 | #define if_obytes if_data.ifi_obytes | |
443 | #define if_imcasts if_data.ifi_imcasts | |
444 | #define if_omcasts if_data.ifi_omcasts | |
445 | #define if_iqdrops if_data.ifi_iqdrops | |
446 | #define if_noproto if_data.ifi_noproto | |
6de344ba | 447 | #define if_oqdrops if_data.ifi_oqdrops |
984263bc | 448 | #define if_lastchange if_data.ifi_lastchange |
7485684f | 449 | #define if_recvquota if_data.ifi_recvquota |
984263bc | 450 | #define if_xmitquota if_data.ifi_xmitquota |
7485684f | 451 | #define if_rawoutput(if, m, sa) if_output(if, m, sa, NULL) |
984263bc MD |
452 | |
453 | /* for compatibility with other BSDs */ | |
984263bc MD |
454 | #define if_list if_link |
455 | ||
bc26e110 SZ |
456 | /* |
457 | * Per-cpu interface statistics | |
458 | */ | |
e1fcdad7 SZ |
459 | struct ifdata_pcpu { |
460 | u_long ifd_ipackets; /* packets received on interface */ | |
461 | u_long ifd_ierrors; /* input errors on interface */ | |
462 | u_long ifd_opackets; /* packets sent on interface */ | |
463 | u_long ifd_oerrors; /* output errors on interface */ | |
464 | u_long ifd_collisions; /* collisions on csma interfaces */ | |
465 | u_long ifd_ibytes; /* total number of octets received */ | |
466 | u_long ifd_obytes; /* total number of octets sent */ | |
467 | u_long ifd_imcasts; /* packets received via multicast */ | |
468 | u_long ifd_omcasts; /* packets sent via multicast */ | |
469 | u_long ifd_iqdrops; /* dropped on input, this interface */ | |
470 | u_long ifd_noproto; /* destined for unsupported protocol */ | |
6de344ba | 471 | u_long ifd_oqdrops; /* dropped on output, this interface */ |
e1fcdad7 SZ |
472 | } __cachealign; |
473 | ||
bc26e110 | 474 | #endif /* _KERNEL || _KERNEL_STRUCTURES */ |
b2632176 | 475 | |
984263bc | 476 | /* |
bc26e110 | 477 | * ifqueue operation macros |
984263bc MD |
478 | */ |
479 | #define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) | |
480 | #define IF_DROP(ifq) ((ifq)->ifq_drops++) | |
8e22f1e8 | 481 | #define IF_QLEN(ifq) ((ifq)->ifq_len) |
fd81ccf9 | 482 | #define IF_QEMPTY(ifq) (IF_QLEN(ifq) == 0) |
1afbcbac | 483 | |
501ade14 | 484 | #define IF_ENQUEUE(ifq, m) do { \ |
716a081c SW |
485 | (m)->m_nextpkt = NULL; \ |
486 | if ((ifq)->ifq_tail == NULL) \ | |
501ade14 HT |
487 | (ifq)->ifq_head = m; \ |
488 | else \ | |
489 | (ifq)->ifq_tail->m_nextpkt = m; \ | |
490 | (ifq)->ifq_tail = m; \ | |
491 | (ifq)->ifq_len++; \ | |
492 | } while (0) | |
1afbcbac | 493 | |
501ade14 HT |
494 | #define IF_PREPEND(ifq, m) do { \ |
495 | (m)->m_nextpkt = (ifq)->ifq_head; \ | |
716a081c | 496 | if ((ifq)->ifq_tail == NULL) \ |
501ade14 HT |
497 | (ifq)->ifq_tail = (m); \ |
498 | (ifq)->ifq_head = (m); \ | |
499 | (ifq)->ifq_len++; \ | |
500 | } while (0) | |
1afbcbac | 501 | |
501ade14 HT |
502 | #define IF_DEQUEUE(ifq, m) do { \ |
503 | (m) = (ifq)->ifq_head; \ | |
504 | if (m) { \ | |
716a081c SW |
505 | if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \ |
506 | (ifq)->ifq_tail = NULL; \ | |
507 | (m)->m_nextpkt = NULL; \ | |
501ade14 HT |
508 | (ifq)->ifq_len--; \ |
509 | } \ | |
510 | } while (0) | |
8e22f1e8 JS |
511 | |
512 | #define IF_POLL(ifq, m) ((m) = (ifq)->ifq_head) | |
513 | ||
8bde602d JH |
514 | #define IF_DRAIN(ifq) do { \ |
515 | struct mbuf *m; \ | |
516 | while (1) { \ | |
517 | IF_DEQUEUE(ifq, m); \ | |
518 | if (m == NULL) \ | |
519 | break; \ | |
520 | m_freem(m); \ | |
521 | } \ | |
522 | } while (0) | |
984263bc MD |
523 | |
524 | #ifdef _KERNEL | |
525 | ||
2c9effcf SZ |
526 | #ifdef INVARIANTS |
527 | #define ASSERT_IFNET_SERIALIZED_ALL(ifp) \ | |
528 | (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_ALL, TRUE) | |
529 | #define ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp) \ | |
530 | (ifp)->if_serialize_assert((ifp), IFNET_SERIALIZE_ALL, FALSE) | |
2c9effcf SZ |
531 | #else |
532 | #define ASSERT_IFNET_SERIALIZED_ALL(ifp) ((void)0) | |
533 | #define ASSERT_IFNET_NOT_SERIALIZED_ALL(ifp) ((void)0) | |
2c9effcf SZ |
534 | #endif |
535 | ||
a3dd34d2 SZ |
536 | static __inline void |
537 | ifnet_serialize_all(struct ifnet *_ifp) | |
538 | { | |
539 | _ifp->if_serialize(_ifp, IFNET_SERIALIZE_ALL); | |
540 | } | |
541 | ||
542 | static __inline void | |
543 | ifnet_deserialize_all(struct ifnet *_ifp) | |
544 | { | |
545 | _ifp->if_deserialize(_ifp, IFNET_SERIALIZE_ALL); | |
546 | } | |
547 | ||
548 | static __inline int | |
549 | ifnet_tryserialize_all(struct ifnet *_ifp) | |
550 | { | |
551 | return _ifp->if_tryserialize(_ifp, IFNET_SERIALIZE_ALL); | |
552 | } | |
553 | ||
984263bc MD |
554 | /* |
555 | * 72 was chosen below because it is the size of a TCP/IP | |
556 | * header (40) + the minimum mss (32). | |
557 | */ | |
558 | #define IF_MINMTU 72 | |
559 | #define IF_MAXMTU 65535 | |
560 | ||
561 | #endif /* _KERNEL */ | |
562 | ||
1b562c24 SZ |
563 | struct in_ifaddr; |
564 | ||
565 | struct in_ifaddr_container { | |
566 | struct in_ifaddr *ia; | |
567 | LIST_ENTRY(in_ifaddr_container) ia_hash; | |
568 | /* entry in bucket of inet addresses */ | |
569 | TAILQ_ENTRY(in_ifaddr_container) ia_link; | |
570 | /* list of internet addresses */ | |
571 | struct ifaddr_container *ia_ifac; /* parent ifaddr_container */ | |
572 | }; | |
573 | ||
bc26e110 SZ |
574 | /* |
575 | * Per-cpu ifaddr container: | |
576 | * - per-cpu ifaddr reference count | |
577 | * - linkage to per-cpu addresses lists | |
578 | * - per-cpu ifaddr statistics | |
579 | */ | |
b2632176 SZ |
580 | struct ifaddr_container { |
581 | #define IFA_CONTAINER_MAGIC 0x19810219 | |
582 | #define IFA_CONTAINER_DEAD 0xc0dedead | |
583 | uint32_t ifa_magic; /* IFA_CONTAINER_MAGIC */ | |
584 | struct ifaddr *ifa; | |
585 | TAILQ_ENTRY(ifaddr_container) ifa_link; /* queue macro glue */ | |
586 | u_int ifa_refcnt; /* references to this structure */ | |
5bd4422e SZ |
587 | uint16_t ifa_listmask; /* IFA_LIST_ */ |
588 | uint16_t ifa_prflags; /* protocol specific flags */ | |
1b562c24 | 589 | |
572fa6a2 SZ |
590 | u_long ifa_ipackets; /* packets received on addr */ |
591 | u_long ifa_ibytes; /* bytes received on addr */ | |
592 | u_long ifa_opackets; /* packets sent on addr */ | |
593 | u_long ifa_obytes; /* bytes sent on addr */ | |
594 | ||
1b562c24 SZ |
595 | /* |
596 | * Protocol specific states | |
597 | */ | |
598 | union { | |
599 | struct in_ifaddr_container u_in_ifac; | |
600 | } ifa_proto_u; | |
7d1c3473 | 601 | } __cachealign; |
b2632176 | 602 | |
5bd4422e SZ |
603 | #define IFA_LIST_IFADDRHEAD 0x01 /* on ifnet.if_addrheads[cpuid] */ |
604 | #define IFA_LIST_IN_IFADDRHEAD 0x02 /* on in_ifaddrheads[cpuid] */ | |
605 | #define IFA_LIST_IN_IFADDRHASH 0x04 /* on in_ifaddrhashtbls[cpuid] */ | |
606 | ||
607 | #define IFA_PRF_FLAG0 0x01 | |
608 | #define IFA_PRF_FLAG1 0x02 | |
609 | #define IFA_PRF_FLAG2 0x04 | |
610 | #define IFA_PRF_FLAG3 0x08 | |
40f667f2 | 611 | |
984263bc MD |
612 | /* |
613 | * The ifaddr structure contains information about one address | |
614 | * of an interface. They are maintained by the different address families, | |
615 | * are allocated and attached when an address is set, and are linked | |
616 | * together so all addresses for an interface can be located. | |
bc26e110 SZ |
617 | * |
618 | * NOTE: | |
619 | * Statistics are no longer stored in if_data, instead, they are stored | |
620 | * in the per-cpu ifaddr_container. So don't use the old style | |
621 | * ifa->if_ipackets++ to update statistics, use IFA_STAT_ macros. | |
984263bc MD |
622 | */ |
623 | struct ifaddr { | |
624 | struct sockaddr *ifa_addr; /* address of interface */ | |
625 | struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ | |
626 | #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ | |
627 | struct sockaddr *ifa_netmask; /* used to determine subnet */ | |
628 | struct if_data if_data; /* not all members are meaningful */ | |
629 | struct ifnet *ifa_ifp; /* back-pointer to interface */ | |
b2632176 | 630 | void *ifa_link_pad; |
bc26e110 | 631 | struct ifaddr_container *ifa_containers; /* per-cpu data */ |
984263bc | 632 | void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ |
3ffea39d | 633 | (int, struct rtentry *); |
984263bc | 634 | u_short ifa_flags; /* mostly rt_flags for cloning */ |
d5a2b87c | 635 | int ifa_ncnt; /* # of valid ifaddr_container */ |
984263bc MD |
636 | int ifa_metric; /* cost of going out this interface */ |
637 | #ifdef notdef | |
638 | struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */ | |
639 | #endif | |
7485684f | 640 | int (*ifa_claim_addr) /* check if an addr goes to this if */ |
984263bc | 641 | (struct ifaddr *, struct sockaddr *); |
984263bc | 642 | }; |
7485684f | 643 | |
984263bc MD |
644 | #define IFA_ROUTE RTF_UP /* route installed */ |
645 | ||
646 | /* for compatibility with other BSDs */ | |
647 | #define ifa_list ifa_link | |
648 | ||
984263bc MD |
649 | /* |
650 | * Multicast address structure. This is analogous to the ifaddr | |
651 | * structure except that it keeps track of multicast addresses. | |
652 | * Also, the reference count here is a count of requests for this | |
653 | * address, not a count of pointers to this structure. | |
654 | */ | |
655 | struct ifmultiaddr { | |
441d34b2 | 656 | TAILQ_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ |
f23061d4 | 657 | struct sockaddr *ifma_addr; /* address this membership is for */ |
984263bc MD |
658 | struct sockaddr *ifma_lladdr; /* link-layer translation, if any */ |
659 | struct ifnet *ifma_ifp; /* back-pointer to interface */ | |
660 | u_int ifma_refcount; /* reference count */ | |
661 | void *ifma_protospec; /* protocol-specific state, if any */ | |
662 | }; | |
663 | ||
664 | #ifdef _KERNEL | |
5bd4422e | 665 | |
9a74b592 SZ |
666 | struct ifaddr_marker { |
667 | struct ifaddr ifa; | |
668 | struct ifaddr_container ifac; | |
669 | struct sockaddr addr; | |
670 | struct sockaddr netmask; | |
671 | struct sockaddr dstaddr; | |
672 | }; | |
673 | ||
bc26e110 SZ |
674 | /* |
675 | * ifaddr statistics update macro | |
676 | */ | |
d40991ef SZ |
677 | #define IFA_STAT_INC(ifa, name, v) \ |
678 | do { \ | |
572fa6a2 | 679 | (ifa)->ifa_containers[mycpuid].ifa_##name += (v); \ |
d40991ef SZ |
680 | } while (0) |
681 | ||
bc26e110 SZ |
682 | /* |
683 | * Interface (ifnet) statistics update macros | |
684 | */ | |
d40991ef SZ |
685 | #define IFNET_STAT_INC(ifp, name, v) \ |
686 | do { \ | |
e1fcdad7 | 687 | (ifp)->if_data_pcpu[mycpuid].ifd_##name += (v); \ |
d40991ef SZ |
688 | } while (0) |
689 | ||
690 | #define IFNET_STAT_SET(ifp, name, v) \ | |
691 | do { \ | |
e1fcdad7 SZ |
692 | int _cpu; \ |
693 | (ifp)->if_data_pcpu[0].ifd_##name = (v); \ | |
694 | for (_cpu = 1; _cpu < ncpus; ++_cpu) \ | |
695 | (ifp)->if_data_pcpu[_cpu].ifd_##name = 0; \ | |
d40991ef SZ |
696 | } while (0) |
697 | ||
698 | #define IFNET_STAT_GET(ifp, name, v) \ | |
699 | do { \ | |
e1fcdad7 SZ |
700 | int _cpu; \ |
701 | (v) = (ifp)->if_data_pcpu[0].ifd_##name; \ | |
702 | for (_cpu = 1; _cpu < ncpus; ++_cpu) \ | |
703 | (v) += (ifp)->if_data_pcpu[_cpu].ifd_##name; \ | |
d40991ef SZ |
704 | } while (0) |
705 | ||
c2e1bb63 | 706 | |
5bd4422e SZ |
707 | enum ifaddr_event { |
708 | IFADDR_EVENT_ADD, | |
709 | IFADDR_EVENT_DELETE, | |
710 | IFADDR_EVENT_CHANGE | |
711 | }; | |
712 | ||
f2bd8b67 | 713 | /* interface address change event */ |
5bd4422e SZ |
714 | typedef void (*ifaddr_event_handler_t)(void *, struct ifnet *, |
715 | enum ifaddr_event, struct ifaddr *); | |
f2bd8b67 | 716 | EVENTHANDLER_DECLARE(ifaddr_event, ifaddr_event_handler_t); |
2949c680 AL |
717 | /* interface link layer address change event */ |
718 | typedef void (*iflladdr_event_handler_t)(void *, struct ifnet *); | |
719 | EVENTHANDLER_DECLARE(iflladdr_event, iflladdr_event_handler_t); | |
f2bd8b67 JS |
720 | /* new interface attach event */ |
721 | typedef void (*ifnet_attach_event_handler_t)(void *, struct ifnet *); | |
722 | EVENTHANDLER_DECLARE(ifnet_attach_event, ifnet_attach_event_handler_t); | |
723 | /* interface detach event */ | |
724 | typedef void (*ifnet_detach_event_handler_t)(void *, struct ifnet *); | |
725 | EVENTHANDLER_DECLARE(ifnet_detach_event, ifnet_detach_event_handler_t); | |
bc1a39e2 AL |
726 | /* Interface link state change event */ |
727 | typedef void (*ifnet_link_event_handler_t)(void *, struct ifnet *, int); | |
728 | EVENTHANDLER_DECLARE(ifnet_link_event, ifnet_link_event_handler_t); | |
fcddd1b6 AL |
729 | /* Interface up/down event */ |
730 | #define IFNET_EVENT_UP 0 | |
731 | #define IFNET_EVENT_DOWN 1 | |
732 | typedef void (*ifnet_event_fn)(void *, struct ifnet *ifp, int event); | |
733 | EVENTHANDLER_DECLARE(ifnet_event, ifnet_event_fn); | |
f2bd8b67 | 734 | |
b4051e25 SZ |
735 | /* Array of all ifnets in the system */ |
736 | struct ifnet_array { | |
737 | int ifnet_count; /* # of elem. in ifnet_arr */ | |
738 | int ifnet_pad; /* explicit */ | |
739 | struct ifnet *ifnet_arr[]; | |
740 | }; | |
741 | ||
70224baa JL |
742 | /* |
743 | * interface groups | |
744 | */ | |
745 | struct ifg_group { | |
233c8570 AL |
746 | char ifg_group[IFNAMSIZ]; |
747 | u_int ifg_refcnt; | |
748 | void *ifg_pf_kif; | |
749 | int ifg_carp_demoted; | |
750 | TAILQ_HEAD(, ifg_member) ifg_members; | |
751 | TAILQ_ENTRY(ifg_group) ifg_next; | |
70224baa JL |
752 | }; |
753 | ||
754 | struct ifg_member { | |
755 | TAILQ_ENTRY(ifg_member) ifgm_next; | |
756 | struct ifnet *ifgm_ifp; | |
757 | }; | |
758 | ||
759 | struct ifg_list { | |
760 | struct ifg_group *ifgl_group; | |
761 | TAILQ_ENTRY(ifg_list) ifgl_next; | |
762 | }; | |
763 | ||
764 | /* group attach event */ | |
765 | typedef void (*group_attach_event_handler_t)(void *, struct ifg_group *); | |
766 | EVENTHANDLER_DECLARE(group_attach_event, group_attach_event_handler_t); | |
767 | /* group detach event */ | |
768 | typedef void (*group_detach_event_handler_t)(void *, struct ifg_group *); | |
769 | EVENTHANDLER_DECLARE(group_detach_event, group_detach_event_handler_t); | |
770 | /* group change event */ | |
771 | typedef void (*group_change_event_handler_t)(void *, const char *); | |
772 | EVENTHANDLER_DECLARE(group_change_event, group_change_event_handler_t); | |
773 | ||
774 | ||
09ff6081 SZ |
775 | #ifdef INVARIANTS |
776 | #define ASSERT_IFAC_VALID(ifac) do { \ | |
777 | KKASSERT((ifac)->ifa_magic == IFA_CONTAINER_MAGIC); \ | |
778 | KKASSERT((ifac)->ifa_refcnt > 0); \ | |
779 | } while (0) | |
780 | #else | |
781 | #define ASSERT_IFAC_VALID(ifac) ((void)0) | |
782 | #endif | |
783 | ||
b2632176 SZ |
784 | static __inline void |
785 | _IFAREF(struct ifaddr *_ifa, int _cpu_id) | |
786 | { | |
787 | struct ifaddr_container *_ifac = &_ifa->ifa_containers[_cpu_id]; | |
788 | ||
789 | crit_enter(); | |
09ff6081 | 790 | ASSERT_IFAC_VALID(_ifac); |
b2632176 SZ |
791 | ++_ifac->ifa_refcnt; |
792 | crit_exit(); | |
793 | } | |
794 | ||
f23061d4 | 795 | static __inline void |
235f6526 | 796 | IFAREF(struct ifaddr *_ifa) |
f23061d4 | 797 | { |
b2632176 | 798 | _IFAREF(_ifa, mycpuid); |
f23061d4 JH |
799 | } |
800 | ||
2949c680 | 801 | #include <sys/serialize2.h> |
f23061d4 | 802 | |
c443c74f | 803 | #ifdef MALLOC_DECLARE |
f23061d4 JH |
804 | MALLOC_DECLARE(M_IFADDR); |
805 | MALLOC_DECLARE(M_IFMADDR); | |
cb80735c | 806 | MALLOC_DECLARE(M_IFNET); |
c443c74f | 807 | #endif |
f23061d4 | 808 | |
b2632176 SZ |
809 | void ifac_free(struct ifaddr_container *, int); |
810 | ||
811 | static __inline void | |
812 | _IFAFREE(struct ifaddr *_ifa, int _cpu_id) | |
813 | { | |
814 | struct ifaddr_container *_ifac = &_ifa->ifa_containers[_cpu_id]; | |
815 | ||
816 | crit_enter(); | |
09ff6081 | 817 | ASSERT_IFAC_VALID(_ifac); |
b2632176 SZ |
818 | if (--_ifac->ifa_refcnt == 0) |
819 | ifac_free(_ifac, _cpu_id); | |
820 | crit_exit(); | |
821 | } | |
822 | ||
f23061d4 | 823 | static __inline void |
235f6526 | 824 | IFAFREE(struct ifaddr *_ifa) |
f23061d4 | 825 | { |
b2632176 | 826 | _IFAFREE(_ifa, mycpuid); |
f23061d4 | 827 | } |
984263bc | 828 | |
c2e1bb63 SZ |
829 | static __inline void |
830 | ifnet_serialize_array_enter(lwkt_serialize_t *_arr, int _arrcnt, | |
06421337 | 831 | enum ifnet_serialize _slz) |
c2e1bb63 | 832 | { |
bfefe4a6 SZ |
833 | KKASSERT(_slz == IFNET_SERIALIZE_ALL); |
834 | lwkt_serialize_array_enter(_arr, _arrcnt, 0); | |
c2e1bb63 SZ |
835 | } |
836 | ||
837 | static __inline void | |
838 | ifnet_serialize_array_exit(lwkt_serialize_t *_arr, int _arrcnt, | |
06421337 | 839 | enum ifnet_serialize _slz) |
c2e1bb63 | 840 | { |
bfefe4a6 SZ |
841 | KKASSERT(_slz == IFNET_SERIALIZE_ALL); |
842 | lwkt_serialize_array_exit(_arr, _arrcnt, 0); | |
c2e1bb63 SZ |
843 | } |
844 | ||
845 | static __inline int | |
846 | ifnet_serialize_array_try(lwkt_serialize_t *_arr, int _arrcnt, | |
06421337 | 847 | enum ifnet_serialize _slz) |
c2e1bb63 | 848 | { |
bfefe4a6 SZ |
849 | KKASSERT(_slz == IFNET_SERIALIZE_ALL); |
850 | return lwkt_serialize_array_try(_arr, _arrcnt, 0); | |
c2e1bb63 SZ |
851 | } |
852 | ||
853 | #ifdef INVARIANTS | |
854 | ||
855 | static __inline void | |
856 | ifnet_serialize_array_assert(lwkt_serialize_t *_arr, int _arrcnt, | |
06421337 | 857 | enum ifnet_serialize _slz, boolean_t _serialized) |
c2e1bb63 | 858 | { |
bfefe4a6 SZ |
859 | int _i; |
860 | ||
861 | KKASSERT(_slz == IFNET_SERIALIZE_ALL); | |
862 | if (_serialized) { | |
863 | for (_i = 0; _i < _arrcnt; ++_i) | |
864 | ASSERT_SERIALIZED(_arr[_i]); | |
865 | } else { | |
866 | for (_i = 0; _i < _arrcnt; ++_i) | |
867 | ASSERT_NOT_SERIALIZED(_arr[_i]); | |
c2e1bb63 | 868 | } |
c2e1bb63 SZ |
869 | } |
870 | ||
871 | #endif /* INVARIANTS */ | |
872 | ||
4ee4f753 MD |
873 | #define REINPUT_KEEPRCVIF 0x0001 /* ether_reinput_oncpu() */ |
874 | #define REINPUT_RUNBPF 0x0002 /* ether_reinput_oncpu() */ | |
875 | ||
b4051e25 SZ |
876 | /* |
877 | * MPSAFE NOTE for ifnet queue (ifnet), ifnet array, ifunit() and | |
878 | * ifindex2ifnet. | |
879 | * | |
880 | * - ifnet queue must only be accessed by non-netisr threads and | |
881 | * ifnet lock must be held (by ifnet_lock()). | |
882 | * - If accessing ifnet queue is needed in netisrs, ifnet array | |
883 | * (obtained through ifnet_array_get()) must be used instead. | |
884 | * There is no need to (must not, actually) hold ifnet lock for | |
885 | * ifnet array accessing. | |
886 | * - ifindex2ifnet could be accessed by both non-netisr threads and | |
887 | * netisrs. Accessing ifindex2ifnet in non-netisr threads must be | |
888 | * protected by ifnet lock (by ifnet_lock()). Accessing | |
889 | * ifindex2ifnet in netisrs is lockless MPSAFE and ifnet lock must | |
890 | * not be held. However, ifindex2ifnet should be saved in a stack | |
891 | * variable to get a consistent view of ifindex2ifnet, if | |
892 | * ifindex2ifnet is accessed multiple times from a function in | |
893 | * netisrs. | |
894 | * - ifunit() must only be called in non-netisr threads and ifnet | |
895 | * lock must be held before calling this function and for the | |
896 | * accessing of the ifp returned by this function. | |
897 | * - If ifunit() is needed in netisr, ifunit_netisr() must be used | |
898 | * instead. There is no need to (must not, actually) hold ifnet | |
899 | * lock for ifunit_netisr() and the returned ifp. | |
900 | */ | |
901 | extern struct ifnethead ifnet; | |
902 | #define ifnetlist ifnet /* easily distinguished ifnet alias */ | |
903 | ||
904 | extern struct ifnet **ifindex2ifnet; | |
905 | extern int if_index; | |
906 | ||
907 | struct ifnet *ifunit(const char *); | |
908 | struct ifnet *ifunit_netisr(const char *); | |
909 | const struct ifnet_array *ifnet_array_get(void); | |
910 | int ifnet_array_isempty(void); | |
911 | ||
2949c680 AL |
912 | extern int ifqmaxlen; |
913 | extern struct ifnet *loif; /* first loopback interface */ | |
233c8570 | 914 | extern struct ifgrouphead ifg_head; |
984263bc | 915 | |
5f60906c SZ |
916 | struct ip; |
917 | struct tcphdr; | |
918 | ||
4105de1c SZ |
919 | void ether_ifattach(struct ifnet *, const uint8_t *, |
920 | struct lwkt_serialize *); | |
921 | void ether_ifattach_bpf(struct ifnet *, const uint8_t *, u_int, u_int, | |
922 | struct lwkt_serialize *); | |
0a8b5977 | 923 | void ether_ifdetach(struct ifnet *); |
48242f47 | 924 | void ether_demux(struct mbuf *); |
297c8124 | 925 | void ether_demux_oncpu(struct ifnet *, struct mbuf *); |
b9ed4403 | 926 | void ether_reinput_oncpu(struct ifnet *, struct mbuf *, int); |
376a6a2a | 927 | void ether_input(struct ifnet *, struct mbuf *, |
ff37a356 | 928 | const struct pktinfo *, int); |
984263bc | 929 | int ether_output_frame(struct ifnet *, struct mbuf *); |
fecfec53 | 930 | int ether_ioctl(struct ifnet *, u_long, caddr_t); |
23aa4e11 AHJ |
931 | u_char *kether_aton(const char *, u_char *); |
932 | char *kether_ntoa(const u_char *, char *); | |
70d9a675 | 933 | struct ifnet *ether_bridge_interface(struct ifnet *ifp); |
d6018c31 JS |
934 | uint32_t ether_crc32_le(const uint8_t *, size_t); |
935 | uint32_t ether_crc32_be(const uint8_t *, size_t); | |
984263bc MD |
936 | |
937 | int if_addmulti(struct ifnet *, struct sockaddr *, struct ifmultiaddr **); | |
72659ed0 SZ |
938 | int if_addmulti_serialized(struct ifnet *, struct sockaddr *, |
939 | struct ifmultiaddr **); | |
984263bc | 940 | int if_allmulti(struct ifnet *, int); |
78195a76 | 941 | void if_attach(struct ifnet *, struct lwkt_serialize *); |
984263bc | 942 | int if_delmulti(struct ifnet *, struct sockaddr *); |
72659ed0 | 943 | void if_delallmulti_serialized(struct ifnet *ifp); |
c727e142 | 944 | void if_purgeaddrs_nolink(struct ifnet *); |
984263bc MD |
945 | void if_detach(struct ifnet *); |
946 | void if_down(struct ifnet *); | |
6de83abe | 947 | void if_link_state_change(struct ifnet *); |
1550dfd9 | 948 | void if_initname(struct ifnet *, const char *, int); |
e9bd1548 | 949 | int if_getanyethermac(uint16_t *, int); |
984263bc | 950 | int if_printf(struct ifnet *, const char *, ...) __printflike(2, 3); |
cb80735c RP |
951 | struct ifnet *if_alloc(uint8_t); |
952 | void if_free(struct ifnet *); | |
984263bc | 953 | int if_setlladdr(struct ifnet *, const u_char *, int); |
b44c913f | 954 | int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, uint32_t, int); |
c42bebbd | 955 | struct ifnet *if_bylla(const void *, unsigned char); |
984263bc MD |
956 | void if_up(struct ifnet *); |
957 | /*void ifinit(void);*/ /* declared in systm.h for main() */ | |
87de5057 | 958 | int ifioctl(struct socket *, u_long, caddr_t, struct ucred *); |
984263bc | 959 | int ifpromisc(struct ifnet *, int); |
984263bc | 960 | |
233c8570 AL |
961 | int ifgroup_lockmgr(u_int flags); |
962 | int if_addgroup(struct ifnet *, const char *); | |
963 | int if_delgroup(struct ifnet *, const char *); | |
315a7da3 | 964 | |
951ecd7f AL |
965 | int ifa_add_loopback_route(struct ifaddr *, struct sockaddr *); |
966 | int ifa_del_loopback_route(struct ifaddr *, struct sockaddr *); | |
967 | ||
984263bc MD |
968 | struct ifaddr *ifa_ifwithaddr(struct sockaddr *); |
969 | struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); | |
970 | struct ifaddr *ifa_ifwithnet(struct sockaddr *); | |
971 | struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); | |
972 | struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); | |
984263bc | 973 | |
aeb3c11e RP |
974 | typedef void *if_com_alloc_t(u_char type, struct ifnet *ifp); |
975 | typedef void if_com_free_t(void *com, u_char type); | |
2949c680 AL |
976 | void if_register_com_alloc(u_char, if_com_alloc_t *a, if_com_free_t *); |
977 | void if_deregister_com_alloc(u_char); | |
aeb3c11e | 978 | |
52fbd92a | 979 | void *ifa_create(int); |
b2632176 SZ |
980 | void ifa_destroy(struct ifaddr *); |
981 | void ifa_iflink(struct ifaddr *, struct ifnet *, int); | |
982 | void ifa_ifunlink(struct ifaddr *, struct ifnet *); | |
9a74b592 | 983 | void ifa_marker_init(struct ifaddr_marker *, struct ifnet *); |
b2632176 | 984 | |
984263bc MD |
985 | struct ifmultiaddr *ifmaof_ifpforaddr(struct sockaddr *, struct ifnet *); |
986 | int if_simloop(struct ifnet *ifp, struct mbuf *m, int af, int hlen); | |
f0a26983 SZ |
987 | void if_devstart(struct ifnet *ifp); /* COMPAT */ |
988 | void if_devstart_sched(struct ifnet *ifp); /* COMPAT */ | |
68732d8f | 989 | |
b4051e25 SZ |
990 | void ifnet_lock(void); |
991 | void ifnet_unlock(void); | |
992 | ||
7485684f AL |
993 | #define IF_LLSOCKADDR(ifp) \ |
994 | ((struct sockaddr_dl *)(ifp)->if_lladdr->ifa_addr) | |
f2682cb9 | 995 | #define IF_LLADDR(ifp) LLADDR(IF_LLSOCKADDR(ifp)) |
984263bc | 996 | |
b3a7093f SZ |
997 | #ifdef IFPOLL_ENABLE |
998 | int ifpoll_register(struct ifnet *); | |
999 | int ifpoll_deregister(struct ifnet *); | |
1000 | #endif /* IFPOLL_ENABLE */ | |
1001 | ||
984263bc MD |
1002 | #endif /* _KERNEL */ |
1003 | ||
1004 | #endif /* !_NET_IF_VAR_H_ */ |