diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2018-07-10 20:44:40 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2018-07-10 20:44:40 +0000 |
commit | b65941cfe1e02b43b0e703c606536827e00f2b86 (patch) | |
tree | b4aa4d661cade22ea1a9fa3b6b8ac44fe42fcd6c | |
parent | 60400c9c09e3dea98df808d4f5cbe1e398928f44 (diff) |
When an interface doesn't have a layer 2 address in6_get_soii_ifid()
failes and then later on a in in6_get_ifid() a layer 2 address is
"borrowed" from from another interface.
Do the "borrowing" in in6_get_soii_ifid(), too so that semantically
opaque interface identifiers work for these kind of interfaces, too.
OK phessler, benno
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 9aea2260ad3..7ea489a9bd7 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_ifattach.c,v 1.108 2018/07/10 20:43:26 florian Exp $ */ +/* $OpenBSD: in6_ifattach.c,v 1.109 2018/07/10 20:44:39 florian Exp $ */ /* $KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $ */ /* @@ -216,8 +216,9 @@ in6_get_hw_ifid(struct ifnet *ifp, struct in6_addr *in6) * in6 - upper 64bits are preserved */ int -in6_get_soii_ifid(struct ifnet *ifp, struct in6_addr *in6) +in6_get_soii_ifid(struct ifnet *ifp0, struct in6_addr *in6) { + struct ifnet *ifp; SHA2_CTX ctx; u_int8_t digest[SHA512_DIGEST_LENGTH]; struct in6_addr prefix; @@ -225,10 +226,25 @@ in6_get_soii_ifid(struct ifnet *ifp, struct in6_addr *in6) int dad_counter = 0; /* XXX not used */ char *addr; - if (ifp->if_xflags & IFXF_INET6_NOSOII) + if (ifp0->if_xflags & IFXF_INET6_NOSOII) return -1; - sdl = ifp->if_sadl; + sdl = ifp0->if_sadl; + + if (sdl == NULL || sdl->sdl_alen == 0) { + /* + * try to get it from some other hardware interface like + * in in6_get_ifid() + */ + TAILQ_FOREACH(ifp, &ifnet, if_list) { + if (ifp == ifp0) + continue; + sdl = ifp->if_sadl; + if (sdl != NULL && sdl->sdl_alen != 0) + break; + } + } + if (sdl == NULL || sdl->sdl_alen == 0) return -1; |