Subject: pfil changes for ipv6
To: None <tech-net@netbsd.org>
From: Darren Reed <darrenr@reed.wattle.id.au>
List: tech-net
Date: 02/15/2000 01:55:22
Below are a set of patches I'd like to commit this week to make it
possible to use the pfil interface with IPv6.  I posted these some
time last year but then subsequently forgot about this and let it
fall by the wayside.

In summary, it moves the pfil details into protosw, adding pr_pfh
to protosw and an include for <net/pfil.h> to <sys/protosw.h>, so
providing the capability to add per-protocol filtering if desired.
Other than that, an extern for inetsw is added to protosw.h and
subsequent per-file extern's removed.

This will obviously require a kernel letter rev. bump. 

Patches below for /sys/sys, /sys/net, /sys/netinet and /sys/netinet6.

Comments ?

Darren

diff -cr sys/net/pfil.c /sys/net/pfil.c
*** sys/net/pfil.c	Mon Oct 11 03:24:28 1999
--- /sys/net/pfil.c	Tue Feb 15 20:41:27 2000
***************
*** 35,63 ****
  #include <sys/socketvar.h>
  #include <sys/systm.h>
  #include <sys/proc.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_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()
  {
  
! 	TAILQ_INIT(&pfil_in_list);
! 	TAILQ_INIT(&pfil_out_list);
! 	done_pfil_init = 1;
  }
  
  /*
--- 35,60 ----
  #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>
  
! 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(ph)
! 	 struct pfil_head *ph;
  {
  
! 	TAILQ_INIT(&ph->ph_in);
! 	TAILQ_INIT(&ph->ph_out);
! 	ph->ph_init = 1;
  }
  
  /*
***************
*** 69,89 ****
   *	PFIL_WAITOK	OK to call malloc with M_WAITOK.
   */
  void
! pfil_add_hook(func, flags)
  	int	(*func) __P((void *, int, struct ifnet *, int,
  			     struct mbuf **));
  	int	flags;
  {
  
! 	if (done_pfil_init == 0)
! 		pfil_init();
  
  	if (flags & PFIL_IN)
! 		pfil_list_add(&pfil_in_list, func, PFIL_IN |
! 		    (flags & PFIL_WAITOK));
  	if (flags & PFIL_OUT)
! 		pfil_list_add(&pfil_out_list, func, PFIL_OUT |
! 		    (flags & PFIL_WAITOK));
  }
  
  static void
--- 66,86 ----
   *	PFIL_WAITOK	OK to call malloc with M_WAITOK.
   */
  void
! 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 (ph->ph_init == 0)
! 		pfil_init(ph);
  
  	if (flags & PFIL_IN)
! 		pfil_list_add(&ph->ph_in, func, flags);
  	if (flags & PFIL_OUT)
! 		pfil_list_add(&ph->ph_out, func, flags);
  }
  
  static void
***************
*** 91,97 ****
  	pfil_list_t *list;
  	int	(*func) __P((void *, int, struct ifnet *, int,
  			     struct mbuf **));
! 	int	flags;
  {
  	struct packet_filter_hook *pfh;
  
--- 88,94 ----
  	pfil_list_t *list;
  	int	(*func) __P((void *, int, struct ifnet *, int,
  			     struct mbuf **));
! 	int flags;
  {
  	struct packet_filter_hook *pfh;
  
***************
*** 99,114 ****
  	    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);
  }
  
  /*
--- 96,107 ----
  	    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.
  	 */
! 	TAILQ_INSERT_TAIL(list, pfh, pfil_link);
  }
  
  /*
***************
*** 116,134 ****
   * hook list.
   */
  void
! pfil_remove_hook(func, flags)
  	int	(*func) __P((void *, int, struct ifnet *, int,
  			     struct mbuf **));
  	int	flags;
  {
  
! 	if (done_pfil_init == 0)
! 		pfil_init();
  
  	if (flags & PFIL_IN)
! 		pfil_list_remove(&pfil_in_list, func);
  	if (flags & PFIL_OUT)
! 		pfil_list_remove(&pfil_out_list, func);
  }
  
  /*
--- 109,129 ----
   * hook list.
   */
  void
! 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 (ph->ph_init == 0)
! 		pfil_init(ph);
  
  	if (flags & PFIL_IN)
! 		pfil_list_remove(&ph->ph_in, func);
  	if (flags & PFIL_OUT)
! 		pfil_list_remove(&ph->ph_out, func);
  }
  
  /*
***************
*** 156,171 ****
  }
  
  struct packet_filter_hook *
! pfil_hook_get(flag)
  	int flag;
  {
  
! 	if (done_pfil_init)
  		switch (flag) {
  		case PFIL_IN:
! 			return (pfil_in_list.tqh_first);
  		case PFIL_OUT:
! 			return (pfil_out_list.tqh_first);
  		}
  	return NULL;
  }
--- 151,168 ----
  }
  
  struct packet_filter_hook *
! pfil_hook_get(flag, psw)
  	int flag;
+ 	struct protosw *psw;
  {
+ 	struct	pfil_head	*ph = &psw->pr_pfh;	
  
! 	if (ph->ph_init != 0)
  		switch (flag) {
  		case PFIL_IN:
! 			return (ph->ph_in.tqh_first);
  		case PFIL_OUT:
! 			return (ph->ph_out.tqh_first);
  		}
  	return NULL;
  }
Only in /sys/net: pfil.c.dist
Only in /sys/net: pfil.c.orig
Only in /sys/net: pfil.c.rej
diff -cr sys/net/pfil.h /sys/net/pfil.h
*** sys/net/pfil.h	Fri Mar 20 02:45:30 1998
--- /sys/net/pfil.h	Tue Feb 15 20:15:04 2000
***************
*** 31,41 ****
  #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>
  
  /*
   * The packet filter hooks are designed for anything to call them to
   * possibly intercept the packet.
--- 31,42 ----
  #ifndef _NET_PFIL_H_
  #define _NET_PFIL_H_
  
  #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,63 ****
  
  #define PFIL_IN		0x00000001
  #define PFIL_OUT	0x00000002
! #define PFIL_WAITOK	0x00000008
  #define PFIL_ALL	(PFIL_IN|PFIL_OUT)
  
! struct packet_filter_hook *pfil_hook_get __P((int));
  void	pfil_add_hook __P((int (*func) __P((void *, int,
! 	    struct ifnet *, int, struct mbuf **)), int));
  void	pfil_remove_hook __P((int (*func) __P((void *, int,
! 	    struct ifnet *, int, struct mbuf **)), int));
! #endif /* _KERNEL */
  
  /* XXX */
  #if defined(_KERNEL) && !defined(_LKM)
--- 50,71 ----
  
  #define PFIL_IN		0x00000001
  #define PFIL_OUT	0x00000002
! #define PFIL_WAITOK	0x00000004
  #define PFIL_ALL	(PFIL_IN|PFIL_OUT)
  
! 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 protosw *));
  void	pfil_remove_hook __P((int (*func) __P((void *, int,
! 	    struct ifnet *, int, struct mbuf **)), int, struct protosw *));
  
  /* XXX */
  #if defined(_KERNEL) && !defined(_LKM)
Only in /sys/net: pfil.h.dist
Only in /sys/net: pfil.h.orig
Only in /sys/netinet: Makefile.foo
Only in /sys/netinet: fil.c.foo
diff -cr sys/netinet/in.h /sys/netinet/in.h
*** sys/netinet/in.h	Thu Dec 16 03:13:48 1999
--- /sys/netinet/in.h	Tue Feb 15 20:15:04 2000
***************
*** 372,377 ****
--- 372,378 ----
  
  #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));
Only in /sys/netinet: in.h.orig
diff -cr sys/netinet/in_proto.c /sys/netinet/in_proto.c
*** sys/netinet/in_proto.c	Thu Dec 16 03:13:48 1999
--- /sys/netinet/in_proto.c	Tue Feb 15 20:15:04 2000
***************
*** 267,272 ****
--- 267,274 ----
        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
  
Only in /sys/netinet: in_proto.c.orig
Only in /sys/netinet: ip_auth.c.foo
Only in /sys/netinet: ip_auth.h.foo
Only in /sys/netinet: ip_compat.h.foo
diff -cr sys/netinet/ip_fil.c /sys/netinet/ip_fil.c
*** sys/netinet/ip_fil.c	Thu Feb  3 04:02:42 2000
--- /sys/netinet/ip_fil.c	Tue Feb 15 20:45:52 2000
***************
*** 263,269 ****
  		return -1;
  
  # ifdef NETBSD_PF
! 	pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
  # endif
  
  # ifdef __sgi
--- 263,270 ----
  		return -1;
  
  # ifdef NETBSD_PF
! 	pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
! 		      &inetsw[ip_protox[IPPROTO_IP]]);
  # endif
  
  # ifdef __sgi
***************
*** 341,347 ****
  	fr_running = 0;
  
  # ifdef NETBSD_PF
! 	pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
  # endif
  
  # ifdef __sgi
--- 342,349 ----
  	fr_running = 0;
  
  # ifdef NETBSD_PF
! 	pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
! 			 &inetsw[ip_protox[IPPROTO_IP]]);
  # endif
  
  # ifdef __sgi
Only in /sys/netinet: ip_fil.c.dist
Only in /sys/netinet: ip_fil.c.foo
Only in /sys/netinet: ip_fil.h.foo
Only in /sys/netinet: ip_frag.c.foo
Only in /sys/netinet: ip_frag.h.foo
Only in /sys/netinet: ip_ftp_pxy.c.foo
diff -cr sys/netinet/ip_icmp.c /sys/netinet/ip_icmp.c
*** sys/netinet/ip_icmp.c	Thu Jan 27 04:10:25 2000
--- /sys/netinet/ip_icmp.c	Tue Feb 15 20:15:04 2000
***************
*** 153,160 ****
  /*static*/ int	ip_next_mtu __P((int, int));
  #endif
  
- extern	struct protosw inetsw[];
- 
  static void icmp_mtudisc __P((struct icmp *));
  static void icmp_mtudisc_timeout __P((struct rtentry *, struct rttimer *));
  
--- 153,158 ----
***************
*** 280,286 ****
  	struct in_ifaddr *ia;
  	void *(*ctlfunc) __P((int, struct sockaddr *, void *));
  	int code;
- 	extern u_char ip_protox[];
  	int hlen;
  	va_list ap;
  
--- 278,283 ----
Only in /sys/netinet: ip_icmp.c.orig
diff -cr sys/netinet/ip_input.c /sys/netinet/ip_input.c
*** sys/netinet/ip_input.c	Wed Feb  2 03:52:59 2000
--- /sys/netinet/ip_input.c	Tue Feb 15 20:15:04 2000
***************
*** 194,201 ****
  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;
--- 194,199 ----
***************
*** 463,471 ****
  	 * in the list may have previously cleared it.
  	 */
  	m0 = m;
! 	for (pfh = pfil_hook_get(PFIL_IN); pfh; pfh = pfh->pfil_link.tqe_next)
  		if (pfh->pfil_func) {
! 			rv = pfh->pfil_func(ip, hlen, m->m_pkthdr.rcvif, 0, &m0);
  			if (rv)
  				return;
  			m = m0;
--- 461,471 ----
  	 * in the list may have previously cleared it.
  	 */
  	m0 = m;
! 	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);
  			if (rv)
  				return;
  			m = m0;
Only in /sys/netinet: ip_input.c.orig
Only in /sys/netinet: ip_log.c.foo
Only in /sys/netinet: ip_nat.c.foo
Only in /sys/netinet: ip_nat.h.foo
diff -cr sys/netinet/ip_output.c /sys/netinet/ip_output.c
*** sys/netinet/ip_output.c	Tue Feb  1 03:54:33 2000
--- /sys/netinet/ip_output.c	Tue Feb 15 20:15:05 2000
***************
*** 417,423 ****
  	 * Run through list of hooks for output packets.
  	 */
  	m1 = m;
! 	for (pfh = pfil_hook_get(PFIL_OUT); pfh; pfh = pfh->pfil_link.tqe_next)
  		if (pfh->pfil_func) {
  		    	rv = pfh->pfil_func(ip, hlen, ifp, 1, &m1);
  			if (rv) {
--- 417,424 ----
  	 * Run through list of hooks for output packets.
  	 */
  	m1 = m;
! 	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) {
Only in /sys/netinet: ip_output.c.orig
Only in /sys/netinet: ip_proxy.c.foo
Only in /sys/netinet: ip_proxy.h.foo
Only in /sys/netinet: ip_state.c.foo
Only in /sys/netinet: ip_state.h.foo
diff -cr sys/netinet/raw_ip.c /sys/netinet/raw_ip.c
*** sys/netinet/raw_ip.c	Fri Feb  4 03:45:01 2000
--- /sys/netinet/raw_ip.c	Tue Feb 15 20:15:05 2000
***************
*** 95,102 ****
  #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 *));
--- 95,100 ----
Only in /sys/netinet: raw_ip.c.orig
diff -cr sys/netinet6/ah_input.c /sys/netinet6/ah_input.c
*** sys/netinet6/ah_input.c	Mon Feb  7 03:43:12 2000
--- /sys/netinet6/ah_input.c	Tue Feb 15 20:23:31 2000
***************
*** 76,84 ****
  #include <net/net_osdep.h>
  
  #ifdef INET
- extern struct protosw inetsw[];
- extern u_char ip_protox[];
- 
  void
  #if __STDC__
  ah4_input(struct mbuf *m, ...)
--- 76,81 ----
Only in /sys/netinet6: ah_input.c.orig
Only in /sys/netinet6: ah_input.c.rej
diff -cr sys/netinet6/icmp6.c /sys/netinet6/icmp6.c
*** sys/netinet6/icmp6.c	Mon Feb  7 03:43:13 2000
--- /sys/netinet6/icmp6.c	Tue Feb 15 20:24:01 2000
***************
*** 107,114 ****
  #include <net/net_osdep.h>
  
  extern struct domain inet6domain;
- extern struct ip6protosw inet6sw[];
- extern u_char ip6_protox[];
  
  struct icmp6stat icmp6stat;
  
--- 107,112 ----
Only in /sys/netinet6: icmp6.c.orig
Only in /sys/netinet6: icmp6.c.rej
diff -cr sys/netinet6/in6.h /sys/netinet6/in6.h
*** sys/netinet6/in6.h	Sat Jan  8 03:46:28 2000
--- /sys/netinet6/in6.h	Tue Feb 15 20:15:13 2000
***************
*** 592,597 ****
--- 592,598 ----
  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))
Only in /sys/netinet6: in6.h.orig
diff -cr sys/netinet6/ip6_input.c /sys/netinet6/ip6_input.c
*** sys/netinet6/ip6_input.c	Mon Feb  7 03:43:14 2000
--- /sys/netinet6/ip6_input.c	Tue Feb 15 20:26:14 2000
***************
*** 66,71 ****
--- 66,72 ----
  
  #include "opt_inet.h"
  #include "opt_ipsec.h"
+ #include "opt_pfil_hooks.h"
  
  #include <sys/param.h>
  #include <sys/systm.h>
***************
*** 86,91 ****
--- 87,95 ----
  #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,124 ****
  #include <net/net_osdep.h>
  
  extern struct domain inet6domain;
- extern struct ip6protosw inet6sw[];
  
  u_char ip6_protox[IPPROTO_MAX];
  static int ip6qmaxlen = IFQ_MAXLEN;
--- 122,127 ----
***************
*** 238,243 ****
--- 241,251 ----
  	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
  	/*
***************
*** 296,301 ****
--- 304,333 ----
  		in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
  		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]++;
  
Only in /sys/netinet6: ip6_input.c.dist
Only in /sys/netinet6: ip6_input.c.orig
Only in /sys/netinet6: ip6_input.c.rej
diff -cr sys/netinet6/ip6_output.c /sys/netinet6/ip6_output.c
*** sys/netinet6/ip6_output.c	Mon Feb  7 03:43:14 2000
--- /sys/netinet6/ip6_output.c	Tue Feb 15 20:26:39 2000
***************
*** 66,71 ****
--- 66,72 ----
  
  #include "opt_inet.h"
  #include "opt_ipsec.h"
+ #include "opt_pfil_hooks.h"
  
  #include <sys/param.h>
  #include <sys/malloc.h>
***************
*** 79,84 ****
--- 80,88 ----
  
  #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,159 ****
--- 158,168 ----
  	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,792 ****
--- 796,820 ----
  		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. 
Only in /sys/netinet6: ip6_output.c.orig
Only in /sys/netinet6: ip6_output.c.rej
diff -cr sys/netinet6/ip6protosw.h /sys/netinet6/ip6protosw.h
*** sys/netinet6/ip6protosw.h	Sat Jan  8 03:46:32 2000
--- /sys/netinet6/ip6protosw.h	Tue Feb 15 20:27:16 2000
***************
*** 74,79 ****
--- 74,80 ----
   * Protocol switch table for IPv6.
   * All other definitions should refer to sys/protosw.h
   */
+ #include <net/pfil.h>
  
  struct mbuf;
  struct sockaddr;
***************
*** 125,130 ****
--- 126,134 ----
  			__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_ */
Only in /sys/netinet6: ip6protosw.h.dist
Only in /sys/netinet6: ip6protosw.h.orig
Only in /sys/netinet6: ip6protosw.h.rej
diff -cr sys/netinet6/ipcomp_input.c /sys/netinet6/ipcomp_input.c
*** sys/netinet6/ipcomp_input.c	Mon Feb  7 03:43:14 2000
--- /sys/netinet6/ipcomp_input.c	Tue Feb 15 20:27:33 2000
***************
*** 78,86 ****
  #define IPLEN_FLIPPED
  
  #ifdef INET
- extern struct protosw inetsw[];
- extern u_char ip_protox[];
- 
  void
  #if __STDC__
  ipcomp4_input(struct mbuf *m, ...)
--- 78,83 ----
Only in /sys/netinet6: ipcomp_input.c.orig
Only in /sys/netinet6: ipcomp_input.c.rej
diff -cr sys/sys/CVS/Entries /sys/sys/CVS/Entries
*** sys/sys/CVS/Entries	Wed Feb  9 03:47:43 2000
--- /sys/sys/CVS/Entries	Tue Feb  8 03:46:31 2000
***************
*** 105,110 ****
--- 105,111 ----
  /Makefile/1.19/Tue Jan 11 16:43:59 2000//
  /null.h/1.1/Mon Jan 10 16:58:39 2000//
  /timepps.h/1.3/Wed Jan 19 16:45:52 2000//
+ /buf.h/1.38/Mon Jan 24 16:48:05 2000//
  /callout.h/1.12/Mon Jan 24 16:48:06 2000//
  /disklabel.h/1.54/Mon Jan 24 16:48:06 2000//
  /exec_elf.h/1.34/Mon Jan 24 16:48:06 2000//
***************
*** 115,120 ****
--- 116,122 ----
  /file.h/1.22/Tue Feb  1 16:53:35 2000//
  /syscall.h/1.106/Tue Feb  1 16:53:36 2000//
  /syscallargs.h/1.87/Tue Feb  1 16:53:36 2000//
+ /param.h/1.85/Wed Feb  2 17:02:49 2000//
  /bswap.h/1.2/Thu Feb  3 16:45:05 2000//
  /cdefs.h/1.31/Thu Feb  3 16:45:05 2000//
  /socket.h/1.49/Thu Feb  3 16:45:05 2000//
***************
*** 124,129 ****
  /protosw.h/1.21/Sun Feb  6 16:43:18 2000//
  /sysctl.h/1.40/Sun Feb  6 16:43:18 2000//
  /proc.h/1.85/Mon Feb  7 16:46:31 2000//
- /buf.h/1.39/Tue Feb  8 16:47:43 2000//
- /param.h/1.86/Tue Feb  8 16:47:43 2000//
  D
--- 126,129 ----
diff -cr sys/sys/buf.h /sys/sys/buf.h
*** sys/sys/buf.h	Wed Feb  9 03:47:43 2000
--- /sys/sys/buf.h	Tue Jan 25 03:48:05 2000
***************
*** 1,4 ****
! /*	$NetBSD: buf.h,v 1.39 2000/02/07 20:16:59 thorpej Exp $	*/
  
  /*-
   * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
--- 1,4 ----
! /*	$NetBSD: buf.h,v 1.38 2000/01/24 04:56:02 thorpej Exp $	*/
  
  /*-
   * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
***************
*** 181,190 ****
  	} b_un;
  	void	*b_saveaddr;		/* Original b_addr for physio. */
  	daddr_t	b_lblkno;		/* Logical block number. */
! 	daddr_t	b_blkno;		/* Underlying physical block number
! 					   (partition relative) */
! 	daddr_t	b_rawblkno;		/* Raw underlying physical block
! 					   number (not partition relative) */
  					/* Function to call upon completion. */
  	void	(*b_iodone) __P((struct buf *));
  	struct	vnode *b_vp;		/* Device vnode. */
--- 181,187 ----
  	} b_un;
  	void	*b_saveaddr;		/* Original b_addr for physio. */
  	daddr_t	b_lblkno;		/* Logical block number. */
! 	daddr_t	b_blkno;		/* Underlying physical block number. */
  					/* Function to call upon completion. */
  	void	(*b_iodone) __P((struct buf *));
  	struct	vnode *b_vp;		/* Device vnode. */
diff -cr sys/sys/param.h /sys/sys/param.h
*** sys/sys/param.h	Wed Feb  9 03:47:43 2000
--- /sys/sys/param.h	Thu Feb  3 04:02:49 2000
***************
*** 1,4 ****
! /*	$NetBSD: param.h,v 1.86 2000/02/07 20:19:13 thorpej Exp $	*/
  
  /*-
   * Copyright (c) 1982, 1986, 1989, 1993
--- 1,4 ----
! /*	$NetBSD: param.h,v 1.85 2000/02/01 23:00:41 thorpej Exp $	*/
  
  /*-
   * Copyright (c) 1982, 1986, 1989, 1993
***************
*** 65,71 ****
   *
   */
  
! #define __NetBSD_Version__  104190000	/* NetBSD 1.4S */
  
  /*
   * Historical NetBSD #define
--- 65,71 ----
   *
   */
  
! #define __NetBSD_Version__  104180000	/* NetBSD 1.4R */
  
  /*
   * Historical NetBSD #define
diff -cr sys/sys/protosw.h /sys/sys/protosw.h
*** sys/sys/protosw.h	Mon Feb  7 03:43:18 2000
--- /sys/sys/protosw.h	Tue Feb 15 20:40:00 2000
***************
*** 61,66 ****
--- 61,71 ----
   * described below.
   */
  
+ /*
+  * For pfil_head structure.
+  */
+ #include <net/pfil.h>
+ 
  struct mbuf;
  struct sockaddr;
  struct socket;
***************
*** 100,105 ****
--- 105,111 ----
  			__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,263 ****
--- 264,270 ----
  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 */
  
Only in /sys/sys: protosw.h.dist