mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-08 05:28:07 +02:00
ifcfg-rh: add IPv6 addressing and routes support (rh #523288)
This commit is contained in:
parent
3b0255f73c
commit
686425adce
19 changed files with 1553 additions and 19 deletions
|
|
@ -26,6 +26,7 @@
|
|||
#define IFCFG_TAG "ifcfg-"
|
||||
#define KEYS_TAG "keys-"
|
||||
#define ROUTE_TAG "route-"
|
||||
#define ROUTE6_TAG "route6-"
|
||||
|
||||
#define BAK_TAG ".bak"
|
||||
#define TILDE_TAG "~"
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@ typedef struct {
|
|||
char *routefile;
|
||||
int routefile_wd;
|
||||
|
||||
char *route6file;
|
||||
int route6file_wd;
|
||||
|
||||
char *udi;
|
||||
char *unmanaged;
|
||||
} NMIfcfgConnectionPrivate;
|
||||
|
|
@ -93,7 +96,7 @@ files_changed_cb (NMInotifyHelper *ih,
|
|||
NMIfcfgConnection *self = NM_IFCFG_CONNECTION (user_data);
|
||||
NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self);
|
||||
|
||||
if ((evt->wd != priv->file_wd) && (evt->wd != priv->keyfile_wd) && (evt->wd != priv->routefile_wd))
|
||||
if ((evt->wd != priv->file_wd) && (evt->wd != priv->keyfile_wd) && (evt->wd != priv->routefile_wd) && (evt->wd != priv->route6file_wd))
|
||||
return;
|
||||
|
||||
/* push the event up to the plugin */
|
||||
|
|
@ -111,11 +114,12 @@ nm_ifcfg_connection_new (const char *filename,
|
|||
char *unmanaged = NULL;
|
||||
char *keyfile = NULL;
|
||||
char *routefile = NULL;
|
||||
char *route6file = NULL;
|
||||
NMInotifyHelper *ih;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
|
||||
tmp = connection_from_file (filename, NULL, NULL, NULL, &unmanaged, &keyfile, &routefile, error, ignore_error);
|
||||
tmp = connection_from_file (filename, NULL, NULL, NULL, &unmanaged, &keyfile, &routefile, &route6file, error, ignore_error);
|
||||
if (!tmp)
|
||||
return NULL;
|
||||
|
||||
|
|
@ -145,6 +149,9 @@ nm_ifcfg_connection_new (const char *filename,
|
|||
priv->routefile = routefile;
|
||||
priv->routefile_wd = nm_inotify_helper_add_watch (ih, routefile);
|
||||
|
||||
priv->route6file = route6file;
|
||||
priv->route6file_wd = nm_inotify_helper_add_watch (ih, route6file);
|
||||
|
||||
return NM_IFCFG_CONNECTION (object);
|
||||
}
|
||||
|
||||
|
|
@ -176,7 +183,6 @@ update (NMSettingsConnectionInterface *connection,
|
|||
IFCFG_DIR,
|
||||
priv->filename,
|
||||
priv->keyfile,
|
||||
priv->routefile,
|
||||
&error)) {
|
||||
callback (connection, error, user_data);
|
||||
g_error_free (error);
|
||||
|
|
@ -199,6 +205,9 @@ do_delete (NMSettingsConnectionInterface *connection,
|
|||
if (priv->routefile)
|
||||
g_unlink (priv->routefile);
|
||||
|
||||
if (priv->route6file)
|
||||
g_unlink (priv->route6file);
|
||||
|
||||
return parent_settings_connection_iface->delete (connection, callback, user_data);
|
||||
}
|
||||
|
||||
|
|
@ -243,6 +252,10 @@ finalize (GObject *object)
|
|||
if (priv->routefile_wd >= 0)
|
||||
nm_inotify_helper_remove_watch (ih, priv->routefile_wd);
|
||||
|
||||
g_free (priv->route6file);
|
||||
if (priv->route6file_wd >= 0)
|
||||
nm_inotify_helper_remove_watch (ih, priv->route6file_wd);
|
||||
|
||||
G_OBJECT_CLASS (nm_ifcfg_connection_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include <NetworkManager.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#include <nm-setting-ip4-config.h>
|
||||
#include <nm-setting-ip6-config.h>
|
||||
#include <nm-setting-wired.h>
|
||||
#include <nm-setting-wireless.h>
|
||||
#include <nm-setting-8021x.h>
|
||||
|
|
@ -494,6 +495,31 @@ read_ip4_address (shvarFile *ifcfg,
|
|||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
parse_ip6_address (const char *value,
|
||||
struct in6_addr *out_addr,
|
||||
GError **error)
|
||||
{
|
||||
struct in6_addr ip6_addr;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
g_return_val_if_fail (out_addr != NULL, FALSE);
|
||||
g_return_val_if_fail (error != NULL, FALSE);
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
*out_addr = in6addr_any;
|
||||
|
||||
if (inet_pton (AF_INET6, value, &ip6_addr) > 0) {
|
||||
*out_addr = ip6_addr;
|
||||
success = TRUE;
|
||||
} else {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Invalid IP6 address '%s'", value);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
static NMIP4Address *
|
||||
read_full_ip4_address (shvarFile *ifcfg,
|
||||
const char *network_file,
|
||||
|
|
@ -851,6 +877,227 @@ error:
|
|||
return success;
|
||||
}
|
||||
|
||||
static NMIP6Address *
|
||||
parse_full_ip6_address (const char *addr_str, GError **error)
|
||||
{
|
||||
NMIP6Address *addr;
|
||||
char **list;
|
||||
char *ip_tag, *prefix_tag;
|
||||
struct in6_addr tmp = IN6ADDR_ANY_INIT;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (addr_str != NULL, NULL);
|
||||
g_return_val_if_fail (error != NULL, NULL);
|
||||
g_return_val_if_fail (*error == NULL, NULL);
|
||||
|
||||
/* Split the adddress and prefix */
|
||||
list = g_strsplit_set (addr_str, "/", 2);
|
||||
if (g_strv_length (list) < 1) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Invalid IP6 address '%s'", addr_str);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ip_tag = list[0];
|
||||
prefix_tag = list[1];
|
||||
|
||||
addr = nm_ip6_address_new ();
|
||||
/* IP address */
|
||||
if (ip_tag) {
|
||||
if (!parse_ip6_address (ip_tag, &tmp, error))
|
||||
goto error;
|
||||
}
|
||||
|
||||
nm_ip6_address_set_address (addr, &tmp);
|
||||
|
||||
/* Prefix */
|
||||
if (prefix_tag) {
|
||||
long int prefix;
|
||||
|
||||
errno = 0;
|
||||
prefix = strtol (prefix_tag, NULL, 10);
|
||||
if (errno || prefix <= 0 || prefix > 128) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Invalid IP6 prefix '%s'", prefix_tag);
|
||||
goto error;
|
||||
}
|
||||
nm_ip6_address_set_prefix (addr, (guint32) prefix);
|
||||
} else {
|
||||
/* Missing prefix is treated as prefix of 64 */
|
||||
nm_ip6_address_set_prefix (addr, 64);
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
error:
|
||||
if (!success) {
|
||||
nm_ip6_address_unref (addr);
|
||||
addr = NULL;
|
||||
}
|
||||
|
||||
g_strfreev (list);
|
||||
return addr;
|
||||
}
|
||||
|
||||
/* IPv6 address is very complex to describe completely by a regular expression,
|
||||
* so don't try to, rather use looser syntax to comprise all possibilities
|
||||
* NOTE: The regexes below don't describe all variants allowed by 'ip route add',
|
||||
* namely destination IP without 'to' keyword is recognized just at line start.
|
||||
*/
|
||||
#define IPV6_ADDR_REGEX "[0-9A-Fa-f:.]+"
|
||||
|
||||
static gboolean
|
||||
read_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error)
|
||||
{
|
||||
char *contents = NULL;
|
||||
gsize len = 0;
|
||||
char **lines = NULL, **iter;
|
||||
GRegex *regex_to1, *regex_to2, *regex_via, *regex_metric;
|
||||
GMatchInfo *match_info;
|
||||
NMIP6Route *route;
|
||||
struct in6_addr ip6_addr;
|
||||
char *dest = NULL, *prefix = NULL, *next_hop = NULL, *metric = NULL;
|
||||
long int prefix_int, metric_int;
|
||||
gboolean success = FALSE;
|
||||
|
||||
const char *pattern_empty = "^\\s*(\\#.*)?$";
|
||||
const char *pattern_to1 = "^\\s*(" IPV6_ADDR_REGEX "|default)" /* IPv6 or 'default' keyword */
|
||||
"(?:/(\\d{1,2}))?"; /* optional prefix */
|
||||
const char *pattern_to2 = "to\\s+(" IPV6_ADDR_REGEX "|default)" /* IPv6 or 'default' keyword */
|
||||
"(?:/(\\d{1,2}))?"; /* optional prefix */
|
||||
const char *pattern_via = "via\\s+(" IPV6_ADDR_REGEX ")"; /* IPv6 of gateway */
|
||||
const char *pattern_metric = "metric\\s+(\\d+)"; /* metric */
|
||||
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (s_ip6 != NULL, FALSE);
|
||||
g_return_val_if_fail (error != NULL, FALSE);
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
/* Read the route file */
|
||||
if (!g_file_get_contents (filename, &contents, &len, NULL))
|
||||
return FALSE;
|
||||
|
||||
if (len == 0) {
|
||||
g_free (contents);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Create regexes for pieces to be matched */
|
||||
regex_to1 = g_regex_new (pattern_to1, 0, 0, NULL);
|
||||
regex_to2 = g_regex_new (pattern_to2, 0, 0, NULL);
|
||||
regex_via = g_regex_new (pattern_via, 0, 0, NULL);
|
||||
regex_metric = g_regex_new (pattern_metric, 0, 0, NULL);
|
||||
|
||||
/* New NMIP6Route structure */
|
||||
route = nm_ip6_route_new ();
|
||||
|
||||
/* Iterate through file lines */
|
||||
lines = g_strsplit_set (contents, "\n\r", -1);
|
||||
for (iter = lines; iter && *iter; iter++) {
|
||||
|
||||
/* Skip empty lines */
|
||||
if (g_regex_match_simple (pattern_empty, *iter, 0, 0))
|
||||
continue;
|
||||
|
||||
/* Destination */
|
||||
g_regex_match (regex_to1, *iter, 0, &match_info);
|
||||
if (!g_match_info_matches (match_info)) {
|
||||
g_match_info_free (match_info);
|
||||
g_regex_match (regex_to2, *iter, 0, &match_info);
|
||||
if (!g_match_info_matches (match_info)) {
|
||||
g_match_info_free (match_info);
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Missing IP6 route destination address in record: '%s'", *iter);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
dest = g_match_info_fetch (match_info, 1);
|
||||
g_match_info_free (match_info);
|
||||
if (!strcmp (dest, "default"))
|
||||
strcpy (dest, "::");
|
||||
if (inet_pton (AF_INET6, dest, &ip6_addr) != 1) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Invalid IP6 route destination address '%s'", dest);
|
||||
g_free (dest);
|
||||
goto error;
|
||||
}
|
||||
nm_ip6_route_set_dest (route, &ip6_addr);
|
||||
g_free (dest);
|
||||
|
||||
/* Prefix - is optional; 128 if missing */
|
||||
prefix = g_match_info_fetch (match_info, 2);
|
||||
prefix_int = 128;
|
||||
if (prefix) {
|
||||
errno = 0;
|
||||
prefix_int = strtol (prefix, NULL, 10);
|
||||
if (errno || prefix_int < 0 || prefix_int > 128) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Invalid IP6 route destination prefix '%s'", prefix);
|
||||
g_free (prefix);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
nm_ip6_route_set_prefix (route, (guint32) prefix_int);
|
||||
g_free (prefix);
|
||||
|
||||
/* Next hop */
|
||||
g_regex_match (regex_via, *iter, 0, &match_info);
|
||||
if (!g_match_info_matches (match_info)) {
|
||||
g_match_info_free (match_info);
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Missing IP6 route gateway address in record: '%s'", *iter);
|
||||
goto error;
|
||||
}
|
||||
next_hop = g_match_info_fetch (match_info, 1);
|
||||
g_match_info_free (match_info);
|
||||
if (inet_pton (AF_INET6, next_hop, &ip6_addr) != 1) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Invalid IP6 route gateway address '%s'", next_hop);
|
||||
g_free (next_hop);
|
||||
goto error;
|
||||
}
|
||||
nm_ip6_route_set_next_hop (route, &ip6_addr);
|
||||
g_free (next_hop);
|
||||
|
||||
/* Metric */
|
||||
g_regex_match (regex_metric, *iter, 0, &match_info);
|
||||
metric_int = 0;
|
||||
if (g_match_info_matches (match_info)) {
|
||||
metric = g_match_info_fetch (match_info, 1);
|
||||
errno = 0;
|
||||
metric_int = strtol (metric, NULL, 10);
|
||||
if (errno || metric_int < 0 || metric_int > G_MAXUINT32) {
|
||||
g_match_info_free (match_info);
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Invalid IP6 route metric '%s'", metric);
|
||||
g_free (metric);
|
||||
goto error;
|
||||
}
|
||||
g_free (metric);
|
||||
}
|
||||
|
||||
nm_ip6_route_set_metric (route, (guint32) metric_int);
|
||||
g_match_info_free (match_info);
|
||||
|
||||
if (!nm_setting_ip6_config_add_route (s_ip6, route))
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP6 route");
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
error:
|
||||
g_free (contents);
|
||||
g_strfreev (lines);
|
||||
nm_ip6_route_unref (route);
|
||||
g_regex_unref (regex_to1);
|
||||
g_regex_unref (regex_to2);
|
||||
g_regex_unref (regex_via);
|
||||
g_regex_unref (regex_metric);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
static NMSetting *
|
||||
make_ip4_setting (shvarFile *ifcfg,
|
||||
|
|
@ -990,16 +1237,31 @@ make_ip4_setting (shvarFile *ifcfg,
|
|||
g_free (value);
|
||||
}
|
||||
|
||||
/* DNS servers */
|
||||
/* DNS servers
|
||||
* Pick up just IPv4 addresses (IPv6 addresses are taken by make_ip6_setting())
|
||||
*/
|
||||
for (i = 1, tmp_success = TRUE; i <= 10 && tmp_success; i++) {
|
||||
char *tag;
|
||||
guint32 dns;
|
||||
struct in6_addr ip6_dns;
|
||||
GError *tmp_err = NULL;
|
||||
|
||||
tag = g_strdup_printf ("DNS%u", i);
|
||||
tmp_success = read_ip4_address (ifcfg, tag, &dns, error);
|
||||
if (!tmp_success) {
|
||||
g_free (tag);
|
||||
goto error;
|
||||
/* if it's IPv6, don't exit */
|
||||
dns = 0;
|
||||
value = svGetValue (ifcfg, tag, FALSE);
|
||||
if (value) {
|
||||
tmp_success = parse_ip6_address (value, &ip6_dns, &tmp_err);
|
||||
g_clear_error (&tmp_err);
|
||||
g_free (value);
|
||||
}
|
||||
if (!tmp_success) {
|
||||
g_free (tag);
|
||||
goto error;
|
||||
}
|
||||
g_clear_error (error);
|
||||
}
|
||||
|
||||
if (dns && !nm_setting_ip4_config_add_dns (s_ip4, dns))
|
||||
|
|
@ -1091,6 +1353,202 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static NMSetting *
|
||||
make_ip6_setting (shvarFile *ifcfg,
|
||||
const char *network_file,
|
||||
const char *iscsiadm_path,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingIP6Config *s_ip6 = NULL;
|
||||
char *value = NULL;
|
||||
char *str_value;
|
||||
char *route6_path = NULL;
|
||||
gboolean bool_value, ipv6forwarding, ipv6_autoconf;
|
||||
char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL;
|
||||
guint32 i;
|
||||
shvarFile *network_ifcfg;
|
||||
gboolean never_default = FALSE, tmp_success;
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
|
||||
if (!s_ip6) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Could not allocate IP6 setting");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Is IPV6 enabled? Set method to "ignored", when not enabled */
|
||||
str_value = svGetValue (ifcfg, "IPV6INIT", FALSE);
|
||||
bool_value = svTrueValue (ifcfg, "IPV6INIT", FALSE);
|
||||
if (!str_value) {
|
||||
network_ifcfg = svNewFile (network_file);
|
||||
if (network_ifcfg) {
|
||||
bool_value = svTrueValue (network_ifcfg, "IPV6INIT", FALSE);
|
||||
svCloseFile (network_ifcfg);
|
||||
}
|
||||
}
|
||||
g_free (str_value);
|
||||
|
||||
if (!bool_value) {
|
||||
/* IPv6 is disabled */
|
||||
g_object_set (s_ip6,
|
||||
NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE,
|
||||
NULL);
|
||||
return NM_SETTING (s_ip6);
|
||||
}
|
||||
|
||||
/* First check if IPV6_DEFROUTE is set for this device; IPV6_DEFROUTE has the
|
||||
* opposite meaning from never-default. The default if IPV6_DEFROUTE is not
|
||||
* specified is IPV6_DEFROUTE=yes which means that this connection can be used
|
||||
* as a default route
|
||||
*/
|
||||
never_default = !svTrueValue (ifcfg, "IPV6_DEFROUTE", TRUE);
|
||||
|
||||
/* Then check if IPV6_DEFAULTGW or IPV6_DEFAULTDEV is specified;
|
||||
* they are global and override IPV6_DEFROUTE
|
||||
* When both are set, the device specified in IPV6_DEFAULTGW takes preference.
|
||||
*/
|
||||
network_ifcfg = svNewFile (network_file);
|
||||
if (network_ifcfg) {
|
||||
char *ipv6_defaultgw, *ipv6_defaultdev;
|
||||
char *default_dev = NULL;
|
||||
|
||||
/* Get the connection ifcfg device name and the global default route device */
|
||||
value = svGetValue (ifcfg, "DEVICE", FALSE);
|
||||
ipv6_defaultgw = svGetValue (network_ifcfg, "IPV6_DEFAULTGW", FALSE);
|
||||
ipv6_defaultdev = svGetValue (network_ifcfg, "IPV6_DEFAULTDEV", FALSE);
|
||||
|
||||
if (ipv6_defaultgw) {
|
||||
default_dev = strchr (ipv6_defaultgw, '%');
|
||||
if (default_dev)
|
||||
default_dev++;
|
||||
}
|
||||
if (!default_dev)
|
||||
default_dev = ipv6_defaultdev;
|
||||
|
||||
/* If there was a global default route device specified, then only connections
|
||||
* for that device can be the default connection.
|
||||
*/
|
||||
if (default_dev && value)
|
||||
never_default = !!strcmp (value, default_dev);
|
||||
|
||||
g_free (ipv6_defaultgw);
|
||||
g_free (ipv6_defaultdev);
|
||||
g_free (value);
|
||||
svCloseFile (network_ifcfg);
|
||||
}
|
||||
|
||||
/* Find out method property */
|
||||
ipv6forwarding = svTrueValue (ifcfg, "IPV6FORWARDING", FALSE);
|
||||
ipv6_autoconf = svTrueValue (ifcfg, "IPV6_AUTOCONF", !ipv6forwarding);
|
||||
|
||||
if (ipv6_autoconf)
|
||||
method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
|
||||
else {
|
||||
/* IPV6_AUTOCONF=no and no IPv6 address -> method 'link-local' */
|
||||
str_value = svGetValue (ifcfg, "IPV6ADDR", FALSE);
|
||||
if (!str_value)
|
||||
str_value = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE);
|
||||
|
||||
if (!str_value)
|
||||
method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL;
|
||||
g_free (str_value);
|
||||
}
|
||||
/* TODO - handle other methods */
|
||||
|
||||
g_object_set (s_ip6,
|
||||
NM_SETTING_IP6_CONFIG_METHOD, method,
|
||||
NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, !svTrueValue (ifcfg, "IPV6_PEERDNS", TRUE),
|
||||
NM_SETTING_IP6_CONFIG_IGNORE_AUTO_ROUTES, !svTrueValue (ifcfg, "IPV6_PEERROUTES", TRUE),
|
||||
NM_SETTING_IP6_CONFIG_NEVER_DEFAULT, never_default,
|
||||
NULL);
|
||||
|
||||
if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
|
||||
NMIP6Address *addr;
|
||||
char *val;
|
||||
char *ipv6addr, *ipv6addr_secondaries;
|
||||
char **list = NULL, **iter;
|
||||
|
||||
ipv6addr = svGetValue (ifcfg, "IPV6ADDR", FALSE);
|
||||
ipv6addr_secondaries = svGetValue (ifcfg, "IPV6ADDR_SECONDARIES", FALSE);
|
||||
|
||||
val = g_strjoin (ipv6addr && ipv6addr_secondaries ? " " : NULL,
|
||||
ipv6addr ? ipv6addr : "",
|
||||
ipv6addr_secondaries ? ipv6addr_secondaries : "",
|
||||
NULL);
|
||||
g_free (ipv6addr);
|
||||
g_free (ipv6addr_secondaries);
|
||||
|
||||
list = g_strsplit_set (val, " ", 0);
|
||||
g_free (val);
|
||||
for (iter = list; iter && *iter; iter++, i++) {
|
||||
addr = parse_full_ip6_address (*iter, error);
|
||||
if (!addr) {
|
||||
g_strfreev (list);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!nm_setting_ip6_config_add_address (s_ip6, addr))
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate IP6 address");
|
||||
nm_ip6_address_unref (addr);
|
||||
}
|
||||
g_strfreev (list);
|
||||
} else if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
|
||||
/* TODO - autoconf or DHCPv6 stuff goes here */
|
||||
}
|
||||
|
||||
/* DNS servers
|
||||
* Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting())
|
||||
*/
|
||||
for (i = 1, tmp_success = TRUE; i <= 10 && tmp_success; i++) {
|
||||
char *tag;
|
||||
struct in6_addr ip6_dns;
|
||||
|
||||
ip6_dns = in6addr_any;
|
||||
tag = g_strdup_printf ("DNS%u", i);
|
||||
value = svGetValue (ifcfg, tag, FALSE);
|
||||
if (value)
|
||||
tmp_success = parse_ip6_address (value, &ip6_dns, error);
|
||||
|
||||
if (!tmp_success) {
|
||||
struct in_addr ip4_addr;
|
||||
if (inet_pton (AF_INET, value, &ip4_addr) != 1) {
|
||||
g_free (tag);
|
||||
g_free (value);
|
||||
goto error;
|
||||
}
|
||||
/* ignore error - it is IPv4 address */
|
||||
tmp_success = TRUE;
|
||||
g_clear_error (error);
|
||||
}
|
||||
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED (&ip6_dns) && !nm_setting_ip6_config_add_dns (s_ip6, &ip6_dns))
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: duplicate DNS server %s", tag);
|
||||
g_free (tag);
|
||||
g_free (value);
|
||||
}
|
||||
|
||||
/* DNS searches ('DOMAIN' key) are read by make_ip4_setting() and included in NMSettingIP4Config */
|
||||
|
||||
/* Read static routes from route6-<interface> file */
|
||||
route6_path = utils_get_route6_path (ifcfg->fileName);
|
||||
if (!route6_path) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Could not get route6 file path for '%s'", ifcfg->fileName);
|
||||
goto error;
|
||||
}
|
||||
|
||||
read_route6_file (route6_path, s_ip6, error);
|
||||
g_free (route6_path);
|
||||
if (error && *error)
|
||||
goto error;
|
||||
|
||||
return NM_SETTING (s_ip6);
|
||||
|
||||
error:
|
||||
g_object_unref (s_ip6);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_one_wep_key (shvarFile *ifcfg,
|
||||
const char *shvar_key,
|
||||
|
|
@ -2575,13 +3033,14 @@ connection_from_file (const char *filename,
|
|||
char **unmanaged,
|
||||
char **keyfile,
|
||||
char **routefile,
|
||||
char **route6file,
|
||||
GError **error,
|
||||
gboolean *ignore_error)
|
||||
{
|
||||
NMConnection *connection = NULL;
|
||||
shvarFile *parsed;
|
||||
char *type, *nmc = NULL, *bootproto;
|
||||
NMSetting *s_ip4;
|
||||
NMSetting *s_ip4, *s_ip6;
|
||||
const char *ifcfg_name = NULL;
|
||||
gboolean nm_controlled = TRUE;
|
||||
|
||||
|
|
@ -2592,6 +3051,8 @@ connection_from_file (const char *filename,
|
|||
g_return_val_if_fail (*keyfile == NULL, NULL);
|
||||
g_return_val_if_fail (routefile != NULL, NULL);
|
||||
g_return_val_if_fail (*routefile == NULL, NULL);
|
||||
g_return_val_if_fail (route6file != NULL, NULL);
|
||||
g_return_val_if_fail (*route6file == NULL, NULL);
|
||||
|
||||
/* Non-NULL only for unit tests; normally use /etc/sysconfig/network */
|
||||
if (!network_file)
|
||||
|
|
@ -2694,6 +3155,14 @@ connection_from_file (const char *filename,
|
|||
nm_connection_add_setting (connection, s_ip4);
|
||||
}
|
||||
|
||||
s_ip6 = make_ip6_setting (parsed, network_file, iscsiadm_path, error);
|
||||
if (*error) {
|
||||
g_object_unref (connection);
|
||||
connection = NULL;
|
||||
goto done;
|
||||
} else if (s_ip6)
|
||||
nm_connection_add_setting (connection, s_ip6);
|
||||
|
||||
/* iSCSI / ibft connections are read-only since their settings are
|
||||
* stored in NVRAM and can only be changed in BIOS.
|
||||
*/
|
||||
|
|
@ -2716,6 +3185,7 @@ connection_from_file (const char *filename,
|
|||
|
||||
*keyfile = utils_get_keys_path (filename);
|
||||
*routefile = utils_get_route_path (filename);
|
||||
*route6file = utils_get_route6_path (filename);
|
||||
|
||||
done:
|
||||
svCloseFile (parsed);
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ NMConnection *connection_from_file (const char *filename,
|
|||
char **unmanaged,
|
||||
char **keyfile,
|
||||
char **routefile,
|
||||
char **route6file,
|
||||
GError **error,
|
||||
gboolean *ignore_error);
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,9 @@ EXTRA_DIST = \
|
|||
ifcfg-test-wired-static-routes \
|
||||
route-test-wired-static-routes \
|
||||
ifcfg-test-wired-static-routes-legacy \
|
||||
route-test-wired-static-routes-legacy
|
||||
route-test-wired-static-routes-legacy \
|
||||
ifcfg-test-wired-ipv6-manual \
|
||||
route6-test-wired-ipv6-manual
|
||||
|
||||
check-local:
|
||||
@for f in $(EXTRA_DIST); do \
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ BOOTPROTO=dhcp
|
|||
DEFROUTE=yes
|
||||
UUID=ba60d05a-7898-820d-c2db-427a88f8f2a5
|
||||
ONBOOT=yes
|
||||
IPV6INIT=no
|
||||
PEERDNS=yes
|
||||
PEERROUTES=yes
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ NM_CONTROLLED=yes
|
|||
PEERDNS=yes
|
||||
DEFROUTE=no
|
||||
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=yes
|
||||
IPV6_DEFROUTE=no
|
||||
|
||||
|
|
|
|||
|
|
@ -9,3 +9,7 @@ NM_CONTROLLED=yes
|
|||
PEERDNS=yes
|
||||
DEFROUTE=no
|
||||
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=yes
|
||||
IPV6_DEFROUTE=no
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
# Intel Corporation 82567LM Gigabit Network Connection
|
||||
TYPE=Ethernet
|
||||
DEVICE=eth2
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=dhcp
|
||||
ONBOOT=yes
|
||||
USERCTL=yes
|
||||
NM_CONTROLLED=yes
|
||||
PEERDNS=yes
|
||||
DNS1=10.2.0.4
|
||||
DNS2=10.2.0.5
|
||||
DNS3=1:2:3:4::a
|
||||
DNS4=1:2:3:4::b
|
||||
DOMAIN="lorem.com ipsum.org dolor.edu"
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=no
|
||||
IPV6ADDR="1001:abba::1234/56"
|
||||
IPV6ADDR_SECONDARIES="2001:abba::2234/64 3001:abba::3234/96"
|
||||
|
|
@ -7,4 +7,5 @@ ONBOOT=yes
|
|||
USERCTL=yes
|
||||
NM_CONTROLLED=yes
|
||||
PEERDNS=yes
|
||||
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=yes
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ HWADDR=00:11:22:33:44:ee
|
|||
BOOTPROTO=none
|
||||
ONBOOT=yes
|
||||
USERCTL=yes
|
||||
IPV6INIT=no
|
||||
MTU=1492
|
||||
NM_CONTROLLED=yes
|
||||
DNS1=4.2.2.1
|
||||
|
|
@ -13,3 +12,9 @@ DNS2=4.2.2.2
|
|||
IPADDR=192.168.1.5
|
||||
NETMASK=255.255.255.0
|
||||
GATEWAY=192.168.1.1
|
||||
IPV6INIT=yes
|
||||
IPV6_AUTOCONF=no
|
||||
IPV6ADDR=dead:beaf::1
|
||||
IPV6ADDR_SECONDARIES="dead:beaf::2/56"
|
||||
DNS3=1:2:3:4::a
|
||||
DNS4=1:2:3:4::b
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
GATEWAYDEV=eth0
|
||||
IPV6_DEFAULTDEV=eth0
|
||||
|
|
|
|||
|
|
@ -1 +1,4 @@
|
|||
GATEWAYDEV=eth0
|
||||
# when devices in IPV6_DEFAULTDEV and IPV6_DEFAULTGW don't match the one in IPV6_DEFAULTGW is prefered
|
||||
IPV6_DEFAULTDEV=eth4
|
||||
IPV6_DEFAULTGW=2001::1234%eth0
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
9876::1234/96 via 9876::7777 metric 2
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -149,7 +149,8 @@ utils_should_ignore_file (const char *filename, gboolean only_ifcfg)
|
|||
|
||||
if (only_ifcfg == FALSE) {
|
||||
if ( !strncmp (base, KEYS_TAG, strlen (KEYS_TAG))
|
||||
|| !strncmp (base, ROUTE_TAG, strlen (ROUTE_TAG)))
|
||||
|| !strncmp (base, ROUTE_TAG, strlen (ROUTE_TAG))
|
||||
|| !strncmp (base, ROUTE6_TAG, strlen (ROUTE6_TAG)))
|
||||
is_other = TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -208,6 +209,8 @@ utils_get_ifcfg_name (const char *file, gboolean only_ifcfg)
|
|||
name = start + strlen (KEYS_TAG);
|
||||
else if (!strncmp (start, ROUTE_TAG, strlen (ROUTE_TAG)))
|
||||
name = start + strlen (ROUTE_TAG);
|
||||
else if (!strncmp (start, ROUTE6_TAG, strlen (ROUTE6_TAG)))
|
||||
name = start + strlen (ROUTE6_TAG);
|
||||
}
|
||||
|
||||
return name;
|
||||
|
|
@ -259,6 +262,12 @@ utils_get_route_path (const char *parent)
|
|||
return utils_get_extra_path (parent, ROUTE_TAG);
|
||||
}
|
||||
|
||||
char *
|
||||
utils_get_route6_path (const char *parent)
|
||||
{
|
||||
return utils_get_extra_path (parent, ROUTE6_TAG);
|
||||
}
|
||||
|
||||
shvarFile *
|
||||
utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create)
|
||||
{
|
||||
|
|
@ -291,9 +300,15 @@ utils_get_route_ifcfg (const char *parent, gboolean should_create)
|
|||
return utils_get_extra_ifcfg (parent, ROUTE_TAG, should_create);
|
||||
}
|
||||
|
||||
shvarFile *
|
||||
utils_get_route6_ifcfg (const char *parent, gboolean should_create)
|
||||
{
|
||||
return utils_get_extra_ifcfg (parent, ROUTE6_TAG, should_create);
|
||||
}
|
||||
|
||||
/* Finds out if route file has new or older format
|
||||
* Returns TRUE - new syntax (ADDRESS<n>=a.b.c.d ...), error opening file or empty
|
||||
* FALSE - legacy syntax (1.2.3.0/24 via 11.22.33.44)
|
||||
* FALSE - older syntax, i.e. argument to 'ip route add' (1.2.3.0/24 via 11.22.33.44)
|
||||
*/
|
||||
gboolean
|
||||
utils_has_route_file_new_syntax (const char *filename)
|
||||
|
|
|
|||
|
|
@ -38,10 +38,12 @@ gboolean utils_should_ignore_file (const char *filename, gboolean only_ifcfg);
|
|||
char *utils_get_ifcfg_path (const char *parent);
|
||||
char *utils_get_keys_path (const char *parent);
|
||||
char *utils_get_route_path (const char *parent);
|
||||
char *utils_get_route6_path (const char *parent);
|
||||
|
||||
shvarFile *utils_get_extra_ifcfg (const char *parent, const char *tag, gboolean should_create);
|
||||
shvarFile *utils_get_keys_ifcfg (const char *parent, gboolean should_create);
|
||||
shvarFile *utils_get_route_ifcfg (const char *parent, gboolean should_create);
|
||||
shvarFile *utils_get_route6_ifcfg (const char *parent, gboolean should_create);
|
||||
|
||||
gboolean utils_has_route_file_new_syntax (const char *filename);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include <nm-setting-wireless.h>
|
||||
#include <nm-setting-8021x.h>
|
||||
#include <nm-setting-ip4-config.h>
|
||||
#include <nm-setting-ip6-config.h>
|
||||
#include <nm-setting-pppoe.h>
|
||||
#include <nm-utils.h>
|
||||
|
||||
|
|
@ -855,8 +856,10 @@ write_route_file_legacy (const char *filename, NMSettingIP4Config *s_ip4, GError
|
|||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
num = nm_setting_ip4_config_get_num_routes (s_ip4);
|
||||
if (num == 0)
|
||||
if (num == 0) {
|
||||
unlink (filename);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
route_items = g_malloc0 (sizeof (char*) * (num + 1));
|
||||
for (i = 0; i < num; i++) {
|
||||
|
|
@ -1117,6 +1120,213 @@ out:
|
|||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_route6_file (const char *filename, NMSettingIP6Config *s_ip6, GError **error)
|
||||
{
|
||||
char dest[INET6_ADDRSTRLEN];
|
||||
char next_hop[INET6_ADDRSTRLEN];
|
||||
char **route_items;
|
||||
char *route_contents;
|
||||
NMIP6Route *route;
|
||||
const struct in6_addr *ip;
|
||||
guint32 prefix, metric;
|
||||
guint32 i, num;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (filename != NULL, FALSE);
|
||||
g_return_val_if_fail (s_ip6 != NULL, FALSE);
|
||||
g_return_val_if_fail (error != NULL, FALSE);
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
num = nm_setting_ip6_config_get_num_routes (s_ip6);
|
||||
if (num == 0) {
|
||||
unlink (filename);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
route_items = g_malloc0 (sizeof (char*) * (num + 1));
|
||||
for (i = 0; i < num; i++) {
|
||||
route = nm_setting_ip6_config_get_route (s_ip6, i);
|
||||
|
||||
memset (dest, 0, sizeof (dest));
|
||||
ip = nm_ip6_route_get_dest (route);
|
||||
inet_ntop (AF_INET6, (const void *) ip, &dest[0], sizeof (dest));
|
||||
|
||||
prefix = nm_ip6_route_get_prefix (route);
|
||||
|
||||
memset (next_hop, 0, sizeof (next_hop));
|
||||
ip = nm_ip6_route_get_next_hop (route);
|
||||
inet_ntop (AF_INET6, (const void *) ip, &next_hop[0], sizeof (next_hop));
|
||||
|
||||
metric = nm_ip6_route_get_metric (route);
|
||||
|
||||
route_items[i] = g_strdup_printf ("%s/%u via %s metric %u\n", dest, prefix, next_hop, metric);
|
||||
}
|
||||
route_items[num] = NULL;
|
||||
route_contents = g_strjoinv (NULL, route_items);
|
||||
g_strfreev (route_items);
|
||||
|
||||
if (!g_file_set_contents (filename, route_contents, -1, NULL)) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Writing route6 file '%s' failed", filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
error:
|
||||
g_free (route_contents);
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
||||
{
|
||||
NMSettingIP6Config *s_ip6;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
const char *value;
|
||||
char *addr_key, *prefix;
|
||||
guint32 i, num, num4;
|
||||
GString *searches;
|
||||
char buf[INET6_ADDRSTRLEN];
|
||||
NMIP6Address *addr;
|
||||
const struct in6_addr *ip;
|
||||
GString *ip_str1, *ip_str2, *ip_ptr;
|
||||
char *route6_path;
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (!s_ip6) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Missing '%s' setting", NM_SETTING_IP6_CONFIG_SETTING_NAME);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
value = nm_setting_ip6_config_get_method (s_ip6);
|
||||
g_assert (value);
|
||||
if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
|
||||
svSetValue (ifcfg, "IPV6INIT", "no", FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
|
||||
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
|
||||
svSetValue (ifcfg, "IPV6_AUTOCONF", "yes", FALSE);
|
||||
}
|
||||
else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
|
||||
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
|
||||
svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
|
||||
}
|
||||
else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
|
||||
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
|
||||
svSetValue (ifcfg, "IPV6_AUTOCONF", "no", FALSE);
|
||||
}
|
||||
else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
|
||||
svSetValue (ifcfg, "IPV6INIT", "yes", FALSE);
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
|
||||
/* Write out IP addresses */
|
||||
num = nm_setting_ip6_config_get_num_addresses (s_ip6);
|
||||
|
||||
ip_str1 = g_string_new (NULL);
|
||||
ip_str2 = g_string_new (NULL);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (i == 0)
|
||||
ip_ptr = ip_str1;
|
||||
else
|
||||
ip_ptr = ip_str2;
|
||||
|
||||
addr = nm_setting_ip6_config_get_address (s_ip6, i);
|
||||
ip = nm_ip6_address_get_address (addr);
|
||||
prefix = g_strdup_printf ("%u", nm_ip6_address_get_prefix (addr));
|
||||
memset (buf, 0, sizeof (buf));
|
||||
inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
|
||||
if (i > 1)
|
||||
g_string_append_c (ip_ptr, ' '); /* separate addresses in IPV6ADDR_SECONDARIES */
|
||||
g_string_append (ip_ptr, buf);
|
||||
g_string_append_c (ip_ptr, '/');
|
||||
g_string_append (ip_ptr, prefix);
|
||||
g_free (prefix);
|
||||
}
|
||||
|
||||
svSetValue (ifcfg, "IPV6ADDR", ip_str1->str, FALSE);
|
||||
svSetValue (ifcfg, "IPV6ADDR_SECONDARIES", ip_str2->str, FALSE);
|
||||
g_string_free (ip_str1, TRUE);
|
||||
g_string_free (ip_str2, TRUE);
|
||||
}
|
||||
|
||||
/* Write out DNS - 'DNS' key is used both for IPv4 and IPv6 */
|
||||
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
num4 = s_ip4 ? nm_setting_ip4_config_get_num_dns (s_ip4) : 0; /* from where to start with IPv6 entries */
|
||||
num = nm_setting_ip6_config_get_num_dns (s_ip6);
|
||||
for (i = 0; i < 254; i++) {
|
||||
addr_key = g_strdup_printf ("DNS%d", i + num4 + 1);
|
||||
|
||||
if (i >= num)
|
||||
svSetValue (ifcfg, addr_key, NULL, FALSE);
|
||||
else {
|
||||
ip = nm_setting_ip6_config_get_dns (s_ip6, i);
|
||||
|
||||
memset (buf, 0, sizeof (buf));
|
||||
inet_ntop (AF_INET6, (const void *) ip, buf, sizeof (buf));
|
||||
svSetValue (ifcfg, addr_key, buf, FALSE);
|
||||
}
|
||||
g_free (addr_key);
|
||||
}
|
||||
|
||||
/* Write out DNS domains - 'DOMAIN' key is shared for both IPv4 and IPv6 domains */
|
||||
num = nm_setting_ip6_config_get_num_dns_searches (s_ip6);
|
||||
if (num > 0) {
|
||||
char *ip4_domains;
|
||||
ip4_domains = svGetValue (ifcfg, "DOMAIN", FALSE);
|
||||
searches = g_string_new (ip4_domains);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (searches->len > 0)
|
||||
g_string_append_c (searches, ' ');
|
||||
g_string_append (searches, nm_setting_ip6_config_get_dns_search (s_ip6, i));
|
||||
}
|
||||
svSetValue (ifcfg, "DOMAIN", searches->str, FALSE);
|
||||
g_string_free (searches, TRUE);
|
||||
g_free (ip4_domains);
|
||||
}
|
||||
|
||||
/* handle IPV6_DEFROUTE */
|
||||
/* IPV6_DEFROUTE has the opposite meaning from 'never-default' */
|
||||
if (nm_setting_ip6_config_get_never_default(s_ip6))
|
||||
svSetValue (ifcfg, "IPV6_DEFROUTE", "no", FALSE);
|
||||
else
|
||||
svSetValue (ifcfg, "IPV6_DEFROUTE", "yes", FALSE);
|
||||
|
||||
svSetValue (ifcfg, "IPV6_PEERDNS", NULL, FALSE);
|
||||
svSetValue (ifcfg, "IPV6_PEERROUTES", NULL, FALSE);
|
||||
if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
|
||||
svSetValue (ifcfg, "IPV6_PEERDNS",
|
||||
nm_setting_ip6_config_get_ignore_auto_dns (s_ip6) ? "no" : "yes",
|
||||
FALSE);
|
||||
|
||||
svSetValue (ifcfg, "IPV6_PEERROUTES",
|
||||
nm_setting_ip6_config_get_ignore_auto_routes (s_ip6) ? "no" : "yes",
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/* Static routes go to route6-<dev> file */
|
||||
route6_path = utils_get_route6_path (ifcfg->fileName);
|
||||
if (!route6_path) {
|
||||
g_set_error (error, ifcfg_plugin_error_quark (), 0,
|
||||
"Could not get route6 file path for '%s'", ifcfg->fileName);
|
||||
goto error;
|
||||
}
|
||||
write_route6_file (route6_path, s_ip6, error);
|
||||
g_free (route6_path);
|
||||
if (error && *error)
|
||||
goto error;
|
||||
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static char *
|
||||
escape_id (const char *id)
|
||||
{
|
||||
|
|
@ -1142,11 +1352,11 @@ write_connection (NMConnection *connection,
|
|||
const char *ifcfg_dir,
|
||||
const char *filename,
|
||||
const char *keyfile,
|
||||
const char *routefile,
|
||||
char **out_filename,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
gboolean success = FALSE;
|
||||
shvarFile *ifcfg = NULL;
|
||||
char *ifcfg_name = NULL;
|
||||
|
|
@ -1216,6 +1426,12 @@ write_connection (NMConnection *connection,
|
|||
if (!write_ip4_setting (connection, ifcfg, error))
|
||||
goto out;
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6) {
|
||||
if (!write_ip6_setting (connection, ifcfg, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
write_connection_setting (s_con, ifcfg);
|
||||
|
||||
if (svWriteFile (ifcfg, 0644)) {
|
||||
|
|
@ -1243,7 +1459,7 @@ writer_new_connection (NMConnection *connection,
|
|||
char **out_filename,
|
||||
GError **error)
|
||||
{
|
||||
return write_connection (connection, ifcfg_dir, NULL, NULL, NULL, out_filename, error);
|
||||
return write_connection (connection, ifcfg_dir, NULL, NULL, out_filename, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -1251,9 +1467,8 @@ writer_update_connection (NMConnection *connection,
|
|||
const char *ifcfg_dir,
|
||||
const char *filename,
|
||||
const char *keyfile,
|
||||
const char *routefile,
|
||||
GError **error)
|
||||
{
|
||||
return write_connection (connection, ifcfg_dir, filename, keyfile, routefile, NULL, error);
|
||||
return write_connection (connection, ifcfg_dir, filename, keyfile, NULL, error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ gboolean writer_update_connection (NMConnection *connection,
|
|||
const char *ifcfg_dir,
|
||||
const char *filename,
|
||||
const char *keyfile,
|
||||
const char *routefile,
|
||||
GError **error);
|
||||
|
||||
#endif /* _WRITER_H_ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue