1*4eaa4710SRishi Srivatsavai /* 2*4eaa4710SRishi Srivatsavai * CDDL HEADER START 3*4eaa4710SRishi Srivatsavai * 4*4eaa4710SRishi Srivatsavai * The contents of this file are subject to the terms of the 5*4eaa4710SRishi Srivatsavai * Common Development and Distribution License (the "License"). 6*4eaa4710SRishi Srivatsavai * You may not use this file except in compliance with the License. 7*4eaa4710SRishi Srivatsavai * 8*4eaa4710SRishi Srivatsavai * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*4eaa4710SRishi Srivatsavai * or http://www.opensolaris.org/os/licensing. 10*4eaa4710SRishi Srivatsavai * See the License for the specific language governing permissions 11*4eaa4710SRishi Srivatsavai * and limitations under the License. 12*4eaa4710SRishi Srivatsavai * 13*4eaa4710SRishi Srivatsavai * When distributing Covered Code, include this CDDL HEADER in each 14*4eaa4710SRishi Srivatsavai * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*4eaa4710SRishi Srivatsavai * If applicable, add the following below this CDDL HEADER, with the 16*4eaa4710SRishi Srivatsavai * fields enclosed by brackets "[]" replaced with your own identifying 17*4eaa4710SRishi Srivatsavai * information: Portions Copyright [yyyy] [name of copyright owner] 18*4eaa4710SRishi Srivatsavai * 19*4eaa4710SRishi Srivatsavai * CDDL HEADER END 20*4eaa4710SRishi Srivatsavai */ 21*4eaa4710SRishi Srivatsavai 22*4eaa4710SRishi Srivatsavai /* 23*4eaa4710SRishi Srivatsavai * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*4eaa4710SRishi Srivatsavai * Use is subject to license terms. 25*4eaa4710SRishi Srivatsavai */ 26*4eaa4710SRishi Srivatsavai 27*4eaa4710SRishi Srivatsavai #ifndef _BRIDGE_IMPL_H 28*4eaa4710SRishi Srivatsavai #define _BRIDGE_IMPL_H 29*4eaa4710SRishi Srivatsavai 30*4eaa4710SRishi Srivatsavai /* 31*4eaa4710SRishi Srivatsavai * These are the internal data structures used by the layer-two (Ethernet) 32*4eaa4710SRishi Srivatsavai * bridging module. 33*4eaa4710SRishi Srivatsavai */ 34*4eaa4710SRishi Srivatsavai 35*4eaa4710SRishi Srivatsavai #ifdef __cplusplus 36*4eaa4710SRishi Srivatsavai extern "C" { 37*4eaa4710SRishi Srivatsavai #endif 38*4eaa4710SRishi Srivatsavai 39*4eaa4710SRishi Srivatsavai #include <sys/list.h> 40*4eaa4710SRishi Srivatsavai #include <sys/sysmacros.h> 41*4eaa4710SRishi Srivatsavai #include <sys/avl.h> 42*4eaa4710SRishi Srivatsavai #include <sys/queue.h> 43*4eaa4710SRishi Srivatsavai #include <sys/kstat.h> 44*4eaa4710SRishi Srivatsavai #include <sys/ksynch.h> 45*4eaa4710SRishi Srivatsavai #include <sys/ethernet.h> 46*4eaa4710SRishi Srivatsavai #include <sys/dld.h> 47*4eaa4710SRishi Srivatsavai #include <sys/mac.h> 48*4eaa4710SRishi Srivatsavai #include <sys/mac_client.h> 49*4eaa4710SRishi Srivatsavai #include <sys/vlan.h> 50*4eaa4710SRishi Srivatsavai #include <net/bridge.h> 51*4eaa4710SRishi Srivatsavai 52*4eaa4710SRishi Srivatsavai #define KSINST_NAMES "recv", "sent", "drops", \ 53*4eaa4710SRishi Srivatsavai "forward_direct", "forward_unknown", "forward_mbcast", \ 54*4eaa4710SRishi Srivatsavai "learn_source", "learn_moved", "learn_expire", "learn_size" 55*4eaa4710SRishi Srivatsavai typedef struct bridge_ksinst_s { 56*4eaa4710SRishi Srivatsavai kstat_named_t bki_recv; /* packets received */ 57*4eaa4710SRishi Srivatsavai kstat_named_t bki_sent; /* packets sent through */ 58*4eaa4710SRishi Srivatsavai kstat_named_t bki_drops; /* packets dropped (untowardly) */ 59*4eaa4710SRishi Srivatsavai kstat_named_t bki_forwards; /* packets forwarded */ 60*4eaa4710SRishi Srivatsavai kstat_named_t bki_unknown; /* packets forwarded (unknown dest) */ 61*4eaa4710SRishi Srivatsavai kstat_named_t bki_mbcast; /* packets forwarded (multi/bcast) */ 62*4eaa4710SRishi Srivatsavai kstat_named_t bki_source; /* source addresses learned */ 63*4eaa4710SRishi Srivatsavai kstat_named_t bki_moved; /* source addresses moved */ 64*4eaa4710SRishi Srivatsavai kstat_named_t bki_expire; /* source addresses expired */ 65*4eaa4710SRishi Srivatsavai kstat_named_t bki_count; /* source addresses known */ 66*4eaa4710SRishi Srivatsavai } bridge_ksinst_t; 67*4eaa4710SRishi Srivatsavai 68*4eaa4710SRishi Srivatsavai #define KSLINK_NAMES "recv", "xmit", "drops" 69*4eaa4710SRishi Srivatsavai typedef struct bridge_kslink_s { 70*4eaa4710SRishi Srivatsavai kstat_named_t bkl_recv; /* packets received */ 71*4eaa4710SRishi Srivatsavai kstat_named_t bkl_xmit; /* packets transmitted */ 72*4eaa4710SRishi Srivatsavai kstat_named_t bkl_drops; /* packets dropped */ 73*4eaa4710SRishi Srivatsavai } bridge_kslink_t; 74*4eaa4710SRishi Srivatsavai 75*4eaa4710SRishi Srivatsavai /* 76*4eaa4710SRishi Srivatsavai * There's one instance structure and one observability mac node for each 77*4eaa4710SRishi Srivatsavai * bridge. Each open non-DLPI stream gets a 'stream' structure; these are used 78*4eaa4710SRishi Srivatsavai * for bridge instance allocation and control. Each link on the bridge has a 79*4eaa4710SRishi Srivatsavai * link structure. Finally, the bridge has a table of learned forwarding 80*4eaa4710SRishi Srivatsavai * entries, each with a list of outputs, which are either links or TRILL 81*4eaa4710SRishi Srivatsavai * nicknames. 82*4eaa4710SRishi Srivatsavai * 83*4eaa4710SRishi Srivatsavai * The mac structure lives as long as the dls and mac layers are busy. It can 84*4eaa4710SRishi Srivatsavai * outlive the bridge instance and be picked up again (by name) if the instance 85*4eaa4710SRishi Srivatsavai * is restarted. 86*4eaa4710SRishi Srivatsavai */ 87*4eaa4710SRishi Srivatsavai 88*4eaa4710SRishi Srivatsavai struct bridge_mac_s; 89*4eaa4710SRishi Srivatsavai struct bridge_stream_s; 90*4eaa4710SRishi Srivatsavai 91*4eaa4710SRishi Srivatsavai typedef struct bridge_inst_s { 92*4eaa4710SRishi Srivatsavai list_node_t bi_node; 93*4eaa4710SRishi Srivatsavai dev_t bi_dev; 94*4eaa4710SRishi Srivatsavai uint_t bi_flags; 95*4eaa4710SRishi Srivatsavai uint_t bi_refs; 96*4eaa4710SRishi Srivatsavai uint32_t bi_tablemax; 97*4eaa4710SRishi Srivatsavai uint_t bi_tshift; 98*4eaa4710SRishi Srivatsavai krwlock_t bi_rwlock; 99*4eaa4710SRishi Srivatsavai list_t bi_links; 100*4eaa4710SRishi Srivatsavai kcondvar_t bi_linkwait; 101*4eaa4710SRishi Srivatsavai avl_tree_t bi_fwd; 102*4eaa4710SRishi Srivatsavai kstat_t *bi_ksp; 103*4eaa4710SRishi Srivatsavai struct bridge_stream_s *bi_control; 104*4eaa4710SRishi Srivatsavai struct bridge_mac_s *bi_mac; 105*4eaa4710SRishi Srivatsavai void *bi_trilldata; 106*4eaa4710SRishi Srivatsavai char bi_name[MAXLINKNAMELEN]; 107*4eaa4710SRishi Srivatsavai bridge_ksinst_t bi_kstats; 108*4eaa4710SRishi Srivatsavai } bridge_inst_t; 109*4eaa4710SRishi Srivatsavai 110*4eaa4710SRishi Srivatsavai #define BIF_SHUTDOWN 0x0001 /* control stream has closed */ 111*4eaa4710SRishi Srivatsavai 112*4eaa4710SRishi Srivatsavai /* 113*4eaa4710SRishi Srivatsavai * The bridge MAC structure has the same lifetime as an observability node. 114*4eaa4710SRishi Srivatsavai * It's created when a bridge instance is allocated, but is not freed when the 115*4eaa4710SRishi Srivatsavai * instance is removed because there's no way for a MAC client to guarantee 116*4eaa4710SRishi Srivatsavai * that all users have disappeared. 117*4eaa4710SRishi Srivatsavai */ 118*4eaa4710SRishi Srivatsavai typedef struct bridge_mac_s { 119*4eaa4710SRishi Srivatsavai list_node_t bm_node; 120*4eaa4710SRishi Srivatsavai mac_handle_t bm_mh; 121*4eaa4710SRishi Srivatsavai bridge_inst_t *bm_inst; 122*4eaa4710SRishi Srivatsavai uint_t bm_flags; /* BMF_* below */ 123*4eaa4710SRishi Srivatsavai uint_t bm_maxsdu; 124*4eaa4710SRishi Srivatsavai link_state_t bm_linkstate; 125*4eaa4710SRishi Srivatsavai char bm_name[MAXLINKNAMELEN]; 126*4eaa4710SRishi Srivatsavai } bridge_mac_t; 127*4eaa4710SRishi Srivatsavai 128*4eaa4710SRishi Srivatsavai #define BMF_DLS 0x0001 /* dls monitor node created */ 129*4eaa4710SRishi Srivatsavai #define BMF_STARTED 0x0002 /* snoop-like client is present */ 130*4eaa4710SRishi Srivatsavai 131*4eaa4710SRishi Srivatsavai /* 132*4eaa4710SRishi Srivatsavai * Bridge streams are used only for instance allocation and control. 133*4eaa4710SRishi Srivatsavai */ 134*4eaa4710SRishi Srivatsavai typedef struct bridge_stream_s { 135*4eaa4710SRishi Srivatsavai bridge_inst_t *bs_inst; 136*4eaa4710SRishi Srivatsavai queue_t *bs_wq; /* write-side queue for stream */ 137*4eaa4710SRishi Srivatsavai minor_t bs_minor; 138*4eaa4710SRishi Srivatsavai uint_t bs_taskq_cnt; /* taskq references */ 139*4eaa4710SRishi Srivatsavai } bridge_stream_t; 140*4eaa4710SRishi Srivatsavai 141*4eaa4710SRishi Srivatsavai /* 142*4eaa4710SRishi Srivatsavai * These macros are used to set and test link membership in particular VLANs. 143*4eaa4710SRishi Srivatsavai * This membership is used to determine how to forward packets between 144*4eaa4710SRishi Srivatsavai * interfaces. 145*4eaa4710SRishi Srivatsavai */ 146*4eaa4710SRishi Srivatsavai 147*4eaa4710SRishi Srivatsavai #define BRIDGE_VLAN_ARR_SIZE \ 148*4eaa4710SRishi Srivatsavai (P2ROUNDUP(VLAN_ID_MAX, NBBY) / NBBY) 149*4eaa4710SRishi Srivatsavai 150*4eaa4710SRishi Srivatsavai #define BRIDGE_VLAN_ISSET(l, v) ((l)->bl_vlans[(v) / NBBY] & \ 151*4eaa4710SRishi Srivatsavai (1 << ((v) % NBBY))) 152*4eaa4710SRishi Srivatsavai 153*4eaa4710SRishi Srivatsavai #define BRIDGE_VLAN_SET(l, v) ((l)->bl_vlans[(v) / NBBY] |= \ 154*4eaa4710SRishi Srivatsavai (1 << ((v) % NBBY))) 155*4eaa4710SRishi Srivatsavai 156*4eaa4710SRishi Srivatsavai #define BRIDGE_VLAN_CLR(l, v) ((l)->bl_vlans[(v) / NBBY] &= \ 157*4eaa4710SRishi Srivatsavai ~(1 << ((v) % NBBY))) 158*4eaa4710SRishi Srivatsavai 159*4eaa4710SRishi Srivatsavai #define BRIDGE_AF_ISSET(l, v) ((l)->bl_afs[(v) / NBBY] & \ 160*4eaa4710SRishi Srivatsavai (1 << ((v) % NBBY))) 161*4eaa4710SRishi Srivatsavai 162*4eaa4710SRishi Srivatsavai /* 163*4eaa4710SRishi Srivatsavai * This structure represents a link attached to a bridge. VLAN membership 164*4eaa4710SRishi Srivatsavai * information is kept here; when forwarding, we must look at the membership of 165*4eaa4710SRishi Srivatsavai * the input link and the output to determine when to update the packet 166*4eaa4710SRishi Srivatsavai * contents and when to discard. 167*4eaa4710SRishi Srivatsavai */ 168*4eaa4710SRishi Srivatsavai typedef struct bridge_link_s { 169*4eaa4710SRishi Srivatsavai list_node_t bl_node; 170*4eaa4710SRishi Srivatsavai uint_t bl_refs; 171*4eaa4710SRishi Srivatsavai datalink_id_t bl_linkid; /* allocated link ID for bridge */ 172*4eaa4710SRishi Srivatsavai bridge_state_t bl_state; /* blocking/learning/forwarding */ 173*4eaa4710SRishi Srivatsavai uint_t bl_pvid; /* VLAN ID for untagged traffic */ 174*4eaa4710SRishi Srivatsavai uint_t bl_flags; /* BLF_* below */ 175*4eaa4710SRishi Srivatsavai uint_t bl_learns; /* learning limit */ 176*4eaa4710SRishi Srivatsavai mac_handle_t bl_mh; 177*4eaa4710SRishi Srivatsavai mac_client_handle_t bl_mch; 178*4eaa4710SRishi Srivatsavai uint32_t bl_margin; 179*4eaa4710SRishi Srivatsavai uint_t bl_maxsdu; 180*4eaa4710SRishi Srivatsavai mac_unicast_handle_t bl_mah; 181*4eaa4710SRishi Srivatsavai mac_notify_handle_t bl_mnh; 182*4eaa4710SRishi Srivatsavai mac_promisc_handle_t bl_mphp; 183*4eaa4710SRishi Srivatsavai bridge_inst_t *bl_inst; /* backpointer to bridge instance */ 184*4eaa4710SRishi Srivatsavai kstat_t *bl_ksp; 185*4eaa4710SRishi Srivatsavai void *bl_trilldata; 186*4eaa4710SRishi Srivatsavai mblk_t *bl_lfailmp; /* preallocated */ 187*4eaa4710SRishi Srivatsavai link_state_t bl_linkstate; 188*4eaa4710SRishi Srivatsavai uint_t bl_trillthreads; 189*4eaa4710SRishi Srivatsavai kcondvar_t bl_trillwait; 190*4eaa4710SRishi Srivatsavai kmutex_t bl_trilllock; 191*4eaa4710SRishi Srivatsavai uint8_t bl_local_mac[ETHERADDRL]; 192*4eaa4710SRishi Srivatsavai uint8_t bl_vlans[BRIDGE_VLAN_ARR_SIZE]; 193*4eaa4710SRishi Srivatsavai uint8_t bl_afs[BRIDGE_VLAN_ARR_SIZE]; 194*4eaa4710SRishi Srivatsavai bridge_kslink_t bl_kstats; 195*4eaa4710SRishi Srivatsavai } bridge_link_t; 196*4eaa4710SRishi Srivatsavai 197*4eaa4710SRishi Srivatsavai #define BLF_DELETED 0x0001 /* waiting for last reference to go */ 198*4eaa4710SRishi Srivatsavai #define BLF_CLIENT_OPEN 0x0002 /* MAC client opened */ 199*4eaa4710SRishi Srivatsavai #define BLF_MARGIN_ADDED 0x0004 /* MAC margin added */ 200*4eaa4710SRishi Srivatsavai #define BLF_SET_BRIDGE 0x0008 /* MAC in bridging mode */ 201*4eaa4710SRishi Srivatsavai #define BLF_PROM_ADDED 0x0010 /* MAC promiscuous added */ 202*4eaa4710SRishi Srivatsavai #define BLF_FREED 0x0020 /* free has begun; debug assertion */ 203*4eaa4710SRishi Srivatsavai #define BLF_TRILLACTIVE 0x0040 /* in active forwarding use */ 204*4eaa4710SRishi Srivatsavai #define BLF_SDUFAIL 0x0080 /* has mismatched SDU */ 205*4eaa4710SRishi Srivatsavai 206*4eaa4710SRishi Srivatsavai /* 207*4eaa4710SRishi Srivatsavai * This represents a learned forwarding entry. These are generally created and 208*4eaa4710SRishi Srivatsavai * refreshed on demand as we learn about nodes through source MAC addresses we 209*4eaa4710SRishi Srivatsavai * see. They're destroyed when they age away. For forwarding, we look up the 210*4eaa4710SRishi Srivatsavai * destination address in an AVL tree, and the entry found tells us where the 211*4eaa4710SRishi Srivatsavai * that source must live. 212*4eaa4710SRishi Srivatsavai */ 213*4eaa4710SRishi Srivatsavai typedef struct bridge_fwd_s { 214*4eaa4710SRishi Srivatsavai avl_node_t bf_node; 215*4eaa4710SRishi Srivatsavai uchar_t bf_dest[ETHERADDRL]; 216*4eaa4710SRishi Srivatsavai uint16_t bf_trill_nick; /* destination nickname */ 217*4eaa4710SRishi Srivatsavai clock_t bf_lastheard; /* time we last heard from this node */ 218*4eaa4710SRishi Srivatsavai uint_t bf_flags; /* BFF_* below */ 219*4eaa4710SRishi Srivatsavai uint_t bf_refs; 220*4eaa4710SRishi Srivatsavai uint16_t bf_vlanid; /* VLAN ID for IVL */ 221*4eaa4710SRishi Srivatsavai uint16_t bf_vcnt; /* number of duplicates */ 222*4eaa4710SRishi Srivatsavai uint_t bf_nlinks; /* number of links in bf_links */ 223*4eaa4710SRishi Srivatsavai uint_t bf_maxlinks; /* allocated size of link array */ 224*4eaa4710SRishi Srivatsavai bridge_link_t **bf_links; 225*4eaa4710SRishi Srivatsavai } bridge_fwd_t; 226*4eaa4710SRishi Srivatsavai 227*4eaa4710SRishi Srivatsavai #define BFF_INTREE 0x0001 228*4eaa4710SRishi Srivatsavai #define BFF_LOCALADDR 0x0002 /* address is known to mac layer */ 229*4eaa4710SRishi Srivatsavai #define BFF_VLANLOCAL 0x0004 /* set if duplicate for IVL */ 230*4eaa4710SRishi Srivatsavai 231*4eaa4710SRishi Srivatsavai /* TRILL linkage */ 232*4eaa4710SRishi Srivatsavai typedef void (*trill_recv_pkt_t)(void *, bridge_link_t *, mac_resource_handle_t, 233*4eaa4710SRishi Srivatsavai mblk_t *, mac_header_info_t *); 234*4eaa4710SRishi Srivatsavai typedef void (*trill_encap_pkt_t)(void *, bridge_link_t *, mac_header_info_t *, 235*4eaa4710SRishi Srivatsavai mblk_t *, uint16_t); 236*4eaa4710SRishi Srivatsavai typedef void (*trill_br_dstr_t)(void *, bridge_inst_t *); 237*4eaa4710SRishi Srivatsavai typedef void (*trill_ln_dstr_t)(void *, bridge_link_t *); 238*4eaa4710SRishi Srivatsavai 239*4eaa4710SRishi Srivatsavai extern void bridge_trill_register_cb(trill_recv_pkt_t, trill_encap_pkt_t, 240*4eaa4710SRishi Srivatsavai trill_br_dstr_t, trill_ln_dstr_t); 241*4eaa4710SRishi Srivatsavai extern bridge_inst_t *bridge_trill_brref(const char *, void *); 242*4eaa4710SRishi Srivatsavai extern void bridge_trill_brunref(bridge_inst_t *); 243*4eaa4710SRishi Srivatsavai extern bridge_link_t *bridge_trill_lnref(bridge_inst_t *, datalink_id_t, 244*4eaa4710SRishi Srivatsavai void *); 245*4eaa4710SRishi Srivatsavai extern void bridge_trill_lnunref(bridge_link_t *); 246*4eaa4710SRishi Srivatsavai extern void bridge_trill_decaps(bridge_link_t *, mblk_t *, uint16_t); 247*4eaa4710SRishi Srivatsavai extern mblk_t *bridge_trill_output(bridge_link_t *, mblk_t *); 248*4eaa4710SRishi Srivatsavai extern void bridge_trill_setvlans(bridge_link_t *, const uint8_t *); 249*4eaa4710SRishi Srivatsavai extern void bridge_trill_flush(bridge_link_t *, uint16_t, boolean_t); 250*4eaa4710SRishi Srivatsavai 251*4eaa4710SRishi Srivatsavai /* Ethernet multicast address; constant stored in bridge module */ 252*4eaa4710SRishi Srivatsavai extern const uint8_t all_isis_rbridges[]; 253*4eaa4710SRishi Srivatsavai extern const uint8_t bridge_group_address[]; 254*4eaa4710SRishi Srivatsavai 255*4eaa4710SRishi Srivatsavai #ifdef __cplusplus 256*4eaa4710SRishi Srivatsavai } 257*4eaa4710SRishi Srivatsavai #endif 258*4eaa4710SRishi Srivatsavai 259*4eaa4710SRishi Srivatsavai #endif /* _BRIDGE_IMPL_H */ 260