All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/8] netconfig: Decouple from station state
@ 2019-09-30 16:35 Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 2/8] station: netconfig devices based on " Tim Kourt
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 4756 bytes --]

Instead of relying on station state changed signal, netconfig
introduces three new API calls to configure, re-configure and
reset the network configurations. The owner of netconfig object
is responsible for initiating the re-configuration of the device
depending on its state.
---
 src/netconfig.c | 79 ++++++++++++++++++++++++++++++---------------------------
 src/netconfig.h |  6 +++++
 2 files changed, 48 insertions(+), 37 deletions(-)

diff --git a/src/netconfig.c b/src/netconfig.c
index 2074689f..88d2588e 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -48,6 +48,8 @@ struct netconfig {
 	struct l_dhcp_client *dhcp_client;
 	struct l_queue *ifaddr_list;
 	uint8_t rtm_protocol;
+
+	const struct l_settings *active_settings;
 };
 
 struct netconfig_ifaddr {
@@ -589,16 +591,10 @@ static void netconfig_ipv4_dhcp_event_handler(struct l_dhcp_client *client,
 	}
 }
 
-static bool netconfig_ipv4_dhcp_create(struct netconfig *netconfig,
-							struct station *station)
+static bool netconfig_ipv4_dhcp_create(struct netconfig *netconfig)
 {
 	netconfig->dhcp_client = l_dhcp_client_new(netconfig->ifindex);
 
-	l_dhcp_client_set_address(netconfig->dhcp_client, ARPHRD_ETHER,
-					netdev_get_address(
-						station_get_netdev(station)),
-					ETH_ALEN);
-
 	l_dhcp_client_set_event_handler(netconfig->dhcp_client,
 					netconfig_ipv4_dhcp_event_handler,
 					netconfig, NULL);
@@ -654,41 +650,57 @@ static void netconfig_ipv4_select_and_uninstall(struct netconfig *netconfig)
 	l_dhcp_client_stop(netconfig->dhcp_client);
 }
 
-static void netconfig_station_state_changed(enum station_state state,
-								void *userdata)
+bool netconfig_configure(struct netconfig *netconfig,
+				const struct l_settings *active_settings,
+				const uint8_t *mac_address)
 {
-	struct netconfig *netconfig = userdata;
+	netconfig->active_settings = active_settings;
 
-	l_debug("");
+	l_dhcp_client_set_address(netconfig->dhcp_client, ARPHRD_ETHER,
+							mac_address, ETH_ALEN);
 
-	switch (state) {
-	case STATION_STATE_CONNECTED:
-		netconfig_ipv4_select_and_install(netconfig);
+	netconfig_ipv4_select_and_install(netconfig);
 
-		/* TODO: IPv6 addressing */
+	/* TODO: IPv6 addressing */
 
-		break;
-	case STATION_STATE_DISCONNECTED:
-		netconfig_ipv4_select_and_uninstall(netconfig);
+	return true;
+}
 
-		/* TODO: IPv6 addressing */
+bool netconfig_reconfigure(struct netconfig *netconfig)
+{
+	if (netconfig->rtm_protocol == RTPROT_DHCP) {
+		/*
+		 *
+		 * TODO l_dhcp_client to try to request a
+		 * previously used address.
+		 *
+		 * return;
+		 */
+	}
 
-		resolve_remove(netconfig->ifindex);
+	netconfig_ipv4_select_and_install(netconfig);
 
-		break;
-	case STATION_STATE_ROAMING:
-		break;
-	default:
-		return;
-	}
+	/* TODO: IPv6 addressing */
 
-	netconfig->station_state = state;
+	return true;
+}
+
+bool netconfig_reset(struct netconfig *netconfig)
+{
+	netconfig_ipv4_select_and_uninstall(netconfig);
+
+	/* TODO: IPv6 addressing */
+
+	resolve_remove(netconfig->ifindex);
+
+	netconfig->rtm_protocol = 0;
+
+	return true;
 }
 
 struct netconfig *netconfig_new(uint32_t ifindex)
 {
 	struct netconfig *netconfig;
-	struct station *station;
 
 	if (!netconfig_list)
 		return NULL;
@@ -699,18 +711,11 @@ struct netconfig *netconfig_new(uint32_t ifindex)
 	if (netconfig)
 		return netconfig;
 
-	station = station_find(ifindex);
-	if (!station)
-		return NULL;
-
 	netconfig = l_new(struct netconfig, 1);
 	netconfig->ifindex = ifindex;
 	netconfig->ifaddr_list = l_queue_new();
 
-	netconfig_ipv4_dhcp_create(netconfig, station);
-
-	station_add_state_watch(station, netconfig_station_state_changed,
-							netconfig, NULL);
+	netconfig_ipv4_dhcp_create(netconfig);
 
 	l_queue_push_tail(netconfig_list, netconfig);
 
@@ -726,7 +731,7 @@ void netconfig_destroy(struct netconfig *netconfig)
 
 	l_queue_remove(netconfig_list, netconfig);
 
-	if (netconfig->station_state != STATION_STATE_DISCONNECTED) {
+	if (netconfig->rtm_protocol) {
 		netconfig_ipv4_select_and_uninstall(netconfig);
 
 		/* TODO Uninstall IPv6 addresses. */
diff --git a/src/netconfig.h b/src/netconfig.h
index fd344830..cacd384a 100644
--- a/src/netconfig.h
+++ b/src/netconfig.h
@@ -22,5 +22,11 @@
 
 struct netconfig;
 
+bool netconfig_configure(struct netconfig *netconfig,
+				const struct l_settings *active_settings,
+				const uint8_t *mac_address);
+bool netconfig_reconfigure(struct netconfig *netconfig);
+bool netconfig_reset(struct netconfig *netconfig);
+
 struct netconfig *netconfig_new(uint32_t ifindex);
 void netconfig_destroy(struct netconfig *netconfig);
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/8] station: netconfig devices based on station state
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
@ 2019-09-30 16:35 ` Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 3/8] netconfig: Switch to internal active network settings Tim Kourt
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1758 bytes --]

---
 src/station.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/src/station.c b/src/station.c
index 02c5260b..0666287b 100644
--- a/src/station.c
+++ b/src/station.c
@@ -1158,8 +1158,23 @@ static void station_enter_state(struct station *station,
 				IWD_NETWORK_INTERFACE, "Connected");
 		/* fall through */
 	case STATION_STATE_DISCONNECTED:
+		periodic_scan_stop(station);
+
+		break;
 	case STATION_STATE_CONNECTED:
 		periodic_scan_stop(station);
+
+		if (station->state == STATION_STATE_ROAMING) {
+			netconfig_reconfigure(station->netconfig);
+
+			break;
+		}
+
+		netconfig_configure(station->netconfig,
+					network_get_settings(
+						station->connected_network),
+					netdev_get_address(
+							station->netdev));
 		break;
 	case STATION_STATE_DISCONNECTING:
 	case STATION_STATE_ROAMING:
@@ -1247,6 +1262,8 @@ static void station_disassociated(struct station *station)
 {
 	l_debug("%u", netdev_get_ifindex(station->netdev));
 
+	netconfig_reset(station->netconfig);
+
 	station_reset_connection_state(station);
 
 	station_enter_state(station, STATION_STATE_DISCONNECTED);
@@ -2327,6 +2344,8 @@ static void station_disconnect_onconnect(struct station *station,
 		return;
 	}
 
+	netconfig_reset(station->netconfig);
+
 	station_reset_connection_state(station);
 
 	station_enter_state(station, STATION_STATE_DISCONNECTING);
@@ -2562,6 +2581,8 @@ int station_disconnect(struct station *station)
 					station_disconnect_cb, station) < 0)
 		return -EIO;
 
+	netconfig_reset(station->netconfig);
+
 	/*
 	 * If the disconnect somehow fails we won't know if we're still
 	 * connected so we may as well indicate now that we're no longer
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 3/8] netconfig: Switch to internal active network settings
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 2/8] station: netconfig devices based on " Tim Kourt
@ 2019-09-30 16:35 ` Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 4/8] netconfig: Subscribe for IPv6 address changes Tim Kourt
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 3762 bytes --]

As part of the de-coupling from station object, switch all of
the network settings inquiries to use active_settings. active_settings
are set with netconfig_configure by the owner of netconfig object
and removed with netconfig_reset once network disconnects.
---
 src/netconfig.c | 46 +++++++++++-----------------------------------
 1 file changed, 11 insertions(+), 35 deletions(-)

diff --git a/src/netconfig.c b/src/netconfig.c
index 88d2588e..4e294512 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -113,29 +113,11 @@ static struct netconfig *netconfig_find(uint32_t ifindex)
 	return NULL;
 }
 
-static struct l_settings *netconfig_get_connected_network_settings(
-						struct netconfig *netconfig)
-{
-	struct station *station;
-	const struct network *network;
-
-	station = station_find(netconfig->ifindex);
-	if (!station)
-		return NULL;
-
-	network = station_get_connected_network(station);
-	if (!network)
-		return NULL;
-
-	return network_get_settings(network);
-}
-
 static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr(
 						struct netconfig *netconfig,
 						uint8_t proto)
 {
 	const struct l_dhcp_lease *lease;
-	const struct l_settings *settings;
 	struct netconfig_ifaddr *ifaddr;
 	struct in_addr in_addr;
 	char *netmask;
@@ -143,18 +125,17 @@ static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr(
 
 	switch (proto) {
 	case RTPROT_STATIC:
-		settings = netconfig_get_connected_network_settings(netconfig);
-		if (!settings)
-			return NULL;
 
-		ip = l_settings_get_string(settings, "IPv4", "ip");
+		ip = l_settings_get_string(netconfig->active_settings, "IPv4",
+									"ip");
 		if (!ip)
 			return NULL;
 
 		ifaddr = l_new(struct netconfig_ifaddr, 1);
 		ifaddr->ip = ip;
 
-		netmask = l_settings_get_string(settings, "IPv4", "netmask");
+		netmask = l_settings_get_string(netconfig->active_settings,
+							"IPv4", "netmask");
 		if (netmask && inet_pton(AF_INET, netmask, &in_addr) > 0)
 			ifaddr->prefix_len = __builtin_popcountl(
 						L_BE32_TO_CPU(in_addr.s_addr));
@@ -163,8 +144,9 @@ static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr(
 
 		l_free(netmask);
 
-		ifaddr->broadcast = l_settings_get_string(settings, "IPv4",
-								"broadcast");
+		ifaddr->broadcast =
+			l_settings_get_string(netconfig->active_settings,
+							"IPv4", "broadcast");
 		ifaddr->family = AF_INET;
 
 		return ifaddr;
@@ -203,15 +185,12 @@ static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr(
 static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig)
 {
 	const struct l_dhcp_lease *lease;
-	const struct l_settings *settings;
 
 	switch (netconfig->rtm_protocol) {
 	case RTPROT_STATIC:
-		settings = netconfig_get_connected_network_settings(netconfig);
-		if (!settings)
-			return NULL;
 
-		return l_settings_get_string(settings, "IPv4", "gateway");
+		return l_settings_get_string(netconfig->active_settings,
+							"IPv4", "gateway");
 
 	case RTPROT_DHCP:
 		lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
@@ -227,15 +206,12 @@ static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig)
 static char **netconfig_ipv4_get_dns(struct netconfig *netconfig, uint8_t proto)
 {
 	const struct l_dhcp_lease *lease;
-	const struct l_settings *settings;
 
 	switch (proto) {
 	case RTPROT_STATIC:
-		settings = netconfig_get_connected_network_settings(netconfig);
-		if (!settings)
-			return NULL;
 
-		return l_settings_get_string_list(settings, "IPv4", "dns", ' ');
+		return l_settings_get_string_list(netconfig->active_settings,
+							"IPv4", "dns", ' ');
 
 	case RTPROT_DHCP:
 		lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 4/8] netconfig: Subscribe for IPv6 address changes
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 2/8] station: netconfig devices based on " Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 3/8] netconfig: Switch to internal active network settings Tim Kourt
@ 2019-09-30 16:35 ` Tim Kourt
  2019-09-30 20:13   ` Denis Kenzior
  2019-09-30 16:35 ` [PATCH v2 5/8] netconfig: Request all known IPv6 addresses Tim Kourt
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2725 bytes --]

The IPv6 addresses changes are maintained in ifaddr_list.
---
 src/netconfig.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/src/netconfig.c b/src/netconfig.c
index 4e294512..140de63a 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -335,6 +335,72 @@ static void netconfig_ifaddr_cmd_cb(int error, uint16_t type,
 	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 netconfig_ifaddr *ifaddr;
+
+	ifaddr = l_new(struct netconfig_ifaddr, 1);
+	ifaddr->family = ifa->ifa_family;
+	ifaddr->prefix_len = ifa->ifa_prefixlen;
+
+	rtnl_ifaddr_ipv6_extract(ifa, len, &ifaddr->ip);
+
+	l_debug("ifindex %u: ifaddr %s/%u", netconfig->ifindex, ifaddr->ip,
+							ifaddr->prefix_len);
+
+	l_queue_push_tail(netconfig->ifaddr_list, ifaddr);
+}
+
+static void netconfig_ifaddr_ipv6_deleted(struct netconfig *netconfig,
+						const struct ifaddrmsg *ifa,
+						uint32_t len)
+{
+	struct netconfig_ifaddr *ifaddr;
+	char *ip;
+
+	rtnl_ifaddr_ipv6_extract(ifa, len, &ip);
+
+	ifaddr = netconfig_ifaddr_find(netconfig, ifa->ifa_family,
+							ifa->ifa_prefixlen, ip);
+
+	l_free(ip);
+
+	if (!ifaddr)
+		return;
+
+	l_debug("ifaddr %s/%u", ifaddr->ip, ifaddr->prefix_len);
+
+	l_queue_remove(netconfig->ifaddr_list, ifaddr);
+
+	netconfig_ifaddr_destroy(ifaddr);
+}
+
+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_route_cmd_cb(int error, uint16_t type,
 						const void *data, uint32_t len,
 						void *user_data)
@@ -757,6 +823,14 @@ static int netconfig_init(void)
 		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;
+	}
+
 	if (!l_settings_get_uint(iwd_get_config(), "General",
 							"route_priority_offset",
 							&ROUTE_PRIORITY_OFFSET))
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 5/8] netconfig: Request all known IPv6 addresses
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
                   ` (2 preceding siblings ...)
  2019-09-30 16:35 ` [PATCH v2 4/8] netconfig: Subscribe for IPv6 address changes Tim Kourt
@ 2019-09-30 16:35 ` Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 6/8] netconfig: Add IPv6 static address installation/removal Tim Kourt
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1267 bytes --]

---
 src/netconfig.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/src/netconfig.c b/src/netconfig.c
index 140de63a..6f97eed5 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -401,6 +401,22 @@ static void netconfig_ifaddr_ipv6_notify(uint16_t type, const void *data,
 	}
 }
 
+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_cmd_cb(int error, uint16_t type,
 						const void *data, uint32_t len,
 						void *user_data)
@@ -831,6 +847,14 @@ static int netconfig_init(void)
 		goto error;
 	}
 
+	r = rtnl_ifaddr_ipv6_get(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(), "General",
 							"route_priority_offset",
 							&ROUTE_PRIORITY_OFFSET))
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 6/8] netconfig: Add IPv6 static address installation/removal
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
                   ` (3 preceding siblings ...)
  2019-09-30 16:35 ` [PATCH v2 5/8] netconfig: Request all known IPv6 addresses Tim Kourt
@ 2019-09-30 16:35 ` Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 7/8] netconfig: Install IPv6 default route Tim Kourt
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 6757 bytes --]

The placeholders for DHCPv6 are placed along the way and marked
as TODO items.
---
 src/netconfig.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 152 insertions(+), 9 deletions(-)

diff --git a/src/netconfig.c b/src/netconfig.c
index 6f97eed5..14aac28f 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -48,6 +48,7 @@ struct netconfig {
 	struct l_dhcp_client *dhcp_client;
 	struct l_queue *ifaddr_list;
 	uint8_t rtm_protocol;
+	uint8_t rtm_v6_protocol;
 
 	const struct l_settings *active_settings;
 };
@@ -224,6 +225,59 @@ static char **netconfig_ipv4_get_dns(struct netconfig *netconfig, uint8_t proto)
 	return NULL;
 }
 
+static struct netconfig_ifaddr *netconfig_ipv6_get_ifaddr(
+						struct netconfig *netconfig,
+						uint8_t proto)
+{
+	struct netconfig_ifaddr *ifaddr;
+	char *ip;
+	char *p;
+
+	switch (proto) {
+	case RTPROT_STATIC:
+		if (!netconfig->active_settings)
+			return NULL;
+
+		ip = l_settings_get_string(netconfig->active_settings, "IPv6",
+									"ip");
+		if (!ip)
+			return NULL;
+
+		ifaddr = l_new(struct netconfig_ifaddr, 1);
+		ifaddr->ip = ip;
+
+		p = strrchr(ifaddr->ip, '/');
+		if (!p)
+			goto no_prefix_len;
+
+		if (*++p == '\0')
+			goto no_prefix_len;
+
+		ifaddr->prefix_len = strtoul(p, NULL, 10);
+
+		p = strrchr(ifaddr->ip, '/');
+		*p = '\0';
+
+		if (!unlikely(errno == ERANGE || !ifaddr->prefix_len ||
+					ifaddr->prefix_len > 128))
+			goto proceed;
+
+no_prefix_len:
+		ifaddr->prefix_len = 128;
+proceed:
+		ifaddr->family = AF_INET6;
+
+		return ifaddr;
+
+	case RTPROT_DHCP:
+		/* TODO */
+
+		return NULL;
+	}
+
+	return NULL;
+}
+
 static struct netconfig_ifaddr *netconfig_ifaddr_find(
 					const struct netconfig *netconfig,
 					uint8_t family, uint8_t prefix_len,
@@ -523,6 +577,19 @@ done:
 	netconfig_ifaddr_destroy(ifaddr);
 }
 
+static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
+						const void *data, uint32_t len,
+						void *user_data)
+{
+	if (error && error != -EEXIST) {
+		l_error("netconfig: Failed to add IPv6 address. "
+				"Error %d: %s", error, strerror(-error));
+		return;
+	}
+
+	/* TODO Install routes and DNS */
+}
+
 static void netconfig_install_address(struct netconfig *netconfig,
 						struct netconfig_ifaddr *ifaddr)
 {
@@ -542,6 +609,16 @@ static void netconfig_install_address(struct netconfig *netconfig,
 		l_error("netconfig: Failed to set IP %s/%u.", ifaddr->ip,
 							ifaddr->prefix_len);
 		break;
+	case AF_INET6:
+		if (rtnl_ifaddr_ipv6_add(rtnl, netconfig->ifindex,
+					ifaddr->prefix_len, ifaddr->ip,
+					netconfig_ipv6_ifaddr_add_cmd_cb,
+					netconfig, NULL))
+			return;
+
+		l_error("netconfig: Failed to set IPv6 address %s/%u.",
+					ifaddr->ip, ifaddr->prefix_len);
+		break;
 	default:
 		l_error("netconfig: Unsupported address family: %u",
 								ifaddr->family);
@@ -588,6 +665,16 @@ static void netconfig_uninstall_address(struct netconfig *netconfig,
 		l_error("netconfig: Failed to delete IP %s/%u.",
 						ifaddr->ip, ifaddr->prefix_len);
 		break;
+	case AF_INET6:
+		if (rtnl_ifaddr_ipv6_delete(rtnl, netconfig->ifindex,
+					ifaddr->prefix_len, ifaddr->ip,
+					netconfig_ifaddr_del_cmd_cb, netconfig,
+					NULL))
+			return;
+
+		l_error("netconfig: Failed to delete IPv6 address %s/%u.",
+						ifaddr->ip, ifaddr->prefix_len);
+		break;
 	default:
 		l_error("netconfig: Unsupported address family: %u",
 								ifaddr->family);
@@ -708,6 +795,51 @@ static void netconfig_ipv4_select_and_uninstall(struct netconfig *netconfig)
 	l_dhcp_client_stop(netconfig->dhcp_client);
 }
 
+static void netconfig_ipv6_select_and_install(struct netconfig *netconfig)
+{
+	struct netconfig_ifaddr *ifaddr;
+
+	ifaddr = netconfig_ipv6_get_ifaddr(netconfig, RTPROT_STATIC);
+	if (ifaddr) {
+		netconfig->rtm_v6_protocol = RTPROT_STATIC;
+		netconfig_install_address(netconfig, ifaddr);
+		netconfig_ifaddr_destroy(ifaddr);
+
+		return;
+	}
+
+	/*
+	 * 	TODO
+	 *
+	 *      netconfig->rtm_v6_protocol = RTPROT_DHCP;
+	 *
+	 *      netconfig_ipv6_dhcp_set_mac_address(netconfig);
+	 *
+	 *	if (l_dhcp_v6_client_start(netconfig->l_dhcp_v6_client))
+	 *		return;
+	 *
+	 * 	l_error("netconfig: Failed to start DHCPv6 client for "
+	 *			"interface %u", netconfig->ifindex);
+	 */
+}
+
+static void netconfig_ipv6_select_and_uninstall(struct netconfig *netconfig)
+{
+	struct netconfig_ifaddr *ifaddr;
+
+	ifaddr = netconfig_ipv6_get_ifaddr(netconfig,
+						netconfig->rtm_v6_protocol);
+	if (ifaddr) {
+		netconfig_uninstall_address(netconfig, ifaddr);
+		netconfig_ifaddr_destroy(ifaddr);
+	}
+
+	/*
+	 * TODO
+	 * l_dhcp_v6_client_start(netconfig->l_dhcp_v6_client);
+	 */
+}
+
 bool netconfig_configure(struct netconfig *netconfig,
 				const struct l_settings *active_settings,
 				const uint8_t *mac_address)
@@ -719,7 +851,7 @@ bool netconfig_configure(struct netconfig *netconfig,
 
 	netconfig_ipv4_select_and_install(netconfig);
 
-	/* TODO: IPv6 addressing */
+	netconfig_ipv6_select_and_install(netconfig);
 
 	return true;
 }
@@ -732,13 +864,23 @@ bool netconfig_reconfigure(struct netconfig *netconfig)
 		 * TODO l_dhcp_client to try to request a
 		 * previously used address.
 		 *
-		 * return;
+		 * goto ipv6;
 		 */
 	}
 
 	netconfig_ipv4_select_and_install(netconfig);
 
-	/* TODO: IPv6 addressing */
+	if (netconfig->rtm_v6_protocol == RTPROT_DHCP) {
+		/*
+		 *
+		 * TODO l_dhcp_v6_client to try to request a
+		 * previously used address.
+		 *
+		 * return
+		 */
+	}
+
+	netconfig_ipv6_select_and_install(netconfig);
 
 	return true;
 }
@@ -746,13 +888,13 @@ bool netconfig_reconfigure(struct netconfig *netconfig)
 bool netconfig_reset(struct netconfig *netconfig)
 {
 	netconfig_ipv4_select_and_uninstall(netconfig);
+	netconfig->rtm_protocol = 0;
 
-	/* TODO: IPv6 addressing */
+	netconfig_ipv6_select_and_uninstall(netconfig);
+	netconfig->rtm_v6_protocol = 0;
 
 	resolve_remove(netconfig->ifindex);
 
-	netconfig->rtm_protocol = 0;
-
 	return true;
 }
 
@@ -789,13 +931,14 @@ void netconfig_destroy(struct netconfig *netconfig)
 
 	l_queue_remove(netconfig_list, netconfig);
 
-	if (netconfig->rtm_protocol) {
+	if (netconfig->rtm_protocol)
 		netconfig_ipv4_select_and_uninstall(netconfig);
 
-		/* TODO Uninstall IPv6 addresses. */
+	if (netconfig->rtm_v6_protocol)
+		netconfig_ipv6_select_and_uninstall(netconfig);
 
+	if (netconfig->rtm_protocol || netconfig->rtm_v6_protocol)
 		resolve_remove(netconfig->ifindex);
-	}
 
 	netconfig_free(netconfig);
 }
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 7/8] netconfig: Install IPv6 default route
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
                   ` (4 preceding siblings ...)
  2019-09-30 16:35 ` [PATCH v2 6/8] netconfig: Add IPv6 static address installation/removal Tim Kourt
@ 2019-09-30 16:35 ` Tim Kourt
  2019-09-30 16:35 ` [PATCH v2 8/8] netconfig: Install IPv6 DNS Tim Kourt
  2019-09-30 20:12 ` [PATCH v2 1/8] netconfig: Decouple from station state Denis Kenzior
  7 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 2248 bytes --]

---
 src/netconfig.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 55 insertions(+), 1 deletion(-)

diff --git a/src/netconfig.c b/src/netconfig.c
index 14aac28f..6651b2cd 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -278,6 +278,25 @@ proceed:
 	return NULL;
 }
 
+static char *netconfig_ipv6_get_gateway(struct netconfig *netconfig)
+{
+	switch (netconfig->rtm_v6_protocol) {
+	case RTPROT_STATIC:
+		if (!netconfig->active_settings)
+			return NULL;
+
+		return l_settings_get_string(netconfig->active_settings, "IPv6",
+								"gateway");
+
+	case RTPROT_DHCP:
+		/* TODO */
+
+		return NULL;
+	}
+
+	return NULL;
+}
+
 static struct netconfig_ifaddr *netconfig_ifaddr_find(
 					const struct netconfig *netconfig,
 					uint8_t family, uint8_t prefix_len,
@@ -577,17 +596,52 @@ done:
 	netconfig_ifaddr_destroy(ifaddr);
 }
 
+static bool netconfig_ipv6_routes_install(struct netconfig *netconfig)
+{
+	L_AUTO_FREE_VAR(char *, gateway) = NULL;
+
+	gateway = netconfig_ipv6_get_gateway(netconfig);
+	if (!gateway) {
+		l_error("netconfig: Failed to obtain gateway from %s.",
+				netconfig->rtm_v6_protocol == RTPROT_STATIC ?
+				"settings file" : "DHCPv6 lease");
+
+		return false;
+	}
+
+	if (!rtnl_route_ipv6_add_gateway(rtnl, netconfig->ifindex, gateway,
+						ROUTE_PRIORITY_OFFSET,
+						netconfig->rtm_v6_protocol,
+						netconfig_route_cmd_cb,
+						NULL, NULL)) {
+		l_error("netconfig: Failed to add route for: %s gateway.",
+								gateway);
+
+		return false;
+	}
+
+	return true;
+}
+
 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;
+
 	if (error && error != -EEXIST) {
 		l_error("netconfig: Failed to add IPv6 address. "
 				"Error %d: %s", error, strerror(-error));
 		return;
 	}
 
-	/* TODO Install routes and DNS */
+	if (!netconfig_ipv6_routes_install(netconfig)) {
+		l_error("netconfig: Failed to install IPv6 routes.");
+
+		return;
+	}
+
+	/* TODO Install DNS */
 }
 
 static void netconfig_install_address(struct netconfig *netconfig,
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 8/8] netconfig: Install IPv6 DNS
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
                   ` (5 preceding siblings ...)
  2019-09-30 16:35 ` [PATCH v2 7/8] netconfig: Install IPv6 default route Tim Kourt
@ 2019-09-30 16:35 ` Tim Kourt
  2019-09-30 20:12 ` [PATCH v2 1/8] netconfig: Decouple from station state Denis Kenzior
  7 siblings, 0 replies; 10+ messages in thread
From: Tim Kourt @ 2019-09-30 16:35 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 1711 bytes --]

---
 src/netconfig.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/netconfig.c b/src/netconfig.c
index 6651b2cd..cb072462 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -297,6 +297,25 @@ static char *netconfig_ipv6_get_gateway(struct netconfig *netconfig)
 	return NULL;
 }
 
+static char **netconfig_ipv6_get_dns(struct netconfig *netconfig, uint8_t proto)
+{
+	switch (proto) {
+	case RTPROT_STATIC:
+		if (!netconfig->active_settings)
+			return NULL;
+
+		return l_settings_get_string_list(netconfig->active_settings,
+							"IPv6", "dns", ' ');
+
+	case RTPROT_DHCP:
+		/* TODO */
+
+		return NULL;
+	}
+
+	return NULL;
+}
+
 static struct netconfig_ifaddr *netconfig_ifaddr_find(
 					const struct netconfig *netconfig,
 					uint8_t family, uint8_t prefix_len,
@@ -628,6 +647,7 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
 						void *user_data)
 {
 	struct netconfig *netconfig = user_data;
+	char **dns;
 
 	if (error && error != -EEXIST) {
 		l_error("netconfig: Failed to add IPv6 address. "
@@ -641,7 +661,16 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
 		return;
 	}
 
-	/* TODO Install DNS */
+	dns = netconfig_ipv6_get_dns(netconfig, netconfig->rtm_v6_protocol);
+	if (!dns) {
+		l_error("netconfig: Failed to obtain DNS addresses from %s.",
+				netconfig->rtm_v6_protocol == RTPROT_STATIC ?
+				"setting file" : "DHCPv6 lease");
+		return;
+	}
+
+	resolve_add_dns(netconfig->ifindex, AF_INET6, dns);
+	l_strv_free(dns);
 }
 
 static void netconfig_install_address(struct netconfig *netconfig,
-- 
2.13.6

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/8] netconfig: Decouple from station state
  2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
                   ` (6 preceding siblings ...)
  2019-09-30 16:35 ` [PATCH v2 8/8] netconfig: Install IPv6 DNS Tim Kourt
@ 2019-09-30 20:12 ` Denis Kenzior
  7 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2019-09-30 20:12 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 577 bytes --]

Hi Tim,

On 9/30/19 11:35 AM, Tim Kourt wrote:
> Instead of relying on station state changed signal, netconfig
> introduces three new API calls to configure, re-configure and
> reset the network configurations. The owner of netconfig object
> is responsible for initiating the re-configuration of the device
> depending on its state.
> ---
>   src/netconfig.c | 79 ++++++++++++++++++++++++++++++---------------------------
>   src/netconfig.h |  6 +++++
>   2 files changed, 48 insertions(+), 37 deletions(-)
> 

Patches 1-3 applied, thanks.

Regards,
-Denis

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 4/8] netconfig: Subscribe for IPv6 address changes
  2019-09-30 16:35 ` [PATCH v2 4/8] netconfig: Subscribe for IPv6 address changes Tim Kourt
@ 2019-09-30 20:13   ` Denis Kenzior
  0 siblings, 0 replies; 10+ messages in thread
From: Denis Kenzior @ 2019-09-30 20:13 UTC (permalink / raw)
  To: iwd

[-- Attachment #1: Type: text/plain, Size: 948 bytes --]

Hi Tim,

On 9/30/19 11:35 AM, Tim Kourt wrote:
> The IPv6 addresses changes are maintained in ifaddr_list.
> ---
>   src/netconfig.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   1 file changed, 74 insertions(+)
> 

<snip>

> +static void netconfig_ifaddr_ipv6_deleted(struct netconfig *netconfig,
> +						const struct ifaddrmsg *ifa,
> +						uint32_t len)
> +{
> +	struct netconfig_ifaddr *ifaddr;
> +	char *ip;
> +
> +	rtnl_ifaddr_ipv6_extract(ifa, len, &ip);
> +
> +	ifaddr = netconfig_ifaddr_find(netconfig, ifa->ifa_family,
> +							ifa->ifa_prefixlen, ip);
> +
> +	l_free(ip);
> +
> +	if (!ifaddr)
> +		return;

Can we use l_queue_remove_if instead here to avoid walking the list twice?

> +
> +	l_debug("ifaddr %s/%u", ifaddr->ip, ifaddr->prefix_len);
> +
> +	l_queue_remove(netconfig->ifaddr_list, ifaddr);
> +
> +	netconfig_ifaddr_destroy(ifaddr);
> +}
> +

Regards,
-Denis

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2019-09-30 20:13 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-30 16:35 [PATCH v2 1/8] netconfig: Decouple from station state Tim Kourt
2019-09-30 16:35 ` [PATCH v2 2/8] station: netconfig devices based on " Tim Kourt
2019-09-30 16:35 ` [PATCH v2 3/8] netconfig: Switch to internal active network settings Tim Kourt
2019-09-30 16:35 ` [PATCH v2 4/8] netconfig: Subscribe for IPv6 address changes Tim Kourt
2019-09-30 20:13   ` Denis Kenzior
2019-09-30 16:35 ` [PATCH v2 5/8] netconfig: Request all known IPv6 addresses Tim Kourt
2019-09-30 16:35 ` [PATCH v2 6/8] netconfig: Add IPv6 static address installation/removal Tim Kourt
2019-09-30 16:35 ` [PATCH v2 7/8] netconfig: Install IPv6 default route Tim Kourt
2019-09-30 16:35 ` [PATCH v2 8/8] netconfig: Install IPv6 DNS Tim Kourt
2019-09-30 20:12 ` [PATCH v2 1/8] netconfig: Decouple from station state Denis Kenzior

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.