Subject: pfil/ipfilter patch
To: None <tech-net@netbsd.org>
From: Darren Reed <darrenr@reed.wattle.id.au>
List: tech-net
Date: 07/19/2005 02:36:41
I've got a patch attached below which uses the PFIL_TYPE_IFNET hook
to provide "instant" updates of when interfaces are created and
destroyed.  It does away with the need to yse "ipf -y" in any script
that does "ifconfig fooo0 <create|destroy>".

Darren

Index: ip_fil_netbsd.c
===================================================================
*** sys/dist/ipf/netinet/ip_fil_netbsd.c.orig	13 Jul 2005 21:40:45 -0000	2.55.2.29
--- sys/dist/ipf/netinet/ip_fil_netbsd.c	18 Jul 2005 01:35:46 -0000
***************
*** 205,210 ****
--- 205,231 ----
  	    ifp, (dir == PFIL_OUT), mp));
  }
  # endif
+ 
+ 
+ # ifdef PFIL_TYPE_IFNET
+ static int ipf_pfilsync(hdr, mp, ifp, dir)
+ void *hdr;
+ struct mbuf **mp;
+ struct ifnet *ifp;
+ int dir;
+ {
+ 	/*
+ 	 * The interface pointer is useless for create (we have nothing to
+ 	 * compare it to) and at detach, the interface name is still in the
+ 	 * list of active NICs (albeit, down, but that's not any real
+ 	 * indicator) and doing ifunit() on the name will still return the
+ 	 * pointer, so it's not much use then, either.
+ 	 */
+ 	frsync(NULL);
+ 	return 0;
+ }
+ # endif
+ 
  #endif /* __NetBSD_Version__ >= 105110000 */
  
  
***************
*** 245,250 ****
--- 266,274 ----
  #  ifdef USE_INET6
          struct pfil_head *ph_inet6;
  #  endif
+ #  ifdef PFIL_TYPE_IFNET
+         struct pfil_head *ph_ifsync;
+ #  endif
  # endif
  #endif
  
***************
*** 267,276 ****
--- 291,307 ----
  #   ifdef USE_INET6
  	ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
  #   endif
+ #   ifdef PFIL_TYPE_IFNET
+ 	ph_ifsync = pfil_head_get(PFIL_TYPE_IFNET, 0);
+ #   endif
+ 
  	if (ph_inet == NULL
  #   ifdef USE_INET6
  	    && ph_inet6 == NULL
  #   endif
+ #   ifdef PFIL_TYPE_IFNET
+ 	    && ph_ifsync == NULL
+ #   endif
  	   ) {
  		printf("pfil_head_get failed\n");
  		return ENODEV;
***************
*** 281,302 ****
  				      PFIL_IN|PFIL_OUT, ph_inet);
  	else
  		error = 0;
! # else
  	error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
  			      &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
- # endif
- 	if (error) {
- #  ifdef USE_INET6
- 		goto pfil_error;
- #  else
- 		fr_deinitialise();
- 		SPL_X(s);
- 		return error;
  #  endif
! 	}
  # else
  	pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
  # endif
  # ifdef USE_INET6
  #  if __NetBSD_Version__ >= 105110000
  	if (ph_inet6 != NULL)
--- 312,327 ----
  				      PFIL_IN|PFIL_OUT, ph_inet);
  	else
  		error = 0;
! #  else
  	error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
  			      &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
  #  endif
! 	if (error)
! 		goto pfil_error;
  # else
  	pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT);
  # endif
+ 
  # ifdef USE_INET6
  #  if __NetBSD_Version__ >= 105110000
  	if (ph_inet6 != NULL)
***************
*** 307,324 ****
  	if (error) {
  		pfil_remove_hook((void *)fr_check_wrapper6, NULL,
  				 PFIL_IN|PFIL_OUT, ph_inet6);
  #  else
  	error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
  			      &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
  	if (error) {
  		pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
  				 &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
! #  endif
! pfil_error:
! 		fr_deinitialise();
! 		SPL_X(s);
! 		return error;
  	}
  # endif
  #endif
  
--- 332,354 ----
  	if (error) {
  		pfil_remove_hook((void *)fr_check_wrapper6, NULL,
  				 PFIL_IN|PFIL_OUT, ph_inet6);
+ 		goto pfil_error;
+ 	}
  #  else
  	error = pfil_add_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
  			      &inetsw[ip_protox[IPPROTO_IPV6]].pr_pfh);
  	if (error) {
  		pfil_remove_hook((void *)fr_check, PFIL_IN|PFIL_OUT,
  				 &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);
! 		goto pfil_error;
  	}
+ #  endif
+ # endif
+ 
+ # ifdef PFIL_TYPE_IFNET
+ 	if (ph_ifsync != NULL)
+ 		(void) pfil_add_hook((void *)ipf_pfilsync, NULL,
+ 				     PFIL_IFNET, ph_ifsync);
  # endif
  #endif
  
***************
*** 341,346 ****
--- 371,383 ----
  	timeout(fr_slowtimer, NULL, (hz / IPF_HZ_DIVIDE) * IPF_HZ_MULT);
  #endif
  	return 0;
+ 
+ #if __NetBSD_Version__ >= 105110000
+ pfil_error:
+ 	fr_deinitialise();
+ 	SPL_X(s);
+ 	return error;
+ #endif
  }
  
  
***************
*** 358,363 ****
--- 395,403 ----
  #  ifdef USE_INET6
  	struct pfil_head *ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
  #  endif
+ #  ifdef PFIL_TYPE_IFNET
+ 	struct pfil_head *ph_ifsync = pfil_head_get(PFIL_TYPE_IFNET, 0);
+ #  endif
  # endif
  #endif
  
***************
*** 381,386 ****
--- 421,431 ----
  #ifdef NETBSD_PF
  # if (__NetBSD_Version__ >= 104200000)
  #  if __NetBSD_Version__ >= 105110000
+ #   ifdef PFIL_TYPE_IFNET
+ 	(void) pfil_remove_hook((void *)ipf_pfilsync, NULL,
+ 				PFIL_IFNET, ph_ifsync);
+ #   endif
+ 
  	if (ph_inet != NULL)
  		error = pfil_remove_hook((void *)fr_check_wrapper, NULL,
  					 PFIL_IN|PFIL_OUT, ph_inet);