⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lec.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	deregister_atm_ioctl(&lane_ioctl_ops);        for (i = 0; i < MAX_LEC_ITF; i++) {                if (dev_lec[i] != NULL) {                        priv = (struct lec_priv *)dev_lec[i]->priv;			unregister_netdev(dev_lec[i]);                        free_netdev(dev_lec[i]);                        dev_lec[i] = NULL;                }        }        return;                                    }module_init(lane_module_init);module_exit(lane_module_cleanup);/* * LANE2: 3.1.3, LE_RESOLVE.request * Non force allocates memory and fills in *tlvs, fills in *sizeoftlvs. * If sizeoftlvs == NULL the default TLVs associated with with this * lec will be used. * If dst_mac == NULL, targetless LE_ARP will be sent */static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,    u8 **tlvs, u32 *sizeoftlvs){        struct lec_priv *priv = (struct lec_priv *)dev->priv;        struct lec_arp_table *table;        struct sk_buff *skb;        int retval;        if (force == 0) {                table = lec_arp_find(priv, dst_mac);                if(table == NULL)                        return -1;                                *tlvs = kmalloc(table->sizeoftlvs, GFP_KERNEL);                if (*tlvs == NULL)                        return -1;                                memcpy(*tlvs, table->tlvs, table->sizeoftlvs);                *sizeoftlvs = table->sizeoftlvs;                                return 0;        }	if (sizeoftlvs == NULL)		retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);			else {		skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);		if (skb == NULL)			return -1;		skb->len = *sizeoftlvs;		memcpy(skb->data, *tlvs, *sizeoftlvs);		retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);	}        return retval;}        /* * LANE2: 3.1.4, LE_ASSOCIATE.request * Associate the *tlvs with the *lan_dst address. * Will overwrite any previous association * Returns 1 for success, 0 for failure (out of memory) * */static int lane2_associate_req (struct net_device *dev, u8 *lan_dst,                         u8 *tlvs, u32 sizeoftlvs){        int retval;        struct sk_buff *skb;        struct lec_priv *priv = (struct lec_priv*)dev->priv;        if ( memcmp(lan_dst, dev->dev_addr, ETH_ALEN) != 0 )                return (0);       /* not our mac address */        kfree(priv->tlvs); /* NULL if there was no previous association */        priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);        if (priv->tlvs == NULL)                return (0);        priv->sizeoftlvs = sizeoftlvs;        memcpy(priv->tlvs, tlvs, sizeoftlvs);        skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);        if (skb == NULL)                return 0;        skb->len = sizeoftlvs;        memcpy(skb->data, tlvs, sizeoftlvs);        retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);        if (retval != 0)                printk("lec.c: lane2_associate_req() failed\n");        /* If the previous association has changed we must         * somehow notify other LANE entities about the change         */        return (1);}/* * LANE2: 3.1.5, LE_ASSOCIATE.indication * */static void lane2_associate_ind (struct net_device *dev, u8 *mac_addr,    u8 *tlvs, u32 sizeoftlvs){#if 0        int i = 0;#endif	struct lec_priv *priv = (struct lec_priv *)dev->priv;#if 0 /* Why have the TLVs in LE_ARP entries since we do not use them? When you         uncomment this code, make sure the TLVs get freed when entry is killed */        struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);        if (entry == NULL)                return;     /* should not happen */        kfree(entry->tlvs);        entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL);        if (entry->tlvs == NULL)                return;        entry->sizeoftlvs = sizeoftlvs;        memcpy(entry->tlvs, tlvs, sizeoftlvs);#endif#if 0        printk("lec.c: lane2_associate_ind()\n");        printk("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);        while (i < sizeoftlvs)                printk("%02x ", tlvs[i++]);                printk("\n");#endif        /* tell MPOA about the TLVs we saw */        if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {                priv->lane2_ops->associate_indicator(dev, mac_addr,                                                     tlvs, sizeoftlvs);        }        return;}/* * Here starts what used to lec_arpc.c * * lec_arpc.c was added here when making * lane client modular. October 1997 * */#include <linux/types.h>#include <linux/sched.h>#include <linux/timer.h>#include <asm/param.h>#include <asm/atomic.h>#include <linux/inetdevice.h>#include <net/route.h>#if 0#define DPRINTK(format,args...)/*#define DPRINTK printk*/#endif#define DEBUG_ARP_TABLE 0#define LEC_ARP_REFRESH_INTERVAL (3*HZ)static void lec_arp_check_expire(unsigned long data);static void lec_arp_expire_arp(unsigned long data);void dump_arp_table(struct lec_priv *priv);/*  * Arp table funcs */#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1))static __inline__ void lec_arp_get(struct lec_priv *priv){        atomic_inc(&priv->lec_arp_users);}static __inline__ void lec_arp_put(struct lec_priv *priv){        atomic_dec(&priv->lec_arp_users);}/* * Initialization of arp-cache */void lec_arp_init(struct lec_priv *priv){        unsigned short i;        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {                priv->lec_arp_tables[i] = NULL;        }        	spin_lock_init(&priv->lec_arp_lock);        init_timer(&priv->lec_arp_timer);        priv->lec_arp_timer.expires = jiffies+LEC_ARP_REFRESH_INTERVAL;        priv->lec_arp_timer.data = (unsigned long)priv;        priv->lec_arp_timer.function = lec_arp_check_expire;        add_timer(&priv->lec_arp_timer);}voidlec_arp_clear_vccs(struct lec_arp_table *entry){        if (entry->vcc) {		struct atm_vcc *vcc = entry->vcc;		struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);		struct net_device *dev = (struct net_device*) vcc->proto_data;                vcc->pop = vpriv->old_pop;		if (vpriv->xoff)			netif_wake_queue(dev);		kfree(vpriv);		vcc->user_back = NULL;                vcc->push = entry->old_push;		vcc_release_async(vcc, -EPIPE);                vcc = NULL;        }        if (entry->recv_vcc) {                entry->recv_vcc->push = entry->old_recv_push;		vcc_release_async(entry->recv_vcc, -EPIPE);                entry->recv_vcc = NULL;        }        }/* * Insert entry to lec_arp_table * LANE2: Add to the end of the list to satisfy 8.1.13 */static inline void lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add){        unsigned long flags;        unsigned short place;        struct lec_arp_table *tmp;        spin_lock_irqsave(&priv->lec_arp_lock, flags);        place = HASH(to_add->mac_addr[ETH_ALEN-1]);        tmp = priv->lec_arp_tables[place];        to_add->next = NULL;        if (tmp == NULL)                priv->lec_arp_tables[place] = to_add;          else {  /* add to the end */                while (tmp->next)                        tmp = tmp->next;                tmp->next = to_add;        }        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);        DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",                0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1],                0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3],                0xff&to_add->mac_addr[4], 0xff&to_add->mac_addr[5]);}/* * Remove entry from lec_arp_table */static int lec_arp_remove(struct lec_priv *priv,               struct lec_arp_table *to_remove){        unsigned long flags;        unsigned short place;        struct lec_arp_table *tmp;        int remove_vcc=1;        spin_lock_irqsave(&priv->lec_arp_lock, flags);        if (!to_remove) {                spin_unlock_irqrestore(&priv->lec_arp_lock, flags);                return -1;        }        place = HASH(to_remove->mac_addr[ETH_ALEN-1]);        tmp = priv->lec_arp_tables[place];        if (tmp == to_remove) {                priv->lec_arp_tables[place] = tmp->next;        } else {                while(tmp && tmp->next != to_remove) {                        tmp = tmp->next;                }                if (!tmp) {/* Entry was not found */                        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);                        return -1;                }        }        tmp->next = to_remove->next;        del_timer(&to_remove->timer);          /* If this is the only MAC connected to this VCC, also tear down           the VCC */        if (to_remove->status >= ESI_FLUSH_PENDING) {                /*                 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT                 */                for(place=0;place<LEC_ARP_TABLE_SIZE;place++) {                        for(tmp = priv->lec_arp_tables[place]; tmp != NULL; tmp = tmp->next) {                                if (memcmp(tmp->atm_addr, to_remove->atm_addr,                                           ATM_ESA_LEN)==0) {                                        remove_vcc=0;                                        break;                                }                        }                }                if (remove_vcc)                        lec_arp_clear_vccs(to_remove);        }        skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */        spin_unlock_irqrestore(&priv->lec_arp_lock, flags);        DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",                0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1],                0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3],                0xff&to_remove->mac_addr[4], 0xff&to_remove->mac_addr[5]);        return 0;}#if DEBUG_ARP_TABLEstatic char*get_status_string(unsigned char st){        switch(st) {        case ESI_UNKNOWN:                return "ESI_UNKNOWN";        case ESI_ARP_PENDING:                return "ESI_ARP_PENDING";        case ESI_VC_PENDING:                return "ESI_VC_PENDING";        case ESI_FLUSH_PENDING:                return "ESI_FLUSH_PENDING";        case ESI_FORWARD_DIRECT:                return "ESI_FORWARD_DIRECT";        default:                return "<UNKNOWN>";        }}#endifvoiddump_arp_table(struct lec_priv *priv){#if DEBUG_ARP_TABLE        int i,j, offset;        struct lec_arp_table *rulla;        char buf[1024];        struct lec_arp_table **lec_arp_tables =                (struct lec_arp_table **)priv->lec_arp_tables;        struct lec_arp_table *lec_arp_empty_ones =                (struct lec_arp_table *)priv->lec_arp_empty_ones;        struct lec_arp_table *lec_no_forward =                (struct lec_arp_table *)priv->lec_no_forward;        struct lec_arp_table *mcast_fwds = priv->mcast_fwds;        printk("Dump %p:\n",priv);        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {                rulla = lec_arp_tables[i];                offset = 0;                offset += sprintf(buf,"%d: %p\n",i, rulla);                while (rulla) {                        offset += sprintf(buf+offset,"Mac:");                        for(j=0;j<ETH_ALEN;j++) {                                offset+=sprintf(buf+offset,                                                "%2.2x ",                                                rulla->mac_addr[j]&0xff);                        }                        offset +=sprintf(buf+offset,"Atm:");                        for(j=0;j<ATM_ESA_LEN;j++) {                                offset+=sprintf(buf+offset,                                                "%2.2x ",                                                rulla->atm_addr[j]&0xff);                        }                              offset+=sprintf(buf+offset,                                        "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",                                        rulla->vcc?rulla->vcc->vpi:0,                                         rulla->vcc?rulla->vcc->vci:0,                                        rulla->recv_vcc?rulla->recv_vcc->vpi:0,                                        rulla->recv_vcc?rulla->recv_vcc->vci:0,                                        rulla->last_used,                                        rulla->timestamp, rulla->no_tries);                        offset+=sprintf(buf+offset,                                        "Flags:%x, Packets_flooded:%x, Status: %s ",                                        rulla->flags, rulla->packets_flooded, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -