aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--net/8021q/vlan_core.c4
-rw-r--r--net/core/dev.c27
3 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index b54ec16dfbda..ba5c4639ea91 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1165,6 +1165,7 @@ extern int netif_rx(struct sk_buff *skb);
1165extern int netif_rx_ni(struct sk_buff *skb); 1165extern int netif_rx_ni(struct sk_buff *skb);
1166#define HAVE_NETIF_RECEIVE_SKB 1 1166#define HAVE_NETIF_RECEIVE_SKB 1
1167extern int netif_receive_skb(struct sk_buff *skb); 1167extern int netif_receive_skb(struct sk_buff *skb);
1168extern void netif_nit_deliver(struct sk_buff *skb);
1168extern int dev_valid_name(const char *name); 1169extern int dev_valid_name(const char *name);
1169extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); 1170extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
1170extern int dev_ethtool(struct net *net, struct ifreq *); 1171extern int dev_ethtool(struct net *net, struct ifreq *);
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c
index 68df12d3664b..916061f681b6 100644
--- a/net/8021q/vlan_core.c
+++ b/net/8021q/vlan_core.c
@@ -14,6 +14,9 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
14 return NET_RX_DROP; 14 return NET_RX_DROP;
15 } 15 }
16 16
17 skb->vlan_tci = vlan_tci;
18 netif_nit_deliver(skb);
19
17 skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK); 20 skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
18 if (skb->dev == NULL) { 21 if (skb->dev == NULL) {
19 dev_kfree_skb_any(skb); 22 dev_kfree_skb_any(skb);
@@ -22,6 +25,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
22 return NET_RX_SUCCESS; 25 return NET_RX_SUCCESS;
23 } 26 }
24 skb->dev->last_rx = jiffies; 27 skb->dev->last_rx = jiffies;
28 skb->vlan_tci = 0;
25 29
26 stats = &skb->dev->stats; 30 stats = &skb->dev->stats;
27 stats->rx_packets++; 31 stats->rx_packets++;
diff --git a/net/core/dev.c b/net/core/dev.c
index a29a359b15d1..feaab4898a5b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2068,6 +2068,33 @@ out:
2068} 2068}
2069#endif 2069#endif
2070 2070
2071/*
2072 * netif_nit_deliver - deliver received packets to network taps
2073 * @skb: buffer
2074 *
2075 * This function is used to deliver incoming packets to network
2076 * taps. It should be used when the normal netif_receive_skb path
2077 * is bypassed, for example because of VLAN acceleration.
2078 */
2079void netif_nit_deliver(struct sk_buff *skb)
2080{
2081 struct packet_type *ptype;
2082
2083 if (list_empty(&ptype_all))
2084 return;
2085
2086 skb_reset_network_header(skb);
2087 skb_reset_transport_header(skb);
2088 skb->mac_len = skb->network_header - skb->mac_header;
2089
2090 rcu_read_lock();
2091 list_for_each_entry_rcu(ptype, &ptype_all, list) {
2092 if (!ptype->dev || ptype->dev == skb->dev)
2093 deliver_skb(skb, ptype, skb->dev);
2094 }
2095 rcu_read_unlock();
2096}
2097
2071/** 2098/**
2072 * netif_receive_skb - process receive buffer from network 2099 * netif_receive_skb - process receive buffer from network
2073 * @skb: buffer to process 2100 * @skb: buffer to process