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