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

📄 lec.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
                                        get_status_string(rulla->status));                        offset+=sprintf(buf+offset,"->%p\n",rulla->next);                        rulla = rulla->next;                }                printk("%s",buf);        }        rulla = lec_no_forward;        if (rulla)                printk("No forward\n");          while(rulla) {                offset=0;                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,                                 get_status_string(rulla->status));                offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);                rulla = rulla->next;                printk("%s",buf);        }        rulla = lec_arp_empty_ones;        if (rulla)                printk("Empty ones\n");          while(rulla) {                offset=0;                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,                                 get_status_string(rulla->status));                offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);                rulla = rulla->next;                printk("%s",buf);        }        rulla = mcast_fwds;        if (rulla)                printk("Multicast Forward VCCs\n");          while(rulla) {                offset=0;                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,                                 get_status_string(rulla->status));                offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next);                rulla = rulla->next;                printk("%s",buf);        }#endif}/* * Destruction of arp-cache */voidlec_arp_destroy(struct lec_priv *priv){        struct lec_arp_table *entry, *next;        int i;        del_timer_sync(&priv->lec_arp_timer);                /*         * Remove all entries         */        for (i=0;i<LEC_ARP_TABLE_SIZE;i++) {                for(entry =priv->lec_arp_tables[i];entry != NULL; entry=next) {                        next = entry->next;                        lec_arp_remove(priv, entry);                        kfree(entry);                }        }        entry = priv->lec_arp_empty_ones;        while(entry) {                next = entry->next;                del_timer_sync(&entry->timer);                lec_arp_clear_vccs(entry);                kfree(entry);                entry = next;        }        priv->lec_arp_empty_ones = NULL;        entry = priv->lec_no_forward;        while(entry) {                next = entry->next;                del_timer_sync(&entry->timer);                lec_arp_clear_vccs(entry);                kfree(entry);                entry = next;        }        priv->lec_no_forward = NULL;        entry = priv->mcast_fwds;        while(entry) {                next = entry->next;                /* No timer, LANEv2 7.1.20 and 2.3.5.3 */                lec_arp_clear_vccs(entry);                kfree(entry);                entry = next;        }        priv->mcast_fwds = NULL;        priv->mcast_vcc = NULL;        memset(priv->lec_arp_tables, 0,                sizeof(struct lec_arp_table*)*LEC_ARP_TABLE_SIZE);}/*  * Find entry by mac_address */static struct lec_arp_table*lec_arp_find(struct lec_priv *priv,             unsigned char *mac_addr){        unsigned short place;        struct lec_arp_table *to_return;        DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",                mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff,                 mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff);        lec_arp_get(priv);        place = HASH(mac_addr[ETH_ALEN-1]);          to_return = priv->lec_arp_tables[place];        while(to_return) {                if (memcmp(mac_addr, to_return->mac_addr, ETH_ALEN) == 0) {                        lec_arp_put(priv);                        return to_return;                }                to_return = to_return->next;        }        lec_arp_put(priv);        return NULL;}static struct lec_arp_table*make_entry(struct lec_priv *priv, unsigned char *mac_addr){        struct lec_arp_table *to_return;        to_return=(struct lec_arp_table *)kmalloc(sizeof(struct lec_arp_table),                                                  GFP_ATOMIC);        if (!to_return) {                printk("LEC: Arp entry kmalloc failed\n");                return NULL;        }        memset(to_return,0,sizeof(struct lec_arp_table));        memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);        init_timer(&to_return->timer);        to_return->timer.function = lec_arp_expire_arp;        to_return->timer.data = (unsigned long)to_return;        to_return->last_used = jiffies;        to_return->priv = priv;        skb_queue_head_init(&to_return->tx_wait);        return to_return;}/* * * Arp sent timer expired * */static voidlec_arp_expire_arp(unsigned long data){        struct lec_arp_table *entry;        entry = (struct lec_arp_table *)data;        DPRINTK("lec_arp_expire_arp\n");        if (entry->status == ESI_ARP_PENDING) {                if (entry->no_tries <= entry->priv->max_retry_count) {                        if (entry->is_rdesc)                                send_to_lecd(entry->priv, l_rdesc_arp_xmt, entry->mac_addr, NULL, NULL);                        else                                send_to_lecd(entry->priv, l_arp_xmt, entry->mac_addr, NULL, NULL);                        entry->no_tries++;                }                mod_timer(&entry->timer, jiffies + (1*HZ));        }}/* * * Unknown/unused vcc expire, remove associated entry * */static voidlec_arp_expire_vcc(unsigned long data){        struct lec_arp_table *to_remove = (struct lec_arp_table*)data;        struct lec_priv *priv = (struct lec_priv *)to_remove->priv;        struct lec_arp_table *entry = NULL;        del_timer(&to_remove->timer);        DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",                to_remove, priv,                 to_remove->vcc?to_remove->recv_vcc->vpi:0,                to_remove->vcc?to_remove->recv_vcc->vci:0);        DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward);        if (to_remove == priv->lec_arp_empty_ones)                priv->lec_arp_empty_ones = to_remove->next;        else {                entry = priv->lec_arp_empty_ones;                while (entry && entry->next != to_remove)                        entry = entry->next;                if (entry)                        entry->next = to_remove->next;        }        if (!entry) {                if (to_remove == priv->lec_no_forward) {                        priv->lec_no_forward = to_remove->next;                } else {                        entry = priv->lec_no_forward;                        while (entry && entry->next != to_remove)                                entry = entry->next;                        if (entry)                                entry->next = to_remove->next;                }	}        lec_arp_clear_vccs(to_remove);        kfree(to_remove);}/* * Expire entries. * 1. Re-set timer * 2. For each entry, delete entries that have aged past the age limit. * 3. For each entry, depending on the status of the entry, perform *    the following maintenance. *    a. If status is ESI_VC_PENDING or ESI_ARP_PENDING then if the *       tick_count is above the max_unknown_frame_time, clear *       the tick_count to zero and clear the packets_flooded counter *       to zero. This supports the packet rate limit per address *       while flooding unknowns. *    b. If the status is ESI_FLUSH_PENDING and the tick_count is greater *       than or equal to the path_switching_delay, change the status *       to ESI_FORWARD_DIRECT. This causes the flush period to end *       regardless of the progress of the flush protocol. */static voidlec_arp_check_expire(unsigned long data){        struct lec_priv *priv = (struct lec_priv *)data;        struct lec_arp_table *entry, *next;        unsigned long now;        unsigned long time_to_check;        int i;        DPRINTK("lec_arp_check_expire %p,%d\n",priv,                atomic_read(&priv->lec_arp_users));        DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones,                priv->lec_no_forward);        if (!atomic_read(&priv->lec_arp_users)) {                lec_arp_get(priv);                now = jiffies;                for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {                        for(entry = priv->lec_arp_tables[i]; entry != NULL; ) {                                if ((entry->flags) & LEC_REMOTE_FLAG &&                                     priv->topology_change)                                        time_to_check=priv->forward_delay_time;                                else                                        time_to_check = priv->aging_time;                                DPRINTK("About to expire: %lx - %lx > %lx\n",                                        now,entry->last_used, time_to_check);                                if( time_after(now, entry->last_used+                                   time_to_check) &&                                     !(entry->flags & LEC_PERMANENT_FLAG) &&                                    !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */                                        /* Remove entry */                                        DPRINTK("LEC:Entry timed out\n");                                        next = entry->next;                                              lec_arp_remove(priv, entry);                                        kfree(entry);                                        entry = next;                                } else {                                        /* Something else */                                        if ((entry->status == ESI_VC_PENDING ||                                             entry->status == ESI_ARP_PENDING)                                             && time_after_eq(now,                                            entry->timestamp +                                            priv->max_unknown_frame_time)) {                                                entry->timestamp = jiffies;                                                entry->packets_flooded = 0;                                                if (entry->status == ESI_VC_PENDING)                                                        send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL);                                        }                                        if (entry->status == ESI_FLUSH_PENDING                                            &&                                           time_after_eq(now, entry->timestamp+                                           priv->path_switching_delay)) {			                        struct sk_buff *skb; 				                while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)					                lec_send(entry->vcc, skb, entry->priv);                                                entry->last_used = jiffies;                                                entry->status =                                                         ESI_FORWARD_DIRECT;                                        }                                        entry = entry->next;                                }                        }                }                lec_arp_put(priv);        }        mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL);}/* * Try to find vcc where mac_address is attached. *  */struct atm_vcc*lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, int is_rdesc,                struct lec_arp_table **ret_entry){        struct lec_arp_table *entry;        if (mac_to_find[0]&0x01) {                switch (priv->lane_version) {                case 1:                        return priv->mcast_vcc;                        break;                case 2:  /* LANE2 wants arp for multicast addresses */                        if ( memcmp(mac_to_find, bus_mac, ETH_ALEN) == 0)                                return priv->mcast_vcc;                        break;                default:                        break;                }        }        entry = lec_arp_find(priv, mac_to_find);          if (entry) {                if (entry->status == ESI_FORWARD_DIRECT) {                        /* Connection Ok */                        entry->last_used = jiffies;                        *ret_entry = entry;                        return entry->vcc;                }                /* Data direct VC not yet set up, check to see if the unknown                   frame count is greater than the limit. I

⌨️ 快捷键说明

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