2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1999 Apple Computer, Inc.
28 * Data Link Inteface Layer
35 #include <sys/appleapiopts.h>
46 #ifdef __APPLE_API_UNSTABLE
47 #define DLIL_LAST_FILTER -1
48 #define DLIL_NULL_FILTER -2
50 #define DLIL_WAIT_FOR_FREE -2
52 #define DLIL_BLUEBOX 1
57 #include <net/if_var.h>
58 #include <sys/kern_event.h>
68 struct dl_tag_attr_str
{
73 u_long protocol_family
;
77 struct dlil_pr_flt_str
{
80 int (*filter_dl_input
)(caddr_t cookie
,
86 int (*filter_dl_output
)(caddr_t cookie
,
89 struct sockaddr
**dest
,
93 int (*filter_dl_event
)(caddr_t cookie
,
94 struct kern_event_msg
*event_msg
);
96 int (*filter_dl_ioctl
)(caddr_t cookie
,
101 int (*filter_detach
)(caddr_t cookie
);
105 struct dlil_if_flt_str
{
107 int (*filter_if_input
)(caddr_t cookie
,
108 struct ifnet
**ifnet_ptr
,
109 struct mbuf
**mbuf_ptr
,
112 int (*filter_if_event
)(caddr_t cookie
,
113 struct ifnet
**ifnet_ptr
,
114 struct kern_event_msg
**event_msg_ptr
);
116 int (*filter_if_output
)(caddr_t cookie
,
117 struct ifnet
**ifnet_ptr
,
118 struct mbuf
**mbuf_ptr
);
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
);
126 int (*filter_if_free
)(caddr_t cookie
,
127 struct ifnet
*ifnet_ptr
);
129 int (*filter_detach
)(caddr_t cookie
);
134 #define DLIL_PR_FILTER 1
135 #define DLIL_IF_FILTER 2
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
,
143 struct sockaddr
*dest
,
149 typedef int (*dl_event_func
)(struct kern_event_msg
*event
,
152 typedef int (*dl_offer_func
)(struct mbuf
*m
, char *frame_header
);
153 typedef int (*dl_ioctl_func
)(u_long dl_tag
,
160 #ifdef __APPLE_API_PRIVATE
161 struct dlil_filterq_entry
{
162 TAILQ_ENTRY(dlil_filterq_entry
) que
;
166 struct dlil_if_flt_str if_filter
;
167 struct dlil_pr_flt_str pr_filter
;
171 struct dlil_filterq_entry
;
172 #endif /* __APPLE_API_PRIVATE */
174 TAILQ_HEAD(dlil_filterq_head
, dlil_filterq_entry
);
178 TAILQ_ENTRY(if_proto
) next
;
180 struct dlil_filterq_head pr_flt_head
;
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
;
192 #ifdef __APPLE_API_PRIVATE
193 TAILQ_HEAD(dlil_proto_head
, if_proto
);
195 struct dlil_tag_list_entry
{
196 TAILQ_ENTRY(dlil_tag_list_entry
) next
;
200 #endif /* __APPLE_API_PRIVATE */
203 #ifdef __APPLE_API_OBSOLETE
205 #define DLIL_DESC_RAW 1
206 #define DLIL_DESC_802_2 2
207 #define DLIL_DESC_802_2_SNAP 3
209 * DLIL_DESC_RAW - obsolete type, data in variants.bitmask or native_type
210 * if variants.bitmask.proto_id_length, native_type in host
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
216 #endif /* __APPLE_API_OBSOLETE */
218 /* Ehernet specific types */
219 #define DLIL_DESC_ETYPE2 4
220 #define DLIL_DESC_SAP 5
221 #define DLIL_DESC_SNAP 6
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
230 * All protocols must be in Network byte order.
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.
238 struct dlil_demux_desc
{
239 TAILQ_ENTRY(dlil_demux_desc
) next
;
245 /* Structs in this union are obsolete. They exist for binary compatability only */
246 /* Only the native_type_length is used */
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
;
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 */
265 u_short protocol_type
; /* In host byte order */
268 /* Length of data pointed to by native_type, must be set correctly */
269 u_int32_t native_type_length
;
273 TAILQ_HEAD(ddesc_head_str
, dlil_demux_desc
);
276 struct dlil_proto_reg_str
{
277 struct ddesc_head_str demux_desc_head
;
278 u_long interface_family
;
279 u_long protocol_family
;
281 int default_proto
; /* 0 or 1 */
283 dl_pre_output_func pre_output
;
291 int dlil_attach_interface_filter(struct ifnet
*ifnet_ptr
,
292 struct dlil_if_flt_str
*interface_filter
,
294 int insertion_point
);
297 dlil_input(struct ifnet
*ifp
, struct mbuf
*m_head
, struct mbuf
*m_tail
);
300 dlil_output(u_long dl_tag
,
303 struct sockaddr
*dest
,
308 dlil_ioctl(u_long proto_family
,
314 dlil_attach_protocol(struct dlil_proto_reg_str
*proto
,
318 dlil_detach_protocol(u_long dl_tag
);
321 dlil_if_attach(struct ifnet
*ifp
);
324 dlil_attach_protocol_filter(u_long dl_tag
,
325 struct dlil_pr_flt_str
*proto_filter
,
327 int insertion_point
);
329 dlil_detach_filter(u_long filter_id
);
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
);
339 int (*init_if
)(struct ifnet
*ifp
);
344 int dlil_reg_if_modules(u_long interface_family
,
345 struct dlil_ifmod_reg_str
*ifmod_reg
);
347 struct dlil_protomod_reg_str
{
349 * attach the protocol to the interface and return the dl_tag
351 int (*attach_proto
)(struct ifnet
*ifp
, u_long
*dl_tag
);
354 * detach the protocol from the interface.
355 * this is optionnal. If it is NULL, DLIL will use 0 default detach function.
357 int (*detach_proto
)(struct ifnet
*ifp
, u_long dl_tag
);
360 * reserved for future use. MUST be NULL.
367 Function : dlil_reg_proto_module
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, ...).
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.
378 The goal of this modules is to insulate the actual protocol (IP, IPv6) from the DLIL details.
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).
395 No memory can be allocated for internal data structure.
399 The protocol family has already been registered for this interface family.
403 The dlil_protomod_reg_str structure contains incorrect values.
407 int dlil_reg_proto_module(u_long protocol_family
, u_long interface_family
,
408 struct dlil_protomod_reg_str
*protomod_reg
);
412 Function : dlil_dereg_proto_module
414 dlil_dereg_proto_module() will unregister the protocol module previously
415 registered with dlil_dereg_proto_module().
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.
421 'protocol_family' is PF_INET, PF_INET6, ...
422 'interface_family' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
432 No module was registered..
436 int dlil_dereg_proto_module(u_long protocol_family
, u_long interface_family
);
440 Function : dlil_plumb_protocol
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.
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.
463 No module was registered.
467 Error returned by the attach_proto function
470 int dlil_plumb_protocol(u_long protocol_family
, struct ifnet
*ifp
, u_long
*dl_tag
);
474 Function : dlil_unplumb_protocol
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.
482 'protocol_family' is PF_INET, PF_INET6, ...
483 'ifp' is APPLE_IF_FAM_ETHERNET, APPLE_IF_FAM_PPP, ...
493 No module was registered.
497 Error returned by the attach_proto function
500 int dlil_unplumb_protocol(u_long protocol_family
, struct ifnet
*ifp
);
503 dlil_inject_if_input(struct mbuf
*m
, char *frame_header
, u_long from_id
);
506 dlil_inject_pr_input(struct mbuf
*m
, char *frame_header
, u_long from_id
);
509 dlil_inject_pr_output(struct mbuf
*m
,
510 struct sockaddr
*dest
,
517 dlil_inject_if_output(struct mbuf
*m
, u_long from_id
);
520 dlil_find_dltag(u_long if_family
, short unit
, u_long proto_family
, u_long
*dl_tag
);
524 dlil_event(struct ifnet
*ifp
, struct kern_event_msg
*event
);
526 int dlil_dereg_if_modules(u_long interface_family
);
529 dlil_if_detach(struct ifnet
*ifp
);
534 Function : dlil_if_acquire
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
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.
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.
551 The typical sequence of call for a driver will be :
552 dlil_if_acquire(... &ifp)
553 ... Fill in the ifnet ...
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.
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.
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.
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].
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.
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.
598 If no matching interface is found, and no memory can be allocated,
599 dlil_if_acquire will return ENOMEM.
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.
610 int dlil_if_acquire(u_long family
, void *uniqueid
, size_t uniqueid_len
,
616 Function : dlil_if_release
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
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.
631 ifp is the pointer to the ifnet to release.
635 void dlil_if_release(struct ifnet
*ifp
);
637 #endif /* __APPLE_API_UNSTABLE */