return ret;
 }
 
+static bool min_mtu(int a, int b)
+{
+       return a < b ? 1 : 0;
+}
+
+static bool max_mtu(int a, int b)
+{
+       return a > b ? 1 : 0;
+}
+
 /* MTU of the bridge pseudo-device: ETH_DATA_LEN or the minimum of the ports */
-int br_min_mtu(const struct net_bridge *br)
+static int __br_mtu(const struct net_bridge *br, bool (compare_fn)(int, int))
 {
        const struct net_bridge_port *p;
        int mtu = 0;
                mtu = ETH_DATA_LEN;
        else {
                list_for_each_entry(p, &br->port_list, list) {
-                       if (!mtu  || p->dev->mtu < mtu)
+                       if (!mtu || compare_fn(p->dev->mtu, mtu))
                                mtu = p->dev->mtu;
                }
        }
        return mtu;
 }
 
+int br_mtu(const struct net_bridge *br)
+{
+       if (br->vlan_enabled)
+               return __br_mtu(br, max_mtu);
+       else
+               return __br_mtu(br, min_mtu);
+}
+
 static void br_set_gso_limits(struct net_bridge *br)
 {
        unsigned int gso_max_size = GSO_MAX_SIZE;
        if (changed_addr)
                call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev);
 
-       dev_set_mtu(br->dev, br_min_mtu(br));
+       dev_set_mtu(br->dev, br_mtu(br));
        br_set_gso_limits(br);
 
        kobject_uevent(&p->kobj, KOBJ_ADD);
         */
        del_nbp(p);
 
-       dev_set_mtu(br->dev, br_min_mtu(br));
+       dev_set_mtu(br->dev, br_mtu(br));
        br_set_gso_limits(br);
 
        spin_lock_bh(&br->lock);
 
 int br_add_if(struct net_bridge *br, struct net_device *dev,
              struct netlink_ext_ack *extack);
 int br_del_if(struct net_bridge *br, struct net_device *dev);
-int br_min_mtu(const struct net_bridge *br);
+int br_mtu(const struct net_bridge *br);
 netdev_features_t br_features_recompute(struct net_bridge *br,
                                        netdev_features_t features);
 void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);