All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 8/8] netconfig: Add IPv6 configuration properties on Station
@ 2021-09-25  1:11 Andrew Zaborowski
  0 siblings, 0 replies; only message in thread
From: Andrew Zaborowski @ 2021-09-25  1:11 UTC (permalink / raw)
  To: iwd

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

Add the net.connman.iwd.IPv6Configuration D-Bus interface on the station
objects to expose current netconfig values.
---
 src/dbus.h      |   1 +
 src/netconfig.c | 127 +++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 121 insertions(+), 7 deletions(-)

diff --git a/src/dbus.h b/src/dbus.h
index a7248554..a345f7ac 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -44,6 +44,7 @@
 #define IWD_AP_DIAGNOSTIC_INTERFACE "net.connman.iwd.AccessPointDiagnostic"
 #define IWD_STATION_DEBUG_INTERFACE "net.connman.iwd.StationDebug"
 #define IWD_IPV4_CONFIG_INTERFACE "net.connman.iwd.IPv4Configuration"
+#define IWD_IPV6_CONFIG_INTERFACE "net.connman.iwd.IPv6Configuration"
 
 #define IWD_BASE_PATH "/net/connman/iwd"
 #define IWD_AGENT_MANAGER_PATH IWD_BASE_PATH
diff --git a/src/netconfig.c b/src/netconfig.c
index b7c0b432..223ebba7 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -75,6 +75,7 @@ struct netconfig {
 	netconfig_notify_func_t notify;
 	void *user_data;
 	bool v4_configured;
+	bool v6_configured;
 
 	struct resolve *resolve;
 
@@ -89,7 +90,7 @@ struct netconfig {
 	struct interface_data {
 		uint8_t af;
 		struct netconfig *netconfig;
-	} v4_data;
+	} v4_data, v6_data;
 };
 
 static struct l_netlink *rtnl;
@@ -271,11 +272,13 @@ static void netconfig_property_changed(struct netconfig *netconfig, uint8_t af,
 	if (!netconfig->dbus_path)
 		return;
 
-	if (!netconfig->v4_configured)
+	if (!(af == AF_INET ? netconfig->v4_configured :
+				netconfig->v6_configured))
 		return;
 
 	l_dbus_property_changed(dbus_get_bus(), netconfig->dbus_path,
-				IWD_IPV4_CONFIG_INTERFACE, property_name);
+				(af == AF_INET) ? IWD_IPV4_CONFIG_INTERFACE :
+				IWD_IPV6_CONFIG_INTERFACE, property_name);
 }
 
 static void netconfig_set_neighbor_entry_cb(int error,
@@ -716,7 +719,8 @@ static void netconfig_connected_v4(struct netconfig *netconfig)
 		l_info("Unable to add %s at %s",
 			IWD_IPV4_CONFIG_INTERFACE, netconfig->dbus_path);
 
-	if (!l_dbus_object_add_interface(dbus, netconfig->dbus_path,
+	if (!netconfig->v6_configured &&
+			!l_dbus_object_add_interface(dbus, netconfig->dbus_path,
 						L_DBUS_INTERFACE_PROPERTIES,
 						netconfig))
 		/* Properties may already exist on the object, not an error */
@@ -740,6 +744,47 @@ static void netconfig_disconnected_v4(struct netconfig *netconfig)
 			IWD_IPV4_CONFIG_INTERFACE, netconfig->dbus_path);
 }
 
+static void netconfig_connected_v6(struct netconfig *netconfig)
+{
+	struct l_dbus *dbus = dbus_get_bus();
+
+	netconfig->v6_configured = true;
+
+	if (!netconfig->dbus_path)
+		return;
+
+	if (unlikely(!l_dbus_object_add_interface(dbus,
+						netconfig->dbus_path,
+						IWD_IPV6_CONFIG_INTERFACE,
+						&netconfig->v6_data)))
+		l_info("Unable to add %s at %s",
+			IWD_IPV6_CONFIG_INTERFACE, netconfig->dbus_path);
+
+	if (!netconfig->v4_configured &&
+			!l_dbus_object_add_interface(dbus, netconfig->dbus_path,
+						L_DBUS_INTERFACE_PROPERTIES,
+						netconfig))
+		/* Properties may already exist on the object, not an error */
+		l_debug("Unable to add %s at %s",
+			L_DBUS_INTERFACE_PROPERTIES, netconfig->dbus_path);
+}
+
+static void netconfig_disconnected_v6(struct netconfig *netconfig)
+{
+	struct l_dbus *dbus = dbus_get_bus();
+
+	netconfig->v6_configured = false;
+
+	if (!netconfig->dbus_path)
+		return;
+
+	if (unlikely(!l_dbus_object_remove_interface(dbus,
+						netconfig->dbus_path,
+						IWD_IPV6_CONFIG_INTERFACE)))
+		l_info("l_dbus_object_remove_interface failed for %s at %s",
+			IWD_IPV6_CONFIG_INTERFACE, netconfig->dbus_path);
+}
+
 static void netconfig_ifaddr_ipv6_added(struct netconfig *netconfig,
 					const struct ifaddrmsg *ifa,
 					uint32_t len)
@@ -865,6 +910,8 @@ static void netconfig_route6_add_cb(int error, uint16_t type,
 						error, strerror(-error));
 		return;
 	}
+
+	netconfig_connected_v6(netconfig);
 }
 
 static bool netconfig_ipv4_routes_install(struct netconfig *netconfig)
@@ -1003,6 +1050,9 @@ static void netconfig_ipv6_ifaddr_add_cmd_cb(int error, uint16_t type,
 
 	netconfig_set_dns(netconfig);
 	netconfig_set_domains(netconfig);
+
+	if (!netconfig->route6_add_cmd_id)
+		netconfig_connected_v6(netconfig);
 }
 
 static void netconfig_ifaddr_del_cmd_cb(int error, uint16_t type,
@@ -1175,10 +1225,23 @@ static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
 		else {
 			l_free(netconfig->v6_gateway_str);
 			netconfig->v6_gateway_str = gateway_str;
+			netconfig_property_changed(netconfig, AF_INET6,
+							"Gateway");
 		}
 
 		address = l_rtnl_address_new(addr_str,
 					l_dhcp6_lease_get_prefix_length(lease));
+
+		if (!netconfig_address_cmp_prefix_len(netconfig->v6_address,
+							address))
+			netconfig_property_changed(netconfig, AF_INET6,
+							"Netmask");
+
+		if (netconfig_address_cmp_address(netconfig->v6_address,
+							address))
+			netconfig_property_changed(netconfig, AF_INET6,
+							"Address");
+
 		l_rtnl_address_free(netconfig->v6_address);
 		netconfig->v6_address = address;
 
@@ -1186,6 +1249,10 @@ static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
 		netconfig_domains_update(netconfig, AF_INET6);
 		netconfig_set_dns(netconfig);
 		netconfig_set_domains(netconfig);
+
+		if (!netconfig->v6_configured)
+			netconfig_connected_v6(netconfig);
+
 		break;
 	}
 	case L_DHCP6_CLIENT_EVENT_LEASE_EXPIRED:
@@ -1198,6 +1265,9 @@ static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
 		netconfig->v6_address = NULL;
 		l_free(l_steal_ptr(netconfig->v6_gateway_str));
 
+		if (netconfig->v6_configured)
+			netconfig_disconnected_v6(netconfig);
+
 		/* Fall through */
 	case L_DHCP6_CLIENT_EVENT_NO_LEASE:
 		if (!l_dhcp6_client_start(netconfig->dhcp6_client))
@@ -1595,6 +1665,9 @@ bool netconfig_reset(struct netconfig *netconfig)
 	if (netconfig->v4_configured)
 		netconfig_disconnected_v4(netconfig);
 
+	if (netconfig->v6_configured)
+		netconfig_disconnected_v6(netconfig);
+
 	if (netconfig->route4_add_gateway_cmd_id) {
 		l_netlink_cancel(rtnl, netconfig->route4_add_gateway_cmd_id);
 		netconfig->route4_add_gateway_cmd_id = 0;
@@ -1747,6 +1820,8 @@ struct netconfig *netconfig_new(uint32_t ifindex, const char *dbus_path)
 	 */
 	netconfig->v4_data.af = AF_INET;
 	netconfig->v4_data.netconfig = netconfig;
+	netconfig->v6_data.af = AF_INET6;
+	netconfig->v6_data.netconfig = netconfig;
 
 	return netconfig;
 }
@@ -1877,7 +1952,28 @@ static bool netconfig_property_get_v4_domains(struct l_dbus *dbus,
 	return true;
 }
 
-static void netconfig_setup_interface(struct l_dbus_interface *interface)
+static bool netconfig_property_get_v6_domains(struct l_dbus *dbus,
+					struct l_dbus_message *message,
+					struct l_dbus_message_builder *builder,
+					void *user_data)
+{
+	const struct interface_data *data = user_data;
+	char **i;
+
+	if (!data->netconfig->v6_domains)
+		return false;
+
+	l_dbus_message_builder_enter_array(builder, "s");
+
+	for (i = data->netconfig->v6_domains; *i; i++)
+		l_dbus_message_builder_append_basic(builder, 's', *i);
+
+	l_dbus_message_builder_leave_array(builder);
+	return true;
+}
+
+static void netconfig_setup_interface(struct l_dbus_interface *interface,
+					uint8_t af)
 {
 	l_dbus_interface_property(interface, "Method", 0, "s",
 					netconfig_property_get_method, NULL);
@@ -1890,10 +1986,22 @@ static void netconfig_setup_interface(struct l_dbus_interface *interface)
 	l_dbus_interface_property(interface, "DomainNameServers", 0, "as",
 					netconfig_property_get_dnses, NULL);
 	l_dbus_interface_property(interface, "DomainNames", 0, "as",
-					netconfig_property_get_v4_domains,
+					af == AF_INET ?
+					netconfig_property_get_v4_domains :
+					netconfig_property_get_v6_domains,
 					NULL);
 }
 
+static void netconfig_setup_v4_interface(struct l_dbus_interface *interface)
+{
+	netconfig_setup_interface(interface, AF_INET);
+}
+
+static void netconfig_setup_v6_interface(struct l_dbus_interface *interface)
+{
+	netconfig_setup_interface(interface, AF_INET6);
+}
+
 static int netconfig_init(void)
 {
 	uint32_t r;
@@ -1947,7 +2055,11 @@ static int netconfig_init(void)
 
 	L_WARN_ON(unlikely(!l_dbus_register_interface(dbus_get_bus(),
 						IWD_IPV4_CONFIG_INTERFACE,
-						netconfig_setup_interface,
+						netconfig_setup_v4_interface,
+						NULL, false)));
+	L_WARN_ON(unlikely(!l_dbus_register_interface(dbus_get_bus(),
+						IWD_IPV6_CONFIG_INTERFACE,
+						netconfig_setup_v6_interface,
 						NULL, false)));
 	return 0;
 
@@ -1967,6 +2079,7 @@ static void netconfig_exit(void)
 	l_queue_destroy(netconfig_list, netconfig_free);
 
 	l_dbus_unregister_interface(dbus_get_bus(), IWD_IPV4_CONFIG_INTERFACE);
+	l_dbus_unregister_interface(dbus_get_bus(), IWD_IPV6_CONFIG_INTERFACE);
 }
 
 IWD_MODULE(netconfig, netconfig_init, netconfig_exit)
-- 
2.30.2

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-09-25  1:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-25  1:11 [PATCH 8/8] netconfig: Add IPv6 configuration properties on Station Andrew Zaborowski

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.