mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 13:02:44 +01:00
netconfig: Re-add FILS handling
Load the settings from FILS IE data into our l_netconfig instance when appropriate.
This commit is contained in:
parent
fbdd4471a1
commit
11bae53408
@ -103,6 +103,10 @@ void netconfig_commit(struct netconfig *netconfig, uint8_t family,
|
||||
if (family == AF_INET &&
|
||||
!netconfig->static_config[INDEX_FOR_AF(family)])
|
||||
netconfig_dhcp_gateway_to_arp(netconfig);
|
||||
|
||||
if (!netconfig->connected[INDEX_FOR_AF(family)] &&
|
||||
netconfig_use_fils_addr(netconfig, family))
|
||||
netconfig_commit_fils_macs(netconfig, family);
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,6 +191,53 @@ void netconfig_dhcp_gateway_to_arp(struct netconfig *netconfig)
|
||||
l_debug("l_rtnl_neighbor_set_hwaddr failed");
|
||||
}
|
||||
|
||||
void netconfig_commit_fils_macs(struct netconfig *netconfig, uint8_t family)
|
||||
{
|
||||
const struct ie_fils_ip_addr_response_info *fils =
|
||||
netconfig->fils_override;
|
||||
const void *addr;
|
||||
const void *hwaddr;
|
||||
size_t addr_len = (family == AF_INET ? 4 : 16);
|
||||
uint32_t ifindex = netdev_get_ifindex(netconfig->netdev);
|
||||
|
||||
if (!fils)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Attempt to use the gateway/DNS MAC addressed received from the AP
|
||||
* by writing the mapping directly into the netdev's ARP table so as
|
||||
* to save one data frame roundtrip before first IP connections are
|
||||
* established. This is very low-priority but print error messages
|
||||
* just because they may indicate bigger problems.
|
||||
*/
|
||||
|
||||
addr = (family == AF_INET ? (void *) &fils->ipv4_gateway :
|
||||
(void *) &fils->ipv6_gateway);
|
||||
hwaddr = (family == AF_INET ?
|
||||
&fils->ipv4_gateway_mac : &fils->ipv6_gateway_mac);
|
||||
|
||||
if (!l_memeqzero(addr, addr_len) && !l_memeqzero(hwaddr, ETH_ALEN) &&
|
||||
unlikely(!l_rtnl_neighbor_set_hwaddr(rtnl, ifindex,
|
||||
family, addr, hwaddr, ETH_ALEN,
|
||||
netconfig_set_neighbor_entry_cb,
|
||||
NULL, NULL)))
|
||||
l_debug("l_rtnl_neighbor_set_hwaddr(%s, gateway) failed",
|
||||
family == AF_INET ? "AF_INET" : "AF_INET6");
|
||||
|
||||
addr = (family == AF_INET ? (void *) &fils->ipv4_dns :
|
||||
(void *) &fils->ipv6_dns);
|
||||
hwaddr = (family == AF_INET ?
|
||||
&fils->ipv4_dns_mac : &fils->ipv6_dns_mac);
|
||||
|
||||
if (!l_memeqzero(addr, addr_len) && !l_memeqzero(hwaddr, ETH_ALEN) &&
|
||||
unlikely(!l_rtnl_neighbor_set_hwaddr(rtnl, ifindex,
|
||||
family, addr, hwaddr, ETH_ALEN,
|
||||
netconfig_set_neighbor_entry_cb,
|
||||
NULL, NULL)))
|
||||
l_debug("l_rtnl_neighbor_set_hwaddr(%s, DNS) failed",
|
||||
family == AF_INET ? "AF_INET" : "AF_INET6");
|
||||
}
|
||||
|
||||
static void netconfig_dns_list_update(struct netconfig *netconfig)
|
||||
{
|
||||
_auto_(l_strv_free) char **dns_list =
|
||||
|
115
src/netconfig.c
115
src/netconfig.c
@ -90,6 +90,26 @@ static void netconfig_free(void *data)
|
||||
l_free(netconfig);
|
||||
}
|
||||
|
||||
static bool netconfig_addr_to_str(uint8_t af, const void *v4_addr,
|
||||
const void *v6_addr, char *out_str,
|
||||
bool *out_is_zero)
|
||||
{
|
||||
const void *addr = (af == AF_INET ? v4_addr : v6_addr);
|
||||
uint8_t bytes = (af == AF_INET ? 4 : 16);
|
||||
|
||||
if (l_memeqzero(addr, bytes)) {
|
||||
*out_is_zero = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
*out_is_zero = false;
|
||||
|
||||
if (L_WARN_ON(!inet_ntop(af, addr, out_str, INET6_ADDRSTRLEN)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool netconfig_use_fils_addr(struct netconfig *netconfig, int af)
|
||||
{
|
||||
if (!netconfig->enabled[INDEX_FOR_AF(af)])
|
||||
@ -408,12 +428,96 @@ mdns:
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool netconfig_load_fils_settings(struct netconfig *netconfig,
|
||||
uint8_t af)
|
||||
{
|
||||
struct ie_fils_ip_addr_response_info *fils = netconfig->fils_override;
|
||||
char addr_str[INET6_ADDRSTRLEN];
|
||||
char gw_addr_str[INET6_ADDRSTRLEN];
|
||||
char dns_addr_str[INET6_ADDRSTRLEN];
|
||||
_auto_(l_rtnl_address_free) struct l_rtnl_address *rtnl_addr = NULL;
|
||||
bool is_zero = false;
|
||||
uint8_t prefix_len;
|
||||
|
||||
if (!netconfig_addr_to_str(af, &fils->ipv4_addr, &fils->ipv6_addr,
|
||||
addr_str, &is_zero) || is_zero)
|
||||
return is_zero;
|
||||
|
||||
prefix_len = (af == AF_INET ? fils->ipv4_prefix_len :
|
||||
fils->ipv6_prefix_len);
|
||||
|
||||
if (L_WARN_ON(!(rtnl_addr = l_rtnl_address_new(addr_str, prefix_len))))
|
||||
return false;
|
||||
|
||||
if (L_WARN_ON(!l_netconfig_set_static_addr(netconfig->nc, af,
|
||||
rtnl_addr)))
|
||||
return false;
|
||||
|
||||
if (af == AF_INET &&
|
||||
L_WARN_ON(!l_netconfig_set_acd_enabled(netconfig->nc,
|
||||
false)))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Done with local address, move on to gateway and DNS.
|
||||
*
|
||||
* Since load_settings is called early, generally before the actual
|
||||
* connection setup starts, and load_fils_settings is called after
|
||||
* 802.11 Authentication & Association, we need to check if either
|
||||
* the gateway or DNS settings were overridden in load_settings so
|
||||
* as not to overwrite the user-provided values. Values received
|
||||
* with FILS are expected to have the same weight as those from
|
||||
* DHCP/SLAAC.
|
||||
*
|
||||
* TODO: If netconfig->fils_override->ipv{4,6}_lifetime is set,
|
||||
* start a timeout to renew the address using FILS IP Address
|
||||
* Assignment or perhaps just start the DHCP client after that
|
||||
* time.
|
||||
*
|
||||
* TODO: validate gateway and/or DNS on local subnet, link-local,
|
||||
* etc.?
|
||||
*/
|
||||
|
||||
if (!netconfig_addr_to_str(af, &fils->ipv4_gateway, &fils->ipv6_gateway,
|
||||
gw_addr_str, &is_zero))
|
||||
return false;
|
||||
|
||||
if (!netconfig->gateway_overridden[INDEX_FOR_AF(af)] && !is_zero &&
|
||||
L_WARN_ON(!l_netconfig_set_gateway_override(
|
||||
netconfig->nc,
|
||||
af,
|
||||
gw_addr_str)))
|
||||
return false;
|
||||
|
||||
if (!netconfig_addr_to_str(af, &fils->ipv4_dns, &fils->ipv6_dns,
|
||||
dns_addr_str, &is_zero))
|
||||
return is_zero;
|
||||
|
||||
if (!netconfig->dns_overridden[INDEX_FOR_AF(af)] && !is_zero) {
|
||||
char *dns_list[2] = { dns_addr_str, NULL };
|
||||
|
||||
if (L_WARN_ON(!l_netconfig_set_dns_override(netconfig->nc,
|
||||
af, dns_list)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool netconfig_configure(struct netconfig *netconfig,
|
||||
netconfig_notify_func_t notify, void *user_data)
|
||||
{
|
||||
netconfig->notify = notify;
|
||||
netconfig->user_data = user_data;
|
||||
|
||||
if (netconfig_use_fils_addr(netconfig, AF_INET) &&
|
||||
!netconfig_load_fils_settings(netconfig, AF_INET))
|
||||
return false;
|
||||
|
||||
if (netconfig_use_fils_addr(netconfig, AF_INET6) &&
|
||||
!netconfig_load_fils_settings(netconfig, AF_INET6))
|
||||
return false;
|
||||
|
||||
if (unlikely(!l_netconfig_start(netconfig->nc)))
|
||||
return false;
|
||||
|
||||
@ -429,9 +533,18 @@ bool netconfig_reconfigure(struct netconfig *netconfig, bool set_arp_gw)
|
||||
* lost or delayed. Try to force the gateway into the ARP cache
|
||||
* to alleviate this
|
||||
*/
|
||||
if (set_arp_gw)
|
||||
if (set_arp_gw) {
|
||||
netconfig_dhcp_gateway_to_arp(netconfig);
|
||||
|
||||
if (netconfig->connected[INDEX_FOR_AF(AF_INET)] &&
|
||||
netconfig_use_fils_addr(netconfig, AF_INET))
|
||||
netconfig_commit_fils_macs(netconfig, AF_INET);
|
||||
|
||||
if (netconfig->connected[INDEX_FOR_AF(AF_INET6)] &&
|
||||
netconfig_use_fils_addr(netconfig, AF_INET6))
|
||||
netconfig_commit_fils_macs(netconfig, AF_INET6);
|
||||
}
|
||||
|
||||
if (!netconfig->static_config[INDEX_FOR_AF(AF_INET)]) {
|
||||
/* TODO l_dhcp_client sending a DHCP inform request */
|
||||
}
|
||||
|
@ -83,3 +83,4 @@ void netconfig_commit(struct netconfig *netconfig, uint8_t family,
|
||||
enum l_netconfig_event event);
|
||||
|
||||
void netconfig_dhcp_gateway_to_arp(struct netconfig *netconfig);
|
||||
void netconfig_commit_fils_macs(struct netconfig *netconfig, uint8_t family);
|
||||
|
Loading…
Reference in New Issue
Block a user