The branch main has been updated by melifaro:

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

commit f9e1cd6c99200846b324a8b65f7f31ded74013bd
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2021-02-19 21:09:17 +0000
Commit:     Alexander V. Chernikov <melif...@freebsd.org>
CommitDate: 2021-02-19 21:17:17 +0000

    Fix arp/ndp deletion broken by 2fe5a79425c7.
    
    Changes in the 2fe5a79425c7 moved dst sockaddr masking from the
     routing control plane to the rtsock code.
    
    It broke arp/ndp deletion.
    It turns out, arp/ndp perform RTM_GET request first to get an
     interface index necessary for the deletion.
    Then they simply stamp the reply with RTF_LLDATA and set the
     command to RTM_DELETE.
    As a result, kernel receives request with non-empty RTA_NETMASK
     and clears RTA_DST host bits before passing the message to the
     lla code.
    
    De facto, the only needed bits are RTA_DST, RTA_GATEWAY and the
     subset of rtm_flags.
    
    With that in mind, fix the interace by clearing RTA_NETMASK
     for every messages with RTF_LLDATA.
    
    While here, cleanup arp/ndp code a bit.
    
    MFC after:      1 day
    Reviewed by:    gnn
    Differential Revision:  https://reviews.freebsd.org/D28804
---
 sys/net/rtsock.c   | 31 +++++++++++++++++++++----------
 usr.sbin/arp/arp.c |  9 ---------
 usr.sbin/ndp/ndp.c | 10 ----------
 3 files changed, 21 insertions(+), 29 deletions(-)

diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 3c1fea497af6..221661585bbf 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1376,6 +1376,14 @@ cleanup_xaddrs_gateway(struct rt_addrinfo *info)
        return (0);
 }
 
+static void
+remove_netmask(struct rt_addrinfo *info)
+{
+       info->rti_info[RTAX_NETMASK] = NULL;
+       info->rti_flags |= RTF_HOST;
+       info->rti_addrs &= ~RTA_NETMASK;
+}
+
 #ifdef INET
 static int
 cleanup_xaddrs_inet(struct rt_addrinfo *info)
@@ -1405,11 +1413,8 @@ cleanup_xaddrs_inet(struct rt_addrinfo *info)
 
        if (mask.s_addr != INADDR_BROADCAST)
                fill_sockaddr_inet(mask_sa, mask);
-       else {
-               info->rti_info[RTAX_NETMASK] = NULL;
-               info->rti_flags |= RTF_HOST;
-               info->rti_addrs &= ~RTA_NETMASK;
-       }
+       else
+               remove_netmask(info);
 
        /* Check gateway */
        if (info->rti_info[RTAX_GATEWAY] != NULL)
@@ -1445,11 +1450,8 @@ cleanup_xaddrs_inet6(struct rt_addrinfo *info)
 
        if (!IN6_ARE_ADDR_EQUAL(&mask, &in6mask128))
                fill_sockaddr_inet6(mask_sa, &mask, 0);
-       else {
-               info->rti_info[RTAX_NETMASK] = NULL;
-               info->rti_flags |= RTF_HOST;
-               info->rti_addrs &= ~RTA_NETMASK;
-       }
+       else
+               remove_netmask(info);
 
        /* Check gateway */
        if (info->rti_info[RTAX_GATEWAY] != NULL)
@@ -1467,6 +1469,15 @@ cleanup_xaddrs(struct rt_addrinfo *info)
        if (info->rti_info[RTAX_DST] == NULL)
                return (EINVAL);
 
+       if (info->rti_flags & RTF_LLDATA) {
+               /*
+                * arp(8)/ndp(8) sends RTA_NETMASK for the associated
+                * prefix along with the actual address in RTA_DST.
+                * Remove netmask to avoid unnecessary address masking.
+                */
+               remove_netmask(info);
+       }
+
        switch (info->rti_info[RTAX_DST]->sa_family) {
 #ifdef INET
        case AF_INET:
diff --git a/usr.sbin/arp/arp.c b/usr.sbin/arp/arp.c
index 07e07f1f2da9..08698c7bc299 100644
--- a/usr.sbin/arp/arp.c
+++ b/usr.sbin/arp/arp.c
@@ -717,7 +717,6 @@ rtmsg(int cmd, struct sockaddr_in *dst, struct sockaddr_dl 
*sdl)
        static int seq;
        int rlen;
        int l;
-       struct sockaddr_in so_mask, *som = &so_mask;
        static int s = -1;
        static pid_t pid;
 
@@ -735,9 +734,6 @@ rtmsg(int cmd, struct sockaddr_in *dst, struct sockaddr_dl 
*sdl)
                        xo_err(1, "socket");
                pid = getpid();
        }
-       bzero(&so_mask, sizeof(so_mask));
-       so_mask.sin_len = 8;
-       so_mask.sin_addr.s_addr = 0xffffffff;
 
        errno = 0;
        /*
@@ -758,10 +754,6 @@ rtmsg(int cmd, struct sockaddr_in *dst, struct sockaddr_dl 
*sdl)
                rtm->rtm_rmx.rmx_expire = expire_time;
                rtm->rtm_inits = RTV_EXPIRE;
                rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);
-               if (doing_proxy) {
-                       rtm->rtm_addrs |= RTA_NETMASK;
-                       rtm->rtm_flags &= ~RTF_HOST;
-               }
                /* FALLTHROUGH */
        case RTM_GET:
                rtm->rtm_addrs |= RTA_DST;
@@ -776,7 +768,6 @@ rtmsg(int cmd, struct sockaddr_in *dst, struct sockaddr_dl 
*sdl)
 
        NEXTADDR(RTA_DST, dst);
        NEXTADDR(RTA_GATEWAY, sdl);
-       NEXTADDR(RTA_NETMASK, som);
 
        rtm->rtm_msglen = cp - (char *)&m_rtmsg;
 doit:
diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c
index aa40e2775a59..ce21e34417c3 100644
--- a/usr.sbin/ndp/ndp.c
+++ b/usr.sbin/ndp/ndp.c
@@ -860,12 +860,6 @@ rtmsg(int cmd)
                        rtm->rtm_inits = RTV_EXPIRE;
                }
                rtm->rtm_flags |= (RTF_HOST | RTF_STATIC | RTF_LLDATA);
-#if 0          /* we don't support ipv6addr/128 type proxying */
-               if (rtm->rtm_flags & RTF_ANNOUNCE) {
-                       rtm->rtm_flags &= ~RTF_HOST;
-                       rtm->rtm_addrs |= RTA_NETMASK;
-               }
-#endif
                /* FALLTHROUGH */
        case RTM_GET:
                rtm->rtm_addrs |= RTA_DST;
@@ -873,10 +867,6 @@ rtmsg(int cmd)
 
        NEXTADDR(RTA_DST, sin_m);
        NEXTADDR(RTA_GATEWAY, sdl_m);
-#if 0  /* we don't support ipv6addr/128 type proxying */
-       memset(&so_mask.sin6_addr, 0xff, sizeof(so_mask.sin6_addr));
-       NEXTADDR(RTA_NETMASK, so_mask);
-#endif
 
        rtm->rtm_msglen = cp - (char *)&m_rtmsg;
 doit:
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to