1
2
3
4
5
6
7#include <linux/kernel.h>
8#include <linux/bitops.h>
9#include <linux/capability.h>
10
11
12#include <linux/if_ether.h>
13#include <linux/netdevice.h>
14#include <linux/etherdevice.h>
15#include <net/sock.h>
16#include <linux/skbuff.h>
17#include <linux/ip.h>
18#include <asm/byteorder.h>
19#include <asm/uaccess.h>
20#include <net/arp.h>
21#include <net/dst.h>
22#include <linux/proc_fs.h>
23#include <linux/spinlock.h>
24#include <linux/seq_file.h>
25
26
27#ifdef CONFIG_TR
28#include <linux/trdevice.h>
29#endif
30
31
32#include <linux/atmdev.h>
33#include <linux/atmlec.h>
34
35
36#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
37#include <linux/if_bridge.h>
38#include "../bridge/br_private.h"
39
40static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
41#endif
42
43
44#include <linux/module.h>
45#include <linux/init.h>
46
47#include "lec.h"
48#include "lec_arpc.h"
49#include "resources.h"
50
51#define DUMP_PACKETS 0
52
53
54
55
56
57#define LEC_UNRES_QUE_LEN 8
58
59
60
61
62static int lec_open(struct net_device *dev);
63static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev);
64static int lec_close(struct net_device *dev);
65static struct net_device_stats *lec_get_stats(struct net_device *dev);
66static void lec_init(struct net_device *dev);
67static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
68 const unsigned char *mac_addr);
69static int lec_arp_remove(struct lec_priv *priv,
70 struct lec_arp_table *to_remove);
71
72static void lane2_associate_ind(struct net_device *dev, const u8 *mac_address,
73 const u8 *tlvs, u32 sizeoftlvs);
74static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force,
75 u8 **tlvs, u32 *sizeoftlvs);
76static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst,
77 const u8 *tlvs, u32 sizeoftlvs);
78
79static int lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr,
80 unsigned long permanent);
81static void lec_arp_check_empties(struct lec_priv *priv,
82 struct atm_vcc *vcc, struct sk_buff *skb);
83static void lec_arp_destroy(struct lec_priv *priv);
84static void lec_arp_init(struct lec_priv *priv);
85static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
86 const unsigned char *mac_to_find,
87 int is_rdesc,
88 struct lec_arp_table **ret_entry);
89static void lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr,
90 const unsigned char *atm_addr, unsigned long remoteflag,
91 unsigned int targetless_le_arp);
92static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id);
93static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc);
94static void lec_set_flush_tran_id(struct lec_priv *priv,
95 const unsigned char *atm_addr,
96 unsigned long tran_id);
97static void lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data,
98 struct atm_vcc *vcc,
99 void (*old_push) (struct atm_vcc *vcc,
100 struct sk_buff *skb));
101static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc);
102
103
104static inline void lec_arp_hold(struct lec_arp_table *entry)
105{
106 atomic_inc(&entry->usage);
107}
108
109static inline void lec_arp_put(struct lec_arp_table *entry)
110{
111 if (atomic_dec_and_test(&entry->usage))
112 kfree(entry);
113}
114
115
116static struct lane2_ops lane2_ops = {
117 lane2_resolve,
118 lane2_associate_req,
119 NULL
120};
121
122static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
123
124
125static struct net_device *dev_lec[MAX_LEC_ITF];
126
127#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
128static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
129{
130 struct ethhdr *eth;
131 char *buff;
132 struct lec_priv *priv;
133
134
135
136
137
138
139 eth = (struct ethhdr *)skb->data;
140 buff = skb->data + skb->dev->hard_header_len;
141 if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
142 struct sock *sk;
143 struct sk_buff *skb2;
144 struct atmlec_msg *mesg;
145
146 skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
147 if (skb2 == NULL)
148 return;
149 skb2->len = sizeof(struct atmlec_msg);
150 mesg = (struct atmlec_msg *)skb2->data;
151 mesg->type = l_topology_change;
152 buff += 4;
153 mesg->content.normal.flag = *buff & 0x01;
154
155 priv = (struct lec_priv *)dev->priv;
156 atm_force_charge(priv->lecd, skb2->truesize);
157 sk = sk_atm(priv->lecd);
158 skb_queue_tail(&sk->sk_receive_queue, skb2);
159 sk->sk_data_ready(sk, skb2->len);
160 }
161
162 return;
163}
164#endif
165
166
167
168
169
170
171
172
173
174
175#ifdef CONFIG_TR
176static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
177{
178 struct trh_hdr *trh;
179 unsigned int riflen, num_rdsc;
180
181 trh = (struct trh_hdr *)packet;
182 if (trh->daddr[0] & (uint8_t) 0x80)
183 return bus_mac;
184
185 if (trh->saddr[0] & TR_RII) {
186 riflen = (ntohs(trh->rcf) & TR_RCF_LEN_MASK) >> 8;
187 if ((ntohs(trh->rcf) >> 13) != 0)
188 return bus_mac;
189 } else
190 return trh->daddr;
191
192 if (riflen < 6)
193 return trh->daddr;
194
195
196 num_rdsc = (riflen / 2) - 1;
197 memset(rdesc, 0, ETH_ALEN);
198
199 if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT))
200 memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(__be16));
201 else {
202 memcpy(&rdesc[4], &trh->rseg[1], sizeof(__be16));
203 rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
204 }
205
206 return NULL;
207}
208#endif
209
210
211
212
213
214
215
216
217
218
219static int lec_open(struct net_device *dev)
220{
221 struct lec_priv *priv = (struct lec_priv *)dev->priv;
222
223 netif_start_queue(dev);
224 memset(&priv->stats, 0, sizeof(struct net_device_stats));
225
226 return 0;
227}
228
229static __inline__ void
230lec_send(struct atm_vcc *vcc, struct sk_buff *skb, struct lec_priv *priv)
231{
232 ATM_SKB(skb)->vcc = vcc;
233 ATM_SKB(skb)->atm_options = vcc->atm_options;
234
235 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
236 if (vcc->send(vcc, skb) < 0) {
237 priv->stats.tx_dropped++;
238 return;
239 }
240
241 priv->stats.tx_packets++;
242 priv->stats.tx_bytes += skb->len;
243}
244
245static void lec_tx_timeout(struct net_device *dev)
246{
247 printk(KERN_INFO "%s: tx timeout\n", dev->name);
248 dev->trans_start = jiffies;
249 netif_wake_queue(dev);
250}
251
252static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
253{
254 struct sk_buff *skb2;
255 struct lec_priv *priv = (struct lec_priv *)dev->priv;
256 struct lecdatahdr_8023 *lec_h;
257 struct atm_vcc *vcc;
258 struct lec_arp_table *entry;
259 unsigned char *dst;
260 int min_frame_size;
261#ifdef CONFIG_TR
262 unsigned char rdesc[ETH_ALEN];
263#endif
264 int is_rdesc;
265#if DUMP_PACKETS > 0
266 char buf[300];
267 int i = 0;
268#endif
269
270 pr_debug("lec_start_xmit called\n");
271 if (!priv->lecd) {
272 printk("%s:No lecd attached\n", dev->name);
273 priv->stats.tx_errors++;
274 netif_stop_queue(dev);
275 return -EUNATCH;
276 }
277
278 pr_debug("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
279 (long)skb->head, (long)skb->data, (long)skb_tail_pointer(skb),
280 (long)skb_end_pointer(skb));
281#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
282 if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
283 lec_handle_bridge(skb, dev);
284#endif
285
286
287 if (skb_headroom(skb) < 2) {
288
289 pr_debug("lec_start_xmit: reallocating skb\n");
290 skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
291 kfree_skb(skb);
292 if (skb2 == NULL)
293 return 0;
294 skb = skb2;
295 }
296 skb_push(skb, 2);
297
298
299 lec_h = (struct lecdatahdr_8023 *)skb->data;
300 lec_h->le_header = htons(priv->lecid);
301
302#ifdef CONFIG_TR
303
304
305
306
307 if (priv->is_trdev) {
308 skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
309 kfree_skb(skb);
310 if (skb2 == NULL)
311 return 0;
312 skb = skb2;
313 }
314#endif
315
316#if DUMP_PACKETS > 0
317 printk("%s: send datalen:%ld lecid:%4.4x\n", dev->name,
318 skb->len, priv->lecid);
319#if DUMP_PACKETS >= 2
320 for (i = 0; i < skb->len && i < 99; i++) {
321 sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
322 }
323#elif DUMP_PACKETS >= 1
324 for (i = 0; i < skb->len && i < 30; i++) {
325 sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
326 }
327#endif
328 if (i == skb->len)
329 printk("%s\n", buf);
330 else
331 printk("%s...\n", buf);
332#endif
333
334
335#ifdef CONFIG_TR
336 if (priv->is_trdev)
337 min_frame_size = LEC_MINIMUM_8025_SIZE;
338 else
339#endif
340 min_frame_size = LEC_MINIMUM_8023_SIZE;
341 if (skb->len < min_frame_size) {
342 if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
343 skb2 = skb_copy_expand(skb, 0,
344 min_frame_size - skb->truesize,
345 GFP_ATOMIC);
346 dev_kfree_skb(skb);
347 if (skb2 == NULL) {
348 priv->stats.tx_dropped++;
349 return 0;
350 }
351 skb = skb2;
352 }
353 skb_put(skb, min_frame_size - skb->len);
354 }
355
356
357 is_rdesc = 0;
358 dst = lec_h->h_dest;
359#ifdef CONFIG_TR
360 if (priv->is_trdev) {
361 dst = get_tr_dst(skb->data + 2, rdesc);
362 if (dst == NULL) {
363 dst = rdesc;
364 is_rdesc = 1;
365 }
366 }
367#endif
368 entry = NULL;
369 vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
370 pr_debug("%s:vcc:%p vcc_flags:%lx, entry:%p\n", dev->name,
371 vcc, vcc ? vcc->flags : 0, entry);
372 if (!vcc || !test_bit(ATM_VF_READY, &vcc->flags)) {
373 if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
374 pr_debug("%s:lec_start_xmit: queuing packet, ",
375 dev->name);
376 pr_debug("MAC address " MAC_FMT "\n",
377 lec_h->h_dest[0], lec_h->h_dest[1],
378 lec_h->h_dest[2], lec_h->h_dest[3],
379 lec_h->h_dest[4], lec_h->h_dest[5]);
380 skb_queue_tail(&entry->tx_wait, skb);
381 } else {
382 pr_debug
383 ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ",
384 dev->name);
385 pr_debug("MAC address " MAC_FMT "\n",
386 lec_h->h_dest[0], lec_h->h_dest[1],
387 lec_h->h_dest[2], lec_h->h_dest[3],
388 lec_h->h_dest[4], lec_h->h_dest[5]);
389 priv->stats.tx_dropped++;
390 dev_kfree_skb(skb);
391 }
392 goto out;
393 }
394#if DUMP_PACKETS > 0
395 printk("%s:sending to vpi:%d vci:%d\n", dev->name, vcc->vpi, vcc->vci);
396#endif
397
398 while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
399 pr_debug("lec.c: emptying tx queue, ");
400 pr_debug("MAC address " MAC_FMT "\n",
401 lec_h->h_dest[0], lec_h->h_dest[1],
402 lec_h->h_dest[2], lec_h->h_dest[3],
403 lec_h->h_dest[4], lec_h->h_dest[5]);
404 lec_send(vcc, skb2, priv);
405 }
406
407 lec_send(vcc, skb, priv);
408
409 if (!atm_may_send(vcc, 0)) {
410 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
411
412 vpriv->xoff = 1;
413 netif_stop_queue(dev);
414
415
416
417
418
419
420
421 if (atm_may_send(vcc, 0))
422 netif_wake_queue(dev);
423 }
424
425out:
426 if (entry)
427 lec_arp_put(entry);
428 dev->trans_start = jiffies;
429 return 0;
430}
431
432
433static int lec_close(struct net_device *dev)
434{
435 netif_stop_queue(dev);
436 return 0;
437}
438
439
440
441
442
443static struct net_device_stats *lec_get_stats(struct net_device *dev)
444{
445 return &((struct lec_priv *)dev->priv)->stats;
446}
447
448static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
449{
450 unsigned long flags;
451 struct net_device *dev = (struct net_device *)vcc->proto_data;
452 struct lec_priv *priv = (struct lec_priv *)dev->priv;
453 struct atmlec_msg *mesg;
454 struct lec_arp_table *entry;
455 int i;
456 char *tmp;
457
458 atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
459 mesg = (struct atmlec_msg *)skb->data;
460 tmp = skb->data;
461 tmp += sizeof(struct atmlec_msg);
462 pr_debug("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
463 switch (mesg->type) {
464 case l_set_mac_addr:
465 for (i = 0; i < 6; i++) {
466 dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
467 }
468 break;
469 case l_del_mac_addr:
470 for (i = 0; i < 6; i++) {
471 dev->dev_addr[i] = 0;
472 }
473 break;
474 case l_addr_delete:
475 lec_addr_delete(priv, mesg->content.normal.atm_addr,
476 mesg->content.normal.flag);
477 break;
478 case l_topology_change:
479 priv->topology_change = mesg->content.normal.flag;
480 break;
481 case l_flush_complete:
482 lec_flush_complete(priv, mesg->content.normal.flag);
483 break;
484 case l_narp_req:
485 spin_lock_irqsave(&priv->lec_arp_lock, flags);
486 entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
487 lec_arp_remove(priv, entry);
488 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
489
490 if (mesg->content.normal.no_source_le_narp)
491 break;
492
493 case l_arp_update:
494 lec_arp_update(priv, mesg->content.normal.mac_addr,
495 mesg->content.normal.atm_addr,
496 mesg->content.normal.flag,
497 mesg->content.normal.targetless_le_arp);
498 pr_debug("lec: in l_arp_update\n");
499 if (mesg->sizeoftlvs != 0) {
500 pr_debug("lec: LANE2 3.1.5, got tlvs, size %d\n",
501 mesg->sizeoftlvs);
502 lane2_associate_ind(dev, mesg->content.normal.mac_addr,
503 tmp, mesg->sizeoftlvs);
504 }
505 break;
506 case l_config:
507 priv->maximum_unknown_frame_count =
508 mesg->content.config.maximum_unknown_frame_count;
509 priv->max_unknown_frame_time =
510 (mesg->content.config.max_unknown_frame_time * HZ);
511 priv->max_retry_count = mesg->content.config.max_retry_count;
512 priv->aging_time = (mesg->content.config.aging_time * HZ);
513 priv->forward_delay_time =
514 (mesg->content.config.forward_delay_time * HZ);
515 priv->arp_response_time =
516 (mesg->content.config.arp_response_time * HZ);
517 priv->flush_timeout = (mesg->content.config.flush_timeout * HZ);
518 priv->path_switching_delay =
519 (mesg->content.config.path_switching_delay * HZ);
520 priv->lane_version = mesg->content.config.lane_version;
521 priv->lane2_ops = NULL;
522 if (priv->lane_version > 1)
523 priv->lane2_ops = &lane2_ops;
524 if (dev->change_mtu(dev, mesg->content.config.mtu))
525 printk("%s: change_mtu to %d failed\n", dev->name,
526 mesg->content.config.mtu);
527 priv->is_proxy = mesg->content.config.is_proxy;
528 break;
529 case l_flush_tran_id:
530 lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
531 mesg->content.normal.flag);
532 break;
533 case l_set_lecid:
534 priv->lecid =
535 (unsigned short)(0xffff & mesg->content.normal.flag);
536 break;
537 case l_should_bridge:
538#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
539 {
540 struct net_bridge_fdb_entry *f;
541
542 pr_debug
543 ("%s: bridge zeppelin asks about " MAC_FMT "\n",
544 dev->name,
545 mesg->content.proxy.mac_addr[0],
546 mesg->content.proxy.mac_addr[1],
547 mesg->content.proxy.mac_addr[2],
548 mesg->content.proxy.mac_addr[3],
549 mesg->content.proxy.mac_addr[4],
550 mesg->content.proxy.mac_addr[5]);
551
552 if (br_fdb_get_hook == NULL || dev->br_port == NULL)
553 break;
554
555 f = br_fdb_get_hook(dev->br_port->br,
556 mesg->content.proxy.mac_addr);
557 if (f != NULL && f->dst->dev != dev
558 && f->dst->state == BR_STATE_FORWARDING) {
559
560 struct sk_buff *skb2;
561 struct sock *sk;
562
563 pr_debug
564 ("%s: entry found, responding to zeppelin\n",
565 dev->name);
566 skb2 =
567 alloc_skb(sizeof(struct atmlec_msg),
568 GFP_ATOMIC);
569 if (skb2 == NULL) {
570 br_fdb_put_hook(f);
571 break;
572 }
573 skb2->len = sizeof(struct atmlec_msg);
574 skb_copy_to_linear_data(skb2, mesg,
575 sizeof(*mesg));
576 atm_force_charge(priv->lecd, skb2->truesize);
577 sk = sk_atm(priv->lecd);
578 skb_queue_tail(&sk->sk_receive_queue, skb2);
579 sk->sk_data_ready(sk, skb2->len);
580 }
581 if (f != NULL)
582 br_fdb_put_hook(f);
583 }
584#endif
585 break;
586 default:
587 printk("%s: Unknown message type %d\n", dev->name, mesg->type);
588 dev_kfree_skb(skb);
589 return -EINVAL;
590 }
591 dev_kfree_skb(skb);
592 return 0;
593}
594
595static void lec_atm_close(struct atm_vcc *vcc)
596{
597 struct sk_buff *skb;
598 struct net_device *dev = (struct net_device *)vcc->proto_data;
599 struct lec_priv *priv = (struct lec_priv *)dev->priv;
600
601 priv->lecd = NULL;
602
603
604 netif_stop_queue(dev);
605 lec_arp_destroy(priv);
606
607 if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
608 printk("%s lec_atm_close: closing with messages pending\n",
609 dev->name);
610 while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue)) != NULL) {
611 atm_return(vcc, skb->truesize);
612 dev_kfree_skb(skb);
613 }
614
615 printk("%s: Shut down!\n", dev->name);
616 module_put(THIS_MODULE);
617}
618
619static struct atmdev_ops lecdev_ops = {
620 .close = lec_atm_close,
621 .send = lec_atm_send
622};
623
624static struct atm_dev lecatm_dev = {
625 .ops = &lecdev_ops,
626 .type = "lec",
627 .number = 999,
628 .lock = __SPIN_LOCK_UNLOCKED(lecatm_dev.lock)
629};
630
631
632
633
634
635static int
636send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
637 const unsigned char *mac_addr, const unsigned char *atm_addr,
638 struct sk_buff *data)
639{
640 struct sock *sk;
641 struct sk_buff *skb;
642 struct atmlec_msg *mesg;
643
644 if (!priv || !priv->lecd) {
645 return -1;
646 }
647 skb = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
648 if (!skb)
649 return -1;
650 skb->len = sizeof(struct atmlec_msg);
651 mesg = (struct atmlec_msg *)skb->data;
652 memset(mesg, 0, sizeof(struct atmlec_msg));
653 mesg->type = type;
654 if (data != NULL)
655 mesg->sizeoftlvs = data->len;
656 if (mac_addr)
657 memcpy(&mesg->content.normal.mac_addr, mac_addr, ETH_ALEN);
658 else
659 mesg->content.normal.targetless_le_arp = 1;
660 if (atm_addr)
661 memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);
662
663 atm_force_charge(priv->lecd, skb->truesize);
664 sk = sk_atm(priv->lecd);
665 skb_queue_tail(&sk->sk_receive_queue, skb);
666 sk->sk_data_ready(sk, skb->len);
667
668 if (data != NULL) {
669 pr_debug("lec: about to send %d bytes of data\n", data->len);
670 atm_force_charge(priv->lecd, data->truesize);
671 skb_queue_tail(&sk->sk_receive_queue, data);
672 sk->sk_data_ready(sk, skb->len);
673 }
674
675 return 0;
676}
677
678
679static int lec_change_mtu(struct net_device *dev, int new_mtu)
680{
681 if ((new_mtu < 68) || (new_mtu > 18190))
682 return -EINVAL;
683 dev->mtu = new_mtu;
684 return 0;
685}
686
687static void lec_set_multicast_list(struct net_device *dev)
688{
689
690
691
692
693 return;
694}
695
696static void lec_init(struct net_device *dev)
697{
698 dev->change_mtu = lec_change_mtu;
699 dev->open = lec_open;
700 dev->stop = lec_close;
701 dev->hard_start_xmit = lec_start_xmit;
702 dev->tx_timeout = lec_tx_timeout;
703
704 dev->get_stats = lec_get_stats;
705 dev->set_multicast_list = lec_set_multicast_list;
706 dev->do_ioctl = NULL;
707 printk("%s: Initialized!\n", dev->name);
708}
709
710static const unsigned char lec_ctrl_magic[] = {
711 0xff,
712 0x00,
713 0x01,
714 0x01
715};
716
717#define LEC_DATA_DIRECT_8023 2
718#define LEC_DATA_DIRECT_8025 3
719
720static int lec_is_data_direct(struct atm_vcc *vcc)
721{
722 return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) ||
723 (vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025));
724}
725
726static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
727{
728 unsigned long flags;
729 struct net_device *dev = (struct net_device *)vcc->proto_data;
730 struct lec_priv *priv = (struct lec_priv *)dev->priv;
731
732#if DUMP_PACKETS >0
733 int i = 0;
734 char buf[300];
735
736 printk("%s: lec_push vcc vpi:%d vci:%d\n", dev->name,
737 vcc->vpi, vcc->vci);
738#endif
739 if (!skb) {
740 pr_debug("%s: null skb\n", dev->name);
741 lec_vcc_close(priv, vcc);
742 return;
743 }
744#if DUMP_PACKETS > 0
745 printk("%s: rcv datalen:%ld lecid:%4.4x\n", dev->name,
746 skb->len, priv->lecid);
747#if DUMP_PACKETS >= 2
748 for (i = 0; i < skb->len && i < 99; i++) {
749 sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
750 }
751#elif DUMP_PACKETS >= 1
752 for (i = 0; i < skb->len && i < 30; i++) {
753 sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
754 }
755#endif
756 if (i == skb->len)
757 printk("%s\n", buf);
758 else
759 printk("%s...\n", buf);
760#endif
761 if (memcmp(skb->data, lec_ctrl_magic, 4) == 0) {
762 struct sock *sk = sk_atm(vcc);
763
764 pr_debug("%s: To daemon\n", dev->name);
765 skb_queue_tail(&sk->sk_receive_queue, skb);
766 sk->sk_data_ready(sk, skb->len);
767 } else {
768 struct lec_arp_table *entry;
769 unsigned char *src, *dst;
770
771 atm_return(vcc, skb->truesize);
772 if (*(__be16 *) skb->data == htons(priv->lecid) ||
773 !priv->lecd || !(dev->flags & IFF_UP)) {
774
775
776
777
778 pr_debug("Ignoring frame...\n");
779 dev_kfree_skb(skb);
780 return;
781 }
782#ifdef CONFIG_TR
783 if (priv->is_trdev)
784 dst = ((struct lecdatahdr_8025 *)skb->data)->h_dest;
785 else
786#endif
787 dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
788
789
790
791
792
793 spin_lock_irqsave(&priv->lec_arp_lock, flags);
794 if (lec_is_data_direct(vcc)) {
795#ifdef CONFIG_TR
796 if (priv->is_trdev)
797 src =
798 ((struct lecdatahdr_8025 *)skb->data)->
799 h_source;
800 else
801#endif
802 src =
803 ((struct lecdatahdr_8023 *)skb->data)->
804 h_source;
805 entry = lec_arp_find(priv, src);
806 if (entry && entry->vcc != vcc) {
807 lec_arp_remove(priv, entry);
808 lec_arp_put(entry);
809 }
810 }
811 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
812
813 if (!(dst[0] & 0x01) &&
814 !priv->is_proxy &&
815 memcmp(dst, dev->dev_addr, dev->addr_len)) {
816 dev_kfree_skb(skb);
817 return;
818 }
819 if (!hlist_empty(&priv->lec_arp_empty_ones)) {
820 lec_arp_check_empties(priv, vcc, skb);
821 }
822 skb_pull(skb, 2);
823#ifdef CONFIG_TR
824 if (priv->is_trdev)
825 skb->protocol = tr_type_trans(skb, dev);
826 else
827#endif
828 skb->protocol = eth_type_trans(skb, dev);
829 priv->stats.rx_packets++;
830 priv->stats.rx_bytes += skb->len;
831 memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
832 netif_rx(skb);
833 }
834}
835
836static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
837{
838 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
839 struct net_device *dev = skb->dev;
840
841 if (vpriv == NULL) {
842 printk("lec_pop(): vpriv = NULL!?!?!?\n");
843 return;
844 }
845
846 vpriv->old_pop(vcc, skb);
847
848 if (vpriv->xoff && atm_may_send(vcc, 0)) {
849 vpriv->xoff = 0;
850 if (netif_running(dev) && netif_queue_stopped(dev))
851 netif_wake_queue(dev);
852 }
853}
854
855static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
856{
857 struct lec_vcc_priv *vpriv;
858 int bytes_left;
859 struct atmlec_ioc ioc_data;
860
861
862 bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
863 if (bytes_left != 0) {
864 printk
865 ("lec: lec_vcc_attach, copy from user failed for %d bytes\n",
866 bytes_left);
867 }
868 if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF ||
869 !dev_lec[ioc_data.dev_num])
870 return -EINVAL;
871 if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
872 return -ENOMEM;
873 vpriv->xoff = 0;
874 vpriv->old_pop = vcc->pop;
875 vcc->user_back = vpriv;
876 vcc->pop = lec_pop;
877 lec_vcc_added(dev_lec[ioc_data.dev_num]->priv,
878 &ioc_data, vcc, vcc->push);
879 vcc->proto_data = dev_lec[ioc_data.dev_num];
880 vcc->push = lec_push;
881 return 0;
882}
883
884static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
885{
886 if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg])
887 return -EINVAL;
888 vcc->proto_data = dev_lec[arg];
889 return (lec_mcast_make((struct lec_priv *)dev_lec[arg]->priv, vcc));
890}
891
892
893static int lecd_attach(struct atm_vcc *vcc, int arg)
894{
895 int i;
896 struct lec_priv *priv;
897
898 if (arg < 0)
899 i = 0;
900 else
901 i = arg;
902#ifdef CONFIG_TR
903 if (arg >= MAX_LEC_ITF)
904 return -EINVAL;
905#else
906 if (arg >= (MAX_LEC_ITF - NUM_TR_DEVS))
907 return -EINVAL;
908#endif
909 if (!dev_lec[i]) {
910 int is_trdev, size;
911
912 is_trdev = 0;
913 if (i >= (MAX_LEC_ITF - NUM_TR_DEVS))
914 is_trdev = 1;
915
916 size = sizeof(struct lec_priv);
917#ifdef CONFIG_TR
918 if (is_trdev)
919 dev_lec[i] = alloc_trdev(size);
920 else
921#endif
922 dev_lec[i] = alloc_etherdev(size);
923 if (!dev_lec[i])
924 return -ENOMEM;
925 snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
926 if (register_netdev(dev_lec[i])) {
927 free_netdev(dev_lec[i]);
928 return -EINVAL;
929 }
930
931 priv = dev_lec[i]->priv;
932 priv->is_trdev = is_trdev;
933 lec_init(dev_lec[i]);
934 } else {
935 priv = dev_lec[i]->priv;
936 if (priv->lecd)
937 return -EADDRINUSE;
938 }
939 lec_arp_init(priv);
940 priv->itfnum = i;
941 priv->lecd = vcc;
942 vcc->dev = &lecatm_dev;
943 vcc_insert_socket(sk_atm(vcc));
944
945 vcc->proto_data = dev_lec[i];
946 set_bit(ATM_VF_META, &vcc->flags);
947 set_bit(ATM_VF_READY, &vcc->flags);
948
949
950 priv->maximum_unknown_frame_count = 1;
951 priv->max_unknown_frame_time = (1 * HZ);
952 priv->vcc_timeout_period = (1200 * HZ);
953 priv->max_retry_count = 1;
954 priv->aging_time = (300 * HZ);
955 priv->forward_delay_time = (15 * HZ);
956 priv->topology_change = 0;
957 priv->arp_response_time = (1 * HZ);
958 priv->flush_timeout = (4 * HZ);
959 priv->path_switching_delay = (6 * HZ);
960
961 if (dev_lec[i]->flags & IFF_UP) {
962 netif_start_queue(dev_lec[i]);
963 }
964 __module_get(THIS_MODULE);
965 return i;
966}
967
968#ifdef CONFIG_PROC_FS
969static char *lec_arp_get_status_string(unsigned char status)
970{
971 static char *lec_arp_status_string[] = {
972 "ESI_UNKNOWN ",
973 "ESI_ARP_PENDING ",
974 "ESI_VC_PENDING ",
975 "<Undefined> ",
976 "ESI_FLUSH_PENDING ",
977 "ESI_FORWARD_DIRECT"
978 };
979
980 if (status > ESI_FORWARD_DIRECT)
981 status = 3;
982 return lec_arp_status_string[status];
983}
984
985static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
986{
987 int i;
988
989 for (i = 0; i < ETH_ALEN; i++)
990 seq_printf(seq, "%2.2x", entry->mac_addr[i] & 0xff);
991 seq_printf(seq, " ");
992 for (i = 0; i < ATM_ESA_LEN; i++)
993 seq_printf(seq, "%2.2x", entry->atm_addr[i] & 0xff);
994 seq_printf(seq, " %s %4.4x", lec_arp_get_status_string(entry->status),
995 entry->flags & 0xffff);
996 if (entry->vcc)
997 seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
998 else
999 seq_printf(seq, " ");
1000 if (entry->recv_vcc) {
1001 seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi,
1002 entry->recv_vcc->vci);
1003 }
1004 seq_putc(seq, '\n');
1005}
1006
1007struct lec_state {
1008 unsigned long flags;
1009 struct lec_priv *locked;
1010 struct hlist_node *node;
1011 struct net_device *dev;
1012 int itf;
1013 int arp_table;
1014 int misc_table;
1015};
1016
1017static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl,
1018 loff_t *l)
1019{
1020 struct hlist_node *e = state->node;
1021 struct lec_arp_table *tmp;
1022
1023 if (!e)
1024 e = tbl->first;
1025 if (e == SEQ_START_TOKEN) {
1026 e = tbl->first;
1027 --*l;
1028 }
1029
1030 hlist_for_each_entry_from(tmp, e, next) {
1031 if (--*l < 0)
1032 break;
1033 }
1034 state->node = e;
1035
1036 return (*l < 0) ? state : NULL;
1037}
1038
1039static void *lec_arp_walk(struct lec_state *state, loff_t *l,
1040 struct lec_priv *priv)
1041{
1042 void *v = NULL;
1043 int p;
1044
1045 for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
1046 v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l);
1047 if (v)
1048 break;
1049 }
1050 state->arp_table = p;
1051 return v;
1052}
1053
1054static void *lec_misc_walk(struct lec_state *state, loff_t *l,
1055 struct lec_priv *priv)
1056{
1057 struct hlist_head *lec_misc_tables[] = {
1058 &priv->lec_arp_empty_ones,
1059 &priv->lec_no_forward,
1060 &priv->mcast_fwds
1061 };
1062 void *v = NULL;
1063 int q;
1064
1065 for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {
1066 v = lec_tbl_walk(state, lec_misc_tables[q], l);
1067 if (v)
1068 break;
1069 }
1070 state->misc_table = q;
1071 return v;
1072}
1073
1074static void *lec_priv_walk(struct lec_state *state, loff_t *l,
1075 struct lec_priv *priv)
1076{
1077 if (!state->locked) {
1078 state->locked = priv;
1079 spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
1080 }
1081 if (!lec_arp_walk(state, l, priv) && !lec_misc_walk(state, l, priv)) {
1082 spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
1083 state->locked = NULL;
1084
1085 state->arp_table = state->misc_table = 0;
1086 }
1087 return state->locked;
1088}
1089
1090static void *lec_itf_walk(struct lec_state *state, loff_t *l)
1091{
1092 struct net_device *dev;
1093 void *v;
1094
1095 dev = state->dev ? state->dev : dev_lec[state->itf];
1096 v = (dev && dev->priv) ? lec_priv_walk(state, l, dev->priv) : NULL;
1097 if (!v && dev) {
1098 dev_put(dev);
1099
1100 dev = NULL;
1101 }
1102 state->dev = dev;
1103 return v;
1104}
1105
1106static void *lec_get_idx(struct lec_state *state, loff_t l)
1107{
1108 void *v = NULL;
1109
1110 for (; state->itf < MAX_LEC_ITF; state->itf++) {
1111 v = lec_itf_walk(state, &l);
1112 if (v)
1113 break;
1114 }
1115 return v;
1116}
1117
1118static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
1119{
1120 struct lec_state *state = seq->private;
1121
1122 state->itf = 0;
1123 state->dev = NULL;
1124 state->locked = NULL;
1125 state->arp_table = 0;
1126 state->misc_table = 0;
1127 state->node = SEQ_START_TOKEN;
1128
1129 return *pos ? lec_get_idx(state, *pos) : SEQ_START_TOKEN;
1130}
1131
1132static void lec_seq_stop(struct seq_file *seq, void *v)
1133{
1134 struct lec_state *state = seq->private;
1135
1136 if (state->dev) {
1137 spin_unlock_irqrestore(&state->locked->lec_arp_lock,
1138 state->flags);
1139 dev_put(state->dev);
1140 }
1141}
1142
1143static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1144{
1145 struct lec_state *state = seq->private;
1146
1147 v = lec_get_idx(state, 1);
1148 *pos += !!PTR_ERR(v);
1149 return v;
1150}
1151
1152static int lec_seq_show(struct seq_file *seq, void *v)
1153{
1154 static char lec_banner[] = "Itf MAC ATM destination"
1155 " Status Flags "
1156 "VPI/VCI Recv VPI/VCI\n";
1157
1158 if (v == SEQ_START_TOKEN)
1159 seq_puts(seq, lec_banner);
1160 else {
1161 struct lec_state *state = seq->private;
1162 struct net_device *dev = state->dev;
1163 struct lec_arp_table *entry = hlist_entry(state->node, struct lec_arp_table, next);
1164
1165 seq_printf(seq, "%s ", dev->name);
1166 lec_info(seq, entry);
1167 }
1168 return 0;
1169}
1170
1171static const struct seq_operations lec_seq_ops = {
1172 .start = lec_seq_start,
1173 .next = lec_seq_next,
1174 .stop = lec_seq_stop,
1175 .show = lec_seq_show,
1176};
1177
1178static int lec_seq_open(struct inode *inode, struct file *file)
1179{
1180 return seq_open_private(file, &lec_seq_ops, sizeof(struct lec_state));
1181}
1182
1183static const struct file_operations lec_seq_fops = {
1184 .owner = THIS_MODULE,
1185 .open = lec_seq_open,
1186 .read = seq_read,
1187 .llseek = seq_lseek,
1188 .release = seq_release_private,
1189};
1190#endif
1191
1192static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1193{
1194 struct atm_vcc *vcc = ATM_SD(sock);
1195 int err = 0;
1196
1197 switch (cmd) {
1198 case ATMLEC_CTRL:
1199 case ATMLEC_MCAST:
1200 case ATMLEC_DATA:
1201 if (!capable(CAP_NET_ADMIN))
1202 return -EPERM;
1203 break;
1204 default:
1205 return -ENOIOCTLCMD;
1206 }
1207
1208 switch (cmd) {
1209 case ATMLEC_CTRL:
1210 err = lecd_attach(vcc, (int)arg);
1211 if (err >= 0)
1212 sock->state = SS_CONNECTED;
1213 break;
1214 case ATMLEC_MCAST:
1215 err = lec_mcast_attach(vcc, (int)arg);
1216 break;
1217 case ATMLEC_DATA:
1218 err = lec_vcc_attach(vcc, (void __user *)arg);
1219 break;
1220 }
1221
1222 return err;
1223}
1224
1225static struct atm_ioctl lane_ioctl_ops = {
1226 .owner = THIS_MODULE,
1227 .ioctl = lane_ioctl,
1228};
1229
1230static int __init lane_module_init(void)
1231{
1232#ifdef CONFIG_PROC_FS
1233 struct proc_dir_entry *p;
1234
1235 p = proc_create("lec", S_IRUGO, atm_proc_root, &lec_seq_fops);
1236 if (!p) {
1237 printk(KERN_ERR "Unable to initialize /proc/net/atm/lec\n");
1238 return -ENOMEM;
1239 }
1240#endif
1241
1242 register_atm_ioctl(&lane_ioctl_ops);
1243 printk("lec.c: " __DATE__ " " __TIME__ " initialized\n");
1244 return 0;
1245}
1246
1247static void __exit lane_module_cleanup(void)
1248{
1249 int i;
1250 struct lec_priv *priv;
1251
1252 remove_proc_entry("lec", atm_proc_root);
1253
1254 deregister_atm_ioctl(&lane_ioctl_ops);
1255
1256 for (i = 0; i < MAX_LEC_ITF; i++) {
1257 if (dev_lec[i] != NULL) {
1258 priv = (struct lec_priv *)dev_lec[i]->priv;
1259 unregister_netdev(dev_lec[i]);
1260 free_netdev(dev_lec[i]);
1261 dev_lec[i] = NULL;
1262 }
1263 }
1264
1265 return;
1266}
1267
1268module_init(lane_module_init);
1269module_exit(lane_module_cleanup);
1270
1271
1272
1273
1274
1275
1276
1277
1278static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force,
1279 u8 **tlvs, u32 *sizeoftlvs)
1280{
1281 unsigned long flags;
1282 struct lec_priv *priv = (struct lec_priv *)dev->priv;
1283 struct lec_arp_table *table;
1284 struct sk_buff *skb;
1285 int retval;
1286
1287 if (force == 0) {
1288 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1289 table = lec_arp_find(priv, dst_mac);
1290 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1291 if (table == NULL)
1292 return -1;
1293
1294 *tlvs = kmemdup(table->tlvs, table->sizeoftlvs, GFP_ATOMIC);
1295 if (*tlvs == NULL)
1296 return -1;
1297
1298 *sizeoftlvs = table->sizeoftlvs;
1299
1300 return 0;
1301 }
1302
1303 if (sizeoftlvs == NULL)
1304 retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);
1305
1306 else {
1307 skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);
1308 if (skb == NULL)
1309 return -1;
1310 skb->len = *sizeoftlvs;
1311 skb_copy_to_linear_data(skb, *tlvs, *sizeoftlvs);
1312 retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);
1313 }
1314 return retval;
1315}
1316
1317
1318
1319
1320
1321
1322
1323
1324static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst,
1325 const u8 *tlvs, u32 sizeoftlvs)
1326{
1327 int retval;
1328 struct sk_buff *skb;
1329 struct lec_priv *priv = (struct lec_priv *)dev->priv;
1330
1331 if (compare_ether_addr(lan_dst, dev->dev_addr))
1332 return (0);
1333
1334 kfree(priv->tlvs);
1335
1336 priv->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL);
1337 if (priv->tlvs == NULL)
1338 return (0);
1339 priv->sizeoftlvs = sizeoftlvs;
1340
1341 skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
1342 if (skb == NULL)
1343 return 0;
1344 skb->len = sizeoftlvs;
1345 skb_copy_to_linear_data(skb, tlvs, sizeoftlvs);
1346 retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
1347 if (retval != 0)
1348 printk("lec.c: lane2_associate_req() failed\n");
1349
1350
1351
1352
1353 return (1);
1354}
1355
1356
1357
1358
1359
1360static void lane2_associate_ind(struct net_device *dev, const u8 *mac_addr,
1361 const u8 *tlvs, u32 sizeoftlvs)
1362{
1363
1364
1365
1366 struct lec_priv *priv = (struct lec_priv *)dev->priv;
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395 if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
1396 priv->lane2_ops->associate_indicator(dev, mac_addr,
1397 tlvs, sizeoftlvs);
1398 }
1399 return;
1400}
1401
1402
1403
1404
1405
1406
1407
1408
1409#include <linux/types.h>
1410#include <linux/timer.h>
1411#include <asm/param.h>
1412#include <asm/atomic.h>
1413#include <linux/inetdevice.h>
1414#include <net/route.h>
1415
1416
1417
1418
1419
1420
1421
1422#define DEBUG_ARP_TABLE 0
1423
1424#define LEC_ARP_REFRESH_INTERVAL (3*HZ)
1425
1426static void lec_arp_check_expire(struct work_struct *work);
1427static void lec_arp_expire_arp(unsigned long data);
1428
1429
1430
1431
1432
1433#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1))
1434
1435
1436
1437
1438static void lec_arp_init(struct lec_priv *priv)
1439{
1440 unsigned short i;
1441
1442 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1443 INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
1444 }
1445 INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
1446 INIT_HLIST_HEAD(&priv->lec_no_forward);
1447 INIT_HLIST_HEAD(&priv->mcast_fwds);
1448 spin_lock_init(&priv->lec_arp_lock);
1449 INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire);
1450 schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
1451}
1452
1453static void lec_arp_clear_vccs(struct lec_arp_table *entry)
1454{
1455 if (entry->vcc) {
1456 struct atm_vcc *vcc = entry->vcc;
1457 struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
1458 struct net_device *dev = (struct net_device *)vcc->proto_data;
1459
1460 vcc->pop = vpriv->old_pop;
1461 if (vpriv->xoff)
1462 netif_wake_queue(dev);
1463 kfree(vpriv);
1464 vcc->user_back = NULL;
1465 vcc->push = entry->old_push;
1466 vcc_release_async(vcc, -EPIPE);
1467 entry->vcc = NULL;
1468 }
1469 if (entry->recv_vcc) {
1470 entry->recv_vcc->push = entry->old_recv_push;
1471 vcc_release_async(entry->recv_vcc, -EPIPE);
1472 entry->recv_vcc = NULL;
1473 }
1474}
1475
1476
1477
1478
1479
1480static inline void
1481lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry)
1482{
1483 struct hlist_head *tmp;
1484
1485 tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])];
1486 hlist_add_head(&entry->next, tmp);
1487
1488 pr_debug("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1489 0xff & entry->mac_addr[0], 0xff & entry->mac_addr[1],
1490 0xff & entry->mac_addr[2], 0xff & entry->mac_addr[3],
1491 0xff & entry->mac_addr[4], 0xff & entry->mac_addr[5]);
1492}
1493
1494
1495
1496
1497static int
1498lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
1499{
1500 struct hlist_node *node;
1501 struct lec_arp_table *entry;
1502 int i, remove_vcc = 1;
1503
1504 if (!to_remove) {
1505 return -1;
1506 }
1507
1508 hlist_del(&to_remove->next);
1509 del_timer(&to_remove->timer);
1510
1511
1512 if (to_remove->status >= ESI_FLUSH_PENDING) {
1513
1514
1515
1516 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1517 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
1518 if (memcmp(to_remove->atm_addr,
1519 entry->atm_addr, ATM_ESA_LEN) == 0) {
1520 remove_vcc = 0;
1521 break;
1522 }
1523 }
1524 }
1525 if (remove_vcc)
1526 lec_arp_clear_vccs(to_remove);
1527 }
1528 skb_queue_purge(&to_remove->tx_wait);
1529
1530 pr_debug("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1531 0xff & to_remove->mac_addr[0], 0xff & to_remove->mac_addr[1],
1532 0xff & to_remove->mac_addr[2], 0xff & to_remove->mac_addr[3],
1533 0xff & to_remove->mac_addr[4], 0xff & to_remove->mac_addr[5]);
1534 return 0;
1535}
1536
1537#if DEBUG_ARP_TABLE
1538static char *get_status_string(unsigned char st)
1539{
1540 switch (st) {
1541 case ESI_UNKNOWN:
1542 return "ESI_UNKNOWN";
1543 case ESI_ARP_PENDING:
1544 return "ESI_ARP_PENDING";
1545 case ESI_VC_PENDING:
1546 return "ESI_VC_PENDING";
1547 case ESI_FLUSH_PENDING:
1548 return "ESI_FLUSH_PENDING";
1549 case ESI_FORWARD_DIRECT:
1550 return "ESI_FORWARD_DIRECT";
1551 default:
1552 return "<UNKNOWN>";
1553 }
1554}
1555
1556static void dump_arp_table(struct lec_priv *priv)
1557{
1558 struct hlist_node *node;
1559 struct lec_arp_table *rulla;
1560 char buf[256];
1561 int i, j, offset;
1562
1563 printk("Dump %p:\n", priv);
1564 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1565 hlist_for_each_entry(rulla, node, &priv->lec_arp_tables[i], next) {
1566 offset = 0;
1567 offset += sprintf(buf, "%d: %p\n", i, rulla);
1568 offset += sprintf(buf + offset, "Mac:");
1569 for (j = 0; j < ETH_ALEN; j++) {
1570 offset += sprintf(buf + offset,
1571 "%2.2x ",
1572 rulla->mac_addr[j] & 0xff);
1573 }
1574 offset += sprintf(buf + offset, "Atm:");
1575 for (j = 0; j < ATM_ESA_LEN; j++) {
1576 offset += sprintf(buf + offset,
1577 "%2.2x ",
1578 rulla->atm_addr[j] & 0xff);
1579 }
1580 offset += sprintf(buf + offset,
1581 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1582 rulla->vcc ? rulla->vcc->vpi : 0,
1583 rulla->vcc ? rulla->vcc->vci : 0,
1584 rulla->recv_vcc ? rulla->recv_vcc->
1585 vpi : 0,
1586 rulla->recv_vcc ? rulla->recv_vcc->
1587 vci : 0, rulla->last_used,
1588 rulla->timestamp, rulla->no_tries);
1589 offset +=
1590 sprintf(buf + offset,
1591 "Flags:%x, Packets_flooded:%x, Status: %s ",
1592 rulla->flags, rulla->packets_flooded,
1593 get_status_string(rulla->status));
1594 printk("%s\n", buf);
1595 }
1596 }
1597
1598 if (!hlist_empty(&priv->lec_no_forward))
1599 printk("No forward\n");
1600 hlist_for_each_entry(rulla, node, &priv->lec_no_forward, next) {
1601 offset = 0;
1602 offset += sprintf(buf + offset, "Mac:");
1603 for (j = 0; j < ETH_ALEN; j++) {
1604 offset += sprintf(buf + offset, "%2.2x ",
1605 rulla->mac_addr[j] & 0xff);
1606 }
1607 offset += sprintf(buf + offset, "Atm:");
1608 for (j = 0; j < ATM_ESA_LEN; j++) {
1609 offset += sprintf(buf + offset, "%2.2x ",
1610 rulla->atm_addr[j] & 0xff);
1611 }
1612 offset += sprintf(buf + offset,
1613 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1614 rulla->vcc ? rulla->vcc->vpi : 0,
1615 rulla->vcc ? rulla->vcc->vci : 0,
1616 rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
1617 rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
1618 rulla->last_used,
1619 rulla->timestamp, rulla->no_tries);
1620 offset += sprintf(buf + offset,
1621 "Flags:%x, Packets_flooded:%x, Status: %s ",
1622 rulla->flags, rulla->packets_flooded,
1623 get_status_string(rulla->status));
1624 printk("%s\n", buf);
1625 }
1626
1627 if (!hlist_empty(&priv->lec_arp_empty_ones))
1628 printk("Empty ones\n");
1629 hlist_for_each_entry(rulla, node, &priv->lec_arp_empty_ones, next) {
1630 offset = 0;
1631 offset += sprintf(buf + offset, "Mac:");
1632 for (j = 0; j < ETH_ALEN; j++) {
1633 offset += sprintf(buf + offset, "%2.2x ",
1634 rulla->mac_addr[j] & 0xff);
1635 }
1636 offset += sprintf(buf + offset, "Atm:");
1637 for (j = 0; j < ATM_ESA_LEN; j++) {
1638 offset += sprintf(buf + offset, "%2.2x ",
1639 rulla->atm_addr[j] & 0xff);
1640 }
1641 offset += sprintf(buf + offset,
1642 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1643 rulla->vcc ? rulla->vcc->vpi : 0,
1644 rulla->vcc ? rulla->vcc->vci : 0,
1645 rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
1646 rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
1647 rulla->last_used,
1648 rulla->timestamp, rulla->no_tries);
1649 offset += sprintf(buf + offset,
1650 "Flags:%x, Packets_flooded:%x, Status: %s ",
1651 rulla->flags, rulla->packets_flooded,
1652 get_status_string(rulla->status));
1653 printk("%s", buf);
1654 }
1655
1656 if (!hlist_empty(&priv->mcast_fwds))
1657 printk("Multicast Forward VCCs\n");
1658 hlist_for_each_entry(rulla, node, &priv->mcast_fwds, next) {
1659 offset = 0;
1660 offset += sprintf(buf + offset, "Mac:");
1661 for (j = 0; j < ETH_ALEN; j++) {
1662 offset += sprintf(buf + offset, "%2.2x ",
1663 rulla->mac_addr[j] & 0xff);
1664 }
1665 offset += sprintf(buf + offset, "Atm:");
1666 for (j = 0; j < ATM_ESA_LEN; j++) {
1667 offset += sprintf(buf + offset, "%2.2x ",
1668 rulla->atm_addr[j] & 0xff);
1669 }
1670 offset += sprintf(buf + offset,
1671 "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
1672 rulla->vcc ? rulla->vcc->vpi : 0,
1673 rulla->vcc ? rulla->vcc->vci : 0,
1674 rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
1675 rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
1676 rulla->last_used,
1677 rulla->timestamp, rulla->no_tries);
1678 offset += sprintf(buf + offset,
1679 "Flags:%x, Packets_flooded:%x, Status: %s ",
1680 rulla->flags, rulla->packets_flooded,
1681 get_status_string(rulla->status));
1682 printk("%s\n", buf);
1683 }
1684
1685}
1686#else
1687#define dump_arp_table(priv) do { } while (0)
1688#endif
1689
1690
1691
1692
1693static void lec_arp_destroy(struct lec_priv *priv)
1694{
1695 unsigned long flags;
1696 struct hlist_node *node, *next;
1697 struct lec_arp_table *entry;
1698 int i;
1699
1700 cancel_rearming_delayed_work(&priv->lec_arp_work);
1701
1702
1703
1704
1705
1706 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1707 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1708 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
1709 lec_arp_remove(priv, entry);
1710 lec_arp_put(entry);
1711 }
1712 INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
1713 }
1714
1715 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
1716 del_timer_sync(&entry->timer);
1717 lec_arp_clear_vccs(entry);
1718 hlist_del(&entry->next);
1719 lec_arp_put(entry);
1720 }
1721 INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
1722
1723 hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
1724 del_timer_sync(&entry->timer);
1725 lec_arp_clear_vccs(entry);
1726 hlist_del(&entry->next);
1727 lec_arp_put(entry);
1728 }
1729 INIT_HLIST_HEAD(&priv->lec_no_forward);
1730
1731 hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
1732
1733 lec_arp_clear_vccs(entry);
1734 hlist_del(&entry->next);
1735 lec_arp_put(entry);
1736 }
1737 INIT_HLIST_HEAD(&priv->mcast_fwds);
1738 priv->mcast_vcc = NULL;
1739 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1740}
1741
1742
1743
1744
1745static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
1746 const unsigned char *mac_addr)
1747{
1748 struct hlist_node *node;
1749 struct hlist_head *head;
1750 struct lec_arp_table *entry;
1751
1752 pr_debug("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
1753 mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff,
1754 mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff);
1755
1756 head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])];
1757 hlist_for_each_entry(entry, node, head, next) {
1758 if (!compare_ether_addr(mac_addr, entry->mac_addr)) {
1759 return entry;
1760 }
1761 }
1762 return NULL;
1763}
1764
1765static struct lec_arp_table *make_entry(struct lec_priv *priv,
1766 const unsigned char *mac_addr)
1767{
1768 struct lec_arp_table *to_return;
1769
1770 to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
1771 if (!to_return) {
1772 printk("LEC: Arp entry kmalloc failed\n");
1773 return NULL;
1774 }
1775 memcpy(to_return->mac_addr, mac_addr, ETH_ALEN);
1776 INIT_HLIST_NODE(&to_return->next);
1777 setup_timer(&to_return->timer, lec_arp_expire_arp,
1778 (unsigned long)to_return);
1779 to_return->last_used = jiffies;
1780 to_return->priv = priv;
1781 skb_queue_head_init(&to_return->tx_wait);
1782 atomic_set(&to_return->usage, 1);
1783 return to_return;
1784}
1785
1786
1787static void lec_arp_expire_arp(unsigned long data)
1788{
1789 struct lec_arp_table *entry;
1790
1791 entry = (struct lec_arp_table *)data;
1792
1793 pr_debug("lec_arp_expire_arp\n");
1794 if (entry->status == ESI_ARP_PENDING) {
1795 if (entry->no_tries <= entry->priv->max_retry_count) {
1796 if (entry->is_rdesc)
1797 send_to_lecd(entry->priv, l_rdesc_arp_xmt,
1798 entry->mac_addr, NULL, NULL);
1799 else
1800 send_to_lecd(entry->priv, l_arp_xmt,
1801 entry->mac_addr, NULL, NULL);
1802 entry->no_tries++;
1803 }
1804 mod_timer(&entry->timer, jiffies + (1 * HZ));
1805 }
1806}
1807
1808
1809static void lec_arp_expire_vcc(unsigned long data)
1810{
1811 unsigned long flags;
1812 struct lec_arp_table *to_remove = (struct lec_arp_table *)data;
1813 struct lec_priv *priv = (struct lec_priv *)to_remove->priv;
1814
1815 del_timer(&to_remove->timer);
1816
1817 pr_debug("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n",
1818 to_remove, priv,
1819 to_remove->vcc ? to_remove->recv_vcc->vpi : 0,
1820 to_remove->vcc ? to_remove->recv_vcc->vci : 0);
1821
1822 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1823 hlist_del(&to_remove->next);
1824 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1825
1826 lec_arp_clear_vccs(to_remove);
1827 lec_arp_put(to_remove);
1828}
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846static void lec_arp_check_expire(struct work_struct *work)
1847{
1848 unsigned long flags;
1849 struct lec_priv *priv =
1850 container_of(work, struct lec_priv, lec_arp_work.work);
1851 struct hlist_node *node, *next;
1852 struct lec_arp_table *entry;
1853 unsigned long now;
1854 unsigned long time_to_check;
1855 int i;
1856
1857 pr_debug("lec_arp_check_expire %p\n", priv);
1858 now = jiffies;
1859restart:
1860 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1861 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
1862 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
1863 if ((entry->flags) & LEC_REMOTE_FLAG &&
1864 priv->topology_change)
1865 time_to_check = priv->forward_delay_time;
1866 else
1867 time_to_check = priv->aging_time;
1868
1869 pr_debug("About to expire: %lx - %lx > %lx\n",
1870 now, entry->last_used, time_to_check);
1871 if (time_after(now, entry->last_used + time_to_check)
1872 && !(entry->flags & LEC_PERMANENT_FLAG)
1873 && !(entry->mac_addr[0] & 0x01)) {
1874
1875 pr_debug("LEC:Entry timed out\n");
1876 lec_arp_remove(priv, entry);
1877 lec_arp_put(entry);
1878 } else {
1879
1880 if ((entry->status == ESI_VC_PENDING ||
1881 entry->status == ESI_ARP_PENDING)
1882 && time_after_eq(now,
1883 entry->timestamp +
1884 priv->
1885 max_unknown_frame_time)) {
1886 entry->timestamp = jiffies;
1887 entry->packets_flooded = 0;
1888 if (entry->status == ESI_VC_PENDING)
1889 send_to_lecd(priv, l_svc_setup,
1890 entry->mac_addr,
1891 entry->atm_addr,
1892 NULL);
1893 }
1894 if (entry->status == ESI_FLUSH_PENDING
1895 &&
1896 time_after_eq(now, entry->timestamp +
1897 priv->path_switching_delay)) {
1898 struct sk_buff *skb;
1899 struct atm_vcc *vcc = entry->vcc;
1900
1901 lec_arp_hold(entry);
1902 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1903 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
1904 lec_send(vcc, skb, entry->priv);
1905 entry->last_used = jiffies;
1906 entry->status = ESI_FORWARD_DIRECT;
1907 lec_arp_put(entry);
1908 goto restart;
1909 }
1910 }
1911 }
1912 }
1913 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
1914
1915 schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
1916}
1917
1918
1919
1920
1921
1922static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
1923 const unsigned char *mac_to_find, int is_rdesc,
1924 struct lec_arp_table **ret_entry)
1925{
1926 unsigned long flags;
1927 struct lec_arp_table *entry;
1928 struct atm_vcc *found;
1929
1930 if (mac_to_find[0] & 0x01) {
1931 switch (priv->lane_version) {
1932 case 1:
1933 return priv->mcast_vcc;
1934 case 2:
1935 if (!compare_ether_addr(mac_to_find, bus_mac))
1936 return priv->mcast_vcc;
1937 break;
1938 default:
1939 break;
1940 }
1941 }
1942
1943 spin_lock_irqsave(&priv->lec_arp_lock, flags);
1944 entry = lec_arp_find(priv, mac_to_find);
1945
1946 if (entry) {
1947 if (entry->status == ESI_FORWARD_DIRECT) {
1948
1949 entry->last_used = jiffies;
1950 lec_arp_hold(entry);
1951 *ret_entry = entry;
1952 found = entry->vcc;
1953 goto out;
1954 }
1955
1956
1957
1958
1959 if (entry->status == ESI_ARP_PENDING) {
1960 entry->no_tries = 0;
1961 }
1962
1963
1964
1965
1966
1967
1968 if (entry->status != ESI_FLUSH_PENDING &&
1969 entry->packets_flooded <
1970 priv->maximum_unknown_frame_count) {
1971 entry->packets_flooded++;
1972 pr_debug("LEC_ARP: Flooding..\n");
1973 found = priv->mcast_vcc;
1974 goto out;
1975 }
1976
1977
1978
1979
1980
1981 lec_arp_hold(entry);
1982 *ret_entry = entry;
1983 pr_debug("lec: entry->status %d entry->vcc %p\n", entry->status,
1984 entry->vcc);
1985 found = NULL;
1986 } else {
1987
1988 entry = make_entry(priv, mac_to_find);
1989 pr_debug("LEC_ARP: Making entry\n");
1990 if (!entry) {
1991 found = priv->mcast_vcc;
1992 goto out;
1993 }
1994 lec_arp_add(priv, entry);
1995
1996 entry->packets_flooded = 1;
1997 entry->status = ESI_ARP_PENDING;
1998 entry->no_tries = 1;
1999 entry->last_used = entry->timestamp = jiffies;
2000 entry->is_rdesc = is_rdesc;
2001 if (entry->is_rdesc)
2002 send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL,
2003 NULL);
2004 else
2005 send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
2006 entry->timer.expires = jiffies + (1 * HZ);
2007 entry->timer.function = lec_arp_expire_arp;
2008 add_timer(&entry->timer);
2009 found = priv->mcast_vcc;
2010 }
2011
2012out:
2013 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2014 return found;
2015}
2016
2017static int
2018lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr,
2019 unsigned long permanent)
2020{
2021 unsigned long flags;
2022 struct hlist_node *node, *next;
2023 struct lec_arp_table *entry;
2024 int i;
2025
2026 pr_debug("lec_addr_delete\n");
2027 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2028 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2029 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
2030 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)
2031 && (permanent ||
2032 !(entry->flags & LEC_PERMANENT_FLAG))) {
2033 lec_arp_remove(priv, entry);
2034 lec_arp_put(entry);
2035 }
2036 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2037 return 0;
2038 }
2039 }
2040 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2041 return -1;
2042}
2043
2044
2045
2046
2047static void
2048lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr,
2049 const unsigned char *atm_addr, unsigned long remoteflag,
2050 unsigned int targetless_le_arp)
2051{
2052 unsigned long flags;
2053 struct hlist_node *node, *next;
2054 struct lec_arp_table *entry, *tmp;
2055 int i;
2056
2057 pr_debug("lec:%s", (targetless_le_arp) ? "targetless " : " ");
2058 pr_debug("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
2059 mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3],
2060 mac_addr[4], mac_addr[5]);
2061
2062 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2063 entry = lec_arp_find(priv, mac_addr);
2064 if (entry == NULL && targetless_le_arp)
2065 goto out;
2066
2067
2068
2069 if (!hlist_empty(&priv->lec_arp_empty_ones)) {
2070 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
2071 if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) {
2072 hlist_del(&entry->next);
2073 del_timer(&entry->timer);
2074 tmp = lec_arp_find(priv, mac_addr);
2075 if (tmp) {
2076 del_timer(&tmp->timer);
2077 tmp->status = ESI_FORWARD_DIRECT;
2078 memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
2079 tmp->vcc = entry->vcc;
2080 tmp->old_push = entry->old_push;
2081 tmp->last_used = jiffies;
2082 del_timer(&entry->timer);
2083 lec_arp_put(entry);
2084 entry = tmp;
2085 } else {
2086 entry->status = ESI_FORWARD_DIRECT;
2087 memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
2088 entry->last_used = jiffies;
2089 lec_arp_add(priv, entry);
2090 }
2091 if (remoteflag)
2092 entry->flags |= LEC_REMOTE_FLAG;
2093 else
2094 entry->flags &= ~LEC_REMOTE_FLAG;
2095 pr_debug("After update\n");
2096 dump_arp_table(priv);
2097 goto out;
2098 }
2099 }
2100 }
2101
2102 entry = lec_arp_find(priv, mac_addr);
2103 if (!entry) {
2104 entry = make_entry(priv, mac_addr);
2105 if (!entry)
2106 goto out;
2107 entry->status = ESI_UNKNOWN;
2108 lec_arp_add(priv, entry);
2109
2110 }
2111 memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
2112 del_timer(&entry->timer);
2113 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2114 hlist_for_each_entry(tmp, node, &priv->lec_arp_tables[i], next) {
2115 if (entry != tmp &&
2116 !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) {
2117
2118 if (tmp->status > ESI_VC_PENDING) {
2119
2120
2121
2122
2123 entry->vcc = tmp->vcc;
2124 entry->old_push = tmp->old_push;
2125 }
2126 entry->status = tmp->status;
2127 break;
2128 }
2129 }
2130 }
2131 if (remoteflag)
2132 entry->flags |= LEC_REMOTE_FLAG;
2133 else
2134 entry->flags &= ~LEC_REMOTE_FLAG;
2135 if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) {
2136 entry->status = ESI_VC_PENDING;
2137 send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
2138 }
2139 pr_debug("After update2\n");
2140 dump_arp_table(priv);
2141out:
2142 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2143}
2144
2145
2146
2147
2148static void
2149lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data,
2150 struct atm_vcc *vcc,
2151 void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb))
2152{
2153 unsigned long flags;
2154 struct hlist_node *node;
2155 struct lec_arp_table *entry;
2156 int i, found_entry = 0;
2157
2158 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2159 if (ioc_data->receive == 2) {
2160
2161
2162 pr_debug("LEC_ARP: Attaching mcast forward\n");
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173 entry = make_entry(priv, bus_mac);
2174 if (entry == NULL)
2175 goto out;
2176 del_timer(&entry->timer);
2177 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2178 entry->recv_vcc = vcc;
2179 entry->old_recv_push = old_push;
2180 hlist_add_head(&entry->next, &priv->mcast_fwds);
2181 goto out;
2182 } else if (ioc_data->receive == 1) {
2183
2184
2185
2186
2187 pr_debug
2188 ("LEC_ARP:Attaching data direct, not default: "
2189 "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
2190 ioc_data->atm_addr[0], ioc_data->atm_addr[1],
2191 ioc_data->atm_addr[2], ioc_data->atm_addr[3],
2192 ioc_data->atm_addr[4], ioc_data->atm_addr[5],
2193 ioc_data->atm_addr[6], ioc_data->atm_addr[7],
2194 ioc_data->atm_addr[8], ioc_data->atm_addr[9],
2195 ioc_data->atm_addr[10], ioc_data->atm_addr[11],
2196 ioc_data->atm_addr[12], ioc_data->atm_addr[13],
2197 ioc_data->atm_addr[14], ioc_data->atm_addr[15],
2198 ioc_data->atm_addr[16], ioc_data->atm_addr[17],
2199 ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
2200 entry = make_entry(priv, bus_mac);
2201 if (entry == NULL)
2202 goto out;
2203 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2204 memset(entry->mac_addr, 0, ETH_ALEN);
2205 entry->recv_vcc = vcc;
2206 entry->old_recv_push = old_push;
2207 entry->status = ESI_UNKNOWN;
2208 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2209 entry->timer.function = lec_arp_expire_vcc;
2210 hlist_add_head(&entry->next, &priv->lec_no_forward);
2211 add_timer(&entry->timer);
2212 dump_arp_table(priv);
2213 goto out;
2214 }
2215 pr_debug
2216 ("LEC_ARP:Attaching data direct, default: "
2217 "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
2218 ioc_data->atm_addr[0], ioc_data->atm_addr[1],
2219 ioc_data->atm_addr[2], ioc_data->atm_addr[3],
2220 ioc_data->atm_addr[4], ioc_data->atm_addr[5],
2221 ioc_data->atm_addr[6], ioc_data->atm_addr[7],
2222 ioc_data->atm_addr[8], ioc_data->atm_addr[9],
2223 ioc_data->atm_addr[10], ioc_data->atm_addr[11],
2224 ioc_data->atm_addr[12], ioc_data->atm_addr[13],
2225 ioc_data->atm_addr[14], ioc_data->atm_addr[15],
2226 ioc_data->atm_addr[16], ioc_data->atm_addr[17],
2227 ioc_data->atm_addr[18], ioc_data->atm_addr[19]);
2228 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2229 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2230 if (memcmp
2231 (ioc_data->atm_addr, entry->atm_addr,
2232 ATM_ESA_LEN) == 0) {
2233 pr_debug("LEC_ARP: Attaching data direct\n");
2234 pr_debug("Currently -> Vcc: %d, Rvcc:%d\n",
2235 entry->vcc ? entry->vcc->vci : 0,
2236 entry->recv_vcc ? entry->recv_vcc->
2237 vci : 0);
2238 found_entry = 1;
2239 del_timer(&entry->timer);
2240 entry->vcc = vcc;
2241 entry->old_push = old_push;
2242 if (entry->status == ESI_VC_PENDING) {
2243 if (priv->maximum_unknown_frame_count
2244 == 0)
2245 entry->status =
2246 ESI_FORWARD_DIRECT;
2247 else {
2248 entry->timestamp = jiffies;
2249 entry->status =
2250 ESI_FLUSH_PENDING;
2251
2252
2253
2254
2255
2256
2257 }
2258 } else {
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270 ;
2271 }
2272 }
2273 }
2274 }
2275 if (found_entry) {
2276 pr_debug("After vcc was added\n");
2277 dump_arp_table(priv);
2278 goto out;
2279 }
2280
2281
2282
2283
2284 entry = make_entry(priv, bus_mac);
2285 if (!entry)
2286 goto out;
2287 entry->vcc = vcc;
2288 entry->old_push = old_push;
2289 memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
2290 memset(entry->mac_addr, 0, ETH_ALEN);
2291 entry->status = ESI_UNKNOWN;
2292 hlist_add_head(&entry->next, &priv->lec_arp_empty_ones);
2293 entry->timer.expires = jiffies + priv->vcc_timeout_period;
2294 entry->timer.function = lec_arp_expire_vcc;
2295 add_timer(&entry->timer);
2296 pr_debug("After vcc was added\n");
2297 dump_arp_table(priv);
2298out:
2299 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2300}
2301
2302static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
2303{
2304 unsigned long flags;
2305 struct hlist_node *node;
2306 struct lec_arp_table *entry;
2307 int i;
2308
2309 pr_debug("LEC:lec_flush_complete %lx\n", tran_id);
2310restart:
2311 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2312 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2313 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2314 if (entry->flush_tran_id == tran_id
2315 && entry->status == ESI_FLUSH_PENDING) {
2316 struct sk_buff *skb;
2317 struct atm_vcc *vcc = entry->vcc;
2318
2319 lec_arp_hold(entry);
2320 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2321 while ((skb = skb_dequeue(&entry->tx_wait)) != NULL)
2322 lec_send(vcc, skb, entry->priv);
2323 entry->last_used = jiffies;
2324 entry->status = ESI_FORWARD_DIRECT;
2325 lec_arp_put(entry);
2326 pr_debug("LEC_ARP: Flushed\n");
2327 goto restart;
2328 }
2329 }
2330 }
2331 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2332 dump_arp_table(priv);
2333}
2334
2335static void
2336lec_set_flush_tran_id(struct lec_priv *priv,
2337 const unsigned char *atm_addr, unsigned long tran_id)
2338{
2339 unsigned long flags;
2340 struct hlist_node *node;
2341 struct lec_arp_table *entry;
2342 int i;
2343
2344 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2345 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
2346 hlist_for_each_entry(entry, node, &priv->lec_arp_tables[i], next) {
2347 if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
2348 entry->flush_tran_id = tran_id;
2349 pr_debug("Set flush transaction id to %lx for %p\n",
2350 tran_id, entry);
2351 }
2352 }
2353 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2354}
2355
2356static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
2357{
2358 unsigned long flags;
2359 unsigned char mac_addr[] = {
2360 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2361 };
2362 struct lec_arp_table *to_add;
2363 struct lec_vcc_priv *vpriv;
2364 int err = 0;
2365
2366 if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL)))
2367 return -ENOMEM;
2368 vpriv->xoff = 0;
2369 vpriv->old_pop = vcc->pop;
2370 vcc->user_back = vpriv;
2371 vcc->pop = lec_pop;
2372 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2373 to_add = make_entry(priv, mac_addr);
2374 if (!to_add) {
2375 vcc->pop = vpriv->old_pop;
2376 kfree(vpriv);
2377 err = -ENOMEM;
2378 goto out;
2379 }
2380 memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
2381 to_add->status = ESI_FORWARD_DIRECT;
2382 to_add->flags |= LEC_PERMANENT_FLAG;
2383 to_add->vcc = vcc;
2384 to_add->old_push = vcc->push;
2385 vcc->push = lec_push;
2386 priv->mcast_vcc = vcc;
2387 lec_arp_add(priv, to_add);
2388out:
2389 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2390 return err;
2391}
2392
2393static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
2394{
2395 unsigned long flags;
2396 struct hlist_node *node, *next;
2397 struct lec_arp_table *entry;
2398 int i;
2399
2400 pr_debug("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci);
2401 dump_arp_table(priv);
2402
2403 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2404
2405 for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
2406 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_tables[i], next) {
2407 if (vcc == entry->vcc) {
2408 lec_arp_remove(priv, entry);
2409 lec_arp_put(entry);
2410 if (priv->mcast_vcc == vcc) {
2411 priv->mcast_vcc = NULL;
2412 }
2413 }
2414 }
2415 }
2416
2417 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
2418 if (entry->vcc == vcc) {
2419 lec_arp_clear_vccs(entry);
2420 del_timer(&entry->timer);
2421 hlist_del(&entry->next);
2422 lec_arp_put(entry);
2423 }
2424 }
2425
2426 hlist_for_each_entry_safe(entry, node, next, &priv->lec_no_forward, next) {
2427 if (entry->recv_vcc == vcc) {
2428 lec_arp_clear_vccs(entry);
2429 del_timer(&entry->timer);
2430 hlist_del(&entry->next);
2431 lec_arp_put(entry);
2432 }
2433 }
2434
2435 hlist_for_each_entry_safe(entry, node, next, &priv->mcast_fwds, next) {
2436 if (entry->recv_vcc == vcc) {
2437 lec_arp_clear_vccs(entry);
2438
2439 hlist_del(&entry->next);
2440 lec_arp_put(entry);
2441 }
2442 }
2443
2444 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2445 dump_arp_table(priv);
2446}
2447
2448static void
2449lec_arp_check_empties(struct lec_priv *priv,
2450 struct atm_vcc *vcc, struct sk_buff *skb)
2451{
2452 unsigned long flags;
2453 struct hlist_node *node, *next;
2454 struct lec_arp_table *entry, *tmp;
2455 struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
2456 unsigned char *src;
2457#ifdef CONFIG_TR
2458 struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
2459
2460 if (priv->is_trdev)
2461 src = tr_hdr->h_source;
2462 else
2463#endif
2464 src = hdr->h_source;
2465
2466 spin_lock_irqsave(&priv->lec_arp_lock, flags);
2467 hlist_for_each_entry_safe(entry, node, next, &priv->lec_arp_empty_ones, next) {
2468 if (vcc == entry->vcc) {
2469 del_timer(&entry->timer);
2470 memcpy(entry->mac_addr, src, ETH_ALEN);
2471 entry->status = ESI_FORWARD_DIRECT;
2472 entry->last_used = jiffies;
2473
2474 if ((tmp = lec_arp_find(priv, src))) {
2475 lec_arp_remove(priv, tmp);
2476 lec_arp_put(tmp);
2477 }
2478 hlist_del(&entry->next);
2479 lec_arp_add(priv, entry);
2480 goto out;
2481 }
2482 }
2483 pr_debug("LEC_ARP: Arp_check_empties: entry not found!\n");
2484out:
2485 spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
2486}
2487
2488MODULE_LICENSE("GPL");