| From: Paul Stewart <pstew@chromium.org> |
| Date: Wed, 16 Sep 2015 20:24:18 -0700 |
| Subject: [PATCH] dhcpcd: ChromiumOS: Ensure gateway probe is broadcast |
| |
| The arp_new() method does not always return a freshly |
| initialized arp_state structure. For example, if |
| dhcp_probe_gw() is called while a probe from |
| start_unicast_arp() is still running, the arp_state |
| object from the unicast ARP call will be returned by |
| arp_new(). This can happen when a DHCP renew succeeds |
| while a unicast "GatewayArp" is still in progress. |
| |
| In the above scenario we need to make sure the dest_hwlen |
| field of the arp_state structure is zero. This signals a |
| broadcast ARP, and will ensure that the callbacks that are |
| invoked by the ARP state machine know which case we are in. |
| |
| While here, add a small optimization that skips a |
| broadcast gateway ARP if a unicast ARP succeeds. |
| |
| BUG=chromium:531042 |
| TEST=Reconnect to WiFi network where ARP fails |
| |
| diff -ur dhcpcd-6.8.2-orig/dhcp.c dhcpcd-6.8.2/dhcp.c |
| --- dhcpcd-6.8.2-orig/dhcp.c 2015-09-16 20:13:52.499886444 -0700 |
| +++ dhcpcd-6.8.2/dhcp.c 2015-09-16 20:19:27.477974649 -0700 |
| @@ -2609,6 +2609,8 @@ |
| if (astate->dest_hwlen) { |
| /* Response to unicast ARP. */ |
| rpc_notify_unicast_arp(astate->iface); |
| + /* Unicast ARP succeeded; no need for broadcast ARP. */ |
| + astate->iface->options->options &= ~DHCPCD_ARPGW; |
| } else { |
| /* Response to arpgw request. */ |
| save_gateway_addr(astate->iface, amsg->sha); |
| @@ -2637,6 +2639,8 @@ |
| state->offer, DHO_ROUTER) == 0) { |
| astate = arp_new(ifp, &gateway_addr); |
| if (astate) { |
| + /* Make sure we're doing a broadcast ARP. */ |
| + astate->dest_hwlen = 0; |
| astate->src_addr.s_addr = state->offer->yiaddr; |
| astate->probed_cb = dhcp_probe_gw_timeout; |
| astate->conflicted_cb = dhcp_probe_gw_response; |
| Only in dhcpcd-6.8.2: dhcp.c.orig |