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 *);