Change the use of pfil hooks. There is no longer a single list of all

pfil information, instead, struct protosw now contains a structure
which caontains list heads, etc.  The per-protosw pfil struct is passed
to pfil_hook_get(), along with an in/out flag to get the head of the
relevant filter list.  This has been done for only IPv4 and IPv6, at
present, with these patches only enabling filtering for IPPROTO_IP and
IPPROTO_IPV6, although it is possible to have tcp/udp, etc, dedicated
filters now also.  The ipfilter code has been updated to only filter
IPv4 packets - next major release of ipfilter is required for ipv6.
This commit is contained in:
darrenr 2000-02-17 10:59:32 +00:00
parent 376d66b867
commit fd7edad6c3
17 changed files with 149 additions and 79 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pfil.c,v 1.9 1999/10/10 09:07:32 mrg Exp $ */
/* $NetBSD: pfil.c,v 1.10 2000/02/17 10:59:32 darrenr Exp $ */
/*
* Copyright (c) 1996 Matthew R. Green
@ -35,29 +35,26 @@
#include <sys/socketvar.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/queue.h>
#include <net/if.h>
#include <net/pfil.h>
typedef TAILQ_HEAD(, packet_filter_hook) pfil_list_t;
pfil_list_t pfil_in_list;
pfil_list_t pfil_out_list;
static int done_pfil_init;
static void pfil_init __P((void));
static void pfil_init __P((struct pfil_head *));
static void pfil_list_add(pfil_list_t *,
int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)), int);
static void pfil_list_remove(pfil_list_t *,
int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)));
static void
pfil_init()
pfil_init(ph)
struct pfil_head *ph;
{
TAILQ_INIT(&pfil_in_list);
TAILQ_INIT(&pfil_out_list);
done_pfil_init = 1;
TAILQ_INIT(&ph->ph_in);
TAILQ_INIT(&ph->ph_out);
ph->ph_init = 1;
}
/*
@ -69,21 +66,21 @@ pfil_init()
* PFIL_WAITOK OK to call malloc with M_WAITOK.
*/
void
pfil_add_hook(func, flags)
pfil_add_hook(func, flags, psw)
int (*func) __P((void *, int, struct ifnet *, int,
struct mbuf **));
int flags;
struct protosw *psw;
{
struct pfil_head *ph = &psw->pr_pfh;
if (done_pfil_init == 0)
pfil_init();
if (ph->ph_init == 0)
pfil_init(ph);
if (flags & PFIL_IN)
pfil_list_add(&pfil_in_list, func, PFIL_IN |
(flags & PFIL_WAITOK));
pfil_list_add(&ph->ph_in, func, flags);
if (flags & PFIL_OUT)
pfil_list_add(&pfil_out_list, func, PFIL_OUT |
(flags & PFIL_WAITOK));
pfil_list_add(&ph->ph_out, func, flags);
}
static void
@ -91,7 +88,7 @@ pfil_list_add(list, func, flags)
pfil_list_t *list;
int (*func) __P((void *, int, struct ifnet *, int,
struct mbuf **));
int flags;
int flags;
{
struct packet_filter_hook *pfh;
@ -99,16 +96,12 @@ pfil_list_add(list, func, flags)
flags & PFIL_WAITOK ? M_WAITOK : M_NOWAIT);
if (pfh == NULL)
panic("no memory for packet filter hook");
pfh->pfil_func = func;
/*
* insert the input list in reverse order of the output list
* so that the same path is followed in or out of the kernel.
*/
if (flags & PFIL_IN)
TAILQ_INSERT_HEAD(list, pfh, pfil_link);
else
TAILQ_INSERT_TAIL(list, pfh, pfil_link);
TAILQ_INSERT_TAIL(list, pfh, pfil_link);
}
/*
@ -116,19 +109,21 @@ pfil_list_add(list, func, flags)
* hook list.
*/
void
pfil_remove_hook(func, flags)
pfil_remove_hook(func, flags, psw)
int (*func) __P((void *, int, struct ifnet *, int,
struct mbuf **));
int flags;
struct protosw *psw;
{
struct pfil_head *ph = &psw->pr_pfh;
if (done_pfil_init == 0)
pfil_init();
if (ph->ph_init == 0)
pfil_init(ph);
if (flags & PFIL_IN)
pfil_list_remove(&pfil_in_list, func);
pfil_list_remove(&ph->ph_in, func);
if (flags & PFIL_OUT)
pfil_list_remove(&pfil_out_list, func);
pfil_list_remove(&ph->ph_out, func);
}
/*
@ -156,16 +151,18 @@ pfil_list_remove(list, func)
}
struct packet_filter_hook *
pfil_hook_get(flag)
pfil_hook_get(flag, psw)
int flag;
struct protosw *psw;
{
struct pfil_head *ph = &psw->pr_pfh;
if (done_pfil_init)
if (ph->ph_init != 0)
switch (flag) {
case PFIL_IN:
return (pfil_in_list.tqh_first);
return (ph->ph_in.tqh_first);
case PFIL_OUT:
return (pfil_out_list.tqh_first);
return (ph->ph_out.tqh_first);
}
return NULL;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pfil.h,v 1.9 1998/03/19 15:45:30 mrg Exp $ */
/* $NetBSD: pfil.h,v 1.10 2000/02/17 10:59:32 darrenr Exp $ */
/*
* Copyright (c) 1996 Matthew R. Green
@ -31,11 +31,12 @@
#ifndef _NET_PFIL_H_
#define _NET_PFIL_H_
/* note: this file needs <net/if.h> and <sys/mbuf.h> */
#ifdef _KERNEL
#include <sys/queue.h>
struct protosw;
struct mbuf;
struct ifnet;
/*
* The packet filter hooks are designed for anything to call them to
* possibly intercept the packet.
@ -49,15 +50,22 @@ struct packet_filter_hook {
#define PFIL_IN 0x00000001
#define PFIL_OUT 0x00000002
#define PFIL_WAITOK 0x00000008
#define PFIL_WAITOK 0x00000004
#define PFIL_ALL (PFIL_IN|PFIL_OUT)
struct packet_filter_hook *pfil_hook_get __P((int));
typedef TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t;
struct pfil_head {
pfil_list_t ph_in;
pfil_list_t ph_out;
int ph_init;
} pfil_head_t;
struct packet_filter_hook *pfil_hook_get __P((int, struct protosw *));
void pfil_add_hook __P((int (*func) __P((void *, int,
struct ifnet *, int, struct mbuf **)), int));
struct ifnet *, int, struct mbuf **)), int, struct protosw *));
void pfil_remove_hook __P((int (*func) __P((void *, int,
struct ifnet *, int, struct mbuf **)), int));
#endif /* _KERNEL */
struct ifnet *, int, struct mbuf **)), int, struct protosw *));
/* XXX */
#if defined(_KERNEL) && !defined(_LKM)

View File

@ -1,4 +1,4 @@
/* $NetBSD: in.h,v 1.45 2000/02/09 00:54:55 itojun Exp $ */
/* $NetBSD: in.h,v 1.46 2000/02/17 10:59:35 darrenr Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -374,6 +374,7 @@ struct ip_mreq {
#ifdef _KERNEL
extern struct in_addr zeroin_addr;
extern u_char ip_protox[];
int in_broadcast __P((struct in_addr, struct ifnet *));
int in_canforward __P((struct in_addr));

View File

@ -1,4 +1,4 @@
/* $NetBSD: in_proto.c,v 1.37 2000/02/15 19:54:11 thorpej Exp $ */
/* $NetBSD: in_proto.c,v 1.38 2000/02/17 10:59:35 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -267,6 +267,8 @@ struct domain inetdomain =
inetsw, &inetsw[sizeof(inetsw)/sizeof(inetsw[0])], 0,
rn_inithead, 32, sizeof(struct sockaddr_in) };
u_char ip_protox[IPPROTO_MAX];
#define TCP_SYN_HASH_SIZE 293
#define TCP_SYN_BUCKET_SIZE 35

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_fil.c,v 1.40 2000/02/01 21:41:36 veego Exp $ */
/* $NetBSD: ip_fil.c,v 1.41 2000/02/17 10:59:35 darrenr Exp $ */
/*
* Copyright (C) 1993-1998 by Darren Reed.
@ -9,7 +9,7 @@
*/
#if !defined(lint)
#if defined(__NetBSD__)
static const char rcsid[] = "$NetBSD: ip_fil.c,v 1.40 2000/02/01 21:41:36 veego Exp $";
static const char rcsid[] = "$NetBSD: ip_fil.c,v 1.41 2000/02/17 10:59:35 darrenr Exp $";
#else
static const char sccsid[] = "@(#)ip_fil.c 2.41 6/5/96 (C) 1993-1995 Darren Reed";
static const char rcsid[] = "@(#)Id: ip_fil.c,v 2.4.2.16 2000/01/16 10:12:42 darrenr Exp";
@ -263,7 +263,8 @@ int iplattach()
return -1;
# ifdef NETBSD_PF
pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]]);
# endif
# ifdef __sgi
@ -341,7 +342,8 @@ int ipldetach()
fr_running = 0;
# ifdef NETBSD_PF
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
&inetsw[ip_protox[IPPROTO_IP]]);
# endif
# ifdef __sgi

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_icmp.c,v 1.40 2000/02/15 04:03:49 thorpej Exp $ */
/* $NetBSD: ip_icmp.c,v 1.41 2000/02/17 10:59:35 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -153,8 +153,6 @@ static int ip_next_mtu __P((int, int));
/*static*/ int ip_next_mtu __P((int, int));
#endif
extern struct protosw inetsw[];
extern struct timeval icmperrratelim;
static void icmp_mtudisc __P((struct icmp *));
@ -293,7 +291,6 @@ icmp_input(m, va_alist)
struct in_ifaddr *ia;
void *(*ctlfunc) __P((int, struct sockaddr *, void *));
int code;
extern u_char ip_protox[];
int hlen;
va_list ap;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_input.c,v 1.100 2000/02/16 12:40:40 itojun Exp $ */
/* $NetBSD: ip_input.c,v 1.101 2000/02/17 10:59:35 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -194,8 +194,6 @@ int ipprintfs = 0;
struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
extern struct domain inetdomain;
extern struct protosw inetsw[];
u_char ip_protox[IPPROTO_MAX];
int ipqmaxlen = IFQ_MAXLEN;
struct in_ifaddrhead in_ifaddr;
struct in_ifaddrhashhead *in_ifaddrhashtbl;
@ -466,9 +464,11 @@ ip_input(struct mbuf *m)
* in the list may have previously cleared it.
*/
m0 = m;
for (pfh = pfil_hook_get(PFIL_IN); pfh; pfh = pfh->pfil_link.tqe_next)
pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IP]]);
for (; pfh; pfh = pfh->pfil_link.tqe_next)
if (pfh->pfil_func) {
rv = pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0);
rv = pfh->pfil_func(ip, hlen,
m->m_pkthdr.rcvif, 0, &m0);
if (rv)
return;
m = m0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip_output.c,v 1.66 2000/01/31 14:18:55 itojun Exp $ */
/* $NetBSD: ip_output.c,v 1.67 2000/02/17 10:59:35 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -417,7 +417,8 @@ sendit:
* Run through list of hooks for output packets.
*/
m1 = m;
for (pfh = pfil_hook_get(PFIL_OUT); pfh; pfh = pfh->pfil_link.tqe_next)
pfh = pfil_hook_get(PFIL_OUT, &inetsw[ip_protox[IPPROTO_IP]]);
for (; pfh; pfh = pfh->pfil_link.tqe_next)
if (pfh->pfil_func) {
rv = pfh->pfil_func(ip, hlen, ifp, 1, &m1);
if (rv) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: raw_ip.c,v 1.50 2000/02/02 23:28:09 thorpej Exp $ */
/* $NetBSD: raw_ip.c,v 1.51 2000/02/17 10:59:36 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -95,8 +95,6 @@
#include <netinet6/ipsec.h>
#endif /*IPSEC*/
extern u_char ip_protox[];
extern struct protosw inetsw[];
struct inpcbtable rawcbtable;
int rip_bind __P((struct inpcb *, struct mbuf *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: ah_input.c,v 1.8 2000/02/06 12:49:42 itojun Exp $ */
/* $NetBSD: ah_input.c,v 1.9 2000/02/17 10:59:38 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -76,9 +76,6 @@
#include <net/net_osdep.h>
#ifdef INET
extern struct protosw inetsw[];
extern u_char ip_protox[];
void
#if __STDC__
ah4_input(struct mbuf *m, ...)

View File

@ -1,4 +1,4 @@
/* $NetBSD: icmp6.c,v 1.21 2000/02/15 00:31:08 thorpej Exp $ */
/* $NetBSD: icmp6.c,v 1.22 2000/02/17 10:59:38 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -107,8 +107,6 @@
#include <net/net_osdep.h>
extern struct domain inet6domain;
extern struct ip6protosw inet6sw[];
extern u_char ip6_protox[];
struct icmp6stat icmp6stat;

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.h,v 1.10 2000/02/09 00:54:56 itojun Exp $ */
/* $NetBSD: in6.h,v 1.11 2000/02/17 10:59:39 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -596,6 +596,7 @@ int in6_addrscope __P((struct in6_addr *));
struct in6_ifaddr *in6_ifawithscope __P((struct ifnet *, struct in6_addr *));
struct in6_ifaddr *in6_ifawithifp __P((struct ifnet *, struct in6_addr *));
extern void in6_if_up __P((struct ifnet *));
extern u_char ip6_protox[];
#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
#define sin6tosa(sin6) ((struct sockaddr *)(sin6))

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_input.c,v 1.14 2000/02/06 12:49:45 itojun Exp $ */
/* $NetBSD: ip6_input.c,v 1.15 2000/02/17 10:59:39 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -66,6 +66,7 @@
#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_pfil_hooks.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -86,6 +87,9 @@
#include <net/if_dl.h>
#include <net/route.h>
#include <net/netisr.h>
#ifdef PFIL_HOOKS
#include <net/pfil.h>
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
@ -118,7 +122,6 @@
#include <net/net_osdep.h>
extern struct domain inet6domain;
extern struct ip6protosw inet6sw[];
u_char ip6_protox[IPPROTO_MAX];
static int ip6qmaxlen = IFQ_MAXLEN;
@ -238,6 +241,11 @@ ip6_input(m)
u_int32_t rtalert = ~0;
int nxt, ours = 0;
struct ifnet *deliverifp = NULL;
#ifdef PFIL_HOOKS
struct packet_filter_hook *pfh;
struct mbuf *m0;
int rv;
#endif /* PFIL_HOOKS */
#ifdef IPSEC
/*
@ -297,6 +305,30 @@ ip6_input(m)
goto bad;
}
#ifdef PFIL_HOOKS
/*
* Run through list of hooks for input packets. If there are any
* filters which require that additional packets in the flow are
* not fast-forwarded, they must clear the M_CANFASTFWD flag.
* Note that filters must _never_ set this flag, as another filter
* in the list may have previously cleared it.
*/
m0 = m;
pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IPV6]]);
for (; pfh; pfh = pfh->pfil_link.tqe_next)
if (pfh->pfil_func) {
rv = pfh->pfil_func(ip6, sizeof(*ip6),
m->m_pkthdr.rcvif, 0, &m0);
if (rv)
return;
m = m0;
if (m == NULL)
return;
ip6 = mtod(m, struct ip6_hdr *);
}
#endif /* PFIL_HOOKS */
ip6stat.ip6s_nxthist[ip6->ip6_nxt]++;
#ifdef IPV6FIREWALL

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_output.c,v 1.14 2000/02/06 12:49:46 itojun Exp $ */
/* $NetBSD: ip6_output.c,v 1.15 2000/02/17 10:59:39 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -66,6 +66,7 @@
#include "opt_inet.h"
#include "opt_ipsec.h"
#include "opt_pfil_hooks.h"
#include <sys/param.h>
#include <sys/malloc.h>
@ -79,6 +80,9 @@
#include <net/if.h>
#include <net/route.h>
#ifdef PFIL_HOOKS
#include <net/pfil.h>
#endif
#include <netinet/in.h>
#include <netinet/in_var.h>
@ -154,6 +158,11 @@ ip6_output(m0, opt, ro, flags, im6o, ifpp)
struct route_in6 *ro_pmtu = NULL;
int hdrsplit = 0;
int needipsec = 0;
#ifdef PFIL_HOOKS
struct packet_filter_hook *pfh;
struct mbuf *m1;
int rv;
#endif /* PFIL_HOOKS */
#ifdef IPSEC
int needipsectun = 0;
struct socket *so;
@ -787,6 +796,25 @@ skip_ipsec2:;
m->m_pkthdr.rcvif = NULL;
}
#ifdef PFIL_HOOKS
/*
* Run through list of hooks for output packets.
*/
m1 = m;
pfh = pfil_hook_get(PFIL_OUT, &inetsw[ip_protox[IPPROTO_IPV6]]);
for (; pfh; pfh = pfh->pfil_link.tqe_next)
if (pfh->pfil_func) {
rv = pfh->pfil_func(ip6, sizeof(*ip6), ifp, 1, &m1);
if (rv) {
error = EHOSTUNREACH;
goto done;
}
m = m1;
if (m == NULL)
goto done;
ip6 = mtod(m, struct ip6_hdr *);
}
#endif /* PFIL_HOOKS */
/*
* Send the packet to the outgoing interface.
* If necessary, do IPv6 fragmentation before sending.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6protosw.h,v 1.5 2000/01/06 15:46:10 itojun Exp $ */
/* $NetBSD: ip6protosw.h,v 1.6 2000/02/17 10:59:39 darrenr Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -74,6 +74,7 @@
* Protocol switch table for IPv6.
* All other definitions should refer to sys/protosw.h
*/
#include <net/pfil.h>
struct mbuf;
struct sockaddr;
@ -125,6 +126,9 @@ struct ip6protosw {
__P((void));
int (*pr_sysctl) /* sysctl for protocol */
__P((int *, u_int, void *, size_t *, void *, size_t));
struct pfil_head pr_pfh;
};
extern struct ip6protosw inet6sw[];
#endif /* !_NETINET6_IP6PROTOSW_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipcomp_input.c,v 1.9 2000/02/06 12:49:46 itojun Exp $ */
/* $NetBSD: ipcomp_input.c,v 1.10 2000/02/17 10:59:39 darrenr Exp $ */
/*
* Copyright (C) 1999 WIDE Project.
@ -78,9 +78,6 @@
#define IPLEN_FLIPPED
#ifdef INET
extern struct protosw inetsw[];
extern u_char ip_protox[];
void
#if __STDC__
ipcomp4_input(struct mbuf *m, ...)

View File

@ -1,4 +1,4 @@
/* $NetBSD: protosw.h,v 1.21 2000/02/06 02:54:15 thorpej Exp $ */
/* $NetBSD: protosw.h,v 1.22 2000/02/17 10:59:41 darrenr Exp $ */
/*-
* Copyright (c) 1982, 1986, 1993
@ -61,6 +61,11 @@
* described below.
*/
/*
* For pfil_head structure.
*/
#include <net/pfil.h>
struct mbuf;
struct sockaddr;
struct socket;
@ -100,6 +105,7 @@ struct protosw {
__P((void));
int (*pr_sysctl) /* sysctl for protocol */
__P((int *, u_int, void *, size_t *, void *, size_t));
struct pfil_head pr_pfh;
};
#define PR_SLOWHZ 2 /* 2 slow timeouts per second */
@ -258,6 +264,7 @@ struct sockaddr;
struct protosw *pffindproto __P((int, int, int));
struct protosw *pffindtype __P((int, int));
struct domain *pffinddomain __P((int));
extern struct protosw inetsw[];
void pfctlinput __P((int, struct sockaddr *));
#endif /* _KERNEL */