summaryrefslogtreecommitdiff
path: root/src/core/NetworkManagerUtils.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-08-06 15:17:05 +0200
committerThomas Haller <thaller@redhat.com>2021-09-30 09:56:19 +0200
commitd64b4a30d21fa98f6a7d11c28ac21a8f9d8ee299 (patch)
treeddb782113363dea1fa8e0a38e2570c269b98ff24 /src/core/NetworkManagerUtils.c
parentf20431bf89fd00c88659275f69419601cf98cb6b (diff)
downloadNetworkManager-next.tar.gz
core: rework IP configuration in NetworkManager using layer 3 configurationnext
Completely rework IP configuration in the daemon. Use NML3Cfg as layer 3 manager for the IP configuration of an interface. Use NML3ConfigData as pieces of configuration that the various components collect and configure. NMDevice is managing most of the IP configuration at a higher level, that is, it starts DHCP and other IP methods. Rework the state handling there. This is a huge rework of how NetworkManager daemon handles IP configuration. Some fallout is to be expected. It appears the patch deletes many lines of code. That is not accurate, because you also have to count the files `src/core/nm-l3*`, which were unused previously. Co-authored-by: Beniamino Galvani <bgalvani@redhat.com>
Diffstat (limited to 'src/core/NetworkManagerUtils.c')
-rw-r--r--src/core/NetworkManagerUtils.c189
1 files changed, 147 insertions, 42 deletions
diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c
index 0da8e0a949..49d011b3d0 100644
--- a/src/core/NetworkManagerUtils.c
+++ b/src/core/NetworkManagerUtils.c
@@ -1298,7 +1298,7 @@ void
nm_utils_ip_route_attribute_to_platform(int addr_family,
NMIPRoute * s_route,
NMPlatformIPRoute *r,
- guint32 route_table)
+ gint64 route_table)
{
GVariant * variant;
guint32 table;
@@ -1310,6 +1310,8 @@ nm_utils_ip_route_attribute_to_platform(int addr_family,
nm_assert(s_route);
nm_assert_addr_family(addr_family);
nm_assert(r);
+ nm_assert(route_table >= -1);
+ nm_assert(route_table <= (gint64) G_MAXUINT32);
#define GET_ATTR(name, dst, variant_type, type, dflt) \
G_STMT_START \
@@ -1336,10 +1338,16 @@ nm_utils_ip_route_attribute_to_platform(int addr_family,
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_TABLE, table, UINT32, uint32, 0);
- if (!table && r->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL))
+ if (table != 0)
+ r->table_coerced = nm_platform_route_table_coerce(table);
+ else if (r->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL))
r->table_coerced = nm_platform_route_table_coerce(RT_TABLE_LOCAL);
+ else if (route_table == 0)
+ r->table_coerced = nm_platform_route_table_coerce(RT_TABLE_MAIN);
+ else if (route_table > 0)
+ r->table_coerced = nm_platform_route_table_coerce(route_table);
else
- r->table_coerced = nm_platform_route_table_coerce(table ?: (route_table ?: RT_TABLE_MAIN));
+ r->table_any = TRUE;
if (NM_IS_IPv4(addr_family)) {
guint8 scope;
@@ -1395,39 +1403,20 @@ nm_utils_ip_route_attribute_to_platform(int addr_family,
/*****************************************************************************/
-static int
-_addresses_sort_cmp_4(gconstpointer a, gconstpointer b, gpointer user_data)
-{
- return nm_platform_ip4_address_pretty_sort_cmp(
- NMP_OBJECT_CAST_IP4_ADDRESS(*((const NMPObject **) a)),
- NMP_OBJECT_CAST_IP4_ADDRESS(*((const NMPObject **) b)));
-}
-
-static int
-_addresses_sort_cmp_6(gconstpointer a, gconstpointer b, gpointer user_data)
-{
- return nm_platform_ip6_address_pretty_sort_cmp(
- NMP_OBJECT_CAST_IP6_ADDRESS(*((const NMPObject **) a)),
- NMP_OBJECT_CAST_IP6_ADDRESS(*((const NMPObject **) b)),
- (((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT(user_data))
- == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR));
-}
-
void
nm_utils_ip_addresses_to_dbus(int addr_family,
const NMDedupMultiHeadEntry *head_entry,
const NMPObject * best_default_route,
- NMSettingIP6ConfigPrivacy ipv6_privacy,
GVariant ** out_address_data,
GVariant ** out_addresses)
{
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
- GVariantBuilder builder_data;
- GVariantBuilder builder_legacy;
- char addr_str[NM_UTILS_INET_ADDRSTRLEN];
- gs_free const NMPObject **addresses = NULL;
- guint naddr;
- guint i;
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
+ GVariantBuilder builder_data;
+ GVariantBuilder builder_legacy;
+ char addr_str[NM_UTILS_INET_ADDRSTRLEN];
+ NMDedupMultiIter iter;
+ const NMPObject *obj;
+ guint i;
nm_assert_addr_family(addr_family);
@@ -1443,19 +1432,11 @@ nm_utils_ip_addresses_to_dbus(int addr_family,
if (!head_entry)
goto out;
- addresses =
- (const NMPObject **) nm_dedup_multi_objs_to_array_head(head_entry, NULL, NULL, &naddr);
-
- nm_assert(addresses && naddr);
-
- g_qsort_with_data(addresses,
- naddr,
- sizeof(addresses[0]),
- IS_IPv4 ? _addresses_sort_cmp_4 : _addresses_sort_cmp_6,
- GINT_TO_POINTER(ipv6_privacy));
-
- for (i = 0; i < naddr; i++) {
- const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(addresses[i]);
+ i = 0;
+ nm_dedup_multi_iter_init(&iter, head_entry);
+ while (
+ nm_platform_dedup_multi_iter_next_obj(&iter, &obj, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4))) {
+ const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(obj);
if (out_address_data) {
GVariantBuilder addr_builder;
@@ -1527,6 +1508,8 @@ nm_utils_ip_addresses_to_dbus(int addr_family,
: &in6addr_any));
}
}
+
+ i++;
}
out:
@@ -1654,6 +1637,128 @@ nm_utils_ip_routes_to_dbus(int addr_family,
/*****************************************************************************/
+NMSetting *
+nm_utils_platform_capture_ip_setting(NMPlatform *platform,
+ int addr_family,
+ int ifindex,
+ gboolean maybe_ipv6_disabled)
+{
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
+ gs_unref_object NMSettingIPConfig *s_ip = NULL;
+ NMPLookup lookup;
+ NMDedupMultiIter iter;
+ const NMPObject * obj;
+ const char * method = NULL;
+ char sbuf[NM_UTILS_INET_ADDRSTRLEN];
+ const NMPlatformIPXRoute * best_default_route = NULL;
+
+ s_ip =
+ NM_SETTING_IP_CONFIG(IS_IPv4 ? nm_setting_ip4_config_new() : nm_setting_ip6_config_new());
+
+ if (ifindex <= 0 || !nm_platform_link_get(platform, ifindex)) {
+ g_object_set(s_ip,
+ NM_SETTING_IP_CONFIG_METHOD,
+ IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED
+ : NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
+ NULL);
+ return NM_SETTING(g_steal_pointer(&s_ip));
+ }
+
+ nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex);
+ nm_platform_iter_obj_for_each (&iter, platform, &lookup, &obj) {
+ const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(obj);
+ nm_auto_unref_ip_address NMIPAddress *s_addr = NULL;
+
+ if (!IS_IPv4) {
+ /* Ignore link-local address. */
+ if (IN6_IS_ADDR_LINKLOCAL(address->ax.address_ptr)) {
+ if (!method)
+ method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
+ continue;
+ }
+ }
+
+ /* Detect dynamic address */
+ if (address->ax.lifetime != NM_PLATFORM_LIFETIME_PERMANENT) {
+ method =
+ IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_AUTO;
+ continue;
+ }
+
+ /* Static address found. */
+ if (IS_IPv4) {
+ if (!method)
+ method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
+ } else {
+ if (NM_IN_STRSET(method, NULL, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
+ method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
+ }
+
+ s_addr =
+ nm_ip_address_new_binary(addr_family, address->ax.address_ptr, address->ax.plen, NULL);
+
+ if (IS_IPv4) {
+ if (address->a4.label[0]) {
+ nm_ip_address_set_attribute(s_addr,
+ NM_IP_ADDRESS_ATTRIBUTE_LABEL,
+ g_variant_new_string(address->a4.label));
+ }
+ }
+
+ nm_setting_ip_config_add_address(s_ip, s_addr);
+ }
+
+ if (!method) {
+ /* Use 'disabled/ignore' if the method wasn't previously set */
+ if (IS_IPv4)
+ method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
+ else
+ method = maybe_ipv6_disabled ? NM_SETTING_IP6_CONFIG_METHOD_DISABLED
+ : NM_SETTING_IP6_CONFIG_METHOD_IGNORE;
+ }
+ g_object_set(s_ip, NM_SETTING_IP_CONFIG_METHOD, method, NULL);
+
+ nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), ifindex);
+ nm_platform_iter_obj_for_each (&iter, platform, &lookup, &obj) {
+ const NMPlatformIPXRoute *route = NMP_OBJECT_CAST_IPX_ROUTE(obj);
+ nm_auto_unref_ip_route NMIPRoute *s_route = NULL;
+
+ if (!IS_IPv4) {
+ /* Ignore link-local route. */
+ if (IN6_IS_ADDR_LINKLOCAL(route->rx.network_ptr))
+ continue;
+ }
+
+ if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)) {
+ if (!best_default_route)
+ best_default_route = route;
+ continue;
+ }
+
+ s_route = nm_ip_route_new_binary(addr_family,
+ route->rx.network_ptr,
+ route->rx.plen,
+ nm_platform_ip_route_get_gateway(addr_family, &route->rx),
+ route->rx.metric,
+ NULL);
+ nm_setting_ip_config_add_route(s_ip, s_route);
+ }
+
+ if (best_default_route && nm_setting_ip_config_get_num_addresses(s_ip) > 0) {
+ g_object_set(s_ip,
+ NM_SETTING_IP_CONFIG_GATEWAY,
+ nm_utils_inet_ntop(
+ addr_family,
+ nm_platform_ip_route_get_gateway(addr_family, &best_default_route->rx),
+ sbuf),
+ NULL);
+ }
+
+ return NM_SETTING(g_steal_pointer(&s_ip));
+}
+
+/*****************************************************************************/
+
/* Singleton NMPlatform subclass instance and cached class object */
NM_DEFINE_SINGLETON_INSTANCE(NMPlatform);