Module Name:    src
Committed By:   roy
Date:           Mon Dec 12 00:06:40 UTC 2011

Modified Files:
        src/sys/net: rtsock.c
        src/sys/netinet: in.c

Log Message:
When adding or scrubbing a prefix, always notify userland even if the
prefix does not have IFA_ROUTE.
Don't scrub the interface in SIOCAIFADDR if the new address does't
have IFA_ROUTE. If more functions are added to in_ifscrub then this logic
might need to be revisited.

Fixes PR/26450.


To generate a diff of this commit:
cvs rdiff -u -r1.137 -r1.138 src/sys/net/rtsock.c
cvs rdiff -u -r1.141 -r1.142 src/sys/netinet/in.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/rtsock.c
diff -u src/sys/net/rtsock.c:1.137 src/sys/net/rtsock.c:1.138
--- src/sys/net/rtsock.c:1.137	Mon Oct 31 12:50:50 2011
+++ src/sys/net/rtsock.c	Mon Dec 12 00:06:39 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtsock.c,v 1.137 2011/10/31 12:50:50 yamt Exp $	*/
+/*	$NetBSD: rtsock.c,v 1.138 2011/12/12 00:06:39 roy Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.137 2011/10/31 12:50:50 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.138 2011/12/12 00:06:39 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -868,7 +868,13 @@ COMPATNAME(rt_newaddrmsg)(int cmd, struc
 		case cmdpass(RTM_ADD, 1):
 		case cmdpass(RTM_CHANGE, 1):
 		case cmdpass(RTM_DELETE, 2):
+		case cmdpass(RTM_NEWADDR, 1):
+		case cmdpass(RTM_DELADDR, 1):
+		case cmdpass(RTM_CHGADDR, 1):
 			switch (cmd) {
+			case RTM_ADD:
+				ncmd = RTM_NEWADDR;
+				break;
 			case RTM_DELETE:
 				ncmd = RTM_DELADDR;
 				break;
@@ -876,7 +882,7 @@ COMPATNAME(rt_newaddrmsg)(int cmd, struc
 				ncmd = RTM_CHGADDR;
 				break;
 			default:
-				ncmd = RTM_NEWADDR;
+				ncmd = cmd;
 			}
 			info.rti_info[RTAX_IFA] = sa = ifa->ifa_addr;
 			info.rti_info[RTAX_IFP] = ifp->if_dl->ifa_addr;

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.141 src/sys/netinet/in.c:1.142
--- src/sys/netinet/in.c:1.141	Sat Nov 19 22:51:25 2011
+++ src/sys/netinet/in.c	Mon Dec 12 00:06:39 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.141 2011/11/19 22:51:25 tls Exp $	*/
+/*	$NetBSD: in.c,v 1.142 2011/12/12 00:06:39 roy Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.141 2011/11/19 22:51:25 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.142 2011/12/12 00:06:39 roy Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet_conf.h"
@@ -501,14 +501,20 @@ in_control(struct socket *so, u_long cmd
 		           ifra->ifra_addr.sin_addr))
 			hostIsNew = 0;
 		if (ifra->ifra_mask.sin_len) {
-			in_ifscrub(ifp, ia);
+			/* Only scrub if we control the prefix route,
+			 * otherwise userland gets a bogus message */
+			if ((ia->ia_flags & IFA_ROUTE))
+				in_ifscrub(ifp, ia);
 			ia->ia_sockmask = ifra->ifra_mask;
 			ia->ia_subnetmask = ia->ia_sockmask.sin_addr.s_addr;
 			maskIsNew = 1;
 		}
 		if ((ifp->if_flags & IFF_POINTOPOINT) &&
 		    (ifra->ifra_dstaddr.sin_family == AF_INET)) {
-			in_ifscrub(ifp, ia);
+			/* Only scrub if we control the prefix route,
+			 * otherwise userland gets a bogus message */
+			if ((ia->ia_flags & IFA_ROUTE))
+				in_ifscrub(ifp, ia);
 			ia->ia_dstaddr = ifra->ifra_dstaddr;
 			maskIsNew  = 1; /* We lie; but the effect's the same */
 		}
@@ -923,9 +929,13 @@ in_addprefix(struct in_ifaddr *target, i
 		 * interface address, we don't need to bother
 		 *
 		 * XXX RADIX_MPATH implications here? -dyoung
+		 *
+		 * But we should still notify userland of the new address
 		 */
-		if (ia->ia_flags & IFA_ROUTE)
+		if (ia->ia_flags & IFA_ROUTE) {
+			rt_newaddrmsg(RTM_NEWADDR, &target->ia_ifa, 0, NULL);
 			return 0;
+		}
 	}
 
 	/*
@@ -955,8 +965,11 @@ in_scrubprefix(struct in_ifaddr *target)
 	struct in_addr prefix, mask, p;
 	int error;
 
-	if ((target->ia_flags & IFA_ROUTE) == 0)
+	/* If we don't have IFA_ROUTE we should still inform userland */
+	if ((target->ia_flags & IFA_ROUTE) == 0) {
+		rt_newaddrmsg(RTM_DELADDR, &target->ia_ifa, 0, NULL);
 		return 0;
+	}
 
 	if (rtinitflags(target))
 		prefix = target->ia_dstaddr.sin_addr;

Reply via email to