mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-30 22:30:11 +01:00
merge: S390 subchannels improvements (bgo #755610)
- export device's S390 subchannels on D-Bus - update 390 subchannels comparison for connection vs.device compatibility - support s390 subchannels in libnm and nmcli https://bugzilla.gnome.org/show_bug.cgi?id=755610
This commit is contained in:
commit
edec77fba4
12 changed files with 357 additions and 44 deletions
|
|
@ -108,12 +108,13 @@ static NmcOutputField nmc_fields_dev_show_cap[] = {
|
|||
|
||||
/* Available fields for 'device show' - wired properties part */
|
||||
static NmcOutputField nmc_fields_dev_show_wired_prop[] = {
|
||||
{"NAME", N_("NAME")}, /* 0 */
|
||||
{"CARRIER", N_("CARRIER")}, /* 1 */
|
||||
{"NAME", N_("NAME")}, /* 0 */
|
||||
{"CARRIER", N_("CARRIER")}, /* 1 */
|
||||
{"S390-SUBCHANNELS", N_("S390-SUBCHANNELS")}, /* 2 */
|
||||
{NULL, NULL}
|
||||
};
|
||||
#define NMC_FIELDS_DEV_SHOW_WIRED_PROP_ALL "NAME,CARRIER"
|
||||
#define NMC_FIELDS_DEV_SHOW_WIRED_PROP_COMMON "NAME,CARRIER"
|
||||
#define NMC_FIELDS_DEV_SHOW_WIRED_PROP_ALL "NAME,CARRIER,S390-SUBCHANNELS"
|
||||
#define NMC_FIELDS_DEV_SHOW_WIRED_PROP_COMMON "NAME,CARRIER,S390-SUBCHANNELS"
|
||||
|
||||
/* Available fields for 'device show' - wireless properties part */
|
||||
static NmcOutputField nmc_fields_dev_show_wifi_prop[] = {
|
||||
|
|
@ -978,6 +979,7 @@ show_device_info (NMDevice *device, NmCli *nmc)
|
|||
set_val_strc (arr, 0, nmc_fields_dev_show_sections[4].name); /* "WIRED-PROPERTIES" */
|
||||
set_val_strc (arr, 1, (nm_device_ethernet_get_carrier (NM_DEVICE_ETHERNET (device))) ?
|
||||
_("on") : _("off"));
|
||||
set_val_arrc (arr, 2, ((const char **) nm_device_ethernet_get_s390_subchannels (NM_DEVICE_ETHERNET (device))));
|
||||
g_ptr_array_add (nmc->output_data, arr);
|
||||
|
||||
print_data (nmc); /* Print all data */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@
|
|||
</tp:docstring>
|
||||
</property>
|
||||
|
||||
<property name="S390Subchannels" type="as" access="read">
|
||||
<tp:docstring>
|
||||
Array of S/390 subchannels for S/390 or z/Architecture devices.
|
||||
</tp:docstring>
|
||||
</property>
|
||||
|
||||
<property name="Carrier" type="b" access="read">
|
||||
<tp:docstring>
|
||||
Indicates whether the physical carrier is found (e.g. whether a cable is plugged in or not).
|
||||
|
|
|
|||
|
|
@ -100,6 +100,29 @@ add_device (const char *method, const char *ifname, char **out_path)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_wired_device (const char *method, const char *ifname, char **out_path)
|
||||
{
|
||||
const char *empty[] = { NULL };
|
||||
GError *error = NULL;
|
||||
GVariant *ret;
|
||||
|
||||
ret = g_dbus_proxy_call_sync (sinfo->proxy,
|
||||
method,
|
||||
g_variant_new ("(ss^as)", ifname, "/", empty),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
3000,
|
||||
NULL,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
|
||||
if (out_path)
|
||||
g_variant_get (ret, "(o)", out_path);
|
||||
g_variant_unref (ret);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -168,7 +191,7 @@ test_device_added (void)
|
|||
g_assert (devices == NULL);
|
||||
|
||||
/* Tell the test service to add a new device */
|
||||
add_device ("AddWiredDevice", "eth0", NULL);
|
||||
add_wired_device ("AddWiredDevice", "eth0", NULL);
|
||||
|
||||
g_signal_connect (client,
|
||||
"device-added",
|
||||
|
|
@ -731,8 +754,8 @@ test_devices_array (void)
|
|||
/*************************************/
|
||||
/* Add some devices */
|
||||
add_device ("AddWifiDevice", "wlan0", &paths[0]);
|
||||
add_device ("AddWiredDevice", "eth0", &paths[1]);
|
||||
add_device ("AddWiredDevice", "eth1", &paths[2]);
|
||||
add_wired_device ("AddWiredDevice", "eth0", &paths[1]);
|
||||
add_wired_device ("AddWiredDevice", "eth1", &paths[2]);
|
||||
info.quit_count = 3;
|
||||
|
||||
g_signal_connect (client,
|
||||
|
|
|
|||
|
|
@ -858,6 +858,7 @@ libnm_1_0_6 {
|
|||
libnm_1_2_0 {
|
||||
global:
|
||||
nm_access_point_get_last_seen;
|
||||
nm_device_ethernet_get_s390_subchannels;
|
||||
nm_device_get_metered;
|
||||
nm_device_get_nm_plugin_missing;
|
||||
nm_device_set_managed;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ typedef struct {
|
|||
char *perm_hw_address;
|
||||
guint32 speed;
|
||||
gboolean carrier;
|
||||
char **s390_subchannels;
|
||||
} NMDeviceEthernetPrivate;
|
||||
|
||||
enum {
|
||||
|
|
@ -50,6 +51,7 @@ enum {
|
|||
PROP_PERM_HW_ADDRESS,
|
||||
PROP_SPEED,
|
||||
PROP_CARRIER,
|
||||
PROP_S390_SUBCHANNELS,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -120,18 +122,88 @@ nm_device_ethernet_get_carrier (NMDeviceEthernet *device)
|
|||
return NM_DEVICE_ETHERNET_GET_PRIVATE (device)->carrier;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_ethernet_get_s390_subchannels:
|
||||
* @device: a #NMDeviceEthernet
|
||||
*
|
||||
* Return the list of s390 subchannels if the device supports them.
|
||||
*
|
||||
* Returns: (transfer none) (element-type utf8): array of strings, each specifying
|
||||
* one subchannel the s390 device uses to communicate to the host.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
const char * const *
|
||||
nm_device_ethernet_get_s390_subchannels (NMDeviceEthernet *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
|
||||
|
||||
return (const char * const *) NM_DEVICE_ETHERNET_GET_PRIVATE (device)->s390_subchannels;
|
||||
}
|
||||
|
||||
static guint32
|
||||
_subchannels_count_num (const char * const *array)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!array)
|
||||
return 0;
|
||||
for (i = 0; array[i]; i++)
|
||||
/* NOP */;
|
||||
return i;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
const char * const *subchans;
|
||||
guint32 num1, num2;
|
||||
int i, j;
|
||||
|
||||
*try_mac = TRUE;
|
||||
|
||||
subchans = nm_setting_wired_get_s390_subchannels (s_wired);
|
||||
num1 = _subchannels_count_num (subchans);
|
||||
num2 = _subchannels_count_num ((const char * const *) priv->s390_subchannels);
|
||||
/* connection has no subchannels */
|
||||
if (num1 == 0)
|
||||
return TRUE;
|
||||
/* connection requires subchannels but the device has none */
|
||||
if (num2 == 0)
|
||||
return FALSE;
|
||||
/* number of subchannels differ */
|
||||
if (num1 != num2)
|
||||
return FALSE;
|
||||
|
||||
/* Make sure each subchannel in the connection is a subchannel of this device */
|
||||
for (i = 0; subchans[i]; i++) {
|
||||
const char *candidate = subchans[i];
|
||||
gboolean found = FALSE;
|
||||
|
||||
for (j = 0; priv->s390_subchannels[j]; j++) {
|
||||
if (!g_strcmp0 (priv->s390_subchannels[j], candidate))
|
||||
found = TRUE;
|
||||
}
|
||||
if (!found)
|
||||
return FALSE; /* a subchannel was not found */
|
||||
}
|
||||
|
||||
*try_mac = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
connection_compatible (NMDevice *device, NMConnection *connection, GError **error)
|
||||
{
|
||||
NMSettingWired *s_wired;
|
||||
gboolean is_pppoe = FALSE;
|
||||
|
||||
if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->connection_compatible (device, connection, error))
|
||||
return FALSE;
|
||||
|
||||
if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME))
|
||||
is_pppoe = TRUE;
|
||||
else if (!nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) {
|
||||
if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) {
|
||||
/* NOP */
|
||||
} else if (!nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) {
|
||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
||||
_("The connection was not an Ethernet or PPPoE connection."));
|
||||
return FALSE;
|
||||
|
|
@ -140,24 +212,49 @@ connection_compatible (NMDevice *device, NMConnection *connection, GError **erro
|
|||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
/* Wired setting optional for PPPoE */
|
||||
if (s_wired) {
|
||||
const char *perm_addr, *setting_addr;
|
||||
const char *perm_addr, *s_mac;
|
||||
gboolean try_mac = TRUE;
|
||||
const char * const *mac_blacklist;
|
||||
int i;
|
||||
|
||||
/* FIXME: filter using s390 subchannels when they are exported over the bus */
|
||||
/* Check s390 subchannels */
|
||||
if (!match_subchans (NM_DEVICE_ETHERNET (device), s_wired, &try_mac)) {
|
||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
||||
_("The connection and device differ in S390 subchannels."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check MAC address */
|
||||
perm_addr = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
|
||||
s_mac = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (perm_addr) {
|
||||
if (!nm_utils_hwaddr_valid (perm_addr, ETH_ALEN)) {
|
||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED,
|
||||
_("Invalid device MAC address."));
|
||||
return FALSE;
|
||||
}
|
||||
setting_addr = nm_setting_wired_get_mac_address (s_wired);
|
||||
if (setting_addr && !nm_utils_hwaddr_matches (setting_addr, -1, perm_addr, -1)) {
|
||||
if (try_mac && s_mac && !nm_utils_hwaddr_matches (s_mac, -1, perm_addr, -1)) {
|
||||
g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
||||
_("The MACs of the device and the connection didn't match."));
|
||||
_("The MACs of the device and the connection do not match."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check for MAC address blacklist */
|
||||
mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired);
|
||||
for (i = 0; mac_blacklist[i]; i++) {
|
||||
if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) {
|
||||
g_warn_if_reached ();
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
||||
_("Invalid MAC in the blacklist: %s."), mac_blacklist[i]);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_addr, -1)) {
|
||||
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION,
|
||||
_("Device MAC (%s) is blacklisted by the connection."), perm_addr);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -193,6 +290,7 @@ init_dbus (NMObject *object)
|
|||
{ NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS, &priv->perm_hw_address },
|
||||
{ NM_DEVICE_ETHERNET_SPEED, &priv->speed },
|
||||
{ NM_DEVICE_ETHERNET_CARRIER, &priv->carrier },
|
||||
{ NM_DEVICE_ETHERNET_S390_SUBCHANNELS, &priv->s390_subchannels },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
|
@ -210,6 +308,7 @@ finalize (GObject *object)
|
|||
|
||||
g_free (priv->hw_address);
|
||||
g_free (priv->perm_hw_address);
|
||||
g_strfreev (priv->s390_subchannels);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_ethernet_parent_class)->finalize (object);
|
||||
}
|
||||
|
|
@ -221,6 +320,7 @@ get_property (GObject *object,
|
|||
GParamSpec *pspec)
|
||||
{
|
||||
NMDeviceEthernet *device = NM_DEVICE_ETHERNET (object);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (device);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_HW_ADDRESS:
|
||||
|
|
@ -235,6 +335,9 @@ get_property (GObject *object,
|
|||
case PROP_CARRIER:
|
||||
g_value_set_boolean (value, nm_device_ethernet_get_carrier (device));
|
||||
break;
|
||||
case PROP_S390_SUBCHANNELS:
|
||||
g_value_set_boxed (value, priv->s390_subchannels);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -312,4 +415,18 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *eth_class)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDeviceEthernet:s390-subchannels:
|
||||
*
|
||||
* Identifies subchannels of this network device used for
|
||||
* communication with z/VM or s390 host.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_S390_SUBCHANNELS,
|
||||
g_param_spec_boxed (NM_DEVICE_ETHERNET_S390_SUBCHANNELS, "", "",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address"
|
||||
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
||||
#define NM_DEVICE_ETHERNET_CARRIER "carrier"
|
||||
#define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels"
|
||||
|
||||
struct _NMDeviceEthernet {
|
||||
NMDevice parent;
|
||||
|
|
@ -59,6 +60,8 @@ const char * nm_device_ethernet_get_hw_address (NMDeviceEthernet *device);
|
|||
const char * nm_device_ethernet_get_permanent_hw_address (NMDeviceEthernet *device);
|
||||
guint32 nm_device_ethernet_get_speed (NMDeviceEthernet *device);
|
||||
gboolean nm_device_ethernet_get_carrier (NMDeviceEthernet *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char * const *nm_device_ethernet_get_s390_subchannels (NMDeviceEthernet *device);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -149,22 +149,53 @@ timeout (gpointer user_data)
|
|||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
NMDevice *
|
||||
nm_test_service_add_device (NMTestServiceInfo *sinfo, NMClient *client,
|
||||
const char *method, const char *ifname)
|
||||
static GVariant *
|
||||
call_add_wired_device (GDBusProxy *proxy, const char *ifname, const char *hwaddr,
|
||||
const char **subchannels, GError **error)
|
||||
{
|
||||
const char *empty[] = { NULL };
|
||||
|
||||
if (!hwaddr)
|
||||
hwaddr = "/";
|
||||
if (!subchannels)
|
||||
subchannels = empty;
|
||||
|
||||
return g_dbus_proxy_call_sync (proxy,
|
||||
"AddWiredDevice",
|
||||
g_variant_new ("(ss^as)", ifname, hwaddr, subchannels),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
3000,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
call_add_device (GDBusProxy *proxy, const char *method, const char *ifname, GError **error)
|
||||
{
|
||||
return g_dbus_proxy_call_sync (proxy,
|
||||
method,
|
||||
g_variant_new ("(s)", ifname),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
3000,
|
||||
NULL,
|
||||
error);
|
||||
}
|
||||
|
||||
static NMDevice *
|
||||
add_device_common (NMTestServiceInfo *sinfo, NMClient *client,
|
||||
const char *method, const char *ifname,
|
||||
const char *hwaddr, const char **subchannels)
|
||||
{
|
||||
AddDeviceInfo info;
|
||||
GError *error = NULL;
|
||||
GVariant *ret;
|
||||
guint timeout_id;
|
||||
|
||||
ret = g_dbus_proxy_call_sync (sinfo->proxy,
|
||||
method,
|
||||
g_variant_new ("(s)", ifname),
|
||||
G_DBUS_CALL_FLAGS_NO_AUTO_START,
|
||||
3000,
|
||||
NULL,
|
||||
&error);
|
||||
if (g_strcmp0 (method, "AddWiredDevice") == 0)
|
||||
ret = call_add_wired_device (sinfo->proxy, ifname, hwaddr, subchannels, &error);
|
||||
else
|
||||
ret = call_add_device (sinfo->proxy, method, ifname, &error);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (ret);
|
||||
g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)");
|
||||
|
|
@ -186,3 +217,18 @@ nm_test_service_add_device (NMTestServiceInfo *sinfo, NMClient *client,
|
|||
|
||||
return info.device;
|
||||
}
|
||||
|
||||
NMDevice *
|
||||
nm_test_service_add_device (NMTestServiceInfo *sinfo, NMClient *client,
|
||||
const char *method, const char *ifname)
|
||||
{
|
||||
return add_device_common (sinfo, client, method, ifname, NULL, NULL);
|
||||
}
|
||||
|
||||
NMDevice *
|
||||
nm_test_service_add_wired_device (NMTestServiceInfo *sinfo, NMClient *client,
|
||||
const char *ifname, const char *hwaddr,
|
||||
const char **subchannels)
|
||||
{
|
||||
return add_device_common (sinfo, client, "AddWiredDevice", ifname, hwaddr, subchannels);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,3 +36,10 @@ NMDevice *nm_test_service_add_device (NMTestServiceInfo *info,
|
|||
NMClient *client,
|
||||
const char *method,
|
||||
const char *ifname);
|
||||
|
||||
NMDevice * nm_test_service_add_wired_device (NMTestServiceInfo *sinfo,
|
||||
NMClient *client,
|
||||
const char *ifname,
|
||||
const char *hwaddr,
|
||||
const char **subchannels);
|
||||
|
||||
|
|
|
|||
|
|
@ -1160,6 +1160,77 @@ test_activate_failed (void)
|
|||
g_clear_pointer (&sinfo, nm_test_service_cleanup);
|
||||
}
|
||||
|
||||
static void
|
||||
test_device_connection_compatibility (void)
|
||||
{
|
||||
NMClient *client;
|
||||
NMDevice *device1, *device2;
|
||||
NMConnection *conn;
|
||||
NMSettingWired *s_wired;
|
||||
GError *error = NULL;
|
||||
const char *subchannels[] = { "0.0.8000", "0.0.8001", "0.0.8002", NULL };
|
||||
const char *subchannels_2[] = { "0.0.8000", "0.0.8001", NULL };
|
||||
const char *subchannels_x[] = { "0.0.8000", "0.0.8001", "0.0.800X", NULL };
|
||||
const char *hw_addr1 = "52:54:00:ab:db:23";
|
||||
const char *hw_addr2 = "52:54:00:ab:db:24";
|
||||
|
||||
sinfo = nm_test_service_init ();
|
||||
client = nm_client_new (NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
/* Create two devices */
|
||||
device1 = nm_test_service_add_wired_device (sinfo, client, "eth0", hw_addr1, subchannels);
|
||||
device2 = nm_test_service_add_wired_device (sinfo, client, "eth1", hw_addr2, NULL);
|
||||
|
||||
g_assert_cmpstr (nm_device_get_hw_address (device1), ==, hw_addr1);
|
||||
g_assert_cmpstr (nm_device_get_hw_address (device2), ==, hw_addr2);
|
||||
|
||||
conn = nmtst_create_minimal_connection ("wired-matches", NULL,
|
||||
NM_SETTING_WIRED_SETTING_NAME, NULL);
|
||||
s_wired = nm_connection_get_setting_wired (conn);
|
||||
nm_setting_wired_add_mac_blacklist_item (s_wired, "00:11:22:33:44:55");
|
||||
|
||||
/* device1 and conn are compatible */
|
||||
g_object_set (s_wired,
|
||||
NM_SETTING_WIRED_MAC_ADDRESS, hw_addr1,
|
||||
NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels,
|
||||
NULL);
|
||||
nm_device_connection_compatible (device1, conn, &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
/* device2 and conn differ in subchannels */
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels_x, NULL);
|
||||
nm_device_connection_compatible (device2, conn, &error);
|
||||
g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION);
|
||||
g_clear_error (&error);
|
||||
|
||||
/* device1 and conn differ in subchannels - 2 in connection, 3 in device */
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels_2, NULL);
|
||||
nm_device_connection_compatible (device1, conn, &error);
|
||||
g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, NULL, NULL);
|
||||
|
||||
/* device2 and conn differ in MAC address */
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, "aa:bb:cc:dd:ee:ee", NULL);
|
||||
nm_device_connection_compatible (device2, conn, &error);
|
||||
g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION);
|
||||
g_clear_error (&error);
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, NULL, NULL);
|
||||
|
||||
/* device1 is blacklisted in conn */
|
||||
nm_setting_wired_add_mac_blacklist_item (s_wired, hw_addr1);
|
||||
nm_device_connection_compatible (device1, conn, &error);
|
||||
g_assert_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION);
|
||||
g_clear_error (&error);
|
||||
|
||||
g_object_unref (conn);
|
||||
g_object_unref (client);
|
||||
|
||||
g_clear_pointer (&sinfo, nm_test_service_cleanup);
|
||||
}
|
||||
|
||||
/*******************************************************************/
|
||||
|
||||
NMTST_DEFINE ();
|
||||
|
|
@ -1182,6 +1253,7 @@ main (int argc, char **argv)
|
|||
g_test_add_func ("/libnm/active-connections", test_active_connections);
|
||||
g_test_add_func ("/libnm/activate-virtual", test_activate_virtual);
|
||||
g_test_add_func ("/libnm/activate-failed", test_activate_failed);
|
||||
g_test_add_func ("/libnm/device-connection-compatibility", test_device_connection_compatibility);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ typedef struct {
|
|||
char * subchan2;
|
||||
char * subchan3;
|
||||
char * subchannels; /* Composite used for checking unmanaged specs */
|
||||
char ** subchannels_dbus; /* Array exported on D-Bus */
|
||||
char * s390_nettype;
|
||||
GHashTable * s390_options;
|
||||
|
||||
|
|
@ -123,6 +124,7 @@ enum {
|
|||
PROP_0,
|
||||
PROP_PERM_HW_ADDRESS,
|
||||
PROP_SPEED,
|
||||
PROP_S390_SUBCHANNELS,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -225,6 +227,12 @@ _update_s390_subchannels (NMDeviceEthernet *self)
|
|||
} else
|
||||
priv->subchannels = g_strdup (priv->subchan1);
|
||||
|
||||
priv->subchannels_dbus = g_new (char *, 3 + 1);
|
||||
priv->subchannels_dbus[0] = g_strdup (priv->subchan1);
|
||||
priv->subchannels_dbus[1] = g_strdup (priv->subchan2);
|
||||
priv->subchannels_dbus[2] = g_strdup (priv->subchan3);
|
||||
priv->subchannels_dbus[3] = NULL;
|
||||
|
||||
driver = nm_device_get_driver (NM_DEVICE (self));
|
||||
_LOGI (LOGD_DEVICE | LOGD_HW, "found s390 '%s' subchannels [%s]",
|
||||
driver ? driver : "(unknown driver)", priv->subchannels);
|
||||
|
|
@ -318,21 +326,39 @@ get_generic_capabilities (NMDevice *device)
|
|||
}
|
||||
}
|
||||
|
||||
static guint32
|
||||
_subchannels_count_num (const char * const *array)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!array)
|
||||
return 0;
|
||||
for (i = 0; array[i]; i++)
|
||||
/* NOP */;
|
||||
return i;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_mac)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
const char * const *subchans;
|
||||
guint32 num1, num2;
|
||||
int i;
|
||||
|
||||
*try_mac = TRUE;
|
||||
|
||||
subchans = nm_setting_wired_get_s390_subchannels (s_wired);
|
||||
if (!subchans)
|
||||
num1 = _subchannels_count_num (subchans);
|
||||
num2 = _subchannels_count_num ((const char * const *) priv->subchannels_dbus);
|
||||
/* connection has no subchannels */
|
||||
if (num1 == 0)
|
||||
return TRUE;
|
||||
|
||||
/* connection requires subchannels but the device has none */
|
||||
if (!priv->subchannels)
|
||||
if (num2 == 0)
|
||||
return FALSE;
|
||||
/* number of subchannels differ */
|
||||
if (num1 != num2)
|
||||
return FALSE;
|
||||
|
||||
/* Make sure each subchannel in the connection is a subchannel of this device */
|
||||
|
|
@ -1546,16 +1572,8 @@ update_connection (NMDevice *device, NMConnection *connection)
|
|||
/* We don't set the MTU as we don't know whether it was set explicitly */
|
||||
|
||||
/* s390 */
|
||||
if (priv->subchannels) {
|
||||
char **subchannels = g_new (char *, 3 + 1);
|
||||
|
||||
subchannels[0] = g_strdup (priv->subchan1);
|
||||
subchannels[1] = g_strdup (priv->subchan2);
|
||||
subchannels[2] = g_strdup (priv->subchan3);
|
||||
subchannels[3] = NULL;
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, subchannels, NULL);
|
||||
g_strfreev (subchannels);
|
||||
}
|
||||
if (priv->subchannels_dbus)
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_S390_SUBCHANNELS, priv->subchannels_dbus, NULL);
|
||||
if (priv->s390_nettype)
|
||||
g_object_set (s_wired, NM_SETTING_WIRED_S390_NETTYPE, priv->s390_nettype, NULL);
|
||||
g_hash_table_iter_init (&iter, priv->s390_options);
|
||||
|
|
@ -1631,6 +1649,7 @@ finalize (GObject *object)
|
|||
g_free (priv->subchan2);
|
||||
g_free (priv->subchan3);
|
||||
g_free (priv->subchannels);
|
||||
g_strfreev (priv->subchannels_dbus);
|
||||
g_free (priv->s390_nettype);
|
||||
g_hash_table_destroy (priv->s390_options);
|
||||
|
||||
|
|
@ -1651,6 +1670,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_SPEED:
|
||||
g_value_set_uint (value, priv->speed);
|
||||
break;
|
||||
case PROP_S390_SUBCHANNELS:
|
||||
g_value_set_boxed (value, priv->subchannels_dbus);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1718,6 +1740,13 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_S390_SUBCHANNELS,
|
||||
g_param_spec_boxed (NM_DEVICE_ETHERNET_S390_SUBCHANNELS, "", "",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
|
||||
NMDBUS_TYPE_DEVICE_ETHERNET_SKELETON,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ G_BEGIN_DECLS
|
|||
|
||||
#define NM_DEVICE_ETHERNET_PERMANENT_HW_ADDRESS "perm-hw-address"
|
||||
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
||||
#define NM_DEVICE_ETHERNET_S390_SUBCHANNELS "s390-subchannels"
|
||||
|
||||
typedef NMDevice NMDeviceEthernet;
|
||||
typedef NMDeviceClass NMDeviceEthernetClass;
|
||||
|
|
|
|||
|
|
@ -207,14 +207,19 @@ PE_HW_ADDRESS = "HwAddress"
|
|||
PE_PERM_HW_ADDRESS = "PermHwAddress"
|
||||
PE_SPEED = "Speed"
|
||||
PE_CARRIER = "Carrier"
|
||||
PE_S390_SUBCHANNELS = "S390Subchannels"
|
||||
|
||||
class WiredDevice(Device):
|
||||
def __init__(self, bus, iface):
|
||||
def __init__(self, bus, iface, mac, subchannels):
|
||||
Device.__init__(self, bus, iface, NM_DEVICE_TYPE_ETHERNET)
|
||||
self.add_dbus_interface(IFACE_WIRED, self.__get_props)
|
||||
|
||||
self.mac = random_mac()
|
||||
if mac is None:
|
||||
self.mac = random_mac()
|
||||
else:
|
||||
self.mac = mac
|
||||
self.carrier = False
|
||||
self.s390_subchannels = subchannels
|
||||
|
||||
# Properties interface
|
||||
def __get_props(self):
|
||||
|
|
@ -223,6 +228,7 @@ class WiredDevice(Device):
|
|||
props[PE_PERM_HW_ADDRESS] = self.mac
|
||||
props[PE_SPEED] = dbus.UInt32(100)
|
||||
props[PE_CARRIER] = self.carrier
|
||||
props[PE_S390_SUBCHANNELS] = self.s390_subchannels
|
||||
return props
|
||||
|
||||
def __notify(self, propname):
|
||||
|
|
@ -838,12 +844,12 @@ class NetworkManager(ExportedObj):
|
|||
def Quit(self):
|
||||
mainloop.quit()
|
||||
|
||||
@dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o')
|
||||
def AddWiredDevice(self, ifname):
|
||||
@dbus.service.method(IFACE_TEST, in_signature='ssas', out_signature='o')
|
||||
def AddWiredDevice(self, ifname, mac, subchannels):
|
||||
for d in self.devices:
|
||||
if d.iface == ifname:
|
||||
raise PermissionDeniedException("Device already added")
|
||||
dev = WiredDevice(self._bus, ifname)
|
||||
dev = WiredDevice(self._bus, ifname, mac, subchannels)
|
||||
self.add_device(dev)
|
||||
return to_path(dev)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue