Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 118542
b: refs/heads/master
c: 9b22ea5
h: refs/heads/master
v: v3
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Nov 4, 2008
1 parent 3d5f877 commit 2b13e8c
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 79654a7698195fa043063092f5c1ca5245276fba
refs/heads/master: 9b22ea560957de1484e6b3e8538f7eef202e3596
7 changes: 7 additions & 0 deletions trunk/include/linux/if_vlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev);

extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
u16 vlan_tci, int polling);
extern int vlan_hwaccel_do_receive(struct sk_buff *skb);

#else
static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
{
Expand All @@ -133,6 +135,11 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
BUG();
return NET_XMIT_SUCCESS;
}

static inline int vlan_hwaccel_do_receive(struct sk_buff *skb)
{
return 0;
}
#endif

/**
Expand Down
46 changes: 33 additions & 13 deletions trunk/net/8021q/vlan_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,56 @@
#include <linux/if_vlan.h>
#include "vlan.h"

struct vlan_hwaccel_cb {
struct net_device *dev;
};

static inline struct vlan_hwaccel_cb *vlan_hwaccel_cb(struct sk_buff *skb)
{
return (struct vlan_hwaccel_cb *)skb->cb;
}

/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */
int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
u16 vlan_tci, int polling)
{
struct net_device_stats *stats;
struct vlan_hwaccel_cb *cb = vlan_hwaccel_cb(skb);

if (skb_bond_should_drop(skb)) {
dev_kfree_skb_any(skb);
return NET_RX_DROP;
}

skb->vlan_tci = vlan_tci;
cb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);

return (polling ? netif_receive_skb(skb) : netif_rx(skb));
}
EXPORT_SYMBOL(__vlan_hwaccel_rx);

int vlan_hwaccel_do_receive(struct sk_buff *skb)
{
struct vlan_hwaccel_cb *cb = vlan_hwaccel_cb(skb);
struct net_device *dev = cb->dev;
struct net_device_stats *stats;

netif_nit_deliver(skb);

skb->dev = vlan_group_get_device(grp, vlan_tci & VLAN_VID_MASK);
if (skb->dev == NULL) {
dev_kfree_skb_any(skb);
/* Not NET_RX_DROP, this is not being dropped
* due to congestion. */
return NET_RX_SUCCESS;
if (dev == NULL) {
kfree_skb(skb);
return -1;
}
skb->dev->last_rx = jiffies;

skb->dev = dev;
skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci);
skb->vlan_tci = 0;

stats = &skb->dev->stats;
dev->last_rx = jiffies;

stats = &dev->stats;
stats->rx_packets++;
stats->rx_bytes += skb->len;

skb->priority = vlan_get_ingress_priority(skb->dev, vlan_tci);
switch (skb->pkt_type) {
case PACKET_BROADCAST:
break;
Expand All @@ -43,13 +64,12 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
* This allows the VLAN to have a different MAC than the
* underlying device, and still route correctly. */
if (!compare_ether_addr(eth_hdr(skb)->h_dest,
skb->dev->dev_addr))
dev->dev_addr))
skb->pkt_type = PACKET_HOST;
break;
};
return (polling ? netif_receive_skb(skb) : netif_rx(skb));
return 0;
}
EXPORT_SYMBOL(__vlan_hwaccel_rx);

struct net_device *vlan_dev_real_dev(const struct net_device *dev)
{
Expand Down
3 changes: 3 additions & 0 deletions trunk/net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2218,6 +2218,9 @@ int netif_receive_skb(struct sk_buff *skb)
int ret = NET_RX_DROP;
__be16 type;

if (skb->vlan_tci && vlan_hwaccel_do_receive(skb))
return NET_RX_SUCCESS;

/* if we've gotten here through NAPI, check netpoll */
if (netpoll_receive_skb(skb))
return NET_RX_DROP;
Expand Down

0 comments on commit 2b13e8c

Please sign in to comment.