tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: IPv6 socket behaviour different to IPv4?



On 4/06/2014 10:55 PM, Roy Marples wrote:
...
I'm still not entirely sure what your use case is or why you believe it's important to talk to an address on a non functioning interface (ie, it's down or no carrier) If you want the same behavioral traits as IPv4 then at a guess you would need to make IN6_IFF_NODAD assignable from userland (currently it's rejected).
I'm not entirely sure that's a good idea though.

I'm inclined to agree with you on that part because DAD is a useful
activity to perform regardless of how the IP address was assigned,
however ...

Looking at the source, it appears that flag is not properly used even now
(see the patch below.)

It would seem that "tentative" is also being overloaded in how it is
used as this comment:

         * If my address is tentative, this means that there's somebody
* already using the same address as mine. This indicates DAD failure.
         * This is defined in RFC 2462.
         *

does not reflect that tentative is used to mark an address that is
newly assigned to an interface or that an interface has gone through
a down/up transition.

There is an existing lever, net.inet6.ip6.dad_count, which when set to 0
turns off DAD completely. If a global such as this exists, why not allow
for a more local setting - even if it is per-interface?

Darren

--- sys/netinet6/in6_var.h.orig      2014-06-05 00:38:38.000000000 +1000
+++ sys/netinet6/in6_var.h   2014-06-05 00:39:09.000000000 +1000
@@ -681,7 +681,7 @@
 int    in6_update_ifa(struct ifnet *, struct in6_aliasreq *,
        struct in6_ifaddr *, int);
 void   in6_purgeaddr(struct ifaddr *);
-int    in6if_do_dad(struct ifnet *);
+int    in6if_do_dad(struct ifnet *, struct struct in6_ifaddr *);
 void   in6_purgeif(struct ifnet *);
 void   in6_savemkludge(struct in6_ifaddr *);
 void   in6_setmaxmtu  (void);

--- sys/netinet6/in6.c.orig  2014-06-05 00:27:51.000000000 +1000
+++ sys/netinet6/in6.c       2014-06-05 00:38:15.000000000 +1000
@@ -1077,7 +1077,7 @@
        if (ifp->if_link_state == LINK_STATE_DOWN) {
                ia->ia6_flags |= IN6_IFF_DETACHED;
                ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
-       } else if (hostIsNew && in6if_do_dad(ifp))
+       } else if (hostIsNew && in6if_do_dad(ifp, ia))
                ia->ia6_flags |= IN6_IFF_TENTATIVE;

        /*
@@ -1303,8 +1303,7 @@
         * XXX It may be of use, if we can administratively
         * disable DAD.
         */
-       if (hostIsNew && in6if_do_dad(ifp) &&
-           ((ifra->ifra_flags & IN6_IFF_NODAD) == 0) &&
+       if (hostIsNew && in6if_do_dad(ifp, ia) &&
            (ia->ia6_flags & IN6_IFF_TENTATIVE))
        {
                int mindelay, maxdelay;
@@ -2232,11 +2231,14 @@
 }

 int
-in6if_do_dad(struct ifnet *ifp)
+in6if_do_dad(struct ifnet *ifp, struct in6_ifaddr *ia)
 {
        if ((ifp->if_flags & IFF_LOOPBACK) != 0)
                return 0;

+       if ((ia->ia6_flags & IN6_IFF_NODAD) != 0))
+               return 0;
+
        switch (ifp->if_type) {
        case IFT_FAITH:
                /*



Home | Main Index | Thread Index | Old Index