]> git.saurik.com Git - apple/xnu.git/blob - bsd/net/dlil.h
d1e4924f9aa0cada1c27299628480e55416dab6e
[apple/xnu.git] / bsd / net / dlil.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Copyright (c) 1999 Apple Computer, Inc.
25 *
26 * Data Link Inteface Layer
27 * Author: Ted Walker
28 */
29 #ifndef DLIL_H
30 #define DLIL_H
31 #ifdef KERNEL
32 #include <sys/kernel_types.h>
33 #include <net/kpi_interface.h>
34
35 #if __STDC__
36
37 struct ifnet;
38 struct mbuf;
39 struct ether_header;
40 struct sockaddr_dl;
41
42 #endif
43
44
45 #ifdef KERNEL_PRIVATE
46 #define DLIL_LAST_FILTER -1
47 #define DLIL_NULL_FILTER -2
48
49 #define DLIL_WAIT_FOR_FREE -2
50
51 #define DLIL_BLUEBOX 1
52
53
54
55 #include <net/if.h>
56 #include <net/if_var.h>
57 #include <sys/kern_event.h>
58
59 #endif KERNEL_PRIVATE
60
61 enum {
62 BPF_TAP_DISABLE,
63 BPF_TAP_INPUT,
64 BPF_TAP_OUTPUT,
65 BPF_TAP_INPUT_OUTPUT
66 };
67
68 #ifdef KERNEL_PRIVATE
69 struct kev_msg;
70 struct iff_filter;
71
72 struct dlil_if_flt_str {
73 caddr_t cookie;
74 int (*filter_if_input)(caddr_t cookie,
75 struct ifnet **ifp,
76 struct mbuf **mbuf_ptr,
77 char **frame_ptr);
78
79 int (*filter_if_event)(caddr_t cookie,
80 struct ifnet *ifp,
81 struct kev_msg *event_msg_ptr);
82
83 int (*filter_if_output)(caddr_t cookie,
84 struct ifnet **ifp,
85 struct mbuf **mbuf_ptr);
86
87
88 int (*filter_if_ioctl)(caddr_t cookie,
89 struct ifnet *ifp,
90 u_long ioctl_code_ptr,
91 caddr_t ioctl_arg_ptr);
92
93 int (*filter_if_free)(caddr_t cookie,
94 struct ifnet *ifp);
95
96 int (*filter_detach)(caddr_t cookie);
97 u_long reserved[2];
98 };
99
100 #define DLIL_PR_FILTER 1
101 #define DLIL_IF_FILTER 2
102
103
104
105 typedef int (*dl_input_func)(struct mbuf *m, char *frame_header,
106 struct ifnet *ifp, u_long protocol_family, int sync_ok);
107 typedef int (*dl_pre_output_func)(struct ifnet *ifp,
108 u_long protocol_family,
109 struct mbuf **m,
110 const struct sockaddr *dest,
111 caddr_t route_entry,
112 char *frame_type,
113 char *dst_addr);
114
115 typedef void (*dl_event_func)(struct ifnet *ifp, struct kev_msg *event);
116
117 typedef int (*dl_offer_func)(struct mbuf *m, char *frame_header);
118 typedef int (*dl_ioctl_func)(u_long protocol_family,
119 struct ifnet *ifp,
120 u_long ioctl_cmd,
121 caddr_t ioctl_arg);
122 typedef int (*dl_detached_func)(u_long protocol_family, struct ifnet *ifp);
123
124 /* Obsolete types */
125 #define DLIL_DESC_RAW 1
126 #define DLIL_DESC_802_2 2
127 #define DLIL_DESC_802_2_SNAP 3
128 /*
129 * DLIL_DESC_RAW - obsolete type, data in variants.bitmask or native_type
130 * if variants.bitmask.proto_id_length, native_type in host
131 * byte order.
132 * DLIL_DESC_802_2 - obsolete, data in variants.desc_802_2
133 * DLIL_DESC_802_2_SNAP - obsolete, data in variants.desc_802_2_SNAP
134 * protocol field in host byte order
135 */
136 #endif KERNEL_PRIVATE
137
138 /* Ethernet specific types */
139 #define DLIL_DESC_ETYPE2 4
140 #define DLIL_DESC_SAP 5
141 #define DLIL_DESC_SNAP 6
142 /*
143 * DLIL_DESC_ETYPE2 - native_type must point to 2 byte ethernet raw protocol,
144 * variants.native_type_length must be set to 2
145 * DLIL_DESC_SAP - native_type must point to 3 byte SAP protocol
146 * variants.native_type_length must be set to 3
147 * DLIL_DESC_SNAP - native_type must point to 5 byte SNAP protocol
148 * variants.native_type_length must be set to 5
149 *
150 * All protocols must be in Network byte order.
151 *
152 * Future interface families may define more protocol types they know about.
153 * The type implies the offset and context of the protocol data at native_type.
154 * The length of the protocol data specified at native_type must be set in
155 * variants.native_type_length.
156 */
157
158 #ifdef KERNEL_PRIVATE
159 struct dlil_demux_desc {
160 TAILQ_ENTRY(dlil_demux_desc) next;
161
162 int type;
163 u_char *native_type;
164
165 union {
166 /* Structs in this union are obsolete. They exist for binary compatability only */
167 /* Only the native_type_length is used */
168 struct {
169 u_long proto_id_length; /* IN LONGWORDS!!! */
170 u_char *proto_id; /* No longer supported by Ethernet family */
171 u_char *proto_id_mask;
172 } bitmask;
173
174 struct {
175 u_char dsap;
176 u_char ssap;
177 u_char control_code;
178 u_char pad;
179 } desc_802_2;
180
181 struct {
182 u_char dsap; /* Ignored, assumed to be 0xAA */
183 u_char ssap; /* Ignored, assumed to be 0xAA */
184 u_char control_code; /* Ignored, assumed to be 0x03 */
185 u_char org[3];
186 u_short protocol_type; /* In host byte order */
187 } desc_802_2_SNAP;
188
189 /* Length of data pointed to by native_type, must be set correctly */
190 u_int32_t native_type_length;
191 } variants;
192 };
193
194 TAILQ_HEAD(ddesc_head_str, dlil_demux_desc);
195
196 struct dlil_proto_reg_str {
197 struct ddesc_head_str demux_desc_head;
198 u_long interface_family;
199 u_long protocol_family;
200 short unit_number;
201 int default_proto; /* 0 or 1 */
202 dl_input_func input;
203 dl_pre_output_func pre_output;
204 dl_event_func event;
205 dl_offer_func offer;
206 dl_ioctl_func ioctl;
207 dl_detached_func detached;
208 u_long reserved[3];
209 };
210
211
212 int dlil_attach_filter(struct ifnet *ifp, const struct iff_filter *if_filter,
213 interface_filter_t *filter_ref);
214
215 struct ifnet_stat_increment_param;
216
217 int
218 dlil_input_with_stats(struct ifnet *ifp, struct mbuf *m_head, struct mbuf *m_tail,
219 const struct ifnet_stat_increment_param *stats);
220
221 int
222 dlil_input(struct ifnet *ifp, struct mbuf *m_head, struct mbuf *m_tail);
223
224 int
225 dlil_output_list(
226 struct ifnet *ifp,
227 u_long protocol_family,
228 struct mbuf *packetlist,
229 caddr_t route,
230 const struct sockaddr *dest,
231 int raw);
232
233 int
234 dlil_output(
235 struct ifnet *ifp,
236 u_long protocol_family,
237 struct mbuf *m,
238 caddr_t route,
239 const struct sockaddr *dest,
240 int raw);
241
242
243 int
244 dlil_ioctl(u_long proto_family,
245 struct ifnet *ifp,
246 u_long ioctl_code,
247 caddr_t ioctl_arg);
248
249 errno_t
250 dlil_resolve_multi(
251 struct ifnet *ifp,
252 const struct sockaddr *proto_addr,
253 struct sockaddr *ll_addr,
254 size_t ll_len);
255
256 /*
257 * Send arp internal bypasses the check for
258 * IPv4LL.
259 */
260 errno_t
261 dlil_send_arp_internal(
262 ifnet_t ifp,
263 u_int16_t arpop,
264 const struct sockaddr_dl* sender_hw,
265 const struct sockaddr* sender_proto,
266 const struct sockaddr_dl* target_hw,
267 const struct sockaddr* target_proto);
268
269 errno_t
270 dlil_send_arp(
271 ifnet_t ifp,
272 u_int16_t arpop,
273 const struct sockaddr_dl* sender_hw,
274 const struct sockaddr* sender_proto,
275 const struct sockaddr_dl* target_hw,
276 const struct sockaddr* target_proto);
277
278 int
279 dlil_ioctl_locked(u_long proto_family,
280 struct ifnet *ifp,
281 u_long ioctl_code,
282 caddr_t ioctl_arg);
283
284 int
285 dlil_attach_protocol(struct dlil_proto_reg_str *proto);
286
287 int
288 dlil_detach_protocol(struct ifnet *ifp, u_long protocol_family);
289
290 int
291 dlil_if_attach(struct ifnet *ifp);
292
293 #ifdef BSD_KERNEL_PRIVATE
294
295 int
296 dlil_if_attach_with_address(
297 struct ifnet *ifp,
298 const struct sockaddr_dl *ll_addr);
299
300 int
301 dlil_attach_protocol_kpi(ifnet_t ifp, protocol_family_t protocol,
302 const struct ifnet_attach_proto_param *proto_details);
303
304 errno_t dlil_set_bpf_tap(ifnet_t ifp, bpf_tap_mode mode,
305 bpf_packet_func callback);
306
307 #endif
308
309 void
310 dlil_detach_filter(interface_filter_t filter);
311
312 struct dlil_ifmod_reg_str {
313 int (*add_if)(struct ifnet *ifp);
314 int (*del_if)(struct ifnet *ifp);
315 int (*add_proto)(struct ifnet *ifp, u_long protocol_family,
316 struct ddesc_head_str *demux_desc_head);
317 #ifdef __KPI_INTERFACE__
318 ifnet_del_proto_func del_proto;
319 ifnet_ioctl_func ifmod_ioctl;
320 #else
321 void* del_proto;
322 void* ifmod_ioctl;
323 #endif
324 int (*shutdown)(void);
325 int (*init_if)(struct ifnet *ifp);
326 u_long reserved[3];
327 };
328
329
330 int dlil_reg_if_modules(u_long interface_family,
331 struct dlil_ifmod_reg_str *ifmod_reg);
332
333 /*
334
335 Function : dlil_reg_proto_module
336
337 A DLIL protocol module is a piece of code that know how to handle a certain type
338 of protocol (PF_INET, PF_INET6, ...) for a certain family of interface (APPLE_IF_FAM_ETHERNET,
339 APPLE_IF_FAM_PPP, ...).
340
341 dlil_reg_proto_module() allows the registration of such a protocol/interface handler before any
342 interface is attached.
343 Typically, the attach and detach function of the protocol handler will call
344 dlil_{attach/detach}_protocol with the parameter specific to the protocol.
345
346 The goal of this modules is to insulate the actual protocol (IP, IPv6) from the DLIL details.
347
348 Parameters :
349 'protocol_family' is PF_INET, PF_INET6, ...
350 'interface_family' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
351 'protomod_reg' is the protocol registration structure.
352 'attach_proto' funtion is mandatory.
353 'detach_proto' funtion is optional (DLIL will manage it).
354
355 Return code :
356
357 0 :
358
359 No error.
360
361 ENOMEM:
362
363 No memory can be allocated for internal data structure.
364
365 EEXIST:
366
367 The protocol family has already been registered for this interface family.
368
369 EINVAL:
370
371 The dlil_protomod_reg_str structure contains incorrect values.
372
373 */
374
375 int dlil_reg_proto_module(u_long protocol_family, u_long interface_family,
376 int (*attach)(struct ifnet *ifp, u_long protocol_family),
377 int (*detach)(struct ifnet *ifp, u_long protocol_family));
378
379 /*
380
381 Function : dlil_dereg_proto_module
382
383 dlil_dereg_proto_module() will unregister the protocol module previously
384 registered with dlil_dereg_proto_module().
385
386 There is no restriction when to call it.
387 Interfaces or protoco can be attached, it will not prevent the deregistration of the module.
388
389 Parameters :
390 'protocol_family' is PF_INET, PF_INET6, ...
391 'interface_family' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
392
393 Return code :
394
395 0 :
396
397 No error.
398
399 ENOENT:
400
401 No module was registered..
402
403 */
404
405 int dlil_dereg_proto_module(u_long protocol_family, u_long interface_family);
406
407 /*
408
409 Function : dlil_plumb_protocol
410
411 dlil_plumb_protocol() will plumb a protocol to an actual interface.
412 This will find a registered protocol module and call its attach function.
413 The module will typically call dlil_attach_protocol with the appropriate parameters.
414
415 Parameters :
416 'protocol_family' is PF_INET, PF_INET6, ...
417 'ifp' is the interface to plumb the protocol to.
418
419 Return code :
420
421 0 :
422
423 No error.
424
425 ENOENT:
426
427 No module was registered.
428
429 other:
430
431 Error returned by the attach_proto function
432
433 */
434 int dlil_plumb_protocol(u_long protocol_family, struct ifnet *ifp);
435
436 /*
437
438 Function : dlil_unplumb_protocol
439
440 dlil_unplumb_protocol() will unplumb a protocol from an interface.
441 This will find a registered protocol module and call its detach function.
442 The module will typically call dlil_detach_protocol with the appropriate parameters.
443 If no module is found, this function will call dlil_detach_protocol directly.
444
445 Parameters :
446 'protocol_family' is PF_INET, PF_INET6, ...
447 'ifp' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
448
449 Return code :
450
451 0 :
452
453 No error.
454
455 ENOENT:
456
457 No module was registered.
458
459 other:
460
461 Error returned by the attach_proto function
462
463 */
464 int dlil_unplumb_protocol(u_long protocol_family, struct ifnet *ifp);
465
466 int
467 dlil_inject_if_input(struct mbuf *m, char *frame_header, u_long from_id);
468
469 int
470 dlil_inject_pr_input(struct mbuf *m, char *frame_header, u_long from_id);
471
472 int
473 dlil_inject_pr_output(struct mbuf *m,
474 struct sockaddr *dest,
475 int raw,
476 char *frame_type,
477 char *dst_linkaddr,
478 u_long from_id);
479
480 int
481 dlil_inject_if_output(struct mbuf *m, u_long from_id);
482
483 #ifdef KERNEL_PRIVATE
484 void
485 dlil_post_msg(struct ifnet *ifp,u_long event_subclass, u_long event_code,
486 struct net_event_data *event_data, u_long event_data_len);
487 #endif
488
489 int
490 dlil_event(struct ifnet *ifp, struct kern_event_msg *event);
491
492 int dlil_dereg_if_modules(u_long interface_family);
493
494 int
495 dlil_if_detach(struct ifnet *ifp);
496
497 void
498 ifp_reference(struct ifnet *ifp);
499
500 void
501 ifp_release(struct ifnet *ifp);
502
503
504 /*
505
506 Function : dlil_if_acquire
507
508 DLIL manages the list of ifnet interfaces allocated using the dlil_if_acquire
509 function. This list if not the same as the list of attached interfaces,
510 visible with ifconfig.
511 This list contains attached as well as detached interfaces.
512 Detached interfaces are kept in the list to prevent the kernel from crashing
513 by using an old ifp.
514
515 if it succeeds, dlil_if_acquire returns an ifnet data structure.
516 This ifnet can either be a new allocated block of memory, or an ifnet
517 that already existed and that DLIL has found in its list of unused
518 interface and that matches the family/uniqueid tuple.
519
520 dlil_if_acquire can fail if the requested interface is already in use,
521 or if no memory is available to create a new interface.
522
523 The typical sequence of call for a driver will be :
524 dlil_if_acquire(... &ifp)
525 ... Fill in the ifnet ...
526 dlil_if_attach(ifp)
527 ... Driver work ...
528 dlil_if_detach(ifp)
529 dlil_if_release(ifp)
530
531 Important : ifnet allocated by DLIL are managed by DLIL. DLIL takes care
532 of them, and keeps them until a driver wants to reuse them, but DLIL may
533 also decide to free them when not in use by a driver.
534
535 Note : the structure returned will actually be large enough to contain
536 an arpcom structure (ifnet + ethernet) structure.
537 Drivers cannot extend the structure and must to store their private
538 information in if_sofc and if_private.
539
540 Parameters :
541 'family' uniquely identifies DLIL interface family.
542 'uniqueid' is a unique identifier for that interface, managed by the
543 driver (for example MAC address for ethernet).
544 'uniqueid_len' is the length of the unique id.
545 'ifp' contains on output the allocated ifnet.
546
547 Return code :
548
549 0 :
550
551 If an ifnet matching the uniqueid is found, the matching ifnet is returned
552 in ifp and the flags IFEF_REUSE and IF_INUSE are set in the if_eflags.
553 The fields in the ifnet are NOT zeroed and may contain old values that
554 the driver can reuse. [They are not necessarily the values that were
555 there when the driver released the ifnet, as protocol might have
556 continued to update them].
557
558 If no matching ifnet is found, a new structure is allocated and returned
559 in ifp with all fields initialized to 0.
560 The flag IF_INUSE is set in the if_eflags. IFEF_REUSE is NOT set.
561 dlil_if_acquire will copy the uniqueid and keep it for matching purpose.
562
563 If 'uniqueid' is NULL, then dlil_if_acquire will return the first
564 ifnet that contains a null uniqueid for that family, with the flags
565 IFEF_REUSE and IF_INUSE set.
566 If no ifnet is available, a new one will be created.
567
568 ENOMEM:
569
570 If no matching interface is found, and no memory can be allocated,
571 dlil_if_acquire will return ENOMEM.
572
573
574 EBUSY:
575
576 If the unique id matches the id of an interface currently in use,
577 dlil_if_acquire will return EBUSY.
578 An interface 'in use' is an allocated interface, not necessarily attached.
579
580 */
581
582 int dlil_if_acquire(u_long family, const void *uniqueid, size_t uniqueid_len,
583 struct ifnet **ifp);
584
585
586 /*
587
588 Function : dlil_if_release
589
590 dlil_if_release will transfer control of the ifnet to DLIL.
591 DLIL will keep the interface in its list, marking it unused.
592 The fields will be left in their current state, so the driver can reuse
593 the ifnet later, by calling dlil_if_acquire.
594 The if_eflags IF_INUSE will be cleared.
595 The fields if_output, if_ioctl, if_free and if_set_bpf_tap will be changed
596 to point to DLIL private functions.
597 After calling dlil_if_release, the driver can safely terminate and
598 unload if necessary.
599 Note: your driver should only call dlil_if_release once your if_free
600 function has been called.
601
602 Parameters :
603 ifp is the pointer to the ifnet to release.
604
605 */
606
607 void dlil_if_release(struct ifnet *ifp);
608
609 #endif /* KERNEL_PRIVATE */
610 #endif /* KERNEL */
611 #endif /* DLIL_H */