From 456c15b8fd18726c4b81021fcc61e8495299b65a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 7 Aug 2024 15:04:46 +0900 Subject: [PATCH] network-generator: parse vlan ID from vlan interface name Fixes #33954. (cherry picked from commit e31a55edf136e777aabdf19894ee886eac47c20e) (cherry picked from commit 4cd435ca49950c2bba86a95b500c6d239f18efe1) (cherry picked from commit f9f74a067c56c40172fbbe79971f3192b4154718) --- src/network/generator/network-generator.c | 30 +++++++++++++++++ src/network/generator/network-generator.h | 3 ++ .../generator/test-network-generator.c | 32 +++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index ce424d83e1..172cf83f80 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -14,6 +14,7 @@ #include "string-table.h" #include "string-util.h" #include "strv.h" +#include "vlan-util.h" /* # .network @@ -929,6 +930,24 @@ static int parse_cmdline_rd_peerdns(Context *context, const char *key, const cha return network_set_dhcp_use_dns(context, "", r); } +static int extract_vlan_id(const char *vlan_name, uint16_t *ret) { + assert(!isempty(vlan_name)); + assert(ret); + + /* From dracut.cmdline(7): + * We support the four styles of vlan names: + * VLAN_PLUS_VID (vlan0005), + * VLAN_PLUS_VID_NO_PAD (vlan5), + * DEV_PLUS_VID (eth0.0005), and + * DEV_PLUS_VID_NO_PAD (eth0.5). */ + + for (const char *p = vlan_name + strlen(vlan_name) - 1; p > vlan_name; p--) + if (!ascii_isdigit(*p)) + return parse_vlanid(p+1, ret); + + return -EINVAL; +} + static int parse_cmdline_vlan(Context *context, const char *key, const char *value) { const char *name, *p; NetDev *netdev; @@ -953,6 +972,10 @@ static int parse_cmdline_vlan(Context *context, const char *key, const char *val return r; } + r = extract_vlan_id(name, &netdev->vlan_id); + if (r < 0) + return log_debug_errno(r, "Failed to parse VLAN ID from VLAN device name '%s': %m", name); + return network_set_vlan(context, p + 1, name); } @@ -1320,6 +1343,13 @@ void netdev_dump(NetDev *netdev, FILE *f) { if (netdev->mtu > 0) fprintf(f, "MTUBytes=%" PRIu32 "\n", netdev->mtu); + + if (streq(netdev->kind, "vlan")) { + fprintf(f, + "\n[VLAN]\n" + "Id=%u\n", + netdev->vlan_id); + } } void link_dump(Link *link, FILE *f) { diff --git a/src/network/generator/network-generator.h b/src/network/generator/network-generator.h index 08e6ac9c1a..a965914d11 100644 --- a/src/network/generator/network-generator.h +++ b/src/network/generator/network-generator.h @@ -78,6 +78,9 @@ struct NetDev { char *ifname; char *kind; uint32_t mtu; + + /* [VLAN] */ + uint16_t vlan_id; }; struct Link { diff --git a/src/network/generator/test-network-generator.c b/src/network/generator/test-network-generator.c index 26a37fd4f6..3aae0e022d 100644 --- a/src/network/generator/test-network-generator.c +++ b/src/network/generator/test-network-generator.c @@ -333,6 +333,38 @@ int main(int argc, char *argv[]) { "MTUBytes=1530\n" ); + test_netdev_one("vlan123", "vlan", "vlan123:eth0", + "[NetDev]\n" + "Kind=vlan\n" + "Name=vlan123\n" + "\n[VLAN]\n" + "Id=123\n" + ); + + test_netdev_one("vlan0013", "vlan", "vlan0013:eth0", + "[NetDev]\n" + "Kind=vlan\n" + "Name=vlan0013\n" + "\n[VLAN]\n" + "Id=11\n" /* 0013 (octal) -> 11 */ + ); + + test_netdev_one("eth0.123", "vlan", "eth0.123:eth0", + "[NetDev]\n" + "Kind=vlan\n" + "Name=eth0.123\n" + "\n[VLAN]\n" + "Id=123\n" + ); + + test_netdev_one("eth0.0013", "vlan", "eth0.0013:eth0", + "[NetDev]\n" + "Kind=vlan\n" + "Name=eth0.0013\n" + "\n[VLAN]\n" + "Id=11\n" /* 0013 (octal) -> 11 */ + ); + test_link_one("hogehoge", "ifname", "hogehoge:00:11:22:33:44:55", "[Match]\n" "MACAddress=00:11:22:33:44:55\n"