summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2018-07-10 20:44:40 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2018-07-10 20:44:40 +0000
commitb65941cfe1e02b43b0e703c606536827e00f2b86 (patch)
treeb4aa4d661cade22ea1a9fa3b6b8ac44fe42fcd6c
parent60400c9c09e3dea98df808d4f5cbe1e398928f44 (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.c24
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;