diff options
| -rw-r--r-- | net/atm/lec.c | 442 | ||||
| -rw-r--r-- | net/atm/lec.h | 8 | ||||
| -rw-r--r-- | net/atm/lec_arpc.h | 2 |
3 files changed, 170 insertions, 282 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) | |||
| 998 | struct lec_state { | 998 | struct 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 | ||
| 1008 | static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl, | 1008 | static 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, | |||
| 1042 | static void *lec_misc_walk(struct lec_state *state, loff_t *l, | 1045 | static 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 | */ |
| 1495 | static inline void | 1502 | static inline void |
| 1496 | lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add) | 1503 | lec_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) | |||
| 1522 | static int | 1519 | static int |
| 1523 | lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove) | 1520 | lec_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 | |||
