diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index f721adf5b3..faba27612d 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -36,6 +36,7 @@ typedef struct { char * iface; + GByteArray * hwaddr; gboolean ipv6; char * uuid; guint32 timeout; @@ -67,6 +68,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, PROP_IFACE, + PROP_HWADDR, PROP_IPV6, PROP_UUID, PROP_TIMEOUT, @@ -1323,6 +1325,9 @@ get_property (GObject *object, guint prop_id, case PROP_IFACE: g_value_set_string (value, priv->iface); break; + case PROP_HWADDR: + g_value_set_boxed (value, priv->hwaddr); + break; case PROP_IPV6: g_value_set_boolean (value, priv->ipv6); break; @@ -1349,6 +1354,10 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->iface = g_strdup (g_value_get_string (value)); break; + case PROP_HWADDR: + /* construct only */ + priv->hwaddr = g_value_dup_boxed (value); + break; case PROP_IPV6: /* construct-only */ priv->ipv6 = g_value_get_boolean (value); @@ -1382,6 +1391,8 @@ dispose (GObject *object) g_hash_table_destroy (priv->options); g_free (priv->iface); + if (priv->hwaddr) + g_byte_array_free (priv->hwaddr, TRUE); G_OBJECT_CLASS (nm_dhcp_client_parent_class)->dispose (object); } @@ -1408,6 +1419,14 @@ nm_dhcp_client_class_init (NMDHCPClientClass *client_class) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property + (object_class, PROP_HWADDR, + g_param_spec_boxed (NM_DHCP_CLIENT_HWADDR, + "hwaddr", + "hardware address", + G_TYPE_BYTE_ARRAY, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, PROP_IPV6, g_param_spec_boolean (NM_DHCP_CLIENT_IPV6, diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index b93515f483..0df23415e1 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -35,6 +35,7 @@ #define NM_DHCP_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DHCP_CLIENT, NMDHCPClientClass)) #define NM_DHCP_CLIENT_INTERFACE "iface" +#define NM_DHCP_CLIENT_HWADDR "hwaddr" #define NM_DHCP_CLIENT_IPV6 "ipv6" #define NM_DHCP_CLIENT_UUID "uuid" #define NM_DHCP_CLIENT_TIMEOUT "timeout" diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 995bff4797..1bd7f98426 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -384,6 +384,7 @@ add_client (NMDHCPManager *self, NMDHCPClient *client) static NMDHCPClient * client_start (NMDHCPManager *self, const char *iface, + const GByteArray *hwaddr, const char *uuid, gboolean ipv6, NMSettingIP4Config *s_ip4, @@ -417,6 +418,7 @@ client_start (NMDHCPManager *self, /* And make a new one */ client = g_object_new (priv->client_type, NM_DHCP_CLIENT_INTERFACE, iface, + NM_DHCP_CLIENT_HWADDR, hwaddr, NM_DHCP_CLIENT_IPV6, ipv6, NM_DHCP_CLIENT_UUID, uuid, NM_DHCP_CLIENT_TIMEOUT, timeout ? timeout : DHCP_TIMEOUT, @@ -442,13 +444,13 @@ client_start (NMDHCPManager *self, NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *self, const char *iface, + const GByteArray *hwaddr, const char *uuid, NMSettingIP4Config *s_ip4, guint32 timeout, guint8 *dhcp_anycast_addr) { NMDHCPManagerPrivate *priv; - NMDHCPClient *client = NULL; const char *hostname = NULL; gboolean send_hostname = TRUE; @@ -485,15 +487,14 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self, } } - client = client_start (self, iface, uuid, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr, hostname, FALSE); - - return client; + return client_start (self, iface, hwaddr, uuid, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr, hostname, FALSE); } /* Caller owns a reference to the NMDHCPClient on return */ NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *self, const char *iface, + const GByteArray *hwaddr, const char *uuid, NMSettingIP6Config *s_ip6, guint32 timeout, @@ -516,7 +517,7 @@ nm_dhcp_manager_start_ip6 (NMDHCPManager *self, hostname = NULL; } - return client_start (self, iface, uuid, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr, hostname, info_only); + return client_start (self, iface, hwaddr, uuid, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr, hostname, info_only); } static void diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index 68db7e3707..a29a33fdbd 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -67,6 +67,7 @@ void nm_dhcp_manager_set_hostname_provider(NMDHCPManager *manager, NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager, const char *iface, + const GByteArray *hwaddr, const char *uuid, NMSettingIP4Config *s_ip4, guint32 timeout, @@ -74,6 +75,7 @@ NMDHCPClient * nm_dhcp_manager_start_ip4 (NMDHCPManager *manager, NMDHCPClient * nm_dhcp_manager_start_ip6 (NMDHCPManager *manager, const char *iface, + const GByteArray *hwaddr, const char *uuid, NMSettingIP6Config *s_ip6, guint32 timeout, diff --git a/src/nm-device.c b/src/nm-device.c index a499db9cc5..32079aa5c3 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -1942,6 +1942,9 @@ dhcp4_start (NMDevice *self, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMSettingIP4Config *s_ip4; guint8 *anycast = NULL; + GByteArray *tmp = NULL; + guint hwaddr_len = 0; + const guint8 *hwaddr; s_ip4 = nm_connection_get_setting_ip4_config (connection); @@ -1953,14 +1956,25 @@ dhcp4_start (NMDevice *self, g_object_unref (priv->dhcp4_config); priv->dhcp4_config = nm_dhcp4_config_new (); + hwaddr = nm_device_get_hw_address (self, &hwaddr_len); + if (hwaddr) { + tmp = g_byte_array_sized_new (hwaddr_len); + g_byte_array_append (tmp, hwaddr, hwaddr_len); + } + /* Begin DHCP on the interface */ g_warn_if_fail (priv->dhcp4_client == NULL); priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager, nm_device_get_ip_iface (self), + tmp, nm_connection_get_uuid (connection), s_ip4, priv->dhcp_timeout, anycast); + + if (tmp) + g_byte_array_free (tmp, TRUE); + if (!priv->dhcp4_client) { *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; @@ -2325,7 +2339,9 @@ dhcp6_start (NMDevice *self, NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; guint8 *anycast = NULL; - const char *ip_iface; + GByteArray *tmp = NULL; + guint hwaddr_len = 0; + const guint8 *hwaddr; if (!connection) { connection = nm_device_get_connection (self); @@ -2348,14 +2364,23 @@ dhcp6_start (NMDevice *self, priv->dhcp6_ip6_config = NULL; } - ip_iface = nm_device_get_ip_iface (self); + hwaddr = nm_device_get_hw_address (self, &hwaddr_len); + if (hwaddr) { + tmp = g_byte_array_sized_new (hwaddr_len); + g_byte_array_append (tmp, hwaddr, hwaddr_len); + } + priv->dhcp6_client = nm_dhcp_manager_start_ip6 (priv->dhcp_manager, - ip_iface, + nm_device_get_ip_iface (self), + tmp, nm_connection_get_uuid (connection), nm_connection_get_setting_ip6_config (connection), priv->dhcp_timeout, anycast, (dhcp_opt == IP6_DHCP_OPT_OTHERCONF) ? TRUE : FALSE); + if (tmp) + g_byte_array_free (tmp, TRUE); + if (priv->dhcp6_client) { priv->dhcp6_state_sigid = g_signal_connect (priv->dhcp6_client, "state-changed",