uipc_accf.c revision 61837
1/*-
2 * Copyright (c) 2000 Alfred Perlstein <alfred@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 *	$FreeBSD: head/sys/kern/uipc_accf.c 61837 2000-06-20 01:09:23Z alfred $
27 */
28
29#define ACCEPT_FILTER_MOD
30
31#include "opt_param.h"
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/domain.h>
35#include <sys/kernel.h>
36#include <sys/proc.h>
37#include <sys/malloc.h>
38#include <sys/mbuf.h>
39#include <sys/protosw.h>
40#include <sys/socket.h>
41#include <sys/socketvar.h>
42#include <sys/queue.h>
43
44static SLIST_HEAD(, accept_filter) accept_filtlsthd =
45	SLIST_HEAD_INITIALIZER(&accept_filtlsthd);
46
47MALLOC_DEFINE(M_ACCF, "accf", "accept filter data");
48
49/*
50 * must be passed a malloc'd structure so we don't explode if the kld
51 * is unloaded, we leak the struct on deallocation to deal with this,
52 * but if a filter is loaded with the same name as a leaked one we re-use
53 * the entry.
54 */
55int
56accept_filt_add(struct accept_filter *filt)
57{
58	struct accept_filter *p;
59
60	SLIST_FOREACH(p, &accept_filtlsthd, accf_next)
61		if (strcmp(p->accf_name, filt->accf_name) == 0)  {
62			if (p->accf_callback != NULL) {
63				return (EEXIST);
64			} else {
65				p->accf_callback = filt->accf_callback;
66				FREE(filt, M_ACCF);
67				return (0);
68			}
69		}
70
71	if (p == NULL)
72		SLIST_INSERT_HEAD(&accept_filtlsthd, filt, accf_next);
73	return (0);
74}
75
76int
77accept_filt_del(char *name)
78{
79	struct accept_filter *p;
80
81	p = accept_filt_get(name);
82	if (p == NULL)
83		return (ENOENT);
84
85	p->accf_callback = NULL;
86	return (0);
87}
88
89struct accept_filter *
90accept_filt_get(char *name)
91{
92	struct accept_filter *p;
93
94	SLIST_FOREACH(p, &accept_filtlsthd, accf_next)
95		if (strcmp(p->accf_name, name) == 0)
96			return (p);
97
98	return (NULL);
99}
100
101int
102accept_filt_generic_mod_event(module_t mod, int event, void *data)
103{
104	struct accept_filter *p;
105	struct accept_filter *accfp = (struct accept_filter *) data;
106	int	s, error;
107
108	switch (event) {
109	case MOD_LOAD:
110		MALLOC(p, struct accept_filter *, sizeof(*p), M_ACCF, M_WAITOK);
111		bcopy(accfp, p, sizeof(*p));
112		s = splnet();
113		error = accept_filt_add(p);
114		splx(s);
115		break;
116
117	case MOD_UNLOAD:
118		s = splnet();
119		error = accept_filt_del(accfp->accf_name);
120		splx(s);
121		break;
122
123	case MOD_SHUTDOWN:
124		error = 0;
125		break;
126
127	default:
128		error = EOPNOTSUPP;
129		break;
130	}
131
132	return (error);
133}
134