Make in6_ifdetach() remove the ff01::1 route for the detaching interface, too.
authorstsp <stsp@openbsd.org>
Mon, 6 Jan 2014 13:01:20 +0000 (13:01 +0000)
committerstsp <stsp@openbsd.org>
Mon, 6 Jan 2014 13:01:20 +0000 (13:01 +0000)
The route used to linger after an interface detached from IPv6.
ok mikeb

sys/netinet6/in6_ifattach.c

index dfd7235..4a558bd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: in6_ifattach.c,v 1.64 2013/11/28 10:16:44 mpi Exp $   */
+/*     $OpenBSD: in6_ifattach.c,v 1.65 2014/01/06 13:01:20 stsp Exp $  */
 /*     $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $  */
 
 /*
@@ -688,6 +688,26 @@ in6_ifdetach(struct ifnet *ifp)
         */
        nd6_purge(ifp);
 
+       /* remove route to interface local allnodes multicast (ff01::1) */
+       bzero(&sin6, sizeof(sin6));
+       sin6.sin6_len = sizeof(struct sockaddr_in6);
+       sin6.sin6_family = AF_INET6;
+       sin6.sin6_addr = in6addr_intfacelocal_allnodes;
+       sin6.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+       rt = rtalloc1(sin6tosa(&sin6), 0, ifp->if_rdomain);
+       if (rt && rt->rt_ifp == ifp) {
+               struct rt_addrinfo info;
+
+               bzero(&info, sizeof(info));
+               info.rti_flags = rt->rt_flags;
+               info.rti_info[RTAX_DST] = rt_key(rt);
+               info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;
+               info.rti_info[RTAX_NETMASK] = rt_mask(rt);
+               rtrequest1(RTM_DELETE, &info, rt->rt_priority, NULL,
+                   ifp->if_rdomain);
+               rtfree(rt);
+       }
+
        /* remove route to link-local allnodes multicast (ff02::1) */
        bzero(&sin6, sizeof(sin6));
        sin6.sin6_len = sizeof(struct sockaddr_in6);