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.c73
1 files changed, 55 insertions, 18 deletions
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index f8d04c256454..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}
@@ -1172,10 +1180,9 @@ static int __init ic_dynamic(void)
1172 schedule_timeout_uninterruptible(1); 1180 schedule_timeout_uninterruptible(1);
1173#ifdef IPCONFIG_DHCP 1181#ifdef IPCONFIG_DHCP
1174 /* DHCP isn't done until we get a DHCPACK. */ 1182 /* DHCP isn't done until we get a DHCPACK. */
1175 if ((ic_got_reply & IC_BOOTP) 1183 if ((ic_got_reply & IC_BOOTP) &&
1176 && (ic_proto_enabled & IC_USE_DHCP) 1184 (ic_proto_enabled & IC_USE_DHCP) &&
1177 && ic_dhcp_msgtype != DHCPACK) 1185 ic_dhcp_msgtype != DHCPACK) {
1178 {
1179 ic_got_reply = 0; 1186 ic_got_reply = 0;
1180 printk(","); 1187 printk(",");
1181 continue; 1188 continue;
@@ -1304,6 +1311,32 @@ __be32 __init root_nfs_parse_addr(char *name)
1304 return addr; 1311 return addr;
1305} 1312}
1306 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
1307/* 1340/*
1308 * IP Autoconfig dispatcher. 1341 * IP Autoconfig dispatcher.
1309 */ 1342 */
@@ -1314,6 +1347,7 @@ static int __init ip_auto_config(void)
1314#ifdef IPCONFIG_DYNAMIC 1347#ifdef IPCONFIG_DYNAMIC
1315 int retries = CONF_OPEN_RETRIES; 1348 int retries = CONF_OPEN_RETRIES;
1316#endif 1349#endif
1350 int err;
1317 1351
1318#ifdef CONFIG_PROC_FS 1352#ifdef CONFIG_PROC_FS
1319 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);
@@ -1326,12 +1360,15 @@ static int __init ip_auto_config(void)
1326#ifdef IPCONFIG_DYNAMIC 1360#ifdef IPCONFIG_DYNAMIC
1327 try_try_again: 1361 try_try_again:
1328#endif 1362#endif
1329 /* Give hardware a chance to settle */ 1363 /* Wait for devices to appear */
1330 msleep(CONF_PRE_OPEN); 1364 err = wait_for_devices();
1365 if (err)
1366 return err;
1331 1367
1332 /* Setup all network devices */ 1368 /* Setup all network devices */
1333 if (ic_open_devs() < 0) 1369 err = ic_open_devs();
1334 return -1; 1370 if (err)
1371 return err;
1335 1372
1336 /* Give drivers a chance to settle */ 1373 /* Give drivers a chance to settle */
1337 ssleep(CONF_POST_OPEN); 1374 ssleep(CONF_POST_OPEN);
@@ -1344,9 +1381,9 @@ static int __init ip_auto_config(void)
1344 */ 1381 */
1345 if (ic_myaddr == NONE || 1382 if (ic_myaddr == NONE ||
1346#ifdef CONFIG_ROOT_NFS 1383#ifdef CONFIG_ROOT_NFS
1347 (root_server_addr == NONE 1384 (root_server_addr == NONE &&
1348 && ic_servaddr == NONE 1385 ic_servaddr == NONE &&
1349 && ROOT_DEV == Root_NFS) || 1386 ROOT_DEV == Root_NFS) ||
1350#endif 1387#endif
1351 ic_first_dev->next) { 1388 ic_first_dev->next) {
1352#ifdef IPCONFIG_DYNAMIC 1389#ifdef IPCONFIG_DYNAMIC
@@ -1447,7 +1484,7 @@ late_initcall(ip_auto_config);
1447 1484
1448/* 1485/*
1449 * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel 1486 * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
1450 * command line parameter. See Documentation/filesystems/nfsroot.txt. 1487 * command line parameter. See Documentation/filesystems/nfs/nfsroot.txt.
1451 */ 1488 */
1452static int __init ic_proto_name(char *name) 1489static int __init ic_proto_name(char *name)
1453{ 1490{