Commit 31ffdbcb authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[VLAN]: Clean up vlan_skb_recv()

- remove three instances of identical code
- remove unnecessary NULL initialization
- remove obvious and unnecessary comments
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ad712087
...@@ -114,77 +114,49 @@ static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb) ...@@ -114,77 +114,49 @@ static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype, struct net_device *orig_dev) struct packet_type *ptype, struct net_device *orig_dev)
{ {
unsigned char *rawp = NULL; unsigned char *rawp;
struct vlan_hdr *vhdr; struct vlan_hdr *vhdr;
unsigned short vid; unsigned short vid;
struct net_device_stats *stats; struct net_device_stats *stats;
unsigned short vlan_TCI; unsigned short vlan_TCI;
__be16 proto; __be16 proto;
if (dev->nd_net != &init_net) { if (dev->nd_net != &init_net)
kfree_skb(skb); goto err_free;
return -1;
}
skb = skb_share_check(skb, GFP_ATOMIC); skb = skb_share_check(skb, GFP_ATOMIC);
if (skb == NULL) if (skb == NULL)
return -1; goto err_free;
if (unlikely(!pskb_may_pull(skb, VLAN_HLEN))) {
kfree_skb(skb);
return -1;
}
vhdr = (struct vlan_hdr *)(skb->data); if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
goto err_free;
/* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */ vhdr = (struct vlan_hdr *)skb->data;
vlan_TCI = ntohs(vhdr->h_vlan_TCI); vlan_TCI = ntohs(vhdr->h_vlan_TCI);
vid = (vlan_TCI & VLAN_VID_MASK); vid = (vlan_TCI & VLAN_VID_MASK);
/* Ok, we will find the correct VLAN device, strip the header,
* and then go on as usual.
*/
/* We have 12 bits of vlan ID.
*
* We must not drop allow preempt until we hold a
* reference to the device (netif_rx does that) or we
* fail.
*/
rcu_read_lock(); rcu_read_lock();
skb->dev = __find_vlan_dev(dev, vid); skb->dev = __find_vlan_dev(dev, vid);
if (!skb->dev) { if (!skb->dev) {
rcu_read_unlock();
pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n", pr_debug("%s: ERROR: No net_device for VID: %u on dev: %s\n",
__FUNCTION__, (unsigned int)vid, dev->name); __FUNCTION__, (unsigned int)vid, dev->name);
kfree_skb(skb); goto err_unlock;
return -1;
} }
skb->dev->last_rx = jiffies; skb->dev->last_rx = jiffies;
/* Bump the rx counters for the VLAN device. */
stats = &skb->dev->stats; stats = &skb->dev->stats;
stats->rx_packets++; stats->rx_packets++;
stats->rx_bytes += skb->len; stats->rx_bytes += skb->len;
/* Take off the VLAN header (4 bytes currently) */
skb_pull_rcsum(skb, VLAN_HLEN); skb_pull_rcsum(skb, VLAN_HLEN);
/*
* Deal with ingress priority mapping.
*/
skb->priority = vlan_get_ingress_priority(skb->dev, skb->priority = vlan_get_ingress_priority(skb->dev,
ntohs(vhdr->h_vlan_TCI)); ntohs(vhdr->h_vlan_TCI));
pr_debug("%s: priority: %u for TCI: %hu\n", pr_debug("%s: priority: %u for TCI: %hu\n",
__FUNCTION__, skb->priority, ntohs(vhdr->h_vlan_TCI)); __FUNCTION__, skb->priority, ntohs(vhdr->h_vlan_TCI));
/* The ethernet driver already did the pkt_type calculations
* for us...
*/
switch (skb->pkt_type) { switch (skb->pkt_type) {
case PACKET_BROADCAST: /* Yeah, stats collect these together.. */ case PACKET_BROADCAST: /* Yeah, stats collect these together.. */
/* stats->broadcast ++; // no such counter :-( */ /* stats->broadcast ++; // no such counter :-( */
...@@ -201,7 +173,6 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, ...@@ -201,7 +173,6 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
*/ */
if (!compare_ether_addr(eth_hdr(skb)->h_dest, if (!compare_ether_addr(eth_hdr(skb)->h_dest,
skb->dev->dev_addr)) skb->dev->dev_addr))
/* It is for our (changed) MAC-address! */
skb->pkt_type = PACKET_HOST; skb->pkt_type = PACKET_HOST;
break; break;
default: default:
...@@ -211,81 +182,45 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, ...@@ -211,81 +182,45 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
/* Was a VLAN packet, grab the encapsulated protocol, which the layer /* Was a VLAN packet, grab the encapsulated protocol, which the layer
* three protocols care about. * three protocols care about.
*/ */
/* proto = get_unaligned(&vhdr->h_vlan_encapsulated_proto); */
proto = vhdr->h_vlan_encapsulated_proto; proto = vhdr->h_vlan_encapsulated_proto;
skb->protocol = proto;
if (ntohs(proto) >= 1536) { if (ntohs(proto) >= 1536) {
/* place it back on the queue to be handled by skb->protocol = proto;
* true layer 3 protocols. goto recv;
*/
/* See if we are configured to re-write the VLAN header
* to make it look like ethernet...
*/
skb = vlan_check_reorder_header(skb);
/* Can be null if skb-clone fails when re-ordering */
if (skb) {
netif_rx(skb);
} else {
/* TODO: Add a more specific counter here. */
stats->rx_errors++;
}
rcu_read_unlock();
return 0;
} }
rawp = skb->data;
/* /*
* This is a magic hack to spot IPX packets. Older Novell breaks * This is a magic hack to spot IPX packets. Older Novell breaks
* the protocol design and runs IPX over 802.3 without an 802.2 LLC * the protocol design and runs IPX over 802.3 without an 802.2 LLC
* layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
* won't work for fault tolerant netware but does for the rest. * won't work for fault tolerant netware but does for the rest.
*/ */
rawp = skb->data;
if (*(unsigned short *)rawp == 0xFFFF) { if (*(unsigned short *)rawp == 0xFFFF) {
skb->protocol = htons(ETH_P_802_3); skb->protocol = htons(ETH_P_802_3);
/* place it back on the queue to be handled by true layer 3 goto recv;
* protocols. */
/* See if we are configured to re-write the VLAN header
* to make it look like ethernet...
*/
skb = vlan_check_reorder_header(skb);
/* Can be null if skb-clone fails when re-ordering */
if (skb) {
netif_rx(skb);
} else {
/* TODO: Add a more specific counter here. */
stats->rx_errors++;
}
rcu_read_unlock();
return 0;
} }
/* /*
* Real 802.2 LLC * Real 802.2 LLC
*/ */
skb->protocol = htons(ETH_P_802_2); skb->protocol = htons(ETH_P_802_2);
/* place it back on the queue to be handled by upper layer protocols.
*/
/* See if we are configured to re-write the VLAN header recv:
* to make it look like ethernet...
*/
skb = vlan_check_reorder_header(skb); skb = vlan_check_reorder_header(skb);
if (!skb) {
/* Can be null if skb-clone fails when re-ordering */
if (skb) {
netif_rx(skb);
} else {
/* TODO: Add a more specific counter here. */
stats->rx_errors++; stats->rx_errors++;
goto err_unlock;
} }
netif_rx(skb);
rcu_read_unlock(); rcu_read_unlock();
return 0; return NET_RX_SUCCESS;
err_unlock:
rcu_read_unlock();
err_free:
kfree_skb(skb);
return NET_RX_DROP;
} }
static inline unsigned short static inline unsigned short
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment