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); } }
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; }
/** * 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); } } }