libnm-core: allow strict and relaxed error behavior for _nm_setting_new_from_dbus()
[NetworkManager.git] / libnm-core / nm-setting-connection.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 - 2013 Red Hat, Inc.
20  * Copyright 2007 - 2008 Novell, Inc.
21  */
22
23 #include "nm-default.h"
24
25 #include "nm-setting-connection.h"
26
27 #include <string.h>
28
29 #include "nm-utils.h"
30 #include "nm-utils-private.h"
31 #include "nm-core-enum-types.h"
32 #include "nm-connection-private.h"
33 #include "nm-setting-bond.h"
34 #include "nm-setting-bridge.h"
35 #include "nm-setting-team.h"
36 #include "nm-setting-vlan.h"
37
38 /**
39  * SECTION:nm-setting-connection
40  * @short_description: Describes general connection properties
41  *
42  * The #NMSettingConnection object is a #NMSetting subclass that describes
43  * properties that apply to all #NMConnection objects, regardless of what type
44  * of network connection they describe.  Each #NMConnection object must contain
45  * a #NMSettingConnection setting.
46  **/
47
48 G_DEFINE_TYPE_WITH_CODE (NMSettingConnection, nm_setting_connection, NM_TYPE_SETTING,
49                          _nm_register_setting (CONNECTION, 0))
50 NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_CONNECTION)
51
52 #define NM_SETTING_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_CONNECTION, NMSettingConnectionPrivate))
53
54 typedef enum {
55         PERM_TYPE_USER = 0,
56 } PermType;
57
58 typedef struct {
59         guint8 ptype;
60         char *item;
61 } Permission;
62
63 typedef struct {
64         char *id;
65         char *uuid;
66         char *interface_name;
67         char *type;
68         char *master;
69         char *slave_type;
70         NMSettingConnectionAutoconnectSlaves autoconnect_slaves;
71         GSList *permissions; /* list of Permission structs */
72         gboolean autoconnect;
73         gint autoconnect_priority;
74         guint64 timestamp;
75         gboolean read_only;
76         char *zone;
77         GSList *secondaries; /* secondary connections to activate with the base connection */
78         guint gateway_ping_timeout;
79         NMMetered metered;
80         NMSettingConnectionLldp lldp;
81 } NMSettingConnectionPrivate;
82
83 enum {
84         PROP_0,
85         PROP_ID,
86         PROP_UUID,
87         PROP_INTERFACE_NAME,
88         PROP_TYPE,
89         PROP_PERMISSIONS,
90         PROP_AUTOCONNECT,
91         PROP_AUTOCONNECT_PRIORITY,
92         PROP_TIMESTAMP,
93         PROP_READ_ONLY,
94         PROP_ZONE,
95         PROP_MASTER,
96         PROP_SLAVE_TYPE,
97         PROP_AUTOCONNECT_SLAVES,
98         PROP_SECONDARIES,
99         PROP_GATEWAY_PING_TIMEOUT,
100         PROP_METERED,
101         PROP_LLDP,
102
103         LAST_PROP
104 };
105
106 /***********************************************************************/
107
108 #define PERM_USER_PREFIX  "user:"
109
110 static Permission *
111 permission_new_from_str (const char *str)
112 {
113         Permission *p;
114         const char *last_colon;
115         size_t ulen = 0, i;
116
117         g_return_val_if_fail (strncmp (str, PERM_USER_PREFIX, strlen (PERM_USER_PREFIX)) == 0, NULL);
118         str += strlen (PERM_USER_PREFIX);
119
120         last_colon = strrchr (str, ':');
121         if (last_colon) {
122                 /* Ensure that somebody didn't pass "user::" */
123                 g_return_val_if_fail (last_colon > str, NULL);
124
125                 /* Reject :[detail] for now */
126                 g_return_val_if_fail (*(last_colon + 1) == '\0', NULL);
127
128                 /* Make sure we don't include detail in the username */
129                 ulen = last_colon - str;
130         } else
131                 ulen = strlen (str);
132
133         /* Sanity check the length of the username */
134         g_return_val_if_fail (ulen < 100, NULL);
135
136         /* Make sure there's no ':' in the username */
137         for (i = 0; i < ulen; i++)
138                 g_return_val_if_fail (str[i] != ':', NULL);
139
140         /* And the username must be valid UTF-8 */
141         g_return_val_if_fail (g_utf8_validate (str, -1, NULL) == TRUE, NULL);
142
143         /* Yay, valid... create the new permission */
144         p = g_slice_new0 (Permission);
145         p->ptype = PERM_TYPE_USER;
146         if (last_colon) {
147                 p->item = g_malloc (ulen + 1);
148                 memcpy (p->item, str, ulen);
149                 p->item[ulen] = '\0';
150         } else
151                 p->item = g_strdup (str);
152
153         return p;
154 }
155
156 static Permission *
157 permission_new (const char *uname)
158 {
159         Permission *p;
160
161         g_return_val_if_fail (uname, NULL);
162         g_return_val_if_fail (uname[0] != '\0', NULL);
163         g_return_val_if_fail (strchr (uname, ':') == NULL, NULL);
164         g_return_val_if_fail (g_utf8_validate (uname, -1, NULL) == TRUE, NULL);
165
166         /* Yay, valid... create the new permission */
167         p = g_slice_new0 (Permission);
168         p->ptype = PERM_TYPE_USER;
169         p->item = g_strdup (uname);
170         return p;
171 }
172
173 static char *
174 permission_to_string (Permission *p)
175 {
176         return g_strdup_printf (PERM_USER_PREFIX "%s:", p->item);
177 }
178
179 static void
180 permission_free (Permission *p)
181 {
182         g_free (p->item);
183         memset (p, 0, sizeof (*p));
184         g_slice_free (Permission, p);
185 }
186
187 /***********************************************************************/
188
189 /**
190  * nm_setting_connection_new:
191  *
192  * Creates a new #NMSettingConnection object with default values.
193  *
194  * Returns: the new empty #NMSettingConnection object
195  **/
196 NMSetting *nm_setting_connection_new (void)
197 {
198         return (NMSetting *) g_object_new (NM_TYPE_SETTING_CONNECTION, NULL);
199 }
200
201 /**
202  * nm_setting_connection_get_id:
203  * @setting: the #NMSettingConnection
204  *
205  * Returns the #NMSettingConnection:id property of the connection.
206  *
207  * Returns: the connection ID
208  **/
209 const char *
210 nm_setting_connection_get_id (NMSettingConnection *setting)
211 {
212         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
213
214         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->id;
215 }
216
217 /**
218  * nm_setting_connection_get_uuid:
219  * @setting: the #NMSettingConnection
220  *
221  * Returns the #NMSettingConnection:uuid property of the connection.
222  *
223  * Returns: the connection UUID
224  **/
225 const char *
226 nm_setting_connection_get_uuid (NMSettingConnection *setting)
227 {
228         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
229
230         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->uuid;
231 }
232
233 /**
234  * nm_setting_connection_get_interface_name:
235  * @setting: the #NMSettingConnection
236  *
237  * Returns the #NMSettingConnection:interface-name property of the connection.
238  *
239  * Returns: the connection's interface name
240  **/
241 const char *
242 nm_setting_connection_get_interface_name (NMSettingConnection *setting)
243 {
244         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
245
246         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->interface_name;
247 }
248
249 /**
250  * nm_setting_connection_get_connection_type:
251  * @setting: the #NMSettingConnection
252  *
253  * Returns the #NMSettingConnection:type property of the connection.
254  *
255  * Returns: the connection type
256  **/
257 const char *
258 nm_setting_connection_get_connection_type (NMSettingConnection *setting)
259 {
260         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
261
262         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->type;
263 }
264
265
266 /**
267  * nm_setting_connection_get_num_permissions:
268  * @setting: the #NMSettingConnection
269  *
270  * Returns the number of entires in the #NMSettingConnection:permissions
271  * property of this setting.
272  *
273  * Returns: the number of permissions entires
274  */
275 guint32
276 nm_setting_connection_get_num_permissions (NMSettingConnection *setting)
277 {
278         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0);
279
280         return g_slist_length (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->permissions);
281 }
282
283 /**
284  * nm_setting_connection_get_permission:
285  * @setting: the #NMSettingConnection
286  * @idx: the zero-based index of the permissions entry
287  * @out_ptype: on return, the permission type (at this time, always "user")
288  * @out_pitem: on return, the permission item (formatted accoring to @ptype, see
289  * #NMSettingConnection:permissions for more detail
290  * @out_detail: on return, the permission detail (at this time, always %NULL)
291  *
292  * Retrieve one of the entries of the #NMSettingConnection:permissions property
293  * of this setting.
294  *
295  * Returns: %TRUE if a permission was returned, %FALSE if @idx was invalid
296  */
297 gboolean
298 nm_setting_connection_get_permission (NMSettingConnection *setting,
299                                       guint32 idx,
300                                       const char **out_ptype,
301                                       const char **out_pitem,
302                                       const char **out_detail)
303 {
304         NMSettingConnectionPrivate *priv;
305         Permission *p;
306
307         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
308
309         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
310
311         g_return_val_if_fail (idx < g_slist_length (priv->permissions), FALSE);
312
313         p = g_slist_nth_data (priv->permissions, idx);
314         if (out_ptype)
315                 *out_ptype = "user";
316         if (out_pitem)
317                 *out_pitem = p->item;
318         if (out_detail)
319                 *out_detail = NULL;
320
321         return TRUE;
322 }
323
324 /**
325  * nm_setting_connection_permissions_user_allowed:
326  * @setting: the #NMSettingConnection
327  * @uname: the user name to check permissions for
328  *
329  * Checks whether the given username is allowed to view/access this connection.
330  *
331  * Returns: %TRUE if the requested user is allowed to view this connection,
332  * %FALSE if the given user is not allowed to view this connection
333  */
334 gboolean
335 nm_setting_connection_permissions_user_allowed (NMSettingConnection *setting,
336                                                 const char *uname)
337 {
338         NMSettingConnectionPrivate *priv;
339         GSList *iter;
340
341         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
342         g_return_val_if_fail (uname != NULL, FALSE);
343         g_return_val_if_fail (*uname != '\0', FALSE);
344
345         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
346
347         /* If no permissions, visible to all */
348         if (priv->permissions == NULL)
349                 return TRUE;
350
351         /* Find the username in the permissions list */
352         for (iter = priv->permissions; iter; iter = g_slist_next (iter)) {
353                 Permission *p = iter->data;
354
355                 if (strcmp (uname, p->item) == 0)
356                         return TRUE;
357         }
358
359         return FALSE;
360 }
361
362 /**
363  * nm_setting_connection_add_permission:
364  * @setting: the #NMSettingConnection
365  * @ptype: the permission type; at this time only "user" is supported
366  * @pitem: the permission item formatted as required for @ptype
367  * @detail: (allow-none): unused at this time; must be %NULL
368  *
369  * Adds a permission to the connection's permission list.  At this time, only
370  * the "user" permission type is supported, and @pitem must be a username. See
371  * #NMSettingConnection:permissions: for more details.
372  *
373  * Returns: %TRUE if the permission was unique and was successfully added to the
374  * list, %FALSE if @ptype or @pitem was invalid or it the permission was already
375  * present in the list
376  */
377 gboolean
378 nm_setting_connection_add_permission (NMSettingConnection *setting,
379                                       const char *ptype,
380                                       const char *pitem,
381                                       const char *detail)
382 {
383         NMSettingConnectionPrivate *priv;
384         Permission *p;
385         GSList *iter;
386
387         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
388         g_return_val_if_fail (ptype, FALSE);
389         g_return_val_if_fail (strlen (ptype) > 0, FALSE);
390         g_return_val_if_fail (detail == NULL, FALSE);
391
392         /* Only "user" for now... */
393         g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE);
394
395         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
396
397         /* No dupes */
398         for (iter = priv->permissions; iter; iter = g_slist_next (iter)) {
399                 p = iter->data;
400                 if (strcmp (pitem, p->item) == 0)
401                         return FALSE;
402         }
403
404         p = permission_new (pitem);
405         g_return_val_if_fail (p != NULL, FALSE);
406         priv->permissions = g_slist_append (priv->permissions, p);
407         g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS);
408
409         return TRUE;
410 }
411
412 /**
413  * nm_setting_connection_remove_permission:
414  * @setting: the #NMSettingConnection
415  * @idx: the zero-based index of the permission to remove
416  *
417  * Removes the permission at index @idx from the connection.
418  */
419 void
420 nm_setting_connection_remove_permission (NMSettingConnection *setting,
421                                          guint32 idx)
422 {
423         NMSettingConnectionPrivate *priv;
424         GSList *iter;
425
426         g_return_if_fail (NM_IS_SETTING_CONNECTION (setting));
427
428         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
429         iter = g_slist_nth (priv->permissions, idx);
430         g_return_if_fail (iter != NULL);
431
432         permission_free ((Permission *) iter->data);
433         priv->permissions = g_slist_delete_link (priv->permissions, iter);
434         g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS);
435 }
436
437 /**
438  * nm_setting_connection_remove_permission_by_value:
439  * @setting: the #NMSettingConnection
440  * @ptype: the permission type; at this time only "user" is supported
441  * @pitem: the permission item formatted as required for @ptype
442  * @detail: (allow-none): unused at this time; must be %NULL
443  *
444  * Removes the permission from the connection.
445  * At this time, only the "user" permission type is supported, and @pitem must
446  * be a username. See #NMSettingConnection:permissions: for more details.
447  *
448  * Returns: %TRUE if the permission was found and removed; %FALSE if it was not.
449  */
450 gboolean
451 nm_setting_connection_remove_permission_by_value (NMSettingConnection *setting,
452                                                   const char *ptype,
453                                                   const char *pitem,
454                                                   const char *detail)
455 {
456         NMSettingConnectionPrivate *priv;
457         Permission *p;
458         GSList *iter;
459
460         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
461         g_return_val_if_fail (ptype, FALSE);
462         g_return_val_if_fail (strlen (ptype) > 0, FALSE);
463         g_return_val_if_fail (detail == NULL, FALSE);
464
465         /* Only "user" for now... */
466         g_return_val_if_fail (strcmp (ptype, "user") == 0, FALSE);
467
468         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
469         for (iter = priv->permissions; iter; iter = g_slist_next (iter)) {
470                 p = iter->data;
471                 if (strcmp (pitem, p->item) == 0) {
472                         permission_free ((Permission *) iter->data);
473                         priv->permissions = g_slist_delete_link (priv->permissions, iter);
474                         g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_PERMISSIONS);
475                         return TRUE;
476                 }
477         }
478         return FALSE;
479 }
480
481 /**
482  * nm_setting_connection_get_autoconnect:
483  * @setting: the #NMSettingConnection
484  *
485  * Returns the #NMSettingConnection:autoconnect property of the connection.
486  *
487  * Returns: the connection's autoconnect behavior
488  **/
489 gboolean
490 nm_setting_connection_get_autoconnect (NMSettingConnection *setting)
491 {
492         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
493
494         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect;
495 }
496
497 /**
498  * nm_setting_connection_get_autoconnect_priority:
499  * @setting: the #NMSettingConnection
500  *
501  * Returns the #NMSettingConnection:autoconnect-priority property of the connection.
502  * The higher number, the higher priority.
503  *
504  * Returns: the connection's autoconnect priority
505  **/
506 gint
507 nm_setting_connection_get_autoconnect_priority (NMSettingConnection *setting)
508 {
509         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0);
510
511         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect_priority;
512 }
513
514 /**
515  * nm_setting_connection_get_timestamp:
516  * @setting: the #NMSettingConnection
517  *
518  * Returns the #NMSettingConnection:timestamp property of the connection.
519  *
520  * Returns: the connection's timestamp
521  **/
522 guint64
523 nm_setting_connection_get_timestamp (NMSettingConnection *setting)
524 {
525         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0);
526
527         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->timestamp;
528 }
529
530 /**
531  * nm_setting_connection_get_read_only:
532  * @setting: the #NMSettingConnection
533  *
534  * Returns the #NMSettingConnection:read-only property of the connection.
535  *
536  * Returns: %TRUE if the connection is read-only, %FALSE if it is not
537  **/
538 gboolean
539 nm_setting_connection_get_read_only (NMSettingConnection *setting)
540 {
541         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), TRUE);
542
543         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->read_only;
544 }
545
546 /**
547  * nm_setting_connection_get_zone:
548  * @setting: the #NMSettingConnection
549  *
550  * Returns the #NMSettingConnection:zone property of the connection.
551  *
552  * Returns: the trust level of a connection
553  **/
554 const char *
555 nm_setting_connection_get_zone (NMSettingConnection *setting)
556 {
557         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
558
559         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->zone;
560 }
561
562 /**
563  * nm_setting_connection_get_master:
564  * @setting: the #NMSettingConnection
565  *
566  * Returns the #NMSettingConnection:master property of the connection.
567  *
568  * Returns: interface name of the master device or UUID of the master
569  * connection.
570  */
571 const char *
572 nm_setting_connection_get_master (NMSettingConnection *setting)
573 {
574         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
575
576         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->master;
577 }
578
579 /**
580  * nm_setting_connection_get_slave_type:
581  * @setting: the #NMSettingConnection
582  *
583  * Returns the #NMSettingConnection:slave-type property of the connection.
584  *
585  * Returns: the type of slave this connection is, if any
586  */
587 const char *
588 nm_setting_connection_get_slave_type (NMSettingConnection *setting)
589 {
590         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
591
592         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->slave_type;
593 }
594
595 /**
596  * nm_setting_connection_is_slave_type:
597  * @setting: the #NMSettingConnection
598  * @type: the setting name (ie #NM_SETTING_BOND_SETTING_NAME) to be matched
599  * against @setting's slave type
600  *
601  * Returns: %TRUE if connection is of the given slave @type
602  */
603 gboolean
604 nm_setting_connection_is_slave_type (NMSettingConnection *setting,
605                                      const char *type)
606 {
607         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
608
609         return !g_strcmp0 (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->slave_type, type);
610 }
611
612 /**
613  * nm_setting_connection_get_autoconnect_slaves:
614  * @setting: the #NMSettingConnection
615  *
616  * Returns the #NMSettingConnection:autoconnect-slaves property of the connection.
617  *
618  * Returns: whether slaves of the connection should be activated together
619  *          with the connection.
620  *
621  * Since: 1.2
622  **/
623 NMSettingConnectionAutoconnectSlaves
624 nm_setting_connection_get_autoconnect_slaves (NMSettingConnection *setting)
625 {
626         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT);
627
628         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->autoconnect_slaves;
629 }
630 NM_BACKPORT_SYMBOL (libnm_1_0_4, NMSettingConnectionAutoconnectSlaves, nm_setting_connection_get_autoconnect_slaves, (NMSettingConnection *setting), (setting));
631
632 NM_BACKPORT_SYMBOL (libnm_1_0_4, GType, nm_setting_connection_autoconnect_slaves_get_type, (void), ());
633
634 /**
635  * nm_setting_connection_get_num_secondaries:
636  * @setting: the #NMSettingConnection
637  *
638  * Returns: the number of configured secondary connection UUIDs
639  **/
640 guint32
641 nm_setting_connection_get_num_secondaries (NMSettingConnection *setting)
642 {
643         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0);
644
645         return g_slist_length (NM_SETTING_CONNECTION_GET_PRIVATE (setting)->secondaries);
646 }
647
648 /**
649  * nm_setting_connection_get_secondary:
650  * @setting: the #NMSettingConnection
651  * @idx: the zero-based index of the secondary connection UUID entry
652  *
653  * Returns: the secondary connection UUID at index @idx
654  **/
655 const char *
656 nm_setting_connection_get_secondary (NMSettingConnection *setting, guint32 idx)
657 {
658         NMSettingConnectionPrivate *priv;
659
660         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NULL);
661
662         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
663         g_return_val_if_fail (idx <= g_slist_length (priv->secondaries), NULL);
664
665         return (const char *) g_slist_nth_data (priv->secondaries, idx);
666 }
667
668 /**
669  * nm_setting_connection_add_secondary:
670  * @setting: the #NMSettingConnection
671  * @sec_uuid: the secondary connection UUID to add
672  *
673  * Adds a new secondary connetion UUID to the setting.
674  *
675  * Returns: %TRUE if the secondary connection UUID was added; %FALSE if the UUID
676  * was already present
677  **/
678 gboolean
679 nm_setting_connection_add_secondary (NMSettingConnection *setting,
680                                      const char *sec_uuid)
681 {
682         NMSettingConnectionPrivate *priv;
683         GSList *iter;
684
685         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
686         g_return_val_if_fail (sec_uuid != NULL, FALSE);
687         g_return_val_if_fail (sec_uuid[0] != '\0', FALSE);
688
689         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
690         for (iter = priv->secondaries; iter; iter = g_slist_next (iter)) {
691                 if (!strcmp (sec_uuid, (char *) iter->data))
692                         return FALSE;
693         }
694
695         priv->secondaries = g_slist_append (priv->secondaries, g_strdup (sec_uuid));
696         g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES);
697         return TRUE;
698 }
699
700 /**
701  * nm_setting_connection_remove_secondary:
702  * @setting: the #NMSettingConnection
703  * @idx: index number of the secondary connection UUID
704  *
705  * Removes the secondary coonnection UUID at index @idx.
706  **/
707 void
708 nm_setting_connection_remove_secondary (NMSettingConnection *setting, guint32 idx)
709 {
710         NMSettingConnectionPrivate *priv;
711         GSList *elt;
712
713         g_return_if_fail (NM_IS_SETTING_CONNECTION (setting));
714
715         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
716         elt = g_slist_nth (priv->secondaries, idx);
717         g_return_if_fail (elt != NULL);
718
719         g_free (elt->data);
720         priv->secondaries = g_slist_delete_link (priv->secondaries, elt);
721         g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES);
722 }
723
724 /**
725  * nm_setting_connection_remove_secondary_by_value:
726  * @setting: the #NMSettingConnection
727  * @sec_uuid: the secondary connection UUID to remove
728  *
729  * Removes the secondary coonnection UUID @sec_uuid.
730  *
731  * Returns: %TRUE if the secondary connection UUID was found and removed; %FALSE if it was not.
732  **/
733 gboolean
734 nm_setting_connection_remove_secondary_by_value (NMSettingConnection *setting,
735                                                  const char *sec_uuid)
736 {
737         NMSettingConnectionPrivate *priv;
738         GSList *iter;
739
740         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), FALSE);
741         g_return_val_if_fail (sec_uuid != NULL, FALSE);
742         g_return_val_if_fail (sec_uuid[0] != '\0', FALSE);
743
744         priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
745         for (iter = priv->secondaries; iter; iter = g_slist_next (iter)) {
746                 if (!strcmp (sec_uuid, (char *) iter->data)) {
747                         priv->secondaries = g_slist_delete_link (priv->secondaries, iter);
748                         g_object_notify (G_OBJECT (setting), NM_SETTING_CONNECTION_SECONDARIES);
749                         return TRUE;
750                 }
751         }
752         return FALSE;
753 }
754
755 /**
756  * nm_setting_connection_get_gateway_ping_timeout:
757  * @setting: the #NMSettingConnection
758  *
759  * Returns: the value contained in the #NMSettingConnection:gateway-ping-timeout
760  * property.
761  **/
762 guint32
763 nm_setting_connection_get_gateway_ping_timeout (NMSettingConnection *setting)
764 {
765         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), 0);
766
767         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->gateway_ping_timeout;
768 }
769
770 /**
771  * nm_setting_connection_get_metered:
772  * @setting: the #NMSettingConnection
773  *
774  * Returns: the #NMSettingConnection:metered property of the setting.
775  *
776  * Since: 1.2
777  **/
778 NMMetered
779 nm_setting_connection_get_metered (NMSettingConnection *setting)
780 {
781         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting),
782                               NM_METERED_UNKNOWN);
783
784         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->metered;
785 }
786
787 NM_BACKPORT_SYMBOL (libnm_1_0_6, NMMetered, nm_setting_connection_get_metered, (NMSettingConnection *setting), (setting));
788
789 NM_BACKPORT_SYMBOL (libnm_1_0_6, GType, nm_metered_get_type, (void), ());
790
791 /**
792  * nm_setting_connection_get_lldp:
793  * @setting: the #NMSettingConnection
794  *
795  * Returns the #NMSettingConnection:lldp property of the connection.
796  *
797  * Returns: a %NMSettingConnectionLldp which indicates whether LLDP must be
798  * enabled for the connection.
799  *
800  * Since: 1.2
801  **/
802 NMSettingConnectionLldp
803 nm_setting_connection_get_lldp (NMSettingConnection *setting)
804 {
805         g_return_val_if_fail (NM_IS_SETTING_CONNECTION (setting), NM_SETTING_CONNECTION_LLDP_DEFAULT);
806
807         return NM_SETTING_CONNECTION_GET_PRIVATE (setting)->lldp;
808 }
809
810 static void
811 _set_error_missing_base_setting (GError **error, const char *type)
812 {
813         g_set_error (error,
814                      NM_CONNECTION_ERROR,
815                      NM_CONNECTION_ERROR_MISSING_SETTING,
816                      _("setting required for connection of type '%s'"),
817                      type);
818         g_prefix_error (error, "%s: ", type);
819 }
820
821 static gboolean
822 verify (NMSetting *setting, NMConnection *connection, GError **error)
823 {
824         NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
825         gboolean is_slave;
826         const char *slave_setting_type = NULL;
827         NMSetting *normerr_base_type = NULL;
828         const char *normerr_slave_setting_type = NULL;
829         const char *normerr_missing_slave_type = NULL;
830         const char *normerr_missing_slave_type_port = NULL;
831         gboolean normerr_base_setting = FALSE;
832
833         if (!priv->id) {
834                 g_set_error_literal (error,
835                                      NM_CONNECTION_ERROR,
836                                      NM_CONNECTION_ERROR_MISSING_PROPERTY,
837                                      _("property is missing"));
838                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID);
839                 return FALSE;
840         } else if (!priv->id[0]) {
841                 g_set_error_literal (error,
842                                      NM_CONNECTION_ERROR,
843                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
844                                      _("property is empty"));
845                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_ID);
846                 return FALSE;
847         }
848
849         if (priv->uuid && !nm_utils_is_uuid (priv->uuid)) {
850                 g_set_error (error,
851                              NM_CONNECTION_ERROR,
852                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
853                              _("'%s' is not a valid UUID"),
854                              priv->uuid);
855                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_UUID);
856                 return FALSE;
857         }
858
859         if (priv->interface_name) {
860                 if (!nm_utils_iface_valid_name (priv->interface_name)) {
861                         g_set_error (error,
862                                      NM_CONNECTION_ERROR,
863                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
864                                      _("'%s' is not a valid interface name"),
865                                      priv->interface_name);
866                         g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_INTERFACE_NAME);
867                         return FALSE;
868                 }
869         }
870
871         if (!priv->type) {
872                 if (!connection || !(normerr_base_type = _nm_connection_find_base_type_setting (connection))) {
873                         g_set_error_literal (error,
874                                              NM_CONNECTION_ERROR,
875                                              NM_CONNECTION_ERROR_MISSING_PROPERTY,
876                                              _("property is missing"));
877                         g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
878                         return FALSE;
879                 }
880         } else {
881                 GType base_type;
882
883                 if (!priv->type[0]) {
884                         g_set_error_literal (error,
885                                              NM_CONNECTION_ERROR,
886                                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
887                                              _("property is empty"));
888                         g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
889                         return FALSE;
890                 }
891
892                 base_type = nm_setting_lookup_type (priv->type);
893                 if (base_type == G_TYPE_INVALID || !_nm_setting_type_is_base_type (base_type)) {
894                         g_set_error (error,
895                                      NM_CONNECTION_ERROR,
896                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
897                                      _("connection type '%s' is not valid"),
898                                      priv->type);
899                         g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
900                         return FALSE;
901                 }
902
903                 /* Make sure the corresponding 'type' item is present */
904                 if (   connection
905                     && !nm_connection_get_setting_by_name (connection, priv->type)) {
906                         NMSetting *s_base;
907                         NMConnection *connection2;
908
909                         s_base = g_object_new (base_type, NULL);
910                         connection2 = nm_simple_connection_new_clone (connection);
911                         nm_connection_add_setting (connection2, s_base);
912
913                         normerr_base_setting = nm_setting_verify (s_base, connection2, NULL);
914
915                         g_object_unref (connection2);
916
917                         if (!normerr_base_setting) {
918                                 _set_error_missing_base_setting (error, priv->type);
919                                 return FALSE;
920                         }
921                 }
922         }
923
924         is_slave = FALSE;
925         if (priv->slave_type)
926                 is_slave = _nm_setting_slave_type_is_valid (priv->slave_type, &slave_setting_type);
927
928         if (priv->slave_type && !is_slave) {
929                 g_set_error (error,
930                              NM_CONNECTION_ERROR,
931                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
932                              _("Unknown slave type '%s'"), priv->slave_type);
933                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
934                 return FALSE;
935         }
936
937         if (is_slave) {
938                 if (!priv->master) {
939                         g_set_error (error,
940                                      NM_CONNECTION_ERROR,
941                                      NM_CONNECTION_ERROR_MISSING_PROPERTY,
942                                      _("Slave connections need a valid '%s' property"), NM_SETTING_CONNECTION_MASTER);
943                         g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_MASTER);
944                         return FALSE;
945                 }
946                 if (   slave_setting_type
947                     && connection
948                     && !nm_connection_get_setting_by_name (connection, slave_setting_type))
949                         normerr_slave_setting_type = slave_setting_type;
950         } else {
951                 if (priv->master) {
952                         const char *slave_type;
953                         NMSetting *s_port;
954
955                         if (   connection
956                             && (slave_type = _nm_connection_detect_slave_type (connection, &s_port))) {
957                                 normerr_missing_slave_type = slave_type;
958                                 normerr_missing_slave_type_port = nm_setting_get_name (s_port);
959                         } else {
960                                 g_set_error (error,
961                                              NM_CONNECTION_ERROR,
962                                              NM_CONNECTION_ERROR_MISSING_PROPERTY,
963                                              _("Cannot set '%s' without '%s'"),
964                                              NM_SETTING_CONNECTION_MASTER, NM_SETTING_CONNECTION_SLAVE_TYPE);
965                                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
966                                 return FALSE;
967                         }
968                 }
969         }
970
971         if (priv->metered != NM_METERED_UNKNOWN &&
972             priv->metered != NM_METERED_YES &&
973             priv->metered != NM_METERED_NO) {
974                 g_set_error (error,
975                              NM_CONNECTION_ERROR,
976                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
977                              _("metered value %d is not valid"), priv->metered);
978                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME,
979                                 NM_SETTING_CONNECTION_METERED);
980                 return FALSE;
981         }
982
983         /* *** errors above here should be always fatal, below NORMALIZABLE_ERROR *** */
984
985         if (!priv->uuid) {
986                 g_set_error_literal (error,
987                                      NM_CONNECTION_ERROR,
988                                      NM_CONNECTION_ERROR_MISSING_PROPERTY,
989                                      _("property is missing"));
990                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_UUID);
991                 return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
992         }
993
994         if (normerr_base_type) {
995                 g_set_error (error,
996                              NM_CONNECTION_ERROR,
997                              NM_CONNECTION_ERROR_MISSING_PROPERTY,
998                              _("property type should be set to '%s'"),
999                              nm_setting_get_name (normerr_base_type));
1000                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_TYPE);
1001                 return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
1002         }
1003
1004         if (normerr_base_setting) {
1005                 _set_error_missing_base_setting (error, priv->type);
1006                 return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
1007         }
1008
1009         if (normerr_slave_setting_type) {
1010                 g_set_error (error,
1011                              NM_CONNECTION_ERROR,
1012                              NM_CONNECTION_ERROR_MISSING_SETTING,
1013                              _("slave-type '%s' requires a '%s' setting in the connection"),
1014                              priv->slave_type, normerr_slave_setting_type);
1015                 g_prefix_error (error, "%s: ", normerr_slave_setting_type);
1016                 return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
1017         }
1018
1019         if (normerr_missing_slave_type) {
1020                 g_set_error (error,
1021                              NM_CONNECTION_ERROR,
1022                              NM_CONNECTION_ERROR_MISSING_PROPERTY,
1023                              _("Detect a slave connection with '%s' set and a port type '%s'. '%s' should be set to '%s'"),
1024                              NM_SETTING_CONNECTION_MASTER, normerr_missing_slave_type_port,
1025                              NM_SETTING_CONNECTION_SLAVE_TYPE, normerr_missing_slave_type);
1026                 g_prefix_error (error, "%s.%s: ", NM_SETTING_CONNECTION_SETTING_NAME, NM_SETTING_CONNECTION_SLAVE_TYPE);
1027                 return NM_SETTING_VERIFY_NORMALIZABLE_ERROR;
1028         }
1029
1030         return TRUE;
1031 }
1032
1033 static const char *
1034 find_virtual_interface_name (GVariant *connection_dict)
1035 {
1036         GVariant *setting_dict;
1037         const char *interface_name;
1038
1039         setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BOND_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
1040         if (!setting_dict)
1041                 setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_BRIDGE_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
1042         if (!setting_dict)
1043                 setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_TEAM_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
1044         if (!setting_dict)
1045                 setting_dict = g_variant_lookup_value (connection_dict, NM_SETTING_VLAN_SETTING_NAME, NM_VARIANT_TYPE_SETTING);
1046
1047         if (!setting_dict)
1048                 return NULL;
1049
1050         /* All of the deprecated virtual interface name properties were named "interface-name". */
1051         if (!g_variant_lookup (setting_dict, "interface-name", "&s", &interface_name))
1052                 interface_name = NULL;
1053
1054         g_variant_unref (setting_dict);
1055         return interface_name;
1056 }
1057
1058 static gboolean
1059 nm_setting_connection_set_interface_name (NMSetting *setting,
1060                                           GVariant *connection_dict,
1061                                           const char *property,
1062                                           GVariant *value,
1063                                           NMSettingParseFlags parse_flags,
1064                                           GError **error)
1065 {
1066         const char *interface_name;
1067
1068         /* For compatibility reasons, if there is an invalid virtual interface name,
1069          * we need to make verification fail, even if that virtual name would be
1070          * overridden by a valid connection.interface-name.
1071          */
1072         interface_name = find_virtual_interface_name (connection_dict);
1073         if (!interface_name || nm_utils_iface_valid_name (interface_name))
1074                 interface_name = g_variant_get_string (value, NULL);
1075
1076         g_object_set (G_OBJECT (setting),
1077                       NM_SETTING_CONNECTION_INTERFACE_NAME, interface_name,
1078                       NULL);
1079
1080         return TRUE;
1081 }
1082
1083 static gboolean
1084 nm_setting_connection_no_interface_name (NMSetting *setting,
1085                                          GVariant *connection_dict,
1086                                          const char *property,
1087                                          NMSettingParseFlags parse_flags,
1088                                          GError **error)
1089 {
1090         const char *virtual_interface_name;
1091
1092         virtual_interface_name = find_virtual_interface_name (connection_dict);
1093         g_object_set (G_OBJECT (setting),
1094                       NM_SETTING_CONNECTION_INTERFACE_NAME, virtual_interface_name,
1095                       NULL);
1096         return TRUE;
1097 }
1098
1099 static gboolean
1100 compare_property (NMSetting *setting,
1101                   NMSetting *other,
1102                   const GParamSpec *prop_spec,
1103                   NMSettingCompareFlags flags)
1104 {
1105         /* Handle ignore ID */
1106         if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_ID)
1107             && g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_ID) == 0)
1108                 return TRUE;
1109
1110         /* Handle ignore timestamp */
1111         if (   (flags & NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP)
1112             && g_strcmp0 (prop_spec->name, NM_SETTING_CONNECTION_TIMESTAMP) == 0)
1113                 return TRUE;
1114
1115         /* Otherwise chain up to parent to handle generic compare */
1116         return NM_SETTING_CLASS (nm_setting_connection_parent_class)->compare_property (setting, other, prop_spec, flags);
1117 }
1118
1119 static void
1120 nm_setting_connection_init (NMSettingConnection *setting)
1121 {
1122 }
1123
1124 static void
1125 finalize (GObject *object)
1126 {
1127         NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (object);
1128
1129         g_free (priv->id);
1130         g_free (priv->uuid);
1131         g_free (priv->interface_name);
1132         g_free (priv->type);
1133         g_free (priv->zone);
1134         g_free (priv->master);
1135         g_free (priv->slave_type);
1136         g_slist_free_full (priv->permissions, (GDestroyNotify) permission_free);
1137         g_slist_free_full (priv->secondaries, g_free);
1138
1139         G_OBJECT_CLASS (nm_setting_connection_parent_class)->finalize (object);
1140 }
1141
1142 static GSList *
1143 perm_strv_to_permlist (char **strv)
1144 {
1145         GSList *list = NULL;
1146         int i;
1147
1148         if (!strv)
1149                 return NULL;
1150
1151         for (i = 0; strv[i]; i++) {
1152                 Permission *p;
1153
1154                 p = permission_new_from_str (strv[i]);
1155                 if (p)
1156                         list = g_slist_append (list, p);
1157         }
1158
1159         return list;
1160 }
1161
1162 static void
1163 set_property (GObject *object, guint prop_id,
1164               const GValue *value, GParamSpec *pspec)
1165 {
1166         NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (object);
1167
1168         switch (prop_id) {
1169         case PROP_ID:
1170                 g_free (priv->id);
1171                 priv->id = g_value_dup_string (value);
1172                 break;
1173         case PROP_UUID:
1174                 g_free (priv->uuid);
1175                 priv->uuid = g_value_dup_string (value);
1176                 break;
1177         case PROP_INTERFACE_NAME:
1178                 g_free (priv->interface_name);
1179                 priv->interface_name = g_value_dup_string (value);
1180                 break;
1181         case PROP_TYPE:
1182                 g_free (priv->type);
1183                 priv->type = g_value_dup_string (value);
1184                 break;
1185         case PROP_PERMISSIONS:
1186                 g_slist_free_full (priv->permissions, (GDestroyNotify) permission_free);
1187                 priv->permissions = perm_strv_to_permlist (g_value_get_boxed (value));
1188                 break;
1189         case PROP_AUTOCONNECT:
1190                 priv->autoconnect = g_value_get_boolean (value);
1191                 break;
1192         case PROP_AUTOCONNECT_PRIORITY:
1193                 priv->autoconnect_priority = g_value_get_int (value);
1194                 break;
1195         case PROP_TIMESTAMP:
1196                 priv->timestamp = g_value_get_uint64 (value);
1197                 break;
1198         case PROP_READ_ONLY:
1199                 priv->read_only = g_value_get_boolean (value);
1200                 break;
1201         case PROP_ZONE:
1202                 g_free (priv->zone);
1203                 priv->zone = g_value_dup_string (value);
1204                 break;
1205         case PROP_MASTER:
1206                 g_free (priv->master);
1207                 priv->master = g_value_dup_string (value);
1208                 break;
1209         case PROP_SLAVE_TYPE:
1210                 g_free (priv->slave_type);
1211                 priv->slave_type = g_value_dup_string (value);
1212                 break;
1213         case PROP_AUTOCONNECT_SLAVES:
1214                 priv->autoconnect_slaves = g_value_get_enum (value);
1215                 break;
1216         case PROP_SECONDARIES:
1217                 g_slist_free_full (priv->secondaries, g_free);
1218                 priv->secondaries = _nm_utils_strv_to_slist (g_value_get_boxed (value), TRUE);
1219                 break;
1220         case PROP_GATEWAY_PING_TIMEOUT:
1221                 priv->gateway_ping_timeout = g_value_get_uint (value);
1222                 break;
1223         case PROP_METERED:
1224                 priv->metered = g_value_get_enum (value);
1225                 break;
1226         case PROP_LLDP:
1227                 priv->lldp = g_value_get_int (value);
1228                 break;
1229         default:
1230                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1231                 break;
1232         }
1233 }
1234
1235 static char **
1236 perm_permlist_to_strv (GSList *permlist)
1237 {
1238         GPtrArray *strings;
1239         GSList *iter;
1240
1241         strings = g_ptr_array_new ();
1242         for (iter = permlist; iter; iter = g_slist_next (iter))
1243                 g_ptr_array_add (strings, permission_to_string ((Permission *) iter->data));
1244         g_ptr_array_add (strings, NULL);
1245
1246         return (char **) g_ptr_array_free (strings, FALSE);
1247 }
1248
1249 static void
1250 get_property (GObject *object, guint prop_id,
1251               GValue *value, GParamSpec *pspec)
1252 {
1253         NMSettingConnection *setting = NM_SETTING_CONNECTION (object);
1254         NMSettingConnectionPrivate *priv = NM_SETTING_CONNECTION_GET_PRIVATE (setting);
1255
1256         switch (prop_id) {
1257         case PROP_ID:
1258                 g_value_set_string (value, nm_setting_connection_get_id (setting));
1259                 break;
1260         case PROP_UUID:
1261                 g_value_set_string (value, nm_setting_connection_get_uuid (setting));
1262                 break;
1263         case PROP_INTERFACE_NAME:
1264                 g_value_set_string (value, nm_setting_connection_get_interface_name (setting));
1265                 break;
1266         case PROP_TYPE:
1267                 g_value_set_string (value, nm_setting_connection_get_connection_type (setting));
1268                 break;
1269         case PROP_PERMISSIONS:
1270                 g_value_take_boxed (value, perm_permlist_to_strv (priv->permissions));
1271                 break;
1272         case PROP_AUTOCONNECT:
1273                 g_value_set_boolean (value, nm_setting_connection_get_autoconnect (setting));
1274                 break;
1275         case PROP_AUTOCONNECT_PRIORITY:
1276                 g_value_set_int (value, nm_setting_connection_get_autoconnect_priority (setting));
1277                 break;
1278         case PROP_TIMESTAMP:
1279                 g_value_set_uint64 (value, nm_setting_connection_get_timestamp (setting));
1280                 break;
1281         case PROP_READ_ONLY:
1282                 g_value_set_boolean (value, nm_setting_connection_get_read_only (setting));
1283                 break;
1284         case PROP_ZONE:
1285                 g_value_set_string (value, nm_setting_connection_get_zone (setting));
1286                 break;
1287         case PROP_MASTER:
1288                 g_value_set_string (value, nm_setting_connection_get_master (setting));
1289                 break;
1290         case PROP_SLAVE_TYPE:
1291                 g_value_set_string (value, nm_setting_connection_get_slave_type (setting));
1292                 break;
1293         case PROP_AUTOCONNECT_SLAVES:
1294                 g_value_set_enum (value, nm_setting_connection_get_autoconnect_slaves (setting));
1295                 break;
1296         case PROP_SECONDARIES:
1297                 g_value_take_boxed (value, _nm_utils_slist_to_strv (priv->secondaries, TRUE));
1298                 break;
1299         case PROP_GATEWAY_PING_TIMEOUT:
1300                 g_value_set_uint (value, priv->gateway_ping_timeout);
1301                 break;
1302         case PROP_METERED:
1303                 g_value_set_enum (value, priv->metered);
1304                 break;
1305         case PROP_LLDP:
1306                 g_value_set_int (value, priv->lldp);
1307                 break;
1308         default:
1309                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1310                 break;
1311         }
1312 }
1313
1314 static void
1315 nm_setting_connection_class_init (NMSettingConnectionClass *setting_class)
1316 {
1317         GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
1318         NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
1319
1320         g_type_class_add_private (setting_class, sizeof (NMSettingConnectionPrivate));
1321
1322         /* virtual methods */
1323         object_class->set_property = set_property;
1324         object_class->get_property = get_property;
1325         object_class->finalize     = finalize;
1326         parent_class->verify       = verify;
1327         parent_class->compare_property = compare_property;
1328
1329         /* Properties */
1330
1331         /**
1332          * NMSettingConnection:id:
1333          *
1334          * A human readable unique identifier for the connection, like "Work Wi-Fi"
1335          * or "T-Mobile 3G".
1336          **/
1337         /* ---ifcfg-rh---
1338          * property: id
1339          * variable: NAME(+)
1340          * description: User friendly name for the connection profile.
1341          * ---end---
1342          */
1343         g_object_class_install_property
1344                 (object_class, PROP_ID,
1345                  g_param_spec_string (NM_SETTING_CONNECTION_ID, "", "",
1346                                       NULL,
1347                                       G_PARAM_READWRITE |
1348                                       NM_SETTING_PARAM_FUZZY_IGNORE |
1349                                       G_PARAM_STATIC_STRINGS));
1350
1351         /**
1352          * NMSettingConnection:uuid:
1353          *
1354          * A universally unique identifier for the connection, for example generated
1355          * with libuuid.  It should be assigned when the connection is created, and
1356          * never changed as long as the connection still applies to the same
1357          * network.  For example, it should not be changed when the
1358          * #NMSettingConnection:id property or #NMSettingIP4Config changes, but
1359          * might need to be re-created when the Wi-Fi SSID, mobile broadband network
1360          * provider, or #NMSettingConnection:type property changes.
1361          *
1362          * The UUID must be in the format "2815492f-7e56-435e-b2e9-246bd7cdc664"
1363          * (ie, contains only hexadecimal characters and "-").  A suitable UUID may
1364          * be generated by nm_utils_uuid_generate() or
1365          * nm_utils_uuid_generate_from_string().
1366          **/
1367         /* ---ifcfg-rh---
1368          * property: uuid
1369          * variable: UUID(+)
1370          * description: UUID for the connection profile. When missing, NetworkManager
1371          *   creates the UUID itself (by hashing the file).
1372          * ---end---
1373          */
1374         g_object_class_install_property
1375                 (object_class, PROP_UUID,
1376                  g_param_spec_string (NM_SETTING_CONNECTION_UUID, "", "",
1377                                       NULL,
1378                                       G_PARAM_READWRITE |
1379                                       NM_SETTING_PARAM_FUZZY_IGNORE |
1380                                       G_PARAM_STATIC_STRINGS));
1381
1382         /**
1383          * NMSettingConnection:interface-name:
1384          *
1385          * The name of the network interface this connection is bound to. If not
1386          * set, then the connection can be attached to any interface of the
1387          * appropriate type (subject to restrictions imposed by other settings).
1388          *
1389          * For software devices this specifies the name of the created device.
1390          *
1391          * For connection types where interface names cannot easily be made
1392          * persistent (e.g. mobile broadband or USB Ethernet), this property should
1393          * not be used. Setting this property restricts the interfaces a connection
1394          * can be used with, and if interface names change or are reordered the
1395          * connection may be applied to the wrong interface.
1396          **/
1397         /* ---ifcfg-rh---
1398          * property: interface-name
1399          * variable: DEVICE
1400          * description: Interface name of the device this profile is bound to. The variable
1401          *   can be left out when the profile should apply for more devices. Note that DEVICE
1402          *   can be required for some connection types.
1403          * ---end---
1404          */
1405         g_object_class_install_property
1406                 (object_class, PROP_INTERFACE_NAME,
1407                  g_param_spec_string (NM_SETTING_CONNECTION_INTERFACE_NAME, "", "",
1408                                       NULL,
1409                                       G_PARAM_READWRITE |
1410                                       NM_SETTING_PARAM_INFERRABLE |
1411                                       G_PARAM_STATIC_STRINGS));
1412         _nm_setting_class_override_property (parent_class, NM_SETTING_CONNECTION_INTERFACE_NAME,
1413                                              G_VARIANT_TYPE_STRING,
1414                                              NULL,
1415                                              nm_setting_connection_set_interface_name,
1416                                              nm_setting_connection_no_interface_name);
1417
1418         /**
1419          * NMSettingConnection:type:
1420          *
1421          * Base type of the connection. For hardware-dependent connections, should
1422          * contain the setting name of the hardware-type specific setting (ie,
1423          * "802-3-ethernet" or "802-11-wireless" or "bluetooth", etc), and for
1424          * non-hardware dependent connections like VPN or otherwise, should contain
1425          * the setting name of that setting type (ie, "vpn" or "bridge", etc).
1426          **/
1427         /* ---ifcfg-rh---
1428          * property: type
1429          * variable: TYPE (DEVICETYPE, DEVICE)
1430          * values: Ethernet, Wireless, InfiniBand, Bridge, Bond, Vlan, Team, TeamPort
1431          * description: Base type of the connection. DEVICETYPE is used for teaming
1432          *   connections.
1433          * example: TYPE=Ethernet; TYPE=Bond; TYPE=Bridge; DEVICETYPE=TeamPort
1434          * ---end---
1435          */
1436         g_object_class_install_property
1437                 (object_class, PROP_TYPE,
1438                  g_param_spec_string (NM_SETTING_CONNECTION_TYPE, "", "",
1439                                       NULL,
1440                                       G_PARAM_READWRITE |
1441                                       NM_SETTING_PARAM_INFERRABLE |
1442                                       G_PARAM_STATIC_STRINGS));
1443
1444         /**
1445          * NMSettingConnection:permissions:
1446          *
1447          * An array of strings defining what access a given user has to this
1448          * connection.  If this is %NULL or empty, all users are allowed to access
1449          * this connection.  Otherwise a user is allowed to access this connection
1450          * if and only if they are in this list. Each entry is of the form
1451          * "[type]:[id]:[reserved]"; for example, "user:dcbw:blah".
1452          *
1453          * At this time only the "user" [type] is allowed.  Any other values are
1454          * ignored and reserved for future use.  [id] is the username that this
1455          * permission refers to, which may not contain the ":" character. Any
1456          * [reserved] information present must be ignored and is reserved for future
1457          * use.  All of [type], [id], and [reserved] must be valid UTF-8.
1458          */
1459         /* ---ifcfg-rh---
1460          * property: permissions
1461          * variable: USERS(+)
1462          * description: USERS restrict the access for this conenction to certain
1463          *   users only.
1464          * example: USERS="joe bob"
1465          * ---end---
1466          */
1467         g_object_class_install_property
1468                 (object_class, PROP_PERMISSIONS,
1469                  g_param_spec_boxed (NM_SETTING_CONNECTION_PERMISSIONS, "", "",
1470                                      G_TYPE_STRV,
1471                                      G_PARAM_READWRITE |
1472                                      G_PARAM_STATIC_STRINGS));
1473
1474         /**
1475          * NMSettingConnection:autoconnect:
1476          *
1477          * Whether or not the connection should be automatically connected by
1478          * NetworkManager when the resources for the connection are available.
1479          * %TRUE to automatically activate the connection, %FALSE to require manual
1480          * intervention to activate the connection.
1481          **/
1482         /* ---ifcfg-rh---
1483          * property: autoconnect
1484          * variable: ONBOOT
1485          * default: yes
1486          * description: Whether the connection should be autoconnected (not only while booting).
1487          * ---end---
1488          */
1489         g_object_class_install_property
1490                 (object_class, PROP_AUTOCONNECT,
1491                  g_param_spec_boolean (NM_SETTING_CONNECTION_AUTOCONNECT, "", "",
1492                                        TRUE,
1493                                        G_PARAM_READWRITE |
1494                                        G_PARAM_CONSTRUCT |
1495                                        NM_SETTING_PARAM_FUZZY_IGNORE |
1496                                        G_PARAM_STATIC_STRINGS));
1497
1498         /**
1499          * NMSettingConnection:autoconnect-priority:
1500          *
1501          * The autoconnect priority. If the connection is set to autoconnect,
1502          * connections with higher priority will be preferred. Defaults to 0.
1503          * The higher number means higher priority.
1504          **/
1505         /* ---ifcfg-rh---
1506          * property: autoconnect-priority
1507          * variable: AUTOCONNECT_PRIORITY(+)
1508          * values: -999 to 999
1509          * default: 0
1510          * description: Connection priority for automatic activation. Connections with
1511          *  higher numbers are preferred when selecting profiles for automatic activation.
1512          * example: AUTOCONNECT_PRIORITY=20
1513          * ---end---
1514          */
1515         g_object_class_install_property
1516             (object_class, PROP_AUTOCONNECT_PRIORITY,
1517              g_param_spec_int (NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, "", "",
1518                                NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN,
1519                                NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX,
1520                                NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT,
1521                                G_PARAM_READWRITE |
1522                                G_PARAM_CONSTRUCT |
1523                                NM_SETTING_PARAM_FUZZY_IGNORE |
1524                                G_PARAM_STATIC_STRINGS));
1525
1526         /**
1527          * NMSettingConnection:timestamp:
1528          *
1529          * The time, in seconds since the Unix Epoch, that the connection was last
1530          * _successfully_ fully activated.
1531          *
1532          * NetworkManager updates the connection timestamp periodically when the
1533          * connection is active to ensure that an active connection has the latest
1534          * timestamp. The property is only meant for reading (changes to this
1535          * property will not be preserved).
1536          **/
1537         g_object_class_install_property
1538                 (object_class, PROP_TIMESTAMP,
1539                  g_param_spec_uint64 (NM_SETTING_CONNECTION_TIMESTAMP, "", "",
1540                                       0, G_MAXUINT64, 0,
1541                                       G_PARAM_READWRITE |
1542                                       G_PARAM_CONSTRUCT |
1543                                       NM_SETTING_PARAM_FUZZY_IGNORE |
1544                                       G_PARAM_STATIC_STRINGS));
1545
1546         /**
1547          * NMSettingConnection:read-only:
1548          *
1549          * %FALSE if the connection can be modified using the provided settings
1550          * service's D-Bus interface with the right privileges, or %TRUE if the
1551          * connection is read-only and cannot be modified.
1552          **/
1553         g_object_class_install_property
1554                 (object_class, PROP_READ_ONLY,
1555                  g_param_spec_boolean (NM_SETTING_CONNECTION_READ_ONLY, "", "",
1556                                        FALSE,
1557                                        G_PARAM_READWRITE |
1558                                        G_PARAM_CONSTRUCT |
1559                                        NM_SETTING_PARAM_FUZZY_IGNORE |
1560                                        G_PARAM_STATIC_STRINGS));
1561
1562         /**
1563          * NMSettingConnection:zone:
1564          *
1565          * The trust level of a the connection.  Free form case-insensitive string
1566          * (for example "Home", "Work", "Public").  %NULL or unspecified zone means
1567          * the connection will be placed in the default zone as defined by the
1568          * firewall.
1569          *
1570          * When updating this property on a currently activated connection,
1571          * the change takes effect immediately.
1572          **/
1573         /* ---ifcfg-rh---
1574          * property: zone
1575          * variable: ZONE(+)
1576          * description: Trust level of this connection. The string is usually used
1577          *   for a firewall.
1578          * example: ZONE=Work
1579          * ---end---
1580          */
1581         g_object_class_install_property
1582                 (object_class, PROP_ZONE,
1583                  g_param_spec_string (NM_SETTING_CONNECTION_ZONE, "", "",
1584                                       NULL,
1585                                       G_PARAM_READWRITE |
1586                                       G_PARAM_CONSTRUCT |
1587                                       NM_SETTING_PARAM_FUZZY_IGNORE |
1588                                       NM_SETTING_PARAM_REAPPLY_IMMEDIATELY |
1589                                       G_PARAM_STATIC_STRINGS));
1590
1591         /**
1592          * NMSettingConnection:master:
1593          *
1594          * Interface name of the master device or UUID of the master connection.
1595          **/
1596         /* ---ifcfg-rh---
1597          * property: master
1598          * variable: MASTER, TEAM_MASTER, BRIDGE
1599          * description: Reference to master connection. The variable used depends on
1600          *   the connection type.
1601          * ---end---
1602          */
1603         g_object_class_install_property
1604                 (object_class, PROP_MASTER,
1605                  g_param_spec_string (NM_SETTING_CONNECTION_MASTER, "", "",
1606                                       NULL,
1607                                       G_PARAM_READWRITE |
1608                                       NM_SETTING_PARAM_FUZZY_IGNORE |
1609                                       NM_SETTING_PARAM_INFERRABLE |
1610                                       G_PARAM_STATIC_STRINGS));
1611
1612         /**
1613          * NMSettingConnection:slave-type:
1614          *
1615          * Setting name of the device type of this slave's master connection (eg,
1616          * %NM_SETTING_BOND_SETTING_NAME), or %NULL if this connection is not a
1617          * slave.
1618          **/
1619         /* ---ifcfg-rh---
1620          * property: slave-type
1621          * variable: MASTER, TEAM_MASTER, DEVICETYPE, BRIDGE
1622          * description: Slave type doesn't map directly to a variable, but it is
1623          *   recognized using different variables.  MASTER for bonding,
1624          *   TEAM_MASTER and DEVICETYPE for teaming, BRIDGE for bridging.
1625          * ---end---
1626          */
1627         g_object_class_install_property
1628                 (object_class, PROP_SLAVE_TYPE,
1629                  g_param_spec_string (NM_SETTING_CONNECTION_SLAVE_TYPE, "", "",
1630                                       NULL,
1631                                       G_PARAM_READWRITE |
1632                                       NM_SETTING_PARAM_FUZZY_IGNORE |
1633                                       NM_SETTING_PARAM_INFERRABLE |
1634                                       G_PARAM_STATIC_STRINGS));
1635
1636         /**
1637          * NMSettingConnection:autoconnect-slaves:
1638          *
1639          * Whether or not slaves of this connection should be automatically brought up
1640          * when NetworkManager activates this connection. This only has a real effect
1641          * for master connections.
1642          * The permitted values are: 0: leave slave connections untouched,
1643          * 1: activate all the slave connections with this connection, -1: default.
1644          * If -1 (default) is set, global connection.autoconnect-slaves is read to
1645          * determine the real value. If it is default as well, this fallbacks to 0.
1646          *
1647          * Since: 1.2
1648          **/
1649         /* ---ifcfg-rh---
1650          * property: autoconnect-slaves
1651          * variable: AUTOCONNECT-SLAVES(+)
1652          * default: missing variable means global default
1653          * description: Whether slaves of this connection should be auto-connected
1654          *   when this connection is activated.
1655          * ---end---
1656          */
1657         g_object_class_install_property
1658                 (object_class, PROP_AUTOCONNECT_SLAVES,
1659                  g_param_spec_enum (NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, "", "",
1660                                     NM_TYPE_SETTING_CONNECTION_AUTOCONNECT_SLAVES,
1661                                     NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT,
1662                                     G_PARAM_READWRITE |
1663                                     G_PARAM_CONSTRUCT |
1664                                     NM_SETTING_PARAM_FUZZY_IGNORE |
1665                                     G_PARAM_STATIC_STRINGS));
1666
1667         /**
1668          * NMSettingConnection:secondaries:
1669          *
1670          * List of connection UUIDs that should be activated when the base
1671          * connection itself is activated. Currently only VPN connections are
1672          * supported.
1673          **/
1674         /* ---ifcfg-rh---
1675          * property: secondaries
1676          * variable: SECONDARY_UUIDS(+)
1677          * description: UUID of VPN connections that should be activated
1678          *   together with this connection.
1679          * ---end---
1680          */
1681         g_object_class_install_property
1682                 (object_class, PROP_SECONDARIES,
1683                  g_param_spec_boxed (NM_SETTING_CONNECTION_SECONDARIES, "", "",
1684                                      G_TYPE_STRV,
1685                                      G_PARAM_READWRITE |
1686                                      NM_SETTING_PARAM_FUZZY_IGNORE |
1687                                      G_PARAM_STATIC_STRINGS));
1688
1689         /**
1690          * NMSettingConnection:gateway-ping-timeout:
1691          *
1692          * If greater than zero, delay success of IP addressing until either the
1693          * timeout is reached, or an IP gateway replies to a ping.
1694          **/
1695         /* ---ifcfg-rh---
1696          * property: gateway-ping-timeout
1697          * variable: GATEWAY_PING_TIMEOUT(+)
1698          * default: 0
1699          * description: If greater than zero, the IP connectivity will be checked by
1700          *   pinging the gateway and waiting for the specified timeout (in seconds).
1701          * example: GATEWAY_PING_TIMEOUT=5
1702          * ---end---
1703          */
1704         g_object_class_install_property
1705                 (object_class, PROP_GATEWAY_PING_TIMEOUT,
1706                  g_param_spec_uint (NM_SETTING_CONNECTION_GATEWAY_PING_TIMEOUT, "", "",
1707                                     0, 600, 0,
1708                                     G_PARAM_READWRITE |
1709                                     G_PARAM_CONSTRUCT |
1710                                     G_PARAM_STATIC_STRINGS));
1711
1712         /**
1713          * NMSettingConnection:metered:
1714          *
1715          * Whether the connection is metered.
1716          *
1717          * When updating this property on a currently activated connection,
1718          * the change takes effect immediately.
1719          *
1720          * Since: 1.2
1721          **/
1722         /* ---ifcfg-rh---
1723          * property: metered
1724          * variable: CONNECTION_METERED
1725          * values: yes,no,unknown
1726          * description: Whether the device is metered
1727          * example: CONNECTION_METERED=yes
1728          * ---end---
1729          */
1730         g_object_class_install_property
1731                 (object_class, PROP_METERED,
1732                  g_param_spec_enum (NM_SETTING_CONNECTION_METERED, "", "",
1733                                     NM_TYPE_METERED,
1734                                     NM_METERED_UNKNOWN,
1735                                     G_PARAM_READWRITE |
1736                                     NM_SETTING_PARAM_REAPPLY_IMMEDIATELY |
1737                                     G_PARAM_STATIC_STRINGS));
1738
1739         /**
1740          * NMSettingConnection:lldp:
1741          *
1742          * Whether LLDP is enabled for the connection.
1743          *
1744          * Since: 1.2
1745          **/
1746         /* ---ifcfg-rh---
1747          * property: lldp
1748          * variable: LLDP
1749          * values: boolean value or 'rx'
1750          * default: missing variable means global default
1751          * description: whether LLDP is enabled for the connection
1752          * example: LLDP=no
1753          * ---end---
1754          */
1755         g_object_class_install_property
1756                 (object_class, PROP_LLDP,
1757                  g_param_spec_int (NM_SETTING_CONNECTION_LLDP, "", "",
1758                                    G_MININT32, G_MAXINT32, NM_SETTING_CONNECTION_LLDP_DEFAULT,
1759                                    NM_SETTING_PARAM_FUZZY_IGNORE |
1760                                    G_PARAM_READWRITE |
1761                                    G_PARAM_CONSTRUCT |
1762                                    G_PARAM_STATIC_STRINGS));
1763 }