summaryrefslogtreecommitdiff
path: root/drivers/net/macvlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r--drivers/net/macvlan.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 958df383068a..a96955597755 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -45,10 +45,9 @@ struct macvlan_port {
struct sk_buff_head bc_queue;
struct work_struct bc_work;
bool passthru;
+ int count;
};
-#define MACVLAN_PORT_IS_EMPTY(port) list_empty(&port->vlans)
-
struct macvlan_skb_cb {
const struct macvlan_dev *src;
};
@@ -646,6 +645,7 @@ static int macvlan_init(struct net_device *dev)
(lowerdev->state & MACVLAN_STATE_MASK);
dev->features = lowerdev->features & MACVLAN_FEATURES;
dev->features |= ALWAYS_ON_FEATURES;
+ dev->vlan_features = lowerdev->vlan_features & MACVLAN_FEATURES;
dev->gso_max_size = lowerdev->gso_max_size;
dev->iflink = lowerdev->ifindex;
dev->hard_header_len = lowerdev->hard_header_len;
@@ -666,7 +666,8 @@ static void macvlan_uninit(struct net_device *dev)
free_percpu(vlan->pcpu_stats);
- if (MACVLAN_PORT_IS_EMPTY(port))
+ port->count -= 1;
+ if (!port->count)
macvlan_port_destroy(port->dev);
}
@@ -738,7 +739,10 @@ static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
struct macvlan_dev *vlan = netdev_priv(dev);
int err = -EINVAL;
- if (!vlan->port->passthru)
+ /* Support unicast filter only on passthru devices.
+ * Multicast filter should be allowed on all devices.
+ */
+ if (!vlan->port->passthru && is_unicast_ether_addr(addr))
return -EOPNOTSUPP;
if (flags & NLM_F_REPLACE)
@@ -759,7 +763,10 @@ static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
struct macvlan_dev *vlan = netdev_priv(dev);
int err = -EINVAL;
- if (!vlan->port->passthru)
+ /* Support unicast filter only on passthru devices.
+ * Multicast filter should be allowed on all devices.
+ */
+ if (!vlan->port->passthru && is_unicast_ether_addr(addr))
return -EOPNOTSUPP;
if (is_unicast_ether_addr(addr))
@@ -1019,12 +1026,13 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
- if (!MACVLAN_PORT_IS_EMPTY(port))
+ if (port->count)
return -EINVAL;
port->passthru = true;
eth_hw_addr_inherit(dev, lowerdev);
}
+ port->count += 1;
err = register_netdevice(dev);
if (err < 0)
goto destroy_port;
@@ -1042,7 +1050,8 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
unregister_netdev:
unregister_netdevice(dev);
destroy_port:
- if (MACVLAN_PORT_IS_EMPTY(port))
+ port->count -= 1;
+ if (!port->count)
macvlan_port_destroy(lowerdev);
return err;