mirror of
https://github.com/systemd/systemd.git
synced 2025-01-23 02:04:32 +03:00
networkd: add support to configure VLAN on bridge ports
This commit is contained in:
parent
6cad256dbe
commit
13b498f967
@ -5480,6 +5480,8 @@ libnetworkd_core_la_SOURCES = \
|
||||
src/network/networkd-manager-bus.c \
|
||||
src/network/networkd-fdb.h \
|
||||
src/network/networkd-fdb.c \
|
||||
src/network/networkd-brvlan.h \
|
||||
src/network/networkd-brvlan.c \
|
||||
src/network/networkd-address-pool.h \
|
||||
src/network/networkd-address-pool.c \
|
||||
src/network/networkd-util.h \
|
||||
|
@ -1130,6 +1130,39 @@
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>[BridgeVLAN] Section Options</title>
|
||||
<para>The <literal>[BridgeVLAN]</literal> section manages the VLAN ID configuration of a bridge port and accepts
|
||||
the following keys. Specify several <literal>[BridgeVLAN]</literal> sections to configure several VLAN entries.
|
||||
The <varname>VLANFiltering=</varname> option has to be enabled, see <literal>[Bridge]</literal> section in
|
||||
<citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<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. VLAN IDs are valid
|
||||
from 1 to 4094.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<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>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>PVID=</varname></term>
|
||||
<listitem>
|
||||
<para>The Port VLAN ID specified here is assigned to all untagged frames at ingress.
|
||||
<varname>PVID=</varname> can be used only once. Configuring <varname>PVID=</varname> implicates the use of
|
||||
<varname>VLAN=</varname> above and will enable the VLAN ID for ingress as well.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Example</title>
|
||||
@ -1174,6 +1207,26 @@ Name=enp2s0
|
||||
|
||||
[Network]
|
||||
Bridge=bridge0</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>/etc/systemd/network/25-bridge-slave-interface-vlan.network</title>
|
||||
|
||||
<programlisting>[Match]
|
||||
Name=enp2s0
|
||||
|
||||
[Network]
|
||||
Bridge=bridge0
|
||||
|
||||
[BridgeVLAN]
|
||||
VLAN=1-32
|
||||
PVID=42
|
||||
EgressUntagged=42
|
||||
|
||||
[BridgeVLAN]
|
||||
VLAN=100-200
|
||||
|
||||
[BridgeVLAN]
|
||||
EgressUntagged=300-400</programlisting>
|
||||
</example>
|
||||
<example>
|
||||
<title>/etc/systemd/network/25-ipip.network</title>
|
||||
|
@ -89,6 +89,15 @@
|
||||
#define UNIQ_T(x, uniq) CONCATENATE(__unique_prefix_, CONCATENATE(x, uniq))
|
||||
#define UNIQ __COUNTER__
|
||||
|
||||
/* builtins */
|
||||
#if __SIZEOF_INT__ == 4
|
||||
#define BUILTIN_FFS_U32(x) __builtin_ffs(x);
|
||||
#elif __SIZEOF_LONG__ == 4
|
||||
#define BUILTIN_FFS_U32(x) __builtin_ffsl(x);
|
||||
#else
|
||||
#error "neither int nor long are four bytes long?!?"
|
||||
#endif
|
||||
|
||||
/* Rounds up */
|
||||
|
||||
#define ALIGN4(l) (((l) + 3) & ~3)
|
||||
|
@ -759,6 +759,14 @@ struct btrfs_ioctl_quota_ctl_args {
|
||||
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
|
||||
#endif
|
||||
|
||||
#ifndef BRIDGE_VLAN_INFO_RANGE_BEGIN
|
||||
#define BRIDGE_VLAN_INFO_RANGE_BEGIN (1<<3) /* VLAN is start of vlan range */
|
||||
#endif
|
||||
|
||||
#ifndef BRIDGE_VLAN_INFO_RANGE_END
|
||||
#define BRIDGE_VLAN_INFO_RANGE_END (1<<4) /* VLAN is end of vlan range */
|
||||
#endif
|
||||
|
||||
#if !HAVE_DECL_IFLA_BR_VLAN_DEFAULT_PVID
|
||||
#define IFLA_BR_UNSPEC 0
|
||||
#define IFLA_BR_FORWARD_DELAY 1
|
||||
|
335
src/network/networkd-brvlan.c
Normal file
335
src/network/networkd-brvlan.c
Normal file
@ -0,0 +1,335 @@
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2016 BISDN GmbH. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if_bridge.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-brvlan.h"
|
||||
#include "networkd.h"
|
||||
#include "parse-util.h"
|
||||
#include "vlan-util.h"
|
||||
|
||||
static bool is_bit_set(unsigned bit, uint32_t scope) {
|
||||
assert(bit < sizeof(scope)*8);
|
||||
return scope & (1 << bit);
|
||||
}
|
||||
|
||||
static inline void set_bit(unsigned nr, uint32_t *addr) {
|
||||
if (nr < BRIDGE_VLAN_BITMAP_MAX)
|
||||
addr[nr / 32] |= (((uint32_t) 1) << (nr % 32));
|
||||
}
|
||||
|
||||
static inline int is_vid_valid(unsigned vid) {
|
||||
if (vid > VLANID_MAX || vid == 0)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_next_bit(int i, uint32_t x) {
|
||||
int j;
|
||||
|
||||
if (i >= 32)
|
||||
return -1;
|
||||
|
||||
/* find first bit */
|
||||
if (i < 0)
|
||||
return BUILTIN_FFS_U32(x);
|
||||
|
||||
/* mask off prior finds to get next */
|
||||
j = __builtin_ffs(x >> i);
|
||||
return j ? j + i : 0;
|
||||
}
|
||||
|
||||
static int append_vlan_info_data(Link *const link, sd_netlink_message *req, uint16_t pvid, const uint32_t *br_vid_bitmap, const uint32_t *br_untagged_bitmap) {
|
||||
struct bridge_vlan_info br_vlan;
|
||||
int i, j, k, r, done, cnt;
|
||||
uint16_t begin, end;
|
||||
bool untagged;
|
||||
|
||||
assert(link);
|
||||
assert(req);
|
||||
assert(br_vid_bitmap);
|
||||
assert(br_untagged_bitmap);
|
||||
|
||||
i = cnt = -1;
|
||||
|
||||
begin = end = UINT16_MAX;
|
||||
for (k = 0; k < BRIDGE_VLAN_BITMAP_LEN; k++) {
|
||||
unsigned base_bit;
|
||||
uint32_t vid_map = br_vid_bitmap[k];
|
||||
uint32_t untagged_map = br_untagged_bitmap[k];
|
||||
|
||||
base_bit = k * 32;
|
||||
i = -1;
|
||||
done = 0;
|
||||
do {
|
||||
j = find_next_bit(i, vid_map);
|
||||
if (j > 0) {
|
||||
/* first hit of any bit */
|
||||
if (begin == UINT16_MAX && end == UINT16_MAX) {
|
||||
begin = end = j - 1 + base_bit;
|
||||
untagged = is_bit_set(j - 1, untagged_map);
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* this bit is a continuation of prior bits */
|
||||
if (j - 2 + base_bit == end && untagged == is_bit_set(j - 1, untagged_map) && (uint16_t)j - 1 + base_bit != pvid && (uint16_t)begin != pvid) {
|
||||
end++;
|
||||
goto next;
|
||||
}
|
||||
} else
|
||||
done = 1;
|
||||
|
||||
if (begin != UINT16_MAX) {
|
||||
cnt++;
|
||||
if (done && k < BRIDGE_VLAN_BITMAP_LEN - 1)
|
||||
break;
|
||||
|
||||
br_vlan.flags = 0;
|
||||
if (untagged)
|
||||
br_vlan.flags |= BRIDGE_VLAN_INFO_UNTAGGED;
|
||||
|
||||
if (begin == end) {
|
||||
br_vlan.vid = begin;
|
||||
|
||||
if (begin == pvid)
|
||||
br_vlan.flags |= BRIDGE_VLAN_INFO_PVID;
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_BRIDGE_VLAN_INFO, &br_vlan, sizeof(br_vlan));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_BRIDGE_VLAN_INFO attribute: %m");
|
||||
} else {
|
||||
br_vlan.vid = begin;
|
||||
br_vlan.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN;
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_BRIDGE_VLAN_INFO, &br_vlan, sizeof(br_vlan));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_BRIDGE_VLAN_INFO attribute: %m");
|
||||
|
||||
br_vlan.vid = end;
|
||||
br_vlan.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
|
||||
br_vlan.flags |= BRIDGE_VLAN_INFO_RANGE_END;
|
||||
|
||||
r = sd_netlink_message_append_data(req, IFLA_BRIDGE_VLAN_INFO, &br_vlan, sizeof(br_vlan));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append IFLA_BRIDGE_VLAN_INFO attribute: %m");
|
||||
}
|
||||
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
if (j > 0) {
|
||||
begin = end = j - 1 + base_bit;
|
||||
untagged = is_bit_set(j - 1, untagged_map);
|
||||
}
|
||||
|
||||
next:
|
||||
i = j;
|
||||
} while(!done);
|
||||
}
|
||||
if (!cnt)
|
||||
return -EINVAL;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static int set_brvlan_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
||||
Link *link = userdata;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
log_link_error_errno(link, r, "Could not add VLAN to bridge port: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int br_vlan_configure(Link *link, uint16_t pvid, uint32_t *br_vid_bitmap, uint32_t *br_untagged_bitmap) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r;
|
||||
uint16_t flags;
|
||||
sd_netlink *rtnl;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(br_vid_bitmap);
|
||||
assert(br_untagged_bitmap);
|
||||
assert(link->network);
|
||||
|
||||
/* pvid might not be in br_vid_bitmap yet */
|
||||
if (pvid)
|
||||
set_bit(pvid, br_vid_bitmap);
|
||||
|
||||
rtnl = link->manager->rtnl;
|
||||
|
||||
/* create new RTM message */
|
||||
r = sd_rtnl_message_new_link(rtnl, &req, RTM_SETLINK, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
|
||||
|
||||
r = sd_rtnl_message_link_set_family(req, PF_BRIDGE);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set message family: %m");
|
||||
|
||||
r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
|
||||
|
||||
/* master needs flag self */
|
||||
if (!link->network->bridge) {
|
||||
flags = BRIDGE_FLAGS_SELF;
|
||||
sd_netlink_message_append_data(req, IFLA_BRIDGE_FLAGS, &flags, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
/* add vlan info */
|
||||
r = append_vlan_info_data(link, req, pvid, br_vid_bitmap, br_untagged_bitmap);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append VLANs: %m");
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
|
||||
|
||||
/* send message to the kernel */
|
||||
r = sd_netlink_call_async(rtnl, req, set_brvlan_handler, link, 0, NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_vid_range(const char *rvalue, uint16_t *vid, uint16_t *vid_end) {
|
||||
int r;
|
||||
char *p;
|
||||
char *_rvalue = NULL;
|
||||
uint16_t _vid = UINT16_MAX;
|
||||
uint16_t _vid_end = UINT16_MAX;
|
||||
|
||||
assert(rvalue);
|
||||
assert(vid);
|
||||
assert(vid_end);
|
||||
|
||||
_rvalue = strdupa(rvalue);
|
||||
p = strchr(_rvalue, '-');
|
||||
if (p) {
|
||||
*p = '\0';
|
||||
p++;
|
||||
r = parse_vlanid(_rvalue, &_vid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!_vid)
|
||||
return -ERANGE;
|
||||
|
||||
r = parse_vlanid(p, &_vid_end);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!_vid_end)
|
||||
return -ERANGE;
|
||||
} else {
|
||||
r = parse_vlanid(_rvalue, &_vid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!_vid)
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
*vid = _vid;
|
||||
*vid_end = _vid_end;
|
||||
return r;
|
||||
}
|
||||
|
||||
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;
|
||||
int r;
|
||||
uint16_t vid, vid_end;
|
||||
|
||||
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_ERR, filename, line, r, "Failed to parse VLAN, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (UINT16_MAX == vid_end)
|
||||
set_bit(vid++, network->br_vid_bitmap);
|
||||
else {
|
||||
if (vid >= vid_end) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid VLAN range, ignoring %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
for (; vid <= vid_end; vid++)
|
||||
set_bit(vid, network->br_vid_bitmap);
|
||||
}
|
||||
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;
|
||||
int r;
|
||||
uint16_t vid, vid_end;
|
||||
|
||||
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_ERR, filename, line, r, "Could not parse VLAN: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (UINT16_MAX == vid_end) {
|
||||
set_bit(vid, network->br_vid_bitmap);
|
||||
set_bit(vid, network->br_untagged_bitmap);
|
||||
} else {
|
||||
if (vid >= vid_end) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid VLAN range, ignoring %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
for (; vid <= vid_end; vid++) {
|
||||
set_bit(vid, network->br_vid_bitmap);
|
||||
set_bit(vid, network->br_untagged_bitmap);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
29
src/network/networkd-brvlan.h
Normal file
29
src/network/networkd-brvlan.h
Normal file
@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright (C) 2016 BISDN GmbH. All rights reserved.
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct Link Link;
|
||||
|
||||
int br_vlan_configure(Link *link, uint16_t pvid, uint32_t *br_vid_bitmap, uint32_t *br_untagged_bitmap);
|
||||
|
||||
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);
|
||||
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);
|
@ -1114,6 +1114,16 @@ int link_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *u
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_set_bridge_vlan(Link *link) {
|
||||
int r = 0;
|
||||
|
||||
r = br_vlan_configure(link, link->network->pvid, link->network->br_vid_bitmap, link->network->br_untagged_bitmap);
|
||||
if (r < 0)
|
||||
log_link_error_errno(link, r, "Failed to assign VLANs to bridge port: %m");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int link_set_bridge_fdb(Link *link) {
|
||||
FdbEntry *fdb_entry;
|
||||
int r = 0;
|
||||
@ -1996,6 +2006,12 @@ static int link_joined(Link *link) {
|
||||
log_link_error_errno(link, r, "Could not set bridge message: %m");
|
||||
}
|
||||
|
||||
if (link->network->bridge || NETDEV_KIND_BRIDGE == netdev_kind_from_string(link->kind)) {
|
||||
r = link_set_bridge_vlan(link);
|
||||
if (r < 0)
|
||||
log_link_error_errno(link, r, "Could not set bridge vlan: %m");
|
||||
}
|
||||
|
||||
return link_enter_set_addresses(link);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "networkd.h"
|
||||
#include "networkd-conf.h"
|
||||
#include "network-internal.h"
|
||||
#include "vlan-util.h"
|
||||
%}
|
||||
struct ConfigPerfItem;
|
||||
%null_strings
|
||||
@ -112,6 +113,9 @@ Bridge.AllowPortToBeRoot, config_parse_bool,
|
||||
Bridge.UnicastFlood, config_parse_bool, 0, offsetof(Network, unicast_flood)
|
||||
BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0
|
||||
BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0
|
||||
BridgeVLAN.PVID, config_parse_vlanid, 0, offsetof(Network, pvid)
|
||||
BridgeVLAN.VLAN, config_parse_brvlan_vlan, 0, 0
|
||||
BridgeVLAN.EgressUntagged, config_parse_brvlan_untagged, 0, 0
|
||||
/* backwards compatibility: do not add new entries to this section */
|
||||
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
|
||||
DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_use_dns)
|
||||
|
@ -147,7 +147,8 @@ static int network_load_one(Manager *manager, const char *filename) {
|
||||
"DHCPServer\0"
|
||||
"IPv6AcceptRA\0"
|
||||
"Bridge\0"
|
||||
"BridgeFDB\0",
|
||||
"BridgeFDB\0"
|
||||
"BridgeVLAN\0",
|
||||
config_item_perf_lookup, network_network_gperf_lookup,
|
||||
false, false, true, network);
|
||||
if (r < 0)
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "resolve-util.h"
|
||||
|
||||
#include "networkd-address.h"
|
||||
#include "networkd-brvlan.h"
|
||||
#include "networkd-fdb.h"
|
||||
#include "networkd-lldp-tx.h"
|
||||
#include "networkd-netdev.h"
|
||||
@ -37,6 +38,9 @@
|
||||
#define DHCP_ROUTE_METRIC 1024
|
||||
#define IPV4LL_ROUTE_METRIC 2048
|
||||
|
||||
#define BRIDGE_VLAN_BITMAP_MAX 4096
|
||||
#define BRIDGE_VLAN_BITMAP_LEN (BRIDGE_VLAN_BITMAP_MAX / 32)
|
||||
|
||||
typedef enum DCHPClientIdentifier {
|
||||
DHCP_CLIENT_ID_MAC,
|
||||
DHCP_CLIENT_ID_DUID,
|
||||
@ -146,6 +150,10 @@ struct Network {
|
||||
bool unicast_flood;
|
||||
unsigned cost;
|
||||
|
||||
uint16_t pvid;
|
||||
uint32_t br_vid_bitmap[BRIDGE_VLAN_BITMAP_LEN];
|
||||
uint32_t br_untagged_bitmap[BRIDGE_VLAN_BITMAP_LEN];
|
||||
|
||||
AddressFamilyBoolean ip_forward;
|
||||
bool ip_masquerade;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user