network: bridge vlan without PVID (#5899)
authorTobias Jungel <Tobias.Jungel@gmail.com>
Mon, 29 May 2017 15:20:01 +0000 (17:20 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 29 May 2017 15:20:01 +0000 (17:20 +0200)
this patch makes it possible to configure a vlan aware bridge without the
PVID. To configure no PVID set DefaultPVID=none in the [BridgeVLAN] section.

fixes #5716

man/systemd.netdev.xml
src/network/netdev/bridge.c
src/network/netdev/netdev-gperf.gperf
src/shared/vlan-util.c
src/shared/vlan-util.h

index 71cf2f2..e925b30 100644 (file)
         <varlistentry>
           <term><varname>DefaultPVID=</varname></term>
           <listitem>
-            <para>This specifies the default port VLAN ID of a newly attached bridge port.</para>
+            <para>This specifies the default port VLAN ID of a newly attached bridge port.
+            Set this to an integer in the range 1–4094 or <literal>none</literal> to disable the PVID.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
index 9fdcb55..cf6c591 100644 (file)
@@ -24,6 +24,7 @@
 #include "netlink-util.h"
 #include "netdev/bridge.h"
 #include "networkd-manager.h"
+#include "vlan-util.h"
 
 /* callback for brige netdev's parameter set */
 static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
@@ -102,7 +103,7 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_PRIORITY attribute: %m");
         }
 
-        if (b->default_pvid > 0) {
+        if (b->default_pvid != VLANID_INVALID) {
                 r = sd_netlink_message_append_u16(req, IFLA_BR_VLAN_DEFAULT_PVID, b->default_pvid);
                 if (r < 0)
                         return log_netdev_error_errno(netdev, r, "Could not append IFLA_BR_VLAN_DEFAULT_PVID attribute: %m");
@@ -160,6 +161,7 @@ static void bridge_init(NetDev *n) {
         b->mcast_snooping = -1;
         b->vlan_filtering = -1;
         b->stp = -1;
+        b->default_pvid = VLANID_INVALID;
         b->forward_delay = USEC_INFINITY;
 }
 
index 766e7cf..8b235a4 100644 (file)
@@ -128,7 +128,7 @@ Bridge.MaxAgeSec,            config_parse_sec,                     0,
 Bridge.AgeingTimeSec,        config_parse_sec,                     0,                             offsetof(Bridge, ageing_time)
 Bridge.ForwardDelaySec,      config_parse_sec,                     0,                             offsetof(Bridge, forward_delay)
 Bridge.Priority,             config_parse_uint16,                  0,                             offsetof(Bridge, priority)
-Bridge.DefaultPVID,          config_parse_vlanid,                  0,                             offsetof(Bridge, default_pvid)
+Bridge.DefaultPVID,          config_parse_default_port_vlanid,     0,                             offsetof(Bridge, default_pvid)
 Bridge.MulticastQuerier,     config_parse_tristate,                0,                             offsetof(Bridge, mcast_querier)
 Bridge.MulticastSnooping,    config_parse_tristate,                0,                             offsetof(Bridge, mcast_snooping)
 Bridge.VLANFiltering,        config_parse_tristate,                0,                             offsetof(Bridge, vlan_filtering)
index 78d66dd..1edd96f 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include "vlan-util.h"
-#include "parse-util.h"
 #include "conf-parser.h"
+#include "parse-util.h"
+#include "string-util.h"
+#include "vlan-util.h"
 
 int parse_vlanid(const char *p, uint16_t *ret) {
         uint16_t id;
@@ -35,6 +36,32 @@ int parse_vlanid(const char *p, uint16_t *ret) {
         return 0;
 }
 
+int config_parse_default_port_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;
+
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (streq(rvalue, "none")) {
+                *id = 0;
+                return 0;
+        }
+
+        return config_parse_vlanid(unit, filename, line, section, section_line,
+                                   lvalue, ltype, rvalue, data, userdata);
+}
+
 int config_parse_vlanid(
                 const char *unit,
                 const char *filename,
index ce6763b..365ed14 100644 (file)
@@ -32,4 +32,5 @@ static inline bool vlanid_is_valid(uint16_t id) {
 
 int parse_vlanid(const char *p, uint16_t *ret);
 
+int config_parse_default_port_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);
 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);