device: renew dhcp leases on awake for software devices
[NetworkManager.git] / libnm-core / nm-setting-dcb.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 2013 Red Hat, Inc.
20  */
21
22 #include "nm-default.h"
23
24 #include <string.h>
25
26 #include "nm-setting-dcb.h"
27 #include "nm-utils.h"
28 #include "nm-utils-private.h"
29 #include "nm-setting-private.h"
30 #include "nm-core-enum-types.h"
31
32 /**
33  * SECTION:nm-setting-dcb
34  * @short_description: Connection properties for Data Center Bridging
35  *
36  * The #NMSettingDcb object is a #NMSetting subclass that describes properties
37  * for enabling and using Data Center Bridging (DCB) on Ethernet networks.
38  * DCB is a set of protocols (including 802.1Qbb, 802.1Qaz, 802.1Qau, and
39  * 802.1AB) to eliminate packet loss in Ethernet networks and support the use
40  * of storage technologies like Fibre Channel over Ethernet (FCoE) and iSCSI.
41  **/
42
43 G_DEFINE_TYPE_WITH_CODE (NMSettingDcb, nm_setting_dcb, NM_TYPE_SETTING,
44                          _nm_register_setting (DCB, 2))
45 NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_DCB)
46
47 #define NM_SETTING_DCB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_DCB, NMSettingDcbPrivate))
48
49 typedef struct {
50         NMSettingDcbFlags app_fcoe_flags;
51         gint              app_fcoe_priority;
52         char *            app_fcoe_mode;
53
54         NMSettingDcbFlags app_iscsi_flags;
55         gint              app_iscsi_priority;
56
57         NMSettingDcbFlags app_fip_flags;
58         gint              app_fip_priority;
59
60         /* Priority Flow Control */
61         NMSettingDcbFlags pfc_flags;
62         guint             pfc[8];
63
64         /* Priority Groups */
65         NMSettingDcbFlags priority_group_flags;
66         guint             priority_group_id[8];
67         guint             priority_group_bandwidth[8];
68         guint             priority_bandwidth[8];
69         guint             priority_strict[8];
70         guint             priority_traffic_class[8];
71 } NMSettingDcbPrivate;
72
73 enum {
74         PROP_0,
75         PROP_APP_FCOE_FLAGS,
76         PROP_APP_FCOE_PRIORITY,
77         PROP_APP_FCOE_MODE,
78
79         PROP_APP_ISCSI_FLAGS,
80         PROP_APP_ISCSI_PRIORITY,
81
82         PROP_APP_FIP_FLAGS,
83         PROP_APP_FIP_PRIORITY,
84
85         PROP_PFC_FLAGS,
86         PROP_PFC,
87
88         PROP_PRIORITY_GROUP_FLAGS,
89         PROP_PRIORITY_GROUP_ID,
90         PROP_PRIORITY_GROUP_BANDWIDTH,
91         PROP_PRIORITY_BANDWIDTH,
92         PROP_PRIORITY_STRICT,
93         PROP_PRIORITY_TRAFFIC_CLASS,
94
95         LAST_PROP
96 };
97
98 /**
99  * nm_setting_dcb_new:
100  *
101  * Creates a new #NMSettingDcb object with default values.
102  *
103  * Returns: (transfer full): the new empty #NMSettingDcb object
104  **/
105 NMSetting *
106 nm_setting_dcb_new (void)
107 {
108         return (NMSetting *) g_object_new (NM_TYPE_SETTING_DCB, NULL);
109 }
110
111 /**
112  * nm_setting_dcb_get_app_fcoe_flags:
113  * @setting: the #NMSettingDcb
114  *
115  * Returns: the #NMSettingDcb:app-fcoe-flags property of the setting
116  **/
117 NMSettingDcbFlags
118 nm_setting_dcb_get_app_fcoe_flags (NMSettingDcb *setting)
119 {
120         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
121
122         return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fcoe_flags;
123 }
124
125 /**
126  * nm_setting_dcb_get_app_fcoe_priority:
127  * @setting: the #NMSettingDcb
128  *
129  * Returns: the #NMSettingDcb:app-fcoe-priority property of the setting
130  **/
131 gint
132 nm_setting_dcb_get_app_fcoe_priority (NMSettingDcb *setting)
133 {
134         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
135
136         return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fcoe_priority;
137 }
138
139 /**
140  * nm_setting_dcb_get_app_fcoe_mode:
141  * @setting: the #NMSettingDcb
142  *
143  * Returns: the #NMSettingDcb:app-fcoe-mode property of the setting
144  **/
145 const char *
146 nm_setting_dcb_get_app_fcoe_mode (NMSettingDcb *setting)
147 {
148         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), NULL);
149
150         return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fcoe_mode;
151 }
152
153 /**
154  * nm_setting_dcb_get_app_iscsi_flags:
155  * @setting: the #NMSettingDcb
156  *
157  * Returns: the #NMSettingDcb:app-iscsi-flags property of the setting
158  **/
159 NMSettingDcbFlags
160 nm_setting_dcb_get_app_iscsi_flags (NMSettingDcb *setting)
161 {
162         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
163
164         return NM_SETTING_DCB_GET_PRIVATE (setting)->app_iscsi_flags;
165 }
166
167 /**
168  * nm_setting_dcb_get_app_iscsi_priority:
169  * @setting: the #NMSettingDcb
170  *
171  * Returns: the #NMSettingDcb:app-iscsi-priority property of the setting
172  **/
173 gint
174 nm_setting_dcb_get_app_iscsi_priority (NMSettingDcb *setting)
175 {
176         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
177
178         return NM_SETTING_DCB_GET_PRIVATE (setting)->app_iscsi_priority;
179 }
180
181 /**
182  * nm_setting_dcb_get_app_fip_flags:
183  * @setting: the #NMSettingDcb
184  *
185  * Returns: the #NMSettingDcb:app-fip-flags property of the setting
186  **/
187 NMSettingDcbFlags
188 nm_setting_dcb_get_app_fip_flags (NMSettingDcb *setting)
189 {
190         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
191
192         return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fip_flags;
193 }
194
195 /**
196  * nm_setting_dcb_get_app_fip_priority:
197  * @setting: the #NMSettingDcb
198  *
199  * Returns: the #NMSettingDcb:app-fip-priority property of the setting
200  **/
201 gint
202 nm_setting_dcb_get_app_fip_priority (NMSettingDcb *setting)
203 {
204         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
205
206         return NM_SETTING_DCB_GET_PRIVATE (setting)->app_fip_priority;
207 }
208
209 /**
210  * nm_setting_dcb_get_priority_flow_control_flags:
211  * @setting: the #NMSettingDcb
212  *
213  * Returns: the #NMSettingDcb:priority-flow-control-flags property of the setting
214  **/
215 NMSettingDcbFlags
216 nm_setting_dcb_get_priority_flow_control_flags (NMSettingDcb *setting)
217 {
218         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
219
220         return NM_SETTING_DCB_GET_PRIVATE (setting)->pfc_flags;
221 }
222
223 /**
224  * nm_setting_dcb_get_priority_flow_control:
225  * @setting: the #NMSettingDcb
226  * @user_priority: the User Priority (0 - 7) to retrieve flow control for
227  *
228  * Returns: %TRUE if flow control is enabled for the given @user_priority,
229  * %FALSE if not enabled
230  **/
231 gboolean
232 nm_setting_dcb_get_priority_flow_control (NMSettingDcb *setting, guint user_priority)
233 {
234         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), FALSE);
235         g_return_val_if_fail (user_priority <= 7, FALSE);
236
237         return !!NM_SETTING_DCB_GET_PRIVATE (setting)->pfc[user_priority];
238 }
239
240 /**
241  * nm_setting_dcb_set_priority_flow_control:
242  * @setting: the #NMSettingDcb
243  * @user_priority: the User Priority (0 - 7) to set flow control for
244  * @enabled: %TRUE to enable flow control for this priority, %FALSE to disable it
245  *
246  * These values are only valid when #NMSettingDcb:priority-flow-control includes
247  * the %NM_SETTING_DCB_FLAG_ENABLE flag.
248  **/
249 void
250 nm_setting_dcb_set_priority_flow_control (NMSettingDcb *setting,
251                                           guint user_priority,
252                                           gboolean enabled)
253 {
254         NMSettingDcbPrivate *priv;
255         guint uint_enabled = enabled ? 1 : 0;
256
257         g_return_if_fail (NM_IS_SETTING_DCB (setting));
258         g_return_if_fail (user_priority <= 7);
259
260         priv = NM_SETTING_DCB_GET_PRIVATE (setting);
261         if (priv->pfc[user_priority] != uint_enabled) {
262                 priv->pfc[user_priority] = uint_enabled;
263                 g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_FLOW_CONTROL);
264         }
265 }
266
267 /**
268  * nm_setting_dcb_get_priority_group_flags:
269  * @setting: the #NMSettingDcb
270  *
271  * Returns: the #NMSettingDcb:priority-group-flags property of the setting
272  **/
273 NMSettingDcbFlags
274 nm_setting_dcb_get_priority_group_flags (NMSettingDcb *setting)
275 {
276         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
277
278         return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_group_flags;
279 }
280
281 /**
282  * nm_setting_dcb_get_priority_group_id:
283  * @setting: the #NMSettingDcb
284  * @user_priority: the User Priority (0 - 7) to retrieve the group ID for
285  *
286  * Returns: the group number @user_priority is assigned to.  These values are
287  * only valid when #NMSettingDcb:priority-group-flags includes the
288  * %NM_SETTING_DCB_FLAG_ENABLE flag.
289  **/
290 guint
291 nm_setting_dcb_get_priority_group_id (NMSettingDcb *setting, guint user_priority)
292 {
293         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
294         g_return_val_if_fail (user_priority <= 7, 0);
295
296         return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_group_id[user_priority];
297 }
298
299 /**
300  * nm_setting_dcb_set_priority_group_id:
301  * @setting: the #NMSettingDcb
302  * @user_priority: the User Priority (0 - 7) to set flow control for
303  * @group_id: the group (0 - 7) to assign @user_priority to, or 15 for the
304  * unrestricted group.
305  *
306  * These values are only valid when #NMSettingDcb:priority-group-flags includes
307  * the %NM_SETTING_DCB_FLAG_ENABLE flag.
308  **/
309 void
310 nm_setting_dcb_set_priority_group_id (NMSettingDcb *setting,
311                                       guint user_priority,
312                                       guint group_id)
313 {
314         NMSettingDcbPrivate *priv;
315
316         g_return_if_fail (NM_IS_SETTING_DCB (setting));
317         g_return_if_fail (user_priority <= 7);
318         g_return_if_fail (group_id <= 7 || group_id == 15);
319
320         priv = NM_SETTING_DCB_GET_PRIVATE (setting);
321         if (priv->priority_group_id[user_priority] != group_id) {
322                 priv->priority_group_id[user_priority] = group_id;
323                 g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_GROUP_ID);
324         }
325 }
326
327 /**
328  * nm_setting_dcb_get_priority_group_bandwidth:
329  * @setting: the #NMSettingDcb
330  * @group_id: the priority group (0 - 7) to retrieve the bandwidth percentage for
331  *
332  * Returns: the bandwidth percentage assigned to @group_id.  These values are
333  * only valid when #NMSettingDcb:priority-group-flags includes the
334  * %NM_SETTING_DCB_FLAG_ENABLE flag.
335  **/
336 guint
337 nm_setting_dcb_get_priority_group_bandwidth (NMSettingDcb *setting, guint group_id)
338 {
339         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
340         g_return_val_if_fail (group_id <= 7, FALSE);
341
342         return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_group_bandwidth[group_id];
343 }
344
345 /**
346  * nm_setting_dcb_set_priority_group_bandwidth:
347  * @setting: the #NMSettingDcb
348  * @group_id: the priority group (0 - 7) to set the bandwidth percentage for
349  * @bandwidth_percent: the bandwidth percentage (0 - 100) to assign to @group_id to
350  *
351  * These values are only valid when #NMSettingDcb:priority-group-flags includes
352  * the %NM_SETTING_DCB_FLAG_ENABLE flag.
353  **/
354 void
355 nm_setting_dcb_set_priority_group_bandwidth (NMSettingDcb *setting,
356                                              guint group_id,
357                                              guint bandwidth_percent)
358 {
359         NMSettingDcbPrivate *priv;
360
361         g_return_if_fail (NM_IS_SETTING_DCB (setting));
362         g_return_if_fail (group_id <= 7);
363         g_return_if_fail (bandwidth_percent <= 100);
364
365         priv = NM_SETTING_DCB_GET_PRIVATE (setting);
366         if (priv->priority_group_bandwidth[group_id] != bandwidth_percent) {
367                 priv->priority_group_bandwidth[group_id] = bandwidth_percent;
368                 g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH);
369         }
370 }
371
372 /**
373  * nm_setting_dcb_get_priority_bandwidth:
374  * @setting: the #NMSettingDcb
375  * @user_priority: the User Priority (0 - 7) to retrieve the group bandwidth percentage for
376  *
377  * Returns: the allowed bandwidth percentage of @user_priority in its priority group.
378  * These values are only valid when #NMSettingDcb:priority-group-flags includes the
379  * %NM_SETTING_DCB_FLAG_ENABLE flag.
380  **/
381 guint
382 nm_setting_dcb_get_priority_bandwidth (NMSettingDcb *setting, guint user_priority)
383 {
384         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
385         g_return_val_if_fail (user_priority <= 7, FALSE);
386
387         return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_bandwidth[user_priority];
388 }
389
390 /**
391  * nm_setting_dcb_set_priority_bandwidth:
392  * @setting: the #NMSettingDcb
393  * @user_priority: the User Priority (0 - 7) to set the bandwidth percentage for
394  * @bandwidth_percent: the bandwidth percentage (0 - 100) that @user_priority is
395  * allowed to use within its priority group
396  *
397  * These values are only valid when #NMSettingDcb:priority-group-flags includes
398  * the %NM_SETTING_DCB_FLAG_ENABLE flag.
399  **/
400 void
401 nm_setting_dcb_set_priority_bandwidth (NMSettingDcb *setting,
402                                        guint user_priority,
403                                        guint bandwidth_percent)
404 {
405         NMSettingDcbPrivate *priv;
406
407         g_return_if_fail (NM_IS_SETTING_DCB (setting));
408         g_return_if_fail (user_priority <= 7);
409         g_return_if_fail (bandwidth_percent <= 100);
410
411         priv = NM_SETTING_DCB_GET_PRIVATE (setting);
412         if (priv->priority_bandwidth[user_priority] != bandwidth_percent) {
413                 priv->priority_bandwidth[user_priority] = bandwidth_percent;
414                 g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_BANDWIDTH);
415         }
416 }
417
418 /**
419  * nm_setting_dcb_get_priority_strict_bandwidth:
420  * @setting: the #NMSettingDcb
421  * @user_priority: the User Priority (0 - 7) to retrieve strict bandwidth for
422  *
423  * Returns: %TRUE if @user_priority may use all of the bandwidth allocated to its
424  * assigned group, or %FALSE if not. These values are only valid when
425  * #NMSettingDcb:priority-group-flags includes the %NM_SETTING_DCB_FLAG_ENABLE flag.
426  **/
427 gboolean
428 nm_setting_dcb_get_priority_strict_bandwidth (NMSettingDcb *setting, guint user_priority)
429 {
430         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
431         g_return_val_if_fail (user_priority <= 7, FALSE);
432
433         return !!NM_SETTING_DCB_GET_PRIVATE (setting)->priority_strict[user_priority];
434 }
435
436 /**
437  * nm_setting_dcb_set_priority_strict_bandwidth:
438  * @setting: the #NMSettingDcb
439  * @user_priority: the User Priority (0 - 7) to set strict bandwidth for
440  * @strict: %TRUE to allow @user_priority to use all the bandwidth allocated to
441  * its priority group, or %FALSE if not
442  *
443  * These values are only valid when #NMSettingDcb:priority-group-flags includes
444  * the %NM_SETTING_DCB_FLAG_ENABLE flag.
445  **/
446 void
447 nm_setting_dcb_set_priority_strict_bandwidth (NMSettingDcb *setting,
448                                               guint user_priority,
449                                               gboolean strict)
450 {
451         NMSettingDcbPrivate *priv;
452         guint uint_strict = strict ? 1 : 0;
453
454         g_return_if_fail (NM_IS_SETTING_DCB (setting));
455         g_return_if_fail (user_priority <= 7);
456
457         priv = NM_SETTING_DCB_GET_PRIVATE (setting);
458         if (priv->priority_strict[user_priority] != uint_strict) {
459                 priv->priority_strict[user_priority] = uint_strict;
460                 g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH);
461         }
462 }
463
464 /**
465  * nm_setting_dcb_get_priority_traffic_class:
466  * @setting: the #NMSettingDcb
467  * @user_priority: the User Priority (0 - 7) to retrieve the traffic class for
468  *
469  * Returns: the traffic class assigned to @user_priority. These values are only
470  * valid when #NMSettingDcb:priority-group-flags includes the
471  * %NM_SETTING_DCB_FLAG_ENABLE flag.
472  **/
473 guint
474 nm_setting_dcb_get_priority_traffic_class (NMSettingDcb *setting, guint user_priority)
475 {
476         g_return_val_if_fail (NM_IS_SETTING_DCB (setting), 0);
477         g_return_val_if_fail (user_priority <= 7, FALSE);
478
479         return NM_SETTING_DCB_GET_PRIVATE (setting)->priority_traffic_class[user_priority];
480 }
481
482 /**
483  * nm_setting_dcb_set_priority_traffic_clas:
484  * @setting: the #NMSettingDcb
485  * @user_priority: the User Priority (0 - 7) to set the bandwidth percentage for
486  * @traffic_class: the traffic_class (0 - 7) that @user_priority should map to
487  *
488  * These values are only valid when #NMSettingDcb:priority-group-flags includes
489  * the %NM_SETTING_DCB_FLAG_ENABLE flag.
490  **/
491 void
492 nm_setting_dcb_set_priority_traffic_class (NMSettingDcb *setting,
493                                            guint user_priority,
494                                            guint traffic_class)
495 {
496         NMSettingDcbPrivate *priv;
497
498         g_return_if_fail (NM_IS_SETTING_DCB (setting));
499         g_return_if_fail (user_priority <= 7);
500         g_return_if_fail (traffic_class <= 7);
501
502         priv = NM_SETTING_DCB_GET_PRIVATE (setting);
503         if (priv->priority_traffic_class[user_priority] != traffic_class) {
504                 priv->priority_traffic_class[user_priority] = traffic_class;
505                 g_object_notify (G_OBJECT (setting), NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS);
506         }
507 }
508
509 /******************************************************************/
510
511 #define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \
512                        NM_SETTING_DCB_FLAG_ADVERTISE | \
513                        NM_SETTING_DCB_FLAG_WILLING)
514
515 static gboolean
516 check_dcb_flags (NMSettingDcbFlags flags, const char *prop_name, GError **error)
517 {
518         if (flags & ~DCB_FLAGS_ALL) {
519                 g_set_error_literal (error,
520                                      NM_CONNECTION_ERROR,
521                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
522                                      _("flags invalid"));
523                 g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name);
524                 return FALSE;
525         }
526
527         if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && (flags & ~NM_SETTING_DCB_FLAG_ENABLE)) {
528                 g_set_error_literal (error,
529                                      NM_CONNECTION_ERROR,
530                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
531                                      _("flags invalid - disabled"));
532                 g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name);
533                 return FALSE;
534         }
535
536         return TRUE;
537 }
538
539 static gboolean
540 check_uint_array (const guint *array,
541                   guint len,
542                   NMSettingDcbFlags flags,
543                   guint max,
544                   guint extra,
545                   gboolean sum_pct,
546                   const char *prop_name,
547                   GError **error)
548 {
549         guint i, sum = 0;
550
551         /* Ensure each element is <= to max or equals extra */
552         for (i = 0; i < len; i++) {
553                 if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && array[i]) {
554                         g_set_error_literal (error,
555                                              NM_CONNECTION_ERROR,
556                                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
557                                              _("property invalid (not enabled)"));
558                         g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name);
559                         return FALSE;
560                 }
561
562                 if ((array[i] > max) && (array[i] != extra)) {
563                         g_set_error_literal (error,
564                                              NM_CONNECTION_ERROR,
565                                              NM_CONNECTION_ERROR_INVALID_PROPERTY,
566                                              _("element invalid"));
567                         g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name);
568                         return FALSE;
569                 }
570                 sum += array[i];
571         }
572
573         /* Verify sum of percentages */
574         if (sum_pct) {
575                 if (flags & NM_SETTING_DCB_FLAG_ENABLE) {
576                         /* If the feature is enabled, sum must equal 100% */
577                         if (sum != 100) {
578                                 g_set_error_literal (error,
579                                                      NM_CONNECTION_ERROR,
580                                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
581                                                      _("sum not 100%"));
582                                 g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name);
583                                 return FALSE;
584                         }
585                 } else {
586                         /* If the feature is disabled, sum must equal 0%, which was checked
587                          * by the for() loop above.
588                          */
589                         g_assert_cmpint (sum, ==, 0);
590                 }
591         }
592
593         return TRUE;
594 }
595
596 static gboolean
597 check_priority (gint val,
598                 NMSettingDcbFlags flags,
599                 const char *prop_name,
600                 GError **error)
601 {
602         if (!(flags & NM_SETTING_DCB_FLAG_ENABLE) && (val >= 0)) {
603                 g_set_error_literal (error,
604                                      NM_CONNECTION_ERROR,
605                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
606                                      _("property invalid (not enabled)"));
607                 g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name);
608                 return FALSE;
609         }
610
611         if (val < -1 || val > 7) {
612                 g_set_error_literal (error,
613                                      NM_CONNECTION_ERROR,
614                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
615                                      _("property invalid"));
616                 g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, prop_name);
617                 return FALSE;
618         }
619         return TRUE;
620 }
621
622 static gboolean
623 verify (NMSetting *setting, NMConnection *connection, GError **error)
624 {
625         NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (setting);
626
627         if (!check_dcb_flags (priv->app_fcoe_flags, NM_SETTING_DCB_APP_FCOE_FLAGS, error))
628                 return FALSE;
629
630         if (!check_priority (priv->app_fcoe_priority, priv->app_fcoe_flags, NM_SETTING_DCB_APP_FCOE_PRIORITY, error))
631                 return FALSE;
632
633         if (!priv->app_fcoe_mode) {
634                 g_set_error_literal (error,
635                                      NM_CONNECTION_ERROR,
636                                      NM_CONNECTION_ERROR_MISSING_PROPERTY,
637                                      _("property missing"));
638                 g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, NM_SETTING_DCB_APP_FCOE_MODE);
639                 return FALSE;
640         }
641
642         if (strcmp (priv->app_fcoe_mode, NM_SETTING_DCB_FCOE_MODE_FABRIC) &&
643             strcmp (priv->app_fcoe_mode, NM_SETTING_DCB_FCOE_MODE_VN2VN)) {
644                 g_set_error_literal (error,
645                                      NM_CONNECTION_ERROR,
646                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
647                                      _("property invalid"));
648                 g_prefix_error (error, "%s.%s: ", NM_SETTING_DCB_SETTING_NAME, NM_SETTING_DCB_APP_FCOE_MODE);
649                 return FALSE;
650         }
651
652         if (!check_dcb_flags (priv->app_iscsi_flags, NM_SETTING_DCB_APP_ISCSI_FLAGS, error))
653                 return FALSE;
654
655         if (!check_priority (priv->app_iscsi_priority, priv->app_iscsi_flags, NM_SETTING_DCB_APP_ISCSI_PRIORITY, error))
656                 return FALSE;
657
658         if (!check_dcb_flags (priv->app_fip_flags, NM_SETTING_DCB_APP_FIP_FLAGS, error))
659                 return FALSE;
660
661         if (!check_priority (priv->app_fip_priority, priv->app_fip_flags, NM_SETTING_DCB_APP_FIP_PRIORITY, error))
662                 return FALSE;
663
664         if (!check_dcb_flags (priv->pfc_flags, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, error))
665                 return FALSE;
666
667         if (!check_uint_array (priv->pfc, G_N_ELEMENTS (priv->pfc), priv->pfc_flags, 1, 0, FALSE, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, error))
668                 return FALSE;
669
670         if (!check_dcb_flags (priv->priority_group_flags, NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, error))
671                 return FALSE;
672
673         if (!check_uint_array (priv->priority_group_id,
674                                G_N_ELEMENTS (priv->priority_group_id),
675                                priv->priority_group_flags,
676                                7,
677                                15,
678                                FALSE,
679                                NM_SETTING_DCB_PRIORITY_GROUP_ID,
680                                error))
681                 return FALSE;
682
683         if (!check_uint_array (priv->priority_group_bandwidth,
684                                G_N_ELEMENTS (priv->priority_group_bandwidth),
685                                priv->priority_group_flags,
686                                100,
687                                0,
688                                TRUE,
689                                NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH,
690                                error))
691                 return FALSE;
692
693         /* FIXME: sum bandwidths in each group */
694         if (!check_uint_array (priv->priority_bandwidth,
695                                G_N_ELEMENTS (priv->priority_bandwidth),
696                                priv->priority_group_flags,
697                                100,
698                                0,
699                                FALSE,
700                                NM_SETTING_DCB_PRIORITY_BANDWIDTH,
701                                error))
702                 return FALSE;
703
704         if (!check_uint_array (priv->priority_strict,
705                                G_N_ELEMENTS (priv->priority_strict),
706                                priv->priority_group_flags,
707                                1,
708                                0,
709                                FALSE,
710                                NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH,
711                                error))
712                 return FALSE;
713
714         if (!check_uint_array (priv->priority_traffic_class,
715                                G_N_ELEMENTS (priv->priority_traffic_class),
716                                priv->priority_group_flags,
717                                7,
718                                0,
719                                FALSE,
720                                NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS,
721                                error))
722                 return FALSE;
723
724         return TRUE;
725 }
726
727 /******************************************************************/
728
729 static void
730 nm_setting_dcb_init (NMSettingDcb *setting)
731 {
732 }
733
734 G_STATIC_ASSERT (sizeof (guint) == sizeof (gboolean));
735
736 static inline void
737 set_array_from_gvalue (const GValue *v, uint *a, size_t len)
738 {
739         GArray *src = g_value_get_boxed (v);
740         const guint total_len = len * sizeof (a[0]);
741
742         memset (a, 0, total_len);
743         if (src) {
744                 g_return_if_fail (g_array_get_element_size (src) == sizeof (a[0]));
745                 g_return_if_fail (src->len == len);
746                 memcpy (a, src->data, total_len);
747         }
748 }
749 #define SET_ARRAY_FROM_GVALUE(v, a)  set_array_from_gvalue (v, a, G_N_ELEMENTS (a))
750
751 static inline void
752 set_gvalue_from_array (GValue *v, uint *a, size_t len)
753 {
754         GArray *src = g_array_sized_new (FALSE, TRUE, sizeof (guint), len);
755
756         g_array_append_vals (src, a, len);
757         g_value_take_boxed (v, src);
758 }
759
760 #define SET_GVALUE_FROM_ARRAY(v, a) set_gvalue_from_array (v, a, G_N_ELEMENTS (a))
761
762 static GVariant *
763 _nm_setting_dcb_uint_array_to_dbus (const GValue *prop_value)
764 {
765         GArray *src = g_value_get_boxed (prop_value);
766
767         return g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, src->data, src->len, sizeof (guint32));
768 }
769
770 static void
771 _nm_setting_dcb_uint_array_from_dbus (GVariant *dbus_value,
772                                       GValue *prop_value)
773 {
774         gconstpointer array;
775         gsize length;
776
777         array = g_variant_get_fixed_array (dbus_value, &length, sizeof (guint32));
778         set_gvalue_from_array (prop_value, (guint *) array, length);
779 }
780
781 static void
782 set_property (GObject *object, guint prop_id,
783               const GValue *value, GParamSpec *pspec)
784 {
785         NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (object);
786
787         switch (prop_id) {
788         case PROP_APP_FCOE_FLAGS:
789                 priv->app_fcoe_flags = g_value_get_flags (value);
790                 break;
791         case PROP_APP_FCOE_PRIORITY:
792                 priv->app_fcoe_priority = g_value_get_int (value);
793                 break;
794         case PROP_APP_FCOE_MODE:
795                 g_free (priv->app_fcoe_mode);
796                 priv->app_fcoe_mode = g_value_dup_string (value);
797                 break;
798         case PROP_APP_ISCSI_FLAGS:
799                 priv->app_iscsi_flags = g_value_get_flags (value);
800                 break;
801         case PROP_APP_ISCSI_PRIORITY:
802                 priv->app_iscsi_priority = g_value_get_int (value);
803                 break;
804         case PROP_APP_FIP_FLAGS:
805                 priv->app_fip_flags = g_value_get_flags (value);
806                 break;
807         case PROP_APP_FIP_PRIORITY:
808                 priv->app_fip_priority = g_value_get_int (value);
809                 break;
810         case PROP_PFC_FLAGS:
811                 priv->pfc_flags = g_value_get_flags (value);
812                 break;
813         case PROP_PFC:
814                 SET_ARRAY_FROM_GVALUE (value, priv->pfc);
815                 break;
816         case PROP_PRIORITY_GROUP_FLAGS:
817                 priv->priority_group_flags = g_value_get_flags (value);
818                 break;
819         case PROP_PRIORITY_GROUP_ID:
820                 SET_ARRAY_FROM_GVALUE (value, priv->priority_group_id);
821                 break;
822         case PROP_PRIORITY_GROUP_BANDWIDTH:
823                 SET_ARRAY_FROM_GVALUE (value, priv->priority_group_bandwidth);
824                 break;
825         case PROP_PRIORITY_BANDWIDTH:
826                 SET_ARRAY_FROM_GVALUE (value, priv->priority_bandwidth);
827                 break;
828         case PROP_PRIORITY_STRICT:
829                 SET_ARRAY_FROM_GVALUE (value, priv->priority_strict);
830                 break;
831         case PROP_PRIORITY_TRAFFIC_CLASS:
832                 SET_ARRAY_FROM_GVALUE (value, priv->priority_traffic_class);
833                 break;
834         default:
835                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
836                 break;
837         }
838 }
839
840 static void
841 get_property (GObject *object, guint prop_id,
842               GValue *value, GParamSpec *pspec)
843 {
844         NMSettingDcb *setting = NM_SETTING_DCB (object);
845         NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (setting);
846
847         switch (prop_id) {
848         case PROP_APP_FCOE_FLAGS:
849                 g_value_set_flags (value, priv->app_fcoe_flags);
850                 break;
851         case PROP_APP_FCOE_PRIORITY:
852                 g_value_set_int (value, priv->app_fcoe_priority);
853                 break;
854         case PROP_APP_FCOE_MODE:
855                 g_value_set_string (value, priv->app_fcoe_mode);
856                 break;
857         case PROP_APP_ISCSI_FLAGS:
858                 g_value_set_flags (value, priv->app_iscsi_flags);
859                 break;
860         case PROP_APP_ISCSI_PRIORITY:
861                 g_value_set_int (value, priv->app_iscsi_priority);
862                 break;
863         case PROP_APP_FIP_FLAGS:
864                 g_value_set_flags (value, priv->app_fip_flags);
865                 break;
866         case PROP_APP_FIP_PRIORITY:
867                 g_value_set_int (value, priv->app_fip_priority);
868                 break;
869         case PROP_PFC_FLAGS:
870                 g_value_set_flags (value, priv->pfc_flags);
871                 break;
872         case PROP_PFC:
873                 SET_GVALUE_FROM_ARRAY (value, priv->pfc);
874                 break;
875         case PROP_PRIORITY_GROUP_FLAGS:
876                 g_value_set_flags (value, priv->priority_group_flags);
877                 break;
878         case PROP_PRIORITY_GROUP_ID:
879                 SET_GVALUE_FROM_ARRAY (value, priv->priority_group_id);
880                 break;
881         case PROP_PRIORITY_GROUP_BANDWIDTH:
882                 SET_GVALUE_FROM_ARRAY (value, priv->priority_group_bandwidth);
883                 break;
884         case PROP_PRIORITY_BANDWIDTH:
885                 SET_GVALUE_FROM_ARRAY (value, priv->priority_bandwidth);
886                 break;
887         case PROP_PRIORITY_STRICT:
888                 SET_GVALUE_FROM_ARRAY (value, priv->priority_strict);
889                 break;
890         case PROP_PRIORITY_TRAFFIC_CLASS:
891                 SET_GVALUE_FROM_ARRAY (value, priv->priority_traffic_class);
892                 break;
893         default:
894                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
895                 break;
896         }
897 }
898
899 static void
900 finalize (GObject *object)
901 {
902         NMSettingDcbPrivate *priv = NM_SETTING_DCB_GET_PRIVATE (object);
903
904         g_free (priv->app_fcoe_mode);
905
906         G_OBJECT_CLASS (nm_setting_dcb_parent_class)->finalize (object);
907 }
908
909 static void
910 nm_setting_dcb_class_init (NMSettingDcbClass *setting_class)
911 {
912         GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
913         NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
914
915         g_type_class_add_private (setting_class, sizeof (NMSettingDcbPrivate));
916
917         /* virtual methods */
918         object_class->set_property = set_property;
919         object_class->get_property = get_property;
920         object_class->finalize = finalize;
921         parent_class->verify       = verify;
922
923         /* Properties */
924         /**
925          * NMSettingDcb:app-fcoe-flags:
926          *
927          * Specifies the #NMSettingDcbFlags for the DCB FCoE application.  Flags may
928          * be any combination of %NM_SETTING_DCB_FLAG_ENABLE,
929          * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING.
930          **/
931         /* ---ifcfg-rh---
932          * property: app-fcoe-flags
933          * variable: DCB_APP_FCOE_ENABLE, DCB_APP_FCOE_ADVERTISE, DCB_APP_FCOE_WILLING
934          * description: FCOE flags.
935          * default: no
936          * example: DCB_APP_FCOE_ENABLE=yes DCB_APP_FCOE_ADVERTISE=yes
937          * ---end---
938          */
939         g_object_class_install_property
940                 (object_class, PROP_APP_FCOE_FLAGS,
941                  g_param_spec_flags (NM_SETTING_DCB_APP_FCOE_FLAGS, "", "",
942                                      NM_TYPE_SETTING_DCB_FLAGS,
943                                      NM_SETTING_DCB_FLAG_NONE,
944                                      G_PARAM_READWRITE |
945                                      G_PARAM_STATIC_STRINGS));
946
947         /**
948          * NMSettingDcb:app-fcoe-priority:
949          *
950          * The highest User Priority (0 - 7) which FCoE frames should use, or -1 for
951          * default priority.  Only used when the #NMSettingDcb:app-fcoe-flags
952          * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag.
953          **/
954         /* ---ifcfg-rh---
955          * property: app-fcoe-priority
956          * variable: DCB_APP_FCOE_PRIORITY
957          * values: 0 - 7
958          * description: Priority of FCoE frames.
959          * ---end---
960          */
961         g_object_class_install_property
962                 (object_class, PROP_APP_FCOE_PRIORITY,
963                  g_param_spec_int (NM_SETTING_DCB_APP_FCOE_PRIORITY, "", "",
964                                    -1, 7, -1,
965                                    G_PARAM_READWRITE |
966                                    G_PARAM_CONSTRUCT |
967                                    G_PARAM_STATIC_STRINGS));
968
969         /**
970          * NMSettingDcb:app-fcoe-mode:
971          *
972          * The FCoE controller mode; either %NM_SETTING_DCB_FCOE_MODE_FABRIC
973          * (default) or %NM_SETTING_DCB_FCOE_MODE_VN2VN.
974          **/
975         /* ---ifcfg-rh---
976          * property: app-fcoe-mode
977          * variable: DCB_APP_FCOE_MODE
978          * values: fabric, vn2vn
979          * default: fabric
980          * description: FCoE controller mode.
981          * ---end---
982          */
983         g_object_class_install_property
984                 (object_class, PROP_APP_FCOE_MODE,
985                  g_param_spec_string (NM_SETTING_DCB_APP_FCOE_MODE, "", "",
986                                       NM_SETTING_DCB_FCOE_MODE_FABRIC,
987                                       G_PARAM_READWRITE |
988                                       G_PARAM_CONSTRUCT |
989                                       G_PARAM_STATIC_STRINGS));
990
991         /**
992          * NMSettingDcb:app-iscsi-flags:
993          *
994          * Specifies the #NMSettingDcbFlags for the DCB iSCSI application.  Flags
995          * may be any combination of %NM_SETTING_DCB_FLAG_ENABLE,
996          * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING.
997          **/
998         /* ---ifcfg-rh---
999          * property: app-iscsi-flags
1000          * variable: DCB_APP_ISCSI_ENABLE, DCB_APP_ISCSI_ADVERTISE, DCB_APP_ISCSI_WILLING
1001          * default: no
1002          * description: iSCSI flags.
1003          * ---end---
1004          */
1005         g_object_class_install_property
1006                 (object_class, PROP_APP_ISCSI_FLAGS,
1007                  g_param_spec_flags (NM_SETTING_DCB_APP_ISCSI_FLAGS, "", "",
1008                                      NM_TYPE_SETTING_DCB_FLAGS,
1009                                      NM_SETTING_DCB_FLAG_NONE,
1010                                      G_PARAM_READWRITE |
1011                                      G_PARAM_STATIC_STRINGS));
1012
1013         /**
1014          * NMSettingDcb:app-iscsi-priority:
1015          *
1016          * The highest User Priority (0 - 7) which iSCSI frames should use, or -1
1017          * for default priority. Only used when the #NMSettingDcb:app-iscsi-flags
1018          * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag.
1019          **/
1020         /* ---ifcfg-rh---
1021          * property: app-iscsi-priority
1022          * variable: DCB_APP_ISCSI_PRIORITY
1023          * values: 0 - 7
1024          * description: Priority of iSCSI frames.
1025          * ---end---
1026          */
1027         g_object_class_install_property
1028                 (object_class, PROP_APP_ISCSI_PRIORITY,
1029                  g_param_spec_int (NM_SETTING_DCB_APP_ISCSI_PRIORITY, "", "",
1030                                    -1, 7, -1,
1031                                    G_PARAM_READWRITE |
1032                                    G_PARAM_CONSTRUCT |
1033                                    G_PARAM_STATIC_STRINGS));
1034
1035         /**
1036          * NMSettingDcb:app-fip-flags:
1037          *
1038          * Specifies the #NMSettingDcbFlags for the DCB FIP application.  Flags may
1039          * be any combination of %NM_SETTING_DCB_FLAG_ENABLE,
1040          * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING.
1041          **/
1042         /* ---ifcfg-rh---
1043          * property: app-fip-flags
1044          * variable: DCB_APP_FIP_ENABLE, DCB_APP_FIP_ADVERTISE, DCB_APP_FIP_WILLING
1045          * default: no
1046          * description: FIP flags.
1047          * ---end---
1048          */
1049         g_object_class_install_property
1050                 (object_class, PROP_APP_FIP_FLAGS,
1051                  g_param_spec_flags (NM_SETTING_DCB_APP_FIP_FLAGS, "", "",
1052                                      NM_TYPE_SETTING_DCB_FLAGS,
1053                                      NM_SETTING_DCB_FLAG_NONE,
1054                                      G_PARAM_READWRITE |
1055                                      G_PARAM_STATIC_STRINGS));
1056
1057         /**
1058          * NMSettingDcb:app-fip-priority:
1059          *
1060          * The highest User Priority (0 - 7) which FIP frames should use, or -1 for
1061          * default priority.  Only used when the #NMSettingDcb:app-fip-flags
1062          * property includes the %NM_SETTING_DCB_FLAG_ENABLE flag.
1063          **/
1064         /* ---ifcfg-rh---
1065          * property: app-fip-priority
1066          * variable: DCB_APP_FIP_PRIORITY
1067          * values: 0 - 7
1068          * description: Priority of FIP frames.
1069          * ---end---
1070          */
1071         g_object_class_install_property
1072                 (object_class, PROP_APP_FIP_PRIORITY,
1073                  g_param_spec_int (NM_SETTING_DCB_APP_FIP_PRIORITY, "", "",
1074                                    -1, 7, -1,
1075                                    G_PARAM_READWRITE |
1076                                    G_PARAM_CONSTRUCT |
1077                                    G_PARAM_STATIC_STRINGS));
1078
1079         /**
1080          * NMSettingDcb:priority-flow-control-flags:
1081          *
1082          * Specifies the #NMSettingDcbFlags for DCB Priority Flow Control (PFC).
1083          * Flags may be any combination of %NM_SETTING_DCB_FLAG_ENABLE,
1084          * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING.
1085          **/
1086         /* ---ifcfg-rh---
1087          * property: priority-flow-control-flags
1088          * variable: DCB_PFC_ENABLE, DCB_PFC_ADVERTISE, DCB_PFC_WILLING
1089          * default: no
1090          * description: Priority flow control flags.
1091          * ---end---
1092          */
1093         g_object_class_install_property
1094                 (object_class, PROP_PFC_FLAGS,
1095                  g_param_spec_flags (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, "", "",
1096                                      NM_TYPE_SETTING_DCB_FLAGS,
1097                                      NM_SETTING_DCB_FLAG_NONE,
1098                                      G_PARAM_READWRITE |
1099                                      G_PARAM_STATIC_STRINGS));
1100
1101         /**
1102          * NMSettingDcb:priority-flow-control:
1103          *
1104          * An array of 8 boolean values, where the array index corresponds to the User
1105          * Priority (0 - 7) and the value indicates whether or not the corresponding
1106          * priority should transmit priority pause.
1107          *
1108          * Element-type: gboolean
1109          **/
1110         /* ---ifcfg-rh---
1111          * property: priority-flow-control
1112          * variable: DCB_PFC_UP
1113          * description: Priority flow control values. String of 8 "0" and "1", where "0".
1114          *   means "do not transmit priority pause", "1" means "transmit pause".
1115          * example: DCB_PFC_UP=01101110
1116          * ---end---
1117          */
1118         g_object_class_install_property
1119                 (object_class, PROP_PFC,
1120                  g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL, "", "",
1121                                      G_TYPE_ARRAY,
1122                                      G_PARAM_READWRITE |
1123                                      G_PARAM_STATIC_STRINGS));
1124         _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_FLOW_CONTROL,
1125                                               G_VARIANT_TYPE ("au"),
1126                                               _nm_setting_dcb_uint_array_to_dbus,
1127                                               _nm_setting_dcb_uint_array_from_dbus);
1128
1129         /**
1130          * NMSettingDcb:priority-group-flags:
1131          *
1132          * Specifies the #NMSettingDcbFlags for DCB Priority Groups.  Flags may be
1133          * any combination of %NM_SETTING_DCB_FLAG_ENABLE,
1134          * %NM_SETTING_DCB_FLAG_ADVERTISE, and %NM_SETTING_DCB_FLAG_WILLING.
1135          **/
1136         /* ---ifcfg-rh---
1137          * property: priority-group-flags
1138          * variable: DCB_PG_ENABLE, DCB_PG_ADVERTISE, DCB_PG_WILLING
1139          * default: no
1140          * description: Priority groups flags.
1141          * ---end---
1142          */
1143         g_object_class_install_property
1144                 (object_class, PROP_PRIORITY_GROUP_FLAGS,
1145                  g_param_spec_flags (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, "", "",
1146                                      NM_TYPE_SETTING_DCB_FLAGS,
1147                                      NM_SETTING_DCB_FLAG_NONE,
1148                                      G_PARAM_READWRITE |
1149                                      G_PARAM_STATIC_STRINGS));
1150
1151         /**
1152          * NMSettingDcb:priority-group-id:
1153          *
1154          * An array of 8 uint values, where the array index corresponds to the User
1155          * Priority (0 - 7) and the value indicates the Priority Group ID.  Allowed
1156          * Priority Group ID values are 0 - 7 or 15 for the unrestricted group.
1157          *
1158          * Element-type: guint
1159          **/
1160         /* ---ifcfg-rh---
1161          * property: priority-group-id
1162          * variable: DCB_PG_ID
1163          * description: Priority groups values. String of eight priorities (0 - 7) or "f"
1164          *   (unrestricted).
1165          * example: DCB_PG_ID=1205f173
1166          * ---end---
1167          */
1168         g_object_class_install_property
1169                 (object_class, PROP_PRIORITY_GROUP_ID,
1170                  g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_GROUP_ID, "", "",
1171                                      G_TYPE_ARRAY,
1172                                      G_PARAM_READWRITE |
1173                                      G_PARAM_STATIC_STRINGS));
1174         _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_ID,
1175                                               G_VARIANT_TYPE ("au"),
1176                                               _nm_setting_dcb_uint_array_to_dbus,
1177                                               _nm_setting_dcb_uint_array_from_dbus);
1178
1179         /**
1180          * NMSettingDcb:priority-group-bandwidth:
1181          *
1182          * An array of 8 uint values, where the array index corresponds to the
1183          * Priority Group ID (0 - 7) and the value indicates the percentage of link
1184          * bandwidth allocated to that group.  Allowed values are 0 - 100, and the
1185          * sum of all values must total 100 percent.
1186          *
1187          * Element-type: guint
1188          **/
1189         /* ---ifcfg-rh---
1190          * property: priority-group-bandwidth
1191          * variable: DCB_PG_PCT
1192          * description: Priority groups values. Eight bandwidths (in percent), separated with commas.
1193          * example: DCB_PG_PCT=10,5,10,15,10,10,10,30
1194          * ---end---
1195          */
1196         g_object_class_install_property
1197                 (object_class, PROP_PRIORITY_GROUP_BANDWIDTH,
1198                  g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH, "", "",
1199                                      G_TYPE_ARRAY,
1200                                      G_PARAM_READWRITE |
1201                                      G_PARAM_STATIC_STRINGS));
1202         _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH,
1203                                               G_VARIANT_TYPE ("au"),
1204                                               _nm_setting_dcb_uint_array_to_dbus,
1205                                               _nm_setting_dcb_uint_array_from_dbus);
1206
1207         /**
1208          * NMSettingDcb:priority-bandwidth:
1209          *
1210          * An array of 8 uint values, where the array index corresponds to the User
1211          * Priority (0 - 7) and the value indicates the percentage of bandwidth of
1212          * the priority's assigned group that the priority may use.  The sum of all
1213          * percentages for priorities which belong to the same group must total 100
1214          * percent.
1215          *
1216          * Element-type: guint
1217          **/
1218         /* ---ifcfg-rh---
1219          * property: priority-bandwidth
1220          * variable: DCB_PG_UPPCT
1221          * description: Priority values. Eight bandwidths (in percent), separated with commas.
1222          *   The sum of the numbers must be 100.
1223          * example: DCB_PG_UPPCT=7,13,10,10,15,15,10,20
1224          * ---end---
1225          */
1226         g_object_class_install_property
1227                 (object_class, PROP_PRIORITY_BANDWIDTH,
1228                  g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_BANDWIDTH, "", "",
1229                                      G_TYPE_ARRAY,
1230                                      G_PARAM_READWRITE |
1231                                      G_PARAM_STATIC_STRINGS));
1232         _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_BANDWIDTH,
1233                                               G_VARIANT_TYPE ("au"),
1234                                               _nm_setting_dcb_uint_array_to_dbus,
1235                                               _nm_setting_dcb_uint_array_from_dbus);
1236
1237         /**
1238          * NMSettingDcb:priority-strict-bandwidth:
1239          *
1240          * An array of 8 boolean values, where the array index corresponds to the User
1241          * Priority (0 - 7) and the value indicates whether or not the priority may
1242          * use all of the bandwidth allocated to its assigned group.
1243          *
1244          * Element-type: gboolean
1245          **/
1246         /* ---ifcfg-rh---
1247          * property: priority-strict-bandwidth
1248          * variable: DCB_PG_STRICT
1249          * description: Priority values. String of eight "0" or "1", where "0" means
1250          *   "may not utilize all bandwidth", "1" means "may utilize all bandwidth".
1251          * example: DCB_PG_STRICT=01101110
1252          * ---end---
1253          */
1254         g_object_class_install_property
1255                 (object_class, PROP_PRIORITY_STRICT,
1256                  g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH, "", "",
1257                                      G_TYPE_ARRAY,
1258                                      G_PARAM_READWRITE |
1259                                      G_PARAM_STATIC_STRINGS));
1260         _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH,
1261                                               G_VARIANT_TYPE ("au"),
1262                                               _nm_setting_dcb_uint_array_to_dbus,
1263                                               _nm_setting_dcb_uint_array_from_dbus);
1264
1265         /**
1266          * NMSettingDcb:priority-traffic-class:
1267          *
1268          * An array of 8 uint values, where the array index corresponds to the User
1269          * Priority (0 - 7) and the value indicates the traffic class (0 - 7) to
1270          * which the priority is mapped.
1271          *
1272          * Element-type: guint
1273          **/
1274         /* ---ifcfg-rh---
1275          * property: priority-traffic-class
1276          * variable: DCB_PG_UP2TC
1277          * description: Priority values. String of eight trafic class values (0 - 7).
1278          * example: DCB_PG_UP2TC=01623701
1279          * ---end---
1280          */
1281         g_object_class_install_property
1282                 (object_class, PROP_PRIORITY_TRAFFIC_CLASS,
1283                  g_param_spec_boxed (NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS, "", "",
1284                                      G_TYPE_ARRAY,
1285                                      G_PARAM_READWRITE |
1286                                      G_PARAM_STATIC_STRINGS));
1287         _nm_setting_class_transform_property (parent_class, NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS,
1288                                               G_VARIANT_TYPE ("au"),
1289                                               _nm_setting_dcb_uint_array_to_dbus,
1290                                               _nm_setting_dcb_uint_array_from_dbus);
1291 }