Subject: kern/26403: pfil(9) doesn't support detection for interface deletion
To: None <gnats-bugs@gnats.NetBSD.org>
From: Peter Postma <peter@pointless.nl>
List: netbsd-bugs
Date: 07/22/2004 13:30:29
>Number:         26403
>Category:       kern
>Synopsis:       pfil(9) doesn't support detection for interface deletion
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jul 22 11:31:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Peter Postma
>Release:        NetBSD 2.0G
>Organization:
>Environment:
System: NetBSD mercury.pointless.nl 2.0G NetBSD 2.0G (mercury) #22: Thu Jul 22 12:48:08 CEST 2004 peter@mercury.pointless.nl:/usr/obj/sys/arch/sparc64/compile/mercury sparc64
Architecture: sparc64
Machine: sparc64
>Description:
recently there was support added to pfil(9) to detect new interfaces
or address changes on interfaces. but there's no support to detect
interface deletion.

so one could add attach routines for new interfaces but no detach routines
when the interface is deleted. that's not nice.

we should really have an interface deletion detection (PFIL_DELIF) to
support code that need a detachment routine for interfaces, e.g. pf(4).

>How-To-Repeat:
try to add detachment routine for interface deletion.

>Fix:
this patch adds support for PFIL_DELIF and adds the hook in sys/net/if.c.
pf(4) should be patched too but i've too many patches here now so i'll leave
that one for now.

Index: if.c
===================================================================
RCS file: /cvsroot/src/sys/net/if.c,v
retrieving revision 1.143
diff -u -r1.143 if.c
--- if.c	22 Jun 2004 12:50:41 -0000	1.143
+++ if.c	21 Jul 2004 14:43:27 -0000
@@ -475,7 +475,7 @@
 	if (pfil_head_register(&ifp->if_pfil) != 0)
 		printf("%s: WARNING: unable to register pfil hook\n",
 		    ifp->if_xname);
-	pfil_run_hooks(&if_pfil, NULL, ifp, PFIL_NEWIF);
+	(void)pfil_run_hooks(&if_pfil, NULL, ifp, PFIL_NEWIF);
 #endif
 
 	if (domains)
@@ -586,7 +586,8 @@
 #endif
 
 #ifdef PFIL_HOOKS
-	(void) pfil_head_unregister(&ifp->if_pfil);
+	(void)pfil_run_hooks(&if_pfil, NULL, ifp, PFIL_DELIF);
+	(void)pfil_head_unregister(&ifp->if_pfil);
 #endif
 
 	/*

Index: pfil.c
===================================================================
RCS file: /cvsroot/src/sys/net/pfil.c,v
retrieving revision 1.22
diff -u -r1.22 pfil.c
--- pfil.c	18 Jul 2004 11:36:04 -0000	1.22
+++ pfil.c	21 Jul 2004 14:43:28 -0000
@@ -107,6 +107,7 @@
 	TAILQ_INIT(&ph->ph_out);
 	TAILQ_INIT(&ph->ph_ifaddr);
 	TAILQ_INIT(&ph->ph_newif);
+	TAILQ_INIT(&ph->ph_delif);
 
 	LIST_INSERT_HEAD(&pfil_head_list, ph, ph_list);
 
@@ -151,6 +152,7 @@
  *	PFIL_ALL	call me on all of the above
  *	PFIL_IFADDR  	call me on interface reconfig (mbuf ** is ioctl #)
  *	PFIL_NEWIF  	call me on interface creation (mbuf ** is ignored)
+ *	PFIL_DELIF	call me on interface deletion (mbuf ** is ignored)
  *	PFIL_WAITOK	OK to call malloc with M_WAITOK.
  */
 int
@@ -173,8 +175,7 @@
 		}
 	}
 	if (flags & PFIL_IFADDR) {
-		err = pfil_list_add(&ph->ph_ifaddr, func, arg,
-		    flags & ~PFIL_IFADDR);
+		err = pfil_list_add(&ph->ph_ifaddr, func, arg, flags);
 		if (err) {
 			if (flags & PFIL_IN)
 				pfil_list_remove(&ph->ph_in, func, arg);
@@ -184,8 +185,7 @@
 		}
 	}
 	if (flags & PFIL_NEWIF) {
-		err = pfil_list_add(&ph->ph_newif, func, arg,
-		    flags & ~PFIL_NEWIF);
+		err = pfil_list_add(&ph->ph_newif, func, arg, flags);
 		if (err) {
 			if (flags & PFIL_IN)
 				pfil_list_remove(&ph->ph_in, func, arg);
@@ -196,6 +196,20 @@
 			return err;
 		}
 	}
+	if (flags & PFIL_DELIF) {
+		err = pfil_list_add(&ph->ph_delif, func, arg, flags);
+		if (err) {
+			if (flags & PFIL_IN)
+				pfil_list_remove(&ph->ph_in, func, arg);
+			if (flags & PFIL_OUT)
+				pfil_list_remove(&ph->ph_out, func, arg);
+			if (flags & PFIL_IFADDR)
+				pfil_list_remove(&ph->ph_ifaddr, func, arg);
+			if (flags & PFIL_NEWIF)
+				pfil_list_remove(&ph->ph_newif, func, arg);
+			return err;
+		}
+	}
 	return 0;
 }
 
@@ -255,6 +269,8 @@
 		err = pfil_list_remove(&ph->ph_ifaddr, func, arg);
 	if ((err == 0) && (flags & PFIL_NEWIF))
 		err = pfil_list_remove(&ph->ph_newif, func, arg);
+	if ((err == 0) && (flags & PFIL_DELIF))
+		err = pfil_list_remove(&ph->ph_delif, func, arg);
 	return err;
 }
 
Index: pfil.h
===================================================================
RCS file: /cvsroot/src/sys/net/pfil.h,v
retrieving revision 1.23
diff -u -r1.23 pfil.h
--- pfil.h	22 Jun 2004 12:50:41 -0000	1.23
+++ pfil.h	21 Jul 2004 14:43:28 -0000
@@ -59,6 +59,7 @@
 #define PFIL_WAITOK	0x00000004
 #define PFIL_IFADDR	0x00000008
 #define PFIL_NEWIF	0x00000010
+#define PFIL_DELIF	0x00000020
 
 typedef	TAILQ_HEAD(pfil_list, packet_filter_hook) pfil_list_t;
 
@@ -70,6 +71,7 @@
 	pfil_list_t	ph_out;
 	pfil_list_t	ph_ifaddr;
 	pfil_list_t	ph_newif;
+	pfil_list_t	ph_delif;
 	int		ph_type;
 	union {
 		u_long		phu_val;
@@ -106,6 +108,8 @@
 		return (TAILQ_FIRST(&ph->ph_ifaddr));
 	else if (dir == PFIL_NEWIF)
 		return (TAILQ_FIRST(&ph->ph_newif));
+	else if (dir == PFIL_DELIF)
+		return (TAILQ_FIRST(&ph->ph_delif));
 	else
 		return (NULL);
 }
>Release-Note:
>Audit-Trail:
>Unformatted: