Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 171608
b: refs/heads/master
c: fccaf71
h: refs/heads/master
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Nov 18, 2009
1 parent 2ec250d commit 5a76764
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 11 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: 9793241fe92f7d9303fb221e43fc598eb065f267
refs/heads/master: fccaf71011b171883efee5bae321eac4760584d1
76 changes: 66 additions & 10 deletions trunk/drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,27 @@ struct macvlan_port {
struct list_head vlans;
};

/**
* struct macvlan_rx_stats - MACVLAN percpu rx stats
* @rx_packets: number of received packets
* @rx_bytes: number of received bytes
* @multicast: number of received multicast packets
* @rx_errors: number of errors
*/
struct macvlan_rx_stats {
unsigned long rx_packets;
unsigned long rx_bytes;
unsigned long multicast;
unsigned long rx_errors;
};

struct macvlan_dev {
struct net_device *dev;
struct list_head list;
struct hlist_node hlist;
struct macvlan_port *port;
struct net_device *lowerdev;
struct macvlan_rx_stats *rx_stats;
};


Expand Down Expand Up @@ -110,24 +125,25 @@ static void macvlan_broadcast(struct sk_buff *skb,
struct net_device *dev;
struct sk_buff *nskb;
unsigned int i;
struct macvlan_rx_stats *rx_stats;

if (skb->protocol == htons(ETH_P_PAUSE))
return;

for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
hlist_for_each_entry_rcu(vlan, n, &port->vlan_hash[i], hlist) {
dev = vlan->dev;
rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());

nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb == NULL) {
dev->stats.rx_errors++;
dev->stats.rx_dropped++;
rx_stats->rx_errors++;
continue;
}

dev->stats.rx_bytes += skb->len + ETH_HLEN;
dev->stats.rx_packets++;
dev->stats.multicast++;
rx_stats->rx_bytes += skb->len + ETH_HLEN;
rx_stats->rx_packets++;
rx_stats->multicast++;

nskb->dev = dev;
if (!compare_ether_addr_64bits(eth->h_dest, dev->broadcast))
Expand All @@ -147,6 +163,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
const struct macvlan_port *port;
const struct macvlan_dev *vlan;
struct net_device *dev;
struct macvlan_rx_stats *rx_stats;

port = rcu_dereference(skb->dev->macvlan_port);
if (port == NULL)
Expand All @@ -166,16 +183,15 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
kfree_skb(skb);
return NULL;
}

rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
skb = skb_share_check(skb, GFP_ATOMIC);
if (skb == NULL) {
dev->stats.rx_errors++;
dev->stats.rx_dropped++;
rx_stats->rx_errors++;
return NULL;
}

dev->stats.rx_bytes += skb->len + ETH_HLEN;
dev->stats.rx_packets++;
rx_stats->rx_bytes += skb->len + ETH_HLEN;
rx_stats->rx_packets++;

skb->dev = dev;
skb->pkt_type = PACKET_HOST;
Expand Down Expand Up @@ -365,9 +381,47 @@ static int macvlan_init(struct net_device *dev)

macvlan_set_lockdep_class(dev);

vlan->rx_stats = alloc_percpu(struct macvlan_rx_stats);
if (!vlan->rx_stats)
return -ENOMEM;

return 0;
}

static void macvlan_uninit(struct net_device *dev)
{
struct macvlan_dev *vlan = netdev_priv(dev);

free_percpu(vlan->rx_stats);
}

static struct net_device_stats *macvlan_dev_get_stats(struct net_device *dev)
{
struct net_device_stats *stats = &dev->stats;
struct macvlan_dev *vlan = netdev_priv(dev);

dev_txq_stats_fold(dev, stats);

if (vlan->rx_stats) {
struct macvlan_rx_stats *p, rx = {0};
int i;

for_each_possible_cpu(i) {
p = per_cpu_ptr(vlan->rx_stats, i);
rx.rx_packets += p->rx_packets;
rx.rx_bytes += p->rx_bytes;
rx.rx_errors += p->rx_errors;
rx.multicast += p->multicast;
}
stats->rx_packets = rx.rx_packets;
stats->rx_bytes = rx.rx_bytes;
stats->rx_errors = rx.rx_errors;
stats->rx_dropped = rx.rx_errors;
stats->multicast = rx.multicast;
}
return stats;
}

static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *drvinfo)
{
Expand Down Expand Up @@ -404,13 +458,15 @@ static const struct ethtool_ops macvlan_ethtool_ops = {

static const struct net_device_ops macvlan_netdev_ops = {
.ndo_init = macvlan_init,
.ndo_uninit = macvlan_uninit,
.ndo_open = macvlan_open,
.ndo_stop = macvlan_stop,
.ndo_start_xmit = macvlan_start_xmit,
.ndo_change_mtu = macvlan_change_mtu,
.ndo_change_rx_flags = macvlan_change_rx_flags,
.ndo_set_mac_address = macvlan_set_mac_address,
.ndo_set_multicast_list = macvlan_set_multicast_list,
.ndo_get_stats = macvlan_dev_get_stats,
.ndo_validate_addr = eth_validate_addr,
};

Expand Down

0 comments on commit 5a76764

Please sign in to comment.