Skip to content

Commit

Permalink
vlan: Avoid hwaccel vlan packets when vid not used.
Browse files Browse the repository at this point in the history
[This patch applies only to 2.6.36 stable.  The problem was introduced
in that release and is already fixed by larger changes to the vlan
code in 2.6.37.]

Normally hardware accelerated vlan packets are quickly dropped if
there is no corresponding vlan device configured.  The one exception
is promiscuous mode, where we allow all of these packets through so
they can be picked up by tcpdump.  However, this behavior causes a
crash if we actually try to receive these packets.  This fixes that
crash by ignoring packets with vids not corresponding to a configured
device in the vlan hwaccel routines and then dropping them before they
get to consumers in the network stack.


Reported-by: Ben Greear <greearb@candelatech.com>
Tested-by: Nikola Ciprich <extmaillist@linuxbox.cz>
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: David Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
jessegross authored and gregkh committed Dec 9, 2010
1 parent 70d5f4e commit 1b7cd15
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
3 changes: 3 additions & 0 deletions net/8021q/vlan_core.c
Expand Up @@ -43,6 +43,9 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb)
struct net_device *dev = skb->dev;
struct vlan_rx_stats *rx_stats;

if (unlikely(!is_vlan_dev(dev)))
return 0;

skb->dev = vlan_dev_info(dev)->real_dev;
netif_nit_deliver(skb);

Expand Down
10 changes: 10 additions & 0 deletions net/core/dev.c
Expand Up @@ -2891,6 +2891,15 @@ static int __netif_receive_skb(struct sk_buff *skb)
ncls:
#endif

/* If we got this far with a hardware accelerated VLAN tag, it means
* that we were put in promiscuous mode but nobody is interested in
* this vid. Drop the packet now to prevent it from getting propagated
* to other parts of the stack that won't know how to deal with packets
* tagged in this manner.
*/
if (unlikely(vlan_tx_tag_present(skb)))
goto bypass;

/* Handle special case of bridge or macvlan */
rx_handler = rcu_dereference(skb->dev->rx_handler);
if (rx_handler) {
Expand Down Expand Up @@ -2927,6 +2936,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
}
}

bypass:
if (pt_prev) {
ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
} else {
Expand Down

0 comments on commit 1b7cd15

Please sign in to comment.