From 80c72fe415698049a477314ac82790c1af0fa7e3 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 May 2007 03:11:29 -0700 Subject: [AFS/AF_RXRPC]: Miscellaneous fixes. Make miscellaneous fixes to AFS and AF_RXRPC: (*) Make AF_RXRPC select KEYS rather than RXKAD or AFS_FS in Kconfig. (*) Don't use FS_BINARY_MOUNTDATA. (*) Remove a done 'TODO' item in a comemnt on afs_get_sb(). (*) Don't pass a void * as the page pointer argument of kmap_atomic() as this breaks on m68k. Patch from Geert Uytterhoeven . (*) Use match_*() functions rather than doing my own parsing. Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/Kconfig | 1 - fs/afs/fsclient.c | 3 +- fs/afs/super.c | 100 +++++++++++++++++++++++------------------------------- 3 files changed, 45 insertions(+), 59 deletions(-) (limited to 'fs') diff --git a/fs/Kconfig b/fs/Kconfig index a42f767dcdd5..e33c08924572 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -2020,7 +2020,6 @@ config AFS_FS tristate "Andrew File System support (AFS) (EXPERIMENTAL)" depends on INET && EXPERIMENTAL select AF_RXRPC - select KEYS help If you say Y here, you will get an experimental Andrew File System driver. It currently only supports unsecured read-only AFS access. diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index 2393d2a08d79..e54e6c2ad343 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -266,7 +266,8 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call, call->unmarshall++; if (call->count < PAGE_SIZE) { - buffer = kmap_atomic(call->reply3, KM_USER0); + page = call->reply3; + buffer = kmap_atomic(page, KM_USER0); memset(buffer + PAGE_SIZE - call->count, 0, call->count); kunmap_atomic(buffer, KM_USER0); diff --git a/fs/afs/super.c b/fs/afs/super.c index cebd03c91f57..41173f81ac47 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "internal.h" #define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ @@ -42,7 +43,7 @@ struct file_system_type afs_fs_type = { .name = "afs", .get_sb = afs_get_sb, .kill_sb = kill_anon_super, - .fs_flags = FS_BINARY_MOUNTDATA, + .fs_flags = 0, }; static const struct super_operations afs_super_ops = { @@ -58,6 +59,20 @@ static const struct super_operations afs_super_ops = { static struct kmem_cache *afs_inode_cachep; static atomic_t afs_count_active_inodes; +enum { + afs_no_opt, + afs_opt_cell, + afs_opt_rwpath, + afs_opt_vol, +}; + +static const match_table_t afs_options_list = { + { afs_opt_cell, "cell=%s" }, + { afs_opt_rwpath, "rwpath" }, + { afs_opt_vol, "vol=%s" }, + { afs_no_opt, NULL }, +}; + /* * initialise the filesystem */ @@ -114,31 +129,6 @@ void __exit afs_fs_exit(void) _leave(""); } -/* - * check that an argument has a value - */ -static int want_arg(char **_value, const char *option) -{ - if (!_value || !*_value || !**_value) { - printk(KERN_NOTICE "kAFS: %s: argument missing\n", option); - return 0; - } - return 1; -} - -/* - * check that there's no subsequent value - */ -static int want_no_value(char *const *_value, const char *option) -{ - if (*_value && **_value) { - printk(KERN_NOTICE "kAFS: %s: Invalid argument: %s\n", - option, *_value); - return 0; - } - return 1; -} - /* * parse the mount options * - this function has been shamelessly adapted from the ext3 fs which @@ -148,48 +138,46 @@ static int afs_parse_options(struct afs_mount_params *params, char *options, const char **devname) { struct afs_cell *cell; - char *key, *value; - int ret; + substring_t args[MAX_OPT_ARGS]; + char *p; + int token; _enter("%s", options); options[PAGE_SIZE - 1] = 0; - ret = 0; - while ((key = strsep(&options, ","))) { - value = strchr(key, '='); - if (value) - *value++ = 0; - - _debug("kAFS: KEY: %s, VAL:%s", key, value ?: "-"); + while ((p = strsep(&options, ","))) { + if (!*p) + continue; - if (strcmp(key, "rwpath") == 0) { - if (!want_no_value(&value, "rwpath")) - return -EINVAL; - params->rwpath = 1; - } else if (strcmp(key, "vol") == 0) { - if (!want_arg(&value, "vol")) - return -EINVAL; - *devname = value; - } else if (strcmp(key, "cell") == 0) { - if (!want_arg(&value, "cell")) - return -EINVAL; - cell = afs_cell_lookup(value, strlen(value)); + token = match_token(p, afs_options_list, args); + switch (token) { + case afs_opt_cell: + cell = afs_cell_lookup(args[0].from, + args[0].to - args[0].from); if (IS_ERR(cell)) return PTR_ERR(cell); afs_put_cell(params->cell); params->cell = cell; - } else { - printk("kAFS: Unknown mount option: '%s'\n", key); - ret = -EINVAL; - goto error; + break; + + case afs_opt_rwpath: + params->rwpath = 1; + break; + + case afs_opt_vol: + *devname = args[0].from; + break; + + default: + printk(KERN_ERR "kAFS:" + " Unknown or invalid mount option: '%s'\n", p); + return -EINVAL; } } - ret = 0; -error: - _leave(" = %d", ret); - return ret; + _leave(" = 0"); + return 0; } /* @@ -361,7 +349,6 @@ error: /* * get an AFS superblock - * - TODO: don't use get_sb_nodev(), but rather call sget() directly */ static int afs_get_sb(struct file_system_type *fs_type, int flags, @@ -386,7 +373,6 @@ static int afs_get_sb(struct file_system_type *fs_type, goto error; } - ret = afs_parse_device_name(¶ms, dev_name); if (ret < 0) goto error; -- cgit v1.2.3 From fbb3fcba72ff52ee3d9990c9dec0c95cd9d0ce17 Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 May 2007 03:12:46 -0700 Subject: [AFS]: Fix use of __exit functions from __init path Fix use of __exit functions from __init path. Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/callback.c | 2 +- fs/afs/internal.h | 4 ++-- fs/afs/vlocation.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'fs') diff --git a/fs/afs/callback.c b/fs/afs/callback.c index 639399f0ab6f..9bdbf36a9aa9 100644 --- a/fs/afs/callback.c +++ b/fs/afs/callback.c @@ -468,7 +468,7 @@ int __init afs_callback_update_init(void) /* * shut down the callback update process */ -void __exit afs_callback_update_kill(void) +void afs_callback_update_kill(void) { destroy_workqueue(afs_callback_update_worker); } diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 34665f7d7a19..3363e311a2f7 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -392,7 +392,7 @@ extern void afs_give_up_callback(struct afs_vnode *); extern void afs_dispatch_give_up_callbacks(struct work_struct *); extern void afs_flush_callback_breaks(struct afs_server *); extern int __init afs_callback_update_init(void); -extern void __exit afs_callback_update_kill(void); +extern void afs_callback_update_kill(void); /* * cell.c @@ -591,7 +591,7 @@ extern struct afs_vlocation *afs_vlocation_lookup(struct afs_cell *, struct key *, const char *, size_t); extern void afs_put_vlocation(struct afs_vlocation *); -extern void __exit afs_vlocation_purge(void); +extern void afs_vlocation_purge(void); /* * vnode.c diff --git a/fs/afs/vlocation.c b/fs/afs/vlocation.c index 6c8e95a7c2c9..3370cdb72566 100644 --- a/fs/afs/vlocation.c +++ b/fs/afs/vlocation.c @@ -602,7 +602,7 @@ int __init afs_vlocation_update_init(void) /* * discard all the volume location records for rmmod */ -void __exit afs_vlocation_purge(void) +void afs_vlocation_purge(void) { afs_vlocation_timeout = 0; -- cgit v1.2.3 From 5b35fad9d4fc2fcaf5c23887c1de1bc3eb28ab8c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 3 May 2007 03:27:39 -0700 Subject: [AFS]: Fix memory leak in SRXAFSCB_GetCapabilities The interface array is not freed on exit. Signed-off-by: Patrick McHardy Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/cmservice.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs') diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 6685f4cbccb3..d5b2ad6575bc 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -443,6 +443,7 @@ static void SRXAFSCB_GetCapabilities(struct work_struct *work) reply.ia.netmask[loop] = ifs[loop].netmask.s_addr; reply.ia.mtu[loop] = htonl(ifs[loop].mtu); } + kfree(ifs); } reply.cap.capcount = htonl(1); -- cgit v1.2.3 From dc1f6bff6a9d6733a07b9b97905bc824c055e8f4 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Thu, 3 May 2007 03:28:49 -0700 Subject: [AFS]: Replace rtnetlink client by direct dev_base walking Replace the large and complicated rtnetlink client by two simple functions for getting the MAC address for the first ethernet device and building a list of IPv4 addresses. Signed-off-by: Patrick McHardy Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/Makefile | 2 +- fs/afs/internal.h | 1 - fs/afs/netdevices.c | 54 ++++++ fs/afs/use-rtnetlink.c | 473 ------------------------------------------------- 4 files changed, 55 insertions(+), 475 deletions(-) create mode 100644 fs/afs/netdevices.c delete mode 100644 fs/afs/use-rtnetlink.c (limited to 'fs') diff --git a/fs/afs/Makefile b/fs/afs/Makefile index 01545eb1d872..cf83e5d63512 100644 --- a/fs/afs/Makefile +++ b/fs/afs/Makefile @@ -18,7 +18,7 @@ kafs-objs := \ security.o \ server.o \ super.o \ - use-rtnetlink.o \ + netdevices.o \ vlclient.o \ vlocation.o \ vnode.o \ diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 3363e311a2f7..551db896afc9 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -349,7 +349,6 @@ struct afs_permits { * record of one of a system's set of network interfaces */ struct afs_interface { - unsigned index; /* interface index */ struct in_addr address; /* IPv4 address bound to interface */ struct in_addr netmask; /* netmask applied to address */ unsigned mtu; /* MTU of interface */ diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c new file mode 100644 index 000000000000..2b3087357fa9 --- /dev/null +++ b/fs/afs/netdevices.c @@ -0,0 +1,54 @@ +/* AFS network device helpers + * + * Copyright (c) 2007 Patrick McHardy + */ + +#include +#include +#include +#include +#include +#include "internal.h" + +int afs_get_MAC_address(u8 mac[ETH_ALEN]) +{ + struct net_device *dev; + int ret = -ENODEV; + + rtnl_lock(); + dev = __dev_getfirstbyhwtype(ARPHRD_ETHER); + if (dev) { + memcpy(mac, dev->dev_addr, ETH_ALEN); + ret = 0; + } + rtnl_unlock(); + return ret; +} + +int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, + bool wantloopback) +{ + struct net_device *dev; + struct in_device *idev; + int n = 0; + + rtnl_lock(); + for (dev = dev_base; dev; dev = dev->next) { + if (dev->type == ARPHRD_LOOPBACK && !wantloopback) + continue; + idev = __in_dev_get_rtnl(dev); + if (!idev) + continue; + for_primary_ifa(idev) { + if (n == maxbufs) + goto out; + bufs[n].address.s_addr = ifa->ifa_address; + bufs[n].netmask.s_addr = ifa->ifa_mask; + bufs[n].mtu = dev->mtu; + n++; + } endfor_ifa(idev) + } +out: + rtnl_unlock(); + return n; +} diff --git a/fs/afs/use-rtnetlink.c b/fs/afs/use-rtnetlink.c deleted file mode 100644 index f8991c700e02..000000000000 --- a/fs/afs/use-rtnetlink.c +++ /dev/null @@ -1,473 +0,0 @@ -/* RTNETLINK client - * - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include -#include -#include -#include -#include "internal.h" - -struct afs_rtm_desc { - struct socket *nlsock; - struct afs_interface *bufs; - u8 *mac; - size_t nbufs; - size_t maxbufs; - void *data; - ssize_t datalen; - size_t datamax; - int msg_seq; - unsigned mac_index; - bool wantloopback; - int (*parse)(struct afs_rtm_desc *, struct nlmsghdr *); -}; - -/* - * parse an RTM_GETADDR response - */ -static int afs_rtm_getaddr_parse(struct afs_rtm_desc *desc, - struct nlmsghdr *nlhdr) -{ - struct afs_interface *this; - struct ifaddrmsg *ifa; - struct rtattr *rtattr; - const char *name; - size_t len; - - ifa = (struct ifaddrmsg *) NLMSG_DATA(nlhdr); - - _enter("{ix=%d,af=%d}", ifa->ifa_index, ifa->ifa_family); - - if (ifa->ifa_family != AF_INET) { - _leave(" = 0 [family %d]", ifa->ifa_family); - return 0; - } - if (desc->nbufs >= desc->maxbufs) { - _leave(" = 0 [max %zu/%zu]", desc->nbufs, desc->maxbufs); - return 0; - } - - this = &desc->bufs[desc->nbufs]; - - this->index = ifa->ifa_index; - this->netmask.s_addr = inet_make_mask(ifa->ifa_prefixlen); - this->mtu = 0; - - rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifaddrmsg)); - len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifaddrmsg)); - - name = "unknown"; - for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) { - switch (rtattr->rta_type) { - case IFA_ADDRESS: - memcpy(&this->address, RTA_DATA(rtattr), 4); - break; - case IFA_LABEL: - name = RTA_DATA(rtattr); - break; - } - } - - _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT, - name, NIPQUAD(this->address), NIPQUAD(this->netmask)); - - desc->nbufs++; - _leave(" = 0"); - return 0; -} - -/* - * parse an RTM_GETLINK response for MTUs - */ -static int afs_rtm_getlink_if_parse(struct afs_rtm_desc *desc, - struct nlmsghdr *nlhdr) -{ - struct afs_interface *this; - struct ifinfomsg *ifi; - struct rtattr *rtattr; - const char *name; - size_t len, loop; - - ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr); - - _enter("{ix=%d}", ifi->ifi_index); - - for (loop = 0; loop < desc->nbufs; loop++) { - this = &desc->bufs[loop]; - if (this->index == ifi->ifi_index) - goto found; - } - - _leave(" = 0 [no match]"); - return 0; - -found: - if (ifi->ifi_type == ARPHRD_LOOPBACK && !desc->wantloopback) { - _leave(" = 0 [loopback]"); - return 0; - } - - rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)); - len = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg)); - - name = "unknown"; - for (; RTA_OK(rtattr, len); rtattr = RTA_NEXT(rtattr, len)) { - switch (rtattr->rta_type) { - case IFLA_MTU: - memcpy(&this->mtu, RTA_DATA(rtattr), 4); - break; - case IFLA_IFNAME: - name = RTA_DATA(rtattr); - break; - } - } - - _debug("%s: "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u", - name, NIPQUAD(this->address), NIPQUAD(this->netmask), - this->mtu); - - _leave(" = 0"); - return 0; -} - -/* - * parse an RTM_GETLINK response for the MAC address belonging to the lowest - * non-internal interface - */ -static int afs_rtm_getlink_mac_parse(struct afs_rtm_desc *desc, - struct nlmsghdr *nlhdr) -{ - struct ifinfomsg *ifi; - struct rtattr *rtattr; - const char *name; - size_t remain, len; - bool set; - - ifi = (struct ifinfomsg *) NLMSG_DATA(nlhdr); - - _enter("{ix=%d}", ifi->ifi_index); - - if (ifi->ifi_index >= desc->mac_index) { - _leave(" = 0 [high]"); - return 0; - } - if (ifi->ifi_type == ARPHRD_LOOPBACK) { - _leave(" = 0 [loopback]"); - return 0; - } - - rtattr = NLMSG_DATA(nlhdr) + NLMSG_ALIGN(sizeof(struct ifinfomsg)); - remain = NLMSG_PAYLOAD(nlhdr, sizeof(struct ifinfomsg)); - - name = "unknown"; - set = false; - for (; RTA_OK(rtattr, remain); rtattr = RTA_NEXT(rtattr, remain)) { - switch (rtattr->rta_type) { - case IFLA_ADDRESS: - len = RTA_PAYLOAD(rtattr); - memcpy(desc->mac, RTA_DATA(rtattr), - min_t(size_t, len, 6)); - desc->mac_index = ifi->ifi_index; - set = true; - break; - case IFLA_IFNAME: - name = RTA_DATA(rtattr); - break; - } - } - - if (set) - _debug("%s: %02x:%02x:%02x:%02x:%02x:%02x", - name, - desc->mac[0], desc->mac[1], desc->mac[2], - desc->mac[3], desc->mac[4], desc->mac[5]); - - _leave(" = 0"); - return 0; -} - -/* - * read the rtnetlink response and pass to parsing routine - */ -static int afs_read_rtm(struct afs_rtm_desc *desc) -{ - struct nlmsghdr *nlhdr, tmphdr; - struct msghdr msg; - struct kvec iov[1]; - void *data; - bool last = false; - int len, ret, remain; - - _enter(""); - - do { - /* first of all peek to see how big the packet is */ - memset(&msg, 0, sizeof(msg)); - iov[0].iov_base = &tmphdr; - iov[0].iov_len = sizeof(tmphdr); - len = kernel_recvmsg(desc->nlsock, &msg, iov, 1, - sizeof(tmphdr), MSG_PEEK | MSG_TRUNC); - if (len < 0) { - _leave(" = %d [peek]", len); - return len; - } - if (len == 0) - continue; - if (len < sizeof(tmphdr) || len < NLMSG_PAYLOAD(&tmphdr, 0)) { - _leave(" = -EMSGSIZE"); - return -EMSGSIZE; - } - - if (desc->datamax < len) { - kfree(desc->data); - desc->data = NULL; - data = kmalloc(len, GFP_KERNEL); - if (!data) - return -ENOMEM; - desc->data = data; - } - desc->datamax = len; - - /* read all the data from this packet */ - iov[0].iov_base = desc->data; - iov[0].iov_len = desc->datamax; - desc->datalen = kernel_recvmsg(desc->nlsock, &msg, iov, 1, - desc->datamax, 0); - if (desc->datalen < 0) { - _leave(" = %zd [recv]", desc->datalen); - return desc->datalen; - } - - nlhdr = desc->data; - - /* check if the header is valid */ - if (!NLMSG_OK(nlhdr, desc->datalen) || - nlhdr->nlmsg_type == NLMSG_ERROR) { - _leave(" = -EIO"); - return -EIO; - } - - /* see if this is the last message */ - if (nlhdr->nlmsg_type == NLMSG_DONE || - !(nlhdr->nlmsg_flags & NLM_F_MULTI)) - last = true; - - /* parse the bits we got this time */ - nlmsg_for_each_msg(nlhdr, desc->data, desc->datalen, remain) { - ret = desc->parse(desc, nlhdr); - if (ret < 0) { - _leave(" = %d [parse]", ret); - return ret; - } - } - - } while (!last); - - _leave(" = 0"); - return 0; -} - -/* - * list the interface bound addresses to get the address and netmask - */ -static int afs_rtm_getaddr(struct afs_rtm_desc *desc) -{ - struct msghdr msg; - struct kvec iov[1]; - int ret; - - struct { - struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO))); - struct ifaddrmsg addr_msg __attribute__((aligned(NLMSG_ALIGNTO))); - } request; - - _enter(""); - - memset(&request, 0, sizeof(request)); - - request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - request.nl_msg.nlmsg_type = RTM_GETADDR; - request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; - request.nl_msg.nlmsg_seq = desc->msg_seq++; - request.nl_msg.nlmsg_pid = 0; - - memset(&msg, 0, sizeof(msg)); - iov[0].iov_base = &request; - iov[0].iov_len = sizeof(request); - - ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len); - _leave(" = %d", ret); - return ret; -} - -/* - * list the interface link statuses to get the MTUs - */ -static int afs_rtm_getlink(struct afs_rtm_desc *desc) -{ - struct msghdr msg; - struct kvec iov[1]; - int ret; - - struct { - struct nlmsghdr nl_msg __attribute__((aligned(NLMSG_ALIGNTO))); - struct ifinfomsg link_msg __attribute__((aligned(NLMSG_ALIGNTO))); - } request; - - _enter(""); - - memset(&request, 0, sizeof(request)); - - request.nl_msg.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - request.nl_msg.nlmsg_type = RTM_GETLINK; - request.nl_msg.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; - request.nl_msg.nlmsg_seq = desc->msg_seq++; - request.nl_msg.nlmsg_pid = 0; - - memset(&msg, 0, sizeof(msg)); - iov[0].iov_base = &request; - iov[0].iov_len = sizeof(request); - - ret = kernel_sendmsg(desc->nlsock, &msg, iov, 1, iov[0].iov_len); - _leave(" = %d", ret); - return ret; -} - -/* - * cull any interface records for which there isn't an MTU value - */ -static void afs_cull_interfaces(struct afs_rtm_desc *desc) -{ - struct afs_interface *bufs = desc->bufs; - size_t nbufs = desc->nbufs; - int loop, point = 0; - - _enter("{%zu}", nbufs); - - for (loop = 0; loop < nbufs; loop++) { - if (desc->bufs[loop].mtu != 0) { - if (loop != point) { - ASSERTCMP(loop, >, point); - bufs[point] = bufs[loop]; - } - point++; - } - } - - desc->nbufs = point; - _leave(" [%zu/%zu]", desc->nbufs, nbufs); -} - -/* - * get a list of this system's interface IPv4 addresses, netmasks and MTUs - * - returns the number of interface records in the buffer - */ -int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, - bool wantloopback) -{ - struct afs_rtm_desc desc; - int ret, loop; - - _enter(""); - - memset(&desc, 0, sizeof(desc)); - desc.bufs = bufs; - desc.maxbufs = maxbufs; - desc.wantloopback = wantloopback; - - ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, - &desc.nlsock); - if (ret < 0) { - _leave(" = %d [sock]", ret); - return ret; - } - - /* issue RTM_GETADDR */ - desc.parse = afs_rtm_getaddr_parse; - ret = afs_rtm_getaddr(&desc); - if (ret < 0) - goto error; - ret = afs_read_rtm(&desc); - if (ret < 0) - goto error; - - /* issue RTM_GETLINK */ - desc.parse = afs_rtm_getlink_if_parse; - ret = afs_rtm_getlink(&desc); - if (ret < 0) - goto error; - ret = afs_read_rtm(&desc); - if (ret < 0) - goto error; - - afs_cull_interfaces(&desc); - ret = desc.nbufs; - - for (loop = 0; loop < ret; loop++) - _debug("[%d] "NIPQUAD_FMT"/"NIPQUAD_FMT" mtu %u", - bufs[loop].index, - NIPQUAD(bufs[loop].address), - NIPQUAD(bufs[loop].netmask), - bufs[loop].mtu); - -error: - kfree(desc.data); - sock_release(desc.nlsock); - _leave(" = %d", ret); - return ret; -} - -/* - * get a MAC address from a random ethernet interface that has a real one - * - the buffer should be 6 bytes in size - */ -int afs_get_MAC_address(u8 mac[6]) -{ - struct afs_rtm_desc desc; - int ret; - - _enter(""); - - memset(&desc, 0, sizeof(desc)); - desc.mac = mac; - desc.mac_index = UINT_MAX; - - ret = sock_create_kern(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE, - &desc.nlsock); - if (ret < 0) { - _leave(" = %d [sock]", ret); - return ret; - } - - /* issue RTM_GETLINK */ - desc.parse = afs_rtm_getlink_mac_parse; - ret = afs_rtm_getlink(&desc); - if (ret < 0) - goto error; - ret = afs_read_rtm(&desc); - if (ret < 0) - goto error; - - if (desc.mac_index < UINT_MAX) { - /* got a MAC address */ - _debug("[%d] %02x:%02x:%02x:%02x:%02x:%02x", - desc.mac_index, - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - } else { - ret = -ENONET; - } - -error: - sock_release(desc.nlsock); - _leave(" = %d", ret); - return ret; -} -- cgit v1.2.3 From ec9c948546a84d0dcee851be1009a8066958e69d Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 3 May 2007 03:29:41 -0700 Subject: [AFS]: Adjust the new netdevice scanning code Adjust the new netdevice scanning code provided by Patrick McHardy: (1) Restore the function banner comments that were dropped. (2) Rather than using an array size of 6 in some places and an array size of ETH_ALEN in others, pass a pointer instead and pass the array size through so that we can actually check it. (3) Do the buffer fill count check before checking the for_primary_ifa condition again. This permits us to skip that check should maxbufs be reached before we run out of interfaces. Signed-off-by: David Howells Signed-off-by: David S. Miller --- fs/afs/internal.h | 2 +- fs/afs/main.c | 2 +- fs/afs/netdevices.c | 24 +++++++++++++++++++----- 3 files changed, 21 insertions(+), 7 deletions(-) (limited to 'fs') diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 551db896afc9..d90c158cd934 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h @@ -563,7 +563,7 @@ extern void afs_fs_exit(void); * use-rtnetlink.c */ extern int afs_get_ipv4_interfaces(struct afs_interface *, size_t, bool); -extern int afs_get_MAC_address(u8 [6]); +extern int afs_get_MAC_address(u8 *, size_t); /* * vlclient.c diff --git a/fs/afs/main.c b/fs/afs/main.c index 40c2704e7557..80ec6fd19a73 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -54,7 +54,7 @@ static int __init afs_get_client_UUID(void) /* read the MAC address of one of the external interfaces and construct * a UUID from it */ - ret = afs_get_MAC_address(afs_uuid.node); + ret = afs_get_MAC_address(afs_uuid.node, sizeof(afs_uuid.node)); if (ret < 0) return ret; diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c index 2b3087357fa9..ce08977858e0 100644 --- a/fs/afs/netdevices.c +++ b/fs/afs/netdevices.c @@ -10,21 +10,33 @@ #include #include "internal.h" -int afs_get_MAC_address(u8 mac[ETH_ALEN]) +/* + * get a MAC address from a random ethernet interface that has a real one + * - the buffer will normally be 6 bytes in size + */ +int afs_get_MAC_address(u8 *mac, size_t maclen) { struct net_device *dev; int ret = -ENODEV; + if (maclen != ETH_ALEN) + BUG(); + rtnl_lock(); dev = __dev_getfirstbyhwtype(ARPHRD_ETHER); if (dev) { - memcpy(mac, dev->dev_addr, ETH_ALEN); + memcpy(mac, dev->dev_addr, maclen); ret = 0; } rtnl_unlock(); return ret; } +/* + * get a list of this system's interface IPv4 addresses, netmasks and MTUs + * - maxbufs must be at least 1 + * - returns the number of interface records in the buffer + */ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, bool wantloopback) { @@ -32,6 +44,8 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, struct in_device *idev; int n = 0; + ASSERT(maxbufs > 0); + rtnl_lock(); for (dev = dev_base; dev; dev = dev->next) { if (dev->type == ARPHRD_LOOPBACK && !wantloopback) @@ -40,13 +54,13 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, if (!idev) continue; for_primary_ifa(idev) { - if (n == maxbufs) - goto out; bufs[n].address.s_addr = ifa->ifa_address; bufs[n].netmask.s_addr = ifa->ifa_mask; bufs[n].mtu = dev->mtu; n++; - } endfor_ifa(idev) + if (n >= maxbufs) + goto out; + } endfor_ifa(idev); } out: rtnl_unlock(); -- cgit v1.2.3 From 7562f876cd93800f2f8c89445f2a563590b24e09 Mon Sep 17 00:00:00 2001 From: Pavel Emelianov Date: Thu, 3 May 2007 15:13:45 -0700 Subject: [NET]: Rework dev_base via list_head (v3) Cleanup of dev_base list use, with the aim to simplify making device list per-namespace. In almost every occasion, use of dev_base variable and dev->next pointer could be easily replaced by for_each_netdev loop. A few most complicated places were converted to using first_netdev()/next_netdev(). Signed-off-by: Pavel Emelianov Acked-by: Kirill Korotaev Signed-off-by: David S. Miller --- arch/s390/appldata/appldata_net_sum.c | 2 +- arch/sparc64/solaris/ioctl.c | 3 +- drivers/block/aoe/aoecmd.c | 8 ++-- drivers/net/wireless/strip.c | 4 +- drivers/parisc/led.c | 2 +- fs/afs/netdevices.c | 2 +- include/linux/netdevice.h | 26 ++++++++++- net/8021q/vlan.c | 3 +- net/8021q/vlanproc.c | 36 ++++++++++----- net/bridge/br_if.c | 4 +- net/bridge/br_ioctl.c | 4 +- net/bridge/br_netlink.c | 3 +- net/core/dev.c | 84 ++++++++++++++++------------------ net/core/dev_mcast.c | 5 +-- net/core/rtnetlink.c | 7 ++- net/decnet/af_decnet.c | 11 +++-- net/decnet/dn_dev.c | 85 +++++++++++++++++------------------ net/decnet/dn_fib.c | 2 +- net/decnet/dn_route.c | 14 +++--- net/ipv4/devinet.c | 17 ++++--- net/ipv4/igmp.c | 15 +++---- net/ipv4/ipconfig.c | 2 +- net/ipv6/addrconf.c | 28 +++++++----- net/ipv6/anycast.c | 17 ++++--- net/ipv6/mcast.c | 15 +++---- net/llc/llc_core.c | 10 ++++- net/netrom/nr_route.c | 5 ++- net/rose/rose_route.c | 8 ++-- net/sched/sch_api.c | 7 ++- net/sctp/protocol.c | 2 +- net/tipc/eth_media.c | 12 ++--- 31 files changed, 249 insertions(+), 194 deletions(-) (limited to 'fs') diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index a43f3488fecf..2180ac105b05 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -107,7 +107,7 @@ static void appldata_get_net_sum_data(void *data) tx_dropped = 0; collisions = 0; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { stats = dev->get_stats(dev); rx_packets += stats->rx_packets; tx_packets += stats->tx_packets; diff --git a/arch/sparc64/solaris/ioctl.c b/arch/sparc64/solaris/ioctl.c index 330743c5b3d8..18352a498628 100644 --- a/arch/sparc64/solaris/ioctl.c +++ b/arch/sparc64/solaris/ioctl.c @@ -686,7 +686,8 @@ static inline int solaris_i(unsigned int fd, unsigned int cmd, u32 arg) int i = 0; read_lock_bh(&dev_base_lock); - for (d = dev_base; d; d = d->next) i++; + for_each_netdev(d) + i++; read_unlock_bh(&dev_base_lock); if (put_user (i, (int __user *)A(arg))) diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 1a6aeac5a1c3..01fbdd38e3be 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -194,15 +194,15 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) sl = sl_tail = NULL; read_lock(&dev_base_lock); - for (ifp = dev_base; ifp; dev_put(ifp), ifp = ifp->next) { + for_each_netdev(ifp) { dev_hold(ifp); if (!is_aoe_netif(ifp)) - continue; + goto cont; skb = new_skb(sizeof *h + sizeof *ch); if (skb == NULL) { printk(KERN_INFO "aoe: skb alloc failure\n"); - continue; + goto cont; } skb_put(skb, sizeof *h + sizeof *ch); skb->dev = ifp; @@ -221,6 +221,8 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) skb->next = sl; sl = skb; +cont: + dev_put(ifp); } read_unlock(&dev_base_lock); diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 2a299a0676a6..ef32a5c1e818 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -1971,8 +1971,7 @@ static struct net_device *get_strip_dev(struct strip *strip_info) sizeof(zero_address))) { struct net_device *dev; read_lock_bh(&dev_base_lock); - dev = dev_base; - while (dev) { + for_each_netdev(dev) { if (dev->type == strip_info->dev->type && !memcmp(dev->dev_addr, &strip_info->true_dev_addr, @@ -1983,7 +1982,6 @@ static struct net_device *get_strip_dev(struct strip *strip_info) read_unlock_bh(&dev_base_lock); return (dev); } - dev = dev->next; } read_unlock_bh(&dev_base_lock); } diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 3df82fe9ce8c..98be2880757d 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -365,7 +365,7 @@ static __inline__ int led_get_net_activity(void) * for reading should be OK */ read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { struct net_device_stats *stats; struct in_device *in_dev = __in_dev_get_rcu(dev); if (!in_dev || !in_dev->ifa_list) diff --git a/fs/afs/netdevices.c b/fs/afs/netdevices.c index ce08977858e0..fc27d4b52e5f 100644 --- a/fs/afs/netdevices.c +++ b/fs/afs/netdevices.c @@ -47,7 +47,7 @@ int afs_get_ipv4_interfaces(struct afs_interface *bufs, size_t maxbufs, ASSERT(maxbufs > 0); rtnl_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (dev->type == ARPHRD_LOOPBACK && !wantloopback) continue; idev = __in_dev_get_rtnl(dev); diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 4428f1c3c13c..30446222b396 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -304,7 +304,7 @@ struct net_device unsigned long state; - struct net_device *next; + struct list_head dev_list; /* The device initialization function. Called only once. */ int (*init)(struct net_device *dev); @@ -575,9 +575,31 @@ struct packet_type { #include extern struct net_device loopback_dev; /* The loopback */ -extern struct net_device *dev_base; /* All devices */ +extern struct list_head dev_base_head; /* All devices */ extern rwlock_t dev_base_lock; /* Device list lock */ +#define for_each_netdev(d) \ + list_for_each_entry(d, &dev_base_head, dev_list) +#define for_each_netdev_safe(d, n) \ + list_for_each_entry_safe(d, n, &dev_base_head, dev_list) +#define for_each_netdev_continue(d) \ + list_for_each_entry_continue(d, &dev_base_head, dev_list) +#define net_device_entry(lh) list_entry(lh, struct net_device, dev_list) + +static inline struct net_device *next_net_device(struct net_device *dev) +{ + struct list_head *lh; + + lh = dev->dev_list.next; + return lh == &dev_base_head ? NULL : net_device_entry(lh); +} + +static inline struct net_device *first_net_device(void) +{ + return list_empty(&dev_base_head) ? NULL : + net_device_entry(dev_base_head.next); +} + extern int netdev_boot_setup_check(struct net_device *dev); extern unsigned long netdev_boot_base(const char *prefix, int unit); extern struct net_device *dev_getbyhwaddr(unsigned short type, char *hwaddr); diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index c0c7bb8e9f07..bd93c45778d4 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -117,8 +117,7 @@ static void __exit vlan_cleanup_devices(void) struct net_device *dev, *nxt; rtnl_lock(); - for (dev = dev_base; dev; dev = nxt) { - nxt = dev->next; + for_each_netdev_safe(dev, nxt) { if (dev->priv_flags & IFF_802_1Q_VLAN) { unregister_vlan_dev(VLAN_DEV_INFO(dev)->real_dev, VLAN_DEV_INFO(dev)->vlan_id); diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c index 5e24f72602a1..d216a64421cd 100644 --- a/net/8021q/vlanproc.c +++ b/net/8021q/vlanproc.c @@ -237,13 +237,9 @@ int vlan_proc_rem_dev(struct net_device *vlandev) * The following few functions build the content of /proc/net/vlan/config */ -/* starting at dev, find a VLAN device */ -static struct net_device *vlan_skip(struct net_device *dev) +static inline int is_vlan_dev(struct net_device *dev) { - while (dev && !(dev->priv_flags & IFF_802_1Q_VLAN)) - dev = dev->next; - - return dev; + return dev->priv_flags & IFF_802_1Q_VLAN; } /* start read of /proc/net/vlan/config */ @@ -257,19 +253,35 @@ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos) if (*pos == 0) return SEQ_START_TOKEN; - for (dev = vlan_skip(dev_base); dev && i < *pos; - dev = vlan_skip(dev->next), ++i); + for_each_netdev(dev) { + if (!is_vlan_dev(dev)) + continue; + + if (i++ == *pos) + return dev; + } - return (i == *pos) ? dev : NULL; + return NULL; } static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos) { + struct net_device *dev; + ++*pos; - return vlan_skip((v == SEQ_START_TOKEN) - ? dev_base - : ((struct net_device *)v)->next); + dev = (struct net_device *)v; + if (v == SEQ_START_TOKEN) + dev = net_device_entry(&dev_base_head); + + for_each_netdev_continue(dev) { + if (!is_vlan_dev(dev)) + continue; + + return dev; + } + + return NULL; } static void vlan_seq_stop(struct seq_file *seq, void *v) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 690573bbf012..849deaf14108 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -475,11 +475,9 @@ void __exit br_cleanup_bridges(void) struct net_device *dev, *nxt; rtnl_lock(); - for (dev = dev_base; dev; dev = nxt) { - nxt = dev->next; + for_each_netdev_safe(dev, nxt) if (dev->priv_flags & IFF_EBRIDGE) del_br(dev->priv); - } rtnl_unlock(); } diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index eda0fbfc923a..bb15e9e259b1 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -27,7 +27,9 @@ static int get_bridge_ifindices(int *indices, int num) struct net_device *dev; int i = 0; - for (dev = dev_base; dev && i < num; dev = dev->next) { + for_each_netdev(dev) { + if (i >= num) + break; if (dev->priv_flags & IFF_EBRIDGE) indices[i++] = dev->ifindex; } diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 35facc0c11c2..0fcf6f073064 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -109,7 +109,8 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) struct net_device *dev; int idx; - for (dev = dev_base, idx = 0; dev; dev = dev->next) { + idx = 0; + for_each_netdev(dev) { /* not a bridge port */ if (dev->br_port == NULL || idx < cb->args[0]) goto skip; diff --git a/net/core/dev.c b/net/core/dev.c index c305819b7266..f27d4ab181e6 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -156,13 +156,13 @@ static spinlock_t net_dma_event_lock; #endif /* - * The @dev_base list is protected by @dev_base_lock and the rtnl + * The @dev_base_head list is protected by @dev_base_lock and the rtnl * semaphore. * * Pure readers hold dev_base_lock for reading. * * Writers must hold the rtnl semaphore while they loop through the - * dev_base list, and hold dev_base_lock for writing when they do the + * dev_base_head list, and hold dev_base_lock for writing when they do the * actual updates. This allows pure readers to access the list even * while a writer is preparing to update it. * @@ -174,11 +174,10 @@ static spinlock_t net_dma_event_lock; * unregister_netdevice(), which must be called with the rtnl * semaphore held. */ -struct net_device *dev_base; -static struct net_device **dev_tail = &dev_base; +LIST_HEAD(dev_base_head); DEFINE_RWLOCK(dev_base_lock); -EXPORT_SYMBOL(dev_base); +EXPORT_SYMBOL(dev_base_head); EXPORT_SYMBOL(dev_base_lock); #define NETDEV_HASHBITS 8 @@ -567,11 +566,12 @@ struct net_device *dev_getbyhwaddr(unsigned short type, char *ha) ASSERT_RTNL(); - for (dev = dev_base; dev; dev = dev->next) + for_each_netdev(dev) if (dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len)) - break; - return dev; + return dev; + + return NULL; } EXPORT_SYMBOL(dev_getbyhwaddr); @@ -581,11 +581,11 @@ struct net_device *__dev_getfirstbyhwtype(unsigned short type) struct net_device *dev; ASSERT_RTNL(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) if (dev->type == type) - break; - } - return dev; + return dev; + + return NULL; } EXPORT_SYMBOL(__dev_getfirstbyhwtype); @@ -617,17 +617,19 @@ EXPORT_SYMBOL(dev_getfirstbyhwtype); struct net_device * dev_get_by_flags(unsigned short if_flags, unsigned short mask) { - struct net_device *dev; + struct net_device *dev, *ret; + ret = NULL; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if (((dev->flags ^ if_flags) & mask) == 0) { dev_hold(dev); + ret = dev; break; } } read_unlock(&dev_base_lock); - return dev; + return ret; } /** @@ -693,7 +695,7 @@ int dev_alloc_name(struct net_device *dev, const char *name) if (!inuse) return -ENOMEM; - for (d = dev_base; d; d = d->next) { + for_each_netdev(d) { if (!sscanf(d->name, name, &i)) continue; if (i < 0 || i >= max_netdevices) @@ -975,7 +977,7 @@ int register_netdevice_notifier(struct notifier_block *nb) rtnl_lock(); err = raw_notifier_chain_register(&netdev_chain, nb); if (!err) { - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { nb->notifier_call(nb, NETDEV_REGISTER, dev); if (dev->flags & IFF_UP) @@ -2049,7 +2051,7 @@ static int dev_ifconf(char __user *arg) */ total = 0; - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { for (i = 0; i < NPROTO; i++) { if (gifconf_list[i]) { int done; @@ -2081,26 +2083,28 @@ static int dev_ifconf(char __user *arg) * This is invoked by the /proc filesystem handler to display a device * in detail. */ -static struct net_device *dev_get_idx(loff_t pos) +void *dev_seq_start(struct seq_file *seq, loff_t *pos) { + loff_t off; struct net_device *dev; - loff_t i; - for (i = 0, dev = dev_base; dev && i < pos; ++i, dev = dev->next); + read_lock(&dev_base_lock); + if (!*pos) + return SEQ_START_TOKEN; - return i == pos ? dev : NULL; -} + off = 1; + for_each_netdev(dev) + if (off++ == *pos) + return dev; -void *dev_seq_start(struct seq_file *seq, loff_t *pos) -{ - read_lock(&dev_base_lock); - return *pos ? dev_get_idx(*pos - 1) : SEQ_START_TOKEN; + return NULL; } void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { ++*pos; - return v == SEQ_START_TOKEN ? dev_base : ((struct net_device *)v)->next; + return v == SEQ_START_TOKEN ? + first_net_device() : next_net_device((struct net_device *)v); } void dev_seq_stop(struct seq_file *seq, void *v) @@ -3082,11 +3086,9 @@ int register_netdevice(struct net_device *dev) set_bit(__LINK_STATE_PRESENT, &dev->state); - dev->next = NULL; dev_init_scheduler(dev); write_lock_bh(&dev_base_lock); - *dev_tail = dev; - dev_tail = &dev->next; + list_add_tail(&dev->dev_list, &dev_base_head); hlist_add_head(&dev->name_hlist, head); hlist_add_head(&dev->index_hlist, dev_index_hash(dev->ifindex)); dev_hold(dev); @@ -3360,8 +3362,6 @@ void synchronize_net(void) void unregister_netdevice(struct net_device *dev) { - struct net_device *d, **dp; - BUG_ON(dev_boot_phase); ASSERT_RTNL(); @@ -3381,19 +3381,11 @@ void unregister_netdevice(struct net_device *dev) dev_close(dev); /* And unlink it from device chain. */ - for (dp = &dev_base; (d = *dp) != NULL; dp = &d->next) { - if (d == dev) { - write_lock_bh(&dev_base_lock); - hlist_del(&dev->name_hlist); - hlist_del(&dev->index_hlist); - if (dev_tail == &dev->next) - dev_tail = dp; - *dp = d->next; - write_unlock_bh(&dev_base_lock); - break; - } - } - BUG_ON(!d); + write_lock_bh(&dev_base_lock); + list_del(&dev->dev_list); + hlist_del(&dev->name_hlist); + hlist_del(&dev->index_hlist); + write_unlock_bh(&dev_base_lock); dev->reg_state = NETREG_UNREGISTERING; diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c index 7d57bf77f3a3..5a54053386c8 100644 --- a/net/core/dev_mcast.c +++ b/net/core/dev_mcast.c @@ -223,7 +223,7 @@ static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos) loff_t off = 0; read_lock(&dev_base_lock); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (off++ == *pos) return dev; } @@ -232,9 +232,8 @@ static void *dev_mc_seq_start(struct seq_file *seq, loff_t *pos) static void *dev_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - struct net_device *dev = v; ++*pos; - return dev->next; + return next_net_device((struct net_device *)v); } static void dev_mc_seq_stop(struct seq_file *seq, void *v) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index cec111109155..8c971a2efe2a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -539,13 +539,16 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) int s_idx = cb->args[0]; struct net_device *dev; - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) break; +cont: + idx++; } cb->args[0] = idx; diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index a205eaa87f52..9fbe87c93802 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -721,7 +721,7 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct sock *sk = sock->sk; struct dn_scp *scp = DN_SK(sk); struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr; - struct net_device *dev; + struct net_device *dev, *ldev; int rv; if (addr_len != sizeof(struct sockaddr_dn)) @@ -746,14 +746,17 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (!(saddr->sdn_flags & SDF_WILD)) { if (dn_ntohs(saddr->sdn_nodeaddrl)) { read_lock(&dev_base_lock); - for(dev = dev_base; dev; dev = dev->next) { + ldev = NULL; + for_each_netdev(dev) { if (!dev->dn_ptr) continue; - if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) + if (dn_dev_islocal(dev, dn_saddr2dn(saddr))) { + ldev = dev; break; + } } read_unlock(&dev_base_lock); - if (dev == NULL) + if (ldev == NULL) return -EADDRNOTAVAIL; } } diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 5c2a9951b638..764a56a13e38 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -799,9 +799,10 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) skip_ndevs = cb->args[0]; skip_naddr = cb->args[1]; - for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < skip_ndevs) - continue; + goto cont; else if (idx > skip_ndevs) { /* Only skip over addresses for first dev dumped * in this iteration (idx == skip_ndevs) */ @@ -809,18 +810,20 @@ static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) } if ((dn_db = dev->dn_ptr) == NULL) - continue; + goto cont; for (ifa = dn_db->ifa_list, dn_idx = 0; ifa; ifa = ifa->ifa_next, dn_idx++) { if (dn_idx < skip_naddr) - continue; + goto cont; if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWADDR, NLM_F_MULTI) < 0) goto done; } +cont: + idx++; } done: cb->args[0] = idx; @@ -1296,7 +1299,7 @@ void dn_dev_devices_off(void) struct net_device *dev; rtnl_lock(); - for(dev = dev_base; dev; dev = dev->next) + for_each_netdev(dev) dn_dev_down(dev); rtnl_unlock(); @@ -1307,7 +1310,7 @@ void dn_dev_devices_on(void) struct net_device *dev; rtnl_lock(); - for(dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (dev->flags & IFF_UP) dn_dev_up(dev); } @@ -1325,62 +1328,56 @@ int unregister_dnaddr_notifier(struct notifier_block *nb) } #ifdef CONFIG_PROC_FS -static inline struct net_device *dn_dev_get_next(struct seq_file *seq, struct net_device *dev) +static inline int is_dn_dev(struct net_device *dev) { - do { - dev = dev->next; - } while(dev && !dev->dn_ptr); - - return dev; + return dev->dn_ptr != NULL; } -static struct net_device *dn_dev_get_idx(struct seq_file *seq, loff_t pos) +static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) { + int i; struct net_device *dev; - dev = dev_base; - if (dev && !dev->dn_ptr) - dev = dn_dev_get_next(seq, dev); - if (pos) { - while(dev && (dev = dn_dev_get_next(seq, dev))) - --pos; - } - return dev; -} + read_lock(&dev_base_lock); -static void *dn_dev_seq_start(struct seq_file *seq, loff_t *pos) -{ - if (*pos) { - struct net_device *dev; - read_lock(&dev_base_lock); - dev = dn_dev_get_idx(seq, *pos - 1); - if (dev == NULL) - read_unlock(&dev_base_lock); - return dev; + if (*pos == 0) + return SEQ_START_TOKEN; + + i = 1; + for_each_netdev(dev) { + if (!is_dn_dev(dev)) + continue; + + if (i++ == *pos) + return dev; } - return SEQ_START_TOKEN; + + return NULL; } static void *dn_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - struct net_device *dev = v; - loff_t one = 1; + struct net_device *dev; - if (v == SEQ_START_TOKEN) { - dev = dn_dev_seq_start(seq, &one); - } else { - dev = dn_dev_get_next(seq, dev); - if (dev == NULL) - read_unlock(&dev_base_lock); - } ++*pos; - return dev; + + dev = (struct net_device *)v; + if (v == SEQ_START_TOKEN) + dev = net_device_entry(&dev_base_head); + + for_each_netdev_continue(dev) { + if (!is_dn_dev(dev)) + continue; + + return dev; + } + + return NULL; } static void dn_dev_seq_stop(struct seq_file *seq, void *v) { - if (v && v != SEQ_START_TOKEN) - read_unlock(&dev_base_lock); + read_unlock(&dev_base_lock); } static char *dn_type2asc(char type) diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 310a86268d2b..d2bc19d47950 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -602,7 +602,7 @@ static void dn_fib_del_ifaddr(struct dn_ifaddr *ifa) /* Scan device list */ read_lock(&dev_base_lock); - for(dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { dn_db = dev->dn_ptr; if (dn_db == NULL) continue; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 5d7337bcf0fe..a8bf106b7a61 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -886,7 +886,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old .iif = loopback_dev.ifindex, .oif = oldflp->oif }; struct dn_route *rt = NULL; - struct net_device *dev_out = NULL; + struct net_device *dev_out = NULL, *dev; struct neighbour *neigh = NULL; unsigned hash; unsigned flags = 0; @@ -925,15 +925,17 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old goto out; } read_lock(&dev_base_lock); - for(dev_out = dev_base; dev_out; dev_out = dev_out->next) { - if (!dev_out->dn_ptr) + for_each_netdev(dev) { + if (!dev->dn_ptr) continue; - if (!dn_dev_islocal(dev_out, oldflp->fld_src)) + if (!dn_dev_islocal(dev, oldflp->fld_src)) continue; - if ((dev_out->flags & IFF_LOOPBACK) && + if ((dev->flags & IFF_LOOPBACK) && oldflp->fld_dst && - !dn_dev_islocal(dev_out, oldflp->fld_dst)) + !dn_dev_islocal(dev, oldflp->fld_dst)) continue; + + dev_out = dev; break; } read_unlock(&dev_base_lock); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 088888db8b3d..7f95e6e9beeb 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -910,7 +910,7 @@ no_in_dev: */ read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if ((in_dev = __in_dev_get_rcu(dev)) == NULL) continue; @@ -989,7 +989,7 @@ __be32 inet_confirm_addr(const struct net_device *dev, __be32 dst, __be32 local, read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if ((in_dev = __in_dev_get_rcu(dev))) { addr = confirm_addr_indev(in_dev, dst, local, scope); if (addr) @@ -1182,23 +1182,26 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) int s_ip_idx, s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; - for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (idx > s_idx) s_ip_idx = 0; if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) - continue; + goto cont; for (ifa = in_dev->ifa_list, ip_idx = 0; ifa; ifa = ifa->ifa_next, ip_idx++) { if (ip_idx < s_ip_idx) - continue; + goto cont; if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWADDR, NLM_F_MULTI) <= 0) goto done; } +cont: + idx++; } done: @@ -1243,7 +1246,7 @@ void inet_forward_change(void) ipv4_devconf_dflt.forwarding = on; read_lock(&dev_base_lock); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { struct in_device *in_dev; rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 2506021c2935..f4dd47453108 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -2288,9 +2288,8 @@ static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) struct ip_mc_list *im = NULL; struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); - for (state->dev = dev_base, state->in_dev = NULL; - state->dev; - state->dev = state->dev->next) { + state->in_dev = NULL; + for_each_netdev(state->dev) { struct in_device *in_dev; in_dev = in_dev_get(state->dev); if (!in_dev) @@ -2316,7 +2315,7 @@ static struct ip_mc_list *igmp_mc_get_next(struct seq_file *seq, struct ip_mc_li read_unlock(&state->in_dev->mc_list_lock); in_dev_put(state->in_dev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->in_dev = NULL; break; @@ -2450,9 +2449,9 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) struct ip_mc_list *im = NULL; struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL, state->im = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + state->im = NULL; + for_each_netdev(state->dev) { struct in_device *idev; idev = in_dev_get(state->dev); if (unlikely(idev == NULL)) @@ -2488,7 +2487,7 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l read_unlock(&state->idev->mc_list_lock); in_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; goto out; diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 597c800b2fdc..342ca8d89458 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -192,7 +192,7 @@ static int __init ic_open_devs(void) if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0) printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { if (dev == &loopback_dev) continue; if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3452433cbc96..d02685c6bc69 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -449,7 +449,7 @@ static void addrconf_forward_change(void) struct inet6_dev *idev; read_lock(&dev_base_lock); - for (dev=dev_base; dev; dev=dev->next) { + for_each_netdev(dev) { rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) { @@ -911,7 +911,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, read_lock(&dev_base_lock); rcu_read_lock(); - for (dev = dev_base; dev; dev=dev->next) { + for_each_netdev(dev) { struct inet6_dev *idev; struct inet6_ifaddr *ifa; @@ -2064,7 +2064,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev) return; } - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { struct in_device * in_dev = __in_dev_get_rtnl(dev); if (in_dev && (dev->flags & IFF_UP)) { struct in_ifaddr * ifa; @@ -2225,7 +2225,7 @@ static void ip6_tnl_add_linklocal(struct inet6_dev *idev) return; } /* then try to inherit it from any device */ - for (link_dev = dev_base; link_dev; link_dev = link_dev->next) { + for_each_netdev(link_dev) { if (!ipv6_inherit_linklocal(idev, link_dev)) return; } @@ -3257,14 +3257,15 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; - for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (idx > s_idx) s_ip_idx = 0; ip_idx = 0; if ((idev = in6_dev_get(dev)) == NULL) - continue; + goto cont; read_lock_bh(&idev->lock); switch (type) { case UNICAST_ADDR: @@ -3311,6 +3312,8 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, } read_unlock_bh(&idev->lock); in6_dev_put(idev); +cont: + idx++; } done: if (err <= 0) { @@ -3575,16 +3578,19 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) struct inet6_dev *idev; read_lock(&dev_base_lock); - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if ((idev = in6_dev_get(dev)) == NULL) - continue; + goto cont; err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); in6_dev_put(idev); if (err <= 0) break; +cont: + idx++; } read_unlock(&dev_base_lock); cb->args[0] = idx; @@ -4247,7 +4253,7 @@ void __exit addrconf_cleanup(void) * clean dev list. */ - for (dev=dev_base; dev; dev=dev->next) { + for_each_netdev(dev) { if ((idev = __in6_dev_get(dev)) == NULL) continue; addrconf_ifdown(dev, 1); diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 09117d63256f..9b81264eb78f 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -423,14 +423,18 @@ static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr) */ int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr) { + int found = 0; + if (dev) return ipv6_chk_acast_dev(dev, addr); read_lock(&dev_base_lock); - for (dev=dev_base; dev; dev=dev->next) - if (ipv6_chk_acast_dev(dev, addr)) + for_each_netdev(dev) + if (ipv6_chk_acast_dev(dev, addr)) { + found = 1; break; + } read_unlock(&dev_base_lock); - return dev != 0; + return found; } @@ -447,9 +451,8 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq) struct ifacaddr6 *im = NULL; struct ac6_iter_state *state = ac6_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + for_each_netdev(state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (!idev) @@ -476,7 +479,7 @@ static struct ifacaddr6 *ac6_get_next(struct seq_file *seq, struct ifacaddr6 *im read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; break; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 6c2758951d60..3e308fb41b49 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -2331,9 +2331,8 @@ static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq) struct ifmcaddr6 *im = NULL; struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + for_each_netdev(state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (!idev) @@ -2360,7 +2359,7 @@ static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; break; @@ -2475,9 +2474,9 @@ static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq) struct ifmcaddr6 *im = NULL; struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq); - for (state->dev = dev_base, state->idev = NULL, state->im = NULL; - state->dev; - state->dev = state->dev->next) { + state->idev = NULL; + state->im = NULL; + for_each_netdev(state->dev) { struct inet6_dev *idev; idev = in6_dev_get(state->dev); if (unlikely(idev == NULL)) @@ -2513,7 +2512,7 @@ static struct ip6_sf_list *igmp6_mcf_get_next(struct seq_file *seq, struct ip6_s read_unlock_bh(&state->idev->lock); in6_dev_put(state->idev); } - state->dev = state->dev->next; + state->dev = next_net_device(state->dev); if (!state->dev) { state->idev = NULL; goto out; diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index d12413cff5bd..d4b13a031fd5 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c @@ -160,8 +160,14 @@ static struct packet_type llc_tr_packet_type = { static int __init llc_init(void) { - if (dev_base->next) - memcpy(llc_station_mac_sa, dev_base->next->dev_addr, ETH_ALEN); + struct net_device *dev; + + dev = first_net_device(); + if (dev != NULL) + dev = next_net_device(dev); + + if (dev != NULL) + memcpy(llc_station_mac_sa, dev->dev_addr, ETH_ALEN); else memset(llc_station_mac_sa, 0, ETH_ALEN); dev_add_pack(&llc_packet_type); diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 8e6bd4e9d82c..2f76e062609d 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c @@ -598,7 +598,7 @@ struct net_device *nr_dev_first(void) struct net_device *dev, *first = NULL; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM) if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; @@ -618,12 +618,13 @@ struct net_device *nr_dev_get(ax25_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_NETROM && ax25cmp(addr, (ax25_address *)dev->dev_addr) == 0) { dev_hold(dev); goto out; } } + dev = NULL; out: read_unlock(&dev_base_lock); return dev; diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 1f9aefd95a99..929a784a86d7 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -596,7 +596,7 @@ struct net_device *rose_dev_first(void) struct net_device *dev, *first = NULL; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE) if (first == NULL || strncmp(dev->name, first->name, 3) < 0) first = dev; @@ -614,12 +614,13 @@ struct net_device *rose_dev_get(rose_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) { dev_hold(dev); goto out; } } + dev = NULL; out: read_unlock(&dev_base_lock); return dev; @@ -630,10 +631,11 @@ static int rose_dev_exists(rose_address *addr) struct net_device *dev; read_lock(&dev_base_lock); - for (dev = dev_base; dev != NULL; dev = dev->next) { + for_each_netdev(dev) { if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ROSE && rosecmp(addr, (rose_address *)dev->dev_addr) == 0) goto out; } + dev = NULL; out: read_unlock(&dev_base_lock); return dev != NULL; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 8699e7006d80..bec600af03ca 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -894,9 +894,10 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) s_idx = cb->args[0]; s_q_idx = q_idx = cb->args[1]; read_lock(&dev_base_lock); - for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { + idx = 0; + for_each_netdev(dev) { if (idx < s_idx) - continue; + goto cont; if (idx > s_idx) s_q_idx = 0; q_idx = 0; @@ -910,6 +911,8 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) goto done; q_idx++; } +cont: + idx++; } done: diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index c361deb6cea9..d4afafc39138 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -170,7 +170,7 @@ static void sctp_get_local_addr_list(void) struct sctp_af *af; read_lock(&dev_base_lock); - for (dev = dev_base; dev; dev = dev->next) { + for_each_netdev(dev) { __list_for_each(pos, &sctp_address_families) { af = list_entry(pos, struct sctp_af, list); af->copy_addrlist(&sctp_local_addr_list, dev); diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 67bb29b44d1b..0ee6ded18f3a 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -120,16 +120,18 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, static int enable_bearer(struct tipc_bearer *tb_ptr) { - struct net_device *dev = dev_base; + struct net_device *dev, *pdev; struct eth_bearer *eb_ptr = ð_bearers[0]; struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; /* Find device with specified name */ - - while (dev && dev->name && strncmp(dev->name, driver_name, IFNAMSIZ)) { - dev = dev->next; - } + dev = NULL; + for_each_netdev(pdev) + if (!strncmp(dev->name, driver_name, IFNAMSIZ)) { + dev = pdev; + break; + } if (!dev) return -ENODEV; -- cgit v1.2.3