static void init (NMSettingsPlugin *config) { SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (config); SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); GHashTable *auto_ifaces; if_block *block = NULL; GList *keys, *iter; GHashTableIter con_iter; const char *block_name; NMIfupdownConnection *connection; const char *subsys[2] = { "net", NULL }; auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); if(!priv->connections) priv->connections = g_hash_table_new (g_str_hash, g_str_equal); if(!priv->kernel_ifaces) priv->kernel_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); if(!priv->eni_ifaces) priv->eni_ifaces = g_hash_table_new (g_str_hash, g_str_equal); nm_log_info (LOGD_SETTINGS, "init!"); priv->client = g_udev_client_new (subsys); if (!priv->client) { nm_log_warn (LOGD_SETTINGS, " error initializing libgudev"); } else g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); /* Read in all the interfaces */ ifparser_init (ENI_INTERFACES_FILE, 0); block = ifparser_getfirst (); while (block) { if(!strcmp ("auto", block->type) || !strcmp ("allow-hotplug", block->type)) g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1)); else if (!strcmp ("iface", block->type)) { NMIfupdownConnection *exported; /* Bridge configuration */ if(!strncmp ("br", block->name, 2)) { /* Try to find bridge ports */ const char *ports = ifparser_getkey (block, "bridge-ports"); if (ports) { int i; int state = 0; char **port_ifaces; nm_log_info (LOGD_SETTINGS, "found bridge ports %s for %s", ports, block->name); port_ifaces = g_strsplit_set (ports, " \t", -1); for (i = 0; i < g_strv_length (port_ifaces); i++) { char *token = port_ifaces[i]; /* Skip crazy stuff like regex or all */ if (!strcmp ("all", token)) { continue; } /* Small SM to skip everything inside regex */ if (!strcmp ("regex", token)) { state++; continue; } if (!strcmp ("noregex", token)) { state--; continue; } if (state == 0 && strlen (token) > 0) { nm_log_info (LOGD_SETTINGS, "adding bridge port %s to eni_ifaces", token); g_hash_table_insert (priv->eni_ifaces, g_strdup (token), "known"); } } g_strfreev (port_ifaces); } goto next; } /* Skip loopback configuration */ if(!strcmp ("lo", block->name)) { goto next; } /* Remove any connection for this block that was previously found */ exported = g_hash_table_lookup (priv->connections, block->name); if (exported) { nm_log_info (LOGD_SETTINGS, "deleting %s from connections", block->name); nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), NULL, NULL); g_hash_table_remove (priv->connections, block->name); } /* add the new connection */ exported = nm_ifupdown_connection_new (block); if (exported) { nm_log_info (LOGD_SETTINGS, "adding %s to connections", block->name); g_hash_table_insert (priv->connections, block->name, exported); } nm_log_info (LOGD_SETTINGS, "adding iface %s to eni_ifaces", block->name); g_hash_table_insert (priv->eni_ifaces, block->name, "known"); } else if (!strcmp ("mapping", block->type)) { g_hash_table_insert (priv->eni_ifaces, block->name, "known"); nm_log_info (LOGD_SETTINGS, "adding mapping %s to eni_ifaces", block->name); } next: block = block->next; } /* Make 'auto' interfaces autoconnect=TRUE */ g_hash_table_iter_init (&con_iter, priv->connections); while (g_hash_table_iter_next (&con_iter, (gpointer) &block_name, (gpointer) &connection)) { NMSettingConnection *setting; if (g_hash_table_lookup (auto_ifaces, block_name)) { setting = nm_connection_get_setting_connection (NM_CONNECTION (connection)); g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); nm_log_info (LOGD_SETTINGS, "autoconnect"); } } g_hash_table_destroy (auto_ifaces); /* Check the config file to find out whether to manage interfaces */ priv->unmanage_well_known = !nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, NM_CONFIG_KEYFILE_GROUP_IFUPDOWN, NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED, !IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT); nm_log_info (LOGD_SETTINGS, "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); /* Add well-known interfaces */ keys = g_udev_client_query_by_subsystem (priv->client, "net"); for (iter = keys; iter; iter = g_list_next (iter)) { udev_device_added (self, G_UDEV_DEVICE (iter->data)); g_object_unref (G_UDEV_DEVICE (iter->data)); } g_list_free (keys); /* Now if we're running in managed mode, let NM know there are new connections */ if (!priv->unmanage_well_known) { GList *con_list = g_hash_table_get_values (priv->connections); GList *cl_iter; for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) { g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, NM_SETTINGS_CONNECTION (cl_iter->data)); } g_list_free (con_list); } nm_log_info (LOGD_SETTINGS, "end _init."); }
static void SCPluginIfupdown_init (NMSystemConfigInterface *config) { SCPluginIfupdown *self = SC_PLUGIN_IFUPDOWN (config); SCPluginIfupdownPrivate *priv = SC_PLUGIN_IFUPDOWN_GET_PRIVATE (self); GHashTable *auto_ifaces; if_block *block = NULL; NMInotifyHelper *inotify_helper; GKeyFile* keyfile; GError *error = NULL; GList *keys, *iter; const char *subsys[2] = { "net", NULL }; auto_ifaces = g_hash_table_new (g_str_hash, g_str_equal); if(!priv->iface_connections) priv->iface_connections = g_hash_table_new (g_str_hash, g_str_equal); if(!priv->well_known_ifaces) priv->well_known_ifaces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); if(!priv->well_known_interfaces) priv->well_known_interfaces = g_hash_table_new (g_str_hash, g_str_equal); PLUGIN_PRINT("SCPlugin-Ifupdown", "init!"); priv->client = g_udev_client_new (subsys); if (!priv->client) { PLUGIN_WARN ("SCPlugin-Ifupdown", " error initializing libgudev"); } else g_signal_connect (priv->client, "uevent", G_CALLBACK (handle_uevent), self); priv->unmanage_well_known = IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT; inotify_helper = nm_inotify_helper_get (); priv->inotify_event_id = g_signal_connect (inotify_helper, "event", G_CALLBACK (update_system_hostname), config); priv->inotify_system_hostname_wd = nm_inotify_helper_add_watch (inotify_helper, IFUPDOWN_SYSTEM_HOSTNAME_FILE); update_system_hostname (inotify_helper, NULL, NULL, config); /* Read in all the interfaces */ ifparser_init (ENI_INTERFACES_FILE, 0); block = ifparser_getfirst (); while (block) { if(!strcmp ("auto", block->type) || !strcmp ("allow-hotplug", block->type)) g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1)); else if (!strcmp ("iface", block->type)) { NMIfupdownConnection *exported; /* Bridge configuration */ if(!strncmp ("br", block->name, 2)) { /* Try to find bridge ports */ const char *ports = ifparser_getkey (block, "bridge-ports"); if (ports) { int i; int state = 0; char **port_ifaces; PLUGIN_PRINT("SCPlugin-Ifupdown", "found bridge ports %s for %s", ports, block->name); port_ifaces = g_strsplit_set (ports, " \t", -1); for (i = 0; i < g_strv_length (port_ifaces); i++) { char *token = port_ifaces[i]; /* Skip crazy stuff like regex or all */ if (!strcmp ("all", token)) { continue; } /* Small SM to skip everything inside regex */ if (!strcmp ("regex", token)) { state++; continue; } if (!strcmp ("noregex", token)) { state--; continue; } if (state == 0 && strlen (token) > 0) { PLUGIN_PRINT("SCPlugin-Ifupdown", "adding bridge port %s to well_known_interfaces", token); g_hash_table_insert (priv->well_known_interfaces, g_strdup (token), "known"); } } g_strfreev (port_ifaces); } goto next; } /* Skip loopback configuration */ if(!strcmp ("lo", block->name)) { goto next; } /* Remove any connection for this block that was previously found */ exported = g_hash_table_lookup (priv->iface_connections, block->name); if (exported) { PLUGIN_PRINT("SCPlugin-Ifupdown", "deleting %s from iface_connections", block->name); nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); g_hash_table_remove (priv->iface_connections, block->name); } /* add the new connection */ exported = nm_ifupdown_connection_new (block); if (exported) { PLUGIN_PRINT("SCPlugin-Ifupdown", "adding %s to iface_connections", block->name); g_hash_table_insert (priv->iface_connections, block->name, exported); } PLUGIN_PRINT("SCPlugin-Ifupdown", "adding iface %s to well_known_interfaces", block->name); g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); } else if (!strcmp ("mapping", block->type)) { g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); PLUGIN_PRINT("SCPlugin-Ifupdown", "adding mapping %s to well_known_interfaces", block->name); } next: block = block->next; } /* Make 'auto' interfaces autoconnect=TRUE */ keys = g_hash_table_get_keys (priv->iface_connections); for (iter = keys; iter; iter = g_list_next (iter)) { NMIfupdownConnection *exported; NMSetting *setting; if (!g_hash_table_lookup (auto_ifaces, iter->data)) continue; exported = g_hash_table_lookup (priv->iface_connections, iter->data); setting = NM_SETTING (nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_CONNECTION)); g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); nm_settings_connection_commit_changes (NM_SETTINGS_CONNECTION (exported), ignore_cb, NULL); PLUGIN_PRINT("SCPlugin-Ifupdown", "autoconnect"); } g_list_free (keys); g_hash_table_destroy (auto_ifaces); /* Find the config file */ if (g_file_test (IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE, G_FILE_TEST_EXISTS)) priv->conf_file = IFUPDOWN_SYSTEM_SETTINGS_KEY_FILE; else priv->conf_file = IFUPDOWN_OLD_SYSTEM_SETTINGS_KEY_FILE; keyfile = g_key_file_new (); if (!g_key_file_load_from_file (keyfile, priv->conf_file, G_KEY_FILE_NONE, &error)) { nm_log_info (LOGD_SETTINGS, "loading system config file (%s) caused error: (%d) %s", priv->conf_file, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } else { gboolean manage_well_known; error = NULL; manage_well_known = g_key_file_get_boolean (keyfile, IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED, &error); if (error) { nm_log_info (LOGD_SETTINGS, "getting keyfile key '%s' in group '%s' failed: (%d) %s", IFUPDOWN_KEY_FILE_GROUP, IFUPDOWN_KEY_FILE_KEY_MANAGED, error ? error->code : -1, error && error->message ? error->message : "(unknown)"); } else priv->unmanage_well_known = !manage_well_known; } PLUGIN_PRINT ("SCPluginIfupdown", "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); if (keyfile) g_key_file_free (keyfile); /* Add well-known interfaces */ keys = g_udev_client_query_by_subsystem (priv->client, "net"); for (iter = keys; iter; iter = g_list_next (iter)) { udev_device_added (self, G_UDEV_DEVICE (iter->data)); g_object_unref (G_UDEV_DEVICE (iter->data)); } g_list_free (keys); /* Now if we're running in managed mode, let NM know there are new connections */ if (!priv->unmanage_well_known) { GList *con_list = g_hash_table_get_values (priv->iface_connections); GList *cl_iter; for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) { g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, NM_SETTINGS_CONNECTION (cl_iter->data)); } g_list_free (con_list); } PLUGIN_PRINT("SCPlugin-Ifupdown", "end _init."); }