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