Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a7097fc authored by Scott Talbert's avatar Scott Talbert Committed by David S. Miller
Browse files

[ATM]: [lec] attempt to support cisco failover



From: Scott Talbert <scott.talbert@lmco.com>
Signed-off-by: default avatarChas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 09e9ec87
Loading
Loading
Loading
Loading
+34 −3
Original line number Diff line number Diff line
@@ -686,9 +686,19 @@ static unsigned char lec_ctrl_magic[] = {
        0x01,
        0x01 };

#define LEC_DATA_DIRECT_8023  2
#define LEC_DATA_DIRECT_8025  3

static int lec_is_data_direct(struct atm_vcc *vcc)
{ 
	return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) ||
		(vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025));
} 

static void 
lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
{
	unsigned long flags;
        struct net_device *dev = (struct net_device *)vcc->proto_data;
        struct lec_priv *priv = (struct lec_priv *)dev->priv; 

@@ -728,7 +738,8 @@ lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
                skb_queue_tail(&sk->sk_receive_queue, skb);
                sk->sk_data_ready(sk, skb->len);
        } else { /* Data frame, queue to protocol handlers */
                unsigned char *dst;
		struct lec_arp_table *entry;
                unsigned char *src, *dst;

                atm_return(vcc,skb->truesize);
                if (*(uint16_t *)skb->data == htons(priv->lecid) ||
@@ -741,11 +752,31 @@ lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
                        return;
                }
#ifdef CONFIG_TR
                if (priv->is_trdev) dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;
                if (priv->is_trdev)
			dst = ((struct lecdatahdr_8025 *) skb->data)->h_dest;
                else
#endif
		dst = ((struct lecdatahdr_8023 *) skb->data)->h_dest;

		/* If this is a Data Direct VCC, and the VCC does not match
		 * the LE_ARP cache entry, delete the LE_ARP cache entry.
		 */
		spin_lock_irqsave(&priv->lec_arp_lock, flags);
		if (lec_is_data_direct(vcc)) {
#ifdef CONFIG_TR
			if (priv->is_trdev)
				src = ((struct lecdatahdr_8025 *) skb->data)->h_source;
			else
#endif
			src = ((struct lecdatahdr_8023 *) skb->data)->h_source;
			entry = lec_arp_find(priv, src);
			if (entry && entry->vcc != vcc) {
				lec_arp_remove(priv, entry);
				kfree(entry);
			}
		}
		spin_unlock_irqrestore(&priv->lec_arp_lock, flags);

                if (!(dst[0]&0x01) &&   /* Never filter Multi/Broadcast */
                    !priv->is_proxy &&  /* Proxy wants all the packets */
		    memcmp(dst, dev->dev_addr, dev->addr_len)) {