diff --git a/interface-definitions/include/interface/vif-s.xml.i b/interface-definitions/include/interface/vif-s.xml.i
index fdd62b63d..02e7ab057 100644
--- a/interface-definitions/include/interface/vif-s.xml.i
+++ b/interface-definitions/include/interface/vif-s.xml.i
@@ -1,75 +1,55 @@
 <!-- include start from interface/vif-s.xml.i -->
 <tagNode name="vif-s">
   <properties>
     <help>QinQ TAG-S Virtual Local Area Network (VLAN) ID</help>
     <valueHelp>
       <format>u32:0-4094</format>
       <description>QinQ Virtual Local Area Network (VLAN) ID</description>
     </valueHelp>
     <constraint>
       <validator name="numeric" argument="--range 0-4094"/>
     </constraint>
     <constraintErrorMessage>VLAN ID must be between 0 and 4094</constraintErrorMessage>
   </properties>
   <children>
     #include <include/generic-description.xml.i>
     #include <include/interface/address-ipv4-ipv6-dhcp.xml.i>
     #include <include/interface/dhcp-options.xml.i>
     #include <include/interface/dhcpv6-options.xml.i>
     #include <include/interface/disable-link-detect.xml.i>
     #include <include/interface/disable.xml.i>
-    <leafNode name="protocol">
-      <properties>
-        <help>Protocol used for service VLAN (default: 802.1ad)</help>
-        <completionHelp>
-          <list>802.1ad 802.1q</list>
-        </completionHelp>
-        <valueHelp>
-          <format>802.1ad</format>
-          <description>Provider Bridging (IEEE 802.1ad, Q-inQ), ethertype 0x88a8</description>
-        </valueHelp>
-        <valueHelp>
-          <format>802.1q</format>
-          <description>VLAN-tagged frame (IEEE 802.1q), ethertype 0x8100</description>
-        </valueHelp>
-        <constraint>
-          <regex>(802.1q|802.1ad)</regex>
-        </constraint>
-        <constraintErrorMessage>Ethertype must be 802.1ad or 802.1q</constraintErrorMessage>
-      </properties>
-      <defaultValue>802.1ad</defaultValue>
-    </leafNode>
+    #include <include/interface/vlan-protocol.xml.i>
     #include <include/interface/ipv4-options.xml.i>
     #include <include/interface/ipv6-options.xml.i>
     #include <include/interface/mac.xml.i>
     #include <include/interface/mirror.xml.i>
     #include <include/interface/mtu-68-16000.xml.i>
     <tagNode name="vif-c">
       <properties>
         <help>QinQ TAG-C Virtual Local Area Network (VLAN) ID</help>
         <constraint>
           <validator name="numeric" argument="--range 0-4094"/>
         </constraint>
         <constraintErrorMessage>VLAN ID must be between 0 and 4094</constraintErrorMessage>
       </properties>
       <children>
         #include <include/generic-description.xml.i>
         #include <include/interface/address-ipv4-ipv6-dhcp.xml.i>
         #include <include/interface/dhcp-options.xml.i>
         #include <include/interface/dhcpv6-options.xml.i>
         #include <include/interface/disable-link-detect.xml.i>
         #include <include/interface/disable.xml.i>
         #include <include/interface/ipv4-options.xml.i>
         #include <include/interface/ipv6-options.xml.i>
         #include <include/interface/mac.xml.i>
         #include <include/interface/mirror.xml.i>
         #include <include/interface/mtu-68-16000.xml.i>
         #include <include/interface/redirect.xml.i>
         #include <include/interface/vrf.xml.i>
       </children>
     </tagNode>
     #include <include/interface/redirect.xml.i>
     #include <include/interface/vrf.xml.i>
   </children>
 </tagNode>
 <!-- include end -->
diff --git a/interface-definitions/include/interface/vlan-protocol.xml.i b/interface-definitions/include/interface/vlan-protocol.xml.i
new file mode 100644
index 000000000..2fe8d65d7
--- /dev/null
+++ b/interface-definitions/include/interface/vlan-protocol.xml.i
@@ -0,0 +1,23 @@
+<!-- include start from interface/vif.xml.i -->
+<leafNode name="protocol">
+  <properties>
+    <help>Protocol used for service VLAN (default: 802.1ad)</help>
+    <completionHelp>
+      <list>802.1ad 802.1q</list>
+    </completionHelp>
+    <valueHelp>
+      <format>802.1ad</format>
+      <description>Provider Bridging (IEEE 802.1ad, Q-inQ), ethertype 0x88a8</description>
+    </valueHelp>
+    <valueHelp>
+      <format>802.1q</format>
+      <description>VLAN-tagged frame (IEEE 802.1q), ethertype 0x8100</description>
+    </valueHelp>
+    <constraint>
+      <regex>(802.1q|802.1ad)</regex>
+    </constraint>
+    <constraintErrorMessage>Ethertype must be 802.1ad or 802.1q</constraintErrorMessage>
+  </properties>
+  <defaultValue>802.1ad</defaultValue>
+</leafNode>
+<!-- include end -->
diff --git a/interface-definitions/interfaces_bridge.xml.in b/interface-definitions/interfaces_bridge.xml.in
index d4d277cfc..7fb5f121a 100644
--- a/interface-definitions/interfaces_bridge.xml.in
+++ b/interface-definitions/interfaces_bridge.xml.in
@@ -1,226 +1,230 @@
 <?xml version="1.0"?>
 <interfaceDefinition>
   <node name="interfaces">
     <children>
       <tagNode name="bridge" owner="${vyos_conf_scripts_dir}/interfaces_bridge.py">
         <properties>
           <help>Bridge Interface</help>
           <priority>310</priority>
           <constraint>
             <regex>br[0-9]+</regex>
           </constraint>
           <constraintErrorMessage>Bridge interface must be named brN</constraintErrorMessage>
           <valueHelp>
             <format>brN</format>
             <description>Bridge interface name</description>
           </valueHelp>
         </properties>
         <children>
           #include <include/interface/address-ipv4-ipv6-dhcp.xml.i>
           <leafNode name="aging">
             <properties>
               <help>MAC address aging interval</help>
               <valueHelp>
                 <format>u32:0</format>
                 <description>Disable MAC address learning (always flood)</description>
               </valueHelp>
               <valueHelp>
                 <format>u32:10-1000000</format>
                 <description>MAC address aging time in seconds</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 0-0 --range 10-1000000"/>
               </constraint>
             </properties>
             <defaultValue>300</defaultValue>
           </leafNode>
           #include <include/generic-description.xml.i>
           #include <include/interface/dhcp-options.xml.i>
           #include <include/interface/dhcpv6-options.xml.i>
           #include <include/interface/disable-link-detect.xml.i>
           #include <include/interface/disable.xml.i>
           #include <include/interface/vrf.xml.i>
           #include <include/interface/mtu-68-16000.xml.i>
           <leafNode name="forwarding-delay">
             <properties>
               <help>Forwarding delay</help>
               <valueHelp>
                 <format>u32:0-200</format>
                 <description>Spanning Tree Protocol forwarding delay in seconds</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 0-200"/>
               </constraint>
               <constraintErrorMessage>Forwarding delay must be between 0 and 200 seconds</constraintErrorMessage>
             </properties>
             <defaultValue>14</defaultValue>
           </leafNode>
           <leafNode name="hello-time">
             <properties>
               <help>Hello packet advertisement interval</help>
               <valueHelp>
                 <format>u32:1-10</format>
                 <description>Spanning Tree Protocol hello advertisement interval in seconds</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 1-10"/>
               </constraint>
               <constraintErrorMessage>Bridge Hello interval must be between 1 and 10 seconds</constraintErrorMessage>
             </properties>
             <defaultValue>2</defaultValue>
           </leafNode>
           <node name="igmp">
             <properties>
               <help>Internet Group Management Protocol (IGMP) and Multicast Listener Discovery (MLD) settings</help>
             </properties>
             <children>
               <leafNode name="querier">
                 <properties>
                   <help>Enable IGMP/MLD querier</help>
                   <valueless/>
                 </properties>
               </leafNode>
               <leafNode name="snooping">
                 <properties>
                   <help>Enable IGMP/MLD snooping</help>
                   <valueless/>
                 </properties>
               </leafNode>
             </children>
           </node>
           #include <include/interface/ipv4-options.xml.i>
           #include <include/interface/ipv6-options.xml.i>
           #include <include/interface/mac.xml.i>
           #include <include/interface/mirror.xml.i>
           <leafNode name="enable-vlan">
             <properties>
               <help>Enable VLAN aware bridge</help>
               <valueless/>
             </properties>
           </leafNode>
+          #include <include/interface/vlan-protocol.xml.i>
+          <leafNode name="protocol">
+            <defaultValue>802.1q</defaultValue>
+          </leafNode>
           <leafNode name="max-age">
             <properties>
               <help>Interval at which neighbor bridges are removed</help>
               <valueHelp>
                 <format>u32:1-40</format>
                 <description>Bridge maximum aging time in seconds</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 1-40"/>
               </constraint>
               <constraintErrorMessage>Bridge max aging value must be between 1 and 40 seconds</constraintErrorMessage>
             </properties>
             <defaultValue>20</defaultValue>
           </leafNode>
           <node name="member">
             <properties>
               <help>Bridge member interfaces</help>
             </properties>
             <children>
               <tagNode name="interface">
                 <properties>
                   <help>Member interface name</help>
                   <completionHelp>
                     <script>${vyos_completion_dir}/list_interfaces --bridgeable</script>
                   </completionHelp>
                   <constraint>
                     #include <include/constraint/interface-name.xml.i>
                   </constraint>
                 </properties>
                 <children>
                   <leafNode name="native-vlan">
                     <properties>
                       <help>Specify VLAN id which should natively be present on the link</help>
                       <valueHelp>
                         <format>u32:1-4094</format>
                         <description>Virtual Local Area Network (VLAN) ID</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 1-4094"/>
                       </constraint>
                       <constraintErrorMessage>VLAN ID must be between 1 and 4094</constraintErrorMessage>
                     </properties>
                   </leafNode>
                   <leafNode name="allowed-vlan">
                     <properties>
                       <help>Specify VLAN id which is allowed in this trunk interface</help>
                       <valueHelp>
                         <format>&lt;id&gt;</format>
                         <description>VLAN id allowed to pass this interface</description>
                       </valueHelp>
                       <valueHelp>
                         <format>&lt;idN&gt;-&lt;idM&gt;</format>
                         <description>VLAN id range allowed on this interface (use '-' as delimiter)</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--allow-range --range 1-4094"/>
                       </constraint>
                       <constraintErrorMessage>not a valid VLAN ID value or range</constraintErrorMessage>
                       <multi/>
                     </properties>
                   </leafNode>
                   <leafNode name="cost">
                     <properties>
                       <help>Bridge port cost</help>
                       <valueHelp>
                         <format>u32:1-65535</format>
                         <description>Path cost value for Spanning Tree Protocol</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 1-65535"/>
                       </constraint>
                       <constraintErrorMessage>Path cost value must be between 1 and 65535</constraintErrorMessage>
                     </properties>
                     <defaultValue>100</defaultValue>
                   </leafNode>
                   <leafNode name="priority">
                     <properties>
                       <help>Bridge port priority</help>
                       <valueHelp>
                         <format>u32:0-63</format>
                         <description>Bridge port priority</description>
                       </valueHelp>
                       <constraint>
                         <validator name="numeric" argument="--range 1-63"/>
                       </constraint>
                       <constraintErrorMessage>Port priority value must be between 0 and 63</constraintErrorMessage>
                     </properties>
                     <defaultValue>32</defaultValue>
                   </leafNode>
                   <leafNode name="isolated">
                     <properties>
                       <help>Port is isolated (also known as Private-VLAN)</help>
                       <valueless/>
                     </properties>
                   </leafNode>
                 </children>
               </tagNode>
             </children>
           </node>
           <leafNode name="priority">
             <properties>
               <help>Priority for this bridge</help>
               <valueHelp>
                 <format>u32:0-65535</format>
                 <description>Bridge priority</description>
               </valueHelp>
               <constraint>
                 <validator name="numeric" argument="--range 0-65535"/>
               </constraint>
               <constraintErrorMessage>Bridge priority must be between 0 and 65535 (multiples of 4096)</constraintErrorMessage>
             </properties>
             <defaultValue>32768</defaultValue>
           </leafNode>
           <leafNode name="stp">
             <properties>
               <help>Enable spanning tree protocol</help>
               <valueless/>
             </properties>
           </leafNode>
           #include <include/interface/redirect.xml.i>
           #include <include/interface/vif.xml.i>
         </children>
       </tagNode>
     </children>
   </node>
 </interfaceDefinition>
diff --git a/python/vyos/ifconfig/bridge.py b/python/vyos/ifconfig/bridge.py
index b29e71394..7936e3da5 100644
--- a/python/vyos/ifconfig/bridge.py
+++ b/python/vyos/ifconfig/bridge.py
@@ -1,388 +1,414 @@
-# Copyright 2019-2021 VyOS maintainers and contributors <maintainers@vyos.io>
+# Copyright 2019-2024 VyOS maintainers and contributors <maintainers@vyos.io>
 #
 # This library 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.
 #
 # This library 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 this library.  If not, see <http://www.gnu.org/licenses/>.
 
 from netifaces import interfaces
-import json
 
 from vyos.ifconfig.interface import Interface
 from vyos.utils.assertion import assert_boolean
+from vyos.utils.assertion import assert_list
 from vyos.utils.assertion import assert_positive
-from vyos.utils.process import cmd
 from vyos.utils.dict import dict_search
 from vyos.configdict import get_vlan_ids
 from vyos.configdict import list_diff
 
 @Interface.register
 class BridgeIf(Interface):
     """
     A bridge is a way to connect two Ethernet segments together in a protocol
     independent way. Packets are forwarded based on Ethernet address, rather
     than IP address (like a router). Since forwarding is done at Layer 2, all
     protocols can go transparently through a bridge.
 
     The Linux bridge code implements a subset of the ANSI/IEEE 802.1d standard.
     """
     iftype = 'bridge'
     definition = {
         **Interface.definition,
         **{
             'section': 'bridge',
             'prefixes': ['br', ],
             'broadcast': True,
             'vlan': True,
         },
     }
 
     _sysfs_get = {
         **Interface._sysfs_get,**{
             'vlan_filter': {
                 'location': '/sys/class/net/{ifname}/bridge/vlan_filtering'
             }
         }
     }
 
     _sysfs_set = {**Interface._sysfs_set, **{
         'ageing_time': {
             'validate': assert_positive,
             'convert': lambda t: int(t) * 100,
             'location': '/sys/class/net/{ifname}/bridge/ageing_time',
         },
         'forward_delay': {
             'validate': assert_positive,
             'convert': lambda t: int(t) * 100,
             'location': '/sys/class/net/{ifname}/bridge/forward_delay',
         },
         'hello_time': {
             'validate': assert_positive,
             'convert': lambda t: int(t) * 100,
             'location': '/sys/class/net/{ifname}/bridge/hello_time',
         },
         'max_age': {
             'validate': assert_positive,
             'convert': lambda t: int(t) * 100,
             'location': '/sys/class/net/{ifname}/bridge/max_age',
         },
         'priority': {
             'validate': assert_positive,
             'location': '/sys/class/net/{ifname}/bridge/priority',
         },
         'stp': {
             'validate': assert_boolean,
             'location': '/sys/class/net/{ifname}/bridge/stp_state',
         },
         'vlan_filter': {
             'validate': assert_boolean,
             'location': '/sys/class/net/{ifname}/bridge/vlan_filtering',
         },
+        'vlan_protocol': {
+            'validate': lambda v: assert_list(v, ['0x88a8', '0x8100']),
+            'location': '/sys/class/net/{ifname}/bridge/vlan_protocol',
+        },
         'multicast_querier': {
             'validate': assert_boolean,
             'location': '/sys/class/net/{ifname}/bridge/multicast_querier',
         },
         'multicast_snooping': {
             'validate': assert_boolean,
             'location': '/sys/class/net/{ifname}/bridge/multicast_snooping',
         },
     }}
 
     _command_set = {**Interface._command_set, **{
         'add_port': {
             'shellcmd': 'ip link set dev {value} master {ifname}',
         },
         'del_port': {
             'shellcmd': 'ip link set dev {value} nomaster',
         },
     }}
 
     def get_vlan_filter(self):
         """
         Get the status of the bridge VLAN filter
         """
 
         return self.get_interface('vlan_filter')
 
 
     def set_ageing_time(self, time):
         """
         Set bridge interface MAC address aging time in seconds. Internal kernel
         representation is in centiseconds. Kernel default is 300 seconds.
 
         Example:
         >>> from vyos.ifconfig import BridgeIf
         >>> BridgeIf('br0').ageing_time(2)
         """
         self.set_interface('ageing_time', time)
 
     def set_forward_delay(self, time):
         """
         Set bridge forwarding delay in seconds. Internal Kernel representation
         is in centiseconds.
 
         Example:
         >>> from vyos.ifconfig import BridgeIf
         >>> BridgeIf('br0').forward_delay(15)
         """
         self.set_interface('forward_delay', time)
 
     def set_hello_time(self, time):
         """
         Set bridge hello time in seconds. Internal Kernel representation
         is in centiseconds.
 
         Example:
         >>> from vyos.ifconfig import BridgeIf
         >>> BridgeIf('br0').set_hello_time(2)
         """
         self.set_interface('hello_time', time)
 
     def set_max_age(self, time):
         """
         Set bridge max message age in seconds. Internal Kernel representation
         is in centiseconds.
 
         Example:
         >>> from vyos.ifconfig import Interface
         >>> BridgeIf('br0').set_max_age(30)
         """
         self.set_interface('max_age', time)
 
     def set_priority(self, priority):
         """
         Set bridge max aging time in seconds.
 
         Example:
         >>> from vyos.ifconfig import BridgeIf
         >>> BridgeIf('br0').set_priority(8192)
         """
         self.set_interface('priority', priority)
 
     def set_stp(self, state):
         """
         Set bridge STP (Spanning Tree) state. 0 -> STP disabled, 1 -> STP enabled
 
         Example:
         >>> from vyos.ifconfig import BridgeIf
         >>> BridgeIf('br0').set_stp(1)
         """
         self.set_interface('stp', state)
 
     def set_vlan_filter(self, state):
         """
         Set bridge Vlan Filter state. 0 -> Vlan Filter disabled, 1 -> Vlan Filter enabled
 
         Example:
         >>> from vyos.ifconfig import BridgeIf
         >>> BridgeIf('br0').set_vlan_filter(1)
         """
         self.set_interface('vlan_filter', state)
 
         # VLAN of bridge parent interface is always 1
         # VLAN 1 is the default VLAN for all unlabeled packets
         cmd = f'bridge vlan add dev {self.ifname} vid 1 pvid untagged self'
         self._cmd(cmd)
 
     def set_multicast_querier(self, enable):
         """
         Sets whether the bridge actively runs a multicast querier or not. When a
         bridge receives a 'multicast host membership' query from another network
         host, that host is tracked based on the time that the query was received
         plus the multicast query interval time.
 
         Use enable=1 to enable or enable=0 to disable
 
         Example:
         >>> from vyos.ifconfig import Interface
         >>> BridgeIf('br0').set_multicast_querier(1)
         """
         self.set_interface('multicast_querier', enable)
 
     def set_multicast_snooping(self, enable):
         """
         Enable or disable multicast snooping on the bridge.
 
         Use enable=1 to enable or enable=0 to disable
 
         Example:
         >>> from vyos.ifconfig import Interface
         >>> BridgeIf('br0').set_multicast_snooping(1)
         """
         self.set_interface('multicast_snooping', enable)
 
     def add_port(self, interface):
         """
         Add physical interface to bridge (member port)
 
         Example:
         >>> from vyos.ifconfig import Interface
         >>> BridgeIf('br0').add_port('eth0')
         >>> BridgeIf('br0').add_port('eth1')
         """
         # Bridge port handling of wireless interfaces is done by hostapd.
         if 'wlan' in interface:
             return
 
         try:
             return self.set_interface('add_port', interface)
         except:
             from vyos import ConfigError
             raise ConfigError('Error: Device does not allow enslaving to a bridge.')
 
     def del_port(self, interface):
         """
         Remove member port from bridge instance.
 
         Example:
         >>> from vyos.ifconfig import Interface
         >>> BridgeIf('br0').del_port('eth1')
         """
         return self.set_interface('del_port', interface)
 
+    def set_vlan_protocol(self, protocol):
+        """
+        Set protocol used for VLAN filtering.
+        The valid values are 0x8100(802.1q) or 0x88A8(802.1ad).
+
+        Example:
+        >>> from vyos.ifconfig import Interface
+        >>> BridgeIf('br0').del_port('eth1')
+        """
+
+        if protocol not in ['802.1q', '802.1ad']:
+            raise ValueError()
+
+        map = {
+            '802.1ad': '0x88a8',
+            '802.1q' : '0x8100'
+        }
+
+        return self.set_interface('vlan_protocol', map[protocol])
+
     def update(self, config):
         """ General helper function which works on a dictionary retrived by
         get_config_dict(). It's main intention is to consolidate the scattered
         interface setup code and provide a single point of entry when workin
         on any interface. """
 
         # Set ageing time
         value = config.get('aging')
         self.set_ageing_time(value)
 
         # set bridge forward delay
         value = config.get('forwarding_delay')
         self.set_forward_delay(value)
 
         # set hello time
         value = config.get('hello_time')
         self.set_hello_time(value)
 
         # set max message age
         value = config.get('max_age')
         self.set_max_age(value)
 
         # set bridge priority
         value = config.get('priority')
         self.set_priority(value)
 
         # enable/disable spanning tree
         value = '1' if 'stp' in config else '0'
         self.set_stp(value)
 
         # enable or disable multicast snooping
         tmp = dict_search('igmp.snooping', config)
         value = '1' if (tmp != None) else '0'
         self.set_multicast_snooping(value)
 
         # enable or disable IGMP querier
         tmp = dict_search('igmp.querier', config)
         value = '1' if (tmp != None) else '0'
         self.set_multicast_querier(value)
 
         # remove interface from bridge
         tmp = dict_search('member.interface_remove', config)
         for member in (tmp or []):
             if member in interfaces():
                 self.del_port(member)
 
-        # enable/disable Vlan Filter
+        # enable/disable VLAN Filter
         tmp = '1' if 'enable_vlan' in config else '0'
         self.set_vlan_filter(tmp)
 
+        tmp = config.get('protocol')
+        self.set_vlan_protocol(tmp)
+
         # add VLAN interfaces to local 'parent' bridge to allow forwarding
         if 'enable_vlan' in config:
             for vlan in config.get('vif_remove', {}):
                 # Remove old VLANs from the bridge
                 cmd = f'bridge vlan del dev {self.ifname} vid {vlan} self'
                 self._cmd(cmd)
 
             for vlan in config.get('vif', {}):
                 cmd = f'bridge vlan add dev {self.ifname} vid {vlan} self'
                 self._cmd(cmd)
 
             # VLAN of bridge parent interface is always 1. VLAN 1 is the default
             # VLAN for all unlabeled packets
             cmd = f'bridge vlan add dev {self.ifname} vid 1 pvid untagged self'
             self._cmd(cmd)
 
         tmp = dict_search('member.interface', config)
         if tmp:
             for interface, interface_config in tmp.items():
                 # if interface does yet not exist bail out early and
                 # add it later
                 if interface not in interfaces():
                     continue
 
                 # Bridge lower "physical" interface
                 lower = Interface(interface)
 
                 # If we've come that far we already verified the interface does
                 # not have any addresses configured by CLI so just flush any
                 # remaining ones
                 lower.flush_addrs()
 
                 # enslave interface port to bridge
                 self.add_port(interface)
 
                 if not interface.startswith('wlan'):
                     # always set private-vlan/port isolation - this can not be
                     # done when lower link is a wifi link, as it will trigger:
                     # RTNETLINK answers: Operation not supported
                     tmp = dict_search('isolated', interface_config)
                     value = 'on' if (tmp != None) else 'off'
                     lower.set_port_isolation(value)
 
                 # set bridge port path cost
                 if 'cost' in interface_config:
                     lower.set_path_cost(interface_config['cost'])
 
                 # set bridge port path priority
                 if 'priority' in interface_config:
                     lower.set_path_priority(interface_config['priority'])
 
                 if 'enable_vlan' in config:
                     add_vlan = []
                     native_vlan_id = None
                     allowed_vlan_ids= []
                     cur_vlan_ids = get_vlan_ids(interface)
 
                     if 'native_vlan' in interface_config:
                         vlan_id = interface_config['native_vlan']
                         add_vlan.append(vlan_id)
                         native_vlan_id = vlan_id
 
                     if 'allowed_vlan' in interface_config:
                         for vlan in interface_config['allowed_vlan']:
                             vlan_range = vlan.split('-')
                             if len(vlan_range) == 2:
                                 for vlan_add in range(int(vlan_range[0]),int(vlan_range[1]) + 1):
                                     add_vlan.append(str(vlan_add))
                                     allowed_vlan_ids.append(str(vlan_add))
                             else:
                                 add_vlan.append(vlan)
                                 allowed_vlan_ids.append(vlan)
 
                     # Remove redundant VLANs from the system
                     for vlan in list_diff(cur_vlan_ids, add_vlan):
                         cmd = f'bridge vlan del dev {interface} vid {vlan} master'
                         self._cmd(cmd)
 
                     for vlan in allowed_vlan_ids:
                         cmd = f'bridge vlan add dev {interface} vid {vlan} master'
                         self._cmd(cmd)
 
                     # Setting native VLAN to system
                     if native_vlan_id:
                         cmd = f'bridge vlan add dev {interface} vid {native_vlan_id} pvid untagged master'
                         self._cmd(cmd)
 
         super().update(config)
diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py
index 3500e97d6..124c1fbcb 100755
--- a/smoketest/scripts/cli/test_interfaces_bridge.py
+++ b/smoketest/scripts/cli/test_interfaces_bridge.py
@@ -1,446 +1,464 @@
 #!/usr/bin/env python3
 #
 # Copyright (C) 2020-2024 VyOS maintainers and contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2 or later as
 # published by the Free Software Foundation.
 #
 # This program 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 General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
 import json
 import unittest
 
 from base_interfaces_test import BasicInterfaceTest
 from copy import deepcopy
 from glob import glob
 
 from vyos.ifconfig import Section
 from vyos.template import ip_from_cidr
 from vyos.utils.process import cmd
 from vyos.utils.file import read_file
 from vyos.utils.network import get_interface_config
 from vyos.utils.network import interface_exists
 
 class BridgeInterfaceTest(BasicInterfaceTest.TestCase):
     @classmethod
     def setUpClass(cls):
         cls._base_path = ['interfaces', 'bridge']
         cls._mirror_interfaces = ['dum21354']
         cls._members = []
 
         # we need to filter out VLAN interfaces identified by a dot (.)
         # in their name - just in case!
         if 'TEST_ETH' in os.environ:
             cls._members = os.environ['TEST_ETH'].split()
         else:
             for tmp in Section.interfaces('ethernet', vlan=False):
                 cls._members.append(tmp)
 
         cls._options['br0'] = []
         for member in cls._members:
             cls._options['br0'].append(f'member interface {member}')
         cls._interfaces = list(cls._options)
 
         # call base-classes classmethod
         super(BridgeInterfaceTest, cls).setUpClass()
 
     def tearDown(self):
         for intf in self._interfaces:
             self.cli_delete(self._base_path + [intf])
 
         super().tearDown()
 
     def test_isolated_interfaces(self):
         # Add member interfaces to bridge and set STP cost/priority
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['stp'])
 
             # assign members to bridge interface
             for member in self._members:
                 base_member = base + ['member', 'interface', member]
                 self.cli_set(base_member + ['isolated'])
 
         # commit config
         self.cli_commit()
 
         for interface in self._interfaces:
             tmp = get_interface_config(interface)
             # STP must be enabled as configured above
             self.assertEqual(1, tmp['linkinfo']['info_data']['stp_state'])
 
             # validate member interface configuration
             for member in self._members:
                 tmp = get_interface_config(member)
                 # verify member is assigned to the bridge
                 self.assertEqual(interface, tmp['master'])
                 # Isolated must be enabled as configured above
                 self.assertTrue(tmp['linkinfo']['info_slave_data']['isolated'])
 
     def test_igmp_querier_snooping(self):
         # Add member interfaces to bridge
         for interface in self._interfaces:
             base = self._base_path + [interface]
 
             # assign members to bridge interface
             for member in self._members:
                 base_member = base + ['member', 'interface', member]
                 self.cli_set(base_member)
 
         # commit config
         self.cli_commit()
 
         for interface in self._interfaces:
             # Verify IGMP default configuration
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping')
             self.assertEqual(tmp, '0')
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier')
             self.assertEqual(tmp, '0')
 
         # Enable IGMP snooping
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['igmp', 'snooping'])
 
         # commit config
         self.cli_commit()
 
         for interface in self._interfaces:
             # Verify IGMP snooping configuration
             # Verify IGMP default configuration
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping')
             self.assertEqual(tmp, '1')
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier')
             self.assertEqual(tmp, '0')
 
         # Enable IGMP querieer
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['igmp', 'querier'])
 
         # commit config
         self.cli_commit()
 
         for interface in self._interfaces:
             # Verify IGMP snooping & querier configuration
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping')
             self.assertEqual(tmp, '1')
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier')
             self.assertEqual(tmp, '1')
 
         # Disable IGMP
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_delete(base + ['igmp'])
 
         # commit config
         self.cli_commit()
 
         for interface in self._interfaces:
             # Verify IGMP snooping & querier configuration
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_snooping')
             self.assertEqual(tmp, '0')
             tmp = read_file(f'/sys/class/net/{interface}/bridge/multicast_querier')
             self.assertEqual(tmp, '0')
 
             # validate member interface configuration
             for member in self._members:
                 tmp = get_interface_config(member)
                 # verify member is assigned to the bridge
                 self.assertEqual(interface, tmp['master'])
 
 
     def test_add_remove_bridge_member(self):
         # Add member interfaces to bridge and set STP cost/priority
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['stp'])
             self.cli_set(base + ['address', '192.0.2.1/24'])
 
             cost = 1000
             priority = 10
             # assign members to bridge interface
             for member in self._members:
                 base_member = base + ['member', 'interface', member]
                 self.cli_set(base_member + ['cost', str(cost)])
                 self.cli_set(base_member + ['priority', str(priority)])
                 cost += 1
                 priority += 1
 
         # commit config
         self.cli_commit()
 
         # Add member interfaces to bridge and set STP cost/priority
         for interface in self._interfaces:
             cost = 1000
             priority = 10
+
+            tmp = get_interface_config(interface)
+            self.assertEqual('802.1Q',  tmp['linkinfo']['info_data']['vlan_protocol']) # default VLAN protocol
+
             for member in self._members:
                 tmp = get_interface_config(member)
                 self.assertEqual(interface, tmp['master'])
                 self.assertFalse(           tmp['linkinfo']['info_slave_data']['isolated'])
                 self.assertEqual(cost,      tmp['linkinfo']['info_slave_data']['cost'])
                 self.assertEqual(priority,  tmp['linkinfo']['info_slave_data']['priority'])
 
                 cost += 1
                 priority += 1
 
 
     def test_vif_8021q_interfaces(self):
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['enable-vlan'])
         super().test_vif_8021q_interfaces()
 
     def test_vif_8021q_lower_up_down(self):
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['enable-vlan'])
         super().test_vif_8021q_lower_up_down()
 
     def test_vif_8021q_qos_change(self):
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['enable-vlan'])
         super().test_vif_8021q_qos_change()
 
     def test_vif_8021q_mtu_limits(self):
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['enable-vlan'])
         super().test_vif_8021q_mtu_limits()
 
     def test_bridge_vlan_filter(self):
         vifs = ['10', '20', '30', '40']
         native_vlan = '20'
 
         # Add member interface to bridge and set VLAN filter
         for interface in self._interfaces:
             base = self._base_path + [interface]
             self.cli_set(base + ['enable-vlan'])
             self.cli_set(base + ['address', '192.0.2.1/24'])
 
             for vif in vifs:
                 self.cli_set(base + ['vif', vif, 'address', f'192.0.{vif}.1/24'])
                 self.cli_set(base + ['vif', vif, 'mtu', self._mtu])
 
             for member in self._members:
                 base_member = base + ['member', 'interface', member]
                 self.cli_set(base_member + ['native-vlan', native_vlan])
                 for vif in vifs:
                     self.cli_set(base_member + ['allowed-vlan', vif])
 
         # commit config
         self.cli_commit()
 
         def _verify_members(interface, members) -> None:
             # check member interfaces are added on the bridge
             bridge_members = []
             for tmp in glob(f'/sys/class/net/{interface}/lower_*'):
                 bridge_members.append(os.path.basename(tmp).replace('lower_', ''))
 
             self.assertListEqual(sorted(members), sorted(bridge_members))
 
         def _check_vlan_filter(interface, vifs) -> None:
             configured_vlan_ids = []
 
             bridge_json = cmd(f'bridge -j vlan show dev {interface}')
             bridge_json = json.loads(bridge_json)
             self.assertIsNotNone(bridge_json)
 
             for tmp in bridge_json:
                 self.assertIn('vlans', tmp)
 
                 for vlan in tmp['vlans']:
                     self.assertIn('vlan', vlan)
                     configured_vlan_ids.append(str(vlan['vlan']))
 
                     # Verify native VLAN ID has 'PVID' flag set on individual member ports
                     if not interface.startswith('br') and str(vlan['vlan']) == native_vlan:
                         self.assertIn('flags', vlan)
                         self.assertIn('PVID', vlan['flags'])
 
             self.assertListEqual(sorted(configured_vlan_ids), sorted(vifs))
 
         # Verify correct setting of VLAN filter function
         for interface in self._interfaces:
             tmp = read_file(f'/sys/class/net/{interface}/bridge/vlan_filtering')
             self.assertEqual(tmp, '1')
 
         # Obtain status information and verify proper VLAN filter setup.
         # First check if all members are present, second check if all VLANs
         # are assigned on the parend bridge interface, third verify all the
         # VLANs are properly setup on the downstream "member" ports
         for interface in self._interfaces:
             # check member interfaces are added on the bridge
             _verify_members(interface, self._members)
 
             # Check if all VLAN ids are properly set up. Bridge interface always
             # has native VLAN 1
             tmp = deepcopy(vifs)
             tmp.append('1')
             _check_vlan_filter(interface, tmp)
 
             for member in self._members:
                 _check_vlan_filter(member, vifs)
 
         # change member interface description to trigger config update,
         # VLANs must still exist (T4565)
         for interface in self._interfaces:
             for member in self._members:
                 self.cli_set(['interfaces', Section.section(member), member, 'description', f'foo {member}'])
 
         # commit config
         self.cli_commit()
 
         # Obtain status information and verify proper VLAN filter setup.
         # First check if all members are present, second check if all VLANs
         # are assigned on the parend bridge interface, third verify all the
         # VLANs are properly setup on the downstream "member" ports
         for interface in self._interfaces:
             # check member interfaces are added on the bridge
             _verify_members(interface, self._members)
 
             # Check if all VLAN ids are properly set up. Bridge interface always
             # has native VLAN 1
             tmp = deepcopy(vifs)
             tmp.append('1')
             _check_vlan_filter(interface, tmp)
 
             for member in self._members:
                 _check_vlan_filter(member, vifs)
 
         # delete all members
         for interface in self._interfaces:
             self.cli_delete(self._base_path + [interface, 'member'])
 
         # commit config
         self.cli_commit()
 
         # verify member interfaces are no longer assigned on the bridge
         for interface in self._interfaces:
             bridge_members = []
             for tmp in glob(f'/sys/class/net/{interface}/lower_*'):
                 bridge_members.append(os.path.basename(tmp).replace('lower_', ''))
 
             self.assertNotEqual(len(self._members), len(bridge_members))
             for member in self._members:
                 self.assertNotIn(member, bridge_members)
 
     def test_bridge_vif_members(self):
         # T2945: ensure that VIFs are not dropped from bridge
         vifs = ['300', '400']
         for interface in self._interfaces:
             for member in self._members:
                 for vif in vifs:
                     self.cli_set(['interfaces', 'ethernet', member, 'vif', vif])
                     self.cli_set(['interfaces', 'bridge', interface, 'member', 'interface', f'{member}.{vif}'])
 
         self.cli_commit()
 
         # Verify config
         for interface in self._interfaces:
             for member in self._members:
                 for vif in vifs:
                     # member interface must be assigned to the bridge
                     self.assertTrue(os.path.exists(f'/sys/class/net/{interface}/lower_{member}.{vif}'))
 
         # delete all members
         for interface in self._interfaces:
             for member in self._members:
                 for vif in vifs:
                     self.cli_delete(['interfaces', 'ethernet', member, 'vif', vif])
                     self.cli_delete(['interfaces', 'bridge', interface, 'member', 'interface', f'{member}.{vif}'])
 
     def test_bridge_vif_s_vif_c_members(self):
         # T2945: ensure that VIFs are not dropped from bridge
         vifs = ['300', '400']
         vifc = ['301', '401']
         for interface in self._interfaces:
             for member in self._members:
                 for vif_s in vifs:
                     for vif_c in vifc:
                         self.cli_set(['interfaces', 'ethernet', member, 'vif-s', vif_s, 'vif-c', vif_c])
                         self.cli_set(['interfaces', 'bridge', interface, 'member', 'interface', f'{member}.{vif_s}.{vif_c}'])
 
         self.cli_commit()
 
         # Verify config
         for interface in self._interfaces:
             for member in self._members:
                 for vif_s in vifs:
                     for vif_c in vifc:
                         # member interface must be assigned to the bridge
                         self.assertTrue(os.path.exists(f'/sys/class/net/{interface}/lower_{member}.{vif_s}.{vif_c}'))
 
         # delete all members
         for interface in self._interfaces:
             for member in self._members:
                 for vif_s in vifs:
                     self.cli_delete(['interfaces', 'ethernet', member, 'vif-s', vif_s])
                     for vif_c in vifc:
                         self.cli_delete(['interfaces', 'bridge', interface, 'member', 'interface', f'{member}.{vif_s}.{vif_c}'])
 
     def test_bridge_tunnel_vxlan_multicast(self):
         # Testcase for T6043 running VXLAN over gretap
         br_if = 'br0'
         tunnel_if = 'tun0'
         eth_if = 'eth1'
         vxlan_if = 'vxlan0'
         multicast_group = '239.0.0.241'
         vni = '123'
         eth0_addr = '192.0.2.2/30'
 
         self.cli_set(['interfaces', 'bridge', br_if, 'member', 'interface', eth_if])
         self.cli_set(['interfaces', 'bridge', br_if, 'member', 'interface', vxlan_if])
 
         self.cli_set(['interfaces', 'ethernet', 'eth0', 'address', eth0_addr])
 
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'address', '10.0.0.2/24'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'enable-multicast'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'encapsulation', 'gretap'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'mtu', '1500'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'parameters', 'ip', 'ignore-df'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'parameters', 'ip', 'key', '1'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'parameters', 'ip', 'no-pmtu-discovery'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'parameters', 'ip', 'ttl', '0'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'remote', '203.0.113.2'])
         self.cli_set(['interfaces', 'tunnel', tunnel_if, 'source-address', ip_from_cidr(eth0_addr)])
 
         self.cli_set(['interfaces', 'vxlan', vxlan_if, 'group', multicast_group])
         self.cli_set(['interfaces', 'vxlan', vxlan_if, 'mtu', '1426'])
         self.cli_set(['interfaces', 'vxlan', vxlan_if, 'source-interface', tunnel_if])
         self.cli_set(['interfaces', 'vxlan', vxlan_if, 'vni', vni])
 
         self.cli_commit()
 
         self.assertTrue(interface_exists(eth_if))
         self.assertTrue(interface_exists(vxlan_if))
         self.assertTrue(interface_exists(tunnel_if))
 
         tmp = get_interface_config(vxlan_if)
         self.assertEqual(tmp['ifname'], vxlan_if)
         self.assertEqual(tmp['linkinfo']['info_data']['link'], tunnel_if)
         self.assertEqual(tmp['linkinfo']['info_data']['group'], multicast_group)
         self.assertEqual(tmp['linkinfo']['info_data']['id'], int(vni))
 
         bridge_members = []
         for tmp in glob(f'/sys/class/net/{br_if}/lower_*'):
             bridge_members.append(os.path.basename(tmp).replace('lower_', ''))
         self.assertIn(eth_if, bridge_members)
         self.assertIn(vxlan_if, bridge_members)
 
         self.cli_delete(['interfaces', 'bridge', br_if])
         self.cli_delete(['interfaces', 'vxlan', vxlan_if])
         self.cli_delete(['interfaces', 'tunnel', tunnel_if])
         self.cli_delete(['interfaces', 'ethernet', 'eth0', 'address', eth0_addr])
 
+    def test_bridge_vlan_protocol(self):
+        protocol = '802.1ad'
+
+        # Add member interface to bridge and set VLAN filter
+        for interface in self._interfaces:
+            self.cli_set(self._base_path + [interface, 'protocol', protocol])
+
+        # commit config
+        self.cli_commit()
+
+        for interface in self._interfaces:
+            tmp = get_interface_config(interface)
+            self.assertEqual(protocol, tmp['linkinfo']['info_data']['vlan_protocol'])
+
 if __name__ == '__main__':
     unittest.main(verbosity=2)