network/brvlan: make [BridgeVLAN] settings support an empty string

This also renames Network.pvid and friends.
This commit is contained in:
Yu Watanabe 2023-11-12 19:26:06 +09:00
parent f0f93d9ce4
commit f269016c3e
7 changed files with 58 additions and 77 deletions

View file

@ -5858,8 +5858,9 @@ ServerAddress=192.168.0.1/24</programlisting>
<varlistentry>
<term><varname>VLAN=</varname></term>
<listitem>
<para>The VLAN ID allowed on the port. This can be either a single ID or a range M-N. Takes
an integer in the range 1…4094.</para>
<para>The VLAN ID allowed on the port. This can be either a single ID or a range M-N. Takes an
integer in the range 1…4094. This setting can be specified multiple times. If an empty string is
assigned, then the all previous assignments are cleared.</para>
<xi:include href="version-info.xml" xpointer="v231"/>
</listitem>
@ -5868,8 +5869,10 @@ ServerAddress=192.168.0.1/24</programlisting>
<term><varname>EgressUntagged=</varname></term>
<listitem>
<para>The VLAN ID specified here will be used to untag frames on egress. Configuring
<varname>EgressUntagged=</varname> implicates the use of <varname>VLAN=</varname> above and will enable the
VLAN ID for ingress as well. This can be either a single ID or a range M-N.</para>
<varname>EgressUntagged=</varname> implicates the use of <varname>VLAN=</varname> above and will
enable the VLAN ID for ingress as well. This can be either a single ID or a range M-N. This
setting can be specified multiple times. If an empty string is assigned, then the all previous
assignments are cleared.</para>
<xi:include href="version-info.xml" xpointer="v231"/>
</listitem>

View file

@ -83,7 +83,7 @@ static int bridge_vlan_append_set_info(Link *link, sd_netlink_message *m) {
for (uint16_t k = 0; k < BRIDGE_VLAN_BITMAP_MAX; k++) {
if (k == link->network->pvid) {
if (k == link->network->bridge_vlan_pvid) {
/* PVID needs to be sent alone. Finish previous bits. */
if (begin != UINT16_MAX) {
assert(begin < k);
@ -95,7 +95,7 @@ static int bridge_vlan_append_set_info(Link *link, sd_netlink_message *m) {
begin = UINT16_MAX;
}
untagged = is_bit_set(k, link->network->br_untagged_bitmap);
untagged = is_bit_set(k, link->network->bridge_vlan_untagged_bitmap);
r = add_single(m, k, untagged, /* is_pvid = */ true);
if (r < 0)
return r;
@ -103,7 +103,7 @@ static int bridge_vlan_append_set_info(Link *link, sd_netlink_message *m) {
continue;
}
if (!is_bit_set(k, link->network->br_vid_bitmap)) {
if (!is_bit_set(k, link->network->bridge_vlan_bitmap)) {
/* This bit is not set. Finish previous bits. */
if (begin != UINT16_MAX) {
assert(begin < k);
@ -123,7 +123,7 @@ static int bridge_vlan_append_set_info(Link *link, sd_netlink_message *m) {
assert(begin < k);
u = is_bit_set(k, link->network->br_untagged_bitmap);
u = is_bit_set(k, link->network->bridge_vlan_untagged_bitmap);
if (untagged == u)
continue;
@ -139,7 +139,7 @@ static int bridge_vlan_append_set_info(Link *link, sd_netlink_message *m) {
/* This is the starting point of a new bit sequence. Save the position and the tagging flag. */
begin = k;
untagged = is_bit_set(k, link->network->br_untagged_bitmap);
untagged = is_bit_set(k, link->network->bridge_vlan_untagged_bitmap);
}
/* No pending bit sequence.
@ -185,15 +185,15 @@ int bridge_vlan_set_message(Link *link, sd_netlink_message *m) {
void network_adjust_bridge_vlan(Network *network) {
assert(network);
if (!network->use_br_vlan)
return;
for (uint16_t k = 0; k < BRIDGE_VLAN_BITMAP_MAX; k++)
if (is_bit_set(k, network->bridge_vlan_untagged_bitmap))
set_bit(k, network->bridge_vlan_bitmap);
/* pvid might not be in br_vid_bitmap yet */
if (vlanid_is_valid(network->pvid))
set_bit(network->pvid, network->br_vid_bitmap);
if (vlanid_is_valid(network->bridge_vlan_pvid))
set_bit(network->bridge_vlan_pvid, network->bridge_vlan_bitmap);
}
int config_parse_brvlan_pvid(
int config_parse_bridge_vlan_id(
const char *unit,
const char *filename,
unsigned line,
@ -205,21 +205,32 @@ int config_parse_brvlan_pvid(
void *data,
void *userdata) {
Network *network = userdata;
uint16_t pvid;
uint16_t v, *id = ASSERT_PTR(data);
int r;
r = parse_vlanid(rvalue, &pvid);
if (r < 0)
return r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
network->pvid = pvid;
network->use_br_vlan = true;
if (isempty(rvalue)) {
*id = UINT16_MAX;
return 0;
}
r = parse_vlanid(rvalue, &v);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring: %s",
lvalue, rvalue);
return 0;
}
*id = v;
return 0;
}
int config_parse_brvlan_vlan(
int config_parse_bridge_vlan_id_range(
const char *unit,
const char *filename,
unsigned line,
@ -231,7 +242,7 @@ int config_parse_brvlan_vlan(
void *data,
void *userdata) {
Network *network = userdata;
uint32_t *bitmap = ASSERT_PTR(data);
uint16_t vid, vid_end;
int r;
@ -239,54 +250,22 @@ int config_parse_brvlan_vlan(
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
memzero(bitmap, BRIDGE_VLAN_BITMAP_LEN * sizeof(uint32_t));
return 0;
}
r = parse_vid_range(rvalue, &vid, &vid_end);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse VLAN, ignoring: %s", rvalue);
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring: %s",
lvalue, rvalue);
return 0;
}
for (; vid <= vid_end; vid++)
set_bit(vid, network->br_vid_bitmap);
set_bit(vid, bitmap);
network->use_br_vlan = true;
return 0;
}
int config_parse_brvlan_untagged(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *network = userdata;
uint16_t vid, vid_end;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = parse_vid_range(rvalue, &vid, &vid_end);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Could not parse VLAN: %s", rvalue);
return 0;
}
for (; vid <= vid_end; vid++) {
set_bit(vid, network->br_vid_bitmap);
set_bit(vid, network->br_untagged_bitmap);
}
network->use_br_vlan = true;
return 0;
}

View file

@ -21,6 +21,5 @@ void network_adjust_bridge_vlan(Network *network);
int bridge_vlan_set_message(Link *link, sd_netlink_message *m);
CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_pvid);
CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_vlan);
CONFIG_PARSER_PROTOTYPE(config_parse_brvlan_untagged);
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_vlan_id);
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_vlan_id_range);

View file

@ -368,9 +368,9 @@ BridgeFDB.AssociatedWith, config_parse_fdb_ntf_flags,
BridgeFDB.OutgoingInterface, config_parse_fdb_interface, 0, 0
BridgeMDB.MulticastGroupAddress, config_parse_mdb_group_address, 0, 0
BridgeMDB.VLANId, config_parse_mdb_vlan_id, 0, 0
BridgeVLAN.PVID, config_parse_brvlan_pvid, 0, 0
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
BridgeVLAN.PVID, config_parse_bridge_vlan_id, 0, offsetof(Network, bridge_vlan_pvid)
BridgeVLAN.VLAN, config_parse_bridge_vlan_id_range, 0, offsetof(Network, bridge_vlan_bitmap)
BridgeVLAN.EgressUntagged, config_parse_bridge_vlan_id_range, 0, offsetof(Network, bridge_vlan_untagged_bitmap)
DHCPPrefixDelegation.UplinkInterface, config_parse_uplink, 0, 0
DHCPPrefixDelegation.SubnetId, config_parse_dhcp_pd_subnet_id, 0, offsetof(Network, dhcp_pd_subnet_id)
DHCPPrefixDelegation.Announce, config_parse_bool, 0, offsetof(Network, dhcp_pd_announce)

View file

@ -450,7 +450,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.priority = LINK_BRIDGE_PORT_PRIORITY_INVALID,
.multicast_router = _MULTICAST_ROUTER_INVALID,
.pvid = UINT16_MAX,
.bridge_vlan_pvid = UINT16_MAX,
.lldp_mode = LLDP_MODE_ROUTERS_ONLY,
.lldp_multicast_mode = _SD_LLDP_MULTICAST_MODE_INVALID,

View file

@ -289,10 +289,9 @@ struct Network {
MulticastRouter multicast_router;
/* Bridge VLAN */
bool use_br_vlan;
uint16_t pvid;
uint32_t br_vid_bitmap[BRIDGE_VLAN_BITMAP_LEN];
uint32_t br_untagged_bitmap[BRIDGE_VLAN_BITMAP_LEN];
uint16_t bridge_vlan_pvid;
uint32_t bridge_vlan_bitmap[BRIDGE_VLAN_BITMAP_LEN];
uint32_t bridge_vlan_untagged_bitmap[BRIDGE_VLAN_BITMAP_LEN];
/* CAN support */
uint32_t can_bitrate;

View file

@ -687,7 +687,8 @@ int link_request_to_set_bridge_vlan(Link *link) {
assert(link);
assert(link->network);
if (!link->network->use_br_vlan)
/* If nothing configured, use the default vlan ID. */
if (memeqzero(link->network->bridge_vlan_bitmap, BRIDGE_VLAN_BITMAP_LEN * sizeof(uint32_t)))
return 0;
if (!link->network->bridge && !streq_ptr(link->kind, "bridge")) {