mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 14:49:24 +01:00
netconfig: Try to put gateway mac into ARP cache
In certain situations, it is possible for us to know the MAC of the default gateway when DHCP finishes. This is quite typical on many home network and small network setups. It is thus possible to pre-populate the ARP cache with the gateway MAC address to save an extra round trip at connection time. Another advantage is during roaming. After version 4.20, linux kernel flushes ARP caches by default whenever netdev encounters a no carrier condition (as is the case during roaming). This can prevent packets from going out after a roam for a significant amount of time due to lost/delayed ARP responses.
This commit is contained in:
parent
5d9e0401fc
commit
2135a4f845
@ -574,6 +574,39 @@ static struct l_rtnl_address *netconfig_get_dhcp4_address(
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void netconfig_gateway_to_arp(struct netconfig *netconfig)
|
||||
{
|
||||
const struct l_dhcp_lease *lease;
|
||||
_auto_(l_free) char *server_id = NULL;
|
||||
_auto_(l_free) char *gw = NULL;
|
||||
const uint8_t *server_mac;
|
||||
struct in_addr in_gw;
|
||||
|
||||
/* Can only do this for DHCP in certain network setups */
|
||||
if (netconfig->rtm_protocol != RTPROT_DHCP)
|
||||
return;
|
||||
|
||||
lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
|
||||
if (!lease)
|
||||
return;
|
||||
|
||||
server_id = l_dhcp_lease_get_server_id(lease);
|
||||
gw = l_dhcp_lease_get_gateway(lease);
|
||||
server_mac = l_dhcp_lease_get_server_mac(lease);
|
||||
|
||||
if (strcmp(server_id, gw) || !server_mac)
|
||||
return;
|
||||
|
||||
l_debug("Gateway MAC is known, setting into ARP cache");
|
||||
in_gw.s_addr = l_dhcp_lease_get_gateway_u32(lease);
|
||||
|
||||
if (!l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex, AF_INET,
|
||||
&in_gw, server_mac, ETH_ALEN,
|
||||
netconfig_set_neighbor_entry_cb, NULL,
|
||||
NULL))
|
||||
l_debug("l_rtnl_neighbor_set_hwaddr failed");
|
||||
}
|
||||
|
||||
static void netconfig_ifaddr_added(struct netconfig *netconfig,
|
||||
const struct ifaddrmsg *ifa,
|
||||
uint32_t len)
|
||||
@ -861,6 +894,8 @@ static void netconfig_ipv4_ifaddr_add_cmd_cb(int error, uint16_t type,
|
||||
return;
|
||||
}
|
||||
|
||||
netconfig_gateway_to_arp(netconfig);
|
||||
|
||||
if (!netconfig_ipv4_routes_install(netconfig)) {
|
||||
l_error("netconfig: Failed to install IPv4 routes.");
|
||||
return;
|
||||
@ -1372,6 +1407,15 @@ bool netconfig_configure(struct netconfig *netconfig,
|
||||
|
||||
bool netconfig_reconfigure(struct netconfig *netconfig)
|
||||
{
|
||||
/*
|
||||
* Starting with kernel 4.20, ARP cache is flushed when the netdev
|
||||
* detects NO CARRIER. This can result in unnecessarily long delays
|
||||
* (about 1 second on some networks) due to ARP query response being
|
||||
* lost or delayed. Try to force the gateway into the ARP cache
|
||||
* to alleviate this
|
||||
*/
|
||||
netconfig_gateway_to_arp(netconfig);
|
||||
|
||||
if (netconfig->rtm_protocol == RTPROT_DHCP) {
|
||||
/* TODO l_dhcp_client sending a DHCP inform request */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user