[PATCH v4 4/7] src: Fixes to add Proxy Feature



src: Fixes in nm-device.c and nm-vpn-connection.c to update PacRunner
at the right place and moment. When a device goes up PacRunner is
configured with the Device IPxConfigs and Proxy Config. When it goes
down the same configuration is removed from PacRunner.

ifcfg-rh: Fixed to read and write proxy settings to the ifcfg network
scripts.
---
 src/Makefile.am                        |  11 ++
 src/devices/nm-device.c                |  73 +++++++++++++-
 src/devices/nm-device.h                |   3 +-
 src/nm-dispatcher.c                    |  78 +++++++++++++--
 src/nm-dispatcher.h                    |   2 +
 src/nm-logging.c                       |   3 +-
 src/nm-logging.h                       |   1 +
 src/nm-types.h                         |   2 +
 src/settings/nm-settings.c             |   1 +
 src/settings/plugins/ifcfg-rh/reader.c | 177 ++++++++++++++++++++++++++++++++-
 src/settings/plugins/ifcfg-rh/writer.c | 145 +++++++++++++++++++++++++++
 src/vpn-manager/nm-vpn-connection.c    |  43 ++++++++
 src/vpn-manager/nm-vpn-connection.h    |   2 +
 13 files changed, 527 insertions(+), 14 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index 41c3169..8ad0404 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -447,6 +447,8 @@ libNetworkManager_la_SOURCES = \
        nm-exported-object.h \
        nm-firewall-manager.c \
        nm-firewall-manager.h \
+       nm-proxy-config.c \
+       nm-proxy-config.h \
        nm-ip4-config.c \
        nm-ip4-config.h \
        nm-ip6-config.c \
@@ -461,6 +463,8 @@ libNetworkManager_la_SOURCES = \
        nm-manager.h \
        nm-multi-index.c \
        nm-multi-index.h \
+       nm-pacrunner-manager.c \
+       nm-pacrunner-manager.h \
        nm-policy.c \
        nm-policy.h \
        nm-rfkill-manager.c \
@@ -560,6 +564,11 @@ libnm_iface_helper_la_SOURCES = \
        platform/wifi/wifi-utils.c \
        platform/wifi/wifi-utils.h \
        \
+       nm-pacrunner-manager.c \
+       nm-pacrunner-manager.h \
+       \
+       rdisc/nm-fake-rdisc.c \
+       rdisc/nm-fake-rdisc.h \
        rdisc/nm-lndp-rdisc.c \
        rdisc/nm-lndp-rdisc.h \
        rdisc/nm-rdisc.c \
@@ -570,6 +579,8 @@ libnm_iface_helper_la_SOURCES = \
        \
        nm-exported-object.c \
        nm-exported-object.h \
+       nm-proxy-config.c \
+       nm-proxy-config.h \
        nm-ip4-config.c \
        nm-ip4-config.h \
        nm-ip6-config.c \
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 177080d..c37f8ef 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -45,8 +45,10 @@
 #include "nm-lndp-rdisc.h"
 #include "nm-dhcp-manager.h"
 #include "nm-activation-request.h"
+#include "nm-proxy-config.h"
 #include "nm-ip4-config.h"
 #include "nm-ip6-config.h"
+#include "nm-pacrunner-manager.h"
 #include "nm-dnsmasq-manager.h"
 #include "nm-dhcp4-config.h"
 #include "nm-dhcp6-config.h"
@@ -301,6 +303,10 @@ typedef struct _NMDevicePrivate {
        guint32         dhcp_timeout;
        char *          dhcp_anycast_address;
 
+       /* Proxy Configuration */
+       NMProxyConfig * proxy_config;
+       NMPacRunnerManager * pacrunner_manager;
+
        /* IP4 configuration info */
        NMIP4Config *   ip4_config;     /* Combined config from VPN, settings, and device */
        IpState         ip4_state;
@@ -409,6 +415,8 @@ typedef struct _NMDevicePrivate {
        guint check_delete_unrealized_id;
 } NMDevicePrivate;
 
+static void nm_device_set_proxy_config (NMDevice *self, GHashTable *options);
+
 static gboolean nm_device_set_ip4_config (NMDevice *self,
                                           NMIP4Config *config,
                                           guint32 default_route_metric,
@@ -4888,6 +4896,8 @@ dhcp4_state_changed (NMDhcpClient *client,
                        break;
                }
 
+               nm_device_set_proxy_config (self, options);
+
                nm_dhcp4_config_set_options (priv->dhcp4.config, options);
                _notify (self, PROP_DHCP4_CONFIG);
                priv->dhcp4.num_tries_left = DHCP_NUM_TRIES_MAX;
@@ -6792,6 +6802,9 @@ activate_stage3_ip_config_start (NMDevice *self)
            && !nm_device_activate_stage3_ip6_start (self))
                return;
 
+       /* Proxy */
+       nm_device_set_proxy_config (self, NULL);
+
        check_ip_failed (self, TRUE);
 }
 
@@ -8315,8 +8328,50 @@ nm_device_is_activating (NMDevice *self)
        return priv->act_handle4.id ? TRUE : FALSE;
 }
 
-/* IP Configuration stuff */
+NMProxyConfig *
+nm_device_get_proxy_config (NMDevice *self)
+{
+       g_return_val_if_fail (NM_IS_DEVICE (self), NULL);
+
+       return NM_DEVICE_GET_PRIVATE (self)->proxy_config;
+}
 
+static void
+nm_device_set_proxy_config (NMDevice *self, GHashTable *options)
+{
+       NMDevicePrivate *priv;
+       NMConnection *connection;
+       NMSettingProxy *s_proxy = NULL;
+       char *pac = NULL;
+
+       g_return_if_fail (NM_IS_DEVICE (self));
+
+       priv = NM_DEVICE_GET_PRIVATE (self);
+
+       g_clear_object (&priv->proxy_config);
+       priv->proxy_config = nm_proxy_config_new ();
+
+       if (options) {
+               pac = g_hash_table_lookup (options, "wpad");
+               if (pac) {
+                       nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
+                       nm_proxy_config_set_pac_url (priv->proxy_config, pac);
+                       _LOGD (LOGD_PROXY, "PAC url: %s",pac);
+               } else {
+                       nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
+                       _LOGI (LOGD_PROXY, "PAC url not obtained from DHCP server");
+               }
+       }
+
+       connection = nm_device_get_applied_connection (self);
+       if (connection)
+               s_proxy = nm_connection_get_setting_proxy (connection);
+
+       if (s_proxy)
+               nm_proxy_config_merge_setting (priv->proxy_config, s_proxy);
+}
+
+/* IP Configuration stuff */
 NMDhcp4Config *
 nm_device_get_dhcp4_config (NMDevice *self)
 {
@@ -10579,6 +10634,7 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type)
         */
        nm_device_set_ip4_config (self, NULL, 0, TRUE, TRUE, NULL);
        nm_device_set_ip6_config (self, NULL, TRUE, TRUE, NULL);
+       g_clear_object (&priv->proxy_config);
        g_clear_object (&priv->con_ip4_config);
        g_clear_object (&priv->dev_ip4_config);
        g_clear_object (&priv->ext_ip4_config);
@@ -11166,6 +11222,9 @@ _set_state_full (NMDevice *self,
                                deactivate_dispatcher_complete (0, self);
                        }
                }
+
+               /* Remove config from PacRunner */
+               nm_pacrunner_manager_remove (priv->pacrunner_manager, nm_device_get_ip_iface (self));
                break;
        case NM_DEVICE_STATE_DISCONNECTED:
                if (   priv->queued_act_request
@@ -11189,6 +11248,14 @@ _set_state_full (NMDevice *self,
                                    nm_act_request_get_settings_connection (req),
                                    nm_act_request_get_applied_connection (req),
                                    self, NULL, NULL, NULL);
+
+               /* Load PacRunner with Device's config */
+               if (!nm_pacrunner_manager_send (priv->pacrunner_manager,
+                                               nm_device_get_ip_iface (self),
+                                               priv->proxy_config,
+                                               priv->ip4_config,
+                                               priv->ip6_config))
+                       _LOGI (LOGD_PROXY, "Couldn't update pacrunner for %s", nm_device_get_ip_iface (self));
                break;
        case NM_DEVICE_STATE_FAILED:
                /* Usually upon failure the activation chain is interrupted in
@@ -11952,6 +12019,8 @@ nm_device_init (NMDevice *self)
        priv->available_connections = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, 
NULL);
        priv->ip6_saved_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
 
+       priv->pacrunner_manager = g_object_ref (nm_pacrunner_manager_get ());
+
        priv->default_route.v4_is_assumed = TRUE;
        priv->default_route.v6_is_assumed = TRUE;
 
@@ -12063,6 +12132,8 @@ dispose (GObject *object)
 
        dispatcher_cleanup (self);
 
+       g_clear_object (&priv->pacrunner_manager);
+
        _cleanup_generic_pre (self, CLEANUP_TYPE_KEEP);
 
        g_warn_if_fail (priv->slaves == NULL);
diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h
index 6a4f22a..6cbe0e3 100644
--- a/src/devices/nm-device.h
+++ b/src/devices/nm-device.h
@@ -366,9 +366,10 @@ const char *    nm_device_get_permanent_hw_address (NMDevice *dev,
                                                     gboolean fallback_fake);
 const char *    nm_device_get_initial_hw_address (NMDevice *dev);
 
+NMProxyConfig * nm_device_get_proxy_config      (NMDevice *dev);
+
 NMDhcp4Config * nm_device_get_dhcp4_config      (NMDevice *dev);
 NMDhcp6Config * nm_device_get_dhcp6_config      (NMDevice *dev);
-
 NMIP4Config *   nm_device_get_ip4_config        (NMDevice *dev);
 void            nm_device_replace_vpn4_config   (NMDevice *dev,
                                                  NMIP4Config *old,
diff --git a/src/nm-dispatcher.c b/src/nm-dispatcher.c
index df9be2e..890e57d 100644
--- a/src/nm-dispatcher.c
+++ b/src/nm-dispatcher.c
@@ -32,6 +32,7 @@
 #include "nm-device.h"
 #include "nm-dhcp4-config.h"
 #include "nm-dhcp6-config.h"
+#include "nm-proxy-config.h"
 #include "nm-ip4-config.h"
 #include "nm-ip6-config.h"
 #include "nm-manager.h"
@@ -91,6 +92,37 @@ _get_monitor_by_action (DispatcherAction action)
 }
 
 static void
+dump_proxy_to_props (NMProxyConfig *proxy, GVariantBuilder *builder)
+{
+       char **proxies = NULL;
+       const char *pac_url = NULL, *pac_script = NULL;
+
+       if (nm_proxy_config_get_method (proxy) == NM_PROXY_CONFIG_METHOD_NONE)
+               return;
+
+       /* Proxies */
+       proxies = nm_proxy_config_get_proxies (proxy);
+       if (proxies && g_strv_length (proxies) > 0)
+               g_variant_builder_add (builder, "{sv}",
+                                      "proxies",
+                                      g_variant_new_strv ((const char *const *) proxies, -1));
+
+       /* PAC Url */
+       pac_url = nm_proxy_config_get_pac_url (proxy);
+       if (pac_url)
+               g_variant_builder_add (builder, "{sv}",
+                                      "pac-url",
+                                      g_variant_new_string (pac_url));
+
+       /* PAC Script */
+       pac_script = nm_proxy_config_get_pac_script (proxy);
+       if (pac_script)
+               g_variant_builder_add (builder, "{sv}",
+                                      "pac-script",
+                                      g_variant_new_string (pac_script));
+}
+
+static void
 dump_ip4_to_props (NMIP4Config *ip4, GVariantBuilder *builder)
 {
        GVariantBuilder int_builder;
@@ -231,11 +263,13 @@ dump_ip6_to_props (NMIP6Config *ip6, GVariantBuilder *builder)
 static void
 fill_device_props (NMDevice *device,
                    GVariantBuilder *dev_builder,
+                   GVariantBuilder *proxy_builder,
                    GVariantBuilder *ip4_builder,
                    GVariantBuilder *ip6_builder,
                    GVariant **dhcp4_props,
                    GVariant **dhcp6_props)
 {
+       NMProxyConfig *proxy_config;
        NMIP4Config *ip4_config;
        NMIP6Config *ip6_config;
        NMDhcp4Config *dhcp4_config;
@@ -254,6 +288,10 @@ fill_device_props (NMDevice *device,
                g_variant_builder_add (dev_builder, "{sv}", NMD_DEVICE_PROPS_PATH,
                                       g_variant_new_object_path (nm_exported_object_get_path 
(NM_EXPORTED_OBJECT (device))));
 
+       proxy_config = nm_device_get_proxy_config (device);
+       if (proxy_config)
+               dump_proxy_to_props (proxy_config, proxy_builder);
+
        ip4_config = nm_device_get_ip4_config (device);
        if (ip4_config)
                dump_ip4_to_props (ip4_config, ip4_builder);
@@ -272,11 +310,15 @@ fill_device_props (NMDevice *device,
 }
 
 static void
-fill_vpn_props (NMIP4Config *ip4_config,
+fill_vpn_props (NMProxyConfig *proxy_config,
+                NMIP4Config *ip4_config,
                 NMIP6Config *ip6_config,
+                GVariantBuilder *proxy_builder,
                 GVariantBuilder *ip4_builder,
                 GVariantBuilder *ip6_builder)
 {
+       if (proxy_config)
+               dump_proxy_to_props (proxy_config, proxy_builder);
        if (ip4_config)
                dump_ip4_to_props (ip4_config, ip4_builder);
        if (ip6_config)
@@ -454,6 +496,7 @@ _dispatcher_call (DispatcherAction action,
                   NMDevice *device,
                   NMConnectivityState connectivity_state,
                   const char *vpn_iface,
+                  NMProxyConfig *vpn_proxy_config,
                   NMIP4Config *vpn_ip4_config,
                   NMIP6Config *vpn_ip6_config,
                   DispatcherFunc callback,
@@ -463,10 +506,12 @@ _dispatcher_call (DispatcherAction action,
        GVariant *connection_dict;
        GVariantBuilder connection_props;
        GVariantBuilder device_props;
+       GVariantBuilder device_proxy_props;
        GVariantBuilder device_ip4_props;
        GVariantBuilder device_ip6_props;
        GVariant *device_dhcp4_props = NULL;
        GVariant *device_dhcp6_props = NULL;
+       GVariantBuilder vpn_proxy_props;
        GVariantBuilder vpn_ip4_props;
        GVariantBuilder vpn_ip6_props;
        DispatchInfo *info = NULL;
@@ -551,8 +596,10 @@ _dispatcher_call (DispatcherAction action,
        }
 
        g_variant_builder_init (&device_props, G_VARIANT_TYPE_VARDICT);
+       g_variant_builder_init (&device_proxy_props, G_VARIANT_TYPE_VARDICT);
        g_variant_builder_init (&device_ip4_props, G_VARIANT_TYPE_VARDICT);
        g_variant_builder_init (&device_ip6_props, G_VARIANT_TYPE_VARDICT);
+       g_variant_builder_init (&vpn_proxy_props, G_VARIANT_TYPE_VARDICT);
        g_variant_builder_init (&vpn_ip4_props, G_VARIANT_TYPE_VARDICT);
        g_variant_builder_init (&vpn_ip6_props, G_VARIANT_TYPE_VARDICT);
 
@@ -561,13 +608,16 @@ _dispatcher_call (DispatcherAction action,
            && action != DISPATCHER_ACTION_CONNECTIVITY_CHANGE) {
                fill_device_props (device,
                                   &device_props,
+                                  &device_proxy_props,
                                   &device_ip4_props,
                                   &device_ip6_props,
                                   &device_dhcp4_props,
                                   &device_dhcp6_props);
                if (vpn_ip4_config || vpn_ip6_config) {
-                       fill_vpn_props (vpn_ip4_config,
+                       fill_vpn_props (vpn_proxy_config,
+                                       vpn_ip4_config,
                                        vpn_ip6_config,
+                                       &vpn_proxy_props,
                                        &vpn_ip4_props,
                                        &vpn_ip6_props);
                }
@@ -584,17 +634,19 @@ _dispatcher_call (DispatcherAction action,
                GVariantIter *results;
 
                ret = _nm_dbus_proxy_call_sync (dispatcher_proxy, "Action",
-                                               g_variant_new 
("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}b)",
+                                               g_variant_new 
("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}a{sv}b)",
                                                               action_to_string (action),
                                                               connection_dict,
                                                               &connection_props,
                                                               &device_props,
+                                                              &device_proxy_props,
                                                               &device_ip4_props,
                                                               &device_ip6_props,
                                                               device_dhcp4_props,
                                                               device_dhcp6_props,
                                                               nm_connectivity_state_to_string 
(connectivity_state),
                                                               vpn_iface ? vpn_iface : "",
+                                                              &vpn_proxy_props,
                                                               &vpn_ip4_props,
                                                               &vpn_ip6_props,
                                                               nm_logging_enabled (LOGL_DEBUG, 
LOGD_DISPATCH)),
@@ -620,17 +672,19 @@ _dispatcher_call (DispatcherAction action,
                info->callback = callback;
                info->user_data = user_data;
                g_dbus_proxy_call (dispatcher_proxy, "Action",
-                                  g_variant_new 
("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}b)",
+                                  g_variant_new 
("(s@a{sa{sv}}a{sv}a{sv}a{sv}a{sv}a{sv}@a{sv}@a{sv}ssa{sv}a{sv}a{sv}b)",
                                                  action_to_string (action),
                                                  connection_dict,
                                                  &connection_props,
                                                  &device_props,
+                                                 &device_proxy_props,
                                                  &device_ip4_props,
                                                  &device_ip6_props,
                                                  device_dhcp4_props,
                                                  device_dhcp6_props,
                                                  nm_connectivity_state_to_string (connectivity_state),
                                                  vpn_iface ? vpn_iface : "",
+                                                 &vpn_proxy_props,
                                                  &vpn_ip4_props,
                                                  &vpn_ip6_props,
                                                  nm_logging_enabled (LOGL_DEBUG, LOGD_DISPATCH)),
@@ -680,7 +734,7 @@ nm_dispatcher_call (DispatcherAction action,
                     guint *out_call_id)
 {
        return _dispatcher_call (action, FALSE, settings_connection, applied_connection, device,
-                                NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL,
+                                NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL,
                                 callback, user_data, out_call_id);
 }
 
@@ -703,7 +757,7 @@ nm_dispatcher_call_sync (DispatcherAction action,
                          NMDevice *device)
 {
        return _dispatcher_call (action, TRUE, settings_connection, applied_connection, device,
-                                NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL);
+                                NM_CONNECTIVITY_UNKNOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 }
 
 /**
@@ -713,6 +767,7 @@ nm_dispatcher_call_sync (DispatcherAction action,
  * @applied_connection: the currently applied connection
  * @parent_device: the parent #NMDevice of the VPN connection
  * @vpn_iface: the IP interface of the VPN tunnel, if any
+ * @vpn_proxy_config: the #NMProxyConfig of the VPN connection
  * @vpn_ip4_config: the #NMIP4Config of the VPN connection
  * @vpn_ip6_config: the #NMIP6Config of the VPN connection
  * @callback: a caller-supplied callback to execute when done
@@ -731,6 +786,7 @@ nm_dispatcher_call_vpn (DispatcherAction action,
                         NMConnection *applied_connection,
                         NMDevice *parent_device,
                         const char *vpn_iface,
+                        NMProxyConfig *vpn_proxy_config,
                         NMIP4Config *vpn_ip4_config,
                         NMIP6Config *vpn_ip6_config,
                         DispatcherFunc callback,
@@ -738,8 +794,8 @@ nm_dispatcher_call_vpn (DispatcherAction action,
                         guint *out_call_id)
 {
        return _dispatcher_call (action, FALSE, settings_connection, applied_connection,
-                                parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_ip4_config,
-                                vpn_ip6_config, callback, user_data, out_call_id);
+                                parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config,
+                                vpn_ip4_config, vpn_ip6_config, callback, user_data, out_call_id);
 }
 
 /**
@@ -749,6 +805,7 @@ nm_dispatcher_call_vpn (DispatcherAction action,
  * @applied_connection: the currently applied connection
  * @parent_device: the parent #NMDevice of the VPN connection
  * @vpn_iface: the IP interface of the VPN tunnel, if any
+ * @vpn_proxy_config: the #NMProxyConfig of the VPN connection
  * @vpn_ip4_config: the #NMIP4Config of the VPN connection
  * @vpn_ip6_config: the #NMIP6Config of the VPN connection
  *
@@ -763,11 +820,12 @@ nm_dispatcher_call_vpn_sync (DispatcherAction action,
                              NMConnection *applied_connection,
                              NMDevice *parent_device,
                              const char *vpn_iface,
+                             NMProxyConfig *vpn_proxy_config,
                              NMIP4Config *vpn_ip4_config,
                              NMIP6Config *vpn_ip6_config)
 {
        return _dispatcher_call (action, TRUE, settings_connection, applied_connection,
-                                parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface,
+                                parent_device, NM_CONNECTIVITY_UNKNOWN, vpn_iface, vpn_proxy_config,
                                 vpn_ip4_config, vpn_ip6_config, NULL, NULL, NULL);
 }
 
@@ -785,7 +843,7 @@ nm_dispatcher_call_connectivity (DispatcherAction action,
                                  NMConnectivityState connectivity_state)
 {
        return _dispatcher_call (action, FALSE, NULL, NULL, NULL, connectivity_state,
-                                NULL, NULL, NULL, NULL, NULL, NULL);
+                                NULL, NULL, NULL, NULL, NULL, NULL, NULL);
 }
 
 void
diff --git a/src/nm-dispatcher.h b/src/nm-dispatcher.h
index 47cb648..919a92d 100644
--- a/src/nm-dispatcher.h
+++ b/src/nm-dispatcher.h
@@ -62,6 +62,7 @@ gboolean nm_dispatcher_call_vpn (DispatcherAction action,
                                  NMConnection *applied_connection,
                                  NMDevice *parent_device,
                                  const char *vpn_iface,
+                                 NMProxyConfig *vpn_proxy_config,
                                  NMIP4Config *vpn_ip4_config,
                                  NMIP6Config *vpn_ip6_config,
                                  DispatcherFunc callback,
@@ -73,6 +74,7 @@ gboolean nm_dispatcher_call_vpn_sync (DispatcherAction action,
                                       NMConnection *applied_connection,
                                       NMDevice *parent_device,
                                       const char *vpn_iface,
+                                      NMProxyConfig *vpn_proxy_config,
                                       NMIP4Config *vpn_ip4_config,
                                       NMIP6Config *vpn_ip6_config);
 
diff --git a/src/nm-logging.c b/src/nm-logging.c
index 8e5a44b..e777f6c 100644
--- a/src/nm-logging.c
+++ b/src/nm-logging.c
@@ -124,7 +124,7 @@ static struct {
        char *logging_domains_to_string;
        const LogLevelDesc level_desc[_LOGL_N];
 
-#define _DOMAIN_DESC_LEN 38
+#define _DOMAIN_DESC_LEN 39
        /* Would be nice to use C99 flexible array member here,
         * but that feature doesn't seem well supported. */
        const LogDesc domain_desc[_DOMAIN_DESC_LEN];
@@ -180,6 +180,7 @@ static struct {
                { LOGD_AUDIT,     "AUDIT" },
                { LOGD_SYSTEMD,   "SYSTEMD" },
                { LOGD_VPN_PLUGIN,"VPN_PLUGIN" },
+               { LOGD_PROXY,     "PROXY" },
                { 0, NULL }
                /* keep _DOMAIN_DESC_LEN in sync */
        },
diff --git a/src/nm-logging.h b/src/nm-logging.h
index 9e2b010..9f85c16 100644
--- a/src/nm-logging.h
+++ b/src/nm-logging.h
@@ -66,6 +66,7 @@ typedef enum  { /*< skip >*/
        LOGD_AUDIT      = (1LL << 34),
        LOGD_SYSTEMD    = (1LL << 35),
        LOGD_VPN_PLUGIN = (1LL << 36),
+       LOGD_PROXY      = (1LL << 37),
 
        __LOGD_MAX,
        LOGD_ALL       = (((__LOGD_MAX - 1LL) << 1) - 1LL),
diff --git a/src/nm-types.h b/src/nm-types.h
index 1fbf043..4e80200 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -42,11 +42,13 @@ typedef struct _NMDefaultRouteManager NMDefaultRouteManager;
 typedef struct _NMDevice             NMDevice;
 typedef struct _NMDhcp4Config        NMDhcp4Config;
 typedef struct _NMDhcp6Config        NMDhcp6Config;
+typedef struct _NMProxyConfig        NMProxyConfig;
 typedef struct _NMIP4Config          NMIP4Config;
 typedef struct _NMIP6Config          NMIP6Config;
 typedef struct _NMManager            NMManager;
 typedef struct _NMPolicy             NMPolicy;
 typedef struct _NMRfkillManager      NMRfkillManager;
+typedef struct _NMPacRunnerManager   NMPacRunnerManager;
 typedef struct _NMRouteManager       NMRouteManager;
 typedef struct _NMSessionMonitor     NMSessionMonitor;
 typedef struct _NMSleepMonitor       NMSleepMonitor;
diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c
index 529d758..60b48ae 100644
--- a/src/settings/nm-settings.c
+++ b/src/settings/nm-settings.c
@@ -57,6 +57,7 @@
 #include "nm-setting-adsl.h"
 #include "nm-setting-wireless.h"
 #include "nm-setting-wireless-security.h"
+#include "nm-setting-proxy.h"
 #include "nm-setting-bond.h"
 #include "nm-utils.h"
 #include "nm-core-internal.h"
diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c
index af5d291..9eb143d 100644
--- a/src/settings/plugins/ifcfg-rh/reader.c
+++ b/src/settings/plugins/ifcfg-rh/reader.c
@@ -48,6 +48,7 @@
 #include "nm-setting-bridge.h"
 #include "nm-setting-bridge-port.h"
 #include "nm-setting-dcb.h"
+#include "nm-setting-proxy.h"
 #include "nm-setting-generic.h"
 #include "nm-core-internal.h"
 #include "nm-utils.h"
@@ -899,6 +900,176 @@ error:
        return success;
 }
 
+static NMSetting *
+make_proxy_setting (shvarFile *ifcfg, GError **error)
+{
+       NMSettingProxy *s_proxy = NULL;
+       char *value = NULL;
+       NMSettingProxyMethod method;
+
+       value = svGetValue (ifcfg, "PROXY_METHOD", FALSE);
+       if (!value)
+               return NULL;
+
+       if (!g_ascii_strcasecmp (value, "auto"))
+               method = NM_SETTING_PROXY_METHOD_AUTO;
+       else if (!g_ascii_strcasecmp (value, "manual"))
+               method = NM_SETTING_PROXY_METHOD_MANUAL;
+       else
+               method = NM_SETTING_PROXY_METHOD_NONE;
+       g_free (value);
+
+       s_proxy = (NMSettingProxy *) nm_setting_proxy_new ();
+
+       switch (method) {
+       case NM_SETTING_PROXY_METHOD_AUTO:
+               g_object_set (s_proxy,
+                             NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_AUTO,
+                             NULL);
+
+               value = svGetValue (ifcfg, "PAC_URL", FALSE);
+               if (value) {
+                       value = g_strstrip (value);
+                       g_object_set (s_proxy, NM_SETTING_PROXY_PAC_URL, value, NULL);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "PAC_SCRIPT", FALSE);
+               if (value) {
+                       value = g_strstrip (value);
+                       g_object_set (s_proxy, NM_SETTING_PROXY_PAC_SCRIPT, value, NULL);
+                       g_free (value);
+               }
+
+               break;
+       case NM_SETTING_PROXY_METHOD_MANUAL:
+               g_object_set (s_proxy,
+                             NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_MANUAL,
+                             NULL);
+
+               value = svGetValue (ifcfg, "NO_PROXY_FOR", FALSE);
+               if (value) {
+                       char **excludes = NULL;
+
+                       excludes = g_strsplit (value, " ", 0);
+                       if (excludes)
+                               g_object_set (s_proxy,
+                                             NM_SETTING_PROXY_NO_PROXY_FOR, excludes,
+                                             NULL);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "HTTP_PROXY", FALSE);
+               if (value) {
+                       value = g_strstrip (value);
+                       g_object_set (s_proxy, NM_SETTING_PROXY_HTTP_PROXY, value, NULL);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "HTTP_PORT", FALSE);
+               if (value) {
+                       int port;
+
+                       port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1);
+                       if (port > 0)
+                               g_object_set (s_proxy, NM_SETTING_PROXY_HTTP_PORT, (guint) port, NULL);
+                       else
+                               PARSE_WARNING ("invalid PORT '%s'", value);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "HTTP_DEFAULT", FALSE);
+               if (value) {
+                       if (!g_ascii_strcasecmp (value, "yes")) {
+                               g_object_set (s_proxy, NM_SETTING_PROXY_HTTP_DEFAULT, TRUE, NULL);
+                               g_free (value);
+                               break;
+                       }
+               }
+
+               value = svGetValue (ifcfg, "SSL_PROXY", FALSE);
+               if (value) {
+                       value = g_strstrip (value);
+                       g_object_set (s_proxy, NM_SETTING_PROXY_SSL_PROXY, value, NULL);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "SSL_PORT", FALSE);
+               if (value) {
+                       int port;
+
+                       port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1);
+                       if (port > 0)
+                               g_object_set (s_proxy, NM_SETTING_PROXY_SSL_PORT, (guint) port, NULL);
+                       else
+                               PARSE_WARNING ("invalid PORT '%s'", value);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "FTP_PROXY", FALSE);
+               if (value) {
+                       value = g_strstrip (value);
+                       g_object_set (s_proxy, NM_SETTING_PROXY_FTP_PROXY, value, NULL);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "FTP_PORT", FALSE);
+               if (value) {
+                       int port;
+
+                       port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1);
+                       if (port > 0)
+                               g_object_set (s_proxy, NM_SETTING_PROXY_FTP_PORT, (guint) port, NULL);
+                       else
+                               PARSE_WARNING ("invalid PORT '%s'", value);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "SOCKS_PROXY", FALSE);
+               if (value) {
+                       value = g_strstrip (value);
+                       g_object_set (s_proxy, NM_SETTING_PROXY_SOCKS_PROXY, value, NULL);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "SOCKS_PORT", FALSE);
+               if (value) {
+                       int port;
+
+                       port = _nm_utils_ascii_str_to_int64 (value, 0, 0, 65535, -1);
+                       if (port > 0)
+                               g_object_set (s_proxy, NM_SETTING_PROXY_SOCKS_PORT, (guint) port, NULL);
+                       else
+                               PARSE_WARNING ("invalid PORT '%s'", value);
+                       g_free (value);
+               }
+
+               value = svGetValue (ifcfg, "SOCKS_VERSION_5", FALSE);
+               if (value) {
+                       if (!g_ascii_strcasecmp (value, "yes")) {
+                               g_object_set (s_proxy, NM_SETTING_PROXY_SOCKS_VERSION_5, TRUE, NULL);
+                               g_free (value);
+                               break;
+                       }
+               }
+
+               break;
+       case NM_SETTING_PROXY_METHOD_NONE:
+               g_object_set (s_proxy,
+                             NM_SETTING_PROXY_METHOD, NM_SETTING_PROXY_METHOD_NONE,
+                             NULL);
+       }
+
+       value = svGetValue (ifcfg, "BROWSER_ONLY", FALSE);
+       if (value) {
+               if (!g_ascii_strcasecmp (value, "yes")) {
+                       g_object_set (s_proxy, NM_SETTING_PROXY_BROWSER_ONLY, TRUE, NULL);
+                       g_free (value);
+               }
+       }
+
+       return NM_SETTING (s_proxy);
+}
 
 static NMSetting *
 make_ip4_setting (shvarFile *ifcfg,
@@ -4959,7 +5130,7 @@ connection_from_file_full (const char *filename,
        shvarFile *parsed;
        gs_free char *type = NULL;
        char *devtype, *bootproto;
-       NMSetting *s_ip4, *s_ip6, *s_port, *s_dcb = NULL;
+       NMSetting *s_ip4, *s_ip6, *s_proxy, *s_port, *s_dcb = NULL;
        const char *ifcfg_name = NULL;
 
        g_return_val_if_fail (filename != NULL, NULL);
@@ -5171,6 +5342,10 @@ connection_from_file_full (const char *filename,
         */
        check_dns_search_domains (parsed, s_ip4, s_ip6);
 
+       s_proxy = make_proxy_setting (parsed, error);
+       if (s_proxy)
+               nm_connection_add_setting (connection, s_proxy);
+
        /* Bridge port? */
        s_port = make_bridge_port_setting (parsed);
        if (s_port)
diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c
index 3682640..77d869d 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -36,6 +36,7 @@
 #include "nm-setting-wired.h"
 #include "nm-setting-wireless.h"
 #include "nm-setting-8021x.h"
+#include "nm-setting-proxy.h"
 #include "nm-setting-ip4-config.h"
 #include "nm-setting-ip6-config.h"
 #include "nm-setting-pppoe.h"
@@ -1984,6 +1985,147 @@ error:
 }
 
 static gboolean
+write_proxy_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
+{
+       NMSettingProxy *s_proxy;
+       NMSettingProxyMethod method;
+       char *tmp;
+       const char *pac_url, *pac_script;
+       const char *http_proxy, *ssl_proxy, *ftp_proxy, *socks_proxy;
+       guint32 http_port, ssl_port, ftp_port, socks_port;
+       gboolean http_default, socks_version_5, browser_only;
+       GString *no_proxy_for;
+       char **iter, **excludes = NULL;
+
+       s_proxy = nm_connection_get_setting_proxy (connection);
+       if (!s_proxy)
+               return TRUE;
+
+       svSetValue (ifcfg, "HTTP_PROXY", NULL, FALSE);
+       svSetValue (ifcfg, "HTTP_PORT", NULL, FALSE);
+       svSetValue (ifcfg, "HTTP_DEFAULT", NULL, FALSE);
+       svSetValue (ifcfg, "SSL_PROXY", NULL, FALSE);
+       svSetValue (ifcfg, "SSL_PORT", NULL, FALSE);
+       svSetValue (ifcfg, "FTP_PROXY", NULL, FALSE);
+       svSetValue (ifcfg, "FTP_PORT", NULL, FALSE);
+       svSetValue (ifcfg, "SOCKS_PROXY", NULL, FALSE);
+       svSetValue (ifcfg, "SOCKS_PORT", NULL, FALSE);
+       svSetValue (ifcfg, "SOCKS_VERSION_5", NULL, FALSE);
+       svSetValue (ifcfg, "NO_PROXY_FOR", NULL, FALSE);
+       svSetValue (ifcfg, "BROWSER_ONLY", NULL, FALSE);
+       svSetValue (ifcfg, "PAC_URL", NULL, FALSE);
+       svSetValue (ifcfg, "PAC_SCRIPT", NULL, FALSE);
+
+       method = nm_setting_proxy_get_method (s_proxy);
+       switch (method) {
+       case NM_SETTING_PROXY_METHOD_AUTO:
+               svSetValue (ifcfg, "PROXY_METHOD", "auto", FALSE);
+
+               pac_url = nm_setting_proxy_get_pac_url (s_proxy);
+               if (pac_url)
+                       svSetValue (ifcfg, "PAC_URL", pac_url, FALSE);
+
+               pac_script = nm_setting_proxy_get_pac_script (s_proxy);
+               if (pac_script)
+                       svSetValue (ifcfg, "PAC_SCRIPT", pac_script, FALSE);
+
+               break;
+       case NM_SETTING_PROXY_METHOD_MANUAL:
+               svSetValue (ifcfg, "PROXY_METHOD", "manual", FALSE);
+
+               excludes = nm_setting_proxy_get_no_proxy_for (s_proxy);
+               if (excludes && g_strv_length (excludes)) {
+                       int counter = 0;
+
+                       no_proxy_for = g_string_new (NULL);
+                       for (iter = excludes; *iter; iter++) {
+                               if (counter > 0)
+                                       g_string_append (no_proxy_for, " ");
+                               counter++;
+                               g_string_append (no_proxy_for, *iter);
+                       }
+
+                       svSetValue (ifcfg, "NO_PROXY_FOR", no_proxy_for->str, FALSE);
+                       g_string_free (no_proxy_for, TRUE);
+               }
+
+               http_proxy = nm_setting_proxy_get_http_proxy (s_proxy);
+               if (http_proxy)
+                       svSetValue (ifcfg, "HTTP_PROXY", http_proxy, FALSE);
+
+               svSetValue (ifcfg, "HTTP_PORT", NULL, FALSE);
+               http_port = nm_setting_proxy_get_http_port (s_proxy);
+               if (http_port) {
+                       tmp = g_strdup_printf ("%u", http_port);
+                       svSetValue (ifcfg, "HTTP_PORT", tmp, FALSE);
+                       g_free (tmp);
+               }
+
+               http_default = nm_setting_proxy_get_http_default (s_proxy);
+               if (http_default) {
+                       svSetValue (ifcfg, "HTTP_DEFAULT", "yes", FALSE);
+                       break;
+               } else
+                       svSetValue (ifcfg, "HTTP_DEFAULT", "no", FALSE);
+
+               ssl_proxy = nm_setting_proxy_get_ssl_proxy (s_proxy);
+               if (ssl_proxy)
+                       svSetValue (ifcfg, "SSL_PROXY", ssl_proxy, FALSE);
+
+               svSetValue (ifcfg, "SSL_PORT", NULL, FALSE);
+               ssl_port = nm_setting_proxy_get_ssl_port (s_proxy);
+               if (ssl_port) {
+                       tmp = g_strdup_printf ("%u", ssl_port);
+                       svSetValue (ifcfg, "SSL_PORT", tmp, FALSE);
+                       g_free (tmp);
+               }
+
+               ftp_proxy = nm_setting_proxy_get_ftp_proxy (s_proxy);
+               if (ftp_proxy)
+                       svSetValue (ifcfg, "FTP_PROXY", ftp_proxy, FALSE);
+
+               svSetValue (ifcfg, "FTP_PORT", NULL, FALSE);
+               ftp_port = nm_setting_proxy_get_ftp_port (s_proxy);
+               if (ftp_port) {
+                       tmp = g_strdup_printf ("%u", ftp_port);
+                       svSetValue (ifcfg, "FTP_PORT", tmp, FALSE);
+                       g_free (tmp);
+               }
+
+               socks_proxy = nm_setting_proxy_get_socks_proxy (s_proxy);
+               if (socks_proxy)
+                       svSetValue (ifcfg, "SOCKS_PROXY", socks_proxy, FALSE);
+
+               svSetValue (ifcfg, "SOCKS_PORT", NULL, FALSE);
+               socks_port = nm_setting_proxy_get_socks_port (s_proxy);
+               if (socks_port) {
+                       tmp = g_strdup_printf ("%u", socks_port);
+                       svSetValue (ifcfg, "SOCKS_PORT", tmp, FALSE);
+                       g_free (tmp);
+               }
+
+               socks_version_5 = nm_setting_proxy_get_socks_version_5 (s_proxy);
+               if (socks_version_5)
+                       svSetValue (ifcfg, "SOCKS_VERSION_5", "yes", FALSE);
+               else
+                       svSetValue (ifcfg, "SOCKS_VERSION_5", "no", FALSE);
+
+               break;
+       case NM_SETTING_PROXY_METHOD_NONE:
+               svSetValue (ifcfg, "PROXY_METHOD", "none", FALSE);
+               /* Write nothing more */
+       }
+
+       browser_only = nm_setting_proxy_get_browser_only (s_proxy);
+       if (browser_only)
+               svSetValue (ifcfg, "BROWSER_ONLY", "yes", FALSE);
+       else
+               svSetValue (ifcfg, "BROWSER_ONLY", "no", FALSE);
+
+       return TRUE;
+}
+
+static gboolean
 write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
 {
        NMSettingIPConfig *s_ip4;
@@ -2862,6 +3004,9 @@ write_connection (NMConnection *connection,
        if (!write_dcb_setting (connection, ifcfg, error))
                goto out;
 
+       if (!write_proxy_setting (connection, ifcfg, error))
+               goto out;
+
        if (!utils_ignore_ip_config (connection)) {
                svSetValue (ifcfg, "DHCP_HOSTNAME", NULL, FALSE);
                svSetValue (ifcfg, "DHCP_FQDN", NULL, FALSE);
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index 5378909..c9651e6 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -31,6 +31,7 @@
 #include <syslog.h>
 
 #include "nm-vpn-connection.h"
+#include "nm-proxy-config.h"
 #include "nm-ip4-config.h"
 #include "nm-ip6-config.h"
 #include "nm-platform.h"
@@ -40,6 +41,7 @@
 #include "nm-dispatcher.h"
 #include "nm-agent-manager.h"
 #include "nm-core-internal.h"
+#include "nm-pacrunner-manager.h"
 #include "nm-default-route-manager.h"
 #include "nm-route-manager.h"
 #include "nm-firewall-manager.h"
@@ -107,6 +109,7 @@ typedef struct {
        GCancellable *cancellable;
        GVariant *connect_hash;
        guint connect_timeout;
+       NMProxyConfig *proxy_config;
        gboolean has_ip4;
        NMIP4Config *ip4_config;
        guint32 ip4_internal_gw;
@@ -511,6 +514,7 @@ _set_vpn_state (NMVpnConnection *self,
                                             _get_applied_connection (self),
                                             parent_dev,
                                             priv->ip_iface,
+                                            priv->proxy_config,
                                             priv->ip4_config,
                                             priv->ip6_config,
                                             dispatcher_pre_up_done,
@@ -530,11 +534,20 @@ _set_vpn_state (NMVpnConnection *self,
                                        _get_applied_connection (self),
                                        parent_dev,
                                        priv->ip_iface,
+                                       priv->proxy_config,
                                        priv->ip4_config,
                                        priv->ip6_config,
                                        NULL,
                                        NULL,
                                        NULL);
+
+               /* Load PacRunner with VPN's config */
+               if (!nm_pacrunner_manager_send (nm_pacrunner_manager_get (),
+                                               priv->ip_iface,
+                                               priv->proxy_config,
+                                               priv->ip4_config,
+                                               priv->ip6_config))
+                       _LOGI ("Couldn't update pacrunner for %s", priv->ip_iface);
                break;
        case STATE_DEACTIVATING:
                if (quitting) {
@@ -543,6 +556,7 @@ _set_vpn_state (NMVpnConnection *self,
                                                     _get_applied_connection (self),
                                                     parent_dev,
                                                     priv->ip_iface,
+                                                    priv->proxy_config,
                                                     priv->ip4_config,
                                                     priv->ip6_config);
                } else {
@@ -551,6 +565,7 @@ _set_vpn_state (NMVpnConnection *self,
                                                     _get_applied_connection (self),
                                                     parent_dev,
                                                     priv->ip_iface,
+                                                    priv->proxy_config,
                                                     priv->ip4_config,
                                                     priv->ip6_config,
                                                     dispatcher_pre_down_done,
@@ -560,6 +575,9 @@ _set_vpn_state (NMVpnConnection *self,
                                dispatcher_pre_down_done (0, self);
                        }
                }
+
+               /* Remove config from PacRunner */
+               nm_pacrunner_manager_remove (nm_pacrunner_manager_get(), priv->ip_iface);
                break;
        case STATE_FAILED:
        case STATE_DISCONNECTED:
@@ -573,6 +591,7 @@ _set_vpn_state (NMVpnConnection *self,
                                                             parent_dev,
                                                             priv->ip_iface,
                                                             NULL,
+                                                            NULL,
                                                             NULL);
                        } else {
                                nm_dispatcher_call_vpn (DISPATCHER_ACTION_VPN_DOWN,
@@ -584,6 +603,7 @@ _set_vpn_state (NMVpnConnection *self,
                                                        NULL,
                                                        NULL,
                                                        NULL,
+                                                       NULL,
                                                        NULL);
                        }
                }
@@ -1251,6 +1271,20 @@ process_generic_config (NMVpnConnection *self, GVariant *dict)
                g_object_notify (G_OBJECT (self), NM_VPN_CONNECTION_BANNER);
        }
 
+       /* Proxy Config */
+       g_clear_object (&priv->proxy_config);
+       priv->proxy_config = nm_proxy_config_new ();
+
+       if (g_variant_lookup (dict, NM_VPN_PLUGIN_CONFIG_PROXY_PAC, "&s", &str)) {
+               nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_AUTO);
+               nm_proxy_config_set_pac_url (priv->proxy_config, str);
+       } else
+               nm_proxy_config_set_method (priv->proxy_config, NM_PROXY_CONFIG_METHOD_NONE);
+
+       /* User overrides if any from the NMConnection's Proxy settings */
+       nm_proxy_config_merge_setting (priv->proxy_config,
+                                      nm_connection_get_setting_proxy (_get_applied_connection (self)));
+
        /* External world-visible address of the VPN server */
        priv->ip4_external_gw = 0;
        g_clear_pointer (&priv->ip6_external_gw, g_free);
@@ -2161,6 +2195,14 @@ nm_vpn_connection_get_banner (NMVpnConnection *self)
        return NM_VPN_CONNECTION_GET_PRIVATE (self)->banner;
 }
 
+NMProxyConfig *
+nm_vpn_connection_get_proxy_config (NMVpnConnection *self)
+{
+       g_return_val_if_fail (NM_IS_VPN_CONNECTION (self), NULL);
+
+       return NM_VPN_CONNECTION_GET_PRIVATE (self)->proxy_config;
+}
+
 NMIP4Config *
 nm_vpn_connection_get_ip4_config (NMVpnConnection *self)
 {
@@ -2559,6 +2601,7 @@ dispose (GObject *object)
                g_cancellable_cancel (priv->cancellable);
                g_clear_object (&priv->cancellable);
        }
+       g_clear_object (&priv->proxy_config);
        nm_exported_object_clear_and_unexport (&priv->ip4_config);
        nm_exported_object_clear_and_unexport (&priv->ip6_config);
        g_clear_object (&priv->proxy);
diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h
index 6837432..09a0379 100644
--- a/src/vpn-manager/nm-vpn-connection.h
+++ b/src/vpn-manager/nm-vpn-connection.h
@@ -89,6 +89,8 @@ void                 nm_vpn_connection_disconnect      (NMVpnConnection *self,
                                                         NMVpnConnectionStateReason reason,
                                                         gboolean quitting);
 
+NMProxyConfig *      nm_vpn_connection_get_proxy_config (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, gboolean fallback_device);
-- 
2.5.5




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]