]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: clean up vlan handling a bit (#3478)
authorLennart Poettering <lennart@poettering.net>
Thu, 9 Jun 2016 16:55:16 +0000 (18:55 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 9 Jun 2016 16:55:16 +0000 (18:55 +0200)
Let's add a generic parser for VLAN ids, which should become handy as
preparation for PR #3428. Let's also make sure we use uint16_t for the vlan ID
type everywhere, and that validity checks are already applied at the time of
parsing, and not only whne we about to prepare a netdev.

Also, establish a common definition VLANID_INVALID we can use for
non-initialized VLAN id fields.

Makefile.am
src/network/networkd-netdev-gperf.gperf
src/network/networkd-netdev-vlan.c
src/network/networkd-netdev-vlan.h
src/shared/vlan-util.c [new file with mode: 0644]
src/shared/vlan-util.h [new file with mode: 0644]

index 9a34c686d513c56552544117be4d0b2614889510..d2336144034273573c3ecc2eb603cb5cbf4ff0a1 100644 (file)
@@ -1042,6 +1042,8 @@ libshared_la_SOURCES = \
        src/shared/resolve-util.h \
        src/shared/bus-unit-util.c \
        src/shared/bus-unit-util.h \
+       src/shared/vlan-util.h \
+       src/shared/vlan-util.c \
        src/shared/tests.h \
        src/shared/tests.c
 
index adc64977b9bdfa03cc92f90de409c62101d7737f..a9512cd77b6f0c438517baf0f2d8a63db1a5baf4 100644 (file)
@@ -3,6 +3,7 @@
 #include "conf-parser.h"
 #include "network-internal.h"
 #include "networkd-netdev-bond.h"
+#include "networkd-netdev-bridge.h"
 #include "networkd-netdev-ipvlan.h"
 #include "networkd-netdev-macvlan.h"
 #include "networkd-netdev-tunnel.h"
@@ -10,8 +11,8 @@
 #include "networkd-netdev-veth.h"
 #include "networkd-netdev-vlan.h"
 #include "networkd-netdev-vxlan.h"
-#include "networkd-netdev-bridge.h"
 #include "networkd-netdev.h"
+#include "vlan-util.h"
 %}
 struct ConfigPerfItem;
 %null_strings
@@ -33,7 +34,7 @@ NetDev.Name,                 config_parse_ifname,                0,
 NetDev.Kind,                 config_parse_netdev_kind,           0,                             offsetof(NetDev, kind)
 NetDev.MTUBytes,             config_parse_iec_size,              0,                             offsetof(NetDev, mtu)
 NetDev.MACAddress,           config_parse_hwaddr,                0,                             offsetof(NetDev, mac)
-VLAN.Id,                     config_parse_uint64,                0,                             offsetof(VLan, id)
+VLAN.Id,                     config_parse_vlanid,                0,                             offsetof(VLan, id)
 MACVLAN.Mode,                config_parse_macvlan_mode,          0,                             offsetof(MacVlan, mode)
 MACVTAP.Mode,                config_parse_macvlan_mode,          0,                             offsetof(MacVlan, mode)
 IPVLAN.Mode,                 config_parse_ipvlan_mode,           0,                             offsetof(IPVlan, mode)
index b1f4714afab4b62255586e46f29592793c2852bf..3cc072388f09a2579059f51f091c8e910dddf855 100644 (file)
@@ -20,6 +20,7 @@
 #include <net/if.h>
 
 #include "networkd-netdev-vlan.h"
+#include "vlan-util.h"
 
 static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
         VLan *v;
@@ -33,11 +34,9 @@ static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlin
 
         assert(v);
 
-        if (v->id <= VLANID_MAX) {
-                r = sd_netlink_message_append_u16(req, IFLA_VLAN_ID, v->id);
-                if (r < 0)
-                        return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_ID attribute: %m");
-        }
+        r = sd_netlink_message_append_u16(req, IFLA_VLAN_ID, v->id);
+        if (r < 0)
+                return log_netdev_error_errno(netdev, r, "Could not append IFLA_VLAN_ID attribute: %m");
 
         return 0;
 }
@@ -52,8 +51,8 @@ static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
 
         assert(v);
 
-        if (v->id > VLANID_MAX) {
-                log_warning("VLAN without valid Id (%"PRIu64") configured in %s. Ignoring", v->id, filename);
+        if (v->id == VLANID_INVALID) {
+                log_warning("VLAN without valid Id (%"PRIu16") configured in %s.", v->id, filename);
                 return -EINVAL;
         }
 
@@ -66,7 +65,7 @@ static void vlan_init(NetDev *netdev) {
         assert(netdev);
         assert(v);
 
-        v->id = VLANID_MAX + 1;
+        v->id = VLANID_INVALID;
 }
 
 const NetDevVTable vlan_vtable = {
index 73aacf4a0f8ae15f1825293d579b9bdc11fac3a6..2dfe314b6e72e17b0ad4295da282ad627dfc3a59 100644 (file)
@@ -23,12 +23,10 @@ typedef struct VLan VLan;
 
 #include "networkd-netdev.h"
 
-#define VLANID_MAX 4094
-
 struct VLan {
         NetDev meta;
 
-        uint64_t id;
+        uint16_t id;
 };
 
 DEFINE_NETDEV_CAST(VLAN, VLan);
diff --git a/src/shared/vlan-util.c b/src/shared/vlan-util.c
new file mode 100644 (file)
index 0000000..78d66dd
--- /dev/null
@@ -0,0 +1,69 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2016 Lennart Poettering
+
+  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 "vlan-util.h"
+#include "parse-util.h"
+#include "conf-parser.h"
+
+int parse_vlanid(const char *p, uint16_t *ret) {
+        uint16_t id;
+        int r;
+
+        r = safe_atou16(p, &id);
+        if (r < 0)
+                return r;
+        if (!vlanid_is_valid(id))
+                return -ERANGE;
+
+        *ret = id;
+        return 0;
+}
+
+int config_parse_vlanid(
+                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) {
+
+        uint16_t *id = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = parse_vlanid(rvalue, id);
+        if (r == -ERANGE) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "VLAN identifier outside of valid range 0…4094, ignoring: %s", rvalue);
+                return 0;
+        }
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse VLAN identifier value, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        return 0;
+}
diff --git a/src/shared/vlan-util.h b/src/shared/vlan-util.h
new file mode 100644 (file)
index 0000000..ce6763b
--- /dev/null
@@ -0,0 +1,35 @@
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2016 Lennart Poettering
+
+  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 <stdbool.h>
+#include <inttypes.h>
+
+#define VLANID_MAX 4094
+#define VLANID_INVALID UINT16_MAX
+
+/* Note that we permit VLAN Id 0 here, as that is apparently OK by the Linux kernel */
+static inline bool vlanid_is_valid(uint16_t id) {
+        return id <= VLANID_MAX;
+}
+
+int parse_vlanid(const char *p, uint16_t *ret);
+
+int config_parse_vlanid(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);