Skip to content

Commit 2647cff

Browse files
Uwe Kleine-Königdavem330
authored andcommitted
net: ipconfig: Support using "delayed" DHCP replies
The dhcp code only waits 1s between sending DHCP requests on different devices and only accepts an answer for the device that sent out the last request. Only the timeout at the end of a loop is increased iteratively which favours only the last device. This makes it impossible to work with a dhcp server that takes little more than 1s connected to a device that is not the last one. Instead of also increasing the inter-device timeout, teach the code to handle delayed replies. To accomplish that, make *ic_dev track the current ic_device instead of the current net_device and adapt all users accordingly. The relevant change then is to reset d to ic_dev on a reply to assert that the followup request goes through the right device. Signed-off-by: Uwe Kleine-König <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 22fc538 commit 2647cff

File tree

1 file changed

+10
-19
lines changed

1 file changed

+10
-19
lines changed

net/ipv4/ipconfig.c

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ struct ic_device {
188188
};
189189

190190
static struct ic_device *ic_first_dev __initdata; /* List of open device */
191-
static struct net_device *ic_dev __initdata; /* Selected device */
191+
static struct ic_device *ic_dev __initdata; /* Selected device */
192192

193193
static bool __init ic_is_init_dev(struct net_device *dev)
194194
{
@@ -307,7 +307,7 @@ static void __init ic_close_devs(void)
307307
while ((d = next)) {
308308
next = d->next;
309309
dev = d->dev;
310-
if (dev != ic_dev && !netdev_uses_dsa(dev)) {
310+
if (dev != ic_dev->dev && !netdev_uses_dsa(dev)) {
311311
pr_debug("IP-Config: Downing %s\n", dev->name);
312312
dev_change_flags(dev, d->flags);
313313
}
@@ -372,7 +372,7 @@ static int __init ic_setup_if(void)
372372
int err;
373373

374374
memset(&ir, 0, sizeof(ir));
375-
strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
375+
strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->dev->name);
376376
set_sockaddr(sin, ic_myaddr, 0);
377377
if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) {
378378
pr_err("IP-Config: Unable to set interface address (%d)\n",
@@ -396,7 +396,7 @@ static int __init ic_setup_if(void)
396396
* out, we'll try to muddle along.
397397
*/
398398
if (ic_dev_mtu != 0) {
399-
strcpy(ir.ifr_name, ic_dev->name);
399+
strcpy(ir.ifr_name, ic_dev->dev->name);
400400
ir.ifr_mtu = ic_dev_mtu;
401401
if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0)
402402
pr_err("IP-Config: Unable to set interface mtu to %d (%d)\n",
@@ -568,7 +568,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
568568
goto drop_unlock;
569569

570570
/* We have a winner! */
571-
ic_dev = dev;
571+
ic_dev = d;
572572
if (ic_myaddr == NONE)
573573
ic_myaddr = tip;
574574
ic_servaddr = sip;
@@ -655,8 +655,6 @@ static struct packet_type bootp_packet_type __initdata = {
655655
.func = ic_bootp_recv,
656656
};
657657

658-
static __be32 ic_dev_xid; /* Device under configuration */
659-
660658
/*
661659
* Initialize DHCP/BOOTP extension fields in the request.
662660
*/
@@ -1038,12 +1036,6 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
10381036
goto drop_unlock;
10391037
}
10401038

1041-
/* Is it a reply for the device we are configuring? */
1042-
if (b->xid != ic_dev_xid) {
1043-
net_err_ratelimited("DHCP/BOOTP: Ignoring delayed packet\n");
1044-
goto drop_unlock;
1045-
}
1046-
10471039
/* Parse extensions */
10481040
if (ext_len >= 4 &&
10491041
!memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
@@ -1130,7 +1122,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
11301122
}
11311123

11321124
/* We have a winner! */
1133-
ic_dev = dev;
1125+
ic_dev = d;
11341126
ic_myaddr = b->your_ip;
11351127
ic_servaddr = b->server_ip;
11361128
ic_addrservaddr = b->iph.saddr;
@@ -1225,9 +1217,6 @@ static int __init ic_dynamic(void)
12251217
timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned int) CONF_TIMEOUT_RANDOM);
12261218
for (;;) {
12271219
#ifdef IPCONFIG_BOOTP
1228-
/* Track the device we are configuring */
1229-
ic_dev_xid = d->xid;
1230-
12311220
if (do_bootp && (d->able & IC_BOOTP))
12321221
ic_bootp_send_if(d, jiffies - start_jiffies);
12331222
#endif
@@ -1245,6 +1234,8 @@ static int __init ic_dynamic(void)
12451234
(ic_proto_enabled & IC_USE_DHCP) &&
12461235
ic_dhcp_msgtype != DHCPACK) {
12471236
ic_got_reply = 0;
1237+
/* continue on device that got the reply */
1238+
d = ic_dev;
12481239
pr_cont(",");
12491240
continue;
12501241
}
@@ -1487,7 +1478,7 @@ static int __init ip_auto_config(void)
14871478
#endif /* IPCONFIG_DYNAMIC */
14881479
} else {
14891480
/* Device selected manually or only one device -> use it */
1490-
ic_dev = ic_first_dev->dev;
1481+
ic_dev = ic_first_dev;
14911482
}
14921483

14931484
addr = root_nfs_parse_addr(root_server_path);
@@ -1522,7 +1513,7 @@ static int __init ip_auto_config(void)
15221513
pr_info("IP-Config: Complete:\n");
15231514

15241515
pr_info(" device=%s, hwaddr=%*phC, ipaddr=%pI4, mask=%pI4, gw=%pI4\n",
1525-
ic_dev->name, ic_dev->addr_len, ic_dev->dev_addr,
1516+
ic_dev->dev->name, ic_dev->dev->addr_len, ic_dev->dev->dev_addr,
15261517
&ic_myaddr, &ic_netmask, &ic_gateway);
15271518
pr_info(" host=%s, domain=%s, nis-domain=%s\n",
15281519
utsname()->nodename, ic_domain, utsname()->domainname);

0 commit comments

Comments
 (0)