10#include "ns3/codel-queue-disc.h" 
   11#include "ns3/fq-codel-queue-disc.h" 
   12#include "ns3/ipv4-address.h" 
   13#include "ns3/ipv4-header.h" 
   14#include "ns3/ipv4-packet-filter.h" 
   15#include "ns3/ipv4-queue-disc-item.h" 
   16#include "ns3/ipv6-header.h" 
   17#include "ns3/ipv6-packet-filter.h" 
   18#include "ns3/ipv6-queue-disc-item.h" 
   19#include "ns3/pointer.h" 
   20#include "ns3/simulator.h" 
   21#include "ns3/string.h" 
   22#include "ns3/tcp-header.h" 
   24#include "ns3/udp-header.h" 
   69                            .SetGroupName(
"Internet")
 
 
  106    void DoRun() 
override;
 
 
  110    : 
TestCase(
"Test packets that are not classified by any filter")
 
 
  125    queueDisc->AddPacketFilter(filter);
 
  128    queueDisc->SetQuantum(1500);
 
  129    queueDisc->Initialize();
 
  137    queueDisc->Enqueue(item);
 
  140                          "no flow queue should have been created");
 
  142    p = 
Create<Packet>(
reinterpret_cast<const uint8_t*
>(
"hello, world"), 12);
 
  144    queueDisc->Enqueue(item);
 
  147                          "no flow queue should have been created");
 
 
  164    void DoRun() 
override;
 
 
  174    : 
TestCase(
"Test IP flows separation and packet limit")
 
 
  189    queue->Enqueue(item);
 
 
  198    queueDisc->SetQuantum(1500);
 
  199    queueDisc->Initialize();
 
  213                          "unexpected number of packets in the queue disc");
 
  216                          "unexpected number of packets in the flow queue");
 
  224                          "unexpected number of packets in the queue disc");
 
  227                          "unexpected number of packets in the flow queue");
 
  230                          "unexpected number of packets in the flow queue");
 
  236                          "unexpected number of packets in the queue disc");
 
  239                          "unexpected number of packets in the flow queue");
 
  242                          "unexpected number of packets in the flow queue");
 
 
  259    void DoRun() 
override;
 
 
  269    : 
TestCase(
"Test credits and flows status")
 
 
  283    queue->Enqueue(item);
 
 
  291    queueDisc->SetQuantum(90);
 
  292    queueDisc->Initialize();
 
  304                          "unexpected number of packets in the queue disc");
 
  307                          "unexpected number of packets in the first flow queue");
 
  310                          static_cast<int32_t>(queueDisc->GetQuantum()),
 
  311                          "the deficit of the first flow must equal the quantum");
 
  314                          "the first flow must be in the list of new queues");
 
  316    queueDisc->Dequeue();
 
  319                          "unexpected number of packets in the queue disc");
 
  322                          "unexpected number of packets in the first flow queue");
 
  331                          "unexpected number of packets in the queue disc");
 
  334                          "unexpected number of packets in the first flow queue");
 
  337                          "the first flow must still be in the list of new queues");
 
  345                          "unexpected number of packets in the queue disc");
 
  348                          "unexpected number of packets in the first flow queue");
 
  351                          "unexpected number of packets in the second flow queue");
 
  354                          static_cast<int32_t>(queueDisc->GetQuantum()),
 
  355                          "the deficit of the second flow must equal the quantum");
 
  358                          "the second flow must be in the list of new queues");
 
  361    queueDisc->Dequeue();
 
  364                          "unexpected number of packets in the queue disc");
 
  367                          "unexpected number of packets in the first flow queue");
 
  370                          "unexpected number of packets in the second flow queue");
 
  376                          "the first flow must be in the list of old queues");
 
  381                          "the second flow must be in the list of new queues");
 
  384    queueDisc->Dequeue();
 
  387                          "unexpected number of packets in the queue disc");
 
  390                          "unexpected number of packets in the first flow queue");
 
  393                          "unexpected number of packets in the second flow queue");
 
  398                          "the first flow must be in the list of old queues");
 
  404                          "the second flow must be in the list of new queues");
 
  407    queueDisc->Dequeue();
 
  410                          "unexpected number of packets in the queue disc");
 
  413                          "unexpected number of packets in the first flow queue");
 
  416                          "unexpected number of packets in the second flow queue");
 
  422                          "the first flow must be in the list of old queues");
 
  427                          "the second flow must be in the list of new queues");
 
  430    queueDisc->Dequeue();
 
  433                          "unexpected number of packets in the queue disc");
 
  436                          "unexpected number of packets in the first flow queue");
 
  439                          "unexpected number of packets in the second flow queue");
 
  444                          "the first flow must be in the list of old queues");
 
  450                          "the second flow must be in the list of new queues");
 
  453    queueDisc->Dequeue();
 
  464                          "the first flow must be inactive");
 
  468                          "the second flow must be inactive");
 
 
  485    void DoRun() 
override;
 
 
  496    : 
TestCase(
"Test TCP flows separation")
 
 
  510    p->AddHeader(tcpHdr);
 
  513    queue->Enqueue(item);
 
 
  522    queueDisc->SetQuantum(1500);
 
  523    queueDisc->Initialize();
 
  541                          "unexpected number of packets in the queue disc");
 
  544                          "unexpected number of packets in the first flow queue");
 
  551                          "unexpected number of packets in the queue disc");
 
  554                          "unexpected number of packets in the first flow queue");
 
  557                          "unexpected number of packets in the second flow queue");
 
  564                          "unexpected number of packets in the queue disc");
 
  567                          "unexpected number of packets in the first flow queue");
 
  570                          "unexpected number of packets in the second flow queue");
 
  573                          "unexpected number of packets in the third flow queue");
 
  581                          "unexpected number of packets in the queue disc");
 
  584                          "unexpected number of packets in the first flow queue");
 
  587                          "unexpected number of packets in the second flow queue");
 
  590                          "unexpected number of packets in the third flow queue");
 
  593                          "unexpected number of packets in the third flow queue");
 
 
  610    void DoRun() 
override;
 
 
  621    : 
TestCase(
"Test UDP flows separation")
 
 
  635    p->AddHeader(udpHdr);
 
  638    queue->Enqueue(item);
 
 
  647    queueDisc->SetQuantum(1500);
 
  648    queueDisc->Initialize();
 
  666                          "unexpected number of packets in the queue disc");
 
  669                          "unexpected number of packets in the first flow queue");
 
  676                          "unexpected number of packets in the queue disc");
 
  679                          "unexpected number of packets in the first flow queue");
 
  682                          "unexpected number of packets in the second flow queue");
 
  689                          "unexpected number of packets in the queue disc");
 
  692                          "unexpected number of packets in the first flow queue");
 
  695                          "unexpected number of packets in the second flow queue");
 
  698                          "unexpected number of packets in the third flow queue");
 
  706                          "unexpected number of packets in the queue disc");
 
  709                          "unexpected number of packets in the first flow queue");
 
  712                          "unexpected number of packets in the second flow queue");
 
  715                          "unexpected number of packets in the third flow queue");
 
  718                          "unexpected number of packets in the third flow queue");
 
 
  738    void DoRun() 
override;
 
 
  788        queue->Enqueue(item);
 
  792                          "unexpected number of flow queues");
 
  795                          "unexpected number of enqueued packets");
 
 
  840    queueDisc->SetQuantum(1514);
 
  841    queueDisc->Initialize();
 
  910        queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
  912        queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
  914        queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
  916        queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
  918        queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
  924                          "There should be some remaining packets");
 
  927                          "There should be some remaining packets");
 
  930                          "There should be some remaining packets");
 
  933                          "There should be some remaining packets");
 
  936                          "There should be some remaining packets");
 
  941                          "There should be 6 marked packets" 
  942                          "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First " 
  943                          "packet dequeues at 110ms which is greater than" 
  944                          "test's default target value 5ms. Sojourn time has just gone above " 
  945                          "target from below, need to stay above for at" 
  946                          "least q->interval before packet can be dropped. Second packet dequeues " 
  947                          "at 220ms which is greater than last dequeue" 
  948                          "time plus q->interval(test default 100ms) so the packet is marked. " 
  949                          "Third packet dequeues at 330ms and the sojourn" 
  950                          "time stayed above the target and dropnext value is less than 320 hence " 
  951                          "the packet is marked. 4 subsequent packets" 
  952                          "are marked as the sojourn time stays above the target. With 8th dequeue " 
  953                          "number of bytes in queue = 120 * 12 = 1440" 
  954                          "which is less m_minBytes(test's default value 1500 bytes) hence the " 
  955                          "packets stop getting marked");
 
  958                          "There should not be any dropped packets");
 
  961                          "There should be 6 marked packets");
 
  964                          "There should not be any dropped packets");
 
  967                          "There should be 6 marked packets");
 
  970                          "There should not be any dropped packets");
 
  976        "There should be 4 dropped packets" 
  977        "with 20 packets, total bytes in the queue = 120 * 20 = 2400. First packet dequeues at " 
  978        "110ms which is greater than" 
  979        "test's default target value 5ms. Sojourn time has just gone above target from below, need " 
  980        "to stay above for at" 
  981        "least q->interval before packet can be dropped. Second packet dequeues at 220ms which is " 
  982        "greater than last dequeue" 
  983        "time plus q->interval(test default 100ms) so packet is dropped and next is dequeued. 4th " 
  984        "packet dequeues at 330ms" 
  985        "and the sojourn time stayed above the target and dropnext value is less than 320 hence " 
  986        "the packet is dropped and next" 
  987        "packet is dequeued. 6th packet dequeues at 440ms and 2 more packets are dropped as " 
  988        "dropnext value is increased twice." 
  989        "12 Packets remaining in the queue, total number of bytes int the queue = 120 * 12 = 1440 " 
  991        "m_minBytes(test's default value 1500 bytes) hence the packets stop getting dropped");
 
  994                          "There should not be any marked packets");
 
  997                          "There should be 4 dropped packets");
 
 1000                          "There should not be any marked packets");
 
 1006                          "flow queue should have ECT0 packets");
 
 1010                          "flow queue should have ECT0 packets");
 
 1014                          "flow queue should have ECT0 packets");
 
 1025    queueDisc->SetQuantum(1514);
 
 1026    queueDisc->Initialize();
 
 1090    q0 = queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1091    q1 = queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1092    q2 = queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1093    q3 = queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1094    q4 = queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1100                          "There should be some remaining packets");
 
 1103                          "There should be some remaining packets");
 
 1106                          "There should be some remaining packets");
 
 1109                          "There should be some remaining packets");
 
 1112                          "There should be some remaining packets");
 
 1117                          "There should not be any dropped packets");
 
 1121        "There should not be any marked packets" 
 1122        "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 13th " 
 1123        "packet is 1.3ms which is" 
 1124        "less than CE threshold");
 
 1127                          "There should not be any dropped packets");
 
 1131        "There should be 6 marked packets" 
 1132        "with quantum of 1514, 13 packets of size 120 bytes can be dequeued. sojourn time of 8th " 
 1133        "packet is 2.1ms which is greater" 
 1134        "than CE threshold and subsequent packet also have sojourn time more 8th packet hence " 
 1135        "remaining packet are marked.");
 
 1138                          "There should not be any dropped packets");
 
 1142        "There should be 13 marked packets" 
 1143        "with quantum of 1514, 13 packets of size 120 bytes can be dequeued and all of them have " 
 1144        "sojourn time more than CE threshold");
 
 1150        "There should not be any marked packets");
 
 1153                          "There should not be any dropped packets");
 
 1157        "There should not be any marked packets");
 
 1160                          "There should not be any dropped packets");
 
 1167                          "flow queue should have ECT0 packets");
 
 1171                          "flow queue should have ECT0 packets");
 
 1175                          "flow queue should have ECT0 packets");
 
 1186    queueDisc->SetQuantum(1514);
 
 1187    queueDisc->Initialize();
 
 1251    q0 = queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1252    q1 = queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1253    q2 = queueDisc->GetQueueDiscClass(2)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1254    q3 = queueDisc->GetQueueDiscClass(3)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1255    q4 = queueDisc->GetQueueDiscClass(4)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1261                          "There should be some remaining packets");
 
 1264                          "There should be some remaining packets");
 
 1267                          "There should be some remaining packets");
 
 1270                          "There should be some remaining packets");
 
 1273                          "There should be some remaining packets");
 
 1278                          "There should not be any dropped packets");
 
 1282        20 - q0->GetNPackets(),
 
 1283        "Number of CE threshold" 
 1284        " exceeded marks plus Number of Target exceeded marks should be equal to total number of " 
 1285        "packets dequeued");
 
 1288                          "There should not be any dropped packets");
 
 1292        20 - q1->GetNPackets(),
 
 1293        "Number of CE threshold" 
 1294        " exceeded marks plus Number of Target exceeded marks should be equal to total number of " 
 1295        "packets dequeued");
 
 1298                          "There should not be any dropped packets");
 
 1302        20 - q2->GetNPackets(),
 
 1303        "Number of CE threshold" 
 1304        " exceeded marks plus Number of Target exceeded marks should be equal to total number of " 
 1305        "packets dequeued");
 
 1311        "There should not be any marked packets");
 
 1315        "There should be 4 dropped packets" 
 1316        " As queue delay is same as in test case 1, number of dropped packets should also be same");
 
 1320        "There should not be any marked packets");
 
 1323                          "There should be 4 dropped packets");
 
 1330                          "flow queue should have ECT0 packets");
 
 1334                          "flow queue should have ECT0 packets");
 
 1338                          "flow queue should have ECT0 packets");
 
 
 1374    void DoRun() 
override;
 
 
 1384    : 
TestCase(
"Test credits and flows status")
 
 
 1398    queue->Enqueue(item);
 
 
 1407    queueDisc->SetQuantum(90);
 
 1408    queueDisc->Initialize();
 
 1411    queueDisc->AddPacketFilter(filter);
 
 1442                          "unexpected number of packets in the queue disc");
 
 1445                          "unexpected number of packets in the first flow queue of set one");
 
 1448                          "unexpected number of packets in the second flow queue of set one");
 
 1451                          "unexpected number of packets in the third flow queue of set one");
 
 1454                          "unexpected number of packets in the fourth flow queue of set one");
 
 1457                          "unexpected number of packets in the fifth flow queue of set one");
 
 1460                          "unexpected number of packets in the sixth flow queue of set one");
 
 1463                          "unexpected number of packets in the seventh flow queue of set one");
 
 1466                          "unexpected number of packets in the eighth flow queue of set one");
 
 1471                          "unexpected number of packets in the first flow of set one");
 
 1476                          "unexpected number of packets in the first flow of set two");
 
 
 1494    void DoRun() 
override;
 
 
 1545    for (
uint32_t i = 0; i < nPkt; i++)
 
 1548        queue->Enqueue(item);
 
 
 1558    for (
uint32_t i = 0; i < nPkt; i++)
 
 
 1572    for (
uint32_t i = 0; i < nPkt; i++)
 
 
 1581    for (
uint32_t i = 0; i < nPkt; i++)
 
 
 1611    queueDisc->SetQuantum(1514);
 
 1612    queueDisc->Initialize();
 
 1622    double delay = 0.0005;
 
 1648        queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1650        queueDisc->GetQueueDiscClass(1)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1655        "There should be 66 marked packets" 
 1656        "4th packet is enqueued at 2ms and dequeued at 4ms hence the delay of 2ms which not " 
 1657        "greater than CE threshold" 
 1658        "5th packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and " 
 1659        "subsequent packet also do have delay" 
 1660        "greater than CE threshold so all the packets after 4th packet are marked");
 
 1663                          "There should not be any dropped packets");
 
 1666                          "There should not be any marked packets");
 
 1669                          "There should be 1 marked packets");
 
 1672                          "There should not be any dropped packets");
 
 1688    queueDisc->SetQuantum(1514);
 
 1689    queueDisc->Initialize();
 
 1727    q0 = queueDisc->GetQueueDiscClass(0)->GetQueueDisc()->GetObject<
CoDelQueueDisc>();
 
 1732        "There should be 68 marked packets" 
 1733        "2nd ECT1 packet is enqueued at 1.5ms and dequeued at 3ms hence the delay of 1.5ms which " 
 1734        "not greater than CE threshold" 
 1735        "3rd packet is enqueued at 2.5ms and dequeued at 5ms hence the delay of 2.5ms and " 
 1736        "subsequent packet also do have delay" 
 1737        "greater than CE threshold so all the packets after 2nd packet are marked");
 
 1740                          "There should not be any dropped packets");
 
 1743                          "There should be 1 marked packets");
 
 
This class tests the deficit per flow.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
void DoRun() override
Implementation to actually run this TestCase.
~FqCoDelQueueDiscDeficit() override
FqCoDelQueueDiscDeficit()
This class tests ECN marking.
void Dequeue(Ptr< FqCoDelQueueDisc > queue, uint32_t nPkt)
Dequeue some packets.
void DoRun() override
Implementation to actually run this TestCase.
FqCoDelQueueDiscECNMarking()
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, uint32_t nPkt, uint32_t nPktEnqueued, uint32_t nQueueFlows)
Enqueue some packets.
void DequeueWithDelay(Ptr< FqCoDelQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue some packets with delay.
~FqCoDelQueueDiscECNMarking() override
This class tests the IP flows separation and the packet limit.
void DoRun() override
Implementation to actually run this TestCase.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
~FqCoDelQueueDiscIPFlowsSeparationAndPacketLimit() override
FqCoDelQueueDiscIPFlowsSeparationAndPacketLimit()
This class tests L4S mode.
void DoRun() override
Implementation to actually run this TestCase.
~FqCoDelQueueDiscL4sMode() override
FqCoDelQueueDiscL4sMode()
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, uint32_t nPkt)
Enqueue some packets.
void AddPacketWithDelay(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr, double delay, uint32_t nPkt)
Enqueue some packets with delay.
void DequeueWithDelay(Ptr< FqCoDelQueueDisc > queue, double delay, uint32_t nPkt)
Dequeue some packets with delay.
void Dequeue(Ptr< FqCoDelQueueDisc > queue, uint32_t nPkt)
Dequeue some packets.
This class tests packets for which there is no suitable filter.
~FqCoDelQueueDiscNoSuitableFilter() override
void DoRun() override
Implementation to actually run this TestCase.
FqCoDelQueueDiscNoSuitableFilter()
This class tests linear probing, collision response, and set creation capability of set associative h...
FqCoDelQueueDiscSetLinearProbing()
~FqCoDelQueueDiscSetLinearProbing() override
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header hdr)
Enqueue a packet.
void DoRun() override
Implementation to actually run this TestCase.
This class tests the TCP flows separation.
FqCoDelQueueDiscTCPFlowsSeparation()
void DoRun() override
Implementation to actually run this TestCase.
~FqCoDelQueueDiscTCPFlowsSeparation() override
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, TcpHeader tcpHdr)
Enqueue a packet.
FQ-CoDel queue disc test suite.
FqCoDelQueueDiscTestSuite()
This class tests the UDP flows separation.
void AddPacket(Ptr< FqCoDelQueueDisc > queue, Ipv4Header ipHdr, UdpHeader udpHdr)
Enqueue a packet.
~FqCoDelQueueDiscUDPFlowsSeparation() override
void DoRun() override
Implementation to actually run this TestCase.
FqCoDelQueueDiscUDPFlowsSeparation()
Simple test packet filter able to classify IPv4 packets.
bool CheckProtocol(Ptr< QueueDiscItem > item) const override
Check the protocol.
int32_t DoClassify(Ptr< QueueDiscItem > item) const override
Classify a QueueDiscItem.
static TypeId GetTypeId()
Get the type ID.
~Ipv4TestPacketFilter() override
a polymophic address class
AttributeValue implementation for Boolean.
A CoDel packet queue disc.
static constexpr const char * TARGET_EXCEEDED_DROP
Sojourn time above target.
static constexpr const char * CE_THRESHOLD_EXCEEDED_MARK
Sojourn time above CE threshold.
static constexpr const char * TARGET_EXCEEDED_MARK
Sojourn time above target.
Ipv4 addresses are stored in host order in this class.
Ipv4PacketFilter is the abstract base class for filters defined for IPv4 packets.
Smart pointer class similar to boost::intrusive_ptr.
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
static void Run()
Run the simulation.
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Hold variables of type string.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
AttributeValue implementation for Time.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Hold an unsigned integer type.
static FqCoDelQueueDiscTestSuite g_fqCoDelQueueDiscTestSuite
Do not forget to allocate an instance of this TestSuite.
static int32_t g_hash
Variable to assign g_hash to a new packet's flow.
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Ptr< T > CreateObjectWithAttributes(Args... args)
Allocate an Object on the heap and initialize with a set of attributes.
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report if not.
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Time Seconds(double value)
Construct a Time in the indicated unit.
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Ptr< T1 > StaticCast(const Ptr< T2 > &p)
Cast a Ptr.