Print this page
Factor out fixed/1-1 processing from vxlnat_vxlan_one(), paving way for
future processing types.
Initial definitions of NAT flows.


  52         in6_addr_t vxnr_myaddr;
  53         in6_addr_t vxnr_pubaddr;
  54         uint8_t vxnr_myether[ETHERADDRL];
  55         uint16_t vxnr_vlanid;   /* Fabrics use this too. */
  56         uint32_t vxnr_refcount;
  57         uint8_t vxnr_prefix;
  58 } vxlnat_rule_t;
  59 #define VXNR_REFHOLD(vxnr) {                    \
  60         atomic_inc_32(&(vxnr)->vxnr_refcount);   \
  61         ASSERT((vxnr)->vxnr_refcount > 0);        \
  62 }
  63 #define VXNR_REFRELE(vxnr) {                                    \
  64         ASSERT((vxnr)->vxnr_refcount > 0);                        \
  65         membar_exit();                                          \
  66         if (atomic_dec_32_nv(&(vxnr)->vxnr_refcount) == 0)       \
  67                 vxlnat_rule_free(vxnr);                         \
  68 }
  69 extern void vxlnat_rule_free(vxlnat_rule_t *);
  70 
  71 /*






























  72  * 1-1 IP mapping.
  73  */
  74 typedef struct vxlnat_fixed_s {
  75         avl_node_t vxnf_treenode;
  76         in6_addr_t vxnf_addr;   /* XXX KEBE ASKS - must it match to a rule? */
  77         in6_addr_t vxnf_pubaddr; /* External IP. */
  78         struct vxlnat_vnet_s *vxnf_vnet;
  79         ire_t *vxnf_ire;        /* Should be a local IRE from the ftable. */
  80         struct vxlnat_remote_s *vxnf_remote;
  81         uint8_t vxnf_myether[ETHERADDRL];
  82         uint16_t vxnf_vlanid;   /* Stored in network order for quick xmit. */
  83         uint32_t vxnf_refcount;
  84         boolean_t vxnf_clear_router;    /* XXX KEBE SAYS CHEESY HACK */
  85 } vxlnat_fixed_t;
  86 #define VXNF_REFHOLD(vxnf) {                    \
  87         atomic_inc_32(&(vxnf)->vxnf_refcount);   \
  88         ASSERT((vxnf)->vxnf_refcount > 0);        \
  89 }
  90 #define VXNF_REFRELE(vxnf) {                                    \
  91         ASSERT((vxnf)->vxnf_refcount > 0);                        \
  92         membar_exit();                                          \
  93         if (atomic_dec_32_nv(&(vxnf)->vxnf_refcount) == 0)       \
  94                 vxlnat_fixed_free(vxnf);                        \
  95 }
  96 extern void vxlnat_fixed_free(vxlnat_fixed_t *);
  97 
  98 /*
  99  * REMOTE VXLAN destinations.
 100  */
 101 typedef struct vxlnat_remote_s {
 102         avl_node_t vxnrem_treenode;
 103         in6_addr_t vxnrem_addr; /* Same prefix as one in rule. */
 104         in6_addr_t vxnrem_uaddr; /* Underlay VXLAN destination. */
 105         struct vxlnat_vnet_s *vxnrem_vnet;      /* Reference-held. */
 106         uint32_t vxnrem_refcount;
 107         uint8_t vxnrem_ether[ETHERADDRL];
 108         uint16_t vxnrem_vlan;
 109         /*
 110          * XXX KEBE SAYS put some lifetime/usetime/etc. here
 111          * so we don't keep too many of these.  Either that, or maybe
 112          * convert to a qqcache or (patents expiring) ARC.
 113          */
 114 } vxlnat_remote_t;
 115 #define VXNREM_REFHOLD(vxnrem) {                        \
 116         atomic_inc_32(&(vxnrem)->vxnrem_refcount);       \
 117         ASSERT((vxnrem)->vxnrem_refcount > 0);            \
 118 }
 119 #define VXNREM_REFRELE(vxnrem) {                                \
 120         ASSERT((vxnrem)->vxnrem_refcount > 0);                    \
 121         membar_exit();                                          \
 122         if (atomic_dec_32_nv(&(vxnrem)->vxnrem_refcount) == 0)   \
 123                 vxlnat_remote_free(vxnrem);                     \
 124 }
 125 extern void vxlnat_remote_free(vxlnat_remote_t *);
 126 
 127 /*
 128  * per-vnetid overarching structure.  AVL tree keyed by vnetid.
 129  * NOTE:  Could be split into vnetid-hashed buckets to split any
 130  * locks.
 131  */
 132 typedef struct vxlnat_vnet_s {
 133         avl_node_t vxnv_treenode;
 134         /*
 135          * 1-1 IP mappings. (1st lookup for an in-to-out packet.)
 136          * Will map to SOMETHING in IP.
 137          * XXX KEBE ASKS - conn_t or something else TBD?!
 138          */
 139         krwlock_t vxnv_fixed_lock;
 140         avl_tree_t vxnv_fixed_ips;

 141         /*
 142          * NAT flows. (2nd lookup for an in-to-out packet.)
 143          * These are also conn_ts with outer-packet fields for out-to-in
 144          * matches against a conn_t.



 145          */
 146         krwlock_t vxnv_flow_lock;
 147         avl_tree_t vxnv_flows;

 148         /* NAT rules. (3rd lookup for an in-to-out packet.) */
 149         kmutex_t vxnv_rule_lock;
 150         list_t vxnv_rules;

 151         /*
 152          * Internal-network remote-nodes. (only lookup for out-to-in packet.)
 153          * Entries here are also refheld by 1-1s or NAT flows.
 154          */
 155         kmutex_t vxnv_remote_lock;
 156         avl_tree_t vxnv_remotes;
 157 
 158         uint32_t vxnv_refcount;
 159         uint32_t vxnv_vnetid;   /* Wire byteorder for less swapping on LE */
 160 } vxlnat_vnet_t;
 161 #define VXNV_REFHOLD(vxnv) {                    \
 162         atomic_inc_32(&(vxnv)->vxnv_refcount);   \
 163         ASSERT((vxnv)->vxnv_refcount > 0);        \
 164 }
 165 #define VXNV_REFRELE(vxnv) {                                    \
 166         ASSERT((vxnv)->vxnv_refcount > 0);                        \
 167         membar_exit();                                          \
 168         if (atomic_dec_32_nv(&(vxnv)->vxnv_refcount) == 0)       \
 169                 vxlnat_vnet_free(vxnv);                         \
 170 }




  52         in6_addr_t vxnr_myaddr;
  53         in6_addr_t vxnr_pubaddr;
  54         uint8_t vxnr_myether[ETHERADDRL];
  55         uint16_t vxnr_vlanid;   /* Fabrics use this too. */
  56         uint32_t vxnr_refcount;
  57         uint8_t vxnr_prefix;
  58 } vxlnat_rule_t;
  59 #define VXNR_REFHOLD(vxnr) {                    \
  60         atomic_inc_32(&(vxnr)->vxnr_refcount);   \
  61         ASSERT((vxnr)->vxnr_refcount > 0);        \
  62 }
  63 #define VXNR_REFRELE(vxnr) {                                    \
  64         ASSERT((vxnr)->vxnr_refcount > 0);                        \
  65         membar_exit();                                          \
  66         if (atomic_dec_32_nv(&(vxnr)->vxnr_refcount) == 0)       \
  67                 vxlnat_rule_free(vxnr);                         \
  68 }
  69 extern void vxlnat_rule_free(vxlnat_rule_t *);
  70 
  71 /*
  72  * NAT FLOWS.  These are per-vnet, and keyed/searched by:
  73  * <inner-IP-source,IP-dest,inner-source-port,dest-port,protocol>.
  74  * They will be tied-to/part-of
  75  */
  76 typedef struct vxlnat_flow_s {
  77         avl_node_t vxnfl_treenode;
  78         /*
  79          * I'm guessing that dst varies more than src.  Also
  80          * the plan is for the comparitor function to bcmp() both
  81          * of these as one call for IPv6 (if we ever get to that..).
  82          */
  83         in6_addr_t vxnfl_dst;
  84         in6_addr_t vxnfl_src;   /* INNER source address. */
  85         uint32_t vxnfl_ports;
  86         uint8_t vxnfl_protocol;
  87         uint8_t vxnfl_isv4 : 1, /* Will save us 12 bytes of compares... */
  88                 vxlfl_reserved1 : 7;
  89         conn_t *vxnfl_connp;    /* Question - embed instead? */
  90         vxlnat_rule_t *vxnfl_rule; /* Refhold to rule that generated me. */
  91 } vxlnat_flow_t;
  92 /* Exploit endianisms, maintain network order... */
  93 #ifdef _BIG_ENDIAN
  94 #define VXNFL_SPORT(ports) (uint16_t)((ports) >> 16) /* Unsigned all around. */
  95 #define VXNFL_DPORT(ports) ((ports) & 0xFFFF)
  96 #else
  97 #define VXNFL_SPORT(ports) ((ports) & 0xFFFF)
  98 #define VXNFL_DPORT(ports) (uint16_t)((ports) >> 16) /* Unsigned all around. */
  99 #endif
 100 
 101 /*
 102  * 1-1 IP mapping.
 103  */
 104 typedef struct vxlnat_fixed_s {
 105         avl_node_t vxnf_treenode;
 106         in6_addr_t vxnf_addr;   /* For now it needn't match to a rule. */
 107         in6_addr_t vxnf_pubaddr; /* External IP. */
 108         struct vxlnat_vnet_s *vxnf_vnet;
 109         ire_t *vxnf_ire;        /* Should be an IRE_LOCAL from the ftable. */
 110         struct vxlnat_remote_s *vxnf_remote;
 111         uint8_t vxnf_myether[ETHERADDRL];
 112         uint16_t vxnf_vlanid;   /* Stored in network order for quick xmit. */
 113         uint32_t vxnf_refcount;
 114         boolean_t vxnf_clear_router;    /* XXX KEBE SAYS CHEESY HACK */
 115 } vxlnat_fixed_t;
 116 #define VXNF_REFHOLD(vxnf) {                    \
 117         atomic_inc_32(&(vxnf)->vxnf_refcount);   \
 118         ASSERT((vxnf)->vxnf_refcount > 0);        \
 119 }
 120 #define VXNF_REFRELE(vxnf) {                                    \
 121         ASSERT((vxnf)->vxnf_refcount > 0);                        \
 122         membar_exit();                                          \
 123         if (atomic_dec_32_nv(&(vxnf)->vxnf_refcount) == 0)       \
 124                 vxlnat_fixed_free(vxnf);                        \
 125 }
 126 extern void vxlnat_fixed_free(vxlnat_fixed_t *);
 127 
 128 /*
 129  * REMOTE VXLAN destinations.
 130  */
 131 typedef struct vxlnat_remote_s {
 132         avl_node_t vxnrem_treenode;
 133         in6_addr_t vxnrem_addr; /* Same prefix as one in rule, or fixed addr. */
 134         in6_addr_t vxnrem_uaddr; /* Underlay VXLAN destination. */
 135         struct vxlnat_vnet_s *vxnrem_vnet;      /* Reference-held. */
 136         uint32_t vxnrem_refcount;
 137         uint8_t vxnrem_ether[ETHERADDRL];
 138         uint16_t vxnrem_vlan;
 139         /*
 140          * XXX KEBE SAYS put some lifetime/usetime/etc. here
 141          * so we don't keep too many of these.  Either that, or maybe
 142          * convert to a qqcache or (patents expiring) ARC.
 143          */
 144 } vxlnat_remote_t;
 145 #define VXNREM_REFHOLD(vxnrem) {                        \
 146         atomic_inc_32(&(vxnrem)->vxnrem_refcount);       \
 147         ASSERT((vxnrem)->vxnrem_refcount > 0);            \
 148 }
 149 #define VXNREM_REFRELE(vxnrem) {                                \
 150         ASSERT((vxnrem)->vxnrem_refcount > 0);                    \
 151         membar_exit();                                          \
 152         if (atomic_dec_32_nv(&(vxnrem)->vxnrem_refcount) == 0)   \
 153                 vxlnat_remote_free(vxnrem);                     \
 154 }
 155 extern void vxlnat_remote_free(vxlnat_remote_t *);
 156 
 157 /*
 158  * per-vnetid overarching structure.  AVL tree keyed by vnetid.
 159  * NOTE:  Could be split into vnetid-hashed buckets to split any
 160  * locks.
 161  */
 162 typedef struct vxlnat_vnet_s {
 163         avl_node_t vxnv_treenode;
 164         /*
 165          * 1-1 IP mappings. (1st lookup for an in-to-out packet.)
 166          * Will map to an IRE_LOCAL in IP.

 167          */
 168         krwlock_t vxnv_fixed_lock;
 169         avl_tree_t vxnv_fixed_ips;
 170 
 171         /*
 172          * NAT flows. (2nd lookup for an in-to-out packet.)
 173          * These are also conn_ts with outer-packet fields for out-to-in
 174          * matches against a conn_t.
 175          *
 176          * NOTE: We're going to keep a separate tree for inner IPv6 NAT, if
 177          * we ever need it.
 178          */
 179         krwlock_t vxnv_flowv4_lock;
 180         avl_tree_t vxnv_flows_v4;
 181 
 182         /* NAT rules. (3rd lookup for an in-to-out packet.) */
 183         kmutex_t vxnv_rule_lock;
 184         list_t vxnv_rules;
 185 
 186         /*
 187          * Internal-network remote-nodes. (only lookup for out-to-in packet.)
 188          * Entries here are also refheld by 1-1s or NAT flows.
 189          */
 190         kmutex_t vxnv_remote_lock;
 191         avl_tree_t vxnv_remotes;
 192 
 193         uint32_t vxnv_refcount;
 194         uint32_t vxnv_vnetid;   /* Wire byteorder for less swapping on LE */
 195 } vxlnat_vnet_t;
 196 #define VXNV_REFHOLD(vxnv) {                    \
 197         atomic_inc_32(&(vxnv)->vxnv_refcount);   \
 198         ASSERT((vxnv)->vxnv_refcount > 0);        \
 199 }
 200 #define VXNV_REFRELE(vxnv) {                                    \
 201         ASSERT((vxnv)->vxnv_refcount > 0);                        \
 202         membar_exit();                                          \
 203         if (atomic_dec_32_nv(&(vxnv)->vxnv_refcount) == 0)       \
 204                 vxlnat_vnet_free(vxnv);                         \
 205 }