Current File : //usr/include/libevs.h
/*
 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
 */

#ifndef _LIBEVS_H
#define	_LIBEVS_H

#include <libdladm.h>
#include <libdlstat.h>
#include <netdb.h>
#include <sys/mac.h>
#include <sys/types.h>
#include <sys/list.h>
#include <sys/param.h>
#include <uuid/uuid.h>
#include <rad/radclient.h>
#include <sqlite3.h>
#include <rad/client/1/evscntl.h>

#ifdef	__cplusplus
extern "C" {
#endif

/* Global tenant */
#define	EVS_SYSTEM_TENANTNAME	"sys-global"

/* flags for vport creation */
#define	EVS_SYS_OBJECT			0x00000001

#define	EVS_TENANTNAME_MAX		128
#define	EVS_EVSNAME_MAX			128
#define	EVS_VPORTNAME_MAX		128
#define	EVS_EVSVPORTNAME_MAX		(EVS_EVSNAME_MAX + EVS_VPORTNAME_MAX)
#define	EVS_STRBUF_MAX			1024
#define	EVS_SQLSTR_MAX			2048
#define	EVS_IPNETNAME_MAX		128
#define	EVS_MACADDRSTR_MAX		18
#define	EVS_ALLOWEDADDRS_NUM		3
#define	EVS_ALLOWEDADDRS_MAX		EVS_ALLOWEDADDRS_NUM * INET6_ADDRSTRLEN
#define	EVS_RANGESTR_MAX		8192
#define	EVS_PROPNAME_MAX		32

#define	EVS_DB_ORD			SQLITE_OPEN_READONLY
#define	EVS_DB_ORW			SQLITE_OPEN_READWRITE

#define	EVS_STATQUERY_TIMEOUT		5

/* extended error codes */
#define	EVS_EXTENDED_ERRCODE(evserr, oerr)	\
	(((oerr) << 8) | ((evserr) & 0x000000FF))

/*
 * When adding a new error code please maintain the existing order and add
 * the error code before EVS_ERRMAX. Add a entry to evs_errlist[] array as-well.
 */
enum {
	EVS_SUCCESS = 0,
	EVS_FAILURE,
	EVS_CONTINUE,
	EVS_EAUTH,
	EVS_EBUSY_IPADDR,
	EVS_EBUSY_IPNET,
	EVS_EBUSY_MACADDR,
	EVS_EBUSY_VPORT,
	EVS_ECOMPAT_ADDR,
	EVS_ECOMPAT_IPVERS,
	EVS_ECOMPAT_L2TYPE,	/* error code - 10 */
	EVS_ECOMPAT_MGROUP,
	EVS_ECOMPAT_DBVERS,
	EVS_EEXISTS,
	EVS_EINVAL,
	EVS_EINVAL_CNTLPROP,
	EVS_EINVAL_COS,
	EVS_EINVAL_HOSTNAME,
	EVS_EINVAL_IPADDR,
	EVS_EINVAL_IPNET,
	EVS_EINVAL_IPRANGE,	/* error code - 20 */
	EVS_EINVAL_IPVERS,
	EVS_EINVAL_L2TYPE,
	EVS_EINVAL_LADDR,
	EVS_EINVAL_MACADDR,
	EVS_EINVAL_MAXBW,
	EVS_EINVAL_MGROUP,
	EVS_EINVAL_NAME,
	EVS_EINVAL_PRIORITY,
	EVS_EINVAL_PROP,
	EVS_EINVAL_RADURI,	/* error code - 30 */
	EVS_EINVAL_RANGE,
	EVS_EINVAL_SUBNET,
	EVS_EINVAL_UPORT,
	EVS_EINVAL_VLANIDRANGE,
	EVS_EINVAL_VLANID,
	EVS_EINVAL_VNI,
	EVS_ELIBDLADM,
	EVS_ELIBIPADM,
	EVS_ELOOKUP_HOSTNAME,
	EVS_ENOBUFS,		/* error code - 40 */
	EVS_ENOENT_EVS,
	EVS_ENOENT_IPNET,
	EVS_ENOENT_VPORT,
	EVS_ENOENT,
	EVS_ENOMEM,
	EVS_ENOOVERLAP_RANGE,
	EVS_ENORSRC,
	EVS_ENORSRC_VLANID,
	EVS_ENORSRC_VNI,
	EVS_ENOTSUP_RADURI,	/* error code - 50 */
	EVS_ENOTSUP,
	EVS_EOVERLAP_IPNET,
	EVS_EOVERFLOW_IPNET,
	EVS_EPARTIAL_PROP,
	EVS_EPERM,
	EVS_ERDONLY_PROP,
	EVS_ERAD,
	EVS_ERAD_ECONCNTL,
	EVS_ERAD_ECONHOST,
	EVS_ERANDOM,		/* error code - 60 */
	EVS_EREQ_ARGS,
	EVS_EREQ_UPLINK,
	EVS_ESCF,
	EVS_ESQL,
	EVS_ESYS,
	EVS_ETIMEDOUT_REMOTE,
	EVS_EUNAVAIL_VLANID,
	EVS_EUNAVAIL_VNI,
	EVS_EUUID,
	EVS_EINVAL_POOL,	/* error code - 70 */
	EVS_EEXCL_RSC,
	EVS_EEXCL_DEFROUTER,
	EVS_EINVAL_PROTECTION,
	EVS_EINVAL_SUBRANGE,
	EVS_EOVERLAP_RANGE,
	EVS_WPARTIAL_RANGE,
	EVS_WRANGE_NEED_UPDATE,
	EVS_EINVAL_URI_TEMPLATE,
	EVS_EINVAL_FILTER_NAME,
	EVS_EINVAL_UPORT_PCOMB,	/* error code - 80 */
	EVS_EINVAL_VXADDR_PCOMB,
	EVS_ERRMAX
};

/* The type of object (EVS, VPort, IPnet) */
typedef enum {
	EVS_TYPE_EVS,
	EVS_TYPE_VPORT,
	EVS_TYPE_IPNET
} evs_type_t;

/* The type of property (EVS, vport, or ipnet) */
typedef enum {
	EVS_PROPTYPE_EVS =	0x1,
	EVS_PROPTYPE_VPORT =	0x2,
	EVS_PROPTYPE_IPNET =	0x4
} evs_proptype_t;

/* The type of L2 network (VLAN, VXLAN, or FLAT) */
typedef enum {
	EVS_L2NTYPE_UNKNOWN = 0,
	EVS_L2NTYPE_VLAN,
	EVS_L2NTYPE_VXLAN,
	EVS_L2NTYPE_FLAT
} evs_l2ntype_t;

typedef enum {
	VPORT_STATUS_FREE = 0,
	VPORT_STATUS_USED = 1
} vport_status_t;

typedef enum {
	EVS_STATUS_IDLE = 0,
	EVS_STATUS_BUSY = 1
} evs_status_t;

typedef struct evs_ipnet_s {
	list_node_t 	ei_node;
	char		ei_tenantname[EVS_TENANTNAME_MAX];
	char 		ei_evsname[EVS_EVSNAME_MAX];
	uuid_t		ei_evsuuid;
	char 		ei_name[EVS_IPNETNAME_MAX];
	uuid_t		ei_uuid;
	nvlist_t	*ei_props;
	sa_family_t	ei_af;
	char 		ei_subnet[INET6_ADDRSTRLEN + 4];
	uint32_t 	ei_prefixlen;
	char 		ei_sastr[INET6_ADDRSTRLEN];
	char 		ei_eastr[INET6_ADDRSTRLEN];
	char		*ei_availrange;
	struct sockaddr_storage ei_ca;
	struct sockaddr_storage ei_sa;
	struct sockaddr_storage ei_ea;
} evs_ipnet_t;

typedef struct evs_prop_s {
	list_node_t	ep_node;
	char		ep_propname[EVS_PROPNAME_MAX];
	char		ep_perm[3];
	char		*ep_current;
	char		ep_default[EVS_STRBUF_MAX];
	char		ep_possible[EVS_STRBUF_MAX];
} evs_prop_t;

typedef struct evs_vport_s {
	list_node_t	evp_node;
	char		evp_tenantname[EVS_TENANTNAME_MAX];
	char		evp_evsname[EVS_EVSNAME_MAX];
	uuid_t		evp_evsuuid;
	char		evp_name[EVS_VPORTNAME_MAX];
	uuid_t		evp_uuid;
	nvlist_t	*evp_props;
	vport_status_t	evp_status;
	char		evp_vnicname[MAXLINKNAMESPECIFIER];
	char		evp_hostname[NI_MAXHOST];
} evs_vport_t;

typedef struct evs_s {
	list_node_t	evs_node;
	char		evs_tenantname[EVS_TENANTNAME_MAX];
	char		evs_name[EVS_EVSNAME_MAX];
	uuid_t		evs_uuid;
	nvlist_t	*evs_props;
	list_t		evs_ipnets;
	list_t		evs_ports;
	evs_status_t	evs_status;
	char		evs_uport[MAXLINKNAMELEN];
	char		evs_localaddr[INET6_ADDRSTRLEN + 4];
	char		evs_mgroup[INET6_ADDRSTRLEN + 4];
	char		evs_ipvers[3];
} evs_t;

typedef struct evs_smfprop_s {
	list_node_t	esp_node;
	char		esp_propname[EVS_PROPNAME_MAX];
	char		esp_propval[EVS_STRBUF_MAX];
	char		esp_defvalue[EVS_STRBUF_MAX];
	char		esp_perm[3];
} evs_smfprop_t;

typedef struct evs_ctrlprop_s {
	list_node_t	ecp_node;
	char		ecp_propname[EVS_PROPNAME_MAX];
	char		*ecp_propval;
	char		ecp_defvalue[EVS_STRBUF_MAX];
	char 		ecp_host[MAXHOSTNAMELEN];
	char		ecp_perm[3];
	char		*ecp_vlanrange;
	char		*ecp_vxlanrange;
	char		*ecp_flatrange;
} evs_ctrlprop_t;

struct evs_dbhandle;
typedef struct evs_dbhandle *evs_dbhandle_t;

/* db related APIs */
extern boolean_t	evs_db_exists(void);
extern int		evs_db_upgrade(void);
extern int		evs_db_create(void);
extern int		evs_db_open(evs_dbhandle_t *, int);
extern void		evs_db_close(evs_dbhandle_t);

extern int		evs_db_add_vport(evs_dbhandle_t, const char *,
			    const char *, const char *, const char *,
			    evs_vport_t **, uint32_t);
extern int		evs_db_remove_vport(evs_dbhandle_t, const char *,
			    const char *, const char *, const char *, uint32_t);
extern int		evs_db_reset_vport(evs_dbhandle_t, const char *,
			    const char *, const char *, const char *, uint32_t);
extern int		evs_db_add_system_vport(evs_dbhandle_t,
			    const char *, const char *, char *);
extern int		evs_db_remove_system_vport(evs_dbhandle_t,
			    const char *, const char *, const char *);
extern int		evs_db_get_filtered_vportlist(evs_dbhandle_t,
			    const char *, list_t *, uint32_t);
extern void		evs_free_vport(evs_vport_t *);
extern void		evs_free_vportlist(void *);

extern int		evs_db_get_filtered_evslist(evs_dbhandle_t,
			    const char *, list_t *, uint32_t);
extern int		evs_db_get_evsvport(evs_dbhandle_t, const char *,
			    const char *, const char *, evs_t **);
extern int		evs_db_get_evslist(evs_dbhandle_t, const char *,
			    const char *, list_t *, uint32_t);
extern void		evs_free_evs(evs_t *);
extern void		evs_free_evslist(void *);

extern int		evs_db_create_evs(evs_dbhandle_t, const char *,
			    const char *, const char *, uint32_t, evs_t **);
extern int		evs_db_delete_evs(evs_dbhandle_t, const char *,
			    const char *, uint32_t);

extern boolean_t	evs_db_vport_exists(evs_dbhandle_t, const char *,
			    const char *, const char *);
extern boolean_t	evs_db_evs_exists(evs_dbhandle_t, const char *,
			    const char *);

extern int		evs_db_assign_vport(evs_dbhandle_t, const char *,
			    const char *, const char *, const char *,
			    const char *, const char *, evs_t **);
extern int		evs_db_unassign_vport(evs_dbhandle_t,
			    const char *, const char *, const char *);

extern boolean_t	evs_db_ipnet_exists(evs_dbhandle_t, const char *,
			    const char *);
extern int		evs_db_add_ipnet(evs_dbhandle_t, const char *,
			    const char *, const char *, const char *,
			    evs_ipnet_t **, uint32_t);
extern int		evs_db_remove_ipnet(evs_dbhandle_t, const char *,
			    const char *, const char *, uint32_t);
extern int		evs_db_get_filtered_ipnetlist(evs_dbhandle_t,
			    const char *, list_t *, uint32_t);
extern int		evs_db_get_ipnetlist(evs_dbhandle_t, const char *,
			    const char *, const char *, list_t *, uint32_t);
extern void		evs_free_ipnetlist(void *);
extern void		evs_free_ipnet(evs_ipnet_t *);
extern int		evs_db_get_filtered_proplist(evs_dbhandle_t,
			    const char *, const char *, list_t *,
			    evs_proptype_t);
extern void		evs_free_prop(evs_prop_t *);
extern void		evs_free_proplist(void *);
extern int		evs_db_get_ctrlprop(evs_dbhandle_t, const char *,
			    const char *, list_t *);
extern int		evs_db_set_ctrlprop(evs_dbhandle_t, const char *,
			    const char *);
extern void		evs_free_ctrlproplist(list_t *);

/* EVS consumers APIs */
extern int		evs_rad_connection_to_controller(rc_conn_t **);
extern int		evs_rad_connection_to_evsnode(evs_dbhandle_t,
			    const char *, rc_conn_t **);
extern int		evs_connect_vnic(dladm_handle_t, const char *,
			    const char *, const char *, const char *,
			    dladm_arg_list_t **, const char *, datalink_id_t *,
			    evscntl_EVSImplInfo_t **, uint32_t);
extern int		evs_disconnect_vnic(dladm_handle_t, const char *,
			    const char *, datalink_id_t, uint32_t);
extern int		evs_get_vnicinfo(const char *, evscntl_VPortInfo_t **,
			    int *);

/* Client and Controller configuration */
extern int		evs_set_client_smfprop(const char *);
extern int		evs_get_client_smfprop(const char *, list_t *);
extern void		evs_free_smfproplist(list_t *);
extern int		evs_set_controller_smfprop(const char *, const char *);
extern int		evs_get_controller_smfprop(const char *, char *,
			    size_t);

/* host related APIs */
extern int		evs_set_vportprop(evs_dbhandle_t, const char *,
			    const char *, const char *, const char *, uint32_t);
extern int		evs_set_evsprop(evs_dbhandle_t, const char *,
			    const char *, const char *, uint32_t);
extern int		evs_set_ipnetprop(evs_dbhandle_t, const char *,
			    const char *, const char *, const char *, uint32_t);
extern int		evs_get_vnicstat(rc_conn_t *, const char *,
			    link_stat_t *);

/* utility APIs */
extern const char 	*evs_errmsg(int err, char *, uint_t);
extern boolean_t	evs_valid_name(const char *);
extern boolean_t	evs_valid_address(const char *);
extern boolean_t	evs_valid_zonevnicname(const char *);
extern boolean_t	evs_address_unspecified(const char *);

extern int		evs_list_count(list_t *);
extern int		evs_str2nvlist(const char *, nvlist_t **,  boolean_t,
			    int);
extern int		evs_nvlist2str(nvlist_t *, char **);
extern int		evs_nvl_count(nvlist_t *);
extern nvlist_t		*evs_create_nvl(int, ...);
extern boolean_t	evs_parse_evsvportname(const char *, char *, char *);
extern boolean_t	evs_parse_evsipnetname(const char *, char *, char *);
extern int		evs_create_nvstr(char *, size_t, const char *,
			    int, ...);
extern int		evs_parse_name(const char *, boolean_t *);
extern char		*evs_propnvl_lookup(evscntl_PropertyNV_t *, int,
			    const char *);
extern int		evs_str2int(const char *, int *);
extern boolean_t	evs_is_system_vport(const char *);
extern void		evs_filterstr2regex(char *);
extern void		evs_str2ntype(char *, evs_l2ntype_t *);
extern int		evs_get_hostname(char *, uint_t);
extern int		evs_validate_filterstr(const char *, evs_type_t,
			    evs_proptype_t);

#ifdef	__cplusplus
}
#endif

#endif	/* _LIBEVS_H */