Crossbow - transition to Mercurial
6724907 flow_ip_accept() cannot parse extended IPv6 headers
6734700 the error message is misleading:flowadm: add flow failed: non-existent processor ID
6741011 Re-visit the fields in the main crossbow data structures
MAC datapath refactoring
6668161 expose receive rings through aggregations
6741067 aggr locking needs to work with mac perimeter design
6734073 deadlock in aggr if aggregation failed to be created for some reason
6742825 system panicked due to recursive locking in aggr
6746501 deadbeef panic in mac_client_close()
6742712 potential message double free in the aggr driver
6754299 a potential race between aggr_m_tx() and aggr_port_delete()
6754799 VNIC can not receive broadcast and multicast traffic
6754805 Default group is not fully started for broadcast/multicast traffic
6755510 mac_address_t for primary MAC address can be removed on failure
6755873 dynamic ring addition and deletion routines need to be consolidated
1000000 mac_srs_create cleanup

   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #ifndef _SYS_MAC_IMPL_H
  27 #define _SYS_MAC_IMPL_H
  28 
  29 #include <sys/modhash.h>
  30 #include <sys/mac_client.h>
  31 #include <sys/mac_provider.h>
  32 #include <net/if.h>
  33 #include <sys/mac_flow_impl.h>
  34 #include <netinet/ip6.h>
  35 
  36 #ifdef  __cplusplus
  37 extern "C" {
  38 #endif
  39 








  40 typedef struct mac_margin_req_s mac_margin_req_t;
  41 
  42 struct mac_margin_req_s {
  43         mac_margin_req_t        *mmr_nextp;
  44         uint_t                  mmr_ref;
  45         uint32_t                mmr_margin;
  46 };
  47 
  48 /* Generic linked chain type */
  49 typedef struct mac_chain_s {
  50         struct mac_chain_s      *next;
  51         void                    *item;
  52 } mac_chain_t;
  53 
  54 /*
  55  * Generic mac callback list manipulation structures and macros. The mac_cb_t
  56  * represents a general callback list element embedded in a particular
  57  * data structure such as a mac_notify_cb_t or a mac_promisc_impl_t.
  58  * The mac_cb_info_t represents general information about list walkers.
  59  * Please see the comments above mac_callback_add for more information.
  60  */
  61 /* mcb_flags */
  62 #define MCB_CONDEMNED           0x1             /* Logically deleted */
  63 #define MCB_NOTIFY_CB_T         0x2
  64 #define MCB_TX_NOTIFY_CB_T      0x4
  65 
  66 typedef struct mac_cb_s {
  67         struct mac_cb_s         *mcb_nextp;     /* Linked list of callbacks */
  68         void                    *mcb_objp;      /* Ptr to enclosing object  */
  69         size_t                  mcb_objsize;    /* Sizeof the enclosing obj */
  70         uint_t                  mcb_flags;
  71 } mac_cb_t;
  72 
  73 typedef struct mac_cb_info_s {
  74         kmutex_t        *mcbi_lockp;
  75         kcondvar_t      mcbi_cv;
  76         uint_t          mcbi_del_cnt;           /* Deleted callback cnt */
  77         uint_t          mcbi_walker_cnt;        /* List walker count */
  78 } mac_cb_info_t;

  79 
  80 typedef struct mac_notify_cb_s {
  81         mac_cb_t        mncb_link;              /* Linked list of callbacks */
  82         mac_notify_t    mncb_fn;                /* callback function */
  83         void            *mncb_arg;              /* callback argument */
  84         struct mac_impl_s *mncb_mip;
  85 } mac_notify_cb_t;
  86 
  87 /*
  88  * mac_callback_add(listinfo, listhead, listelement)
  89  * mac_callback_remove(listinfo, listhead, listelement)
  90  */
  91 typedef boolean_t (*mcb_func_t)(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
  92 
  93 #define MAC_CALLBACK_WALKER_INC(mcbi) {                         \
  94         mutex_enter((mcbi)->mcbi_lockp);                     \
  95         (mcbi)->mcbi_walker_cnt++;                           \
  96         mutex_exit((mcbi)->mcbi_lockp);                              \
  97 }
  98 
  99 #define MAC_CALLBACK_WALKER_INC_HELD(mcbi)      (mcbi)->mcbi_walker_cnt++;
 100 
 101 #define MAC_CALLBACK_WALKER_DCR(mcbi, headp) {                  \
 102         mac_cb_t        *rmlist;                                \
 103                                                                 \
 104         mutex_enter((mcbi)->mcbi_lockp);                     \
 105         if (--(mcbi)->mcbi_walker_cnt == 0 && (mcbi)->mcbi_del_cnt != 0) { \
 106                 rmlist = mac_callback_walker_cleanup((mcbi), headp);    \
 107                 mac_callback_free(rmlist);                      \
 108                 cv_broadcast(&(mcbi)->mcbi_cv);                  \
 109         }                                                       \
 110         mutex_exit((mcbi)->mcbi_lockp);                              \
 111 }
 112 
 113 #define MAC_PROMISC_WALKER_INC(mip)                             \
 114         MAC_CALLBACK_WALKER_INC(&(mip)->mi_promisc_cb_info)
 115 
 116 #define MAC_PROMISC_WALKER_DCR(mip) {                           \
 117         mac_cb_info_t   *mcbi;                                  \
 118                                                                 \
 119         mcbi = &(mip)->mi_promisc_cb_info;                       \
 120         mutex_enter(mcbi->mcbi_lockp);                               \
 121         if (--mcbi->mcbi_walker_cnt == 0 && mcbi->mcbi_del_cnt != 0) { \
 122                 i_mac_promisc_walker_cleanup(mip);              \
 123                 cv_broadcast(&mcbi->mcbi_cv);                    \
 124         }                                                       \
 125         mutex_exit(mcbi->mcbi_lockp);                                \
 126 }
 127 
 128 typedef struct mactype_s {
 129         const char      *mt_ident;
 130         uint32_t        mt_ref;
 131         uint_t          mt_type;
 132         uint_t          mt_nativetype;
 133         size_t          mt_addr_length;
 134         uint8_t         *mt_brdcst_addr;
 135         mactype_ops_t   mt_ops;
 136         mac_stat_info_t *mt_stats;      /* array of mac_stat_info_t elements */
 137         size_t          mt_statcount;   /* number of elements in mt_stats */
 138         mac_ndd_mapping_t *mt_mapping;
 139         size_t          mt_mappingcount;
 140 } mactype_t;
 141 
 142 /*
 143  * Multiple rings implementation.
 144  */
 145 typedef enum {
 146         MAC_GROUP_STATE_UNINIT  = 0,    /* initial state of data structure */
 147         MAC_GROUP_STATE_REGISTERED,     /* hooked with h/w group */
 148         MAC_GROUP_STATE_RESERVED,       /* group is reserved and opened */
 149         MAC_GROUP_STATE_SHARED          /* default group shared among */
 150                                         /* multiple mac clients */
 151 } mac_group_state_t;
 152 
 153 typedef struct mac_ring_s mac_ring_t;
 154 typedef struct mac_group_s mac_group_t;
 155 
 156 /*
 157  * Ring data structure for ring control and management.
 158  */
 159 typedef enum {
 160         MR_FREE,                /* Available for assignment to flows */
 161         MR_NEWLY_ADDED,         /* Just assigned to another group */
 162         MR_INUSE,               /* Assigned to an SRS */
 163 } mac_ring_state_t;
 164 
 165 /* mr_flag values */
 166 #define MR_INCIPIENT    0x1
 167 #define MR_CONDEMNED    0x2
 168 #define MR_QUIESCE      0x4
 169 
 170 struct mac_ring_s {
 171         int                     mr_index;       /* index in the original list */
 172         mac_ring_type_t         mr_type;        /* ring type */
 173         mac_ring_t              *mr_next;       /* next ring in the chain */
 174         mac_group_handle_t      mr_gh;          /* reference to group */
 175 
 176         mac_classify_type_t     mr_classify_type;       /* HW vs SW */
 177         struct mac_soft_ring_set_s *mr_srs;             /* associated SRS */
 178         uint_t                  mr_refcnt;              /* Ring references */
 179         /* ring generation no. to guard against drivers using stale rings */
 180         uint64_t                mr_gen_num;
 181 
 182         kmutex_t                mr_lock;
 183         kcondvar_t              mr_cv;                  /* mr_lock */
 184         mac_ring_state_t        mr_state;               /* mr_lock */
 185         uint_t                  mr_flag;                /* mr_lock */
 186 
 187         mac_ring_info_t         mr_info;        /* driver supplied info */
 188 };
 189 #define mr_driver               mr_info.mri_driver
 190 #define mr_start                mr_info.mri_start
 191 #define mr_stop                 mr_info.mri_stop
 192 
 193 #define MAC_RING_MARK(mr, flag)         \
 194         (mr)->mr_flag |= flag;
 195 
 196 #define MAC_RING_UNMARK(mr, flag)       \
 197         (mr)->mr_flag &= ~flag;
 198 
 199 /*
 200  * Reference hold and release on mac_ring_t 'mr'
 201  */
 202 #define MR_REFHOLD_LOCKED(mr)           {               \
 203         ASSERT(MUTEX_HELD(&mr->mr_lock));                \
 204         (mr)->mr_refcnt++;                           \
 205 }
 206 
 207 #define MR_REFRELE(mr)          {                       \
 208         mutex_enter(&(mr)->mr_lock);                     \
 209         ASSERT((mr)->mr_refcnt != 0);                        \
 210         (mr)->mr_refcnt--;                           \
 211         if ((mr)->mr_refcnt == 0 &&                  \
 212             ((mr)->mr_flag & (MR_CONDEMNED | MR_QUIESCE))) \
 213                 cv_signal(&(mr)->mr_cv);         \
 214         mutex_exit(&(mr)->mr_lock);                      \
 215 }
 216 
 217 /*
 218  * Per mac client flow information associated with a RX group.
 219  * The entire structure is SL protected.
 220  */
 221 typedef struct mac_grp_client {
 222         struct mac_grp_client           *mgc_next;
 223         struct mac_client_impl_s        *mgc_client;
 224 } mac_grp_client_t;
 225 
 226 #define MAC_RX_GROUP_NO_CLIENT(g)       ((g)->mrg_clients == NULL)
 227 
 228 #define MAC_RX_GROUP_ONLY_CLIENT(g)                     \
 229         ((((g)->mrg_clients != NULL) &&                      \
 230         ((g)->mrg_clients->mgc_next == NULL)) ?           \
 231         (g)->mrg_clients->mgc_client : NULL)
 232 
 233 /*
 234  * Common ring group data structure for ring control and management.
 235  * The entire structure is SL protected
 236  */
 237 struct mac_group_s {
 238         int                     mrg_index;      /* index in the list */
 239         mac_ring_type_t         mrg_type;       /* ring type */
 240         mac_group_state_t       mrg_state;      /* state of the group */
 241         mac_group_t             *mrg_next;      /* next ring in the chain */
 242         mac_handle_t            mrg_mh;         /* reference to MAC */
 243         mac_ring_t              *mrg_rings;     /* grouped rings */
 244         uint_t                  mrg_cur_count;  /* actual size of group */











 245 
 246         mac_grp_client_t        *mrg_clients;   /* clients list */




 247 
 248         struct mac_client_impl_s *mrg_tx_client; /* TX client pointer */
 249         mac_group_info_t        mrg_info;       /* driver supplied info */
 250 };
 251 
 252 #define mrg_driver              mrg_info.mgi_driver
 253 #define mrg_start               mrg_info.mgi_start
 254 #define mrg_stop                mrg_info.mgi_stop







 255 
 256 #define GROUP_INTR_HANDLE(g)            (g)->mrg_info.mgi_intr.mi_handle
 257 #define GROUP_INTR_ENABLE_FUNC(g)       (g)->mrg_info.mgi_intr.mi_enable
 258 #define GROUP_INTR_DISABLE_FUNC(g)      (g)->mrg_info.mgi_intr.mi_disable



 259 
 260 #define MAC_DEFAULT_GROUP(mh)           (((mac_impl_t *)mh)->mi_rx_groups)



 261 
 262 /* mci_tx_flag */
 263 #define MCI_TX_QUIESCE  0x1

 264 
 265 typedef struct mac_factory_addr_s {
 266         boolean_t               mfa_in_use;
 267         uint8_t                 mfa_addr[MAXMACADDRLEN];
 268         struct mac_client_impl_s        *mfa_client;
 269 } mac_factory_addr_t;
 270 
 271 typedef struct mac_mcast_addrs_s {
 272         struct mac_mcast_addrs_s        *mma_next;
 273         uint8_t                         mma_addr[MAXMACADDRLEN];
 274         int                             mma_ref;
 275 } mac_mcast_addrs_t;
 276 
 277 typedef enum {
 278         MAC_ADDRESS_TYPE_UNICAST_CLASSIFIED = 1,        /* hardware steering */
 279         MAC_ADDRESS_TYPE_UNICAST_PROMISC                /* promiscuous mode */
 280 } mac_address_type_t;
 281 
 282 typedef struct mac_impl_s mac_impl_t;
 283 
 284 typedef struct mac_address_s {
 285         mac_address_type_t      ma_type;                /* address type */
 286         int                     ma_nusers;              /* number of users */
 287                                                         /* of that address */
 288         struct mac_address_s    *ma_next;               /* next address */
 289         uint8_t                 ma_addr[MAXMACADDRLEN]; /* address value */
 290         size_t                  ma_len;                 /* address length */
 291         mac_group_t             *ma_group;              /* asscociated group */
 292         mac_impl_t              *ma_mip;                /* MAC handle */
 293 } mac_address_t;
 294 
 295 extern krwlock_t i_mac_impl_lock;
 296 extern mod_hash_t *i_mac_impl_hash;
 297 extern kmem_cache_t *i_mac_impl_cachep;
 298 extern uint_t i_mac_impl_count;
 299 
 300 /*
 301  * Each registered MAC is associated with a mac_impl_t structure. The
 302  * structure represents the undelying hardware, in terms of definition,
 303  * resources (transmit, receive rings etc.), callback functions etc. It
 304  * also holds the table of MAC clients that are configured on the device.
 305  * The table is used for classifying incoming packets in software.
 306  *
 307  * The protection scheme uses 2 elements, a coarse serialization mechanism
 308  * called perimeter and a finer traditional lock based scheme. More details
 309  * can be found in the big block comment in mac.c.
 310  *
 311  * The protection scheme for each member of the mac_impl_t is described below.
 312  *
 313  * Write Once Only (WO): Typically these don't change for the lifetime of the
 314  * data structure. For example something in mac_impl_t that stays the same
 315  * from mac_register to mac_unregister, or something in a mac_client_impl_t
 316  * that stays the same from mac_client_open to mac_client_close.
 317  *
 318  * Serializer (SL): Protected by the Serializer. All SLOP operations on a
 319  * mac endpoint go through the serializer. MTOPs don't care about reading
 320  * these fields atomically.
 321  *
 322  * Lock: Traditional mutex/rw lock. Modify operations still go through the
 323  * mac serializer, the lock helps synchronize readers with writers.
 324  */
 325 struct mac_impl_s {
 326         krwlock_t               mi_rw_lock;
 327         char                    mi_name[LIFNAMSIZ];     /* WO */
 328         uint32_t                mi_state_flags;
 329         void                    *mi_driver;             /* Driver private, WO */
 330         mac_info_t              mi_info;                /* WO */
 331         mactype_t               *mi_type;               /* WO */
 332         void                    *mi_pdata;              /* WO */
 333         size_t                  mi_pdata_size;          /* WO */
 334         mac_callbacks_t         *mi_callbacks;          /* WO */
 335         dev_info_t              *mi_dip;                /* WO */
 336         uint32_t                mi_ref;                 /* i_mac_impl_lock */
 337         uint_t                  mi_active;              /* SL */
 338         link_state_t            mi_linkstate;           /* none */
 339         link_state_t            mi_lastlinkstate;       /* none */
 340         uint_t                  mi_promisc;             /* SL */
 341         uint_t                  mi_devpromisc;          /* SL */
 342         kmutex_t                mi_lock;
 343         uint8_t                 mi_addr[MAXMACADDRLEN]; /* mi_rw_lock */
 344         uint8_t                 mi_dstaddr[MAXMACADDRLEN]; /* mi_rw_lock */
 345 
 346         /*
 347          * The mac perimeter. All client initiated create/modify operations
 348          * on a mac end point go through this.
 349          */
 350         kmutex_t                mi_perim_lock;
 351         kthread_t               *mi_perim_owner;        /* mi_perim_lock */
 352         uint_t                  mi_perim_ocnt;          /* mi_perim_lock */
 353         kcondvar_t              mi_perim_cv;            /* mi_perim_lock */
 354 
 355         /* mac notification callbacks */
 356         kmutex_t                mi_notify_lock;
 357         mac_cb_info_t           mi_notify_cb_info;      /* mi_notify_lock */
 358         mac_cb_t                *mi_notify_cb_list;     /* mi_notify_lock */
 359         kthread_t               *mi_notify_thread;      /* mi_notify_lock */
 360         uint_t                  mi_notify_bits;         /* mi_notify_lock */
 361 
 362         /* XXX thiru following 2 blocks obsolete */
 363         krwlock_t               mi_rx_lock;
 364         kcondvar_t              mi_rx_cv;
 365         uint32_t                mi_rx_removed;
 366         krwlock_t               mi_tx_lock;





 367 
 368         uint32_t                mi_v12n_level;          /* Virt'ion readiness */


 369 
 370         /*
 371          * RX groups, ring capability
 372          * Fields of this block are SL protected.
 373          */
 374         mac_group_type_t        mi_rx_group_type;       /* grouping type */
 375         uint_t                  mi_rx_group_count;
 376         mac_group_t             *mi_rx_groups;
 377 
 378         mac_capab_rings_t       mi_rx_rings_cap;
 379 
 380         /*
 381          * TX groups and ring capability, SL Protected.
 382          */
 383         mac_group_type_t        mi_tx_group_type;       /* grouping type */
 384         uint_t                  mi_tx_group_count;
 385         uint_t                  mi_tx_group_free;
 386         mac_group_t             *mi_tx_groups;
 387 
 388         mac_capab_rings_t       mi_tx_rings_cap;
 389 
 390         /*
 391          * MAC address list. SL protected.
 392          */
 393         mac_address_t           *mi_addresses;
 394 
 395         /*
 396          * This MAC's table of sub-flows
 397          */
 398         flow_tab_t              *mi_flow_tab;           /* WO */
 399 
 400         kstat_t                 *mi_ksp;                /* WO */
 401         uint_t                  mi_kstat_count;         /* WO */
 402         uint_t                  mi_nactiveclients;      /* SL */
 403 
 404         /* for broadcast and multicast support */
 405         struct mac_mcast_addrs_s *mi_mcast_addrs;       /* mi_rw_lock */
 406         struct mac_bcast_grp_s *mi_bcast_grp;           /* mi_rw_lock */
 407         uint_t                  mi_bcast_ngrps;         /* mi_rw_lock */
 408 
 409         /* list of MAC clients which opened this MAC */
 410         struct mac_client_impl_s *mi_clients_list;      /* mi_rw_lock */
 411         uint_t                  mi_nclients;            /* mi_rw_lock */
 412 
 413         uint32_t                mi_margin;              /* mi_rw_lock */
 414         uint_t                  mi_sdu_min;             /* mi_rw_lock */
 415         uint_t                  mi_sdu_max;             /* mi_rw_lock */
 416 
 417         /*
 418          * Cache of factory MAC addresses provided by the driver. If
 419          * the driver doesn't provide multiple factory MAC addresses,
 420          * the mi_factory_addr is set to NULL, and mi_factory_addr_num
 421          * is set to zero.
 422          */
 423         mac_factory_addr_t      *mi_factory_addr;       /* mi_rw_lock */
 424         uint_t                  mi_factory_addr_num;    /* mi_rw_lock */
 425 
 426         /* for promiscuous mode support */
 427         kmutex_t                mi_promisc_lock;
 428         mac_cb_t                *mi_promisc_list;       /* mi_promisc_lock */
 429         mac_cb_info_t           mi_promisc_cb_info;     /* mi_promisc_lock */
 430 
 431         /* cache of rings over this mac_impl */
 432         kmutex_t                mi_ring_lock;
 433         mac_ring_t              *mi_ring_freelist;      /* mi_ring_lock */
 434 
 435         /*
 436          * These are used for caching the properties, if any, for the
 437          * primary MAC client. If the MAC client is not yet in place
 438          * when the properties are set then we cache them here to be
 439          * applied to the MAC client when it is created.
 440          */
 441         mac_resource_props_t    mi_resource_props;      /* SL */
 442 
 443         minor_t                 mi_minor;               /* WO */
 444         dev_t                   mi_phy_dev;             /* WO */
 445         uint32_t                mi_oref;                /* SL */
 446         uint32_t                mi_unsup_note;          /* WO */
 447         /*
 448          * List of margin value requests added by mac clients. This list is
 449          * sorted: the first one has the greatest value.
 450          */
 451         mac_margin_req_t        *mi_mmrp;
 452         mac_priv_prop_t         *mi_priv_prop;
 453         uint_t                  mi_priv_prop_count;

 454 
 455         /*
 456          * Hybrid I/O related definitions.
 457          */
 458         mac_capab_share_t       mi_share_capab;
 459 
 460 /* This should be the last block in this structure */
 461 #ifdef DEBUG
 462 #define MAC_PERIM_STACK_DEPTH   15
 463         int                     mi_perim_stack_depth;
 464         pc_t                    mi_perim_stack[MAC_PERIM_STACK_DEPTH];
 465 #endif
 466 };
 467 
 468 /* for mi_state_flags */
 469 #define MIS_DISABLED            0x0001
 470 #define MIS_IS_VNIC             0x0002
 471 #define MIS_IS_AGGR             0x0004
 472 #define MIS_NOTIFY_DONE         0x0008
 473 #define MIS_EXCLUSIVE           0x0010
 474 #define MIS_EXCLUSIVE_HELD      0x0020
 475 #define MIS_LEGACY              0x0040
 476 
 477 #define mi_getstat      mi_callbacks->mc_getstat
 478 #define mi_start        mi_callbacks->mc_start
 479 #define mi_stop         mi_callbacks->mc_stop
 480 #define mi_open         mi_callbacks->mc_open
 481 #define mi_close        mi_callbacks->mc_close
 482 #define mi_setpromisc   mi_callbacks->mc_setpromisc
 483 #define mi_multicst     mi_callbacks->mc_multicst
 484 #define mi_unicst       mi_callbacks->mc_unicst

 485 #define mi_tx           mi_callbacks->mc_tx
 486 #define mi_ioctl        mi_callbacks->mc_ioctl
 487 #define mi_getcapab     mi_callbacks->mc_getcapab
 488 
 489 typedef struct mac_notify_task_arg {
 490         mac_impl_t              *mnt_mip;
 491         mac_notify_type_t       mnt_type;
 492         mac_ring_t              *mnt_ring;
 493 } mac_notify_task_arg_t;
 494 
 495 typedef enum {
 496         MAC_RX_NO_RESERVE,
 497         MAC_RX_RESERVE_DEFAULT,
 498         MAC_RX_RESERVE_NONDEFAULT
 499 } mac_rx_group_reserve_type_t;
 500 
 501 /*
 502  * XXX All MAC_DBG_PRTs must be replaced with call to dtrace probes. For now
 503  * it may be easier to have these printfs for easier debugging
 504  */
 505 #ifdef DEBUG
 506 extern int mac_dbg;
 507 #define MAC_DBG_PRT(a)  if (mac_dbg > 0) {(void) printf a; }
 508 #else
 509 #define MAC_DBG_PRT(a)
 510 #endif
 511 
 512 /*
 513  * The mac_perim_handle_t is an opaque type that encodes the 'mip' pointer
 514  * and whether internally a mac_open was done when acquiring the perimeter.
 515  */
 516 #define MAC_ENCODE_MPH(mph, mh, need_close)             \
 517         (mph) = (mac_perim_handle_t)((uintptr_t)(mh) | need_close)
 518 
 519 #define MAC_DECODE_MPH(mph, mip, need_close) {          \
 520         mip = (mac_impl_t *)(((uintptr_t)mph) & ~0x1);      \
 521         (need_close) = ((uintptr_t)mph & 0x1);              \
 522 }
 523 
 524 typedef struct mac_client_impl_s mac_client_impl_t;
 525 
 526 extern void     mac_init(void);
 527 extern int      mac_fini(void);
 528 
 529 extern void     mac_stat_create(mac_impl_t *);
 530 extern void     mac_stat_destroy(mac_impl_t *);
 531 extern uint64_t mac_stat_default(mac_impl_t *, uint_t);

 532 extern void     mac_ndd_ioctl(mac_impl_t *, queue_t *, mblk_t *);
 533 extern void     mac_create_soft_ring_kstats(mac_impl_t *, int32_t);
 534 extern boolean_t mac_ip_hdr_length_v6(mblk_t *, ip6_t *, uint16_t *,
 535     uint8_t *);
 536 
 537 extern mblk_t *mac_copymsgchain_cksum(mblk_t *);
 538 extern mblk_t *mac_fix_cksum(mblk_t *);
 539 extern void mac_packet_print(mac_handle_t, mblk_t *);
 540 extern void mac_rx_deliver(void *, mac_resource_handle_t, mblk_t *,
 541     mac_header_info_t *);
 542 extern void mac_tx_notify(mac_impl_t *);
 543 
 544 extern  boolean_t mac_callback_find(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
 545 extern  void    mac_callback_add(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
 546 extern  boolean_t mac_callback_remove(mac_cb_info_t *, mac_cb_t **, mac_cb_t *);
 547 extern  void    mac_callback_remove_wait(mac_cb_info_t *);
 548 extern  void    mac_callback_free(mac_cb_t *);
 549 extern  mac_cb_t *mac_callback_walker_cleanup(mac_cb_info_t *, mac_cb_t **);
 550 
 551 /* in mac_bcast.c */
 552 extern void mac_bcast_init(void);
 553 extern void mac_bcast_fini(void);
 554 extern mac_impl_t *mac_bcast_grp_mip(void *);
 555 extern int mac_bcast_add(mac_client_impl_t *, const uint8_t *, uint16_t,
 556     mac_addrtype_t);
 557 extern void mac_bcast_delete(mac_client_impl_t *, const uint8_t *, uint16_t);
 558 extern void mac_bcast_send(void *, void *, mblk_t *, boolean_t);
 559 extern void mac_bcast_grp_free(void *);
 560 extern void mac_bcast_refresh(mac_impl_t *, mac_multicst_t, void *,
 561     boolean_t);
 562 extern void mac_client_bcast_refresh(mac_client_impl_t *, mac_multicst_t,
 563     void *, boolean_t);
 564 
 565 /*
 566  * Grouping functions are used internally by MAC layer.
 567  */
 568 extern int mac_group_addmac(mac_group_t *, const uint8_t *);
 569 extern int mac_group_remmac(mac_group_t *, const uint8_t *);
 570 extern int mac_rx_group_add_flow(mac_client_impl_t *, flow_entry_t *,
 571     mac_group_t *);
 572 extern mblk_t *mac_ring_tx(mac_ring_handle_t, mblk_t *);
 573 
 574 extern mac_ring_t *mac_reserve_tx_ring(mac_impl_t *, mac_ring_t *);
 575 extern void mac_release_tx_ring(mac_ring_handle_t);
 576 extern mac_group_t *mac_reserve_tx_group(mac_impl_t *, mac_share_handle_t);
 577 extern void mac_release_tx_group(mac_impl_t *, mac_group_t *);
 578 
 579 /*
 580  * MAC address functions are used internally by MAC layer.
 581  */
 582 extern mac_address_t *mac_find_macaddr(mac_impl_t *, uint8_t *);
 583 extern boolean_t mac_check_macaddr_shared(mac_address_t *);
 584 extern int mac_update_macaddr(mac_address_t *, uint8_t *);
 585 extern void mac_freshen_macaddr(mac_address_t *, uint8_t *);
 586 extern void mac_init_macaddr(mac_impl_t *);
 587 extern void mac_fini_macaddr(mac_impl_t *);
 588 
 589 /*
 590  * Flow construction/destruction routines.
 591  * Not meant to be used by mac clients.
 592  */
 593 extern int mac_link_flow_init(mac_client_handle_t, flow_entry_t *);
 594 extern void mac_link_flow_clean(mac_client_handle_t, flow_entry_t *);
 595 
 596 /*
 597  * The following functions are used internally by the MAC layer to
 598  * add/remove/update flows associated with a mac_impl_t. They should
 599  * never be used directly by MAC clients.
 600  */
 601 extern int mac_datapath_setup(mac_client_impl_t *, flow_entry_t *, uint32_t);
 602 extern void mac_datapath_teardown(mac_client_impl_t *, flow_entry_t *,
 603     uint32_t);
 604 extern void mac_srs_group_setup(mac_client_impl_t *, flow_entry_t *,
 605     mac_group_t *, uint32_t);
 606 extern void mac_srs_group_teardown(mac_client_impl_t *, flow_entry_t *,
 607             uint32_t);
 608 extern int mac_rx_classify_flow_quiesce(flow_entry_t *, void *);
 609 extern int mac_rx_classify_flow_restart(flow_entry_t *, void *);
 610 extern void mac_tx_client_quiesce(mac_client_impl_t *, uint_t);
 611 extern void mac_tx_client_restart(mac_client_impl_t *);
 612 extern void mac_client_quiesce(mac_client_impl_t *);
 613 extern void mac_client_restart(mac_client_impl_t *);
 614 
 615 extern void mac_flow_update_priority(mac_client_impl_t *, flow_entry_t *);
 616 
 617 extern void mac_flow_rem_subflow(flow_entry_t *);
 618 extern void mac_rename_flow(flow_entry_t *, const char *);
 619 extern void mac_flow_set_name(flow_entry_t *, const char *);
 620 
 621 extern mblk_t *mac_add_vlan_tag_chain(mblk_t *, uint_t, uint16_t);
 622 extern mblk_t *mac_strip_vlan_tag_chain(mblk_t *);
 623 extern void mac_pkt_drop(void *, mac_resource_handle_t, mblk_t *, boolean_t);
 624 extern mblk_t *mac_rx_flow(mac_handle_t, mac_resource_handle_t, mblk_t *);
 625 
 626 extern void i_mac_share_alloc(mac_client_impl_t *);
 627 extern void i_mac_share_free(mac_client_impl_t *);
 628 extern void i_mac_perim_enter(mac_impl_t *);
 629 extern void i_mac_perim_exit(mac_impl_t *);
 630 extern int i_mac_perim_enter_nowait(mac_impl_t *);
 631 extern void i_mac_tx_srs_notify(mac_impl_t *, mac_ring_handle_t);
 632 extern int mac_hold(const char *, mac_impl_t **);
 633 extern void mac_rele(mac_impl_t *);
 634 extern int i_mac_disable(mac_impl_t *);
 635 extern void i_mac_notify(mac_impl_t *, mac_notify_type_t);
 636 extern void i_mac_notify_exit(mac_impl_t *);
 637 extern int mac_start(mac_handle_t);
 638 extern void mac_stop(mac_handle_t);
 639 extern void mac_rx_group_unmark(mac_group_t *, uint_t);
 640 extern void mac_tx_client_flush(mac_client_impl_t *);
 641 extern void mac_tx_client_block(mac_client_impl_t *);
 642 extern void mac_tx_client_unblock(mac_client_impl_t *);
 643 extern int i_mac_promisc_set(mac_impl_t *, boolean_t, mac_promisc_type_t);
 644 extern void i_mac_promisc_walker_cleanup(mac_impl_t *);
 645 extern mactype_t *mactype_getplugin(const char *);
 646 extern void mac_addr_factory_init(mac_impl_t *);
 647 extern void mac_addr_factory_fini(mac_impl_t *);
 648 extern void mac_register_priv_prop(mac_impl_t *, mac_priv_prop_t *, uint_t);
 649 extern void mac_free_priv_prop(mac_impl_t *);
 650 extern int mac_init_rings(mac_impl_t *, mac_ring_type_t);
 651 extern void mac_free_rings(mac_impl_t *, mac_ring_type_t);
 652 
 653 extern int mac_start_group(mac_group_t *);
 654 extern void mac_stop_group(mac_group_t *);
 655 extern int mac_start_ring(mac_ring_t *);
 656 extern void mac_stop_ring(mac_ring_t *);
 657 extern int mac_add_macaddr(mac_impl_t *, mac_group_t *, uint8_t *);
 658 extern int mac_remove_macaddr(mac_address_t *);
 659 
 660 extern void mac_set_rx_group_state(mac_group_t *, mac_group_state_t);
 661 extern void mac_rx_group_add_client(mac_group_t *, mac_client_impl_t *);
 662 extern void mac_rx_group_remove_client(mac_group_t *, mac_client_impl_t *)
 663 ;
 664 extern int i_mac_group_add_ring(mac_group_t *, mac_ring_t *, int);
 665 extern void i_mac_group_rem_ring(mac_group_t *, mac_ring_t *, boolean_t);
 666 
 667 #ifdef  __cplusplus
 668 }
 669 #endif
 670 
 671 #endif  /* _SYS_MAC_IMPL_H */
--- EOF ---