1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2018 Joyent, Inc.
*/
#ifndef _OVERLAY_TARGET_H
#define _OVERLAY_TARGET_H
/*
* Overlay device varpd ioctl interface (/dev/overlay)
*/
#include <sys/types.h>
#include <sys/ethernet.h>
#include <netinet/in.h>
#include <sys/overlay_common.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
* The overlay_target_point_t structure represents the destination where
* encapsulated frames are sent. Currently supported virtualization protocols
* (i.e. vxlan) only use otp_ip and otp_port, but other methods might use
* a L2 address instead of an L3 address to represent a destination.
*/
typedef struct overlay_target_point {
struct in6_addr otp_ip;
uint16_t otp_port;
uint8_t otp_mac[ETHERADDRL];
} overlay_target_point_t __aligned(8);
/*
* An overlay_target_mac_t represents the overlay representation of a VL2 MAC
* address. With the advent of cross-DC routing, it is possible to have
* duplicate MAC addresses in different data centers, so the data center id
* is necessary to uniquely identify a MAC address.
*
* XXX: In hindsight, using a uint16_t for the DCID might have been nicer.
*/
typedef struct overlay_target_mac {
uint32_t otm_dcid;
uint8_t otm_mac[ETHERADDRL];
} overlay_target_mac_t;
/*
* The overlay_target_route_t represents the fields of the packet that
* have to be modified to deliver a packet to remote (routed) destinations.
* All three values are always populated when a packet is routed, even if
* some of the overlay_target_route_t values end up being the same as the
* original values in the packet being routed.
*/
typedef struct overlay_target_route {
uint64_t otr_vnet;
uint8_t otr_srcmac[ETHERADDRL];
uint16_t otr_vlan;
} overlay_target_route_t;
#define OVERLAY_TARG_IOCTL (('o' << 24) | ('v' << 16) | ('t' << 8))
#define OVERLAY_TARG_INFO (OVERLAY_TARG_IOCTL | 0x01)
typedef enum overlay_targ_info_flags {
OVERLAY_TARG_INFO_F_ACTIVE = 0x01,
OVERLAY_TARG_INFO_F_DEGRADED = 0x02
} overlay_targ_info_flags_t;
/*
* Get target information about an overlay device
*/
typedef struct overlay_targ_info {
datalink_id_t oti_linkid;
uint32_t oti_needs;
uint64_t oti_flags;
uint64_t oti_vnetid;
uint32_t oti_dcid;
} overlay_targ_info_t;
/*
* Declare an association between a given varpd instance and a datalink.
*/
#define OVERLAY_TARG_ASSOCIATE (OVERLAY_TARG_IOCTL | 0x02)
typedef struct overlay_targ_associate {
datalink_id_t ota_linkid;
uint32_t ota_mode;
uint64_t ota_id;
uint32_t ota_provides;
overlay_target_point_t ota_point;
} overlay_targ_associate_t;
/*
* Remove an association from a device. If the device has already been started,
* this implies OVERLAY_TARG_DEGRADE.
*/
#define OVERLAY_TARG_DISASSOCIATE (OVERLAY_TARG_IOCTL | 0x3)
/*
* Tells the kernel that while a varpd instance still exists, it basically isn't
* making any forward progress, so the device should consider itself degraded.
*/
#define OVERLAY_TARG_DEGRADE (OVERLAY_TARG_IOCTL | 0x4)
typedef struct overlay_targ_degrade {
datalink_id_t otd_linkid;
uint32_t otd_pad;
char otd_buf[OVERLAY_STATUS_BUFLEN];
} overlay_targ_degrade_t;
/*
* Tells the kernel to remove the degraded status that it set on a device.
*/
#define OVERLAY_TARG_RESTORE (OVERLAY_TARG_IOCTL | 0x5)
typedef struct overlay_targ_id {
datalink_id_t otid_linkid;
} overlay_targ_id_t;
/*
* The following ioctls are all used to support dynamic lookups from userland,
* generally serviced by varpd.
*
* The way this is designed to work is that user land will have threads sitting
* in OVERLAY_TARG_LOOKUP ioctls waiting to service requests. A thread will sit
* waiting for work for up to approximately one second of time before they will
* be sent back out to user land to give user land a chance to clean itself up
* or more generally, come back into the kernel for work. Once these threads
* return, they will have a request with which more action can be done. The
* following ioctls can all be used to answer the request.
*
* OVERLAY_TARG_RESPOND - overlay_targ_resp_t
*
* The overlay_targ_resp_t has the appropriate information from
* which a reply can be generated. The information is filled into
* an overlay_targ_point_t as appropriate based on the
* overlay_plugin_dest_t type.
*
*
* OVERLAY_TARG_DROP - overlay_targ_resp_t
*
* The overlay_targ_resp_t should identify a request for which to
* drop a packet.
*
*
* OVERLAY_TARG_INJECT - overlay_targ_pkt_t
*
* The overlay_targ_pkt_t injects a fully formed packet into the
* virtual network. It may either be identified by its data link id
* or by the request id. If both are specified, the
* datalink id will be used. Note, that an injection is not
* considered a reply and if this corresponds to a requeset, then
* that individual packet must still be dropped.
*
*
* OVERLAY_TARG_PKT - overlay_targ_pkt_t
*
* This ioctl can be used to copy data from a given request into a
* user buffer. This can be used in combination with
* OVERLAY_TARG_INJECT to implement services such as a proxy-arp.
*
*
* OVERLAY_TARG_RESEND - overlay_targ_pkt_t
*
* This ioctl is similar to the OVERLAY_TARG_INJECT, except instead
* of receiving it on the local mac handle, it queues it for
* retransmission again. This is useful if you have a packet that
* was originally destined for some broadcast or multicast address
* that you now want to send to a unicast address.
*/
#define OVERLAY_TARG_LOOKUP (OVERLAY_TARG_IOCTL | 0x10)
#define OVERLAY_TARG_RESPOND (OVERLAY_TARG_IOCTL | 0x11)
#define OVERLAY_TARG_DROP (OVERLAY_TARG_IOCTL | 0x12)
#define OVERLAY_TARG_INJECT (OVERLAY_TARG_IOCTL | 0x13)
#define OVERLAY_TARG_PKT (OVERLAY_TARG_IOCTL | 0x14)
#define OVERLAY_TARG_RESEND (OVERLAY_TARG_IOCTL | 0x15)
typedef struct overlay_targ_l2 {
uint8_t otl2_srcaddr[ETHERADDRL];
uint8_t otl2_dstaddr[ETHERADDRL];
uint32_t otl2_dsttype;
uint32_t otl2_sap;
} overlay_targ_l2_t;
typedef struct overlay_targ_l3 {
struct in6_addr otl3_srcip;
struct in6_addr otl3_dstip;
} overlay_targ_l3_t;
typedef struct overlay_targ_lookup {
uint64_t otl_dlid;
uint64_t otl_reqid;
uint64_t otl_varpdid;
uint64_t otl_vnetid;
uint64_t otl_hdrsize;
uint64_t otl_pktsize;
union {
overlay_targ_l2_t otlu_l2;
overlay_targ_l3_t otlu_l3;
} otl_addru;
int32_t otl_vlan;
boolean_t otl_l3req;
} overlay_targ_lookup_t;
typedef struct overlay_targ_resp {
uint64_t otr_reqid;
overlay_target_route_t otr_route; /* Ignored for VL2->UL3 requests */
overlay_target_mac_t otr_mac; /* Ignored for VL2->UL3 requests */
overlay_target_point_t otr_answer;
} overlay_targ_resp_t;
typedef struct overlay_targ_pkt {
uint64_t otp_linkid;
uint64_t otp_reqid;
uint64_t otp_size;
void *otp_buf;
} overlay_targ_pkt_t;
#ifdef _KERNEL
typedef struct overlay_targ_pkt32 {
uint64_t otp_linkid;
uint64_t otp_reqid;
uint64_t otp_size;
caddr32_t otp_buf;
} overlay_targ_pkt32_t;
#endif /* _KERNEL */
/*
* This provides a way to get a list of active overlay devices independently
* from dlmgmtd. At the end of the day the kernel always knows what will exist
* and this allows varpd which is an implementation of libdladm not to end up
* needing to call back into dlmgmtd via libdladm and create an unfortunate
* dependency cycle.
*/
#define OVERLAY_TARG_LIST (OVERLAY_TARG_IOCTL | 0x20)
typedef struct overlay_targ_list {
uint32_t otl_nents;
uint32_t otl_ents[];
} overlay_targ_list_t;
/*
* The following family of ioctls all manipulate the target cache of a given
* device.
*
* OVERLAY_TARG_CACHE_GET - overlay_targ_cache_t
*
* The overlay_targ_cache_t should be have its link identifier and
* the desired mac address filled in. On return, it will fill in
* the otc_dest member, if the entry exists in the table.
*
*
* OVERLAY_TARG_CACHE_SET - overlay_targ_cache_t
*
* The cache table entry of the mac address referred to by otc_mac
* and otd_linkid will be filled in with the details provided by in
* the otc_dest member.
*
* OVERLAY_TARG_CACHE_REMOVE - overlay_targ_cache_t
*
* Removes the cache entry identified by otc_mac from the table.
* Note that this does not stop any in-flight lookups or deal with
* any data that is awaiting a lookup.
*
*
* OVERLAY_TARG_CACHE_FLUSH - overlay_targ_cache_t
*
* Similar to OVERLAY_TARG_CACHE_REMOVE, but functions on the
* entire table identified by otc_linkid. All other parameters are
* ignored.
*
*
* OVERLAY_TARG_CACHE_ITER - overlay_targ_cache_iter_t
*
* Iterates over the contents of a target cache identified by
* otci_linkid. Iteration is guaranteed to be exactly once for
* items which are in the hashtable at the beginning and end of
* iteration. For items which are added or removed after iteration
* has begun, only at most once semantics are guaranteed. Consumers
* should ensure that otci_marker is zeroed before starting
* iteration and should preserve its contents across calls.
*
* Before calling in, otci_count should be set to the number of
* entries that space has been allocated for in otci_ents. The
* value will be updated to indicate the total number written out.
*/
#define OVERLAY_TARG_CACHE_GET (OVERLAY_TARG_IOCTL | 0x30)
#define OVERLAY_TARG_CACHE_SET (OVERLAY_TARG_IOCTL | 0x31)
#define OVERLAY_TARG_CACHE_REMOVE (OVERLAY_TARG_IOCTL | 0x32)
#define OVERLAY_TARG_CACHE_FLUSH (OVERLAY_TARG_IOCTL | 0x33)
#define OVERLAY_TARG_CACHE_ITER (OVERLAY_TARG_IOCTL | 0x34)
#define OVERLAY_TARG_CACHE_REMOVE_NET (OVERLAY_TARG_IOCTL | 0x35)
/*
* This is a pretty arbitrary number that we're constraining ourselves to
* for iteration. Basically the goal is to make sure that we can't have a user
* ask us to allocate too much memory on their behalf at any time. A more
* dynamic form may be necessary some day.
*/
#define OVERLAY_TARGET_ITER_MAX 500
#define OVERLAY_TARGET_CACHE_DROP 0x01
#define OVERLAY_TARGET_CACHE_ROUTER 0x02
typedef struct overlay_targ_cache_entry {
overlay_target_mac_t otce_mac;
uint16_t otce_flags;
overlay_target_point_t otce_dest;
} overlay_targ_cache_entry_t;
typedef struct overlay_targ_cache_net_entry {
struct in6_addr otcne_src;
struct in6_addr otcne_dst;
uint16_t otcne_vlan; /* src vlan */
uint8_t otcne_src_prefixlen;
uint8_t otcne_dst_prefixlen;
} overlay_targ_cache_net_entry_t;
typedef struct overlay_targ_cache {
datalink_id_t otc_linkid;
overlay_targ_cache_entry_t otc_entry;
} overlay_targ_cache_t;
typedef struct overlay_targ_cache_net {
datalink_id_t otcn_linkid;
overlay_targ_cache_net_entry_t otcn_entry;
} overlay_targ_cache_net_t;
typedef struct overlay_targ_cache_iter {
datalink_id_t otci_linkid;
uint32_t otci_pad;
uint64_t otci_marker[2];
uint16_t otci_count;
uint8_t otci_pad2[3];
overlay_targ_cache_entry_t otci_ents[];
} overlay_targ_cache_iter_t;
#ifdef __cplusplus
}
#endif
#endif /* _OVERLAY_TARGET_H */
|