device: renew dhcp leases on awake for software devices
[NetworkManager.git] / libnm / nm-device-vlan.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 2012 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-vlan.h"
27 #include "nm-setting-wired.h"
28 #include "nm-utils.h"
29
30 #include "nm-device-vlan.h"
31 #include "nm-device-private.h"
32 #include "nm-object-private.h"
33
34 G_DEFINE_TYPE (NMDeviceVlan, nm_device_vlan, NM_TYPE_DEVICE)
35
36 #define NM_DEVICE_VLAN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_VLAN, NMDeviceVlanPrivate))
37
38 typedef struct {
39         char *hw_address;
40         gboolean carrier;
41         NMDevice *parent;
42         guint vlan_id;
43 } NMDeviceVlanPrivate;
44
45 enum {
46         PROP_0,
47         PROP_HW_ADDRESS,
48         PROP_CARRIER,
49         PROP_PARENT,
50         PROP_VLAN_ID,
51
52         LAST_PROP
53 };
54
55 /**
56  * nm_device_vlan_get_hw_address:
57  * @device: a #NMDeviceVlan
58  *
59  * Gets the hardware (MAC) address of the #NMDeviceVlan
60  *
61  * Returns: the hardware address. This is the internal string used by the
62  * device, and must not be modified.
63  **/
64 const char *
65 nm_device_vlan_get_hw_address (NMDeviceVlan *device)
66 {
67         g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), NULL);
68
69         return NM_DEVICE_VLAN_GET_PRIVATE (device)->hw_address;
70 }
71
72 /**
73  * nm_device_vlan_get_carrier:
74  * @device: a #NMDeviceVlan
75  *
76  * Whether the device has carrier.
77  *
78  * Returns: %TRUE if the device has carrier
79  **/
80 gboolean
81 nm_device_vlan_get_carrier (NMDeviceVlan *device)
82 {
83         g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
84
85         return NM_DEVICE_VLAN_GET_PRIVATE (device)->carrier;
86 }
87
88 /**
89  * nm_device_vlan_get_parent:
90  * @device: a #NMDeviceVlan
91  *
92  * Returns: (transfer none): the device's parent device
93  **/
94 NMDevice *
95 nm_device_vlan_get_parent (NMDeviceVlan *device)
96 {
97         g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
98
99         return NM_DEVICE_VLAN_GET_PRIVATE (device)->parent;
100 }
101
102 /**
103  * nm_device_vlan_get_vlan_id:
104  * @device: a #NMDeviceVlan
105  *
106  * Returns: the device's VLAN ID
107  **/
108 guint
109 nm_device_vlan_get_vlan_id (NMDeviceVlan *device)
110 {
111         g_return_val_if_fail (NM_IS_DEVICE_VLAN (device), FALSE);
112
113         return NM_DEVICE_VLAN_GET_PRIVATE (device)->vlan_id;
114 }
115
116 static gboolean
117 connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
118 {
119         NMSettingVlan *s_vlan;
120         NMSettingWired *s_wired;
121         const char *setting_hwaddr;
122
123         if (!NM_DEVICE_CLASS (nm_device_vlan_parent_class)->connection_compatible (device, connection, error))
124                 return FALSE;
125
126         if (!nm_connection_is_type (connection, NM_SETTING_VLAN_SETTING_NAME)) {
127                 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
128                                      _("The connection was not a VLAN connection."));
129                 return FALSE;
130         }
131
132         s_vlan = nm_connection_get_setting_vlan (connection);
133         if (nm_setting_vlan_get_id (s_vlan) != nm_device_vlan_get_vlan_id (NM_DEVICE_VLAN (device))) {
134                 g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
135                                      _("The VLAN identifiers of the device and the connection didn't match."));
136                 return FALSE;
137         }
138
139         s_wired = nm_connection_get_setting_wired (connection);
140         if (s_wired)
141                 setting_hwaddr = nm_setting_wired_get_mac_address (s_wired);
142         else
143                 setting_hwaddr = NULL;
144         if (setting_hwaddr) {
145                 if (!nm_utils_hwaddr_matches (setting_hwaddr, -1,
146                                               NM_DEVICE_VLAN_GET_PRIVATE (device)->hw_address, -1)) {
147                         g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
148                                              _("The hardware address of the device and the connection didn't match."));
149                 }
150         }
151
152         return TRUE;
153 }
154
155 static GType
156 get_setting_type (NMDevice *device)
157 {
158         return NM_TYPE_SETTING_VLAN;
159 }
160
161 static const char *
162 get_hw_address (NMDevice *device)
163 {
164         return nm_device_vlan_get_hw_address (NM_DEVICE_VLAN (device));
165 }
166
167 /***********************************************************/
168
169 static void
170 nm_device_vlan_init (NMDeviceVlan *device)
171 {
172         _nm_device_set_device_type (NM_DEVICE (device), NM_DEVICE_TYPE_VLAN);
173 }
174
175 static void
176 init_dbus (NMObject *object)
177 {
178         NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
179         const NMPropertiesInfo property_info[] = {
180                 { NM_DEVICE_VLAN_HW_ADDRESS, &priv->hw_address },
181                 { NM_DEVICE_VLAN_CARRIER,    &priv->carrier },
182                 { NM_DEVICE_VLAN_PARENT,     &priv->parent, NULL, NM_TYPE_DEVICE },
183                 { NM_DEVICE_VLAN_VLAN_ID,    &priv->vlan_id },
184                 { NULL },
185         };
186
187         NM_OBJECT_CLASS (nm_device_vlan_parent_class)->init_dbus (object);
188
189         _nm_object_register_properties (object,
190                                         NM_DBUS_INTERFACE_DEVICE_VLAN,
191                                         property_info);
192 }
193
194 static void
195 finalize (GObject *object)
196 {
197         NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (object);
198
199         g_free (priv->hw_address);
200         g_clear_object (&priv->parent);
201
202         G_OBJECT_CLASS (nm_device_vlan_parent_class)->finalize (object);
203 }
204
205 static void
206 get_property (GObject *object,
207               guint prop_id,
208               GValue *value,
209               GParamSpec *pspec)
210 {
211         NMDeviceVlan *device = NM_DEVICE_VLAN (object);
212
213         switch (prop_id) {
214         case PROP_HW_ADDRESS:
215                 g_value_set_string (value, nm_device_vlan_get_hw_address (device));
216                 break;
217         case PROP_CARRIER:
218                 g_value_set_boolean (value, nm_device_vlan_get_carrier (device));
219                 break;
220         case PROP_PARENT:
221                 g_value_set_object (value, nm_device_vlan_get_parent (device));
222                 break;
223         case PROP_VLAN_ID:
224                 g_value_set_uint (value, nm_device_vlan_get_vlan_id (device));
225                 break;
226         default:
227                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
228                 break;
229         }
230 }
231
232 static void
233 nm_device_vlan_class_init (NMDeviceVlanClass *vlan_class)
234 {
235         GObjectClass *object_class = G_OBJECT_CLASS (vlan_class);
236         NMObjectClass *nm_object_class = NM_OBJECT_CLASS (vlan_class);
237         NMDeviceClass *device_class = NM_DEVICE_CLASS (vlan_class);
238
239         g_type_class_add_private (vlan_class, sizeof (NMDeviceVlanPrivate));
240
241         _nm_object_class_add_interface (nm_object_class, NM_DBUS_INTERFACE_DEVICE_VLAN);
242
243         /* virtual methods */
244         object_class->finalize = finalize;
245         object_class->get_property = get_property;
246
247         nm_object_class->init_dbus = init_dbus;
248
249         device_class->connection_compatible = connection_compatible;
250         device_class->get_setting_type = get_setting_type;
251         device_class->get_hw_address = get_hw_address;
252
253         /* properties */
254
255         /**
256          * NMDeviceVlan:hw-address:
257          *
258          * The hardware (MAC) address of the device.
259          **/
260         g_object_class_install_property
261                 (object_class, PROP_HW_ADDRESS,
262                  g_param_spec_string (NM_DEVICE_VLAN_HW_ADDRESS, "", "",
263                                       NULL,
264                                       G_PARAM_READABLE |
265                                       G_PARAM_STATIC_STRINGS));
266
267         /**
268          * NMDeviceVlan:carrier:
269          *
270          * Whether the device has carrier.
271          **/
272         g_object_class_install_property
273                 (object_class, PROP_CARRIER,
274                  g_param_spec_boolean (NM_DEVICE_VLAN_CARRIER, "", "",
275                                        FALSE,
276                                        G_PARAM_READABLE |
277                                        G_PARAM_STATIC_STRINGS));
278
279         /**
280          * NMDeviceVlan:parent:
281          *
282          * The devices's parent device.
283          **/
284         g_object_class_install_property
285             (object_class, PROP_PARENT,
286              g_param_spec_object (NM_DEVICE_VLAN_PARENT, "", "",
287                                   NM_TYPE_DEVICE,
288                                   G_PARAM_READABLE |
289                                   G_PARAM_STATIC_STRINGS));
290
291         /**
292          * NMDeviceVlan:vlan-id:
293          *
294          * The device's VLAN ID.
295          **/
296         g_object_class_install_property
297                 (object_class, PROP_VLAN_ID,
298                  g_param_spec_uint (NM_DEVICE_VLAN_VLAN_ID, "", "",
299                                     0, 4095, 0,
300                                     G_PARAM_READABLE |
301                                     G_PARAM_STATIC_STRINGS));
302 }