From 59223edaa18759982db0a8aced0e77457d10c68e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 17 Jun 1999 13:25:08 +0000 Subject: Merge with Linux 2.3.6. Sorry, this isn't tested on silicon, I don't have a MIPS box at hand. --- net/ipv4/devinet.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'net/ipv4/devinet.c') diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index c8b0fbbc8..ff2c930d1 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1,7 +1,7 @@ /* * NET3 IP device support routines. * - * Version: $Id: devinet.c,v 1.28 1999/05/08 20:00:16 davem Exp $ + * Version: $Id: devinet.c,v 1.32 1999/06/09 11:15:33 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -607,41 +607,39 @@ inet_gifconf(struct device *dev, char *buf, int len) { struct in_device *in_dev = dev->ip_ptr; struct in_ifaddr *ifa; - struct ifreq ifr; + struct ifreq *ifr = (struct ifreq *) buf; int done=0; if (in_dev==NULL || (ifa=in_dev->ifa_list)==NULL) return 0; for ( ; ifa; ifa = ifa->ifa_next) { - if (!buf) { + if (!ifr) { done += sizeof(ifr); continue; } if (len < (int) sizeof(ifr)) return done; - memset(&ifr, 0, sizeof(struct ifreq)); + memset(ifr, 0, sizeof(struct ifreq)); if (ifa->ifa_label) - strcpy(ifr.ifr_name, ifa->ifa_label); + strcpy(ifr->ifr_name, ifa->ifa_label); else - strcpy(ifr.ifr_name, dev->name); + strcpy(ifr->ifr_name, dev->name); - (*(struct sockaddr_in *) &ifr.ifr_addr).sin_family = AF_INET; - (*(struct sockaddr_in *) &ifr.ifr_addr).sin_addr.s_addr = ifa->ifa_local; + (*(struct sockaddr_in *) &ifr->ifr_addr).sin_family = AF_INET; + (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr = ifa->ifa_local; - if (copy_to_user(buf, &ifr, sizeof(struct ifreq))) - return -EFAULT; - buf += sizeof(struct ifreq); + ifr++; len -= sizeof(struct ifreq); done += sizeof(struct ifreq); } return done; } -u32 inet_select_addr(struct device *dev, u32 dst, int scope) +u32 inet_select_addr(const struct device *dev, u32 dst, int scope) { u32 addr = 0; - struct in_device *in_dev = dev->ip_ptr; + const struct in_device *in_dev = dev->ip_ptr; if (in_dev == NULL) return 0; @@ -661,15 +659,19 @@ u32 inet_select_addr(struct device *dev, u32 dst, int scope) in this case. It is importnat that lo is the first interface in dev_base list. */ + read_lock(&dev_base_lock); for (dev=dev_base; dev; dev=dev->next) { if ((in_dev=dev->ip_ptr) == NULL) continue; for_primary_ifa(in_dev) { - if (ifa->ifa_scope <= scope) + if (ifa->ifa_scope <= scope) { + read_unlock(&dev_base_lock); return ifa->ifa_local; + } } endfor_ifa(in_dev); } + read_unlock(&dev_base_lock); return 0; } @@ -790,6 +792,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) s_idx = cb->args[0]; s_ip_idx = ip_idx = cb->args[1]; + read_lock(&dev_base_lock); for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { if (idx < s_idx) continue; @@ -807,6 +810,7 @@ static int inet_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) } } done: + read_unlock(&dev_base_lock); cb->args[0] = idx; cb->args[1] = ip_idx; @@ -881,11 +885,13 @@ void inet_forward_change() ipv4_devconf.accept_redirects = !on; ipv4_devconf_dflt.forwarding = on; + read_lock(&dev_base_lock); for (dev = dev_base; dev; dev = dev->next) { struct in_device *in_dev = dev->ip_ptr; if (in_dev) in_dev->cnf.forwarding = on; } + read_unlock(&dev_base_lock); rt_cache_flush(0); -- cgit v1.2.3