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