]) # LIBCFS_I_UID_READ
#
-# LIBCFS_SOCK_ALLOC_FILE
-#
-# FC18 3.7.2-201 unexport sock_map_fd() change to
-# use sock_alloc_file().
-# upstream commit 56b31d1c9f1e6a3ad92e7bfe252721e05d92b285
-#
-AC_DEFUN([LIBCFS_SOCK_ALLOC_FILE], [
-LB_CHECK_EXPORT([sock_alloc_file], [net/socket.c], [
- LB_CHECK_COMPILE([if 'sock_alloc_file' takes 3 arguments],
- sock_alloc_file_3args, [
- #include <linux/net.h>
- ],[
- sock_alloc_file(NULL, 0, NULL);
- ],[
- AC_DEFINE(HAVE_SOCK_ALLOC_FILE_3ARGS, 1,
- [sock_alloc_file takes 3 arguments])
- ],[
- AC_DEFINE(HAVE_SOCK_ALLOC_FILE, 1,
- [sock_alloc_file is exported])
- ])
-])
-]) # LIBCFS_SOCK_ALLOC_FILE
-
-#
# LIBCFS_HAVE_CRC32
#
AC_DEFUN([LIBCFS_HAVE_CRC32], [
# 3.5
LIBCFS_PROCESS_NAMESPACE
LIBCFS_I_UID_READ
-# 3.7
-LIBCFS_SOCK_ALLOC_FILE
# 3.8
LIBCFS_HAVE_CRC32
LIBCFS_ENABLE_CRC32_ACCEL
#include <lnet/lib-lnet.h>
static int
-kernel_sock_unlocked_ioctl(struct file *filp, int cmd, unsigned long arg)
-{
- mm_segment_t oldfs = get_fs();
- int err;
-
- set_fs(KERNEL_DS);
- err = filp->f_op->unlocked_ioctl(filp, cmd, arg);
- set_fs(oldfs);
-
- return err;
-}
-
-static int
lnet_sock_ioctl(int cmd, unsigned long arg)
{
- struct file *sock_filp;
- struct socket *sock;
- int fd = -1;
- int rc;
+ struct socket *sock;
+ int rc;
#ifdef HAVE_SOCK_CREATE_KERN_USE_NET
rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock);
return rc;
}
-#if !defined(HAVE_SOCK_ALLOC_FILE) && !defined(HAVE_SOCK_ALLOC_FILE_3ARGS)
- fd = sock_map_fd(sock, 0);
- if (fd < 0) {
- rc = fd;
- sock_release(sock);
- goto out;
- }
- sock_filp = fget(fd);
-#else
-# ifdef HAVE_SOCK_ALLOC_FILE_3ARGS
- sock_filp = sock_alloc_file(sock, 0, NULL);
-# else
- sock_filp = sock_alloc_file(sock, 0);
-# endif
-#endif
- if (IS_ERR(sock_filp)) {
- rc = PTR_ERR(sock_filp);
- sock_release(sock);
- goto out;
+ if (cmd == SIOCGIFFLAGS) {
+ /* This cmd is used only to get IFF_UP flag */
+ struct ifreq *ifr = (struct ifreq *) arg;
+ struct net_device *dev;
+
+ dev = dev_get_by_name(sock_net(sock->sk), ifr->ifr_name);
+ if (dev) {
+ ifr->ifr_flags = dev->flags;
+ dev_put(dev);
+ rc = 0;
+ } else {
+ rc = -ENODEV;
+ }
+ } else {
+ rc = kernel_sock_ioctl(sock, cmd, arg);
}
+ sock_release(sock);
- rc = kernel_sock_unlocked_ioctl(sock_filp, cmd, arg);
-
- fput(sock_filp);
-out:
- if (fd >= 0)
- sys_close(fd);
return rc;
}
lnet_ipif_enumerate(char ***namesp)
{
/* Allocate and fill in 'names', returning # interfaces/error */
- char **names;
- int toobig;
- int nalloc;
- int nfound;
- struct ifreq *ifr;
- struct ifconf ifc;
- int rc;
- int nob;
- int i;
+ struct net_device *dev;
+ struct socket *sock;
+ char **names;
+ int toobig;
+ int nalloc;
+ int nfound;
+ int rc;
+ int nob;
+ int i;
nalloc = 16; /* first guess at max interfaces */
toobig = 0;
- for (;;) {
- if (nalloc * sizeof(*ifr) > PAGE_SIZE) {
- toobig = 1;
- nalloc = PAGE_SIZE / sizeof(*ifr);
- CWARN("Too many interfaces: only enumerating "
- "first %d\n", nalloc);
- }
-
- LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr));
- if (ifr == NULL) {
- CERROR("ENOMEM enumerating up to %d interfaces\n",
- nalloc);
- rc = -ENOMEM;
- goto out0;
- }
-
- ifc.ifc_buf = (char *)ifr;
- ifc.ifc_len = nalloc * sizeof(*ifr);
-
- rc = lnet_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);
- if (rc < 0) {
- CERROR("Error %d enumerating interfaces\n", rc);
- goto out1;
- }
+ nfound = 0;
- LASSERT(rc == 0);
-
- nfound = ifc.ifc_len/sizeof(*ifr);
- LASSERT(nfound <= nalloc);
-
- if (nfound < nalloc || toobig)
- break;
-
- LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
- nalloc *= 2;
+#ifdef HAVE_SOCK_CREATE_KERN_USE_NET
+ rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock);
+#else
+ rc = sock_create_kern(PF_INET, SOCK_STREAM, 0, &sock);
+#endif
+ if (rc) {
+ CERROR("Can't create socket: %d\n", rc);
+ return rc;
}
+ for_each_netdev(sock_net(sock->sk), dev)
+ nfound++;
+
if (nfound == 0)
- goto out1;
+ goto out_release_sock;
LIBCFS_ALLOC(names, nfound * sizeof(*names));
if (names == NULL) {
rc = -ENOMEM;
- goto out1;
+ goto out_release_sock;
}
- for (i = 0; i < nfound; i++) {
- nob = strnlen(ifr[i].ifr_name, IFNAMSIZ);
+ i = 0;
+ for_each_netdev(sock_net(sock->sk), dev) {
+ nob = strnlen(dev->name, IFNAMSIZ);
+ CERROR("netdev %s\n", dev->name);
if (nob == IFNAMSIZ) {
/* no space for terminating NULL */
CERROR("interface name %.*s too long (%d max)\n",
- nob, ifr[i].ifr_name, IFNAMSIZ);
+ nob, dev->name, IFNAMSIZ);
rc = -ENAMETOOLONG;
- goto out2;
+ goto out_free_names;
}
LIBCFS_ALLOC(names[i], IFNAMSIZ);
- if (names[i] == NULL) {
+ if (!names[i]) {
rc = -ENOMEM;
- goto out2;
+ goto out_free_names;
}
- memcpy(names[i], ifr[i].ifr_name, nob);
+ memcpy(names[i], dev->name, nob);
names[i][nob] = 0;
+ i++;
}
*namesp = names;
- rc = nfound;
+ rc = i;
- out2:
+out_free_names:
if (rc < 0)
lnet_ipif_free_enumeration(names, nfound);
- out1:
- LIBCFS_FREE(ifr, nalloc * sizeof(*ifr));
- out0:
+out_release_sock:
+ sock_release(sock);
return rc;
}
EXPORT_SYMBOL(lnet_ipif_enumerate);