Re: Extending EVFILT_NETDEV to support ip-address changes

From: Fredrik Lindberg <fli+freebsd-current_at_shapeshifter.se>
Date: Sun, 30 Jul 2006 13:30:20 +0200
Fredrik Lindberg wrote:
> The documented way of using EVFILT_NETDEV according to kqueue(2) is to
> obtain the status from fflags, but as it apparently sets data too
> somebody is using it, that's for sure.
> 
> Users of EVFILT_NETDEV are required to pass a mask of
> NOTE_LINK{UP,DOWN,INV} in fflags with the initial kevent call, otherwise
> no events will fire.
> 
> What if we add NOTE_ADDR{NEW,DEL} as bit masks and change filt_netdev to
> only set kn_data when a monitored event occurs instead of just setting
> it regardless of if the event is being monitored or not.
> If we also restrict the values of kn_data to NOTE_LINK{UP,DOWN,INV},
> existing applications shouldn't break as they would only receive the 
> events they subscribed to and both data and fflags would be
> intact. NOTE_ADDR{NEW,DEL} would be obtain only through fflags and
> kn_data would be left as it is in these cases (0 with EV_CLEAR set).
> 
> Doing it this way shouldn't break the API, as no fields would be touched
> because kn_sfflags & hint would fail for ADDR{NEW,DEL} on existing
> applications as they would only be subscribed to one or more of the
> NOTE_LINK{UP,DOWN,INV} events.
> But maybe I'm missing some rare edge case...
> 

Replying to myself here, but anyway. I've attached a complete patch
with the modified filt_netdev as described above.

Fredrik Lindberg


Index: sys/event.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/event.h,v
retrieving revision 1.36
diff -u -r1.36 event.h
--- sys/event.h	16 Mar 2006 11:19:36 -0000	1.36
+++ sys/event.h	30 Jul 2006 10:54:31 -0000
_at__at_ -115,6 +115,8 _at__at_
 #define NOTE_LINKUP	0x0001			/* link is up */
 #define NOTE_LINKDOWN	0x0002			/* link is down */
 #define NOTE_LINKINV	0x0004			/* link state is invalid */
+#define NOTE_ADDRNEW	0x0008			/* ip-address added */
+#define NOTE_ADDRDEL	0x0010			/* ip-address removed */
 
 struct knote;
 SLIST_HEAD(klist, knote);
Index: netinet/in.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in.c,v
retrieving revision 1.93
diff -u -r1.93 in.c
--- netinet/in.c	24 Jan 2006 16:19:31 -0000	1.93
+++ netinet/in.c	30 Jul 2006 10:54:31 -0000
_at__at_ -399,8 +399,10 _at__at_
 		    (struct sockaddr_in *) &ifr->ifr_addr, 1);
 		if (error != 0 && iaIsNew)
 			break;
-		if (error == 0)
+		if (error == 0) {
 			EVENTHANDLER_INVOKE(ifaddr_event, ifp);
+			KNOTE_UNLOCKED(&ifp->if_klist, NOTE_ADDRNEW);
+		}
 		return (0);
 
 	case SIOCSIFNETMASK:
_at__at_ -443,8 +445,10 _at__at_
 		if ((ifp->if_flags & IFF_BROADCAST) &&
 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
 			ia->ia_broadaddr = ifra->ifra_broadaddr;
-		if (error == 0)
+		if (error == 0) {
 			EVENTHANDLER_INVOKE(ifaddr_event, ifp);
+			KNOTE_UNLOCKED(&ifp->if_klist, NOTE_ADDRNEW);
+		}
 		return (error);
 
 	case SIOCDIFADDR:
_at__at_ -460,6 +464,7 _at__at_
 		 */
 		in_ifadown(&ia->ia_ifa, 1);
 		EVENTHANDLER_INVOKE(ifaddr_event, ifp);
+		KNOTE_UNLOCKED(&ifp->if_klist, NOTE_ADDRDEL);
 		error = 0;
 		break;
 
Index: net/if.c
===================================================================
RCS file: /home/ncvs/src/sys/net/if.c,v
retrieving revision 1.261
diff -u -r1.261 if.c
--- net/if.c	9 Jul 2006 06:04:00 -0000	1.261
+++ net/if.c	30 Jul 2006 10:54:31 -0000
_at__at_ -265,10 +265,12 _at__at_
 		knlist_remove_inevent(klist, kn);
 		return (1);
 	}
-	if (hint != 0)
-		kn->kn_data = hint;			/* current status */
-	if (kn->kn_sfflags & hint)
+
+	if (kn->kn_sfflags & hint) {
 		kn->kn_fflags |= hint;
+		if (hint & (NOTE_LINKUP | NOTE_LINKDOWN))
+			kn->kn_data = hint;		/* current link status */
+	}
 	return (kn->kn_fflags != 0);
 }
 
Received on Sun Jul 30 2006 - 09:30:35 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:58 UTC