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.
diff --git in6_ifattach.c in6_ifattach.c
index f40b1905fe4..adc54b1a4da 100644
--- in6_ifattach.c
+++ in6_ifattach.c
@@ -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;
--
I'm not entirely sure you are real.