diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c --- a/sys/compat/linsysfs/linsysfs.c +++ b/sys/compat/linsysfs/linsysfs.c @@ -72,18 +72,23 @@ static int linsysfs_ifnet_addr(PFS_FILL_ARGS) { + struct epoch_tracker et; struct l_sockaddr lsa; struct ifnet *ifp; - - ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL); - if (ifp == NULL) - return (ENOENT); - if (linux_ifhwaddr(ifp, &lsa) != 0) - return (ENOENT); - sbuf_printf(sb, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", - lsa.sa_data[0], lsa.sa_data[1], lsa.sa_data[2], - lsa.sa_data[3], lsa.sa_data[4], lsa.sa_data[5]); - return (0); + int error; + + CURVNET_SET(TD_TO_VNET(td)); + NET_EPOCH_ENTER(et); + ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name); + if (ifp != NULL && (error = linux_ifhwaddr(ifp, &lsa)) == 0) + error = sbuf_printf(sb, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", + lsa.sa_data[0], lsa.sa_data[1], lsa.sa_data[2], + lsa.sa_data[3], lsa.sa_data[4], lsa.sa_data[5]); + else + error = ENOENT; + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); + return (error == -1 ? ERANGE : error); } static int @@ -97,37 +102,58 @@ static int linsysfs_ifnet_flags(PFS_FILL_ARGS) { + struct epoch_tracker et; struct ifnet *ifp; - - ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL); - if (ifp == NULL) - return (ENOENT); - sbuf_printf(sb, "0x%x\n", linux_ifflags(ifp)); - return (0); + int error; + + CURVNET_SET(TD_TO_VNET(td)); + NET_EPOCH_ENTER(et); + ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name); + if (ifp != NULL) + error = sbuf_printf(sb, "0x%x\n", linux_ifflags(ifp)); + else + error = ENOENT; + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); + return (error == -1 ? ERANGE : error); } static int linsysfs_ifnet_ifindex(PFS_FILL_ARGS) { + struct epoch_tracker et; struct ifnet *ifp; - - ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL); - if (ifp == NULL) - return (ENOENT); - sbuf_printf(sb, "%u\n", if_getindex(ifp)); - return (0); + int error; + + CURVNET_SET(TD_TO_VNET(td)); + NET_EPOCH_ENTER(et); + ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name); + if (ifp != NULL) + error = sbuf_printf(sb, "%u\n", if_getindex(ifp)); + else + error = ENOENT; + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); + return (error == -1 ? ERANGE : error); } static int linsysfs_ifnet_mtu(PFS_FILL_ARGS) { + struct epoch_tracker et; struct ifnet *ifp; - - ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL); - if (ifp == NULL) - return (ENOENT); - sbuf_printf(sb, "%u\n", if_getmtu(ifp)); - return (0); + int error; + + CURVNET_SET(TD_TO_VNET(td)); + NET_EPOCH_ENTER(et); + ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name); + if (ifp != NULL) + error = sbuf_printf(sb, "%u\n", if_getmtu(ifp)); + else + error = ENOENT; + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); + return (error == -1 ? ERANGE : error); } static int @@ -142,16 +168,21 @@ static int linsysfs_ifnet_type(PFS_FILL_ARGS) { + struct epoch_tracker et; struct l_sockaddr lsa; struct ifnet *ifp; - - ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL); - if (ifp == NULL) - return (ENOENT); - if (linux_ifhwaddr(ifp, &lsa) != 0) - return (ENOENT); - sbuf_printf(sb, "%d\n", lsa.sa_family); - return (0); + int error; + + CURVNET_SET(TD_TO_VNET(td)); + NET_EPOCH_ENTER(et); + ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name); + if (ifp != NULL && (error = linux_ifhwaddr(ifp, &lsa)) == 0) + error = sbuf_printf(sb, "%d\n", lsa.sa_family); + else + error = ENOENT; + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); + return (error == -1 ? ERANGE : error); } static void diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c --- a/sys/compat/linux/linux.c +++ b/sys/compat/linux/linux.c @@ -342,7 +342,7 @@ * bsdname and lxname need to be least IFNAMSIZ bytes long, but * can point to the same buffer. */ -struct ifname_linux_to_bsd_cb_s { +struct ifname_linux_to_ifp_cb_s { bool is_lo; bool is_eth; int ethno; @@ -352,9 +352,9 @@ }; static int -ifname_linux_to_bsd_cb(if_t ifp, void *arg) +ifname_linux_to_ifp_cb(if_t ifp, void *arg) { - struct ifname_linux_to_bsd_cb_s *cbs = arg; + struct ifname_linux_to_ifp_cb_s *cbs = arg; NET_EPOCH_ASSERT(); @@ -379,17 +379,18 @@ } struct ifnet * -ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) +ifname_linux_to_ifp(struct thread *td, const char *lxname) { - struct ifname_linux_to_bsd_cb_s arg = { + struct ifname_linux_to_ifp_cb_s arg = { .ethno = 0, .lxname = lxname, .ifp = NULL, }; - struct epoch_tracker et; - int len, ret; + int len; char *ep; + NET_EPOCH_ASSERT(); + for (len = 0; len < LINUX_IFNAMSIZ; ++len) if (!isalpha(lxname[len]) || lxname[len] == '\0') break; @@ -406,14 +407,24 @@ return (NULL); arg.is_eth = (len == 3 && strncmp(lxname, "eth", len) == 0); + if_foreach(ifname_linux_to_ifp_cb, &arg); + return (arg.ifp); +} + +struct ifnet * +ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) +{ + struct epoch_tracker et; + struct ifnet *ifp; + CURVNET_SET(TD_TO_VNET(td)); NET_EPOCH_ENTER(et); - ret = if_foreach(ifname_linux_to_bsd_cb, &arg); + ifp = ifname_linux_to_ifp(td, lxname); + if (ifp != NULL && bsdname != NULL) + strlcpy(bsdname, if_name(ifp), IFNAMSIZ); NET_EPOCH_EXIT(et); CURVNET_RESTORE(); - if (ret > 0 && arg.ifp != NULL && bsdname != NULL) - strlcpy(bsdname, if_name(arg.ifp), IFNAMSIZ); - return (arg.ifp); + return (ifp); } unsigned short diff --git a/sys/compat/linux/linux_common.h b/sys/compat/linux/linux_common.h --- a/sys/compat/linux/linux_common.h +++ b/sys/compat/linux/linux_common.h @@ -33,6 +33,7 @@ int ifname_bsd_to_linux_ifp(struct ifnet *, char *, size_t); int ifname_bsd_to_linux_idx(u_int, char *, size_t); int ifname_bsd_to_linux_name(const char *, char *, size_t); +struct ifnet *ifname_linux_to_ifp(struct thread *, const char *); struct ifnet *ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname);