1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright (c) 2015 Joyent, Inc.
14  */
15 
16 #ifndef _SYS_OVERLAY_PLUGIN_H
17 #define	_SYS_OVERLAY_PLUGIN_H
18 
19 /*
20  * overlay plugin interface for encapsulation/decapsulation modules
21  *
22  * This header file defines how encapsulation and decapsulation plugins
23  * interact within the broader system. At this time, these interfaces are
24  * considered private to illumos and therefore are subject to change. As we gain
25  * more experience with a few of the different encapsulation formats, say nvgre
26  * or geneve, then we can move to make this a more-stable interface.
27  *
28  * A plugin is a general kernel module that uses the miscellaneous mod-linkage.
29  *
30  * In it's _init(9E) routine, it must register itself with the overlay
31  * subsystem. To do this, it allocates an overlay_plugin_register_t via
32  * overlay_plugin_alloc(), that it then  * fills out with various required
33  * information and then attempts to register with the system via a call to
34  * overlay_plugin_register(). If that succeeds, it should then call
35  * mod_install(9F). If the mod_install(9F) fails, then it should call
36  * overlay_plugin_unregister(). Regardless of success or failure, it should call
37  * overlay_plugin_free() to ensure that any memory that may be associated with
38  * the registration is freed.
39  *
40  * When the module's _fini(9E) is called, overlay_plugin_unregister() should be
41  * called first. It may return an error, such as EBUSY. In such cases, it should
42  * be returned as the return status of _fini(9E). This is quite necessary, it
43  * ensures that if the module is in use it doesn't get unloaded out from under
44  * us the broader subsystem while it's still in use. A driver can use that to
45  * know that there are no current instances of its private data.
46  *
47  * ------------------
48  * Plugin Definitions
49  * ------------------
50  *
51  * A plugin is required to fill in both an operations vector and a series of
52  * information to the callback routine. Here are the routines and their
53  * purposes. The full signatures are available below.
54  *
55  *   overlay_plugin_init_t
56  *
57  *	This interface is used to create a new instance of a plugin. An instance
58  *	of a plugin will be created for each overlay device that is created. For
59  *	example, if a device is created with VXLAN ID 23 and ID 42, then there
60  *	will be two different calls to this function.
61  *
62  *	This function gives the plugin a chance to create a private data
63  *	structure that will be returned on subsequent calls to the system.
64  *
65  *   overlay_plugin_fini_t
66  *
67  *	This is the opposite of overlay_plugin_init_t. It will be called when it
68  *	is safe to remove any private data that is associated with this instance
69  *	of the plugin.
70  *
71  *   overlay_plugin_propinfo_t
72  *
73  *	This is called with the name of a property that is registered when the
74  *	plugin is created. This function will be called with the name of the
75  *	property that information is being requested about. The plugin is
76  *	responsible for filling out information such as setting the name, the
77  *	type of property it is, the protection of the property (can a user
78  *	update it?), whether the property is required, an optional default value
79  *	for the property, and an optional set of values or ranges that are
80  *	allowed.
81  *
82  *   overlay_plugin_getprop_t
83  *
84  *	Return the value of the named property from the current instance of the
85  *	plugin.
86  *
87  *   overlay_plugin_setprop_t
88  *
89  *	Set the value of the named property to the specified value for the
90  *	current instance of the plugin. Note, that it is the plugin's
91  *	responsibility to ensure that the value of the property is valid and to
92  *	update state as appropriate.
93  *
94  *   overlay_plugin_socket_t
95  *
96  *	Every overlay device has a corresponding socket that it uses to send and
97  *	receive traffic. This routine is used to get the parameters that should
98  *	be used to define such a socket. The actual socket may be multiplexed
99  *	with other uses of it.
100  *
101  *   overlay_plugin_sockopt_t
102  *
103  *	Allow a plugin to set any necessary socket options that it needs on the
104  *	kernel socket that is being used by a mux. This will only be called once
105  *	for a given mux, if additional devices are added to a mux, it will not
106  *	be called additional times.
107  *
108  *   overlay_plugin_encap_t
109  *
110  *	In this routine you're given a message block and information about the
111  *	packet, such as the identifier and are asked to fill out a message block
112  *	that represents the encapsulation header and optionally manipulate the
113  *	input message if required.
114  *
115  *   overlay_plugin_decap_t
116  *
117  *	In this routine, you're given the encapsulated message block. The
118  *	requirement is to decapsulate it and determine what is the correct
119  *	overlay identifier for this network and to fill in the header size so
120  *	the broader system knows how much of this data should be considered
121  *	consumed.
122  *
123  *   ovpo_callbacks
124  *
125  *	This should be set to zero, it's reserved for future use.
126  *
127  * Once these properties are defined, the module should define the following
128  * members in the overlay_plugin_register_t.
129  *
130  *   ovep_version
131  *
132  *	Should be set to the value of the macro OVEP_VERSION.
133  *
134  *   ovep_name
135  *
136  *	Should be set to a character string that has the name of the module.
137  *	Generally this should match the name of the kernel module; however, this
138  *	is the name that users will use to refer to this module when creating
139  *	devices.
140  *
141  *   overlay_plugin_ops_t
142  *
143  *	Should be set to the functions as described above.
144  *
145  *   ovep_props
146  *
147  *	This is an array of character strings that holds the names of the
148  *	properties of the encapsulation plugin.
149  *
150  *
151  *   ovep_id_size
152  *
153  *	This is the size in bytes of the valid range for the identifier. The
154  *	valid identifier range is considered a ovep_id_size byte unsigned
155  *	integer, [ 0, 1 << (ovep_id_size * 8) ).
156  *
157  *   ovep_flags
158  *
159  *	A series of flags that indicate optional features that are supported.
160  *	Valid flags include:
161  *
162  *		OVEP_F_VLAN_TAG
163  *
164  *			The encapsulation format allows for the encapsulated
165  *			packet to maintain a VLAN tag.
166  *
167  *   ovep_dest
168  *
169  *	Describes the kind of destination that the overlay plugin supports for
170  *	sending traffic. For example, vxlan uses UDP, therefore it requires both
171  *	an IP address and a port; however, nvgre uses the gre header and
172  *	therefore only requires an IP address. The following flags may be
173  *	combined:
174  *
175  *		OVERLAY_PLUGIN_D_ETHERNET
176  *
177  *			Indicates that to send a packet to its destination, we
178  *			require a link-layer ethernet address.
179  *
180  *		OVERLAY_PLUGIN_D_IP
181  *
182  *			Indicates that to send a packet to its destination, we
183  *			require an IP address. Note, all IP addresses are
184  *			transmitted as IPv6 addresses and for an IPv4
185  *			destination, using an IPv4-mapped IPv6 address is the
186  *			expected way to transmit that.
187  *
188  *		OVERLAY_PLUGIN_D_PORT
189  *
190  *			Indicates that to send a packet to its destination, a
191  *			port is required, this usually indicates that the
192  *			protocol uses something like TCP or UDP.
193  *
194  *
195  * -------------------------------------------------
196  * Downcalls, Upcalls, and Synchronization Guarantees
197  * -------------------------------------------------
198  *
199  * Every instance of a given module is independent. The kernel only guarantees
200  * that it will probably perform downcalls into different instances in parallel
201  * at some point. No locking is provided by the framework for synchronization
202  * across instances. If a module finds itself needing that, it will be up to it
203  * to provide it.
204  *
205  * In a given instance, the kernel may call into entry points in parallel. If
206  * the instance has private data, it should likely synchronize it. The one
207  * guarantee that we do make, is that calls to getprop and setprop will be done
208  * synchronized by a caller holding the MAC perimeter.
209  *
210  * While servicing a downcall from the general overlay device framework, a
211  * kernel module should not make any upcalls, excepting those functions that are
212  * defined in this header file, eg. the property related callbacks. Importantly,
213  * it cannot make any assumptions about what locks may or may not be held by the
214  * broader system. The only thing that it is safe for it to use are its own
215  * locks.
216  *
217  * ----------------
218  * Downcall Context
219  * ----------------
220  *
221  * For all of the downcalls, excepting the overlay_plugin_encap_t and
222  * overlay_plugin_decap_t, the calls will be made either in kernel or user
223  * context, the module should not assume either way.
224  *
225  * overlay_plugin_encap_t and overlay_plugin_decap_t may be called in user,
226  * kernel or interrupt context; however, it is guaranteed that the interrupt
227  * will be below LOCK_LEVEL, and therefore it is safe to grab locks.
228  */
229 
230 #include <sys/stream.h>
231 #include <sys/mac_provider.h>
232 #include <sys/ksocket.h>
233 #include <sys/overlay_common.h>
234 
235 #ifdef __cplusplus
236 extern "C" {
237 #endif
238 
239 #define	OVEP_VERSION	0x1
240 
241 typedef enum overlay_plugin_flags {
242 	OVEP_F_VLAN_TAG	= 0x01	/* Supports VLAN Tags */
243 } overlay_plugin_flags_t;
244 
245 /*
246  * The ID space could easily be more than a 64-bit number, even
247  * though today it's either a 24-64 bit value. How should we future
248  * proof ourselves here?
249  */
250 typedef struct ovep_encap_info {
251 	uint64_t	ovdi_id;
252 	size_t		ovdi_hdr_size;
253 } ovep_encap_info_t;
254 
255 typedef struct __overlay_prop_handle *overlay_prop_handle_t;
256 typedef struct __overlay_handle *overlay_handle_t;
257 
258 /*
259  * Plugins are guaranteed that calls to setprop are serialized. However, any
260  * number of other calls can be going on in parallel otherwise.
261  */
262 typedef int (*overlay_plugin_encap_t)(void *, mblk_t *,
263     ovep_encap_info_t *, mblk_t **);
264 typedef int (*overlay_plugin_decap_t)(void *, mblk_t *,
265     ovep_encap_info_t *);
266 typedef int (*overlay_plugin_init_t)(overlay_handle_t, void **);
267 typedef void (*overlay_plugin_fini_t)(void *);
268 typedef int (*overlay_plugin_socket_t)(void *, int *, int *, int *,
269     struct sockaddr *, socklen_t *);
270 typedef int (*overlay_plugin_sockopt_t)(ksocket_t);
271 typedef int (*overlay_plugin_getprop_t)(void *, const char *, void *,
272     uint32_t *);
273 typedef int (*overlay_plugin_setprop_t)(void *, const char *, const void *,
274     uint32_t);
275 typedef int (*overlay_plugin_propinfo_t)(const char *, overlay_prop_handle_t);
276 
277 typedef struct overlay_plugin_ops {
278 	uint_t			ovpo_callbacks;
279 	overlay_plugin_init_t	ovpo_init;
280 	overlay_plugin_fini_t	ovpo_fini;
281 	overlay_plugin_encap_t	ovpo_encap;
282 	overlay_plugin_decap_t	ovpo_decap;
283 	overlay_plugin_socket_t ovpo_socket;
284 	overlay_plugin_sockopt_t ovpo_sockopt;
285 	overlay_plugin_getprop_t ovpo_getprop;
286 	overlay_plugin_setprop_t ovpo_setprop;
287 	overlay_plugin_propinfo_t ovpo_propinfo;
288 } overlay_plugin_ops_t;
289 
290 typedef struct overlay_plugin_register {
291 	uint_t			ovep_version;
292 	const char		*ovep_name;
293 	const overlay_plugin_ops_t	*ovep_ops;
294 	const char		**ovep_props;
295 	uint_t			ovep_id_size;
296 	uint_t			ovep_flags;
297 	uint_t			ovep_dest;
298 } overlay_plugin_register_t;
299 
300 /*
301  * Functions that interact with registration
302  */
303 extern overlay_plugin_register_t *overlay_plugin_alloc(uint_t);
304 extern void overlay_plugin_free(overlay_plugin_register_t *);
305 extern int overlay_plugin_register(overlay_plugin_register_t *);
306 extern int overlay_plugin_unregister(const char *);
307 
308 /*
309  * Property information callbacks
310  */
311 extern void overlay_prop_set_name(overlay_prop_handle_t, const char *);
312 extern void overlay_prop_set_prot(overlay_prop_handle_t, overlay_prop_prot_t);
313 extern void overlay_prop_set_type(overlay_prop_handle_t, overlay_prop_type_t);
314 extern int overlay_prop_set_default(overlay_prop_handle_t, void *, ssize_t);
315 extern void overlay_prop_set_nodefault(overlay_prop_handle_t);
316 extern void overlay_prop_set_range_uint32(overlay_prop_handle_t, uint32_t,
317     uint32_t);
318 extern void overlay_prop_set_range_str(overlay_prop_handle_t, const char *);
319 
320 #ifdef __cplusplus
321 }
322 #endif
323 
324 #endif /* _SYS_OVERLAY_PLUGIN_H */
325