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.c38
1 files changed, 13 insertions, 25 deletions
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index d07223c834af..353fccf1cde3 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -53,6 +53,7 @@ static const unsigned char ethertype_ipv4[] = { ETHERTYPE_IPV4 };
53static const unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 }; 53static const unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 };
54static const unsigned char llc_oui_pid_pad[] = 54static const unsigned char llc_oui_pid_pad[] =
55 { LLC, SNAP_BRIDGED, PID_ETHERNET, PAD_BRIDGED }; 55 { LLC, SNAP_BRIDGED, PID_ETHERNET, PAD_BRIDGED };
56static const unsigned char pad[] = { PAD_BRIDGED };
56static const unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 }; 57static const unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 };
57static const unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 }; 58static const unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 };
58 59
@@ -202,7 +203,10 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev,
202{ 203{
203 struct br2684_dev *brdev = BRPRIV(dev); 204 struct br2684_dev *brdev = BRPRIV(dev);
204 struct atm_vcc *atmvcc; 205 struct atm_vcc *atmvcc;
205 int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2; 206 int minheadroom = (brvcc->encaps == e_llc) ?
207 ((brdev->payload == p_bridged) ?
208 sizeof(llc_oui_pid_pad) : sizeof(llc_oui_ipv4)) :
209 ((brdev->payload == p_bridged) ? BR2684_PAD_LEN : 0);
206 210
207 if (skb_headroom(skb) < minheadroom) { 211 if (skb_headroom(skb) < minheadroom) {
208 struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom); 212 struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
@@ -450,7 +454,7 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
450 skb->pkt_type = PACKET_HOST; 454 skb->pkt_type = PACKET_HOST;
451 } else { /* p_bridged */ 455 } else { /* p_bridged */
452 /* first 2 chars should be 0 */ 456 /* first 2 chars should be 0 */
453 if (*((u16 *) (skb->data)) != 0) 457 if (memcmp(skb->data, pad, BR2684_PAD_LEN) != 0)
454 goto error; 458 goto error;
455 skb_pull(skb, BR2684_PAD_LEN); 459 skb_pull(skb, BR2684_PAD_LEN);
456 skb->protocol = eth_type_trans(skb, net_dev); 460 skb->protocol = eth_type_trans(skb, net_dev);
@@ -489,15 +493,11 @@ free_skb:
489 */ 493 */
490static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) 494static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
491{ 495{
492 struct sk_buff_head queue;
493 int err;
494 struct br2684_vcc *brvcc; 496 struct br2684_vcc *brvcc;
495 struct sk_buff *skb, *tmp;
496 struct sk_buff_head *rq;
497 struct br2684_dev *brdev; 497 struct br2684_dev *brdev;
498 struct net_device *net_dev; 498 struct net_device *net_dev;
499 struct atm_backend_br2684 be; 499 struct atm_backend_br2684 be;
500 unsigned long flags; 500 int err;
501 501
502 if (copy_from_user(&be, arg, sizeof be)) 502 if (copy_from_user(&be, arg, sizeof be))
503 return -EFAULT; 503 return -EFAULT;
@@ -550,23 +550,6 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
550 atmvcc->push = br2684_push; 550 atmvcc->push = br2684_push;
551 atmvcc->pop = br2684_pop; 551 atmvcc->pop = br2684_pop;
552 552
553 __skb_queue_head_init(&queue);
554 rq = &sk_atm(atmvcc)->sk_receive_queue;
555
556 spin_lock_irqsave(&rq->lock, flags);
557 skb_queue_splice_init(rq, &queue);
558 spin_unlock_irqrestore(&rq->lock, flags);
559
560 skb_queue_walk_safe(&queue, skb, tmp) {
561 struct net_device *dev;
562
563 br2684_push(atmvcc, skb);
564 dev = skb->dev;
565
566 dev->stats.rx_bytes -= skb->len;
567 dev->stats.rx_packets--;
568 }
569
570 /* initialize netdev carrier state */ 553 /* initialize netdev carrier state */
571 if (atmvcc->dev->signal == ATM_PHY_SIG_LOST) 554 if (atmvcc->dev->signal == ATM_PHY_SIG_LOST)
572 netif_carrier_off(net_dev); 555 netif_carrier_off(net_dev);
@@ -574,6 +557,10 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
574 netif_carrier_on(net_dev); 557 netif_carrier_on(net_dev);
575 558
576 __module_get(THIS_MODULE); 559 __module_get(THIS_MODULE);
560
561 /* re-process everything received between connection setup and
562 backend setup */
563 vcc_process_recv_queue(atmvcc);
577 return 0; 564 return 0;
578 565
579error: 566error:
@@ -600,6 +587,7 @@ static void br2684_setup(struct net_device *netdev)
600 struct br2684_dev *brdev = BRPRIV(netdev); 587 struct br2684_dev *brdev = BRPRIV(netdev);
601 588
602 ether_setup(netdev); 589 ether_setup(netdev);
590 netdev->hard_header_len += sizeof(llc_oui_pid_pad); /* worst case */
603 brdev->net_dev = netdev; 591 brdev->net_dev = netdev;
604 592
605 netdev->netdev_ops = &br2684_netdev_ops; 593 netdev->netdev_ops = &br2684_netdev_ops;
@@ -612,7 +600,7 @@ static void br2684_setup_routed(struct net_device *netdev)
612 struct br2684_dev *brdev = BRPRIV(netdev); 600 struct br2684_dev *brdev = BRPRIV(netdev);
613 601
614 brdev->net_dev = netdev; 602 brdev->net_dev = netdev;
615 netdev->hard_header_len = 0; 603 netdev->hard_header_len = sizeof(llc_oui_ipv4); /* worst case */
616 netdev->netdev_ops = &br2684_netdev_ops_routed; 604 netdev->netdev_ops = &br2684_netdev_ops_routed;
617 netdev->addr_len = 0; 605 netdev->addr_len = 0;
618 netdev->mtu = 1500; 606 netdev->mtu = 1500;