Hi,
If we delete cloning routes, we also delete their cloned routes.
This doesn't make sense if we delete a multipath cloning route and may result in
broken gateway routes:
# netstat -rn | grep 192.168.178
default 192.168.178.1 UGS 5 4939 - 12 iwn0
192.168.178/24 192.168.178.52 UCPn 1 51 - 8 iwn0
192.168.178/24 192.168.178.53 UCPn 0 0 - 8 iwn0
192.168.178.1 34:31:c4:24:83:d4 UHLch 1 118 - 7 iwn0
192.168.178.52 a4:4e:31:38:70:7c UHLl 0 3749 - 1 iwn0
192.168.178.53 a4:4e:31:38:70:7c UHLl 0 0 - 1 iwn0
192.168.178.255 192.168.178.52 UHPb 0 0 - 1 iwn0
192.168.178.255 192.168.178.53 UHPb 0 0 - 1 iwn0
As you can see above, iwn0 has 192.168.178.52/24 and 192.168.178.53/24 assigned
and therefore we have 2 mpath cloning routes (P). Their is a cloned route to
192.168.178.1 with RTF_CACHED (h) to reach the default gateway.
# ifconfig iwn0 inet 192.168.178.53 delete
# netstat -rn | grep 192.168.178
default 192.168.178.1 UGS 5 4955 - 12 iwn0
192.168.178/24 192.168.178.52 UCn 0 51 - 8 iwn0
192.168.178.52 a4:4e:31:38:70:7c UHLl 0 3754 - 1 iwn0
192.168.178.255 192.168.178.52 UHb 0 0 - 1 iwn0
Now 192.168.178.53/24 was deleted, therefore the cloned route to the gateway
(192.168.178.1) is also gone and the default route is 'broken':
# ping 8.8.8.8
# dmesg | tail
arpresolve: 192.168.178.1: route contains no arp information
arpresolve: 192.168.178.1: route contains no arp information
arpresolve: 192.168.178.1: route contains no arp information
arpresolve: 192.168.178.1: route contains no arp information
I think there is no need to delete cloned routes as long as we don't delete
the last cloning route to a network.
ok?
friehm
Index: sys/net/route.c
===================================================================
RCS file: /home/friehm/repos/openbsd-cvs/cvs/src/sys/net/route.c,v
retrieving revision 1.371
diff -u -p -r1.371 route.c
--- sys/net/route.c 10 Feb 2018 09:17:56 -0000 1.371
+++ sys/net/route.c 14 Feb 2018 09:37:29 -0000
@@ -781,7 +781,7 @@ rtrequest_delete(struct rt_addrinfo *inf
rt_putgwroute(rt);
/* Clean up any cloned children. */
- if (ISSET(rt->rt_flags, RTF_CLONING))
+ if (ISSET(rt->rt_flags, RTF_CLONING) && !ISSET(rt->rt_flags, RTF_MPATH))
rtflushclone(tableid, rt);
rtfree(rt->rt_parent);