A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv6-flow-probe.cc
Go to the documentation of this file.
1//
2// Copyright (c) 2009 INESC Porto
3//
4// SPDX-License-Identifier: GPL-2.0-only
5//
6// Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
7// Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
8//
9
10#include "ipv6-flow-probe.h"
11
12#include "flow-monitor.h"
14
15#include "ns3/config.h"
16#include "ns3/flow-id-tag.h"
17#include "ns3/log.h"
18#include "ns3/node.h"
19#include "ns3/packet.h"
20#include "ns3/pointer.h"
21
22namespace ns3
23{
24
25NS_LOG_COMPONENT_DEFINE("Ipv6FlowProbe");
26
27//////////////////////////////////////
28// Ipv6FlowProbeTag class implementation //
29//////////////////////////////////////
30
31/**
32 * \ingroup flow-monitor
33 *
34 * \brief Tag used to allow a fast identification of the packet
35 *
36 * This tag is added by FlowMonitor when a packet is seen for
37 * the first time, and it is then used to classify the packet in
38 * the following hops.
39 */
40class Ipv6FlowProbeTag : public Tag
41{
42 public:
43 /**
44 * \brief Get the type ID.
45 * \return the object TypeId
46 */
47 static TypeId GetTypeId();
48 TypeId GetInstanceTypeId() const override;
49 uint32_t GetSerializedSize() const override;
50 void Serialize(TagBuffer buf) const override;
51 void Deserialize(TagBuffer buf) override;
52 void Print(std::ostream& os) const override;
54 /**
55 * \brief Constructor
56 * \param flowId the flow identifier
57 * \param packetId the packet identifier
58 * \param packetSize the packet size
59 */
61 /**
62 * \brief Set the flow identifier
63 * \param flowId the flow identifier
64 */
65 void SetFlowId(uint32_t flowId);
66 /**
67 * \brief Set the packet identifier
68 * \param packetId the packet identifier
69 */
70 void SetPacketId(uint32_t packetId);
71 /**
72 * \brief Set the packet size
73 * \param packetSize the packet size
74 */
76 /**
77 * \brief Set the flow identifier
78 * \returns the flow identifier
79 */
80 uint32_t GetFlowId() const;
81 /**
82 * \brief Set the packet identifier
83 * \returns the packet identifier
84 */
85 uint32_t GetPacketId() const;
86 /**
87 * \brief Get the packet size
88 * \returns the packet size
89 */
90 uint32_t GetPacketSize() const;
91
92 private:
93 uint32_t m_flowId; //!< flow identifier
94 uint32_t m_packetId; //!< packet identifier
95 uint32_t m_packetSize; //!< packet size
96};
97
100{
101 static TypeId tid = TypeId("ns3::Ipv6FlowProbeTag")
102 .SetParent<Tag>()
103 .SetGroupName("FlowMonitor")
104 .AddConstructor<Ipv6FlowProbeTag>();
105 return tid;
106}
107
108TypeId
110{
111 return GetTypeId();
112}
113
116{
117 return 4 + 4 + 4;
118}
119
120void
127
128void
130{
131 m_flowId = buf.ReadU32();
132 m_packetId = buf.ReadU32();
133 m_packetSize = buf.ReadU32();
134}
135
136void
137Ipv6FlowProbeTag::Print(std::ostream& os) const
138{
139 os << "FlowId=" << m_flowId;
140 os << "PacketId=" << m_packetId;
141 os << "PacketSize=" << m_packetSize;
142}
143
148
150 : Tag(),
151 m_flowId(flowId),
152 m_packetId(packetId),
153 m_packetSize(packetSize)
154{
155}
156
157void
162
163void
168
169void
174
177{
178 return m_flowId;
179}
180
183{
184 return m_packetId;
185}
186
189{
190 return m_packetSize;
191}
192
193////////////////////////////////////////
194// Ipv6FlowProbe class implementation //
195////////////////////////////////////////
196
198 Ptr<Ipv6FlowClassifier> classifier,
199 Ptr<Node> node)
200 : FlowProbe(monitor),
201 m_classifier(classifier)
202{
203 NS_LOG_FUNCTION(this << node->GetId());
204
205 Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol>();
206
207 if (!ipv6->TraceConnectWithoutContext(
208 "SendOutgoing",
210 {
211 NS_FATAL_ERROR("trace fail");
212 }
213 if (!ipv6->TraceConnectWithoutContext(
214 "UnicastForward",
216 {
217 NS_FATAL_ERROR("trace fail");
218 }
219 if (!ipv6->TraceConnectWithoutContext(
220 "LocalDeliver",
222 {
223 NS_FATAL_ERROR("trace fail");
224 }
225
226 if (!ipv6->TraceConnectWithoutContext(
227 "Drop",
229 {
230 NS_FATAL_ERROR("trace fail");
231 }
232
233 std::ostringstream qd;
234 qd << "/NodeList/" << node->GetId() << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
236 qd.str(),
238
239 // code copied from point-to-point-helper.cc
240 std::ostringstream oss;
241 oss << "/NodeList/" << node->GetId() << "/DeviceList/*/TxQueue/Drop";
243 oss.str(),
245}
246
247/* static */
248TypeId
250{
251 static TypeId tid =
252 TypeId("ns3::Ipv6FlowProbe").SetParent<FlowProbe>().SetGroupName("FlowMonitor")
253 // No AddConstructor because this class has no default constructor.
254 ;
255
256 return tid;
257}
258
262
263void
268
269void
271 Ptr<const Packet> ipPayload,
272 uint32_t interface)
273{
274 FlowId flowId;
275 FlowPacketId packetId;
276
277 if (m_classifier->Classify(ipHeader, ipPayload, &flowId, &packetId))
278 {
279 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
280 NS_LOG_DEBUG("ReportFirstTx (" << this << ", " << flowId << ", " << packetId << ", " << size
281 << "); " << ipHeader << *ipPayload);
282 m_flowMonitor->ReportFirstTx(this, flowId, packetId, size);
283
284 // tag the packet with the flow id and packet id, so that the packet can be identified even
285 // when Ipv6Header is not accessible at some non-IPv6 protocol layer
286 Ipv6FlowProbeTag fTag(flowId, packetId, size);
287 ipPayload->AddByteTag(fTag);
288 }
289}
290
291void
293 Ptr<const Packet> ipPayload,
294 uint32_t interface)
295{
296 Ipv6FlowProbeTag fTag;
297 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
298
299 if (found)
300 {
301 FlowId flowId = fTag.GetFlowId();
302 FlowPacketId packetId = fTag.GetPacketId();
303
304 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
305 NS_LOG_DEBUG("ReportForwarding (" << this << ", " << flowId << ", " << packetId << ", "
306 << size << ");");
307 m_flowMonitor->ReportForwarding(this, flowId, packetId, size);
308 }
309}
310
311void
313 Ptr<const Packet> ipPayload,
314 uint32_t interface)
315{
316 Ipv6FlowProbeTag fTag;
317 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
318
319 if (found)
320 {
321 FlowId flowId = fTag.GetFlowId();
322 FlowPacketId packetId = fTag.GetPacketId();
323
324 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
325 NS_LOG_DEBUG("ReportLastRx (" << this << ", " << flowId << ", " << packetId << ", " << size
326 << ");");
327 m_flowMonitor->ReportLastRx(this, flowId, packetId, size);
328 }
329}
330
331void
333 Ptr<const Packet> ipPayload,
335 Ptr<Ipv6> ipv6,
336 uint32_t ifIndex)
337{
338#if 0
339 switch (reason)
340 {
342 break;
343
345 case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
346 Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
347 Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
348 Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
349 if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
350 {
351 return;
352 }
353 }
354#endif
355
356 Ipv6FlowProbeTag fTag;
357 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
358
359 if (found)
360 {
361 FlowId flowId = fTag.GetFlowId();
362 FlowPacketId packetId = fTag.GetPacketId();
363
364 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
365 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
366 << reason << ", destIp=" << ipHeader.GetDestination() << "); "
367 << "HDR: " << ipHeader << " PKT: " << *ipPayload);
368
369 DropReason myReason;
370
371 switch (reason)
372 {
374 myReason = DROP_TTL_EXPIRE;
375 NS_LOG_DEBUG("DROP_TTL_EXPIRE");
376 break;
378 myReason = DROP_NO_ROUTE;
379 NS_LOG_DEBUG("DROP_NO_ROUTE");
380 break;
382 myReason = DROP_INTERFACE_DOWN;
383 NS_LOG_DEBUG("DROP_INTERFACE_DOWN");
384 break;
386 myReason = DROP_ROUTE_ERROR;
387 NS_LOG_DEBUG("DROP_ROUTE_ERROR");
388 break;
390 myReason = DROP_UNKNOWN_PROTOCOL;
391 NS_LOG_DEBUG("DROP_UNKNOWN_PROTOCOL");
392 break;
394 myReason = DROP_UNKNOWN_OPTION;
395 NS_LOG_DEBUG("DROP_UNKNOWN_OPTION");
396 break;
398 myReason = DROP_MALFORMED_HEADER;
399 NS_LOG_DEBUG("DROP_MALFORMED_HEADER");
400 break;
402 myReason = DROP_FRAGMENT_TIMEOUT;
403 NS_LOG_DEBUG("DROP_FRAGMENT_TIMEOUT");
404 break;
405 default:
406 myReason = DROP_INVALID_REASON;
407 NS_FATAL_ERROR("Unexpected drop reason code " << reason);
408 }
409
410 m_flowMonitor->ReportDrop(this, flowId, packetId, size, myReason);
411 }
412}
413
414void
416{
417 Ipv6FlowProbeTag fTag;
418 bool tagFound = ipPayload->FindFirstMatchingByteTag(fTag);
419
420 if (!tagFound)
421 {
422 return;
423 }
424
425 FlowId flowId = fTag.GetFlowId();
426 FlowPacketId packetId = fTag.GetPacketId();
427 uint32_t size = fTag.GetPacketSize();
428
429 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
430 << DROP_QUEUE << "); ");
431
432 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE);
433}
434
435void
437{
438 Ipv6FlowProbeTag fTag;
439 bool tagFound = item->GetPacket()->FindFirstMatchingByteTag(fTag);
440
441 if (!tagFound)
442 {
443 return;
444 }
445
446 FlowId flowId = fTag.GetFlowId();
447 FlowPacketId packetId = fTag.GetPacketId();
448 uint32_t size = fTag.GetPacketSize();
449
450 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
451 << DROP_QUEUE_DISC << "); ");
452
453 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE_DISC);
454}
455
456} // namespace ns3
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition flow-probe.h:30
void DoDispose() override
Destructor implementation.
Definition flow-probe.cc:38
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition flow-probe.h:98
Describes an IPv6 address.
void DoDispose() override
Destructor implementation.
void QueueDiscDropLogger(Ptr< const QueueDiscItem > item)
Log a packet being dropped by a queue disc.
void QueueDropLogger(Ptr< const Packet > ipPayload)
Log a packet being dropped by a queue.
static TypeId GetTypeId()
Register this type.
Ptr< Ipv6FlowClassifier > m_classifier
the Ipv6FlowClassifier this probe is associated with
void DropLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, Ipv6L3Protocol::DropReason reason, Ptr< Ipv6 > ipv6, uint32_t ifIndex)
Log a packet being dropped.
void ForwardLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being forwarded.
Ipv6FlowProbe(Ptr< FlowMonitor > monitor, Ptr< Ipv6FlowClassifier > classifier, Ptr< Node > node)
Constructor.
void ForwardUpLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being received by the destination.
DropReason
enumeration of possible reasons why a packet may be dropped
@ DROP_TTL_EXPIRE
Packet dropped due to TTL decremented to zero during IPv4 forwarding.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout exceeded.
@ DROP_NO_ROUTE
Packet dropped due to missing route to the destination.
@ DROP_UNKNOWN_OPTION
Unknown option.
@ DROP_QUEUE_DISC
Packet dropped by the queue disc.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_MALFORMED_HEADER
Malformed header.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_UNKNOWN_PROTOCOL
Unknown L4 protocol.
@ DROP_INVALID_REASON
Fallback reason (no known reason)
@ DROP_QUEUE
Packet dropped due to queue overflow.
void SendOutgoingLogger(const Ipv6Header &ipHeader, Ptr< const Packet > ipPayload, uint32_t interface)
Log a packet being sent.
Tag used to allow a fast identification of the packet.
uint32_t GetFlowId() const
Set the flow identifier.
uint32_t m_flowId
flow identifier
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void SetFlowId(uint32_t flowId)
Set the flow identifier.
void SetPacketId(uint32_t packetId)
Set the packet identifier.
void Deserialize(TagBuffer buf) override
void SetPacketSize(uint32_t packetSize)
Set the packet size.
uint32_t GetPacketSize() const
Get the packet size.
static TypeId GetTypeId()
Get the type ID.
uint32_t GetPacketId() const
Set the packet identifier.
uint32_t GetSerializedSize() const override
void Print(std::ostream &os) const override
void Serialize(TagBuffer buf) const override
uint32_t m_packetSize
packet size
uint32_t m_packetId
packet identifier
Packet header for IPv6.
Definition ipv6-header.h:24
Ipv6Address GetDestination() const
Get the "Destination address" field.
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
IPv6 layer implementation.
DropReason
Reason why a packet has been dropped.
@ DROP_FRAGMENT_TIMEOUT
Fragment timeout.
@ DROP_ROUTE_ERROR
Route error.
@ DROP_TTL_EXPIRED
Packet TTL has expired.
@ DROP_INTERFACE_DOWN
Interface is down so can not send packet.
@ DROP_UNKNOWN_OPTION
Unknown option.
@ DROP_NO_ROUTE
No route to host.
@ DROP_UNKNOWN_PROTOCOL
Unknown L4 protocol.
@ DROP_MALFORMED_HEADER
Malformed header.
Smart pointer class similar to boost::intrusive_ptr.
read and write tag data
Definition tag-buffer.h:41
TAG_BUFFER_INLINE uint32_t ReadU32()
Definition tag-buffer.h:206
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition tag-buffer.h:176
tag a set of bytes in a packet
Definition tag.h:28
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition config.cc:953
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
static const uint32_t packetSize
Packet size generated at the AP.