When I sent this around in april it still needed the kernel lock which
made it fuggly... Now the netlock is enough.

Introduce RTM_CHGADDRATTR to inform userland on the route socket when
an attribute of an address is changed.
For now it's used when IPv6 duplicate address detection finishes.

With this slaacd(8) can find out if a configured address is not
duplicated without the need to poll.

OK?

diff --git sbin/route/route.c sbin/route/route.c
index a0ac03c646a..5dff7eec3aa 100644
--- sbin/route/route.c
+++ sbin/route/route.c
@@ -1226,7 +1226,8 @@ char *msgtypes[] = {
        "RTM_DESYNC: route socket overflow",
        "RTM_INVALIDATE: invalidate cache of L2 route",
        "RTM_BFD: bidirectional forwarding detection",
-       "RTM_PROPOSAL: config proposal"
+       "RTM_PROPOSAL: config proposal",
+       "RTM_CHGADDRATTR: address attributes being changed"
 };
 
 char metricnames[] =
@@ -1297,6 +1298,7 @@ print_rtmsg(struct rt_msghdr *rtm, int msglen)
                break;
        case RTM_NEWADDR:
        case RTM_DELADDR:
+       case RTM_CHGADDRATTR:
                ifam = (struct ifa_msghdr *)rtm;
                printf(", metric %d, flags:", ifam->ifam_metric);
                bprintf(stdout, ifam->ifam_flags, routeflags);
diff --git sys/net/route.h sys/net/route.h
index 43386fa41a6..b6fc1f3aee9 100644
--- sys/net/route.h
+++ sys/net/route.h
@@ -240,6 +240,7 @@ struct rt_msghdr {
 #define RTM_INVALIDATE 0x11    /* Invalidate cache of L2 route */
 #define RTM_BFD                0x12    /* bidirectional forwarding detection */
 #define RTM_PROPOSAL   0x13    /* proposal for netconfigd */
+#define RTM_CHGADDRATTR        0x14    /* address attribute change */
 
 #define RTV_MTU                0x1     /* init or lock _mtu */
 #define RTV_HOPCOUNT   0x2     /* init or lock _hopcount */
diff --git sys/netinet6/nd6_nbr.c sys/netinet6/nd6_nbr.c
index d63279a0b8b..2ef3f116e2e 100644
--- sys/netinet6/nd6_nbr.c
+++ sys/netinet6/nd6_nbr.c
@@ -1100,6 +1100,9 @@ nd6_dad_start(struct ifaddr *ifa)
        KASSERT(ia6->ia6_flags & IN6_IFF_TENTATIVE);
        if ((ia6->ia6_flags & IN6_IFF_ANYCAST) || (!ip6_dad_count)) {
                ia6->ia6_flags &= ~IN6_IFF_TENTATIVE;
+
+               rtm_addr(RTM_CHGADDRATTR, ifa);
+
                return;
        }
 
@@ -1248,6 +1251,8 @@ nd6_dad_timer(void *xifa)
                         */
                        ia6->ia6_flags &= ~IN6_IFF_TENTATIVE;
 
+                       rtm_addr(RTM_CHGADDRATTR, ifa);
+
                        nd6log((LOG_DEBUG,
                            "%s: DAD complete for %s - no duplicates found\n",
                            ifa->ifa_ifp->if_xname,
@@ -1291,6 +1296,9 @@ nd6_dad_duplicated(struct dadq *dp)
            ia6->ia_ifp->if_xname);
 
        TAILQ_REMOVE(&dadq, dp, dad_list);
+
+       rtm_addr(RTM_CHGADDRATTR, dp->dad_ifa);
+
        ifafree(dp->dad_ifa);
        free(dp, M_IP6NDP, sizeof(*dp));
        ip6_dad_pending--;


-- 
I'm not entirely sure you are real.

Reply via email to