d76179c8e3db0e73e33bc0e1c755fce4c3eb1b95
[NetworkManager.git] / libnm-core / nm-setting-ip-config.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2
3 /*
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.
8  *
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.
13  *
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.
18  *
19  * Copyright 2007 - 2014 Red Hat, Inc.
20  * Copyright 2007 - 2008 Novell, Inc.
21  */
22
23 #include "nm-default.h"
24
25 #include <string.h>
26 #include <arpa/inet.h>
27
28 #include "nm-setting-ip-config.h"
29 #include "nm-setting-ip4-config.h"
30 #include "nm-setting-ip6-config.h"
31 #include "nm-utils.h"
32 #include "nm-setting-private.h"
33 #include "nm-utils-private.h"
34
35 /**
36  * SECTION:nm-setting-ip-config
37  * @short_description: Abstract base class for IPv4 and IPv6
38  *   addressing, routing, and name service properties
39  * @include: nm-setting-ip-config.h
40  * @see_also: #NMSettingIP4Config, #NMSettingIP6Config
41  *
42  * #NMSettingIPConfig is the abstract base class of
43  * #NMSettingIP4Config and #NMSettingIP6Config, providing properties
44  * related to IP addressing, routing, and Domain Name Service.
45  **/
46
47 const NMUtilsDNSOptionDesc _nm_utils_dns_option_descs[] = {
48         { NM_SETTING_DNS_OPTION_DEBUG,                 FALSE,   FALSE },
49         { NM_SETTING_DNS_OPTION_NDOTS,                 TRUE,    FALSE },
50         { NM_SETTING_DNS_OPTION_TIMEOUT,               TRUE,    FALSE },
51         { NM_SETTING_DNS_OPTION_ATTEMPTS,              TRUE,    FALSE },
52         { NM_SETTING_DNS_OPTION_ROTATE,                FALSE,   FALSE },
53         { NM_SETTING_DNS_OPTION_NO_CHECK_NAMES,        FALSE,   FALSE },
54         { NM_SETTING_DNS_OPTION_INET6,                 FALSE,   TRUE },
55         { NM_SETTING_DNS_OPTION_IP6_BYTESTRING,        FALSE,   TRUE },
56         { NM_SETTING_DNS_OPTION_IP6_DOTINT,            FALSE,   TRUE },
57         { NM_SETTING_DNS_OPTION_NO_IP6_DOTINT,         FALSE,   TRUE },
58         { NM_SETTING_DNS_OPTION_EDNS0,                 FALSE,   FALSE },
59         { NM_SETTING_DNS_OPTION_SINGLE_REQUEST,        FALSE,   FALSE },
60         { NM_SETTING_DNS_OPTION_SINGLE_REQUEST_REOPEN, FALSE,   FALSE },
61         { NM_SETTING_DNS_OPTION_NO_TLD_QUERY,          FALSE,   FALSE },
62         { NULL,                                        FALSE,   FALSE }
63 };
64
65 static int
66 _addr_size (int family)
67 {
68         switch (family) {
69         case AF_INET:
70                 return sizeof (in_addr_t);
71         case AF_INET6:
72                 return sizeof (struct in6_addr);
73         default:
74                 g_return_val_if_reached (0);
75         }
76 }
77
78 static char *
79 canonicalize_ip (int family, const char *ip, gboolean null_any)
80 {
81         guint8 addr_bytes[sizeof (struct in6_addr)];
82         char addr_str[NM_UTILS_INET_ADDRSTRLEN];
83         int ret;
84
85         if (!ip) {
86                 if (null_any)
87                         return NULL;
88                 if (family == AF_INET)
89                         return g_strdup ("0.0.0.0");
90                 if (family == AF_INET6)
91                         return g_strdup ("::");
92                 g_return_val_if_reached (NULL);
93         }
94
95         ret = inet_pton (family, ip, addr_bytes);
96         g_return_val_if_fail (ret == 1, NULL);
97
98         if (null_any) {
99                 if (!memcmp (addr_bytes, &in6addr_any, _addr_size (family)))
100                         return NULL;
101         }
102
103         return g_strdup (inet_ntop (family, addr_bytes, addr_str, sizeof (addr_str)));
104 }
105
106 static char *
107 canonicalize_ip_binary (int family, gconstpointer ip, gboolean null_any)
108 {
109         char string[NM_UTILS_INET_ADDRSTRLEN];
110
111         if (!ip) {
112                 if (null_any)
113                         return NULL;
114                 if (family == AF_INET)
115                         return g_strdup ("0.0.0.0");
116                 if (family == AF_INET6)
117                         return g_strdup ("::");
118                 g_return_val_if_reached (NULL);
119         }
120         if (null_any) {
121                 if (!memcmp (ip, &in6addr_any, _addr_size (family)))
122                         return NULL;
123         }
124         return g_strdup (inet_ntop (family, ip, string, sizeof (string)));
125 }
126
127 static gboolean
128 valid_ip (int family, const char *ip, GError **error)
129 {
130         if (!ip) {
131                 g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
132                              family == AF_INET ? _("Missing IPv4 address") : _("Missing IPv6 address"));
133                 return FALSE;
134         }
135         if (!nm_utils_ipaddr_valid (family, ip)) {
136                 g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
137                              family == AF_INET ? _("Invalid IPv4 address '%s'") : _("Invalid IPv6 address '%s'"),
138                              ip);
139                 return FALSE;
140         } else
141                 return TRUE;
142 }
143
144 static gboolean
145 valid_prefix (int family, guint prefix, GError **error, gboolean allow_zero_prefix)
146 {
147         if (   (family == AF_INET && prefix > 32)
148             || (family == AF_INET6 && prefix > 128)
149             || (!allow_zero_prefix && prefix == 0)) {
150                 g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
151                              family == AF_INET ? _("Invalid IPv4 address prefix '%u'") : _("Invalid IPv6 address prefix '%u'"),
152                              prefix);
153                 return FALSE;
154         }
155
156         return TRUE;
157 }
158
159 static gboolean
160 valid_metric (gint64 metric, GError **error)
161 {
162         if (metric < -1 || metric > G_MAXUINT32) {
163                 if (error) {
164                         char buf[64];
165
166                         /* We can't concatenate G_GINT64_FORMAT into a translatable string */
167                         g_snprintf (buf, sizeof (buf), "%" G_GINT64_FORMAT, metric);
168                         g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_FAILED,
169                                      _("Invalid routing metric '%s'"), buf);
170                 }
171                 return FALSE;
172         }
173
174         return TRUE;
175 }
176
177
178 G_DEFINE_BOXED_TYPE (NMIPAddress, nm_ip_address, nm_ip_address_dup, nm_ip_address_unref)
179
180 struct NMIPAddress {
181         guint refcount;
182
183         char *address;
184         int prefix, family;
185
186         GHashTable *attributes;
187 };
188
189 /**
190  * nm_ip_address_new:
191  * @family: the IP address family (<literal>AF_INET</literal> or
192  *   <literal>AF_INET6</literal>)
193  * @addr: the IP address
194  * @prefix: the address prefix length
195  * @error: location to store error, or %NULL
196  *
197  * Creates a new #NMIPAddress object.
198  *
199  * Returns: (transfer full): the new #NMIPAddress object, or %NULL on error
200  **/
201 NMIPAddress *
202 nm_ip_address_new (int family,
203                    const char *addr, guint prefix,
204                    GError **error)
205 {
206         NMIPAddress *address;
207
208         g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL);
209         g_return_val_if_fail (addr != NULL, NULL);
210
211         if (!valid_ip (family, addr, error))
212                 return NULL;
213         if (!valid_prefix (family, prefix, error, FALSE))
214                 return NULL;
215
216         address = g_slice_new0 (NMIPAddress);
217         address->refcount = 1;
218
219         address->family = family;
220         address->address = canonicalize_ip (family, addr, FALSE);
221         address->prefix = prefix;
222
223         return address;
224 }
225
226 /**
227  * nm_ip_address_new_binary:
228  * @family: the IP address family (<literal>AF_INET</literal> or
229  *   <literal>AF_INET6</literal>)
230  * @addr: the IP address
231  * @prefix: the address prefix length
232  * @error: location to store error, or %NULL
233  *
234  * Creates a new #NMIPAddress object. @addr must point to a buffer of the
235  * correct size for @family.
236  *
237  * Returns: (transfer full): the new #NMIPAddress object, or %NULL on error
238  **/
239 NMIPAddress *
240 nm_ip_address_new_binary (int family,
241                           gconstpointer addr, guint prefix,
242                           GError **error)
243 {
244         NMIPAddress *address;
245         char string[NM_UTILS_INET_ADDRSTRLEN];
246
247         g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL);
248         g_return_val_if_fail (addr != NULL, NULL);
249
250         if (!valid_prefix (family, prefix, error, FALSE))
251                 return NULL;
252
253         address = g_slice_new0 (NMIPAddress);
254         address->refcount = 1;
255
256         address->family = family;
257         address->address = g_strdup (inet_ntop (family, addr, string, sizeof (string)));
258         address->prefix = prefix;
259
260         return address;
261 }
262
263 /**
264  * nm_ip_address_ref:
265  * @address: the #NMIPAddress
266  *
267  * Increases the reference count of the object.
268  **/
269 void
270 nm_ip_address_ref (NMIPAddress *address)
271 {
272         g_return_if_fail (address != NULL);
273         g_return_if_fail (address->refcount > 0);
274
275         address->refcount++;
276 }
277
278 /**
279  * nm_ip_address_unref:
280  * @address: the #NMIPAddress
281  *
282  * Decreases the reference count of the object.  If the reference count
283  * reaches zero, the object will be destroyed.
284  **/
285 void
286 nm_ip_address_unref (NMIPAddress *address)
287 {
288         g_return_if_fail (address != NULL);
289         g_return_if_fail (address->refcount > 0);
290
291         address->refcount--;
292         if (address->refcount == 0) {
293                 g_free (address->address);
294                 if (address->attributes)
295                         g_hash_table_unref (address->attributes);
296                 g_slice_free (NMIPAddress, address);
297         }
298 }
299
300 /**
301  * nm_ip_address_equal:
302  * @address: the #NMIPAddress
303  * @other: the #NMIPAddress to compare @address to.
304  *
305  * Determines if two #NMIPAddress objects contain the same address and prefix
306  * (attributes are not compared).
307  *
308  * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
309  **/
310 gboolean
311 nm_ip_address_equal (NMIPAddress *address, NMIPAddress *other)
312 {
313         g_return_val_if_fail (address != NULL, FALSE);
314         g_return_val_if_fail (address->refcount > 0, FALSE);
315
316         g_return_val_if_fail (other != NULL, FALSE);
317         g_return_val_if_fail (other->refcount > 0, FALSE);
318
319         if (   address->family != other->family
320             || address->prefix != other->prefix
321             || strcmp (address->address, other->address) != 0)
322                 return FALSE;
323         return TRUE;
324 }
325
326 /**
327  * nm_ip_address_dup:
328  * @address: the #NMIPAddress
329  *
330  * Creates a copy of @address
331  *
332  * Returns: (transfer full): a copy of @address
333  **/
334 NMIPAddress *
335 nm_ip_address_dup (NMIPAddress *address)
336 {
337         NMIPAddress *copy;
338
339         g_return_val_if_fail (address != NULL, NULL);
340         g_return_val_if_fail (address->refcount > 0, NULL);
341
342         copy = nm_ip_address_new (address->family,
343                                   address->address, address->prefix,
344                                   NULL);
345         if (address->attributes) {
346                 GHashTableIter iter;
347                 const char *key;
348                 GVariant *value;
349
350                 g_hash_table_iter_init (&iter, address->attributes);
351                 while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value))
352                         nm_ip_address_set_attribute (copy, key, value);
353         }
354
355         return copy;
356 }
357
358 /**
359  * nm_ip_address_get_family:
360  * @address: the #NMIPAddress
361  *
362  * Gets the IP address family (eg, AF_INET) property of this address
363  * object.
364  *
365  * Returns: the IP address family
366  **/
367 int
368 nm_ip_address_get_family (NMIPAddress *address)
369 {
370         g_return_val_if_fail (address != NULL, 0);
371         g_return_val_if_fail (address->refcount > 0, 0);
372
373         return address->family;
374 }
375
376 /**
377  * nm_ip_address_get_address:
378  * @address: the #NMIPAddress
379  *
380  * Gets the IP address property of this address object.
381  *
382  * Returns: the IP address
383  **/
384 const char *
385 nm_ip_address_get_address (NMIPAddress *address)
386 {
387         g_return_val_if_fail (address != NULL, NULL);
388         g_return_val_if_fail (address->refcount > 0, NULL);
389
390         return address->address;
391 }
392
393 /**
394  * nm_ip_address_set_address:
395  * @address: the #NMIPAddress
396  * @addr: the IP address, as a string
397  *
398  * Sets the IP address property of this address object.
399  *
400  * @addr must be a valid address of @address's family. If you aren't sure you
401  * have a valid address, use nm_utils_ipaddr_valid() to check it.
402  **/
403 void
404 nm_ip_address_set_address (NMIPAddress *address,
405                            const char *addr)
406 {
407         g_return_if_fail (address != NULL);
408         g_return_if_fail (addr != NULL);
409         g_return_if_fail (nm_utils_ipaddr_valid (address->family, addr));
410
411         g_free (address->address);
412         address->address = canonicalize_ip (address->family, addr, FALSE);
413 }
414
415 /**
416  * nm_ip_address_get_address_binary: (skip)
417  * @address: the #NMIPAddress
418  * @addr: a buffer in which to store the address in binary format.
419  *
420  * Gets the IP address property of this address object.
421  *
422  * @addr must point to a buffer that is the correct size for @address's family.
423  **/
424 void
425 nm_ip_address_get_address_binary (NMIPAddress *address,
426                                   gpointer addr)
427 {
428         g_return_if_fail (address != NULL);
429         g_return_if_fail (addr != NULL);
430
431         inet_pton (address->family, address->address, addr);
432 }
433
434 /**
435  * nm_ip_address_set_address_binary: (skip)
436  * @address: the #NMIPAddress
437  * @addr: the address, in binary format
438  *
439  * Sets the IP address property of this address object.
440  *
441  * @addr must point to a buffer that is the correct size for @address's family.
442  **/
443 void
444 nm_ip_address_set_address_binary (NMIPAddress *address,
445                                   gconstpointer addr)
446 {
447         char string[NM_UTILS_INET_ADDRSTRLEN];
448
449         g_return_if_fail (address != NULL);
450         g_return_if_fail (addr != NULL);
451
452         g_free (address->address);
453         address->address = g_strdup (inet_ntop (address->family, addr, string, sizeof (string)));
454 }
455
456 /**
457  * nm_ip_address_get_prefix:
458  * @address: the #NMIPAddress
459  *
460  * Gets the IP address prefix (ie "24" or "30" etc) property of this address
461  * object.
462  *
463  * Returns: the IP address prefix
464  **/
465 guint
466 nm_ip_address_get_prefix (NMIPAddress *address)
467 {
468         g_return_val_if_fail (address != NULL, 0);
469         g_return_val_if_fail (address->refcount > 0, 0);
470
471         return address->prefix;
472 }
473
474 /**
475  * nm_ip_address_set_prefix:
476  * @address: the #NMIPAddress
477  * @prefix: the IP address prefix
478  *
479  * Sets the IP address prefix property of this address object.
480  **/
481 void
482 nm_ip_address_set_prefix (NMIPAddress *address,
483                           guint prefix)
484 {
485         g_return_if_fail (address != NULL);
486         g_return_if_fail (valid_prefix (address->family, prefix, NULL, FALSE));
487
488         address->prefix = prefix;
489 }
490
491 /**
492  * nm_ip_address_get_attribute_names:
493  * @address: the #NMIPAddress
494  *
495  * Gets an array of attribute names defined on @address.
496  *
497  * Returns: (transfer full): a %NULL-terminated array of attribute names,
498  **/
499 char **
500 nm_ip_address_get_attribute_names (NMIPAddress *address)
501 {
502         GHashTableIter iter;
503         const char *key;
504         GPtrArray *names;
505
506         g_return_val_if_fail (address != NULL, NULL);
507
508         names = g_ptr_array_new ();
509
510         if (address->attributes) {
511                 g_hash_table_iter_init (&iter, address->attributes);
512                 while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
513                         g_ptr_array_add (names, g_strdup (key));
514         }
515         g_ptr_array_add (names, NULL);
516
517         return (char **) g_ptr_array_free (names, FALSE);
518 }
519
520 /**
521  * nm_ip_address_get_attribute:
522  * @address: the #NMIPAddress
523  * @name: the name of an address attribute
524  *
525  * Gets the value of the attribute with name @name on @address
526  *
527  * Returns: (transfer none): the value of the attribute with name @name on
528  *   @address, or %NULL if @address has no such attribute.
529  **/
530 GVariant *
531 nm_ip_address_get_attribute (NMIPAddress *address, const char *name)
532 {
533         g_return_val_if_fail (address != NULL, NULL);
534         g_return_val_if_fail (name != NULL && *name != '\0', NULL);
535
536         if (address->attributes)
537                 return g_hash_table_lookup (address->attributes, name);
538         else
539                 return NULL;
540 }
541
542 /**
543  * nm_ip_address_set_attribute:
544  * @address: the #NMIPAddress
545  * @name: the name of an address attribute
546  * @value: (transfer none) (allow-none): the value
547  *
548  * Sets or clears the named attribute on @address to the given value.
549  **/
550 void
551 nm_ip_address_set_attribute (NMIPAddress *address, const char *name, GVariant *value)
552 {
553         g_return_if_fail (address != NULL);
554         g_return_if_fail (name != NULL && *name != '\0');
555         g_return_if_fail (strcmp (name, "address") != 0 && strcmp (name, "prefix") != 0);
556
557         if (!address->attributes) {
558                 address->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
559                                                              g_free, (GDestroyNotify) g_variant_unref);
560         }
561
562         if (value)
563                 g_hash_table_insert (address->attributes, g_strdup (name), g_variant_ref_sink (value));
564         else
565                 g_hash_table_remove (address->attributes, name);
566 }
567
568
569 G_DEFINE_BOXED_TYPE (NMIPRoute, nm_ip_route, nm_ip_route_dup, nm_ip_route_unref)
570
571 struct NMIPRoute {
572         guint refcount;
573
574         int family;
575         char *dest;
576         guint prefix;
577         char *next_hop;
578         gint64 metric;
579
580         GHashTable *attributes;
581 };
582
583 /**
584  * nm_ip_route_new:
585  * @family: the IP address family (<literal>AF_INET</literal> or
586  *   <literal>AF_INET6</literal>)
587  * @dest: the IP address of the route's destination
588  * @prefix: the address prefix length
589  * @next_hop: (allow-none): the IP address of the next hop (or %NULL)
590  * @metric: the route metric (or -1 for "default")
591  * @error: location to store error, or %NULL
592  *
593  * Creates a new #NMIPRoute object.
594  *
595  * Returns: (transfer full): the new #NMIPRoute object, or %NULL on error
596  **/
597 NMIPRoute *
598 nm_ip_route_new (int family,
599                  const char *dest,
600                  guint prefix,
601                  const char *next_hop,
602                  gint64 metric,
603                  GError **error)
604 {
605         NMIPRoute *route;
606
607         g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL);
608         g_return_val_if_fail (dest, NULL);
609
610         if (!valid_ip (family, dest, error))
611                 return NULL;
612         if (!valid_prefix (family, prefix, error, TRUE))
613                 return NULL;
614         if (next_hop && !valid_ip (family, next_hop, error))
615                 return NULL;
616         if (!valid_metric (metric, error))
617                 return NULL;
618
619         route = g_slice_new0 (NMIPRoute);
620         route->refcount = 1;
621
622         route->family = family;
623         route->dest = canonicalize_ip (family, dest, FALSE);
624         route->prefix = prefix;
625         route->next_hop = canonicalize_ip (family, next_hop, TRUE);
626         route->metric = metric;
627
628         return route;
629 }
630
631 /**
632  * nm_ip_route_new_binary:
633  * @family: the IP address family (<literal>AF_INET</literal> or
634  *   <literal>AF_INET6</literal>)
635  * @dest: the IP address of the route's destination
636  * @prefix: the address prefix length
637  * @next_hop: (allow-none): the IP address of the next hop (or %NULL)
638  * @metric: the route metric (or -1 for "default")
639  * @error: location to store error, or %NULL
640  *
641  * Creates a new #NMIPRoute object. @dest and @next_hop (if non-%NULL) must
642  * point to buffers of the correct size for @family.
643  *
644  * Returns: (transfer full): the new #NMIPRoute object, or %NULL on error
645  **/
646 NMIPRoute *
647 nm_ip_route_new_binary (int family,
648                         gconstpointer dest,
649                         guint prefix,
650                         gconstpointer next_hop,
651                         gint64 metric,
652                         GError **error)
653 {
654         NMIPRoute *route;
655
656         g_return_val_if_fail (family == AF_INET || family == AF_INET6, NULL);
657         g_return_val_if_fail (dest, NULL);
658
659         if (!valid_prefix (family, prefix, error, TRUE))
660                 return NULL;
661         if (!valid_metric (metric, error))
662                 return NULL;
663
664         route = g_slice_new0 (NMIPRoute);
665         route->refcount = 1;
666
667         route->family = family;
668         route->dest = canonicalize_ip_binary (family, dest, FALSE);
669         route->prefix = prefix;
670         route->next_hop = canonicalize_ip_binary (family, next_hop, TRUE);
671         route->metric = metric;
672
673         return route;
674 }
675
676 /**
677  * nm_ip_route_ref:
678  * @route: the #NMIPRoute
679  *
680  * Increases the reference count of the object.
681  **/
682 void
683 nm_ip_route_ref (NMIPRoute *route)
684 {
685         g_return_if_fail (route != NULL);
686         g_return_if_fail (route->refcount > 0);
687
688         route->refcount++;
689 }
690
691 /**
692  * nm_ip_route_unref:
693  * @route: the #NMIPRoute
694  *
695  * Decreases the reference count of the object.  If the reference count
696  * reaches zero, the object will be destroyed.
697  **/
698 void
699 nm_ip_route_unref (NMIPRoute *route)
700 {
701         g_return_if_fail (route != NULL);
702         g_return_if_fail (route->refcount > 0);
703
704         route->refcount--;
705         if (route->refcount == 0) {
706                 g_free (route->dest);
707                 g_free (route->next_hop);
708                 if (route->attributes)
709                         g_hash_table_unref (route->attributes);
710                 g_slice_free (NMIPRoute, route);
711         }
712 }
713
714 /**
715  * nm_ip_route_equal:
716  * @route: the #NMIPRoute
717  * @other: the #NMIPRoute to compare @route to.
718  *
719  * Determines if two #NMIPRoute objects contain the same destination, prefix,
720  * next hop, and metric. (Attributes are not compared.)
721  *
722  * Returns: %TRUE if the objects contain the same values, %FALSE if they do not.
723  **/
724 gboolean
725 nm_ip_route_equal (NMIPRoute *route, NMIPRoute *other)
726 {
727         g_return_val_if_fail (route != NULL, FALSE);
728         g_return_val_if_fail (route->refcount > 0, FALSE);
729
730         g_return_val_if_fail (other != NULL, FALSE);
731         g_return_val_if_fail (other->refcount > 0, FALSE);
732
733         if (   route->prefix != other->prefix
734             || route->metric != other->metric
735             || strcmp (route->dest, other->dest) != 0
736             || g_strcmp0 (route->next_hop, other->next_hop) != 0)
737                 return FALSE;
738         return TRUE;
739 }
740
741 /**
742  * nm_ip_route_dup:
743  * @route: the #NMIPRoute
744  *
745  * Creates a copy of @route
746  *
747  * Returns: (transfer full): a copy of @route
748  **/
749 NMIPRoute *
750 nm_ip_route_dup (NMIPRoute *route)
751 {
752         NMIPRoute *copy;
753
754         g_return_val_if_fail (route != NULL, NULL);
755         g_return_val_if_fail (route->refcount > 0, NULL);
756
757         copy = nm_ip_route_new (route->family,
758                                 route->dest, route->prefix,
759                                 route->next_hop, route->metric,
760                                 NULL);
761         if (route->attributes) {
762                 GHashTableIter iter;
763                 const char *key;
764                 GVariant *value;
765
766                 g_hash_table_iter_init (&iter, route->attributes);
767                 while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value))
768                         nm_ip_route_set_attribute (copy, key, value);
769         }
770
771         return copy;
772 }
773
774 /**
775  * nm_ip_route_get_family:
776  * @route: the #NMIPRoute
777  *
778  * Gets the IP address family (eg, AF_INET) property of this route
779  * object.
780  *
781  * Returns: the IP address family
782  **/
783 int
784 nm_ip_route_get_family (NMIPRoute *route)
785 {
786         g_return_val_if_fail (route != NULL, 0);
787         g_return_val_if_fail (route->refcount > 0, 0);
788
789         return route->family;
790 }
791
792 /**
793  * nm_ip_route_get_dest:
794  * @route: the #NMIPRoute
795  *
796  * Gets the IP destination address property of this route object.
797  *
798  * Returns: the IP address of the route's destination
799  **/
800 const char *
801 nm_ip_route_get_dest (NMIPRoute *route)
802 {
803         g_return_val_if_fail (route != NULL, NULL);
804         g_return_val_if_fail (route->refcount > 0, NULL);
805
806         return route->dest;
807 }
808
809 /**
810  * nm_ip_route_set_dest:
811  * @route: the #NMIPRoute
812  * @dest: the route's destination, as a string
813  *
814  * Sets the destination property of this route object.
815  *
816  * @dest must be a valid address of @route's family. If you aren't sure you
817  * have a valid address, use nm_utils_ipaddr_valid() to check it.
818  **/
819 void
820 nm_ip_route_set_dest (NMIPRoute *route,
821                       const char *dest)
822 {
823         g_return_if_fail (route != NULL);
824         g_return_if_fail (nm_utils_ipaddr_valid (route->family, dest));
825
826         g_free (route->dest);
827         route->dest = canonicalize_ip (route->family, dest, FALSE);
828 }
829
830 /**
831  * nm_ip_route_get_dest_binary: (skip)
832  * @route: the #NMIPRoute
833  * @dest: a buffer in which to store the destination in binary format.
834  *
835  * Gets the destination property of this route object.
836  *
837  * @dest must point to a buffer that is the correct size for @route's family.
838  **/
839 void
840 nm_ip_route_get_dest_binary (NMIPRoute *route,
841                              gpointer dest)
842 {
843         g_return_if_fail (route != NULL);
844         g_return_if_fail (dest != NULL);
845
846         inet_pton (route->family, route->dest, dest);
847 }
848
849 /**
850  * nm_ip_route_set_dest_binary: (skip)
851  * @route: the #NMIPRoute
852  * @dest: the route's destination, in binary format
853  *
854  * Sets the destination property of this route object.
855  *
856  * @dest must point to a buffer that is the correct size for @route's family.
857  **/
858 void
859 nm_ip_route_set_dest_binary (NMIPRoute *route,
860                              gconstpointer dest)
861 {
862         char string[NM_UTILS_INET_ADDRSTRLEN];
863
864         g_return_if_fail (route != NULL);
865         g_return_if_fail (dest != NULL);
866
867         g_free (route->dest);
868         route->dest = g_strdup (inet_ntop (route->family, dest, string, sizeof (string)));
869 }
870
871 /**
872  * nm_ip_route_get_prefix:
873  * @route: the #NMIPRoute
874  *
875  * Gets the IP prefix (ie "24" or "30" etc) of this route.
876  *
877  * Returns: the IP prefix
878  **/
879 guint
880 nm_ip_route_get_prefix (NMIPRoute *route)
881 {
882         g_return_val_if_fail (route != NULL, 0);
883         g_return_val_if_fail (route->refcount > 0, 0);
884
885         return route->prefix;
886 }
887
888 /**
889  * nm_ip_route_set_prefix:
890  * @route: the #NMIPRoute
891  * @prefix: the route prefix
892  *
893  * Sets the prefix property of this route object.
894  **/
895 void
896 nm_ip_route_set_prefix (NMIPRoute *route,
897                         guint prefix)
898 {
899         g_return_if_fail (route != NULL);
900         g_return_if_fail (valid_prefix (route->family, prefix, NULL, TRUE));
901
902         route->prefix = prefix;
903 }
904
905 /**
906  * nm_ip_route_get_next_hop:
907  * @route: the #NMIPRoute
908  *
909  * Gets the IP address of the next hop of this route; this will be %NULL if the
910  * route has no next hop.
911  *
912  * Returns: the IP address of the next hop, or %NULL if this is a device route.
913  **/
914 const char *
915 nm_ip_route_get_next_hop (NMIPRoute *route)
916 {
917         g_return_val_if_fail (route != NULL, NULL);
918         g_return_val_if_fail (route->refcount > 0, NULL);
919
920         return route->next_hop;
921 }
922
923 /**
924  * nm_ip_route_set_next_hop:
925  * @route: the #NMIPRoute
926  * @next_hop: (allow-none): the route's next hop, as a string
927  *
928  * Sets the next-hop property of this route object.
929  *
930  * @next_hop (if non-%NULL) must be a valid address of @route's family. If you
931  * aren't sure you have a valid address, use nm_utils_ipaddr_valid() to check
932  * it.
933  **/
934 void
935 nm_ip_route_set_next_hop (NMIPRoute *route,
936                           const char *next_hop)
937 {
938         g_return_if_fail (route != NULL);
939         g_return_if_fail (!next_hop || nm_utils_ipaddr_valid (route->family, next_hop));
940
941         g_free (route->next_hop);
942         route->next_hop = canonicalize_ip (route->family, next_hop, TRUE);
943 }
944
945 /**
946  * nm_ip_route_get_next_hop_binary: (skip)
947  * @route: the #NMIPRoute
948  * @next_hop: a buffer in which to store the next hop in binary format.
949  *
950  * Gets the next hop property of this route object.
951  *
952  * @next_hop must point to a buffer that is the correct size for @route's family.
953  *
954  * Returns: %TRUE if @route has a next hop, %FALSE if not (in which case
955  * @next_hop will be zeroed out)
956  **/
957 gboolean
958 nm_ip_route_get_next_hop_binary (NMIPRoute *route,
959                                  gpointer next_hop)
960 {
961         g_return_val_if_fail (route != NULL, FALSE);
962         g_return_val_if_fail (next_hop != NULL, FALSE);
963
964         if (route->next_hop) {
965                 inet_pton (route->family, route->next_hop, next_hop);
966                 return TRUE;
967         } else {
968                 memset (next_hop, 0, _addr_size (route->family));
969                 return FALSE;
970         }
971 }
972
973 /**
974  * nm_ip_route_set_next_hop_binary: (skip)
975  * @route: the #NMIPRoute
976  * @next_hop: the route's next hop, in binary format
977  *
978  * Sets the destination property of this route object.
979  *
980  * @next_hop (if non-%NULL) must point to a buffer that is the correct size for
981  * @route's family.
982  **/
983 void
984 nm_ip_route_set_next_hop_binary (NMIPRoute *route,
985                                  gconstpointer next_hop)
986 {
987         g_return_if_fail (route != NULL);
988
989         g_free (route->next_hop);
990         route->next_hop = canonicalize_ip_binary (route->family, next_hop, TRUE);
991 }
992
993 /**
994  * nm_ip_route_get_metric:
995  * @route: the #NMIPRoute
996  *
997  * Gets the route metric property of this route object; lower values
998  * indicate "better" or more preferred routes; -1 indicates "default"
999  * (meaning NetworkManager will set it appropriately).
1000  *
1001  * Returns: the route metric
1002  **/
1003 gint64
1004 nm_ip_route_get_metric (NMIPRoute *route)
1005 {
1006         g_return_val_if_fail (route != NULL, 0);
1007         g_return_val_if_fail (route->refcount > 0, 0);
1008
1009         return route->metric;
1010 }
1011
1012 /**
1013  * nm_ip_route_set_metric:
1014  * @route: the #NMIPRoute
1015  * @metric: the route metric (or -1 for "default")
1016  *
1017  * Sets the metric property of this route object.
1018  **/
1019 void
1020 nm_ip_route_set_metric (NMIPRoute *route,
1021                         gint64 metric)
1022 {
1023         g_return_if_fail (route != NULL);
1024         g_return_if_fail (valid_metric (metric, NULL));
1025
1026         route->metric = metric;
1027 }
1028
1029 /**
1030  * nm_ip_route_get_attribute_names:
1031  * @route: the #NMIPRoute
1032  *
1033  * Gets an array of attribute names defined on @route.
1034  *
1035  * Returns: (transfer full): a %NULL-terminated array of attribute names
1036  **/
1037 char **
1038 nm_ip_route_get_attribute_names (NMIPRoute *route)
1039 {
1040         GHashTableIter iter;
1041         const char *key;
1042         GPtrArray *names;
1043
1044         g_return_val_if_fail (route != NULL, NULL);
1045
1046         names = g_ptr_array_new ();
1047
1048         if (route->attributes) {
1049                 g_hash_table_iter_init (&iter, route->attributes);
1050                 while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
1051                         g_ptr_array_add (names, g_strdup (key));
1052         }
1053         g_ptr_array_add (names, NULL);
1054
1055         return (char **) g_ptr_array_free (names, FALSE);
1056 }
1057
1058 /**
1059  * nm_ip_route_get_attribute:
1060  * @route: the #NMIPRoute
1061  * @name: the name of an route attribute
1062  *
1063  * Gets the value of the attribute with name @name on @route
1064  *
1065  * Returns: (transfer none): the value of the attribute with name @name on
1066  *   @route, or %NULL if @route has no such attribute.
1067  **/
1068 GVariant *
1069 nm_ip_route_get_attribute (NMIPRoute *route, const char *name)
1070 {
1071         g_return_val_if_fail (route != NULL, NULL);
1072         g_return_val_if_fail (name != NULL && *name != '\0', NULL);
1073
1074         if (route->attributes)
1075                 return g_hash_table_lookup (route->attributes, name);
1076         else
1077                 return NULL;
1078 }
1079
1080 /**
1081  * nm_ip_route_set_attribute:
1082  * @route: the #NMIPRoute
1083  * @name: the name of a route attribute
1084  * @value: (transfer none) (allow-none): the value
1085  *
1086  * Sets the named attribute on @route to the given value.
1087  **/
1088 void
1089 nm_ip_route_set_attribute (NMIPRoute *route, const char *name, GVariant *value)
1090 {
1091         g_return_if_fail (route != NULL);
1092         g_return_if_fail (name != NULL && *name != '\0');
1093         g_return_if_fail (   strcmp (name, "dest") != 0 && strcmp (name, "prefix") != 0
1094                           && strcmp (name, "next-hop") != 0 && strcmp (name, "metric") != 0);
1095
1096         if (!route->attributes) {
1097                 route->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
1098                                                            g_free, (GDestroyNotify) g_variant_unref);
1099         }
1100
1101         if (value)
1102                 g_hash_table_insert (route->attributes, g_strdup (name), g_variant_ref_sink (value));
1103         else
1104                 g_hash_table_remove (route->attributes, name);
1105 }
1106
1107
1108 G_DEFINE_ABSTRACT_TYPE (NMSettingIPConfig, nm_setting_ip_config, NM_TYPE_SETTING)
1109
1110 #define NM_SETTING_IP_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfigPrivate))
1111
1112 typedef struct {
1113         char *method;
1114         GPtrArray *dns;        /* array of IP address strings */
1115         GPtrArray *dns_search; /* array of domain name strings */
1116         GPtrArray *dns_options;/* array of DNS options */
1117         GPtrArray *addresses;  /* array of NMIPAddress */
1118         GPtrArray *routes;     /* array of NMIPRoute */
1119         gint64 route_metric;
1120         char *gateway;
1121         gboolean ignore_auto_routes;
1122         gboolean ignore_auto_dns;
1123         char *dhcp_hostname;
1124         gboolean dhcp_send_hostname;
1125         gboolean never_default;
1126         gboolean may_fail;
1127         gint dad_timeout;
1128         gint dhcp_timeout;
1129 } NMSettingIPConfigPrivate;
1130
1131 enum {
1132         PROP_0,
1133         PROP_METHOD,
1134         PROP_DNS,
1135         PROP_DNS_SEARCH,
1136         PROP_DNS_OPTIONS,
1137         PROP_ADDRESSES,
1138         PROP_GATEWAY,
1139         PROP_ROUTES,
1140         PROP_ROUTE_METRIC,
1141         PROP_IGNORE_AUTO_ROUTES,
1142         PROP_IGNORE_AUTO_DNS,
1143         PROP_DHCP_HOSTNAME,
1144         PROP_DHCP_SEND_HOSTNAME,
1145         PROP_NEVER_DEFAULT,
1146         PROP_MAY_FAIL,
1147         PROP_DAD_TIMEOUT,
1148         PROP_DHCP_TIMEOUT,
1149
1150         LAST_PROP
1151 };
1152
1153 #define NM_SETTING_IP_CONFIG_GET_FAMILY(setting) (NM_IS_SETTING_IP4_CONFIG (setting) ? AF_INET : AF_INET6)
1154
1155 /**
1156  * nm_setting_ip_config_get_method:
1157  * @setting: the #NMSettingIPConfig
1158  *
1159  * Returns: the #NMSettingIPConfig:method property of the setting; see
1160  * #NMSettingIP4Config and #NMSettingIP6Config for details of the
1161  * methods available with each type.
1162  **/
1163 const char *
1164 nm_setting_ip_config_get_method (NMSettingIPConfig *setting)
1165 {
1166         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
1167
1168         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->method;
1169 }
1170
1171 /**
1172  * nm_setting_ip_config_get_num_dns:
1173  * @setting: the #NMSettingIPConfig
1174  *
1175  * Returns: the number of configured DNS servers
1176  **/
1177 guint
1178 nm_setting_ip_config_get_num_dns (NMSettingIPConfig *setting)
1179 {
1180         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
1181
1182         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns->len;
1183 }
1184
1185 /**
1186  * nm_setting_ip_config_get_dns:
1187  * @setting: the #NMSettingIPConfig
1188  * @idx: index number of the DNS server to return
1189  *
1190  * Returns: the IP address of the DNS server at index @idx
1191  **/
1192 const char *
1193 nm_setting_ip_config_get_dns (NMSettingIPConfig *setting, int idx)
1194 {
1195         NMSettingIPConfigPrivate *priv;
1196
1197         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
1198
1199         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1200         g_return_val_if_fail (idx < priv->dns->len, NULL);
1201
1202         return priv->dns->pdata[idx];
1203 }
1204
1205 /**
1206  * nm_setting_ip_config_add_dns:
1207  * @setting: the #NMSettingIPConfig
1208  * @dns: the IP address of the DNS server to add
1209  *
1210  * Adds a new DNS server to the setting.
1211  *
1212  * Returns: %TRUE if the DNS server was added; %FALSE if the server was already
1213  * known
1214  **/
1215 gboolean
1216 nm_setting_ip_config_add_dns (NMSettingIPConfig *setting, const char *dns)
1217 {
1218         NMSettingIPConfigPrivate *priv;
1219         char *dns_canonical;
1220         int i;
1221
1222         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1223         g_return_val_if_fail (dns != NULL, FALSE);
1224         g_return_val_if_fail (nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns), FALSE);
1225
1226         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1227
1228         dns_canonical = canonicalize_ip (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns, FALSE);
1229         for (i = 0; i < priv->dns->len; i++) {
1230                 if (!strcmp (dns_canonical, priv->dns->pdata[i])) {
1231                         g_free (dns_canonical);
1232                         return FALSE;
1233                 }
1234         }
1235
1236         g_ptr_array_add (priv->dns, dns_canonical);
1237         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS);
1238         return TRUE;
1239 }
1240
1241 /**
1242  * nm_setting_ip_config_remove_dns:
1243  * @setting: the #NMSettingIPConfig
1244  * @idx: index number of the DNS server to remove
1245  *
1246  * Removes the DNS server at index @idx.
1247  **/
1248 void
1249 nm_setting_ip_config_remove_dns (NMSettingIPConfig *setting, int idx)
1250 {
1251         NMSettingIPConfigPrivate *priv;
1252
1253         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1254
1255         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1256         g_return_if_fail (idx < priv->dns->len);
1257
1258         g_ptr_array_remove_index (priv->dns, idx);
1259         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS);
1260 }
1261
1262 /**
1263  * nm_setting_ip_config_remove_dns_by_value:
1264  * @setting: the #NMSettingIPConfig
1265  * @dns: the DNS server to remove
1266  *
1267  * Removes the DNS server @dns.
1268  *
1269  * Returns: %TRUE if the DNS server was found and removed; %FALSE if it was not.
1270  **/
1271 gboolean
1272 nm_setting_ip_config_remove_dns_by_value (NMSettingIPConfig *setting, const char *dns)
1273 {
1274         NMSettingIPConfigPrivate *priv;
1275         char *dns_canonical;
1276         int i;
1277
1278         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1279         g_return_val_if_fail (dns != NULL, FALSE);
1280         g_return_val_if_fail (nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns), FALSE);
1281
1282         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1283
1284         dns_canonical = canonicalize_ip (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns, FALSE);
1285         for (i = 0; i < priv->dns->len; i++) {
1286                 if (!strcmp (dns_canonical, priv->dns->pdata[i])) {
1287                         g_ptr_array_remove_index (priv->dns, i);
1288                         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS);
1289                         g_free (dns_canonical);
1290                         return TRUE;
1291                 }
1292         }
1293         g_free (dns_canonical);
1294         return FALSE;
1295 }
1296
1297 /**
1298  * nm_setting_ip_config_clear_dns:
1299  * @setting: the #NMSettingIPConfig
1300  *
1301  * Removes all configured DNS servers.
1302  **/
1303 void
1304 nm_setting_ip_config_clear_dns (NMSettingIPConfig *setting)
1305 {
1306         NMSettingIPConfigPrivate *priv;
1307
1308         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1309
1310         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1311         g_ptr_array_set_size (priv->dns, 0);
1312         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS);
1313 }
1314
1315 /**
1316  * nm_setting_ip_config_get_num_dns_searches:
1317  * @setting: the #NMSettingIPConfig
1318  *
1319  * Returns: the number of configured DNS search domains
1320  **/
1321 guint
1322 nm_setting_ip_config_get_num_dns_searches (NMSettingIPConfig *setting)
1323 {
1324         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
1325
1326         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_search->len;
1327 }
1328
1329 /**
1330  * nm_setting_ip_config_get_dns_search:
1331  * @setting: the #NMSettingIPConfig
1332  * @idx: index number of the DNS search domain to return
1333  *
1334  * Returns: the DNS search domain at index @idx
1335  **/
1336 const char *
1337 nm_setting_ip_config_get_dns_search (NMSettingIPConfig *setting, int idx)
1338 {
1339         NMSettingIPConfigPrivate *priv;
1340
1341         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
1342
1343         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1344         g_return_val_if_fail (idx < priv->dns_search->len, NULL);
1345
1346         return priv->dns_search->pdata[idx];
1347 }
1348
1349 /**
1350  * nm_setting_ip_config_add_dns_search:
1351  * @setting: the #NMSettingIPConfig
1352  * @dns_search: the search domain to add
1353  *
1354  * Adds a new DNS search domain to the setting.
1355  *
1356  * Returns: %TRUE if the DNS search domain was added; %FALSE if the search
1357  * domain was already known
1358  **/
1359 gboolean
1360 nm_setting_ip_config_add_dns_search (NMSettingIPConfig *setting,
1361                                      const char *dns_search)
1362 {
1363         NMSettingIPConfigPrivate *priv;
1364         int i;
1365
1366         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1367         g_return_val_if_fail (dns_search != NULL, FALSE);
1368         g_return_val_if_fail (dns_search[0] != '\0', FALSE);
1369
1370         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1371         for (i = 0; i < priv->dns_search->len; i++) {
1372                 if (!strcmp (dns_search, priv->dns_search->pdata[i]))
1373                         return FALSE;
1374         }
1375
1376         g_ptr_array_add (priv->dns_search, g_strdup (dns_search));
1377         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH);
1378         return TRUE;
1379 }
1380
1381 /**
1382  * nm_setting_ip_config_remove_dns_search:
1383  * @setting: the #NMSettingIPConfig
1384  * @idx: index number of the DNS search domain
1385  *
1386  * Removes the DNS search domain at index @idx.
1387  **/
1388 void
1389 nm_setting_ip_config_remove_dns_search (NMSettingIPConfig *setting, int idx)
1390 {
1391         NMSettingIPConfigPrivate *priv;
1392
1393         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1394
1395         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1396         g_return_if_fail (idx < priv->dns_search->len);
1397
1398         g_ptr_array_remove_index (priv->dns_search, idx);
1399         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH);
1400 }
1401
1402 /**
1403  * nm_setting_ip_config_remove_dns_search_by_value:
1404  * @setting: the #NMSettingIPConfig
1405  * @dns_search: the search domain to remove
1406  *
1407  * Removes the DNS search domain @dns_search.
1408  *
1409  * Returns: %TRUE if the DNS search domain was found and removed; %FALSE if it was not.
1410  *
1411  * Since 0.9.10
1412  **/
1413 gboolean
1414 nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig *setting,
1415                                                  const char *dns_search)
1416 {
1417         NMSettingIPConfigPrivate *priv;
1418         int i;
1419
1420         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1421         g_return_val_if_fail (dns_search != NULL, FALSE);
1422         g_return_val_if_fail (dns_search[0] != '\0', FALSE);
1423
1424         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1425         for (i = 0; i < priv->dns_search->len; i++) {
1426                 if (!strcmp (dns_search, priv->dns_search->pdata[i])) {
1427                         g_ptr_array_remove_index (priv->dns_search, i);
1428                         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH);
1429                         return TRUE;
1430                 }
1431         }
1432         return FALSE;
1433 }
1434
1435 /**
1436  * nm_setting_ip_config_clear_dns_searches:
1437  * @setting: the #NMSettingIPConfig
1438  *
1439  * Removes all configured DNS search domains.
1440  **/
1441 void
1442 nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting)
1443 {
1444         NMSettingIPConfigPrivate *priv;
1445
1446         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1447
1448         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1449         g_ptr_array_set_size (priv->dns_search, 0);
1450         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_SEARCH);
1451 }
1452
1453 /**
1454  * nm_setting_ip_config_get_num_dns_options:
1455  * @setting: the #NMSettingIPConfig
1456  *
1457  * Returns: the number of configured DNS options
1458  *
1459  * Since: 1.2
1460  **/
1461 guint
1462 nm_setting_ip_config_get_num_dns_options (NMSettingIPConfig *setting)
1463 {
1464         NMSettingIPConfigPrivate *priv;
1465
1466         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
1467
1468         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1469
1470         return priv->dns_options ? priv->dns_options->len : 0;
1471 }
1472
1473 /**
1474  * nm_setting_ip_config_has_dns_options:
1475  * @setting: the #NMSettingIPConfig
1476  *
1477  * NMSettingIPConfig can have a list of dns-options. If the list
1478  * is empty, there are two similar (but differentiated) states.
1479  * Either the options are explicitly set to have no values,
1480  * or the options are left undefined. The latter means to use
1481  * a default configuration, while the former explicitly means "no-options".
1482  *
1483  * Returns: whether DNS options are initalized or left unset (the default).
1484  **/
1485 gboolean
1486 nm_setting_ip_config_has_dns_options (NMSettingIPConfig *setting)
1487 {
1488         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
1489
1490         return !!NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_options;
1491 }
1492
1493 /**
1494  * nm_setting_ip_config_get_dns_option:
1495  * @setting: the #NMSettingIPConfig
1496  * @idx: index number of the DNS option
1497  *
1498  * Returns: the DNS option at index @idx
1499  *
1500  * Since: 1.2
1501  **/
1502 const char *
1503 nm_setting_ip_config_get_dns_option (NMSettingIPConfig *setting, guint idx)
1504 {
1505         NMSettingIPConfigPrivate *priv;
1506
1507         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
1508
1509         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1510         g_return_val_if_fail (priv->dns_options, NULL);
1511         g_return_val_if_fail (idx < priv->dns_options->len, NULL);
1512
1513         return priv->dns_options->pdata[idx];
1514 }
1515
1516 /**
1517  * nm_setting_ip_config_next_valid_dns_option:
1518  * @setting: the #NMSettingIPConfig
1519  * @idx: index to start the search from
1520  *
1521  * Returns: the index, greater or equal than @idx, of the first valid
1522  * DNS option, or -1 if no valid option is found
1523  *
1524  * Since: 1.2
1525  **/
1526 gint
1527 nm_setting_ip_config_next_valid_dns_option (NMSettingIPConfig *setting, guint idx)
1528 {
1529         NMSettingIPConfigPrivate *priv;
1530
1531         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), -1);
1532
1533         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1534
1535         if (!priv->dns_options)
1536                 return -1;
1537
1538         for (; idx < priv->dns_options->len; idx++) {
1539                 if (_nm_utils_dns_option_validate (priv->dns_options->pdata[idx], NULL, NULL,
1540                                                    NM_IS_SETTING_IP6_CONFIG (setting),
1541                                                    _nm_utils_dns_option_descs))
1542                         return idx;
1543         }
1544
1545         return -1;
1546 }
1547
1548 /**
1549  * nm_setting_ip_config_add_dns_option:
1550  * @setting: the #NMSettingIPConfig
1551  * @dns_option: the DNS option to add
1552  *
1553  * Adds a new DNS option to the setting.
1554  *
1555  * Returns: %TRUE if the DNS option was added; %FALSE otherwise
1556  *
1557  * Since: 1.2
1558  **/
1559 gboolean
1560 nm_setting_ip_config_add_dns_option (NMSettingIPConfig *setting,
1561                                      const char *dns_option)
1562 {
1563         NMSettingIPConfigPrivate *priv;
1564
1565         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1566         g_return_val_if_fail (dns_option != NULL, FALSE);
1567         g_return_val_if_fail (dns_option[0] != '\0', FALSE);
1568
1569         if (!_nm_utils_dns_option_validate (dns_option, NULL, NULL, FALSE, NULL))
1570                 return FALSE;
1571
1572         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1573         if (!priv->dns_options)
1574                 priv->dns_options = g_ptr_array_new_with_free_func (g_free);
1575         else {
1576                 if (_nm_utils_dns_option_find_idx (priv->dns_options, dns_option) >= 0)
1577                         return FALSE;
1578         }
1579
1580         g_ptr_array_add (priv->dns_options, g_strdup (dns_option));
1581         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
1582         return TRUE;
1583 }
1584
1585 /**
1586  * nm_setting_ip_config_remove_dns_option:
1587  * @setting: the #NMSettingIPConfig
1588  * @idx: index number of the DNS option
1589  *
1590  * Removes the DNS option at index @idx.
1591  *
1592  * Since: 1.2
1593  **/
1594 void
1595 nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting, int idx)
1596 {
1597         NMSettingIPConfigPrivate *priv;
1598
1599         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1600
1601         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1602         g_return_if_fail (priv->dns_options);
1603         g_return_if_fail (idx < priv->dns_options->len);
1604
1605         g_ptr_array_remove_index (priv->dns_options, idx);
1606         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
1607 }
1608
1609 /**
1610  * nm_setting_ip_config_remove_dns_option_by_value:
1611  * @setting: the #NMSettingIPConfig
1612  * @dns_option: the DNS option to remove
1613  *
1614  * Removes the DNS option @dns_option.
1615  *
1616  * Returns: %TRUE if the DNS option was found and removed; %FALSE if it was not.
1617  *
1618  * Since: 1.2
1619  **/
1620 gboolean
1621 nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting,
1622                                                  const char *dns_option)
1623 {
1624         NMSettingIPConfigPrivate *priv;
1625         int i;
1626
1627         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1628         g_return_val_if_fail (dns_option != NULL, FALSE);
1629         g_return_val_if_fail (dns_option[0] != '\0', FALSE);
1630
1631         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1632         if (!priv->dns_options)
1633                 return FALSE;
1634
1635         i = _nm_utils_dns_option_find_idx (priv->dns_options, dns_option);
1636         if (i >= 0) {
1637                 g_ptr_array_remove_index (priv->dns_options, i);
1638                 g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
1639                 return TRUE;
1640         }
1641
1642         return FALSE;
1643 }
1644
1645 /**
1646  * nm_setting_ip_config_clear_dns_options:
1647  * @setting: the #NMSettingIPConfig
1648  * @is_set: the dns-options can be either empty or unset (default).
1649  *   Specify how to clear the options.
1650  *
1651  * Removes all configured DNS options.
1652  *
1653  * Since: 1.2
1654  **/
1655 void
1656 nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting, gboolean is_set)
1657 {
1658         NMSettingIPConfigPrivate *priv;
1659
1660         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1661
1662         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1663         if (!priv->dns_options) {
1664                 if (!is_set)
1665                         return;
1666                 priv->dns_options = g_ptr_array_new_with_free_func (g_free);
1667         } else {
1668                 if (!is_set) {
1669                         g_ptr_array_unref (priv->dns_options);
1670                         priv->dns_options = NULL;
1671                 } else {
1672                         if (priv->dns_options->len == 0)
1673                                 return;
1674                         g_ptr_array_set_size (priv->dns_options, 0);
1675                 }
1676         }
1677         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
1678 }
1679
1680 /**
1681  * nm_setting_ip_config_get_num_addresses:
1682  * @setting: the #NMSettingIPConfig
1683  *
1684  * Returns: the number of configured addresses
1685  **/
1686 guint
1687 nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting)
1688 {
1689         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
1690
1691         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->addresses->len;
1692 }
1693
1694 /**
1695  * nm_setting_ip_config_get_address:
1696  * @setting: the #NMSettingIPConfig
1697  * @idx: index number of the address to return
1698  *
1699  * Returns: (transfer none): the address at index @idx
1700  **/
1701 NMIPAddress *
1702 nm_setting_ip_config_get_address (NMSettingIPConfig *setting, int idx)
1703 {
1704         NMSettingIPConfigPrivate *priv;
1705
1706         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
1707
1708         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1709         g_return_val_if_fail (idx < priv->addresses->len, NULL);
1710
1711         return priv->addresses->pdata[idx];
1712 }
1713
1714 /**
1715  * nm_setting_ip_config_add_address:
1716  * @setting: the #NMSettingIPConfig
1717  * @address: the new address to add
1718  *
1719  * Adds a new IP address and associated information to the setting.  The
1720  * given address is duplicated internally and is not changed by this function.
1721  *
1722  * Returns: %TRUE if the address was added; %FALSE if the address was already
1723  * known.
1724  **/
1725 gboolean
1726 nm_setting_ip_config_add_address (NMSettingIPConfig *setting,
1727                                   NMIPAddress *address)
1728 {
1729         NMSettingIPConfigPrivate *priv;
1730         int i;
1731
1732         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1733         g_return_val_if_fail (address != NULL, FALSE);
1734         g_return_val_if_fail (address->family == NM_SETTING_IP_CONFIG_GET_FAMILY (setting), FALSE);
1735
1736         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1737         for (i = 0; i < priv->addresses->len; i++) {
1738                 if (nm_ip_address_equal (priv->addresses->pdata[i], address))
1739                         return FALSE;
1740         }
1741
1742         g_ptr_array_add (priv->addresses, nm_ip_address_dup (address));
1743
1744         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
1745         return TRUE;
1746 }
1747
1748 /**
1749  * nm_setting_ip_config_remove_address:
1750  * @setting: the #NMSettingIPConfig
1751  * @idx: index number of the address to remove
1752  *
1753  * Removes the address at index @idx.
1754  **/
1755 void
1756 nm_setting_ip_config_remove_address (NMSettingIPConfig *setting, int idx)
1757 {
1758         NMSettingIPConfigPrivate *priv;
1759
1760         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1761
1762         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1763         g_return_if_fail (idx < priv->addresses->len);
1764
1765         g_ptr_array_remove_index (priv->addresses, idx);
1766
1767         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
1768 }
1769
1770 /**
1771  * nm_setting_ip_config_remove_address_by_value:
1772  * @setting: the #NMSettingIPConfig
1773  * @address: the IP address to remove
1774  *
1775  * Removes the address @address.
1776  *
1777  * Returns: %TRUE if the address was found and removed; %FALSE if it was not.
1778  **/
1779 gboolean
1780 nm_setting_ip_config_remove_address_by_value (NMSettingIPConfig *setting,
1781                                               NMIPAddress *address)
1782 {
1783         NMSettingIPConfigPrivate *priv;
1784         int i;
1785
1786         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1787         g_return_val_if_fail (address != NULL, FALSE);
1788
1789         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1790         for (i = 0; i < priv->addresses->len; i++) {
1791                 if (nm_ip_address_equal (priv->addresses->pdata[i], address)) {
1792                         g_ptr_array_remove_index (priv->addresses, i);
1793                         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
1794                         return TRUE;
1795                 }
1796         }
1797         return FALSE;
1798 }
1799
1800 /**
1801  * nm_setting_ip_config_clear_addresses:
1802  * @setting: the #NMSettingIPConfig
1803  *
1804  * Removes all configured addresses.
1805  **/
1806 void
1807 nm_setting_ip_config_clear_addresses (NMSettingIPConfig *setting)
1808 {
1809         NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1810
1811         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1812
1813         g_ptr_array_set_size (priv->addresses, 0);
1814         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
1815 }
1816
1817 /**
1818  * nm_setting_ip_config_get_gateway:
1819  * @setting: the #NMSettingIPConfig
1820  *
1821  * Returns: the IP address of the gateway associated with this configuration, or
1822  * %NULL.
1823  **/
1824 const char *
1825 nm_setting_ip_config_get_gateway (NMSettingIPConfig *setting)
1826 {
1827         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
1828
1829         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->gateway;
1830 }
1831
1832 /**
1833  * nm_setting_ip_config_get_num_routes:
1834  * @setting: the #NMSettingIPConfig
1835  *
1836  * Returns: the number of configured routes
1837  **/
1838 guint
1839 nm_setting_ip_config_get_num_routes (NMSettingIPConfig *setting)
1840 {
1841         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
1842
1843         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->routes->len;
1844 }
1845
1846 /**
1847  * nm_setting_ip_config_get_route:
1848  * @setting: the #NMSettingIPConfig
1849  * @idx: index number of the route to return
1850  *
1851  * Returns: (transfer none): the route at index @idx
1852  **/
1853 NMIPRoute *
1854 nm_setting_ip_config_get_route (NMSettingIPConfig *setting, int idx)
1855 {
1856         NMSettingIPConfigPrivate *priv;
1857
1858         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
1859
1860         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1861         g_return_val_if_fail (idx < priv->routes->len, NULL);
1862
1863         return priv->routes->pdata[idx];
1864 }
1865
1866 /**
1867  * nm_setting_ip_config_add_route:
1868  * @setting: the #NMSettingIPConfig
1869  * @route: the route to add
1870  *
1871  * Adds a new route and associated information to the setting.  The
1872  * given route is duplicated internally and is not changed by this function.
1873  *
1874  * Returns: %TRUE if the route was added; %FALSE if the route was already known.
1875  **/
1876 gboolean
1877 nm_setting_ip_config_add_route (NMSettingIPConfig *setting,
1878                                 NMIPRoute *route)
1879 {
1880         NMSettingIPConfigPrivate *priv;
1881         int i;
1882
1883         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1884         g_return_val_if_fail (route != NULL, FALSE);
1885         g_return_val_if_fail (route->family == NM_SETTING_IP_CONFIG_GET_FAMILY (setting), FALSE);
1886
1887         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1888         for (i = 0; i < priv->routes->len; i++) {
1889                 if (nm_ip_route_equal (priv->routes->pdata[i], route))
1890                         return FALSE;
1891         }
1892
1893         g_ptr_array_add (priv->routes, nm_ip_route_dup (route));
1894         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES);
1895         return TRUE;
1896 }
1897
1898 /**
1899  * nm_setting_ip_config_remove_route:
1900  * @setting: the #NMSettingIPConfig
1901  * @idx: index number of the route
1902  *
1903  * Removes the route at index @idx.
1904  **/
1905 void
1906 nm_setting_ip_config_remove_route (NMSettingIPConfig *setting, int idx)
1907 {
1908         NMSettingIPConfigPrivate *priv;
1909
1910         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1911
1912         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1913         g_return_if_fail (idx < priv->routes->len);
1914
1915         g_ptr_array_remove_index (priv->routes, idx);
1916         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES);
1917 }
1918
1919 /**
1920  * nm_setting_ip_config_remove_route_by_value:
1921  * @setting: the #NMSettingIPConfig
1922  * @route: the route to remove
1923  *
1924  * Removes the route @route.
1925  *
1926  * Returns: %TRUE if the route was found and removed; %FALSE if it was not.
1927  **/
1928 gboolean
1929 nm_setting_ip_config_remove_route_by_value (NMSettingIPConfig *setting,
1930                                              NMIPRoute *route)
1931 {
1932         NMSettingIPConfigPrivate *priv;
1933         int i;
1934
1935         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1936         g_return_val_if_fail (route != NULL, FALSE);
1937
1938         priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1939         for (i = 0; i < priv->routes->len; i++) {
1940                 if (nm_ip_route_equal (priv->routes->pdata[i], route)) {
1941                         g_ptr_array_remove_index (priv->routes, i);
1942                         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES);
1943                         return TRUE;
1944                 }
1945         }
1946         return FALSE;
1947 }
1948
1949 /**
1950  * nm_setting_ip_config_clear_routes:
1951  * @setting: the #NMSettingIPConfig
1952  *
1953  * Removes all configured routes.
1954  **/
1955 void
1956 nm_setting_ip_config_clear_routes (NMSettingIPConfig *setting)
1957 {
1958         NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
1959
1960         g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
1961
1962         g_ptr_array_set_size (priv->routes, 0);
1963         g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_ROUTES);
1964 }
1965
1966 /**
1967  * nm_setting_ip_config_get_route_metric:
1968  * @setting: the #NMSettingIPConfig
1969  *
1970  * Returns the value contained in the #NMSettingIPConfig:route-metric
1971  * property.
1972  *
1973  * Returns: the route metric that is used for routes that don't explicitly
1974  * specify a metric. See #NMSettingIPConfig:route-metric for more details.
1975  **/
1976 gint64
1977 nm_setting_ip_config_get_route_metric (NMSettingIPConfig *setting)
1978 {
1979         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), -1);
1980
1981         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->route_metric;
1982 }
1983
1984
1985 /**
1986  * nm_setting_ip_config_get_ignore_auto_routes:
1987  * @setting: the #NMSettingIPConfig
1988  *
1989  * Returns the value contained in the #NMSettingIPConfig:ignore-auto-routes
1990  * property.
1991  *
1992  * Returns: %TRUE if automatically configured (ie via DHCP) routes should be
1993  * ignored.
1994  **/
1995 gboolean
1996 nm_setting_ip_config_get_ignore_auto_routes (NMSettingIPConfig *setting)
1997 {
1998         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
1999
2000         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->ignore_auto_routes;
2001 }
2002
2003 /**
2004  * nm_setting_ip_config_get_ignore_auto_dns:
2005  * @setting: the #NMSettingIPConfig
2006  *
2007  * Returns the value contained in the #NMSettingIPConfig:ignore-auto-dns
2008  * property.
2009  *
2010  * Returns: %TRUE if automatically configured (ie via DHCP) DNS information
2011  * should be ignored.
2012  **/
2013 gboolean
2014 nm_setting_ip_config_get_ignore_auto_dns (NMSettingIPConfig *setting)
2015 {
2016         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
2017
2018         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->ignore_auto_dns;
2019 }
2020
2021 /**
2022  * nm_setting_ip_config_get_dhcp_hostname:
2023  * @setting: the #NMSettingIPConfig
2024  *
2025  * Returns the value contained in the #NMSettingIPConfig:dhcp-hostname
2026  * property.
2027  *
2028  * Returns: the configured hostname to send to the DHCP server
2029  **/
2030 const char *
2031 nm_setting_ip_config_get_dhcp_hostname (NMSettingIPConfig *setting)
2032 {
2033         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
2034
2035         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dhcp_hostname;
2036 }
2037
2038 /**
2039  * nm_setting_ip_config_get_dhcp_send_hostname:
2040  * @setting: the #NMSettingIPConfig
2041  *
2042  * Returns the value contained in the #NMSettingIPConfig:dhcp-send-hostname
2043  * property.
2044  *
2045  * Returns: %TRUE if NetworkManager should send the machine hostname to the
2046  * DHCP server when requesting addresses to allow the server to automatically
2047  * update DNS information for this machine.
2048  **/
2049 gboolean
2050 nm_setting_ip_config_get_dhcp_send_hostname (NMSettingIPConfig *setting)
2051 {
2052         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
2053
2054         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dhcp_send_hostname;
2055 }
2056
2057 /**
2058  * nm_setting_ip_config_get_never_default:
2059  * @setting: the #NMSettingIPConfig
2060  *
2061  * Returns the value contained in the #NMSettingIPConfig:never-default
2062  * property.
2063  *
2064  * Returns: %TRUE if this connection should never be the default
2065  *   connection
2066  **/
2067 gboolean
2068 nm_setting_ip_config_get_never_default (NMSettingIPConfig *setting)
2069 {
2070         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
2071
2072         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->never_default;
2073 }
2074
2075 /**
2076  * nm_setting_ip_config_get_may_fail:
2077  * @setting: the #NMSettingIPConfig
2078  *
2079  * Returns the value contained in the #NMSettingIPConfig:may-fail
2080  * property.
2081  *
2082  * Returns: %TRUE if this connection doesn't require this type of IP
2083  * addressing to complete for the connection to succeed.
2084  **/
2085 gboolean
2086 nm_setting_ip_config_get_may_fail (NMSettingIPConfig *setting)
2087 {
2088         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
2089
2090         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->may_fail;
2091 }
2092
2093 /**
2094  * nm_setting_ip_config_get_dad_timeout:
2095  * @setting: the #NMSettingIPConfig
2096  *
2097  * Returns: the #NMSettingIPConfig:dad-timeout property.
2098  *
2099  * Since: 1.2
2100  **/
2101 gint
2102 nm_setting_ip_config_get_dad_timeout (NMSettingIPConfig *setting)
2103 {
2104         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
2105
2106         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dad_timeout;
2107 }
2108
2109 /**
2110  * nm_setting_ip_config_get_dhcp_timeout:
2111  * @setting: the #NMSettingIPConfig
2112  *
2113  * Returns the value contained in the #NMSettingIPConfig:dhcp-timeout
2114  * property.
2115  *
2116  * Returns: the configured DHCP timeout in seconds. 0 = default for
2117  * the particular kind of device.
2118  *
2119  * Since: 1.2
2120  **/
2121 gint
2122 nm_setting_ip_config_get_dhcp_timeout (NMSettingIPConfig *setting)
2123 {
2124         g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
2125
2126         return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dhcp_timeout;
2127 }
2128
2129 static gboolean
2130 verify_label (const char *label)
2131 {
2132         const char *p;
2133         char *iface;
2134
2135         p = strchr (label, ':');
2136         if (!p)
2137                 return FALSE;
2138         iface = g_strndup (label, p - label);
2139         if (!nm_utils_iface_valid_name (iface)) {
2140                 g_free (iface);
2141                 return FALSE;
2142         }
2143         g_free (iface);
2144
2145         for (p++; *p; p++) {
2146                 if (!g_ascii_isalnum (*p) && *p != '_')
2147                         return FALSE;
2148         }
2149
2150         return TRUE;
2151 }
2152
2153 static gboolean
2154 verify (NMSetting *setting, NMConnection *connection, GError **error)
2155 {
2156         NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
2157         int i;
2158
2159         if (!priv->method) {
2160                 g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_PROPERTY,
2161                                      _("property is missing"));
2162                 g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_METHOD);
2163                 return FALSE;
2164         }
2165
2166         if (priv->dhcp_hostname && !*priv->dhcp_hostname) {
2167                 g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY,
2168                                      _("property is empty"));
2169                 g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_DHCP_HOSTNAME);
2170                 return FALSE;
2171         }
2172
2173         /* Validate DNS */
2174         for (i = 0; i < priv->dns->len; i++) {
2175                 const char *dns = priv->dns->pdata[i];
2176
2177                 if (!nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), dns)) {
2178                         g_set_error (error,
2179                                      NM_CONNECTION_ERROR,
2180                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
2181                                      _("%d. DNS server address is invalid"),
2182                                      i+1);
2183                         g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_DNS);
2184                         return FALSE;
2185                 }
2186         }
2187
2188         /* Validate addresses */
2189         for (i = 0; i < priv->addresses->len; i++) {
2190                 NMIPAddress *addr = (NMIPAddress *) priv->addresses->pdata[i];
2191                 GVariant *label;
2192
2193                 if (nm_ip_address_get_family (addr) != NM_SETTING_IP_CONFIG_GET_FAMILY (setting)) {
2194                         g_set_error (error,
2195                                      NM_CONNECTION_ERROR,
2196                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
2197                                      _("%d. IP address is invalid"),
2198                                      i+1);
2199                         g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
2200                         return FALSE;
2201                 }
2202
2203                 label = nm_ip_address_get_attribute (addr, "label");
2204                 if (label) {
2205                         if (!g_variant_is_of_type (label, G_VARIANT_TYPE_STRING)) {
2206                                 g_set_error (error,
2207                                              NM_CONNECTION_ERROR,
2208                                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
2209                                              _("%d. IP address has 'label' property with invalid type"),
2210                                              i+1);
2211                                 g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
2212                                 return FALSE;
2213                         }
2214                         if (!verify_label (g_variant_get_string (label, NULL))) {
2215                                 g_set_error (error,
2216                                              NM_CONNECTION_ERROR,
2217                                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
2218                                              _("%d. IP address has invalid label '%s'"),
2219                                              i+1, g_variant_get_string (label, NULL));
2220                                 g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ADDRESSES);
2221                                 return FALSE;
2222                         }
2223                 }
2224         }
2225
2226         /* Validate gateway */
2227         if (priv->gateway) {
2228                 if (!priv->addresses->len) {
2229                         g_set_error_literal (error,
2230                                              NM_CONNECTION_ERROR,
2231                                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
2232                                              _("gateway cannot be set if there are no addresses configured"));
2233                         g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_GATEWAY);
2234                         return FALSE;
2235                 }
2236
2237                 if (!nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), priv->gateway)) {
2238                         g_set_error_literal (error,
2239                                              NM_CONNECTION_ERROR,
2240                                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
2241                                              _("gateway is invalid"));
2242                         g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_GATEWAY);
2243                         return FALSE;
2244                 }
2245         }
2246
2247         /* Validate routes */
2248         for (i = 0; i < priv->routes->len; i++) {
2249                 NMIPRoute *route = (NMIPRoute *) priv->routes->pdata[i];
2250
2251                 if (nm_ip_route_get_family (route) != NM_SETTING_IP_CONFIG_GET_FAMILY (setting)) {
2252                         g_set_error (error,
2253                                      NM_CONNECTION_ERROR,
2254                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
2255                                      _("%d. route is invalid"),
2256                                      i+1);
2257                         g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES);
2258                         return FALSE;
2259                 }
2260                 if (nm_ip_route_get_prefix (route) == 0) {
2261                         g_set_error (error,
2262                                      NM_CONNECTION_ERROR,
2263                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
2264                                      _("%d. route cannot be a default route"),
2265                                      i+1);
2266                         g_prefix_error (error, "%s.%s: ", nm_setting_get_name (setting), NM_SETTING_IP_CONFIG_ROUTES);
2267                         return FALSE;
2268                 }
2269         }
2270
2271         return TRUE;
2272 }
2273
2274
2275 static void
2276 nm_setting_ip_config_init (NMSettingIPConfig *setting)
2277 {
2278         NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
2279
2280         priv->dns = g_ptr_array_new_with_free_func (g_free);
2281         priv->dns_search = g_ptr_array_new_with_free_func (g_free);
2282         priv->dns_options = NULL;
2283         priv->addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
2284         priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref);
2285 }
2286
2287 static void
2288 finalize (GObject *object)
2289 {
2290         NMSettingIPConfig *self = NM_SETTING_IP_CONFIG (object);
2291         NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (self);
2292
2293         g_free (priv->method);
2294         g_free (priv->gateway);
2295         g_free (priv->dhcp_hostname);
2296
2297         g_ptr_array_unref (priv->dns);
2298         g_ptr_array_unref (priv->dns_search);
2299         if (priv->dns_options)
2300                 g_ptr_array_unref (priv->dns_options);
2301         g_ptr_array_unref (priv->addresses);
2302         g_ptr_array_unref (priv->routes);
2303
2304         G_OBJECT_CLASS (nm_setting_ip_config_parent_class)->finalize (object);
2305 }
2306
2307 static void
2308 set_property (GObject *object, guint prop_id,
2309               const GValue *value, GParamSpec *pspec)
2310 {
2311         NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG (object);
2312         NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
2313         const char *gateway;
2314         char **strv;
2315         int i;
2316
2317         switch (prop_id) {
2318         case PROP_METHOD:
2319                 g_free (priv->method);
2320                 priv->method = g_value_dup_string (value);
2321                 break;
2322         case PROP_DNS:
2323                 g_ptr_array_unref (priv->dns);
2324                 priv->dns = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value));
2325                 break;
2326         case PROP_DNS_SEARCH:
2327                 g_ptr_array_unref (priv->dns_search);
2328                 priv->dns_search = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value));
2329                 break;
2330         case PROP_DNS_OPTIONS:
2331                 strv = g_value_get_boxed (value);
2332                 if (!strv) {
2333                         if (priv->dns_options) {
2334                                 g_ptr_array_unref (priv->dns_options);
2335                                 priv->dns_options = NULL;
2336                         }
2337                 } else {
2338                         if (priv->dns_options)
2339                                 g_ptr_array_set_size (priv->dns_options, 0);
2340                         else
2341                                 priv->dns_options = g_ptr_array_new_with_free_func (g_free);
2342                         for (i = 0; strv[i]; i++) {
2343                                 if (   _nm_utils_dns_option_validate (strv[i], NULL, NULL, FALSE, NULL)
2344                                     && _nm_utils_dns_option_find_idx (priv->dns_options, strv[i]) < 0)
2345                                         g_ptr_array_add (priv->dns_options, g_strdup (strv[i]));
2346                         }
2347                 }
2348                 break;
2349         case PROP_ADDRESSES:
2350                 g_ptr_array_unref (priv->addresses);
2351                 priv->addresses = _nm_utils_copy_array (g_value_get_boxed (value),
2352                                                         (NMUtilsCopyFunc) nm_ip_address_dup,
2353                                                         (GDestroyNotify) nm_ip_address_unref);
2354                 break;
2355         case PROP_GATEWAY:
2356                 gateway = g_value_get_string (value);
2357                 g_return_if_fail (!gateway || nm_utils_ipaddr_valid (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), gateway));
2358                 g_free (priv->gateway);
2359                 priv->gateway = canonicalize_ip (NM_SETTING_IP_CONFIG_GET_FAMILY (setting), gateway, TRUE);
2360                 break;
2361         case PROP_ROUTES:
2362                 g_ptr_array_unref (priv->routes);
2363                 priv->routes = _nm_utils_copy_array (g_value_get_boxed (value),
2364                                                      (NMUtilsCopyFunc) nm_ip_route_dup,
2365                                                      (GDestroyNotify) nm_ip_route_unref);
2366                 break;
2367         case PROP_ROUTE_METRIC:
2368                 priv->route_metric = g_value_get_int64 (value);
2369                 break;
2370         case PROP_IGNORE_AUTO_ROUTES:
2371                 priv->ignore_auto_routes = g_value_get_boolean (value);
2372                 break;
2373         case PROP_IGNORE_AUTO_DNS:
2374                 priv->ignore_auto_dns = g_value_get_boolean (value);
2375                 break;
2376         case PROP_DHCP_HOSTNAME:
2377                 g_free (priv->dhcp_hostname);
2378                 priv->dhcp_hostname = g_value_dup_string (value);
2379                 break;
2380         case PROP_DHCP_SEND_HOSTNAME:
2381                 priv->dhcp_send_hostname = g_value_get_boolean (value);
2382                 break;
2383         case PROP_NEVER_DEFAULT:
2384                 priv->never_default = g_value_get_boolean (value);
2385                 break;
2386         case PROP_MAY_FAIL:
2387                 priv->may_fail = g_value_get_boolean (value);
2388                 break;
2389         case PROP_DAD_TIMEOUT:
2390                 priv->dad_timeout = g_value_get_int (value);
2391                 break;
2392         case PROP_DHCP_TIMEOUT:
2393                 priv->dhcp_timeout = g_value_get_int (value);
2394                 break;
2395         default:
2396                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2397                 break;
2398         }
2399 }
2400
2401 static void
2402 get_property (GObject *object, guint prop_id,
2403               GValue *value, GParamSpec *pspec)
2404 {
2405         NMSettingIPConfig *setting = NM_SETTING_IP_CONFIG (object);
2406         NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
2407
2408         switch (prop_id) {
2409         case PROP_METHOD:
2410                 g_value_set_string (value, nm_setting_ip_config_get_method (setting));
2411                 break;
2412         case PROP_DNS:
2413                 g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns));
2414                 break;
2415         case PROP_DNS_SEARCH:
2416                 g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns_search));
2417                 break;
2418         case PROP_DNS_OPTIONS:
2419                 g_value_take_boxed (value, priv->dns_options ? _nm_utils_ptrarray_to_strv (priv->dns_options) : NULL);
2420                 break;
2421         case PROP_ADDRESSES:
2422                 g_value_take_boxed (value, _nm_utils_copy_array (priv->addresses,
2423                                                                  (NMUtilsCopyFunc) nm_ip_address_dup,
2424                                                                  (GDestroyNotify) nm_ip_address_unref));
2425                 break;
2426         case PROP_GATEWAY:
2427                 g_value_set_string (value, nm_setting_ip_config_get_gateway (setting));
2428                 break;
2429         case PROP_ROUTES:
2430                 g_value_take_boxed (value, _nm_utils_copy_array (priv->routes,
2431                                                                  (NMUtilsCopyFunc) nm_ip_route_dup,
2432                                                                  (GDestroyNotify) nm_ip_route_unref));
2433                 break;
2434         case PROP_ROUTE_METRIC:
2435                 g_value_set_int64 (value, priv->route_metric);
2436                 break;
2437         case PROP_IGNORE_AUTO_ROUTES:
2438                 g_value_set_boolean (value, nm_setting_ip_config_get_ignore_auto_routes (setting));
2439                 break;
2440         case PROP_IGNORE_AUTO_DNS:
2441                 g_value_set_boolean (value, nm_setting_ip_config_get_ignore_auto_dns (setting));
2442                 break;
2443         case PROP_DHCP_HOSTNAME:
2444                 g_value_set_string (value, nm_setting_ip_config_get_dhcp_hostname (setting));
2445                 break;
2446         case PROP_DHCP_SEND_HOSTNAME:
2447                 g_value_set_boolean (value, nm_setting_ip_config_get_dhcp_send_hostname (setting));
2448                 break;
2449         case PROP_NEVER_DEFAULT:
2450                 g_value_set_boolean (value, priv->never_default);
2451                 break;
2452         case PROP_MAY_FAIL:
2453                 g_value_set_boolean (value, priv->may_fail);
2454                 break;
2455         case PROP_DAD_TIMEOUT:
2456                 g_value_set_int (value, nm_setting_ip_config_get_dad_timeout (setting));
2457                 break;
2458         case PROP_DHCP_TIMEOUT:
2459                 g_value_set_int (value, nm_setting_ip_config_get_dhcp_timeout (setting));
2460                 break;
2461         default:
2462                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2463                 break;
2464         }
2465 }
2466
2467 static void
2468 ip_gateway_set (NMSetting  *setting,
2469                 GVariant   *connection_dict,
2470                 const char *property,
2471                 GVariant   *value)
2472 {
2473         /* Don't set from 'gateway' if we're going to use the gateway in 'addresses' */
2474         if (_nm_setting_use_legacy_property (setting, connection_dict, "addresses", "gateway"))
2475                 return;
2476
2477         g_object_set (setting, property, g_variant_get_string (value, NULL), NULL);
2478 }
2479
2480 static void
2481 nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
2482 {
2483         GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
2484         NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
2485
2486         g_type_class_add_private (setting_class, sizeof (NMSettingIPConfigPrivate));
2487
2488         /* virtual methods */
2489         object_class->set_property = set_property;
2490         object_class->get_property = get_property;
2491         object_class->finalize     = finalize;
2492         parent_class->verify       = verify;
2493
2494         /* Properties */
2495
2496         /**
2497          * NMSettingIPConfig:method:
2498          *
2499          * IP configuration method.
2500          *
2501          * #NMSettingIP4Config and #NMSettingIP6Config both support "auto",
2502          * "manual", and "link-local". See the subclass-specific documentation for
2503          * other values.
2504          *
2505          * In general, for the "auto" method, properties such as
2506          * #NMSettingIPConfig:dns and #NMSettingIPConfig:routes specify information
2507          * that is added on to the information returned from automatic
2508          * configuration.  The #NMSettingIPConfig:ignore-auto-routes and
2509          * #NMSettingIPConfig:ignore-auto-dns properties modify this behavior.
2510          *
2511          * For methods that imply no upstream network, such as "shared" or
2512          * "link-local", these properties must be empty.
2513          *
2514          * For IPv4 method "shared", the IP subnet can be configured by adding one
2515          * manual IPv4 address or otherwise 10.42.x.0/24 is chosen.
2516          **/
2517         g_object_class_install_property
2518                 (object_class, PROP_METHOD,
2519                  g_param_spec_string (NM_SETTING_IP_CONFIG_METHOD, "", "",
2520                                       NULL,
2521                                       G_PARAM_READWRITE |
2522                                       NM_SETTING_PARAM_INFERRABLE |
2523                                       G_PARAM_STATIC_STRINGS));
2524
2525         /**
2526          * NMSettingIPConfig:dns:
2527          *
2528          * Array of IP addresses of DNS servers.
2529          **/
2530         g_object_class_install_property
2531                 (object_class, PROP_DNS,
2532                  g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS, "", "",
2533                                      G_TYPE_STRV,
2534                                      G_PARAM_READWRITE |
2535                                      G_PARAM_STATIC_STRINGS));
2536
2537         /**
2538          * NMSettingIPConfig:dns-search:
2539          *
2540          * Array of DNS search domains.
2541          **/
2542         g_object_class_install_property
2543                 (object_class, PROP_DNS_SEARCH,
2544                  g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS_SEARCH, "", "",
2545                                      G_TYPE_STRV,
2546                                      G_PARAM_READWRITE |
2547                                      G_PARAM_STATIC_STRINGS));
2548
2549         /**
2550          * NMSettingIPConfig:dns-options:
2551          *
2552          * Array of DNS options.
2553          *
2554          * %NULL means that the options are unset and left at the default.
2555          * In this case NetworkManager will use default options. This is
2556          * distinct from an empty list of properties.
2557          *
2558          * Since: 1.2
2559          **/
2560         g_object_class_install_property
2561                 (object_class, PROP_DNS_OPTIONS,
2562                  g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS_OPTIONS, "", "",
2563                                      G_TYPE_STRV,
2564                                      G_PARAM_READWRITE |
2565                                      G_PARAM_STATIC_STRINGS));
2566
2567         /**
2568          * NMSettingIPConfig:addresses:
2569          *
2570          * Array of IP addresses.
2571          *
2572          * Element-Type: NMIPAddress
2573          **/
2574         g_object_class_install_property
2575                 (object_class, PROP_ADDRESSES,
2576                  g_param_spec_boxed (NM_SETTING_IP_CONFIG_ADDRESSES, "", "",
2577                                      G_TYPE_PTR_ARRAY,
2578                                      G_PARAM_READWRITE |
2579                                      NM_SETTING_PARAM_INFERRABLE |
2580                                      /* "addresses" is a legacy D-Bus property, because the
2581                                       * "addresses" GObject property normally gets set from
2582                                       * the "address-data" D-Bus property...
2583                                       */
2584                                      NM_SETTING_PARAM_LEGACY |
2585                                      G_PARAM_STATIC_STRINGS));
2586
2587         /**
2588          * NMSettingIPConfig:gateway:
2589          *
2590          * The gateway associated with this configuration. This is only meaningful
2591          * if #NMSettingIPConfig:addresses is also set.
2592          **/
2593         g_object_class_install_property
2594                 (object_class, PROP_GATEWAY,
2595                  g_param_spec_string (NM_SETTING_IP_CONFIG_GATEWAY, "", "",
2596                                       NULL,
2597                                       G_PARAM_READWRITE |
2598                                       NM_SETTING_PARAM_INFERRABLE |
2599                                       G_PARAM_STATIC_STRINGS));
2600
2601         _nm_setting_class_override_property (parent_class,
2602                                              NM_SETTING_IP_CONFIG_GATEWAY,
2603                                              G_VARIANT_TYPE_STRING,
2604                                              NULL,
2605                                              ip_gateway_set,
2606                                              NULL);
2607
2608         /**
2609          * NMSettingIPConfig:routes:
2610          *
2611          * Array of IP routes.
2612          *
2613          * Element-Type: NMIPRoute
2614          **/
2615         g_object_class_install_property
2616                 (object_class, PROP_ROUTES,
2617                  g_param_spec_boxed (NM_SETTING_IP_CONFIG_ROUTES, "", "",
2618                                      G_TYPE_PTR_ARRAY,
2619                                      G_PARAM_READWRITE |
2620                                      NM_SETTING_PARAM_INFERRABLE |
2621                                      /* See :addresses above Re: LEGACY */
2622                                      NM_SETTING_PARAM_LEGACY |
2623                                      G_PARAM_STATIC_STRINGS));
2624
2625         /**
2626          * NMSettingIPConfig:route-metric:
2627          *
2628          * The default metric for routes that don't explicitly specify a metric.
2629          * The default value -1 means that the metric is choosen automatically
2630          * based on the device type.
2631          * The metric applies to dynamic routes, manual (static) routes that
2632          * don't have an explicit metric setting, address prefix routes, and
2633          * the default route.
2634          * Note that for IPv6, the kernel accepts zero (0) but coerces it to
2635          * 1024 (user default). Hence, setting this property to zero effectively
2636          * mean setting it to 1024.
2637          * For IPv4, zero is a regular value for the metric.
2638          **/
2639         g_object_class_install_property
2640             (object_class, PROP_ROUTE_METRIC,
2641              g_param_spec_int64 (NM_SETTING_IP_CONFIG_ROUTE_METRIC, "", "",
2642                                  -1, G_MAXUINT32, -1,
2643                                  G_PARAM_READWRITE |
2644                                  G_PARAM_CONSTRUCT |
2645                                  G_PARAM_STATIC_STRINGS));
2646
2647         /**
2648          * NMSettingIPConfig:ignore-auto-routes:
2649          *
2650          * When #NMSettingIPConfig:method is set to "auto" and this property to
2651          * %TRUE, automatically configured routes are ignored and only routes
2652          * specified in the #NMSettingIPConfig:routes property, if any, are used.
2653          **/
2654         g_object_class_install_property
2655                 (object_class, PROP_IGNORE_AUTO_ROUTES,
2656                  g_param_spec_boolean (NM_SETTING_IP_CONFIG_IGNORE_AUTO_ROUTES, "", "",
2657                                        FALSE,
2658                                        G_PARAM_READWRITE |
2659                                        G_PARAM_CONSTRUCT |
2660                                        G_PARAM_STATIC_STRINGS));
2661
2662         /**
2663          * NMSettingIPConfig:ignore-auto-dns:
2664          *
2665          * When #NMSettingIPConfig:method is set to "auto" and this property to
2666          * %TRUE, automatically configured nameservers and search domains are
2667          * ignored and only nameservers and search domains specified in the
2668          * #NMSettingIPConfig:dns and #NMSettingIPConfig:dns-search properties, if
2669          * any, are used.
2670          **/
2671         g_object_class_install_property
2672                 (object_class, PROP_IGNORE_AUTO_DNS,
2673                  g_param_spec_boolean (NM_SETTING_IP_CONFIG_IGNORE_AUTO_DNS, "", "",
2674                                        FALSE,
2675                                        G_PARAM_READWRITE |
2676                                        G_PARAM_CONSTRUCT |
2677                                        G_PARAM_STATIC_STRINGS));
2678
2679         /**
2680          * NMSettingIPConfig:dhcp-hostname:
2681          *
2682          * If the #NMSettingIPConfig:dhcp-send-hostname property is %TRUE, then the
2683          * specified name will be sent to the DHCP server when acquiring a lease.
2684          * This property and #NMSettingIP4Config:dhcp-fqdn are mutually exclusive and
2685          * cannot be set at the same time.
2686          **/
2687         g_object_class_install_property
2688                 (object_class, PROP_DHCP_HOSTNAME,
2689                  g_param_spec_string (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME, "", "",
2690                                       NULL,
2691                                       G_PARAM_READWRITE |
2692                                       NM_SETTING_PARAM_INFERRABLE |
2693                                       G_PARAM_STATIC_STRINGS));
2694
2695         /**
2696          * NMSettingIPConfig:dhcp-send-hostname:
2697          *
2698          * If %TRUE, a hostname is sent to the DHCP server when acquiring a lease.
2699          * Some DHCP servers use this hostname to update DNS databases, essentially
2700          * providing a static hostname for the computer.  If the
2701          * #NMSettingIPConfig:dhcp-hostname property is %NULL and this property is
2702          * %TRUE, the current persistent hostname of the computer is sent.
2703          **/
2704         g_object_class_install_property
2705                 (object_class, PROP_DHCP_SEND_HOSTNAME,
2706                  g_param_spec_boolean (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME, "", "",
2707                                        TRUE,
2708                                        G_PARAM_READWRITE |
2709                                        G_PARAM_CONSTRUCT |
2710                                        G_PARAM_STATIC_STRINGS));
2711
2712         /**
2713          * NMSettingIPConfig:never-default:
2714          *
2715          * If %TRUE, this connection will never be the default connection for this
2716          * IP type, meaning it will never be assigned the default route by
2717          * NetworkManager.
2718          **/
2719         g_object_class_install_property
2720                 (object_class, PROP_NEVER_DEFAULT,
2721                  g_param_spec_boolean (NM_SETTING_IP_CONFIG_NEVER_DEFAULT, "", "",
2722                                        FALSE,
2723                                        G_PARAM_READWRITE |
2724                                        G_PARAM_CONSTRUCT |
2725                                        G_PARAM_STATIC_STRINGS));
2726
2727         /**
2728          * NMSettingIPConfig:may-fail:
2729          *
2730          * If %TRUE, allow overall network configuration to proceed even if the
2731          * configuration specified by this property times out.  Note that at least
2732          * one IP configuration must succeed or overall network configuration will
2733          * still fail.  For example, in IPv6-only networks, setting this property to
2734          * %TRUE on the #NMSettingIP4Config allows the overall network configuration
2735          * to succeed if IPv4 configuration fails but IPv6 configuration completes
2736          * successfully.
2737          **/
2738         g_object_class_install_property
2739                 (object_class, PROP_MAY_FAIL,
2740                  g_param_spec_boolean (NM_SETTING_IP_CONFIG_MAY_FAIL, "", "",
2741                                        TRUE,
2742                                        G_PARAM_READWRITE |
2743                                        G_PARAM_CONSTRUCT |
2744                                        G_PARAM_STATIC_STRINGS));
2745
2746         /**
2747          * NMSettingIPConfig:dad-timeout:
2748          *
2749          * Timeout in milliseconds used to check for the presence of duplicate IP
2750          * addresses on the network.  If an address conflict is detected, the
2751          * activation will fail.  A zero value means that no duplicate address
2752          * detection is performed, -1 means the default value (either configuration
2753          * ipvx.dad-timeout override or 3 seconds).  A value greater than zero is a
2754          * timeout in milliseconds.
2755          *
2756          * Since: 1.2
2757          **/
2758         g_object_class_install_property
2759                 (object_class, PROP_DAD_TIMEOUT,
2760                  g_param_spec_int (NM_SETTING_IP_CONFIG_DAD_TIMEOUT, "", "",
2761                                     -1, NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, -1,
2762                                     G_PARAM_READWRITE |
2763                                     G_PARAM_CONSTRUCT |
2764                                     NM_SETTING_PARAM_FUZZY_IGNORE |
2765                                     G_PARAM_STATIC_STRINGS));
2766         /**
2767          * NMSettingIPConfig:dhcp-timeout:
2768          *
2769          * A timeout for a DHCP transaction in seconds.
2770          **/
2771         g_object_class_install_property
2772                 (object_class, PROP_DHCP_TIMEOUT,
2773                  g_param_spec_int (NM_SETTING_IP_CONFIG_DHCP_TIMEOUT, "", "",
2774                                    0, G_MAXINT32, 0,
2775                                    G_PARAM_READWRITE |
2776                                    NM_SETTING_PARAM_FUZZY_IGNORE |
2777                                    G_PARAM_STATIC_STRINGS));
2778 }