Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Enable to remove multiple ARP/NDP entries for one destination
details: https://anonhg.NetBSD.org/src/rev/d3e33578de6f
branches: trunk
changeset: 354756:d3e33578de6f
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Wed Jun 28 08:17:50 2017 +0000
description:
Enable to remove multiple ARP/NDP entries for one destination
The kernel can have multiple ARP/NDP entries which have an indentical
destination on different interfaces. This is normal and can be
reproduce easily by ping -I or ping6 -S. We should be able to remove
such entries.
arp -d <ip> and ndp -d <ip> are changed to fetch all ARP/NDP entries
and remove matched entries. So we can remove multiple entries
described above. This fetch all and selective removal behavior is
the same as arp <ip> and ndp <ip>; they also do fetch all entries
and show only matched entries.
Related to PR 51179
diffstat:
tests/net/arp/t_arp.sh | 92 ++++++++++++++++++++++++++++++++++++++----
tests/net/ndp/t_ndp.sh | 94 ++++++++++++++++++++++++++++++++++++++----
usr.sbin/arp/arp.c | 107 ++++++++++++++++++++++--------------------------
usr.sbin/ndp/ndp.c | 104 +++++++++++++++++++++++++++--------------------
4 files changed, 277 insertions(+), 120 deletions(-)
diffs (truncated from 731 to 300 lines):
diff -r 77ec9f80856e -r d3e33578de6f tests/net/arp/t_arp.sh
--- a/tests/net/arp/t_arp.sh Wed Jun 28 04:14:53 2017 +0000
+++ b/tests/net/arp/t_arp.sh Wed Jun 28 08:17:50 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: t_arp.sh,v 1.32 2017/06/28 04:14:53 ozaki-r Exp $
+# $NetBSD: t_arp.sh,v 1.33 2017/06/28 08:17:50 ozaki-r Exp $
#
# Copyright (c) 2015 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -654,7 +654,7 @@
str="$IP4DST link#2"
atf_check -s exit:0 -o match:"$str" cat $file
- # Test arp -d and resulting routing messages (RTM_GET and RTM_DELETE)
+ # Test arp -d and resulting routing messages (RTM_DELETE)
rump.route -n monitor -c 2 > $file &
pid=$?
sleep 1
@@ -662,13 +662,7 @@
wait $pid
$DEBUG && cat $file
- str="RTM_GET.+<UP,DONE,LLINFO>"
- atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
- str="<DST,GATEWAY>"
- atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
- str="$IP4DST $macaddr_dst"
- atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
- str="RTM_DELETE.+<DONE,LLINFO>"
+ str="RTM_DELETE.+<HOST,DONE,LLINFO,CLONED>"
atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
str="<DST,GATEWAY>"
atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
@@ -803,6 +797,85 @@
cleanup
}
+atf_test_case arp_stray_entries cleanup
+arp_stray_entries_head()
+{
+
+ atf_set "descr" "Tests if ARP entries are removed on route change"
+ atf_set "require.progs" "rump_server"
+}
+
+arp_stray_entries_body()
+{
+
+ rump_server_start $SOCKSRC
+ rump_server_start $SOCKDST
+
+ setup_dst_server
+ setup_src_server
+
+ rump_server_add_iface $SOCKSRC shmif1 bus1
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 rump.ifconfig shmif1 inet $IP4SRC2/24
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet
+ atf_check -s exit:0 -o ignore rump.ping -n -w 1 -c 1 $IP4DST
+ $DEBUG && rump.arp -na
+ atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
+ atf_check -s exit:0 -o not-match:'shmif1' rump.arp -n $IP4DST
+
+ # Clean up
+ atf_check -s exit:0 -o ignore rump.arp -da
+ atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
+
+ # ping from a different source address
+ atf_check -s exit:0 -o ignore \
+ rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST
+ $DEBUG && rump.arp -na
+ atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
+ # ARP reply goes back via shmif1, so a cache is created on shmif1
+ atf_check -s exit:0 -o match:'shmif1' rump.arp -n $IP4DST
+
+ # Clean up by arp -da
+ atf_check -s exit:0 -o ignore rump.arp -da
+ atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
+
+ # ping from a different source address again
+ atf_check -s exit:0 -o ignore \
+ rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST
+ atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
+ # ARP reply doen't come
+ atf_check -s exit:0 -o not-match:'shmif1' rump.arp -n $IP4DST
+
+ # Cleanup caches on the destination
+ export RUMP_SERVER=$SOCKDST
+ atf_check -s exit:0 -o ignore rump.arp -da
+ export RUMP_SERVER=$SOCKSRC
+
+ # ping from a different source address again
+ atf_check -s exit:0 -o ignore \
+ rump.ping -n -w 1 -c 1 -I $IP4SRC2 $IP4DST
+ atf_check -s exit:0 -o match:'shmif0' rump.arp -n $IP4DST
+ # ARP reply goes back via shmif1
+ atf_check -s exit:0 -o match:'shmif1' rump.arp -n $IP4DST
+
+ # Clean up by arp -d <ip>
+ atf_check -s exit:0 -o ignore rump.arp -d $IP4DST
+ # Both entries should be deleted
+ atf_check -s not-exit:0 -e match:'no entry' rump.arp -n $IP4DST
+
+ rump_server_destroy_ifaces
+}
+
+arp_stray_entries_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case arp_cache_expiration_5s
@@ -818,4 +891,5 @@
atf_add_test_case arp_purge_on_route_change
atf_add_test_case arp_purge_on_route_delete
atf_add_test_case arp_purge_on_ifdown
+ atf_add_test_case arp_stray_entries
}
diff -r 77ec9f80856e -r d3e33578de6f tests/net/ndp/t_ndp.sh
--- a/tests/net/ndp/t_ndp.sh Wed Jun 28 04:14:53 2017 +0000
+++ b/tests/net/ndp/t_ndp.sh Wed Jun 28 08:17:50 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: t_ndp.sh,v 1.28 2017/06/28 04:14:53 ozaki-r Exp $
+# $NetBSD: t_ndp.sh,v 1.29 2017/06/28 08:17:50 ozaki-r Exp $
#
# Copyright (c) 2015 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -446,7 +446,7 @@
str="$IP6DST link#2"
atf_check -s exit:0 -o match:"$str" cat $file
- # Test ndp -d and resulting routing messages (RTM_GET and RTM_DELETE)
+ # Test ndp -d and resulting routing messages (RTM_DELETE)
rump.route -n monitor -c 2 > $file &
pid=$?
sleep 1
@@ -454,13 +454,7 @@
wait $pid
$DEBUG && cat $file
- str="RTM_GET.+<UP,DONE,LLINFO>"
- atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
- str="<DST,GATEWAY>"
- atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
- str="$IP6DST $macaddr_dst"
- atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_GET $file
- str="RTM_DELETE.+<DONE,LLINFO>"
+ str="RTM_DELETE.+<HOST,DONE,LLINFO,CLONED>"
atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
str="<DST,GATEWAY>"
atf_check -s exit:0 -o match:"$str" grep -A 3 RTM_DELETE $file
@@ -600,6 +594,87 @@
cleanup
}
+atf_test_case ndp_stray_entries cleanup
+ndp_stray_entries_head()
+{
+
+ atf_set "descr" "Tests if NDP entries are removed on route change"
+ atf_set "require.progs" "rump_server"
+}
+
+ndp_stray_entries_body()
+{
+
+ rump_server_start $SOCKSRC netinet6
+ rump_server_start $SOCKDST netinet6
+
+ setup_dst_server
+ setup_src_server
+
+ rump_server_add_iface $SOCKSRC shmif1 bus1
+
+ export RUMP_SERVER=$SOCKSRC
+ atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6SRC2/64
+ atf_check -s exit:0 rump.ifconfig -w 10
+
+ $DEBUG && rump.netstat -nr -f inet6
+ atf_check -s exit:0 -o ignore rump.ping6 -n -X 1 -c 1 $IP6DST
+ $DEBUG && rump.ndp -na
+ atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
+ atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
+
+ # Clean up
+ atf_check -s exit:0 -o ignore rump.ndp -c
+ atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
+
+ # ping from a different source address
+ atf_check -s exit:0 -o ignore \
+ rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
+ $DEBUG && rump.ndp -na
+ atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
+ # ARP reply goes back via shmif1, so a cache is created on shmif1
+ atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
+
+ # Clean up by ndp -c
+ atf_check -s exit:0 -o ignore rump.ndp -c
+ atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
+
+ # ping from a different source address again
+ atf_check -s exit:0 -o ignore \
+ rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
+ atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
+ # ARP reply doen't come
+ atf_check -s exit:0 -o not-match:'shmif1' rump.ndp -n $IP6DST
+
+ # Cleanup caches on the destination
+ export RUMP_SERVER=$SOCKDST
+ $DEBUG && rump.ndp -na
+ atf_check -s exit:0 -o ignore rump.ndp -c
+ $DEBUG && rump.ndp -na
+ export RUMP_SERVER=$SOCKSRC
+
+ # ping from a different source address again
+ atf_check -s exit:0 -o ignore \
+ rump.ping6 -n -X 1 -c 1 -S $IP6SRC2 $IP6DST
+ atf_check -s exit:0 -o match:'shmif0' rump.ndp -n $IP6DST
+ # ARP reply goes back via shmif1
+ atf_check -s exit:0 -o match:'shmif1' rump.ndp -n $IP6DST
+
+ # Clean up by ndp -d <ip>
+ atf_check -s exit:0 -o ignore rump.ndp -d $IP6DST
+ # Both entries should be deleted
+ atf_check -s not-exit:0 -o ignore -e match:'no entry' rump.ndp -n $IP6DST
+
+ rump_server_destroy_ifaces
+}
+
+ndp_stray_entries_cleanup()
+{
+
+ $DEBUG && dump
+ cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case ndp_cache_expiration
@@ -611,4 +686,5 @@
atf_add_test_case ndp_purge_on_route_change
atf_add_test_case ndp_purge_on_route_delete
atf_add_test_case ndp_purge_on_ifdown
+ atf_add_test_case ndp_stray_entries
}
diff -r 77ec9f80856e -r d3e33578de6f usr.sbin/arp/arp.c
--- a/usr.sbin/arp/arp.c Wed Jun 28 04:14:53 2017 +0000
+++ b/usr.sbin/arp/arp.c Wed Jun 28 08:17:50 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: arp.c,v 1.57 2017/06/26 03:13:40 ozaki-r Exp $ */
+/* $NetBSD: arp.c,v 1.58 2017/06/28 08:17:50 ozaki-r Exp $ */
/*
* Copyright (c) 1984, 1993
@@ -42,7 +42,7 @@
#if 0
static char sccsid[] = "@(#)arp.c 8.3 (Berkeley) 4/28/95";
#else
-__RCSID("$NetBSD: arp.c,v 1.57 2017/06/26 03:13:40 ozaki-r Exp $");
+__RCSID("$NetBSD: arp.c,v 1.58 2017/06/28 08:17:50 ozaki-r Exp $");
#endif
#endif /* not lint */
@@ -79,9 +79,9 @@
#include "prog_ops.h"
static int is_llinfo(const struct sockaddr_dl *, int);
-static int delete(const char *, const char *);
+static int delete_one(struct rt_msghdr *);
static void dump(uint32_t);
-static void delete_all(void);
+static void delete(const char *, const char *);
static void sdl_print(const struct sockaddr_dl *);
static int getifname(u_int16_t, char *, size_t);
static int atosdl(const char *s, struct sockaddr_dl *sdl);
@@ -90,8 +90,8 @@
static int getinetaddr(const char *, struct in_addr *);
static int getsocket(void);
static struct rt_msghdr *
- rtmsg(const int, const int, const struct sockaddr_inarp *,
- const struct sockaddr_dl *);
+ rtmsg(const int, const int, struct rt_msghdr *,
+ const struct sockaddr_inarp *, const struct sockaddr_dl *);
static int set(int, char **);
static void usage(void) __dead;
@@ -157,11 +157,11 @@
break;
case 'd':
if (aflag && argc == 0)
- delete_all();
+ delete(NULL, NULL);
else {
Home |
Main Index |
Thread Index |
Old Index