atm: [br2864] fix routed vcmux support
From: Eric Kinzie <ekinzie@cmf.nrl.navy.mil> Signed-off-by: Chas Williams <chas@cmf.nrl.navy.mil> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
059e3779b5
commit
7e903c2ae3
@@ -188,10 +188,13 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else { /* e_vc */
|
||||||
skb_push(skb, 2);
|
if (brdev->payload == p_bridged) {
|
||||||
if (brdev->payload == p_bridged)
|
skb_push(skb, 2);
|
||||||
memset(skb->data, 0, 2);
|
memset(skb->data, 0, 2);
|
||||||
|
} else { /* p_routed */
|
||||||
|
skb_pull(skb, ETH_HLEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
skb_debug(skb);
|
skb_debug(skb);
|
||||||
|
|
||||||
@@ -377,11 +380,8 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
|
|||||||
(skb->data + 6, ethertype_ipv4,
|
(skb->data + 6, ethertype_ipv4,
|
||||||
sizeof(ethertype_ipv4)) == 0)
|
sizeof(ethertype_ipv4)) == 0)
|
||||||
skb->protocol = __constant_htons(ETH_P_IP);
|
skb->protocol = __constant_htons(ETH_P_IP);
|
||||||
else {
|
else
|
||||||
brdev->stats.rx_errors++;
|
goto error;
|
||||||
dev_kfree_skb(skb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
skb_pull(skb, sizeof(llc_oui_ipv4));
|
skb_pull(skb, sizeof(llc_oui_ipv4));
|
||||||
skb_reset_network_header(skb);
|
skb_reset_network_header(skb);
|
||||||
skb->pkt_type = PACKET_HOST;
|
skb->pkt_type = PACKET_HOST;
|
||||||
@@ -394,44 +394,56 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
|
|||||||
(memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
|
(memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
|
||||||
skb_pull(skb, sizeof(llc_oui_pid_pad));
|
skb_pull(skb, sizeof(llc_oui_pid_pad));
|
||||||
skb->protocol = eth_type_trans(skb, net_dev);
|
skb->protocol = eth_type_trans(skb, net_dev);
|
||||||
} else {
|
} else
|
||||||
brdev->stats.rx_errors++;
|
goto error;
|
||||||
dev_kfree_skb(skb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else { /* e_vc */
|
||||||
/* first 2 chars should be 0 */
|
if (brdev->payload == p_routed) {
|
||||||
if (*((u16 *) (skb->data)) != 0) {
|
struct iphdr *iph;
|
||||||
brdev->stats.rx_errors++;
|
|
||||||
dev_kfree_skb(skb);
|
skb_reset_network_header(skb);
|
||||||
return;
|
iph = ip_hdr(skb);
|
||||||
|
if (iph->version == 4)
|
||||||
|
skb->protocol = __constant_htons(ETH_P_IP);
|
||||||
|
else if (iph->version == 6)
|
||||||
|
skb->protocol = __constant_htons(ETH_P_IPV6);
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
skb->pkt_type = PACKET_HOST;
|
||||||
|
} else { /* p_bridged */
|
||||||
|
/* first 2 chars should be 0 */
|
||||||
|
if (*((u16 *) (skb->data)) != 0)
|
||||||
|
goto error;
|
||||||
|
skb_pull(skb, BR2684_PAD_LEN);
|
||||||
|
skb->protocol = eth_type_trans(skb, net_dev);
|
||||||
}
|
}
|
||||||
skb_pull(skb, BR2684_PAD_LEN + ETH_HLEN); /* pad, dstmac, srcmac, ethtype */
|
|
||||||
skb->protocol = eth_type_trans(skb, net_dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ATM_BR2684_IPFILTER
|
#ifdef CONFIG_ATM_BR2684_IPFILTER
|
||||||
if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) {
|
if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb)))
|
||||||
brdev->stats.rx_dropped++;
|
goto dropped;
|
||||||
dev_kfree_skb(skb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_ATM_BR2684_IPFILTER */
|
#endif /* CONFIG_ATM_BR2684_IPFILTER */
|
||||||
skb->dev = net_dev;
|
skb->dev = net_dev;
|
||||||
ATM_SKB(skb)->vcc = atmvcc; /* needed ? */
|
ATM_SKB(skb)->vcc = atmvcc; /* needed ? */
|
||||||
pr_debug("received packet's protocol: %x\n", ntohs(skb->protocol));
|
pr_debug("received packet's protocol: %x\n", ntohs(skb->protocol));
|
||||||
skb_debug(skb);
|
skb_debug(skb);
|
||||||
if (unlikely(!(net_dev->flags & IFF_UP))) {
|
/* sigh, interface is down? */
|
||||||
/* sigh, interface is down */
|
if (unlikely(!(net_dev->flags & IFF_UP)))
|
||||||
brdev->stats.rx_dropped++;
|
goto dropped;
|
||||||
dev_kfree_skb(skb);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
brdev->stats.rx_packets++;
|
brdev->stats.rx_packets++;
|
||||||
brdev->stats.rx_bytes += skb->len;
|
brdev->stats.rx_bytes += skb->len;
|
||||||
memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
|
memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
|
||||||
netif_rx(skb);
|
netif_rx(skb);
|
||||||
|
return;
|
||||||
|
|
||||||
|
dropped:
|
||||||
|
brdev->stats.rx_dropped++;
|
||||||
|
goto free_skb;
|
||||||
|
error:
|
||||||
|
brdev->stats.rx_errors++;
|
||||||
|
free_skb:
|
||||||
|
dev_kfree_skb(skb);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user