device: renew dhcp leases on awake for software devices
[NetworkManager.git] / libnm-glib / nm-ip6-config.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /*
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the
15  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301 USA.
17  *
18  * Copyright 2007 - 2008 Novell, Inc.
19  * Copyright 2008 - 2014 Red Hat, Inc.
20  */
21
22 #include "nm-default.h"
23
24 #include <string.h>
25
26 #include "nm-setting-ip6-config.h"
27 #include "nm-ip6-config.h"
28 #include "NetworkManager.h"
29 #include "nm-types-private.h"
30 #include "nm-object-private.h"
31 #include "nm-utils.h"
32
33 G_DEFINE_TYPE (NMIP6Config, nm_ip6_config, NM_TYPE_OBJECT)
34
35 #define NM_IP6_CONFIG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IP6_CONFIG, NMIP6ConfigPrivate))
36
37 typedef struct {
38         DBusGProxy *proxy;
39
40         char *gateway;
41         GSList *addresses;
42         GSList *routes;
43         GSList *nameservers;
44         GPtrArray *domains;
45         GPtrArray *searches;
46 } NMIP6ConfigPrivate;
47
48 enum {
49         PROP_0,
50         PROP_GATEWAY,
51         PROP_ADDRESSES,
52         PROP_ROUTES,
53         PROP_NAMESERVERS,
54         PROP_DOMAINS,
55         PROP_SEARCHES,
56
57         LAST_PROP
58 };
59
60 /**
61  * nm_ip6_config_new:
62  * @connection: the #DBusGConnection
63  * @object_path: the DBus object path of the device
64  *
65  * Creates a new #NMIP6Config.
66  *
67  * Returns: (transfer full): a new IP6 configuration
68  **/
69 GObject *
70 nm_ip6_config_new (DBusGConnection *connection, const char *object_path)
71 {
72         return (GObject *) g_object_new (NM_TYPE_IP6_CONFIG,
73                                          NM_OBJECT_DBUS_CONNECTION, connection,
74                                          NM_OBJECT_DBUS_PATH, object_path,
75                                          NULL);
76 }
77
78 static gboolean
79 demarshal_ip6_address_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
80 {
81         NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
82
83         g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip6_address_unref);
84         priv->addresses = NULL;
85
86         priv->addresses = nm_utils_ip6_addresses_from_gvalue (value);
87         _nm_object_queue_notify (object, NM_IP6_CONFIG_ADDRESSES);
88
89         return TRUE;
90 }
91
92 static gboolean
93 demarshal_ip6_nameserver_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
94 {
95         if (!_nm_ip6_address_array_demarshal (value, (GSList **) field))
96                 return FALSE;
97
98         if (pspec && !strcmp (pspec->name, NM_IP6_CONFIG_NAMESERVERS))
99                 _nm_object_queue_notify (object, NM_IP6_CONFIG_NAMESERVERS);
100
101         return TRUE;
102 }
103
104 static gboolean
105 demarshal_domains (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
106 {
107         if (!_nm_string_array_demarshal (value, (GPtrArray **) field))
108                 return FALSE;
109
110         _nm_object_queue_notify (object, NM_IP6_CONFIG_DOMAINS);
111         return TRUE;
112 }
113
114 static gboolean
115 demarshal_searches (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
116 {
117         if (!_nm_string_array_demarshal (value, (GPtrArray **) field))
118                 return FALSE;
119
120         _nm_object_queue_notify (object, NM_IP6_CONFIG_SEARCHES);
121         return TRUE;
122 }
123
124 static gboolean
125 demarshal_ip6_routes_array (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
126 {
127         NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
128
129         g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref);
130         priv->routes = NULL;
131
132         priv->routes = nm_utils_ip6_routes_from_gvalue (value);
133         _nm_object_queue_notify (object, NM_IP6_CONFIG_ROUTES);
134
135         return TRUE;
136 }
137
138 static void
139 register_properties (NMIP6Config *config)
140 {
141         NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config);
142         const NMPropertiesInfo property_info[] = {
143                 { NM_IP6_CONFIG_GATEWAY,      &priv->gateway, },
144                 { NM_IP6_CONFIG_ADDRESSES,    &priv->addresses, demarshal_ip6_address_array },
145                 { NM_IP6_CONFIG_ROUTES,       &priv->routes, demarshal_ip6_routes_array },
146                 { NM_IP6_CONFIG_NAMESERVERS,  &priv->nameservers, demarshal_ip6_nameserver_array },
147                 { NM_IP6_CONFIG_DOMAINS,      &priv->domains, demarshal_domains },
148                 { NM_IP6_CONFIG_SEARCHES,     &priv->searches, demarshal_searches },
149                 { NULL },
150         };
151
152         _nm_object_register_properties (NM_OBJECT (config),
153                                         priv->proxy,
154                                         property_info);
155 }
156
157 /**
158  * nm_ip6_config_get_gateway:
159  * @config: a #NMIP6Config
160  *
161  * Gets the IP6 gateway.
162  *
163  * Returns: the IPv6 gateway of the configuration.
164  *
165  * Since: 0.9.10
166  **/
167 const char *
168 nm_ip6_config_get_gateway (NMIP6Config *config)
169 {
170         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
171
172         _nm_object_ensure_inited (NM_OBJECT (config));
173         return NM_IP6_CONFIG_GET_PRIVATE (config)->gateway;
174 }
175
176 /**
177  * nm_ip6_config_get_addresses:
178  * @config: a #NMIP6Config
179  *
180  * Gets the IP6 addresses (containing the address, prefix, and gateway).
181  *
182  * Returns: (element-type NMIP6Address): the #GSList containing
183  * #NMIP6Address<!-- -->es. This is the internal copy used by the configuration
184  * and must not be modified.
185  **/
186 const GSList *
187 nm_ip6_config_get_addresses (NMIP6Config *config)
188 {
189         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
190
191         _nm_object_ensure_inited (NM_OBJECT (config));
192         return NM_IP6_CONFIG_GET_PRIVATE (config)->addresses;
193 }
194
195 /**
196  * nm_ip6_config_get_num_nameservers:
197  * @config: a #NMIP6Config
198  *
199  * Gets the number of the domain name servers in the configuration.
200  *
201  * Returns: the number of domain name servers
202  *
203  * Since: 0.9.10
204  **/
205 guint32
206 nm_ip6_config_get_num_nameservers (NMIP6Config *config)
207 {
208         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), 0);
209
210         _nm_object_ensure_inited (NM_OBJECT (config));
211         return g_slist_length (NM_IP6_CONFIG_GET_PRIVATE (config)->nameservers);
212 }
213
214 /**
215  * nm_ip6_config_get_nameserver:
216  * @config: a #NMIP6Config
217  * @idx: index of the nameserver to return
218  *
219  * Gets the domain name server at index @idx in the configuration.
220  *
221  * Returns: (array fixed-size=16) (element-type guint8) (transfer none):
222  *          the IPv6 address of domain name server at index @iidx
223  *
224  * Since: 0.9.10
225  **/
226 const struct in6_addr *
227 nm_ip6_config_get_nameserver (NMIP6Config *config, guint32 idx)
228 {
229         NMIP6ConfigPrivate *priv;
230         GSList *item;
231         guint32 i = 0;
232
233         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
234
235         _nm_object_ensure_inited (NM_OBJECT (config));
236         priv = NM_IP6_CONFIG_GET_PRIVATE (config);
237
238         for (item = priv->nameservers; item && i < idx; i++)
239                 item = item->next;
240
241         g_return_val_if_fail (item, NULL);
242         return item ? (const struct in6_addr *) item->data : NULL;
243 }
244
245 /* FIXME: like in libnm_util, in6_addr is not introspectable, so skipping here */
246 /**
247  * nm_ip6_config_get_nameservers: (skip)
248  * @config: a #NMIP6Config
249  *
250  * Gets the domain name servers (DNS).
251  *
252  * Returns: a #GSList containing elements of type 'struct in6_addr' which
253  * contain the addresses of nameservers of the configuration.  This is the
254  * internal copy used by the configuration and must not be modified.
255  **/
256 const GSList *
257 nm_ip6_config_get_nameservers (NMIP6Config *config)
258 {
259         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
260
261         _nm_object_ensure_inited (NM_OBJECT (config));
262         return NM_IP6_CONFIG_GET_PRIVATE (config)->nameservers;
263 }
264
265 /**
266  * nm_ip6_config_get_domains:
267  * @config: a #NMIP6Config
268  *
269  * Gets the domain names.
270  *
271  * Returns: (element-type utf8): the #GPtrArray containing domains as strings.
272  * This is the internal copy used by the configuration, and must not be modified.
273  **/
274 const GPtrArray *
275 nm_ip6_config_get_domains (NMIP6Config *config)
276 {
277         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
278
279         _nm_object_ensure_inited (NM_OBJECT (config));
280         return handle_ptr_array_return (NM_IP6_CONFIG_GET_PRIVATE (config)->domains);
281 }
282
283 /**
284  * nm_ip6_config_get_searches:
285  * @config: a #NMIP6Config
286  *
287  * Gets the dns searches.
288  *
289  * Returns: (element-type utf8): the #GPtrArray containing dns searches as strings.
290  * This is the internal copy used by the configuration, and must not be modified.
291  *
292  * Since: 0.9.10
293  **/
294 const GPtrArray *
295 nm_ip6_config_get_searches (NMIP6Config *config)
296 {
297         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
298
299         _nm_object_ensure_inited (NM_OBJECT (config));
300         return handle_ptr_array_return (NM_IP6_CONFIG_GET_PRIVATE (config)->searches);
301 }
302
303 /**
304  * nm_ip6_config_get_routes:
305  * @config: a #NMIP6Config
306  *
307  * Gets the routes.
308  *
309  * Returns: (element-type NMIP6Route): the #GSList containing
310  * #NMIP6Routes. This is the internal copy used by the configuration,
311  * and must not be modified.
312  **/
313 const GSList *
314 nm_ip6_config_get_routes (NMIP6Config *config)
315 {
316         g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL);
317
318         _nm_object_ensure_inited (NM_OBJECT (config));
319         return NM_IP6_CONFIG_GET_PRIVATE (config)->routes;
320 }
321
322 static void
323 constructed (GObject *object)
324 {
325         NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
326
327         G_OBJECT_CLASS (nm_ip6_config_parent_class)->constructed (object);
328
329         priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_IP6_CONFIG);
330         register_properties (NM_IP6_CONFIG (object));
331 }
332
333 static void
334 finalize (GObject *object)
335 {
336         NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (object);
337
338         g_free (priv->gateway);
339
340         g_slist_free_full (priv->addresses, (GDestroyNotify) nm_ip6_address_unref);
341         g_slist_free_full (priv->routes, (GDestroyNotify) nm_ip6_route_unref);
342         g_slist_free_full (priv->nameservers, g_free);
343
344         if (priv->domains) {
345                 g_ptr_array_set_free_func (priv->domains, g_free);
346                 g_ptr_array_free (priv->domains, TRUE);
347         }
348
349         if (priv->searches) {
350                 g_ptr_array_set_free_func (priv->searches, g_free);
351                 g_ptr_array_free (priv->searches, TRUE);
352         }
353
354         g_object_unref (priv->proxy);
355
356         G_OBJECT_CLASS (nm_ip6_config_parent_class)->finalize (object);
357 }
358
359 static void
360 get_property (GObject *object,
361               guint prop_id,
362               GValue *value,
363               GParamSpec *pspec)
364 {
365         NMIP6Config *self = NM_IP6_CONFIG (object);
366         NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self);
367
368         _nm_object_ensure_inited (NM_OBJECT (object));
369
370         switch (prop_id) {
371         case PROP_GATEWAY:
372                 g_value_set_string (value, nm_ip6_config_get_gateway (self));
373                 break;
374         case PROP_ADDRESSES:
375                 nm_utils_ip6_addresses_to_gvalue (priv->addresses, value);
376                 break;
377         case PROP_ROUTES:
378                 nm_utils_ip6_routes_to_gvalue (priv->routes, value);
379                 break;
380         case PROP_NAMESERVERS:
381                 g_value_set_boxed (value, nm_ip6_config_get_nameservers (self));
382                 break;
383         case PROP_DOMAINS:
384                 g_value_set_boxed (value, nm_ip6_config_get_domains (self));
385                 break;
386         case PROP_SEARCHES:
387                 g_value_set_boxed (value, nm_ip6_config_get_searches (self));
388                 break;
389         default:
390                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
391                 break;
392         }
393 }
394
395 static void
396 nm_ip6_config_init (NMIP6Config *config)
397 {
398 }
399
400 static void
401 nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
402 {
403         GObjectClass *object_class = G_OBJECT_CLASS (config_class);
404
405         g_type_class_add_private (config_class, sizeof (NMIP6ConfigPrivate));
406
407         /* virtual methods */
408         object_class->constructed = constructed;
409         object_class->get_property = get_property;
410         object_class->finalize = finalize;
411
412         /* properties */
413
414         /**
415          * NMIP6Config:gateway:
416          *
417          * The IPv6 gateway as string
418          *
419          * Since: 0.9.10
420          **/
421         g_object_class_install_property
422             (object_class, PROP_GATEWAY,
423              g_param_spec_string (NM_IP6_CONFIG_GATEWAY, "", "",
424                                   NULL,
425                                   G_PARAM_READABLE |
426                                   G_PARAM_STATIC_STRINGS));
427
428         /**
429          * NMIP6Config:addresses:
430          *
431          * The #GPtrArray containing the IPv6 addresses;  use
432          * nm_utils_ip6_addresses_from_gvalue() to return a #GSList of
433          * #NMSettingIP6Address objects that is more usable than the raw data.
434          **/
435         g_object_class_install_property
436             (object_class, PROP_ADDRESSES,
437              g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES, "", "",
438                                  NM_TYPE_IP6_ADDRESS_OBJECT_ARRAY,
439                                  G_PARAM_READABLE |
440                                  G_PARAM_STATIC_STRINGS));
441
442         /**
443          * NMIP6Config:routes:
444          *
445          * The #GPtrArray containing the IPv6 routes;  use
446          * nm_utils_ip6_routes_from_gvalue() to return a #GSList of
447          * #NMSettingIP6Address objects that is more usable than the raw data.
448          **/
449         g_object_class_install_property
450             (object_class, PROP_ROUTES,
451              g_param_spec_boxed (NM_IP6_CONFIG_ROUTES, "", "",
452                                  NM_TYPE_IP6_ROUTE_OBJECT_ARRAY,
453                                  G_PARAM_READABLE |
454                                  G_PARAM_STATIC_STRINGS));
455
456         /**
457          * NMIP6Config:nameservers:
458          *
459          * The #GPtrArray containing elements of type 'struct ip6_addr' which
460          * contain the addresses of nameservers of the configuration.
461          **/
462         g_object_class_install_property
463             (object_class, PROP_NAMESERVERS,
464              g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS, "", "",
465                                  NM_TYPE_IP6_ADDRESS_ARRAY,
466                                  G_PARAM_READABLE |
467                                  G_PARAM_STATIC_STRINGS));
468
469         /**
470          * NMIP6Config:domains:
471          *
472          * The #GPtrArray containing domain strings of the configuration.
473          **/
474         g_object_class_install_property
475             (object_class, PROP_DOMAINS,
476              g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS, "", "",
477                                  NM_TYPE_STRING_ARRAY,
478                                  G_PARAM_READABLE |
479                                  G_PARAM_STATIC_STRINGS));
480
481         /**
482          * NMIP6Config:searches:
483          *
484          * The #GPtrArray containing dns search strings of the configuration.
485          *
486          * Since: 0.9.10
487          **/
488         g_object_class_install_property
489             (object_class, PROP_SEARCHES,
490              g_param_spec_boxed (NM_IP6_CONFIG_SEARCHES, "", "",
491                                  NM_TYPE_STRING_ARRAY,
492                                  G_PARAM_READABLE |
493                                  G_PARAM_STATIC_STRINGS));
494
495 }