network/brvlan: read bridge vlan IDs through netlink and save them

In this commit, obtained vlan IDs are not used, but they will be used in
the later commits.
This commit is contained in:
Yu Watanabe
2023-11-13 02:13:03 +09:00
parent f269016c3e
commit 11cee6efbf
5 changed files with 90 additions and 0 deletions

View File

@@ -182,6 +182,67 @@ int bridge_vlan_set_message(Link *link, sd_netlink_message *m) {
return 0;
}
#define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK)
int link_update_bridge_vlan(Link *link, sd_netlink_message *m) {
_cleanup_free_ void *data = NULL;
size_t len;
uint16_t begin = UINT16_MAX;
int r, family;
assert(link);
assert(m);
r = sd_rtnl_message_get_family(m, &family);
if (r < 0)
return r;
if (family != AF_BRIDGE)
return 0;
r = sd_netlink_message_read_data(m, IFLA_AF_SPEC, &len, &data);
if (r == -ENODATA)
return 0;
if (r < 0)
return r;
memzero(link->bridge_vlan_bitmap, sizeof(link->bridge_vlan_bitmap));
for (struct rtattr *rta = data; RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
struct bridge_vlan_info *p;
if (RTA_TYPE(rta) != IFLA_BRIDGE_VLAN_INFO)
continue;
if (RTA_PAYLOAD(rta) != sizeof(struct bridge_vlan_info))
continue;
p = RTA_DATA(rta);
if (FLAGS_SET(p->flags, BRIDGE_VLAN_INFO_RANGE_BEGIN)) {
begin = p->vid;
continue;
}
if (FLAGS_SET(p->flags, BRIDGE_VLAN_INFO_RANGE_END)) {
for (uint16_t k = begin; k <= p->vid; k++)
set_bit(k, link->bridge_vlan_bitmap);
begin = UINT16_MAX;
continue;
}
if (FLAGS_SET(p->flags, BRIDGE_VLAN_INFO_PVID)) {
link->bridge_vlan_pvid = p->vid;
link->bridge_vlan_pvid_is_untagged = FLAGS_SET(p->flags, BRIDGE_VLAN_INFO_UNTAGGED);
}
set_bit(p->vid, link->bridge_vlan_bitmap);
begin = UINT16_MAX;
}
return 0;
}
void network_adjust_bridge_vlan(Network *network) {
assert(network);

View File

@@ -21,5 +21,7 @@ void network_adjust_bridge_vlan(Network *network);
int bridge_vlan_set_message(Link *link, sd_netlink_message *m);
int link_update_bridge_vlan(Link *link, sd_netlink_message *m);
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_vlan_id);
CONFIG_PARSER_PROTOTYPE(config_parse_bridge_vlan_id_range);

View File

@@ -35,6 +35,7 @@
#include "networkd-address.h"
#include "networkd-bridge-fdb.h"
#include "networkd-bridge-mdb.h"
#include "networkd-bridge-vlan.h"
#include "networkd-can.h"
#include "networkd-dhcp-prefix-delegation.h"
#include "networkd-dhcp-server.h"
@@ -2435,6 +2436,10 @@ static int link_update(Link *link, sd_netlink_message *message) {
if (r < 0)
return r;
r = link_update_bridge_vlan(link, message);
if (r < 0)
return r;
return needs_reconfigure;
}
@@ -2508,6 +2513,8 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
.ifname = TAKE_PTR(ifname),
.kind = TAKE_PTR(kind),
.bridge_vlan_pvid = UINT16_MAX,
.ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID,
.state_file = TAKE_PTR(state_file),

View File

@@ -21,6 +21,7 @@
#include "log-link.h"
#include "netif-util.h"
#include "network-util.h"
#include "networkd-bridge-vlan.h"
#include "networkd-ipv6ll.h"
#include "networkd-util.h"
#include "ordered-set.h"
@@ -72,6 +73,11 @@ typedef struct Link {
sd_device *dev;
char *driver;
/* bridge vlan */
uint16_t bridge_vlan_pvid;
bool bridge_vlan_pvid_is_untagged;
uint32_t bridge_vlan_bitmap[BRIDGE_VLAN_BITMAP_LEN];
/* to prevent multiple ethtool calls */
bool ethtool_driver_read;
bool ethtool_permanent_hw_addr_read;

View File

@@ -753,6 +753,20 @@ static int manager_enumerate_links(Manager *m) {
if (r < 0)
return r;
r = manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link);
if (r < 0)
return r;
req = sd_netlink_message_unref(req);
r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
if (r < 0)
return r;
r = sd_rtnl_message_link_set_family(req, AF_BRIDGE);
if (r < 0)
return r;
return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link);
}