summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/net
diff options
context:
space:
mode:
authorRishi Srivatsavai <Rishi.Srivatsavai@Sun.COM>2009-09-10 15:11:49 -0400
committerRishi Srivatsavai <Rishi.Srivatsavai@Sun.COM>2009-09-10 15:11:49 -0400
commit4eaa471005973e11a6110b69fe990530b3b95a38 (patch)
tree3aca4c2ad771c935bfa146d4a6abbe51ee464a57 /usr/src/uts/common/net
parentd5688513c1985c22c27675da44b5b691f123818e (diff)
downloadillumos-joyent-4eaa471005973e11a6110b69fe990530b3b95a38.tar.gz
PSARC 2007/596 RBridges: Routing Bridges
PSARC 2008/055 Solaris Bridging PSARC 2009/344 Bridging Updates 6223953 Solaris should provide layer 2 bridging 6770623 bogus error messages generated by dladm should be cleaned up
Diffstat (limited to 'usr/src/uts/common/net')
-rw-r--r--usr/src/uts/common/net/Makefile2
-rw-r--r--usr/src/uts/common/net/bridge.h117
-rw-r--r--usr/src/uts/common/net/bridge_impl.h259
-rw-r--r--usr/src/uts/common/net/trill.h174
4 files changed, 551 insertions, 1 deletions
diff --git a/usr/src/uts/common/net/Makefile b/usr/src/uts/common/net/Makefile
index 288be848d6..b5341f74c0 100644
--- a/usr/src/uts/common/net/Makefile
+++ b/usr/src/uts/common/net/Makefile
@@ -28,7 +28,7 @@ include ../../../Makefile.master
HDRS= af.h if.h if_arp.h if_dl.h if_types.h route.h pfkeyv2.h pfpolicy.h \
ppp-comp.h ppp_defs.h pppio.h vjcompress.h sppptun.h pppoe.h radix.h \
- wpa.h simnet.h
+ wpa.h simnet.h bridge.h bridge_impl.h trill.h
ROOTDIRS= $(ROOT)/usr/include/net
diff --git a/usr/src/uts/common/net/bridge.h b/usr/src/uts/common/net/bridge.h
new file mode 100644
index 0000000000..47249a36f5
--- /dev/null
+++ b/usr/src/uts/common/net/bridge.h
@@ -0,0 +1,117 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _NET_BRIDGE_H
+#define _NET_BRIDGE_H
+
+/*
+ * Private communication interface between bridging related daemons and kernel
+ * layer-two (Ethernet) bridging module.
+ */
+
+#include <sys/param.h>
+#include <sys/dld.h>
+#include <sys/dld_ioc.h>
+#include <sys/ethernet.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Specified by IEEE 802.1d */
+#define BRIDGE_GROUP_ADDRESS { 0x01, 0x80, 0xC2, 0, 0, 0 }
+
+/* The constant below is "BRG" in hex. */
+#define _BRIOC(n) (0x42524700 + (n))
+
+#define BRIOC_NEWBRIDGE _BRIOC(1) /* Create bridge; bridge_newbridge_t */
+#define BRIOC_ADDLINK _BRIOC(2) /* Add link to bridge; linkid+name */
+#define BRIOC_REMLINK _BRIOC(3) /* Remove link from bridge; linkid */
+#define BRIOC_SETSTATE _BRIOC(4) /* bridge_setstate_t */
+#define BRIOC_SETPVID _BRIOC(5) /* bridge_setpvid_t */
+#define BRIOC_VLANENAB _BRIOC(6) /* bridge_vlanenab_t */
+#define BRIOC_FLUSHFWD _BRIOC(7) /* bridge_flushfwd_t */
+#define BRIOC_LISTFWD _BRIOC(8) /* bridge_listfwd_t */
+#define BRIOC_TABLEMAX _BRIOC(8) /* uint32_t */
+
+#define BRIDGE_CTL "bridgectl"
+#define BRIDGE_CTLPATH "/dev/" BRIDGE_CTL
+
+typedef struct bridge_newbridge_s {
+ datalink_id_t bnb_linkid; /* bridge link ID */
+ char bnb_name[MAXNAMELEN]; /* bridge name */
+} bridge_newbridge_t;
+
+typedef enum bridge_state_e {
+ BLS_BLOCKLISTEN, /* blocking or listening state */
+ BLS_LEARNING, /* learning state */
+ BLS_FORWARDING /* forwarding state */
+} bridge_state_t;
+
+typedef struct bridge_setstate_s {
+ datalink_id_t bss_linkid;
+ bridge_state_t bss_state;
+} bridge_setstate_t;
+
+typedef struct bridge_setpvid_s {
+ datalink_id_t bsv_linkid;
+ uint_t bsv_vlan;
+} bridge_setpvid_t;
+
+typedef struct bridge_vlanenab_s {
+ datalink_id_t bve_linkid;
+ uint_t bve_vlan;
+ boolean_t bve_onoff;
+} bridge_vlanenab_t;
+
+typedef struct bridge_flushfwd_s {
+ datalink_id_t bff_linkid;
+ boolean_t bff_exclude;
+} bridge_flushfwd_t;
+
+typedef struct bridge_listfwd_s {
+ char blf_name[MAXNAMELEN]; /* bridge name */
+ ether_addr_t blf_dest;
+ uint16_t blf_trill_nick;
+ uint_t blf_ms_age;
+ boolean_t blf_is_local;
+ datalink_id_t blf_linkid;
+} bridge_listfwd_t;
+
+/* Upward control messages */
+typedef struct bridge_ctl_s {
+ datalink_id_t bc_linkid;
+ boolean_t bc_failed; /* Max SDU mismatch */
+} bridge_ctl_t;
+
+/* GLDv3 control ioctls used by Bridging */
+#define BRIDGE_IOC_LISTFWD BRIDGEIOC(1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NET_BRIDGE_H */
diff --git a/usr/src/uts/common/net/bridge_impl.h b/usr/src/uts/common/net/bridge_impl.h
new file mode 100644
index 0000000000..a25f63286a
--- /dev/null
+++ b/usr/src/uts/common/net/bridge_impl.h
@@ -0,0 +1,259 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _BRIDGE_IMPL_H
+#define _BRIDGE_IMPL_H
+
+/*
+ * These are the internal data structures used by the layer-two (Ethernet)
+ * bridging module.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/list.h>
+#include <sys/sysmacros.h>
+#include <sys/avl.h>
+#include <sys/queue.h>
+#include <sys/kstat.h>
+#include <sys/ksynch.h>
+#include <sys/ethernet.h>
+#include <sys/dld.h>
+#include <sys/mac.h>
+#include <sys/mac_client.h>
+#include <sys/vlan.h>
+#include <net/bridge.h>
+
+#define KSINST_NAMES "recv", "sent", "drops", \
+ "forward_direct", "forward_unknown", "forward_mbcast", \
+ "learn_source", "learn_moved", "learn_expire", "learn_size"
+typedef struct bridge_ksinst_s {
+ kstat_named_t bki_recv; /* packets received */
+ kstat_named_t bki_sent; /* packets sent through */
+ kstat_named_t bki_drops; /* packets dropped (untowardly) */
+ kstat_named_t bki_forwards; /* packets forwarded */
+ kstat_named_t bki_unknown; /* packets forwarded (unknown dest) */
+ kstat_named_t bki_mbcast; /* packets forwarded (multi/bcast) */
+ kstat_named_t bki_source; /* source addresses learned */
+ kstat_named_t bki_moved; /* source addresses moved */
+ kstat_named_t bki_expire; /* source addresses expired */
+ kstat_named_t bki_count; /* source addresses known */
+} bridge_ksinst_t;
+
+#define KSLINK_NAMES "recv", "xmit", "drops"
+typedef struct bridge_kslink_s {
+ kstat_named_t bkl_recv; /* packets received */
+ kstat_named_t bkl_xmit; /* packets transmitted */
+ kstat_named_t bkl_drops; /* packets dropped */
+} bridge_kslink_t;
+
+/*
+ * There's one instance structure and one observability mac node for each
+ * bridge. Each open non-DLPI stream gets a 'stream' structure; these are used
+ * for bridge instance allocation and control. Each link on the bridge has a
+ * link structure. Finally, the bridge has a table of learned forwarding
+ * entries, each with a list of outputs, which are either links or TRILL
+ * nicknames.
+ *
+ * The mac structure lives as long as the dls and mac layers are busy. It can
+ * outlive the bridge instance and be picked up again (by name) if the instance
+ * is restarted.
+ */
+
+struct bridge_mac_s;
+struct bridge_stream_s;
+
+typedef struct bridge_inst_s {
+ list_node_t bi_node;
+ dev_t bi_dev;
+ uint_t bi_flags;
+ uint_t bi_refs;
+ uint32_t bi_tablemax;
+ uint_t bi_tshift;
+ krwlock_t bi_rwlock;
+ list_t bi_links;
+ kcondvar_t bi_linkwait;
+ avl_tree_t bi_fwd;
+ kstat_t *bi_ksp;
+ struct bridge_stream_s *bi_control;
+ struct bridge_mac_s *bi_mac;
+ void *bi_trilldata;
+ char bi_name[MAXLINKNAMELEN];
+ bridge_ksinst_t bi_kstats;
+} bridge_inst_t;
+
+#define BIF_SHUTDOWN 0x0001 /* control stream has closed */
+
+/*
+ * The bridge MAC structure has the same lifetime as an observability node.
+ * It's created when a bridge instance is allocated, but is not freed when the
+ * instance is removed because there's no way for a MAC client to guarantee
+ * that all users have disappeared.
+ */
+typedef struct bridge_mac_s {
+ list_node_t bm_node;
+ mac_handle_t bm_mh;
+ bridge_inst_t *bm_inst;
+ uint_t bm_flags; /* BMF_* below */
+ uint_t bm_maxsdu;
+ link_state_t bm_linkstate;
+ char bm_name[MAXLINKNAMELEN];
+} bridge_mac_t;
+
+#define BMF_DLS 0x0001 /* dls monitor node created */
+#define BMF_STARTED 0x0002 /* snoop-like client is present */
+
+/*
+ * Bridge streams are used only for instance allocation and control.
+ */
+typedef struct bridge_stream_s {
+ bridge_inst_t *bs_inst;
+ queue_t *bs_wq; /* write-side queue for stream */
+ minor_t bs_minor;
+ uint_t bs_taskq_cnt; /* taskq references */
+} bridge_stream_t;
+
+/*
+ * These macros are used to set and test link membership in particular VLANs.
+ * This membership is used to determine how to forward packets between
+ * interfaces.
+ */
+
+#define BRIDGE_VLAN_ARR_SIZE \
+ (P2ROUNDUP(VLAN_ID_MAX, NBBY) / NBBY)
+
+#define BRIDGE_VLAN_ISSET(l, v) ((l)->bl_vlans[(v) / NBBY] & \
+ (1 << ((v) % NBBY)))
+
+#define BRIDGE_VLAN_SET(l, v) ((l)->bl_vlans[(v) / NBBY] |= \
+ (1 << ((v) % NBBY)))
+
+#define BRIDGE_VLAN_CLR(l, v) ((l)->bl_vlans[(v) / NBBY] &= \
+ ~(1 << ((v) % NBBY)))
+
+#define BRIDGE_AF_ISSET(l, v) ((l)->bl_afs[(v) / NBBY] & \
+ (1 << ((v) % NBBY)))
+
+/*
+ * This structure represents a link attached to a bridge. VLAN membership
+ * information is kept here; when forwarding, we must look at the membership of
+ * the input link and the output to determine when to update the packet
+ * contents and when to discard.
+ */
+typedef struct bridge_link_s {
+ list_node_t bl_node;
+ uint_t bl_refs;
+ datalink_id_t bl_linkid; /* allocated link ID for bridge */
+ bridge_state_t bl_state; /* blocking/learning/forwarding */
+ uint_t bl_pvid; /* VLAN ID for untagged traffic */
+ uint_t bl_flags; /* BLF_* below */
+ uint_t bl_learns; /* learning limit */
+ mac_handle_t bl_mh;
+ mac_client_handle_t bl_mch;
+ uint32_t bl_margin;
+ uint_t bl_maxsdu;
+ mac_unicast_handle_t bl_mah;
+ mac_notify_handle_t bl_mnh;
+ mac_promisc_handle_t bl_mphp;
+ bridge_inst_t *bl_inst; /* backpointer to bridge instance */
+ kstat_t *bl_ksp;
+ void *bl_trilldata;
+ mblk_t *bl_lfailmp; /* preallocated */
+ link_state_t bl_linkstate;
+ uint_t bl_trillthreads;
+ kcondvar_t bl_trillwait;
+ kmutex_t bl_trilllock;
+ uint8_t bl_local_mac[ETHERADDRL];
+ uint8_t bl_vlans[BRIDGE_VLAN_ARR_SIZE];
+ uint8_t bl_afs[BRIDGE_VLAN_ARR_SIZE];
+ bridge_kslink_t bl_kstats;
+} bridge_link_t;
+
+#define BLF_DELETED 0x0001 /* waiting for last reference to go */
+#define BLF_CLIENT_OPEN 0x0002 /* MAC client opened */
+#define BLF_MARGIN_ADDED 0x0004 /* MAC margin added */
+#define BLF_SET_BRIDGE 0x0008 /* MAC in bridging mode */
+#define BLF_PROM_ADDED 0x0010 /* MAC promiscuous added */
+#define BLF_FREED 0x0020 /* free has begun; debug assertion */
+#define BLF_TRILLACTIVE 0x0040 /* in active forwarding use */
+#define BLF_SDUFAIL 0x0080 /* has mismatched SDU */
+
+/*
+ * This represents a learned forwarding entry. These are generally created and
+ * refreshed on demand as we learn about nodes through source MAC addresses we
+ * see. They're destroyed when they age away. For forwarding, we look up the
+ * destination address in an AVL tree, and the entry found tells us where the
+ * that source must live.
+ */
+typedef struct bridge_fwd_s {
+ avl_node_t bf_node;
+ uchar_t bf_dest[ETHERADDRL];
+ uint16_t bf_trill_nick; /* destination nickname */
+ clock_t bf_lastheard; /* time we last heard from this node */
+ uint_t bf_flags; /* BFF_* below */
+ uint_t bf_refs;
+ uint16_t bf_vlanid; /* VLAN ID for IVL */
+ uint16_t bf_vcnt; /* number of duplicates */
+ uint_t bf_nlinks; /* number of links in bf_links */
+ uint_t bf_maxlinks; /* allocated size of link array */
+ bridge_link_t **bf_links;
+} bridge_fwd_t;
+
+#define BFF_INTREE 0x0001
+#define BFF_LOCALADDR 0x0002 /* address is known to mac layer */
+#define BFF_VLANLOCAL 0x0004 /* set if duplicate for IVL */
+
+/* TRILL linkage */
+typedef void (*trill_recv_pkt_t)(void *, bridge_link_t *, mac_resource_handle_t,
+ mblk_t *, mac_header_info_t *);
+typedef void (*trill_encap_pkt_t)(void *, bridge_link_t *, mac_header_info_t *,
+ mblk_t *, uint16_t);
+typedef void (*trill_br_dstr_t)(void *, bridge_inst_t *);
+typedef void (*trill_ln_dstr_t)(void *, bridge_link_t *);
+
+extern void bridge_trill_register_cb(trill_recv_pkt_t, trill_encap_pkt_t,
+ trill_br_dstr_t, trill_ln_dstr_t);
+extern bridge_inst_t *bridge_trill_brref(const char *, void *);
+extern void bridge_trill_brunref(bridge_inst_t *);
+extern bridge_link_t *bridge_trill_lnref(bridge_inst_t *, datalink_id_t,
+ void *);
+extern void bridge_trill_lnunref(bridge_link_t *);
+extern void bridge_trill_decaps(bridge_link_t *, mblk_t *, uint16_t);
+extern mblk_t *bridge_trill_output(bridge_link_t *, mblk_t *);
+extern void bridge_trill_setvlans(bridge_link_t *, const uint8_t *);
+extern void bridge_trill_flush(bridge_link_t *, uint16_t, boolean_t);
+
+/* Ethernet multicast address; constant stored in bridge module */
+extern const uint8_t all_isis_rbridges[];
+extern const uint8_t bridge_group_address[];
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BRIDGE_IMPL_H */
diff --git a/usr/src/uts/common/net/trill.h b/usr/src/uts/common/net/trill.h
new file mode 100644
index 0000000000..4200557133
--- /dev/null
+++ b/usr/src/uts/common/net/trill.h
@@ -0,0 +1,174 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _NET_TRILL_H
+#define _NET_TRILL_H
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/ethernet.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Various well-known Ethernet addresses used by TRILL */
+#define ALL_RBRIDGES { 0x01, 0x80, 0xC2, 0x00, 0x02, 0x00 }
+#define ALL_ISIS_RBRIDGES { 0x01, 0x80, 0xC2, 0x00, 0x02, 0x01 }
+#define ALL_ESADI_RBRIDGES { 0x01, 0x80, 0xC2, 0x00, 0x02, 0x02 }
+
+#define TRILL_PROTOCOL_VERS 0 /* th_version */
+#define TRILL_DEFAULT_HOPS 21 /* th_hopcount */
+
+/* Nickname range */
+#define RBRIDGE_NICKNAME_MIN 0x0000
+#define RBRIDGE_NICKNAME_MAX 0xFFFF
+
+/* Define well-known nicknames */
+#define RBRIDGE_NICKNAME_NONE RBRIDGE_NICKNAME_MIN
+#define RBRIDGE_NICKNAME_MINRES 0xFFC0
+#define RBRIDGE_NICKNAME_MAXRES (RBRIDGE_NICKNAME_MAX - 1)
+#define RBRIDGE_NICKNAME_UNUSED RBRIDGE_NICKNAME_MAX
+
+#define MIN_RBRIDGE_RANDOM_NICKNAME (RBRIDGE_NICKNAME_NONE + 1)
+#define MAX_RBRIDGE_RANDOM_NICKNAME (RBRIDGE_NICKNAME_MINRES - 1)
+
+/* AF_TRILL IOCTL codes */
+#define TRILL_BASE (0x54524c00) /* base (TRL in hex) */
+#define TRILL_SETNICK (TRILL_BASE + 0) /* trill_node_t */
+#define TRILL_GETNICK (TRILL_BASE + 1) /* uint16_t */
+#define TRILL_ADDNICK (TRILL_BASE + 2) /* trill_node_t */
+#define TRILL_DELNICK (TRILL_BASE + 3) /* uint16_t */
+#define TRILL_DELALL (TRILL_BASE + 4) /* void */
+#define TRILL_HWADDR (TRILL_BASE + 5) /* uint8_t[ETHERADDRL] */
+#define TRILL_TREEROOT (TRILL_BASE + 6) /* uint16_t */
+#define TRILL_NEWBRIDGE (TRILL_BASE + 7) /* char[MAXLINKNAMELEN] */
+#define TRILL_VLANFWDER (TRILL_BASE + 8) /* uint8_t[TRILL_VLANS_ARRSIZE] */
+#define TRILL_DESIGVLAN (TRILL_BASE + 9) /* uint16_t */
+#define TRILL_LISTNICK (TRILL_BASE + 10) /* trill_listnick_t */
+#define TRILL_GETBRIDGE (TRILL_BASE + 11) /* char[MAXLINKNAMELEN] */
+#define TRILL_PORTFLUSH (TRILL_BASE + 12) /* uint16_t */
+#define TRILL_NICKFLUSH (TRILL_BASE + 13) /* uint16_t */
+#define TRILL_GETMTU (TRILL_BASE + 14) /* uint_t * */
+
+typedef struct trill_header {
+#ifdef _BIT_FIELDS_HTOL
+ uint8_t th_version : 2;
+ uint8_t th_reserved : 2;
+ uint8_t th_multidest : 1;
+ uint8_t th_optslen_hi : 3;
+#else
+ uint8_t th_optslen_hi : 3;
+ uint8_t th_multidest : 1;
+ uint8_t th_reserved : 2;
+ uint8_t th_version : 2;
+#endif
+
+#ifdef _BIT_FIELDS_HTOL
+ uint8_t th_optslen_lo : 2;
+ uint8_t th_hopcount : 6;
+#else
+ uint8_t th_hopcount : 6;
+ uint8_t th_optslen_lo : 2;
+#endif
+ uint16_t th_egressnick;
+ uint16_t th_ingressnick;
+} trill_header_t;
+
+#define TRILL_HDR_ALIGN (sizeof (uint16_t))
+
+#define SET_TRILL_OPTS_LEN(hdr_p, val) \
+ do { \
+ (hdr_p)->th_optslen_lo = (val)&0x03; \
+ (hdr_p)->th_optslen_hi = (val)>>2; \
+ _NOTE(CONSTANTCONDITION) \
+ } while (0)
+
+#define GET_TRILL_OPTS_LEN(hdr_p) \
+ ((hdr_p)->th_optslen_lo|((hdr_p)->th_optslen_hi<<2))
+
+/* RBridge nick and tree information (*variable* size) */
+typedef struct trill_nickinfo_s {
+ /* Nickname of the RBridge */
+ uint16_t tni_nick;
+ /* Next-hop SNPA address to reach this RBridge */
+ ether_addr_t tni_adjsnpa;
+ /* Link on our system to use to reach next-hop */
+ datalink_id_t tni_linkid;
+ /* Num of *our* adjacencies on a tree rooted at this RBridge */
+ uint16_t tni_adjcount;
+ /* Num of distribution tree root nicks chosen by this RBridge */
+ uint16_t tni_dtrootcount;
+ /*
+ * Variable size bytes to store adjacency nicks, distribution
+ * tree roots and VLAN filter lists. Adjacency nicks and
+ * distribution tree roots are 16-bit fields.
+ *
+ * Number of VLAN filter lists is equal to tni_adjcount as
+ * the VLAN filter list is one per adjacency in each DT.
+ * VLAN filter list is a 512 byte bitmap with the set of VLANs
+ * that are reachable downstream via the adjacency.
+ */
+} trill_nickinfo_t;
+
+typedef struct trill_listnick_s {
+ uint16_t tln_nick;
+ ether_addr_t tln_nexthop;
+ datalink_id_t tln_linkid;
+ boolean_t tln_ours;
+} trill_listnick_t;
+
+/* Access the adjacency nick list at the end of trill_nickinfo_t */
+#define TNI_ADJNICKSPTR(v) ((uint16_t *)((trill_nickinfo_t *)(v)+1))
+#define TNI_ADJNICK(v, n) (TNI_ADJNICKSPTR(v)[(n)])
+
+/* Access the DT root nick list in trill_nickinfo_t after adjacency nicks */
+#define TNI_DTROOTNICKSPTR(v) (TNI_ADJNICKSPTR(v)+(v)->tni_adjcount)
+#define TNI_DTROOTNICK(v, n) (TNI_DTROOTNICKSPTR(v)[(n)])
+
+/* Access the VLAN filter list in trill_nickinfo_t after DT Roots */
+#define TNI_VLANFILTERSPTR(v) (TNI_DTROOTNICKSPTR(v)+(v)->tni_dtrootcount)
+#define TNI_VLANFILTERMAP(v, n) \
+ (((uint8_t *)(TNI_VLANFILTERSPTR(v)))+((n)*((1<<12)/NBBY)))
+
+#define TNI_TOTALSIZE(v) (sizeof (trill_nickinfo_t) + \
+ (sizeof (uint16_t) * (v)->tni_adjcount) + \
+ (sizeof (uint16_t) * (v)->tni_dtrootcount) + \
+ (((1<<12)/NBBY) * (v)->tni_adjcount))
+
+/*
+ * This is a special value used in the sockaddr_dl "selector" field to denote
+ * that the packet represents a Bridging PDU. The core STP instance is not
+ * defined on a VLAN, so this overload is safe. All other selector values are
+ * used for TRILL IS-IS PDUs to indicate VLAN ID.
+ */
+#define TRILL_TCI_BPDU 0xFFFF
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _NET_TRILL_H */