Module Name:    src
Committed By:   roy
Date:           Fri Sep 16 14:17:23 UTC 2016

Modified Files:
        src/sys/net: if_spppsubr.c
        src/sys/netinet: in.c in_var.h

Log Message:
Drop hostIsNew from in_ifinit, let the function work out if the address
has changed.
Sync address flag setup with the IPv6 counterpart.
When scrubbing the address, or setting up the address fails, restore the
old address flags as well as the old address.


To generate a diff of this commit:
cvs rdiff -u -r1.151 -r1.152 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.181 -r1.182 src/sys/netinet/in.c
cvs rdiff -u -r1.82 -r1.83 src/sys/netinet/in_var.h

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_spppsubr.c
diff -u src/sys/net/if_spppsubr.c:1.151 src/sys/net/if_spppsubr.c:1.152
--- src/sys/net/if_spppsubr.c:1.151	Wed Sep 14 11:54:42 2016
+++ src/sys/net/if_spppsubr.c	Fri Sep 16 14:17:23 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_spppsubr.c,v 1.151 2016/09/14 11:54:42 roy Exp $	 */
+/*	$NetBSD: if_spppsubr.c,v 1.152 2016/09/16 14:17:23 roy Exp $	 */
 
 /*
  * Synchronous PPP/Cisco link level subroutines.
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.151 2016/09/14 11:54:42 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.152 2016/09/16 14:17:23 roy Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -4902,7 +4902,7 @@ sppp_set_ip_addrs(struct sppp *sp, uint3
 
 found:
 	{
-		int error, hostIsNew;
+		int error;
 		struct sockaddr_in new_sin = *si;
 		struct sockaddr_in new_dst = *dest;
 
@@ -4913,13 +4913,8 @@ found:
 		 */
 		in_ifscrub(ifp, ifatoia(ifa));
 
-		hostIsNew = 0;
-		if (myaddr != 0) {
-			if (new_sin.sin_addr.s_addr != htonl(myaddr)) {
-				new_sin.sin_addr.s_addr = htonl(myaddr);
-				hostIsNew = 1;
-			}
-		}
+		if (myaddr != 0)
+			new_sin.sin_addr.s_addr = htonl(myaddr);
 		if (hisaddr != 0) {
 			new_dst.sin_addr.s_addr = htonl(hisaddr);
 			if (new_dst.sin_addr.s_addr != dest->sin_addr.s_addr) {
@@ -4931,7 +4926,7 @@ found:
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
 
-		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0, hostIsNew);
+		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0);
 
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ifatoia(ifa)->ia_addr.sin_addr.s_addr),
 		    ifatoia(ifa), ia_hash);
@@ -4993,7 +4988,7 @@ found:
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
 
-		in_ifinit(ifp, ifatoia(ifa), &new_sin, 0, 0);
+		in_ifinit(ifp, ifatoia(ifa), &new_sin, 0);
 
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ifatoia(ifa)->ia_addr.sin_addr.s_addr),
 		    ifatoia(ifa), ia_hash);

Index: src/sys/netinet/in.c
diff -u src/sys/netinet/in.c:1.181 src/sys/netinet/in.c:1.182
--- src/sys/netinet/in.c:1.181	Tue Sep 13 15:57:50 2016
+++ src/sys/netinet/in.c	Fri Sep 16 14:17:23 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.181 2016/09/13 15:57:50 christos Exp $	*/
+/*	$NetBSD: in.c,v 1.182 2016/09/16 14:17:23 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.181 2016/09/13 15:57:50 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.182 2016/09/16 14:17:23 roy Exp $");
 
 #include "arp.h"
 
@@ -600,8 +600,7 @@ in_control0(struct socket *so, u_long cm
 			mutex_exit(&in_ifaddr_lock);
 			need_reinsert = true;
 		}
-		error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)),
-		    1, hostIsNew);
+		error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)),1);
 
 		run_hook = true;
 		break;
@@ -617,7 +616,7 @@ in_control0(struct socket *so, u_long cm
 			mutex_exit(&in_ifaddr_lock);
 			need_reinsert = true;
 		}
-		error = in_ifinit(ifp, ia, NULL, 0, 0);
+		error = in_ifinit(ifp, ia, NULL, 0);
 		break;
 
 	case SIOCAIFADDR:
@@ -649,8 +648,7 @@ in_control0(struct socket *so, u_long cm
 				mutex_exit(&in_ifaddr_lock);
 				need_reinsert = true;
 			}
-			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0,
-			    hostIsNew);
+			error = in_ifinit(ifp, ia, &ifra->ifra_addr, 0);
 		}
 		if ((ifp->if_flags & IFF_BROADCAST) &&
 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
@@ -1051,11 +1049,11 @@ in_ifscrub(struct ifnet *ifp, struct in_
  */
 int
 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia,
-    const struct sockaddr_in *sin, int scrub, int hostIsNew)
+    const struct sockaddr_in *sin, int scrub)
 {
 	u_int32_t i;
 	struct sockaddr_in oldaddr;
-	int s = splnet(), flags = RTF_UP, error;
+	int s, oldflags, flags = RTF_UP, error, hostIsNew;
 
 	if (sin == NULL)
 		sin = &ia->ia_addr;
@@ -1064,32 +1062,50 @@ in_ifinit(struct ifnet *ifp, struct in_i
 	 * Set up new addresses.
 	 */
 	oldaddr = ia->ia_addr;
+	oldflags = ia->ia4_flags;
 	ia->ia_addr = *sin;
+	hostIsNew = oldaddr.sin_family != AF_INET ||
+	    !in_hosteq(ia->ia_addr.sin_addr, oldaddr.sin_addr);
 
-	/* Set IN_IFF flags early for if_addr_init() */
-	if (hostIsNew && if_do_dad(ifp) && !in_nullhost(ia->ia_addr.sin_addr)) {
-		if (ifp->if_link_state == LINK_STATE_DOWN)
-			ia->ia4_flags |= IN_IFF_DETACHED;
-		else
-			/* State the intent to try DAD if possible */
-			ia->ia4_flags |= IN_IFF_TRYTENTATIVE;
-	}
+	/*
+	 * Configure address flags.
+	 * We need to do this early because they maybe adjusted
+	 * by if_addr_init depending on the address.
+	 */
+	if (ia->ia4_flags & IN_IFF_DUPLICATED) {
+		ia->ia4_flags &= ~IN_IFF_DUPLICATED;
+		hostIsNew = 1;
+	}
+	if (ifp->if_link_state == LINK_STATE_DOWN) {
+		ia->ia4_flags |= IN_IFF_DETACHED;
+		ia->ia4_flags &= ~IN_IFF_TENTATIVE;
+	} else if (hostIsNew && if_do_dad(ifp))
+		ia->ia4_flags |= IN_IFF_TRYTENTATIVE;
 
 	/*
 	 * Give the interface a chance to initialize
 	 * if this is its first address,
 	 * and to validate the address if necessary.
 	 */
-	if ((error = if_addr_init(ifp, &ia->ia_ifa, true)) != 0)
-		goto bad;
+	s = splnet();
+	error = if_addr_init(ifp, &ia->ia_ifa, true);
+	splx(s);
 	/* Now clear the try tentative flag, it's job is done. */
 	ia->ia4_flags &= ~IN_IFF_TRYTENTATIVE;
-	splx(s);
+	if (error != 0) {
+		ia->ia_addr = oldaddr;
+		ia->ia4_flags = oldflags;
+		return error;
+	}
 
 	if (scrub) {
+		int newflags = ia->ia4_flags;
+
 		ia->ia_ifa.ifa_addr = sintosa(&oldaddr);
+		ia->ia4_flags = oldflags;
 		in_ifscrub(ifp, ia);
 		ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
+		ia->ia4_flags = newflags;
 	}
 
 	/* Add the local route to the address */
@@ -1147,16 +1163,12 @@ in_ifinit(struct ifnet *ifp, struct in_i
 		ia->ia_allhosts = in_addmulti(&addr, ifp);
 	}
 
-	if (hostIsNew && if_do_dad(ifp) &&
-	    !in_nullhost(ia->ia_addr.sin_addr) &&
-	    ia->ia4_flags & IN_IFF_TENTATIVE)
+	if (hostIsNew &&
+	    ia->ia4_flags & IN_IFF_TENTATIVE &&
+	    if_do_dad(ifp))
 		ia->ia_dad_start((struct ifaddr *)ia);
 
-	return (error);
-bad:
-	splx(s);
-	ia->ia_addr = oldaddr;
-	return (error);
+	return error;
 }
 
 #define rtinitflags(x) \

Index: src/sys/netinet/in_var.h
diff -u src/sys/netinet/in_var.h:1.82 src/sys/netinet/in_var.h:1.83
--- src/sys/netinet/in_var.h:1.82	Thu Sep 15 18:17:29 2016
+++ src/sys/netinet/in_var.h	Fri Sep 16 14:17:23 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_var.h,v 1.82 2016/09/15 18:17:29 roy Exp $	*/
+/*	$NetBSD: in_var.h,v 1.83 2016/09/16 14:17:23 roy Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -405,7 +405,7 @@ int in_multi_lock_held(void);
 struct ifaddr;
 
 int	in_ifinit(struct ifnet *,
-	    struct in_ifaddr *, const struct sockaddr_in *, int, int);
+	    struct in_ifaddr *, const struct sockaddr_in *, int);
 void	in_savemkludge(struct in_ifaddr *);
 void	in_restoremkludge(struct in_ifaddr *, struct ifnet *);
 void	in_purgemkludge(struct ifnet *);

Reply via email to