diff options
Diffstat (limited to 'net/atm/lec.c')
| -rw-r--r-- | net/atm/lec.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/net/atm/lec.c b/net/atm/lec.c index a0752487026d..ad840b9afba8 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
| @@ -686,9 +686,19 @@ static unsigned char lec_ctrl_magic[] = { | |||
| 686 | 0x01, | 686 | 0x01, |
| 687 | 0x01 }; | 687 | 0x01 }; |
| 688 | 688 | ||
| 689 | #define LEC_DATA_DIRECT_8023 2 | ||
| 690 | #define LEC_DATA_DIRECT_8025 3 | ||
| 691 | |||
| 692 | static int lec_is_data_direct(struct atm_vcc *vcc) | ||
| 693 | { | ||
| 694 | return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) || | ||
| 695 | (vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025)); | ||
| 696 | } | ||
| 697 | |||
| 689 | static void | 698 | static void |
| 690 | lec_push(struct atm_vcc *vcc, struct sk_buff *skb) | 699 | lec_push(struct atm_vcc *vcc, struct sk_buff *skb) |
| 691 | { | 700 | { |
| 701 | unsigned long flags; | ||
| 692 | struct net_device *dev = (struct net_device *)vcc->proto_data; | 702 | struct net_device *dev = (struct net_device *)vcc->proto_data; |
| 693 | struct lec_priv *priv = (struct lec_priv *)dev->priv; | 703 | struct lec_priv *priv = (struct lec_priv *)dev->priv; |
| 694 | 704 | ||
| @@ -728,7 +738,8 @@ lec_push(struct atm_vcc *vcc, struct sk_buff *skb) | |||
| 728 | skb_queue_tail(&sk->sk_receive_queue, skb); | 738 | skb_queue_tail(&sk->sk_receive_queue, skb); |
| 729 | sk->sk_data_ready(sk, skb->len); | 739 | sk->sk_data_ready(sk, skb->len); |
| 730 | } else { /* Data frame, queue to protocol handlers */ | 740 | } else { /* Data frame, queue to protocol handlers */ |
| 731 | unsigned char *dst; | 741 | struct lec_arp_table *entry; |
| 742 | unsigned char *src, *dst; | ||
| 732 | 743 | ||
| 733 | atm_return(vcc,skb->truesize); | 744 | atm_return(vcc,skb->truesize); |
| 734 | if (*(uint16_t *)skb->data == htons(priv->lecid) || | 745 | if (*(uint16_t *)skb->data == htons(priv->lecid) || |
| @@ -741,10 +752,30 @@ lec_push(struct atm_vcc *vcc, struct sk_buff *skb) | |||
| 741 | return; | 752 | return; |
| 742 | } | 753 | } |
| 743 | #ifdef CONFIG_TR | 754 | #ifdef CONFIG_TR |
| 744 | if (priv->is_trdev) dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest; | 755 | if (priv->is_trdev) |
| 756 | dst = ((struct lecdatahdr_8025 *) skb->data)->h_dest; | ||
| 745 | else | 757 | else |
| 746 | #endif | 758 | #endif |
| 747 | dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; | 759 | dst = ((struct lecdatahdr_8023 *) skb->data)->h_dest; |
| 760 | |||
| 761 | /* If this is a Data Direct VCC, and the VCC does not match | ||
| 762 | * the LE_ARP cache entry, delete the LE_ARP cache entry. | ||
| 763 | */ | ||
| 764 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | ||
| 765 | if (lec_is_data_direct(vcc)) { | ||
| 766 | #ifdef CONFIG_TR | ||
| 767 | if (priv->is_trdev) | ||
| 768 | src = ((struct lecdatahdr_8025 *) skb->data)->h_source; | ||
| 769 | else | ||
| 770 | #endif | ||
| 771 | src = ((struct lecdatahdr_8023 *) skb->data)->h_source; | ||
| 772 | entry = lec_arp_find(priv, src); | ||
| 773 | if (entry && entry->vcc != vcc) { | ||
| 774 | lec_arp_remove(priv, entry); | ||
| 775 | kfree(entry); | ||
| 776 | } | ||
| 777 | } | ||
| 778 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | ||
| 748 | 779 | ||
| 749 | if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */ | 780 | if (!(dst[0]&0x01) && /* Never filter Multi/Broadcast */ |
| 750 | !priv->is_proxy && /* Proxy wants all the packets */ | 781 | !priv->is_proxy && /* Proxy wants all the packets */ |
| @@ -1990,6 +2021,12 @@ lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, | |||
| 1990 | found = entry->vcc; | 2021 | found = entry->vcc; |
| 1991 | goto out; | 2022 | goto out; |
| 1992 | } | 2023 | } |
| 2024 | /* If the LE_ARP cache entry is still pending, reset count to 0 | ||
| 2025 | * so another LE_ARP request can be made for this frame. | ||
| 2026 | */ | ||
| 2027 | if (entry->status == ESI_ARP_PENDING) { | ||
| 2028 | entry->no_tries = 0; | ||
| 2029 | } | ||
| 1993 | /* Data direct VC not yet set up, check to see if the unknown | 2030 | /* Data direct VC not yet set up, check to see if the unknown |
| 1994 | frame count is greater than the limit. If the limit has | 2031 | frame count is greater than the limit. If the limit has |
| 1995 | not been reached, allow the caller to send packet to | 2032 | not been reached, allow the caller to send packet to |
