The branch main has been updated by melifaro:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7634919e15f1147b6f26d55354be375bc9b198db

commit 7634919e15f1147b6f26d55354be375bc9b198db
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2021-03-08 20:27:29 +0000
Commit:     Alexander V. Chernikov <melif...@freebsd.org>
CommitDate: 2021-03-08 21:28:35 +0000

    Fix 'in6_purgeaddr: err=65, destination address delete failed' message.
    
    P2P ifa may require 2 routes: one is the loopback route, another is
     the "prefix" route towards its destination.
    
    Current code marks loopback routes existence with IFA_RTSELF and
     "prefix" p2p routes with IFA_ROUTE.
    
    For historic reasons, we fill in ifa_dstaddr for loopback interfaces.
    To avoid installing the same route twice, we preemptively set
     IFA_RTSELF when adding "prefix" route for loopback.
    However, the teardown part doesn't have this hack, so we try to
     remove the same route twice.
    
    Fix this by checking if ifa_dstaddr is different from the ifa_addr
     and moving this logic into a separate function.
    
    Reviewed By: kp
    Differential Revision: https://reviews.freebsd.org/D29121
    MFC after:      3 days
---
 sys/netinet6/in6.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c
index 4665a21c28fd..02cb9df7da3a 100644
--- a/sys/netinet6/in6.c
+++ b/sys/netinet6/in6.c
@@ -1294,13 +1294,27 @@ in6_handle_dstaddr_rtrequest(int cmd, struct in6_ifaddr 
*ia)
        return (error);
 }
 
+static bool
+ifa_is_p2p(struct in6_ifaddr *ia)
+{
+       int plen;
+
+       plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
+
+       if ((plen == 128) && (ia->ia_dstaddr.sin6_family == AF_INET6) &&
+           !IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, 
&ia->ia_dstaddr.sin6_addr))
+               return (true);
+
+       return (false);
+}
+
 void
 in6_purgeaddr(struct ifaddr *ifa)
 {
        struct ifnet *ifp = ifa->ifa_ifp;
        struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa;
        struct in6_multi_mship *imm;
-       int plen, error;
+       int error;
 
        if (ifa->ifa_carp)
                (*carp_detach_p)(ifa, false);
@@ -1328,10 +1342,7 @@ in6_purgeaddr(struct ifaddr *ifa)
                free(imm, M_IP6MADDR);
        }
        /* Check if we need to remove p2p route */
-       plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
-       if (ia->ia_dstaddr.sin6_family != AF_INET6)
-               plen = 0;
-       if ((ia->ia_flags & IFA_ROUTE) && plen == 128) {
+       if ((ia->ia_flags & IFA_ROUTE) && ifa_is_p2p(ia)) {
                error = in6_handle_dstaddr_rtrequest(RTM_DELETE, ia);
                if (error != 0)
                        log(LOG_INFO, "%s: err=%d, destination address delete "
@@ -1434,7 +1445,7 @@ static int
 in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia,
     struct in6_aliasreq *ifra, int hostIsNew)
 {
-       int     error = 0, plen, ifacount = 0;
+       int     error = 0, ifacount = 0;
        struct ifaddr *ifa;
        struct sockaddr_in6 *pdst;
        char ip6buf[INET6_ADDRSTRLEN];
@@ -1487,14 +1498,7 @@ in6_notify_ifa(struct ifnet *ifp, struct in6_ifaddr *ia,
         * XXX: the logic below rejects assigning multiple addresses on a p2p
         * interface that share the same destination.
         */
-       plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
-       if (!(ia->ia_flags & IFA_ROUTE) && plen == 128 &&
-           ia->ia_dstaddr.sin6_family == AF_INET6) {
-               /*
-                * Handle the case for ::1 .
-                */
-               if (ifp->if_flags & IFF_LOOPBACK)
-                       ia->ia_flags |= IFA_RTSELF;
+       if (!(ia->ia_flags & IFA_ROUTE) && ifa_is_p2p(ia)) {
                error = in6_handle_dstaddr_rtrequest(RTM_ADD, ia);
                if (error)
                        goto done;
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to