git: 934a24e55a78 - main - ndp: improve -c and -d handling in ndp_netlink

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 23 Oct 2023 20:58:57 UTC
The branch main has been updated by kp:

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

commit 934a24e55a785e27faf96979602ae1954f384d67
Author:     R. Christian McDonald <rcm@rcm.sh>
AuthorDate: 2023-10-23 19:43:44 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2023-10-23 20:58:29 +0000

    ndp: improve -c and -d handling in ndp_netlink
    
    This patch restores/fixes some of the behavior present in pre-netlink ndp(8).
    
     1. Deleting a local address now correctly returns EPERM (instead of
        ENOENT)
     2. ndp -c no longer dumps the entire table while complaining about
        local addresses
     3. Return exit code when deleting entry (e.g. trying ndp -d on a local
        address is an error)
    
    Reviewed by:    kp
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
    Differential Revision:  https://reviews.freebsd.org/D42316
---
 usr.sbin/ndp/ndp.c         |  8 +++++---
 usr.sbin/ndp/ndp.h         |  2 +-
 usr.sbin/ndp/ndp_netlink.c | 13 ++++++++-----
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/usr.sbin/ndp/ndp.c b/usr.sbin/ndp/ndp.c
index b7bc25dd7aa4..23643dd6c200 100644
--- a/usr.sbin/ndp/ndp.c
+++ b/usr.sbin/ndp/ndp.c
@@ -201,6 +201,7 @@ main(int argc, char **argv)
 {
 	int ch, mode = 0;
 	char *arg = NULL;
+	int ret = 0;
 
 	pid = getpid();
 	thiszone = utc_offset();
@@ -280,7 +281,7 @@ main(int argc, char **argv)
 			/*NOTREACHED*/
 		}
 		xo_open_list("neighbor-cache");
-		delete(arg);
+		ret = delete(arg);
 		xo_close_list("neighbor-cache");
 		break;
 	case 'I':
@@ -353,7 +354,8 @@ main(int argc, char **argv)
 	}
 	xo_close_container("ndp");
 	xo_finish();
-	exit(0);
+
+	return (ret);
 }
 
 /*
@@ -841,7 +843,7 @@ static int
 delete(char *host)
 {
 #ifndef WITHOUT_NETLINK
-	return (delete_nl(0, host));
+	return (delete_nl(0, host, true)); /* do warn */
 #else
 	return (delete_rtsock(host));
 #endif
diff --git a/usr.sbin/ndp/ndp.h b/usr.sbin/ndp/ndp.h
index 5b2558982e86..f89ab19a9d3f 100644
--- a/usr.sbin/ndp/ndp.h
+++ b/usr.sbin/ndp/ndp.h
@@ -20,7 +20,7 @@ char *ether_str(struct sockaddr_dl *sdl);
 char *sec2str(time_t total);
 int getaddr(char *host, struct sockaddr_in6 *sin6);
 int print_entries_nl(uint32_t ifindex, struct sockaddr_in6 *addr, bool cflag);
-int delete_nl(uint32_t ifindex, char *host);
+int delete_nl(uint32_t ifindex, char *host, bool warn);
 int set_nl(uint32_t ifindex, struct sockaddr_in6 *dst, struct sockaddr_dl *sdl,
     char *host);
 
diff --git a/usr.sbin/ndp/ndp_netlink.c b/usr.sbin/ndp/ndp_netlink.c
index 79bdec2356d0..e18d64175619 100644
--- a/usr.sbin/ndp/ndp_netlink.c
+++ b/usr.sbin/ndp/ndp_netlink.c
@@ -180,7 +180,7 @@ guess_ifindex(struct snl_state *ss, uint32_t fibnum, const struct sockaddr_in6 *
 
 	int off = snl_add_msg_attr_nested(&nw, NHA_FREEBSD);
 	snl_add_msg_attr_u32(&nw, NHAF_KID, r.rta_knh_id);
-	snl_add_msg_attr_u8(&nw, NHAF_FAMILY, AF_INET);
+	snl_add_msg_attr_u8(&nw, NHAF_FAMILY, AF_INET6);
 	snl_add_msg_attr_u32(&nw, NHAF_TABLE, fibnum);
 	snl_end_attr_nested(&nw, off);
 
@@ -372,13 +372,14 @@ print_entries_nl(uint32_t ifindex, struct sockaddr_in6 *addr, bool cflag)
 				continue;
 		}
 
-		print_entry(&neigh, &link);
 		if (cflag) {
 			char dst_str[INET6_ADDRSTRLEN];
 
 			inet_ntop(AF_INET6, &dst->sin6_addr, dst_str, sizeof(dst_str));
-			delete_nl(neigh.nda_ifindex, dst_str);
-		}
+			delete_nl(neigh.nda_ifindex, dst_str, false); /* no warn */
+		} else
+			print_entry(&neigh, &link);
+
 		count++;
 		snl_clear_lb(&ss_req);
 	}
@@ -391,8 +392,9 @@ print_entries_nl(uint32_t ifindex, struct sockaddr_in6 *addr, bool cflag)
 }
 
 int
-delete_nl(uint32_t ifindex, char *host)
+delete_nl(uint32_t ifindex, char *host, bool warn)
 {
+#define xo_warnx(...) do { if (warn) { xo_warnx(__VA_ARGS__); } } while(0)
 	struct snl_state ss = {};
 	struct snl_writer nw;
 	struct sockaddr_in6 dst;
@@ -458,6 +460,7 @@ delete_nl(uint32_t ifindex, char *host)
 	snl_free(&ss);
 
 	return (e.error != 0);
+#undef xo_warnx /* see above */
 }
 
 int