diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 5be6a6a8..3bcb9063 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -406,7 +406,7 @@ static const char usage_message[] =
     "                  to its initialization function.\n"
 #endif
     "--vlan-tagging  : Enable 802.1Q-based VLAN tagging.\n"
-    "--vlan-accept tagged|untagged : Set VLAN tagging mode.\n"
+    "--vlan-accept tagged|untagged|all : Set VLAN tagging mode. Default is 'all'.\n"
     "--vlan-pvid v   : Sets the Port VLAN Identifier. Defaults to 1.\n"
 #if P2MP
 #if P2MP_SERVER
@@ -853,7 +853,7 @@ init_options(struct options *o, const bool init_gc)
     o->route_method = ROUTE_METHOD_ADAPTIVE;
     o->block_outside_dns = false;
 #endif
-    o->vlan_accept = VLAN_ONLY_UNTAGGED_OR_PRIORITY;
+    o->vlan_accept = VLAN_ALL;
     o->vlan_pvid = 1;
 #if P2MP_SERVER
     o->real_hash_size = 256;
@@ -1239,6 +1239,8 @@ print_vlan_accept(enum vlan_acceptable_frames mode)
             return "tagged";
         case VLAN_ONLY_UNTAGGED_OR_PRIORITY:
             return "untagged";
+        case VLAN_ALL:
+            return "all";
     }
     return NULL;
 }
@@ -8418,9 +8420,13 @@ add_option(struct options *options,
         {
             options->vlan_accept = VLAN_ONLY_UNTAGGED_OR_PRIORITY;
         }
+        else if (streq(p[1], "all"))
+        {
+            options->vlan_accept = VLAN_ALL;
+        }
         else
         {
-            msg(msglevel, "--vlan-accept must be 'tagged', 'untagged'");
+            msg(msglevel, "--vlan-accept must be 'tagged', 'untagged' or 'all'");
             goto err;
         }
     }
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 3447b7e2..6f5e1f53 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -173,6 +173,7 @@ enum vlan_acceptable_frames
 {
     VLAN_ONLY_TAGGED,
     VLAN_ONLY_UNTAGGED_OR_PRIORITY,
+    VLAN_ALL,
 };
 
 struct remote_host_store
diff --git a/src/openvpn/vlan.c b/src/openvpn/vlan.c
index 88c90574..a5885de2 100644
--- a/src/openvpn/vlan.c
+++ b/src/openvpn/vlan.c
@@ -74,6 +74,10 @@ vlanhdr_set_vid(struct openvpn_8021qhdr *hdr, const uint16_t vid)
  *   returned.  Any included priority information is lost.
  *   If a frame isn't VLAN-tagged, the frame is dropped.
  *
+ * For vlan_accept == VLAN_ALL:
+ *   Accepts both VLAN-tagged and untagged (or priority-tagged) frames and
+ *   and handles them as described above.
+ *
  * @param c   The global context.
  * @param buf The ethernet frame.
  * @return    Returns -1 if the frame is dropped or the VID if it is accepted.
@@ -133,6 +137,7 @@ vlan_decapsulate(const struct context *c, struct buffer *buf)
 
             /* vid == 0 means prio-tagged packet: don't drop and fall-through */
         case VLAN_ONLY_TAGGED:
+        case VLAN_ALL:
             /* tagged frame can be accepted: extract vid and strip encapsulation */
 
             /* in case of prio-tagged frame (vid == 0), assume the sender
@@ -310,6 +315,18 @@ vlan_process_outgoing_tun(struct multi_context *m, struct multi_instance *mi)
             mi->context.c2.to_tun.len = 0;
         }
     }
+    else if (m->top.options.vlan_accept == VLAN_ALL)
+    {
+        /* Packets either need to be VLAN-tagged or not, depending on the
+         * packet's originating VID and the port's native VID (PVID).  */
+
+        if (m->top.options.vlan_pvid != mi->context.options.vlan_pvid)
+        {
+            /* Packets need to be VLAN-tagged, because the packet's VID does not
+             * match the port's PVID.  */
+            vlan_encapsulate(&mi->context, &mi->context.c2.to_tun);
+        }
+    }
     else if (m->top.options.vlan_accept == VLAN_ONLY_TAGGED)
     {
         /* All packets on the port (the tap device) need to be VLAN-tagged.  */
