Module Name:    src
Committed By:   roy
Date:           Thu Sep 29 15:04:17 UTC 2016

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

Log Message:
Set dstaddr in in_ifinit so that sppp consumers announce the correct
dstaddr in routing messages.


To generate a diff of this commit:
cvs rdiff -u -r1.153 -r1.154 src/sys/net/if_spppsubr.c
cvs rdiff -u -r1.183 -r1.184 src/sys/netinet/in.c
cvs rdiff -u -r1.85 -r1.86 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.153 src/sys/net/if_spppsubr.c:1.154
--- src/sys/net/if_spppsubr.c:1.153	Thu Sep 29 14:08:40 2016
+++ src/sys/net/if_spppsubr.c	Thu Sep 29 15:04:17 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_spppsubr.c,v 1.153 2016/09/29 14:08:40 roy Exp $	 */
+/*	$NetBSD: if_spppsubr.c,v 1.154 2016/09/29 15:04:17 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.153 2016/09/29 14:08:40 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.154 2016/09/29 15:04:17 roy Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -4906,27 +4906,18 @@ found:
 		struct sockaddr_in new_sin = *si;
 		struct sockaddr_in new_dst = *dest;
 
-		/*
-		 * Scrub old routes now instead of calling in_ifinit with
-		 * scrub=1, because we may change the dstaddr
-		 * before the call to in_ifinit.
-		 */
-		in_ifscrub(ifp, ifatoia(ifa));
-
 		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) {
+			if (new_dst.sin_addr.s_addr != dest->sin_addr.s_addr)
 				sp->ipcp.saved_hisaddr = dest->sin_addr.s_addr;
-				*dest = new_dst; /* fix dstaddr in place */
-			}
 		}
 
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
 
-		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0);
+		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, &new_dst, 0);
 
 		LIST_INSERT_HEAD(&IN_IFADDR_HASH(ifatoia(ifa)->ia_addr.sin_addr.s_addr),
 		    ifatoia(ifa), ia_hash);
@@ -4977,19 +4968,18 @@ sppp_clear_ip_addrs(struct sppp *sp)
 found:
 	{
 		struct sockaddr_in new_sin = *si;
+		struct sockaddr_in new_dst = *dest;
 		int error;
 
-		in_ifscrub(ifp, ifatoia(ifa));
 		if (sp->ipcp.flags & IPCP_MYADDR_DYN)
 			new_sin.sin_addr.s_addr = 0;
 		if (sp->ipcp.flags & IPCP_HISADDR_DYN)
-			/* replace peer addr in place */
-			dest->sin_addr.s_addr = sp->ipcp.saved_hisaddr;
+			new_dst.sin_addr.s_addr = sp->ipcp.saved_hisaddr;
 
 		LIST_REMOVE(ifatoia(ifa), ia_hash);
 		IN_ADDRHASH_WRITER_REMOVE(ifatoia(ifa));
 
-		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, 0);
+		error = in_ifinit(ifp, ifatoia(ifa), &new_sin, &new_dst, 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.183 src/sys/netinet/in.c:1.184
--- src/sys/netinet/in.c:1.183	Thu Sep 29 14:18:38 2016
+++ src/sys/netinet/in.c	Thu Sep 29 15:04:17 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in.c,v 1.183 2016/09/29 14:18:38 roy Exp $	*/
+/*	$NetBSD: in.c,v 1.184 2016/09/29 15:04:17 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.183 2016/09/29 14:18:38 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.184 2016/09/29 15:04:17 roy Exp $");
 
 #include "arp.h"
 
@@ -381,7 +381,7 @@ in_control0(struct socket *so, u_long cm
 	struct ifreq *ifr = (struct ifreq *)data;
 	struct in_ifaddr *ia = NULL;
 	struct in_aliasreq *ifra = (struct in_aliasreq *)data;
-	struct sockaddr_in oldaddr;
+	struct sockaddr_in oldaddr, *new_dstaddr;
 	int error, hostIsNew, maskIsNew;
 	int newifaddr = 0;
 	bool run_hook = false;
@@ -601,7 +601,8 @@ 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);
+		error = in_ifinit(ifp, ia, satocsin(ifreq_getaddr(cmd, ifr)),
+		    NULL, 1);
 
 		run_hook = true;
 		break;
@@ -617,7 +618,7 @@ in_control0(struct socket *so, u_long cm
 			mutex_exit(&in_ifaddr_lock);
 			need_reinsert = true;
 		}
-		error = in_ifinit(ifp, ia, NULL, 0);
+		error = in_ifinit(ifp, ia, NULL, NULL, 0);
 		break;
 
 	case SIOCAIFADDR:
@@ -637,9 +638,10 @@ in_control0(struct socket *so, u_long cm
 			 * otherwise userland gets a bogus message */
 			if ((ia->ia_flags & IFA_ROUTE))
 				in_ifscrub(ifp, ia);
-			ia->ia_dstaddr = ifra->ifra_dstaddr;
+			new_dstaddr = &ifra->ifra_dstaddr;
 			maskIsNew  = 1; /* We lie; but the effect's the same */
-		}
+		} else
+			new_dstaddr = NULL;
 		if (ifra->ifra_addr.sin_family == AF_INET &&
 		    (hostIsNew || maskIsNew)) {
 			if (!newifaddr) {
@@ -649,7 +651,8 @@ 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);
+			error = in_ifinit(ifp, ia, &ifra->ifra_addr,
+			    new_dstaddr, 0);
 		}
 		if ((ifp->if_flags & IFF_BROADCAST) &&
 		    (ifra->ifra_broadaddr.sin_family == AF_INET))
@@ -1059,23 +1062,30 @@ in_ifscrub(struct ifnet *ifp, struct in_
  */
 int
 in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia,
-    const struct sockaddr_in *sin, int scrub)
+    const struct sockaddr_in *sin, const struct sockaddr_in *dst, int scrub)
 {
 	u_int32_t i;
-	struct sockaddr_in oldaddr;
+	struct sockaddr_in oldaddr, olddst;
 	int s, oldflags, flags = RTF_UP, error, hostIsNew;
 
 	if (sin == NULL)
 		sin = &ia->ia_addr;
+	if (dst == NULL)
+		dst = &ia->ia_dstaddr;
 
 	/*
 	 * Set up new addresses.
 	 */
 	oldaddr = ia->ia_addr;
+	olddst = ia->ia_dstaddr;
 	oldflags = ia->ia4_flags;
 	ia->ia_addr = *sin;
+	ia->ia_dstaddr = *dst;
 	hostIsNew = oldaddr.sin_family != AF_INET ||
 	    !in_hosteq(ia->ia_addr.sin_addr, oldaddr.sin_addr);
+	if (!scrub)
+		scrub = oldaddr.sin_family != ia->ia_dstaddr.sin_family ||
+		    !in_hosteq(ia->ia_dstaddr.sin_addr, olddst.sin_addr);
 
 	/*
 	 * Configure address flags.
@@ -1104,6 +1114,7 @@ in_ifinit(struct ifnet *ifp, struct in_i
 	ia->ia4_flags &= ~IN_IFF_TRYTENTATIVE;
 	if (error != 0) {
 		ia->ia_addr = oldaddr;
+		ia->ia_dstaddr = olddst;
 		ia->ia4_flags = oldflags;
 		return error;
 	}
@@ -1112,12 +1123,14 @@ in_ifinit(struct ifnet *ifp, struct in_i
 		int newflags = ia->ia4_flags;
 
 		ia->ia_ifa.ifa_addr = sintosa(&oldaddr);
+		ia->ia_ifa.ifa_dstaddr = sintosa(&olddst);
 		ia->ia4_flags = oldflags;
 		if (hostIsNew)
 			in_scrubaddr(ia);
 		else if (scrub)
 			in_ifscrub(ifp, ia);
 		ia->ia_ifa.ifa_addr = sintosa(&ia->ia_addr);
+		ia->ia_ifa.ifa_dstaddr = sintosa(&ia->ia_dstaddr);
 		ia->ia4_flags = newflags;
 	}
 

Index: src/sys/netinet/in_var.h
diff -u src/sys/netinet/in_var.h:1.85 src/sys/netinet/in_var.h:1.86
--- src/sys/netinet/in_var.h:1.85	Sun Sep 18 02:17:43 2016
+++ src/sys/netinet/in_var.h	Thu Sep 29 15:04:17 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in_var.h,v 1.85 2016/09/18 02:17:43 christos Exp $	*/
+/*	$NetBSD: in_var.h,v 1.86 2016/09/29 15:04:17 roy Exp $	*/
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -408,8 +408,8 @@ int in_multi_lock_held(void);
 
 struct ifaddr;
 
-int	in_ifinit(struct ifnet *,
-	    struct in_ifaddr *, const struct sockaddr_in *, int);
+int	in_ifinit(struct ifnet *, struct in_ifaddr *,
+    const struct sockaddr_in *, 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