提交 9d237342 编写于 作者: S Stephan Gatzka 提交者: Stefan Richter

firewire: net: Fix handling of fragmented multicast/broadcast packets.

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: NStephan Gatzka <stephan.gatzka@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: NStefan Richter <stefanr@s5r6.in-berlin.de>
上级 b0ea5f19
...@@ -861,8 +861,8 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, ...@@ -861,8 +861,8 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) { if (specifier_id == IANA_SPECIFIER_ID && ver == RFC2734_SW_VERSION) {
buf_ptr += 2; buf_ptr += 2;
length -= IEEE1394_GASP_HDR_SIZE; length -= IEEE1394_GASP_HDR_SIZE;
fwnet_incoming_packet(dev, buf_ptr, length, fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
source_node_id, -1, true); context->card->generation, true);
} }
packet.payload_length = dev->rcv_buffer_size; packet.payload_length = dev->rcv_buffer_size;
...@@ -958,7 +958,12 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) ...@@ -958,7 +958,12 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
break; 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) { if (ptask->outstanding_pkts > 1) {
fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG,
dg_size, fg_off, datagram_label); dg_size, fg_off, datagram_label);
...@@ -1062,7 +1067,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) ...@@ -1062,7 +1067,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
smp_rmb(); smp_rmb();
node_id = dev->card->node_id; 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(node_id << 16 | IANA_SPECIFIER_ID >> 8, p);
put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24 put_unaligned_be32((IANA_SPECIFIER_ID & 0xff) << 24
| RFC2734_SW_VERSION, &p[4]); | RFC2734_SW_VERSION, &p[4]);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册