/**
 * nm_arping_manager_start_probe:
 * @self: a #NMArpingManager
 * @timeout: maximum probe duration in milliseconds
 * @error: location to store error, or %NULL
 *
 * Start probing IP addresses for duplicates; when the probe terminates a
 * PROBE_TERMINATED signal is emitted.
 *
 * Returns: %TRUE on success, %FALSE on failure
 */
gboolean
nm_arping_manager_start_probe (NMArpingManager *self, guint timeout, GError **error)
{
    const char *argv[] = { NULL, "-D", "-q", "-I", NULL, "-c", NULL, "-w", NULL, NULL, NULL };
    NMArpingManagerPrivate *priv;
    GHashTableIter iter;
    AddressInfo *info;
    gs_free char *timeout_str = NULL;

    g_return_val_if_fail (NM_IS_ARPING_MANAGER (self), FALSE);
    g_return_val_if_fail (!error || !*error, FALSE);
    g_return_val_if_fail (timeout, FALSE);

    priv = NM_ARPING_MANAGER_GET_PRIVATE (self);
    g_return_val_if_fail (priv->state == STATE_INIT, FALSE);

    argv[4] = nm_platform_link_get_name (NM_PLATFORM_GET, priv->ifindex);
    g_return_val_if_fail (argv[4], FALSE);

    priv->completed = 0;

    argv[0] = nm_utils_find_helper ("arping", NULL, NULL);
    if (!argv[0]) {
        g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
                             "arping could not be found");
        return FALSE;
    }

    timeout_str = g_strdup_printf ("%u", timeout / 1000 + 2);
    argv[6] = timeout_str;
    argv[8] = timeout_str;

    g_hash_table_iter_init (&iter, priv->addresses);

    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) {
        gs_free char *tmp_str = NULL;
        gboolean success;

        argv[9] = nm_utils_inet4_ntop (info->address, NULL);
        _LOGD ("run %s", (tmp_str = g_strjoinv (" ", (char **) argv)));

        success = g_spawn_async (NULL, (char **) argv, NULL,
                                 G_SPAWN_STDOUT_TO_DEV_NULL |
                                 G_SPAWN_STDERR_TO_DEV_NULL |
                                 G_SPAWN_DO_NOT_REAP_CHILD,
                                 NULL, NULL, &info->pid, NULL);

        info->watch = g_child_watch_add (info->pid, arping_watch_cb, info);
    }

    priv->timer = g_timeout_add (timeout, arping_timeout_cb, self);
    priv->state = STATE_PROBING;

    return TRUE;
}
static void
send_announcements (NMArpingManager *self, const char *mode_arg)
{
    NMArpingManagerPrivate *priv = NM_ARPING_MANAGER_GET_PRIVATE (self);
    const char *argv[] = { NULL, mode_arg, "-q", "-I", NULL, "-c", "1", NULL, NULL };
    int ip_arg = G_N_ELEMENTS (argv) - 2;
    GError *error = NULL;
    GHashTableIter iter;
    AddressInfo *info;

    argv[4] = nm_platform_link_get_name (NM_PLATFORM_GET, priv->ifindex);
    g_return_if_fail (argv[4]);

    argv[0] = nm_utils_find_helper ("arping", NULL, NULL);
    if (!argv[0]) {
        _LOGW ("arping could not be found; no ARPs will be sent");
        return;
    }

    g_hash_table_iter_init (&iter, priv->addresses);

    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &info)) {
        gs_free char *tmp_str = NULL;
        gboolean success;

        if (info->duplicate)
            continue;

        argv[ip_arg] = nm_utils_inet4_ntop (info->address, NULL);
        _LOGD ("run %s", (tmp_str = g_strjoinv (" ", (char **) argv)));

        success = g_spawn_async (NULL, (char **) argv, NULL,
                                 G_SPAWN_STDOUT_TO_DEV_NULL |
                                 G_SPAWN_STDERR_TO_DEV_NULL,
                                 NULL, NULL, NULL, &error);
        if (!success) {
            _LOGW ("could not send ARP for address %s: %s", argv[ip_arg],
                   error->message);
            g_clear_error (&error);
        }
    }
}
示例#3
0
static gboolean
run_helper (char **argv, guint which, gpointer user_data, GError **error)
{
	const char *helper_path;
	int exit_status = 0;
	gboolean success;
	char *errmsg = NULL, *outmsg = NULL;
	char *cmdline;

	helper_path = nm_utils_find_helper ((which == DCBTOOL) ? "dcbtool" : "fcoeadm", NULL, error);
	if (!helper_path)
		return FALSE;

	argv[0] = (char *) helper_path;
	cmdline = g_strjoinv (" ", argv);
	nm_log_dbg (LOGD_DCB, "%s", cmdline);

	success = g_spawn_sync ("/", argv, NULL, 0 /*G_SPAWN_DEFAULT*/,
	                        NULL, NULL,
	                        &outmsg, &errmsg, &exit_status, error);
	/* Log any stderr output */
	if (success && WIFEXITED (exit_status) && WEXITSTATUS (exit_status) && (errmsg || outmsg)) {
		gboolean ignore_error = FALSE;

		/* Ignore fcoeadm "success" errors like when FCoE is already set up */
		if (errmsg && strstr (errmsg, "Connection already created"))
			ignore_error = TRUE;

		if (ignore_error == FALSE) {
			nm_log_warn (LOGD_DCB, "'%s' failed: '%s'",
			             cmdline, (errmsg && strlen (errmsg)) ? errmsg : outmsg);
			g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_FAILED,
			             "Failed to run '%s'", cmdline);
			success = FALSE;
		}
	}

	g_free (outmsg);
	g_free (errmsg);
	g_free (cmdline);
	return success;
}
static gboolean
teamd_kill (NMDeviceTeam *self, const char *teamd_binary, GError **error)
{
	gs_unref_ptrarray GPtrArray *argv = NULL;
	gs_free char *tmp_str = NULL;

	if (!teamd_binary) {
		teamd_binary = nm_utils_find_helper ("teamd", NULL, error);
		if (!teamd_binary) {
			_LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found");
			return FALSE;
		}
	}

	argv = g_ptr_array_new ();
	g_ptr_array_add (argv, (gpointer) teamd_binary);
	g_ptr_array_add (argv, (gpointer) "-k");
	g_ptr_array_add (argv, (gpointer) "-t");
	g_ptr_array_add (argv, (gpointer) nm_device_get_iface (NM_DEVICE (self)));
	g_ptr_array_add (argv, NULL);

	_LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata)));
	return g_spawn_sync ("/", (char **) argv->pdata, NULL, 0, NULL, NULL, NULL, NULL, NULL, error);
}
示例#5
0
static NMCmdLine *
create_pppd_cmd_line (NMPPPManager *self,
                      NMSettingPpp *setting,
                      NMSettingPppoe *pppoe,
                      NMSettingAdsl  *adsl,
                      const char *ppp_name,
                      GError **err)
{
	NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self);
	const char *pppd_binary = NULL;
	NMCmdLine *cmd;
	gboolean ppp_debug;

	g_return_val_if_fail (setting != NULL, NULL);

	pppd_binary = nm_utils_find_helper ("pppd", NULL, err);
	if (!pppd_binary)
		return NULL;

	/* Create pppd command line */
	cmd = nm_cmd_line_new ();
	nm_cmd_line_add_string (cmd, pppd_binary);

	nm_cmd_line_add_string (cmd, "nodetach");
	nm_cmd_line_add_string (cmd, "lock");

	/* NM handles setting the default route */
	nm_cmd_line_add_string (cmd, "nodefaultroute");

	/* Allow IPv6 to be configured by IPV6CP */
	nm_cmd_line_add_string (cmd, "ipv6");
	nm_cmd_line_add_string (cmd, ",");

	ppp_debug = !!getenv ("NM_PPP_DEBUG");
	if (nm_logging_enabled (LOGL_DEBUG, LOGD_PPP))
		ppp_debug = TRUE;

	if (ppp_debug)
		nm_cmd_line_add_string (cmd, "debug");

	if (ppp_name) {
		nm_cmd_line_add_string (cmd, "user");
		nm_cmd_line_add_string (cmd, ppp_name);
	}

	if (pppoe) {
		char *dev_str;
		const char *pppoe_service;

		nm_cmd_line_add_string (cmd, "plugin");
		nm_cmd_line_add_string (cmd, "rp-pppoe.so");

		dev_str = g_strdup_printf ("nic-%s", priv->parent_iface);
		nm_cmd_line_add_string (cmd, dev_str);
		g_free (dev_str);

		pppoe_service = nm_setting_pppoe_get_service (pppoe);
		if (pppoe_service) {
			nm_cmd_line_add_string (cmd, "rp_pppoe_service");
			nm_cmd_line_add_string (cmd, pppoe_service);
		}
	} else if (adsl) {
		const gchar *protocol = nm_setting_adsl_get_protocol (adsl);

		if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA)) {
			guint32 vpi = nm_setting_adsl_get_vpi (adsl);
			guint32 vci = nm_setting_adsl_get_vci (adsl);
			const char *encaps = nm_setting_adsl_get_encapsulation (adsl);
			gchar *vpivci;

			nm_cmd_line_add_string (cmd, "plugin");
			nm_cmd_line_add_string (cmd, "pppoatm.so");

			vpivci = g_strdup_printf("%d.%d", vpi, vci);
			nm_cmd_line_add_string (cmd, vpivci);
			g_free (vpivci);

			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)*/
				nm_cmd_line_add_string (cmd, "vc-encaps");

		} else if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOE)) {
			nm_cmd_line_add_string (cmd, "plugin");
			nm_cmd_line_add_string (cmd, "rp-pppoe.so");
			nm_cmd_line_add_string (cmd, priv->parent_iface);
		}

		nm_cmd_line_add_string (cmd, "noipdefault");
	} else {
		nm_cmd_line_add_string (cmd, priv->parent_iface);
		/* Don't send some random address as the local address */
		nm_cmd_line_add_string (cmd, "noipdefault");
	}

	if (nm_setting_ppp_get_baud (setting))
		nm_cmd_line_add_int (cmd, nm_setting_ppp_get_baud (setting));

	/* noauth by default, because we certainly don't have any information
	 * with which to verify anything the peer gives us if we ask it to
	 * authenticate itself, which is what 'auth' really means.
	 */
	nm_cmd_line_add_string (cmd, "noauth");

	if (nm_setting_ppp_get_refuse_eap (setting))
		nm_cmd_line_add_string (cmd, "refuse-eap");
	if (nm_setting_ppp_get_refuse_pap (setting))
		nm_cmd_line_add_string (cmd, "refuse-pap");
	if (nm_setting_ppp_get_refuse_chap (setting))
		nm_cmd_line_add_string (cmd, "refuse-chap");
	if (nm_setting_ppp_get_refuse_mschap (setting))
		nm_cmd_line_add_string (cmd, "refuse-mschap");
	if (nm_setting_ppp_get_refuse_mschapv2 (setting))
		nm_cmd_line_add_string (cmd, "refuse-mschap-v2");
	if (nm_setting_ppp_get_nobsdcomp (setting))
		nm_cmd_line_add_string (cmd, "nobsdcomp");
	if (nm_setting_ppp_get_no_vj_comp (setting))
		nm_cmd_line_add_string (cmd, "novj");
	if (nm_setting_ppp_get_nodeflate (setting))
		nm_cmd_line_add_string (cmd, "nodeflate");
	if (nm_setting_ppp_get_require_mppe (setting))
		nm_cmd_line_add_string (cmd, "require-mppe");
	if (nm_setting_ppp_get_require_mppe_128 (setting))
		nm_cmd_line_add_string (cmd, "require-mppe-128");
	if (nm_setting_ppp_get_mppe_stateful (setting))
		nm_cmd_line_add_string (cmd, "mppe-stateful");
	if (nm_setting_ppp_get_crtscts (setting))
		nm_cmd_line_add_string (cmd, "crtscts");

	/* Always ask for DNS, we don't have to use them if the connection
	 * overrides the returned servers.
	 */
	nm_cmd_line_add_string (cmd, "usepeerdns");

	if (nm_setting_ppp_get_mru (setting)) {
		nm_cmd_line_add_string (cmd, "mru");
		nm_cmd_line_add_int (cmd, nm_setting_ppp_get_mru (setting));
	}

	if (nm_setting_ppp_get_mtu (setting)) {
		nm_cmd_line_add_string (cmd, "mtu");
		nm_cmd_line_add_int (cmd, nm_setting_ppp_get_mtu (setting));
	}

	nm_cmd_line_add_string (cmd, "lcp-echo-failure");
	nm_cmd_line_add_int (cmd, nm_setting_ppp_get_lcp_echo_failure (setting));

	nm_cmd_line_add_string (cmd, "lcp-echo-interval");
	nm_cmd_line_add_int (cmd, nm_setting_ppp_get_lcp_echo_interval (setting));

	/* Avoid pppd to exit if no traffic going through */
	nm_cmd_line_add_string (cmd, "idle");
	nm_cmd_line_add_int (cmd, 0);

	nm_cmd_line_add_string (cmd, "ipparam");
	nm_cmd_line_add_string (cmd, nm_exported_object_get_path (NM_EXPORTED_OBJECT (self)));

	nm_cmd_line_add_string (cmd, "plugin");
	nm_cmd_line_add_string (cmd, NM_PPPD_PLUGIN);

	return cmd;
}
示例#6
0
static gboolean
update (NMDnsPlugin *plugin,
        const GSList *vpn_configs,
        const GSList *dev_configs,
        const GSList *other_configs,
        const NMGlobalDnsConfig *global_config,
        const char *hostname)
{
	NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin);
	const char *dm_binary;
	GString *conf;
	GSList *iter;
	const char *argv[15];
	GError *error = NULL;
	int ignored;
	GPid pid = 0;
	guint idx = 0;

	/* Kill the old dnsmasq; there doesn't appear to be a way to get dnsmasq
	 * to reread the config file using SIGHUP or similar.  This is a small race
	 * here when restarting dnsmasq when DNS requests could go to the upstream
	 * servers instead of to dnsmasq.
	 */
	nm_dns_plugin_child_kill (plugin);

	dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, NULL);
	if (!dm_binary) {
		nm_log_warn (LOGD_DNS, "Could not find dnsmasq binary");
		return FALSE;
	}

	/* Build up the new dnsmasq config file */
	conf = g_string_sized_new (150);

	if (global_config)
		add_global_config (conf, global_config);
	else {
		/* Use split DNS for VPN configs */
		for (iter = (GSList *) vpn_configs; iter; iter = g_slist_next (iter)) {
			if (NM_IS_IP4_CONFIG (iter->data))
				add_ip4_config (conf, NM_IP4_CONFIG (iter->data), TRUE);
			else if (NM_IS_IP6_CONFIG (iter->data))
				add_ip6_config (conf, NM_IP6_CONFIG (iter->data), TRUE);
		}

		/* Now add interface configs without split DNS */
		for (iter = (GSList *) dev_configs; iter; iter = g_slist_next (iter)) {
			if (NM_IS_IP4_CONFIG (iter->data))
				add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE);
			else if (NM_IS_IP6_CONFIG (iter->data))
				add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE);
		}

		/* And any other random configs */
		for (iter = (GSList *) other_configs; iter; iter = g_slist_next (iter)) {
			if (NM_IS_IP4_CONFIG (iter->data))
				add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE);
			else if (NM_IS_IP6_CONFIG (iter->data))
				add_ip6_config (conf, NM_IP6_CONFIG (iter->data), FALSE);
		}
	}

	/* Write out the config file */
	if (!g_file_set_contents (CONFFILE, conf->str, -1, &error)) {
		nm_log_warn (LOGD_DNS, "Failed to write dnsmasq config file %s: (%d) %s",
		             CONFFILE,
		             error ? error->code : -1,
		             error && error->message ? error->message : "(unknown)");
		g_clear_error (&error);
		goto out;
	}
	ignored = chmod (CONFFILE, 0644);

	nm_log_dbg (LOGD_DNS, "dnsmasq local caching DNS configuration:");
	nm_log_dbg (LOGD_DNS, "%s", conf->str);

	argv[idx++] = dm_binary;
	argv[idx++] = "--no-resolv";  /* Use only commandline */
	argv[idx++] = "--keep-in-foreground";
	argv[idx++] = "--no-hosts"; /* don't use /etc/hosts to resolve */
	argv[idx++] = "--bind-interfaces";
	argv[idx++] = "--pid-file=" PIDFILE;
	argv[idx++] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
	argv[idx++] = "--conf-file=" CONFFILE;
	argv[idx++] = "--cache-size=400";
	argv[idx++] = "--proxy-dnssec"; /* Allow DNSSEC to pass through */

	/* dnsmasq exits if the conf dir is not present */
	if (g_file_test (CONFDIR, G_FILE_TEST_IS_DIR))
		argv[idx++] = "--conf-dir=" CONFDIR;

	argv[idx++] = NULL;
	g_warn_if_fail (idx <= G_N_ELEMENTS (argv));

	/* And finally spawn dnsmasq */
	pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq");

out:
	g_string_free (conf, TRUE);
	return pid ? TRUE : FALSE;
}
static NMCmdLine *
create_dm_cmd_line (const char *iface,
                    NMIP4Config *ip4_config,
                    const char *pidfile,
                    GError **error)
{
	NMCmdLine *cmd;
	GString *s;
	const NMPlatformIP4Address *tmp;
	char first[INET_ADDRSTRLEN];
	char last[INET_ADDRSTRLEN];
	char localaddr[INET_ADDRSTRLEN];
	char *error_desc = NULL;
	const char *dm_binary;

	dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, error);
	if (!dm_binary)
		return NULL;

	/* Create dnsmasq command line */
	cmd = nm_cmd_line_new ();
	nm_cmd_line_add_string (cmd, dm_binary);

	if (getenv ("NM_DNSMASQ_DEBUG")) {
		nm_cmd_line_add_string (cmd, "--log-dhcp");
		nm_cmd_line_add_string (cmd, "--log-queries");
	}

	/* dnsmasq may read from it's default config file location, which if that
	 * location is a valid config file, it will combine with the options here
	 * and cause undesirable side-effects.  Like sending bogus IP addresses
	 * as the gateway or whatever.  So tell dnsmasq not to use any config file
	 * at all.
	 */
	nm_cmd_line_add_string (cmd, "--conf-file");

	nm_cmd_line_add_string (cmd, "--no-hosts");
	nm_cmd_line_add_string (cmd, "--keep-in-foreground");
	nm_cmd_line_add_string (cmd, "--bind-interfaces");
	nm_cmd_line_add_string (cmd, "--except-interface=lo");
	nm_cmd_line_add_string (cmd, "--clear-on-reload");

	/* Use strict order since in the case of VPN connections, the VPN's
	 * nameservers will be first in resolv.conf, and those need to be tried
	 * first by dnsmasq to successfully resolve names from the VPN.
	 */
	nm_cmd_line_add_string (cmd, "--strict-order");

	/* Find the IP4 address to use */
	tmp = nm_ip4_config_get_address (ip4_config, 0);

	s = g_string_new ("--listen-address=");
	nm_utils_inet4_ntop (tmp->address, localaddr);
	g_string_append (s, localaddr);
	nm_cmd_line_add_string (cmd, s->str);
	g_string_free (s, TRUE);

	if (!nm_dnsmasq_utils_get_range (tmp, first, last, &error_desc)) {
		g_set_error_literal (error,
		                     NM_MANAGER_ERROR,
		                     NM_MANAGER_ERROR_FAILED,
		                     error_desc);
		nm_log_warn (LOGD_SHARING, "Failed to find DHCP address ranges: %s", error_desc);
		g_free (error_desc);
		nm_cmd_line_destroy (cmd);
		return NULL;
	}

	s = g_string_new ("--dhcp-range=");
	g_string_append_printf (s, "%s,%s,60m", first, last);
	nm_cmd_line_add_string (cmd, s->str);
	g_string_free (s, TRUE);

	s = g_string_new ("--dhcp-option=option:router,");
	g_string_append (s, localaddr);
	nm_cmd_line_add_string (cmd, s->str);
	g_string_free (s, TRUE);

	nm_cmd_line_add_string (cmd, "--dhcp-lease-max=50");

	s = g_string_new ("--pid-file=");
	g_string_append (s, pidfile);
	nm_cmd_line_add_string (cmd, s->str);
	g_string_free (s, TRUE);

	return cmd;
}
static gboolean
teamd_start (NMDevice *device, NMSettingTeam *s_team)
{
	NMDeviceTeam *self = NM_DEVICE_TEAM (device);
	NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self);
	const char *iface = nm_device_get_ip_iface (device);
	gs_unref_ptrarray GPtrArray *argv = NULL;
	gs_free_error GError *error = NULL;
	gs_free char *tmp_str = NULL;
	const char *teamd_binary;
	const char *config;

	teamd_binary = nm_utils_find_helper ("teamd", NULL, NULL);
	if (!teamd_binary) {
		_LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: teamd binary not found");
		return FALSE;
	}

	if (priv->teamd_process_watch || priv->teamd_pid > 0 || priv->tdc) {
		g_warn_if_reached ();
		if (!priv->teamd_pid)
			teamd_kill (self, teamd_binary, NULL);
		teamd_cleanup (device, TRUE);
	}

	/* Start teamd now */
	argv = g_ptr_array_new ();
	g_ptr_array_add (argv, (gpointer) teamd_binary);
	g_ptr_array_add (argv, (gpointer) "-o");
	g_ptr_array_add (argv, (gpointer) "-n");
	g_ptr_array_add (argv, (gpointer) "-U");
	g_ptr_array_add (argv, (gpointer) "-D");
	g_ptr_array_add (argv, (gpointer) "-N");
	g_ptr_array_add (argv, (gpointer) "-t");
	g_ptr_array_add (argv, (gpointer) iface);

	config = nm_setting_team_get_config(s_team);
	if (config) {
		g_ptr_array_add (argv, (gpointer) "-c");
		g_ptr_array_add (argv, (gpointer) config);
	}

	if (nm_logging_enabled (LOGL_DEBUG, LOGD_TEAM))
		g_ptr_array_add (argv, (gpointer) "-gg");
	g_ptr_array_add (argv, NULL);

	_LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata)));
	if (!g_spawn_async ("/", (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
	                    nm_utils_setpgid, NULL, &priv->teamd_pid, &error)) {
		_LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message);
		teamd_cleanup (device, TRUE);
		return FALSE;
	}

	/* Start a timeout for teamd to appear at D-Bus */
	if (!priv->teamd_timeout)
		priv->teamd_timeout = g_timeout_add_seconds (5, teamd_timeout_cb, device);

	/* Monitor the child process so we know when it dies */
	priv->teamd_process_watch = g_child_watch_add (priv->teamd_pid,
	                                               teamd_process_watch_cb,
	                                               device);

	_LOGI (LOGD_TEAM, "Activation: (team) started teamd [pid %u]...", (guint) priv->teamd_pid);
	return TRUE;
}
示例#9
0
static void
start_dnsmasq (NMDnsDnsmasq *self)
{
	NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self);
	const char *dm_binary;
	const char *argv[15];
	GPid pid = 0;
	guint idx = 0;
	NMBusManager *dbus_mgr;
	GDBusConnection *connection;

	if (priv->running) {
		/* the dnsmasq process is running. Nothing to do. */
		return;
	}

	if (nm_dns_plugin_child_pid ((NMDnsPlugin *) self) > 0) {
		/* if we already have a child process spawned, don't do
		 * it again. */
		return;
	}

	dm_binary = nm_utils_find_helper ("dnsmasq", DNSMASQ_PATH, NULL);
	if (!dm_binary) {
		_LOGW ("could not find dnsmasq binary");
		return;
	}

	argv[idx++] = dm_binary;
	argv[idx++] = "--no-resolv";  /* Use only commandline */
	argv[idx++] = "--keep-in-foreground";
	argv[idx++] = "--no-hosts"; /* don't use /etc/hosts to resolve */
	argv[idx++] = "--bind-interfaces";
	argv[idx++] = "--pid-file=" PIDFILE;
	argv[idx++] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
	argv[idx++] = "--cache-size=400";
	argv[idx++] = "--conf-file=/dev/null"; /* avoid loading /etc/dnsmasq.conf */
	argv[idx++] = "--proxy-dnssec"; /* Allow DNSSEC to pass through */
	argv[idx++] = "--enable-dbus=" DNSMASQ_DBUS_SERVICE;

	/* dnsmasq exits if the conf dir is not present */
	if (g_file_test (CONFDIR, G_FILE_TEST_IS_DIR))
		argv[idx++] = "--conf-dir=" CONFDIR;

	argv[idx++] = NULL;
	nm_assert (idx <= G_N_ELEMENTS (argv));

	/* And finally spawn dnsmasq */
	pid = nm_dns_plugin_child_spawn (NM_DNS_PLUGIN (self), argv, PIDFILE, "bin/dnsmasq");
	if (!pid)
		return;

	if (   priv->dnsmasq
	    || priv->dnsmasq_cancellable) {
		/* we already have a proxy or are about to create it.
		 * We are done. */
		return;
	}

	dbus_mgr = nm_bus_manager_get ();
	g_return_if_fail (dbus_mgr);

	connection = nm_bus_manager_get_connection (dbus_mgr);
	g_return_if_fail (connection);

	priv->dnsmasq_cancellable = g_cancellable_new ();
	g_dbus_proxy_new (connection,
	                  G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
	                  NULL,
	                  DNSMASQ_DBUS_SERVICE,
	                  DNSMASQ_DBUS_PATH,
	                  DNSMASQ_DBUS_SERVICE,
	                  priv->dnsmasq_cancellable,
	                  dnsmasq_proxy_cb,
	                  self);
}