diff --git a/sys/nfs/bootp_subr.c b/sys/nfs/bootp_subr.c --- a/sys/nfs/bootp_subr.c +++ b/sys/nfs/bootp_subr.c @@ -137,7 +137,7 @@ } _req; #define ireq _req._ifreq #define iareq _req._in_alias_req - struct ifnet *ifp; + if_t ifp; struct sockaddr_dl *sdl; struct sockaddr_in myaddr; struct sockaddr_in netmask; @@ -263,7 +263,6 @@ unsigned char *start, int len, int tag); #ifdef BOOTP_DEBUG -void bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa); void bootpboot_p_iflist(void); #endif @@ -295,38 +294,38 @@ */ #ifdef BOOTP_DEBUG -void -bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa) +static u_int +bootpboot_p_ifa(void *ifp, struct ifaddr *ifa, u_int count __unused) { printf("%s flags %x, addr ", - ifp->if_xname, ifp->if_flags); + if_name(ifp), if_getflags(ifp)); print_sin_addr((struct sockaddr_in *) ifa->ifa_addr); printf(", broadcast "); print_sin_addr((struct sockaddr_in *) ifa->ifa_dstaddr); printf(", netmask "); print_sin_addr((struct sockaddr_in *) ifa->ifa_netmask); printf("\n"); + + return (0); +} + +static int +bootpboot_p_iflist_cb(if_t ifp, void *arg __unused) +{ + if_foreach_addr_type(ifp, AF_INET, bootpboot_p_ifa, ifp); + return (0); } void bootpboot_p_iflist(void) { - struct ifnet *ifp; - struct ifaddr *ifa; + struct epoch_tracker et; printf("Interface list:\n"); - IFNET_RLOCK(); - for (ifp = CK_STAILQ_FIRST(&V_ifnet); - ifp != NULL; - ifp = CK_STAILQ_NEXT(ifp, if_link)) { - for (ifa = CK_STAILQ_FIRST(&ifp->if_addrhead); - ifa != NULL; - ifa = CK_STAILQ_NEXT(ifa, ifa_link)) - if (ifa->ifa_addr->sa_family == AF_INET) - bootpboot_p_if(ifp, ifa); - } - IFNET_RUNLOCK(); + NET_EPOCH_ENTER(et); + if_foreach(bootpboot_p_iflist_cb, NULL); + NET_EPOCH_EXIT(et); } #endif /* defined(BOOTP_DEBUG) */ @@ -1498,14 +1497,80 @@ } } +static u_int +bootpc_init_ifa_cb(void *arg, struct ifaddr *ifa, u_int count) +{ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr; + + if (count != 0) + return (0); + + if (sdl->sdl_type != IFT_ETHER) + return (0); + + *(struct sockaddr_dl **)arg = sdl; + + return (1); +} +static int +bootpc_init_ifnet_cb(if_t ifp, void *arg) +{ + struct bootpc_ifcontext *ifctx = arg; + struct sockaddr_dl *sdl; + + if (ifctx == NULL) + return (-1); +#ifdef BOOTP_WIRED_TO + if (strcmp(if_name(ifp), __XSTRING(BOOTP_WIRED_TO)) != 0) + return (0); +#else + if ((if_getflags(ifp) & + (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != + IFF_BROADCAST) + return (0); + switch (if_getalloctype(ifp)) { + case IFT_ETHER: + break; + default: + return (0); + } +#endif + strlcpy(ifctx->ireq.ifr_name, if_name(ifp), + sizeof(ifctx->ireq.ifr_name)); + ifctx->ifp = ifp; + + /* Get HW address */ + sdl = NULL; + if_foreach_addr_type(ifp, AF_LINK, bootpc_init_ifa_cb, &sdl); + if (sdl == NULL) + panic("bootpc: Unable to find HW address for %s", + ifctx->ireq.ifr_name); + ifctx->sdl = sdl; + + ifctx = STAILQ_NEXT(ifctx, next); + return (1); +} + +#ifndef BOOTP_WIRED_TO +static int +bootpc_init_count_if_cb(if_t ifp, void *arg) +{ + int *ifcnt = arg; + + if ((if_getflags(ifp) & + (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) == + IFF_BROADCAST) + (*ifcnt)++; + return (0); +} +#endif + void bootpc_init(void) { + struct epoch_tracker et; struct bootpc_ifcontext *ifctx = NULL; /* Interface BOOTP contexts */ struct bootpc_globalcontext *gctx; /* Global BOOTP context */ - struct ifnet *ifp; - struct sockaddr_dl *sdl; - struct ifaddr *ifa; int error; #ifndef BOOTP_WIRED_TO int ifcnt; @@ -1574,20 +1639,7 @@ */ ifcnt = 0; IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { - if ((ifp->if_flags & - (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != - IFF_BROADCAST) - continue; - switch (ifp->if_alloctype) { - case IFT_ETHER: - break; - default: - continue; - } - ifcnt++; - } - + if_foreach(bootpc_init_count_if_cb, &ifcnt); IFNET_RUNLOCK(); if (ifcnt == 0) { printf("WARNING: BOOTP found no eligible network interfaces, skipping!\n"); @@ -1600,45 +1652,9 @@ retry: ifctx = STAILQ_FIRST(&gctx->interfaces); - IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { - if (ifctx == NULL) - break; -#ifdef BOOTP_WIRED_TO - if (strcmp(ifp->if_xname, __XSTRING(BOOTP_WIRED_TO)) != 0) - continue; -#else - if ((ifp->if_flags & - (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != - IFF_BROADCAST) - continue; - switch (ifp->if_alloctype) { - case IFT_ETHER: - break; - default: - continue; - } -#endif - strlcpy(ifctx->ireq.ifr_name, ifp->if_xname, - sizeof(ifctx->ireq.ifr_name)); - ifctx->ifp = ifp; - - /* Get HW address */ - sdl = NULL; - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) - if (ifa->ifa_addr->sa_family == AF_LINK) { - sdl = (struct sockaddr_dl *)ifa->ifa_addr; - if (sdl->sdl_type == IFT_ETHER) - break; - } - if (sdl == NULL) - panic("bootpc: Unable to find HW address for %s", - ifctx->ireq.ifr_name); - ifctx->sdl = sdl; - - ifctx = STAILQ_NEXT(ifctx, next); - } - IFNET_RUNLOCK(); + NET_EPOCH_ENTER(et); + if_foreach(bootpc_init_ifnet_cb, ifctx); + NET_EPOCH_EXIT(et); CURVNET_RESTORE(); if (STAILQ_EMPTY(&gctx->interfaces) || @@ -1702,7 +1718,7 @@ if (gctx->gotrootpath != 0) { struct epoch_tracker et; - kern_setenv("boot.netif.name", ifctx->ifp->if_xname); + kern_setenv("boot.netif.name", if_name(ifctx->ifp)); NET_EPOCH_ENTER(et); bootpc_add_default_route(ifctx); diff --git a/sys/nfs/nfs_diskless.c b/sys/nfs/nfs_diskless.c --- a/sys/nfs/nfs_diskless.c +++ b/sys/nfs/nfs_diskless.c @@ -146,6 +146,38 @@ free(opts, M_TEMP); } +struct nfs_setup_ifa_s { + if_t ifp; + struct sockaddr_dl *ourdl; +}; + +static u_int +nfs_setup_diskless_ifa_cb(void *arg, struct sockaddr_dl *sdl, u_int count) +{ + struct nfs_setup_ifa_s *cbs = arg; + + if ((sdl->sdl_type == cbs->ourdl->sdl_type) && + (sdl->sdl_alen == cbs->ourdl->sdl_alen) && + !bcmp(LLADDR(sdl), LLADDR(cbs->ourdl), sdl->sdl_alen)) + return (1); + + return (0); +} + +static int +nfs_setup_diskless_if_cb(if_t ifp, void *arg) +{ + struct nfs_setup_ifa_s *cbs = arg; + u_int count; + + count = if_foreach_lladdr(ifp, nfs_setup_diskless_ifa_cb, arg); + + if (count > 0) + cbs->ifp = ifp; + + return (count); +} + /* * Populate the essential fields in the nfsv3_diskless structure. * @@ -168,9 +200,9 @@ { struct nfs_diskless *nd = &nfs_diskless; struct nfsv3_diskless *nd3 = &nfsv3_diskless; - struct ifnet *ifp; - struct ifaddr *ifa; - struct sockaddr_dl *sdl, ourdl; + struct nfs_setup_ifa_s cbs; + if_t ifp; + struct sockaddr_dl ourdl; struct sockaddr_in myaddr, netmask; char *cp; int cnt, fhlen, is_nfsv3; @@ -219,29 +251,20 @@ printf("nfs_diskless: no hardware address\n"); return; } - ifa = NULL; timeout_at = time_uptime + NFS_IFACE_TIMEOUT_SECS; + cbs.ourdl = &ourdl; retry: CURVNET_SET(TD_TO_VNET(curthread)); IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family == AF_LINK) { - sdl = (struct sockaddr_dl *)ifa->ifa_addr; - if ((sdl->sdl_type == ourdl.sdl_type) && - (sdl->sdl_alen == ourdl.sdl_alen) && - !bcmp(LLADDR(sdl), - LLADDR(&ourdl), - sdl->sdl_alen)) { - IFNET_RUNLOCK(); - CURVNET_RESTORE(); - goto match_done; - } - } - } - } + + cnt = if_foreach(nfs_setup_diskless_if_cb, &cbs); IFNET_RUNLOCK(); CURVNET_RESTORE(); + if (cnt > 0) { + ifp = cbs.ifp; + goto match_done; + } + if (time_uptime < timeout_at) { pause("nfssdl", hz / 5); goto retry; @@ -249,9 +272,9 @@ printf("nfs_diskless: no interface\n"); return; /* no matching interface */ match_done: - kern_setenv("boot.netif.name", ifp->if_xname); + kern_setenv("boot.netif.name", if_name(ifp)); if (is_nfsv3 != 0) { - strlcpy(nd3->myif.ifra_name, ifp->if_xname, + strlcpy(nd3->myif.ifra_name, if_name(ifp), sizeof(nd3->myif.ifra_name)); /* set up gateway */ @@ -290,7 +313,7 @@ nfs_diskless_valid = 3; } else { - strlcpy(nd->myif.ifra_name, ifp->if_xname, + strlcpy(nd->myif.ifra_name, if_name(ifp), sizeof(nd->myif.ifra_name)); /* set up gateway */