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 }
|