aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/br2684.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/br2684.c')
-rw-r--r--net/atm/br2684.c150
1 files changed, 97 insertions, 53 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index c9230c398697..ad2b232a2055 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -6,6 +6,8 @@
6 * Eric Kinzie, 2006-2007, US Naval Research Laboratory 6 * Eric Kinzie, 2006-2007, US Naval Research Laboratory
7 */ 7 */
8 8
9#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
10
9#include <linux/module.h> 11#include <linux/module.h>
10#include <linux/init.h> 12#include <linux/init.h>
11#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -15,7 +17,8 @@
15#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
16#include <linux/rtnetlink.h> 18#include <linux/rtnetlink.h>
17#include <linux/ip.h> 19#include <linux/ip.h>
18#include <asm/uaccess.h> 20#include <linux/uaccess.h>
21#include <linux/slab.h>
19#include <net/arp.h> 22#include <net/arp.h>
20#include <linux/atm.h> 23#include <linux/atm.h>
21#include <linux/atmdev.h> 24#include <linux/atmdev.h>
@@ -26,20 +29,14 @@
26 29
27#include "common.h" 30#include "common.h"
28 31
29#ifdef SKB_DEBUG
30static void skb_debug(const struct sk_buff *skb) 32static void skb_debug(const struct sk_buff *skb)
31{ 33{
34#ifdef SKB_DEBUG
32#define NUM2PRINT 50 35#define NUM2PRINT 50
33 char buf[NUM2PRINT * 3 + 1]; /* 3 chars per byte */ 36 print_hex_dump(KERN_DEBUG, "br2684: skb: ", DUMP_OFFSET,
34 int i = 0; 37 16, 1, skb->data, min(NUM2PRINT, skb->len), true);
35 for (i = 0; i < skb->len && i < NUM2PRINT; i++) {
36 sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
37 }
38 printk(KERN_DEBUG "br2684: skb: %s\n", buf);
39}
40#else
41#define skb_debug(skb) do {} while (0)
42#endif 38#endif
39}
43 40
44#define BR2684_ETHERTYPE_LEN 2 41#define BR2684_ETHERTYPE_LEN 2
45#define BR2684_PAD_LEN 2 42#define BR2684_PAD_LEN 2
@@ -68,7 +65,7 @@ struct br2684_vcc {
68 struct atm_vcc *atmvcc; 65 struct atm_vcc *atmvcc;
69 struct net_device *device; 66 struct net_device *device;
70 /* keep old push, pop functions for chaining */ 67 /* keep old push, pop functions for chaining */
71 void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb); 68 void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb);
72 void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); 69 void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
73 enum br2684_encaps encaps; 70 enum br2684_encaps encaps;
74 struct list_head brvccs; 71 struct list_head brvccs;
@@ -142,13 +139,50 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
142 return NULL; 139 return NULL;
143} 140}
144 141
142static int atm_dev_event(struct notifier_block *this, unsigned long event,
143 void *arg)
144{
145 struct atm_dev *atm_dev = arg;
146 struct list_head *lh;
147 struct net_device *net_dev;
148 struct br2684_vcc *brvcc;
149 struct atm_vcc *atm_vcc;
150 unsigned long flags;
151
152 pr_debug("event=%ld dev=%p\n", event, atm_dev);
153
154 read_lock_irqsave(&devs_lock, flags);
155 list_for_each(lh, &br2684_devs) {
156 net_dev = list_entry_brdev(lh);
157
158 list_for_each_entry(brvcc, &BRPRIV(net_dev)->brvccs, brvccs) {
159 atm_vcc = brvcc->atmvcc;
160 if (atm_vcc && brvcc->atmvcc->dev == atm_dev) {
161
162 if (atm_vcc->dev->signal == ATM_PHY_SIG_LOST)
163 netif_carrier_off(net_dev);
164 else
165 netif_carrier_on(net_dev);
166
167 }
168 }
169 }
170 read_unlock_irqrestore(&devs_lock, flags);
171
172 return NOTIFY_DONE;
173}
174
175static struct notifier_block atm_dev_notifier = {
176 .notifier_call = atm_dev_event,
177};
178
145/* chained vcc->pop function. Check if we should wake the netif_queue */ 179/* chained vcc->pop function. Check if we should wake the netif_queue */
146static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb) 180static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
147{ 181{
148 struct br2684_vcc *brvcc = BR2684_VCC(vcc); 182 struct br2684_vcc *brvcc = BR2684_VCC(vcc);
149 struct net_device *net_dev = skb->dev; 183 struct net_device *net_dev = skb->dev;
150 184
151 pr_debug("br2684_pop(vcc %p ; net_dev %p )\n", vcc, net_dev); 185 pr_debug("(vcc %p ; net_dev %p )\n", vcc, net_dev);
152 brvcc->old_pop(vcc, skb); 186 brvcc->old_pop(vcc, skb);
153 187
154 if (!net_dev) 188 if (!net_dev)
@@ -244,7 +278,7 @@ static netdev_tx_t br2684_start_xmit(struct sk_buff *skb,
244 struct br2684_dev *brdev = BRPRIV(dev); 278 struct br2684_dev *brdev = BRPRIV(dev);
245 struct br2684_vcc *brvcc; 279 struct br2684_vcc *brvcc;
246 280
247 pr_debug("br2684_start_xmit, skb_dst(skb)=%p\n", skb_dst(skb)); 281 pr_debug("skb_dst(skb)=%p\n", skb_dst(skb));
248 read_lock(&devs_lock); 282 read_lock(&devs_lock);
249 brvcc = pick_outgoing_vcc(skb, brdev); 283 brvcc = pick_outgoing_vcc(skb, brdev);
250 if (brvcc == NULL) { 284 if (brvcc == NULL) {
@@ -300,7 +334,8 @@ static int br2684_setfilt(struct atm_vcc *atmvcc, void __user * arg)
300 struct br2684_dev *brdev; 334 struct br2684_dev *brdev;
301 read_lock(&devs_lock); 335 read_lock(&devs_lock);
302 brdev = BRPRIV(br2684_find_dev(&fs.ifspec)); 336 brdev = BRPRIV(br2684_find_dev(&fs.ifspec));
303 if (brdev == NULL || list_empty(&brdev->brvccs) || brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */ 337 if (brdev == NULL || list_empty(&brdev->brvccs) ||
338 brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */
304 brvcc = NULL; 339 brvcc = NULL;
305 else 340 else
306 brvcc = list_entry_brvcc(brdev->brvccs.next); 341 brvcc = list_entry_brvcc(brdev->brvccs.next);
@@ -352,7 +387,7 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
352 struct net_device *net_dev = brvcc->device; 387 struct net_device *net_dev = brvcc->device;
353 struct br2684_dev *brdev = BRPRIV(net_dev); 388 struct br2684_dev *brdev = BRPRIV(net_dev);
354 389
355 pr_debug("br2684_push\n"); 390 pr_debug("\n");
356 391
357 if (unlikely(skb == NULL)) { 392 if (unlikely(skb == NULL)) {
358 /* skb==NULL means VCC is being destroyed */ 393 /* skb==NULL means VCC is being destroyed */
@@ -376,29 +411,25 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
376 __skb_trim(skb, skb->len - 4); 411 __skb_trim(skb, skb->len - 4);
377 412
378 /* accept packets that have "ipv[46]" in the snap header */ 413 /* accept packets that have "ipv[46]" in the snap header */
379 if ((skb->len >= (sizeof(llc_oui_ipv4))) 414 if ((skb->len >= (sizeof(llc_oui_ipv4))) &&
380 && 415 (memcmp(skb->data, llc_oui_ipv4,
381 (memcmp 416 sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) {
382 (skb->data, llc_oui_ipv4, 417 if (memcmp(skb->data + 6, ethertype_ipv6,
383 sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) { 418 sizeof(ethertype_ipv6)) == 0)
384 if (memcmp
385 (skb->data + 6, ethertype_ipv6,
386 sizeof(ethertype_ipv6)) == 0)
387 skb->protocol = htons(ETH_P_IPV6); 419 skb->protocol = htons(ETH_P_IPV6);
388 else if (memcmp 420 else if (memcmp(skb->data + 6, ethertype_ipv4,
389 (skb->data + 6, ethertype_ipv4, 421 sizeof(ethertype_ipv4)) == 0)
390 sizeof(ethertype_ipv4)) == 0)
391 skb->protocol = htons(ETH_P_IP); 422 skb->protocol = htons(ETH_P_IP);
392 else 423 else
393 goto error; 424 goto error;
394 skb_pull(skb, sizeof(llc_oui_ipv4)); 425 skb_pull(skb, sizeof(llc_oui_ipv4));
395 skb_reset_network_header(skb); 426 skb_reset_network_header(skb);
396 skb->pkt_type = PACKET_HOST; 427 skb->pkt_type = PACKET_HOST;
397 /* 428 /*
398 * Let us waste some time for checking the encapsulation. 429 * Let us waste some time for checking the encapsulation.
399 * Note, that only 7 char is checked so frames with a valid FCS 430 * Note, that only 7 char is checked so frames with a valid FCS
400 * are also accepted (but FCS is not checked of course). 431 * are also accepted (but FCS is not checked of course).
401 */ 432 */
402 } else if ((skb->len >= sizeof(llc_oui_pid_pad)) && 433 } else if ((skb->len >= sizeof(llc_oui_pid_pad)) &&
403 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) { 434 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
404 skb_pull(skb, sizeof(llc_oui_pid_pad)); 435 skb_pull(skb, sizeof(llc_oui_pid_pad));
@@ -452,7 +483,6 @@ error:
452 net_dev->stats.rx_errors++; 483 net_dev->stats.rx_errors++;
453free_skb: 484free_skb:
454 dev_kfree_skb(skb); 485 dev_kfree_skb(skb);
455 return;
456} 486}
457 487
458/* 488/*
@@ -479,8 +509,7 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
479 write_lock_irq(&devs_lock); 509 write_lock_irq(&devs_lock);
480 net_dev = br2684_find_dev(&be.ifspec); 510 net_dev = br2684_find_dev(&be.ifspec);
481 if (net_dev == NULL) { 511 if (net_dev == NULL) {
482 printk(KERN_ERR 512 pr_err("tried to attach to non-existant device\n");
483 "br2684: tried to attach to non-existant device\n");
484 err = -ENXIO; 513 err = -ENXIO;
485 goto error; 514 goto error;
486 } 515 }
@@ -494,17 +523,16 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
494 err = -EEXIST; 523 err = -EEXIST;
495 goto error; 524 goto error;
496 } 525 }
497 if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO || 526 if (be.fcs_in != BR2684_FCSIN_NO ||
498 be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps != 527 be.fcs_out != BR2684_FCSOUT_NO ||
499 BR2684_ENCAPS_VC 528 be.fcs_auto || be.has_vpiid || be.send_padding ||
500 && be.encaps != 529 (be.encaps != BR2684_ENCAPS_VC &&
501 BR2684_ENCAPS_LLC) 530 be.encaps != BR2684_ENCAPS_LLC) ||
502 || be.min_size != 0) { 531 be.min_size != 0) {
503 err = -EINVAL; 532 err = -EINVAL;
504 goto error; 533 goto error;
505 } 534 }
506 pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, 535 pr_debug("vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps, brvcc);
507 be.encaps, brvcc);
508 if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) { 536 if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) {
509 unsigned char *esi = atmvcc->dev->esi; 537 unsigned char *esi = atmvcc->dev->esi;
510 if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5]) 538 if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5])
@@ -539,9 +567,17 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
539 567
540 br2684_push(atmvcc, skb); 568 br2684_push(atmvcc, skb);
541 } 569 }
570
571 /* initialize netdev carrier state */
572 if (atmvcc->dev->signal == ATM_PHY_SIG_LOST)
573 netif_carrier_off(net_dev);
574 else
575 netif_carrier_on(net_dev);
576
542 __module_get(THIS_MODULE); 577 __module_get(THIS_MODULE);
543 return 0; 578 return 0;
544 error: 579
580error:
545 write_unlock_irq(&devs_lock); 581 write_unlock_irq(&devs_lock);
546 kfree(brvcc); 582 kfree(brvcc);
547 return err; 583 return err;
@@ -587,7 +623,7 @@ static void br2684_setup_routed(struct net_device *netdev)
587 INIT_LIST_HEAD(&brdev->brvccs); 623 INIT_LIST_HEAD(&brdev->brvccs);
588} 624}
589 625
590static int br2684_create(void __user * arg) 626static int br2684_create(void __user *arg)
591{ 627{
592 int err; 628 int err;
593 struct net_device *netdev; 629 struct net_device *netdev;
@@ -595,11 +631,10 @@ static int br2684_create(void __user * arg)
595 struct atm_newif_br2684 ni; 631 struct atm_newif_br2684 ni;
596 enum br2684_payload payload; 632 enum br2684_payload payload;
597 633
598 pr_debug("br2684_create\n"); 634 pr_debug("\n");
599 635
600 if (copy_from_user(&ni, arg, sizeof ni)) { 636 if (copy_from_user(&ni, arg, sizeof ni))
601 return -EFAULT; 637 return -EFAULT;
602 }
603 638
604 if (ni.media & BR2684_FLAG_ROUTED) 639 if (ni.media & BR2684_FLAG_ROUTED)
605 payload = p_routed; 640 payload = p_routed;
@@ -607,9 +642,8 @@ static int br2684_create(void __user * arg)
607 payload = p_bridged; 642 payload = p_bridged;
608 ni.media &= 0xffff; /* strip flags */ 643 ni.media &= 0xffff; /* strip flags */
609 644
610 if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) { 645 if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500)
611 return -EINVAL; 646 return -EINVAL;
612 }
613 647
614 netdev = alloc_netdev(sizeof(struct br2684_dev), 648 netdev = alloc_netdev(sizeof(struct br2684_dev),
615 ni.ifname[0] ? ni.ifname : "nas%d", 649 ni.ifname[0] ? ni.ifname : "nas%d",
@@ -624,15 +658,21 @@ static int br2684_create(void __user * arg)
624 /* open, stop, do_ioctl ? */ 658 /* open, stop, do_ioctl ? */
625 err = register_netdev(netdev); 659 err = register_netdev(netdev);
626 if (err < 0) { 660 if (err < 0) {
627 printk(KERN_ERR "br2684_create: register_netdev failed\n"); 661 pr_err("register_netdev failed\n");
628 free_netdev(netdev); 662 free_netdev(netdev);
629 return err; 663 return err;
630 } 664 }
631 665
632 write_lock_irq(&devs_lock); 666 write_lock_irq(&devs_lock);
667
633 brdev->payload = payload; 668 brdev->payload = payload;
634 brdev->number = list_empty(&br2684_devs) ? 1 : 669
635 BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; 670 if (list_empty(&br2684_devs)) {
671 /* 1st br2684 device */
672 brdev->number = 1;
673 } else
674 brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
675
636 list_add_tail(&brdev->br2684_devs, &br2684_devs); 676 list_add_tail(&brdev->br2684_devs, &br2684_devs);
637 write_unlock_irq(&devs_lock); 677 write_unlock_irq(&devs_lock);
638 return 0; 678 return 0;
@@ -768,6 +808,7 @@ static int __init br2684_init(void)
768 return -ENOMEM; 808 return -ENOMEM;
769#endif 809#endif
770 register_atm_ioctl(&br2684_ioctl_ops); 810 register_atm_ioctl(&br2684_ioctl_ops);
811 register_atmdevice_notifier(&atm_dev_notifier);
771 return 0; 812 return 0;
772} 813}
773 814
@@ -782,6 +823,9 @@ static void __exit br2684_exit(void)
782 remove_proc_entry("br2684", atm_proc_root); 823 remove_proc_entry("br2684", atm_proc_root);
783#endif 824#endif
784 825
826
827 unregister_atmdevice_notifier(&atm_dev_notifier);
828
785 while (!list_empty(&br2684_devs)) { 829 while (!list_empty(&br2684_devs)) {
786 net_dev = list_entry_brdev(br2684_devs.next); 830 net_dev = list_entry_brdev(br2684_devs.next);
787 brdev = BRPRIV(net_dev); 831 brdev = BRPRIV(net_dev);