git: 0785c323f31c - main - Convert nfs bootp/diskless to use IfAPI
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 02 May 2023 18:46:52 UTC
The branch main has been updated by jhibbits: URL: https://cgit.FreeBSD.org/src/commit/?id=0785c323f31cd7c4039139bc8fb1f994dfe6cba6 commit 0785c323f31cd7c4039139bc8fb1f994dfe6cba6 Author: Justin Hibbits <jhibbits@FreeBSD.org> AuthorDate: 2023-02-07 19:37:03 +0000 Commit: Justin Hibbits <jhibbits@FreeBSD.org> CommitDate: 2023-05-02 18:35:58 +0000 Convert nfs bootp/diskless to use IfAPI Use the new IfAPI interface and address iterators so the nfs driver doesn't need direct access to the interface structures. Sponsored by: Juniper Networks, Inc. Differential Revision: https://reviews.freebsd.org/D38962 --- sys/nfs/bootp_subr.c | 100 +++++++++++++++++++++++++------------------------ sys/nfs/nfs_diskless.c | 59 +++++++++++++++++------------ 2 files changed, 86 insertions(+), 73 deletions(-) diff --git a/sys/nfs/bootp_subr.c b/sys/nfs/bootp_subr.c index 62fcb06fbc5d..d10139756447 100644 --- a/sys/nfs/bootp_subr.c +++ b/sys/nfs/bootp_subr.c @@ -137,7 +137,7 @@ struct bootpc_ifcontext { } _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 @@ static void bootpc_tag_helper(struct bootpc_tagcontext *tctx, 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,35 @@ static __inline int bootpc_ifctx_isfailed(struct bootpc_ifcontext *ifctx); */ #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); } void bootpboot_p_iflist(void) { - struct ifnet *ifp; - struct ifaddr *ifa; + struct epoch_tracker et; + struct if_iter iter; + if_t ifp; 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); + for (ifp = if_iter_start(&iter); ifp != NULL; ifp = if_iter_next(&iter)) + if_foreach_addr_type(ifp, AF_INET, bootpboot_p_ifa, ifp); + if_iter_finish(&iter); + NET_EPOCH_EXIT(et); } #endif /* defined(BOOTP_DEBUG) */ @@ -1498,14 +1494,31 @@ bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx, } } +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); +} + 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; + struct if_iter iter; + if_t ifp; int error; #ifndef BOOTP_WIRED_TO int ifcnt; @@ -1573,22 +1586,15 @@ bootpc_init(void) * attaches and wins the race, it won't be eligible for bootp. */ ifcnt = 0; - IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { - if ((ifp->if_flags & - (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != + NET_EPOCH_ENTER(et); + for (if_t ifp = if_iter_start(&iter); ifp != NULL; ifp = if_iter_next(&iter)) { + if ((if_getflags(ifp) & + (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) == IFF_BROADCAST) - continue; - switch (ifp->if_alloctype) { - case IFT_ETHER: - break; - default: - continue; - } - ifcnt++; + ifcnt++; } - - IFNET_RUNLOCK(); + if_iter_finish(&iter); + NET_EPOCH_EXIT(et); if (ifcnt == 0) { printf("WARNING: BOOTP found no eligible network interfaces, skipping!\n"); goto out; @@ -1600,37 +1606,32 @@ bootpc_init(void) retry: ifctx = STAILQ_FIRST(&gctx->interfaces); - IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { + NET_EPOCH_ENTER(et); + for (ifp = if_iter_start(&iter); ifp != NULL; ifp = if_iter_next(&iter)) { if (ifctx == NULL) break; #ifdef BOOTP_WIRED_TO - if (strcmp(ifp->if_xname, __XSTRING(BOOTP_WIRED_TO)) != 0) + if (strcmp(if_name(ifp), __XSTRING(BOOTP_WIRED_TO)) != 0) continue; #else - if ((ifp->if_flags & + if ((if_getflags(ifp) & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST)) != IFF_BROADCAST) - continue; - switch (ifp->if_alloctype) { + break; + switch (if_getalloctype(ifp)) { case IFT_ETHER: break; default: continue; } #endif - strlcpy(ifctx->ireq.ifr_name, ifp->if_xname, + strlcpy(ifctx->ireq.ifr_name, if_name(ifp), 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_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); @@ -1638,7 +1639,8 @@ retry: ifctx = STAILQ_NEXT(ifctx, next); } - IFNET_RUNLOCK(); + if_iter_finish(&iter); + NET_EPOCH_EXIT(et); CURVNET_RESTORE(); if (STAILQ_EMPTY(&gctx->interfaces) || @@ -1702,7 +1704,7 @@ retry: 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 index 6df01e56f9b2..8f21861ab27e 100644 --- a/sys/nfs/nfs_diskless.c +++ b/sys/nfs/nfs_diskless.c @@ -146,6 +146,19 @@ nfs_parse_options(const char *envopts, struct nfs_args *nd) free(opts, M_TEMP); } +static u_int +nfs_setup_diskless_ifa_cb(void *arg, struct sockaddr_dl *sdl, u_int count) +{ + struct sockaddr_dl *ourdl = arg; + + if ((sdl->sdl_type == ourdl->sdl_type) && + (sdl->sdl_alen == ourdl->sdl_alen) && + !bcmp(LLADDR(sdl), LLADDR(ourdl), sdl->sdl_alen)) + return (1); + + return (0); +} + /* * Populate the essential fields in the nfsv3_diskless structure. * @@ -166,16 +179,18 @@ nfs_parse_options(const char *envopts, struct nfs_args *nd) void nfs_setup_diskless(void) { + struct epoch_tracker et; + struct if_iter iter; struct nfs_diskless *nd = &nfs_diskless; struct nfsv3_diskless *nd3 = &nfsv3_diskless; - struct ifnet *ifp; - struct ifaddr *ifa; - struct sockaddr_dl *sdl, ourdl; + if_t ifp; + struct sockaddr_dl ourdl; struct sockaddr_in myaddr, netmask; char *cp; int cnt, fhlen, is_nfsv3; uint32_t len; time_t timeout_at; + u_int count; if (nfs_diskless_valid != 0) return; @@ -219,29 +234,25 @@ nfs_setup_diskless(void) printf("nfs_diskless: no hardware address\n"); return; } - ifa = NULL; timeout_at = time_uptime + NFS_IFACE_TIMEOUT_SECS; 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; - } - } - } + NET_EPOCH_ENTER(et); + + for (ifp = if_iter_start(&iter); ifp != NULL; ifp = if_iter_next(&iter)) { + count = if_foreach_lladdr(ifp, nfs_setup_diskless_ifa_cb, &ourdl); + + if (count > 0) + break; + } - IFNET_RUNLOCK(); + if_iter_finish(&iter); + NET_EPOCH_EXIT(et); CURVNET_RESTORE(); + if (cnt > 0) { + goto match_done; + } + if (time_uptime < timeout_at) { pause("nfssdl", hz / 5); goto retry; @@ -249,9 +260,9 @@ retry: 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 +301,7 @@ match_done: 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 */