]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network-generator: parse vlan ID from vlan interface name
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 7 Aug 2024 06:04:46 +0000 (15:04 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 9 Aug 2024 10:12:01 +0000 (19:12 +0900)
Fixes #33954.

src/network/generator/network-generator.c
src/network/generator/network-generator.h
src/network/generator/test-network-generator.c

index 8c96598e2045057413b3d7148f12613ad582f3ad..e1f4e598c6aaf63f3883abda06193372f8d1a4b0 100644 (file)
@@ -14,6 +14,7 @@
 #include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
+#include "vlan-util.h"
 
 /*
   # .network
@@ -965,6 +966,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;
@@ -989,6 +1008,10 @@ static int parse_cmdline_vlan(Context *context, const char *key, const char *val
                         return log_debug_errno(r, "Failed to create VLAN device for '%s': %m", name);
         }
 
+        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);
 }
 
@@ -1367,6 +1390,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) {
index 166ec68fe6020d3d0706c363b1a76521e89ccf24..f2fdd02808c3c4d3273bdcf6f2a96bd53afcf6b3 100644 (file)
@@ -79,6 +79,9 @@ struct NetDev {
         char *ifname;
         char *kind;
         uint32_t mtu;
+
+        /* [VLAN] */
+        uint16_t vlan_id;
 };
 
 struct Link {
index 436b6b820d9acf263aba57d7dbfc4fbfddc181d7..92118907b7e02c3cae3fc3ac5a2577d0d8461ae8 100644 (file)
@@ -375,6 +375,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"