diff options
| author | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2015-01-22 00:29:39 +0100 |
| commit | 2c032d8f1c6292c1338a615e6ec40252889ba85c (patch) | |
| tree | 1f77182220b2b0264288ba4a476ab47e5bc48716 /src/ppp-manager | |
| parent | 33491bc4279481db8ae47213e34a6d695a0e8830 (diff) | |
Imported Upstream version 1.0.0 upstream/1.0.0
Diffstat (limited to 'src/ppp-manager')
| -rw-r--r-- | src/ppp-manager/Makefile.am | 10 | ||||
| -rw-r--r-- | src/ppp-manager/Makefile.in | 20 | ||||
| -rw-r--r-- | src/ppp-manager/nm-ppp-manager.c | 293 | ||||
| -rw-r--r-- | src/ppp-manager/nm-ppp-manager.h | 17 | ||||
| -rw-r--r-- | src/ppp-manager/nm-ppp-status.h | 6 | ||||
| -rw-r--r-- | src/ppp-manager/nm-pppd-plugin.c | 264 | ||||
| -rw-r--r-- | src/ppp-manager/nm-pppd-plugin.h | 19 |
7 files changed, 360 insertions, 269 deletions
diff --git a/src/ppp-manager/Makefile.am b/src/ppp-manager/Makefile.am index 46fc9138..fd2fe76b 100644 --- a/src/ppp-manager/Makefile.am +++ b/src/ppp-manager/Makefile.am @@ -1,11 +1,12 @@ if WITH_PPP AM_CPPFLAGS = \ - -I${top_builddir}/include \ -I${top_srcdir}/include \ + -I${top_srcdir}/libnm-core \ + -I${top_builddir}/libnm-core \ -DG_LOG_DOMAIN=\""nm-pppd-plugin"\" \ + -DNETWORKMANAGER_COMPILATION \ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ - $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) pppd_plugindir = $(PPPD_PLUGIN_DIR) @@ -19,8 +20,7 @@ nm_pppd_plugin_la_SOURCES = \ nm_pppd_plugin_la_LDFLAGS = -module -avoid-version nm_pppd_plugin_la_LIBADD = \ - $(top_builddir)/libnm-util/libnm-util.la \ - $(DBUS_LIBS) \ - $(GLIB_LIBS) + $(GLIB_LIBS) \ + -ldl endif diff --git a/src/ppp-manager/Makefile.in b/src/ppp-manager/Makefile.in index 731a9459..775e4b5a 100644 --- a/src/ppp-manager/Makefile.in +++ b/src/ppp-manager/Makefile.in @@ -131,9 +131,7 @@ am__uninstall_files_from_dir = { \ am__installdirs = "$(DESTDIR)$(pppd_plugindir)" LTLIBRARIES = $(pppd_plugin_LTLIBRARIES) am__DEPENDENCIES_1 = -@WITH_PPP_TRUE@nm_pppd_plugin_la_DEPENDENCIES = \ -@WITH_PPP_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@WITH_PPP_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +@WITH_PPP_TRUE@nm_pppd_plugin_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__nm_pppd_plugin_la_SOURCES_DIST = nm-pppd-plugin.c nm-pppd-plugin.h \ nm-ppp-status.h @WITH_PPP_TRUE@am_nm_pppd_plugin_la_OBJECTS = nm-pppd-plugin.lo @@ -217,6 +215,8 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BLUEZ5_CFLAGS = @BLUEZ5_CFLAGS@ +BLUEZ5_LIBS = @BLUEZ5_LIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ @@ -340,6 +340,7 @@ NEWT_CFLAGS = @NEWT_CFLAGS@ NEWT_LIBS = @NEWT_LIBS@ NM = @NM@ NMEDIT = @NMEDIT@ +NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@ NM_MAJOR_VERSION = @NM_MAJOR_VERSION@ NM_MICRO_VERSION = @NM_MICRO_VERSION@ NM_MINOR_VERSION = @NM_MINOR_VERSION@ @@ -359,6 +360,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ @@ -385,7 +387,7 @@ SYSTEMD_INHIBIT_LIBS = @SYSTEMD_INHIBIT_LIBS@ SYSTEMD_LOGIN_CFLAGS = @SYSTEMD_LOGIN_CFLAGS@ SYSTEMD_LOGIN_LIBS = @SYSTEMD_LOGIN_LIBS@ SYSTEM_CA_PATH = @SYSTEM_CA_PATH@ -UDEV_BASE_DIR = @UDEV_BASE_DIR@ +UDEV_DIR = @UDEV_DIR@ USE_NLS = @USE_NLS@ UUID_CFLAGS = @UUID_CFLAGS@ UUID_LIBS = @UUID_LIBS@ @@ -465,11 +467,12 @@ with_netconfig = @with_netconfig@ with_resolvconf = @with_resolvconf@ with_valgrind = @with_valgrind@ @WITH_PPP_TRUE@AM_CPPFLAGS = \ -@WITH_PPP_TRUE@ -I${top_builddir}/include \ @WITH_PPP_TRUE@ -I${top_srcdir}/include \ +@WITH_PPP_TRUE@ -I${top_srcdir}/libnm-core \ +@WITH_PPP_TRUE@ -I${top_builddir}/libnm-core \ @WITH_PPP_TRUE@ -DG_LOG_DOMAIN=\""nm-pppd-plugin"\" \ +@WITH_PPP_TRUE@ -DNETWORKMANAGER_COMPILATION \ @WITH_PPP_TRUE@ -DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \ -@WITH_PPP_TRUE@ $(DBUS_CFLAGS) \ @WITH_PPP_TRUE@ $(GLIB_CFLAGS) @WITH_PPP_TRUE@pppd_plugindir = $(PPPD_PLUGIN_DIR) @@ -481,9 +484,8 @@ with_valgrind = @with_valgrind@ @WITH_PPP_TRUE@nm_pppd_plugin_la_LDFLAGS = -module -avoid-version @WITH_PPP_TRUE@nm_pppd_plugin_la_LIBADD = \ -@WITH_PPP_TRUE@ $(top_builddir)/libnm-util/libnm-util.la \ -@WITH_PPP_TRUE@ $(DBUS_LIBS) \ -@WITH_PPP_TRUE@ $(GLIB_LIBS) +@WITH_PPP_TRUE@ $(GLIB_LIBS) \ +@WITH_PPP_TRUE@ -ldl all: all-am diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index e856fc19..4fac96dc 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -19,7 +19,8 @@ * Copyright (C) 2008 - 2012 Red Hat, Inc. */ -#include <config.h> +#include "config.h" + #include <sys/types.h> #include <sys/wait.h> #include <signal.h> @@ -32,7 +33,6 @@ #include <sys/socket.h> #include <sys/ioctl.h> #include <asm/types.h> -#include <linux/if.h> #include <sys/stat.h> #include <linux/ppp_defs.h> @@ -41,18 +41,14 @@ #endif #include <linux/if_ppp.h> -#include "NetworkManager.h" +#include "NetworkManagerUtils.h" #include "nm-glib-compat.h" #include "nm-ppp-manager.h" -#include "nm-setting-connection.h" -#include "nm-setting-ppp.h" -#include "nm-setting-pppoe.h" -#include "nm-setting-adsl.h" -#include "nm-setting-gsm.h" -#include "nm-setting-cdma.h" #include "nm-dbus-manager.h" #include "nm-logging.h" #include "nm-posix-signals.h" +#include "nm-platform.h" +#include "nm-core-internal.h" static void impl_ppp_manager_need_secrets (NMPPPManager *manager, DBusGMethodInvocation *context); @@ -65,6 +61,10 @@ static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, GHashTable *config, GError **err); +static gboolean impl_ppp_manager_set_ip6_config (NMPPPManager *manager, + GHashTable *config, + GError **err); + #include "nm-ppp-manager-glue.h" static void _ppp_cleanup (NMPPPManager *manager); @@ -99,6 +99,7 @@ G_DEFINE_TYPE (NMPPPManager, nm_ppp_manager, G_TYPE_OBJECT) enum { STATE_CHANGED, IP4_CONFIG, + IP6_CONFIG, STATS, LAST_SIGNAL @@ -112,24 +113,10 @@ enum { LAST_PROP }; -typedef enum { - NM_PPP_MANAGER_ERROR_UNKOWN -} NMPPPManagerError; - -GQuark -nm_ppp_manager_error_quark (void) -{ - static GQuark quark; - - if (!quark) - quark = g_quark_from_static_string ("nm_ppp_manager_error"); - - return quark; -} - static void nm_ppp_manager_init (NMPPPManager *manager) { + NM_PPP_MANAGER_GET_PRIVATE (manager)->monitor_fd = -1; } static void @@ -218,11 +205,10 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) /* Properties */ g_object_class_install_property (object_class, PROP_PARENT_IFACE, - g_param_spec_string (NM_PPP_MANAGER_PARENT_IFACE, - "ParentIface", - "Parent interface", + g_param_spec_string (NM_PPP_MANAGER_PARENT_IFACE, "", "", NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); /* signals */ signals[STATE_CHANGED] = @@ -244,6 +230,14 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) G_TYPE_STRING, G_TYPE_OBJECT); + signals[IP6_CONFIG] = + g_signal_new ("ip6-config", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMPPPManagerClass, ip6_config), + NULL, NULL, NULL, + G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_OBJECT); + signals[STATS] = g_signal_new ("stats", G_OBJECT_CLASS_TYPE (object_class), @@ -299,8 +293,12 @@ monitor_stats (NMPPPManager *manager) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + /* already monitoring */ + if (priv->monitor_fd >= 0) + return; + priv->monitor_fd = socket (AF_INET, SOCK_DGRAM, 0); - if (priv->monitor_fd > 0) { + if (priv->monitor_fd >= 0) { g_warn_if_fail (priv->monitor_id == 0); if (priv->monitor_id) g_source_remove (priv->monitor_id); @@ -370,7 +368,8 @@ extract_details_from_connection (NMConnection *connection, setting = nm_connection_get_setting_by_name (connection, setting_name); if (!setting) { - g_set_error_literal (error, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR_UNKOWN, + /* This shouldn't ever happen */ + g_set_error_literal (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED, "Missing type-specific setting; no secrets could be found."); return FALSE; } @@ -425,7 +424,7 @@ ppp_secrets_cb (NMActRequest *req, /* This is sort of a hack but... * pppd plugin only ever needs username and password. Passing the full * connection there would mean some bloat: the plugin would need to link - * against libnm-util just to parse this. So instead, let's just send what + * against libnm just to parse this. So instead, let's just send what * it needs. */ dbus_g_method_return (priv->pending_secrets_context, username, password); @@ -447,7 +446,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, guint32 tries; GPtrArray *hints = NULL; GError *error = NULL; - NMSettingsGetSecretsFlags flags = NM_SETTINGS_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMSecretAgentGetSecretsFlags flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; connection = nm_act_request_get_connection (priv->act_req); @@ -473,7 +472,7 @@ impl_ppp_manager_need_secrets (NMPPPManager *manager, */ tries = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES)); if (tries > 1) - flags |= NM_SETTINGS_GET_SECRETS_FLAG_REQUEST_NEW; + flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; priv->secrets_id = nm_act_request_get_secrets (priv->act_req, priv->secrets_setting_name, @@ -498,19 +497,51 @@ static gboolean impl_ppp_manager_set_state (NMPPPManager *manager, } static gboolean +set_ip_config_common (NMPPPManager *self, + GHashTable *hash, + const char *iface_prop, + guint32 *out_mtu) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); + NMConnection *connection; + NMSettingPpp *s_ppp; + GValue *val; + + val = g_hash_table_lookup (hash, iface_prop); + if (!val || !G_VALUE_HOLDS_STRING (val)) { + nm_log_err (LOGD_PPP, "no interface received!"); + return FALSE; + } + if (priv->ip_iface == NULL) + priv->ip_iface = g_value_dup_string (val); + + /* Got successful IP config; obviously the secrets worked */ + connection = nm_act_request_get_connection (priv->act_req); + g_assert (connection); + g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); + + /* Get any custom MTU */ + s_ppp = nm_connection_get_setting_ppp (connection); + if (s_ppp && out_mtu) + *out_mtu = nm_setting_ppp_get_mtu (s_ppp); + + monitor_stats (self); + return TRUE; +} + +static gboolean impl_ppp_manager_set_ip4_config (NMPPPManager *manager, GHashTable *config_hash, GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); - NMConnection *connection; - NMSettingPPP *s_ppp; NMIP4Config *config; NMPlatformIP4Address address; GValue *val; int i; + guint32 mtu = 0; - nm_log_info (LOGD_PPP, "PPP manager(IP Config Get) reply received."); + nm_log_info (LOGD_PPP, "PPP manager (IPv4 Config Get) reply received."); remove_timeout_handler (manager); @@ -533,7 +564,7 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, address.plen = g_value_get_uint (val); if (address.address && address.plen) { - address.source = NM_PLATFORM_SOURCE_PPP; + address.source = NM_IP_CONFIG_SOURCE_PPP; nm_ip4_config_add_address (config, &address); } else { nm_log_err (LOGD_PPP, "invalid IPv4 address received!"); @@ -556,35 +587,89 @@ impl_ppp_manager_set_ip4_config (NMPPPManager *manager, nm_ip4_config_add_wins (config, g_array_index (wins, guint, i)); } - val = (GValue *) g_hash_table_lookup (config_hash, NM_PPP_IP4_CONFIG_INTERFACE); - if (!val || !G_VALUE_HOLDS_STRING (val)) { - nm_log_err (LOGD_PPP, "no interface received!"); + if (!set_ip_config_common (manager, config_hash, NM_PPP_IP4_CONFIG_INTERFACE, &mtu)) goto out; + + if (mtu) + nm_ip4_config_set_mtu (config, mtu, NM_IP_CONFIG_SOURCE_PPP); + + /* Push the IP4 config up to the device */ + g_signal_emit (manager, signals[IP4_CONFIG], 0, priv->ip_iface, config); + +out: + g_object_unref (config); + return TRUE; +} + +/* Converts the named Interface Identifier item to an IPv6 LL address and + * returns the IID. + */ +static gboolean +iid_value_to_ll6_addr (GHashTable *hash, + const char *prop, + struct in6_addr *out_addr, + NMUtilsIPv6IfaceId *out_iid) +{ + GValue *val; + guint64 iid; + + val = g_hash_table_lookup (hash, prop); + if (!val || !G_VALUE_HOLDS (val, G_TYPE_UINT64)) { + nm_log_dbg (LOGD_PPP, "pppd plugin property '%s' missing or not a uint64", prop); + return FALSE; } - priv->ip_iface = g_value_dup_string (val); - /* Got successful IP4 config; obviously the secrets worked */ - connection = nm_act_request_get_connection (priv->act_req); - g_assert (connection); - g_object_set_data (G_OBJECT (connection), PPP_MANAGER_SECRET_TRIES, NULL); + iid = g_value_get_uint64 (val); + g_return_val_if_fail (iid != 0, FALSE); - /* Merge in custom MTU */ - s_ppp = nm_connection_get_setting_ppp (connection); - if (s_ppp) { - guint32 mtu = nm_setting_ppp_get_mtu (s_ppp); + /* Construct an IPv6 LL address from the interface identifier. See + * http://tools.ietf.org/html/rfc4291#section-2.5.1 (IPv6) and + * http://tools.ietf.org/html/rfc5072#section-4.1 (IPv6 over PPP). + */ + memset (out_addr->s6_addr, 0, sizeof (out_addr->s6_addr)); + out_addr->s6_addr16[0] = htons (0xfe80); + memcpy (out_addr->s6_addr + 8, &iid, sizeof (iid)); + if (out_iid) + nm_utils_ipv6_interface_identfier_get_from_addr (out_iid, out_addr); + return TRUE; +} - if (mtu) - nm_ip4_config_set_mtu (config, mtu); +static gboolean +impl_ppp_manager_set_ip6_config (NMPPPManager *manager, + GHashTable *hash, + GError **err) +{ + NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager); + NMIP6Config *config; + NMPlatformIP6Address addr; + struct in6_addr a; + NMUtilsIPv6IfaceId iid = NM_UTILS_IPV6_IFACE_ID_INIT; + + nm_log_info (LOGD_PPP, "PPP manager (IPv6 Config Get) reply received."); + + remove_timeout_handler (manager); + + config = nm_ip6_config_new (); + + memset (&addr, 0, sizeof (addr)); + addr.plen = 64; + + if (iid_value_to_ll6_addr (hash, NM_PPP_IP6_CONFIG_PEER_IID, &a, NULL)) { + nm_ip6_config_set_gateway (config, &a); + addr.peer_address = a; } - /* Push the IP4 config up to the device */ - g_signal_emit (manager, signals[IP4_CONFIG], 0, priv->ip_iface, config); + if (iid_value_to_ll6_addr (hash, NM_PPP_IP6_CONFIG_OUR_IID, &addr.address, &iid)) { + nm_ip6_config_add_address (config, &addr); - monitor_stats (manager); + if (set_ip_config_common (manager, hash, NM_PPP_IP6_CONFIG_INTERFACE, NULL)) { + /* Push the IPv6 config and interface identifier up to the device */ + g_signal_emit (manager, signals[IP6_CONFIG], 0, priv->ip_iface, &iid, config); + } + } else + nm_log_err (LOGD_PPP, "invalid IPv6 address received!"); - out: g_object_unref (config); - return TRUE; } @@ -647,36 +732,6 @@ nm_cmd_line_add_int (NMCmdLine *cmd, int i) /*******************************************/ -static const char *pppd_binary_paths[] = { - PPPD_PATH, - "/usr/local/sbin/pppd", - "/usr/sbin/pppd", - "/sbin/pppd", - NULL -}; - -static const char *pppoe_binary_paths[] = { - PPPOE_PATH, - "/usr/local/sbin/pppoe", - "/usr/sbin/pppoe", - "/sbin/pppoe", - NULL -}; - -static inline const char * -nm_find_binary (const char *paths[]) -{ - const char **binary = paths; - - while (*binary != NULL) { - if (**binary && g_file_test (*binary, G_FILE_TEST_EXISTS)) - break; - binary++; - } - - return *binary; -} - static void ppp_exit_code (guint pppd_exit_status, GPid pid) { @@ -789,34 +844,28 @@ pppd_timed_out (gpointer data) static NMCmdLine * create_pppd_cmd_line (NMPPPManager *self, - NMSettingPPP *setting, - NMSettingPPPOE *pppoe, + NMSettingPpp *setting, + NMSettingPppoe *pppoe, NMSettingAdsl *adsl, const char *ppp_name, GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); - const char *pppd_binary, *pppoe_binary = NULL; + const char *pppd_binary = NULL, *pppoe_binary = NULL; NMCmdLine *cmd; gboolean ppp_debug; g_return_val_if_fail (setting != NULL, NULL); - pppd_binary = nm_find_binary (pppd_binary_paths); - if (!pppd_binary) { - g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR, - "Could not find pppd binary."); + pppd_binary = nm_utils_find_helper ("pppd", NULL, err); + if (!pppd_binary) return NULL; - } if ( pppoe || (adsl && strcmp (nm_setting_adsl_get_protocol (adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE))) { - pppoe_binary = nm_find_binary (pppoe_binary_paths); - if (!pppoe_binary) { - g_set_error (err, NM_PPP_MANAGER_ERROR, NM_PPP_MANAGER_ERROR, - "Could not find pppoe binary."); + pppoe_binary = nm_utils_find_helper ("pppoe", NULL, err); + if (!pppoe_binary) return NULL; - } } /* Create pppd command line */ @@ -888,7 +937,7 @@ create_pppd_cmd_line (NMPPPManager *self, if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_LLC) == 0) nm_cmd_line_add_string (cmd, "llc-encaps"); - else if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) == 0) + else /*if (g_strcmp0 (encaps, NM_SETTING_ADSL_ENCAPSULATION_VCMUX) == 0)*/ nm_cmd_line_add_string (cmd, "vc-encaps"); } else if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) { @@ -992,7 +1041,7 @@ pppd_child_setup (gpointer user_data G_GNUC_UNUSED) } static void -pppoe_fill_defaults (NMSettingPPP *setting) +pppoe_fill_defaults (NMSettingPpp *setting) { if (!nm_setting_ppp_get_mtu (setting)) g_object_set (setting, NM_SETTING_PPP_MTU, (guint32) 1492, NULL); @@ -1005,7 +1054,7 @@ pppoe_fill_defaults (NMSettingPPP *setting) NM_SETTING_PPP_NODEFLATE, TRUE, NULL); - /* FIXME: These commented settings should be set as well, update NMSettingPPP first. */ + /* FIXME: These commented settings should be set as well, update NMSettingPpp first. */ #if 0 setting->noipdefault = TRUE; setting->default_asyncmap = TRUE; @@ -1027,9 +1076,9 @@ nm_ppp_manager_start (NMPPPManager *manager, { NMPPPManagerPrivate *priv; NMConnection *connection; - NMSettingPPP *s_ppp; + NMSettingPpp *s_ppp; gboolean s_ppp_created = FALSE; - NMSettingPPPOE *pppoe_setting; + NMSettingPppoe *pppoe_setting; NMSettingAdsl *adsl_setting; NMCmdLine *ppp_cmd; char *cmd_str; @@ -1044,8 +1093,8 @@ nm_ppp_manager_start (NMPPPManager *manager, #if !WITH_PPP /* PPP support disabled */ g_set_error_literal (err, - NM_PPP_MANAGER_ERROR, - NM_PPP_MANAGER_ERROR_UNKOWN, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_FAILED, "PPP support is not enabled."); return FALSE; #endif @@ -1110,22 +1159,6 @@ out: return priv->pid > 0; } -static gboolean -ensure_killed (gpointer data) -{ - int pid = GPOINTER_TO_INT (data); - - if (kill (pid, 0) == 0) - kill (pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_PPP, "waiting for pppd pid %d to exit", pid); - waitpid (pid, NULL, 0); - nm_log_dbg (LOGD_PPP, "pppd pid %d cleaned up", pid); - - return FALSE; -} - static void _ppp_cleanup (NMPPPManager *manager) { @@ -1142,11 +1175,11 @@ _ppp_cleanup (NMPPPManager *manager) priv->monitor_id = 0; } - if (priv->monitor_fd) { + if (priv->monitor_fd >= 0) { /* Get the stats one last time */ monitor_cb (manager); close (priv->monitor_fd); - priv->monitor_fd = 0; + priv->monitor_fd = -1; } if (priv->ppp_timeout_handler) { @@ -1160,17 +1193,7 @@ _ppp_cleanup (NMPPPManager *manager) } if (priv->pid) { - if (kill (priv->pid, SIGTERM) == 0) - g_timeout_add_seconds (2, ensure_killed, GINT_TO_POINTER (priv->pid)); - else { - kill (priv->pid, SIGKILL); - - /* ensure the child is reaped */ - nm_log_dbg (LOGD_PPP, "waiting for pppd pid %d to exit", priv->pid); - waitpid (priv->pid, NULL, 0); - nm_log_dbg (LOGD_PPP, "pppd pid %d cleaned up", priv->pid); - } - + nm_utils_kill_child_async (priv->pid, SIGTERM, LOGD_PPP, "pppd", 2000, NULL, NULL); priv->pid = 0; } } diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index 1b4bc188..84be76d0 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -19,8 +19,8 @@ * Copyright (C) 2008 - 2010 Red Hat, Inc. */ -#ifndef NM_PPP_MANAGER_H -#define NM_PPP_MANAGER_H +#ifndef __NETWORKMANAGER_PPP_MANAGER_H__ +#define __NETWORKMANAGER_PPP_MANAGER_H__ #include <glib.h> #include <glib-object.h> @@ -29,7 +29,9 @@ #include "nm-activation-request.h" #include "nm-connection.h" #include "nm-ip4-config.h" +#include "nm-ip6-config.h" #include "nm-pppd-plugin.h" +#include "NetworkManagerUtils.h" #define NM_TYPE_PPP_MANAGER (nm_ppp_manager_get_type ()) #define NM_PPP_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PPP_MANAGER, NMPPPManager)) @@ -50,6 +52,10 @@ typedef struct { /* Signals */ void (*state_changed) (NMPPPManager *manager, NMPPPStatus status); void (*ip4_config) (NMPPPManager *manager, const char *iface, NMIP4Config *config); + void (*ip6_config) (NMPPPManager *manager, + const char *iface, + const NMUtilsIPv6IfaceId *iid, + NMIP6Config *config); void (*stats) (NMPPPManager *manager, guint32 in_bytes, guint32 out_bytes); } NMPPPManagerClass; @@ -64,9 +70,4 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager, GError **err); -#define NM_PPP_MANAGER_ERROR nm_ppp_manager_error_quark() -#define NM_TYPE_PPP_MANAGER_ERROR (nm_ppp_manager_error_get_type ()) - -GQuark nm_ppp_manager_error_quark (void); - -#endif /* NM_PPP_MANAGER_H */ +#endif /* __NETWORKMANAGER_PPP_MANAGER_H__ */ diff --git a/src/ppp-manager/nm-ppp-status.h b/src/ppp-manager/nm-ppp-status.h index cfc7c393..391b5aa9 100644 --- a/src/ppp-manager/nm-ppp-status.h +++ b/src/ppp-manager/nm-ppp-status.h @@ -19,8 +19,8 @@ * Copyright (C) 2008 Red Hat, Inc. */ -#ifndef NM_PPP_STATUS_H -#define NM_PPP_STATUS_H +#ifndef __NETWORKMANAGER_PPP_STATUS_H__ +#define __NETWORKMANAGER_PPP_STATUS_H__ typedef enum { NM_PPP_STATUS_UNKNOWN, @@ -40,4 +40,4 @@ typedef enum { NM_PPP_STATUS_MASTER } NMPPPStatus; -#endif /* NM_PPP_STATUS_H */ +#endif /* __NETWORKMANAGER_PPP_STATUS_H__ */ diff --git a/src/ppp-manager/nm-pppd-plugin.c b/src/ppp-manager/nm-pppd-plugin.c index e6ee86f7..d5e8d707 100644 --- a/src/ppp-manager/nm-pppd-plugin.c +++ b/src/ppp-manager/nm-pppd-plugin.c @@ -19,6 +19,8 @@ * Copyright (C) 2008 Red Hat, Inc. */ +#include "config.h" + #include <string.h> #include <pppd/pppd.h> #include <pppd/fsm.h> @@ -26,20 +28,22 @@ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <glib.h> -#include <glib-object.h> -#include <dbus/dbus-glib.h> +#include <dlfcn.h> +#include <gio/gio.h> + +#define INET6 +#include <pppd/eui64.h> +#include <pppd/ipv6cp.h> -#include "NetworkManager.h" +#include "nm-dbus-interface.h" #include "nm-pppd-plugin.h" #include "nm-ppp-status.h" -#include "nm-dbus-glib-types.h" int plugin_init (void); char pppd_version[] = VERSION; -static DBusGProxy *proxy = NULL; +static GDBusProxy *proxy = NULL; static void nm_phasechange (void *data, int arg) @@ -47,7 +51,7 @@ nm_phasechange (void *data, int arg) NMPPPStatus ppp_status = NM_PPP_STATUS_UNKNOWN; char *ppp_phase; - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); switch (arg) { case PHASE_DEAD: @@ -114,56 +118,24 @@ nm_phasechange (void *data, int arg) ppp_phase); if (ppp_status != NM_PPP_STATUS_UNKNOWN) { - dbus_g_proxy_call_no_reply (proxy, "SetState", - G_TYPE_UINT, ppp_status, G_TYPE_INVALID, - G_TYPE_INVALID); + g_dbus_proxy_call (proxy, + "SetState", + g_variant_new ("(u)", ppp_status), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + NULL, NULL); } } -static GValue * -str_to_gvalue (const char *str) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_STRING); - g_value_set_string (val, str); - - return val; -} - -static GValue * -uint_to_gvalue (guint32 i) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, G_TYPE_UINT); - g_value_set_uint (val, i); - - return val; -} - -static void -value_destroy (gpointer data) -{ - GValue *val = (GValue *) data; - - g_value_unset (val); - g_slice_free (GValue, val); -} - static void nm_ip_up (void *data, int arg) { ipcp_options opts = ipcp_gotoptions[0]; ipcp_options peer_opts = ipcp_hisoptions[0]; - GHashTable *hash; - GArray *array; - GValue *val; + GVariantBuilder builder; guint32 pppd_made_up_address = htonl (0x0a404040 + ifunit); - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); g_message ("nm-ppp-plugin: (%s): ip-up event", __func__); @@ -173,70 +145,122 @@ nm_ip_up (void *data, int arg) return; } - hash = g_hash_table_new_full (g_str_hash, g_str_equal, - NULL, value_destroy); + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_INTERFACE, - str_to_gvalue (ifname)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_INTERFACE, + g_variant_new_string (ifname)); - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_ADDRESS, - uint_to_gvalue (opts.ouraddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_ADDRESS, + g_variant_new_uint32 (opts.ouraddr)); /* Prefer the peer options remote address first, _unless_ pppd made the * address up, at which point prefer the local options remote address, * and if that's not right, use the made-up address as a last resort. */ if (peer_opts.hisaddr && (peer_opts.hisaddr != pppd_made_up_address)) { - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (peer_opts.hisaddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_GATEWAY, + g_variant_new_uint32 (peer_opts.hisaddr)); } else if (opts.hisaddr) { - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (opts.hisaddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_GATEWAY, + g_variant_new_uint32 (opts.hisaddr)); } else if (peer_opts.hisaddr == pppd_made_up_address) { /* As a last resort, use the made-up address */ - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_GATEWAY, - uint_to_gvalue (peer_opts.hisaddr)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_GATEWAY, + g_variant_new_uint32 (peer_opts.ouraddr)); } - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_PREFIX, uint_to_gvalue (32)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_PREFIX, + g_variant_new_uint32 (32)); if (opts.dnsaddr[0] || opts.dnsaddr[1]) { - array = g_array_new (FALSE, FALSE, sizeof (guint32)); + guint32 dns[2]; + int len = 0; if (opts.dnsaddr[0]) - g_array_append_val (array, opts.dnsaddr[0]); + dns[len++] = opts.dnsaddr[0]; if (opts.dnsaddr[1]) - g_array_append_val (array, opts.dnsaddr[1]); + dns[len++] = opts.dnsaddr[1]; - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UINT_ARRAY); - g_value_set_boxed (val, array); - - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_DNS, val); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_DNS, + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + dns, len, sizeof (guint32))); } if (opts.winsaddr[0] || opts.winsaddr[1]) { - array = g_array_new (FALSE, FALSE, sizeof (guint32)); + guint32 wins[2]; + int len = 0; if (opts.winsaddr[0]) - g_array_append_val (array, opts.winsaddr[0]); + wins[len++] = opts.winsaddr[0]; if (opts.winsaddr[1]) - g_array_append_val (array, opts.winsaddr[1]); - - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UINT_ARRAY); - g_value_set_boxed (val, array); + wins[len++] = opts.winsaddr[1]; - g_hash_table_insert (hash, NM_PPP_IP4_CONFIG_WINS, val); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP4_CONFIG_WINS, + g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, + wins, len, sizeof (guint32))); } - g_message ("nm-ppp-plugin: (%s): sending Ip4Config to NetworkManager...", __func__); + g_message ("nm-ppp-plugin: (%s): sending IPv4 config to NetworkManager...", __func__); + + g_dbus_proxy_call (proxy, + "SetIp4Config", + g_variant_new ("(a{sv})", &builder), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + NULL, NULL); +} + +static GVariant * +eui64_to_variant (eui64_t eui) +{ + guint64 iid; + + G_STATIC_ASSERT (sizeof (iid) == sizeof (eui)); - dbus_g_proxy_call_no_reply (proxy, "SetIp4Config", - DBUS_TYPE_G_MAP_OF_VARIANT, hash, G_TYPE_INVALID, - G_TYPE_INVALID); + memcpy (&iid, &eui, sizeof (eui)); + return g_variant_new_uint64 (iid); +} - g_hash_table_destroy (hash); +static void +nm_ip6_up (void *data, int arg) +{ + ipv6cp_options *ho = &ipv6cp_hisoptions[0]; + ipv6cp_options *go = &ipv6cp_gotoptions[0]; + GVariantBuilder builder; + + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); + + g_message ("nm-ppp-plugin: (%s): ip6-up event", __func__); + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP6_CONFIG_INTERFACE, + g_variant_new_string (ifname)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP6_CONFIG_OUR_IID, + eui64_to_variant (go->ourid)); + g_variant_builder_add (&builder, "{sv}", + NM_PPP_IP6_CONFIG_PEER_IID, + eui64_to_variant (ho->hisid)); + + /* DNS is done via DHCPv6 or router advertisements */ + + g_message ("nm-ppp-plugin: (%s): sending IPv6 config to NetworkManager...", __func__); + + g_dbus_proxy_call (proxy, + "SetIp6Config", + g_variant_new ("(a{sv})", &builder), + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, + NULL, NULL); } static int @@ -254,9 +278,10 @@ get_pap_check (void) static int get_credentials (char *username, char *password) { - char *my_username = NULL; - char *my_password = NULL; + const char *my_username = NULL; + const char *my_password = NULL; size_t len; + GVariant *ret; GError *err = NULL; if (!password) { @@ -266,15 +291,16 @@ get_credentials (char *username, char *password) } g_return_val_if_fail (username, -1); - g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), -1); + g_return_val_if_fail (G_IS_DBUS_PROXY (proxy), -1); g_message ("nm-ppp-plugin: (%s): passwd-hook, requesting credentials...", __func__); - if (!dbus_g_proxy_call (proxy, "NeedSecrets", &err, - G_TYPE_INVALID, - G_TYPE_STRING, &my_username, - G_TYPE_STRING, &my_password, - G_TYPE_INVALID)) { + ret = g_dbus_proxy_call_sync (proxy, + "NeedSecrets", + NULL, + G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &err); + if (!ret) { g_warning ("nm-ppp-plugin: (%s): could not get secrets: (%d) %s", __func__, err ? err->code : -1, @@ -285,14 +311,14 @@ get_credentials (char *username, char *password) g_message ("nm-ppp-plugin: (%s): got credentials from NetworkManager", __func__); + g_variant_get (ret, "(&s&s)", &my_username, &my_password); + if (my_username) { len = strlen (my_username) + 1; len = len < MAXNAMELEN ? len : MAXNAMELEN; strncpy (username, my_username, len); username[len - 1] = '\0'; - - g_free (my_username); } if (my_password) { @@ -301,17 +327,17 @@ get_credentials (char *username, char *password) strncpy (password, my_password, len); password[len - 1] = '\0'; - - g_free (my_password); } + g_variant_unref (ret); + return 1; } static void nm_exit_notify (void *data, int arg) { - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); g_message ("nm-ppp-plugin: (%s): cleaning up", __func__); @@ -319,10 +345,31 @@ nm_exit_notify (void *data, int arg) proxy = NULL; } +static void +add_ip6_notifier (void) +{ + static struct notifier **notifier = NULL; + static gsize load_once = 0; + + if (g_once_init_enter (&load_once)) { + void *handle = dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); + + if (handle) { + notifier = dlsym (handle, "ipv6_up_notifier"); + dlclose (handle); + } + g_once_init_leave (&load_once, 1); + } + if (notifier) + add_notifier (notifier, nm_ip6_up, NULL); + else + g_message ("nm-ppp-plugin: no IPV6CP notifier support; IPv6 not available"); +} + int plugin_init (void) { - DBusGConnection *bus; + GDBusConnection *bus; GError *err = NULL; #if !GLIB_CHECK_VERSION (2, 35, 0) @@ -331,12 +378,10 @@ plugin_init (void) g_message ("nm-ppp-plugin: (%s): initializing", __func__); - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &err); if (!bus) { - g_warning ("nm-pppd-plugin: (%s): couldn't connect to system bus: (%d) %s", - __func__, - err ? err->code : -1, - err && err->message ? err->message : "(unknown)"); + g_warning ("nm-pppd-plugin: (%s): couldn't connect to system bus: %s", + __func__, err->message); g_error_free (err); return -1; } @@ -344,9 +389,21 @@ plugin_init (void) /* NM passes in the object path of the corresponding PPPManager * object as the 'ipparam' argument to pppd. */ - proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE, ipparam, NM_DBUS_INTERFACE_PPP); - - dbus_g_connection_unref (bus); + proxy = g_dbus_proxy_new_sync (bus, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + NM_DBUS_SERVICE, + ipparam, + NM_DBUS_INTERFACE_PPP, + NULL, &err); + g_object_unref (bus); + + if (!proxy) { + g_warning ("nm-pppd-plugin: (%s): couldn't create D-Bus proxy: %s", + __func__, err->message); + g_error_free (err); + return -1; + } chap_passwd_hook = get_credentials; chap_check_hook = get_chap_check; @@ -356,6 +413,7 @@ plugin_init (void) add_notifier (&phasechange, nm_phasechange, NULL); add_notifier (&ip_up_notifier, nm_ip_up, NULL); add_notifier (&exitnotify, nm_exit_notify, proxy); + add_ip6_notifier (); return 0; } diff --git a/src/ppp-manager/nm-pppd-plugin.h b/src/ppp-manager/nm-pppd-plugin.h index 95a2a182..2c3073e4 100644 --- a/src/ppp-manager/nm-pppd-plugin.h +++ b/src/ppp-manager/nm-pppd-plugin.h @@ -16,14 +16,21 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 Red Hat, Inc. + * Copyright (C) 2008 - 2014 Red Hat, Inc. */ #define NM_DBUS_INTERFACE_PPP "org.freedesktop.NetworkManager.PPP" #define NM_PPP_IP4_CONFIG_INTERFACE "interface" -#define NM_PPP_IP4_CONFIG_ADDRESS "address" -#define NM_PPP_IP4_CONFIG_PREFIX "prefix" -#define NM_PPP_IP4_CONFIG_GATEWAY "gateway" -#define NM_PPP_IP4_CONFIG_DNS "dns" -#define NM_PPP_IP4_CONFIG_WINS "wins" +#define NM_PPP_IP4_CONFIG_ADDRESS "address" +#define NM_PPP_IP4_CONFIG_PREFIX "prefix" +#define NM_PPP_IP4_CONFIG_GATEWAY "gateway" +#define NM_PPP_IP4_CONFIG_DNS "dns" +#define NM_PPP_IP4_CONFIG_WINS "wins" + +#define NM_PPP_IP6_CONFIG_INTERFACE "interface" +#define NM_PPP_IP6_CONFIG_OUR_IID "our-iid" +#define NM_PPP_IP6_CONFIG_PEER_IID "peer-iid" + +#define DBUS_TYPE_EUI64 (dbus_g_type_get_collection ("GByteArray", G_TYPE_UINT8)) + |