1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA.
19 * Copyright 2007 - 2014 Red Hat, Inc.
22 #include "nm-default.h"
24 #include "nm-setting-ip6-config.h"
28 #include "nm-setting-private.h"
29 #include "nm-core-enum-types.h"
32 * SECTION:nm-setting-ip6-config
33 * @short_description: Describes IPv6 addressing, routing, and name service properties
35 * The #NMSettingIP6Config object is a #NMSetting subclass that describes
36 * properties related to IPv6 addressing, routing, and Domain Name Service
38 * #NMSettingIP6Config has few properties or methods of its own; it inherits
39 * almost everything from #NMSettingIPConfig.
41 * NetworkManager supports 6 values for the #NMSettingIPConfig:method property
42 * for IPv6. If "auto" is specified then the appropriate automatic method (PPP,
43 * router advertisement, etc) is used for the device and most other properties
44 * can be left unset. To force the use of DHCP only, specify "dhcp"; this
45 * method is only valid for Ethernet- based hardware. If "link-local" is
46 * specified, then an IPv6 link-local address will be assigned to the interface.
47 * If "manual" is specified, static IP addressing is used and at least one IP
48 * address must be given in the "addresses" property. If "ignore" is specified,
49 * IPv6 configuration is not done. Note: the "shared" method is not yet
53 G_DEFINE_TYPE_WITH_CODE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG,
54 _nm_register_setting (IP6_CONFIG, 4))
55 NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP6_CONFIG)
57 #define NM_SETTING_IP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigPrivate))
60 NMSettingIP6ConfigPrivacy ip6_privacy;
61 NMSettingIP6ConfigAddrGenMode addr_gen_mode;
62 } NMSettingIP6ConfigPrivate;
74 * nm_setting_ip6_config_new:
76 * Creates a new #NMSettingIP6Config object with default values.
78 * Returns: (transfer full): the new empty #NMSettingIP6Config object
81 nm_setting_ip6_config_new (void)
83 return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP6_CONFIG, NULL);
87 * nm_setting_ip6_config_get_ip6_privacy:
88 * @setting: the #NMSettingIP6Config
90 * Returns the value contained in the #NMSettingIP6Config:ip6-privacy
93 * Returns: IPv6 Privacy Extensions configuration value (#NMSettingIP6ConfigPrivacy).
95 NMSettingIP6ConfigPrivacy
96 nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting)
98 g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
100 return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->ip6_privacy;
104 * nm_setting_ip6_config_get_addr_gen_mode:
105 * @setting: the #NMSettingIP6Config
107 * Returns the value contained in the #NMSettingIP6Config:addr-gen-mode
110 * Returns: IPv6 Address Generation Mode.
114 NMSettingIP6ConfigAddrGenMode
115 nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting)
117 g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting),
118 NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY);
120 return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->addr_gen_mode;
124 verify (NMSetting *setting, NMConnection *connection, GError **error)
126 NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting);
127 NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
128 NMSettingVerifyResult ret;
131 ret = NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error);
132 if (ret != NM_SETTING_VERIFY_SUCCESS)
135 method = nm_setting_ip_config_get_method (s_ip);
136 /* Base class already checked that it exists */
139 if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
140 if (nm_setting_ip_config_get_num_addresses (s_ip) == 0) {
143 NM_CONNECTION_ERROR_MISSING_PROPERTY,
144 _("this property cannot be empty for '%s=%s'"),
145 NM_SETTING_IP_CONFIG_METHOD, method);
146 g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES);
149 } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)
150 || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)
151 || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
152 if (nm_setting_ip_config_get_num_dns (s_ip) > 0) {
155 NM_CONNECTION_ERROR_INVALID_PROPERTY,
156 _("this property is not allowed for '%s=%s'"),
157 NM_SETTING_IP_CONFIG_METHOD, method);
158 g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS);
162 if (nm_setting_ip_config_get_num_dns_searches (s_ip) > 0) {
165 NM_CONNECTION_ERROR_INVALID_PROPERTY,
166 _("this property is not allowed for '%s=%s'"),
167 NM_SETTING_IP_CONFIG_METHOD, method);
168 g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS_SEARCH);
172 if (nm_setting_ip_config_get_num_addresses (s_ip) > 0) {
175 NM_CONNECTION_ERROR_INVALID_PROPERTY,
176 _("this property is not allowed for '%s=%s'"),
177 NM_SETTING_IP_CONFIG_METHOD, method);
178 g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES);
181 } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
182 || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
185 g_set_error_literal (error,
187 NM_CONNECTION_ERROR_INVALID_PROPERTY,
188 _("property is invalid"));
189 g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD);
193 if (!NM_IN_SET (priv->addr_gen_mode,
194 NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
195 NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY)) {
196 g_set_error_literal (error,
198 NM_CONNECTION_ERROR_INVALID_PROPERTY,
199 _("property is invalid"));
200 g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD);
209 nm_setting_ip6_config_init (NMSettingIP6Config *setting)
214 ip6_dns_to_dbus (const GValue *prop_value)
216 return nm_utils_ip6_dns_to_variant (g_value_get_boxed (prop_value));
220 ip6_dns_from_dbus (GVariant *dbus_value,
223 g_value_take_boxed (prop_value, nm_utils_ip6_dns_from_variant (dbus_value));
227 ip6_addresses_get (NMSetting *setting,
228 const char *property)
234 g_object_get (setting, property, &addrs, NULL);
235 gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting));
236 ret = nm_utils_ip6_addresses_to_variant (addrs, gateway);
237 g_ptr_array_unref (addrs);
243 ip6_addresses_set (NMSetting *setting,
244 GVariant *connection_dict,
245 const char *property,
247 NMSettingParseFlags parse_flags,
251 char *gateway = NULL;
253 /* FIXME: properly handle errors */
255 if (!_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data"))
258 addrs = nm_utils_ip6_addresses_from_variant (value, &gateway);
260 g_object_set (setting,
261 NM_SETTING_IP_CONFIG_ADDRESSES, addrs,
262 NM_SETTING_IP_CONFIG_GATEWAY, gateway,
264 g_ptr_array_unref (addrs);
270 ip6_address_data_get (NMSetting *setting,
271 NMConnection *connection,
272 const char *property)
277 g_object_get (setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL);
278 ret = nm_utils_ip_addresses_to_variant (addrs);
279 g_ptr_array_unref (addrs);
285 ip6_address_data_set (NMSetting *setting,
286 GVariant *connection_dict,
287 const char *property,
289 NMSettingParseFlags parse_flags,
294 /* FIXME: properly handle errors */
296 /* Ignore 'address-data' if we're going to process 'addresses' */
297 if (_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data"))
300 addrs = nm_utils_ip_addresses_from_variant (value, AF_INET6);
301 g_object_set (setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL);
302 g_ptr_array_unref (addrs);
307 ip6_routes_get (NMSetting *setting,
308 const char *property)
313 g_object_get (setting, property, &routes, NULL);
314 ret = nm_utils_ip6_routes_to_variant (routes);
315 g_ptr_array_unref (routes);
321 ip6_routes_set (NMSetting *setting,
322 GVariant *connection_dict,
323 const char *property,
325 NMSettingParseFlags parse_flags,
330 /* FIXME: properly handle errors */
332 if (!_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data"))
335 routes = nm_utils_ip6_routes_from_variant (value);
336 g_object_set (setting, property, routes, NULL);
337 g_ptr_array_unref (routes);
342 ip6_route_data_get (NMSetting *setting,
343 NMConnection *connection,
344 const char *property)
349 g_object_get (setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL);
350 ret = nm_utils_ip_routes_to_variant (routes);
351 g_ptr_array_unref (routes);
357 ip6_route_data_set (NMSetting *setting,
358 GVariant *connection_dict,
359 const char *property,
361 NMSettingParseFlags parse_flags,
366 /* FIXME: properly handle errors */
368 /* Ignore 'route-data' if we're going to process 'routes' */
369 if (_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data"))
372 routes = nm_utils_ip_routes_from_variant (value, AF_INET6);
373 g_object_set (setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL);
374 g_ptr_array_unref (routes);
379 set_property (GObject *object, guint prop_id,
380 const GValue *value, GParamSpec *pspec)
382 NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object);
385 case PROP_IP6_PRIVACY:
386 priv->ip6_privacy = g_value_get_enum (value);
388 case PROP_ADDR_GEN_MODE:
389 priv->addr_gen_mode = g_value_get_int (value);
392 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
398 get_property (GObject *object, guint prop_id,
399 GValue *value, GParamSpec *pspec)
401 NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object);
404 case PROP_IP6_PRIVACY:
405 g_value_set_enum (value, priv->ip6_privacy);
407 case PROP_ADDR_GEN_MODE:
408 g_value_set_int (value, priv->addr_gen_mode);
411 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
417 nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class)
419 GObjectClass *object_class = G_OBJECT_CLASS (ip6_class);
420 NMSettingClass *setting_class = NM_SETTING_CLASS (ip6_class);
422 g_type_class_add_private (ip6_class, sizeof (NMSettingIP6ConfigPrivate));
424 /* virtual methods */
425 object_class->set_property = set_property;
426 object_class->get_property = get_property;
427 setting_class->verify = verify;
433 * variable: IPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6C
434 * default: IPV6INIT=yes; IPV6FORWARDING=no; IPV6_AUTOCONF=!IPV6FORWARDING, DHCPV6=no
435 * description: Method used for IPv6 protocol configuration.
436 * ignore ~ IPV6INIT=no; auto ~ IPV6_AUTOCONF=yes; dhcp ~ IPV6_AUTOCONF=no and DHCPV6C=yes
442 * format: list of DNS IP addresses
443 * description: List of DNS servers.
444 * example: dns=2001:4860:4860::8888;2001:4860:4860::8844;
448 * variable: DNS1, DNS2, ...
450 * description: List of DNS servers. NetworkManager uses the variables both
456 * property: dns-search
458 * format: string (space-separated domains)
459 * description: List of DNS search domains.
464 * property: addresses
465 * variable: address1, address2, ...
466 * format: address/plen
467 * description: List of static IP addresses.
468 * example: address1=abbe::cafe/96 address2=2001::1234
471 * property: addresses
472 * variable: IPV6ADDR, IPV6ADDR_SECONDARIES
473 * description: List of static IP addresses.
474 * example: IPV6ADDR=ab12:9876::1
475 * IPV6ADDR_SECONDARIES="ab12:9876::2 ab12:9876::3"
483 * description: Gateway IP addresses as a string.
484 * example: gateway=abbe::1
488 * variable: IPV6_DEFAULTGW
489 * description: Gateway IP address.
490 * example: IPV6_DEFAULTGW=abbe::1
496 * variable: route1, route2, ...
497 * format: route/plen[,gateway,metric]
498 * description: List of IP routes.
499 * example: route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403
504 * description: List of static routes. They are not stored in ifcfg-* file,
505 * but in route6-* file instead in the form of command line for 'ip route add'.
510 * property: ignore-auto-routes
511 * variable: IPV6_PEERROUTES(+)
513 * description: IPV6_PEERROUTES has the opposite meaning as 'ignore-auto-routes' property.
518 * property: ignore-auto-dns
519 * variable: IPV6_PEERDNS(+)
521 * description: IPV6_PEERDNS has the opposite meaning as 'ignore-auto-dns' property.
526 * property: dhcp-hostname
527 * variable: DHCP_HOSTNAME
528 * description: Hostname to send the DHCP server.
533 * property: never-default
534 * variable: IPV6_DEFROUTE(+), (and IPV6_DEFAULTGW, IPV6_DEFAULTDEV in /etc/sysconfig/network)
535 * default: IPV6_DEFROUTE=yes (when no variable specified)
536 * description: IPV6_DEFROUTE=no tells NetworkManager that this connection
537 * should not be assigned the default IPv6 route. IPV6_DEFROUTE has the opposite
538 * meaning as 'never-default' property.
544 * variable: IPV6_FAILURE_FATAL(+)
546 * description: IPV6_FAILURE_FATAL has the opposite meaning as 'may-fail' property.
551 * property: route-metric
552 * variable: IPV6_ROUTE_METRIC(+)
554 * description: IPV6_ROUTE_METRIC is the default IPv6 metric for routes on this connection.
555 * If set to -1, a default metric based on the device type is used.
560 * NMSettingIP6Config:ip6-privacy:
562 * Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If
563 * enabled, it makes the kernel generate a temporary IPv6 address in
564 * addition to the public one generated from MAC address via modified
565 * EUI-64. This enhances privacy, but could cause problems in some
566 * applications, on the other hand. The permitted values are: -1: unknown,
567 * 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary
570 * Having a per-connection setting set to "-1" (unknown) means fallback to
571 * global configuration "ipv6.ip6-privacy".
573 * If also global configuration is unspecified or set to "-1", fallback to read
574 * "/proc/sys/net/ipv6/conf/default/use_tempaddr".
576 * Note that this setting is distinct from the Stable Privacy addresses
577 * that can be enabled with the "addr-gen-mode" property's "stable-privacy"
578 * setting as another way of avoiding host tracking with IPv6 addresses.
581 * property: ip6-privacy
582 * variable: IPV6_PRIVACY, IPV6_PRIVACY_PREFER_PUBLIC_IP(+)
583 * values: IPV6_PRIVACY: no, yes (rfc3041 or rfc4941);
584 * IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no
586 * description: Configure IPv6 Privacy Extensions for SLAAC (RFC4941).
587 * example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes
590 g_object_class_install_property
591 (object_class, PROP_IP6_PRIVACY,
592 g_param_spec_enum (NM_SETTING_IP6_CONFIG_IP6_PRIVACY, "", "",
593 NM_TYPE_SETTING_IP6_CONFIG_PRIVACY,
594 NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
597 G_PARAM_STATIC_STRINGS));
600 * NMSettingIP6Config:addr-gen-mode:
602 * Configure method for creating the address for use with RFC4862 IPv6
603 * Stateless Address Autoconfiguration. The permitted values are: "eui64",
604 * "stable-privacy" or unset.
606 * If the property is set to "eui64", the addresses will be generated
607 * using the interface tokens derived from hardware address. This makes
608 * the host part of the address to stay constant, making it possible
609 * to track host's presence when it changes networks. The address changes
610 * when the interface hardware is replaced.
612 * The value of "stable-privacy" enables use of cryptographically
613 * secure hash of a secret host-specific key along with the connection
614 * identification and the network address as specified by RFC7217.
615 * This makes it impossible to use the address track host's presence,
616 * and makes the address stable when the network interface hardware is
619 * Leaving this unset causes a default that could be subject to change
620 * in future versions to be used.
622 * Note that this setting is distinct from the Privacy Extensions as
623 * configured by "ip6-privacy" property and it does not affect the
624 * temporary addresses configured with this option.
629 * property: addr-gen-mode
630 * variable: IPV6_ADDR_GEN_MODE
631 * values: IPV6_ADDR_GEN_MODE: eui64, stable-privacy
633 * description: Configure IPv6 Stable Privacy addressing for SLAAC (RFC7217).
634 * example: IPV6_ADDR_GEN_MODE=stable-privacy
637 g_object_class_install_property
638 (object_class, PROP_ADDR_GEN_MODE,
639 g_param_spec_int (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, "", "",
641 NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY,
644 G_PARAM_STATIC_STRINGS));
646 /* IP6-specific property overrides */
650 * format: array of byte array
651 * description: Array of IP addresses of DNS servers (in network byte order)
654 _nm_setting_class_transform_property (setting_class,
655 NM_SETTING_IP_CONFIG_DNS,
656 G_VARIANT_TYPE ("aay"),
661 * property: addresses
662 * format: array of legacy IPv6 address struct (a(ayuay))
663 * description: Deprecated in favor of the 'address-data' and 'gateway'
664 * properties, but this can be used for backward-compatibility with older
665 * daemons. Note that if you send this property the daemon will ignore
666 * 'address-data' and 'gateway'.
668 * Array of IPv6 address structures. Each IPv6 address structure is
669 * composed of an IPv6 address, a prefix length (1 - 128), and an IPv6
670 * gateway address. The gateway may be zeroed out if no gateway exists for
674 _nm_setting_class_override_property (setting_class,
675 NM_SETTING_IP_CONFIG_ADDRESSES,
676 G_VARIANT_TYPE ("a(ayuay)"),
682 * property: address-data
683 * format: array of vardict
684 * description: Array of IPv6 addresses. Each address dictionary contains at
685 * least 'address' and 'prefix' entries, containing the IP address as a
686 * string, and the prefix length as a uint32. Additional attributes may
687 * also exist on some addresses.
690 _nm_setting_class_add_dbus_only_property (setting_class,
692 G_VARIANT_TYPE ("aa{sv}"),
693 ip6_address_data_get,
694 ip6_address_data_set);
698 * format: array of legacy IPv6 route struct (a(ayuayu))
699 * description: Deprecated in favor of the 'route-data' property, but this
700 * can be used for backward-compatibility with older daemons. Note that if
701 * you send this property the daemon will ignore 'route-data'.
703 * Array of IPv6 route structures. Each IPv6 route structure is
704 * composed of an IPv6 address, a prefix length (1 - 128), an IPv6
705 * next hop address (which may be zeroed out if there is no next hop),
706 * and a metric. If the metric is 0, NM will choose an appropriate
707 * default metric for the device.
710 _nm_setting_class_override_property (setting_class,
711 NM_SETTING_IP_CONFIG_ROUTES,
712 G_VARIANT_TYPE ("a(ayuayu)"),
718 * property: route-data
719 * format: array of vardict
720 * description: Array of IPv6 routes. Each route dictionary contains at
721 * least 'dest' and 'prefix' entries, containing the destination IP
722 * address as a string, and the prefix length as a uint32. Most routes
723 * will also have a 'next-hop' entry, containing the next hop IP address as
724 * a string. If the route has a 'metric' entry (containing a uint32), that
725 * will be used as the metric for the route (otherwise NM will pick a
726 * default value appropriate to the device). Additional attributes may
727 * also exist on some routes.
730 _nm_setting_class_add_dbus_only_property (setting_class,
732 G_VARIANT_TYPE ("aa{sv}"),