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