int err;
 
        if (vlan->port->passthru) {
-               dev_set_promiscuity(lowerdev, 1);
+               if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
+                       dev_set_promiscuity(lowerdev, 1);
                goto hash_add;
        }
 
        struct macvlan_dev *vlan = netdev_priv(dev);
        struct net_device *lowerdev = vlan->lowerdev;
 
+       dev_uc_unsync(lowerdev, dev);
+       dev_mc_unsync(lowerdev, dev);
+
        if (vlan->port->passthru) {
-               dev_set_promiscuity(lowerdev, -1);
+               if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
+                       dev_set_promiscuity(lowerdev, -1);
                goto hash_del;
        }
 
-       dev_mc_unsync(lowerdev, dev);
        if (dev->flags & IFF_ALLMULTI)
                dev_set_allmulti(lowerdev, -1);
 
                dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
 }
 
-static void macvlan_set_multicast_list(struct net_device *dev)
+static void macvlan_set_mac_lists(struct net_device *dev)
 {
        struct macvlan_dev *vlan = netdev_priv(dev);
 
+       dev_uc_sync(vlan->lowerdev, dev);
        dev_mc_sync(vlan->lowerdev, dev);
 }
 
        return 0;
 }
 
+static int macvlan_fdb_add(struct ndmsg *ndm,
+                          struct net_device *dev,
+                          unsigned char *addr,
+                          u16 flags)
+{
+       struct macvlan_dev *vlan = netdev_priv(dev);
+       int err = -EINVAL;
+
+       if (!vlan->port->passthru)
+               return -EOPNOTSUPP;
+
+       if (is_unicast_ether_addr(addr))
+               err = dev_uc_add_excl(dev, addr);
+       else if (is_multicast_ether_addr(addr))
+               err = dev_mc_add_excl(dev, addr);
+
+       return err;
+}
+
+static int macvlan_fdb_del(struct ndmsg *ndm,
+                          struct net_device *dev,
+                          unsigned char *addr)
+{
+       struct macvlan_dev *vlan = netdev_priv(dev);
+       int err = -EINVAL;
+
+       if (!vlan->port->passthru)
+               return -EOPNOTSUPP;
+
+       if (is_unicast_ether_addr(addr))
+               err = dev_uc_del(dev, addr);
+       else if (is_multicast_ether_addr(addr))
+               err = dev_mc_del(dev, addr);
+
+       return err;
+}
+
 static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
                                        struct ethtool_drvinfo *drvinfo)
 {
        .ndo_change_mtu         = macvlan_change_mtu,
        .ndo_change_rx_flags    = macvlan_change_rx_flags,
        .ndo_set_mac_address    = macvlan_set_mac_address,
-       .ndo_set_rx_mode        = macvlan_set_multicast_list,
+       .ndo_set_rx_mode        = macvlan_set_mac_lists,
        .ndo_get_stats64        = macvlan_dev_get_stats64,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_vlan_rx_add_vid    = macvlan_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = macvlan_vlan_rx_kill_vid,
+       .ndo_fdb_add            = macvlan_fdb_add,
+       .ndo_fdb_del            = macvlan_fdb_del,
+       .ndo_fdb_dump           = ndo_dflt_fdb_dump,
 };
 
 void macvlan_common_setup(struct net_device *dev)
        if (data && data[IFLA_MACVLAN_MODE])
                vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
 
+       if (data && data[IFLA_MACVLAN_FLAGS])
+               vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
+
        if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
                if (port->count)
                        return -EINVAL;
        struct macvlan_dev *vlan = netdev_priv(dev);
        if (data && data[IFLA_MACVLAN_MODE])
                vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
+       if (data && data[IFLA_MACVLAN_FLAGS]) {
+               __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
+               bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC;
+
+               if (promisc && (flags & MACVLAN_FLAG_NOPROMISC))
+                       dev_set_promiscuity(vlan->lowerdev, -1);
+               else if (promisc && !(flags & MACVLAN_FLAG_NOPROMISC))
+                       dev_set_promiscuity(vlan->lowerdev, 1);
+               vlan->flags = flags;
+       }
        return 0;
 }
 
 
        if (nla_put_u32(skb, IFLA_MACVLAN_MODE, vlan->mode))
                goto nla_put_failure;
+       if (nla_put_u16(skb, IFLA_MACVLAN_FLAGS, vlan->flags))
+               goto nla_put_failure;
        return 0;
 
 nla_put_failure:
 }
 
 static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
-       [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
+       [IFLA_MACVLAN_MODE]  = { .type = NLA_U32 },
+       [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
 };
 
 int macvlan_link_register(struct rtnl_link_ops *ops)