static void
arping_watch_cb (GPid pid, gint status, gpointer user_data)
{
    AddressInfo *info = user_data;
    NMArpingManager *self = info->manager;
    NMArpingManagerPrivate *priv = NM_ARPING_MANAGER_GET_PRIVATE (self);
    const char *addr;

    info->pid = 0;
    info->watch = 0;
    addr = nm_utils_inet4_ntop (info->address, NULL);

    if (WIFEXITED (status)) {
        if (WEXITSTATUS (status) != 0) {
            _LOGD ("%s already used in the %s network",
                   addr, nm_platform_link_get_name (NM_PLATFORM_GET, priv->ifindex));
            info->duplicate = TRUE;
        } else
            _LOGD ("DAD succeeded for %s", addr);
    } else {
        _LOGD ("stopped unexpectedly with status %d for %s", status, addr);
    }

    if (++priv->completed == g_hash_table_size (priv->addresses)) {
        priv->state = STATE_PROBE_DONE;
        nm_clear_g_source (&priv->timer);
        g_signal_emit (self, signals[PROBE_TERMINATED], 0);
    }
}
static void
send_dnsmasq_update (NMDnsDnsmasq *self)
{
	NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);

	if (!priv->set_server_ex_args)
		return;

	if (priv->running) {
		_LOGD ("trying to update dnsmasq nameservers");

		nm_clear_g_cancellable (&priv->update_cancellable);
		priv->update_cancellable = g_cancellable_new ();

		g_dbus_proxy_call (priv->dnsmasq,
		                   "SetServersEx",
		                   priv->set_server_ex_args,
		                   G_DBUS_CALL_FLAGS_NONE,
		                   -1,
		                   priv->update_cancellable,
		                   (GAsyncReadyCallback) dnsmasq_update_done,
		                   self);
		g_clear_pointer (&priv->set_server_ex_args, g_variant_unref);
	} else
		_LOGD ("dnsmasq not found on the bus. The nameserver update will be sent when dnsmasq appears");
}
static NMActStageReturn
act_stage3_ip4_config_start (NMDevice *device,
                             NMIP4Config **out_config,
                             NMDeviceStateReason *reason)
{
	NMDeviceAdsl *self = NM_DEVICE_ADSL (device);
	NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
	NMConnection *connection;
	NMSettingAdsl *s_adsl;
	NMActRequest *req;
	GError *err = NULL;
	NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
	const char *ppp_iface;

	req = nm_device_get_act_request (device);
	g_assert (req);

	connection = nm_act_request_get_applied_connection (req);
	g_assert (req);

	s_adsl = nm_connection_get_setting_adsl (connection);
	g_assert (s_adsl);

	/* PPPoE uses the NAS interface, not the ATM interface */
	if (g_strcmp0 (nm_setting_adsl_get_protocol (s_adsl), NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) {
		g_assert (priv->nas_ifname);
		ppp_iface = priv->nas_ifname;

		_LOGD (LOGD_ADSL, "starting PPPoE on NAS interface %s", priv->nas_ifname);
	} else {
		ppp_iface = nm_device_get_iface (device);
		_LOGD (LOGD_ADSL, "starting PPPoA");
	}

	priv->ppp_manager = nm_ppp_manager_new (ppp_iface);
	if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_adsl_get_username (s_adsl), 30, &err)) {
		g_signal_connect (priv->ppp_manager, "state-changed",
		                  G_CALLBACK (ppp_state_changed),
		                  self);
		g_signal_connect (priv->ppp_manager, "ip4-config",
		                  G_CALLBACK (ppp_ip4_config),
		                  self);
		ret = NM_ACT_STAGE_RETURN_POSTPONE;
	} else {
		_LOGW (LOGD_ADSL, "PPP failed to start: %s", err->message);
		g_error_free (err);

		g_object_unref (priv->ppp_manager);
		priv->ppp_manager = NULL;

		*reason = NM_DEVICE_STATE_REASON_PPP_START_FAILED;
	}

	return ret;
}
static NMActStageReturn
act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason)
{
	NMDeviceAdsl *self = NM_DEVICE_ADSL (device);
	NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
	NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
	NMSettingAdsl *s_adsl;
	const char *protocol;

	g_assert (out_reason);

	s_adsl = nm_connection_get_setting_adsl (nm_device_get_applied_connection (device));
	g_assert (s_adsl);

	protocol = nm_setting_adsl_get_protocol (s_adsl);
	_LOGD (LOGD_ADSL, "using ADSL protocol '%s'", protocol);

	if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) {

		/* PPPoE needs RFC2684 bridging before we can do PPP over it */
		if (!br2684_create_iface (self, s_adsl)) {
			*out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED;
			goto done;
		}

		/* Set up the VCC */
		if (!br2684_assign_vcc (self, s_adsl)) {
			*out_reason = NM_DEVICE_STATE_REASON_BR2684_FAILED;
			goto done;
		}

		/* Watch for the 'nas' interface going away */
		g_signal_connect (nm_platform_get (), NM_PLATFORM_SIGNAL_LINK_CHANGED,
		                  G_CALLBACK (link_changed_cb),
		                  self);

		_LOGD (LOGD_ADSL, "ATM setup successful");

		/* otherwise we're good for stage3 */
		nm_platform_link_set_up (NM_PLATFORM_GET, priv->nas_ifindex, NULL);
		ret = NM_ACT_STAGE_RETURN_SUCCESS;

	} else if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) == 0) {
		/* PPPoA doesn't need anything special */
		ret = NM_ACT_STAGE_RETURN_SUCCESS;
	} else
		_LOGW (LOGD_ADSL, "unhandled ADSL protocol '%s'", protocol);

done:
	return ret;
}
static NMActStageReturn
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
{
	NMDeviceTeam *self = NM_DEVICE_TEAM (device);
	NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
	NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
	gs_free_error GError *error = NULL;
	NMConnection *connection;
	NMSettingTeam *s_team;
	const char *cfg;

	g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);

	ret = NM_DEVICE_CLASS (nm_device_team_parent_class)->act_stage1_prepare (device, reason);
	if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
		return ret;

	connection = nm_device_get_applied_connection (device);
	g_assert (connection);
	s_team = nm_connection_get_setting_team (connection);
	g_assert (s_team);

	if (priv->tdc) {
		/* If the existing teamd config is the same as we're about to use,
		 * then we can proceed.  If it's not the same, and we have a PID,
		 * kill it so we can respawn it with the right config.  If we don't
		 * have a PID, then we must fail.
		 */
		cfg = teamdctl_config_get_raw (priv->tdc);
		if (cfg && strcmp (cfg,  nm_setting_team_get_config (s_team)) == 0) {
			_LOGD (LOGD_TEAM, "using existing matching teamd config");
			return NM_ACT_STAGE_RETURN_SUCCESS;
		}

		if (!priv->teamd_pid) {
			_LOGD (LOGD_TEAM, "existing teamd config mismatch; killing existing via teamdctl");
			if (!teamd_kill (self, NULL, &error)) {
				_LOGW (LOGD_TEAM, "existing teamd config mismatch; failed to kill existing teamd: %s", error->message);
				*reason = NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED;
				return NM_ACT_STAGE_RETURN_FAILURE;
			}
		}

		_LOGD (LOGD_TEAM, "existing teamd config mismatch; respawning...");
		teamd_cleanup (device, TRUE);
	}

	return teamd_start (device, s_team) ?
		NM_ACT_STAGE_RETURN_POSTPONE : NM_ACT_STAGE_RETURN_FAILURE;
}
void
nm_connectivity_check_async (NMConnectivity      *self,
                             GAsyncReadyCallback  callback,
                             gpointer             user_data)
{
	NMConnectivityPrivate *priv;
	GSimpleAsyncResult *simple;

	g_return_if_fail (NM_IS_CONNECTIVITY (self));
	priv = NM_CONNECTIVITY_GET_PRIVATE (self);

	simple = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
	                                    nm_connectivity_check_async);

#if WITH_CONCHECK
	if (priv->uri && priv->interval) {
		SoupMessage *msg;
		ConCheckCbData *cb_data = g_slice_new (ConCheckCbData);

		msg = soup_message_new ("GET", priv->uri);
		soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT);
		/* Disable HTTP/1.1 keepalive; the connection should not persist */
		soup_message_headers_append (msg->request_headers, "Connection", "close");
		cb_data->simple = simple;
		cb_data->uri = g_strdup (priv->uri);
		cb_data->response = g_strdup (priv->response);

		/* For internal calls (periodic), remember the check-id at time of scheduling. */
		cb_data->check_id_when_scheduled = IS_PERIODIC_CHECK (callback) ? priv->check_id : 0;

		soup_session_queue_message (priv->soup_session,
		                            msg,
		                            nm_connectivity_check_cb,
		                            cb_data);
		priv->initial_check_obsoleted = TRUE;

		_LOGD ("check: send %srequest to '%s'", IS_PERIODIC_CHECK (callback) ? "periodic " : "", priv->uri);
		return;
	} else {
		g_warn_if_fail (!IS_PERIODIC_CHECK (callback));
		_LOGD ("check: faking request. Connectivity check disabled");
	}
#else
	_LOGD ("check: faking request. Compiled without connectivity-check support");
#endif

	g_simple_async_result_set_op_res_gssize (simple, priv->state);
	g_simple_async_result_complete_in_idle (simple);
	g_object_unref (simple);
}
int _pkg_plugin_get_library_path(const char *pkg_type, char *library_path)
{
	FILE *fp = NULL;
	char buffer[1024] = { 0 };

	if (pkg_type == NULL || library_path == NULL) {
		_LOGE("invalid argument\n");
		return -1;
	}

	fp = fopen(PKG_CONF_PATH, "r");
	if (fp == NULL) {
		_LOGE("no matching backendlib\n");
		return PKGMGR_R_ERROR;
	}

	char *path = NULL;
	while (fgets(buffer, 1024, fp) != NULL) {
		if (buffer[0] == '#')
			continue;

		_app_str_trim(buffer);

		if ((path = strstr(buffer, PKG_BACKENDLIB)) != NULL) {
			_LOGD("[%s]\n", buffer);
			_LOGD("[%s]\n", path);
			path = path + strlen(PKG_BACKENDLIB);
			_LOGD("[%s]\n", path);

			break;
		}

		memset(buffer, 0x00, 1024);
	}

	if (fp != NULL)
		fclose(fp);

	if (path == NULL) {
		_LOGE("no matching backendlib\n");
		return PKGMGR_R_ERROR;
	}

	snprintf(library_path, 1024, "%slib%s.so", path, pkg_type);

	return PKGMGR_R_OK;

}
Exemple #8
0
static NMPNetns *
_netns_new (GError **error)
{
	NMPNetns *self;
	int fd_net, fd_mnt;
	int errsv;

	fd_net = open (PROC_SELF_NS_NET, O_RDONLY);
	if (fd_net == -1) {
		errsv = errno;
		g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
		             "Failed opening netns: %s",
		             g_strerror (errsv));
		return NULL;
	}

	fd_mnt = open (PROC_SELF_NS_MNT, O_RDONLY);
	if (fd_mnt == -1) {
		errsv = errno;
		g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN,
		             "Failed opening mntns: %s",
		             g_strerror (errsv));
		close (fd_net);
		return NULL;
	}

	self = g_object_new (NMP_TYPE_NETNS,
	                     NMP_NETNS_FD_NET, fd_net,
	                     NMP_NETNS_FD_MNT, fd_mnt,
	                     NULL);

	_LOGD (self, "new netns (net:%d, mnt:%d)", fd_net, fd_mnt);

	return self;
}
static void
child_quit (NMDnsPlugin *plugin, gint status)
{
	NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
	NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
	gboolean failed = TRUE;
	int err;

	if (WIFEXITED (status)) {
		err = WEXITSTATUS (status);
		if (err) {
			_LOGW ("dnsmasq exited with error: %s",
			       nm_utils_dnsmasq_status_to_string (err, NULL, 0));
		} else {
			_LOGD ("dnsmasq exited normally");
			failed = FALSE;
		}
	} else if (WIFSTOPPED (status))
		_LOGW ("dnsmasq stopped unexpectedly with signal %d", WSTOPSIG (status));
	else if (WIFSIGNALED (status))
		_LOGW ("dnsmasq died with signal %d", WTERMSIG (status));
	else
		_LOGW ("dnsmasq died from an unknown cause");

	priv->running = FALSE;

	if (failed)
		g_signal_emit_by_name (self, NM_DNS_PLUGIN_FAILED);
}
static void
ppp_watch_cb (GPid pid, gint status, gpointer user_data)
{
	NMPPPManager *manager = NM_PPP_MANAGER (user_data);
	NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (manager);
	guint err;

	g_assert (pid == priv->pid);

	if (WIFEXITED (status)) {
		err = WEXITSTATUS (status);
		if (err != 0)
			ppp_exit_code (err, priv->pid);
	} else if (WIFSTOPPED (status)) {
		_LOGI ("pppd pid %d stopped unexpectedly with signal %d", priv->pid, WSTOPSIG (status));
	} else if (WIFSIGNALED (status)) {
		_LOGI ("pppd pid %d died with signal %d", priv->pid, WTERMSIG (status));
	} else
		_LOGI ("pppd pid %d died from an unknown cause", priv->pid);

	_LOGD ("pppd pid %d cleaned up", priv->pid);
	priv->pid = 0;
	priv->ppp_watch_id = 0;
	g_signal_emit (manager, signals[STATE_CHANGED], 0, NM_PPP_STATUS_DEAD);
}
/* Converts the named Interface Identifier item to an IPv6 LL address and
 * returns the IID.
 */
static gboolean
iid_value_to_ll6_addr (GVariant *dict,
                       const char *prop,
                       struct in6_addr *out_addr,
                       NMUtilsIPv6IfaceId *out_iid)
{
	guint64 iid;

	if (!g_variant_lookup (dict, prop, "t", &iid)) {
		_LOGD ("pppd plugin property '%s' missing or not a uint64", prop);
		return FALSE;
	}
	g_return_val_if_fail (iid != 0, FALSE);

	/* 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;
}
Exemple #12
0
static void
ifcfg_dir_changed (GFileMonitor *monitor,
                   GFile *file,
                   GFile *other_file,
                   GFileMonitorEvent event_type,
                   gpointer user_data)
{
	SettingsPluginIfcfg *plugin = SETTINGS_PLUGIN_IFCFG (user_data);
	char *path, *ifcfg_path;
	NMIfcfgConnection *connection;

	path = g_file_get_path (file);

	ifcfg_path = utils_detect_ifcfg_path (path, FALSE);
	_LOGD ("ifcfg_dir_changed(%s) = %d // %s", path, event_type, ifcfg_path ? ifcfg_path : "(none)");
	if (ifcfg_path) {
		connection = find_by_path (plugin, ifcfg_path);
		switch (event_type) {
		case G_FILE_MONITOR_EVENT_DELETED:
			if (connection)
				remove_connection (plugin, connection);
			break;
		case G_FILE_MONITOR_EVENT_CREATED:
		case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
			/* Update or new */
			update_connection (plugin, NULL, ifcfg_path, connection, TRUE, NULL, NULL);
			break;
		default:
			break;
		}
		g_free (ifcfg_path);
	}
	g_free (path);
}
static void
reload_tun_properties (NMDeviceTun *self)
{
	NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self);
	GObject *object = G_OBJECT (self);
	NMPlatformTunProperties props;

	if (!nm_platform_tun_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (NM_DEVICE (self)), &props)) {
		_LOGD (LOGD_HW, "could not read tun properties");
		return;
	}

	g_object_freeze_notify (object);

	if (priv->props.owner != props.owner)
		g_object_notify (object, NM_DEVICE_TUN_OWNER);
	if (priv->props.group != props.group)
		g_object_notify (object, NM_DEVICE_TUN_GROUP);
	if (priv->props.no_pi != props.no_pi)
		g_object_notify (object, NM_DEVICE_TUN_NO_PI);
	if (priv->props.vnet_hdr != props.vnet_hdr)
		g_object_notify (object, NM_DEVICE_TUN_VNET_HDR);
	if (priv->props.multi_queue != props.multi_queue)
		g_object_notify (object, NM_DEVICE_TUN_MULTI_QUEUE);

	memcpy (&priv->props, &props, sizeof (NMPlatformTunProperties));

	g_object_thaw_notify (object);
}
static void
constructed (GObject *object)
{
	NMFirewallManager *self = (NMFirewallManager *) object;
	NMFirewallManagerPrivate *priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);
	gs_free char *owner = NULL;
	gs_free_error GError *error = NULL;

	G_OBJECT_CLASS (nm_firewall_manager_parent_class)->constructed (object);

	priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
	                                             G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
	                                                 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
	                                             NULL,
	                                             FIREWALL_DBUS_SERVICE,
	                                             FIREWALL_DBUS_PATH,
	                                             FIREWALL_DBUS_INTERFACE_ZONE,
	                                             NULL, &error);
        if (priv->proxy) {
		g_signal_connect (priv->proxy, "notify::g-name-owner",
				  G_CALLBACK (name_owner_changed), self);
		owner = g_dbus_proxy_get_name_owner (priv->proxy);
		priv->running = (owner != NULL);
        } else {
                _LOGW (NULL, "could not connect to system D-Bus (%s)", error->message);
	}

	_LOGD (NULL, "firewall constructed (%srunning)", priv->running ? "" : "not");
}
void
nm_firewall_manager_cancel_call (NMFirewallManagerCallId call)
{
	NMFirewallManager *self;
	NMFirewallManagerPrivate *priv;
	CBInfo *info = call;
	gs_free_error GError *error = NULL;

	g_return_if_fail (info);
	g_return_if_fail (NM_IS_FIREWALL_MANAGER (info->self));

	self = info->self;
	priv = NM_FIREWALL_MANAGER_GET_PRIVATE (self);

	if (!g_hash_table_remove (priv->pending_calls, info))
		g_return_if_reached ();

	nm_utils_error_set_cancelled (&error, FALSE, "NMFirewallManager");

	_LOGD (info, "complete: cancel (%s)", error->message);

	_cb_info_callback (info, error);

	if (_cb_info_is_idle (info)) {
		g_source_remove (info->idle.id);
		_cb_info_free (info);
	} else {
		info->mode = CB_INFO_MODE_DBUS_COMPLETED;
		g_cancellable_cancel (info->dbus.cancellable);
		g_clear_object (&info->self);
	}
}
static void
teamd_process_watch_cb (GPid pid, gint status, gpointer user_data)
{
	NMDeviceTeam *self = NM_DEVICE_TEAM (user_data);
	NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
	NMDevice *device = NM_DEVICE (self);
	NMDeviceState state = nm_device_get_state (device);

	g_return_if_fail (priv->teamd_process_watch);

	_LOGD (LOGD_TEAM, "teamd died with status %d", status);
	priv->teamd_pid = 0;
	priv->teamd_process_watch = 0;

	/* If teamd quit within 5 seconds of starting, it's probably hosed
	 * and will just die again, so fail the activation.
	 */
	if (priv->teamd_timeout &&
	    (state >= NM_DEVICE_STATE_PREPARE) &&
	    (state <= NM_DEVICE_STATE_ACTIVATED)) {
		_LOGW (LOGD_TEAM, "teamd process quit unexpectedly; failing activation");
		teamd_cleanup (device, TRUE);
		nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
	}
}
static void
teamd_dbus_vanished (GDBusConnection *dbus_connection,
                     const gchar *name,
                     gpointer user_data)
{
	NMDeviceTeam *self = NM_DEVICE_TEAM (user_data);
	NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
	NMDevice *device = NM_DEVICE (self);
	NMDeviceState state = nm_device_get_state (device);

	g_return_if_fail (priv->teamd_dbus_watch);

	if (!priv->tdc) {
		/* g_bus_watch_name will always raise an initial signal, to indicate whether the
		 * name exists/not exists initially. Do not take this as a failure if it hadn't
		 * previously appeared.
		 */
		_LOGD (LOGD_TEAM, "teamd not on D-Bus (ignored)");
		return;
	}

	_LOGI (LOGD_TEAM, "teamd vanished from D-Bus");
	teamd_cleanup (device, TRUE);

	/* Attempt to respawn teamd */
	if (state >= NM_DEVICE_STATE_PREPARE && state <= NM_DEVICE_STATE_ACTIVATED) {
		NMConnection *connection = nm_device_get_applied_connection (device);

		g_assert (connection);
		if (!teamd_start (device, nm_connection_get_setting_team (connection)))
			nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED);
	}
}
Exemple #18
0
static gboolean
_nmp_netns_push_type (NMPNetns *self, int ns_types)
{
	NetnsInfo *info;
	char sbuf[100];

	_stack_ensure_init ();

	info = _stack_peek ();
	g_return_val_if_fail (info, FALSE);

	if (info->netns == self && info->ns_types == ns_types) {
		info->count++;
		_LOGt (self, "push#%u* %s (increase count to %d)",
		       _stack_size () - 1,
		       _ns_types_to_str (ns_types, ns_types, sbuf), info->count);
		return TRUE;
	}

	_LOGD (self, "push#%u %s",
	       _stack_size (),
	       _ns_types_to_str (ns_types,
	                         _stack_current_ns_types (self, ns_types),
	                         sbuf));

	if (!_netns_switch_push (self, ns_types))
		return FALSE;

	_stack_push (self, ns_types);
	return TRUE;
}
Exemple #19
0
gboolean
nmp_netns_pop (NMPNetns *self)
{
	NetnsInfo *info;
	int ns_types;

	g_return_val_if_fail (NMP_IS_NETNS (self), FALSE);

	_stack_ensure_init ();

	info = _stack_peek ();

	g_return_val_if_fail (info, FALSE);
	g_return_val_if_fail (info->netns == self, FALSE);

	if (info->count > 1) {
		info->count--;
		_LOGt (self, "pop#%u* (decrease count to %d)",
		       _stack_size () - 1, info->count);
		return TRUE;
	}
	g_return_val_if_fail (info->count == 1, FALSE);

	/* cannot pop the original netns. */
	g_return_val_if_fail (_stack_size () > 1, FALSE);

	_LOGD (self, "pop#%u", _stack_size () - 1);

	ns_types = info->ns_types;

	_stack_pop ();

	return _netns_switch_pop (self, ns_types);
}
static GObject*
constructor (GType type,
			 guint n_construct_params,
			 GObjectConstructParam *construct_params)
{
	GObject *object;
	NMDeviceAdsl *self;
	NMDeviceAdslPrivate *priv;

	object = G_OBJECT_CLASS (nm_device_adsl_parent_class)->constructor (type,
	                                                                    n_construct_params,
	                                                                    construct_params);
	if (!object)
		return NULL;

	self = NM_DEVICE_ADSL (object);
	priv = NM_DEVICE_ADSL_GET_PRIVATE (object);

	priv->atm_index = get_atm_index (nm_device_get_iface (NM_DEVICE (object)));
	if (priv->atm_index < 0) {
		_LOGE (LOGD_ADSL, "error reading ATM device index");
		g_object_unref (object);
		return NULL;
	} else
		_LOGD (LOGD_ADSL, "ATM device index %d", priv->atm_index);

	/* Poll the carrier */
	priv->carrier_poll_id = g_timeout_add_seconds (5, carrier_update_cb, object);

	return object;
}
/**
 * nm_active_connection_set_master:
 * @self: the #NMActiveConnection
 * @master: if the activation depends on another device (ie, bond or bridge
 * master to which this device will be enslaved) pass the #NMActiveConnection
 * that this activation request is a child of
 *
 * Sets the master active connection of @self.
 */
void
nm_active_connection_set_master (NMActiveConnection *self, NMActiveConnection *master)
{
	NMActiveConnectionPrivate *priv;

	g_return_if_fail (NM_IS_ACTIVE_CONNECTION (self));
	g_return_if_fail (NM_IS_ACTIVE_CONNECTION (master));

	priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);

	/* Master is write-once, and must be set before exporting the object */
	g_return_if_fail (priv->master == NULL);
	g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self)));
	if (priv->device) {
		/* Note, the master ActiveConnection may not yet have a device */
		g_return_if_fail (priv->device != nm_active_connection_get_device (master));
	}

	_LOGD ("set master %p, %s, state %s",
	       master,
	       nm_active_connection_get_settings_connection_id (master),
	       state_to_string (nm_active_connection_get_state (master)));

	priv->master = g_object_ref (master);
	g_signal_connect (priv->master,
	                  "notify::" NM_ACTIVE_CONNECTION_STATE,
	                  (GCallback) master_state_cb,
	                  self);

	check_master_ready (self);
}
static void
dhcp6_event_cb (sd_dhcp6_client *client, int event, gpointer user_data)
{
	NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data);
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);

	g_assert (priv->client6 == client);

	_LOGD ("client event %d", event);

	switch (event) {
	case SD_DHCP6_CLIENT_EVENT_RETRANS_MAX:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_TIMEOUT, NULL, NULL);
		break;
	case SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE:
	case SD_DHCP6_CLIENT_EVENT_STOP:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_FAIL, NULL, NULL);
		break;
	case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE:
	case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST:
		bound6_handle (self);
		break;
	default:
		_LOGW ("unhandled event %d", event);
		break;
	}
}
static void
dispatcher_done_cb (GObject *proxy, GAsyncResult *result, gpointer user_data)
{
	DispatchInfo *info = user_data;
	GVariant *ret;
	GVariantIter *results;
	GError *error = NULL;

	ret = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), result,
	                                  G_VARIANT_TYPE ("(a(sus))"),
	                                  &error);
	if (ret) {
		g_variant_get (ret, "(a(sus))", &results);
		dispatcher_results_process (info->request_id, info->action, results);
		g_variant_iter_free (results);
		g_variant_unref (ret);
	} else {
		if (_nm_dbus_error_has_name (error, "org.freedesktop.systemd1.LoadFailed")) {
			g_dbus_error_strip_remote_error (error);
			_LOGW ("(%u) failed to call dispatcher scripts: %s",
			       info->request_id, error->message);
		} else {
			_LOGD ("(%u) failed to call dispatcher scripts: %s",
			       info->request_id, error->message);
		}
		g_clear_error (&error);
	}

	if (info->callback)
		info->callback (info->request_id, info->user_data);

	dispatcher_info_cleanup (info);
}
static void
dispose (GObject *object)
{
	NMActiveConnection *self = NM_ACTIVE_CONNECTION (object);
	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);

	_LOGD ("disposing");

	if (priv->chain) {
		nm_auth_chain_unref (priv->chain);
		priv->chain = NULL;
	}

	g_free (priv->specific_object);
	priv->specific_object = NULL;

	_set_settings_connection (self, NULL);
	g_clear_object (&priv->applied_connection);

	_device_cleanup (self);

	if (priv->master) {
		g_signal_handlers_disconnect_by_func (priv->master,
		                                      (GCallback) master_state_cb,
		                                      self);
	}
	g_clear_object (&priv->master);

	if (priv->parent)
		unwatch_parent (self);

	g_clear_object (&priv->subject);

	G_OBJECT_CLASS (nm_active_connection_parent_class)->dispose (object);
}
static void
dhcp_event_cb (sd_dhcp_client *client, int event, gpointer user_data)
{
	NMDhcpSystemd *self = NM_DHCP_SYSTEMD (user_data);
	NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self);

	g_assert (priv->client4 == client);

	_LOGD ("client event %d", event);

	switch (event) {
	case SD_DHCP_CLIENT_EVENT_EXPIRED:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_EXPIRE, NULL, NULL);
		break;
	case SD_DHCP_CLIENT_EVENT_STOP:
		nm_dhcp_client_set_state (NM_DHCP_CLIENT (user_data), NM_DHCP_STATE_FAIL, NULL, NULL);
		break;
	case SD_DHCP_CLIENT_EVENT_RENEW:
	case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
	case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
		bound4_handle (self);
		break;
	default:
		_LOGW ("unhandled DHCP event %d", event);
		break;
	}
}
static NMActStageReturn
act_stage2_config (NMDevice *device, NMDeviceStateReason *out_reason)
{
	NMDeviceAdsl *self = NM_DEVICE_ADSL (device);
	NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE;
	NMSettingAdsl *s_adsl;
	const char *protocol;

	g_assert (out_reason);

	s_adsl = nm_connection_get_setting_adsl (nm_device_get_applied_connection (device));
	g_assert (s_adsl);

	protocol = nm_setting_adsl_get_protocol (s_adsl);
	_LOGD (LOGD_ADSL, "using ADSL protocol '%s'", protocol);

	if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE) == 0) {
		/* PPPoE needs RFC2684 bridging before we can do PPP over it */
		ret = br2684_create_iface (self, s_adsl, out_reason);
	} else if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA) == 0) {
		/* PPPoA doesn't need anything special */
		ret = NM_ACT_STAGE_RETURN_SUCCESS;
	} else
		_LOGW (LOGD_ADSL, "unhandled ADSL protocol '%s'", protocol);

	return ret;
}
static gboolean
pppoe_vcc_config (NMDeviceAdsl *self)
{
	NMDeviceAdslPrivate *priv = NM_DEVICE_ADSL_GET_PRIVATE (self);
	NMDevice *device = NM_DEVICE (self);
	NMSettingAdsl *s_adsl;

	s_adsl = nm_connection_get_setting_adsl (nm_device_get_applied_connection (device));
	g_assert (s_adsl);

	/* Set up the VCC */
	if (!br2684_assign_vcc (self, s_adsl))
		return FALSE;

	/* Watch for the 'nas' interface going away */
	g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED,
	                  G_CALLBACK (link_changed_cb),
	                  self);

	_LOGD (LOGD_ADSL, "ATM setup successful");

	/* otherwise we're good for stage3 */
	nm_platform_link_set_up (NM_PLATFORM_GET, priv->nas_ifindex, NULL);

	return TRUE;
}
static gboolean
arping_timeout_cb (gpointer user_data)
{
    NMArpingManager *self = user_data;
    NMArpingManagerPrivate *priv = NM_ARPING_MANAGER_GET_PRIVATE (self);
    GHashTableIter iter;
    AddressInfo *info;

    priv->timer = 0;

    g_hash_table_iter_init (&iter, priv->addresses);
    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) {
        nm_clear_g_source (&info->watch);
        if (info->pid) {
            _LOGD ("DAD timed out for %s",
                   nm_utils_inet4_ntop (info->address, NULL));
            nm_utils_kill_child_async (info->pid, SIGTERM, LOGD_IP4,
                                       "arping", 1000, NULL, NULL);
            info->pid = 0;
        }
    }

    priv->state = STATE_PROBE_DONE;
    g_signal_emit (self, signals[PROBE_TERMINATED], 0);

    return G_SOURCE_REMOVE;
}
static void
dispatcher_dir_changed (GFileMonitor *monitor,
                        GFile *file,
                        GFile *other_file,
                        GFileMonitorEvent event_type,
                        Monitor *item)
{
	const char *name;
	char *full_name;
	GDir *dir;
	GError *error = NULL;

	dir = g_dir_open (item->dir, 0, &error);
	if (dir) {
		int errsv = 0;

		item->has_scripts = FALSE;
		errno = 0;
		while (!item->has_scripts
		    && (name = g_dir_read_name (dir))) {
			full_name = g_build_filename (item->dir, name, NULL);
			item->has_scripts = g_file_test (full_name, G_FILE_TEST_IS_EXECUTABLE);
			g_free (full_name);
		}
		errsv = errno;
		g_dir_close (dir);
		if (item->has_scripts)
			_LOGD ("%s script directory '%s' has scripts", item->description, item->dir);
		else if (errsv == 0)
			_LOGD ("%s script directory '%s' has no scripts", item->description, item->dir);
		else {
			_LOGD ("%s script directory '%s' error reading (%s)", item->description, item->dir, strerror (errsv));
			item->has_scripts = TRUE;
		}
	} else {
		if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT)) {
			_LOGD ("%s script directory '%s' does not exist", item->description, item->dir);
			item->has_scripts = FALSE;
		} else {
			_LOGD ("%s script directory '%s' error (%s)", item->description, item->dir, error->message);
			item->has_scripts = TRUE;
		}
		g_error_free (error);
	}

}
void
nm_active_connection_set_state (NMActiveConnection *self,
                                NMActiveConnectionState new_state)
{
	NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
	NMActiveConnectionState old_state;

	if (priv->state == new_state)
		return;

	/* DEACTIVATED is a terminal state */
	if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED)
		g_return_if_fail (new_state != NM_ACTIVE_CONNECTION_STATE_DEACTIVATED);

	_LOGD ("set state %s (was %s)",
	       state_to_string (new_state),
	       state_to_string (priv->state));

	old_state = priv->state;
	priv->state = new_state;
	priv->state_set = TRUE;
	_notify (self, PROP_STATE);

	check_master_ready (self);

	if (   new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
	    || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
		nm_settings_connection_update_timestamp (priv->settings_connection,
		                                         (guint64) time (NULL), TRUE);
	}

	if (priv->device) {
		if (   old_state < NM_ACTIVE_CONNECTION_STATE_ACTIVATED
		    && new_state >= NM_ACTIVE_CONNECTION_STATE_ACTIVATED &&
		    priv->pending_activation_id)
		{
			nm_device_remove_pending_action (priv->device, priv->pending_activation_id, TRUE);
			g_clear_pointer (&priv->pending_activation_id, g_free);
		}
	}

	if (   new_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED
	    || old_state == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
		_notify (self, PROP_IP4_CONFIG);
		_notify (self, PROP_DHCP4_CONFIG);
		_notify (self, PROP_IP6_CONFIG);
		_notify (self, PROP_DHCP6_CONFIG);
	}

	if (priv->state == NM_ACTIVE_CONNECTION_STATE_DEACTIVATED) {
		/* Device is no longer relevant when deactivated. So remove it and
		 * emit property change notification so clients re-read the value,
		 * which will be NULL due to conditions in get_property().
		 */
		_device_cleanup (self);
		_notify (self, PROP_DEVICES);
	}
}