Commit 91dfe8ef authored by Herbert Xu's avatar Herbert Xu Committed by James Morris

[IPV4]: inetdev ifa_list handling fixes outside of net/ipv4.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 2b12caa0
......@@ -50,6 +50,7 @@
#include <linux/random.h>
#include <linux/pkt_sched.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <net/syncppp.h>
......@@ -767,9 +768,9 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
struct in_ifaddr *ifa;
u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */
#ifdef CONFIG_INET
if ((in_dev=in_dev_get(dev)) != NULL)
rcu_read_lock();
if ((in_dev = __in_dev_get(dev)) != NULL)
{
read_lock(&in_dev->lock);
for (ifa=in_dev->ifa_list; ifa != NULL;
ifa=ifa->ifa_next) {
if (strcmp(dev->name, ifa->ifa_label) == 0)
......@@ -779,9 +780,8 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
break;
}
}
read_unlock(&in_dev->lock);
in_dev_put(in_dev);
}
rcu_read_unlock();
#endif
/* I hope both addr and mask are in the net order */
sppp_cisco_send (sp, CISCO_ADDR_REPLY, addr, mask);
......
......@@ -106,6 +106,7 @@ static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/rcupdate.h>
#include <net/arp.h>
#include <linux/ip.h>
......@@ -1348,14 +1349,17 @@ static unsigned char *strip_make_packet(unsigned char *buffer,
*/
if (haddr.c[0] == 0xFF) {
u32 brd = 0;
struct in_device *in_dev = in_dev_get(strip_info->dev);
if (in_dev == NULL)
struct in_device *in_dev;
rcu_read_lock();
in_dev = __in_dev_get(strip_info->dev);
if (in_dev == NULL) {
rcu_read_unlock();
return NULL;
read_lock(&in_dev->lock);
}
if (in_dev->ifa_list)
brd = in_dev->ifa_list->ifa_broadcast;
read_unlock(&in_dev->lock);
in_dev_put(in_dev);
rcu_read_unlock();
/* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
if (!arp_query(haddr.c, brd, strip_info->dev)) {
......@@ -1500,17 +1504,18 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
}
if (1) {
struct in_device *in_dev = in_dev_get(strip_info->dev);
struct in_device *in_dev;
brd = addr = 0;
rcu_read_lock();
in_dev = __in_dev_get(strip_info->dev);
if (in_dev) {
read_lock(&in_dev->lock);
if (in_dev->ifa_list) {
brd = in_dev->ifa_list->ifa_broadcast;
addr = in_dev->ifa_list->ifa_local;
}
read_unlock(&in_dev->lock);
in_dev_put(in_dev);
}
rcu_read_unlock();
}
......
......@@ -18,6 +18,7 @@
#include <linux/interrupt.h>
#include <linux/netpoll.h>
#include <linux/sched.h>
#include <linux/rcupdate.h>
#include <net/tcp.h>
#include <net/udp.h>
......@@ -572,16 +573,18 @@ int netpoll_setup(struct netpoll *np)
memcpy(np->local_mac, ndev->dev_addr, 6);
if (!np->local_ip) {
in_dev = in_dev_get(ndev);
rcu_read_lock();
in_dev = __in_dev_get(ndev);
if (!in_dev) {
rcu_read_unlock();
printk(KERN_ERR "%s: no IP address for %s, aborting\n",
np->name, np->dev_name);
goto release;
}
np->local_ip = ntohl(in_dev->ifa_list->ifa_local);
in_dev_put(in_dev);
rcu_read_unlock();
printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
np->name, HIPQUAD(np->local_ip));
}
......
......@@ -70,6 +70,7 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/inet.h>
#include <linux/rcupdate.h>
#include <asm/byteorder.h>
#include <asm/bitops.h>
#include <asm/io.h>
......@@ -263,14 +264,17 @@ static struct net_device *setup_inject(struct pktgen_info* info)
info->saddr_min = 0;
info->saddr_max = 0;
if (strlen(info->src_min) == 0) {
struct in_device *in_dev = in_dev_get(odev);
struct in_device *in_dev;
rcu_read_lock();
in_dev = __in_dev_get(odev);
if (in_dev) {
if (in_dev->ifa_list) {
info->saddr_min = in_dev->ifa_list->ifa_address;
info->saddr_max = info->saddr_min;
}
in_dev_put(in_dev);
}
rcu_read_unlock();
}
else {
info->saddr_min = in_aton(info->src_min);
......
......@@ -39,6 +39,7 @@
#include <net/udp.h>
#include <net/ip.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
#include <asm/uaccess.h>
#include <asm/system.h>
......@@ -401,16 +402,17 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
y.x maps to IP a.b.c.x. This should be replaced with something
more flexible and more aware of subnet masks. */
{
struct in_device *idev = in_dev_get(dev);
struct in_device *idev;
unsigned long network = 0;
rcu_read_lock();
idev = __in_dev_get(dev);
if (idev) {
read_lock(&idev->lock);
if (idev->ifa_list)
network = ntohl(idev->ifa_list->ifa_address) &
0xffffff00; /* !!! */
read_unlock(&idev->lock);
in_dev_put(idev);
}
rcu_read_unlock();
udpdest.sin_addr.s_addr = htonl(network | addr.station);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment