1 | /* |
2 | * Copyright (c) 2000-2023 Apple Inc. All rights reserved. |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License |
8 | * Version 2.0 (the 'License'). You may not use this file except in |
9 | * compliance with the License. The rights granted to you under the License |
10 | * may not be used to create, or enable the creation or redistribution of, |
11 | * unlawful or unlicensed copies of an Apple operating system, or to |
12 | * circumvent, violate, or enable the circumvention or violation of, any |
13 | * terms of an Apple operating system software license agreement. |
14 | * |
15 | * Please obtain a copy of the License at |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. |
17 | * |
18 | * The Original Code and all software distributed under the License are |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
23 | * Please see the License for the specific language governing rights and |
24 | * limitations under the License. |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ |
28 | /* |
29 | * Copyright (c) 1982, 1986, 1989, 1993 |
30 | * The Regents of the University of California. All rights reserved. |
31 | * |
32 | * Redistribution and use in source and binary forms, with or without |
33 | * modification, are permitted provided that the following conditions |
34 | * are met: |
35 | * 1. Redistributions of source code must retain the above copyright |
36 | * notice, this list of conditions and the following disclaimer. |
37 | * 2. Redistributions in binary form must reproduce the above copyright |
38 | * notice, this list of conditions and the following disclaimer in the |
39 | * documentation and/or other materials provided with the distribution. |
40 | * 3. All advertising materials mentioning features or use of this software |
41 | * must display the following acknowledgement: |
42 | * This product includes software developed by the University of |
43 | * California, Berkeley and its contributors. |
44 | * 4. Neither the name of the University nor the names of its contributors |
45 | * may be used to endorse or promote products derived from this software |
46 | * without specific prior written permission. |
47 | * |
48 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
49 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
50 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
51 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
52 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
53 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
54 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
55 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
56 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
57 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
58 | * SUCH DAMAGE. |
59 | * |
60 | * From: @(#)if.h 8.1 (Berkeley) 6/10/93 |
61 | * $FreeBSD: src/sys/net/if_var.h,v 1.18.2.7 2001/07/24 19:10:18 brooks Exp $ |
62 | */ |
63 | |
64 | #ifndef _NET_IF_VAR_PRIVATE_H_ |
65 | #define _NET_IF_VAR_PRIVATE_H_ |
66 | |
67 | #ifndef DRIVERKIT |
68 | #ifndef DRIVERKIT_PRIVATE |
69 | #include <net/if_var_status.h> |
70 | #endif |
71 | #include <net/route.h> |
72 | #include <stdint.h> |
73 | #include <sys/types.h> |
74 | #ifdef KERNEL_PRIVATE |
75 | #include <kern/locks.h> |
76 | #endif /* KERNEL_PRIVATE */ |
77 | |
78 | struct if_traffic_class { |
79 | u_int64_t ifi_ibepackets;/* TC_BE packets received on interface */ |
80 | u_int64_t ifi_ibebytes;/* TC_BE bytes received on interface */ |
81 | u_int64_t ifi_obepackets;/* TC_BE packet sent on interface */ |
82 | u_int64_t ifi_obebytes;/* TC_BE bytes sent on interface */ |
83 | u_int64_t ifi_ibkpackets;/* TC_BK packets received on interface */ |
84 | u_int64_t ifi_ibkbytes;/* TC_BK bytes received on interface */ |
85 | u_int64_t ifi_obkpackets;/* TC_BK packet sent on interface */ |
86 | u_int64_t ifi_obkbytes;/* TC_BK bytes sent on interface */ |
87 | u_int64_t ifi_ivipackets;/* TC_VI packets received on interface */ |
88 | u_int64_t ifi_ivibytes;/* TC_VI bytes received on interface */ |
89 | u_int64_t ifi_ovipackets;/* TC_VI packets sent on interface */ |
90 | u_int64_t ifi_ovibytes;/* TC_VI bytes sent on interface */ |
91 | u_int64_t ifi_ivopackets;/* TC_VO packets received on interface */ |
92 | u_int64_t ifi_ivobytes;/* TC_VO bytes received on interface */ |
93 | u_int64_t ifi_ovopackets;/* TC_VO packets sent on interface */ |
94 | u_int64_t ifi_ovobytes;/* TC_VO bytes sent on interface */ |
95 | u_int64_t ifi_ipvpackets;/* TC priv packets received on interface */ |
96 | u_int64_t ifi_ipvbytes;/* TC priv bytes received on interface */ |
97 | u_int64_t ifi_opvpackets;/* TC priv packets sent on interface */ |
98 | u_int64_t ifi_opvbytes;/* TC priv bytes sent on interface */ |
99 | }; |
100 | |
101 | struct if_data_extended { |
102 | u_int64_t ifi_alignerrs;/* unaligned (32-bit) input pkts */ |
103 | u_int64_t ifi_dt_bytes;/* Data threshold counter */ |
104 | u_int64_t ifi_fpackets;/* forwarded packets on interface */ |
105 | u_int64_t ifi_fbytes; /* forwarded bytes on interface */ |
106 | u_int64_t reserved[12];/* for future */ |
107 | }; |
108 | |
109 | struct if_packet_stats { |
110 | /* TCP */ |
111 | u_int64_t ifi_tcp_badformat; |
112 | u_int64_t ifi_tcp_unspecv6; |
113 | u_int64_t ifi_tcp_synfin; |
114 | u_int64_t ifi_tcp_badformatipsec; |
115 | u_int64_t ifi_tcp_noconnnolist; |
116 | u_int64_t ifi_tcp_noconnlist; |
117 | u_int64_t ifi_tcp_listbadsyn; |
118 | u_int64_t ifi_tcp_icmp6unreach; |
119 | u_int64_t ifi_tcp_deprecate6; |
120 | u_int64_t ifi_tcp_rstinsynrcv; |
121 | u_int64_t ifi_tcp_ooopacket; |
122 | u_int64_t ifi_tcp_dospacket; |
123 | u_int64_t ifi_tcp_cleanup; |
124 | u_int64_t ifi_tcp_synwindow; |
125 | u_int64_t reserved[6]; |
126 | /* UDP */ |
127 | u_int64_t ifi_udp_port_unreach; |
128 | u_int64_t ifi_udp_faithprefix; |
129 | u_int64_t ifi_udp_port0; |
130 | u_int64_t ifi_udp_badlength; |
131 | u_int64_t ifi_udp_badchksum; |
132 | u_int64_t ifi_udp_badmcast; |
133 | u_int64_t ifi_udp_cleanup; |
134 | u_int64_t ifi_udp_badipsec; |
135 | u_int64_t _reserved[4]; |
136 | }; |
137 | |
138 | struct if_description { |
139 | u_int32_t ifd_maxlen; /* must be IF_DESCSIZE */ |
140 | u_int32_t ifd_len; /* actual ifd_desc length */ |
141 | u_int8_t *ifd_desc; /* ptr to desc buffer */ |
142 | }; |
143 | |
144 | struct if_bandwidths { |
145 | uint64_t eff_bw; /* effective bandwidth */ |
146 | uint64_t max_bw; /* maximum theoretical bandwidth */ |
147 | }; |
148 | |
149 | struct if_latencies { |
150 | u_int64_t eff_lt; /* effective latency */ |
151 | u_int64_t max_lt; /* maximum theoretical latency */ |
152 | }; |
153 | |
154 | typedef enum { |
155 | IF_NETEM_MODEL_NULL = 0, |
156 | IF_NETEM_MODEL_NLC = 1, |
157 | } if_netem_model_t; |
158 | |
159 | #define IF_NETEM_PARAMS_PSCALE 100000 |
160 | struct if_netem_params { |
161 | /* packet scheduler model */ |
162 | if_netem_model_t ifnetem_model; |
163 | |
164 | /* bandwidth limit */ |
165 | uint64_t ifnetem_bandwidth_bps; |
166 | |
167 | /* latency (normal distribution with jitter as stdev) */ |
168 | uint32_t ifnetem_latency_ms; |
169 | uint32_t ifnetem_jitter_ms; |
170 | |
171 | /* |
172 | * NetEm probabilistic model parameters has a scaling factor of 100,000 |
173 | * for 5 digits precision. For instance, probability 12.345% is |
174 | * expressed as uint32_t fixed point 12345 in ifnet_*_p variable below. |
175 | */ |
176 | /* random packet corruption */ |
177 | uint32_t ifnetem_corruption_p; |
178 | |
179 | /* random packet duplication */ |
180 | uint32_t ifnetem_duplication_p; |
181 | |
182 | /* 4 state Markov loss model */ |
183 | uint32_t ifnetem_loss_p_gr_gl;/* P( gap_loss | gap_rx ) */ |
184 | uint32_t ifnetem_loss_p_gr_bl;/* P( burst_loss | gap_rx ) */ |
185 | uint32_t ifnetem_loss_p_bl_br;/* P( burst_rx | burst_loss ) */ |
186 | uint32_t ifnetem_loss_p_bl_gr;/* P( gap_rx | burst_loss ) */ |
187 | uint32_t ifnetem_loss_p_br_bl;/* P( burst_loss | burst_rx ) */ |
188 | |
189 | uint32_t ifnetem_loss_recovery_ms;/* time to recovery loss */ |
190 | |
191 | /* random packet reordering */ |
192 | uint32_t ifnetem_reordering_p;/* reorder probability */ |
193 | |
194 | /* |
195 | * NetEm output scheduler by default is waken up upon input event as |
196 | * well as timer interval to avoid excessive delay. If |
197 | * ifnetem_output_ival is set to non-zero value, it overrides the |
198 | * default output interval as well as disables output scheduler wakeup |
199 | * upon input events. |
200 | */ |
201 | uint32_t ifnetem_output_ival_ms;/* output interval */ |
202 | }; |
203 | |
204 | struct if_rxpoll_stats { |
205 | u_int32_t ifi_poll_off_req; /* total # of POLL_OFF reqs */ |
206 | u_int32_t ifi_poll_off_err; /* total # of POLL_OFF errors */ |
207 | u_int32_t ifi_poll_on_req; /* total # of POLL_ON reqs */ |
208 | u_int32_t ifi_poll_on_err; /* total # of POLL_ON errors */ |
209 | |
210 | u_int32_t ifi_poll_wakeups_avg;/* avg # of wakeup reqs */ |
211 | u_int32_t ifi_poll_wakeups_lowat;/* wakeups low watermark */ |
212 | u_int32_t ifi_poll_wakeups_hiwat;/* wakeups high watermark */ |
213 | |
214 | u_int64_t ifi_poll_packets; /* total # of polled packets */ |
215 | u_int32_t ifi_poll_packets_avg;/* average polled packets */ |
216 | u_int32_t ifi_poll_packets_min;/* smallest polled packets */ |
217 | u_int32_t ifi_poll_packets_max;/* largest polled packets */ |
218 | u_int32_t ifi_poll_packets_lowat;/* packets low watermark */ |
219 | u_int32_t ifi_poll_packets_hiwat;/* packets high watermark */ |
220 | |
221 | u_int64_t ifi_poll_bytes; /* total # of polled bytes */ |
222 | u_int32_t ifi_poll_bytes_avg; /* average polled bytes */ |
223 | u_int32_t ifi_poll_bytes_min; /* smallest polled bytes */ |
224 | u_int32_t ifi_poll_bytes_max; /* largest polled bytes */ |
225 | u_int32_t ifi_poll_bytes_lowat;/* bytes low watermark */ |
226 | u_int32_t ifi_poll_bytes_hiwat;/* bytes high watermark */ |
227 | |
228 | u_int32_t ifi_poll_packets_limit;/* max packets per poll call */ |
229 | u_int64_t ifi_poll_interval_time;/* poll interval (nsec) */ |
230 | }; |
231 | |
232 | struct if_netif_stats { |
233 | u_int64_t ifn_rx_mit_interval;/* rx mitigation ival (nsec) */ |
234 | u_int32_t ifn_rx_mit_mode; /* 0: static, 1: dynamic */ |
235 | u_int32_t ifn_rx_mit_packets_avg;/* average # of packets */ |
236 | u_int32_t ifn_rx_mit_packets_min;/* smallest # of packets */ |
237 | u_int32_t ifn_rx_mit_packets_max;/* largest # of packets */ |
238 | u_int32_t ifn_rx_mit_bytes_avg;/* average # of bytes */ |
239 | u_int32_t ifn_rx_mit_bytes_min;/* smallest # of bytes */ |
240 | u_int32_t ifn_rx_mit_bytes_max;/* largest # of bytes */ |
241 | u_int32_t ifn_rx_mit_cfg_idx; /* current config selector */ |
242 | u_int32_t ifn_rx_mit_cfg_packets_lowat;/* pkts low watermark */ |
243 | u_int32_t ifn_rx_mit_cfg_packets_hiwat;/* pkts high watermark */ |
244 | u_int32_t ifn_rx_mit_cfg_bytes_lowat;/* bytes low watermark */ |
245 | u_int32_t ifn_rx_mit_cfg_bytes_hiwat;/* bytes high watermark */ |
246 | u_int32_t ifn_rx_mit_cfg_interval;/* delay interval (nsec) */ |
247 | }; |
248 | |
249 | struct if_tcp_ecn_perf_stat { |
250 | u_int64_t total_txpkts; |
251 | u_int64_t total_rxmitpkts; |
252 | u_int64_t total_rxpkts; |
253 | u_int64_t total_oopkts; |
254 | u_int64_t total_reorderpkts; |
255 | u_int64_t rtt_avg; |
256 | u_int64_t rtt_var; |
257 | u_int64_t sack_episodes; |
258 | u_int64_t rxmit_drop; |
259 | u_int64_t rst_drop; |
260 | u_int64_t oo_percent; |
261 | u_int64_t reorder_percent; |
262 | u_int64_t rxmit_percent; |
263 | }; |
264 | |
265 | struct if_tcp_ecn_stat { |
266 | u_int64_t timestamp; |
267 | u_int64_t ecn_client_setup; |
268 | u_int64_t ecn_server_setup; |
269 | u_int64_t ecn_client_success; |
270 | u_int64_t ecn_server_success; |
271 | u_int64_t ecn_peer_nosupport; |
272 | u_int64_t ecn_syn_lost; |
273 | u_int64_t ecn_synack_lost; |
274 | u_int64_t ecn_recv_ce; |
275 | u_int64_t ecn_recv_ece; |
276 | u_int64_t ecn_conn_recv_ce; |
277 | u_int64_t ecn_conn_recv_ece; |
278 | u_int64_t ecn_conn_plnoce; |
279 | u_int64_t ecn_conn_plce; |
280 | u_int64_t ecn_conn_noplce; |
281 | u_int64_t ecn_fallback_synloss; |
282 | u_int64_t ecn_fallback_reorder; |
283 | u_int64_t ecn_fallback_ce; |
284 | u_int64_t ecn_off_conn; |
285 | u_int64_t ecn_total_conn; |
286 | u_int64_t ecn_fallback_droprst; |
287 | u_int64_t ecn_fallback_droprxmt; |
288 | u_int64_t ecn_fallback_synrst; |
289 | struct if_tcp_ecn_perf_stat ecn_on; |
290 | struct if_tcp_ecn_perf_stat ecn_off; |
291 | }; |
292 | |
293 | struct if_lim_perf_stat { |
294 | u_int64_t lim_dl_max_bandwidth; /* bits per second */ |
295 | u_int64_t lim_ul_max_bandwidth; /* bits per second */ |
296 | u_int64_t lim_total_txpkts; /* Total transmit packets, count */ |
297 | u_int64_t lim_total_rxpkts; /* Total receive packets, count */ |
298 | u_int64_t lim_total_retxpkts; /* Total retransmit packets */ |
299 | u_int64_t lim_packet_loss_percent; /* Packet loss rate */ |
300 | u_int64_t lim_total_oopkts; /* Total out-of-order packets */ |
301 | u_int64_t lim_packet_ooo_percent; /* Out-of-order packet rate */ |
302 | u_int64_t lim_rtt_variance; /* RTT variance, milliseconds */ |
303 | u_int64_t lim_rtt_average; /* RTT average, milliseconds */ |
304 | u_int64_t lim_rtt_min; /* RTT minimum, milliseconds */ |
305 | u_int64_t lim_conn_timeouts; /* connection timeouts */ |
306 | u_int64_t lim_conn_attempts; /* connection attempts */ |
307 | u_int64_t lim_conn_timeout_percent; /* Rate of connection timeouts */ |
308 | u_int64_t lim_bk_txpkts; /* Transmit packets with BK service class, that use delay based algorithms */ |
309 | u_int64_t lim_dl_detected:1, /* Low internet */ |
310 | lim_ul_detected:1; |
311 | }; |
312 | |
313 | #define IF_VAR_H_HAS_IFNET_STATS_PER_FLOW 1 |
314 | struct ifnet_stats_per_flow { |
315 | u_int64_t bk_txpackets; |
316 | u_int64_t txpackets; |
317 | u_int64_t rxpackets; |
318 | u_int32_t txretransmitbytes; |
319 | u_int32_t rxoutoforderbytes; |
320 | u_int32_t rxmitpkts; |
321 | u_int32_t rcvoopack; |
322 | u_int32_t pawsdrop; |
323 | u_int32_t sack_recovery_episodes; |
324 | u_int32_t reordered_pkts; |
325 | u_int32_t dsack_sent; |
326 | u_int32_t dsack_recvd; |
327 | u_int32_t srtt; |
328 | u_int32_t rttupdated; |
329 | u_int32_t rttvar; |
330 | u_int32_t rttmin; |
331 | u_int32_t bw_sndbw_max; |
332 | u_int32_t bw_rcvbw_max; |
333 | u_int32_t ecn_recv_ece; |
334 | u_int32_t ecn_recv_ce; |
335 | u_int32_t ecn_flags; |
336 | u_int16_t ipv4:1, |
337 | local:1, |
338 | connreset:1, |
339 | conntimeout:1, |
340 | rxmit_drop:1, |
341 | ecn_fallback_synloss:1, |
342 | ecn_fallback_droprst:1, |
343 | ecn_fallback_droprxmt:1, |
344 | ecn_fallback_ce:1, |
345 | ecn_fallback_reorder:1; |
346 | }; |
347 | |
348 | struct if_interface_state { |
349 | /* |
350 | * The bitmask tells which of the fields |
351 | * to consider: |
352 | * - When setting, to control which fields |
353 | * are being modified; |
354 | * - When getting, it tells which fields are set. |
355 | */ |
356 | u_int8_t valid_bitmask; |
357 | #define IF_INTERFACE_STATE_RRC_STATE_VALID 0x1 |
358 | #define IF_INTERFACE_STATE_LQM_STATE_VALID 0x2 |
359 | #define IF_INTERFACE_STATE_INTERFACE_AVAILABILITY_VALID 0x4 |
360 | |
361 | /* |
362 | * Valid only for cellular interface |
363 | */ |
364 | u_int8_t rrc_state; |
365 | #define IF_INTERFACE_STATE_RRC_STATE_IDLE 0x0 |
366 | #define IF_INTERFACE_STATE_RRC_STATE_CONNECTED 0x1 |
367 | |
368 | /* |
369 | * Values normalized to the edge of the following values |
370 | * that are defined on <net/if.h>: |
371 | * IFNET_LQM_THRESH_BAD |
372 | * IFNET_LQM_THRESH_POOR |
373 | * IFNET_LQM_THRESH_GOOD |
374 | */ |
375 | int8_t lqm_state; |
376 | |
377 | /* |
378 | * Indicate if the underlying link is currently |
379 | * available |
380 | */ |
381 | u_int8_t interface_availability; |
382 | #define IF_INTERFACE_STATE_INTERFACE_AVAILABLE 0x0 |
383 | #define IF_INTERFACE_STATE_INTERFACE_UNAVAILABLE 0x1 |
384 | }; |
385 | |
386 | struct chain_len_stats { |
387 | uint64_t cls_one; |
388 | uint64_t cls_two; |
389 | uint64_t cls_three; |
390 | uint64_t cls_four; |
391 | uint64_t cls_five_or_more; |
392 | } __attribute__((__aligned__(sizeof(uint64_t)))); |
393 | |
394 | #ifdef BSD_KERNEL_PRIVATE |
395 | #define IFNETS_MAX 64 |
396 | |
397 | /* |
398 | * Internal storage of if_data. This is bound to change. Various places in the |
399 | * stack will translate this data structure in to the externally visible |
400 | * if_data structure above. Note that during interface attach time, the |
401 | * embedded if_data structure in ifnet is cleared, with the exception of |
402 | * some non-statistics related fields. |
403 | */ |
404 | struct if_data_internal { |
405 | /* generic interface information */ |
406 | u_char ifi_type; /* ethernet, tokenring, etc */ |
407 | u_char ifi_typelen; /* Length of frame type id */ |
408 | u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */ |
409 | u_char ifi_addrlen; /* media address length */ |
410 | u_char ifi_hdrlen; /* media header length */ |
411 | u_char ifi_recvquota; /* polling quota for receive intrs */ |
412 | u_char ifi_xmitquota; /* polling quota for xmit intrs */ |
413 | u_char ifi_unused1; /* for future use */ |
414 | u_int32_t ifi_mtu; /* maximum transmission unit */ |
415 | u_int32_t ifi_metric; /* routing metric (external only) */ |
416 | u_int32_t ifi_baudrate; /* linespeed */ |
417 | /* volatile statistics */ |
418 | u_int64_t ifi_ipackets; /* packets received on interface */ |
419 | u_int64_t ifi_ierrors; /* input errors on interface */ |
420 | u_int64_t ifi_opackets; /* packets sent on interface */ |
421 | u_int64_t ifi_oerrors; /* output errors on interface */ |
422 | u_int64_t ifi_collisions; /* collisions on csma interfaces */ |
423 | u_int64_t ifi_ibytes; /* total number of octets received */ |
424 | u_int64_t ifi_obytes; /* total number of octets sent */ |
425 | u_int64_t ifi_imcasts; /* packets received via multicast */ |
426 | u_int64_t ifi_omcasts; /* packets sent via multicast */ |
427 | u_int64_t ifi_iqdrops; /* dropped on input, this interface */ |
428 | u_int64_t ifi_noproto; /* destined for unsupported protocol */ |
429 | u_int32_t ifi_recvtiming; /* usec spent receiving when timing */ |
430 | u_int32_t ifi_xmittiming; /* usec spent xmitting when timing */ |
431 | u_int64_t ifi_alignerrs; /* unaligned (32-bit) input pkts */ |
432 | u_int64_t ifi_dt_bytes; /* Data threshold counter */ |
433 | u_int64_t ifi_fpackets; /* forwarded packets on interface */ |
434 | u_int64_t ifi_fbytes; /* forwarded bytes on interface */ |
435 | struct timeval ifi_lastchange; /* time of last administrative change */ |
436 | struct timeval ifi_lastupdown; /* time of last up/down event */ |
437 | u_int32_t ifi_hwassist; /* HW offload capabilities */ |
438 | u_int32_t ifi_tso_v4_mtu; /* TCP Segment Offload IPv4 maximum segment size */ |
439 | u_int32_t ifi_tso_v6_mtu; /* TCP Segment Offload IPv6 maximum segment size */ |
440 | }; |
441 | #endif /* BSD_KERNEL_PRIVATE */ |
442 | |
443 | #define if_mtu if_data.ifi_mtu |
444 | #define if_type if_data.ifi_type |
445 | #define if_typelen if_data.ifi_typelen |
446 | #define if_physical if_data.ifi_physical |
447 | #define if_addrlen if_data.ifi_addrlen |
448 | #define if_hdrlen if_data.ifi_hdrlen |
449 | #define if_metric if_data.ifi_metric |
450 | #define if_baudrate if_data.ifi_baudrate |
451 | #define if_hwassist if_data.ifi_hwassist |
452 | #define if_ipackets if_data.ifi_ipackets |
453 | #define if_ierrors if_data.ifi_ierrors |
454 | #define if_opackets if_data.ifi_opackets |
455 | #define if_oerrors if_data.ifi_oerrors |
456 | #define if_collisions if_data.ifi_collisions |
457 | #define if_ibytes if_data.ifi_ibytes |
458 | #define if_obytes if_data.ifi_obytes |
459 | #define if_imcasts if_data.ifi_imcasts |
460 | #define if_omcasts if_data.ifi_omcasts |
461 | #define if_iqdrops if_data.ifi_iqdrops |
462 | #define if_noproto if_data.ifi_noproto |
463 | #define if_lastchange if_data.ifi_lastchange |
464 | #define if_recvquota if_data.ifi_recvquota |
465 | #define if_xmitquota if_data.ifi_xmitquota |
466 | #ifdef BSD_KERNEL_PRIVATE |
467 | #define if_tso_v4_mtu if_data.ifi_tso_v4_mtu |
468 | #define if_tso_v6_mtu if_data.ifi_tso_v6_mtu |
469 | #define if_alignerrs if_data.ifi_alignerrs |
470 | #define if_dt_bytes if_data.ifi_dt_bytes |
471 | #define if_fpackets if_data.ifi_fpackets |
472 | #define if_fbytes if_data.ifi_fbytes |
473 | #define if_lastupdown if_data.ifi_lastupdown |
474 | |
475 | /* |
476 | * Forward structure declarations for function prototypes [sic]. |
477 | */ |
478 | struct proc; |
479 | struct rtentry; |
480 | struct socket; |
481 | struct ifnet_filter; |
482 | struct mbuf; |
483 | struct ifaddr; |
484 | struct tqdummy; |
485 | struct proto_hash_entry; |
486 | struct dlil_threading_info; |
487 | struct tcpstat_local; |
488 | struct udpstat_local; |
489 | #if PF |
490 | struct pfi_kif; |
491 | #endif /* PF */ |
492 | #if SKYWALK |
493 | struct nexus_netif_adapter; |
494 | #endif /* SKYWALK */ |
495 | |
496 | /* we use TAILQs so that the order of instantiation is preserved in the list */ |
497 | TAILQ_HEAD(ifnethead, ifnet); |
498 | TAILQ_HEAD(ifaddrhead, ifaddr); |
499 | LIST_HEAD(ifmultihead, ifmultiaddr); |
500 | TAILQ_HEAD(tailq_head, tqdummy); |
501 | TAILQ_HEAD(ifnet_filter_head, ifnet_filter); |
502 | TAILQ_HEAD(ddesc_head_name, dlil_demux_desc); |
503 | |
504 | extern bool intcoproc_unrestricted; |
505 | extern bool management_data_unrestricted; |
506 | extern bool management_control_unrestricted; |
507 | extern bool if_management_interface_check_needed; |
508 | extern int if_management_verbose; |
509 | #endif /* BSD_KERNEL_PRIVATE */ |
510 | |
511 | /* |
512 | * All of the following IF_HWASSIST_* flags are defined in kpi_interface.h as |
513 | * IFNET_* flags. These are redefined here as constants to avoid failures to |
514 | * build user level programs that can not include kpi_interface.h. It is |
515 | * important to keep this in sync with the definitions in kpi_interface.h. |
516 | * The corresponding constant for each definition is mentioned in the comment. |
517 | * |
518 | * Bottom 16 bits reserved for hardware checksum |
519 | */ |
520 | #define IF_HWASSIST_CSUM_IP 0x0001 /* will csum IP, IFNET_CSUM_IP */ |
521 | #define IF_HWASSIST_CSUM_TCP 0x0002 /* will csum TCP, IFNET_CSUM_TCP */ |
522 | #define IF_HWASSIST_CSUM_UDP 0x0004 /* will csum UDP, IFNET_CSUM_UDP */ |
523 | #define IF_HWASSIST_CSUM_IP_FRAGS 0x0008 /* will csum IP fragments, IFNET_CSUM_FRAGMENT */ |
524 | #define IF_HWASSIST_CSUM_FRAGMENT 0x0010 /* will do IP fragmentation, IFNET_IP_FRAGMENT */ |
525 | #define IF_HWASSIST_CSUM_TCPIPV6 0x0020 /* will csum TCPv6, IFNET_CSUM_TCPIPV6 */ |
526 | #define IF_HWASSIST_CSUM_UDPIPV6 0x0040 /* will csum UDPv6, IFNET_CSUM_UDP */ |
527 | #define IF_HWASSIST_CSUM_FRAGMENT_IPV6 0x0080 /* will do IPv6 fragmentation, IFNET_IPV6_FRAGMENT */ |
528 | #define IF_HWASSIST_CSUM_PARTIAL 0x1000 /* simple Sum16 computation, IFNET_CSUM_PARTIAL */ |
529 | #define IF_HWASSIST_CSUM_ZERO_INVERT 0x2000 /* capable of inverting csum of 0 to -0 (0xffff) */ |
530 | #define IF_HWASSIST_CSUM_MASK 0xffff |
531 | #define IF_HWASSIST_CSUM_FLAGS(hwassist) ((hwassist) & IF_HWASSIST_CSUM_MASK) |
532 | |
533 | /* VLAN support */ |
534 | #define IF_HWASSIST_VLAN_TAGGING 0x00010000 /* supports VLAN tagging, IFNET_VLAN_TAGGING */ |
535 | #define IF_HWASSIST_VLAN_MTU 0x00020000 /* supports VLAN MTU-sized packet (for software VLAN), IFNET_VLAN_MTU */ |
536 | |
537 | /* TCP Segment Offloading support */ |
538 | |
539 | #define IF_HWASSIST_TSO_V4 0x00200000 /* will do TCP Segment offload for IPv4, IFNET_TSO_IPV4 */ |
540 | #define IF_HWASSIST_TSO_V6 0x00400000 /* will do TCP Segment offload for IPv6, IFNET_TSO_IPV6 */ |
541 | |
542 | #define IFXNAMSIZ (IFNAMSIZ + 8) /* external name (name + unit) */ |
543 | #define IFNET_NETWORK_ID_LEN 32 |
544 | |
545 | #ifdef BSD_KERNEL_PRIVATE |
546 | /* |
547 | * ifnet is private to BSD portion of kernel |
548 | */ |
549 | #include <sys/mcache.h> |
550 | #include <sys/tree.h> |
551 | #include <netinet/in.h> |
552 | #include <net/if_dl.h> |
553 | #include <net/classq/if_classq.h> |
554 | #include <net/if_types.h> |
555 | #include <net/route.h> |
556 | |
557 | RB_HEAD(ll_reach_tree, if_llreach); /* define struct ll_reach_tree */ |
558 | |
559 | #if SKYWALK |
560 | struct nexus_ifnet_ops { |
561 | void (*ni_finalize)(struct nexus_netif_adapter *, struct ifnet *); |
562 | void (*ni_reap)(struct nexus_netif_adapter *, struct ifnet *, |
563 | uint32_t, boolean_t); |
564 | errno_t (*ni_dequeue)(struct nexus_netif_adapter *, uint32_t, |
565 | uint32_t, uint32_t, classq_pkt_t *, classq_pkt_t *, uint32_t *, |
566 | uint32_t *, boolean_t, errno_t); |
567 | errno_t (*ni_get_len)(struct nexus_netif_adapter *, uint32_t, |
568 | uint32_t *, uint32_t *, errno_t); |
569 | }; |
570 | typedef struct { |
571 | uuid_t if_nif_provider; |
572 | uuid_t if_nif_instance; |
573 | uuid_t if_nif_attach; |
574 | } if_nexus_netif, *if_nexus_netif_t; |
575 | |
576 | typedef struct { |
577 | uuid_t if_fsw_provider; |
578 | uuid_t if_fsw_instance; |
579 | uuid_t if_fsw_device; |
580 | uint32_t if_fsw_ipaddr_gencnt; |
581 | } if_nexus_flowswitch, *if_nexus_flowswitch_t; |
582 | |
583 | typedef void (*ifnet_fsw_rx_cb_t)(void *, struct pktq *); |
584 | typedef void (*ifnet_detach_notify_cb_t)(void *); |
585 | #endif /* SKYWALK */ |
586 | |
587 | typedef errno_t (*dlil_input_func)(ifnet_t ifp, mbuf_t m_head, |
588 | mbuf_t m_tail, const struct ifnet_stat_increment_param *s, |
589 | boolean_t poll, struct thread *tp); |
590 | typedef errno_t (*dlil_output_func)(ifnet_t interface, mbuf_t data); |
591 | |
592 | typedef u_int8_t ipv6_router_mode_t; |
593 | |
594 | #define if_name(ifp) ifp->if_xname |
595 | /* |
596 | * Structure defining a network interface. |
597 | * |
598 | * (Would like to call this struct ``if'', but C isn't PL/1.) |
599 | */ |
600 | struct ifnet { |
601 | /* |
602 | * Lock (RW or mutex) to protect this data structure (static storage.) |
603 | */ |
604 | decl_lck_rw_data(, if_lock); |
605 | void *if_softc; /* pointer to driver state */ |
606 | const char *if_name; /* name, e.g. ``en'' or ``lo'' */ |
607 | const char *if_xname; /* external name (name + unit) */ |
608 | struct if_description if_desc; /* extended description */ |
609 | TAILQ_ENTRY(ifnet) if_link; /* all struct ifnets are chained */ |
610 | TAILQ_ENTRY(ifnet) if_detaching_link; /* list of detaching ifnets */ |
611 | TAILQ_ENTRY(ifnet) if_ordered_link; /* list of ordered ifnets */ |
612 | |
613 | decl_lck_mtx_data(, if_ref_lock); |
614 | u_int32_t if_refflags; /* see IFRF flags below */ |
615 | u_int32_t if_refio; /* number of io ops to the underlying driver */ |
616 | u_int32_t if_threads_pending; /* Threads created but waiting for first run */ |
617 | u_int32_t if_datamov; /* number of threads moving data */ |
618 | u_int32_t if_drainers; /* number of draining threads */ |
619 | u_int32_t if_suspend; /* number of suspend requests */ |
620 | |
621 | #define if_list if_link |
622 | struct ifaddrhead if_addrhead; /* linked list of addresses per if */ |
623 | #define if_addrlist if_addrhead |
624 | struct ifaddr *if_lladdr; /* link address (first/permanent) */ |
625 | |
626 | u_int32_t if_qosmarking_mode; /* generation to use with NECP clients */ |
627 | |
628 | int if_pcount; /* number of promiscuous listeners */ |
629 | struct bpf_if *if_bpf; /* packet filter structure */ |
630 | u_short if_index; /* numeric abbreviation for this if */ |
631 | short if_unit; /* sub-unit for lower level driver */ |
632 | short if_timer; /* time 'til if_watchdog called */ |
633 | short if_flags; /* up/down, broadcast, etc. */ |
634 | u_int32_t if_eflags; /* see <net/if.h> */ |
635 | u_int32_t if_xflags; /* see <net/if.h> */ |
636 | |
637 | int if_capabilities; /* interface features & capabilities */ |
638 | int if_capenable; /* enabled features & capabilities */ |
639 | |
640 | void *if_linkmib; /* link-type-specific MIB data */ |
641 | uint32_t if_linkmiblen; /* length of above data */ |
642 | |
643 | struct if_data_internal if_data __attribute__((aligned(8))); |
644 | |
645 | ifnet_family_t if_family; /* value assigned by Apple */ |
646 | ifnet_subfamily_t if_subfamily; /* value assigned by Apple */ |
647 | uintptr_t if_family_cookie; |
648 | volatile dlil_input_func if_input_dlil; |
649 | volatile dlil_output_func if_output_dlil; |
650 | volatile ifnet_start_func if_start; |
651 | ifnet_output_func if_output; |
652 | ifnet_pre_enqueue_func if_pre_enqueue; |
653 | ifnet_ctl_func if_output_ctl; |
654 | ifnet_input_poll_func if_input_poll; |
655 | ifnet_ctl_func if_input_ctl; |
656 | ifnet_ioctl_func if_ioctl; |
657 | ifnet_set_bpf_tap if_set_bpf_tap; |
658 | ifnet_detached_func if_free; |
659 | ifnet_demux_func if_demux; |
660 | ifnet_event_func if_event; |
661 | ifnet_framer_func if_framer_legacy; |
662 | ifnet_framer_extended_func if_framer; |
663 | ifnet_add_proto_func if_add_proto; |
664 | ifnet_del_proto_func if_del_proto; |
665 | ifnet_check_multi if_check_multi; |
666 | struct proto_hash_entry *if_proto_hash; |
667 | ifnet_detached_func if_detach; |
668 | |
669 | u_int32_t if_flowhash; /* interface flow control ID */ |
670 | |
671 | decl_lck_mtx_data(, if_start_lock); |
672 | u_int32_t if_start_flags; /* see IFSF flags below */ |
673 | u_int32_t if_start_req; |
674 | u_int8_t if_start_embryonic; |
675 | u_int8_t if_start_active; /* output is active */ |
676 | u_int16_t if_start_delayed; |
677 | u_int16_t if_start_delay_qlen; |
678 | u_int16_t if_start_delay_idle; |
679 | u_int64_t if_start_delay_swin; |
680 | u_int32_t if_start_delay_cnt; |
681 | u_int32_t if_start_delay_timeout; /* nanoseconds */ |
682 | struct timespec if_start_cycle; /* restart interval */ |
683 | struct thread *if_start_thread; |
684 | |
685 | struct ifclassq *if_snd; /* transmit queue */ |
686 | u_int32_t if_output_sched_model; /* tx sched model */ |
687 | |
688 | struct if_bandwidths if_output_bw; |
689 | struct if_bandwidths if_input_bw; |
690 | |
691 | struct if_latencies if_output_lt; |
692 | struct if_latencies if_input_lt; |
693 | |
694 | decl_lck_mtx_data(, if_flt_lock); |
695 | u_int32_t if_flt_busy; |
696 | u_int32_t if_flt_waiters; |
697 | struct ifnet_filter_head if_flt_head; |
698 | uint32_t if_flt_non_os_count; |
699 | uint32_t if_flt_no_tso_count; |
700 | |
701 | struct ifmultihead if_multiaddrs; /* multicast addresses */ |
702 | u_int32_t if_updatemcasts; /* mcast addrs need updating */ |
703 | int if_amcount; /* # of all-multicast reqs */ |
704 | decl_lck_mtx_data(, if_addrconfig_lock); /* for serializing addr config */ |
705 | struct in_multi *if_allhostsinm; /* store all-hosts inm for this ifp */ |
706 | |
707 | /* |
708 | * Opportunistic polling parameters. |
709 | */ |
710 | decl_lck_mtx_data(, if_poll_lock); |
711 | struct if_poll_params { |
712 | u_int16_t poll_req; |
713 | u_int16_t poll_update; /* link update */ |
714 | u_int32_t poll_flags; |
715 | #define IF_POLLF_READY 0x1 /* poll thread is ready */ |
716 | #define IF_POLLF_RUNNING 0x2 /* poll thread is running/active */ |
717 | #define IF_POLLF_TERMINATING 0x4 /* poll thread is terminating */ |
718 | #define IF_POLLF_EMBRYONIC 0x8000 /* poll thread is being setup */ |
719 | struct timespec poll_cycle; /* poll interval */ |
720 | struct thread *poll_thread; |
721 | |
722 | ifnet_model_t poll_mode; /* current mode */ |
723 | struct pktcntr poll_tstats; /* incremental polling statistics */ |
724 | struct if_rxpoll_stats poll_pstats; /* polling statistics */ |
725 | struct pktcntr poll_sstats; /* packets and bytes per sampling */ |
726 | struct timespec poll_mode_holdtime; /* mode holdtime in nsec */ |
727 | struct timespec poll_mode_lasttime; /* last mode change time in nsec */ |
728 | struct timespec poll_sample_holdtime; /* sampling holdtime in nsec */ |
729 | struct timespec poll_sample_lasttime; /* last sampling time in nsec */ |
730 | struct timespec poll_dbg_lasttime; /* last debug message time in nsec */ |
731 | } rxpoll_params; |
732 | #define if_poll_req rxpoll_params.poll_req |
733 | #define if_poll_update rxpoll_params.poll_update |
734 | #define if_poll_flags rxpoll_params.poll_flags |
735 | #define if_poll_cycle rxpoll_params.poll_cycle |
736 | #define if_poll_thread rxpoll_params.poll_thread |
737 | #define if_poll_mode rxpoll_params.poll_mode |
738 | #define if_poll_tstats rxpoll_params.poll_tstats |
739 | #define if_poll_sstats rxpoll_params.poll_sstats |
740 | #define if_poll_pstats rxpoll_params.poll_pstats |
741 | |
742 | #define if_poll_mode_holdtime rxpoll_params.poll_mode_holdtime |
743 | #define if_poll_mode_lasttime rxpoll_params.poll_mode_lasttime |
744 | #define if_poll_sample_holdtime rxpoll_params.poll_sample_holdtime |
745 | #define if_poll_sample_lasttime rxpoll_params.poll_sample_lasttime |
746 | #define if_poll_dbg_lasttime rxpoll_params.poll_dbg_lasttime |
747 | |
748 | #define if_rxpoll_offreq rxpoll_params.poll_pstats.ifi_poll_off_req |
749 | #define if_rxpoll_offerr rxpoll_params.poll_pstats.ifi_poll_off_err |
750 | #define if_rxpoll_onreq rxpoll_params.poll_pstats.ifi_poll_on_req |
751 | #define if_rxpoll_onerr rxpoll_params.poll_pstats.ifi_poll_on_err |
752 | #define if_rxpoll_wavg rxpoll_params.poll_pstats.ifi_poll_wakeups_avg |
753 | #define if_rxpoll_wlowat rxpoll_params.poll_pstats.ifi_poll_wakeups_lowat |
754 | #define if_rxpoll_whiwat rxpoll_params.poll_pstats.ifi_poll_wakeups_hiwat |
755 | #define if_rxpoll_pavg rxpoll_params.poll_pstats.ifi_poll_packets_avg |
756 | #define if_rxpoll_pmin rxpoll_params.poll_pstats.ifi_poll_packets_min |
757 | #define if_rxpoll_pmax rxpoll_params.poll_pstats.ifi_poll_packets_max |
758 | #define if_rxpoll_plowat rxpoll_params.poll_pstats.ifi_poll_packets_lowat |
759 | #define if_rxpoll_phiwat rxpoll_params.poll_pstats.ifi_poll_packets_hiwat |
760 | #define if_rxpoll_bavg rxpoll_params.poll_pstats.ifi_poll_bytes_avg |
761 | #define if_rxpoll_bmin rxpoll_params.poll_pstats.ifi_poll_bytes_min |
762 | #define if_rxpoll_bmax rxpoll_params.poll_pstats.ifi_poll_bytes_max |
763 | #define if_rxpoll_blowat rxpoll_params.poll_pstats.ifi_poll_bytes_lowat |
764 | #define if_rxpoll_bhiwat rxpoll_params.poll_pstats.ifi_poll_bytes_hiwat |
765 | #define if_rxpoll_plim rxpoll_params.poll_pstats.ifi_poll_packets_limit |
766 | #define if_rxpoll_ival rxpoll_params.poll_pstats.ifi_poll_interval_time |
767 | |
768 | struct dlil_threading_info *if_inp; |
769 | |
770 | /* allocated once along with dlil_ifnet and is never freed */ |
771 | thread_call_t if_dt_tcall; |
772 | |
773 | struct { |
774 | u_int32_t length; |
775 | union { |
776 | u_char buffer[8]; |
777 | u_char *ptr; |
778 | } u; |
779 | } if_broadcast; |
780 | |
781 | #if PF |
782 | struct pfi_kif *if_pf_kif; |
783 | #endif /* PF */ |
784 | #if SKYWALK |
785 | struct nexus_ifnet_ops *if_na_ops; |
786 | struct nexus_netif_adapter *if_na; |
787 | |
788 | /* compat netif attachment */ |
789 | if_nexus_netif if_nx_netif; |
790 | |
791 | /* flowswitch attachment */ |
792 | if_nexus_flowswitch if_nx_flowswitch; |
793 | |
794 | /* headroom space to be reserved in tx packets */ |
795 | uint16_t if_tx_headroom; |
796 | |
797 | /* trailer space to be reserved in tx packets */ |
798 | uint16_t if_tx_trailer; |
799 | |
800 | /* |
801 | * mitigation interval in microseconds for the rx interrupt mitigation |
802 | * logic while operating in the high throughput mode. |
803 | */ |
804 | uint32_t if_rx_mit_ival; |
805 | |
806 | /* |
807 | * Number of threads waiting for the start callback to be finished; |
808 | * access is protected by if_start_lock; also serves as wait channel. |
809 | */ |
810 | uint32_t if_start_waiters; |
811 | |
812 | ifnet_start_func if_save_start; |
813 | ifnet_output_func if_save_output; |
814 | |
815 | /* |
816 | * Used for intercepting packets meant for the host stack. |
817 | */ |
818 | ifnet_fsw_rx_cb_t if_fsw_rx_cb; |
819 | void *if_fsw_rx_cb_arg; |
820 | uint32_t if_fsw_rx_cb_ref; |
821 | |
822 | uint32_t if_delegate_parent_ref; |
823 | struct ifnet *if_delegate_parent; |
824 | decl_lck_mtx_data(, if_delegate_lock); |
825 | |
826 | /* |
827 | * Detach notify callback. Used by llw and redirect interfaces. |
828 | */ |
829 | ifnet_detach_notify_cb_t if_detach_notify; |
830 | void *if_detach_notify_arg; |
831 | #endif /* SKYWALK */ |
832 | |
833 | decl_lck_mtx_data(, if_cached_route_lock); |
834 | u_int32_t if_fwd_cacheok; |
835 | struct route if_fwd_route; /* cached forwarding route */ |
836 | struct route if_src_route; /* cached ipv4 source route */ |
837 | struct route_in6 if_src_route6; /* cached ipv6 source route */ |
838 | |
839 | decl_lck_rw_data(, if_llreach_lock); |
840 | struct ll_reach_tree if_ll_srcs; /* source link-layer tree */ |
841 | |
842 | void *if_bridge; /* bridge glue */ |
843 | |
844 | u_int32_t if_idle_flags; /* idle flags */ |
845 | u_int32_t if_idle_new_flags; /* temporary idle flags */ |
846 | u_int32_t if_idle_new_flags_mask; /* temporary mask */ |
847 | u_int32_t if_route_refcnt; /* idle: route ref count */ |
848 | u_int32_t if_rt_sendts; /* last of a real time packet */ |
849 | |
850 | struct if_traffic_class if_tc __attribute__((aligned(8))); |
851 | #if INET |
852 | struct igmp_ifinfo *if_igi; /* for IGMPv3 */ |
853 | #endif /* INET */ |
854 | struct mld_ifinfo *if_mli; /* for MLDv2 */ |
855 | |
856 | struct tcpstat_local *if_tcp_stat; /* TCP specific stats */ |
857 | struct udpstat_local *if_udp_stat; /* UDP specific stats */ |
858 | |
859 | struct { |
860 | int32_t level; /* cached logging level */ |
861 | u_int32_t flags; /* cached logging flags */ |
862 | int32_t category; /* cached category */ |
863 | int32_t subcategory; /* cached subcategory */ |
864 | } if_log; |
865 | |
866 | struct { |
867 | struct ifnet *ifp; /* delegated ifp */ |
868 | u_int32_t type; /* delegated i/f type */ |
869 | u_int32_t family; /* delegated i/f family */ |
870 | u_int32_t subfamily; /* delegated i/f sub-family */ |
871 | uint32_t expensive:1, /* delegated i/f expensive? */ |
872 | constrained:1; /* delegated i/f constrained? */ |
873 | } if_delegated; |
874 | |
875 | uuid_t *if_agentids; /* network agents attached to interface */ |
876 | u_int32_t if_agentcount; |
877 | |
878 | volatile uint32_t if_low_power_gencnt; |
879 | |
880 | u_int32_t if_generation; /* generation to use with NECP clients */ |
881 | u_int32_t if_fg_sendts; /* last send on a fg socket in seconds */ |
882 | |
883 | u_int64_t if_data_threshold; |
884 | |
885 | /* Total bytes in send socket buffer */ |
886 | int64_t if_sndbyte_total __attribute__ ((aligned(8))); |
887 | /* Total unsent bytes in send socket buffer */ |
888 | int64_t if_sndbyte_unsent __attribute__ ((aligned(8))); |
889 | /* count of times, when there was data to send when sleep is impending */ |
890 | uint32_t if_unsent_data_cnt; |
891 | |
892 | boolean_t if_inet6_ioctl_busy; |
893 | decl_lck_mtx_data(, if_inet6_ioctl_lock); |
894 | |
895 | #if INET |
896 | decl_lck_rw_data(, if_inetdata_lock); |
897 | struct in_ifextra *if_inetdata; |
898 | #endif /* INET */ |
899 | decl_lck_rw_data(, if_inet6data_lock); |
900 | struct in6_ifextra *if_inet6data; |
901 | decl_lck_rw_data(, if_link_status_lock); |
902 | struct if_link_status *if_link_status; |
903 | struct if_interface_state if_interface_state; |
904 | struct if_tcp_ecn_stat *if_ipv4_stat; |
905 | struct if_tcp_ecn_stat *if_ipv6_stat; |
906 | |
907 | #if SKYWALK |
908 | /* Keeps track of local ports bound to this interface |
909 | * Protected by the global lock in skywalk/netns/netns.c */ |
910 | SLIST_HEAD(, ns_token) if_netns_tokens; |
911 | #endif /* SKYWALK */ |
912 | struct if_lim_perf_stat if_lim_stat; |
913 | |
914 | uint32_t if_tcp_kao_max; |
915 | uint32_t if_tcp_kao_cnt; |
916 | |
917 | #if SKYWALK |
918 | struct netem *if_input_netem; |
919 | #endif /* SKYWALK */ |
920 | struct netem *if_output_netem; |
921 | |
922 | ipv6_router_mode_t if_ipv6_router_mode; /* see <netinet6/in6_var.h> */ |
923 | |
924 | u_int8_t if_estimated_up_bucket; |
925 | u_int8_t if_estimated_down_bucket; |
926 | u_int8_t if_radio_type; |
927 | u_int8_t if_radio_channel; |
928 | |
929 | uint8_t network_id[IFNET_NETWORK_ID_LEN]; |
930 | uint8_t network_id_len; |
931 | |
932 | atomic_bool if_mcast_add_signaled; |
933 | atomic_bool if_mcast_del_signaled; |
934 | |
935 | uint32_t if_traffic_rule_count; |
936 | uint32_t if_traffic_rule_genid; |
937 | |
938 | /* |
939 | * if_creation_generation_id is assigned the value of a global counter that |
940 | * is incremented when the interface is allocated and when it is freed. |
941 | * |
942 | * This allows to discriminate between different instances of an interface |
943 | * that has the same name or same index |
944 | */ |
945 | uint64_t if_creation_generation_id; |
946 | }; |
947 | |
948 | /* Interface event handling declarations */ |
949 | extern struct eventhandler_lists_ctxt ifnet_evhdlr_ctxt; |
950 | |
951 | typedef enum { |
952 | INTF_EVENT_CODE_CREATED, |
953 | INTF_EVENT_CODE_REMOVED, |
954 | INTF_EVENT_CODE_STATUS_UPDATE, |
955 | INTF_EVENT_CODE_IPADDR_ATTACHED, |
956 | INTF_EVENT_CODE_IPADDR_DETACHED, |
957 | INTF_EVENT_CODE_LLADDR_UPDATE, |
958 | INTF_EVENT_CODE_MTU_CHANGED, |
959 | INTF_EVENT_CODE_LOW_POWER_UPDATE, |
960 | } intf_event_code_t; |
961 | |
962 | typedef void (*ifnet_event_fn)(struct eventhandler_entry_arg, struct ifnet *, struct sockaddr *, intf_event_code_t); |
963 | EVENTHANDLER_DECLARE(ifnet_event, ifnet_event_fn); |
964 | |
965 | #define IF_TCP_STATINC(_ifp, _s) do { \ |
966 | if ((_ifp)->if_tcp_stat != NULL) \ |
967 | os_atomic_inc(&(_ifp)->if_tcp_stat->_s, relaxed); \ |
968 | } while (0); |
969 | |
970 | #define IF_UDP_STATINC(_ifp, _s) do { \ |
971 | if ((_ifp)->if_udp_stat != NULL) \ |
972 | os_atomic_inc(&(_ifp)->if_udp_stat->_s, relaxed); \ |
973 | } while (0); |
974 | |
975 | /* |
976 | * Valid values for if_refflags |
977 | */ |
978 | #define IFRF_EMBRYONIC 0x1 /* ifnet is allocated; awaiting attach */ |
979 | #define IFRF_ATTACHED 0x2 /* ifnet attach is completely done */ |
980 | #define IFRF_DETACHING 0x4 /* detach has been requested */ |
981 | #define IFRF_READY 0x8 /* data path is ready */ |
982 | |
983 | #define IFRF_ATTACH_MASK \ |
984 | (IFRF_EMBRYONIC|IFRF_ATTACHED|IFRF_DETACHING) |
985 | |
986 | #define IF_FULLY_ATTACHED(_ifp) \ |
987 | (((_ifp)->if_refflags & IFRF_ATTACH_MASK) == IFRF_ATTACHED) |
988 | |
989 | #define IF_FULLY_ATTACHED_AND_READY(_ifp) \ |
990 | (IF_FULLY_ATTACHED(_ifp) && ((_ifp)->if_refflags & IFRF_READY)) |
991 | /* |
992 | * Valid values for if_start_flags |
993 | */ |
994 | #define IFSF_FLOW_CONTROLLED 0x1 /* flow controlled */ |
995 | #define IFSF_TERMINATING 0x2 /* terminating */ |
996 | #define IFSF_NO_DELAY 0x4 /* no delay */ |
997 | |
998 | /* |
999 | * Structure describing a `cloning' interface. |
1000 | */ |
1001 | struct if_clone { |
1002 | LIST_ENTRY(if_clone) ifc_list; /* on list of cloners */ |
1003 | decl_lck_mtx_data(, ifc_mutex); /* To serialize clone create/delete */ |
1004 | u_int32_t ifc_minifs; /* minimum number of interfaces */ |
1005 | u_int32_t ifc_maxunit; /* maximum unit number */ |
1006 | unsigned char *ifc_units; /* bitmap to handle units */ |
1007 | u_int32_t ifc_bmlen; /* bitmap length */ |
1008 | int (*ifc_create)(struct if_clone *, u_int32_t, void *); |
1009 | int (*ifc_destroy)(struct ifnet *); |
1010 | uint8_t ifc_namelen; /* length of name */ |
1011 | char ifc_name[IFNAMSIZ + 1]; /* name of device, e.g. `vlan' */ |
1012 | }; |
1013 | |
1014 | #define IF_CLONE_INITIALIZER(name, create, destroy, minifs, maxunit) { \ |
1015 | .ifc_name = "" name, \ |
1016 | .ifc_namelen = (sizeof(name) - 1), \ |
1017 | .ifc_minifs = (minifs), \ |
1018 | .ifc_maxunit = (maxunit), \ |
1019 | .ifc_create = (create), \ |
1020 | .ifc_destroy = (destroy) \ |
1021 | } |
1022 | |
1023 | /* |
1024 | * Macros to manipulate ifqueue. Users of these macros are responsible |
1025 | * for serialization, by holding whatever lock is appropriate for the |
1026 | * corresponding structure that is referring the ifqueue. |
1027 | */ |
1028 | #define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) |
1029 | #define IF_DROP(ifq) ((ifq)->ifq_drops++) |
1030 | |
1031 | #define IF_ENQUEUE(ifq, m) do { \ |
1032 | (m)->m_nextpkt = NULL; \ |
1033 | if ((ifq)->ifq_tail == NULL) \ |
1034 | (ifq)->ifq_head = m; \ |
1035 | else \ |
1036 | ((struct mbuf*)(ifq)->ifq_tail)->m_nextpkt = m; \ |
1037 | (ifq)->ifq_tail = m; \ |
1038 | (ifq)->ifq_len++; \ |
1039 | } while (0) |
1040 | |
1041 | #define IF_PREPEND(ifq, m) do { \ |
1042 | (m)->m_nextpkt = (mbuf_ref_t)(ifq)->ifq_head; \ |
1043 | if ((ifq)->ifq_tail == NULL) \ |
1044 | (ifq)->ifq_tail = (m); \ |
1045 | (ifq)->ifq_head = (m); \ |
1046 | (ifq)->ifq_len++; \ |
1047 | } while (0) |
1048 | |
1049 | #define IF_DEQUEUE(ifq, m) do { \ |
1050 | (m) = (mbuf_ref_t)(ifq)->ifq_head; \ |
1051 | if (m != NULL) { \ |
1052 | if (((ifq)->ifq_head = (m)->m_nextpkt) == NULL) \ |
1053 | (ifq)->ifq_tail = NULL; \ |
1054 | (m)->m_nextpkt = NULL; \ |
1055 | (ifq)->ifq_len--; \ |
1056 | } \ |
1057 | } while (0) |
1058 | |
1059 | #define IF_REMQUEUE(ifq, m) do { \ |
1060 | mbuf_ref_t _p = (mbuf_ref_t)(ifq)->ifq_head; \ |
1061 | mbuf_ref_t _n = (m)->m_nextpkt; \ |
1062 | if ((m) == _p) \ |
1063 | _p = NULL; \ |
1064 | while (_p != NULL) { \ |
1065 | if (_p->m_nextpkt == (m)) \ |
1066 | break; \ |
1067 | _p = _p->m_nextpkt; \ |
1068 | } \ |
1069 | VERIFY(_p != NULL || ((m) == (ifq)->ifq_head)); \ |
1070 | if ((m) == (ifq)->ifq_head) \ |
1071 | (ifq)->ifq_head = _n; \ |
1072 | if ((m) == (ifq)->ifq_tail) \ |
1073 | (ifq)->ifq_tail = _p; \ |
1074 | VERIFY((ifq)->ifq_tail != NULL || (ifq)->ifq_head == NULL); \ |
1075 | VERIFY((ifq)->ifq_len != 0); \ |
1076 | --(ifq)->ifq_len; \ |
1077 | if (_p != NULL) \ |
1078 | _p->m_nextpkt = _n; \ |
1079 | (m)->m_nextpkt = NULL; \ |
1080 | } while (0) |
1081 | |
1082 | #define IF_DRAIN(ifq) do { \ |
1083 | struct mbuf *_m; \ |
1084 | for (;;) { \ |
1085 | IF_DEQUEUE(ifq, _m); \ |
1086 | if (_m == NULL) \ |
1087 | break; \ |
1088 | m_freem(_m); \ |
1089 | } \ |
1090 | } while (0) |
1091 | |
1092 | /* |
1093 | * The ifaddr structure contains information about one address |
1094 | * of an interface. They are maintained by the different address families, |
1095 | * are allocated and attached when an address is set, and are linked |
1096 | * together so all addresses for an interface can be located. |
1097 | */ |
1098 | struct ifaddr { |
1099 | decl_lck_mtx_data(, ifa_lock); /* lock for ifaddr */ |
1100 | os_ref_atomic_t ifa_refcnt; /* ref count, use IFA_{ADD,REM}REF */ |
1101 | uint32_t ifa_debug; /* debug flags */ |
1102 | struct sockaddr *ifa_addr; /* address of interface */ |
1103 | struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */ |
1104 | #define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ |
1105 | struct sockaddr *ifa_netmask; /* used to determine subnet */ |
1106 | struct ifnet *ifa_ifp; /* back-pointer to interface */ |
1107 | TAILQ_ENTRY(ifaddr) ifa_link; /* queue macro glue */ |
1108 | void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */ |
1109 | (int, struct rtentry *, struct sockaddr *); |
1110 | uint32_t ifa_flags; /* mostly rt_flags for cloning */ |
1111 | int32_t ifa_metric; /* cost of going out this interface */ |
1112 | void (*ifa_free)(struct ifaddr *); /* callback fn for freeing */ |
1113 | void *ifa_del_wc; /* Wait channel to avoid address deletion races */ |
1114 | int ifa_del_waiters; /* Threads in wait to delete the address */ |
1115 | }; |
1116 | |
1117 | /* |
1118 | * Valid values for ifa_flags |
1119 | */ |
1120 | #define IFA_ROUTE RTF_UP /* route installed (0x1) */ |
1121 | #define IFA_CLONING RTF_CLONING /* (0x100) */ |
1122 | |
1123 | /* |
1124 | * Valid values for ifa_debug |
1125 | */ |
1126 | #define IFD_ATTACHED 0x1 /* attached to list */ |
1127 | #define IFD_ALLOC 0x2 /* dynamically allocated */ |
1128 | #define IFD_DEBUG 0x4 /* has debugging info */ |
1129 | #define IFD_LINK 0x8 /* link address */ |
1130 | #define IFD_TRASHED 0x10 /* in trash list */ |
1131 | #define IFD_DETACHING 0x20 /* detach is in progress */ |
1132 | #define IFD_NOTREADY 0x40 /* embryonic; not yet ready */ |
1133 | |
1134 | #define IFA_LOCK_ASSERT_HELD(_ifa) \ |
1135 | LCK_MTX_ASSERT(&(_ifa)->ifa_lock, LCK_MTX_ASSERT_OWNED) |
1136 | |
1137 | #define IFA_LOCK_ASSERT_NOTHELD(_ifa) \ |
1138 | LCK_MTX_ASSERT(&(_ifa)->ifa_lock, LCK_MTX_ASSERT_NOTOWNED) |
1139 | |
1140 | #define IFA_LOCK(_ifa) \ |
1141 | lck_mtx_lock(&(_ifa)->ifa_lock) |
1142 | |
1143 | #define IFA_LOCK_SPIN(_ifa) \ |
1144 | lck_mtx_lock_spin(&(_ifa)->ifa_lock) |
1145 | |
1146 | #define IFA_CONVERT_LOCK(_ifa) do { \ |
1147 | IFA_LOCK_ASSERT_HELD(_ifa); \ |
1148 | lck_mtx_convert_spin(&(_ifa)->ifa_lock); \ |
1149 | } while (0) |
1150 | |
1151 | #define IFA_UNLOCK(_ifa) \ |
1152 | lck_mtx_unlock(&(_ifa)->ifa_lock) |
1153 | |
1154 | os_refgrp_decl(static, ifa_refgrp, "ifa refcounts" , NULL); |
1155 | |
1156 | static inline void |
1157 | ifa_addref(struct ifaddr *ifa) |
1158 | { |
1159 | os_ref_retain_raw(&ifa->ifa_refcnt, &ifa_refgrp); |
1160 | } |
1161 | |
1162 | __private_extern__ void ifa_deallocated(struct ifaddr *ifa); |
1163 | |
1164 | static inline void |
1165 | ifa_remref(struct ifaddr *ifa) |
1166 | { |
1167 | /* We can use _relaxed, because if we hit 0 we make sure the lock is held */ |
1168 | if (os_ref_release_raw_relaxed(&ifa->ifa_refcnt, &ifa_refgrp) == 0) { |
1169 | ifa_deallocated(ifa); |
1170 | } |
1171 | } |
1172 | |
1173 | /* |
1174 | * Multicast address structure. This is analogous to the ifaddr |
1175 | * structure except that it keeps track of multicast addresses. |
1176 | * Also, the request count here is a count of requests for this |
1177 | * address, not a count of pointers to this structure; anonymous |
1178 | * membership(s) holds one outstanding request count. |
1179 | */ |
1180 | struct ifmultiaddr { |
1181 | decl_lck_mtx_data(, ifma_lock); |
1182 | u_int32_t ifma_refcount; /* reference count */ |
1183 | u_int32_t ifma_anoncnt; /* # of anonymous requests */ |
1184 | u_int32_t ifma_reqcnt; /* total requests for this address */ |
1185 | u_int32_t ifma_debug; /* see ifa_debug flags */ |
1186 | u_int32_t ifma_flags; /* see below */ |
1187 | LIST_ENTRY(ifmultiaddr) ifma_link; /* queue macro glue */ |
1188 | struct sockaddr *ifma_addr; /* address this membership is for */ |
1189 | struct ifmultiaddr *ifma_ll; /* link-layer translation, if any */ |
1190 | struct ifnet *ifma_ifp; /* back-pointer to interface */ |
1191 | void *ifma_protospec; /* protocol-specific state, if any */ |
1192 | void (*ifma_trace) /* callback fn for tracing refs */ |
1193 | (struct ifmultiaddr *, int); |
1194 | }; |
1195 | |
1196 | /* |
1197 | * Values for ifma_flags |
1198 | */ |
1199 | #define IFMAF_ANONYMOUS 0x1 /* has anonymous request ref(s) held */ |
1200 | |
1201 | #define IFMA_LOCK_ASSERT_HELD(_ifma) \ |
1202 | LCK_MTX_ASSERT(&(_ifma)->ifma_lock, LCK_MTX_ASSERT_OWNED) |
1203 | |
1204 | #define IFMA_LOCK_ASSERT_NOTHELD(_ifma) \ |
1205 | LCK_MTX_ASSERT(&(_ifma)->ifma_lock, LCK_MTX_ASSERT_NOTOWNED) |
1206 | |
1207 | #define IFMA_LOCK(_ifma) \ |
1208 | lck_mtx_lock(&(_ifma)->ifma_lock) |
1209 | |
1210 | #define IFMA_LOCK_SPIN(_ifma) \ |
1211 | lck_mtx_lock_spin(&(_ifma)->ifma_lock) |
1212 | |
1213 | #define IFMA_CONVERT_LOCK(_ifma) do { \ |
1214 | IFMA_LOCK_ASSERT_HELD(_ifma); \ |
1215 | lck_mtx_convert_spin(&(_ifma)->ifma_lock); \ |
1216 | } while (0) |
1217 | |
1218 | #define IFMA_UNLOCK(_ifma) \ |
1219 | lck_mtx_unlock(&(_ifma)->ifma_lock) |
1220 | |
1221 | #define IFMA_ADDREF(_ifma) \ |
1222 | ifma_addref(_ifma, 0) |
1223 | |
1224 | #define IFMA_ADDREF_LOCKED(_ifma) \ |
1225 | ifma_addref(_ifma, 1) |
1226 | |
1227 | #define IFMA_REMREF(_ifma) \ |
1228 | ifma_remref(_ifma) |
1229 | |
1230 | /* |
1231 | * Indicate whether or not the immediate interface, or the interface delegated |
1232 | * by it, is a cellular interface (IFT_CELLULAR). Delegated interface type is |
1233 | * set/cleared along with the delegated ifp; we cache the type for performance |
1234 | * to avoid dereferencing delegated ifp each time. |
1235 | * |
1236 | * Note that this is meant to be used only for accounting and policy purposes; |
1237 | * certain places need to explicitly know the immediate interface type, and |
1238 | * this macro should not be used there. |
1239 | * |
1240 | * The test is done against IFT_CELLULAR instead of IFNET_FAMILY_CELLULAR to |
1241 | * handle certain cases where the family isn't set to the latter. |
1242 | * |
1243 | * This macro also handles the case of IFNET_FAMILY_ETHERNET with |
1244 | * IFNET_SUBFAMILY_SIMCELL which is used to simulate a cellular interface |
1245 | * for testing purposes. The underlying interface is Ethernet but we treat |
1246 | * it as cellular for accounting and policy purposes. |
1247 | */ |
1248 | #define IFNET_IS_CELLULAR(_ifp) \ |
1249 | ((_ifp)->if_type == IFT_CELLULAR || \ |
1250 | (_ifp)->if_delegated.type == IFT_CELLULAR || \ |
1251 | (((_ifp)->if_family == IFNET_FAMILY_ETHERNET && \ |
1252 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_SIMCELL)) || \ |
1253 | ((_ifp)->if_delegated.family == IFNET_FAMILY_ETHERNET && \ |
1254 | (_ifp)->if_delegated.subfamily == IFNET_SUBFAMILY_SIMCELL)) |
1255 | |
1256 | /* |
1257 | * Indicate whether or not the immediate interface, or the interface delegated |
1258 | * by it, is an ETHERNET interface. |
1259 | */ |
1260 | #define IFNET_IS_ETHERNET(_ifp) \ |
1261 | ((_ifp)->if_family == IFNET_FAMILY_ETHERNET || \ |
1262 | (_ifp)->if_delegated.family == IFNET_FAMILY_ETHERNET) |
1263 | /* |
1264 | * Indicate whether or not the immediate interface, or the interface delegated |
1265 | * by it, is a Wi-Fi interface (IFNET_SUBFAMILY_WIFI). Delegated interface |
1266 | * subfamily is set/cleared along with the delegated ifp; we cache the subfamily |
1267 | * for performance to avoid dereferencing delegated ifp each time. |
1268 | * |
1269 | * Note that this is meant to be used only for accounting and policy purposes; |
1270 | * certain places need to explicitly know the immediate interface type, and |
1271 | * this macro should not be used there. |
1272 | * |
1273 | * The test is done against IFNET_SUBFAMILY_WIFI as the family may be set to |
1274 | * IFNET_FAMILY_ETHERNET (as well as type to IFT_ETHER) which is too generic. |
1275 | */ |
1276 | #define IFNET_IS_WIFI(_ifp) \ |
1277 | (((_ifp)->if_family == IFNET_FAMILY_ETHERNET && \ |
1278 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_WIFI) || \ |
1279 | ((_ifp)->if_delegated.family == IFNET_FAMILY_ETHERNET && \ |
1280 | (_ifp)->if_delegated.subfamily == IFNET_SUBFAMILY_WIFI)) |
1281 | |
1282 | /* |
1283 | * Indicate whether or not the immediate interface, or the interface delegated |
1284 | * by it, is a Wired interface (several families). Delegated interface |
1285 | * family is set/cleared along with the delegated ifp; we cache the family |
1286 | * for performance to avoid dereferencing delegated ifp each time. |
1287 | * |
1288 | * Note that this is meant to be used only for accounting and policy purposes; |
1289 | * certain places need to explicitly know the immediate interface type, and |
1290 | * this macro should not be used there. |
1291 | */ |
1292 | #define IFNET_IS_WIRED(_ifp) \ |
1293 | ((_ifp)->if_family == IFNET_FAMILY_ETHERNET || \ |
1294 | (_ifp)->if_delegated.family == IFNET_FAMILY_ETHERNET || \ |
1295 | (_ifp)->if_family == IFNET_FAMILY_FIREWIRE || \ |
1296 | (_ifp)->if_delegated.family == IFNET_FAMILY_FIREWIRE) |
1297 | |
1298 | /* |
1299 | * Indicate whether or not the immediate WiFi interface is on an infrastructure |
1300 | * network |
1301 | */ |
1302 | #define IFNET_IS_WIFI_INFRA(_ifp) \ |
1303 | ((_ifp)->if_family == IFNET_FAMILY_ETHERNET && \ |
1304 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_WIFI && \ |
1305 | !((_ifp)->if_eflags & IFEF_AWDL) && \ |
1306 | !((_ifp)->if_xflags & IFXF_LOW_LATENCY)) |
1307 | |
1308 | /* |
1309 | * Indicate whether or not the immediate interface is a companion link |
1310 | * interface. |
1311 | */ |
1312 | #define IFNET_IS_COMPANION_LINK(_ifp) \ |
1313 | ((_ifp)->if_family == IFNET_FAMILY_IPSEC && \ |
1314 | ((_ifp)->if_subfamily == IFNET_SUBFAMILY_BLUETOOTH || \ |
1315 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_WIFI || \ |
1316 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_QUICKRELAY || \ |
1317 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_DEFAULT)) |
1318 | |
1319 | /* |
1320 | * Indicate whether or not the immediate interface, or the interface delegated |
1321 | * by it, is marked as expensive. The delegated interface is set/cleared |
1322 | * along with the delegated ifp; we cache the flag for performance to avoid |
1323 | * dereferencing delegated ifp each time. |
1324 | * |
1325 | * Note that this is meant to be used only for policy purposes. |
1326 | */ |
1327 | #define IFNET_IS_EXPENSIVE(_ifp) \ |
1328 | ((_ifp)->if_eflags & IFEF_EXPENSIVE || \ |
1329 | (_ifp)->if_delegated.expensive) |
1330 | |
1331 | #define IFNET_IS_LOW_POWER(_ifp) \ |
1332 | (if_low_power_restricted != 0 && \ |
1333 | ((_ifp)->if_xflags & IFXF_LOW_POWER) || \ |
1334 | ((_ifp)->if_delegated.ifp != NULL && \ |
1335 | ((_ifp)->if_delegated.ifp->if_xflags & IFXF_LOW_POWER))) |
1336 | |
1337 | #define IFNET_IS_CONSTRAINED(_ifp) \ |
1338 | ((_ifp)->if_xflags & IFXF_CONSTRAINED || \ |
1339 | (_ifp)->if_delegated.constrained) |
1340 | |
1341 | /* |
1342 | * We don't support AWDL interface delegation. |
1343 | */ |
1344 | #define IFNET_IS_AWDL_RESTRICTED(_ifp) \ |
1345 | (((_ifp)->if_eflags & (IFEF_AWDL|IFEF_AWDL_RESTRICTED)) == \ |
1346 | (IFEF_AWDL|IFEF_AWDL_RESTRICTED)) |
1347 | |
1348 | #define IFNET_IS_INTCOPROC(_ifp) \ |
1349 | ((_ifp)->if_family == IFNET_FAMILY_ETHERNET && \ |
1350 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_INTCOPROC) |
1351 | |
1352 | #define IFNET_IS_VMNET(_ifp) \ |
1353 | ((_ifp)->if_family == IFNET_FAMILY_ETHERNET && \ |
1354 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_VMNET) |
1355 | |
1356 | #define IFNET_IS_MANAGEMENT(_ifp) \ |
1357 | (((_ifp)->if_xflags & IFXF_MANAGEMENT) != 0) |
1358 | |
1359 | /* |
1360 | * Indicate whether or not the immediate interface is IP over Thunderbolt. |
1361 | */ |
1362 | #define IFNET_IS_THUNDERBOLT_IP(_ifp) \ |
1363 | ((_ifp)->if_family == IFNET_FAMILY_ETHERNET && \ |
1364 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_THUNDERBOLT) |
1365 | |
1366 | #define IFNET_IS_REDIRECT(_ifp) \ |
1367 | (((_ifp)->if_family == IFNET_FAMILY_ETHERNET || \ |
1368 | (_ifp)->if_family == IFNET_FAMILY_CELLULAR) && \ |
1369 | (_ifp)->if_subfamily == IFNET_SUBFAMILY_REDIRECT) |
1370 | |
1371 | extern int if_index; |
1372 | extern uint32_t ifindex2ifnetcount; |
1373 | extern struct ifnethead ifnet_head; |
1374 | extern struct ifnethead ifnet_ordered_head; |
1375 | extern struct ifnet **__counted_by(ifindex2ifnetcount) ifindex2ifnet; |
1376 | extern u_int32_t if_sndq_maxlen; |
1377 | extern u_int32_t if_rcvq_maxlen; |
1378 | extern struct ifaddr **__counted_by(if_index) ifnet_addrs; |
1379 | extern lck_attr_t ifa_mtx_attr; |
1380 | extern lck_grp_t ifa_mtx_grp; |
1381 | extern lck_grp_t ifnet_lock_group; |
1382 | extern lck_attr_t ifnet_lock_attr; |
1383 | extern ifnet_t lo_ifp; |
1384 | extern uint32_t net_wake_pkt_debug; |
1385 | |
1386 | extern int if_addmulti(struct ifnet *, const struct sockaddr *, |
1387 | struct ifmultiaddr **); |
1388 | extern int if_addmulti_anon(struct ifnet *, const struct sockaddr *, |
1389 | struct ifmultiaddr **); |
1390 | extern int if_allmulti(struct ifnet *, int); |
1391 | extern int if_delmulti(struct ifnet *, const struct sockaddr *); |
1392 | extern int if_delmulti_ifma(struct ifmultiaddr *); |
1393 | extern int if_delmulti_anon(struct ifnet *, const struct sockaddr *); |
1394 | extern void if_down(struct ifnet *); |
1395 | extern int if_down_all(void); |
1396 | extern void if_up(struct ifnet *); |
1397 | __private_extern__ void if_updown(struct ifnet *ifp, int up); |
1398 | extern int ifioctl(struct socket *, u_long, caddr_t, struct proc *); |
1399 | extern int ifioctllocked(struct socket *, u_long, caddr_t, struct proc *); |
1400 | extern struct ifnet *ifunit(const char *); |
1401 | extern struct ifnet *ifunit_ref(const char *); |
1402 | extern int (const char *src, char *dst, size_t dstlen, int *unit); |
1403 | extern struct ifnet *if_withname(struct sockaddr *); |
1404 | extern void if_qflush(struct ifnet *, struct ifclassq *, bool); |
1405 | extern void if_qflush_snd(struct ifnet *, bool); |
1406 | extern void if_qflush_sc(struct ifnet *, mbuf_svc_class_t, u_int32_t, |
1407 | u_int32_t *, u_int32_t *, int); |
1408 | |
1409 | extern struct if_clone *if_clone_lookup(const char *, u_int32_t *); |
1410 | extern int if_clone_attach(struct if_clone *); |
1411 | extern void if_clone_detach(struct if_clone *); |
1412 | extern u_int32_t if_functional_type(struct ifnet *, bool); |
1413 | |
1414 | extern errno_t if_mcasts_update(struct ifnet *); |
1415 | |
1416 | typedef enum { |
1417 | IFNET_LCK_ASSERT_EXCLUSIVE, /* RW: held as writer */ |
1418 | IFNET_LCK_ASSERT_SHARED, /* RW: held as reader */ |
1419 | IFNET_LCK_ASSERT_OWNED, /* RW: writer/reader, MTX: held */ |
1420 | IFNET_LCK_ASSERT_NOTOWNED /* not held */ |
1421 | } ifnet_lock_assert_t; |
1422 | |
1423 | #define IF_LLADDR(_ifp) \ |
1424 | (LLADDR(SDL(((_ifp)->if_lladdr)->ifa_addr))) |
1425 | |
1426 | #define IF_INDEX_IN_RANGE(_ind_) ((_ind_) > 0 && \ |
1427 | (unsigned int)(_ind_) <= (unsigned int)if_index) |
1428 | |
1429 | __private_extern__ void ifnet_lock_assert(struct ifnet *, ifnet_lock_assert_t); |
1430 | __private_extern__ void ifnet_lock_shared(struct ifnet *ifp); |
1431 | __private_extern__ void ifnet_lock_exclusive(struct ifnet *ifp); |
1432 | __private_extern__ void ifnet_lock_done(struct ifnet *ifp); |
1433 | |
1434 | #if INET |
1435 | __private_extern__ void if_inetdata_lock_shared(struct ifnet *ifp); |
1436 | __private_extern__ void if_inetdata_lock_exclusive(struct ifnet *ifp); |
1437 | __private_extern__ void if_inetdata_lock_done(struct ifnet *ifp); |
1438 | #endif |
1439 | |
1440 | __private_extern__ void if_inet6data_lock_shared(struct ifnet *ifp); |
1441 | __private_extern__ void if_inet6data_lock_exclusive(struct ifnet *ifp); |
1442 | __private_extern__ void if_inet6data_lock_done(struct ifnet *ifp); |
1443 | |
1444 | __private_extern__ void ifnet_head_lock_shared(void); |
1445 | __private_extern__ void ifnet_head_lock_exclusive(void); |
1446 | __private_extern__ void ifnet_head_done(void); |
1447 | __private_extern__ void ifnet_head_assert_exclusive(void); |
1448 | |
1449 | __private_extern__ errno_t ifnet_set_idle_flags_locked(ifnet_t, u_int32_t, |
1450 | u_int32_t); |
1451 | __private_extern__ int ifnet_is_attached(struct ifnet *, int refio); |
1452 | __private_extern__ void ifnet_incr_pending_thread_count(struct ifnet *); |
1453 | __private_extern__ void ifnet_decr_pending_thread_count(struct ifnet *); |
1454 | __private_extern__ void ifnet_incr_iorefcnt(struct ifnet *); |
1455 | __private_extern__ void ifnet_decr_iorefcnt(struct ifnet *); |
1456 | __private_extern__ boolean_t ifnet_datamov_begin(struct ifnet *); |
1457 | __private_extern__ void ifnet_datamov_end(struct ifnet *); |
1458 | __private_extern__ void ifnet_datamov_suspend(struct ifnet *); |
1459 | __private_extern__ boolean_t ifnet_datamov_suspend_if_needed(struct ifnet *); |
1460 | __private_extern__ void ifnet_datamov_drain(struct ifnet *); |
1461 | __private_extern__ void ifnet_datamov_suspend_and_drain(struct ifnet *); |
1462 | __private_extern__ void ifnet_datamov_resume(struct ifnet *); |
1463 | __private_extern__ void ifnet_set_start_cycle(struct ifnet *, |
1464 | struct timespec *); |
1465 | __private_extern__ void ifnet_set_poll_cycle(struct ifnet *, |
1466 | struct timespec *); |
1467 | |
1468 | __private_extern__ void if_attach_ifa(struct ifnet *, struct ifaddr *); |
1469 | __private_extern__ void if_attach_link_ifa(struct ifnet *, struct ifaddr *); |
1470 | __private_extern__ void if_detach_ifa(struct ifnet *, struct ifaddr *); |
1471 | __private_extern__ void if_detach_link_ifa(struct ifnet *, struct ifaddr *); |
1472 | |
1473 | __private_extern__ void dlil_if_lock(void); |
1474 | __private_extern__ void dlil_if_unlock(void); |
1475 | __private_extern__ void dlil_if_lock_assert(void); |
1476 | |
1477 | extern struct ifaddr *ifa_ifwithaddr(const struct sockaddr *); |
1478 | extern struct ifaddr *ifa_ifwithaddr_locked(const struct sockaddr *); |
1479 | extern struct ifaddr *ifa_ifwithaddr_scoped(const struct sockaddr *, |
1480 | unsigned int); |
1481 | extern struct ifaddr *ifa_ifwithaddr_scoped_locked(const struct sockaddr *, |
1482 | unsigned int); |
1483 | extern struct ifaddr *ifa_ifwithdstaddr(const struct sockaddr *); |
1484 | extern struct ifaddr *ifa_ifwithdstaddr_scoped(const struct sockaddr *, |
1485 | unsigned int); |
1486 | extern struct ifaddr *ifa_ifwithnet(const struct sockaddr *); |
1487 | extern struct ifaddr *ifa_ifwithnet_scoped(const struct sockaddr *, |
1488 | unsigned int); |
1489 | extern struct ifaddr *ifa_ifwithroute(int, const struct sockaddr *, |
1490 | const struct sockaddr *); |
1491 | extern struct ifaddr *ifa_ifwithroute_locked(int, const struct sockaddr *, |
1492 | const struct sockaddr *); |
1493 | extern struct ifaddr *ifa_ifwithroute_scoped_locked(int, |
1494 | const struct sockaddr *, const struct sockaddr *, unsigned int); |
1495 | extern struct ifaddr *ifaof_ifpforaddr_select(const struct sockaddr *, struct ifnet *); |
1496 | extern struct ifaddr *ifaof_ifpforaddr(const struct sockaddr *, struct ifnet *); |
1497 | __private_extern__ struct ifaddr *ifa_ifpgetprimary(struct ifnet *, int); |
1498 | extern void ifa_initref(struct ifaddr *); |
1499 | extern void ifa_lock_init(struct ifaddr *); |
1500 | extern void ifa_lock_destroy(struct ifaddr *); |
1501 | extern void ifma_addref(struct ifmultiaddr *, int); |
1502 | extern void ifma_remref(struct ifmultiaddr *); |
1503 | |
1504 | extern void ifa_init(void); |
1505 | |
1506 | __private_extern__ struct in_ifaddr *ifa_foraddr(unsigned int); |
1507 | __private_extern__ struct in_ifaddr *ifa_foraddr_scoped(unsigned int, |
1508 | unsigned int); |
1509 | |
1510 | struct ifreq; |
1511 | extern errno_t ifnet_getset_opportunistic(struct ifnet *, u_long, |
1512 | struct ifreq *, struct proc *); |
1513 | extern int ifnet_get_throttle(struct ifnet *, u_int32_t *); |
1514 | extern int ifnet_set_throttle(struct ifnet *, u_int32_t); |
1515 | extern errno_t ifnet_getset_log(struct ifnet *, u_long, |
1516 | struct ifreq *, struct proc *); |
1517 | extern int ifnet_set_log(struct ifnet *, int32_t, uint32_t, int32_t, int32_t); |
1518 | extern int ifnet_get_log(struct ifnet *, int32_t *, uint32_t *, int32_t *, |
1519 | int32_t *); |
1520 | extern int ifnet_notify_address(struct ifnet *, int); |
1521 | extern void ifnet_notify_data_threshold(struct ifnet *); |
1522 | |
1523 | struct in6_addr; |
1524 | __private_extern__ struct in6_ifaddr *ifa_foraddr6(struct in6_addr *); |
1525 | __private_extern__ struct in6_ifaddr *ifa_foraddr6_scoped(struct in6_addr *, |
1526 | unsigned int); |
1527 | |
1528 | __private_extern__ void if_data_internal_to_if_data(struct ifnet *ifp, |
1529 | const struct if_data_internal *if_data_int, struct if_data *if_data); |
1530 | __private_extern__ void if_data_internal_to_if_data64(struct ifnet *ifp, |
1531 | const struct if_data_internal *if_data_int, struct if_data64 *if_data64); |
1532 | __private_extern__ void if_copy_traffic_class(struct ifnet *ifp, |
1533 | struct if_traffic_class *if_tc); |
1534 | __private_extern__ void if_copy_data_extended(struct ifnet *ifp, |
1535 | struct if_data_extended *if_de); |
1536 | __private_extern__ void if_copy_packet_stats(struct ifnet *ifp, |
1537 | struct if_packet_stats *if_ps); |
1538 | __private_extern__ void if_copy_rxpoll_stats(struct ifnet *ifp, |
1539 | struct if_rxpoll_stats *if_rs); |
1540 | __private_extern__ void if_copy_netif_stats(struct ifnet *ifp, |
1541 | struct if_netif_stats *if_ns); |
1542 | |
1543 | __private_extern__ struct rtentry *ifnet_cached_rtlookup_inet(struct ifnet *, |
1544 | struct in_addr); |
1545 | __private_extern__ struct rtentry *ifnet_cached_rtlookup_inet6(struct ifnet *, |
1546 | struct in6_addr *); |
1547 | |
1548 | __private_extern__ u_int32_t if_get_protolist(struct ifnet * ifp, |
1549 | u_int32_t *protolist, u_int32_t count); |
1550 | __private_extern__ void if_free_protolist(u_int32_t *list); |
1551 | __private_extern__ errno_t if_state_update(struct ifnet *, |
1552 | struct if_interface_state *); |
1553 | __private_extern__ void if_get_state(struct ifnet *, |
1554 | struct if_interface_state *); |
1555 | __private_extern__ errno_t if_probe_connectivity(struct ifnet *ifp, |
1556 | u_int32_t conn_probe); |
1557 | __private_extern__ void if_lqm_update(struct ifnet *, int32_t, int); |
1558 | __private_extern__ void ifnet_update_sndq(struct ifclassq *, cqev_t); |
1559 | __private_extern__ void ifnet_update_rcv(struct ifnet *, cqev_t); |
1560 | |
1561 | __private_extern__ void ifnet_flowadv(uint32_t); |
1562 | |
1563 | __private_extern__ errno_t ifnet_set_input_bandwidths(struct ifnet *, |
1564 | struct if_bandwidths *); |
1565 | __private_extern__ errno_t ifnet_set_output_bandwidths(struct ifnet *, |
1566 | struct if_bandwidths *, boolean_t); |
1567 | __private_extern__ u_int64_t ifnet_output_linkrate(struct ifnet *); |
1568 | __private_extern__ u_int64_t ifnet_input_linkrate(struct ifnet *); |
1569 | |
1570 | __private_extern__ errno_t ifnet_set_input_latencies(struct ifnet *, |
1571 | struct if_latencies *); |
1572 | __private_extern__ errno_t ifnet_set_output_latencies(struct ifnet *, |
1573 | struct if_latencies *, boolean_t); |
1574 | |
1575 | __private_extern__ void ifnet_clear_netagent(uuid_t); |
1576 | |
1577 | __private_extern__ int ifnet_set_netsignature(struct ifnet *, uint8_t, |
1578 | uint8_t, uint16_t, uint8_t *); |
1579 | __private_extern__ int ifnet_get_netsignature(struct ifnet *, uint8_t, |
1580 | uint8_t *, uint16_t *, uint8_t *); |
1581 | |
1582 | struct ipv6_prefix; |
1583 | __private_extern__ int ifnet_set_nat64prefix(struct ifnet *, |
1584 | struct ipv6_prefix *); |
1585 | __private_extern__ int ifnet_get_nat64prefix(struct ifnet *, |
1586 | struct ipv6_prefix *); |
1587 | |
1588 | /* Required exclusive ifnet_head lock */ |
1589 | __private_extern__ void ifnet_remove_from_ordered_list(struct ifnet *); |
1590 | |
1591 | __private_extern__ void ifnet_increment_generation(struct ifnet *); |
1592 | __private_extern__ u_int32_t ifnet_get_generation(struct ifnet *); |
1593 | |
1594 | /* Adding and deleting netagents will take ifnet lock */ |
1595 | __private_extern__ int if_add_netagent(struct ifnet *, uuid_t); |
1596 | __private_extern__ int if_add_netagent_locked(struct ifnet *, uuid_t); |
1597 | __private_extern__ int if_delete_netagent(struct ifnet *, uuid_t); |
1598 | __private_extern__ boolean_t if_check_netagent(struct ifnet *, uuid_t); |
1599 | |
1600 | #if SKYWALK |
1601 | extern unsigned int if_enable_fsw_ip_netagent; |
1602 | static inline boolean_t |
1603 | if_is_fsw_ip_netagent_enabled(void) |
1604 | { |
1605 | return if_enable_fsw_ip_netagent != 0; |
1606 | } |
1607 | extern unsigned int if_enable_fsw_transport_netagent; |
1608 | static inline boolean_t |
1609 | if_is_fsw_transport_netagent_enabled(void) |
1610 | { |
1611 | return if_enable_fsw_transport_netagent != 0; |
1612 | } |
1613 | static inline boolean_t |
1614 | if_is_fsw_netagent_enabled(void) |
1615 | { |
1616 | return if_is_fsw_transport_netagent_enabled() || |
1617 | if_is_fsw_ip_netagent_enabled(); |
1618 | } |
1619 | #endif /* SKYWALK */ |
1620 | |
1621 | extern int if_set_qosmarking_mode(struct ifnet *, u_int32_t); |
1622 | __private_extern__ uint32_t ifnet_mbuf_packetpreamblelen(struct ifnet *); |
1623 | __private_extern__ void intf_event_enqueue_nwk_wq_entry(struct ifnet *ifp, |
1624 | struct sockaddr *addrp, uint32_t intf_event_code); |
1625 | __private_extern__ void ifnet_update_stats_per_flow(struct ifnet_stats_per_flow *, |
1626 | struct ifnet *); |
1627 | __private_extern__ int if_get_tcp_kao_max(struct ifnet *); |
1628 | #if XNU_TARGET_OS_OSX |
1629 | __private_extern__ errno_t ifnet_framer_stub(struct ifnet *, struct mbuf **, |
1630 | const struct sockaddr *, const char *, const char *, u_int32_t *, |
1631 | u_int32_t *); |
1632 | #endif /* XNU_TARGET_OS_OSX */ |
1633 | __private_extern__ void ifnet_enqueue_multi_setup(struct ifnet *, uint16_t, |
1634 | uint16_t); |
1635 | __private_extern__ errno_t ifnet_enqueue_mbuf(struct ifnet *, struct mbuf *, |
1636 | boolean_t, boolean_t *); |
1637 | __private_extern__ errno_t ifnet_enqueue_mbuf_chain(struct ifnet *, |
1638 | struct mbuf *, struct mbuf *, uint32_t, uint32_t, boolean_t, boolean_t *); |
1639 | __private_extern__ int ifnet_enqueue_netem(void *handle, pktsched_pkt_t *pkts, |
1640 | uint32_t n_pkts); |
1641 | #if SKYWALK |
1642 | struct __kern_packet; |
1643 | extern errno_t ifnet_enqueue_pkt(struct ifnet *, |
1644 | struct __kern_packet *, boolean_t, boolean_t *); |
1645 | extern errno_t ifnet_enqueue_ifcq_pkt(struct ifnet *, struct ifclassq *, |
1646 | struct __kern_packet *, boolean_t, boolean_t *); |
1647 | extern errno_t ifnet_enqueue_pkt_chain(struct ifnet *, struct __kern_packet *, |
1648 | struct __kern_packet *, uint32_t, uint32_t, boolean_t, boolean_t *); |
1649 | extern errno_t ifnet_enqueue_ifcq_pkt_chain(struct ifnet *, struct ifclassq *, |
1650 | struct __kern_packet *, struct __kern_packet *, uint32_t, uint32_t, boolean_t, |
1651 | boolean_t *); |
1652 | extern errno_t ifnet_set_output_handler(struct ifnet *, ifnet_output_func); |
1653 | extern void ifnet_reset_output_handler(struct ifnet *); |
1654 | extern errno_t ifnet_set_start_handler(struct ifnet *, ifnet_start_func); |
1655 | extern void ifnet_reset_start_handler(struct ifnet *); |
1656 | |
1657 | #define SK_NXS_MS_IF_ADDR_GENCNT_INC(ifp) \ |
1658 | os_atomic_inc(&(ifp)->if_nx_flowswitch.if_fsw_ipaddr_gencnt, relaxed); |
1659 | #endif /* SKYWALK */ |
1660 | |
1661 | extern int if_low_power_verbose; |
1662 | extern int if_low_power_restricted; |
1663 | extern void if_low_power_evhdlr_init(void); |
1664 | extern int if_set_low_power(struct ifnet *, bool); |
1665 | extern u_int32_t if_set_eflags(ifnet_t, u_int32_t); |
1666 | extern void if_clear_eflags(ifnet_t, u_int32_t); |
1667 | extern u_int32_t if_set_xflags(ifnet_t, u_int32_t); |
1668 | extern void if_clear_xflags(ifnet_t, u_int32_t); |
1669 | extern boolean_t sa_equal(const struct sockaddr *, const struct sockaddr *); |
1670 | extern void ifnet_update_traffic_rule_genid(struct ifnet *); |
1671 | extern boolean_t ifnet_sync_traffic_rule_genid(struct ifnet *, uint32_t *); |
1672 | extern void ifnet_update_traffic_rule_count(struct ifnet *, uint32_t); |
1673 | |
1674 | #endif /* BSD_KERNEL_PRIVATE */ |
1675 | #endif /* DRIVERKIT */ |
1676 | |
1677 | #endif /* !_NET_IF_VAR_PRIVATE_H_ */ |
1678 | |