aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipconfig.c')
-rw-r--r--net/ipv4/ipconfig.c58
1 files changed, 48 insertions, 10 deletions
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 10a6a604bf32..067ce9e043dc 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -53,6 +53,7 @@
53#include <linux/root_dev.h> 53#include <linux/root_dev.h>
54#include <linux/delay.h> 54#include <linux/delay.h>
55#include <linux/nfs_fs.h> 55#include <linux/nfs_fs.h>
56#include <linux/slab.h>
56#include <net/net_namespace.h> 57#include <net/net_namespace.h>
57#include <net/arp.h> 58#include <net/arp.h>
58#include <net/ip.h> 59#include <net/ip.h>
@@ -187,6 +188,16 @@ struct ic_device {
187static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ 188static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
188static struct net_device *ic_dev __initdata = NULL; /* Selected device */ 189static struct net_device *ic_dev __initdata = NULL; /* Selected device */
189 190
191static bool __init ic_device_match(struct net_device *dev)
192{
193 if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
194 (!(dev->flags & IFF_LOOPBACK) &&
195 (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
196 strncmp(dev->name, "dummy", 5)))
197 return true;
198 return false;
199}
200
190static int __init ic_open_devs(void) 201static int __init ic_open_devs(void)
191{ 202{
192 struct ic_device *d, **last; 203 struct ic_device *d, **last;
@@ -207,10 +218,7 @@ static int __init ic_open_devs(void)
207 for_each_netdev(&init_net, dev) { 218 for_each_netdev(&init_net, dev) {
208 if (dev->flags & IFF_LOOPBACK) 219 if (dev->flags & IFF_LOOPBACK)
209 continue; 220 continue;
210 if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) : 221 if (ic_device_match(dev)) {
211 (!(dev->flags & IFF_LOOPBACK) &&
212 (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
213 strncmp(dev->name, "dummy", 5))) {
214 int able = 0; 222 int able = 0;
215 if (dev->mtu >= 364) 223 if (dev->mtu >= 364)
216 able |= IC_BOOTP; 224 able |= IC_BOOTP;
@@ -228,7 +236,7 @@ static int __init ic_open_devs(void)
228 } 236 }
229 if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) { 237 if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
230 rtnl_unlock(); 238 rtnl_unlock();
231 return -1; 239 return -ENOMEM;
232 } 240 }
233 d->dev = dev; 241 d->dev = dev;
234 *last = d; 242 *last = d;
@@ -253,7 +261,7 @@ static int __init ic_open_devs(void)
253 printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name); 261 printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
254 else 262 else
255 printk(KERN_ERR "IP-Config: No network devices available.\n"); 263 printk(KERN_ERR "IP-Config: No network devices available.\n");
256 return -1; 264 return -ENODEV;
257 } 265 }
258 return 0; 266 return 0;
259} 267}
@@ -1303,6 +1311,32 @@ __be32 __init root_nfs_parse_addr(char *name)
1303 return addr; 1311 return addr;
1304} 1312}
1305 1313
1314#define DEVICE_WAIT_MAX 12 /* 12 seconds */
1315
1316static int __init wait_for_devices(void)
1317{
1318 int i;
1319
1320 msleep(CONF_PRE_OPEN);
1321 for (i = 0; i < DEVICE_WAIT_MAX; i++) {
1322 struct net_device *dev;
1323 int found = 0;
1324
1325 rtnl_lock();
1326 for_each_netdev(&init_net, dev) {
1327 if (ic_device_match(dev)) {
1328 found = 1;
1329 break;
1330 }
1331 }
1332 rtnl_unlock();
1333 if (found)
1334 return 0;
1335 ssleep(1);
1336 }
1337 return -ENODEV;
1338}
1339
1306/* 1340/*
1307 * IP Autoconfig dispatcher. 1341 * IP Autoconfig dispatcher.
1308 */ 1342 */
@@ -1313,6 +1347,7 @@ static int __init ip_auto_config(void)
1313#ifdef IPCONFIG_DYNAMIC 1347#ifdef IPCONFIG_DYNAMIC
1314 int retries = CONF_OPEN_RETRIES; 1348 int retries = CONF_OPEN_RETRIES;
1315#endif 1349#endif
1350 int err;
1316 1351
1317#ifdef CONFIG_PROC_FS 1352#ifdef CONFIG_PROC_FS
1318 proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops); 1353 proc_net_fops_create(&init_net, "pnp", S_IRUGO, &pnp_seq_fops);
@@ -1325,12 +1360,15 @@ static int __init ip_auto_config(void)
1325#ifdef IPCONFIG_DYNAMIC 1360#ifdef IPCONFIG_DYNAMIC
1326 try_try_again: 1361 try_try_again:
1327#endif 1362#endif
1328 /* Give hardware a chance to settle */ 1363 /* Wait for devices to appear */
1329 msleep(CONF_PRE_OPEN); 1364 err = wait_for_devices();
1365 if (err)
1366 return err;
1330 1367
1331 /* Setup all network devices */ 1368 /* Setup all network devices */
1332 if (ic_open_devs() < 0) 1369 err = ic_open_devs();
1333 return -1; 1370 if (err)
1371 return err;
1334 1372
1335 /* Give drivers a chance to settle */ 1373 /* Give drivers a chance to settle */
1336 ssleep(CONF_POST_OPEN); 1374 ssleep(CONF_POST_OPEN);