== 2 && strncmp(lxname, "lo", LINUX_IFNAMSIZ) == 0); + arg.unit = (int)strtoul(lxname + len, &ep, 10); + if ((ep == NULL || ep == lxname + len || ep >= lxname + LINUX_IFNAMSIZ) && + arg.is_lo == 0) + return (NULL); + arg.is_eth = (len == 3 && strncmp(lxname, "eth", len) == 0); + + if_foreach(ifname_linux_to_ifp_cb, &arg); + return (arg.ifp); +} + +int +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); + ifp = ifname_linux_to_ifp(td, lxname); + if (ifp != NULL && bsdname != NULL) + strlcpy(bsdname, if_name(ifp), IFNAMSIZ); + NET_EPOCH_EXIT(et); + CURVNET_RESTORE(); + return (ifp != NULL ? 0 : EINVAL); +} + +unsigned short +linux_ifflags(struct ifnet *ifp) +{ + unsigned short flags; + + NET_EPOCH_ASSERT(); + + flags = if_getflags(ifp) | if_getdrvflags(ifp); + return (bsd_to_linux_ifflags(flags)); +} + +unsigned short +bsd_to_linux_ifflags(int fl) +{ + unsigned short flags = 0; + + if (fl & IFF_UP) + flags |= LINUX_IFF_UP; + if (fl & IFF_BROADCAST) + flags |= LINUX_IFF_BROADCAST; + if (fl & IFF_DEBUG) + flags |= LINUX_IFF_DEBUG; + if (fl & IFF_LOOPBACK) + flags |= LINUX_IFF_LOOPBACK; + if (fl & IFF_POINTOPOINT) + flags |= LINUX_IFF_POINTOPOINT; + if (fl & IFF_DRV_RUNNING) + flags |= LINUX_IFF_RUNNING; + if (fl & IFF_NOARP) + flags |= LINUX_IFF_NOARP; + if (fl & IFF_PROMISC) + flags |= LINUX_IFF_PROMISC; + if (fl & IFF_ALLMULTI) + flags |= LINUX_IFF_ALLMULTI; + if (fl & IFF_MULTICAST) + flags |= LINUX_IFF_MULTICAST; + return (flags); +} + +static u_int +linux_ifhwaddr_cb(void *arg, struct ifaddr *ifa, u_int count) +{ + struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr; + struct l_sockaddr *lsa = arg; + + if (count > 0) + return (0); + if (sdl->sdl_type != IFT_ETHER) + return (0); + bzero(lsa, sizeof(*lsa)); + lsa->sa_family = LINUX_ARPHRD_ETHER; + bcopy(LLADDR(sdl), lsa->sa_data, LINUX_IFHWADDRLEN); + return (1); +} + +int +linux_ifhwaddr(struct ifnet *ifp, struct l_sockaddr *lsa) +{ + + NET_EPOCH_ASSERT(); + + if (IFP_IS_LOOP(ifp)) { + bzero(lsa, sizeof(*lsa)); + lsa->sa_family = LINUX_ARPHRD_LOOPBACK; + return (0); + } + if (!IFP_IS_ETH(ifp)) + return (ENOENT); + if (if_foreach_addr_type(ifp, AF_LINK, linux_ifhwaddr_cb, lsa) > 0) + return (0); + return (ENOENT); +} diff --git a/sys/modules/linux_common/Makefile b/sys/modules/linux_common/Makefile index f9f4c791e9d1..291fc6d25f8c 100644 --- a/sys/modules/linux_common/Makefile +++ b/sys/modules/linux_common/Makefile @@ -5,7 +5,7 @@ KMOD= linux_common SRCS= linux_common.c linux_mib.c linux_mmap.c linux_util.c linux_emul.c \ - linux_dummy.c linux_errno.c linux_netlink.c \ + linux_dummy.c linux_errno.c linux_netlink.c linux_if.c \ linux.c device_if.h vnode_if.h bus_if.h opt_inet6.h opt_inet.h .if ${MACHINE_CPUARCH} == "amd64" @@ -15,7 +15,6 @@ SRCS+= linux_x86.c linux_vdso_selector_x86.c EXPORT_SYMS= EXPORT_SYMS+= linux_get_osname EXPORT_SYMS+= linux_get_osrelease -EXPORT_SYMS+= linux_use_real_ifname .if !defined(KERNBUILDDIR) .warning Building Linuxulator outside of a kernel does not make sense