17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5f12af565Snd99603 * Common Development and Distribution License (the "License"). 6f12af565Snd99603 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22d62bc4baSyz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #ifndef _SYS_AGGR_IMPL_H 277c478bd9Sstevel@tonic-gate #define _SYS_AGGR_IMPL_H 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 30ba2e4443Sseb #include <sys/mac_ether.h> 31*da14cebeSEric Cheng #include <sys/mac_provider.h> 32*da14cebeSEric Cheng #include <sys/mac_client.h> 33*da14cebeSEric Cheng #include <sys/mac_client_priv.h> 347c478bd9Sstevel@tonic-gate #include <sys/aggr_lacp.h> 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #ifdef __cplusplus 377c478bd9Sstevel@tonic-gate extern "C" { 387c478bd9Sstevel@tonic-gate #endif 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #ifdef _KERNEL 417c478bd9Sstevel@tonic-gate 42210db224Sericheng #define AGGR_MINOR_CTL 1 /* control interface minor */ 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate /* flags for aggr_grp_modify() */ 457c478bd9Sstevel@tonic-gate #define AGGR_MODIFY_POLICY 0x01 467c478bd9Sstevel@tonic-gate #define AGGR_MODIFY_MAC 0x02 477c478bd9Sstevel@tonic-gate #define AGGR_MODIFY_LACP_MODE 0x04 487c478bd9Sstevel@tonic-gate #define AGGR_MODIFY_LACP_TIMER 0x08 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* 51*da14cebeSEric Cheng * Possible value of aggr_rseudo_rx_ring_t.arr_flags. Set when the ring entry 52*da14cebeSEric Cheng * in the pseudo RX group is used. 53*da14cebeSEric Cheng */ 54*da14cebeSEric Cheng #define MAC_PSEUDO_RING_INUSE 0x01 55*da14cebeSEric Cheng 56*da14cebeSEric Cheng typedef struct aggr_unicst_addr_s { 57*da14cebeSEric Cheng uint8_t aua_addr[ETHERADDRL]; 58*da14cebeSEric Cheng struct aggr_unicst_addr_s *aua_next; 59*da14cebeSEric Cheng } aggr_unicst_addr_t; 60*da14cebeSEric Cheng 61*da14cebeSEric Cheng typedef struct aggr_pseudo_rx_ring_s { 62*da14cebeSEric Cheng mac_ring_handle_t arr_rh; /* filled in by aggr_fill_ring() */ 63*da14cebeSEric Cheng struct aggr_port_s *arr_port; 64*da14cebeSEric Cheng mac_ring_handle_t arr_hw_rh; 65*da14cebeSEric Cheng uint_t arr_flags; 66*da14cebeSEric Cheng uint64_t arr_gen; 67*da14cebeSEric Cheng } aggr_pseudo_rx_ring_t; 68*da14cebeSEric Cheng 69*da14cebeSEric Cheng typedef struct aggr_pseudo_rx_group_s { 70*da14cebeSEric Cheng struct aggr_grp_s *arg_grp; /* filled in by aggr_fill_group() */ 71*da14cebeSEric Cheng mac_group_handle_t arg_gh; /* filled in by aggr_fill_group() */ 72*da14cebeSEric Cheng aggr_unicst_addr_t *arg_macaddr; 73*da14cebeSEric Cheng aggr_pseudo_rx_ring_t arg_rings[MAX_RINGS_PER_GROUP]; 74*da14cebeSEric Cheng uint_t arg_ring_cnt; 75*da14cebeSEric Cheng } aggr_pseudo_rx_group_t; 76*da14cebeSEric Cheng 77*da14cebeSEric Cheng /* 787c478bd9Sstevel@tonic-gate * A link aggregation MAC port. 797c478bd9Sstevel@tonic-gate * Note that lp_next is protected by the lg_lock of the group the 807c478bd9Sstevel@tonic-gate * port is part of. 817c478bd9Sstevel@tonic-gate */ 827c478bd9Sstevel@tonic-gate typedef struct aggr_port_s { 837c478bd9Sstevel@tonic-gate struct aggr_port_s *lp_next; 847c478bd9Sstevel@tonic-gate struct aggr_grp_s *lp_grp; /* back ptr to group */ 85d62bc4baSyz147064 datalink_id_t lp_linkid; 86392b1d6eSyz147064 uint16_t lp_portid; 877c478bd9Sstevel@tonic-gate uint8_t lp_addr[ETHERADDRL]; /* port MAC address */ 887c478bd9Sstevel@tonic-gate uint32_t lp_refs; /* refcount */ 897c478bd9Sstevel@tonic-gate aggr_port_state_t lp_state; 907c478bd9Sstevel@tonic-gate uint32_t lp_started : 1, 917c478bd9Sstevel@tonic-gate lp_tx_enabled : 1, 927c478bd9Sstevel@tonic-gate lp_collector_enabled : 1, 937c478bd9Sstevel@tonic-gate lp_promisc_on : 1, 94d62bc4baSyz147064 lp_no_link_update : 1, 95*da14cebeSEric Cheng lp_grp_added : 1, 96*da14cebeSEric Cheng lp_closing : 1, 97*da14cebeSEric Cheng lp_pad_bits : 25; 987c478bd9Sstevel@tonic-gate mac_handle_t lp_mh; 99*da14cebeSEric Cheng mac_client_handle_t lp_mch; 1007c478bd9Sstevel@tonic-gate const mac_info_t *lp_mip; 1017c478bd9Sstevel@tonic-gate mac_notify_handle_t lp_mnh; 1027c478bd9Sstevel@tonic-gate uint_t lp_tx_idx; /* idx in group's tx array */ 1037c478bd9Sstevel@tonic-gate uint64_t lp_ifspeed; 1047c478bd9Sstevel@tonic-gate link_state_t lp_link_state; 1057c478bd9Sstevel@tonic-gate link_duplex_t lp_link_duplex; 1067c478bd9Sstevel@tonic-gate uint64_t lp_stat[MAC_NSTAT]; 107ba2e4443Sseb uint64_t lp_ether_stat[ETHER_NSTAT]; 1087c478bd9Sstevel@tonic-gate aggr_lacp_port_t lp_lacp; /* LACP state */ 1097c478bd9Sstevel@tonic-gate lacp_stats_t lp_lacp_stats; 110d62bc4baSyz147064 uint32_t lp_margin; 111*da14cebeSEric Cheng mac_promisc_handle_t lp_mphp; 112*da14cebeSEric Cheng mac_unicast_handle_t lp_mah; 1137c478bd9Sstevel@tonic-gate 114*da14cebeSEric Cheng /* List of non-primary addresses that requires promiscous mode set */ 115*da14cebeSEric Cheng aggr_unicst_addr_t *lp_prom_addr; 116*da14cebeSEric Cheng /* handle of the underlying HW RX group */ 117*da14cebeSEric Cheng mac_group_handle_t lp_hwgh; 118*da14cebeSEric Cheng } aggr_port_t; 11919599311Sudpa 1207c478bd9Sstevel@tonic-gate /* 1217c478bd9Sstevel@tonic-gate * A link aggregation group. 1227c478bd9Sstevel@tonic-gate * 1237c478bd9Sstevel@tonic-gate * The following per-group flags are defined: 1247c478bd9Sstevel@tonic-gate * 1257c478bd9Sstevel@tonic-gate * - lg_addr_fixed: set when the MAC address has been explicitely set 1267c478bd9Sstevel@tonic-gate * when the group was created, or by a m_unicst_set() request. 1277c478bd9Sstevel@tonic-gate * If this flag is not set, the MAC address of the group will be 1287c478bd9Sstevel@tonic-gate * set to the first port that is added to the group. 1297c478bd9Sstevel@tonic-gate * 1307c478bd9Sstevel@tonic-gate * - lg_add_set: used only when lg_addr_fixed is not set. Captures whether 1317c478bd9Sstevel@tonic-gate * the MAC address was initialized according to the members of the group. 1327c478bd9Sstevel@tonic-gate * When set, the lg_port field points to the port from which the 1337c478bd9Sstevel@tonic-gate * MAC address was initialized. 1347c478bd9Sstevel@tonic-gate * 1357c478bd9Sstevel@tonic-gate */ 1367c478bd9Sstevel@tonic-gate typedef struct aggr_grp_s { 137d62bc4baSyz147064 datalink_id_t lg_linkid; 1387c478bd9Sstevel@tonic-gate uint16_t lg_key; /* key (group port number) */ 1397c478bd9Sstevel@tonic-gate uint32_t lg_refs; /* refcount */ 1407c478bd9Sstevel@tonic-gate uint16_t lg_nports; /* number of MAC ports */ 1417c478bd9Sstevel@tonic-gate uint8_t lg_addr[ETHERADDRL]; /* group MAC address */ 1427c478bd9Sstevel@tonic-gate uint16_t 1434deae11aSyz147064 lg_closing : 1, 1447c478bd9Sstevel@tonic-gate lg_addr_fixed : 1, /* fixed MAC address? */ 1457c478bd9Sstevel@tonic-gate lg_started : 1, /* group started? */ 1467c478bd9Sstevel@tonic-gate lg_promisc : 1, /* in promiscuous mode? */ 147d62bc4baSyz147064 lg_zcopy : 1, 148d62bc4baSyz147064 lg_vlan : 1, 149d62bc4baSyz147064 lg_force : 1, 150*da14cebeSEric Cheng lg_pad_bits : 9; 1517c478bd9Sstevel@tonic-gate aggr_port_t *lg_ports; /* list of configured ports */ 1527c478bd9Sstevel@tonic-gate aggr_port_t *lg_mac_addr_port; 153ba2e4443Sseb mac_handle_t lg_mh; 1547c478bd9Sstevel@tonic-gate uint_t lg_nattached_ports; 155*da14cebeSEric Cheng krwlock_t lg_tx_lock; 1567c478bd9Sstevel@tonic-gate uint_t lg_ntx_ports; 1577c478bd9Sstevel@tonic-gate aggr_port_t **lg_tx_ports; /* array of tx ports */ 1587c478bd9Sstevel@tonic-gate uint_t lg_tx_ports_size; /* size of lg_tx_ports */ 1597c478bd9Sstevel@tonic-gate uint32_t lg_tx_policy; /* outbound policy */ 1607c478bd9Sstevel@tonic-gate uint64_t lg_ifspeed; 1617c478bd9Sstevel@tonic-gate link_state_t lg_link_state; 1627c478bd9Sstevel@tonic-gate link_duplex_t lg_link_duplex; 1637c478bd9Sstevel@tonic-gate uint64_t lg_stat[MAC_NSTAT]; 164ba2e4443Sseb uint64_t lg_ether_stat[ETHER_NSTAT]; 1657c478bd9Sstevel@tonic-gate aggr_lacp_mode_t lg_lacp_mode; /* off, active, or passive */ 1667c478bd9Sstevel@tonic-gate Agg_t aggr; /* 802.3ad data */ 167ba2e4443Sseb uint32_t lg_hcksum_txflags; 168f4420ae7Snd99603 uint_t lg_max_sdu; 169d62bc4baSyz147064 uint32_t lg_margin; 1707c478bd9Sstevel@tonic-gate 171*da14cebeSEric Cheng /* 172*da14cebeSEric Cheng * The following fields are used by the LACP packets processing. 173*da14cebeSEric Cheng * Specifically, as the LACP packets processing is not performance 174*da14cebeSEric Cheng * critical, all LACP packets will be handled by a dedicated thread 175*da14cebeSEric Cheng * instead of in the mac_rx() call. This is to avoid the dead lock 176*da14cebeSEric Cheng * with mac_unicast_remove(), which holding the mac perimeter of the 177*da14cebeSEric Cheng * aggr, and wait for the mr_refcnt of the RX ring to drop to zero. 178*da14cebeSEric Cheng */ 179*da14cebeSEric Cheng kmutex_t lg_lacp_lock; 180*da14cebeSEric Cheng kcondvar_t lg_lacp_cv; 181*da14cebeSEric Cheng mblk_t *lg_lacp_head; 182*da14cebeSEric Cheng mblk_t *lg_lacp_tail; 183*da14cebeSEric Cheng kthread_t *lg_lacp_rx_thread; 184*da14cebeSEric Cheng boolean_t lg_lacp_done; 185*da14cebeSEric Cheng aggr_pseudo_rx_group_t lg_rx_group; 186*da14cebeSEric Cheng 187*da14cebeSEric Cheng /* 188*da14cebeSEric Cheng * The following fields are used by aggr to wait for all the 189*da14cebeSEric Cheng * aggr_port_notify_cb() and aggr_port_timer_thread() to finish 190*da14cebeSEric Cheng * before it calls mac_unregister() when the aggr is deleted. 191*da14cebeSEric Cheng */ 192*da14cebeSEric Cheng kmutex_t lg_port_lock; 193*da14cebeSEric Cheng kcondvar_t lg_port_cv; 194*da14cebeSEric Cheng int lg_port_ref; 195*da14cebeSEric Cheng } aggr_grp_t; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate #define AGGR_GRP_REFHOLD(grp) { \ 1987c478bd9Sstevel@tonic-gate atomic_add_32(&(grp)->lg_refs, 1); \ 1997c478bd9Sstevel@tonic-gate ASSERT((grp)->lg_refs != 0); \ 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate 2027c478bd9Sstevel@tonic-gate #define AGGR_GRP_REFRELE(grp) { \ 2037c478bd9Sstevel@tonic-gate ASSERT((grp)->lg_refs != 0); \ 2047c478bd9Sstevel@tonic-gate membar_exit(); \ 2057c478bd9Sstevel@tonic-gate if (atomic_add_32_nv(&(grp)->lg_refs, -1) == 0) \ 2067c478bd9Sstevel@tonic-gate aggr_grp_free(grp); \ 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate #define AGGR_PORT_REFHOLD(port) { \ 2107c478bd9Sstevel@tonic-gate atomic_add_32(&(port)->lp_refs, 1); \ 2117c478bd9Sstevel@tonic-gate ASSERT((port)->lp_refs != 0); \ 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate 2147c478bd9Sstevel@tonic-gate #define AGGR_PORT_REFRELE(port) { \ 2157c478bd9Sstevel@tonic-gate ASSERT((port)->lp_refs != 0); \ 2167c478bd9Sstevel@tonic-gate membar_exit(); \ 2177c478bd9Sstevel@tonic-gate if (atomic_add_32_nv(&(port)->lp_refs, -1) == 0) \ 2187c478bd9Sstevel@tonic-gate aggr_port_free(port); \ 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate extern dev_info_t *aggr_dip; 222eae72b5bSSebastien Roy extern int aggr_ioc_init(void); 223eae72b5bSSebastien Roy extern void aggr_ioc_fini(void); 2247c478bd9Sstevel@tonic-gate 225d62bc4baSyz147064 typedef int (*aggr_grp_info_new_grp_fn_t)(void *, datalink_id_t, uint32_t, 226d62bc4baSyz147064 uchar_t *, boolean_t, boolean_t, uint32_t, uint32_t, aggr_lacp_mode_t, 227d62bc4baSyz147064 aggr_lacp_timer_t); 228d62bc4baSyz147064 typedef int (*aggr_grp_info_new_port_fn_t)(void *, datalink_id_t, uchar_t *, 229ba2e4443Sseb aggr_port_state_t, aggr_lacp_state_t *); 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate extern void aggr_grp_init(void); 232c0192a57Sericheng extern void aggr_grp_fini(void); 233d62bc4baSyz147064 extern int aggr_grp_create(datalink_id_t, uint32_t, uint_t, laioc_port_t *, 234d62bc4baSyz147064 uint32_t, boolean_t, boolean_t, uchar_t *, aggr_lacp_mode_t, 235d62bc4baSyz147064 aggr_lacp_timer_t); 236d62bc4baSyz147064 extern int aggr_grp_delete(datalink_id_t); 2377c478bd9Sstevel@tonic-gate extern void aggr_grp_free(aggr_grp_t *); 2387c478bd9Sstevel@tonic-gate 239d62bc4baSyz147064 extern int aggr_grp_info(datalink_id_t, void *, aggr_grp_info_new_grp_fn_t, 240d62bc4baSyz147064 aggr_grp_info_new_port_fn_t); 2417c478bd9Sstevel@tonic-gate extern void aggr_grp_notify(aggr_grp_t *, uint32_t); 2427c478bd9Sstevel@tonic-gate extern boolean_t aggr_grp_attach_port(aggr_grp_t *, aggr_port_t *); 243*da14cebeSEric Cheng extern boolean_t aggr_grp_detach_port(aggr_grp_t *, aggr_port_t *); 2444deae11aSyz147064 extern void aggr_grp_port_mac_changed(aggr_grp_t *, aggr_port_t *, 2454deae11aSyz147064 boolean_t *, boolean_t *); 246d62bc4baSyz147064 extern int aggr_grp_add_ports(datalink_id_t, uint_t, boolean_t, 247d62bc4baSyz147064 laioc_port_t *); 248d62bc4baSyz147064 extern int aggr_grp_rem_ports(datalink_id_t, uint_t, laioc_port_t *); 2494deae11aSyz147064 extern boolean_t aggr_grp_update_ports_mac(aggr_grp_t *); 250*da14cebeSEric Cheng extern int aggr_grp_modify(datalink_id_t, uint8_t, uint32_t, boolean_t, 251*da14cebeSEric Cheng const uchar_t *, aggr_lacp_mode_t, aggr_lacp_timer_t); 2527c478bd9Sstevel@tonic-gate extern void aggr_grp_multicst_port(aggr_port_t *, boolean_t); 253210db224Sericheng extern uint_t aggr_grp_count(void); 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate extern void aggr_port_init(void); 256c0192a57Sericheng extern void aggr_port_fini(void); 257*da14cebeSEric Cheng extern int aggr_port_create(aggr_grp_t *, const datalink_id_t, boolean_t, 258*da14cebeSEric Cheng aggr_port_t **); 2597c478bd9Sstevel@tonic-gate extern void aggr_port_delete(aggr_port_t *); 2607c478bd9Sstevel@tonic-gate extern void aggr_port_free(aggr_port_t *); 2617c478bd9Sstevel@tonic-gate extern int aggr_port_start(aggr_port_t *); 2627c478bd9Sstevel@tonic-gate extern void aggr_port_stop(aggr_port_t *); 2637c478bd9Sstevel@tonic-gate extern int aggr_port_promisc(aggr_port_t *, boolean_t); 264*da14cebeSEric Cheng extern int aggr_port_unicst(aggr_port_t *); 2657c478bd9Sstevel@tonic-gate extern int aggr_port_multicst(void *, boolean_t, const uint8_t *); 266ba2e4443Sseb extern uint64_t aggr_port_stat(aggr_port_t *, uint_t); 267*da14cebeSEric Cheng extern boolean_t aggr_port_notify_link(aggr_grp_t *, aggr_port_t *); 268c615009fSyz147064 extern void aggr_port_init_callbacks(aggr_port_t *); 2697c478bd9Sstevel@tonic-gate 270*da14cebeSEric Cheng extern void aggr_recv_cb(void *, mac_resource_handle_t, mblk_t *, boolean_t); 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate extern mblk_t *aggr_m_tx(void *, mblk_t *); 2737c478bd9Sstevel@tonic-gate extern void aggr_send_port_enable(aggr_port_t *); 2747c478bd9Sstevel@tonic-gate extern void aggr_send_port_disable(aggr_port_t *); 2757c478bd9Sstevel@tonic-gate extern void aggr_send_update_policy(aggr_grp_t *, uint32_t); 2767c478bd9Sstevel@tonic-gate 277f12af565Snd99603 extern void aggr_lacp_init(void); 278f12af565Snd99603 extern void aggr_lacp_fini(void); 2797c478bd9Sstevel@tonic-gate extern void aggr_lacp_init_port(aggr_port_t *); 2807c478bd9Sstevel@tonic-gate extern void aggr_lacp_init_grp(aggr_grp_t *); 2817c478bd9Sstevel@tonic-gate extern void aggr_lacp_set_mode(aggr_grp_t *, aggr_lacp_mode_t, 2827c478bd9Sstevel@tonic-gate aggr_lacp_timer_t); 2837c478bd9Sstevel@tonic-gate extern void aggr_lacp_update_mode(aggr_grp_t *, aggr_lacp_mode_t); 2847c478bd9Sstevel@tonic-gate extern void aggr_lacp_update_timer(aggr_grp_t *, aggr_lacp_timer_t); 285*da14cebeSEric Cheng extern void aggr_lacp_rx_enqueue(aggr_port_t *, mblk_t *); 2867c478bd9Sstevel@tonic-gate extern void aggr_lacp_port_attached(aggr_port_t *); 2877c478bd9Sstevel@tonic-gate extern void aggr_lacp_port_detached(aggr_port_t *); 288*da14cebeSEric Cheng extern void aggr_port_lacp_set_mode(aggr_grp_t *, aggr_port_t *); 289*da14cebeSEric Cheng 290*da14cebeSEric Cheng extern void aggr_lacp_rx_thread(void *); 291*da14cebeSEric Cheng extern void aggr_recv_lacp(aggr_port_t *, mac_resource_handle_t, mblk_t *); 292*da14cebeSEric Cheng 293*da14cebeSEric Cheng extern void aggr_grp_port_hold(aggr_port_t *); 294*da14cebeSEric Cheng extern void aggr_grp_port_rele(aggr_port_t *); 295*da14cebeSEric Cheng extern void aggr_grp_port_wait(aggr_grp_t *); 296*da14cebeSEric Cheng 297*da14cebeSEric Cheng extern int aggr_port_addmac(aggr_port_t *, const uint8_t *); 298*da14cebeSEric Cheng extern void aggr_port_remmac(aggr_port_t *, const uint8_t *); 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate #ifdef __cplusplus 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate #endif 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate #endif /* _SYS_AGGR_IMPL_H */ 307