diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-08-16 17:45:54 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-08-19 14:28:25 -0400 |
commit | 1bf145fed572583d4cb7c1784689a0b42c997ba6 (patch) | |
tree | 3ef524b2af2ea77f2ea99478b8a4058a8cf07d13 /drivers/firewire/net.c | |
parent | a481e97d3cdc40b9d58271675bd4f0abb79d4872 (diff) |
firewire: net: fix unicast reception RCODE in failure paths
The incoming request hander fwnet_receive_packet() expects subsequent
datagram handling code to return non-zero on errors. However, almost
none of the failure paths did so. Fix them all.
(This error reporting is used to send and RCODE_CONFLICT_ERROR to the
sender node in such failure cases. Two modes of failure exist: Out of
memory, or firewire-net is unaware of any peer node to which a fragment
or an ARP packet belongs. However, it is unclear whether a sender can
actually make use of such information. A Linux peer apparently can't.
Maybe it should all be simplified to void functions.)
Reported-by: Julia Lawall <julia@diku.dk>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/net.c')
-rw-r--r-- | drivers/firewire/net.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index da17d409a244..33f8421c71cc 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -579,7 +579,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
579 | if (!peer) { | 579 | if (!peer) { |
580 | fw_notify("No peer for ARP packet from %016llx\n", | 580 | fw_notify("No peer for ARP packet from %016llx\n", |
581 | (unsigned long long)peer_guid); | 581 | (unsigned long long)peer_guid); |
582 | goto failed_proto; | 582 | goto no_peer; |
583 | } | 583 | } |
584 | 584 | ||
585 | /* | 585 | /* |
@@ -656,7 +656,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
656 | 656 | ||
657 | return 0; | 657 | return 0; |
658 | 658 | ||
659 | failed_proto: | 659 | no_peer: |
660 | net->stats.rx_errors++; | 660 | net->stats.rx_errors++; |
661 | net->stats.rx_dropped++; | 661 | net->stats.rx_dropped++; |
662 | 662 | ||
@@ -664,7 +664,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
664 | if (netif_queue_stopped(net)) | 664 | if (netif_queue_stopped(net)) |
665 | netif_wake_queue(net); | 665 | netif_wake_queue(net); |
666 | 666 | ||
667 | return 0; | 667 | return -ENOENT; |
668 | } | 668 | } |
669 | 669 | ||
670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | 670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, |
@@ -701,7 +701,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
701 | fw_error("out of memory\n"); | 701 | fw_error("out of memory\n"); |
702 | net->stats.rx_dropped++; | 702 | net->stats.rx_dropped++; |
703 | 703 | ||
704 | return -1; | 704 | return -ENOMEM; |
705 | } | 705 | } |
706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); | 706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); |
707 | memcpy(skb_put(skb, len), buf, len); | 707 | memcpy(skb_put(skb, len), buf, len); |
@@ -726,8 +726,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
726 | spin_lock_irqsave(&dev->lock, flags); | 726 | spin_lock_irqsave(&dev->lock, flags); |
727 | 727 | ||
728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); | 728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); |
729 | if (!peer) | 729 | if (!peer) { |
730 | goto bad_proto; | 730 | retval = -ENOENT; |
731 | goto fail; | ||
732 | } | ||
731 | 733 | ||
732 | pd = fwnet_pd_find(peer, datagram_label); | 734 | pd = fwnet_pd_find(peer, datagram_label); |
733 | if (pd == NULL) { | 735 | if (pd == NULL) { |
@@ -741,7 +743,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
741 | dg_size, buf, fg_off, len); | 743 | dg_size, buf, fg_off, len); |
742 | if (pd == NULL) { | 744 | if (pd == NULL) { |
743 | retval = -ENOMEM; | 745 | retval = -ENOMEM; |
744 | goto bad_proto; | 746 | goto fail; |
745 | } | 747 | } |
746 | peer->pdg_size++; | 748 | peer->pdg_size++; |
747 | } else { | 749 | } else { |
@@ -755,9 +757,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
755 | pd = fwnet_pd_new(net, peer, datagram_label, | 757 | pd = fwnet_pd_new(net, peer, datagram_label, |
756 | dg_size, buf, fg_off, len); | 758 | dg_size, buf, fg_off, len); |
757 | if (pd == NULL) { | 759 | if (pd == NULL) { |
758 | retval = -ENOMEM; | ||
759 | peer->pdg_size--; | 760 | peer->pdg_size--; |
760 | goto bad_proto; | 761 | retval = -ENOMEM; |
762 | goto fail; | ||
761 | } | 763 | } |
762 | } else { | 764 | } else { |
763 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { | 765 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { |
@@ -768,7 +770,8 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
768 | */ | 770 | */ |
769 | fwnet_pd_delete(pd); | 771 | fwnet_pd_delete(pd); |
770 | peer->pdg_size--; | 772 | peer->pdg_size--; |
771 | goto bad_proto; | 773 | retval = -ENOMEM; |
774 | goto fail; | ||
772 | } | 775 | } |
773 | } | 776 | } |
774 | } /* new datagram or add to existing one */ | 777 | } /* new datagram or add to existing one */ |
@@ -794,14 +797,13 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
794 | spin_unlock_irqrestore(&dev->lock, flags); | 797 | spin_unlock_irqrestore(&dev->lock, flags); |
795 | 798 | ||
796 | return 0; | 799 | return 0; |
797 | 800 | fail: | |
798 | bad_proto: | ||
799 | spin_unlock_irqrestore(&dev->lock, flags); | 801 | spin_unlock_irqrestore(&dev->lock, flags); |
800 | 802 | ||
801 | if (netif_queue_stopped(net)) | 803 | if (netif_queue_stopped(net)) |
802 | netif_wake_queue(net); | 804 | netif_wake_queue(net); |
803 | 805 | ||
804 | return 0; | 806 | return retval; |
805 | } | 807 | } |
806 | 808 | ||
807 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, | 809 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, |