diff options
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | net/8021q/vlan_core.c | 4 | ||||
-rw-r--r-- | net/core/dev.c | 27 |
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); | |||
1165 | extern int netif_rx_ni(struct sk_buff *skb); | 1165 | extern int netif_rx_ni(struct sk_buff *skb); |
1166 | #define HAVE_NETIF_RECEIVE_SKB 1 | 1166 | #define HAVE_NETIF_RECEIVE_SKB 1 |
1167 | extern int netif_receive_skb(struct sk_buff *skb); | 1167 | extern int netif_receive_skb(struct sk_buff *skb); |
1168 | extern void netif_nit_deliver(struct sk_buff *skb); | ||
1168 | extern int dev_valid_name(const char *name); | 1169 | extern int dev_valid_name(const char *name); |
1169 | extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); | 1170 | extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); |
1170 | extern int dev_ethtool(struct net *net, struct ifreq *); | 1171 | extern 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 | */ | ||
2079 | void 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 |