#ifndef _SOCKFS_SOCKFILTER_H
#define _SOCKFS_SOCKFILTER_H
#include <sys/kstat.h>
#include <sys/list.h>
#include <sys/mutex.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sockfilter.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sonode;
struct sockparams;
typedef struct sof_module sof_module_t;
typedef struct sof_entry_kstat sof_entry_kstat_t;
typedef struct sof_entry sof_entry_t;
typedef struct sof_instance sof_instance_t;
typedef struct sof_kstat sof_kstat_t;
#define SOF_MAXNAMELEN FILNAME_MAX
#define SOF_MAXSOCKTUPLECNT 32
#define SOF_MODPATH SOCKMOD_PATH
struct sof_module {
char *sofm_name;
sof_ops_t sofm_ops;
uint_t sofm_refcnt;
list_node_t sofm_node;
};
struct sof_kstat {
kstat_named_t sofks_defer_closed;
kstat_named_t sofks_defer_close_backlog;
kstat_named_t sofks_defer_close_failed_backlog_too_big;
};
#define SOF_GLOBAL_STAT_BUMP(s) \
atomic_inc_64(&sof_stat.sofks_##s.value.ui64)
struct sof_entry_kstat {
kstat_named_t sofek_nactive;
kstat_named_t sofek_tot_active_attach;
kstat_named_t sofek_tot_passive_attach;
kstat_named_t sofek_ndeferred;
kstat_named_t sofek_attach_failures;
};
struct sof_entry {
char sofe_name[SOF_MAXNAMELEN];
char sofe_modname[MODMAXNAMELEN];
sof_hint_t sofe_hint;
char *sofe_hintarg;
list_node_t sofe_node;
uint_t sofe_socktuple_cnt;
sof_socktuple_t *sofe_socktuple;
sof_entry_kstat_t sofe_kstat;
kstat_t *sofe_ksp;
kmutex_t sofe_lock;
char sofe_flags;
uint_t sofe_refcnt;
sof_module_t *sofe_mod;
};
#define SOFEF_AUTO 0x1
#define SOFEF_PROG 0x2
#define SOFEF_CONDEMED 0x4
struct sof_instance {
sof_ops_t *sofi_ops;
void *sofi_cookie;
char sofi_flags;
sof_instance_t *sofi_prev;
sof_instance_t *sofi_next;
struct sonode *sofi_sonode;
sof_entry_t *sofi_filter;
};
#define SOFIF_BYPASS 0x1
#define SOFIF_DEFER 0x2
#define SOFIF_RCV_FLOWCTRL 0x4
#define SOFIF_SND_FLOWCTRL 0x8
#define SOF_STAT_ADD(i, s, v) \
atomic_add_64(&(i)->sofi_filter->sofe_kstat.sofek_##s.value.ui64, (v))
extern void sof_init(void);
extern void sof_entry_free(sof_entry_t *);
extern int sof_entry_add(sof_entry_t *);
extern sof_entry_t *sof_entry_remove_by_name(const char *);
extern int sof_entry_proc_sockparams(sof_entry_t *, struct sockparams *);
extern int sof_sockparams_init(struct sockparams *);
extern void sof_sockparams_fini(struct sockparams *);
extern int sof_sonode_autoattach_filters(struct sonode *, cred_t *);
extern int sof_sonode_inherit_filters(struct sonode *, struct sonode *);
extern void sof_sonode_closing(struct sonode *);
extern void sof_sonode_cleanup(struct sonode *);
extern void sof_sonode_notify_filters(struct sonode *, sof_event_t,
uintptr_t);
extern boolean_t sof_sonode_drop_deferred(struct sonode *);
extern int sof_setsockopt(struct sonode *, int, const void *, socklen_t,
struct cred *);
extern int sof_getsockopt(struct sonode *, int, void *, socklen_t *,
struct cred *);
extern int sof_rval2errno(sof_rval_t);
#define SOF_INTERESTED(inst, op) \
(!((inst)->sofi_flags & SOFIF_BYPASS) && \
(inst)->sofi_ops->sofop_##op != NULL)
#define __SOF_FILTER_OP(so, op, cr, ...) \
sof_instance_t *__inst; \
sof_rval_t __rval; \
\
for (__inst = (so)->so_filter_top; __inst != NULL; \
__inst = __inst->sofi_next) { \
if (!SOF_INTERESTED(__inst, op)) \
continue; \
__rval = (__inst->sofi_ops->sofop_##op)((sof_handle_t)__inst,\
__inst->sofi_cookie, __VA_ARGS__, cr); \
DTRACE_PROBE2(filter__action, (sof_instance_t), __inst,\
(sof_rval_t), __rval); \
if (__rval != SOF_RVAL_CONTINUE) \
return (sof_rval2errno(__rval)); \
} \
return (-1);
extern mblk_t *sof_filter_data_out_from(struct sonode *so,
sof_instance_t *, mblk_t *, struct nmsghdr *, cred_t *, int *);
extern mblk_t *sof_filter_data_in_proc(struct sonode *so,
mblk_t *, mblk_t **);
extern int sof_filter_bind(struct sonode *, struct sockaddr *,
socklen_t *, cred_t *);
extern int sof_filter_listen(struct sonode *, int *, cred_t *);
extern int sof_filter_connect(struct sonode *, struct sockaddr *,
socklen_t *, cred_t *);
extern int sof_filter_accept(struct sonode *, cred_t *);
extern int sof_filter_shutdown(struct sonode *, int *, cred_t *);
extern int sof_filter_getsockname(struct sonode *, struct sockaddr *,
socklen_t *, cred_t *);
extern int sof_filter_getpeername(struct sonode *, struct sockaddr *,
socklen_t *, cred_t *);
extern int sof_filter_setsockopt(struct sonode *, int, int, void *,
socklen_t *, cred_t *);
extern int sof_filter_getsockopt(struct sonode *, int, int, void *,
socklen_t *, cred_t *);
extern int sof_filter_ioctl(struct sonode *, int, intptr_t, int,
int32_t *, cred_t *);
#define SOF_FILTER_DATA_OUT(so, mp, msg, cr, errp) \
sof_filter_data_out_from(so, (so)->so_filter_top, mp, msg, cr, errp)
#define SOF_FILTER_DATA_OUT_FROM(so, inst, mp, msg, cr, errp) \
sof_filter_data_out_from(so, inst, mp, msg, cr, errp)
#ifdef __cplusplus
}
#endif
#endif