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