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