summaryrefslogtreecommitdiff
path: root/clients
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-05-24 15:57:16 +0200
committerThomas Haller <thaller@redhat.com>2016-06-30 08:29:56 +0200
commit8eed67122c58540360b617eb42d5df8328e21b5d (patch)
treedc235662d6ced2cb0267eee6c14ff53df168c2c0 /clients
parent1a6d6d56e646c8c148f442f1d089ecf6a6776298 (diff)
downloadNetworkManager-8eed67122c58540360b617eb42d5df8328e21b5d.tar.gz
device: extend MAC address handling including randomization for ethernet and wifi
Extend the "ethernet.cloned-mac-address" and "wifi.cloned-mac-address" settings. Instead of specifying an explicit MAC address, the additional special values "permanent", "preserve", "random", "random-bia", "stable" and "stable-bia" are supported. "permanent" means to use the permanent hardware address. Previously that was the default if no explict cloned-mac-address was set. The default is thus still "permanent", but it can be overwritten by global configuration. "preserve" means not to configure the MAC address when activating the device. That was actually the default behavior before introducing MAC address handling with commit 1b49f941a69af910b0e68530be7339e8053068e5. "random" and "random-bia" use a randomized MAC address for each connection. "stable" and "stable-bia" use a generated, stable address based on some token. The "bia" suffix says to generate a burned-in address. The stable method by default uses as token the connection UUID, but the token can be explicitly choosen via "stable:<TOKEN>" and "stable-bia:<TOKEN>". On a D-Bus level, the "cloned-mac-address" is a bytestring and thus cannot express the new forms. It is replaced by the new "assigned-mac-address" field. For the GObject property, libnm's API, nmcli, keyfile, etc. the old name "cloned-mac-address" is still used. Deprecating the old field seems more complicated then just extending the use of the existing "cloned-mac-address" field, although the name doesn't match well with the extended meaning. There is some overlap with the "wifi.mac-address-randomization" setting. https://bugzilla.gnome.org/show_bug.cgi?id=705545 https://bugzilla.gnome.org/show_bug.cgi?id=708820 https://bugzilla.gnome.org/show_bug.cgi?id=758301
Diffstat (limited to 'clients')
-rw-r--r--clients/cli/settings.c22
-rw-r--r--clients/tui/nmt-mac-entry.c43
-rw-r--r--clients/tui/nmt-mac-entry.h8
-rw-r--r--clients/tui/nmt-page-ethernet.c2
-rw-r--r--clients/tui/nmt-page-vlan.c2
-rw-r--r--clients/tui/nmt-page-wifi.c4
6 files changed, 69 insertions, 12 deletions
diff --git a/clients/cli/settings.c b/clients/cli/settings.c
index 6573e0b2bc..d3645ee031 100644
--- a/clients/cli/settings.c
+++ b/clients/cli/settings.c
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <arpa/inet.h>
+#include "nm-common-macros.h"
#include "utils.h"
#include "common.h"
#include "nm-vpn-helpers.h"
@@ -2889,11 +2890,12 @@ nmc_property_set_ssid (NMSetting *setting, const char *prop, const char *val, GE
}
static gboolean
-nmc_property_set_mac (NMSetting *setting, const char *prop, const char *val, GError **error)
+_property_set_mac (NMSetting *setting, const char *prop, const char *val, gboolean cloned_mac_addr, GError **error)
{
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- if (!nm_utils_hwaddr_valid (val, ETH_ALEN)) {
+ if ( (!cloned_mac_addr || !NM_CLONED_MAC_IS_SPECIAL (val))
+ && !nm_utils_hwaddr_valid (val, ETH_ALEN)) {
g_set_error (error, 1, 0, _("'%s' is not a valid Ethernet MAC"), val);
return FALSE;
}
@@ -2903,6 +2905,18 @@ nmc_property_set_mac (NMSetting *setting, const char *prop, const char *val, GEr
}
static gboolean
+nmc_property_set_mac (NMSetting *setting, const char *prop, const char *val, GError **error)
+{
+ return _property_set_mac (setting, prop, val, FALSE, error);
+}
+
+static gboolean
+nmc_property_set_mac_cloned (NMSetting *setting, const char *prop, const char *val, GError **error)
+{
+ return _property_set_mac (setting, prop, val, TRUE, error);
+}
+
+static gboolean
nmc_property_set_mtu (NMSetting *setting, const char *prop, const char *val, GError **error)
{
const char *mtu = val;
@@ -7198,7 +7212,7 @@ nmc_properties_init (void)
NULL);
nmc_add_prop_funcs (GLUE (WIRED, CLONED_MAC_ADDRESS),
nmc_property_wired_get_cloned_mac_address,
- nmc_property_set_mac,
+ nmc_property_set_mac_cloned,
NULL,
NULL,
NULL,
@@ -7316,7 +7330,7 @@ nmc_properties_init (void)
NULL);
nmc_add_prop_funcs (GLUE (WIRELESS, CLONED_MAC_ADDRESS),
nmc_property_wireless_get_cloned_mac_address,
- nmc_property_set_mac,
+ nmc_property_set_mac_cloned,
NULL,
NULL,
NULL,
diff --git a/clients/tui/nmt-mac-entry.c b/clients/tui/nmt-mac-entry.c
index d0f07e120a..da7f55fac1 100644
--- a/clients/tui/nmt-mac-entry.c
+++ b/clients/tui/nmt-mac-entry.c
@@ -28,11 +28,13 @@
#include "nm-default.h"
+#include "nmt-mac-entry.h"
+
#include <string.h>
#include "NetworkManager.h"
+#include "nm-common-macros.h"
-#include "nmt-mac-entry.h"
G_DEFINE_TYPE (NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
@@ -41,6 +43,7 @@ G_DEFINE_TYPE (NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
typedef struct {
int mac_length;
int mac_str_length;
+ NmtMacEntryType entry_type;
} NmtMacEntryPrivate;
@@ -48,6 +51,7 @@ enum {
PROP_0,
PROP_MAC_LENGTH,
PROP_MAC_ADDRESS,
+ PROP_ENTRY_TYPE,
LAST_PROP
};
@@ -57,6 +61,7 @@ enum {
* @width: the width in characters of the entry
* @mac_length: the length in bytes of the hardware address
* (either %ETH_ALEN or %INFINIBAND_ALEN)
+ * @entry_type: the type of the entry.
*
* Creates a new #NmtMacEntry.
*
@@ -64,11 +69,13 @@ enum {
*/
NmtNewtWidget *
nmt_mac_entry_new (int width,
- int mac_length)
+ int mac_length,
+ NmtMacEntryType entry_type)
{
return g_object_new (NMT_TYPE_MAC_ENTRY,
"width", width,
"mac-length", mac_length,
+ "entry-type", (int) entry_type,
NULL);
}
@@ -81,6 +88,9 @@ mac_filter (NmtNewtEntry *entry,
{
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE (entry);
+ if (priv->entry_type != NMT_MAC_ENTRY_TYPE_MAC)
+ return TRUE;
+
if (position >= priv->mac_str_length)
return FALSE;
@@ -98,6 +108,11 @@ mac_validator (NmtNewtEntry *entry,
if (!*text)
return TRUE;
+ if (priv->entry_type == NMT_MAC_ENTRY_TYPE_CLONED) {
+ if (NM_CLONED_MAC_IS_SPECIAL (text))
+ return TRUE;
+ }
+
p = text;
while ( g_ascii_isxdigit (p[0])
&& g_ascii_isxdigit (p[1])
@@ -112,7 +127,9 @@ mac_validator (NmtNewtEntry *entry,
if (!*p)
return (p - text == priv->mac_str_length);
- if (g_ascii_isxdigit (p[0]) && !p[1]) {
+ if ( g_ascii_isxdigit (p[0])
+ && !p[1]
+ && p - text < priv->mac_str_length) {
char *fixed = g_strdup_printf ("%.*s:%c", (int)(p - text), text, *p);
nmt_newt_entry_set_text (entry, fixed);
@@ -161,6 +178,10 @@ nmt_mac_entry_set_property (GObject *object,
case PROP_MAC_ADDRESS:
nmt_newt_entry_set_text (NMT_NEWT_ENTRY (object), g_value_get_string (value));
break;
+ case PROP_ENTRY_TYPE:
+ /* construct-only */
+ priv->entry_type = g_value_get_int (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -182,6 +203,9 @@ nmt_mac_entry_get_property (GObject *object,
case PROP_MAC_ADDRESS:
g_value_set_string (value, nmt_newt_entry_get_text (NMT_NEWT_ENTRY (object)));
break;
+ case PROP_ENTRY_TYPE:
+ g_value_set_int (value, priv->entry_type);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -224,4 +248,17 @@ nmt_mac_entry_class_init (NmtMacEntryClass *entry_class)
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
+ /**
+ * NmtMacEntry:entry-type:
+ *
+ * The type of the #NmtMacEntry. Can be either used for plain
+ * MAC addresses or for the extended format for cloned MAC addresses.
+ */
+ g_object_class_install_property
+ (object_class, PROP_ENTRY_TYPE,
+ g_param_spec_int ("entry-type", "", "",
+ NMT_MAC_ENTRY_TYPE_MAC, NMT_MAC_ENTRY_TYPE_CLONED, NMT_MAC_ENTRY_TYPE_MAC,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
}
diff --git a/clients/tui/nmt-mac-entry.h b/clients/tui/nmt-mac-entry.h
index 099bacb71b..b318911767 100644
--- a/clients/tui/nmt-mac-entry.h
+++ b/clients/tui/nmt-mac-entry.h
@@ -25,6 +25,11 @@
G_BEGIN_DECLS
+typedef enum { /*< skip >*/
+ NMT_MAC_ENTRY_TYPE_MAC,
+ NMT_MAC_ENTRY_TYPE_CLONED,
+} NmtMacEntryType;
+
#define NMT_TYPE_MAC_ENTRY (nmt_mac_entry_get_type ())
#define NMT_MAC_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMT_TYPE_MAC_ENTRY, NmtMacEntry))
#define NMT_MAC_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMT_TYPE_MAC_ENTRY, NmtMacEntryClass))
@@ -45,7 +50,8 @@ typedef struct {
GType nmt_mac_entry_get_type (void);
NmtNewtWidget *nmt_mac_entry_new (int width,
- int mac_length);
+ int mac_length,
+ NmtMacEntryType type);
G_END_DECLS
diff --git a/clients/tui/nmt-page-ethernet.c b/clients/tui/nmt-page-ethernet.c
index dfe2e44077..6b9243271f 100644
--- a/clients/tui/nmt-page-ethernet.c
+++ b/clients/tui/nmt-page-ethernet.c
@@ -70,7 +70,7 @@ nmt_page_ethernet_constructed (GObject *object)
section = nmt_editor_section_new (_("ETHERNET"), NULL, FALSE);
grid = nmt_editor_section_get_body (section);
- widget = nmt_mac_entry_new (40, ETH_ALEN);
+ widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_CLONED);
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
diff --git a/clients/tui/nmt-page-vlan.c b/clients/tui/nmt-page-vlan.c
index c63b190430..9cd6542163 100644
--- a/clients/tui/nmt-page-vlan.c
+++ b/clients/tui/nmt-page-vlan.c
@@ -115,7 +115,7 @@ nmt_page_vlan_constructed (GObject *object)
nmt_editor_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
- widget = nmt_mac_entry_new (40, ETH_ALEN);
+ widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_CLONED);
g_object_bind_property (s_wired, NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
diff --git a/clients/tui/nmt-page-wifi.c b/clients/tui/nmt-page-wifi.c
index cd9b60e109..35625fe4c7 100644
--- a/clients/tui/nmt-page-wifi.c
+++ b/clients/tui/nmt-page-wifi.c
@@ -351,13 +351,13 @@ nmt_page_wifi_constructed (GObject *object)
nmt_editor_grid_append (grid, NULL, nmt_newt_separator_new (), NULL);
- widget = nmt_mac_entry_new (40, ETH_ALEN);
+ widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_MAC);
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_BSSID,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
nmt_editor_grid_append (grid, _("BSSID"), widget, NULL);
- widget = nmt_mac_entry_new (40, ETH_ALEN);
+ widget = nmt_mac_entry_new (40, ETH_ALEN, NMT_MAC_ENTRY_TYPE_CLONED);
g_object_bind_property (s_wireless, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS,
widget, "mac-address",
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);