lkml.org 
[lkml]   [2013]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 08/71] firewire: net: Fix handling of fragmented multicast/broadcast packets.
    Date
    3.0-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Stephan Gatzka <stephan.gatzka@gmail.com>

    commit 9d2373420900a39f5212a3b289331aa3535b1000 upstream.

    This patch fixes both the transmit and receive portion of sending
    fragmented mutlicast and broadcast packets.

    The transmit section was broken because the offset for INTFRAG and
    LASTFRAG packets were just miscalculated by IEEE1394_GASP_HDR_SIZE (which
    was reserved with skb_push() in fwnet_send_packet).

    The receive section was broken because in fwnet_incoming_packet is a call
    to fwnet_peer_find_by_node_id(). Called with generation == -1 it will
    not find a peer and the partial datagrams are associated to a peer.

    [Stefan R: The fix to use context->card->generation is not perfect.
    It relies on the IR tasklet which processes packets from the prior bus
    generation to run before the self-ID-complete worklet which sets the
    current card generation. Alas, there is no simple way of a race-free
    implementation. Let's do it this way for now.]

    Signed-off-by: Stephan Gatzka <stephan.gatzka@gmail.com>
    Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/firewire/net.c | 13 +++++++++----
    1 file changed, 9 insertions(+), 4 deletions(-)

    --- a/drivers/firewire/net.c
    +++ b/drivers/firewire/net.c
    @@ -863,8 +863,8 @@ static void fwnet_receive_broadcast(stru
    if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) {
    buf_ptr += 2;
    length -= IEEE1394_GASP_HDR_SIZE;
    - fwnet_incoming_packet(dev, buf_ptr, length,
    - source_node_id, -1, true);
    + fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
    + context->card->generation, true);
    }

    packet.payload_length = dev->rcv_buffer_size;
    @@ -959,7 +959,12 @@ static void fwnet_transmit_packet_done(s
    break;
    }

    - skb_pull(skb, ptask->max_payload);
    + if (ptask->dest_node == IEEE1394_ALL_NODES) {
    + skb_pull(skb,
    + ptask->max_payload + IEEE1394_GASP_HDR_SIZE);
    + } else {
    + skb_pull(skb, ptask->max_payload);
    + }
    if (ptask->outstanding_pkts > 1) {
    fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG,
    dg_size, fg_off, datagram_label);
    @@ -1062,7 +1067,7 @@ static int fwnet_send_packet(struct fwne
    smp_rmb();
    node_id = dev->card->node_id;

    - p = skb_push(ptask->skb, 8);
    + p = skb_push(ptask->skb, IEEE1394_GASP_HDR_SIZE);
    put_unaligned_be32(node_id << 16 | IANA_SPECIFIER_ID >> 8, p);
    put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24
    | RFC2734_SW_VERSION, &p[4]);



    \
     
     \ /
      Last update: 2013-01-16 01:41    [W:4.375 / U:0.228 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site