aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/outqueue.c
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-12-20 17:11:47 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:59:23 -0500
commita08de64d074b36a56ee3bb985cd171281db78e96 (patch)
tree15b3c77a7078b5dc0510a23cc7d95922f7ad420a /net/sctp/outqueue.c
parentba8a06daed7d7c8785c92c343da9e202e6988fda (diff)
[SCTP]: Update ASCONF processing to conform to spec.
The processing of the ASCONF chunks has changed a lot in the spec. New items are: 1. A list of ASCONF-ACK chunks is now cached 2. The source of the packet is used in response. 3. New handling for unexpect ASCONF chunks. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r--net/sctp/outqueue.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index fa76f235169b..a42af865c2ef 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -716,7 +716,29 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
716 new_transport = chunk->transport; 716 new_transport = chunk->transport;
717 717
718 if (!new_transport) { 718 if (!new_transport) {
719 new_transport = asoc->peer.active_path; 719 /*
720 * If we have a prior transport pointer, see if
721 * the destination address of the chunk
722 * matches the destination address of the
723 * current transport. If not a match, then
724 * try to look up the transport with a given
725 * destination address. We do this because
726 * after processing ASCONFs, we may have new
727 * transports created.
728 */
729 if (transport &&
730 sctp_cmp_addr_exact(&chunk->dest,
731 &transport->ipaddr))
732 new_transport = transport;
733 else
734 new_transport = sctp_assoc_lookup_paddr(asoc,
735 &chunk->dest);
736
737 /* if we still don't have a new transport, then
738 * use the current active path.
739 */
740 if (!new_transport)
741 new_transport = asoc->peer.active_path;
720 } else if ((new_transport->state == SCTP_INACTIVE) || 742 } else if ((new_transport->state == SCTP_INACTIVE) ||
721 (new_transport->state == SCTP_UNCONFIRMED)) { 743 (new_transport->state == SCTP_UNCONFIRMED)) {
722 /* If the chunk is Heartbeat or Heartbeat Ack, 744 /* If the chunk is Heartbeat or Heartbeat Ack,
@@ -729,9 +751,12 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
729 * address of the IP datagram containing the 751 * address of the IP datagram containing the
730 * HEARTBEAT chunk to which this ack is responding. 752 * HEARTBEAT chunk to which this ack is responding.
731 * ... 753 * ...
754 *
755 * ASCONF_ACKs also must be sent to the source.
732 */ 756 */
733 if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT && 757 if (chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT &&
734 chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK) 758 chunk->chunk_hdr->type != SCTP_CID_HEARTBEAT_ACK &&
759 chunk->chunk_hdr->type != SCTP_CID_ASCONF_ACK)
735 new_transport = asoc->peer.active_path; 760 new_transport = asoc->peer.active_path;
736 } 761 }
737 762