#!/usr/bin/perl # # SCTP Conformance Test Suite Implementation # (C) Copyright Fujitsu Ltd. 2008, 2009 # # This file is part of the SCTP Conformance Test Suite implementation. # # The SCTP Conformance Test Suite implementation is free software; # you can redistribute it and/or modify it under the terms of # the GNU General Public License version 2 as published by # the Free Software Foundation. # # The SCTP Conformance Test Suite implementation is distributed in the # hope that it will be useful, but WITHOUT ANY WARRANTY; without even # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU CC; see the file COPYING. If not, write to # the Free Software Foundation, 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # # Please send any bug reports or fixes you make to the # email address(es): # networktest sctp # # Or submit a bug report through the following website: # http://networktest.sourceforge.net/ # # Written or modified by: # Hiroaki Kago # Wei Yongjun # # Any bugs reported given to us we will try to fix... any fixes shared will # be incorporated into the next SCTP release. # ############################################################################## BEGIN { $V6evalTool::TestVersion = '$Name: REL_1_0_0 $'; } use lib "../common"; use V6evalTool; use SCTP; %pktdesc = ( sctp_chunk_data_big => "Recv SCTP CHUNK_DATA (Not fragmented)", sctp_chunk_data_seg1 => "Recv SCTP CHUNK_DATA (1st segment)", sctp_chunk_data_seg2 => "Recv SCTP CHUNK_DATA (2st segment)", echo_request => "Send Echo Request (Link1 to Link0)", echo_reply_1st => "Recv Echo Reply (1st fragment)", echo_reply_2nd => "Recv Echo Reply (2nd fragment)", echo_reply => "Recv Echo Reply (Link0 to Link1)" ); if ($SCTP::CONF{ENABLE_IPV6} == 0) { $pktdesc{"icmp_pkt_too_big1"} = "Send ICMPv4 Fragmentation Needed messages (Link1 to Link1)"; $pktdesc{"icmp_pkt_too_big2"} = "Send ICMPv4 Fragmentation Needed messages (Link1 to Link0)"; } else { $pktdesc{"icmp_pkt_too_big1"} = "Send ICMPv6 Packet Too Big messages (Link1 to Link1)"; $pktdesc{"icmp_pkt_too_big2"} = "Send ICMPv6 Packet Too Big messages (Link1 to Link0)"; } $IF0 = Link0; $IF1 = Link1; vCapture($IF0); vCapture($IF1); sctpCheckEnv($IF0, $IF1); vRegisterExtNS("ns_on_link0_to_link1", "na_on_link1_to_link0"); vRegisterExtNS("arp_request_link0_to_link1", "arp_reply_link1_to_link0"); vLogHTML('======= Check PMTU is set correctly ======='); # We have changed Remote System's PMTU, need reboot to restore it $SCTP::CONF{"NEEDREBOOT"} = 1; $retrycnt = 5; retry: vSend($IF1, "icmp_pkt_too_big1"); vSend($IF1, "icmp_pkt_too_big2"); vSend($IF1, "echo_request"); %ret = vWarpRecv($IF1, 10, 0, 0, echo_reply_1st, echo_reply_2nd, echo_reply); if ($ret{status} != 0) { vLogHTML('Cannot receive Echo Reply
'); vLogHTML('NG'); exit $V6evalTool::exitFail; } if ($ret{recvFrame} eq echo_reply) { if ($retrycnt-- > 0) { vSleep(10); goto retry; } vLogHTML('Fail to set PMTU
'); vLogHTML('NG'); exit $V6evalTool::exitFail; } elsif ($ret{recvFrame} eq echo_reply_1st) { %ret = vWarpRecv($IF1, 10, 0, 0, echo_reply_2nd); if ($ret{status} != 0 || $ret{recvFrame} ne echo_reply_2nd) { vLogHTML('Cannot receive Echo Reply (Fragment 2nd)
'); vLogHTML('NG'); exit $V6evalTool::exitFail; } } elsif ($ret{recvFrame} eq echo_reply_2nd) { %ret = vWarpRecv($IF1, 10, 0, 0, echo_reply_1st); if ($ret{status} != 0 || $ret{recvFrame} ne echo_reply_1st) { vLogHTML('Cannot receive Echo Reply (Fragment 1st)
'); vLogHTML('NG'); exit $V6evalTool::exitFail; } } sctpStartClient($IF0, 1, ($SCTP::CONF{ENABLE_IPV6} == 0) ? 1452 : 1432); vListen($IF0); vAccept($IF0); vLogHTML('================ Main Test ================='); sctpUpdateRecvACK(); %ret = vWarpRecv($IF0, 30, 0, 0, sctp_chunk_data_seg1, sctp_chunk_data_big); if ($ret{status} != 0 || ($ret{recvFrame} ne sctp_chunk_data_big && $ret{recvFrame} ne sctp_chunk_data_seg1)) { vLogHTML('Cannot receive SCTP CHUNK_DATA
'); vLogHTML('NG'); exit $V6evalTool::exitFail; } $TSN = $ret{sctpGetFieldName("CHUNK_DATA.TSN")}; vWarpCPP("-DSACK=$TSN"); if ($ret{recvFrame} eq sctp_chunk_data_big) { vLogHTML("The sender does not used the smallest PMTU discovered for all of the peer's destination addresses
"); vSend($IF0, sctp_chunk_abort_snd); vLogHTML('NG'); exit $V6evalTool::exitFail; } vSend($IF0, sctp_chunk_sack_snd); sctpUpdateRecvACK(); %ret = vWarpRecv($IF0, 30, 0, 0, sctp_chunk_data_seg2); if ($ret{status} != 0 && $ret{recvFrame} ne sctp_chunk_data_seg2) { vLogHTML('Cannot receive SCTP CHUNK_DATA
'); vLogHTML('NG'); exit $V6evalTool::exitFail; } vSend($IF0, sctp_chunk_sack_snd); vShutdown($IF0); vLogHTML(OK); exit $V6evalTool::exitPass; ###################################################################### __END__ =head1 NAME PMTU_UseSmallest.seq - Association PMTU is the smallest Path MTU of all destination addresses if its peer is multi-homed =head1 PURPOSE To check whether the endpoint used the smallest PMTU discovered of all destination addresses if its peer is multi-homed. =head1 SYNOPSIS =begin html
  ./PMTU_UseSmallest.seq [-tooloption ...] -pkt ./PMTU_UseSmallest.def
    -tooloption : v6eval tool option
  See Also: ../common/STD_PKT_COMMON.def
            ../common/SCTP_COMMON.def
=end html =head1 PRE-TEST CONDITION Association not established between endpoint A and B. Also arrange the data in endpoint B such that upper layers send associate primitive to startup an association with endpoint A. =head1 TEST PROCEDURE Endpoint A Endpoint B ULP (CLOSED) (CLOSED) ICMP (IP=y) -----------------> (Fragmentation Needed or Packet Too Big) <----- Association ...... <----- Send <---------------- DATA (Fragment 1) (IP=x) <---------------- DATA (Fragment 2) (IP=x) SACK -----------------> TEST DESCRIPTION: 1. Attempt to change PMTU between endpoint A (IP=y) and endpoint B by sending ICMP message. 2. Associate primitive to startup an association with endpoint A. 4. Check B: Data be retransmission be fragmented used the PMTU of y on IP=x. =head1 NOTE None =head1 REFERENCE RFC 4960 7.3. Path MTU Discovery [RFC4821], [RFC1981], and [RFC1191] specify "Packetization Layer Path MTU Discovery", whereby an endpoint maintains an estimate of the maximum transmission unit (MTU) along a given Internet path and refrains from sending packets along that path that exceed the MTU, other than occasional attempts to probe for a change in the Path MTU (PMTU). [RFC4821] is thorough in its discussion of the MTU discovery mechanism and strategies for determining the current end-to-end MTU setting as well as detecting changes in this value. An endpoint SHOULD apply these techniques, and SHOULD do so on a per-destination-address basis. There are two important SCTP-specific points regarding Path MTU discovery: 1) SCTP associations can span multiple addresses. An endpoint MUST maintain separate MTU estimates for each destination address of its peer. =begin html
    2)  The sender should track an association PMTU that will be the
        smallest PMTU discovered for all of the peer's destination
        addresses.  When fragmenting messages into multiple parts this
        association PMTU should be used to calculate the size of each
        fragment.  This will allow retransmissions to be seamlessly sent
        to an alternate address without encountering IP fragmentation.
=end html