4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
25 #ifndef _SOCKFS_SOCKFILTER_H
26 #define _SOCKFS_SOCKFILTER_H
28 #include <sys/kstat.h>
30 #include <sys/mutex.h>
31 #include <sys/socket.h>
32 #include <sys/socketvar.h>
33 #include <sys/sockfilter.h>
42 typedef struct sof_module sof_module_t
;
43 typedef struct sof_entry_kstat sof_entry_kstat_t
;
44 typedef struct sof_entry sof_entry_t
;
45 typedef struct sof_instance sof_instance_t
;
46 typedef struct sof_kstat sof_kstat_t
;
48 #define SOF_MAXNAMELEN FILNAME_MAX
49 #define SOF_MAXSOCKTUPLECNT 32
50 #define SOF_MODPATH SOCKMOD_PATH
56 list_node_t sofm_node
;
60 kstat_named_t sofks_defer_closed
;
61 kstat_named_t sofks_defer_close_backlog
;
62 kstat_named_t sofks_defer_close_failed_backlog_too_big
;
65 #define SOF_GLOBAL_STAT_BUMP(s) \
66 atomic_inc_64(&sof_stat.sofks_##s.value.ui64)
69 * Per filter statistics.
71 struct sof_entry_kstat
{
72 kstat_named_t sofek_nactive
; /* # of consumers */
73 kstat_named_t sofek_tot_active_attach
;
74 kstat_named_t sofek_tot_passive_attach
;
75 kstat_named_t sofek_ndeferred
; /* # of deferred conns */
76 kstat_named_t sofek_attach_failures
;
80 * Socket filter entry - one for each configured filter (added and
81 * removed by soconfig(8)).
83 * sofe_flags, sofe_refcnt and sofe_mod are protected by sofe_lock, and all
84 * other fields are write once.
87 char sofe_name
[SOF_MAXNAMELEN
]; /* filter name */
88 char sofe_modname
[MODMAXNAMELEN
]; /* filter module */
89 sof_hint_t sofe_hint
; /* order hint */
90 char *sofe_hintarg
; /* hint argument */
91 list_node_t sofe_node
; /* global list node */
92 uint_t sofe_socktuple_cnt
; /* # of socket tuples */
93 sof_socktuple_t
*sofe_socktuple
; /* socket tuple list */
95 sof_entry_kstat_t sofe_kstat
; /* filter stats */
99 char sofe_flags
; /* SOFEF_* flags */
100 uint_t sofe_refcnt
; /* # of instances */
101 sof_module_t
*sofe_mod
; /* filter module */
104 /* Filter entry flags */
105 #define SOFEF_AUTO 0x1 /* automatic filter */
106 #define SOFEF_PROG 0x2 /* programmatic filter */
107 #define SOFEF_CONDEMED 0x4 /* removed by soconfig(8) */
110 * Socket filter instance - one for each socket using a sof_entry_t
112 struct sof_instance
{
113 sof_ops_t
*sofi_ops
; /* filter ops */
114 void *sofi_cookie
; /* filter cookie (from attach) */
115 char sofi_flags
; /* instance flags (SOFIF_*) */
116 sof_instance_t
*sofi_prev
; /* up the stack */
117 sof_instance_t
*sofi_next
; /* down the stack */
118 struct sonode
*sofi_sonode
; /* socket instance is attached to */
119 sof_entry_t
*sofi_filter
; /* filter this is an instance of */
122 /* Filter instance flags */
123 #define SOFIF_BYPASS 0x1 /* filter does not want any callbacks */
124 #define SOFIF_DEFER 0x2 /* defer notification of socket */
125 #define SOFIF_RCV_FLOWCTRL 0x4 /* flow control recv path */
126 #define SOFIF_SND_FLOWCTRL 0x8 /* flow control send path */
128 #define SOF_STAT_ADD(i, s, v) \
129 atomic_add_64(&(i)->sofi_filter->sofe_kstat.sofek_##s.value.ui64, (v))
131 extern void sof_init(void);
133 extern void sof_entry_free(sof_entry_t
*);
134 extern int sof_entry_add(sof_entry_t
*);
135 extern sof_entry_t
*sof_entry_remove_by_name(const char *);
136 extern int sof_entry_proc_sockparams(sof_entry_t
*, struct sockparams
*);
138 extern int sof_sockparams_init(struct sockparams
*);
139 extern void sof_sockparams_fini(struct sockparams
*);
141 extern int sof_sonode_autoattach_filters(struct sonode
*, cred_t
*);
142 extern int sof_sonode_inherit_filters(struct sonode
*, struct sonode
*);
143 extern void sof_sonode_closing(struct sonode
*);
144 extern void sof_sonode_cleanup(struct sonode
*);
145 extern void sof_sonode_notify_filters(struct sonode
*, sof_event_t
,
147 extern boolean_t
sof_sonode_drop_deferred(struct sonode
*);
149 extern int sof_setsockopt(struct sonode
*, int, const void *, socklen_t
,
151 extern int sof_getsockopt(struct sonode
*, int, void *, socklen_t
*,
154 extern int sof_rval2errno(sof_rval_t
);
156 #define SOF_INTERESTED(inst, op) \
157 (!((inst)->sofi_flags & SOFIF_BYPASS) && \
158 (inst)->sofi_ops->sofop_##op != NULL)
161 * SOF_FILTER_OP traverses the filter stack for sonode `so' top-down,
162 * calling `op' for each filter with the supplied `args'. A non-negative
163 * return value indicates that a filter action was taken.
165 #define __SOF_FILTER_OP(so, op, cr, ...) \
166 sof_instance_t *__inst; \
169 for (__inst = (so)->so_filter_top; __inst != NULL; \
170 __inst = __inst->sofi_next) { \
171 if (!SOF_INTERESTED(__inst, op)) \
173 __rval = (__inst->sofi_ops->sofop_##op)((sof_handle_t)__inst,\
174 __inst->sofi_cookie, __VA_ARGS__, cr); \
175 DTRACE_PROBE2(filter__action, (sof_instance_t), __inst,\
176 (sof_rval_t), __rval); \
177 if (__rval != SOF_RVAL_CONTINUE) \
178 return (sof_rval2errno(__rval)); \
182 extern mblk_t
*sof_filter_data_out_from(struct sonode
*so
,
183 sof_instance_t
*, mblk_t
*, struct msghdr
*, cred_t
*, int *);
184 extern mblk_t
*sof_filter_data_in_proc(struct sonode
*so
,
185 mblk_t
*, mblk_t
**);
186 extern int sof_filter_bind(struct sonode
*, struct sockaddr
*,
187 socklen_t
*, cred_t
*);
188 extern int sof_filter_listen(struct sonode
*, int *, cred_t
*);
189 extern int sof_filter_connect(struct sonode
*, struct sockaddr
*,
190 socklen_t
*, cred_t
*);
191 extern int sof_filter_accept(struct sonode
*, cred_t
*);
192 extern int sof_filter_shutdown(struct sonode
*, int *, cred_t
*);
193 extern int sof_filter_getsockname(struct sonode
*, struct sockaddr
*,
194 socklen_t
*, cred_t
*);
195 extern int sof_filter_getpeername(struct sonode
*, struct sockaddr
*,
196 socklen_t
*, cred_t
*);
197 extern int sof_filter_setsockopt(struct sonode
*, int, int, void *,
198 socklen_t
*, cred_t
*);
199 extern int sof_filter_getsockopt(struct sonode
*, int, int, void *,
200 socklen_t
*, cred_t
*);
201 extern int sof_filter_ioctl(struct sonode
*, int, intptr_t, int,
202 int32_t *, cred_t
*);
204 #define SOF_FILTER_DATA_OUT(so, mp, msg, cr, errp) \
205 sof_filter_data_out_from(so, (so)->so_filter_top, mp, msg, cr, errp)
206 #define SOF_FILTER_DATA_OUT_FROM(so, inst, mp, msg, cr, errp) \
207 sof_filter_data_out_from(so, inst, mp, msg, cr, errp)
213 #endif /* _SOCKFS_SOCKFILTER_H */