From c7586e63885e1de9b80b9dc94feceea0f3fe4bf2 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 27 Apr 2020 20:28:04 +0200 Subject: [PATCH 1/2] vpn: clear host part of IPv6 routes received from VPN plugin Kernel would reject adding a route with a destination host part not all zero. NetworkManager generally coerces such routes and there are assertions in place to ensure that. We forgot to ensure that for certain IPv6 routes from VPN plugins. This can cause an assertion failure and wrong behavior. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/425 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/482 (cherry picked from commit b437bb4a6e8f4b1ca8678e8727b02b21d4cb7562) --- src/vpn/nm-vpn-connection.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c index 35bf4afb3e..6be8d9bac6 100644 --- a/src/vpn/nm-vpn-connection.c +++ b/src/vpn/nm-vpn-connection.c @@ -1790,6 +1790,8 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) route.metric = route_metric; route.rt_source = NM_IP_CONFIG_SOURCE_VPN; + nm_utils_ip6_address_clear_host_address (&route.network, &route.network, route.plen); + /* Ignore host routes to the VPN gateway since NM adds one itself. * Since NM knows more about the routing situation than the VPN * server, we want to use the NM created route instead of whatever From 61e65e42dce617eb292dcc0203135b4a5e4ec9cb Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 27 Apr 2020 20:29:13 +0200 Subject: [PATCH 2/2] vpn: cleanup loop in nm_vpn_connection_ip6_config_get() I find it simpler to follow the pattern of checking conditions and "erroring out", by going to the next entry. The entire loop already behaves like that. (cherry picked from commit f89b841b37b2642fb0aaccf233dc5eb4de50ccf6) --- src/vpn/nm-vpn-connection.c | 38 +++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c index 6be8d9bac6..6d995dc489 100644 --- a/src/vpn/nm-vpn-connection.c +++ b/src/vpn/nm-vpn-connection.c @@ -1595,13 +1595,18 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) route.plen = plen; route.network = nm_utils_ip4_address_clear_host_address (route.network, plen); - /* Ignore host routes to the VPN gateway since NM adds one itself - * below. Since NM knows more about the routing situation than - * the VPN server, we want to use the NM created route instead of - * whatever the server provides. - */ - if (!(priv->ip4_external_gw && route.network == priv->ip4_external_gw && route.plen == 32)) - nm_ip4_config_add_route (config, &route, NULL); + if ( priv->ip4_external_gw + && route.network == priv->ip4_external_gw + && route.plen == 32) { + /* Ignore host routes to the VPN gateway since NM adds one itself + * below. Since NM knows more about the routing situation than + * the VPN server, we want to use the NM created route instead of + * whatever the server provides. + */ + break; + } + + nm_ip4_config_add_route (config, &route, NULL); break; default: break; @@ -1792,13 +1797,18 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) nm_utils_ip6_address_clear_host_address (&route.network, &route.network, route.plen); - /* Ignore host routes to the VPN gateway since NM adds one itself. - * Since NM knows more about the routing situation than the VPN - * server, we want to use the NM created route instead of whatever - * the server provides. - */ - if (!(priv->ip6_external_gw && IN6_ARE_ADDR_EQUAL (&route.network, priv->ip6_external_gw) && route.plen == 128)) - nm_ip6_config_add_route (config, &route, NULL); + if ( priv->ip6_external_gw + && IN6_ARE_ADDR_EQUAL (&route.network, priv->ip6_external_gw) + && route.plen == 128) { + /* Ignore host routes to the VPN gateway since NM adds one itself. + * Since NM knows more about the routing situation than the VPN + * server, we want to use the NM created route instead of whatever + * the server provides. + */ + goto next; + } + + nm_ip6_config_add_route (config, &route, NULL); next: g_variant_unref (dest);