nm-setting-ip6-config.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979
  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
  2. /*
  3. * This library is free software; you can redistribute it and/or
  4. * modify it under the terms of the GNU Lesser General Public
  5. * License as published by the Free Software Foundation; either
  6. * version 2 of the License, or (at your option) any later version.
  7. *
  8. * This library is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * Lesser General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Lesser General Public
  14. * License along with this library; if not, write to the
  15. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  16. * Boston, MA 02110-1301 USA.
  17. *
  18. * Copyright 2007 - 2014 Red Hat, Inc.
  19. */
  20. #include "nm-default.h"
  21. #include "nm-setting-ip6-config.h"
  22. #include <string.h>
  23. #include <arpa/inet.h>
  24. #include "nm-setting-private.h"
  25. #include "nm-core-enum-types.h"
  26. #include "nm-core-internal.h"
  27. /**
  28. * SECTION:nm-setting-ip6-config
  29. * @short_description: Describes IPv6 addressing, routing, and name service properties
  30. *
  31. * The #NMSettingIP6Config object is a #NMSetting subclass that describes
  32. * properties related to IPv6 addressing, routing, and Domain Name Service
  33. *
  34. * #NMSettingIP6Config has few properties or methods of its own; it inherits
  35. * almost everything from #NMSettingIPConfig.
  36. *
  37. * NetworkManager supports 6 values for the #NMSettingIPConfig:method property
  38. * for IPv6. If "auto" is specified then the appropriate automatic method (PPP,
  39. * router advertisement, etc) is used for the device and most other properties
  40. * can be left unset. To force the use of DHCP only, specify "dhcp"; this
  41. * method is only valid for Ethernet- based hardware. If "link-local" is
  42. * specified, then an IPv6 link-local address will be assigned to the interface.
  43. * If "manual" is specified, static IP addressing is used and at least one IP
  44. * address must be given in the "addresses" property. If "ignore" is specified,
  45. * IPv6 configuration is not done. Note: the "shared" method is not yet
  46. * supported.
  47. **/
  48. G_DEFINE_TYPE (NMSettingIP6Config, nm_setting_ip6_config, NM_TYPE_SETTING_IP_CONFIG)
  49. #define NM_SETTING_IP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP6_CONFIG, NMSettingIP6ConfigPrivate))
  50. typedef struct {
  51. NMSettingIP6ConfigPrivacy ip6_privacy;
  52. NMSettingIP6ConfigAddrGenMode addr_gen_mode;
  53. char *token;
  54. char *dhcp_duid;
  55. } NMSettingIP6ConfigPrivate;
  56. enum {
  57. PROP_0,
  58. PROP_IP6_PRIVACY,
  59. PROP_ADDR_GEN_MODE,
  60. PROP_TOKEN,
  61. PROP_DHCP_DUID,
  62. LAST_PROP
  63. };
  64. /**
  65. * nm_setting_ip6_config_new:
  66. *
  67. * Creates a new #NMSettingIP6Config object with default values.
  68. *
  69. * Returns: (transfer full): the new empty #NMSettingIP6Config object
  70. **/
  71. NMSetting *
  72. nm_setting_ip6_config_new (void)
  73. {
  74. return (NMSetting *) g_object_new (NM_TYPE_SETTING_IP6_CONFIG, NULL);
  75. }
  76. /**
  77. * nm_setting_ip6_config_get_ip6_privacy:
  78. * @setting: the #NMSettingIP6Config
  79. *
  80. * Returns the value contained in the #NMSettingIP6Config:ip6-privacy
  81. * property.
  82. *
  83. * Returns: IPv6 Privacy Extensions configuration value (#NMSettingIP6ConfigPrivacy).
  84. **/
  85. NMSettingIP6ConfigPrivacy
  86. nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting)
  87. {
  88. g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
  89. return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->ip6_privacy;
  90. }
  91. /**
  92. * nm_setting_ip6_config_get_addr_gen_mode:
  93. * @setting: the #NMSettingIP6Config
  94. *
  95. * Returns the value contained in the #NMSettingIP6Config:addr-gen-mode
  96. * property.
  97. *
  98. * Returns: IPv6 Address Generation Mode.
  99. *
  100. * Since: 1.2
  101. **/
  102. NMSettingIP6ConfigAddrGenMode
  103. nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting)
  104. {
  105. g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting),
  106. NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY);
  107. return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->addr_gen_mode;
  108. }
  109. /**
  110. * nm_setting_ip6_config_get_token:
  111. * @setting: the #NMSettingIP6Config
  112. *
  113. * Returns the value contained in the #NMSettingIP6Config:token
  114. * property.
  115. *
  116. * Returns: A string.
  117. *
  118. * Since: 1.4
  119. **/
  120. const char *
  121. nm_setting_ip6_config_get_token (NMSettingIP6Config *setting)
  122. {
  123. g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NULL);
  124. return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->token;
  125. }
  126. /**
  127. * nm_setting_ip6_config_get_dhcp_duid:
  128. * @setting: the #NMSettingIP6Config
  129. *
  130. * Returns the value contained in the #NMSettingIP6Config:dhcp-duid
  131. * property.
  132. *
  133. * Returns: The configured DUID value to be included in the DHCPv6 requests
  134. * sent to the DHCPv6 servers.
  135. *
  136. * Since: 1.12
  137. **/
  138. const char *
  139. nm_setting_ip6_config_get_dhcp_duid (NMSettingIP6Config *setting)
  140. {
  141. g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NULL);
  142. return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->dhcp_duid;
  143. }
  144. static gboolean
  145. verify (NMSetting *setting, NMConnection *connection, GError **error)
  146. {
  147. NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting);
  148. NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting);
  149. NMSettingVerifyResult ret;
  150. const char *method;
  151. gboolean token_needs_normalization = FALSE;
  152. ret = NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error);
  153. if (ret != NM_SETTING_VERIFY_SUCCESS)
  154. return ret;
  155. method = nm_setting_ip_config_get_method (s_ip);
  156. /* Base class already checked that it exists */
  157. g_assert (method);
  158. if (!strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) {
  159. if (nm_setting_ip_config_get_num_addresses (s_ip) == 0) {
  160. g_set_error (error,
  161. NM_CONNECTION_ERROR,
  162. NM_CONNECTION_ERROR_MISSING_PROPERTY,
  163. _("this property cannot be empty for '%s=%s'"),
  164. NM_SETTING_IP_CONFIG_METHOD, method);
  165. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES);
  166. return FALSE;
  167. }
  168. } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)
  169. || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)
  170. || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) {
  171. /* Shared allows IP addresses and DNS; link-local and disabled do not */
  172. if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) != 0) {
  173. if (nm_setting_ip_config_get_num_dns (s_ip) > 0) {
  174. g_set_error (error,
  175. NM_CONNECTION_ERROR,
  176. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  177. _("this property is not allowed for '%s=%s'"),
  178. NM_SETTING_IP_CONFIG_METHOD, method);
  179. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS);
  180. return FALSE;
  181. }
  182. if (nm_setting_ip_config_get_num_dns_searches (s_ip) > 0) {
  183. g_set_error (error,
  184. NM_CONNECTION_ERROR,
  185. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  186. _("this property is not allowed for '%s=%s'"),
  187. NM_SETTING_IP_CONFIG_METHOD, method);
  188. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS_SEARCH);
  189. return FALSE;
  190. }
  191. if (nm_setting_ip_config_get_num_addresses (s_ip) > 0) {
  192. g_set_error (error,
  193. NM_CONNECTION_ERROR,
  194. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  195. _("this property is not allowed for '%s=%s'"),
  196. NM_SETTING_IP_CONFIG_METHOD, method);
  197. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES);
  198. return FALSE;
  199. }
  200. }
  201. } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO)
  202. || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) {
  203. /* nothing to do */
  204. } else {
  205. g_set_error_literal (error,
  206. NM_CONNECTION_ERROR,
  207. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  208. _("property is invalid"));
  209. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_METHOD);
  210. return FALSE;
  211. }
  212. if (!NM_IN_SET (priv->addr_gen_mode,
  213. NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64,
  214. NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY)) {
  215. g_set_error_literal (error,
  216. NM_CONNECTION_ERROR,
  217. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  218. _("property is invalid"));
  219. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE);
  220. return FALSE;
  221. }
  222. if (priv->token) {
  223. if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) {
  224. struct in6_addr i6_token;
  225. char s_token[NM_UTILS_INET_ADDRSTRLEN];
  226. if ( inet_pton (AF_INET6, priv->token, &i6_token) != 1
  227. || !_nm_utils_inet6_is_token (&i6_token)) {
  228. g_set_error_literal (error,
  229. NM_CONNECTION_ERROR,
  230. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  231. _("value is not a valid token"));
  232. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
  233. return FALSE;
  234. }
  235. if (g_strcmp0 (priv->token, nm_utils_inet6_ntop (&i6_token, s_token)))
  236. token_needs_normalization = TRUE;
  237. } else {
  238. g_set_error_literal (error,
  239. NM_CONNECTION_ERROR,
  240. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  241. _("only makes sense with EUI64 address generation mode"));
  242. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
  243. return FALSE;
  244. }
  245. }
  246. if (priv->dhcp_duid) {
  247. if (!_nm_utils_dhcp_duid_valid (priv->dhcp_duid, NULL)) {
  248. g_set_error_literal (error,
  249. NM_CONNECTION_ERROR,
  250. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  251. _("invalid DUID"));
  252. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_DHCP_DUID);
  253. return FALSE;
  254. }
  255. }
  256. /* Failures from here on, are NORMALIZABLE_ERROR... */
  257. if (token_needs_normalization) {
  258. g_set_error_literal (error,
  259. NM_CONNECTION_ERROR,
  260. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  261. _("token is not in canonical form"));
  262. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN);
  263. return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
  264. }
  265. /* Failures from here on are NORMALIZABLE... */
  266. if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)
  267. && !nm_setting_ip_config_get_may_fail (s_ip)) {
  268. g_set_error_literal (error,
  269. NM_CONNECTION_ERROR,
  270. NM_CONNECTION_ERROR_INVALID_PROPERTY,
  271. _("property should be TRUE when method is set to ignore"));
  272. g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_MAY_FAIL);
  273. return NM_SETTING_VERIFY_NORMALIZABLE;
  274. }
  275. return TRUE;
  276. }
  277. static void
  278. nm_setting_ip6_config_init (NMSettingIP6Config *setting)
  279. {
  280. }
  281. static GVariant *
  282. ip6_dns_to_dbus (const GValue *prop_value)
  283. {
  284. return nm_utils_ip6_dns_to_variant (g_value_get_boxed (prop_value));
  285. }
  286. static void
  287. ip6_dns_from_dbus (GVariant *dbus_value,
  288. GValue *prop_value)
  289. {
  290. g_value_take_boxed (prop_value, nm_utils_ip6_dns_from_variant (dbus_value));
  291. }
  292. static GVariant *
  293. ip6_addresses_get (NMSetting *setting,
  294. const char *property)
  295. {
  296. GPtrArray *addrs;
  297. const char *gateway;
  298. GVariant *ret;
  299. g_object_get (setting, property, &addrs, NULL);
  300. gateway = nm_setting_ip_config_get_gateway (NM_SETTING_IP_CONFIG (setting));
  301. ret = nm_utils_ip6_addresses_to_variant (addrs, gateway);
  302. g_ptr_array_unref (addrs);
  303. return ret;
  304. }
  305. static gboolean
  306. ip6_addresses_set (NMSetting *setting,
  307. GVariant *connection_dict,
  308. const char *property,
  309. GVariant *value,
  310. NMSettingParseFlags parse_flags,
  311. GError **error)
  312. {
  313. GPtrArray *addrs;
  314. char *gateway = NULL;
  315. /* FIXME: properly handle errors */
  316. if (!_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data"))
  317. return TRUE;
  318. addrs = nm_utils_ip6_addresses_from_variant (value, &gateway);
  319. g_object_set (setting,
  320. NM_SETTING_IP_CONFIG_ADDRESSES, addrs,
  321. NM_SETTING_IP_CONFIG_GATEWAY, gateway,
  322. NULL);
  323. g_ptr_array_unref (addrs);
  324. g_free (gateway);
  325. return TRUE;
  326. }
  327. static GVariant *
  328. ip6_address_data_get (NMSetting *setting,
  329. NMConnection *connection,
  330. const char *property)
  331. {
  332. GPtrArray *addrs;
  333. GVariant *ret;
  334. g_object_get (setting, NM_SETTING_IP_CONFIG_ADDRESSES, &addrs, NULL);
  335. ret = nm_utils_ip_addresses_to_variant (addrs);
  336. g_ptr_array_unref (addrs);
  337. return ret;
  338. }
  339. static gboolean
  340. ip6_address_data_set (NMSetting *setting,
  341. GVariant *connection_dict,
  342. const char *property,
  343. GVariant *value,
  344. NMSettingParseFlags parse_flags,
  345. GError **error)
  346. {
  347. GPtrArray *addrs;
  348. /* FIXME: properly handle errors */
  349. /* Ignore 'address-data' if we're going to process 'addresses' */
  350. if (_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "address-data"))
  351. return TRUE;
  352. addrs = nm_utils_ip_addresses_from_variant (value, AF_INET6);
  353. g_object_set (setting, NM_SETTING_IP_CONFIG_ADDRESSES, addrs, NULL);
  354. g_ptr_array_unref (addrs);
  355. return TRUE;
  356. }
  357. static GVariant *
  358. ip6_routes_get (NMSetting *setting,
  359. const char *property)
  360. {
  361. GPtrArray *routes;
  362. GVariant *ret;
  363. g_object_get (setting, property, &routes, NULL);
  364. ret = nm_utils_ip6_routes_to_variant (routes);
  365. g_ptr_array_unref (routes);
  366. return ret;
  367. }
  368. static gboolean
  369. ip6_routes_set (NMSetting *setting,
  370. GVariant *connection_dict,
  371. const char *property,
  372. GVariant *value,
  373. NMSettingParseFlags parse_flags,
  374. GError **error)
  375. {
  376. GPtrArray *routes;
  377. /* FIXME: properly handle errors */
  378. if (!_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data"))
  379. return TRUE;
  380. routes = nm_utils_ip6_routes_from_variant (value);
  381. g_object_set (setting, property, routes, NULL);
  382. g_ptr_array_unref (routes);
  383. return TRUE;
  384. }
  385. static GVariant *
  386. ip6_route_data_get (NMSetting *setting,
  387. NMConnection *connection,
  388. const char *property)
  389. {
  390. GPtrArray *routes;
  391. GVariant *ret;
  392. g_object_get (setting, NM_SETTING_IP_CONFIG_ROUTES, &routes, NULL);
  393. ret = nm_utils_ip_routes_to_variant (routes);
  394. g_ptr_array_unref (routes);
  395. return ret;
  396. }
  397. static gboolean
  398. ip6_route_data_set (NMSetting *setting,
  399. GVariant *connection_dict,
  400. const char *property,
  401. GVariant *value,
  402. NMSettingParseFlags parse_flags,
  403. GError **error)
  404. {
  405. GPtrArray *routes;
  406. /* FIXME: properly handle errors */
  407. /* Ignore 'route-data' if we're going to process 'routes' */
  408. if (_nm_setting_use_legacy_property (setting, connection_dict, "routes", "route-data"))
  409. return TRUE;
  410. routes = nm_utils_ip_routes_from_variant (value, AF_INET6);
  411. g_object_set (setting, NM_SETTING_IP_CONFIG_ROUTES, routes, NULL);
  412. g_ptr_array_unref (routes);
  413. return TRUE;
  414. }
  415. static void
  416. set_property (GObject *object, guint prop_id,
  417. const GValue *value, GParamSpec *pspec)
  418. {
  419. NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object);
  420. switch (prop_id) {
  421. case PROP_IP6_PRIVACY:
  422. priv->ip6_privacy = g_value_get_enum (value);
  423. break;
  424. case PROP_ADDR_GEN_MODE:
  425. priv->addr_gen_mode = g_value_get_int (value);
  426. break;
  427. case PROP_TOKEN:
  428. g_free (priv->token);
  429. priv->token = g_value_dup_string (value);
  430. break;
  431. case PROP_DHCP_DUID:
  432. g_free (priv->dhcp_duid);
  433. priv->dhcp_duid = g_value_dup_string (value);
  434. break;
  435. default:
  436. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  437. break;
  438. }
  439. }
  440. static void
  441. get_property (GObject *object, guint prop_id,
  442. GValue *value, GParamSpec *pspec)
  443. {
  444. NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (object);
  445. switch (prop_id) {
  446. case PROP_IP6_PRIVACY:
  447. g_value_set_enum (value, priv->ip6_privacy);
  448. break;
  449. case PROP_ADDR_GEN_MODE:
  450. g_value_set_int (value, priv->addr_gen_mode);
  451. break;
  452. case PROP_TOKEN:
  453. g_value_set_string (value, priv->token);
  454. break;
  455. case PROP_DHCP_DUID:
  456. g_value_set_string (value, priv->dhcp_duid);
  457. break;
  458. default:
  459. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  460. break;
  461. }
  462. }
  463. static void
  464. finalize (GObject *object)
  465. {
  466. NMSettingIP6Config *self = NM_SETTING_IP6_CONFIG (object);
  467. NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (self);
  468. g_free (priv->token);
  469. g_free (priv->dhcp_duid);
  470. G_OBJECT_CLASS (nm_setting_ip6_config_parent_class)->finalize (object);
  471. }
  472. static void
  473. nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *klass)
  474. {
  475. GObjectClass *object_class = G_OBJECT_CLASS (klass);
  476. NMSettingClass *setting_class = NM_SETTING_CLASS (klass);
  477. GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config ();
  478. g_type_class_add_private (klass, sizeof (NMSettingIP6ConfigPrivate));
  479. object_class->set_property = set_property;
  480. object_class->get_property = get_property;
  481. object_class->finalize = finalize;
  482. setting_class->verify = verify;
  483. /* ---ifcfg-rh---
  484. * property: method
  485. * variable: IPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6C
  486. * default: IPV6INIT=yes; IPV6FORWARDING=no; IPV6_AUTOCONF=!IPV6FORWARDING, DHCPV6=no
  487. * description: Method used for IPv6 protocol configuration.
  488. * ignore ~ IPV6INIT=no; auto ~ IPV6_AUTOCONF=yes; dhcp ~ IPV6_AUTOCONF=no and DHCPV6C=yes
  489. * ---end---
  490. */
  491. /* ---keyfile---
  492. * property: dns
  493. * format: list of DNS IP addresses
  494. * description: List of DNS servers.
  495. * example: dns=2001:4860:4860::8888;2001:4860:4860::8844;
  496. * ---end---
  497. * ---ifcfg-rh---
  498. * property: dns
  499. * variable: DNS1, DNS2, ...
  500. * format: string
  501. * description: List of DNS servers. NetworkManager uses the variables both
  502. * for IPv4 and IPv6.
  503. * ---end---
  504. */
  505. /* ---ifcfg-rh---
  506. * property: dns-search
  507. * variable: IPV6_DOMAIN(+)
  508. * format: string (space-separated domains)
  509. * description: List of DNS search domains.
  510. * ---end---
  511. */
  512. /* ---keyfile---
  513. * property: addresses
  514. * variable: address1, address2, ...
  515. * format: address/plen
  516. * description: List of static IP addresses.
  517. * example: address1=abbe::cafe/96 address2=2001::1234
  518. * ---end---
  519. * ---ifcfg-rh---
  520. * property: addresses
  521. * variable: IPV6ADDR, IPV6ADDR_SECONDARIES
  522. * description: List of static IP addresses.
  523. * example: IPV6ADDR=ab12:9876::1
  524. * IPV6ADDR_SECONDARIES="ab12:9876::2 ab12:9876::3"
  525. * ---end---
  526. */
  527. /* ---keyfile---
  528. * property: gateway
  529. * variable: gateway
  530. * format: string
  531. * description: Gateway IP addresses as a string.
  532. * example: gateway=abbe::1
  533. * ---end---
  534. * ---ifcfg-rh---
  535. * property: gateway
  536. * variable: IPV6_DEFAULTGW
  537. * description: Gateway IP address.
  538. * example: IPV6_DEFAULTGW=abbe::1
  539. * ---end---
  540. */
  541. /* ---keyfile---
  542. * property: routes
  543. * variable: route1, route2, ...
  544. * format: route/plen[,gateway,metric]
  545. * description: List of IP routes.
  546. * example: route1=2001:4860:4860::/64,2620:52:0:2219:222:68ff:fe11:5403
  547. * ---end---
  548. * ---ifcfg-rh---
  549. * property: routes
  550. * variable: (none)
  551. * description: List of static routes. They are not stored in ifcfg-* file,
  552. * but in route6-* file instead in the form of command line for 'ip route add'.
  553. * ---end---
  554. */
  555. /* ---ifcfg-rh---
  556. * property: ignore-auto-routes
  557. * variable: IPV6_PEERROUTES(+)
  558. * default: yes
  559. * description: IPV6_PEERROUTES has the opposite meaning as 'ignore-auto-routes' property.
  560. * ---end---
  561. */
  562. /* ---ifcfg-rh---
  563. * property: ignore-auto-dns
  564. * variable: IPV6_PEERDNS(+)
  565. * default: yes
  566. * description: IPV6_PEERDNS has the opposite meaning as 'ignore-auto-dns' property.
  567. * ---end---
  568. */
  569. /* ---ifcfg-rh---
  570. * property: dhcp-hostname
  571. * variable: DHCP_HOSTNAME
  572. * description: Hostname to send the DHCP server.
  573. * ---end---
  574. */
  575. /* ---ifcfg-rh---
  576. * property: never-default
  577. * variable: IPV6_DEFROUTE(+), (and IPV6_DEFAULTGW, IPV6_DEFAULTDEV in /etc/sysconfig/network)
  578. * default: IPV6_DEFROUTE=yes (when no variable specified)
  579. * description: IPV6_DEFROUTE=no tells NetworkManager that this connection
  580. * should not be assigned the default IPv6 route. IPV6_DEFROUTE has the opposite
  581. * meaning as 'never-default' property.
  582. * ---end---
  583. */
  584. /* ---ifcfg-rh---
  585. * property: may-fail
  586. * variable: IPV6_FAILURE_FATAL(+)
  587. * default: no
  588. * description: IPV6_FAILURE_FATAL has the opposite meaning as 'may-fail' property.
  589. * ---end---
  590. */
  591. /* ---ifcfg-rh---
  592. * property: route-metric
  593. * variable: IPV6_ROUTE_METRIC(+)
  594. * default: -1
  595. * description: IPV6_ROUTE_METRIC is the default IPv6 metric for routes on this connection.
  596. * If set to -1, a default metric based on the device type is used.
  597. * ---end---
  598. */
  599. /* ---ifcfg-rh---
  600. * property: route-table
  601. * variable: IPV6_ROUTE_TABLE(+)
  602. * default: 0
  603. * description: IPV6_ROUTE_TABLE enables policy-routing and sets the default routing table.
  604. * ---end---
  605. */
  606. /* ---ifcfg-rh---
  607. * property: dns-priority
  608. * variable: IPV6_DNS_PRIORITY(+)
  609. * description: The priority for DNS servers of this connection. Lower values have higher priority.
  610. * If zero, the default value will be used (50 for VPNs, 100 for other connections).
  611. * A negative value prevents DNS from other connections with greater values to be used.
  612. * default: 0
  613. * example: IPV6_DNS_PRIORITY=20
  614. * ---end---
  615. */
  616. /* ---ifcfg-rh---
  617. * property: dns-options
  618. * variable: IPV6_RES_OPTIONS(+)
  619. * description: List of DNS options to be added to /etc/resolv.conf
  620. * example: IPV6_RES_OPTIONS=ndots:2 timeout:3
  621. * ---end---
  622. */
  623. /**
  624. * NMSettingIP6Config:ip6-privacy:
  625. *
  626. * Configure IPv6 Privacy Extensions for SLAAC, described in RFC4941. If
  627. * enabled, it makes the kernel generate a temporary IPv6 address in
  628. * addition to the public one generated from MAC address via modified
  629. * EUI-64. This enhances privacy, but could cause problems in some
  630. * applications, on the other hand. The permitted values are: -1: unknown,
  631. * 0: disabled, 1: enabled (prefer public address), 2: enabled (prefer temporary
  632. * addresses).
  633. *
  634. * Having a per-connection setting set to "-1" (unknown) means fallback to
  635. * global configuration "ipv6.ip6-privacy".
  636. *
  637. * If also global configuration is unspecified or set to "-1", fallback to read
  638. * "/proc/sys/net/ipv6/conf/default/use_tempaddr".
  639. *
  640. * Note that this setting is distinct from the Stable Privacy addresses
  641. * that can be enabled with the "addr-gen-mode" property's "stable-privacy"
  642. * setting as another way of avoiding host tracking with IPv6 addresses.
  643. **/
  644. /* ---ifcfg-rh---
  645. * property: ip6-privacy
  646. * variable: IPV6_PRIVACY, IPV6_PRIVACY_PREFER_PUBLIC_IP(+)
  647. * values: IPV6_PRIVACY: no, yes (rfc3041 or rfc4941);
  648. * IPV6_PRIVACY_PREFER_PUBLIC_IP: yes, no
  649. * default: no
  650. * description: Configure IPv6 Privacy Extensions for SLAAC (RFC4941).
  651. * example: IPV6_PRIVACY=rfc3041 IPV6_PRIVACY_PREFER_PUBLIC_IP=yes
  652. * ---end---
  653. */
  654. g_object_class_install_property
  655. (object_class, PROP_IP6_PRIVACY,
  656. g_param_spec_enum (NM_SETTING_IP6_CONFIG_IP6_PRIVACY, "", "",
  657. NM_TYPE_SETTING_IP6_CONFIG_PRIVACY,
  658. NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
  659. G_PARAM_READWRITE |
  660. G_PARAM_CONSTRUCT |
  661. G_PARAM_STATIC_STRINGS));
  662. /**
  663. * NMSettingIP6Config:addr-gen-mode:
  664. *
  665. * Configure method for creating the address for use with RFC4862 IPv6
  666. * Stateless Address Autoconfiguration. The permitted values are:
  667. * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 or
  668. * %NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY.
  669. *
  670. * If the property is set to EUI64, the addresses will be generated
  671. * using the interface tokens derived from hardware address. This makes
  672. * the host part of the address to stay constant, making it possible
  673. * to track host's presence when it changes networks. The address changes
  674. * when the interface hardware is replaced.
  675. *
  676. * The value of stable-privacy enables use of cryptographically
  677. * secure hash of a secret host-specific key along with the connection's
  678. * stable-id and the network address as specified by RFC7217.
  679. * This makes it impossible to use the address track host's presence,
  680. * and makes the address stable when the network interface hardware is
  681. * replaced.
  682. *
  683. * On D-Bus, the absence of an addr-gen-mode setting equals enabling
  684. * stable-privacy. For keyfile plugin, the absence of the setting
  685. * on disk means EUI64 so that the property doesn't change on upgrade
  686. * from older versions.
  687. *
  688. * Note that this setting is distinct from the Privacy Extensions as
  689. * configured by "ip6-privacy" property and it does not affect the
  690. * temporary addresses configured with this option.
  691. *
  692. * Since: 1.2
  693. **/
  694. /* ---ifcfg-rh---
  695. * property: addr-gen-mode
  696. * variable: IPV6_ADDR_GEN_MODE
  697. * values: IPV6_ADDR_GEN_MODE: eui64, stable-privacy
  698. * default: eui64
  699. * description: Configure IPv6 Stable Privacy addressing for SLAAC (RFC7217).
  700. * example: IPV6_ADDR_GEN_MODE=stable-privacy
  701. * ---end---
  702. */
  703. g_object_class_install_property
  704. (object_class, PROP_ADDR_GEN_MODE,
  705. g_param_spec_int (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, "", "",
  706. G_MININT, G_MAXINT,
  707. NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY,
  708. G_PARAM_READWRITE |
  709. G_PARAM_CONSTRUCT |
  710. G_PARAM_STATIC_STRINGS));
  711. /**
  712. * NMSettingIP6Config:token:
  713. *
  714. * Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02
  715. * IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode.
  716. *
  717. * Since: 1.4
  718. **/
  719. /* ---ifcfg-rh---
  720. * property: token
  721. * variable: IPV6_TOKEN
  722. * description: The IPv6 tokenized interface identifier token
  723. * example: IPV6_TOKEN=::53
  724. * ---end---
  725. */
  726. g_object_class_install_property
  727. (object_class, PROP_TOKEN,
  728. g_param_spec_string (NM_SETTING_IP6_CONFIG_TOKEN, "", "",
  729. NULL,
  730. G_PARAM_READWRITE |
  731. NM_SETTING_PARAM_INFERRABLE |
  732. G_PARAM_STATIC_STRINGS));
  733. /**
  734. * NMSettingIP6Config:dhcp-duid:
  735. *
  736. * A string containing the DHCPv6 Unique Identifier (DUID) used by the dhcp
  737. * client to identify itself to DHCPv6 servers (RFC 3315). The DUID is carried
  738. * in the Client Identifier option.
  739. * If the property is a hex string ('aa:bb:cc') it is interpreted as a binary
  740. * DUID and filled as an opaque value in the Client Identifier option.
  741. *
  742. * The special value "lease" will retrieve the DUID previously used from the
  743. * lease file belonging to the connection. If no DUID is found and "dhclient"
  744. * is the configured dhcp client, the DUID is searched in the system-wide
  745. * dhclient lease file. If still no DUID is found, or another dhcp client is
  746. * used, a global and permanent DUID-UUID (RFC 6355) will be generated based
  747. * on the machine-id.
  748. *
  749. * The special values "llt" and "ll" will generate a DUID of type LLT or LL
  750. * (see RFC 3315) based on the current MAC address of the device. In order to
  751. * try providing a stable DUID-LLT, the time field will contain a constant
  752. * timestamp that is used globally (for all profiles) and persisted to disk.
  753. *
  754. * The special values "stable-llt", "stable-ll" and "stable-uuid" will generate
  755. * a DUID of the corresponding type, derived from the connection's stable-id and
  756. * a per-host unique key.
  757. * So, the link-layer address of "stable-ll" and "stable-llt" will be a generated
  758. * address derived from the stable id. The DUID-LLT time value in the "stable-llt"
  759. * option will be picked among a static timespan of three years (the upper bound
  760. * of the interval is the same constant timestamp used in "llt").
  761. *
  762. * When the property is unset, the global value provided for "ipv6.dhcp-duid" is
  763. * used. If no global value is provided, the default "lease" value is assumed.
  764. *
  765. * Since: 1.12
  766. **/
  767. /* ---ifcfg-rh---
  768. * property: dhcp-duid
  769. * variable: DHCPV6_DUID(+)
  770. * description: A string sent to the DHCPv6 server to identify the local machine.
  771. * Apart from the special values "lease", "stable-llt", "stable-ll", "stable-uuid",
  772. * "llt" and "ll" a binary value in hex format is expected. An hex string where
  773. * each octet is separated by a colon is also accepted.
  774. * example: DHCPV6_DUID=LL; DHCPV6_DUID=0301deadbeef0001; DHCPV6_DUID=03:01:de:ad:be:ef:00:01
  775. * ---end---
  776. */
  777. g_object_class_install_property
  778. (object_class, PROP_DHCP_DUID,
  779. g_param_spec_string (NM_SETTING_IP6_CONFIG_DHCP_DUID, "", "",
  780. NULL,
  781. G_PARAM_READWRITE |
  782. G_PARAM_STATIC_STRINGS));
  783. /* IP6-specific property overrides */
  784. /* ---dbus---
  785. * property: dns
  786. * format: array of byte array
  787. * description: Array of IP addresses of DNS servers (in network byte order)
  788. * ---end---
  789. */
  790. _properties_override_add_transform (properties_override,
  791. g_object_class_find_property (G_OBJECT_CLASS (setting_class),
  792. NM_SETTING_IP_CONFIG_DNS),
  793. G_VARIANT_TYPE ("aay"),
  794. ip6_dns_to_dbus,
  795. ip6_dns_from_dbus);
  796. /* ---dbus---
  797. * property: addresses
  798. * format: array of legacy IPv6 address struct (a(ayuay))
  799. * description: Deprecated in favor of the 'address-data' and 'gateway'
  800. * properties, but this can be used for backward-compatibility with older
  801. * daemons. Note that if you send this property the daemon will ignore
  802. * 'address-data' and 'gateway'.
  803. *
  804. * Array of IPv6 address structures. Each IPv6 address structure is
  805. * composed of an IPv6 address, a prefix length (1 - 128), and an IPv6
  806. * gateway address. The gateway may be zeroed out if no gateway exists for
  807. * that subnet.
  808. * ---end---
  809. */
  810. _properties_override_add_override (properties_override,
  811. g_object_class_find_property (G_OBJECT_CLASS (setting_class),
  812. NM_SETTING_IP_CONFIG_ADDRESSES),
  813. G_VARIANT_TYPE ("a(ayuay)"),
  814. ip6_addresses_get,
  815. ip6_addresses_set,
  816. NULL);
  817. /* ---dbus---
  818. * property: address-data
  819. * format: array of vardict
  820. * description: Array of IPv6 addresses. Each address dictionary contains at
  821. * least 'address' and 'prefix' entries, containing the IP address as a
  822. * string, and the prefix length as a uint32. Additional attributes may
  823. * also exist on some addresses.
  824. * ---end---
  825. */
  826. _properties_override_add_dbus_only (properties_override,
  827. "address-data",
  828. G_VARIANT_TYPE ("aa{sv}"),
  829. ip6_address_data_get,
  830. ip6_address_data_set);
  831. /* ---dbus---
  832. * property: routes
  833. * format: array of legacy IPv6 route struct (a(ayuayu))
  834. * description: Deprecated in favor of the 'route-data' property, but this
  835. * can be used for backward-compatibility with older daemons. Note that if
  836. * you send this property the daemon will ignore 'route-data'.
  837. *
  838. * Array of IPv6 route structures. Each IPv6 route structure is
  839. * composed of an IPv6 address, a prefix length (1 - 128), an IPv6
  840. * next hop address (which may be zeroed out if there is no next hop),
  841. * and a metric. If the metric is 0, NM will choose an appropriate
  842. * default metric for the device.
  843. * ---end---
  844. */
  845. _properties_override_add_override (properties_override,
  846. g_object_class_find_property (G_OBJECT_CLASS (setting_class),
  847. NM_SETTING_IP_CONFIG_ROUTES),
  848. G_VARIANT_TYPE ("a(ayuayu)"),
  849. ip6_routes_get,
  850. ip6_routes_set,
  851. NULL);
  852. /* ---dbus---
  853. * property: route-data
  854. * format: array of vardict
  855. * description: Array of IPv6 routes. Each route dictionary contains at
  856. * least 'dest' and 'prefix' entries, containing the destination IP
  857. * address as a string, and the prefix length as a uint32. Most routes
  858. * will also have a 'next-hop' entry, containing the next hop IP address as
  859. * a string. If the route has a 'metric' entry (containing a uint32), that
  860. * will be used as the metric for the route (otherwise NM will pick a
  861. * default value appropriate to the device). Additional attributes may
  862. * also exist on some routes.
  863. * ---end---
  864. */
  865. _properties_override_add_dbus_only (properties_override,
  866. "route-data",
  867. G_VARIANT_TYPE ("aa{sv}"),
  868. ip6_route_data_get,
  869. ip6_route_data_set);
  870. _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_IP6_CONFIG,
  871. NULL, properties_override);
  872. }