diff options
author | Amerigo Wang <amwang@redhat.com> | 2012-08-09 21:24:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-14 17:33:32 -0400 |
commit | 689971b44613883ee74ae9c1b31a864aaa3a8e17 (patch) | |
tree | 1c0544b1a44a4ba5f05461c697b565f67121b344 /net/core | |
parent | 6eacf8ad8d01c49b95b994b0bf379db2b5b29460 (diff) |
netpoll: handle vlan tags in netpoll tx and rx path
Without this patch, I can't get netconsole logs remotely over
vlan. The reason is probably we don't handle vlan tags in either
netpoll tx or rx path.
I am not sure if I use these vlan functions correctly, at
least this patch works.
Cc: Benjamin LaHaise <bcrl@kvack.org>
Cc: Patrick McHardy <kaber@trash.net>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/netpoll.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 174346ac15a0..e4ba3e70c174 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/export.h> | 28 | #include <linux/export.h> |
29 | #include <linux/if_vlan.h> | ||
29 | #include <net/tcp.h> | 30 | #include <net/tcp.h> |
30 | #include <net/udp.h> | 31 | #include <net/udp.h> |
31 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
@@ -334,6 +335,14 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
334 | tries > 0; --tries) { | 335 | tries > 0; --tries) { |
335 | if (__netif_tx_trylock(txq)) { | 336 | if (__netif_tx_trylock(txq)) { |
336 | if (!netif_xmit_stopped(txq)) { | 337 | if (!netif_xmit_stopped(txq)) { |
338 | if (vlan_tx_tag_present(skb) && | ||
339 | !(netif_skb_features(skb) & NETIF_F_HW_VLAN_TX)) { | ||
340 | skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); | ||
341 | if (unlikely(!skb)) | ||
342 | break; | ||
343 | skb->vlan_tci = 0; | ||
344 | } | ||
345 | |||
337 | status = ops->ndo_start_xmit(skb, dev); | 346 | status = ops->ndo_start_xmit(skb, dev); |
338 | if (status == NETDEV_TX_OK) | 347 | if (status == NETDEV_TX_OK) |
339 | txq_trans_update(txq); | 348 | txq_trans_update(txq); |
@@ -567,6 +576,12 @@ int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo) | |||
567 | return 1; | 576 | return 1; |
568 | } | 577 | } |
569 | 578 | ||
579 | if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { | ||
580 | skb = vlan_untag(skb); | ||
581 | if (unlikely(!skb)) | ||
582 | goto out; | ||
583 | } | ||
584 | |||
570 | proto = ntohs(eth_hdr(skb)->h_proto); | 585 | proto = ntohs(eth_hdr(skb)->h_proto); |
571 | if (proto != ETH_P_IP) | 586 | if (proto != ETH_P_IP) |
572 | goto out; | 587 | goto out; |