aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/br2684.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /net/atm/br2684.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'net/atm/br2684.c')
-rw-r--r--net/atm/br2684.c102
1 files changed, 49 insertions, 53 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 26a646d4eb32..d6c7ceaf13e9 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;
@@ -148,7 +145,7 @@ static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
148 struct br2684_vcc *brvcc = BR2684_VCC(vcc); 145 struct br2684_vcc *brvcc = BR2684_VCC(vcc);
149 struct net_device *net_dev = skb->dev; 146 struct net_device *net_dev = skb->dev;
150 147
151 pr_debug("br2684_pop(vcc %p ; net_dev %p )\n", vcc, net_dev); 148 pr_debug("(vcc %p ; net_dev %p )\n", vcc, net_dev);
152 brvcc->old_pop(vcc, skb); 149 brvcc->old_pop(vcc, skb);
153 150
154 if (!net_dev) 151 if (!net_dev)
@@ -244,7 +241,7 @@ static netdev_tx_t br2684_start_xmit(struct sk_buff *skb,
244 struct br2684_dev *brdev = BRPRIV(dev); 241 struct br2684_dev *brdev = BRPRIV(dev);
245 struct br2684_vcc *brvcc; 242 struct br2684_vcc *brvcc;
246 243
247 pr_debug("br2684_start_xmit, skb_dst(skb)=%p\n", skb_dst(skb)); 244 pr_debug("skb_dst(skb)=%p\n", skb_dst(skb));
248 read_lock(&devs_lock); 245 read_lock(&devs_lock);
249 brvcc = pick_outgoing_vcc(skb, brdev); 246 brvcc = pick_outgoing_vcc(skb, brdev);
250 if (brvcc == NULL) { 247 if (brvcc == NULL) {
@@ -300,7 +297,8 @@ static int br2684_setfilt(struct atm_vcc *atmvcc, void __user * arg)
300 struct br2684_dev *brdev; 297 struct br2684_dev *brdev;
301 read_lock(&devs_lock); 298 read_lock(&devs_lock);
302 brdev = BRPRIV(br2684_find_dev(&fs.ifspec)); 299 brdev = BRPRIV(br2684_find_dev(&fs.ifspec));
303 if (brdev == NULL || list_empty(&brdev->brvccs) || brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */ 300 if (brdev == NULL || list_empty(&brdev->brvccs) ||
301 brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */
304 brvcc = NULL; 302 brvcc = NULL;
305 else 303 else
306 brvcc = list_entry_brvcc(brdev->brvccs.next); 304 brvcc = list_entry_brvcc(brdev->brvccs.next);
@@ -352,7 +350,7 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
352 struct net_device *net_dev = brvcc->device; 350 struct net_device *net_dev = brvcc->device;
353 struct br2684_dev *brdev = BRPRIV(net_dev); 351 struct br2684_dev *brdev = BRPRIV(net_dev);
354 352
355 pr_debug("br2684_push\n"); 353 pr_debug("\n");
356 354
357 if (unlikely(skb == NULL)) { 355 if (unlikely(skb == NULL)) {
358 /* skb==NULL means VCC is being destroyed */ 356 /* skb==NULL means VCC is being destroyed */
@@ -376,29 +374,25 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
376 __skb_trim(skb, skb->len - 4); 374 __skb_trim(skb, skb->len - 4);
377 375
378 /* accept packets that have "ipv[46]" in the snap header */ 376 /* accept packets that have "ipv[46]" in the snap header */
379 if ((skb->len >= (sizeof(llc_oui_ipv4))) 377 if ((skb->len >= (sizeof(llc_oui_ipv4))) &&
380 && 378 (memcmp(skb->data, llc_oui_ipv4,
381 (memcmp 379 sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) {
382 (skb->data, llc_oui_ipv4, 380 if (memcmp(skb->data + 6, ethertype_ipv6,
383 sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) { 381 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); 382 skb->protocol = htons(ETH_P_IPV6);
388 else if (memcmp 383 else if (memcmp(skb->data + 6, ethertype_ipv4,
389 (skb->data + 6, ethertype_ipv4, 384 sizeof(ethertype_ipv4)) == 0)
390 sizeof(ethertype_ipv4)) == 0)
391 skb->protocol = htons(ETH_P_IP); 385 skb->protocol = htons(ETH_P_IP);
392 else 386 else
393 goto error; 387 goto error;
394 skb_pull(skb, sizeof(llc_oui_ipv4)); 388 skb_pull(skb, sizeof(llc_oui_ipv4));
395 skb_reset_network_header(skb); 389 skb_reset_network_header(skb);
396 skb->pkt_type = PACKET_HOST; 390 skb->pkt_type = PACKET_HOST;
397 /* 391 /*
398 * Let us waste some time for checking the encapsulation. 392 * Let us waste some time for checking the encapsulation.
399 * Note, that only 7 char is checked so frames with a valid FCS 393 * Note, that only 7 char is checked so frames with a valid FCS
400 * are also accepted (but FCS is not checked of course). 394 * are also accepted (but FCS is not checked of course).
401 */ 395 */
402 } else if ((skb->len >= sizeof(llc_oui_pid_pad)) && 396 } else if ((skb->len >= sizeof(llc_oui_pid_pad)) &&
403 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) { 397 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
404 skb_pull(skb, sizeof(llc_oui_pid_pad)); 398 skb_pull(skb, sizeof(llc_oui_pid_pad));
@@ -479,8 +473,7 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
479 write_lock_irq(&devs_lock); 473 write_lock_irq(&devs_lock);
480 net_dev = br2684_find_dev(&be.ifspec); 474 net_dev = br2684_find_dev(&be.ifspec);
481 if (net_dev == NULL) { 475 if (net_dev == NULL) {
482 printk(KERN_ERR 476 pr_err("tried to attach to non-existant device\n");
483 "br2684: tried to attach to non-existant device\n");
484 err = -ENXIO; 477 err = -ENXIO;
485 goto error; 478 goto error;
486 } 479 }
@@ -494,17 +487,16 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
494 err = -EEXIST; 487 err = -EEXIST;
495 goto error; 488 goto error;
496 } 489 }
497 if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO || 490 if (be.fcs_in != BR2684_FCSIN_NO ||
498 be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps != 491 be.fcs_out != BR2684_FCSOUT_NO ||
499 BR2684_ENCAPS_VC 492 be.fcs_auto || be.has_vpiid || be.send_padding ||
500 && be.encaps != 493 (be.encaps != BR2684_ENCAPS_VC &&
501 BR2684_ENCAPS_LLC) 494 be.encaps != BR2684_ENCAPS_LLC) ||
502 || be.min_size != 0) { 495 be.min_size != 0) {
503 err = -EINVAL; 496 err = -EINVAL;
504 goto error; 497 goto error;
505 } 498 }
506 pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, 499 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) { 500 if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) {
509 unsigned char *esi = atmvcc->dev->esi; 501 unsigned char *esi = atmvcc->dev->esi;
510 if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5]) 502 if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5])
@@ -541,7 +533,8 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
541 } 533 }
542 __module_get(THIS_MODULE); 534 __module_get(THIS_MODULE);
543 return 0; 535 return 0;
544 error: 536
537error:
545 write_unlock_irq(&devs_lock); 538 write_unlock_irq(&devs_lock);
546 kfree(brvcc); 539 kfree(brvcc);
547 return err; 540 return err;
@@ -554,6 +547,12 @@ static const struct net_device_ops br2684_netdev_ops = {
554 .ndo_validate_addr = eth_validate_addr, 547 .ndo_validate_addr = eth_validate_addr,
555}; 548};
556 549
550static const struct net_device_ops br2684_netdev_ops_routed = {
551 .ndo_start_xmit = br2684_start_xmit,
552 .ndo_set_mac_address = br2684_mac_addr,
553 .ndo_change_mtu = eth_change_mtu
554};
555
557static void br2684_setup(struct net_device *netdev) 556static void br2684_setup(struct net_device *netdev)
558{ 557{
559 struct br2684_dev *brdev = BRPRIV(netdev); 558 struct br2684_dev *brdev = BRPRIV(netdev);
@@ -569,11 +568,10 @@ static void br2684_setup(struct net_device *netdev)
569static void br2684_setup_routed(struct net_device *netdev) 568static void br2684_setup_routed(struct net_device *netdev)
570{ 569{
571 struct br2684_dev *brdev = BRPRIV(netdev); 570 struct br2684_dev *brdev = BRPRIV(netdev);
572 brdev->net_dev = netdev;
573 571
572 brdev->net_dev = netdev;
574 netdev->hard_header_len = 0; 573 netdev->hard_header_len = 0;
575 574 netdev->netdev_ops = &br2684_netdev_ops_routed;
576 netdev->netdev_ops = &br2684_netdev_ops;
577 netdev->addr_len = 0; 575 netdev->addr_len = 0;
578 netdev->mtu = 1500; 576 netdev->mtu = 1500;
579 netdev->type = ARPHRD_PPP; 577 netdev->type = ARPHRD_PPP;
@@ -582,7 +580,7 @@ static void br2684_setup_routed(struct net_device *netdev)
582 INIT_LIST_HEAD(&brdev->brvccs); 580 INIT_LIST_HEAD(&brdev->brvccs);
583} 581}
584 582
585static int br2684_create(void __user * arg) 583static int br2684_create(void __user *arg)
586{ 584{
587 int err; 585 int err;
588 struct net_device *netdev; 586 struct net_device *netdev;
@@ -590,11 +588,10 @@ static int br2684_create(void __user * arg)
590 struct atm_newif_br2684 ni; 588 struct atm_newif_br2684 ni;
591 enum br2684_payload payload; 589 enum br2684_payload payload;
592 590
593 pr_debug("br2684_create\n"); 591 pr_debug("\n");
594 592
595 if (copy_from_user(&ni, arg, sizeof ni)) { 593 if (copy_from_user(&ni, arg, sizeof ni))
596 return -EFAULT; 594 return -EFAULT;
597 }
598 595
599 if (ni.media & BR2684_FLAG_ROUTED) 596 if (ni.media & BR2684_FLAG_ROUTED)
600 payload = p_routed; 597 payload = p_routed;
@@ -602,9 +599,8 @@ static int br2684_create(void __user * arg)
602 payload = p_bridged; 599 payload = p_bridged;
603 ni.media &= 0xffff; /* strip flags */ 600 ni.media &= 0xffff; /* strip flags */
604 601
605 if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) { 602 if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500)
606 return -EINVAL; 603 return -EINVAL;
607 }
608 604
609 netdev = alloc_netdev(sizeof(struct br2684_dev), 605 netdev = alloc_netdev(sizeof(struct br2684_dev),
610 ni.ifname[0] ? ni.ifname : "nas%d", 606 ni.ifname[0] ? ni.ifname : "nas%d",
@@ -619,7 +615,7 @@ static int br2684_create(void __user * arg)
619 /* open, stop, do_ioctl ? */ 615 /* open, stop, do_ioctl ? */
620 err = register_netdev(netdev); 616 err = register_netdev(netdev);
621 if (err < 0) { 617 if (err < 0) {
622 printk(KERN_ERR "br2684_create: register_netdev failed\n"); 618 pr_err("register_netdev failed\n");
623 free_netdev(netdev); 619 free_netdev(netdev);
624 return err; 620 return err;
625 } 621 }