Module Name:    src
Committed By:   dyoung
Date:           Fri Oct 28 20:11:59 UTC 2011

Modified Files:
        src/sys/net: if.c

Log Message:
Userland may not change the IFF_CANTCHANGE flags, however, the kernel
may, so make sure if_flags_set() takes care of them.  Fixes a regression
in ifpromisc().


To generate a diff of this commit:
cvs rdiff -u -r1.255 -r1.256 src/sys/net/if.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if.c
diff -u src/sys/net/if.c:1.255 src/sys/net/if.c:1.256
--- src/sys/net/if.c:1.255	Tue Oct 25 22:26:18 2011
+++ src/sys/net/if.c	Fri Oct 28 20:11:58 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.255 2011/10/25 22:26:18 dyoung Exp $	*/
+/*	$NetBSD: if.c,v 1.256 2011/10/28 20:11:58 dyoung Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.255 2011/10/25 22:26:18 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.256 2011/10/28 20:11:58 dyoung Exp $");
 
 #include "opt_inet.h"
 
@@ -2154,14 +2154,24 @@ int
 if_flags_set(ifnet_t *ifp, const short flags)
 {
 	int rc;
-	struct ifreq ifr;
 
 	if (ifp->if_setflags != NULL)
 		rc = (*ifp->if_setflags)(ifp, flags);
 	else {
+		short cantflags;
+		struct ifreq ifr;
+
 		memset(&ifr, 0, sizeof(ifr));
-		ifr.ifr_flags = flags;
+
+		cantflags = (ifp->if_flags ^ flags) & IFF_CANTCHANGE;
+		if (cantflags != 0)
+			ifp->if_flags ^= cantflags;
+
+		ifr.ifr_flags = flags & ~IFF_CANTCHANGE;
 		rc = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, &ifr);
+
+		if (rc != 0 && cantflags != 0)
+			ifp->if_flags ^= cantflags;
 	}
 
 	return rc;

Reply via email to