blob: cead44111385cf55cda23de6d77499795590b576 [file] [log] [blame]
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