summaryrefslogtreecommitdiff
path: root/net/8021q
diff options
context:
space:
mode:
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan.c6
-rw-r--r--net/8021q/vlan.h2
-rw-r--r--net/8021q/vlan_core.c16
-rw-r--r--net/8021q/vlan_dev.c13
4 files changed, 25 insertions, 12 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index a2ad15250575..25c21332e9c3 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -321,7 +321,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id)
if (new_dev == NULL)
return -ENOBUFS;
- new_dev->real_num_tx_queues = real_dev->real_num_tx_queues;
+ netif_copy_real_num_queues(new_dev, real_dev);
dev_net_set(new_dev, net);
/* need 4 bytes for extra VLAN header info,
* hope the underlying device can handle it.
@@ -525,6 +525,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
break;
case NETDEV_UNREGISTER:
+ /* twiddle thumbs on netns device moves */
+ if (dev->reg_state != NETREG_UNREGISTERING)
+ break;
+
/* Delete all VLANs for this dev. */
grp->killall = 1;
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h
index 8d9503ad01da..b26ce343072c 100644
--- a/net/8021q/vlan.h
+++ b/net/8021q/vlan.h
@@ -25,6 +25,7 @@ struct vlan_priority_tci_mapping {
* @rx_multicast: number of received multicast packets
* @syncp: synchronization point for 64bit counters
* @rx_errors: number of errors
+ * @rx_dropped: number of dropped packets
*/
struct vlan_rx_stats {
u64 rx_packets;
@@ -32,6 +33,7 @@ struct vlan_rx_stats {
u64 rx_multicast;
struct u64_stats_sync syncp;
unsigned long rx_errors;
+ unsigned long rx_dropped;
};
/**
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 0eb96f7e44be..b6d55a9304f2 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -30,7 +30,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
skb->pkt_type = PACKET_OTHERHOST;
}
- return (polling ? netif_receive_skb(skb) : netif_rx(skb));
+ return polling ? netif_receive_skb(skb) : netif_rx(skb);
drop:
dev_kfree_skb_any(skb);
@@ -38,12 +38,12 @@ drop:
}
EXPORT_SYMBOL(__vlan_hwaccel_rx);
-int vlan_hwaccel_do_receive(struct sk_buff *skb)
+void vlan_hwaccel_do_receive(struct sk_buff *skb)
{
struct net_device *dev = skb->dev;
struct vlan_rx_stats *rx_stats;
- skb->dev = vlan_dev_info(dev)->real_dev;
+ skb->dev = vlan_dev_real_dev(dev);
netif_nit_deliver(skb);
skb->dev = dev;
@@ -72,7 +72,6 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb)
break;
}
u64_stats_update_end(&rx_stats->syncp);
- return 0;
}
struct net_device *vlan_dev_real_dev(const struct net_device *dev)
@@ -112,9 +111,12 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,
}
for (p = napi->gro_list; p; p = p->next) {
- NAPI_GRO_CB(p)->same_flow =
- p->dev == skb->dev && !compare_ether_header(
- skb_mac_header(p), skb_gro_mac_header(skb));
+ unsigned long diffs;
+
+ diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
+ diffs |= compare_ether_header(skb_mac_header(p),
+ skb_gro_mac_header(skb));
+ NAPI_GRO_CB(p)->same_flow = !diffs;
NAPI_GRO_CB(p)->flush = 0;
}
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 3bccdd12a264..f6fbcc0f1af9 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -177,8 +177,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
} else {
skb->dev = vlan_dev;
- rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats,
- smp_processor_id());
+ rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats);
+
u64_stats_update_begin(&rx_stats->syncp);
rx_stats->rx_packets++;
rx_stats->rx_bytes += skb->len;
@@ -225,7 +225,10 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
}
}
- netif_rx(skb);
+ if (unlikely(netif_rx(skb) == NET_RX_DROP)) {
+ if (rx_stats)
+ rx_stats->rx_dropped++;
+ }
rcu_read_unlock();
return NET_RX_SUCCESS;
@@ -843,13 +846,15 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st
accum.rx_packets += rxpackets;
accum.rx_bytes += rxbytes;
accum.rx_multicast += rxmulticast;
- /* rx_errors is an ulong, not protected by syncp */
+ /* rx_errors, rx_dropped are ulong, not protected by syncp */
accum.rx_errors += p->rx_errors;
+ accum.rx_dropped += p->rx_dropped;
}
stats->rx_packets = accum.rx_packets;
stats->rx_bytes = accum.rx_bytes;
stats->rx_errors = accum.rx_errors;
stats->multicast = accum.rx_multicast;
+ stats->rx_dropped = accum.rx_dropped;
}
return stats;
}