2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1999 Apple Computer, Inc.
25 * Data Link Inteface Layer
32 #include <sys/appleapiopts.h>
43 #ifdef __APPLE_API_UNSTABLE
44 #define DLIL_LAST_FILTER -1
45 #define DLIL_NULL_FILTER -2
47 #define DLIL_WAIT_FOR_FREE -2
49 #define DLIL_BLUEBOX 1
54 #include <net/if_var.h>
55 #include <sys/kern_event.h>
65 struct dl_tag_attr_str
{
70 u_long protocol_family
;
74 struct dlil_pr_flt_str
{
77 int (*filter_dl_input
)(caddr_t cookie
,
83 int (*filter_dl_output
)(caddr_t cookie
,
86 struct sockaddr
**dest
,
90 int (*filter_dl_event
)(caddr_t cookie
,
91 struct kern_event_msg
*event_msg
);
93 int (*filter_dl_ioctl
)(caddr_t cookie
,
98 int (*filter_detach
)(caddr_t cookie
);
102 struct dlil_if_flt_str
{
104 int (*filter_if_input
)(caddr_t cookie
,
105 struct ifnet
**ifnet_ptr
,
106 struct mbuf
**mbuf_ptr
,
109 int (*filter_if_event
)(caddr_t cookie
,
110 struct ifnet
**ifnet_ptr
,
111 struct kern_event_msg
**event_msg_ptr
);
113 int (*filter_if_output
)(caddr_t cookie
,
114 struct ifnet
**ifnet_ptr
,
115 struct mbuf
**mbuf_ptr
);
118 int (*filter_if_ioctl
)(caddr_t cookie
,
119 struct ifnet
*ifnet_ptr
,
120 u_long ioctl_code_ptr
,
121 caddr_t ioctl_arg_ptr
);
123 int (*filter_if_free
)(caddr_t cookie
,
124 struct ifnet
*ifnet_ptr
);
126 int (*filter_detach
)(caddr_t cookie
);
131 #define DLIL_PR_FILTER 1
132 #define DLIL_IF_FILTER 2
136 typedef int (*dl_input_func
)(struct mbuf
*m
, char *frame_header
,
137 struct ifnet
*ifp
, u_long dl_tag
, int sync_ok
);
138 typedef int (*dl_pre_output_func
)(struct ifnet
*ifp
,
140 struct sockaddr
*dest
,
146 typedef int (*dl_event_func
)(struct kern_event_msg
*event
,
149 typedef int (*dl_offer_func
)(struct mbuf
*m
, char *frame_header
);
150 typedef int (*dl_ioctl_func
)(u_long dl_tag
,
157 #ifdef __APPLE_API_PRIVATE
158 struct dlil_filterq_entry
{
159 TAILQ_ENTRY(dlil_filterq_entry
) que
;
163 struct dlil_if_flt_str if_filter
;
164 struct dlil_pr_flt_str pr_filter
;
168 struct dlil_filterq_entry
;
169 #endif /* __APPLE_API_PRIVATE */
171 TAILQ_HEAD(dlil_filterq_head
, dlil_filterq_entry
);
175 TAILQ_ENTRY(if_proto
) next
;
177 struct dlil_filterq_head pr_flt_head
;
179 dl_input_func dl_input
;
180 dl_pre_output_func dl_pre_output
;
181 dl_event_func dl_event
;
182 dl_offer_func dl_offer
;
183 dl_ioctl_func dl_ioctl
;
184 u_long protocol_family
;
189 #ifdef __APPLE_API_PRIVATE
190 TAILQ_HEAD(dlil_proto_head
, if_proto
);
192 struct dlil_tag_list_entry
{
193 TAILQ_ENTRY(dlil_tag_list_entry
) next
;
197 #endif /* __APPLE_API_PRIVATE */
200 #ifdef __APPLE_API_OBSOLETE
202 #define DLIL_DESC_RAW 1
203 #define DLIL_DESC_802_2 2
204 #define DLIL_DESC_802_2_SNAP 3
206 * DLIL_DESC_RAW - obsolete type, data in variants.bitmask or native_type
207 * if variants.bitmask.proto_id_length, native_type in host
209 * DLIL_DESC_802_2 - obsolete, data in variants.desc_802_2
210 * DLIL_DESC_802_2_SNAP - obsolete, data in variants.desc_802_2_SNAP
211 * protocol field in host byte order
213 #endif /* __APPLE_API_OBSOLETE */
215 /* Ehernet specific types */
216 #define DLIL_DESC_ETYPE2 4
217 #define DLIL_DESC_SAP 5
218 #define DLIL_DESC_SNAP 6
220 * DLIL_DESC_ETYPE2 - native_type must point to 2 byte ethernet raw protocol,
221 * variants.native_type_length must be set to 2
222 * DLIL_DESC_SAP - native_type must point to 3 byte SAP protocol
223 * variants.native_type_length must be set to 3
224 * DLIL_DESC_SNAP - native_type must point to 5 byte SNAP protocol
225 * variants.native_type_length must be set to 5
227 * All protocols must be in Network byte order.
229 * Future interface families may define more protocol types they know about.
230 * The type implies the offset and context of the protocol data at native_type.
231 * The length of the protocol data specified at native_type must be set in
232 * variants.native_type_length.
235 struct dlil_demux_desc
{
236 TAILQ_ENTRY(dlil_demux_desc
) next
;
242 /* Structs in this union are obsolete. They exist for binary compatability only */
243 /* Only the native_type_length is used */
245 u_long proto_id_length
; /* IN LONGWORDS!!! */
246 u_char
*proto_id
; /* No longer supported by Ethernet family */
247 u_char
*proto_id_mask
;
258 u_char dsap
; /* Ignored, assumed to be 0xAA */
259 u_char ssap
; /* Ignored, assumed to be 0xAA */
260 u_char control_code
; /* Ignored, assumed to be 0x03 */
262 u_short protocol_type
; /* In host byte order */
265 /* Length of data pointed to by native_type, must be set correctly */
266 u_int32_t native_type_length
;
270 TAILQ_HEAD(ddesc_head_str
, dlil_demux_desc
);
273 struct dlil_proto_reg_str
{
274 struct ddesc_head_str demux_desc_head
;
275 u_long interface_family
;
276 u_long protocol_family
;
278 int default_proto
; /* 0 or 1 */
280 dl_pre_output_func pre_output
;
288 int dlil_attach_interface_filter(struct ifnet
*ifnet_ptr
,
289 struct dlil_if_flt_str
*interface_filter
,
291 int insertion_point
);
294 dlil_input(struct ifnet
*ifp
, struct mbuf
*m_head
, struct mbuf
*m_tail
);
297 dlil_output(u_long dl_tag
,
300 struct sockaddr
*dest
,
305 dlil_ioctl(u_long proto_family
,
311 dlil_attach_protocol(struct dlil_proto_reg_str
*proto
,
315 dlil_detach_protocol(u_long dl_tag
);
318 dlil_if_attach(struct ifnet
*ifp
);
321 dlil_attach_protocol_filter(u_long dl_tag
,
322 struct dlil_pr_flt_str
*proto_filter
,
324 int insertion_point
);
326 dlil_detach_filter(u_long filter_id
);
328 struct dlil_ifmod_reg_str
{
329 int (*add_if
)(struct ifnet
*ifp
);
330 int (*del_if
)(struct ifnet
*ifp
);
331 int (*add_proto
)(struct ddesc_head_str
*demux_desc_head
,
332 struct if_proto
*proto
, u_long dl_tag
);
333 int (*del_proto
)(struct if_proto
*proto
, u_long dl_tag
);
334 int (*ifmod_ioctl
)(struct ifnet
*ifp
, u_long ioctl_cmd
, caddr_t data
);
336 int (*init_if
)(struct ifnet
*ifp
);
341 int dlil_reg_if_modules(u_long interface_family
,
342 struct dlil_ifmod_reg_str
*ifmod_reg
);
344 struct dlil_protomod_reg_str
{
346 * attach the protocol to the interface and return the dl_tag
348 int (*attach_proto
)(struct ifnet
*ifp
, u_long
*dl_tag
);
351 * detach the protocol from the interface.
352 * this is optionnal. If it is NULL, DLIL will use 0 default detach function.
354 int (*detach_proto
)(struct ifnet
*ifp
, u_long dl_tag
);
357 * reserved for future use. MUST be NULL.
364 Function : dlil_reg_proto_module
366 A DLIL protocol module is a piece of code that know how to handle a certain type
367 of protocol (PF_INET, PF_INET6, ...) for a certain family of interface (APPLE_IF_FAM_ETHERNET,
368 APPLE_IF_FAM_PPP, ...).
370 dlil_reg_proto_module() allows the registration of such a protocol/interface handler before any
371 interface is attached.
372 Typically, the attach and detach function of the protocol handler will call
373 dlil_{attach/detach}_protocol with the parameter specific to the protocol.
375 The goal of this modules is to insulate the actual protocol (IP, IPv6) from the DLIL details.
378 'protocol_family' is PF_INET, PF_INET6, ...
379 'interface_family' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
380 'protomod_reg' is the protocol registration structure.
381 'attach_proto' funtion is mandatory.
382 'detach_proto' funtion is optional (DLIL will manage it).
392 No memory can be allocated for internal data structure.
396 The protocol family has already been registered for this interface family.
400 The dlil_protomod_reg_str structure contains incorrect values.
404 int dlil_reg_proto_module(u_long protocol_family
, u_long interface_family
,
405 struct dlil_protomod_reg_str
*protomod_reg
);
409 Function : dlil_dereg_proto_module
411 dlil_dereg_proto_module() will unregister the protocol module previously
412 registered with dlil_dereg_proto_module().
414 There is no restriction when to call it.
415 Interfaces or protoco can be attached, it will not prevent the deregistration of the module.
418 'protocol_family' is PF_INET, PF_INET6, ...
419 'interface_family' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
429 No module was registered..
433 int dlil_dereg_proto_module(u_long protocol_family
, u_long interface_family
);
437 Function : dlil_plumb_protocol
439 dlil_plumb_protocol() will plumb a protocol to an actual interface.
440 This will find a registered protocol module and call its attach function.
441 The module will typically call dlil_attach_protocol with the appropriate parameters,
442 and will return the dl_tag of the attachement.
443 It is up to the caller to handle the dl_tag.
444 Some protocol (IPv4) will stick it in their internal structure for future use.
445 Some other protocol (IPv6) can ignore the dl_tag.
448 'protocol_family' is PF_INET, PF_INET6, ...
449 'ifp' is the interface to plumb the protocol to.
450 'dl_tag' is the tag returned from the succesful attachement.
460 No module was registered.
464 Error returned by the attach_proto function
467 int dlil_plumb_protocol(u_long protocol_family
, struct ifnet
*ifp
, u_long
*dl_tag
);
471 Function : dlil_unplumb_protocol
473 dlil_unplumb_protocol() will unplumb a protocol from an interface.
474 This will find a registered protocol module and call its detach function.
475 The module will typically call dlil_detach_protocol with the appropriate parameters.
476 If no module is found, this function will call dlil_detach_protocol directly.
479 'protocol_family' is PF_INET, PF_INET6, ...
480 'ifp' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
490 No module was registered.
494 Error returned by the attach_proto function
497 int dlil_unplumb_protocol(u_long protocol_family
, struct ifnet
*ifp
);
500 dlil_inject_if_input(struct mbuf
*m
, char *frame_header
, u_long from_id
);
503 dlil_inject_pr_input(struct mbuf
*m
, char *frame_header
, u_long from_id
);
506 dlil_inject_pr_output(struct mbuf
*m
,
507 struct sockaddr
*dest
,
514 dlil_inject_if_output(struct mbuf
*m
, u_long from_id
);
517 dlil_find_dltag(u_long if_family
, short unit
, u_long proto_family
, u_long
*dl_tag
);
521 dlil_event(struct ifnet
*ifp
, struct kern_event_msg
*event
);
523 int dlil_dereg_if_modules(u_long interface_family
);
526 dlil_if_detach(struct ifnet
*ifp
);
531 Function : dlil_if_acquire
533 DLIL manages the list of ifnet interfaces allocated using the dlil_if_acquire
534 function. This list if not the same as the list of attached interfaces,
535 visible with ifconfig.
536 This list contains attached as well as detached interfaces.
537 Detached interfaces are kept in the list to prevent the kernel from crashing
540 if it succeeds, dlil_if_acquire returns an ifnet data structure.
541 This ifnet can either be a new allocated block of memory, or an ifnet
542 that already existed and that DLIL has found in its list of unused
543 interface and that matches the family/uniqueid tuple.
545 dlil_if_acquire can fail if the requested interface is already in use,
546 or if no memory is available to create a new interface.
548 The typical sequence of call for a driver will be :
549 dlil_if_acquire(... &ifp)
550 ... Fill in the ifnet ...
556 Important : ifnet allocated by DLIL are managed by DLIL. DLIL takes care
557 of them, and keeps them until a driver wants to reuse them, but DLIL may
558 also decide to free them when not in use by a driver.
560 Note : the structure returned will actually be large enough to contain
561 an arpcom structure (ifnet + ethernet) structure.
562 Drivers cannot extend the structure and must to store their private
563 information in if_sofc and if_private.
566 'family' uniquely identifies DLIL interface family.
567 'uniqueid' is a unique identifier for that interface, managed by the
568 driver (for example MAC address for ethernet).
569 'uniqueid_len' is the length of the unique id.
570 'ifp' contains on output the allocated ifnet.
576 If an ifnet matching the uniqueid is found, the matching ifnet is returned
577 in ifp and the flags IFEF_REUSE and IF_INUSE are set in the if_eflags.
578 The fields in the ifnet are NOT zeroed and may contain old values that
579 the driver can reuse. [They are not necessarily the values that were
580 there when the driver released the ifnet, as protocol might have
581 continued to update them].
583 If no matching ifnet is found, a new structure is allocated and returned
584 in ifp with all fields initialized to 0.
585 The flag IF_INUSE is set in the if_eflags. IFEF_REUSE is NOT set.
586 dlil_if_acquire will copy the uniqueid and keep it for matching purpose.
588 If 'uniqueid' is NULL, then dlil_if_acquire will return the first
589 ifnet that contains a null uniqueid for that family, with the flags
590 IFEF_REUSE and IF_INUSE set.
591 If no ifnet is available, a new one will be created.
595 If no matching interface is found, and no memory can be allocated,
596 dlil_if_acquire will return ENOMEM.
601 If the unique id matches the id of an interface currently in use,
602 dlil_if_acquire will return EBUSY.
603 An interface 'in use' is an allocated interface, not necessarily attached.
607 int dlil_if_acquire(u_long family
, void *uniqueid
, size_t uniqueid_len
,
613 Function : dlil_if_release
615 dlil_if_release will transfer control of the ifnet to DLIL.
616 DLIL will keep the interface in its list, marking it unused.
617 The fields will be left in their current state, so the driver can reuse
618 the ifnet later, by calling dlil_if_acquire.
619 The if_eflags IF_INUSE will be cleared.
620 The fields if_output, if_ioctl, if_free and if_set_bpf_tap will be changed
621 to point to DLIL private functions.
622 After calling dlil_if_acquire, the driver can safely terminate and
624 Note : if the call to dlil_if_detach returns DLIL_WAIT_FOR_FREE, the
625 driver can safely ignore it and call dlil_if_release.
628 ifp is the pointer to the ifnet to release.
632 void dlil_if_release(struct ifnet
*ifp
);
634 #endif /* __APPLE_API_UNSTABLE */