136589d6bSRobert Mustacchi /*
236589d6bSRobert Mustacchi  * This file and its contents are supplied under the terms of the
336589d6bSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
436589d6bSRobert Mustacchi  * You may only use this file in accordance with the terms of version
536589d6bSRobert Mustacchi  * 1.0 of the CDDL.
636589d6bSRobert Mustacchi  *
736589d6bSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
836589d6bSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
936589d6bSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
1036589d6bSRobert Mustacchi  */
1136589d6bSRobert Mustacchi 
1236589d6bSRobert Mustacchi /*
1336589d6bSRobert Mustacchi  * Copyright 2016 Joyent, Inc.
1436589d6bSRobert Mustacchi  */
1536589d6bSRobert Mustacchi 
1636589d6bSRobert Mustacchi #ifndef _SYS_OVERLAY_IMPL_H
1736589d6bSRobert Mustacchi #define	_SYS_OVERLAY_IMPL_H
1836589d6bSRobert Mustacchi 
1936589d6bSRobert Mustacchi /*
2036589d6bSRobert Mustacchi  * Overlay device support
2136589d6bSRobert Mustacchi  */
2236589d6bSRobert Mustacchi 
2336589d6bSRobert Mustacchi #include <sys/overlay.h>
2436589d6bSRobert Mustacchi #include <sys/overlay_common.h>
2536589d6bSRobert Mustacchi #include <sys/overlay_plugin.h>
2636589d6bSRobert Mustacchi #include <sys/overlay_target.h>
2736589d6bSRobert Mustacchi #include <sys/ksynch.h>
2836589d6bSRobert Mustacchi #include <sys/list.h>
2936589d6bSRobert Mustacchi #include <sys/avl.h>
3036589d6bSRobert Mustacchi #include <sys/ksocket.h>
3136589d6bSRobert Mustacchi #include <sys/socket.h>
3236589d6bSRobert Mustacchi #include <sys/refhash.h>
3336589d6bSRobert Mustacchi #include <sys/ethernet.h>
3436589d6bSRobert Mustacchi #include <sys/list.h>
3536589d6bSRobert Mustacchi 
3636589d6bSRobert Mustacchi #ifdef __cplusplus
3736589d6bSRobert Mustacchi extern "C" {
3836589d6bSRobert Mustacchi #endif
3936589d6bSRobert Mustacchi 
4036589d6bSRobert Mustacchi #define	OVEP_VERSION_ONE	0x1
4136589d6bSRobert Mustacchi 
4236589d6bSRobert Mustacchi typedef struct overlay_plugin {
4336589d6bSRobert Mustacchi 	kmutex_t ovp_mutex;
4436589d6bSRobert Mustacchi 	list_node_t ovp_link;			/* overlay_plugin_lock */
4536589d6bSRobert Mustacchi 	uint_t ovp_active;			/* ovp_mutex */
4636589d6bSRobert Mustacchi 	const char *ovp_name;			/* RO */
4736589d6bSRobert Mustacchi 	const overlay_plugin_ops_t *ovp_ops;	/* RO */
4836589d6bSRobert Mustacchi 	const char *const *ovp_props;		/* RO */
4936589d6bSRobert Mustacchi 	uint_t ovp_nprops;			/* RO */
5036589d6bSRobert Mustacchi 	uint_t ovp_id_size;			/* RO */
5136589d6bSRobert Mustacchi 	overlay_plugin_flags_t ovp_flags;	/* RO */
5236589d6bSRobert Mustacchi 	overlay_plugin_dest_t ovp_dest;		/* RO */
5336589d6bSRobert Mustacchi } overlay_plugin_t;
5436589d6bSRobert Mustacchi 
5536589d6bSRobert Mustacchi typedef struct overlay_mux {
5636589d6bSRobert Mustacchi 	list_node_t		omux_lnode;
5736589d6bSRobert Mustacchi 	ksocket_t		omux_ksock;	/* RO */
5836589d6bSRobert Mustacchi 	overlay_plugin_t	*omux_plugin;	/* RO: associated encap */
5936589d6bSRobert Mustacchi 	int			omux_domain;	/* RO: socket domain */
6036589d6bSRobert Mustacchi 	int			omux_family;	/* RO: socket family */
6136589d6bSRobert Mustacchi 	int			omux_protocol;	/* RO: socket protocol */
6236589d6bSRobert Mustacchi 	struct sockaddr		*omux_addr;	/* RO: socket address */
6336589d6bSRobert Mustacchi 	socklen_t		omux_alen;	/* RO: sockaddr len */
6436589d6bSRobert Mustacchi 	kmutex_t		omux_lock;	/* Protects everything below */
6536589d6bSRobert Mustacchi 	uint_t			omux_count;	/* Active instances */
6636589d6bSRobert Mustacchi 	avl_tree_t		omux_devices;	/* Tree of devices */
6736589d6bSRobert Mustacchi } overlay_mux_t;
6836589d6bSRobert Mustacchi 
6936589d6bSRobert Mustacchi typedef enum overlay_target_flag {
7036589d6bSRobert Mustacchi 	OVERLAY_T_TEARDOWN	= 0x1
7136589d6bSRobert Mustacchi } overlay_target_flag_t;
7236589d6bSRobert Mustacchi 
7336589d6bSRobert Mustacchi typedef struct overlay_target {
7436589d6bSRobert Mustacchi 	kmutex_t		ott_lock;
7536589d6bSRobert Mustacchi 	kcondvar_t		ott_cond;
7636589d6bSRobert Mustacchi 	overlay_target_mode_t	ott_mode;	/* RO */
7736589d6bSRobert Mustacchi 	overlay_plugin_dest_t	ott_dest;	/* RO */
7836589d6bSRobert Mustacchi 	uint64_t		ott_id;		/* RO */
7936589d6bSRobert Mustacchi 	overlay_target_flag_t	ott_flags;	/* ott_lock */
8036589d6bSRobert Mustacchi 	uint_t			ott_ocount;	/* ott_lock */
8136589d6bSRobert Mustacchi 	union {					/* ott_lock */
8236589d6bSRobert Mustacchi 		overlay_target_point_t	ott_point;
8336589d6bSRobert Mustacchi 		struct overlay_target_dyn {
8436589d6bSRobert Mustacchi 			refhash_t	*ott_dhash;
8536589d6bSRobert Mustacchi 			avl_tree_t	ott_tree;
8636589d6bSRobert Mustacchi 		} ott_dyn;
8736589d6bSRobert Mustacchi 	} ott_u;
8836589d6bSRobert Mustacchi } overlay_target_t;
8936589d6bSRobert Mustacchi 
9036589d6bSRobert Mustacchi typedef enum overlay_dev_flag {
9136589d6bSRobert Mustacchi 	OVERLAY_F_ACTIVATED	= 0x01, /* Activate ioctl completed */
9236589d6bSRobert Mustacchi 	OVERLAY_F_IN_MUX	= 0x02,	/* Currently in a mux */
9336589d6bSRobert Mustacchi 	OVERLAY_F_IN_TX		= 0x04,	/* Currently doing tx */
9436589d6bSRobert Mustacchi 	OVERLAY_F_IN_RX		= 0x08, /* Currently doing rx */
9536589d6bSRobert Mustacchi 	OVERLAY_F_IOMASK	= 0x0c,	/* A mask for rx and tx */
9636589d6bSRobert Mustacchi 	OVERLAY_F_MDDROP	= 0x10,	/* Drop traffic for metadata update */
9736589d6bSRobert Mustacchi 	OVERLAY_F_STOPMASK	= 0x1e,	/* None set when stopping */
9836589d6bSRobert Mustacchi 	OVERLAY_F_VARPD		= 0x20,	/* varpd plugin exists */
9936589d6bSRobert Mustacchi 	OVERLAY_F_DEGRADED	= 0x40,	/* device is degraded */
10036589d6bSRobert Mustacchi 	OVERLAY_F_MASK		= 0x7f	/* mask of everything */
10136589d6bSRobert Mustacchi } overlay_dev_flag_t;
10236589d6bSRobert Mustacchi 
10336589d6bSRobert Mustacchi typedef struct overlay_dev {
10436589d6bSRobert Mustacchi 	kmutex_t	odd_lock;
10536589d6bSRobert Mustacchi 	kcondvar_t	odd_iowait;
10636589d6bSRobert Mustacchi 	list_node_t	odd_link;		/* overlay_dev_lock */
10736589d6bSRobert Mustacchi 	mac_handle_t	odd_mh;			/* RO */
10836589d6bSRobert Mustacchi 	overlay_plugin_t *odd_plugin;		/* RO */
10936589d6bSRobert Mustacchi 	datalink_id_t	odd_linkid;		/* RO */
11036589d6bSRobert Mustacchi 	void		*odd_pvoid;		/* RO -- only used by plugin */
11136589d6bSRobert Mustacchi 	uint_t		odd_ref;		/* protected by odd_lock */
11236589d6bSRobert Mustacchi 	uint_t		odd_mtu;		/* protected by odd_lock */
11336589d6bSRobert Mustacchi 	overlay_dev_flag_t odd_flags;		/* protected by odd_lock */
11436589d6bSRobert Mustacchi 	uint_t		odd_rxcount;		/* protected by odd_lock */
11536589d6bSRobert Mustacchi 	uint_t		odd_txcount;		/* protected by odd_lock */
11636589d6bSRobert Mustacchi 	overlay_mux_t	*odd_mux;		/* protected by odd_lock */
11736589d6bSRobert Mustacchi 	uint64_t	odd_vid;		/* RO if active else odd_lock */
11836589d6bSRobert Mustacchi 	avl_node_t	odd_muxnode;		/* managed by mux */
11936589d6bSRobert Mustacchi 	overlay_target_t *odd_target;		/* See big theory statement */
12036589d6bSRobert Mustacchi 	char		odd_fmamsg[OVERLAY_STATUS_BUFLEN];	/* odd_lock */
12136589d6bSRobert Mustacchi } overlay_dev_t;
12236589d6bSRobert Mustacchi 
12336589d6bSRobert Mustacchi typedef enum overlay_target_entry_flags {
12436589d6bSRobert Mustacchi 	OVERLAY_ENTRY_F_PENDING		= 0x01,	/* lookup in progress */
12536589d6bSRobert Mustacchi 	OVERLAY_ENTRY_F_VALID		= 0x02,	/* entry is currently valid */
12636589d6bSRobert Mustacchi 	OVERLAY_ENTRY_F_DROP		= 0x04,	/* always drop target */
12736589d6bSRobert Mustacchi 	OVERLAY_ENTRY_F_VALID_MASK	= 0x06
12836589d6bSRobert Mustacchi } overlay_target_entry_flags_t;
12936589d6bSRobert Mustacchi 
13036589d6bSRobert Mustacchi typedef struct overlay_target_entry {
13136589d6bSRobert Mustacchi 	kmutex_t		ote_lock;
13236589d6bSRobert Mustacchi 	refhash_link_t		ote_reflink;	/* hashtable link */
13336589d6bSRobert Mustacchi 	avl_node_t		ote_avllink;	/* iteration link */
13436589d6bSRobert Mustacchi 	list_node_t		ote_qlink;
13536589d6bSRobert Mustacchi 	overlay_target_entry_flags_t ote_flags;	/* RW: state flags */
13636589d6bSRobert Mustacchi 	uint8_t			ote_addr[ETHERADDRL];	/* RO: mac addr */
13736589d6bSRobert Mustacchi 	overlay_target_t	*ote_ott;	/* RO */
13836589d6bSRobert Mustacchi 	overlay_dev_t		*ote_odd;	/* RO */
13936589d6bSRobert Mustacchi 	overlay_target_point_t	ote_dest;	/* RW: destination */
14036589d6bSRobert Mustacchi 	mblk_t			*ote_chead;	/* RW: blocked mb chain head */
14136589d6bSRobert Mustacchi 	mblk_t			*ote_ctail;	/* RW: blocked mb chain tail */
14236589d6bSRobert Mustacchi 	size_t			ote_mbsize;	/* RW: outstanding mblk size */
14336589d6bSRobert Mustacchi 	hrtime_t		ote_vtime;	/* RW: valid timestamp */
14436589d6bSRobert Mustacchi } overlay_target_entry_t;
14536589d6bSRobert Mustacchi 
14636589d6bSRobert Mustacchi 
14736589d6bSRobert Mustacchi #define	OVERLAY_CTL	"overlay"
14836589d6bSRobert Mustacchi 
149*bdb51392SDan McDonald #define	OVERLAY_FREEMSG(mp, reason) \
150*bdb51392SDan McDonald     DTRACE_PROBE2(overlay__freemsg, mblk_t *, mp, char *, reason)
151*bdb51392SDan McDonald 
15236589d6bSRobert Mustacchi extern dev_info_t *overlay_dip;
15336589d6bSRobert Mustacchi 
15436589d6bSRobert Mustacchi extern mblk_t *overlay_m_tx(void *, mblk_t *);
15536589d6bSRobert Mustacchi 
15636589d6bSRobert Mustacchi typedef int (*overlay_dev_iter_f)(overlay_dev_t *, void *);
15736589d6bSRobert Mustacchi extern void overlay_dev_iter(overlay_dev_iter_f, void *);
15836589d6bSRobert Mustacchi 
15936589d6bSRobert Mustacchi extern void overlay_plugin_init(void);
16036589d6bSRobert Mustacchi extern overlay_plugin_t *overlay_plugin_lookup(const char *);
16136589d6bSRobert Mustacchi extern void overlay_plugin_rele(overlay_plugin_t *);
16236589d6bSRobert Mustacchi extern void overlay_plugin_fini(void);
16336589d6bSRobert Mustacchi typedef int (*overlay_plugin_walk_f)(overlay_plugin_t *, void *);
16436589d6bSRobert Mustacchi extern void overlay_plugin_walk(overlay_plugin_walk_f, void *);
16536589d6bSRobert Mustacchi 
16636589d6bSRobert Mustacchi extern void overlay_io_start(overlay_dev_t *, overlay_dev_flag_t);
16736589d6bSRobert Mustacchi extern void overlay_io_done(overlay_dev_t *, overlay_dev_flag_t);
16836589d6bSRobert Mustacchi 
16936589d6bSRobert Mustacchi extern void overlay_mux_init(void);
17036589d6bSRobert Mustacchi extern void overlay_mux_fini(void);
17136589d6bSRobert Mustacchi 
17236589d6bSRobert Mustacchi extern overlay_mux_t *overlay_mux_open(overlay_plugin_t *, int, int, int,
17336589d6bSRobert Mustacchi     struct sockaddr *, socklen_t, int *);
17436589d6bSRobert Mustacchi extern void overlay_mux_close(overlay_mux_t *);
17536589d6bSRobert Mustacchi extern void overlay_mux_add_dev(overlay_mux_t *, overlay_dev_t *);
17636589d6bSRobert Mustacchi extern void overlay_mux_remove_dev(overlay_mux_t *, overlay_dev_t *);
17736589d6bSRobert Mustacchi extern int overlay_mux_tx(overlay_mux_t *, struct msghdr *, mblk_t *);
17836589d6bSRobert Mustacchi 
17936589d6bSRobert Mustacchi extern void overlay_prop_init(overlay_prop_handle_t);
18036589d6bSRobert Mustacchi 
18136589d6bSRobert Mustacchi extern void overlay_target_init(void);
18236589d6bSRobert Mustacchi extern int overlay_target_busy(void);
18336589d6bSRobert Mustacchi extern int overlay_target_open(dev_t *, int, int, cred_t *);
18436589d6bSRobert Mustacchi extern int overlay_target_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
18536589d6bSRobert Mustacchi extern int overlay_target_close(dev_t, int, int, cred_t *);
18636589d6bSRobert Mustacchi extern void overlay_target_free(overlay_dev_t *);
18736589d6bSRobert Mustacchi 
18836589d6bSRobert Mustacchi #define	OVERLAY_TARGET_OK	0
18936589d6bSRobert Mustacchi #define	OVERLAY_TARGET_DROP	1
19036589d6bSRobert Mustacchi #define	OVERLAY_TARGET_ASYNC	2
19136589d6bSRobert Mustacchi extern int overlay_target_lookup(overlay_dev_t *, mblk_t *, struct sockaddr *,
19236589d6bSRobert Mustacchi     socklen_t *);
19336589d6bSRobert Mustacchi extern void overlay_target_quiesce(overlay_target_t *);
19436589d6bSRobert Mustacchi extern void overlay_target_fini(void);
19536589d6bSRobert Mustacchi 
19636589d6bSRobert Mustacchi extern void overlay_fm_init(void);
19736589d6bSRobert Mustacchi extern void overlay_fm_fini(void);
19836589d6bSRobert Mustacchi extern void overlay_fm_degrade(overlay_dev_t *, const char *);
19936589d6bSRobert Mustacchi extern void overlay_fm_restore(overlay_dev_t *);
20036589d6bSRobert Mustacchi 
20136589d6bSRobert Mustacchi extern overlay_dev_t *overlay_hold_by_dlid(datalink_id_t);
20236589d6bSRobert Mustacchi extern void overlay_hold_rele(overlay_dev_t *);
20336589d6bSRobert Mustacchi 
20436589d6bSRobert Mustacchi #ifdef __cplusplus
20536589d6bSRobert Mustacchi }
20636589d6bSRobert Mustacchi #endif
20736589d6bSRobert Mustacchi 
20836589d6bSRobert Mustacchi #endif /* _SYS_OVERLAY_IMPL_H */
209