mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-24 19:30:07 +01:00
Merge branch 'th/bgo729844_set_bridge_mac_address'
https://bugzilla.gnome.org/show_bug.cgi?id=729844 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
commit
fad5472b34
20 changed files with 217 additions and 41 deletions
|
|
@ -947,7 +947,7 @@ _nmcli()
|
|||
OPTIONS_IP=()
|
||||
;;
|
||||
bridge)
|
||||
OPTIONS_TYPED=(stp priority forward-delay hello-time max-age ageing-time)
|
||||
OPTIONS_TYPED=(stp priority forward-delay hello-time max-age ageing-time mac)
|
||||
;;
|
||||
bridge-|bridge-s|bridge-sl|bridge-sla|bridge-slav|bridge-slave)
|
||||
OPTIONS_TYPED=(master priority path-cost hairpin)
|
||||
|
|
|
|||
|
|
@ -395,7 +395,8 @@ usage_connection_add (void)
|
|||
" [forward-delay <2-30>]\n"
|
||||
" [hello-time <1-10>]\n"
|
||||
" [max-age <6-40>]\n"
|
||||
" [ageing-time <0-1000000>]\n\n"
|
||||
" [ageing-time <0-1000000>]\n"
|
||||
" [mac <MAC address>]\n\n"
|
||||
" bridge-slave: master <master (ifname, or connection UUID or name)>\n"
|
||||
" [priority <0-63>]\n"
|
||||
" [path-cost <1-65535>]\n"
|
||||
|
|
@ -3320,8 +3321,8 @@ do_questionnaire_team_slave (char **config)
|
|||
}
|
||||
|
||||
static void
|
||||
do_questionnaire_bridge (char **stp, char **priority, char **fwd_delay,
|
||||
char **hello_time, char **max_age, char **ageing_time)
|
||||
do_questionnaire_bridge (char **stp, char **priority, char **fwd_delay, char **hello_time,
|
||||
char **max_age, char **ageing_time, char **mac)
|
||||
{
|
||||
char *answer;
|
||||
gboolean answer_bool;
|
||||
|
|
@ -3330,7 +3331,7 @@ do_questionnaire_bridge (char **stp, char **priority, char **fwd_delay,
|
|||
GError *error = NULL;
|
||||
|
||||
/* Ask for optional 'bridge' arguments. */
|
||||
printf (_("There are 6 optional arguments for 'bridge' connection type.\n"));
|
||||
printf (_("There are 7 optional arguments for 'bridge' connection type.\n"));
|
||||
answer = nmc_get_user_input (_("Do you want to provide them? (yes/no) [yes] "));
|
||||
if (answer && (!nmc_string_to_bool (answer, &answer_bool, NULL) || !answer_bool)) {
|
||||
g_free (answer);
|
||||
|
|
@ -3411,6 +3412,17 @@ do_questionnaire_bridge (char **stp, char **priority, char **fwd_delay,
|
|||
}
|
||||
} while (once_more);
|
||||
}
|
||||
if (!*mac) {
|
||||
do {
|
||||
*mac = nmc_get_user_input (_("MAC [none]: "));
|
||||
once_more = !check_and_convert_mac (*mac, NULL, ARPHRD_ETHER, "mac", &error);
|
||||
if (once_more) {
|
||||
printf ("%s\n", error->message);
|
||||
g_clear_error (&error);
|
||||
g_free (*mac);
|
||||
}
|
||||
} while (once_more);
|
||||
}
|
||||
|
||||
g_free (answer);
|
||||
return;
|
||||
|
|
@ -4562,12 +4574,16 @@ cleanup_team_slave:
|
|||
gboolean stp_bool;
|
||||
unsigned long stp_prio_int, fwd_delay_int, hello_time_int,
|
||||
max_age_int, ageing_time_int;
|
||||
const char *mac_c = NULL;
|
||||
char *mac = NULL;
|
||||
GByteArray *mac_array = NULL;
|
||||
nmc_arg_t exp_args[] = { {"stp", TRUE, &stp_c, FALSE},
|
||||
{"priority", TRUE, &priority_c, FALSE},
|
||||
{"forward-delay", TRUE, &fwd_delay_c, FALSE},
|
||||
{"hello-time", TRUE, &hello_time_c, FALSE},
|
||||
{"max-age", TRUE, &max_age_c, FALSE},
|
||||
{"ageing-time", TRUE, &ageing_time_c, FALSE},
|
||||
{"mac", TRUE, &mac_c, FALSE},
|
||||
{NULL} };
|
||||
|
||||
if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error))
|
||||
|
|
@ -4580,9 +4596,10 @@ cleanup_team_slave:
|
|||
hello_time = hello_time_c ? g_strdup (hello_time_c) : NULL;
|
||||
max_age = max_age_c ? g_strdup (max_age_c) : NULL;
|
||||
ageing_time = ageing_time_c ? g_strdup (ageing_time_c) : NULL;
|
||||
mac = g_strdup (mac_c);
|
||||
if (ask)
|
||||
do_questionnaire_bridge (&stp, &priority, &fwd_delay, &hello_time,
|
||||
&max_age, &ageing_time);
|
||||
&max_age, &ageing_time, &mac);
|
||||
|
||||
/* Use connection's ifname as 'bridge' ifname if exists, else generate one */
|
||||
ifname = nm_setting_connection_get_interface_name (s_con);
|
||||
|
|
@ -4629,6 +4646,8 @@ cleanup_team_slave:
|
|||
if (!bridge_prop_string_to_uint (ageing_time, "ageing-time", NM_TYPE_SETTING_BRIDGE,
|
||||
NM_SETTING_BRIDGE_AGEING_TIME, &ageing_time_int, error))
|
||||
goto cleanup_bridge;
|
||||
if (!check_and_convert_mac (mac, &mac_array, ARPHRD_ETHER, "mac", error))
|
||||
goto cleanup_bridge;
|
||||
|
||||
/* Set bridge options */
|
||||
g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, bridge_ifname, NULL);
|
||||
|
|
@ -4644,6 +4663,8 @@ cleanup_team_slave:
|
|||
g_object_set (s_bridge, NM_SETTING_BRIDGE_MAX_AGE, max_age_int, NULL);
|
||||
if (ageing_time)
|
||||
g_object_set (s_bridge, NM_SETTING_BRIDGE_AGEING_TIME, ageing_time_int, NULL);
|
||||
if (mac_array)
|
||||
g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, mac_array, NULL);
|
||||
|
||||
success = TRUE;
|
||||
cleanup_bridge:
|
||||
|
|
@ -4654,6 +4675,9 @@ cleanup_bridge:
|
|||
g_free (hello_time);
|
||||
g_free (max_age);
|
||||
g_free (ageing_time);
|
||||
g_free (mac);
|
||||
if (mac_array)
|
||||
g_byte_array_free (mac_array, TRUE);
|
||||
if (!success)
|
||||
return FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -564,16 +564,18 @@ NmcOutputField nmc_fields_setting_vlan[] = {
|
|||
NmcOutputField nmc_fields_setting_bridge[] = {
|
||||
SETTING_FIELD ("name", 8), /* 0 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_INTERFACE_NAME, 15), /* 1 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_STP, 5), /* 2 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_PRIORITY, 6), /* 3 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_FORWARD_DELAY, 6), /* 4 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_HELLO_TIME, 6), /* 5 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_MAX_AGE, 6), /* 6 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_AGEING_TIME, 6), /* 7 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_MAC_ADDRESS, 19), /* 2 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_STP, 5), /* 3 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_PRIORITY, 6), /* 4 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_FORWARD_DELAY, 6), /* 5 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_HELLO_TIME, 6), /* 6 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_MAX_AGE, 6), /* 7 */
|
||||
SETTING_FIELD (NM_SETTING_BRIDGE_AGEING_TIME, 6), /* 8 */
|
||||
{NULL, NULL, 0, NULL, FALSE, FALSE, 0}
|
||||
};
|
||||
#define NMC_FIELDS_SETTING_BRIDGE_ALL "name"","\
|
||||
NM_SETTING_BRIDGE_INTERFACE_NAME","\
|
||||
NM_SETTING_BRIDGE_MAC_ADDRESS","\
|
||||
NM_SETTING_BRIDGE_STP","\
|
||||
NM_SETTING_BRIDGE_PRIORITY","\
|
||||
NM_SETTING_BRIDGE_FORWARD_DELAY","\
|
||||
|
|
@ -1053,6 +1055,7 @@ nmc_property_bond_get_options (NMSetting *setting)
|
|||
|
||||
/* --- NM_SETTING_BRIDGE_SETTING_NAME property get functions --- */
|
||||
DEFINE_GETTER (nmc_property_bridge_get_interface_name, NM_SETTING_BRIDGE_INTERFACE_NAME)
|
||||
DEFINE_HWADDR_GETTER (nmc_property_bridge_get_mac_address, NM_SETTING_BRIDGE_MAC_ADDRESS)
|
||||
DEFINE_GETTER (nmc_property_bridge_get_stp, NM_SETTING_BRIDGE_STP)
|
||||
DEFINE_GETTER (nmc_property_bridge_get_priority, NM_SETTING_BRIDGE_PRIORITY)
|
||||
DEFINE_GETTER (nmc_property_bridge_get_forward_delay, NM_SETTING_BRIDGE_FORWARD_DELAY)
|
||||
|
|
@ -4926,6 +4929,13 @@ nmc_properties_init (void)
|
|||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
nmc_add_prop_funcs (GLUE (BRIDGE, MAC_ADDRESS),
|
||||
nmc_property_bridge_get_mac_address,
|
||||
nmc_property_set_mac,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
nmc_add_prop_funcs (GLUE (BRIDGE, STP),
|
||||
nmc_property_bridge_get_stp,
|
||||
nmc_property_set_bool,
|
||||
|
|
@ -7127,12 +7137,13 @@ setting_bridge_details (NMSetting *setting, NmCli *nmc, const char *one_prop)
|
|||
arr = nmc_dup_fields_array (tmpl, tmpl_len, NMC_OF_FLAG_SECTION_PREFIX);
|
||||
set_val_str (arr, 0, g_strdup (nm_setting_get_name (setting)));
|
||||
set_val_str (arr, 1, nmc_property_bridge_get_interface_name (setting));
|
||||
set_val_str (arr, 2, nmc_property_bridge_get_stp (setting));
|
||||
set_val_str (arr, 3, nmc_property_bridge_get_priority (setting));
|
||||
set_val_str (arr, 4, nmc_property_bridge_get_forward_delay (setting));
|
||||
set_val_str (arr, 5, nmc_property_bridge_get_hello_time (setting));
|
||||
set_val_str (arr, 6, nmc_property_bridge_get_max_age (setting));
|
||||
set_val_str (arr, 7, nmc_property_bridge_get_ageing_time (setting));
|
||||
set_val_str (arr, 2, nmc_property_bridge_get_mac_address (setting));
|
||||
set_val_str (arr, 3, nmc_property_bridge_get_stp (setting));
|
||||
set_val_str (arr, 4, nmc_property_bridge_get_priority (setting));
|
||||
set_val_str (arr, 5, nmc_property_bridge_get_forward_delay (setting));
|
||||
set_val_str (arr, 6, nmc_property_bridge_get_hello_time (setting));
|
||||
set_val_str (arr, 7, nmc_property_bridge_get_max_age (setting));
|
||||
set_val_str (arr, 8, nmc_property_bridge_get_ageing_time (setting));
|
||||
g_ptr_array_add (nmc->output_data, arr);
|
||||
|
||||
print_data (nmc); /* Print all data */
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ global:
|
|||
nm_setting_bridge_get_forward_delay;
|
||||
nm_setting_bridge_get_hello_time;
|
||||
nm_setting_bridge_get_interface_name;
|
||||
nm_setting_bridge_get_mac_address;
|
||||
nm_setting_bridge_get_max_age;
|
||||
nm_setting_bridge_get_priority;
|
||||
nm_setting_bridge_get_stp;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#include "nm-setting-bridge.h"
|
||||
#include "nm-param-spec-specialized.h"
|
||||
|
|
@ -76,6 +77,7 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_BRIDGE)
|
|||
|
||||
typedef struct {
|
||||
char * interface_name;
|
||||
GByteArray *mac_address;
|
||||
gboolean stp;
|
||||
guint16 priority;
|
||||
guint16 forward_delay;
|
||||
|
|
@ -87,6 +89,7 @@ typedef struct {
|
|||
enum {
|
||||
PROP_0,
|
||||
PROP_INTERFACE_NAME,
|
||||
PROP_MAC_ADDRESS,
|
||||
PROP_STP,
|
||||
PROP_PRIORITY,
|
||||
PROP_FORWARD_DELAY,
|
||||
|
|
@ -127,6 +130,22 @@ nm_setting_bridge_get_interface_name (NMSettingBridge *setting)
|
|||
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->interface_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_get_mac_address:
|
||||
* @setting: the #NMSettingBridge
|
||||
*
|
||||
* Returns: the #NMSettingBridge:mac-address property of the setting
|
||||
*
|
||||
* Since: 0.9.10
|
||||
**/
|
||||
const GByteArray *
|
||||
nm_setting_bridge_get_mac_address (NMSettingBridge *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), NULL);
|
||||
|
||||
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->mac_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_get_stp:
|
||||
* @setting: the #NMSettingBridge
|
||||
|
|
@ -280,6 +299,15 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (priv->mac_address && priv->mac_address->len != ETH_ALEN) {
|
||||
g_set_error_literal (error,
|
||||
NM_SETTING_BRIDGE_ERROR,
|
||||
NM_SETTING_BRIDGE_ERROR_INVALID_PROPERTY,
|
||||
_("is not a valid MAC address"));
|
||||
g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAC_ADDRESS);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!check_range (priv->forward_delay,
|
||||
BR_MIN_FORWARD_DELAY,
|
||||
BR_MAX_FORWARD_DELAY,
|
||||
|
|
@ -331,6 +359,9 @@ finalize (GObject *object)
|
|||
|
||||
g_free (priv->interface_name);
|
||||
|
||||
if (priv->mac_address)
|
||||
g_byte_array_free (priv->mac_address, TRUE);
|
||||
|
||||
G_OBJECT_CLASS (nm_setting_bridge_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
|
@ -345,6 +376,11 @@ set_property (GObject *object, guint prop_id,
|
|||
g_free (priv->interface_name);
|
||||
priv->interface_name = g_value_dup_string (value);
|
||||
break;
|
||||
case PROP_MAC_ADDRESS:
|
||||
if (priv->mac_address)
|
||||
g_byte_array_free (priv->mac_address, TRUE);
|
||||
priv->mac_address = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_STP:
|
||||
priv->stp = g_value_get_boolean (value);
|
||||
break;
|
||||
|
|
@ -380,6 +416,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_INTERFACE_NAME:
|
||||
g_value_set_string (value, nm_setting_bridge_get_interface_name (setting));
|
||||
break;
|
||||
case PROP_MAC_ADDRESS:
|
||||
g_value_set_boxed (value, nm_setting_bridge_get_mac_address (setting));
|
||||
break;
|
||||
case PROP_STP:
|
||||
g_value_set_boolean (value, priv->stp);
|
||||
break;
|
||||
|
|
@ -435,6 +474,23 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *setting_class)
|
|||
NULL,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE));
|
||||
|
||||
/**
|
||||
* NMSettingBridge:mac-address:
|
||||
*
|
||||
* If specified, the MAC address of bridge. When creating a new bridge, this MAC address
|
||||
* will be set. When matching an existing (outside NetworkManager created) bridge, this
|
||||
* MAC address must match.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_MAC_ADDRESS,
|
||||
_nm_param_spec_specialized (NM_SETTING_BRIDGE_MAC_ADDRESS,
|
||||
"MAC Address",
|
||||
"The MAC address of the bridge",
|
||||
DBUS_TYPE_G_UCHAR_ARRAY,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE));
|
||||
|
||||
/**
|
||||
* NMSettingBridge:stp:
|
||||
*
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ typedef enum {
|
|||
GQuark nm_setting_bridge_error_quark (void);
|
||||
|
||||
#define NM_SETTING_BRIDGE_INTERFACE_NAME "interface-name"
|
||||
#define NM_SETTING_BRIDGE_MAC_ADDRESS "mac-address"
|
||||
#define NM_SETTING_BRIDGE_STP "stp"
|
||||
#define NM_SETTING_BRIDGE_PRIORITY "priority"
|
||||
#define NM_SETTING_BRIDGE_FORWARD_DELAY "forward-delay"
|
||||
|
|
@ -83,6 +84,9 @@ NMSetting * nm_setting_bridge_new (void);
|
|||
|
||||
const char * nm_setting_bridge_get_interface_name (NMSettingBridge *setting);
|
||||
|
||||
NM_AVAILABLE_IN_0_9_10
|
||||
const GByteArray *nm_setting_bridge_get_mac_address (NMSettingBridge *setting);
|
||||
|
||||
gboolean nm_setting_bridge_get_stp (NMSettingBridge *setting);
|
||||
|
||||
guint16 nm_setting_bridge_get_priority (NMSettingBridge *setting);
|
||||
|
|
|
|||
|
|
@ -555,6 +555,9 @@ The value can be prefixed with \fBifname/\fP, \fBuuid/\fP or \fBid/\fP to disamb
|
|||
\(en STP maximum message age, in seconds (default: 20)
|
||||
.IP "\fI[ageing-time <0-1000000>]\fP" 42
|
||||
\(en the Ethernet MAC address aging time, in seconds (default: 300)
|
||||
.IP "\fI[mac <MAC address>]\fP" 42
|
||||
\(en MAC address of the bridge (note: this requires a recent kernel feature,
|
||||
originally introduced in 3.15 upstream kernel)
|
||||
.RE
|
||||
.RS
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ check_connection_compatible (NMDevice *device,
|
|||
{
|
||||
const char *iface;
|
||||
NMSettingBridge *s_bridge;
|
||||
const GByteArray *mac_address;
|
||||
|
||||
if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_compatible (device, connection, error))
|
||||
return FALSE;
|
||||
|
|
@ -121,6 +122,21 @@ check_connection_compatible (NMDevice *device,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
mac_address = nm_setting_bridge_get_mac_address (s_bridge);
|
||||
if (mac_address) {
|
||||
guint hw_len;
|
||||
const guint8 *hw_addr;
|
||||
|
||||
hw_addr = nm_device_get_hw_address (device, &hw_len);
|
||||
if ( !hw_addr
|
||||
|| hw_len != mac_address->len
|
||||
|| memcmp (mac_address->data, hw_addr, hw_len) != 0) {
|
||||
g_set_error (error, NM_BRIDGE_ERROR, NM_BRIDGE_ERROR_CONNECTION_INVALID,
|
||||
"The bridge mac-address does not match the address of the device.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -438,13 +454,22 @@ NMDevice *
|
|||
nm_device_bridge_new_for_connection (NMConnection *connection)
|
||||
{
|
||||
const char *iface;
|
||||
NMSettingBridge *s_bridge;
|
||||
const GByteArray *mac_address;
|
||||
|
||||
g_return_val_if_fail (connection != NULL, NULL);
|
||||
|
||||
iface = nm_connection_get_virtual_iface_name (connection);
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
|
||||
if ( !nm_platform_bridge_add (iface)
|
||||
s_bridge = nm_connection_get_setting_bridge (connection);
|
||||
g_return_val_if_fail (s_bridge, NULL);
|
||||
|
||||
mac_address = nm_setting_bridge_get_mac_address (s_bridge);
|
||||
|
||||
if ( !nm_platform_bridge_add (iface,
|
||||
mac_address ? mac_address->data : NULL,
|
||||
mac_address ? mac_address->len : 0)
|
||||
&& nm_platform_get_error () != NM_PLATFORM_ERROR_EXISTS) {
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_BRIDGE, "(%s): failed to create bridge master interface for '%s': %s",
|
||||
iface, nm_connection_get_id (connection),
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ link_added_emit (gpointer user_data)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
link_add (NMPlatform *platform, const char *name, NMLinkType type)
|
||||
link_add (NMPlatform *platform, const char *name, NMLinkType type, const void *address, size_t address_len)
|
||||
{
|
||||
NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform);
|
||||
NMFakePlatformLink device;
|
||||
|
|
@ -600,7 +600,7 @@ vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint
|
|||
{
|
||||
NMFakePlatformLink *device;
|
||||
|
||||
if (!link_add (platform, name, NM_LINK_TYPE_VLAN))
|
||||
if (!link_add (platform, name, NM_LINK_TYPE_VLAN, NULL, 0))
|
||||
return FALSE;
|
||||
|
||||
device = link_get (platform, link_get_ifindex (platform, name));
|
||||
|
|
@ -651,7 +651,7 @@ infiniband_partition_add (NMPlatform *platform, int parent, int p_key)
|
|||
g_return_val_if_fail (parent_device != NULL, FALSE);
|
||||
|
||||
name = g_strdup_printf ("%s.%04x", parent_device->link.name, p_key);
|
||||
success = link_add (platform, name, NM_LINK_TYPE_INFINIBAND);
|
||||
success = link_add (platform, name, NM_LINK_TYPE_INFINIBAND, NULL, 0);
|
||||
g_free (name);
|
||||
|
||||
return success;
|
||||
|
|
@ -1232,15 +1232,15 @@ static gboolean
|
|||
setup (NMPlatform *platform)
|
||||
{
|
||||
/* skip zero element */
|
||||
link_add (platform, NULL, NM_LINK_TYPE_NONE);
|
||||
link_add (platform, NULL, NM_LINK_TYPE_NONE, NULL, 0);
|
||||
|
||||
/* add loopback interface */
|
||||
link_add (platform, "lo", NM_LINK_TYPE_LOOPBACK);
|
||||
link_add (platform, "lo", NM_LINK_TYPE_LOOPBACK, NULL, 0);
|
||||
|
||||
/* add some ethernets */
|
||||
link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET);
|
||||
link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET);
|
||||
link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET);
|
||||
link_add (platform, "eth0", NM_LINK_TYPE_ETHERNET, NULL, 0);
|
||||
link_add (platform, "eth1", NM_LINK_TYPE_ETHERNET, NULL, 0);
|
||||
link_add (platform, "eth2", NM_LINK_TYPE_ETHERNET, NULL, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1871,9 +1871,10 @@ build_rtnl_link (int ifindex, const char *name, NMLinkType type)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
link_add (NMPlatform *platform, const char *name, NMLinkType type)
|
||||
link_add (NMPlatform *platform, const char *name, NMLinkType type, const void *address, size_t address_len)
|
||||
{
|
||||
int r;
|
||||
struct nl_object *link;
|
||||
|
||||
if (type == NM_LINK_TYPE_BOND) {
|
||||
/* When the kernel loads the bond module, either via explicit modprobe
|
||||
|
|
@ -1891,7 +1892,15 @@ link_add (NMPlatform *platform, const char *name, NMLinkType type)
|
|||
debug ("link: add link '%s' of type '%s' (%d)",
|
||||
name, type_to_string (type), (int) type);
|
||||
|
||||
return add_object (platform, build_rtnl_link (0, name, type));
|
||||
link = build_rtnl_link (0, name, type);
|
||||
|
||||
g_assert ( (address != NULL) ^ (address_len == 0) );
|
||||
if (address) {
|
||||
auto_nl_addr struct nl_addr *nladdr = _nm_nl_addr_build (AF_LLC, address, address_len);
|
||||
|
||||
rtnl_link_set_addr ((struct rtnl_link *) link, nladdr);
|
||||
}
|
||||
return add_object (platform, link);
|
||||
}
|
||||
|
||||
static struct rtnl_link *
|
||||
|
|
|
|||
|
|
@ -443,18 +443,21 @@ nm_platform_link_get_all (void)
|
|||
* nm_platform_link_add:
|
||||
* @name: Interface name
|
||||
* @type: Interface type
|
||||
* @address: (allow-none): set the mac address of the link
|
||||
* @address_len: the length of the @address
|
||||
*
|
||||
* Add a software interface. Sets platform->error to NM_PLATFORM_ERROR_EXISTS
|
||||
* if interface is already already exists. Any link-added signal will be
|
||||
* emitted from an idle handler and not within this function.
|
||||
*/
|
||||
static gboolean
|
||||
nm_platform_link_add (const char *name, NMLinkType type)
|
||||
nm_platform_link_add (const char *name, NMLinkType type, const void *address, size_t address_len)
|
||||
{
|
||||
reset_error ();
|
||||
|
||||
g_return_val_if_fail (name, FALSE);
|
||||
g_return_val_if_fail (klass->link_add, FALSE);
|
||||
g_return_val_if_fail ( (address != NULL) ^ (address_len == 0) , FALSE);
|
||||
|
||||
if (nm_platform_link_exists (name)) {
|
||||
debug ("link: already exists");
|
||||
|
|
@ -462,7 +465,7 @@ nm_platform_link_add (const char *name, NMLinkType type)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
return klass->link_add (platform, name, type);
|
||||
return klass->link_add (platform, name, type, address, address_len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -477,7 +480,7 @@ nm_platform_dummy_add (const char *name)
|
|||
g_return_val_if_fail (name, FALSE);
|
||||
|
||||
debug ("link: adding dummy '%s'", name);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_DUMMY);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_DUMMY, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -985,14 +988,16 @@ nm_platform_link_get_master (int slave)
|
|||
/**
|
||||
* nm_platform_bridge_add:
|
||||
* @name: New interface name
|
||||
* @address: (allow-none): set the mac address of the new bridge
|
||||
* @address_len: the length of the @address
|
||||
*
|
||||
* Create a software bridge.
|
||||
*/
|
||||
gboolean
|
||||
nm_platform_bridge_add (const char *name)
|
||||
nm_platform_bridge_add (const char *name, const void *address, size_t address_len)
|
||||
{
|
||||
debug ("link: adding bridge '%s'", name);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_BRIDGE);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_BRIDGE, address, address_len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1005,7 +1010,7 @@ gboolean
|
|||
nm_platform_bond_add (const char *name)
|
||||
{
|
||||
debug ("link: adding bond '%s'", name);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_BOND);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_BOND, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1018,7 +1023,7 @@ gboolean
|
|||
nm_platform_team_add (const char *name)
|
||||
{
|
||||
debug ("link: adding team '%s'", name);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_TEAM);
|
||||
return nm_platform_link_add (name, NM_LINK_TYPE_TEAM, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -347,7 +347,7 @@ typedef struct {
|
|||
char * (*sysctl_get) (NMPlatform *, const char *path);
|
||||
|
||||
GArray *(*link_get_all) (NMPlatform *);
|
||||
gboolean (*link_add) (NMPlatform *, const char *name, NMLinkType type);
|
||||
gboolean (*link_add) (NMPlatform *, const char *name, NMLinkType type, const void *address, size_t address_len);
|
||||
gboolean (*link_delete) (NMPlatform *, int ifindex);
|
||||
int (*link_get_ifindex) (NMPlatform *, const char *name);
|
||||
const char *(*link_get_name) (NMPlatform *, int ifindex);
|
||||
|
|
@ -479,7 +479,7 @@ gint64 nm_platform_sysctl_get_int_checked (const char *path, guint base, gint64
|
|||
|
||||
GArray *nm_platform_link_get_all (void);
|
||||
gboolean nm_platform_dummy_add (const char *name);
|
||||
gboolean nm_platform_bridge_add (const char *name);
|
||||
gboolean nm_platform_bridge_add (const char *name, const void *address, size_t address_len);
|
||||
gboolean nm_platform_bond_add (const char *name);
|
||||
gboolean nm_platform_team_add (const char *name);
|
||||
gboolean nm_platform_link_exists (const char *name);
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ do_dummy_add (char **argv)
|
|||
static gboolean
|
||||
do_bridge_add (char **argv)
|
||||
{
|
||||
return nm_platform_bridge_add (argv[0]);
|
||||
return nm_platform_bridge_add (argv[0], NULL, 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ software_add (NMLinkType link_type, const char *name)
|
|||
case NM_LINK_TYPE_DUMMY:
|
||||
return nm_platform_dummy_add (name);
|
||||
case NM_LINK_TYPE_BRIDGE:
|
||||
return nm_platform_bridge_add (name);
|
||||
return nm_platform_bridge_add (name, NULL, 0);
|
||||
case NM_LINK_TYPE_BOND:
|
||||
{
|
||||
gboolean bond0_exists = nm_platform_link_exists ("bond0");
|
||||
|
|
@ -111,7 +111,7 @@ software_add (NMLinkType link_type, const char *name)
|
|||
|
||||
/* Don't call link_callback for the bridge interface */
|
||||
parent_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, PARENT_NAME);
|
||||
if (nm_platform_bridge_add (PARENT_NAME))
|
||||
if (nm_platform_bridge_add (PARENT_NAME, NULL, 0))
|
||||
wait_signal (parent_added);
|
||||
free_signal (parent_added);
|
||||
|
||||
|
|
|
|||
|
|
@ -4508,6 +4508,7 @@ make_bridge_setting (shvarFile *ifcfg,
|
|||
guint32 u;
|
||||
gboolean stp = FALSE;
|
||||
gboolean stp_set = FALSE;
|
||||
GByteArray *array = NULL;
|
||||
|
||||
s_bridge = NM_SETTING_BRIDGE (nm_setting_bridge_new ());
|
||||
|
||||
|
|
@ -4520,6 +4521,16 @@ make_bridge_setting (shvarFile *ifcfg,
|
|||
g_object_set (s_bridge, NM_SETTING_BRIDGE_INTERFACE_NAME, value, NULL);
|
||||
g_free (value);
|
||||
|
||||
if (read_mac_address (ifcfg, "MACADDR", ARPHRD_ETHER, &array, error)) {
|
||||
if (array) {
|
||||
g_object_set (s_bridge, NM_SETTING_BRIDGE_MAC_ADDRESS, array, NULL);
|
||||
g_byte_array_free (array, TRUE);
|
||||
}
|
||||
} else {
|
||||
PARSE_WARNING ("%s", (*error)->message);
|
||||
g_clear_error (error);
|
||||
}
|
||||
|
||||
value = svGetValue (ifcfg, "STP", FALSE);
|
||||
if (value) {
|
||||
if (!strcasecmp (value, "on") || !strcasecmp (value, "yes")) {
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ BOOTPROTO=dhcp
|
|||
STP=on
|
||||
DELAY=0
|
||||
BRIDGING_OPTS="priority=32744 hello_time=7 max_age=39 ageing_time=235352"
|
||||
MACADDR=00:16:41:11:22:33
|
||||
|
|
|
|||
|
|
@ -12056,6 +12056,8 @@ test_read_bridge_main (void)
|
|||
{
|
||||
NMConnection *connection;
|
||||
NMSettingBridge *s_bridge;
|
||||
const GByteArray *array;
|
||||
char expected_mac_address[ETH_ALEN] = { 0x00, 0x16, 0x41, 0x11, 0x22, 0x33 };
|
||||
char *unmanaged = NULL;
|
||||
char *keyfile = NULL;
|
||||
char *routefile = NULL;
|
||||
|
|
@ -12088,6 +12090,11 @@ test_read_bridge_main (void)
|
|||
g_assert_cmpuint (nm_setting_bridge_get_hello_time (s_bridge), ==, 7);
|
||||
g_assert_cmpuint (nm_setting_bridge_get_max_age (s_bridge), ==, 39);
|
||||
g_assert_cmpuint (nm_setting_bridge_get_ageing_time (s_bridge), ==, 235352);
|
||||
/* MAC address */
|
||||
array = nm_setting_bridge_get_mac_address (s_bridge);
|
||||
g_assert (array);
|
||||
g_assert_cmpint (array->len, ==, ETH_ALEN);
|
||||
g_assert (memcmp (array->data, &expected_mac_address[0], ETH_ALEN) == 0);
|
||||
|
||||
g_free (unmanaged);
|
||||
g_free (keyfile);
|
||||
|
|
@ -12110,6 +12117,8 @@ test_write_bridge_main (void)
|
|||
const guint32 gw = htonl (0x01010101);
|
||||
const guint32 prefix = 24;
|
||||
NMIP4Address *addr;
|
||||
static unsigned char bridge_mac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
|
||||
GByteArray *mac_array;
|
||||
gboolean success;
|
||||
GError *error = NULL;
|
||||
char *testfile = NULL;
|
||||
|
|
@ -12141,9 +12150,13 @@ test_write_bridge_main (void)
|
|||
g_assert (s_bridge);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_bridge));
|
||||
|
||||
mac_array = g_byte_array_sized_new (sizeof (bridge_mac));
|
||||
g_byte_array_append (mac_array, bridge_mac, sizeof (bridge_mac));
|
||||
g_object_set (s_bridge,
|
||||
NM_SETTING_BRIDGE_INTERFACE_NAME, "br0",
|
||||
NM_SETTING_BRIDGE_MAC_ADDRESS, mac_array,
|
||||
NULL);
|
||||
g_byte_array_free (mac_array, TRUE);
|
||||
|
||||
/* IP4 setting */
|
||||
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||
|
|
|
|||
|
|
@ -1379,6 +1379,7 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, GError **error
|
|||
const char *iface;
|
||||
guint32 i;
|
||||
GString *opts;
|
||||
const GByteArray *mac;
|
||||
char *s;
|
||||
|
||||
s_bridge = nm_connection_get_setting_bridge (connection);
|
||||
|
|
@ -1398,6 +1399,11 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, GError **error
|
|||
svSetValue (ifcfg, "BRIDGING_OPTS", NULL, FALSE);
|
||||
svSetValue (ifcfg, "STP", "no", FALSE);
|
||||
svSetValue (ifcfg, "DELAY", NULL, FALSE);
|
||||
svSetValue (ifcfg, "MACADDR", NULL, FALSE);
|
||||
|
||||
mac = nm_setting_bridge_get_mac_address (s_bridge);
|
||||
if (mac)
|
||||
svSetValue_free (ifcfg, "MACADDR", nm_utils_hwaddr_ntoa_len (mac->data, mac->len), FALSE);
|
||||
|
||||
/* Bridge options */
|
||||
opts = g_string_sized_new (32);
|
||||
|
|
|
|||
|
|
@ -901,6 +901,10 @@ static KeyParser key_parsers[] = {
|
|||
NM_SETTING_CONNECTION_TYPE,
|
||||
TRUE,
|
||||
setting_alias_parser },
|
||||
{ NM_SETTING_BRIDGE_SETTING_NAME,
|
||||
NM_SETTING_BRIDGE_MAC_ADDRESS,
|
||||
TRUE,
|
||||
mac_address_parser_ETHER },
|
||||
{ NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES,
|
||||
FALSE,
|
||||
|
|
|
|||
|
|
@ -774,6 +774,9 @@ static KeyWriter key_writers[] = {
|
|||
{ NM_SETTING_CONNECTION_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_TYPE,
|
||||
setting_alias_writer },
|
||||
{ NM_SETTING_BRIDGE_SETTING_NAME,
|
||||
NM_SETTING_BRIDGE_MAC_ADDRESS,
|
||||
mac_address_writer },
|
||||
{ NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_ADDRESSES,
|
||||
ip4_addr_writer },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue