From 18501d7b684fe5e56fcb81798660e66de7bcae10 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 27 May 2016 12:42:06 +0200 Subject: [PATCH] vpn-connection: add @fallback_device argument to nm_vpn_connection_get_ip_iface() and nm_vpn_connection_get_ip_ifindex(). For VPN types that have no own IP interface, we often want instead lookup the IP interface from the parent device. --- src/nm-default-route-manager.c | 16 ++----- src/nm-policy.c | 2 +- src/vpn-manager/nm-vpn-connection.c | 68 +++++++++++++++++++++++------ src/vpn-manager/nm-vpn-connection.h | 4 +- 4 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index a637c6cb88..5d6e5ae016 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -727,16 +727,8 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, if (device) ip_ifindex = nm_device_get_ip_ifindex (device); - else { - ip_ifindex = nm_vpn_connection_get_ip_ifindex (vpn); - - if (ip_ifindex <= 0) { - NMDevice *parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - - if (parent) - ip_ifindex = nm_device_get_ip_ifindex (parent); - } - } + else + ip_ifindex = nm_vpn_connection_get_ip_ifindex (vpn, TRUE); entries = vtable->get_entries (priv); entry = _entry_find_by_source (entries, source, &entry_idx); @@ -818,7 +810,7 @@ _ipx_update_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, } } } - if (nm_vpn_connection_get_ip_ifindex (vpn) > 0) + if (nm_vpn_connection_get_ip_ifindex (vpn, FALSE) > 0) synced = TRUE; else { /* a VPN connection without tunnel device cannot have a non-synced, missing default route. @@ -1149,7 +1141,7 @@ _ipx_get_best_config (const VTableIP *vtable, if (out_ac) *out_ac = NM_ACTIVE_CONNECTION (vpn); if (out_ip_iface) - *out_ip_iface = nm_vpn_connection_get_ip_iface (vpn); + *out_ip_iface = nm_vpn_connection_get_ip_iface (vpn, FALSE); } else { NMDevice *device = entry->source.device; NMActRequest *req; diff --git a/src/nm-policy.c b/src/nm-policy.c index 0d39723344..de6bc5d13b 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1441,7 +1441,7 @@ vpn_connection_activated (NMPolicy *self, NMVpnConnection *vpn) nm_dns_manager_begin_updates (priv->dns_manager, __func__); - ip_iface = nm_vpn_connection_get_ip_iface (vpn); + ip_iface = nm_vpn_connection_get_ip_iface (vpn, FALSE); /* Add the VPN connection's IP configs from DNS */ diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 663bd1b8c4..b2aa8f6bc6 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1340,7 +1340,6 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) const char *str; GVariant *v; gboolean b; - int ifindex; g_return_if_fail (dict && g_variant_is_of_type (dict, G_VARIANT_TYPE_VARDICT)); @@ -1368,13 +1367,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) priv->has_ip6 = FALSE; } - if (priv->ip_ifindex > 0) { - ifindex = priv->ip_ifindex; - } else { - NMDevice *parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self)); - ifindex = nm_device_get_ip_ifindex (parent_dev); - } - config = nm_ip4_config_new (ifindex); + config = nm_ip4_config_new (nm_vpn_connection_get_ip_ifindex (self, TRUE)); nm_ip4_config_set_dns_priority (config, NM_DNS_PRIORITY_DEFAULT_VPN); memset (&address, 0, sizeof (address)); @@ -2158,20 +2151,67 @@ nm_vpn_connection_get_ip6_config (NMVpnConnection *self) return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip6_config; } -const char * -nm_vpn_connection_get_ip_iface (NMVpnConnection *self) +static int +_get_ip_iface_for_device (NMVpnConnection *self, const char **out_iface) { + NMDevice *parent_dev; + int ifindex; + const char *iface; + + nm_assert (NM_IS_VPN_CONNECTION (self)); + + /* the ifindex and the ifname in this case should come together. + * They either must be both set, or none. */ + + parent_dev = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self)); + if (!parent_dev) + goto none; + ifindex = nm_device_get_ip_ifindex (parent_dev); + if (ifindex <= 0) + goto none; + iface = nm_device_get_ip_iface (parent_dev); + if (!iface) + goto none; + + NM_SET_OUT (out_iface, iface); + return ifindex; +none: + NM_SET_OUT (out_iface, NULL); + return 0; +} + +const char * +nm_vpn_connection_get_ip_iface (NMVpnConnection *self, gboolean fallback_device) +{ + NMVpnConnectionPrivate *priv; + const char *iface; + g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL); - return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip_iface; + priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + + if (priv->ip_iface || !fallback_device) + return priv->ip_iface; + + _get_ip_iface_for_device (self, &iface); + return iface; } int -nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self) +nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self, gboolean fallback_device) { - g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), -1); + NMVpnConnectionPrivate *priv; - return NM_VPN_CONNECTION_GET_PRIVATE (self)->ip_ifindex; + g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), 0); + + priv = NM_VPN_CONNECTION_GET_PRIVATE (self); + + if (priv->ip_ifindex > 0) + return priv->ip_ifindex; + if (!fallback_device) + return 0; + + return _get_ip_iface_for_device (self, NULL); } guint32 diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index 19b0eb3feb..6837432926 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -91,8 +91,8 @@ void nm_vpn_connection_disconnect (NMVpnConnection *self, NMIP4Config * nm_vpn_connection_get_ip4_config (NMVpnConnection *self); NMIP6Config * nm_vpn_connection_get_ip6_config (NMVpnConnection *self); -const char * nm_vpn_connection_get_ip_iface (NMVpnConnection *self); -int nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self); +const char * nm_vpn_connection_get_ip_iface (NMVpnConnection *self, gboolean fallback_device); +int nm_vpn_connection_get_ip_ifindex (NMVpnConnection *self, gboolean fallback_device); guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVpnConnection *self); struct in6_addr * nm_vpn_connection_get_ip6_internal_gateway (NMVpnConnection *self);