diff options
-rw-r--r-- | sys/netinet/in.c | 11 | ||||
-rw-r--r-- | sys/netinet6/in6.c | 9 |
2 files changed, 17 insertions, 3 deletions
diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 2b805c6..6cb37e5 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -819,14 +819,19 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, return (error); /* - * Give the interface a chance to initialize - * if this is its first address, - * and to validate the address if necessary. + * Give the interface a chance to initialize if this is its first + * address, and to validate the address if necessary. + * + * Historically, drivers managed IFF_UP flag theirselves, so we + * need to check whether driver did that. */ + flags = ifp->if_flags; if (ifp->if_ioctl != NULL && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia)) != 0) /* LIST_REMOVE(ia, ia_hash) is done in in_control */ return (error); + if ((ifp->if_flags & IFF_UP) && (flags & IFF_UP) == 0) + if_up(ifp); /* * Be compatible with network classes, if netmask isn't supplied, diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index e260e5d..08dd259 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1874,9 +1874,18 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, ia->ia_addr = *sin6; if (ifacount <= 1 && ifp->if_ioctl) { + int flags; + + /* + * Historically, drivers managed IFF_UP flag theirselves, so we + * need to check whether driver did that. + */ + flags = ifp->if_flags; error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia); if (error) return (error); + if ((ifp->if_flags & IFF_UP) && (flags & IFF_UP) == 0) + if_up(ifp); } ia->ia_ifa.ifa_metric = ifp->if_metric; |