<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>
<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>
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);
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;
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);
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;
/* 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.
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,
void *data,
void *userdata) {
- Network *network = userdata;
- uint16_t pvid;
- int r;
-
- r = parse_vlanid(rvalue, &pvid);
- if (r < 0)
- return r;
-
- network->pvid = pvid;
- network->use_br_vlan = true;
-
- return 0;
-}
-
-int config_parse_brvlan_vlan(
- 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;
+ uint16_t v, *id = ASSERT_PTR(data);
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, "Failed to parse VLAN, ignoring: %s", rvalue);
+ if (isempty(rvalue)) {
+ *id = UINT16_MAX;
return 0;
}
- for (; vid <= vid_end; vid++)
- set_bit(vid, network->br_vid_bitmap);
+ 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;
+ }
- network->use_br_vlan = true;
+ *id = v;
return 0;
}
-int config_parse_brvlan_untagged(
+int config_parse_bridge_vlan_id_range(
const char *unit,
const char *filename,
unsigned line,
void *data,
void *userdata) {
- Network *network = userdata;
+ uint32_t *bitmap = ASSERT_PTR(data);
uint16_t vid, vid_end;
int r;
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, "Could not parse VLAN: %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, network->br_untagged_bitmap);
- }
+ for (; vid <= vid_end; vid++)
+ set_bit(vid, bitmap);
- network->use_br_vlan = true;
return 0;
}
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)