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