summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-02-18 18:54:42 +0000
committerrwatson <rwatson@FreeBSD.org>2005-02-18 18:54:42 +0000
commitcb47ade08f79b52cb97c0c7593f4925607de5733 (patch)
treee4c1aa170f49c89091c87f3460a610ff5bb97f5b
parentde4599e9a3c0761274ac2851028761ea59ba8f06 (diff)
downloadFreeBSD-src-cb47ade08f79b52cb97c0c7593f4925607de5733.zip
FreeBSD-src-cb47ade08f79b52cb97c0c7593f4925607de5733.tar.gz
Move do_setopt_accept_filter() from uipc_socket.c to uipc_accf.c, where
the rest of the accept filter code currently lives. MFC after: 3 days
-rw-r--r--sys/kern/uipc_accf.c120
-rw-r--r--sys/kern/uipc_socket.c126
-rw-r--r--sys/sys/socketvar.h1
3 files changed, 121 insertions, 126 deletions
diff --git a/sys/kern/uipc_accf.c b/sys/kern/uipc_accf.c
index 874f75e..a764e8d 100644
--- a/sys/kern/uipc_accf.c
+++ b/sys/kern/uipc_accf.c
@@ -160,3 +160,123 @@ accept_filt_generic_mod_event(module_t mod, int event, void *data)
return (error);
}
+
+int
+do_setopt_accept_filter(so, sopt)
+ struct socket *so;
+ struct sockopt *sopt;
+{
+ struct accept_filter_arg *afap;
+ struct accept_filter *afp;
+ struct so_accf *newaf;
+ int error = 0;
+
+ newaf = NULL;
+ afap = NULL;
+
+ /*
+ * XXXRW: Configuring accept filters should be an atomic test-and-set
+ * operation to prevent races during setup and attach. There may be
+ * more general issues of racing and ordering here that are not yet
+ * addressed by locking.
+ */
+ /* do not set/remove accept filters on non listen sockets */
+ SOCK_LOCK(so);
+ if ((so->so_options & SO_ACCEPTCONN) == 0) {
+ SOCK_UNLOCK(so);
+ return (EINVAL);
+ }
+
+ /* removing the filter */
+ if (sopt == NULL) {
+ if (so->so_accf != NULL) {
+ struct so_accf *af = so->so_accf;
+ if (af->so_accept_filter != NULL &&
+ af->so_accept_filter->accf_destroy != NULL) {
+ af->so_accept_filter->accf_destroy(so);
+ }
+ if (af->so_accept_filter_str != NULL) {
+ FREE(af->so_accept_filter_str, M_ACCF);
+ }
+ FREE(af, M_ACCF);
+ so->so_accf = NULL;
+ }
+ so->so_options &= ~SO_ACCEPTFILTER;
+ SOCK_UNLOCK(so);
+ return (0);
+ }
+ SOCK_UNLOCK(so);
+
+ /*-
+ * Adding a filter.
+ *
+ * Do memory allocation, copyin, and filter lookup now while we're
+ * not holding any locks. Avoids sleeping with a mutex, as well as
+ * introducing a lock order between accept filter locks and socket
+ * locks here.
+ */
+ MALLOC(afap, struct accept_filter_arg *, sizeof(*afap), M_TEMP,
+ M_WAITOK);
+ /* don't put large objects on the kernel stack */
+ error = sooptcopyin(sopt, afap, sizeof *afap, sizeof *afap);
+ afap->af_name[sizeof(afap->af_name)-1] = '\0';
+ afap->af_arg[sizeof(afap->af_arg)-1] = '\0';
+ if (error) {
+ FREE(afap, M_TEMP);
+ return (error);
+ }
+ afp = accept_filt_get(afap->af_name);
+ if (afp == NULL) {
+ FREE(afap, M_TEMP);
+ return (ENOENT);
+ }
+
+ /*
+ * Allocate the new accept filter instance storage. We may have to
+ * free it again later if we fail to attach it. If attached
+ * properly, 'newaf' is NULLed to avoid a free() while in use.
+ */
+ MALLOC(newaf, struct so_accf *, sizeof(*newaf), M_ACCF, M_WAITOK |
+ M_ZERO);
+ if (afp->accf_create != NULL && afap->af_name[0] != '\0') {
+ int len = strlen(afap->af_name) + 1;
+ MALLOC(newaf->so_accept_filter_str, char *, len, M_ACCF,
+ M_WAITOK);
+ strcpy(newaf->so_accept_filter_str, afap->af_name);
+ }
+
+ SOCK_LOCK(so);
+ /* must remove previous filter first */
+ if (so->so_accf != NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ /*
+ * Invoke the accf_create() method of the filter if required.
+ * XXXRW: the socket mutex is held over this call, so the create
+ * method cannot block. This may be something we have to change, but
+ * it would require addressing possible races.
+ */
+ if (afp->accf_create != NULL) {
+ newaf->so_accept_filter_arg =
+ afp->accf_create(so, afap->af_arg);
+ if (newaf->so_accept_filter_arg == NULL) {
+ error = EINVAL;
+ goto out;
+ }
+ }
+ newaf->so_accept_filter = afp;
+ so->so_accf = newaf;
+ so->so_options |= SO_ACCEPTFILTER;
+ newaf = NULL;
+out:
+ SOCK_UNLOCK(so);
+ if (newaf != NULL) {
+ if (newaf->so_accept_filter_str != NULL)
+ FREE(newaf->so_accept_filter_str, M_ACCF);
+ FREE(newaf, M_ACCF);
+ }
+ if (afap != NULL)
+ FREE(afap, M_TEMP);
+ return (error);
+}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index c66db4c..7fbf6fd 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -68,10 +68,6 @@ __FBSDID("$FreeBSD$");
static int soreceive_rcvoob(struct socket *so, struct uio *uio,
int flags);
-#ifdef INET
-static int do_setopt_accept_filter(struct socket *so, struct sockopt *sopt);
-#endif
-
static void filt_sordetach(struct knote *kn);
static int filt_soread(struct knote *kn, long hint);
static void filt_sowdetach(struct knote *kn);
@@ -1463,128 +1459,6 @@ sorflush(so)
SOCKBUF_LOCK_DESTROY(&asb);
}
-#ifdef INET
-static int
-do_setopt_accept_filter(so, sopt)
- struct socket *so;
- struct sockopt *sopt;
-{
- struct accept_filter_arg *afap;
- struct accept_filter *afp;
- struct so_accf *newaf;
- int error = 0;
-
- newaf = NULL;
- afap = NULL;
-
- /*
- * XXXRW: Configuring accept filters should be an atomic test-and-set
- * operation to prevent races during setup and attach. There may be
- * more general issues of racing and ordering here that are not yet
- * addressed by locking.
- */
- /* do not set/remove accept filters on non listen sockets */
- SOCK_LOCK(so);
- if ((so->so_options & SO_ACCEPTCONN) == 0) {
- SOCK_UNLOCK(so);
- return (EINVAL);
- }
-
- /* removing the filter */
- if (sopt == NULL) {
- if (so->so_accf != NULL) {
- struct so_accf *af = so->so_accf;
- if (af->so_accept_filter != NULL &&
- af->so_accept_filter->accf_destroy != NULL) {
- af->so_accept_filter->accf_destroy(so);
- }
- if (af->so_accept_filter_str != NULL) {
- FREE(af->so_accept_filter_str, M_ACCF);
- }
- FREE(af, M_ACCF);
- so->so_accf = NULL;
- }
- so->so_options &= ~SO_ACCEPTFILTER;
- SOCK_UNLOCK(so);
- return (0);
- }
- SOCK_UNLOCK(so);
-
- /*-
- * Adding a filter.
- *
- * Do memory allocation, copyin, and filter lookup now while we're
- * not holding any locks. Avoids sleeping with a mutex, as well as
- * introducing a lock order between accept filter locks and socket
- * locks here.
- */
- MALLOC(afap, struct accept_filter_arg *, sizeof(*afap), M_TEMP,
- M_WAITOK);
- /* don't put large objects on the kernel stack */
- error = sooptcopyin(sopt, afap, sizeof *afap, sizeof *afap);
- afap->af_name[sizeof(afap->af_name)-1] = '\0';
- afap->af_arg[sizeof(afap->af_arg)-1] = '\0';
- if (error) {
- FREE(afap, M_TEMP);
- return (error);
- }
- afp = accept_filt_get(afap->af_name);
- if (afp == NULL) {
- FREE(afap, M_TEMP);
- return (ENOENT);
- }
-
- /*
- * Allocate the new accept filter instance storage. We may have to
- * free it again later if we fail to attach it. If attached
- * properly, 'newaf' is NULLed to avoid a free() while in use.
- */
- MALLOC(newaf, struct so_accf *, sizeof(*newaf), M_ACCF, M_WAITOK |
- M_ZERO);
- if (afp->accf_create != NULL && afap->af_name[0] != '\0') {
- int len = strlen(afap->af_name) + 1;
- MALLOC(newaf->so_accept_filter_str, char *, len, M_ACCF,
- M_WAITOK);
- strcpy(newaf->so_accept_filter_str, afap->af_name);
- }
-
- SOCK_LOCK(so);
- /* must remove previous filter first */
- if (so->so_accf != NULL) {
- error = EINVAL;
- goto out;
- }
- /*
- * Invoke the accf_create() method of the filter if required.
- * XXXRW: the socket mutex is held over this call, so the create
- * method cannot block. This may be something we have to change, but
- * it would require addressing possible races.
- */
- if (afp->accf_create != NULL) {
- newaf->so_accept_filter_arg =
- afp->accf_create(so, afap->af_arg);
- if (newaf->so_accept_filter_arg == NULL) {
- error = EINVAL;
- goto out;
- }
- }
- newaf->so_accept_filter = afp;
- so->so_accf = newaf;
- so->so_options |= SO_ACCEPTFILTER;
- newaf = NULL;
-out:
- SOCK_UNLOCK(so);
- if (newaf != NULL) {
- if (newaf->so_accept_filter_str != NULL)
- FREE(newaf->so_accept_filter_str, M_ACCF);
- FREE(newaf, M_ACCF);
- }
- if (afap != NULL)
- FREE(afap, M_TEMP);
- return (error);
-}
-#endif /* INET */
-
/*
* Perhaps this routine, and sooptcopyout(), below, ought to come in
* an additional variant to handle the case where the option value needs
diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h
index 6403389..9ac3dfe 100644
--- a/sys/sys/socketvar.h
+++ b/sys/sys/socketvar.h
@@ -447,6 +447,7 @@ struct uio;
/*
* From uipc_socket and friends
*/
+int do_setopt_accept_filter(struct socket *so, struct sockopt *sopt);
int so_setsockopt(struct socket *so, int level, int optname,
void *optval, size_t optlen);
int sockargs(struct mbuf **mp, caddr_t buf, int buflen, int type);
OpenPOWER on IntegriCloud