aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/lec.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/lec.c')
-rw-r--r--net/atm/lec.c442
1 files changed, 165 insertions, 277 deletions
diff --git a/net/atm/lec.c b/net/atm/lec.c
index d2b44e91badf..eb94e94bffa9 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -806,7 +806,7 @@ static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
806 dev_kfree_skb(skb); 806 dev_kfree_skb(skb);
807 return; 807 return;
808 } 808 }
809 if (priv->lec_arp_empty_ones) { 809 if (!hlist_empty(&priv->lec_arp_empty_ones)) {
810 lec_arp_check_empties(priv, vcc, skb); 810 lec_arp_check_empties(priv, vcc, skb);
811 } 811 }
812 skb->dev = dev; 812 skb->dev = dev;
@@ -998,29 +998,32 @@ static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
998struct lec_state { 998struct lec_state {
999 unsigned long flags; 999 unsigned long flags;
1000 struct lec_priv *locked; 1000 struct lec_priv *locked;
1001 struct lec_arp_table *entry; 1001 struct hlist_node *node;
1002 struct net_device *dev; 1002 struct net_device *dev;
1003 int itf; 1003 int itf;
1004 int arp_table; 1004 int arp_table;
1005 int misc_table; 1005 int misc_table;
1006}; 1006};
1007 1007
1008static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl, 1008static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl,
1009 loff_t *l) 1009 loff_t *l)
1010{ 1010{
1011 struct lec_arp_table *e = state->entry; 1011 struct hlist_node *e = state->node;
1012 struct lec_arp_table *tmp;
1012 1013
1013 if (!e) 1014 if (!e)
1014 e = tbl; 1015 e = tbl->first;
1015 if (e == (void *)1) { 1016 if (e == (void *)1) {
1016 e = tbl; 1017 e = tbl->first;
1017 --*l; 1018 --*l;
1018 } 1019 }
1019 for (; e; e = e->next) { 1020
1021 hlist_for_each_entry_from(tmp, e, next) {
1020 if (--*l < 0) 1022 if (--*l < 0)
1021 break; 1023 break;
1022 } 1024 }
1023 state->entry = e; 1025 state->node = e;
1026
1024 return (*l < 0) ? state : NULL; 1027 return (*l < 0) ? state : NULL;
1025} 1028}
1026 1029
@@ -1031,7 +1034,7 @@ static void *lec_arp_walk(struct lec_state *state, loff_t *l,
1031 int p; 1034 int p;
1032 1035
1033 for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) { 1036 for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
1034 v = lec_tbl_walk(state, priv->lec_arp_tables[p], l); 1037 v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l);
1035 if (v) 1038 if (v)
1036 break; 1039 break;
1037 } 1040 }
@@ -1042,10 +1045,10 @@ static void *lec_arp_walk(struct lec_state *state, loff_t *l,
1042static void *lec_misc_walk(struct lec_state *state, loff_t *l, 1045static void *lec_misc_walk(struct lec_state *state, loff_t *l,
1043 struct lec_priv *priv) 1046 struct lec_priv *priv)
1044{ 1047{
1045 struct lec_arp_table *lec_misc_tables[] = { 1048 struct hlist_head *lec_misc_tables[] = {
1046 priv->lec_arp_empty_ones, 1049 &priv->lec_arp_empty_ones,
1047 priv->lec_no_forward, 1050 &priv->lec_no_forward,
1048 priv->mcast_fwds 1051 &priv->mcast_fwds
1049 }; 1052 };
1050 void *v = NULL; 1053 void *v = NULL;
1051 int q; 1054 int q;
@@ -1112,7 +1115,7 @@ static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
1112 state->locked = NULL; 1115 state->locked = NULL;
1113 state->arp_table = 0; 1116 state->arp_table = 0;
1114 state->misc_table = 0; 1117 state->misc_table = 0;
1115 state->entry = (void *)1; 1118 state->node = (void *)1;
1116 1119
1117 return *pos ? lec_get_idx(state, *pos) : (void *)1; 1120 return *pos ? lec_get_idx(state, *pos) : (void *)1;
1118} 1121}
@@ -1148,9 +1151,10 @@ static int lec_seq_show(struct seq_file *seq, void *v)
1148 else { 1151 else {
1149 struct lec_state *state = seq->private; 1152 struct lec_state *state = seq->private;
1150 struct net_device *dev = state->dev; 1153 struct net_device *dev = state->dev;
1154 struct lec_arp_table *entry = hlist_entry(state->node, struct lec_arp_table, next);
1151 1155
1152 seq_printf(seq, "%s ", dev->name); 1156 seq_printf(seq, "%s ", dev->name);
1153 lec_info(seq, state->entry); 1157 lec_info(seq, entry);
1154 } 1158 }
1155 return 0; 1159 return 0;
1156} 1160}
@@ -1455,8 +1459,11 @@ static void lec_arp_init(struct lec_priv *priv)
1455 unsigned short i; 1459 unsigned short i;
1456 1460
1457 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 1461 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1458 priv->lec_arp_tables[i] = NULL; 1462 INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
1459 } 1463 }
1464 INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
1465 INIT_HLIST_HEAD(&priv->lec_no_forward);
1466 INIT_HLIST_HEAD(&priv->mcast_fwds);
1460 spin_lock_init(&priv->lec_arp_lock); 1467 spin_lock_init(&priv->lec_arp_lock);
1461 init_timer(&priv->lec_arp_timer); 1468 init_timer(&priv->lec_arp_timer);
1462 priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL; 1469 priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
@@ -1479,7 +1486,7 @@ static void lec_arp_clear_vccs(struct lec_arp_table *entry)
1479 vcc->user_back = NULL; 1486 vcc->user_back = NULL;
1480 vcc->push = entry->old_push; 1487 vcc->push = entry->old_push;
1481 vcc_release_async(vcc, -EPIPE); 1488 vcc_release_async(vcc, -EPIPE);
1482 vcc = NULL; 1489 entry->vcc = NULL;
1483 } 1490 }
1484 if (entry->recv_vcc) { 1491 if (entry->recv_vcc) {
1485 entry->recv_vcc->push = entry->old_recv_push; 1492 entry->recv_vcc->push = entry->old_recv_push;
@@ -1493,27 +1500,17 @@ static void lec_arp_clear_vccs(struct lec_arp_table *entry)
1493 * LANE2: Add to the end of the list to satisfy 8.1.13 1500 * LANE2: Add to the end of the list to satisfy 8.1.13
1494 */ 1501 */
1495static inline void 1502static inline void
1496lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add) 1503lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry)
1497{ 1504{
1498 unsigned short place; 1505 struct hlist_head *tmp;
1499 struct lec_arp_table *tmp;
1500 1506
1501 place = HASH(to_add->mac_addr[ETH_ALEN - 1]); 1507 tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])];
1502 tmp = priv->lec_arp_tables[place]; 1508 hlist_add_head(&entry->next, tmp);
1503 to_add->next = NULL;
1504 if (tmp == NULL)
1505 priv->lec_arp_tables[place] = to_add;
1506
1507 else { /* add to the end */
1508 while (tmp->next)
1509 tmp = tmp->next;
1510 tmp->next = to_add;
1511 }
1512 1509
1513 DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", 1510 DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1514 0xff & to_add->mac_addr[0], 0xff & to_add->mac_addr[1], 1511 0xff & entry->mac_addr[0], 0xff & entry->mac_addr[1],
1515 0xff & to_add->mac_addr[2], 0xff & to_add->mac_addr[3], 1512 0xff & entry->mac_addr[2], 0xff & entry->mac_addr[3],
1516 0xff & to_add->mac_addr[4], 0xff & to_add->mac_addr[5]); 1513 0xff & entry->mac_addr[4], 0xff & entry->mac_addr[5]);
1517} 1514}
1518 1515
1519/* 1516/*
@@ -1522,40 +1519,26 @@ lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add)
1522static int 1519static int
1523lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove) 1520lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
1524{ 1521{
1525 unsigned short place; 1522 struct hlist_node *node;
1526 struct lec_arp_table *tmp; 1523 struct lec_arp_table *entry;
1527 int remove_vcc = 1; 1524 int i, remove_vcc = 1;
1528 1525
1529 if (!to_remove) { 1526 if (!to_remove) {
1530 return -1; 1527 return -1;
1531 } 1528 }
1532 place = HASH(to_remove->mac_addr[ETH_ALEN - 1]); 1529
1533 tmp = priv->lec_arp_tables[place]; 1530 hlist_del(&to_remove->next);
1534 if (tmp == to_remove) {
1535 priv->lec_arp_tables[place] = tmp->next;
1536 } else {
1537 while (tmp && tmp->next != to_remove) {
1538 tmp = tmp->next;
1539 }
1540 if (!tmp) { /* Entry was not found */
1541 return -1;
1542 }
1543 }
1544 tmp->next = to_remove->next;
1545 del_timer(&to_remove->timer); 1531 del_timer(&to_remove->timer);
1546 1532
1547 /* If this is the only MAC connected to this VCC, also tear down 1533 /* If this is the only MAC connected to this VCC, also tear down the VCC */
1548 the VCC */
1549 if (to_remove->status >= ESI_FLUSH_PENDING) { 1534 if (to_remove->status >= ESI_FLUSH_PENDING) {
1550 /* 1535 /*
1551 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT 1536 * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
1552 */ 1537 */
1553 for (place = 0; place < LEC_ARP_TABLE_SIZE; place++) { 1538 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1554 for (tmp = priv->lec_arp_tables[place]; tmp != NULL; 1539 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
1555 tmp = tmp->next) { 1540 if (memcmp(to_remove->atm_addr,
1556 if (memcmp 1541 entry->atm_addr, ATM_ESA_LEN) == 0) {
1557 (tmp->atm_addr, to_remove->atm_addr,
1558 ATM_ESA_LEN) == 0) {
1559 remove_vcc = 0; 1542 remove_vcc = 0;
1560 break; 1543 break;
1561 } 1544 }
@@ -1591,28 +1574,19 @@ static char *get_status_string(unsigned char st)
1591 return "<UNKNOWN>"; 1574 return "<UNKNOWN>";
1592 } 1575 }
1593} 1576}
1594#endif
1595 1577
1596static void dump_arp_table(struct lec_priv *priv) 1578static void dump_arp_table(struct lec_priv *priv)
1597{ 1579{
1598#if DEBUG_ARP_TABLE 1580 struct hlist_node *node;
1599 int i, j, offset;
1600 struct lec_arp_table *rulla; 1581 struct lec_arp_table *rulla;
1601 char buf[1024]; 1582 char buf[256];
1602 struct lec_arp_table **lec_arp_tables = 1583 int i, j, offset;
1603 (struct lec_arp_table **)priv->lec_arp_tables;
1604 struct lec_arp_table *lec_arp_empty_ones =
1605 (struct lec_arp_table *)priv->lec_arp_empty_ones;
1606 struct lec_arp_table *lec_no_forward =
1607 (struct lec_arp_table *)priv->lec_no_forward;
1608 struct lec_arp_table *mcast_fwds = priv->mcast_fwds;
1609 1584
1610 printk("Dump %p:\n", priv); 1585 printk("Dump %p:\n", priv);
1611 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 1586 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1612 rulla = lec_arp_tables[i]; 1587 hlist_for_each_entry(rulla, node, &priv->lec_arp_tables[i], next) {
1613 offset = 0; 1588 offset = 0;
1614 offset += sprintf(buf, "%d: %p\n", i, rulla); 1589 offset += sprintf(buf, "%d: %p\n", i, rulla);
1615 while (rulla) {
1616 offset += sprintf(buf + offset, "Mac:"); 1590 offset += sprintf(buf + offset, "Mac:");
1617 for (j = 0; j < ETH_ALEN; j++) { 1591 for (j = 0; j < ETH_ALEN; j++) {
1618 offset += sprintf(buf + offset, 1592 offset += sprintf(buf + offset,
@@ -1639,15 +1613,13 @@ static void dump_arp_table(struct lec_priv *priv)
1639 "Flags:%x, Packets_flooded:%x, Status: %s ", 1613 "Flags:%x, Packets_flooded:%x, Status: %s ",
1640 rulla->flags, rulla->packets_flooded, 1614 rulla->flags, rulla->packets_flooded,
1641 get_status_string(rulla->status)); 1615 get_status_string(rulla->status));
1642 offset += sprintf(buf + offset, "->%p\n", rulla->next); 1616 printk("%s\n", buf);
1643 rulla = rulla->next;
1644 } 1617 }
1645 printk("%s", buf);
1646 } 1618 }
1647 rulla = lec_no_forward; 1619
1648 if (rulla) 1620 if (!hlist_empty(&priv->lec_no_forward))
1649 printk("No forward\n"); 1621 printk("No forward\n");
1650 while (rulla) { 1622 hlist_for_each_entry(rulla, node, &priv->lec_no_forward, next) {
1651 offset = 0; 1623 offset = 0;
1652 offset += sprintf(buf + offset, "Mac:"); 1624 offset += sprintf(buf + offset, "Mac:");
1653 for (j = 0; j < ETH_ALEN; j++) { 1625 for (j = 0; j < ETH_ALEN; j++) {
@@ -1671,14 +1643,12 @@ static void dump_arp_table(struct lec_priv *priv)
1671 "Flags:%x, Packets_flooded:%x, Status: %s ", 1643 "Flags:%x, Packets_flooded:%x, Status: %s ",
1672 rulla->flags, rulla->packets_flooded, 1644 rulla->flags, rulla->packets_flooded,
1673 get_status_string(rulla->status)); 1645 get_status_string(rulla->status));
1674 offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next); 1646 printk("%s\n", buf);
1675 rulla = rulla->next;
1676 printk("%s", buf);
1677 } 1647 }
1678 rulla = lec_arp_empty_ones; 1648
1679 if (rulla) 1649 if (!hlist_empty(&priv->lec_arp_empty_ones))
1680 printk("Empty ones\n"); 1650 printk("Empty ones\n");
1681 while (rulla) { 1651 hlist_for_each_entry(rulla, node, &priv->lec_arp_empty_ones, next) {
1682 offset = 0; 1652 offset = 0;
1683 offset += sprintf(buf + offset, "Mac:"); 1653 offset += sprintf(buf + offset, "Mac:");
1684 for (j = 0; j < ETH_ALEN; j++) { 1654 for (j = 0; j < ETH_ALEN; j++) {
@@ -1702,15 +1672,12 @@ static void dump_arp_table(struct lec_priv *priv)
1702 "Flags:%x, Packets_flooded:%x, Status: %s ", 1672 "Flags:%x, Packets_flooded:%x, Status: %s ",
1703 rulla->flags, rulla->packets_flooded, 1673 rulla->flags, rulla->packets_flooded,
1704 get_status_string(rulla->status)); 1674 get_status_string(rulla->status));
1705 offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next);
1706 rulla = rulla->next;
1707 printk("%s", buf); 1675 printk("%s", buf);
1708 } 1676 }
1709 1677
1710 rulla = mcast_fwds; 1678 if (!hlist_empty(&priv->mcast_fwds))
1711 if (rulla)
1712 printk("Multicast Forward VCCs\n"); 1679 printk("Multicast Forward VCCs\n");
1713 while (rulla) { 1680 hlist_for_each_entry(rulla, node, &priv->mcast_fwds, next) {
1714 offset = 0; 1681 offset = 0;
1715 offset += sprintf(buf + offset, "Mac:"); 1682 offset += sprintf(buf + offset, "Mac:");
1716 for (j = 0; j < ETH_ALEN; j++) { 1683 for (j = 0; j < ETH_ALEN; j++) {
@@ -1734,13 +1701,13 @@ static void dump_arp_table(struct lec_priv *priv)
1734 "Flags:%x, Packets_flooded:%x, Status: %s ", 1701 "Flags:%x, Packets_flooded:%x, Status: %s ",
1735 rulla->flags, rulla->packets_flooded, 1702 rulla->flags, rulla->packets_flooded,
1736 get_status_string(rulla->status)); 1703 get_status_string(rulla->status));
1737 offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next); 1704 printk("%s\n", buf);
1738 rulla = rulla->next;
1739 printk("%s", buf);
1740 } 1705 }
1741 1706
1742#endif
1743} 1707}
1708#else
1709#define dump_arp_table(priv) do { } while (0)
1710#endif
1744 1711
1745/* 1712/*
1746 * Destruction of arp-cache 1713 * Destruction of arp-cache
@@ -1748,7 +1715,8 @@ static void dump_arp_table(struct lec_priv *priv)
1748static void lec_arp_destroy(struct lec_priv *priv) 1715static void lec_arp_destroy(struct lec_priv *priv)
1749{ 1716{
1750 unsigned long flags; 1717 unsigned long flags;
1751 struct lec_arp_table *entry, *next; 1718 struct hlist_node *node, *next;
1719 struct lec_arp_table *entry;
1752 int i; 1720 int i;
1753 1721
1754 del_timer_sync(&priv->lec_arp_timer); 1722 del_timer_sync(&priv->lec_arp_timer);
@@ -1759,43 +1727,37 @@ static void lec_arp_destroy(struct lec_priv *priv)
1759 1727
1760 spin_lock_irqsave(&priv->lec_arp_lock, flags); 1728 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1761 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 1729 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1762 for (entry = priv->lec_arp_tables[i]; entry != NULL; 1730 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
1763 entry = next) {
1764 next = entry->next;
1765 lec_arp_remove(priv, entry); 1731 lec_arp_remove(priv, entry);
1766 kfree(entry); 1732 kfree(entry);
1767 } 1733 }
1734 INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
1768 } 1735 }
1769 entry = priv->lec_arp_empty_ones; 1736
1770 while (entry) { 1737 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
1771 next = entry->next;
1772 del_timer_sync(&entry->timer); 1738 del_timer_sync(&entry->timer);
1773 lec_arp_clear_vccs(entry); 1739 lec_arp_clear_vccs(entry);
1740 hlist_del(&entry->next);
1774 kfree(entry); 1741 kfree(entry);
1775 entry = next;
1776 } 1742 }
1777 priv->lec_arp_empty_ones = NULL; 1743 INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
1778 entry = priv->lec_no_forward; 1744
1779 while (entry) { 1745 hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
1780 next = entry->next;
1781 del_timer_sync(&entry->timer); 1746 del_timer_sync(&entry->timer);
1782 lec_arp_clear_vccs(entry); 1747 lec_arp_clear_vccs(entry);
1748 hlist_del(&entry->next);
1783 kfree(entry); 1749 kfree(entry);
1784 entry = next;
1785 } 1750 }
1786 priv->lec_no_forward = NULL; 1751 INIT_HLIST_HEAD(&priv->lec_no_forward);
1787 entry = priv->mcast_fwds; 1752
1788 while (entry) { 1753 hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
1789 next = entry->next;
1790 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ 1754 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
1791 lec_arp_clear_vccs(entry); 1755 lec_arp_clear_vccs(entry);
1756 hlist_del(&entry->next);
1792 kfree(entry); 1757 kfree(entry);
1793 entry = next;
1794 } 1758 }
1795 priv->mcast_fwds = NULL; 1759 INIT_HLIST_HEAD(&priv->mcast_fwds);
1796 priv->mcast_vcc = NULL; 1760 priv->mcast_vcc = NULL;
1797 memset(priv->lec_arp_tables, 0,
1798 sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE);
1799 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 1761 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1800} 1762}
1801 1763
@@ -1805,20 +1767,19 @@ static void lec_arp_destroy(struct lec_priv *priv)
1805static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, 1767static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
1806 unsigned char *mac_addr) 1768 unsigned char *mac_addr)
1807{ 1769{
1808 unsigned short place; 1770 struct hlist_node *node;
1809 struct lec_arp_table *to_return; 1771 struct hlist_head *head;
1772 struct lec_arp_table *entry;
1810 1773
1811 DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", 1774 DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1812 mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff, 1775 mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff,
1813 mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff); 1776 mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff);
1814 place = HASH(mac_addr[ETH_ALEN - 1]);
1815 1777
1816 to_return = priv->lec_arp_tables[place]; 1778 head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])];
1817 while (to_return) { 1779 hlist_for_each_entry(entry, node, head, next) {
1818 if (!compare_ether_addr(mac_addr, to_return->mac_addr)) { 1780 if (!compare_ether_addr(mac_addr, entry->mac_addr)) {
1819 return to_return; 1781 return entry;
1820 } 1782 }
1821 to_return = to_return->next;
1822 } 1783 }
1823 return NULL; 1784 return NULL;
1824} 1785}
@@ -1834,6 +1795,7 @@ static struct lec_arp_table *make_entry(struct lec_priv *priv,
1834 return NULL; 1795 return NULL;
1835 } 1796 }
1836 memcpy(to_return->mac_addr, mac_addr, ETH_ALEN); 1797 memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
1798 INIT_HLIST_NODE(&to_return->next);
1837 init_timer(&to_return->timer); 1799 init_timer(&to_return->timer);
1838 to_return->timer.function = lec_arp_expire_arp; 1800 to_return->timer.function = lec_arp_expire_arp;
1839 to_return->timer.data = (unsigned long)to_return; 1801 to_return->timer.data = (unsigned long)to_return;
@@ -1871,7 +1833,6 @@ static void lec_arp_expire_vcc(unsigned long data)
1871 unsigned long flags; 1833 unsigned long flags;
1872 struct lec_arp_table *to_remove = (struct lec_arp_table *)data; 1834 struct lec_arp_table *to_remove = (struct lec_arp_table *)data;
1873 struct lec_priv *priv = (struct lec_priv *)to_remove->priv; 1835 struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
1874 struct lec_arp_table *entry = NULL;
1875 1836
1876 del_timer(&to_remove->timer); 1837 del_timer(&to_remove->timer);
1877 1838
@@ -1879,30 +1840,9 @@ static void lec_arp_expire_vcc(unsigned long data)
1879 to_remove, priv, 1840 to_remove, priv,
1880 to_remove->vcc ? to_remove->recv_vcc->vpi : 0, 1841 to_remove->vcc ? to_remove->recv_vcc->vpi : 0,
1881 to_remove->vcc ? to_remove->recv_vcc->vci : 0); 1842 to_remove->vcc ? to_remove->recv_vcc->vci : 0);
1882 DPRINTK("eo:%p nf:%p\n", priv->lec_arp_empty_ones,
1883 priv->lec_no_forward);
1884 1843
1885 spin_lock_irqsave(&priv->lec_arp_lock, flags); 1844 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1886 if (to_remove == priv->lec_arp_empty_ones) 1845 hlist_del(&to_remove->next);
1887 priv->lec_arp_empty_ones = to_remove->next;
1888 else {
1889 entry = priv->lec_arp_empty_ones;
1890 while (entry && entry->next != to_remove)
1891 entry = entry->next;
1892 if (entry)
1893 entry->next = to_remove->next;
1894 }
1895 if (!entry) {
1896 if (to_remove == priv->lec_no_forward) {
1897 priv->lec_no_forward = to_remove->next;
1898 } else {
1899 entry = priv->lec_no_forward;
1900 while (entry && entry->next != to_remove)
1901 entry = entry->next;
1902 if (entry)
1903 entry->next = to_remove->next;
1904 }
1905 }
1906 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 1846 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1907 1847
1908 lec_arp_clear_vccs(to_remove); 1848 lec_arp_clear_vccs(to_remove);
@@ -1929,18 +1869,17 @@ static void lec_arp_check_expire(unsigned long data)
1929{ 1869{
1930 unsigned long flags; 1870 unsigned long flags;
1931 struct lec_priv *priv = (struct lec_priv *)data; 1871 struct lec_priv *priv = (struct lec_priv *)data;
1932 struct lec_arp_table *entry, *next; 1872 struct hlist_node *node, *next;
1873 struct lec_arp_table *entry;
1933 unsigned long now; 1874 unsigned long now;
1934 unsigned long time_to_check; 1875 unsigned long time_to_check;
1935 int i; 1876 int i;
1936 1877
1937 DPRINTK("lec_arp_check_expire %p\n", priv); 1878 DPRINTK("lec_arp_check_expire %p\n", priv);
1938 DPRINTK("expire: eo:%p nf:%p\n", priv->lec_arp_empty_ones,
1939 priv->lec_no_forward);
1940 now = jiffies; 1879 now = jiffies;
1941 spin_lock_irqsave(&priv->lec_arp_lock, flags); 1880 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1942 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 1881 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1943 for (entry = priv->lec_arp_tables[i]; entry != NULL;) { 1882 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
1944 if ((entry->flags) & LEC_REMOTE_FLAG && 1883 if ((entry->flags) & LEC_REMOTE_FLAG &&
1945 priv->topology_change) 1884 priv->topology_change)
1946 time_to_check = priv->forward_delay_time; 1885 time_to_check = priv->forward_delay_time;
@@ -1954,10 +1893,8 @@ static void lec_arp_check_expire(unsigned long data)
1954 && !(entry->mac_addr[0] & 0x01)) { /* LANE2: 7.1.20 */ 1893 && !(entry->mac_addr[0] & 0x01)) { /* LANE2: 7.1.20 */
1955 /* Remove entry */ 1894 /* Remove entry */
1956 DPRINTK("LEC:Entry timed out\n"); 1895 DPRINTK("LEC:Entry timed out\n");
1957 next = entry->next;
1958 lec_arp_remove(priv, entry); 1896 lec_arp_remove(priv, entry);
1959 kfree(entry); 1897 kfree(entry);
1960 entry = next;
1961 } else { 1898 } else {
1962 /* Something else */ 1899 /* Something else */
1963 if ((entry->status == ESI_VC_PENDING || 1900 if ((entry->status == ESI_VC_PENDING ||
@@ -1988,7 +1925,6 @@ static void lec_arp_check_expire(unsigned long data)
1988 entry->last_used = jiffies; 1925 entry->last_used = jiffies;
1989 entry->status = ESI_FORWARD_DIRECT; 1926 entry->status = ESI_FORWARD_DIRECT;
1990 } 1927 }
1991 entry = entry->next;
1992 } 1928 }
1993 } 1929 }
1994 } 1930 }
@@ -2100,15 +2036,14 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
2100 unsigned long permanent) 2036 unsigned long permanent)
2101{ 2037{
2102 unsigned long flags; 2038 unsigned long flags;
2103 struct lec_arp_table *entry, *next; 2039 struct hlist_node *node, *next;
2040 struct lec_arp_table *entry;
2104 int i; 2041 int i;
2105 2042
2106 DPRINTK("lec_addr_delete\n"); 2043 DPRINTK("lec_addr_delete\n");
2107 spin_lock_irqsave(&priv->lec_arp_lock, flags); 2044 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2108 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 2045 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2109 for (entry = priv->lec_arp_tables[i]; entry != NULL; 2046 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
2110 entry = next) {
2111 next = entry->next;
2112 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) 2047 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
2113 && (permanent || 2048 && (permanent ||
2114 !(entry->flags & LEC_PERMANENT_FLAG))) { 2049 !(entry->flags & LEC_PERMANENT_FLAG))) {
@@ -2132,6 +2067,7 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
2132 unsigned int targetless_le_arp) 2067 unsigned int targetless_le_arp)
2133{ 2068{
2134 unsigned long flags; 2069 unsigned long flags;
2070 struct hlist_node *node, *next;
2135 struct lec_arp_table *entry, *tmp; 2071 struct lec_arp_table *entry, *tmp;
2136 int i; 2072 int i;
2137 2073
@@ -2147,50 +2083,39 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
2147 * LANE2: ignore targetless LE_ARPs for which 2083 * LANE2: ignore targetless LE_ARPs for which
2148 * we have no entry in the cache. 7.1.30 2084 * we have no entry in the cache. 7.1.30
2149 */ 2085 */
2150 if (priv->lec_arp_empty_ones) { 2086 if (!hlist_empty(&priv->lec_arp_empty_ones)) {
2151 entry = priv->lec_arp_empty_ones; 2087 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
2152 if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) { 2088 if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) {
2153 priv->lec_arp_empty_ones = entry->next; 2089 hlist_del(&entry->next);
2154 } else {
2155 while (entry->next && memcmp(entry->next->atm_addr,
2156 atm_addr, ATM_ESA_LEN))
2157 entry = entry->next;
2158 if (entry->next) {
2159 tmp = entry;
2160 entry = entry->next;
2161 tmp->next = entry->next;
2162 } else
2163 entry = NULL;
2164
2165 }
2166 if (entry) {
2167 del_timer(&entry->timer);
2168 tmp = lec_arp_find(priv, mac_addr);
2169 if (tmp) {
2170 del_timer(&tmp->timer);
2171 tmp->status = ESI_FORWARD_DIRECT;
2172 memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
2173 tmp->vcc = entry->vcc;
2174 tmp->old_push = entry->old_push;
2175 tmp->last_used = jiffies;
2176 del_timer(&entry->timer); 2090 del_timer(&entry->timer);
2177 kfree(entry); 2091 tmp = lec_arp_find(priv, mac_addr);
2178 entry = tmp; 2092 if (tmp) {
2179 } else { 2093 del_timer(&tmp->timer);
2180 entry->status = ESI_FORWARD_DIRECT; 2094 tmp->status = ESI_FORWARD_DIRECT;
2181 memcpy(entry->mac_addr, mac_addr, ETH_ALEN); 2095 memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
2182 entry->last_used = jiffies; 2096 tmp->vcc = entry->vcc;
2183 lec_arp_add(priv, entry); 2097 tmp->old_push = entry->old_push;
2098 tmp->last_used = jiffies;
2099 del_timer(&entry->timer);
2100 kfree(entry);
2101 entry = tmp;
2102 } else {
2103 entry->status = ESI_FORWARD_DIRECT;
2104 memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
2105 entry->last_used = jiffies;
2106 lec_arp_add(priv, entry);
2107 }
2108 if (remoteflag)
2109 entry->flags |= LEC_REMOTE_FLAG;
2110 else
2111 entry->flags &= ~LEC_REMOTE_FLAG;
2112 DPRINTK("After update\n");
2113 dump_arp_table(priv);
2114 goto out;
2184 } 2115 }
2185 if (remoteflag)
2186 entry->flags |= LEC_REMOTE_FLAG;
2187 else
2188 entry->flags &= ~LEC_REMOTE_FLAG;
2189 DPRINTK("After update\n");
2190 dump_arp_table(priv);
2191 goto out;
2192 } 2116 }
2193 } 2117 }
2118
2194 entry = lec_arp_find(priv, mac_addr); 2119 entry = lec_arp_find(priv, mac_addr);
2195 if (!entry) { 2120 if (!entry) {
2196 entry = make_entry(priv, mac_addr); 2121 entry = make_entry(priv, mac_addr);
@@ -2203,7 +2128,7 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
2203 memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN); 2128 memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
2204 del_timer(&entry->timer); 2129 del_timer(&entry->timer);
2205 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 2130 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2206 for (tmp = priv->lec_arp_tables[i]; tmp; tmp = tmp->next) { 2131 hlist_for_each_entry(tmp, node, &priv->lec_arp_tables[i], next) {
2207 if (entry != tmp && 2132 if (entry != tmp &&
2208 !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) { 2133 !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) {
2209 /* Vcc to this host exists */ 2134 /* Vcc to this host exists */
@@ -2226,8 +2151,7 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
2226 entry->flags &= ~LEC_REMOTE_FLAG; 2151 entry->flags &= ~LEC_REMOTE_FLAG;
2227 if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) { 2152 if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) {
2228 entry->status = ESI_VC_PENDING; 2153 entry->status = ESI_VC_PENDING;
2229 send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, 2154 send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
2230 NULL);
2231 } 2155 }
2232 DPRINTK("After update2\n"); 2156 DPRINTK("After update2\n");
2233 dump_arp_table(priv); 2157 dump_arp_table(priv);
@@ -2244,6 +2168,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
2244 void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb)) 2168 void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb))
2245{ 2169{
2246 unsigned long flags; 2170 unsigned long flags;
2171 struct hlist_node *node;
2247 struct lec_arp_table *entry; 2172 struct lec_arp_table *entry;
2248 int i, found_entry = 0; 2173 int i, found_entry = 0;
2249 2174
@@ -2269,8 +2194,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
2269 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); 2194 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2270 entry->recv_vcc = vcc; 2195 entry->recv_vcc = vcc;
2271 entry->old_recv_push = old_push; 2196 entry->old_recv_push = old_push;
2272 entry->next = priv->mcast_fwds; 2197 hlist_add_head(&entry->next, &priv->mcast_fwds);
2273 priv->mcast_fwds = entry;
2274 goto out; 2198 goto out;
2275 } else if (ioc_data->receive == 1) { 2199 } else if (ioc_data->receive == 1) {
2276 /* 2200 /*
@@ -2300,9 +2224,8 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
2300 entry->status = ESI_UNKNOWN; 2224 entry->status = ESI_UNKNOWN;
2301 entry->timer.expires = jiffies + priv->vcc_timeout_period; 2225 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2302 entry->timer.function = lec_arp_expire_vcc; 2226 entry->timer.function = lec_arp_expire_vcc;
2227 hlist_add_head(&entry->next, &priv->lec_no_forward);
2303 add_timer(&entry->timer); 2228 add_timer(&entry->timer);
2304 entry->next = priv->lec_no_forward;
2305 priv->lec_no_forward = entry;
2306 dump_arp_table(priv); 2229 dump_arp_table(priv);
2307 goto out; 2230 goto out;
2308 } 2231 }
@@ -2320,8 +2243,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
2320 ioc_data->atm_addr[16], ioc_data->atm_addr[17], 2243 ioc_data->atm_addr[16], ioc_data->atm_addr[17],
2321 ioc_data->atm_addr[18], ioc_data->atm_addr[19]); 2244 ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
2322 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 2245 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2323 for (entry = priv->lec_arp_tables[i]; entry; 2246 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2324 entry = entry->next) {
2325 if (memcmp 2247 if (memcmp
2326 (ioc_data->atm_addr, entry->atm_addr, 2248 (ioc_data->atm_addr, entry->atm_addr,
2327 ATM_ESA_LEN) == 0) { 2249 ATM_ESA_LEN) == 0) {
@@ -2384,8 +2306,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
2384 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); 2306 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2385 memset(entry->mac_addr, 0, ETH_ALEN); 2307 memset(entry->mac_addr, 0, ETH_ALEN);
2386 entry->status = ESI_UNKNOWN; 2308 entry->status = ESI_UNKNOWN;
2387 entry->next = priv->lec_arp_empty_ones; 2309 hlist_add_head(&entry->next, &priv->lec_arp_empty_ones);
2388 priv->lec_arp_empty_ones = entry;
2389 entry->timer.expires = jiffies + priv->vcc_timeout_period; 2310 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2390 entry->timer.function = lec_arp_expire_vcc; 2311 entry->timer.function = lec_arp_expire_vcc;
2391 add_timer(&entry->timer); 2312 add_timer(&entry->timer);
@@ -2398,14 +2319,14 @@ out:
2398static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) 2319static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
2399{ 2320{
2400 unsigned long flags; 2321 unsigned long flags;
2322 struct hlist_node *node;
2401 struct lec_arp_table *entry; 2323 struct lec_arp_table *entry;
2402 int i; 2324 int i;
2403 2325
2404 DPRINTK("LEC:lec_flush_complete %lx\n", tran_id); 2326 DPRINTK("LEC:lec_flush_complete %lx\n", tran_id);
2405 spin_lock_irqsave(&priv->lec_arp_lock, flags); 2327 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2406 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 2328 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2407 for (entry = priv->lec_arp_tables[i]; entry; 2329 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2408 entry = entry->next) {
2409 if (entry->flush_tran_id == tran_id 2330 if (entry->flush_tran_id == tran_id
2410 && entry->status == ESI_FLUSH_PENDING) { 2331 && entry->status == ESI_FLUSH_PENDING) {
2411 struct sk_buff *skb; 2332 struct sk_buff *skb;
@@ -2427,19 +2348,19 @@ lec_set_flush_tran_id(struct lec_priv *priv,
2427 unsigned char *atm_addr, unsigned long tran_id) 2348 unsigned char *atm_addr, unsigned long tran_id)
2428{ 2349{
2429 unsigned long flags; 2350 unsigned long flags;
2351 struct hlist_node *node;
2430 struct lec_arp_table *entry; 2352 struct lec_arp_table *entry;
2431 int i; 2353 int i;
2432 2354
2433 spin_lock_irqsave(&priv->lec_arp_lock, flags); 2355 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2434 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) 2356 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
2435 for (entry = priv->lec_arp_tables[i]; entry; 2357 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2436 entry = entry->next)
2437 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) { 2358 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
2438 entry->flush_tran_id = tran_id; 2359 entry->flush_tran_id = tran_id;
2439 DPRINTK 2360 DPRINTK("Set flush transaction id to %lx for %p\n",
2440 ("Set flush transaction id to %lx for %p\n", 2361 tran_id, entry);
2441 tran_id, entry);
2442 } 2362 }
2363 }
2443 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 2364 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2444} 2365}
2445 2366
@@ -2483,15 +2404,17 @@ out:
2483static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) 2404static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
2484{ 2405{
2485 unsigned long flags; 2406 unsigned long flags;
2486 struct lec_arp_table *entry, *next; 2407 struct hlist_node *node, *next;
2408 struct lec_arp_table *entry;
2487 int i; 2409 int i;
2488 2410
2489 DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci); 2411 DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci);
2490 dump_arp_table(priv); 2412 dump_arp_table(priv);
2413
2491 spin_lock_irqsave(&priv->lec_arp_lock, flags); 2414 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2415
2492 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { 2416 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2493 for (entry = priv->lec_arp_tables[i]; entry; entry = next) { 2417 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
2494 next = entry->next;
2495 if (vcc == entry->vcc) { 2418 if (vcc == entry->vcc) {
2496 lec_arp_remove(priv, entry); 2419 lec_arp_remove(priv, entry);
2497 kfree(entry); 2420 kfree(entry);
@@ -2502,49 +2425,31 @@ static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
2502 } 2425 }
2503 } 2426 }
2504 2427
2505 entry = priv->lec_arp_empty_ones; 2428 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
2506 priv->lec_arp_empty_ones = NULL; 2429 if (entry->vcc == vcc) {
2507 while (entry != NULL) {
2508 next = entry->next;
2509 if (entry->vcc == vcc) { /* leave it out from the list */
2510 lec_arp_clear_vccs(entry); 2430 lec_arp_clear_vccs(entry);
2511 del_timer(&entry->timer); 2431 del_timer(&entry->timer);
2432 hlist_del(&entry->next);
2512 kfree(entry); 2433 kfree(entry);
2513 } else { /* put it back to the list */
2514 entry->next = priv->lec_arp_empty_ones;
2515 priv->lec_arp_empty_ones = entry;
2516 } 2434 }
2517 entry = next;
2518 } 2435 }
2519 2436
2520 entry = priv->lec_no_forward; 2437 hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
2521 priv->lec_no_forward = NULL;
2522 while (entry != NULL) {
2523 next = entry->next;
2524 if (entry->recv_vcc == vcc) { 2438 if (entry->recv_vcc == vcc) {
2525 lec_arp_clear_vccs(entry); 2439 lec_arp_clear_vccs(entry);
2526 del_timer(&entry->timer); 2440 del_timer(&entry->timer);
2441 hlist_del(&entry->next);
2527 kfree(entry); 2442 kfree(entry);
2528 } else {
2529 entry->next = priv->lec_no_forward;
2530 priv->lec_no_forward = entry;
2531 } 2443 }
2532 entry = next;
2533 } 2444 }
2534 2445
2535 entry = priv->mcast_fwds; 2446 hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
2536 priv->mcast_fwds = NULL;
2537 while (entry != NULL) {
2538 next = entry->next;
2539 if (entry->recv_vcc == vcc) { 2447 if (entry->recv_vcc == vcc) {
2540 lec_arp_clear_vccs(entry); 2448 lec_arp_clear_vccs(entry);
2541 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ 2449 /* No timer, LANEv2 7.1.20 and 2.3.5.3 */
2450 hlist_del(&entry->next);
2542 kfree(entry); 2451 kfree(entry);
2543 } else {
2544 entry->next = priv->mcast_fwds;
2545 priv->mcast_fwds = entry;
2546 } 2452 }
2547 entry = next;
2548 } 2453 }
2549 2454
2550 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 2455 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
@@ -2556,7 +2461,8 @@ lec_arp_check_empties(struct lec_priv *priv,
2556 struct atm_vcc *vcc, struct sk_buff *skb) 2461 struct atm_vcc *vcc, struct sk_buff *skb)
2557{ 2462{
2558 unsigned long flags; 2463 unsigned long flags;
2559 struct lec_arp_table *entry, *prev; 2464 struct hlist_node *node, *next;
2465 struct lec_arp_table *entry, *tmp;
2560 struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; 2466 struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
2561 unsigned char *src; 2467 unsigned char *src;
2562#ifdef CONFIG_TR 2468#ifdef CONFIG_TR
@@ -2569,41 +2475,23 @@ lec_arp_check_empties(struct lec_priv *priv,
2569 src = hdr->h_source; 2475 src = hdr->h_source;
2570 2476
2571 spin_lock_irqsave(&priv->lec_arp_lock, flags); 2477 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2572 entry = priv->lec_arp_empty_ones; 2478 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
2573 if (vcc == entry->vcc) { 2479 if (vcc == entry->vcc) {
2574 del_timer(&entry->timer); 2480 del_timer(&entry->timer);
2575 memcpy(entry->mac_addr, src, ETH_ALEN); 2481 memcpy(entry->mac_addr, src, ETH_ALEN);
2576 entry->status = ESI_FORWARD_DIRECT; 2482 entry->status = ESI_FORWARD_DIRECT;
2577 entry->last_used = jiffies; 2483 entry->last_used = jiffies;
2578 priv->lec_arp_empty_ones = entry->next; 2484 /* We might have got an entry */
2579 /* We might have got an entry */ 2485 if ((tmp = lec_arp_find(priv, src))) {
2580 if ((prev = lec_arp_find(priv, src))) { 2486 lec_arp_remove(priv, tmp);
2581 lec_arp_remove(priv, prev); 2487 kfree(tmp);
2582 kfree(prev); 2488 }
2489 hlist_del(&entry->next);
2490 lec_arp_add(priv, entry);
2491 goto out;
2583 } 2492 }
2584 lec_arp_add(priv, entry);
2585 goto out;
2586 }
2587 prev = entry;
2588 entry = entry->next;
2589 while (entry && entry->vcc != vcc) {
2590 prev = entry;
2591 entry = entry->next;
2592 } 2493 }
2593 if (!entry) { 2494 DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
2594 DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
2595 goto out;
2596 }
2597 del_timer(&entry->timer);
2598 memcpy(entry->mac_addr, src, ETH_ALEN);
2599 entry->status = ESI_FORWARD_DIRECT;
2600 entry->last_used = jiffies;
2601 prev->next = entry->next;
2602 if ((prev = lec_arp_find(priv, src))) {
2603 lec_arp_remove(priv, prev);
2604 kfree(prev);
2605 }
2606 lec_arp_add(priv, entry);
2607out: 2495out:
2608 spin_unlock_irqrestore(&priv->lec_arp_lock, flags); 2496 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2609} 2497}