Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 224473
b: refs/heads/master
c: eb06acd
h: refs/heads/master
i:
  224471: dfeb548
v: v3
  • Loading branch information
Sridhar Samudrala authored and David S. Miller committed Nov 22, 2010
1 parent 9d51adb commit 7284fb6
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 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: e5700c740da2cb9f5a3aa978cd1fa3a79916ba04
refs/heads/master: eb06acdc85585f28864261f28659157848762ee4
33 changes: 32 additions & 1 deletion trunk/drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ struct macvlan_port {
struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
struct list_head vlans;
struct rcu_head rcu;
bool passthru;
};

#define macvlan_port_get_rcu(dev) \
Expand Down Expand Up @@ -169,6 +170,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
macvlan_broadcast(skb, port, NULL,
MACVLAN_MODE_PRIVATE |
MACVLAN_MODE_VEPA |
MACVLAN_MODE_PASSTHRU|
MACVLAN_MODE_BRIDGE);
else if (src->mode == MACVLAN_MODE_VEPA)
/* flood to everyone except source */
Expand All @@ -185,7 +187,10 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
return skb;
}

vlan = macvlan_hash_lookup(port, eth->h_dest);
if (port->passthru)
vlan = list_first_entry(&port->vlans, struct macvlan_dev, list);
else
vlan = macvlan_hash_lookup(port, eth->h_dest);
if (vlan == NULL)
return skb;

Expand Down Expand Up @@ -288,6 +293,11 @@ static int macvlan_open(struct net_device *dev)
struct net_device *lowerdev = vlan->lowerdev;
int err;

if (vlan->port->passthru) {
dev_set_promiscuity(lowerdev, 1);
goto hash_add;
}

err = -EBUSY;
if (macvlan_addr_busy(vlan->port, dev->dev_addr))
goto out;
Expand All @@ -300,6 +310,8 @@ static int macvlan_open(struct net_device *dev)
if (err < 0)
goto del_unicast;
}

hash_add:
macvlan_hash_add(vlan);
return 0;

Expand All @@ -314,12 +326,18 @@ static int macvlan_stop(struct net_device *dev)
struct macvlan_dev *vlan = netdev_priv(dev);
struct net_device *lowerdev = vlan->lowerdev;

if (vlan->port->passthru) {
dev_set_promiscuity(lowerdev, -1);
goto hash_del;
}

dev_mc_unsync(lowerdev, dev);
if (dev->flags & IFF_ALLMULTI)
dev_set_allmulti(lowerdev, -1);

dev_uc_del(lowerdev, dev->dev_addr);

hash_del:
macvlan_hash_del(vlan);
return 0;
}
Expand Down Expand Up @@ -559,6 +577,7 @@ static int macvlan_port_create(struct net_device *dev)
if (port == NULL)
return -ENOMEM;

port->passthru = false;
port->dev = dev;
INIT_LIST_HEAD(&port->vlans);
for (i = 0; i < MACVLAN_HASH_SIZE; i++)
Expand Down Expand Up @@ -603,6 +622,7 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
case MACVLAN_MODE_PRIVATE:
case MACVLAN_MODE_VEPA:
case MACVLAN_MODE_BRIDGE:
case MACVLAN_MODE_PASSTHRU:
break;
default:
return -EINVAL;
Expand Down Expand Up @@ -652,6 +672,10 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
}
port = macvlan_port_get(lowerdev);

/* Only 1 macvlan device can be created in passthru mode */
if (port->passthru)
return -EINVAL;

vlan->lowerdev = lowerdev;
vlan->dev = dev;
vlan->port = port;
Expand All @@ -662,6 +686,13 @@ 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 (vlan->mode == MACVLAN_MODE_PASSTHRU) {
if (!list_empty(&port->vlans))
return -EINVAL;
port->passthru = true;
memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN);
}

err = register_netdevice(dev);
if (err < 0)
goto destroy_port;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ enum macvlan_mode {
MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
};

/* SR-IOV virtual function management section */
Expand Down

0 comments on commit 7284fb6

Please sign in to comment.