aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm')
-rw-r--r--net/atm/br2684.c72
1 files changed, 31 insertions, 41 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index d72b1a579911..4d64d87e7578 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -17,7 +17,7 @@
17#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
18#include <linux/rtnetlink.h> 18#include <linux/rtnetlink.h>
19#include <linux/ip.h> 19#include <linux/ip.h>
20#include <asm/uaccess.h> 20#include <linux/uaccess.h>
21#include <net/arp.h> 21#include <net/arp.h>
22#include <linux/atm.h> 22#include <linux/atm.h>
23#include <linux/atmdev.h> 23#include <linux/atmdev.h>
@@ -28,20 +28,14 @@
28 28
29#include "common.h" 29#include "common.h"
30 30
31#ifdef SKB_DEBUG
32static void skb_debug(const struct sk_buff *skb) 31static void skb_debug(const struct sk_buff *skb)
33{ 32{
33#ifdef SKB_DEBUG
34#define NUM2PRINT 50 34#define NUM2PRINT 50
35 char buf[NUM2PRINT * 3 + 1]; /* 3 chars per byte */ 35 print_hex_dump(KERN_DEBUG, "br2684: skb: ", DUMP_OFFSET,
36 int i = 0; 36 16, 1, skb->data, min(NUM2PRINT, skb->len), true);
37 for (i = 0; i < skb->len && i < NUM2PRINT; i++) {
38 sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
39 }
40 printk(KERN_DEBUG "br2684: skb: %s\n", buf);
41}
42#else
43#define skb_debug(skb) do {} while (0)
44#endif 37#endif
38}
45 39
46#define BR2684_ETHERTYPE_LEN 2 40#define BR2684_ETHERTYPE_LEN 2
47#define BR2684_PAD_LEN 2 41#define BR2684_PAD_LEN 2
@@ -70,7 +64,7 @@ struct br2684_vcc {
70 struct atm_vcc *atmvcc; 64 struct atm_vcc *atmvcc;
71 struct net_device *device; 65 struct net_device *device;
72 /* keep old push, pop functions for chaining */ 66 /* keep old push, pop functions for chaining */
73 void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb); 67 void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb);
74 void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); 68 void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb);
75 enum br2684_encaps encaps; 69 enum br2684_encaps encaps;
76 struct list_head brvccs; 70 struct list_head brvccs;
@@ -302,7 +296,8 @@ static int br2684_setfilt(struct atm_vcc *atmvcc, void __user * arg)
302 struct br2684_dev *brdev; 296 struct br2684_dev *brdev;
303 read_lock(&devs_lock); 297 read_lock(&devs_lock);
304 brdev = BRPRIV(br2684_find_dev(&fs.ifspec)); 298 brdev = BRPRIV(br2684_find_dev(&fs.ifspec));
305 if (brdev == NULL || list_empty(&brdev->brvccs) || brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */ 299 if (brdev == NULL || list_empty(&brdev->brvccs) ||
300 brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */
306 brvcc = NULL; 301 brvcc = NULL;
307 else 302 else
308 brvcc = list_entry_brvcc(brdev->brvccs.next); 303 brvcc = list_entry_brvcc(brdev->brvccs.next);
@@ -378,29 +373,25 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
378 __skb_trim(skb, skb->len - 4); 373 __skb_trim(skb, skb->len - 4);
379 374
380 /* accept packets that have "ipv[46]" in the snap header */ 375 /* accept packets that have "ipv[46]" in the snap header */
381 if ((skb->len >= (sizeof(llc_oui_ipv4))) 376 if ((skb->len >= (sizeof(llc_oui_ipv4))) &&
382 && 377 (memcmp(skb->data, llc_oui_ipv4,
383 (memcmp 378 sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) {
384 (skb->data, llc_oui_ipv4, 379 if (memcmp(skb->data + 6, ethertype_ipv6,
385 sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) { 380 sizeof(ethertype_ipv6)) == 0)
386 if (memcmp
387 (skb->data + 6, ethertype_ipv6,
388 sizeof(ethertype_ipv6)) == 0)
389 skb->protocol = htons(ETH_P_IPV6); 381 skb->protocol = htons(ETH_P_IPV6);
390 else if (memcmp 382 else if (memcmp(skb->data + 6, ethertype_ipv4,
391 (skb->data + 6, ethertype_ipv4, 383 sizeof(ethertype_ipv4)) == 0)
392 sizeof(ethertype_ipv4)) == 0)
393 skb->protocol = htons(ETH_P_IP); 384 skb->protocol = htons(ETH_P_IP);
394 else 385 else
395 goto error; 386 goto error;
396 skb_pull(skb, sizeof(llc_oui_ipv4)); 387 skb_pull(skb, sizeof(llc_oui_ipv4));
397 skb_reset_network_header(skb); 388 skb_reset_network_header(skb);
398 skb->pkt_type = PACKET_HOST; 389 skb->pkt_type = PACKET_HOST;
399 /* 390 /*
400 * Let us waste some time for checking the encapsulation. 391 * Let us waste some time for checking the encapsulation.
401 * Note, that only 7 char is checked so frames with a valid FCS 392 * Note, that only 7 char is checked so frames with a valid FCS
402 * are also accepted (but FCS is not checked of course). 393 * are also accepted (but FCS is not checked of course).
403 */ 394 */
404 } else if ((skb->len >= sizeof(llc_oui_pid_pad)) && 395 } else if ((skb->len >= sizeof(llc_oui_pid_pad)) &&
405 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) { 396 (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) {
406 skb_pull(skb, sizeof(llc_oui_pid_pad)); 397 skb_pull(skb, sizeof(llc_oui_pid_pad));
@@ -495,12 +486,12 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
495 err = -EEXIST; 486 err = -EEXIST;
496 goto error; 487 goto error;
497 } 488 }
498 if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO || 489 if (be.fcs_in != BR2684_FCSIN_NO ||
499 be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps != 490 be.fcs_out != BR2684_FCSOUT_NO ||
500 BR2684_ENCAPS_VC 491 be.fcs_auto || be.has_vpiid || be.send_padding ||
501 && be.encaps != 492 (be.encaps != BR2684_ENCAPS_VC &&
502 BR2684_ENCAPS_LLC) 493 be.encaps != BR2684_ENCAPS_LLC) ||
503 || be.min_size != 0) { 494 be.min_size != 0) {
504 err = -EINVAL; 495 err = -EINVAL;
505 goto error; 496 goto error;
506 } 497 }
@@ -541,7 +532,8 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
541 } 532 }
542 __module_get(THIS_MODULE); 533 __module_get(THIS_MODULE);
543 return 0; 534 return 0;
544 error: 535
536error:
545 write_unlock_irq(&devs_lock); 537 write_unlock_irq(&devs_lock);
546 kfree(brvcc); 538 kfree(brvcc);
547 return err; 539 return err;
@@ -587,7 +579,7 @@ static void br2684_setup_routed(struct net_device *netdev)
587 INIT_LIST_HEAD(&brdev->brvccs); 579 INIT_LIST_HEAD(&brdev->brvccs);
588} 580}
589 581
590static int br2684_create(void __user * arg) 582static int br2684_create(void __user *arg)
591{ 583{
592 int err; 584 int err;
593 struct net_device *netdev; 585 struct net_device *netdev;
@@ -597,9 +589,8 @@ static int br2684_create(void __user * arg)
597 589
598 pr_debug("\n"); 590 pr_debug("\n");
599 591
600 if (copy_from_user(&ni, arg, sizeof ni)) { 592 if (copy_from_user(&ni, arg, sizeof ni))
601 return -EFAULT; 593 return -EFAULT;
602 }
603 594
604 if (ni.media & BR2684_FLAG_ROUTED) 595 if (ni.media & BR2684_FLAG_ROUTED)
605 payload = p_routed; 596 payload = p_routed;
@@ -607,9 +598,8 @@ static int br2684_create(void __user * arg)
607 payload = p_bridged; 598 payload = p_bridged;
608 ni.media &= 0xffff; /* strip flags */ 599 ni.media &= 0xffff; /* strip flags */
609 600
610 if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) { 601 if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500)
611 return -EINVAL; 602 return -EINVAL;
612 }
613 603
614 netdev = alloc_netdev(sizeof(struct br2684_dev), 604 netdev = alloc_netdev(sizeof(struct br2684_dev),
615 ni.ifname[0] ? ni.ifname : "nas%d", 605 ni.ifname[0] ? ni.ifname : "nas%d",