14eaa4710SRishi Srivatsavai /*
24eaa4710SRishi Srivatsavai  * CDDL HEADER START
34eaa4710SRishi Srivatsavai  *
44eaa4710SRishi Srivatsavai  * The contents of this file are subject to the terms of the
54eaa4710SRishi Srivatsavai  * Common Development and Distribution License (the "License").
64eaa4710SRishi Srivatsavai  * You may not use this file except in compliance with the License.
74eaa4710SRishi Srivatsavai  *
84eaa4710SRishi Srivatsavai  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94eaa4710SRishi Srivatsavai  * or http://www.opensolaris.org/os/licensing.
104eaa4710SRishi Srivatsavai  * See the License for the specific language governing permissions
114eaa4710SRishi Srivatsavai  * and limitations under the License.
124eaa4710SRishi Srivatsavai  *
134eaa4710SRishi Srivatsavai  * When distributing Covered Code, include this CDDL HEADER in each
144eaa4710SRishi Srivatsavai  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154eaa4710SRishi Srivatsavai  * If applicable, add the following below this CDDL HEADER, with the
164eaa4710SRishi Srivatsavai  * fields enclosed by brackets "[]" replaced with your own identifying
174eaa4710SRishi Srivatsavai  * information: Portions Copyright [yyyy] [name of copyright owner]
184eaa4710SRishi Srivatsavai  *
194eaa4710SRishi Srivatsavai  * CDDL HEADER END
204eaa4710SRishi Srivatsavai  */
214eaa4710SRishi Srivatsavai 
224eaa4710SRishi Srivatsavai /*
23*6f40bf67SRishi Srivatsavai  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
244eaa4710SRishi Srivatsavai  * Use is subject to license terms.
254eaa4710SRishi Srivatsavai  */
264eaa4710SRishi Srivatsavai 
274eaa4710SRishi Srivatsavai #ifndef _BRIDGE_IMPL_H
284eaa4710SRishi Srivatsavai #define	_BRIDGE_IMPL_H
294eaa4710SRishi Srivatsavai 
304eaa4710SRishi Srivatsavai /*
314eaa4710SRishi Srivatsavai  * These are the internal data structures used by the layer-two (Ethernet)
324eaa4710SRishi Srivatsavai  * bridging module.
334eaa4710SRishi Srivatsavai  */
344eaa4710SRishi Srivatsavai 
354eaa4710SRishi Srivatsavai #ifdef __cplusplus
364eaa4710SRishi Srivatsavai extern "C" {
374eaa4710SRishi Srivatsavai #endif
384eaa4710SRishi Srivatsavai 
394eaa4710SRishi Srivatsavai #include <sys/list.h>
404eaa4710SRishi Srivatsavai #include <sys/sysmacros.h>
414eaa4710SRishi Srivatsavai #include <sys/avl.h>
424eaa4710SRishi Srivatsavai #include <sys/queue.h>
434eaa4710SRishi Srivatsavai #include <sys/kstat.h>
444eaa4710SRishi Srivatsavai #include <sys/ksynch.h>
454eaa4710SRishi Srivatsavai #include <sys/ethernet.h>
464eaa4710SRishi Srivatsavai #include <sys/dld.h>
474eaa4710SRishi Srivatsavai #include <sys/mac.h>
484eaa4710SRishi Srivatsavai #include <sys/mac_client.h>
494eaa4710SRishi Srivatsavai #include <sys/vlan.h>
504eaa4710SRishi Srivatsavai #include <net/bridge.h>
514eaa4710SRishi Srivatsavai 
52f2905fb7SRishi Srivatsavai #define	BRIDGE_DEV_NAME	"bridge"
53f2905fb7SRishi Srivatsavai 
544eaa4710SRishi Srivatsavai #define	KSINST_NAMES	"recv", "sent", "drops", \
554eaa4710SRishi Srivatsavai 	"forward_direct", "forward_unknown", "forward_mbcast",	\
564eaa4710SRishi Srivatsavai 	"learn_source", "learn_moved", "learn_expire", "learn_size"
574eaa4710SRishi Srivatsavai typedef struct bridge_ksinst_s {
584eaa4710SRishi Srivatsavai 	kstat_named_t	bki_recv;	/* packets received */
594eaa4710SRishi Srivatsavai 	kstat_named_t	bki_sent;	/* packets sent through */
604eaa4710SRishi Srivatsavai 	kstat_named_t	bki_drops;	/* packets dropped (untowardly) */
614eaa4710SRishi Srivatsavai 	kstat_named_t	bki_forwards;	/* packets forwarded */
624eaa4710SRishi Srivatsavai 	kstat_named_t	bki_unknown;	/* packets forwarded (unknown dest) */
634eaa4710SRishi Srivatsavai 	kstat_named_t	bki_mbcast;	/* packets forwarded (multi/bcast) */
644eaa4710SRishi Srivatsavai 	kstat_named_t	bki_source;	/* source addresses learned */
654eaa4710SRishi Srivatsavai 	kstat_named_t	bki_moved;	/* source addresses moved */
664eaa4710SRishi Srivatsavai 	kstat_named_t	bki_expire;	/* source addresses expired */
674eaa4710SRishi Srivatsavai 	kstat_named_t	bki_count;	/* source addresses known */
684eaa4710SRishi Srivatsavai } bridge_ksinst_t;
694eaa4710SRishi Srivatsavai 
704eaa4710SRishi Srivatsavai #define	KSLINK_NAMES	"recv", "xmit", "drops"
714eaa4710SRishi Srivatsavai typedef struct bridge_kslink_s {
724eaa4710SRishi Srivatsavai 	kstat_named_t	bkl_recv;	/* packets received */
734eaa4710SRishi Srivatsavai 	kstat_named_t	bkl_xmit;	/* packets transmitted */
744eaa4710SRishi Srivatsavai 	kstat_named_t	bkl_drops;	/* packets dropped */
754eaa4710SRishi Srivatsavai } bridge_kslink_t;
764eaa4710SRishi Srivatsavai 
774eaa4710SRishi Srivatsavai /*
784eaa4710SRishi Srivatsavai  * There's one instance structure and one observability mac node for each
794eaa4710SRishi Srivatsavai  * bridge.  Each open non-DLPI stream gets a 'stream' structure; these are used
804eaa4710SRishi Srivatsavai  * for bridge instance allocation and control.  Each link on the bridge has a
814eaa4710SRishi Srivatsavai  * link structure.  Finally, the bridge has a table of learned forwarding
824eaa4710SRishi Srivatsavai  * entries, each with a list of outputs, which are either links or TRILL
834eaa4710SRishi Srivatsavai  * nicknames.
844eaa4710SRishi Srivatsavai  *
854eaa4710SRishi Srivatsavai  * The mac structure lives as long as the dls and mac layers are busy.  It can
864eaa4710SRishi Srivatsavai  * outlive the bridge instance and be picked up again (by name) if the instance
874eaa4710SRishi Srivatsavai  * is restarted.
884eaa4710SRishi Srivatsavai  */
894eaa4710SRishi Srivatsavai 
904eaa4710SRishi Srivatsavai struct bridge_mac_s;
914eaa4710SRishi Srivatsavai struct bridge_stream_s;
924eaa4710SRishi Srivatsavai 
934eaa4710SRishi Srivatsavai typedef struct bridge_inst_s {
944eaa4710SRishi Srivatsavai 	list_node_t	bi_node;
954eaa4710SRishi Srivatsavai 	dev_t		bi_dev;
964eaa4710SRishi Srivatsavai 	uint_t		bi_flags;
974eaa4710SRishi Srivatsavai 	uint_t		bi_refs;
984eaa4710SRishi Srivatsavai 	uint32_t	bi_tablemax;
994eaa4710SRishi Srivatsavai 	uint_t		bi_tshift;
1004eaa4710SRishi Srivatsavai 	krwlock_t	bi_rwlock;
1014eaa4710SRishi Srivatsavai 	list_t		bi_links;
1024eaa4710SRishi Srivatsavai 	kcondvar_t	bi_linkwait;
1034eaa4710SRishi Srivatsavai 	avl_tree_t	bi_fwd;
1044eaa4710SRishi Srivatsavai 	kstat_t		*bi_ksp;
1054eaa4710SRishi Srivatsavai 	struct bridge_stream_s *bi_control;
1064eaa4710SRishi Srivatsavai 	struct bridge_mac_s *bi_mac;
1074eaa4710SRishi Srivatsavai 	void		*bi_trilldata;
1084eaa4710SRishi Srivatsavai 	char		bi_name[MAXLINKNAMELEN];
1094eaa4710SRishi Srivatsavai 	bridge_ksinst_t	bi_kstats;
1104eaa4710SRishi Srivatsavai } bridge_inst_t;
1114eaa4710SRishi Srivatsavai 
1124eaa4710SRishi Srivatsavai #define	BIF_SHUTDOWN	0x0001		/* control stream has closed */
1134eaa4710SRishi Srivatsavai 
1144eaa4710SRishi Srivatsavai /*
1154eaa4710SRishi Srivatsavai  * The bridge MAC structure has the same lifetime as an observability node.
1164eaa4710SRishi Srivatsavai  * It's created when a bridge instance is allocated, but is not freed when the
1174eaa4710SRishi Srivatsavai  * instance is removed because there's no way for a MAC client to guarantee
1184eaa4710SRishi Srivatsavai  * that all users have disappeared.
1194eaa4710SRishi Srivatsavai  */
1204eaa4710SRishi Srivatsavai typedef struct bridge_mac_s {
1214eaa4710SRishi Srivatsavai 	list_node_t	bm_node;
1224eaa4710SRishi Srivatsavai 	mac_handle_t	bm_mh;
1234eaa4710SRishi Srivatsavai 	bridge_inst_t	*bm_inst;
1244eaa4710SRishi Srivatsavai 	uint_t		bm_flags;	/* BMF_* below */
1254eaa4710SRishi Srivatsavai 	uint_t		bm_maxsdu;
1264eaa4710SRishi Srivatsavai 	link_state_t	bm_linkstate;
1274eaa4710SRishi Srivatsavai 	char		bm_name[MAXLINKNAMELEN];
1284eaa4710SRishi Srivatsavai } bridge_mac_t;
1294eaa4710SRishi Srivatsavai 
1304eaa4710SRishi Srivatsavai #define	BMF_DLS		0x0001		/* dls monitor node created */
1314eaa4710SRishi Srivatsavai #define	BMF_STARTED	0x0002		/* snoop-like client is present */
1324eaa4710SRishi Srivatsavai 
1334eaa4710SRishi Srivatsavai /*
1344eaa4710SRishi Srivatsavai  * Bridge streams are used only for instance allocation and control.
1354eaa4710SRishi Srivatsavai  */
1364eaa4710SRishi Srivatsavai typedef struct bridge_stream_s {
1374eaa4710SRishi Srivatsavai 	bridge_inst_t	*bs_inst;
1384eaa4710SRishi Srivatsavai 	queue_t		*bs_wq;		/* write-side queue for stream */
1394eaa4710SRishi Srivatsavai 	minor_t		bs_minor;
1404eaa4710SRishi Srivatsavai 	uint_t		bs_taskq_cnt;	/* taskq references */
1414eaa4710SRishi Srivatsavai } bridge_stream_t;
1424eaa4710SRishi Srivatsavai 
1434eaa4710SRishi Srivatsavai /*
1444eaa4710SRishi Srivatsavai  * These macros are used to set and test link membership in particular VLANs.
1454eaa4710SRishi Srivatsavai  * This membership is used to determine how to forward packets between
1464eaa4710SRishi Srivatsavai  * interfaces.
1474eaa4710SRishi Srivatsavai  */
1484eaa4710SRishi Srivatsavai 
1494eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_ARR_SIZE	\
1504eaa4710SRishi Srivatsavai 	(P2ROUNDUP(VLAN_ID_MAX, NBBY) / NBBY)
1514eaa4710SRishi Srivatsavai 
1524eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_ISSET(l, v)	((l)->bl_vlans[(v) / NBBY] & \
1534eaa4710SRishi Srivatsavai 	(1 << ((v) % NBBY)))
1544eaa4710SRishi Srivatsavai 
1554eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_SET(l, v)	((l)->bl_vlans[(v) / NBBY] |= \
1564eaa4710SRishi Srivatsavai 	(1 << ((v) % NBBY)))
1574eaa4710SRishi Srivatsavai 
1584eaa4710SRishi Srivatsavai #define	BRIDGE_VLAN_CLR(l, v)	((l)->bl_vlans[(v) / NBBY] &= \
1594eaa4710SRishi Srivatsavai 	~(1 << ((v) % NBBY)))
1604eaa4710SRishi Srivatsavai 
1614eaa4710SRishi Srivatsavai #define	BRIDGE_AF_ISSET(l, v)	((l)->bl_afs[(v) / NBBY] & \
1624eaa4710SRishi Srivatsavai 	(1 << ((v) % NBBY)))
1634eaa4710SRishi Srivatsavai 
1644eaa4710SRishi Srivatsavai /*
1654eaa4710SRishi Srivatsavai  * This structure represents a link attached to a bridge.  VLAN membership
1664eaa4710SRishi Srivatsavai  * information is kept here; when forwarding, we must look at the membership of
1674eaa4710SRishi Srivatsavai  * the input link and the output to determine when to update the packet
1684eaa4710SRishi Srivatsavai  * contents and when to discard.
1694eaa4710SRishi Srivatsavai  */
1704eaa4710SRishi Srivatsavai typedef struct bridge_link_s {
1714eaa4710SRishi Srivatsavai 	list_node_t	bl_node;
1724eaa4710SRishi Srivatsavai 	uint_t		bl_refs;
1734eaa4710SRishi Srivatsavai 	datalink_id_t	bl_linkid;	/* allocated link ID for bridge */
1744eaa4710SRishi Srivatsavai 	bridge_state_t	bl_state;	/* blocking/learning/forwarding */
1754eaa4710SRishi Srivatsavai 	uint_t		bl_pvid;	/* VLAN ID for untagged traffic */
1764eaa4710SRishi Srivatsavai 	uint_t		bl_flags;	/* BLF_* below */
1774eaa4710SRishi Srivatsavai 	uint_t		bl_learns;	/* learning limit */
1784eaa4710SRishi Srivatsavai 	mac_handle_t	bl_mh;
1794eaa4710SRishi Srivatsavai 	mac_client_handle_t	bl_mch;
1804eaa4710SRishi Srivatsavai 	uint32_t	bl_margin;
1814eaa4710SRishi Srivatsavai 	uint_t		bl_maxsdu;
1824eaa4710SRishi Srivatsavai 	mac_unicast_handle_t	bl_mah;
1834eaa4710SRishi Srivatsavai 	mac_notify_handle_t	bl_mnh;
1844eaa4710SRishi Srivatsavai 	mac_promisc_handle_t	bl_mphp;
1854eaa4710SRishi Srivatsavai 	bridge_inst_t	*bl_inst;	/* backpointer to bridge instance */
1864eaa4710SRishi Srivatsavai 	kstat_t		*bl_ksp;
1874eaa4710SRishi Srivatsavai 	void		*bl_trilldata;
1884eaa4710SRishi Srivatsavai 	mblk_t		*bl_lfailmp;	/* preallocated */
1894eaa4710SRishi Srivatsavai 	link_state_t	bl_linkstate;
1904eaa4710SRishi Srivatsavai 	uint_t		bl_trillthreads;
1914eaa4710SRishi Srivatsavai 	kcondvar_t	bl_trillwait;
1924eaa4710SRishi Srivatsavai 	kmutex_t	bl_trilllock;
1934eaa4710SRishi Srivatsavai 	uint8_t		bl_local_mac[ETHERADDRL];
1944eaa4710SRishi Srivatsavai 	uint8_t		bl_vlans[BRIDGE_VLAN_ARR_SIZE];
1954eaa4710SRishi Srivatsavai 	uint8_t		bl_afs[BRIDGE_VLAN_ARR_SIZE];
1964eaa4710SRishi Srivatsavai 	bridge_kslink_t	bl_kstats;
1974eaa4710SRishi Srivatsavai } bridge_link_t;
1984eaa4710SRishi Srivatsavai 
1994eaa4710SRishi Srivatsavai #define	BLF_DELETED		0x0001	/* waiting for last reference to go */
2004eaa4710SRishi Srivatsavai #define	BLF_CLIENT_OPEN		0x0002	/* MAC client opened */
2014eaa4710SRishi Srivatsavai #define	BLF_MARGIN_ADDED	0x0004	/* MAC margin added */
2024eaa4710SRishi Srivatsavai #define	BLF_SET_BRIDGE		0x0008	/* MAC in bridging mode */
2034eaa4710SRishi Srivatsavai #define	BLF_PROM_ADDED		0x0010	/* MAC promiscuous added */
2044eaa4710SRishi Srivatsavai #define	BLF_FREED		0x0020	/* free has begun; debug assertion */
2054eaa4710SRishi Srivatsavai #define	BLF_TRILLACTIVE		0x0040	/* in active forwarding use */
2064eaa4710SRishi Srivatsavai #define	BLF_SDUFAIL		0x0080	/* has mismatched SDU */
207*6f40bf67SRishi Srivatsavai #define	BLF_LINK_ADDED		0x0100	/* link added in bridge instance */
2084eaa4710SRishi Srivatsavai 
2094eaa4710SRishi Srivatsavai /*
2104eaa4710SRishi Srivatsavai  * This represents a learned forwarding entry.  These are generally created and
2114eaa4710SRishi Srivatsavai  * refreshed on demand as we learn about nodes through source MAC addresses we
2124eaa4710SRishi Srivatsavai  * see.  They're destroyed when they age away.  For forwarding, we look up the
2134eaa4710SRishi Srivatsavai  * destination address in an AVL tree, and the entry found tells us where the
2144eaa4710SRishi Srivatsavai  * that source must live.
2154eaa4710SRishi Srivatsavai  */
2164eaa4710SRishi Srivatsavai typedef struct bridge_fwd_s {
2174eaa4710SRishi Srivatsavai 	avl_node_t	bf_node;
2184eaa4710SRishi Srivatsavai 	uchar_t		bf_dest[ETHERADDRL];
2194eaa4710SRishi Srivatsavai 	uint16_t	bf_trill_nick;	/* destination nickname */
2204eaa4710SRishi Srivatsavai 	clock_t		bf_lastheard;	/* time we last heard from this node */
2214eaa4710SRishi Srivatsavai 	uint_t		bf_flags;	/* BFF_* below */
2224eaa4710SRishi Srivatsavai 	uint_t		bf_refs;
2234eaa4710SRishi Srivatsavai 	uint16_t	bf_vlanid;	/* VLAN ID for IVL */
2244eaa4710SRishi Srivatsavai 	uint16_t	bf_vcnt;	/* number of duplicates */
2254eaa4710SRishi Srivatsavai 	uint_t		bf_nlinks;	/* number of links in bf_links */
2264eaa4710SRishi Srivatsavai 	uint_t		bf_maxlinks;	/* allocated size of link array */
2274eaa4710SRishi Srivatsavai 	bridge_link_t	**bf_links;
2284eaa4710SRishi Srivatsavai } bridge_fwd_t;
2294eaa4710SRishi Srivatsavai 
2304eaa4710SRishi Srivatsavai #define	BFF_INTREE	0x0001
2314eaa4710SRishi Srivatsavai #define	BFF_LOCALADDR	0x0002		/* address is known to mac layer */
2324eaa4710SRishi Srivatsavai #define	BFF_VLANLOCAL	0x0004		/* set if duplicate for IVL */
2334eaa4710SRishi Srivatsavai 
2344eaa4710SRishi Srivatsavai /* TRILL linkage */
2354eaa4710SRishi Srivatsavai typedef void (*trill_recv_pkt_t)(void *, bridge_link_t *, mac_resource_handle_t,
2364eaa4710SRishi Srivatsavai     mblk_t *, mac_header_info_t *);
2374eaa4710SRishi Srivatsavai typedef void (*trill_encap_pkt_t)(void *, bridge_link_t *, mac_header_info_t *,
2384eaa4710SRishi Srivatsavai     mblk_t *, uint16_t);
2394eaa4710SRishi Srivatsavai typedef void (*trill_br_dstr_t)(void *, bridge_inst_t *);
2404eaa4710SRishi Srivatsavai typedef void (*trill_ln_dstr_t)(void *, bridge_link_t *);
2414eaa4710SRishi Srivatsavai 
2424eaa4710SRishi Srivatsavai extern void bridge_trill_register_cb(trill_recv_pkt_t, trill_encap_pkt_t,
2434eaa4710SRishi Srivatsavai     trill_br_dstr_t, trill_ln_dstr_t);
2444eaa4710SRishi Srivatsavai extern bridge_inst_t *bridge_trill_brref(const char *, void *);
2454eaa4710SRishi Srivatsavai extern void bridge_trill_brunref(bridge_inst_t *);
2464eaa4710SRishi Srivatsavai extern bridge_link_t *bridge_trill_lnref(bridge_inst_t *, datalink_id_t,
2474eaa4710SRishi Srivatsavai     void *);
2484eaa4710SRishi Srivatsavai extern void bridge_trill_lnunref(bridge_link_t *);
2494eaa4710SRishi Srivatsavai extern void bridge_trill_decaps(bridge_link_t *, mblk_t *, uint16_t);
2504eaa4710SRishi Srivatsavai extern mblk_t *bridge_trill_output(bridge_link_t *, mblk_t *);
2514eaa4710SRishi Srivatsavai extern void bridge_trill_setvlans(bridge_link_t *, const uint8_t *);
2524eaa4710SRishi Srivatsavai extern void bridge_trill_flush(bridge_link_t *, uint16_t, boolean_t);
2534eaa4710SRishi Srivatsavai 
2544eaa4710SRishi Srivatsavai /* Ethernet multicast address; constant stored in bridge module */
2554eaa4710SRishi Srivatsavai extern const uint8_t all_isis_rbridges[];
2564eaa4710SRishi Srivatsavai extern const uint8_t bridge_group_address[];
2574eaa4710SRishi Srivatsavai 
2584eaa4710SRishi Srivatsavai #ifdef __cplusplus
2594eaa4710SRishi Srivatsavai }
2604eaa4710SRishi Srivatsavai #endif
2614eaa4710SRishi Srivatsavai 
2624eaa4710SRishi Srivatsavai #endif /* _BRIDGE_IMPL_H */