all: add vlan-filtering and vlan-default-pvid bridge properties
This commit is contained in:
@@ -4808,6 +4808,12 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = {
|
||||
.prompt = N_("Enable IGMP snooping [no]"),
|
||||
.property_type = &_pt_gobject_bool,
|
||||
),
|
||||
PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_FILTERING,
|
||||
.property_type = &_pt_gobject_bool,
|
||||
),
|
||||
PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID,
|
||||
.property_type = &_pt_gobject_int,
|
||||
),
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@@ -118,6 +118,8 @@
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_SNOOPING N_("Controls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PRIORITY N_("Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are \"better\"; the lowest priority bridge will be elected the root bridge.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_STP N_("Controls whether Spanning Tree Protocol (STP) is enabled for this bridge.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID N_("The default PVID for the ports of the bridge, that is the VLAN id assigned to incoming untagged frames.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_FILTERING N_("Control whether VLAN filtering is enabled on the bridge.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE N_("Enables or disables \"hairpin mode\" for the port, which allows frames to be sent back out through the port the frame was received on.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PATH_COST N_("The Spanning Tree Protocol (STP) port cost for destinations via this port.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PRIORITY N_("The Spanning Tree Protocol (STP) priority of this bridge port.")
|
||||
|
@@ -50,6 +50,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
||||
PROP_AGEING_TIME,
|
||||
PROP_GROUP_FORWARD_MASK,
|
||||
PROP_MULTICAST_SNOOPING,
|
||||
PROP_VLAN_FILTERING,
|
||||
PROP_VLAN_DEFAULT_PVID,
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
@@ -62,6 +64,8 @@ typedef struct {
|
||||
guint32 ageing_time;
|
||||
guint16 group_forward_mask;
|
||||
gboolean multicast_snooping;
|
||||
gboolean vlan_filtering;
|
||||
guint16 vlan_default_pvid;
|
||||
} NMSettingBridgePrivate;
|
||||
|
||||
G_DEFINE_TYPE (NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING)
|
||||
@@ -200,6 +204,38 @@ nm_setting_bridge_get_multicast_snooping (NMSettingBridge *setting)
|
||||
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->multicast_snooping;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_get_vlan_filtering:
|
||||
* @setting: the #NMSettingBridge
|
||||
*
|
||||
* Returns: the #NMSettingBridge:vlan-filtering property of the setting
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
gboolean
|
||||
nm_setting_bridge_get_vlan_filtering (NMSettingBridge *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), FALSE);
|
||||
|
||||
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->vlan_filtering;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_get_vlan_default_pvid:
|
||||
* @setting: the #NMSettingBridge
|
||||
*
|
||||
* Returns: the #NMSettingBridge:vlan-default-pvid property of the setting
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
guint16
|
||||
nm_setting_bridge_get_vlan_default_pvid (NMSettingBridge *setting)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 1);
|
||||
|
||||
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->vlan_default_pvid;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_range (guint32 val,
|
||||
guint32 min,
|
||||
@@ -318,6 +354,12 @@ get_property (GObject *object, guint prop_id,
|
||||
case PROP_MULTICAST_SNOOPING:
|
||||
g_value_set_boolean (value, priv->multicast_snooping);
|
||||
break;
|
||||
case PROP_VLAN_FILTERING:
|
||||
g_value_set_boolean (value, priv->vlan_filtering);
|
||||
break;
|
||||
case PROP_VLAN_DEFAULT_PVID:
|
||||
g_value_set_uint (value, priv->vlan_default_pvid);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -360,6 +402,12 @@ set_property (GObject *object, guint prop_id,
|
||||
case PROP_MULTICAST_SNOOPING:
|
||||
priv->multicast_snooping = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_VLAN_FILTERING:
|
||||
priv->vlan_filtering = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_VLAN_DEFAULT_PVID:
|
||||
priv->vlan_default_pvid = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -627,6 +675,53 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass)
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* NMSettingBridge:vlan-filtering:
|
||||
*
|
||||
* Control whether VLAN filtering is enabled on the bridge.
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
/* ---ifcfg-rh---
|
||||
* property: vlan-filtering
|
||||
* variable: BRIDGING_OPTS: vlan_filtering=
|
||||
* values: 0 or 1
|
||||
* default: 0
|
||||
* description: VLAN filtering support.
|
||||
* ---end---
|
||||
*/
|
||||
obj_properties[PROP_VLAN_FILTERING] =
|
||||
g_param_spec_boolean (NM_SETTING_BRIDGE_VLAN_FILTERING, "", "",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* NMSettingBridge:vlan-default-pvid:
|
||||
*
|
||||
* The default PVID for the ports of the bridge, that is the VLAN id
|
||||
* assigned to incoming untagged frames.
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
/* ---ifcfg-rh---
|
||||
* property: vlan-default-pvid
|
||||
* variable: BRIDGING_OPTS: default_pvid=
|
||||
* values: 0 - 4094
|
||||
* default: 1
|
||||
* description: default VLAN PVID.
|
||||
* ---end---
|
||||
*/
|
||||
obj_properties[PROP_VLAN_DEFAULT_PVID] =
|
||||
g_param_spec_uint (NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, "", "",
|
||||
0, 4094, 1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/* ---dbus---
|
||||
* property: interface-name
|
||||
* format: string
|
||||
|
@@ -48,6 +48,8 @@ G_BEGIN_DECLS
|
||||
#define NM_SETTING_BRIDGE_AGEING_TIME "ageing-time"
|
||||
#define NM_SETTING_BRIDGE_GROUP_FORWARD_MASK "group-forward-mask"
|
||||
#define NM_SETTING_BRIDGE_MULTICAST_SNOOPING "multicast-snooping"
|
||||
#define NM_SETTING_BRIDGE_VLAN_FILTERING "vlan-filtering"
|
||||
#define NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID "vlan-default-pvid"
|
||||
|
||||
/**
|
||||
* NMSettingBridge:
|
||||
@@ -86,6 +88,10 @@ NM_AVAILABLE_IN_1_10
|
||||
guint16 nm_setting_bridge_get_group_forward_mask (NMSettingBridge *setting);
|
||||
|
||||
gboolean nm_setting_bridge_get_multicast_snooping (NMSettingBridge *setting);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
gboolean nm_setting_bridge_get_vlan_filtering (NMSettingBridge *setting);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
guint16 nm_setting_bridge_get_vlan_default_pvid (NMSettingBridge *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -1518,3 +1518,9 @@ global:
|
||||
nm_wireguard_peer_set_public_key;
|
||||
nm_wireguard_peer_unref;
|
||||
} libnm_1_14_0;
|
||||
|
||||
libnm_1_18_0 {
|
||||
global:
|
||||
nm_setting_bridge_get_vlan_filtering;
|
||||
nm_setting_bridge_get_vlan_default_pvid;
|
||||
} libnm_1_16_0;
|
||||
|
@@ -37,6 +37,7 @@ _LOG_DECLARE_SELF(NMDeviceBridge);
|
||||
|
||||
struct _NMDeviceBridge {
|
||||
NMDevice parent;
|
||||
bool vlan_configured:1;
|
||||
};
|
||||
|
||||
struct _NMDeviceBridgeClass {
|
||||
@@ -267,16 +268,6 @@ commit_option (NMDevice *device, NMSetting *setting, const Option *option, gbool
|
||||
nm_platform_sysctl_master_set_option (nm_device_get_platform (device), ifindex, option->sysname, value);
|
||||
}
|
||||
|
||||
static void
|
||||
commit_master_options (NMDevice *device, NMSettingBridge *setting)
|
||||
{
|
||||
const Option *option;
|
||||
NMSetting *s = NM_SETTING (setting);
|
||||
|
||||
for (option = master_options; option->name; option++)
|
||||
commit_option (device, s, option, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
commit_slave_options (NMDevice *device, NMSettingBridgePort *setting)
|
||||
{
|
||||
@@ -396,22 +387,97 @@ master_update_slave_connection (NMDevice *device,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
bridge_set_vlan_options (NMDevice *device, NMSettingBridge *s_bridge)
|
||||
{
|
||||
NMDeviceBridge *self = NM_DEVICE_BRIDGE (device);
|
||||
gconstpointer hwaddr;
|
||||
size_t length;
|
||||
gboolean enabled;
|
||||
guint16 pvid;
|
||||
NMPlatform *plat;
|
||||
int ifindex;
|
||||
|
||||
if (self->vlan_configured)
|
||||
return TRUE;
|
||||
|
||||
plat = nm_device_get_platform (device);
|
||||
ifindex = nm_device_get_ifindex (device);
|
||||
enabled = nm_setting_bridge_get_vlan_filtering (s_bridge);
|
||||
|
||||
if (!enabled) {
|
||||
nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "0");
|
||||
nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", "1");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
hwaddr = nm_platform_link_get_address (plat, ifindex, &length);
|
||||
g_return_val_if_fail (length == ETH_ALEN, FALSE);
|
||||
if (nm_utils_hwaddr_matches (hwaddr, ETH_ALEN, nm_ip_addr_zero.addr_eth, ETH_ALEN)) {
|
||||
/* We need a non-zero MAC address to set the default pvid.
|
||||
* Retry later. */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
self->vlan_configured = TRUE;
|
||||
|
||||
/* Filtering must be disabled to change the default PVID */
|
||||
if (!nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "0"))
|
||||
return FALSE;
|
||||
|
||||
/* Clear the default PVID so that we later can force the re-creation of
|
||||
* default PVID VLANs by writing the option again. */
|
||||
if (!nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", "0"))
|
||||
return FALSE;
|
||||
|
||||
/* Now set the default PVID. After this point the kernel creates
|
||||
* a PVID VLAN on each port, including the bridge itself. */
|
||||
pvid = nm_setting_bridge_get_vlan_default_pvid (s_bridge);
|
||||
if (pvid) {
|
||||
char value[32];
|
||||
|
||||
nm_sprintf_buf (value, "%u", pvid);
|
||||
if (!nm_platform_sysctl_master_set_option (plat, ifindex, "default_pvid", value))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nm_platform_sysctl_master_set_option (plat, ifindex, "vlan_filtering", "1"))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMActStageReturn
|
||||
act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
||||
{
|
||||
NMActStageReturn ret;
|
||||
NMConnection *connection = nm_device_get_applied_connection (device);
|
||||
NMConnection *connection;
|
||||
NMSetting *s_bridge;
|
||||
const Option *option;
|
||||
|
||||
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
NM_DEVICE_BRIDGE (device)->vlan_configured = FALSE;
|
||||
|
||||
ret = NM_DEVICE_CLASS (nm_device_bridge_parent_class)->act_stage1_prepare (device, out_failure_reason);
|
||||
if (ret != NM_ACT_STAGE_RETURN_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE))
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
connection = nm_device_get_applied_connection (device);
|
||||
g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
s_bridge = (NMSetting *) nm_connection_get_setting_bridge (connection);
|
||||
g_return_val_if_fail (s_bridge, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
commit_master_options (device, nm_connection_get_setting_bridge (connection));
|
||||
if (!nm_device_hw_addr_set_cloned (device, connection, FALSE)) {
|
||||
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
for (option = master_options; option->name; option++)
|
||||
commit_option (device, s_bridge, option, FALSE);
|
||||
|
||||
if (!bridge_set_vlan_options (device, (NMSettingBridge *) s_bridge)) {
|
||||
NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
|
||||
return NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
@@ -457,12 +523,22 @@ enslave_slave (NMDevice *device,
|
||||
gboolean configure)
|
||||
{
|
||||
NMDeviceBridge *self = NM_DEVICE_BRIDGE (device);
|
||||
NMConnection *master_connection;
|
||||
NMSettingBridge *s_bridge;
|
||||
NMSettingBridgePort *s_port;
|
||||
|
||||
if (configure) {
|
||||
if (!nm_platform_link_enslave (nm_device_get_platform (device), nm_device_get_ip_ifindex (device), nm_device_get_ip_ifindex (slave)))
|
||||
return FALSE;
|
||||
|
||||
commit_slave_options (slave, nm_connection_get_setting_bridge_port (connection));
|
||||
master_connection = nm_device_get_applied_connection (device);
|
||||
nm_assert (master_connection);
|
||||
s_bridge = nm_connection_get_setting_bridge (master_connection);
|
||||
nm_assert (s_bridge);
|
||||
s_port = nm_connection_get_setting_bridge_port (connection);
|
||||
|
||||
bridge_set_vlan_options (device, s_bridge);
|
||||
commit_slave_options (slave, s_port);
|
||||
|
||||
_LOGI (LOGD_BRIDGE, "attached bridge port %s",
|
||||
nm_device_get_ip_iface (slave));
|
||||
|
@@ -4958,6 +4958,8 @@ handle_bridge_option (NMSetting *setting,
|
||||
{ "max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE },
|
||||
{ "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION },
|
||||
{ "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION },
|
||||
{ "vlan_filtering", NM_SETTING_BRIDGE_VLAN_FILTERING, BRIDGE_OPT_TYPE_OPTION },
|
||||
{ "default_pvid", NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, BRIDGE_OPT_TYPE_OPTION },
|
||||
{ "group_fwd_mask", NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, BRIDGE_OPT_TYPE_OPTION },
|
||||
{ "priority", NM_SETTING_BRIDGE_PORT_PRIORITY, BRIDGE_OPT_TYPE_PORT_OPTION },
|
||||
{ "path_cost", NM_SETTING_BRIDGE_PORT_PATH_COST, BRIDGE_OPT_TYPE_PORT_OPTION },
|
||||
|
@@ -1534,6 +1534,20 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire
|
||||
g_string_append_printf (opts, "multicast_snooping=%u", (guint32) b);
|
||||
}
|
||||
|
||||
b = nm_setting_bridge_get_vlan_filtering (s_bridge);
|
||||
if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_FILTERING)) {
|
||||
if (opts->len)
|
||||
g_string_append_c (opts, ' ');
|
||||
g_string_append_printf (opts, "vlan_filtering=%u", (guint32) b);
|
||||
}
|
||||
|
||||
i = nm_setting_bridge_get_vlan_default_pvid (s_bridge);
|
||||
if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID)) {
|
||||
if (opts->len)
|
||||
g_string_append_c (opts, ' ');
|
||||
g_string_append_printf (opts, "default_pvid=%u", i);
|
||||
}
|
||||
|
||||
if (opts->len)
|
||||
svSetValueStr (ifcfg, "BRIDGING_OPTS", opts->str);
|
||||
g_string_free (opts, TRUE);
|
||||
|
@@ -4,5 +4,5 @@ TYPE=Bridge
|
||||
BOOTPROTO=dhcp
|
||||
STP=on
|
||||
DELAY=2
|
||||
BRIDGING_OPTS="priority=32744 hello_time=7 max_age=39 ageing_time=235352 multicast_snooping=0 group_fwd_mask=24"
|
||||
BRIDGING_OPTS="priority=32744 hello_time=7 max_age=39 ageing_time=235352 multicast_snooping=0 group_fwd_mask=24 vlan_filtering=1 default_pvid=99"
|
||||
MACADDR=00:16:41:11:22:33
|
||||
|
@@ -7507,6 +7507,8 @@ test_read_bridge_main (void)
|
||||
g_assert_cmpuint (nm_setting_bridge_get_ageing_time (s_bridge), ==, 235352);
|
||||
g_assert_cmpuint (nm_setting_bridge_get_group_forward_mask (s_bridge), ==, 24);
|
||||
g_assert (!nm_setting_bridge_get_multicast_snooping (s_bridge));
|
||||
g_assert_cmpint (nm_setting_bridge_get_vlan_filtering (s_bridge), ==, TRUE);
|
||||
g_assert_cmpint (nm_setting_bridge_get_vlan_default_pvid (s_bridge), ==, 99);
|
||||
|
||||
/* MAC address */
|
||||
s_wired = nm_connection_get_setting_wired (connection);
|
||||
@@ -7554,6 +7556,8 @@ test_write_bridge_main (void)
|
||||
g_object_set (s_bridge,
|
||||
NM_SETTING_BRIDGE_MAC_ADDRESS, mac,
|
||||
NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, 19008,
|
||||
NM_SETTING_BRIDGE_VLAN_FILTERING, TRUE,
|
||||
NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, 4000,
|
||||
NULL);
|
||||
|
||||
/* IP4 setting */
|
||||
|
Reference in New Issue
Block a user