Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 300777
b: refs/heads/master
c: df8ef8f
h: refs/heads/master
i:
  300775: 5a0055d
v: v3
  • Loading branch information
John Fastabend authored and David S. Miller committed Apr 15, 2012
1 parent 0e6b9df commit b9dc5ca
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2b2027124ff1bc420d4a86e37a57feae5e356d2d
refs/heads/master: df8ef8f3aaa6692970a436204c4429210addb23a
73 changes: 67 additions & 6 deletions trunk/drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,8 @@ static int macvlan_open(struct net_device *dev)
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;
}

Expand Down Expand Up @@ -344,12 +345,15 @@ static int macvlan_stop(struct net_device *dev)
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);

Expand Down Expand Up @@ -399,10 +403,11 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change)
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);
}

Expand Down Expand Up @@ -542,6 +547,43 @@ static int macvlan_vlan_rx_kill_vid(struct net_device *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)
{
Expand Down Expand Up @@ -572,11 +614,14 @@ static const struct net_device_ops macvlan_netdev_ops = {
.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)
Expand Down Expand Up @@ -711,6 +756,9 @@ int macvlan_common_newlink(struct net *src_net, 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;
Expand Down Expand Up @@ -760,6 +808,16 @@ static int macvlan_changelink(struct net_device *dev,
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;
}

Expand All @@ -775,14 +833,17 @@ static int macvlan_fill_info(struct sk_buff *skb,

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:
return -EMSGSIZE;
}

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)
Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ struct ifla_vlan_qos_mapping {
enum {
IFLA_MACVLAN_UNSPEC,
IFLA_MACVLAN_MODE,
IFLA_MACVLAN_FLAGS,
__IFLA_MACVLAN_MAX,
};

Expand All @@ -267,6 +268,8 @@ enum macvlan_mode {
MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
};

#define MACVLAN_FLAG_NOPROMISC 1

/* SR-IOV virtual function management section */

enum {
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/if_macvlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct macvlan_dev {
struct net_device *lowerdev;
struct macvlan_pcpu_stats __percpu *pcpu_stats;
enum macvlan_mode mode;
u16 flags;
int (*receive)(struct sk_buff *skb);
int (*forward)(struct net_device *dev, struct sk_buff *skb);
struct macvtap_queue *taps[MAX_MACVTAP_QUEUES];
Expand Down

0 comments on commit b9dc5ca

Please sign in to comment.