Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Feb 2021 21:17:38 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: f9e1cd6c9920 - main - Fix arp/ndp deletion broken by 2fe5a79425c7.
Message-ID:  <202102192117.11JLHcxg000466@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by melifaro:

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

commit f9e1cd6c99200846b324a8b65f7f31ded74013bd
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2021-02-19 21:09:17 +0000
Commit:     Alexander V. Chernikov <melifaro@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102192117.11JLHcxg000466>