Skip to content

Commit

Permalink
vlan: deliver packets received with VLAN acceleration to network taps
Browse files Browse the repository at this point in the history
When VLAN header stripping is used, packets currently bypass packet
sockets (and other network taps) completely. For locally existing
VLANs, they appear directly on the VLAN device, for unknown VLANs
they are silently dropped.

Add a new function netif_nit_deliver() to deliver incoming packets
to all network interface taps and use it in __vlan_hwaccel_rx() to
make VLAN packets visible on the underlying device.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Jul 15, 2008
1 parent 6aa895b commit bc1d041
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/linux/netdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,7 @@ extern int netif_rx(struct sk_buff *skb);
extern int netif_rx_ni(struct sk_buff *skb);
#define HAVE_NETIF_RECEIVE_SKB 1
extern int netif_receive_skb(struct sk_buff *skb);
extern void netif_nit_deliver(struct sk_buff *skb);
extern int dev_valid_name(const char *name);
extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *);
extern int dev_ethtool(struct net *net, struct ifreq *);
Expand Down
4 changes: 4 additions & 0 deletions net/8021q/vlan_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_RX_DROP;
}

skb->vlan_tci = vlan_tci;
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);
Expand All @@ -22,6 +25,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,
return NET_RX_SUCCESS;
}
skb->dev->last_rx = jiffies;
skb->vlan_tci = 0;

stats = &skb->dev->stats;
stats->rx_packets++;
Expand Down
27 changes: 27 additions & 0 deletions net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2068,6 +2068,33 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb,
}
#endif

/*
* netif_nit_deliver - deliver received packets to network taps
* @skb: buffer
*
* This function is used to deliver incoming packets to network
* taps. It should be used when the normal netif_receive_skb path
* is bypassed, for example because of VLAN acceleration.
*/
void netif_nit_deliver(struct sk_buff *skb)
{
struct packet_type *ptype;

if (list_empty(&ptype_all))
return;

skb_reset_network_header(skb);
skb_reset_transport_header(skb);
skb->mac_len = skb->network_header - skb->mac_header;

rcu_read_lock();
list_for_each_entry_rcu(ptype, &ptype_all, list) {
if (!ptype->dev || ptype->dev == skb->dev)
deliver_skb(skb, ptype, skb->dev);
}
rcu_read_unlock();
}

/**
* netif_receive_skb - process receive buffer from network
* @skb: buffer to process
Expand Down

0 comments on commit bc1d041

Please sign in to comment.