@@ -54,8 +54,6 @@
struct netconfig {
uint32_t ifindex;
- struct l_dhcp_client *dhcp_client;
- struct l_dhcp6_client *dhcp6_client;
uint8_t rtm_protocol;
uint8_t rtm_v6_protocol;
struct l_rtnl_address *v4_address;
@@ -77,17 +75,9 @@ struct netconfig {
void *user_data;
struct resolve *resolve;
-
- struct l_acd *acd;
-
- uint32_t addr4_add_cmd_id;
- uint32_t addr6_add_cmd_id;
- uint32_t route4_add_gateway_cmd_id;
- uint32_t route6_add_cmd_id;
};
static struct l_netlink *rtnl;
-static struct l_queue *netconfig_list;
/*
* Routing priority offset, configurable in main.conf. The route with lower
@@ -123,59 +113,9 @@ static void netconfig_free(void *data)
{
struct netconfig *netconfig = data;
- l_dhcp_client_destroy(netconfig->dhcp_client);
- l_dhcp6_client_destroy(netconfig->dhcp6_client);
-
l_free(netconfig);
}
-static struct netconfig *netconfig_find(uint32_t ifindex)
-{
- const struct l_queue_entry *entry;
-
- for (entry = l_queue_get_entries(netconfig_list); entry;
- entry = entry->next) {
- struct netconfig *netconfig = entry->data;
-
- if (netconfig->ifindex != ifindex)
- continue;
-
- return netconfig;
- }
-
- return NULL;
-}
-
-static inline char *netconfig_ipv4_to_string(uint32_t addr)
-{
- struct in_addr in_addr = { .s_addr = addr };
- char *addr_str = l_malloc(INET_ADDRSTRLEN);
-
- if (L_WARN_ON(unlikely(!inet_ntop(AF_INET, &in_addr, addr_str,
- INET_ADDRSTRLEN)))) {
- l_free(addr_str);
- return NULL;
- }
-
- return addr_str;
-}
-
-static inline char *netconfig_ipv6_to_string(const uint8_t *addr)
-{
- struct in6_addr in6_addr;
- char *addr_str = l_malloc(INET6_ADDRSTRLEN);
-
- memcpy(in6_addr.s6_addr, addr, 16);
-
- if (L_WARN_ON(unlikely(!inet_ntop(AF_INET6, &in6_addr, addr_str,
- INET6_ADDRSTRLEN)))) {
- l_free(addr_str);
- return NULL;
- }
-
- return addr_str;
-}
-
static bool netconfig_use_fils_addr(struct netconfig *netconfig, int af)
{
if ((af == AF_INET ? netconfig->rtm_protocol :
@@ -191,88 +131,6 @@ static bool netconfig_use_fils_addr(struct netconfig *netconfig, int af)
return !l_memeqzero(netconfig->fils_override->ipv6_addr, 16);
}
-static bool netconfig_use_fils_gateway(struct netconfig *netconfig, int af)
-{
- if ((af == AF_INET ? netconfig->rtm_protocol :
- netconfig->rtm_v6_protocol) != RTPROT_DHCP)
- return false;
-
- if (!netconfig->fils_override)
- return false;
-
- if (af == AF_INET)
- return !!netconfig->fils_override->ipv4_gateway;
-
- return !l_memeqzero(netconfig->fils_override->ipv6_gateway, 16);
-}
-
-static char **netconfig_get_dns_list(struct netconfig *netconfig, int af,
- const uint8_t **out_dns_mac)
-{
- const struct ie_fils_ip_addr_response_info *fils =
- netconfig->fils_override;
-
- if (af == AF_INET) {
- const struct l_dhcp_lease *lease;
-
- if (netconfig->dns4_overrides)
- return l_strv_copy(netconfig->dns4_overrides);
-
- if (netconfig->rtm_protocol != RTPROT_DHCP)
- return NULL;
-
- if (fils && fils->ipv4_dns) {
- char **dns_list = l_new(char *, 2);
-
- if (!l_memeqzero(fils->ipv4_dns_mac, 6) &&
- out_dns_mac &&
- util_ip_subnet_match(
- fils->ipv4_prefix_len,
- &fils->ipv4_addr,
- &fils->ipv4_dns))
- *out_dns_mac = fils->ipv4_dns_mac;
-
- dns_list[0] = netconfig_ipv4_to_string(fils->ipv4_dns);
- return dns_list;
- }
-
- lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
- if (!lease)
- return NULL;
-
- return l_dhcp_lease_get_dns(lease);
- } else {
- const struct l_dhcp6_lease *lease;
-
- if (netconfig->dns6_overrides)
- return l_strv_copy(netconfig->dns6_overrides);
-
- if (netconfig->rtm_v6_protocol != RTPROT_DHCP)
- return NULL;
-
- if (fils && !l_memeqzero(fils->ipv6_dns, 16)) {
- char **dns_list = l_new(char *, 2);
-
- if (!l_memeqzero(fils->ipv6_dns_mac, 6) &&
- out_dns_mac &&
- util_ip_subnet_match(
- fils->ipv6_prefix_len,
- fils->ipv6_addr,
- fils->ipv6_dns))
- *out_dns_mac = fils->ipv6_dns_mac;
-
- dns_list[0] = netconfig_ipv6_to_string(fils->ipv6_dns);
- return dns_list;
- }
-
- lease = l_dhcp6_client_get_lease(netconfig->dhcp6_client);
- if (!lease)
- return NULL;
-
- return l_dhcp6_lease_get_dns(lease);
- }
-}
-
static void netconfig_set_neighbor_entry_cb(int error,
uint16_t type, const void *data,
uint32_t len, void *user_data)
@@ -282,146 +140,6 @@ static void netconfig_set_neighbor_entry_cb(int error,
strerror(-error), error);
}
-static void netconfig_set_dns(struct netconfig *netconfig)
-{
- if (!netconfig->dns4_list && !netconfig->dns6_list)
- return;
-
- if (netconfig->dns4_list && netconfig->dns6_list) {
- unsigned int n_entries4 = l_strv_length(netconfig->dns4_list);
- unsigned int n_entries6 = l_strv_length(netconfig->dns6_list);
- char **dns_list = l_malloc(sizeof(char *) *
- (n_entries4 + n_entries6 + 1));
-
- memcpy(dns_list, netconfig->dns4_list,
- sizeof(char *) * n_entries4);
- memcpy(dns_list + n_entries4, netconfig->dns6_list,
- sizeof(char *) * (n_entries6 + 1));
- resolve_set_dns(netconfig->resolve, dns_list);
- l_free(dns_list);
- return;
- }
-
- resolve_set_dns(netconfig->resolve,
- netconfig->dns4_list ?: netconfig->dns6_list);
-}
-
-static bool netconfig_dns_list_update(struct netconfig *netconfig, uint8_t af)
-{
- const uint8_t *fils_dns_mac = NULL;
- char ***dns_list_ptr = af == AF_INET ?
- &netconfig->dns4_list : &netconfig->dns6_list;
- char **new_dns_list = netconfig_get_dns_list(netconfig, af,
- &fils_dns_mac);
-
- if (l_strv_eq(*dns_list_ptr, new_dns_list)) {
- l_strv_free(new_dns_list);
- return false;
- }
-
- l_strv_free(*dns_list_ptr);
- *dns_list_ptr = new_dns_list;
-
- if (fils_dns_mac) {
- const struct ie_fils_ip_addr_response_info *fils =
- netconfig->fils_override;
- const void *dns_ip = af == AF_INET ?
- (const void *) &fils->ipv4_dns :
- (const void *) &fils->ipv6_dns;
-
- if (!l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex, af,
- dns_ip, fils_dns_mac, 6,
- netconfig_set_neighbor_entry_cb,
- NULL, NULL))
- l_debug("l_rtnl_neighbor_set_hwaddr failed");
- }
-
- return true;
-}
-
-static void append_domain(char **domains, unsigned int *n_domains,
- size_t max, char *domain)
-{
- unsigned int i;
-
- if (*n_domains == max)
- return;
-
- for (i = 0; i < *n_domains; i++)
- if (!strcmp(domains[i], domain))
- return;
-
- domains[*n_domains] = domain;
- *n_domains += 1;
-}
-
-static void netconfig_set_domains(struct netconfig *netconfig)
-{
- char *domains[31];
- unsigned int n_domains = 0;
- char **p;
-
- memset(domains, 0, sizeof(domains));
-
- append_domain(domains, &n_domains,
- L_ARRAY_SIZE(domains) - 1, netconfig->v4_domain);
-
- for (p = netconfig->v6_domains; p && *p; p++)
- append_domain(domains, &n_domains,
- L_ARRAY_SIZE(domains) - 1, *p);
-
- resolve_set_domains(netconfig->resolve, domains);
-}
-
-static bool netconfig_domains_update(struct netconfig *netconfig, uint8_t af)
-{
- bool changed = false;
-
- if (af == AF_INET) {
- /* Allow to override the DHCP domain name with setting entry. */
- char *v4_domain = l_settings_get_string(
- netconfig->active_settings,
- "IPv4", "DomainName");
-
- if (!v4_domain && netconfig->rtm_protocol == RTPROT_DHCP) {
- const struct l_dhcp_lease *lease =
- l_dhcp_client_get_lease(netconfig->dhcp_client);
-
- if (lease)
- v4_domain = l_dhcp_lease_get_domain_name(lease);
- }
-
- if (l_streq0(v4_domain, netconfig->v4_domain))
- l_free(v4_domain);
- else {
- l_free(netconfig->v4_domain);
- netconfig->v4_domain = v4_domain;
- changed = true;
- }
- } else {
- char **v6_domains = NULL;
-
- if (netconfig->rtm_v6_protocol == RTPROT_DHCP) {
- const struct l_dhcp6_lease *lease =
- l_dhcp6_client_get_lease(
- netconfig->dhcp6_client);
-
- if (lease)
- v6_domains = l_dhcp6_lease_get_domains(lease);
- }
-
- if (l_strv_eq(netconfig->v6_domains, v6_domains))
- l_strv_free(v6_domains);
- else {
- l_strv_free(netconfig->v6_domains);
- netconfig->v6_domains = v6_domains;
- changed = true;
- }
- }
-
- return changed;
-}
-
static struct l_rtnl_address *netconfig_get_static4_address(
const struct l_settings *active_settings)
{
@@ -470,46 +188,6 @@ static struct l_rtnl_address *netconfig_get_static4_address(
return ifaddr;
}
-static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig,
- const uint8_t **out_mac)
-{
- const struct l_dhcp_lease *lease;
- char *gateway;
- const struct ie_fils_ip_addr_response_info *fils =
- netconfig->fils_override;
-
- switch (netconfig->rtm_protocol) {
- case RTPROT_STATIC:
- gateway = l_settings_get_string(netconfig->active_settings,
- "IPv4", "Gateway");
- if (!gateway)
- gateway = l_settings_get_string(
- netconfig->active_settings,
- "IPv4", "gateway");
-
- return gateway;
-
- case RTPROT_DHCP:
- if (netconfig_use_fils_gateway(netconfig, AF_INET)) {
- gateway = netconfig_ipv4_to_string(fils->ipv4_gateway);
-
- if (gateway && out_mac &&
- !l_memeqzero(fils->ipv4_gateway_mac, 6))
- *out_mac = fils->ipv4_gateway_mac;
-
- return gateway;
- }
-
- lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
- if (!lease)
- return NULL;
-
- return l_dhcp_lease_get_gateway(lease);
- }
-
- return NULL;
-}
-
static struct l_rtnl_address *netconfig_get_static6_address(
const struct l_settings *active_settings)
{
@@ -549,75 +227,9 @@ no_prefix_len:
return ret;
}
-static struct l_rtnl_route *netconfig_get_static6_gateway(
- struct netconfig *netconfig,
- char **out_str,
- const uint8_t **out_mac)
-{
- L_AUTO_FREE_VAR(char *, gateway);
- struct l_rtnl_route *ret;
- const uint8_t *mac = NULL;
-
- gateway = l_settings_get_string(netconfig->active_settings,
- "IPv6", "Gateway");
- if (!gateway && netconfig_use_fils_gateway(netconfig, AF_INET6)) {
- gateway = netconfig_ipv6_to_string(
- netconfig->fils_override->ipv6_gateway);
-
- if (!l_memeqzero(netconfig->fils_override->ipv6_gateway_mac, 6))
- mac = netconfig->fils_override->ipv6_gateway_mac;
- } else if (!gateway)
- return NULL;
-
- ret = l_rtnl_route_new_gateway(gateway);
- if (!ret) {
- l_error("netconfig: Invalid IPv6 gateway address %s is "
- "provided in network configuration file.",
- gateway);
- return ret;
- }
-
- l_rtnl_route_set_priority(ret, ROUTE_PRIORITY_OFFSET);
- l_rtnl_route_set_protocol(ret, RTPROT_STATIC);
- *out_str = l_steal_ptr(gateway);
- *out_mac = mac;
-
- return ret;
-}
-
-static struct l_rtnl_address *netconfig_get_dhcp4_address(
- struct netconfig *netconfig)
-{
- const struct l_dhcp_lease *lease =
- l_dhcp_client_get_lease(netconfig->dhcp_client);
- L_AUTO_FREE_VAR(char *, ip) = NULL;
- L_AUTO_FREE_VAR(char *, broadcast) = NULL;
- uint32_t prefix_len;
- struct l_rtnl_address *ret;
-
- if (L_WARN_ON(!lease))
- return NULL;
-
- ip = l_dhcp_lease_get_address(lease);
- broadcast = l_dhcp_lease_get_broadcast(lease);
-
- prefix_len = l_dhcp_lease_get_prefix_length(lease);
- if (!prefix_len)
- prefix_len = 24;
-
- ret = l_rtnl_address_new(ip, prefix_len);
- if (!ret)
- return ret;
-
- if (broadcast)
- l_rtnl_address_set_broadcast(ret, broadcast);
-
- l_rtnl_address_set_noprefixroute(ret, true);
- return ret;
-}
-
static void netconfig_gateway_to_arp(struct netconfig *netconfig)
{
+ struct l_dhcp_client *dhcp = NULL; /* TODO */
const struct l_dhcp_lease *lease;
_auto_(l_free) char *server_id = NULL;
_auto_(l_free) char *gw = NULL;
@@ -628,7 +240,7 @@ static void netconfig_gateway_to_arp(struct netconfig *netconfig)
if (netconfig->rtm_protocol != RTPROT_DHCP)
return;
- lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
+ lease = l_dhcp_client_get_lease(dhcp);
if (!lease)
return;
@@ -649,515 +261,11 @@ static void netconfig_gateway_to_arp(struct netconfig *netconfig)
l_debug("l_rtnl_neighbor_set_hwaddr failed");
}
-static void netconfig_ifaddr_added(struct netconfig *netconfig,
- const struct ifaddrmsg *ifa,
- uint32_t len)
-{
- L_AUTO_FREE_VAR(char *, label) = NULL;
- L_AUTO_FREE_VAR(char *, ip) = NULL;
- L_AUTO_FREE_VAR(char *, broadcast) = NULL;
-
- l_rtnl_ifaddr4_extract(ifa, len, &label, &ip, &broadcast);
- l_debug("%s: ifaddr %s/%u broadcast %s", label,
- ip, ifa->ifa_prefixlen, broadcast);
-}
-
-static void netconfig_ifaddr_deleted(struct netconfig *netconfig,
- const struct ifaddrmsg *ifa,
- uint32_t len)
-{
- L_AUTO_FREE_VAR(char *, ip);
-
- l_rtnl_ifaddr4_extract(ifa, len, NULL, &ip, NULL);
- l_debug("ifaddr %s/%u", ip, ifa->ifa_prefixlen);
-}
-
-static void netconfig_ifaddr_notify(uint16_t type, const void *data,
- uint32_t len, void *user_data)
-{
- const struct ifaddrmsg *ifa = data;
- struct netconfig *netconfig;
- uint32_t bytes;
-
- netconfig = netconfig_find(ifa->ifa_index);
- if (!netconfig)
- /* Ignore the interfaces which aren't managed by iwd. */
- return;
-
- bytes = len - NLMSG_ALIGN(sizeof(struct ifaddrmsg));
-
- switch (type) {
- case RTM_NEWADDR:
- netconfig_ifaddr_added(netconfig, ifa, bytes);
- break;
- case RTM_DELADDR:
- netconfig_ifaddr_deleted(netconfig, ifa, bytes);
- break;
- }
-}
-
-static void netconfig_ifaddr_cmd_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- if (error) {
- l_error("netconfig: ifaddr command failure. "
- "Error %d: %s", error, strerror(-error));
- return;
- }
-
- if (type != RTM_NEWADDR)
- return;
-
- netconfig_ifaddr_notify(type, data, len, user_data);
-}
-
-static void netconfig_ifaddr_ipv6_added(struct netconfig *netconfig,
- const struct ifaddrmsg *ifa,
- uint32_t len)
-{
- struct in6_addr in6;
- L_AUTO_FREE_VAR(char *, ip) = NULL;
-
- if (ifa->ifa_flags & IFA_F_TENTATIVE)
- return;
-
- l_rtnl_ifaddr6_extract(ifa, len, &ip);
-
- l_debug("ifindex %u: ifaddr %s/%u", netconfig->ifindex,
- ip, ifa->ifa_prefixlen);
-
- if (netconfig->rtm_v6_protocol != RTPROT_DHCP ||
- netconfig_use_fils_addr(netconfig, AF_INET6))
- return;
-
- inet_pton(AF_INET6, ip, &in6);
- if (!IN6_IS_ADDR_LINKLOCAL(&in6))
- return;
-
- l_dhcp6_client_set_link_local_address(netconfig->dhcp6_client, ip);
-
- if (l_dhcp6_client_start(netconfig->dhcp6_client))
- return;
-
- l_error("netconfig: Failed to start DHCPv6 client for "
- "interface %u", netconfig->ifindex);
-}
-
-static void netconfig_ifaddr_ipv6_deleted(struct netconfig *netconfig,
- const struct ifaddrmsg *ifa,
- uint32_t len)
-{
- L_AUTO_FREE_VAR(char *, ip);
-
- l_rtnl_ifaddr6_extract(ifa, len, &ip);
- l_debug("ifindex %u: ifaddr %s/%u", netconfig->ifindex,
- ip, ifa->ifa_prefixlen);
-}
-
-static void netconfig_ifaddr_ipv6_notify(uint16_t type, const void *data,
- uint32_t len, void *user_data)
-{
- const struct ifaddrmsg *ifa = data;
- struct netconfig *netconfig;
- uint32_t bytes;
-
- netconfig = netconfig_find(ifa->ifa_index);
- if (!netconfig)
- /* Ignore the interfaces which aren't managed by iwd. */
- return;
-
- bytes = len - NLMSG_ALIGN(sizeof(struct ifaddrmsg));
-
- switch (type) {
- case RTM_NEWADDR:
- netconfig_ifaddr_ipv6_added(netconfig, ifa, bytes);
- break;
- case RTM_DELADDR:
- netconfig_ifaddr_ipv6_deleted(netconfig, ifa, bytes);
- break;
- }
-}
-
-static void netconfig_ifaddr_ipv6_cmd_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- if (error) {
- l_error("netconfig: ifaddr IPv6 command failure. "
- "Error %d: %s", error, strerror(-error));
- return;
- }
-
- if (type != RTM_NEWADDR)
- return;
-
- netconfig_ifaddr_ipv6_notify(type, data, len, user_data);
-}
-
-static void netconfig_route_generic_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- if (error) {
- l_error("netconfig: Failed to add route. Error %d: %s",
- error, strerror(-error));
- return;
- }
-}
-
-static void netconfig_route_add_cmd_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- struct netconfig *netconfig = user_data;
-
- netconfig->route4_add_gateway_cmd_id = 0;
-
- if (error) {
- l_error("netconfig: Failed to add route. Error %d: %s",
- error, strerror(-error));
- return;
- }
-
- if (!netconfig->notify)
- return;
-
- netconfig->notify(NETCONFIG_EVENT_CONNECTED, netconfig->user_data);
- netconfig->notify = NULL;
-}
-
-static void netconfig_route6_add_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- struct netconfig *netconfig = user_data;
-
- netconfig->route6_add_cmd_id = 0;
-
- if (error) {
- l_error("netconfig: Failed to add route. Error %d: %s",
- error, strerror(-error));
- return;
- }
-}
-
-static bool netconfig_ipv4_subnet_route_install(struct netconfig *netconfig)
-{
- struct in_addr in_addr;
- char ip[INET_ADDRSTRLEN];
- char network[INET_ADDRSTRLEN];
- unsigned int prefix_len =
- l_rtnl_address_get_prefix_length(netconfig->v4_address);
-
- if (!l_rtnl_address_get_address(netconfig->v4_address, ip) ||
- inet_pton(AF_INET, ip, &in_addr) < 1)
- return false;
-
- in_addr.s_addr = in_addr.s_addr &
- htonl(0xFFFFFFFFLU << (32 - prefix_len));
-
- if (!inet_ntop(AF_INET, &in_addr, network, INET_ADDRSTRLEN))
- return false;
-
- if (!l_rtnl_route4_add_connected(rtnl, netconfig->ifindex,
- prefix_len, network, ip,
- netconfig->rtm_protocol,
- netconfig_route_generic_cb,
- netconfig, NULL)) {
- l_error("netconfig: Failed to add subnet route.");
- return false;
- }
-
- return true;
-}
-
-static bool netconfig_ipv4_gateway_route_install(struct netconfig *netconfig)
-{
- L_AUTO_FREE_VAR(char *, gateway) = NULL;
- const uint8_t *gateway_mac = NULL;
- struct in_addr in_addr;
- char ip[INET_ADDRSTRLEN];
-
- gateway = netconfig_ipv4_get_gateway(netconfig, &gateway_mac);
- if (!gateway) {
- l_debug("No gateway obtained from %s.",
- netconfig->rtm_protocol == RTPROT_STATIC ?
- "setting file" : "DHCPv4 lease");
-
- if (netconfig->notify) {
- netconfig->notify(NETCONFIG_EVENT_CONNECTED,
- netconfig->user_data);
- netconfig->notify = NULL;
- }
-
- return true;
- }
-
- if (!l_rtnl_address_get_address(netconfig->v4_address, ip) ||
- inet_pton(AF_INET, ip, &in_addr) < 1)
- return false;
-
- netconfig->route4_add_gateway_cmd_id =
- l_rtnl_route4_add_gateway(rtnl, netconfig->ifindex, gateway, ip,
- ROUTE_PRIORITY_OFFSET,
- netconfig->rtm_protocol,
- netconfig_route_add_cmd_cb,
- netconfig, NULL);
- if (!netconfig->route4_add_gateway_cmd_id) {
- l_error("netconfig: Failed to add route for: %s gateway.",
- gateway);
-
- return false;
- }
-
- /*
- * Attempt to use the gateway MAC address 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.
- */
- if (gateway_mac && !l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex,
- AF_INET,
- &netconfig->fils_override->ipv4_gateway,
- gateway_mac, 6,
- netconfig_set_neighbor_entry_cb, NULL,
- NULL))
- l_debug("l_rtnl_neighbor_set_hwaddr failed");
-
- return true;
-}
-
-static void netconfig_ipv4_ifaddr_add_cmd_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- struct netconfig *netconfig = user_data;
-
- netconfig->addr4_add_cmd_id = 0;
-
- if (error && error != -EEXIST) {
- l_error("netconfig: Failed to add IP address. "
- "Error %d: %s", error, strerror(-error));
- return;
- }
-
- netconfig_gateway_to_arp(netconfig);
-
- if (!netconfig_ipv4_subnet_route_install(netconfig) ||
- !netconfig_ipv4_gateway_route_install(netconfig))
- return;
-
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
-}
-
-static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- struct netconfig *netconfig = user_data;
- struct l_rtnl_route *gateway;
- const uint8_t *gateway_mac;
-
- netconfig->addr6_add_cmd_id = 0;
-
- if (error && error != -EEXIST) {
- l_error("netconfig: Failed to add IPv6 address. "
- "Error %d: %s", error, strerror(-error));
- return;
- }
-
- gateway = netconfig_get_static6_gateway(netconfig,
- &netconfig->v6_gateway_str,
- &gateway_mac);
- if (gateway) {
- netconfig->route6_add_cmd_id = l_rtnl_route_add(rtnl,
- netconfig->ifindex,
- gateway,
- netconfig_route6_add_cb,
- netconfig, NULL);
- L_WARN_ON(unlikely(!netconfig->route6_add_cmd_id));
- l_rtnl_route_free(gateway);
-
- if (gateway_mac && !l_rtnl_neighbor_set_hwaddr(rtnl,
- netconfig->ifindex, AF_INET6,
- netconfig->fils_override->ipv6_gateway,
- gateway_mac, 6,
- netconfig_set_neighbor_entry_cb, NULL,
- NULL))
- l_debug("l_rtnl_neighbor_set_hwaddr failed");
- }
-
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
-}
-
-static void netconfig_ifaddr_del_cmd_cb(int error, uint16_t type,
- const void *data, uint32_t len,
- void *user_data)
-{
- if (error == -ENODEV)
- /* The device is unplugged, we are done. */
- return;
-
- if (!error)
- /*
- * The kernel removes all of the routes associated with the
- * deleted IP on its own. There is no need to explicitly remove
- * them.
- */
- return;
-
- l_error("netconfig: Failed to delete IP address. "
- "Error %d: %s", error, strerror(-error));
-}
-
-static void netconfig_ipv4_dhcp_event_handler(struct l_dhcp_client *client,
- enum l_dhcp_client_event event,
- void *userdata)
-{
- struct netconfig *netconfig = userdata;
-
- l_debug("DHCPv4 event %d", event);
-
- switch (event) {
- case L_DHCP_CLIENT_EVENT_IP_CHANGED:
- L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ifaddr_del_cmd_cb,
- netconfig, NULL));
- /* Fall through. */
- case L_DHCP_CLIENT_EVENT_LEASE_OBTAINED:
- {
- char *gateway_str;
- struct l_rtnl_address *address;
-
- gateway_str = netconfig_ipv4_get_gateway(netconfig, NULL);
- if (l_streq0(netconfig->v4_gateway_str, gateway_str))
- l_free(gateway_str);
- else {
- l_free(netconfig->v4_gateway_str);
- netconfig->v4_gateway_str = gateway_str;
- }
-
- address = netconfig_get_dhcp4_address(netconfig);
- l_rtnl_address_free(netconfig->v4_address);
- netconfig->v4_address = address;
-
- if (!netconfig->v4_address) {
- l_error("netconfig: Failed to obtain IP addresses from "
- "DHCPv4 lease.");
- return;
- }
-
- netconfig_dns_list_update(netconfig, AF_INET);
- netconfig_domains_update(netconfig, AF_INET);
-
- L_WARN_ON(!(netconfig->addr4_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ipv4_ifaddr_add_cmd_cb,
- netconfig, NULL)));
- break;
- }
- case L_DHCP_CLIENT_EVENT_LEASE_RENEWED:
- break;
- case L_DHCP_CLIENT_EVENT_LEASE_EXPIRED:
- L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ifaddr_del_cmd_cb,
- netconfig, NULL));
- l_rtnl_address_free(netconfig->v4_address);
- netconfig->v4_address = NULL;
- l_free(l_steal_ptr(netconfig->v4_gateway_str));
-
- /* Fall through. */
- case L_DHCP_CLIENT_EVENT_NO_LEASE:
- /*
- * The requested address is no longer available, try to restart
- * the client.
- */
- if (!l_dhcp_client_start(client))
- l_error("netconfig: Failed to re-start DHCPv4 client "
- "for interface %u", netconfig->ifindex);
-
- break;
- default:
- l_error("netconfig: Received unsupported DHCPv4 event: %d",
- event);
- }
-}
-
-static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
- enum l_dhcp6_client_event event,
- void *userdata)
-{
- struct netconfig *netconfig = userdata;
-
- switch (event) {
- case L_DHCP6_CLIENT_EVENT_IP_CHANGED:
- case L_DHCP6_CLIENT_EVENT_LEASE_OBTAINED:
- case L_DHCP6_CLIENT_EVENT_LEASE_RENEWED:
- {
- const struct l_dhcp6_lease *lease =
- l_dhcp6_client_get_lease(netconfig->dhcp6_client);
- _auto_(l_free) char *addr_str =
- l_dhcp6_lease_get_address(lease);
- struct l_rtnl_address *address;
- struct l_icmp6_client *icmp6 =
- l_dhcp6_client_get_icmp6(netconfig->dhcp6_client);
- const struct l_icmp6_router *router =
- l_icmp6_client_get_router(icmp6);
- char *gateway_str = l_icmp6_router_get_address(router);
-
- if (l_streq0(netconfig->v6_gateway_str, gateway_str))
- l_free(gateway_str);
- else {
- l_free(netconfig->v6_gateway_str);
- netconfig->v6_gateway_str = gateway_str;
- }
-
- address = l_rtnl_address_new(addr_str,
- l_dhcp6_lease_get_prefix_length(lease));
- l_rtnl_address_free(netconfig->v6_address);
- netconfig->v6_address = address;
-
- netconfig_dns_list_update(netconfig, AF_INET6);
- netconfig_domains_update(netconfig, AF_INET6);
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
- break;
- }
- case L_DHCP6_CLIENT_EVENT_LEASE_EXPIRED:
- l_debug("Lease for interface %u expired", netconfig->ifindex);
- netconfig_dns_list_update(netconfig, AF_INET6);
- netconfig_domains_update(netconfig, AF_INET6);
- netconfig_set_dns(netconfig);
- netconfig_set_domains(netconfig);
- l_rtnl_address_free(netconfig->v6_address);
- netconfig->v6_address = NULL;
- l_free(l_steal_ptr(netconfig->v6_gateway_str));
-
- /* Fall through */
- case L_DHCP6_CLIENT_EVENT_NO_LEASE:
- if (!l_dhcp6_client_start(netconfig->dhcp6_client))
- l_error("netconfig: Failed to re-start DHCPv6 client "
- "for interface %u", netconfig->ifindex);
- break;
- }
-}
-
static void netconfig_remove_v4_address(struct netconfig *netconfig)
{
if (!netconfig->v4_address)
return;
- L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ifaddr_del_cmd_cb,
- netconfig, NULL));
l_rtnl_address_free(netconfig->v4_address);
netconfig->v4_address = NULL;
}
@@ -1170,178 +278,14 @@ static void netconfig_reset_v4(struct netconfig *netconfig)
l_strv_free(l_steal_ptr(netconfig->dns4_overrides));
l_strv_free(l_steal_ptr(netconfig->dns4_list));
- l_dhcp_client_stop(netconfig->dhcp_client);
netconfig->rtm_protocol = 0;
- l_acd_destroy(netconfig->acd);
- netconfig->acd = NULL;
-
l_free(l_steal_ptr(netconfig->v4_gateway_str));
l_free(l_steal_ptr(netconfig->v4_domain));
}
}
-static void netconfig_ipv4_acd_event(enum l_acd_event event, void *user_data)
-{
- struct netconfig *netconfig = user_data;
-
- switch (event) {
- case L_ACD_EVENT_AVAILABLE:
- L_WARN_ON(!(netconfig->addr4_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ipv4_ifaddr_add_cmd_cb,
- netconfig, NULL)));
- return;
- case L_ACD_EVENT_CONFLICT:
- /*
- * Conflict found, no IP was actually set so just free/unset
- * anything we set prior to starting ACD.
- */
- l_error("netconfig: statically configured address conflict!");
- l_rtnl_address_free(netconfig->v4_address);
- netconfig->v4_address = NULL;
- netconfig->rtm_protocol = 0;
- break;
- case L_ACD_EVENT_LOST:
- /*
- * Set IP but lost it some time after. Full (IPv4) reset in this
- * case.
- */
- l_error("netconfig: statically configured address was lost");
- netconfig_remove_v4_address(netconfig);
- break;
- }
-}
-
-static bool netconfig_ipv4_select_and_install(struct netconfig *netconfig)
-{
- struct netdev *netdev = netdev_find(netconfig->ifindex);
- bool set_address = (netconfig->rtm_protocol == RTPROT_STATIC);
-
- if (netconfig_use_fils_addr(netconfig, AF_INET)) {
- L_AUTO_FREE_VAR(char *, addr_str) = netconfig_ipv4_to_string(
- netconfig->fils_override->ipv4_addr);
- uint8_t prefix_len = netconfig->fils_override->ipv4_prefix_len;
-
- if (unlikely(!addr_str))
- return false;
-
- netconfig->v4_address = l_rtnl_address_new(addr_str,
- prefix_len);
- if (L_WARN_ON(!netconfig->v4_address))
- return false;
-
- l_rtnl_address_set_noprefixroute(netconfig->v4_address, true);
- set_address = true;
-
- /*
- * TODO: If netconfig->fils_override->ipv4_lifetime is set,
- * start a timeout to renew the address using FILS IP Address
- * Assignment or perhaps just start the DHCP client at that
- * time.
- */
- }
-
- if (set_address) {
- char ip[INET6_ADDRSTRLEN];
-
- if (L_WARN_ON(!netconfig->v4_address ||
- !l_rtnl_address_get_address(
- netconfig->v4_address,
- ip)))
- return false;
-
- netconfig_dns_list_update(netconfig, AF_INET);
- netconfig_domains_update(netconfig, AF_INET);
-
- netconfig->acd = l_acd_new(netconfig->ifindex);
- l_acd_set_event_handler(netconfig->acd,
- netconfig_ipv4_acd_event, netconfig,
- NULL);
- if (getenv("IWD_ACD_DEBUG"))
- l_acd_set_debug(netconfig->acd, do_debug,
- "[ACD] ", NULL);
-
- if (!l_acd_start(netconfig->acd, ip)) {
- l_error("failed to start ACD, continuing anyways");
- l_acd_destroy(netconfig->acd);
- netconfig->acd = NULL;
-
- L_WARN_ON(!(netconfig->addr4_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ipv4_ifaddr_add_cmd_cb,
- netconfig, NULL)));
- }
-
- return true;
- }
-
- l_dhcp_client_set_address(netconfig->dhcp_client, ARPHRD_ETHER,
- netdev_get_address(netdev), ETH_ALEN);
-
- if (l_dhcp_client_start(netconfig->dhcp_client))
- return true;
-
- l_error("netconfig: Failed to start DHCPv4 client for interface %u",
- netconfig->ifindex);
- return false;
-}
-
-static bool netconfig_ipv6_select_and_install(struct netconfig *netconfig)
-{
- struct netdev *netdev = netdev_find(netconfig->ifindex);
-
- if (netconfig->rtm_v6_protocol == RTPROT_UNSPEC) {
- l_debug("IPV6 configuration disabled");
- return true;
- }
-
- sysfs_write_ipv6_setting(netdev_get_name(netdev), "disable_ipv6", "0");
-
- if (netconfig_use_fils_addr(netconfig, AF_INET6)) {
- uint8_t prefix_len = netconfig->fils_override->ipv6_prefix_len;
- L_AUTO_FREE_VAR(char *, addr_str) = netconfig_ipv6_to_string(
- netconfig->fils_override->ipv6_addr);
-
- if (unlikely(!addr_str))
- return false;
-
- netconfig->v6_address = l_rtnl_address_new(addr_str,
- prefix_len);
- if (L_WARN_ON(unlikely(!netconfig->v6_address)))
- return false;
-
- l_rtnl_address_set_noprefixroute(netconfig->v6_address, true);
-
- /*
- * TODO: If netconfig->fils_override->ipv6_lifetime is set,
- * start a timeout to renew the address using FILS IP Address
- * Assignment or perhaps just start the DHCP client at that
- * time.
- */
- }
-
- if (netconfig->v6_address) {
- netconfig_dns_list_update(netconfig, AF_INET6);
-
- L_WARN_ON(!(netconfig->addr6_add_cmd_id =
- l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
- netconfig->v6_address,
- netconfig_ipv6_ifaddr_add_cmd_cb,
- netconfig, NULL)));
- return true;
- }
-
- /* DHCPv6 or RA, update MAC */
- l_dhcp6_client_set_address(netconfig->dhcp6_client, ARPHRD_ETHER,
- netdev_get_address(netdev), ETH_ALEN);
-
- return true;
-}
-
static int validate_dns_list(int family, char **dns_list)
{
unsigned int n_valid = 0;
@@ -1465,9 +409,6 @@ bool netconfig_load_settings(struct netconfig *netconfig,
else
netconfig->rtm_v6_protocol = RTPROT_DHCP;
- if (send_hostname)
- l_dhcp_client_set_hostname(netconfig->dhcp_client, hostname);
-
netconfig_free_settings(netconfig);
if (netconfig->rtm_protocol == RTPROT_STATIC)
@@ -1489,11 +430,7 @@ bool netconfig_configure(struct netconfig *netconfig,
netconfig->notify = notify;
netconfig->user_data = user_data;
- if (unlikely(!netconfig_ipv4_select_and_install(netconfig)))
- return false;
-
- if (unlikely(!netconfig_ipv6_select_and_install(netconfig)))
- return false;
+ /* TODO */
resolve_set_mdns(netconfig->resolve, netconfig->mdns);
@@ -1525,31 +462,6 @@ bool netconfig_reconfigure(struct netconfig *netconfig, bool set_arp_gw)
bool netconfig_reset(struct netconfig *netconfig)
{
- struct netdev *netdev = netdev_find(netconfig->ifindex);
-
- if (netconfig->route4_add_gateway_cmd_id) {
- l_netlink_cancel(rtnl, netconfig->route4_add_gateway_cmd_id);
- netconfig->route4_add_gateway_cmd_id = 0;
- }
-
- if (netconfig->route6_add_cmd_id) {
- l_netlink_cancel(rtnl, netconfig->route6_add_cmd_id);
- netconfig->route6_add_cmd_id = 0;
- }
-
- if (netconfig->addr4_add_cmd_id) {
- l_netlink_cancel(rtnl, netconfig->addr4_add_cmd_id);
- netconfig->addr4_add_cmd_id = 0;
- }
-
- if (netconfig->addr6_add_cmd_id) {
- l_netlink_cancel(rtnl, netconfig->addr6_add_cmd_id);
- netconfig->addr6_add_cmd_id = 0;
- }
-
- if (netconfig->rtm_protocol || netconfig->rtm_v6_protocol)
- resolve_revert(netconfig->resolve);
-
netconfig_reset_v4(netconfig);
if (netconfig->rtm_v6_protocol) {
@@ -1559,12 +471,8 @@ bool netconfig_reset(struct netconfig *netconfig)
l_strv_free(l_steal_ptr(netconfig->dns6_overrides));
l_strv_free(l_steal_ptr(netconfig->dns6_list));
- l_dhcp6_client_stop(netconfig->dhcp6_client);
netconfig->rtm_v6_protocol = 0;
- sysfs_write_ipv6_setting(netdev_get_name(netdev),
- "disable_ipv6", "1");
-
l_free(l_steal_ptr(netconfig->v6_gateway_str));
l_strv_free(l_steal_ptr(netconfig->v6_domains));
@@ -1577,12 +485,10 @@ bool netconfig_reset(struct netconfig *netconfig)
char *netconfig_get_dhcp_server_ipv4(struct netconfig *netconfig)
{
+ struct l_dhcp_client *client = NULL; /* TODO */
const struct l_dhcp_lease *lease;
- if (!netconfig->dhcp_client)
- return NULL;
-
- lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
+ lease = l_dhcp_client_get_lease(client);
if (!lease)
return NULL;
@@ -1622,28 +528,17 @@ struct netconfig *netconfig_new(uint32_t ifindex)
{
struct netdev *netdev = netdev_find(ifindex);
struct netconfig *netconfig;
- struct l_icmp6_client *icmp6;
const char *debug_level = NULL;
int dhcp_priority = L_LOG_INFO;
-
- if (!netconfig_list)
- return NULL;
+ struct l_dhcp_client *dhcp = NULL; /* TODO */
+ struct l_dhcp6_client *dhcp6 = NULL; /* TODO */
l_debug("Starting netconfig for interface: %d", ifindex);
- netconfig = netconfig_find(ifindex);
- if (netconfig)
- return netconfig;
-
netconfig = l_new(struct netconfig, 1);
netconfig->ifindex = ifindex;
netconfig->resolve = resolve_new(ifindex);
- netconfig->dhcp_client = l_dhcp_client_new(ifindex);
- l_dhcp_client_set_event_handler(netconfig->dhcp_client,
- netconfig_ipv4_dhcp_event_handler,
- netconfig, NULL);
-
debug_level = getenv("IWD_DHCP_DEBUG");
if (debug_level != NULL) {
if (!strcmp("debug", debug_level))
@@ -1658,42 +553,22 @@ struct netconfig *netconfig_new(uint32_t ifindex)
dhcp_priority = L_LOG_DEBUG;
}
- l_dhcp_client_set_debug(netconfig->dhcp_client, do_debug,
- "[DHCPv4] ", NULL, dhcp_priority);
+ l_dhcp_client_set_debug(dhcp, do_debug, "[DHCPv4] ", NULL,
+ dhcp_priority);
- netconfig->dhcp6_client = l_dhcp6_client_new(ifindex);
- l_dhcp6_client_set_event_handler(netconfig->dhcp6_client,
- netconfig_dhcp6_event_handler,
- netconfig, NULL);
- l_dhcp6_client_set_lla_randomized(netconfig->dhcp6_client, true);
- l_dhcp6_client_set_nodelay(netconfig->dhcp6_client, true);
- l_dhcp6_client_set_rtnl(netconfig->dhcp6_client, rtnl);
+ l_dhcp6_client_set_lla_randomized(dhcp6, true);
+ l_dhcp6_client_set_nodelay(dhcp6, true);
if (getenv("IWD_DHCP_DEBUG"))
- l_dhcp6_client_set_debug(netconfig->dhcp6_client, do_debug,
- "[DHCPv6] ", NULL);
-
- icmp6 = l_dhcp6_client_get_icmp6(netconfig->dhcp6_client);
- l_icmp6_client_set_rtnl(icmp6, rtnl);
- l_icmp6_client_set_route_priority(icmp6, ROUTE_PRIORITY_OFFSET);
-
- l_queue_push_tail(netconfig_list, netconfig);
-
- sysfs_write_ipv6_setting(netdev_get_name(netdev), "accept_ra", "0");
- sysfs_write_ipv6_setting(netdev_get_name(netdev), "disable_ipv6", "1");
+ l_dhcp6_client_set_debug(dhcp6, do_debug, "[DHCPv6] ", NULL);
return netconfig;
}
void netconfig_destroy(struct netconfig *netconfig)
{
- if (!netconfig_list)
- return;
-
l_debug("");
- l_queue_remove(netconfig_list, netconfig);
-
netconfig_reset(netconfig);
resolve_free(netconfig->resolve);
netconfig_free(netconfig);
@@ -1710,43 +585,6 @@ bool netconfig_enabled(void)
static int netconfig_init(void)
{
- uint32_t r;
-
- if (netconfig_list)
- return -EALREADY;
-
- rtnl = iwd_get_rtnl();
-
- r = l_netlink_register(rtnl, RTNLGRP_IPV4_IFADDR,
- netconfig_ifaddr_notify, NULL, NULL);
- if (!r) {
- l_error("netconfig: Failed to register for RTNL link address"
- " notifications.");
- goto error;
- }
-
- r = l_rtnl_ifaddr4_dump(rtnl, netconfig_ifaddr_cmd_cb, NULL, NULL);
- if (!r) {
- l_error("netconfig: Failed to get addresses from RTNL link.");
- goto error;
- }
-
- r = l_netlink_register(rtnl, RTNLGRP_IPV6_IFADDR,
- netconfig_ifaddr_ipv6_notify, NULL, NULL);
- if (!r) {
- l_error("netconfig: Failed to register for RTNL link IPv6 "
- "address notifications.");
- goto error;
- }
-
- r = l_rtnl_ifaddr6_dump(rtnl, netconfig_ifaddr_ipv6_cmd_cb, NULL,
- NULL);
- if (!r) {
- l_error("netconfig: Failed to get IPv6 addresses from RTNL"
- " link.");
- goto error;
- }
-
if (!l_settings_get_uint(iwd_get_config(), "Network",
"RoutePriorityOffset",
&ROUTE_PRIORITY_OFFSET))
@@ -1757,24 +595,11 @@ static int netconfig_init(void)
&ipv6_enabled))
ipv6_enabled = false;
- netconfig_list = l_queue_new();
-
return 0;
-
-error:
- rtnl = NULL;
-
- return r;
}
static void netconfig_exit(void)
{
- if (!netconfig_list)
- return;
-
- rtnl = NULL;
-
- l_queue_destroy(netconfig_list, netconfig_free);
}
IWD_MODULE(netconfig, netconfig_init, netconfig_exit)