Print this page
Factor out fixed/1-1 processing from vxlnat_vxlan_one(), paving way for
future processing types.
Initial definitions of NAT flows.
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/inet/vxlnat_impl.h
+++ new/usr/src/uts/common/inet/vxlnat_impl.h
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright 2018, Joyent, Inc.
14 14 */
15 15
16 16 #ifndef _INET_VXLNAT_IMPL_H
17 17 #define _INET_VXLNAT_IMPL_H
18 18
19 19 #include <inet/vxlnat.h>
20 20 #include <inet/ip.h>
21 21 #include <inet/ip6.h>
22 22 #include <inet/ip_ire.h>
23 23 #include <sys/clock_impl.h>
24 24 #include <sys/avl.h>
25 25 #include <sys/uio.h>
26 26 #include <sys/list.h>
27 27 #include <sys/byteorder.h>
28 28 #include <sys/vxlan.h>
29 29
30 30 /*
31 31 * XXX KEBE ASKS --> do we assume port IPPORT_VXLAN all the time?
32 32 * IF NOT, then we need to add ports to various things here that deal
33 33 * with the underlay network.
34 34 *
35 35 * NOTE: All reference counts *include* table/tree/list/whatever internment.
36 36 * Once an entry is removed, *_REFRELE() must be invoked, and it may or may
37 37 * not free something.
38 38 */
39 39
40 40 #ifdef __cplusplus
41 41 extern "C" {
42 42 #endif
43 43
44 44 /*
45 45 * NAT RULES. Instantiated per-vnet, write-once/read-only entries,
46 46 * linkage/entries protected by "rule lock" outside this structure.
47 47 */
48 48 typedef struct vxlnat_rule_s {
49 49 list_node_t vxnr_link;
50 50 /* refheld link, or if NULL, this rule is "condemned" and no good. */
51 51 struct vxlnat_vnet_s *vxnr_vnet;
52 52 in6_addr_t vxnr_myaddr;
53 53 in6_addr_t vxnr_pubaddr;
54 54 uint8_t vxnr_myether[ETHERADDRL];
55 55 uint16_t vxnr_vlanid; /* Fabrics use this too. */
56 56 uint32_t vxnr_refcount;
57 57 uint8_t vxnr_prefix;
58 58 } vxlnat_rule_t;
59 59 #define VXNR_REFHOLD(vxnr) { \
60 60 atomic_inc_32(&(vxnr)->vxnr_refcount); \
61 61 ASSERT((vxnr)->vxnr_refcount > 0); \
|
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
62 62 }
63 63 #define VXNR_REFRELE(vxnr) { \
64 64 ASSERT((vxnr)->vxnr_refcount > 0); \
65 65 membar_exit(); \
66 66 if (atomic_dec_32_nv(&(vxnr)->vxnr_refcount) == 0) \
67 67 vxlnat_rule_free(vxnr); \
68 68 }
69 69 extern void vxlnat_rule_free(vxlnat_rule_t *);
70 70
71 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 +/*
72 102 * 1-1 IP mapping.
73 103 */
74 104 typedef struct vxlnat_fixed_s {
75 105 avl_node_t vxnf_treenode;
76 - in6_addr_t vxnf_addr; /* XXX KEBE ASKS - must it match to a rule? */
106 + in6_addr_t vxnf_addr; /* For now it needn't match to a rule. */
77 107 in6_addr_t vxnf_pubaddr; /* External IP. */
78 108 struct vxlnat_vnet_s *vxnf_vnet;
79 - ire_t *vxnf_ire; /* Should be a local IRE from the ftable. */
109 + ire_t *vxnf_ire; /* Should be an IRE_LOCAL from the ftable. */
80 110 struct vxlnat_remote_s *vxnf_remote;
81 111 uint8_t vxnf_myether[ETHERADDRL];
82 112 uint16_t vxnf_vlanid; /* Stored in network order for quick xmit. */
83 113 uint32_t vxnf_refcount;
84 114 boolean_t vxnf_clear_router; /* XXX KEBE SAYS CHEESY HACK */
85 115 } vxlnat_fixed_t;
86 116 #define VXNF_REFHOLD(vxnf) { \
87 117 atomic_inc_32(&(vxnf)->vxnf_refcount); \
88 118 ASSERT((vxnf)->vxnf_refcount > 0); \
89 119 }
90 120 #define VXNF_REFRELE(vxnf) { \
91 121 ASSERT((vxnf)->vxnf_refcount > 0); \
92 122 membar_exit(); \
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
93 123 if (atomic_dec_32_nv(&(vxnf)->vxnf_refcount) == 0) \
94 124 vxlnat_fixed_free(vxnf); \
95 125 }
96 126 extern void vxlnat_fixed_free(vxlnat_fixed_t *);
97 127
98 128 /*
99 129 * REMOTE VXLAN destinations.
100 130 */
101 131 typedef struct vxlnat_remote_s {
102 132 avl_node_t vxnrem_treenode;
103 - in6_addr_t vxnrem_addr; /* Same prefix as one in rule. */
133 + in6_addr_t vxnrem_addr; /* Same prefix as one in rule, or fixed addr. */
104 134 in6_addr_t vxnrem_uaddr; /* Underlay VXLAN destination. */
105 135 struct vxlnat_vnet_s *vxnrem_vnet; /* Reference-held. */
106 136 uint32_t vxnrem_refcount;
107 137 uint8_t vxnrem_ether[ETHERADDRL];
108 138 uint16_t vxnrem_vlan;
109 139 /*
110 140 * XXX KEBE SAYS put some lifetime/usetime/etc. here
111 141 * so we don't keep too many of these. Either that, or maybe
112 142 * convert to a qqcache or (patents expiring) ARC.
113 143 */
114 144 } vxlnat_remote_t;
115 145 #define VXNREM_REFHOLD(vxnrem) { \
116 146 atomic_inc_32(&(vxnrem)->vxnrem_refcount); \
117 147 ASSERT((vxnrem)->vxnrem_refcount > 0); \
118 148 }
119 149 #define VXNREM_REFRELE(vxnrem) { \
120 150 ASSERT((vxnrem)->vxnrem_refcount > 0); \
121 151 membar_exit(); \
122 152 if (atomic_dec_32_nv(&(vxnrem)->vxnrem_refcount) == 0) \
123 153 vxlnat_remote_free(vxnrem); \
124 154 }
125 155 extern void vxlnat_remote_free(vxlnat_remote_t *);
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
126 156
127 157 /*
128 158 * per-vnetid overarching structure. AVL tree keyed by vnetid.
129 159 * NOTE: Could be split into vnetid-hashed buckets to split any
130 160 * locks.
131 161 */
132 162 typedef struct vxlnat_vnet_s {
133 163 avl_node_t vxnv_treenode;
134 164 /*
135 165 * 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?!
166 + * Will map to an IRE_LOCAL in IP.
138 167 */
139 168 krwlock_t vxnv_fixed_lock;
140 169 avl_tree_t vxnv_fixed_ips;
170 +
141 171 /*
142 172 * NAT flows. (2nd lookup for an in-to-out packet.)
143 173 * These are also conn_ts with outer-packet fields for out-to-in
144 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.
145 178 */
146 - krwlock_t vxnv_flow_lock;
147 - avl_tree_t vxnv_flows;
179 + krwlock_t vxnv_flowv4_lock;
180 + avl_tree_t vxnv_flows_v4;
181 +
148 182 /* NAT rules. (3rd lookup for an in-to-out packet.) */
149 183 kmutex_t vxnv_rule_lock;
150 184 list_t vxnv_rules;
185 +
151 186 /*
152 187 * Internal-network remote-nodes. (only lookup for out-to-in packet.)
153 188 * Entries here are also refheld by 1-1s or NAT flows.
154 189 */
155 190 kmutex_t vxnv_remote_lock;
156 191 avl_tree_t vxnv_remotes;
157 192
158 193 uint32_t vxnv_refcount;
159 194 uint32_t vxnv_vnetid; /* Wire byteorder for less swapping on LE */
160 195 } vxlnat_vnet_t;
161 196 #define VXNV_REFHOLD(vxnv) { \
162 197 atomic_inc_32(&(vxnv)->vxnv_refcount); \
163 198 ASSERT((vxnv)->vxnv_refcount > 0); \
164 199 }
165 200 #define VXNV_REFRELE(vxnv) { \
166 201 ASSERT((vxnv)->vxnv_refcount > 0); \
167 202 membar_exit(); \
168 203 if (atomic_dec_32_nv(&(vxnv)->vxnv_refcount) == 0) \
169 204 vxlnat_vnet_free(vxnv); \
170 205 }
171 206 extern void vxlnat_vnet_free(vxlnat_vnet_t *);
172 207
173 208 /*
174 209 * Endian-independent macros for rapid off-wire header reading. i.e. avoid
175 210 * [nh]to[hn]*()
176 211 *
177 212 * VXLAN_ID_WIRE32(id) ==> Zero-out "reserved" bits, preserve wire-order
178 213 * and position of vnetid.
179 214 * VXLAN_FLAGS_WIRE32(vni) ==> Zero-out reserved bits, preserve wire-order
180 215 * and position of flags.
181 216 * VXLAN_F_VDI_WIRE ==> VXLAN_F_VDI, but w/o needing to swap.
182 217 *
183 218 * ALSO: HTON/NTOH for kernel-makes-right interactions with userland, which
184 219 * means shifting actual ID to/from low-24-bits of 32-bit word.
185 220 * VXLAN_ID_HTON(id)
186 221 * VXLAN_ID_NTOH(id)
187 222 *
188 223 * XXX KEBE ASKS ==> If not confusing to folks, move into sys/vxlan.h and
189 224 * have overlay's VXLAN encap adopt them?
190 225 */
191 226 #ifdef _BIG_ENDIAN
192 227 #define VXLAN_ID_WIRE32(id) ((id) & 0xFFFFFF00)
193 228 #define VXLAN_F_VDI_WIRE VXLAN_F_VDI
194 229 /* XXX KEBE ASKS, do masking here? */
195 230 #define VXLAN_ID_HTON(id) ((id) << VXLAN_ID_SHIFT)
196 231 #define VXLAN_ID_NTOH(id) ((id) >> VXLAN_ID_SHIFT)
197 232 #else /* i.e. _LITTLE_ENDIAN */
198 233 #define VXLAN_ID_WIRE32(id) ((id) & 0xFFFFFF)
199 234 #define VXLAN_F_VDI_WIRE 0x08
200 235 #define VXLAN_ID_HTON(id) htonl((id) << VXLAN_ID_SHIFT)
201 236 #define VXLAN_ID_NTOH(id) (ntohl(id) >> VXLAN_ID_SHIFT)
202 237 #endif /* _BIG_ENDIAN */
203 238 #define VXLAN_FLAGS_WIRE32(flags) ((flags) & VXLAN_F_VDI_WIRE)
204 239
205 240 extern kmutex_t vxlnat_mutex;
206 241 extern netstack_t *vxlnat_netstack;
207 242 extern int vxlnat_command(vxn_msg_t *);
208 243 extern int vxlnat_read_dump(struct uio *);
209 244 extern int vxlnat_vxlan_addr(in6_addr_t *);
210 245 extern void vxlnat_closesock(void);
211 246 extern void vxlnat_state_init(void);
212 247 extern void vxlnat_state_fini(void);
213 248
214 249 extern void vxlnat_public_init(void);
215 250 extern void vxlnat_public_fini(void);
216 251 extern boolean_t vxlnat_public_hold(in6_addr_t *, boolean_t);
217 252 extern void vxlnat_public_rele(in6_addr_t *);
218 253
219 254 extern int vxlnat_tree_plus_in6_cmp(const void *, const void *);
220 255
221 256 /* ire_recvfn & ire_sendfn functions for 1-1/fixed maps. */
222 257 extern void vxlnat_fixed_ire_recv_v4(ire_t *, mblk_t *, void *,
223 258 ip_recv_attr_t *);
224 259 extern void vxlnat_fixed_ire_recv_v6(ire_t *, mblk_t *, void *,
225 260 ip_recv_attr_t *);
226 261 extern int vxlnat_fixed_ire_send_v4(ire_t *, mblk_t *, void *,
227 262 ip_xmit_attr_t *, uint32_t *);
228 263 extern int vxlnat_fixed_ire_send_v6(ire_t *, mblk_t *, void *,
229 264 ip_xmit_attr_t *, uint32_t *);
230 265
231 266
232 267 extern vxlnat_vnet_t *vxlnat_get_vnet(uint32_t, boolean_t);
233 268
234 269 #ifdef __cplusplus
235 270 }
236 271 #endif
237 272
238 273 #endif /* _INET_VXLNAT_IMPL_H */
|
↓ open down ↓ |
78 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX