uipc_accf.c revision 61837
161837Salfred/*-
261837Salfred * Copyright (c) 2000 Alfred Perlstein <alfred@FreeBSD.org>
361837Salfred * All rights reserved.
461837Salfred *
561837Salfred * Redistribution and use in source and binary forms, with or without
661837Salfred * modification, are permitted provided that the following conditions
761837Salfred * are met:
861837Salfred * 1. Redistributions of source code must retain the above copyright
961837Salfred *    notice, this list of conditions and the following disclaimer.
1061837Salfred * 2. Redistributions in binary form must reproduce the above copyright
1161837Salfred *    notice, this list of conditions and the following disclaimer in the
1261837Salfred *    documentation and/or other materials provided with the distribution.
1361837Salfred *
1461837Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1561837Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1661837Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1761837Salfred * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1861837Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1961837Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2061837Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2161837Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2261837Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2361837Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2461837Salfred * SUCH DAMAGE.
2561837Salfred *
2661837Salfred *	$FreeBSD: head/sys/kern/uipc_accf.c 61837 2000-06-20 01:09:23Z alfred $
2761837Salfred */
2861837Salfred
2961837Salfred#define ACCEPT_FILTER_MOD
3061837Salfred
3161837Salfred#include "opt_param.h"
3261837Salfred#include <sys/param.h>
3361837Salfred#include <sys/systm.h>
3461837Salfred#include <sys/domain.h>
3561837Salfred#include <sys/kernel.h>
3661837Salfred#include <sys/proc.h>
3761837Salfred#include <sys/malloc.h>
3861837Salfred#include <sys/mbuf.h>
3961837Salfred#include <sys/protosw.h>
4061837Salfred#include <sys/socket.h>
4161837Salfred#include <sys/socketvar.h>
4261837Salfred#include <sys/queue.h>
4361837Salfred
4461837Salfredstatic SLIST_HEAD(, accept_filter) accept_filtlsthd =
4561837Salfred	SLIST_HEAD_INITIALIZER(&accept_filtlsthd);
4661837Salfred
4761837SalfredMALLOC_DEFINE(M_ACCF, "accf", "accept filter data");
4861837Salfred
4961837Salfred/*
5061837Salfred * must be passed a malloc'd structure so we don't explode if the kld
5161837Salfred * is unloaded, we leak the struct on deallocation to deal with this,
5261837Salfred * but if a filter is loaded with the same name as a leaked one we re-use
5361837Salfred * the entry.
5461837Salfred */
5561837Salfredint
5661837Salfredaccept_filt_add(struct accept_filter *filt)
5761837Salfred{
5861837Salfred	struct accept_filter *p;
5961837Salfred
6061837Salfred	SLIST_FOREACH(p, &accept_filtlsthd, accf_next)
6161837Salfred		if (strcmp(p->accf_name, filt->accf_name) == 0)  {
6261837Salfred			if (p->accf_callback != NULL) {
6361837Salfred				return (EEXIST);
6461837Salfred			} else {
6561837Salfred				p->accf_callback = filt->accf_callback;
6661837Salfred				FREE(filt, M_ACCF);
6761837Salfred				return (0);
6861837Salfred			}
6961837Salfred		}
7061837Salfred
7161837Salfred	if (p == NULL)
7261837Salfred		SLIST_INSERT_HEAD(&accept_filtlsthd, filt, accf_next);
7361837Salfred	return (0);
7461837Salfred}
7561837Salfred
7661837Salfredint
7761837Salfredaccept_filt_del(char *name)
7861837Salfred{
7961837Salfred	struct accept_filter *p;
8061837Salfred
8161837Salfred	p = accept_filt_get(name);
8261837Salfred	if (p == NULL)
8361837Salfred		return (ENOENT);
8461837Salfred
8561837Salfred	p->accf_callback = NULL;
8661837Salfred	return (0);
8761837Salfred}
8861837Salfred
8961837Salfredstruct accept_filter *
9061837Salfredaccept_filt_get(char *name)
9161837Salfred{
9261837Salfred	struct accept_filter *p;
9361837Salfred
9461837Salfred	SLIST_FOREACH(p, &accept_filtlsthd, accf_next)
9561837Salfred		if (strcmp(p->accf_name, name) == 0)
9661837Salfred			return (p);
9761837Salfred
9861837Salfred	return (NULL);
9961837Salfred}
10061837Salfred
10161837Salfredint
10261837Salfredaccept_filt_generic_mod_event(module_t mod, int event, void *data)
10361837Salfred{
10461837Salfred	struct accept_filter *p;
10561837Salfred	struct accept_filter *accfp = (struct accept_filter *) data;
10661837Salfred	int	s, error;
10761837Salfred
10861837Salfred	switch (event) {
10961837Salfred	case MOD_LOAD:
11061837Salfred		MALLOC(p, struct accept_filter *, sizeof(*p), M_ACCF, M_WAITOK);
11161837Salfred		bcopy(accfp, p, sizeof(*p));
11261837Salfred		s = splnet();
11361837Salfred		error = accept_filt_add(p);
11461837Salfred		splx(s);
11561837Salfred		break;
11661837Salfred
11761837Salfred	case MOD_UNLOAD:
11861837Salfred		s = splnet();
11961837Salfred		error = accept_filt_del(accfp->accf_name);
12061837Salfred		splx(s);
12161837Salfred		break;
12261837Salfred
12361837Salfred	case MOD_SHUTDOWN:
12461837Salfred		error = 0;
12561837Salfred		break;
12661837Salfred
12761837Salfred	default:
12861837Salfred		error = EOPNOTSUPP;
12961837Salfred		break;
13061837Salfred	}
13161837Salfred
13261837Salfred	return (error);
13361837Salfred}
134