예제 #1
0
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);
    }
}
예제 #2
0
gboolean
nm_team_update_slave_connection (NMDevice *slave, NMConnection *connection)
{
	NMSettingTeamPort *s_port;
	const char *iface = nm_device_get_iface (slave);
	char *port_config = NULL;
	gboolean with_teamdctl = FALSE;
	int err = 0;
#if WITH_TEAMDCTL
	const char *master_iface;
	int master_ifindex;
	struct teamdctl *tdc;
	const char *team_port_config = NULL;
#endif

	g_return_val_if_fail (NM_IS_DEVICE (slave), FALSE);
	g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);

#if WITH_TEAMDCTL
	master_ifindex = nm_platform_link_get_master (nm_device_get_ifindex (slave));
	g_assert (master_ifindex > 0);
	master_iface = nm_platform_link_get_name (master_ifindex);
	g_assert (master_iface);

	tdc = teamdctl_alloc ();
	g_assert (tdc);
	err = teamdctl_connect (tdc, master_iface, NULL, NULL);
	if (err) {
		nm_log_err (LOGD_TEAM, "(%s): failed to connect to teamd for master %s (err=%d)",
		            iface, master_iface, err);
		teamdctl_free (tdc);
		return FALSE;
	}
	err = teamdctl_port_config_get_raw_direct (tdc, iface, (char **)&team_port_config);
	port_config = g_strdup (team_port_config);
	teamdctl_free (tdc);
	with_teamdctl = TRUE;
#endif

	s_port = nm_connection_get_setting_team_port (connection);
	if (!s_port) {
		s_port = (NMSettingTeamPort *) nm_setting_team_port_new ();
		nm_connection_add_setting (connection, NM_SETTING (s_port));
	}

	g_object_set (G_OBJECT (s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL);
	g_free (port_config);

	if (!with_teamdctl || err != 0) {
		if (!with_teamdctl)
			nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration "
			                       " (compiled without libteamdctl support)", iface);
		else
			nm_log_err (LOGD_TEAM, "(%s): failed to read teamd port configuration (err=%d)",
			            iface, err);
		return FALSE;
	}

	return TRUE;
}
예제 #3
0
/**
 * 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;
}
예제 #4
0
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);
        }
    }
}