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 *);