Print this page
Overlay fabric router
@@ -22,18 +22,20 @@
#include <sys/overlay.h>
#include <sys/overlay_common.h>
#include <sys/overlay_plugin.h>
#include <sys/overlay_target.h>
+#include <sys/overlay_router.h>
#include <sys/ksynch.h>
#include <sys/list.h>
#include <sys/avl.h>
#include <sys/ksocket.h>
#include <sys/socket.h>
#include <sys/refhash.h>
#include <sys/ethernet.h>
#include <sys/list.h>
+#include <sys/atomic.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -82,43 +84,21 @@
overlay_target_point_t ott_point;
struct overlay_target_dyn {
refhash_t *ott_dhash;
refhash_t *ott_l3dhash;
avl_tree_t ott_tree;
- /* XXX: Do we actually need a tree sorted by VL3? */
avl_tree_t ott_l3tree;
} ott_dyn;
} ott_u;
} overlay_target_t;
-/*
- * Initially at least, we represent a group of fabrics that are attached to
- * each other as a circular linked list. Within an overlay_dev_t, we then
- * maintain a list of pointers into these lists for each fabric that's
- * present locally on the CN as we learn them:
- *
- */
-typedef struct overlay_fabric_attach {
- struct overlay_fabric_attach *ofa_next;
- struct in6_addr ofa_addr;
- uint32_t ofa_dcid;
- uint16_t ofa_vlan;
- uint8_t ofa_prefixlen;
- uint8_t ofa_pad;
-} overlay_fabric_attach_t;
+typedef struct overlay_router {
+ kmutex_t otr_lock;
+ avl_tree_t otr_tree; /* RW tree of all fabrics */
+ list_t otr_tables;
+} overlay_router_t;
-/*
- * Since we have two different refhashes for an overlay_target_entry_t
- * (VL2 aka MAC address and VL3 aka IP address), we want to maintain
- * the refcount in only one place. We elect to use the ott_dhash
- * refhash to do so.
- */
-#define OVERLAY_TARGET_ENTRY_HOLD(tgt, e) \
- refhash_hold((tgt)->ott_u.ott_dyn.ott_dhash, e)
-#define OVERLAY_TARGET_ENTRY_RELE(tgt, e) \
- refhash_rele((tgt)->ott_u.ott_dyn.ott_dhash, e)
-
typedef enum overlay_dev_flag {
OVERLAY_F_ACTIVATED = 0x01, /* Activate ioctl completed */
OVERLAY_F_IN_MUX = 0x02, /* Currently in a mux */
OVERLAY_F_IN_TX = 0x04, /* Currently doing tx */
OVERLAY_F_IN_RX = 0x08, /* Currently doing rx */
@@ -145,43 +125,73 @@
uint_t odd_txcount; /* protected by odd_lock */
overlay_mux_t *odd_mux; /* protected by odd_lock */
uint64_t odd_vid; /* RO if active else odd_lock */
avl_node_t odd_muxnode; /* managed by mux */
overlay_target_t *odd_target; /* See big theory statement */
- overlay_fabric_attach_t **odd_fattach; /* protected by odd_lock */
+ overlay_router_t *odd_router;
uint32_t odd_dcid; /* RO if active else odd_lock */
uint8_t odd_macaddr[ETHERADDRL]; /* RO same as odd_dcid */
char odd_fmamsg[OVERLAY_STATUS_BUFLEN]; /* odd_lock */
} overlay_dev_t;
+struct overlay_route_table;
+typedef struct overlay_route_table overlay_route_table_t;
+
+typedef struct overlay_fabric_entry {
+ avl_node_t ofe_avllink;
+ overlay_dev_t *ofe_odd;
+ overlay_route_table_t *ofe_route_table;
+ volatile uint32_t ofe_refcnt;
+ overlay_fabric_t ofe_fabric;
+ list_t ofe_targ_list;
+} overlay_fabric_entry_t;
+#define OVERLAY_FAB_ENTRY_REFHOLD(ofe) atomic_inc_32(&(ofe)->ofe_refcnt)
+#define OVERLAY_FAB_ENTRY_REFRELE(ofe) \
+ (void) ((atomic_dec_32_nv(&(ofe)->ofe_refcnt) != 0) || \
+ (overlay_fabric_entry_free(ofe), 0))
+
+struct overlay_route_table {
+ list_node_t ort_link;
+ overlay_fabric_entry_t **ort_dest;
+ size_t ort_nalloc;
+};
+
typedef enum overlay_target_entry_flags {
OVERLAY_ENTRY_F_PENDING = 0x01, /* lookup in progress */
OVERLAY_ENTRY_F_VALID = 0x02, /* entry is currently valid */
OVERLAY_ENTRY_F_DROP = 0x04, /* always drop target */
- OVERLAY_ENTRY_F_VALID_MASK = 0x06
+ OVERLAY_ENTRY_F_ROUTER = 0x08, /* entry is for router */
+ OVERLAY_ENTRY_F_VALID_MASK = 0x0e,
+ OVERLAY_ENTRY_F_VL3_PENDING = 0x10,
+ OVERLAY_ENTRY_F_VL3_VALID = 0x20,
} overlay_target_entry_flags_t;
typedef struct overlay_target_entry {
kmutex_t ote_lock;
refhash_link_t ote_reflink; /* hashtable link */
refhash_link_t ote_l3_reflink; /* IP hashtable link */
avl_node_t ote_avllink; /* iteration link */
avl_node_t ote_l3_avllink; /* IP iteration link */
list_node_t ote_qlink;
+ list_node_t ote_fablink;
+ volatile uint32_t ote_refcnt;
overlay_target_entry_flags_t ote_flags; /* RW: state flags */
- uint32_t ote_dcid;
- uint16_t ote_vlan; /* RO: VL3 vlan id */
- uint8_t ote_addr[ETHERADDRL]; /* RO: mac addr */
struct in6_addr ote_ip; /* RO: VL3 IP */
+ uint8_t ote_addr[ETHERADDRL]; /* RO: mac addr */
overlay_target_t *ote_ott; /* RO */
overlay_dev_t *ote_odd; /* RO */
+ overlay_fabric_entry_t *ote_fab; /* RO */
overlay_target_point_t ote_dest; /* RW: destination */
mblk_t *ote_chead; /* RW: blocked mb chain head */
mblk_t *ote_ctail; /* RW: blocked mb chain tail */
size_t ote_mbsize; /* RW: outstanding mblk size */
hrtime_t ote_vtime; /* RW: valid timestamp */
} overlay_target_entry_t;
+#define OVERLAY_TARG_ENTRY_REFHOLD(ote) atomic_inc_32(&(ote)->ote_refcnt)
+#define OVERLAY_TARG_ENTRY_REFRELE(ote) \
+ (void) ((atomic_dec_32_nv(&(ote)->ote_refcnt) != 0) || \
+ (overlay_target_entry_dtor(ote), 0))
#define OVERLAY_CTL "overlay"
extern dev_info_t *overlay_dip;
@@ -216,19 +226,27 @@
extern int overlay_target_busy(void);
extern int overlay_target_open(dev_t *, int, int, cred_t *);
extern int overlay_target_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
extern int overlay_target_close(dev_t, int, int, cred_t *);
extern void overlay_target_free(overlay_dev_t *);
+extern void overlay_target_entry_dtor(void *);
#define OVERLAY_TARGET_OK 0
#define OVERLAY_TARGET_DROP 1
#define OVERLAY_TARGET_ASYNC 2
extern int overlay_target_lookup(overlay_dev_t *, mblk_t *, struct sockaddr *,
- socklen_t *);
+ socklen_t *, uint64_t *);
+extern void overlay_target_queue(overlay_target_entry_t *);
extern void overlay_target_quiesce(overlay_target_t *);
extern void overlay_target_fini(void);
+extern int overlay_route_lookup(overlay_dev_t *, mblk_t *,
+ const mac_header_info_t *, struct sockaddr *, socklen_t *, uint64_t *);
+extern int overlay_mblk_vl3ip(mblk_t *, struct in6_addr *, struct in6_addr *);
+extern int overlay_router_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
+extern int overlay_fabric_avl(const void *, const void *);
+
extern void overlay_fm_init(void);
extern void overlay_fm_fini(void);
extern void overlay_fm_degrade(overlay_dev_t *, const char *);
extern void overlay_fm_restore(overlay_dev_t *);