diff options
Diffstat (limited to 'net/ipv4/ipconfig.c')
| -rw-r--r-- | net/ipv4/ipconfig.c | 73 |
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 { | |||
| 187 | static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ | 188 | static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ |
| 188 | static struct net_device *ic_dev __initdata = NULL; /* Selected device */ | 189 | static struct net_device *ic_dev __initdata = NULL; /* Selected device */ |
| 189 | 190 | ||
| 191 | static 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 | |||
| 190 | static int __init ic_open_devs(void) | 201 | static 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 | |||
| 1316 | static 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 | */ |
| 1452 | static int __init ic_proto_name(char *name) | 1489 | static int __init ic_proto_name(char *name) |
| 1453 | { | 1490 | { |
