00341accc253a54d47b7813b31188217817952f1
[NetworkManager.git] / libnm-core / nm-setting-macvlan.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 2015 Red Hat, Inc.
20  */
21
22 #include "nm-default.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "nm-setting-macvlan.h"
28 #include "nm-utils.h"
29 #include "nm-setting-connection.h"
30 #include "nm-setting-private.h"
31 #include "nm-setting-wired.h"
32 #include "nm-connection-private.h"
33
34 /**
35  * SECTION:nm-setting-macvlan
36  * @short_description: Describes connection properties for macvlan interfaces
37  *
38  * The #NMSettingMacvlan object is a #NMSetting subclass that describes properties
39  * necessary for connection to macvlan interfaces.
40  **/
41
42 G_DEFINE_TYPE_WITH_CODE (NMSettingMacvlan, nm_setting_macvlan, NM_TYPE_SETTING,
43                          _nm_register_setting (MACVLAN, 1))
44 NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_MACVLAN)
45
46 #define NM_SETTING_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_MACVLAN, NMSettingMacvlanPrivate))
47
48 typedef struct {
49         char *parent;
50         NMSettingMacvlanMode mode;
51         gboolean promiscuous;
52         gboolean tap;
53 } NMSettingMacvlanPrivate;
54
55 enum {
56         PROP_0,
57         PROP_PARENT,
58         PROP_MODE,
59         PROP_PROMISCUOUS,
60         PROP_TAP,
61         LAST_PROP
62 };
63
64 /**
65  * nm_setting_macvlan_new:
66  *
67  * Creates a new #NMSettingMacvlan object with default values.
68  *
69  * Returns: (transfer full): the new empty #NMSettingMacvlan object
70  *
71  * Since: 1.2
72  **/
73 NMSetting *
74 nm_setting_macvlan_new (void)
75 {
76         return (NMSetting *) g_object_new (NM_TYPE_SETTING_MACVLAN, NULL);
77 }
78
79 /**
80  * nm_setting_macvlan_get_parent:
81  * @setting: the #NMSettingMacvlan
82  *
83  * Returns: the #NMSettingMacvlan:parent property of the setting
84  *
85  * Since: 1.2
86  **/
87 const char *
88 nm_setting_macvlan_get_parent (NMSettingMacvlan *setting)
89 {
90         g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NULL);
91         return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->parent;
92 }
93
94 /**
95  * nm_setting_macvlan_get_mode:
96  * @setting: the #NMSettingMacvlan
97  *
98  * Returns: the #NMSettingMacvlan:mode property of the setting
99  *
100  * Since: 1.2
101  **/
102 NMSettingMacvlanMode
103 nm_setting_macvlan_get_mode (NMSettingMacvlan *setting)
104 {
105         g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), NM_SETTING_MACVLAN_MODE_UNKNOWN);
106         return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->mode;
107 }
108
109 /**
110  * nm_setting_macvlan_get_promiscuous:
111  * @setting: the #NMSettingMacvlan
112  *
113  * Returns: the #NMSettingMacvlan:promiscuous property of the setting
114  *
115  * Since: 1.2
116  **/
117 gboolean
118 nm_setting_macvlan_get_promiscuous (NMSettingMacvlan *setting)
119 {
120         g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE);
121         return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->promiscuous;
122 }
123
124 /**
125  * nm_setting_macvlan_get_tap:
126  * @setting: the #NMSettingMacvlan
127  *
128  * Returns: the #NMSettingMacvlan:tap property of the setting
129  *
130  * Since: 1.2
131  **/
132 gboolean
133 nm_setting_macvlan_get_tap (NMSettingMacvlan *setting)
134 {
135         g_return_val_if_fail (NM_IS_SETTING_MACVLAN (setting), FALSE);
136         return NM_SETTING_MACVLAN_GET_PRIVATE (setting)->tap;
137 }
138
139 /*********************************************************************/
140
141 static void
142 nm_setting_macvlan_init (NMSettingMacvlan *setting)
143 {
144 }
145
146 static gboolean
147 verify (NMSetting *setting, NMConnection *connection, GError **error)
148 {
149         NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
150         NMSettingConnection *s_con;
151         NMSettingWired *s_wired;
152
153         if (connection) {
154                 s_con = nm_connection_get_setting_connection (connection);
155                 s_wired = nm_connection_get_setting_wired (connection);
156         } else {
157                 s_con = NULL;
158                 s_wired = NULL;
159         }
160
161         if (priv->parent) {
162                 if (   !nm_utils_is_uuid (priv->parent)
163                     && !nm_utils_iface_valid_name (priv->parent)) {
164                         g_set_error (error,
165                                      NM_CONNECTION_ERROR,
166                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
167                                      _("'%s' is neither an UUID nor an interface name"),
168                                      priv->parent);
169                         g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT);
170                         return FALSE;
171                 }
172         } else {
173                 /* If parent is NULL, the parent must be specified via
174                  * NMSettingWired:mac-address.
175                  */
176                 if (   connection
177                     && (!s_wired || !nm_setting_wired_get_mac_address (s_wired))) {
178                         g_set_error (error,
179                                      NM_CONNECTION_ERROR,
180                                      NM_CONNECTION_ERROR_MISSING_PROPERTY,
181                                      _("property is not specified and neither is '%s:%s'"),
182                                      NM_SETTING_WIRED_SETTING_NAME, NM_SETTING_WIRED_MAC_ADDRESS);
183                         g_prefix_error (error, "%s.%s: ", NM_SETTING_MACVLAN_SETTING_NAME, NM_SETTING_MACVLAN_PARENT);
184                         return FALSE;
185                 }
186         }
187
188         if (!priv->promiscuous && priv->mode != NM_SETTING_MACVLAN_MODE_PASSTHRU) {
189                 g_set_error_literal (error,
190                                      NM_CONNECTION_ERROR,
191                                      NM_CONNECTION_ERROR_INVALID_PROPERTY,
192                                      _("non promiscuous operation is allowed only in passthru mode'"));
193                 g_prefix_error (error, "%s.%s: ",
194                                 NM_SETTING_MACVLAN_SETTING_NAME,
195                                 NM_SETTING_MACVLAN_PROMISCUOUS);
196                 return FALSE;
197
198         }
199
200         return TRUE;
201 }
202
203 static void
204 set_property (GObject *object, guint prop_id,
205               const GValue *value, GParamSpec *pspec)
206 {
207         NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object);
208         NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
209
210         switch (prop_id) {
211         case PROP_PARENT:
212                 g_free (priv->parent);
213                 priv->parent = g_value_dup_string (value);
214                 break;
215         case PROP_MODE:
216                 priv->mode = g_value_get_uint (value);
217                 break;
218         case PROP_PROMISCUOUS:
219                 priv->promiscuous = g_value_get_boolean (value);
220                 break;
221         case PROP_TAP:
222                 priv->tap = g_value_get_boolean (value);
223                 break;
224         default:
225                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
226                 break;
227         }
228 }
229
230 static void
231 get_property (GObject *object, guint prop_id,
232               GValue *value, GParamSpec *pspec)
233 {
234         NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object);
235         NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
236
237         switch (prop_id) {
238         case PROP_PARENT:
239                 g_value_set_string (value, priv->parent);
240                 break;
241         case PROP_MODE:
242                 g_value_set_uint (value, priv->mode);
243                 break;
244         case PROP_PROMISCUOUS:
245                 g_value_set_boolean (value, priv->promiscuous);
246                 break;
247         case PROP_TAP:
248                 g_value_set_boolean (value, priv->tap);
249                 break;
250         default:
251                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
252                 break;
253         }
254 }
255
256 static void
257 finalize (GObject *object)
258 {
259         NMSettingMacvlan *setting = NM_SETTING_MACVLAN (object);
260         NMSettingMacvlanPrivate *priv = NM_SETTING_MACVLAN_GET_PRIVATE (setting);
261
262         g_free (priv->parent);
263
264         G_OBJECT_CLASS (nm_setting_macvlan_parent_class)->finalize (object);
265 }
266
267 static void
268 nm_setting_macvlan_class_init (NMSettingMacvlanClass *setting_class)
269 {
270         GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
271         NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
272
273         g_type_class_add_private (setting_class, sizeof (NMSettingMacvlanPrivate));
274
275         /* virtual methods */
276         object_class->set_property = set_property;
277         object_class->get_property = get_property;
278         object_class->finalize     = finalize;
279         parent_class->verify       = verify;
280
281         /* Properties */
282
283         /**
284          * NMSettingMacvlan:parent:
285          *
286          * If given, specifies the parent interface name or parent connection UUID
287          * from which this MAC-VLAN interface should be created.  If this property is
288          * not specified, the connection must contain an #NMSettingWired setting
289          * with a #NMSettingWired:mac-address property.
290          *
291          * Since: 1.2
292          **/
293         g_object_class_install_property
294                 (object_class, PROP_PARENT,
295                  g_param_spec_string (NM_SETTING_MACVLAN_PARENT, "", "",
296                                       NULL,
297                                       G_PARAM_READWRITE |
298                                       G_PARAM_CONSTRUCT |
299                                       NM_SETTING_PARAM_INFERRABLE |
300                                       G_PARAM_STATIC_STRINGS));
301
302         /**
303          * NMSettingMacvlan:mode:
304          *
305          * The macvlan mode, which specifies the communication mechanism between multiple
306          * macvlans on the same lower device.
307          *
308          * Since: 1.2
309          **/
310         g_object_class_install_property
311                 (object_class, PROP_MODE,
312                  g_param_spec_uint (NM_SETTING_MACVLAN_MODE, "", "",
313                                     0, G_MAXUINT, 0,
314                                     G_PARAM_READWRITE |
315                                     G_PARAM_CONSTRUCT |
316                                     NM_SETTING_PARAM_INFERRABLE |
317                                     G_PARAM_STATIC_STRINGS));
318
319         /**
320          * NMSettingMacvlan:promiscuous:
321          *
322          * Whether the interface should be put in promiscuous mode.
323          *
324          * Since: 1.2
325          **/
326         g_object_class_install_property
327                 (object_class, PROP_PROMISCUOUS,
328                  g_param_spec_boolean (NM_SETTING_MACVLAN_PROMISCUOUS, "", "",
329                                        TRUE,
330                                        G_PARAM_READWRITE |
331                                        G_PARAM_CONSTRUCT |
332                                        NM_SETTING_PARAM_INFERRABLE |
333                                        G_PARAM_STATIC_STRINGS));
334
335         /**
336          * NMSettingMacvlan:tap:
337          *
338          * Whether the interface should be a MACVTAP.
339          *
340          * Since: 1.2
341          **/
342         g_object_class_install_property
343                 (object_class, PROP_TAP,
344                  g_param_spec_boolean (NM_SETTING_MACVLAN_TAP, "", "",
345                                        FALSE,
346                                        G_PARAM_READWRITE |
347                                        G_PARAM_CONSTRUCT |
348                                        NM_SETTING_PARAM_INFERRABLE |
349                                        G_PARAM_STATIC_STRINGS));
350 }