From owner-svn-src-stable-11@freebsd.org Mon Aug 20 01:01:35 2018 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 45C9A107E4FF; Mon, 20 Aug 2018 01:01:35 +0000 (UTC) (envelope-from loos@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id ED1C0732FB; Mon, 20 Aug 2018 01:01:34 +0000 (UTC) (envelope-from loos@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CE0816448; Mon, 20 Aug 2018 01:01:34 +0000 (UTC) (envelope-from loos@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w7K11YcC083019; Mon, 20 Aug 2018 01:01:34 GMT (envelope-from loos@FreeBSD.org) Received: (from loos@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w7K11Xbu083014; Mon, 20 Aug 2018 01:01:33 GMT (envelope-from loos@FreeBSD.org) Message-Id: <201808200101.w7K11Xbu083014@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: loos set sender to loos@FreeBSD.org using -f From: Luiz Otavio O Souza Date: Mon, 20 Aug 2018 01:01:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r338081 - in stable/11/sys: net netinet netinet6 X-SVN-Group: stable-11 X-SVN-Commit-Author: loos X-SVN-Commit-Paths: in stable/11/sys: net netinet netinet6 X-SVN-Commit-Revision: 338081 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Aug 2018 01:01:35 -0000 Author: loos Date: Mon Aug 20 01:01:33 2018 New Revision: 338081 URL: https://svnweb.freebsd.org/changeset/base/338081 Log: MFC r312770 and r337854: After the in_control() changes in r257692, an existing address is (intentionally) deleted first and then completely added again (so all the events, announces and hooks are given a chance to run). This cause an issue with CARP where the existing CARP data structure is removed together with the last address for a given VHID, which will cause a subsequent fail when the address is later re-added. This change fixes this issue by adding a new flag to keep the CARP data structure when an address is not being removed. There was an additional issue with IPv6 CARP addresses, where the CARP data structure would never be removed after a change and lead to VHIDs which cannot be destroyed. PR: 229384 Sponsored by: Rubicon Communications, LLC (Netgate) Modified: stable/11/sys/net/if.c stable/11/sys/netinet/in.c stable/11/sys/netinet/ip_carp.c stable/11/sys/netinet/ip_carp.h stable/11/sys/netinet6/in6.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/net/if.c ============================================================================== --- stable/11/sys/net/if.c Mon Aug 20 00:53:38 2018 (r338080) +++ stable/11/sys/net/if.c Mon Aug 20 01:01:33 2018 (r338081) @@ -224,7 +224,7 @@ int (*carp_output_p)(struct ifnet *ifp, struct mbuf *m const struct sockaddr *sa); int (*carp_ioctl_p)(struct ifreq *, u_long, struct thread *); int (*carp_attach_p)(struct ifaddr *, int); -void (*carp_detach_p)(struct ifaddr *); +void (*carp_detach_p)(struct ifaddr *, bool); #endif #ifdef INET int (*carp_iamatch_p)(struct ifaddr *, uint8_t **); Modified: stable/11/sys/netinet/in.c ============================================================================== --- stable/11/sys/netinet/in.c Mon Aug 20 00:53:38 2018 (r338080) +++ stable/11/sys/netinet/in.c Mon Aug 20 01:01:33 2018 (r338081) @@ -71,7 +71,7 @@ __FBSDID("$FreeBSD$"); #include static int in_aifaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); -static int in_difaddr_ioctl(caddr_t, struct ifnet *, struct thread *); +static int in_difaddr_ioctl(u_long, caddr_t, struct ifnet *, struct thread *); static void in_socktrim(struct sockaddr_in *); static void in_purgemaddrs(struct ifnet *); @@ -245,7 +245,7 @@ in_control(struct socket *so, u_long cmd, caddr_t data break; case SIOCDIFADDR: sx_xlock(&in_control_sx); - error = in_difaddr_ioctl(data, ifp, td); + error = in_difaddr_ioctl(cmd, data, ifp, td); sx_xunlock(&in_control_sx); return (error); case OSIOCAIFADDR: /* 9.x compat */ @@ -390,7 +390,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifne IF_ADDR_RUNLOCK(ifp); if (ia != NULL) - (void )in_difaddr_ioctl(data, ifp, td); + (void )in_difaddr_ioctl(cmd, data, ifp, td); ifa = ifa_alloc(sizeof(struct in_ifaddr), M_WAITOK); ia = (struct in_ifaddr *)ifa; @@ -528,7 +528,7 @@ fail2: fail1: if (ia->ia_ifa.ifa_carp) - (*carp_detach_p)(&ia->ia_ifa); + (*carp_detach_p)(&ia->ia_ifa, false); IF_ADDR_WLOCK(ifp); TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); @@ -545,7 +545,7 @@ fail1: } static int -in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, struct thread *td) +in_difaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td) { const struct ifreq *ifr = (struct ifreq *)data; const struct sockaddr_in *addr = (const struct sockaddr_in *) @@ -618,7 +618,7 @@ in_difaddr_ioctl(caddr_t data, struct ifnet *ifp, stru in_ifadown(&ia->ia_ifa, 1); if (ia->ia_ifa.ifa_carp) - (*carp_detach_p)(&ia->ia_ifa); + (*carp_detach_p)(&ia->ia_ifa, cmd == SIOCAIFADDR); /* * If this is the last IPv4 address configured on this Modified: stable/11/sys/netinet/ip_carp.c ============================================================================== --- stable/11/sys/netinet/ip_carp.c Mon Aug 20 00:53:38 2018 (r338080) +++ stable/11/sys/netinet/ip_carp.c Mon Aug 20 01:01:33 2018 (r338081) @@ -1872,7 +1872,7 @@ carp_attach(struct ifaddr *ifa, int vhid) } void -carp_detach(struct ifaddr *ifa) +carp_detach(struct ifaddr *ifa, bool keep_cif) { struct ifnet *ifp = ifa->ifa_ifp; struct carp_if *cif = ifp->if_carp; @@ -1918,12 +1918,13 @@ carp_detach(struct ifaddr *ifa) carp_hmac_prepare(sc); carp_sc_state(sc); - if (sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0) + if (!keep_cif && sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0) carp_destroy(sc); else CARP_UNLOCK(sc); - CIF_FREE(cif); + if (!keep_cif) + CIF_FREE(cif); sx_xunlock(&carp_sx); } Modified: stable/11/sys/netinet/ip_carp.h ============================================================================== --- stable/11/sys/netinet/ip_carp.h Mon Aug 20 00:53:38 2018 (r338080) +++ stable/11/sys/netinet/ip_carp.h Mon Aug 20 01:01:33 2018 (r338081) @@ -138,7 +138,7 @@ struct carpreq { #ifdef _KERNEL int carp_ioctl(struct ifreq *, u_long, struct thread *); int carp_attach(struct ifaddr *, int); -void carp_detach(struct ifaddr *); +void carp_detach(struct ifaddr *, bool); void carp_carpdev_state(struct ifnet *); int carp_input(struct mbuf **, int *, int); int carp6_input (struct mbuf **, int *, int); @@ -154,7 +154,7 @@ int carp_forus(struct ifnet *, u_char *); /* net/if.c */ extern int (*carp_ioctl_p)(struct ifreq *, u_long, struct thread *); extern int (*carp_attach_p)(struct ifaddr *, int); -extern void (*carp_detach_p)(struct ifaddr *); +extern void (*carp_detach_p)(struct ifaddr *, bool); extern void (*carp_linkstate_p)(struct ifnet *); extern void (*carp_demote_adj_p)(int, char *); extern int (*carp_master_p)(struct ifaddr *); Modified: stable/11/sys/netinet6/in6.c ============================================================================== --- stable/11/sys/netinet6/in6.c Mon Aug 20 00:53:38 2018 (r338080) +++ stable/11/sys/netinet6/in6.c Mon Aug 20 01:01:33 2018 (r338081) @@ -556,8 +556,11 @@ in6_control(struct socket *so, u_long cmd, caddr_t dat */ if ((error = in6_update_ifa(ifp, ifra, ia, 0)) != 0) goto out; - if (ia != NULL) + if (ia != NULL) { + if (ia->ia_ifa.ifa_carp) + (*carp_detach_p)(&ia->ia_ifa, true); ifa_free(&ia->ia_ifa); + } if ((ia = in6ifa_ifpwithaddr(ifp, &ifra->ifra_addr.sin6_addr)) == NULL) { /* @@ -624,7 +627,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t dat */ if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) { if (carp_attached) - (*carp_detach_p)(&ia->ia_ifa); + (*carp_detach_p)(&ia->ia_ifa, false); goto out; } } @@ -1244,7 +1247,7 @@ in6_purgeaddr(struct ifaddr *ifa) int plen, error; if (ifa->ifa_carp) - (*carp_detach_p)(ifa); + (*carp_detach_p)(ifa, false); /* * Remove the loopback route to the interface address.