device: renew dhcp leases on awake for software devices
[NetworkManager.git] / libnm / nm-device-macvlan.c
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 /*
3  * This library is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU Lesser General Public
5  * License as published by the Free Software Foundation; either
6  * version 2 of the License, or (at your option) any later version.
7  *
8  * This library is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public
14  * License along with this library; if not, write to the
15  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16  * Boston, MA 02110-1301 USA.
17  *
18  * Copyright 2015 Red Hat, Inc.
19  */
20
21 #include "nm-default.h"
22
23 #include <string.h>
24
25 #include "nm-setting-connection.h"
26 #include "nm-setting-macvlan.h"
27 #include "nm-setting-wired.h"
28 #include "nm-utils.h"
29
30 #include "nm-device-macvlan.h"
31 #include "nm-device-private.h"
32 #include "nm-object-private.h"
33
34 G_DEFINE_TYPE (NMDeviceMacvlan, nm_device_macvlan, NM_TYPE_DEVICE)
35
36 #define NM_DEVICE_MACVLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlanPrivate))
37
38 typedef struct {
39         NMDevice *parent;
40         char *mode;
41         gboolean no_promisc;
42         gboolean tap;
43         char *hw_address;
44 } NMDeviceMacvlanPrivate;
45
46 enum {
47         PROP_0,
48         PROP_PARENT,
49         PROP_MODE,
50         PROP_NO_PROMISC,
51         PROP_TAP,
52         PROP_HW_ADDRESS,
53
54         LAST_PROP
55 };
56
57 /**
58  * nm_device_macvlan_get_parent:
59  * @device: a #NMDeviceMacvlan
60  *
61  * Returns: (transfer none): the device's parent device
62  *
63  * Since: 1.2
64  **/
65 NMDevice *
66 nm_device_macvlan_get_parent (NMDeviceMacvlan *device)
67 {
68         g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE);
69
70         return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->parent;
71 }
72
73 /**
74  * nm_device_macvlan_get_mode:
75  * @device: a #NMDeviceMacvlan
76  *
77  * Gets the MACVLAN mode of the device.
78  *
79  * Returns: the MACVLAN mode. This is the internal string used by the
80  * device, and must not be modified.
81  *
82  * Since: 1.2
83  **/
84 const char *
85 nm_device_macvlan_get_mode (NMDeviceMacvlan *device)
86 {
87         g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), NULL);
88
89         return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->mode;
90 }
91
92 /**
93  * nm_device_macvlan_get_no_promisc
94  * @device: a #NMDeviceMacvlan
95  *
96  * Gets the no-promiscuous flag of the device.
97  *
98  * Returns: the no-promiscuous flag of the device.
99  *
100  * Since: 1.2
101  **/
102 gboolean
103 nm_device_macvlan_get_no_promisc (NMDeviceMacvlan *device)
104 {
105         g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE);
106
107         return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->no_promisc;
108 }
109
110 /**
111  * nm_device_macvlan_get_tap:
112  * @device: a #NMDeviceMacvlan
113  *
114  * Gets the device type (MACVLAN or MACVTAP).
115  *
116  * Returns: %TRUE if the device is a MACVTAP, %FALSE if it is a MACVLAN.
117  *
118  * Since: 1.2
119  **/
120 gboolean
121 nm_device_macvlan_get_tap (NMDeviceMacvlan *device)
122 {
123         g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), FALSE);
124
125         return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->tap;
126 }
127
128 /**
129  * nm_device_macvlan_get_hw_address:
130  * @device: a #NMDeviceMacvlan
131  *
132  * Gets the hardware (MAC) address of the #NMDeviceMacvlan
133  *
134  * Returns: the hardware address. This is the internal string used by the
135  * device, and must not be modified.
136  *
137  * Since: 1.2
138  **/
139 const char *
140 nm_device_macvlan_get_hw_address (NMDeviceMacvlan *device)
141 {
142         g_return_val_if_fail (NM_IS_DEVICE_MACVLAN (device), NULL);
143
144         return NM_DEVICE_MACVLAN_GET_PRIVATE (device)->hw_address;
145 }
146
147
148 static gboolean
149 connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
150 {
151         NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (device);
152         NMSettingMacvlan *s_macvlan;
153
154         if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->connection_compatible (device, connection, error))
155                 return FALSE;
156
157         if (!nm_connection_is_type (connection, NM_SETTING_MACVLAN_SETTING_NAME)) {
158                 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
159                                      _("The connection was not a MAC-VLAN connection."));
160                 return FALSE;
161         }
162
163         s_macvlan = nm_connection_get_setting_macvlan (connection);
164         if (s_macvlan) {
165                 if (nm_setting_macvlan_get_tap (s_macvlan) != priv->tap)
166                         return FALSE;
167         }
168
169         return TRUE;
170 }
171
172 static const char *
173 get_hw_address (NMDevice *device)
174 {
175         return nm_device_macvlan_get_hw_address (NM_DEVICE_MACVLAN (device));
176 }
177
178 static GType
179 get_setting_type (NMDevice *device)
180 {
181         return NM_TYPE_SETTING_MACVLAN;
182 }
183
184 /***********************************************************/
185
186 static void
187 nm_device_macvlan_init (NMDeviceMacvlan *device)
188 {
189         _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_MACVLAN);
190 }
191
192 static void
193 init_dbus (NMObject *object)
194 {
195         NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
196         const NMPropertiesInfo property_info[] = {
197                 { NM_DEVICE_MACVLAN_PARENT,      &priv->parent, NULL, NM_TYPE_DEVICE },
198                 { NM_DEVICE_MACVLAN_MODE,        &priv->mode },
199                 { NM_DEVICE_MACVLAN_NO_PROMISC,  &priv->no_promisc },
200                 { NM_DEVICE_MACVLAN_TAP,         &priv->tap },
201                 { NM_DEVICE_MACVLAN_HW_ADDRESS,  &priv->hw_address },
202                 { NULL },
203         };
204
205         NM_OBJECT_CLASS (nm_device_macvlan_parent_class)->init_dbus (object);
206
207         _nm_object_register_properties (object,
208                                         NM_DBUS_INTERFACE_DEVICE_MACVLAN,
209                                         property_info);
210 }
211
212 static void
213 finalize (GObject *object)
214 {
215         NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE (object);
216
217         g_free (priv->mode);
218         g_free (priv->hw_address);
219         g_clear_object (&priv->parent);
220
221         G_OBJECT_CLASS (nm_device_macvlan_parent_class)->finalize (object);
222 }
223
224 static void
225 get_property (GObject *object,
226               guint prop_id,
227               GValue *value,
228               GParamSpec *pspec)
229 {
230         NMDeviceMacvlan *device = NM_DEVICE_MACVLAN (object);
231
232         switch (prop_id) {
233         case PROP_PARENT:
234                 g_value_set_object (value, nm_device_macvlan_get_parent (device));
235                 break;
236         case PROP_MODE:
237                 g_value_set_string (value, nm_device_macvlan_get_mode (device));
238                 break;
239         case PROP_NO_PROMISC:
240                 g_value_set_boolean (value, nm_device_macvlan_get_no_promisc (device));
241                 break;
242         case PROP_TAP:
243                 g_value_set_boolean (value, nm_device_macvlan_get_tap (device));
244                 break;
245         case PROP_HW_ADDRESS:
246                 g_value_set_string (value, nm_device_macvlan_get_hw_address (device));
247                 break;
248         default:
249                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
250                 break;
251         }
252 }
253
254 static void
255 nm_device_macvlan_class_init (NMDeviceMacvlanClass *gre_class)
256 {
257         GObjectClass *object_class = G_OBJECT_CLASS (gre_class);
258         NMObjectClass *nm_object_class = NM_OBJECT_CLASS (gre_class);
259         NMDeviceClass *device_class = NM_DEVICE_CLASS (gre_class);
260
261         g_type_class_add_private (gre_class, sizeof (NMDeviceMacvlanPrivate));
262
263         _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_MACVLAN);
264
265         /* virtual methods */
266         object_class->finalize = finalize;
267         object_class->get_property = get_property;
268
269         nm_object_class->init_dbus = init_dbus;
270
271         device_class->connection_compatible = connection_compatible;
272         device_class->get_setting_type = get_setting_type;
273         device_class->get_hw_address = get_hw_address;
274
275         /* properties */
276
277         /**
278          * NMDeviceMacvlan:parent:
279          *
280          * The devices's parent device.
281          *
282          * Since: 1.2
283          **/
284         g_object_class_install_property
285             (object_class, PROP_PARENT,
286              g_param_spec_object (NM_DEVICE_MACVLAN_PARENT, "", "",
287                                   NM_TYPE_DEVICE,
288                                   G_PARAM_READABLE |
289                                   G_PARAM_STATIC_STRINGS));
290
291         /**
292          * NMDeviceMacvlan:mode:
293          *
294          * The MACVLAN mode.
295          *
296          * Since: 1.2
297          **/
298         g_object_class_install_property
299                 (object_class, PROP_MODE,
300                  g_param_spec_string (NM_DEVICE_MACVLAN_MODE, "", "",
301                                       NULL,
302                                       G_PARAM_READABLE |
303                                       G_PARAM_STATIC_STRINGS));
304
305         /**
306          * NMDeviceMacvlan:no-promisc:
307          *
308          * Whether the device has the no-promiscuos flag.
309          *
310          * Since: 1.2
311          **/
312         g_object_class_install_property
313                 (object_class, PROP_NO_PROMISC,
314                  g_param_spec_boolean (NM_DEVICE_MACVLAN_NO_PROMISC, "", "",
315                                        FALSE,
316                                        G_PARAM_READABLE |
317                                        G_PARAM_STATIC_STRINGS));
318
319         /**
320          * NMDeviceMacvlan:tap:
321          *
322          * Whether the device is a MACVTAP.
323          *
324          * Since: 1.2
325          **/
326         g_object_class_install_property
327                 (object_class, PROP_TAP,
328                  g_param_spec_boolean (NM_DEVICE_MACVLAN_TAP, "", "",
329                                        FALSE,
330                                        G_PARAM_READABLE |
331                                        G_PARAM_STATIC_STRINGS));
332
333         /**
334          * NMDeviceMacvlan:hw-address:
335          *
336          * The hardware (MAC) address of the device.
337          *
338          * Since: 1.2
339          **/
340         g_object_class_install_property
341                 (object_class, PROP_HW_ADDRESS,
342                  g_param_spec_string (NM_DEVICE_MACVLAN_HW_ADDRESS, "", "",
343                                       NULL,
344                                       G_PARAM_READABLE |
345                                       G_PARAM_STATIC_STRINGS));
346 }