diff options
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r-- | drivers/net/macvlan.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 99eed9f37c8..3aabfd9dd21 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -54,7 +54,7 @@ static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, struct hlist_node *n; hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[addr[5]], hlist) { - if (!compare_ether_addr(vlan->dev->dev_addr, addr)) + if (!compare_ether_addr_64bits(vlan->dev->dev_addr, addr)) return vlan; } return NULL; @@ -92,7 +92,7 @@ static int macvlan_addr_busy(const struct macvlan_port *port, * currently in use by the underlying device or * another macvlan. */ - if (memcmp(port->dev->dev_addr, addr, ETH_ALEN) == 0) + if (!compare_ether_addr_64bits(port->dev->dev_addr, addr)) return 1; if (macvlan_hash_lookup(port, addr)) @@ -130,7 +130,7 @@ static void macvlan_broadcast(struct sk_buff *skb, dev->stats.multicast++; nskb->dev = dev; - if (!compare_ether_addr(eth->h_dest, dev->broadcast)) + if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast)) nskb->pkt_type = PACKET_BROADCAST; else nskb->pkt_type = PACKET_MULTICAST; @@ -184,8 +184,11 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) return NULL; } -static int macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, + struct net_device *dev) { + int i = skb_get_queue_mapping(skb); + struct netdev_queue *txq = netdev_get_tx_queue(dev, i); const struct macvlan_dev *vlan = netdev_priv(dev); unsigned int len = skb->len; int ret; @@ -194,12 +197,11 @@ static int macvlan_start_xmit(struct sk_buff *skb, struct net_device *dev) ret = dev_queue_xmit(skb); if (likely(ret == NET_XMIT_SUCCESS)) { - dev->stats.tx_packets++; - dev->stats.tx_bytes += len; - } else { - dev->stats.tx_errors++; - dev->stats.tx_aborted_errors++; - } + txq->tx_packets++; + txq->tx_bytes += len; + } else + txq->tx_dropped++; + return NETDEV_TX_OK; } @@ -483,6 +485,25 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) return 0; } +static int macvlan_get_tx_queues(struct net *net, + struct nlattr *tb[], + unsigned int *num_tx_queues, + unsigned int *real_num_tx_queues) +{ + struct net_device *real_dev; + + if (!tb[IFLA_LINK]) + return -EINVAL; + + real_dev = __dev_get_by_index(net, nla_get_u32(tb[IFLA_LINK])); + if (!real_dev) + return -ENODEV; + + *num_tx_queues = real_dev->num_tx_queues; + *real_num_tx_queues = real_dev->real_num_tx_queues; + return 0; +} + static int macvlan_newlink(struct net_device *dev, struct nlattr *tb[], struct nlattr *data[]) { @@ -549,6 +570,7 @@ static void macvlan_dellink(struct net_device *dev) static struct rtnl_link_ops macvlan_link_ops __read_mostly = { .kind = "macvlan", .priv_size = sizeof(struct macvlan_dev), + .get_tx_queues = macvlan_get_tx_queues, .setup = macvlan_setup, .validate = macvlan_validate, .newlink = macvlan_newlink, |