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// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License version 2 as
6// published by the Free Software Foundation;
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program; if not, write to the Free Software
15// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16//
17// Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
18// Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
19//
20
21#include "ipv6-flow-probe.h"
22
23#include "flow-monitor.h"
25
26#include "ns3/config.h"
27#include "ns3/flow-id-tag.h"
28#include "ns3/log.h"
29#include "ns3/node.h"
30#include "ns3/packet.h"
31#include "ns3/pointer.h"
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("Ipv6FlowProbe");
37
38//////////////////////////////////////
39// Ipv6FlowProbeTag class implementation //
40//////////////////////////////////////
41
42/**
43 * \ingroup flow-monitor
44 *
45 * \brief Tag used to allow a fast identification of the packet
46 *
47 * This tag is added by FlowMonitor when a packet is seen for
48 * the first time, and it is then used to classify the packet in
49 * the following hops.
50 */
51class Ipv6FlowProbeTag : public Tag
52{
53 public:
54 /**
55 * \brief Get the type ID.
56 * \return the object TypeId
57 */
58 static TypeId GetTypeId();
59 TypeId GetInstanceTypeId() const override;
60 uint32_t GetSerializedSize() const override;
61 void Serialize(TagBuffer buf) const override;
62 void Deserialize(TagBuffer buf) override;
63 void Print(std::ostream& os) const override;
65 /**
66 * \brief Constructor
67 * \param flowId the flow identifier
68 * \param packetId the packet identifier
69 * \param packetSize the packet size
70 */
72 /**
73 * \brief Set the flow identifier
74 * \param flowId the flow identifier
75 */
76 void SetFlowId(uint32_t flowId);
77 /**
78 * \brief Set the packet identifier
79 * \param packetId the packet identifier
80 */
81 void SetPacketId(uint32_t packetId);
82 /**
83 * \brief Set the packet size
84 * \param packetSize the packet size
85 */
87 /**
88 * \brief Set the flow identifier
89 * \returns the flow identifier
90 */
91 uint32_t GetFlowId() const;
92 /**
93 * \brief Set the packet identifier
94 * \returns the packet identifier
95 */
96 uint32_t GetPacketId() const;
97 /**
98 * \brief Get the packet size
99 * \returns the packet size
100 */
101 uint32_t GetPacketSize() const;
102
103 private:
104 uint32_t m_flowId; //!< flow identifier
105 uint32_t m_packetId; //!< packet identifier
106 uint32_t m_packetSize; //!< packet size
107};
108
109TypeId
111{
112 static TypeId tid = TypeId("ns3::Ipv6FlowProbeTag")
113 .SetParent<Tag>()
114 .SetGroupName("FlowMonitor")
115 .AddConstructor<Ipv6FlowProbeTag>();
116 return tid;
117}
118
119TypeId
121{
122 return GetTypeId();
123}
124
127{
128 return 4 + 4 + 4;
129}
130
131void
133{
134 buf.WriteU32(m_flowId);
135 buf.WriteU32(m_packetId);
137}
138
139void
141{
142 m_flowId = buf.ReadU32();
143 m_packetId = buf.ReadU32();
144 m_packetSize = buf.ReadU32();
145}
146
147void
148Ipv6FlowProbeTag::Print(std::ostream& os) const
149{
150 os << "FlowId=" << m_flowId;
151 os << "PacketId=" << m_packetId;
152 os << "PacketSize=" << m_packetSize;
153}
154
156 : Tag()
157{
158}
159
161 : Tag(),
162 m_flowId(flowId),
163 m_packetId(packetId),
164 m_packetSize(packetSize)
165{
166}
167
168void
170{
171 m_flowId = id;
172}
173
174void
176{
177 m_packetId = id;
178}
179
180void
182{
183 m_packetSize = size;
184}
185
188{
189 return m_flowId;
190}
191
194{
195 return m_packetId;
196}
197
200{
201 return m_packetSize;
202}
203
204////////////////////////////////////////
205// Ipv6FlowProbe class implementation //
206////////////////////////////////////////
207
209 Ptr<Ipv6FlowClassifier> classifier,
210 Ptr<Node> node)
211 : FlowProbe(monitor),
212 m_classifier(classifier)
213{
214 NS_LOG_FUNCTION(this << node->GetId());
215
216 Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol>();
217
218 if (!ipv6->TraceConnectWithoutContext(
219 "SendOutgoing",
221 {
222 NS_FATAL_ERROR("trace fail");
223 }
224 if (!ipv6->TraceConnectWithoutContext(
225 "UnicastForward",
227 {
228 NS_FATAL_ERROR("trace fail");
229 }
230 if (!ipv6->TraceConnectWithoutContext(
231 "LocalDeliver",
233 {
234 NS_FATAL_ERROR("trace fail");
235 }
236
237 if (!ipv6->TraceConnectWithoutContext(
238 "Drop",
240 {
241 NS_FATAL_ERROR("trace fail");
242 }
243
244 std::ostringstream qd;
245 qd << "/NodeList/" << node->GetId() << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
247 qd.str(),
249
250 // code copied from point-to-point-helper.cc
251 std::ostringstream oss;
252 oss << "/NodeList/" << node->GetId() << "/DeviceList/*/TxQueue/Drop";
254 oss.str(),
256}
257
258/* static */
259TypeId
261{
262 static TypeId tid =
263 TypeId("ns3::Ipv6FlowProbe").SetParent<FlowProbe>().SetGroupName("FlowMonitor")
264 // No AddConstructor because this class has no default constructor.
265 ;
266
267 return tid;
268}
269
271{
272}
273
274void
276{
278}
279
280void
282 Ptr<const Packet> ipPayload,
283 uint32_t interface)
284{
285 FlowId flowId;
286 FlowPacketId packetId;
287
288 if (m_classifier->Classify(ipHeader, ipPayload, &flowId, &packetId))
289 {
290 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
291 NS_LOG_DEBUG("ReportFirstTx (" << this << ", " << flowId << ", " << packetId << ", " << size
292 << "); " << ipHeader << *ipPayload);
293 m_flowMonitor->ReportFirstTx(this, flowId, packetId, size);
294
295 // tag the packet with the flow id and packet id, so that the packet can be identified even
296 // when Ipv6Header is not accessible at some non-IPv6 protocol layer
297 Ipv6FlowProbeTag fTag(flowId, packetId, size);
298 ipPayload->AddByteTag(fTag);
299 }
300}
301
302void
304 Ptr<const Packet> ipPayload,
305 uint32_t interface)
306{
307 Ipv6FlowProbeTag fTag;
308 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
309
310 if (found)
311 {
312 FlowId flowId = fTag.GetFlowId();
313 FlowPacketId packetId = fTag.GetPacketId();
314
315 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
316 NS_LOG_DEBUG("ReportForwarding (" << this << ", " << flowId << ", " << packetId << ", "
317 << size << ");");
318 m_flowMonitor->ReportForwarding(this, flowId, packetId, size);
319 }
320}
321
322void
324 Ptr<const Packet> ipPayload,
325 uint32_t interface)
326{
327 Ipv6FlowProbeTag fTag;
328 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
329
330 if (found)
331 {
332 FlowId flowId = fTag.GetFlowId();
333 FlowPacketId packetId = fTag.GetPacketId();
334
335 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
336 NS_LOG_DEBUG("ReportLastRx (" << this << ", " << flowId << ", " << packetId << ", " << size
337 << ");");
338 m_flowMonitor->ReportLastRx(this, flowId, packetId, size);
339 }
340}
341
342void
344 Ptr<const Packet> ipPayload,
346 Ptr<Ipv6> ipv6,
347 uint32_t ifIndex)
348{
349#if 0
350 switch (reason)
351 {
353 break;
354
356 case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
357 Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
358 Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
359 Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
360 if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
361 {
362 return;
363 }
364 }
365#endif
366
367 Ipv6FlowProbeTag fTag;
368 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
369
370 if (found)
371 {
372 FlowId flowId = fTag.GetFlowId();
373 FlowPacketId packetId = fTag.GetPacketId();
374
375 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
376 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
377 << reason << ", destIp=" << ipHeader.GetDestination() << "); "
378 << "HDR: " << ipHeader << " PKT: " << *ipPayload);
379
380 DropReason myReason;
381
382 switch (reason)
383 {
385 myReason = DROP_TTL_EXPIRE;
386 NS_LOG_DEBUG("DROP_TTL_EXPIRE");
387 break;
389 myReason = DROP_NO_ROUTE;
390 NS_LOG_DEBUG("DROP_NO_ROUTE");
391 break;
393 myReason = DROP_INTERFACE_DOWN;
394 NS_LOG_DEBUG("DROP_INTERFACE_DOWN");
395 break;
397 myReason = DROP_ROUTE_ERROR;
398 NS_LOG_DEBUG("DROP_ROUTE_ERROR");
399 break;
401 myReason = DROP_UNKNOWN_PROTOCOL;
402 NS_LOG_DEBUG("DROP_UNKNOWN_PROTOCOL");
403 break;
405 myReason = DROP_UNKNOWN_OPTION;
406 NS_LOG_DEBUG("DROP_UNKNOWN_OPTION");
407 break;
409 myReason = DROP_MALFORMED_HEADER;
410 NS_LOG_DEBUG("DROP_MALFORMED_HEADER");
411 break;
413 myReason = DROP_FRAGMENT_TIMEOUT;
414 NS_LOG_DEBUG("DROP_FRAGMENT_TIMEOUT");
415 break;
416 default:
417 myReason = DROP_INVALID_REASON;
418 NS_FATAL_ERROR("Unexpected drop reason code " << reason);
419 }
420
421 m_flowMonitor->ReportDrop(this, flowId, packetId, size, myReason);
422 }
423}
424
425void
427{
428 Ipv6FlowProbeTag fTag;
429 bool tagFound = ipPayload->FindFirstMatchingByteTag(fTag);
430
431 if (!tagFound)
432 {
433 return;
434 }
435
436 FlowId flowId = fTag.GetFlowId();
437 FlowPacketId packetId = fTag.GetPacketId();
438 uint32_t size = fTag.GetPacketSize();
439
440 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
441 << DROP_QUEUE << "); ");
442
443 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE);
444}
445
446void
448{
449 Ipv6FlowProbeTag fTag;
450 bool tagFound = item->GetPacket()->FindFirstMatchingByteTag(fTag);
451
452 if (!tagFound)
453 {
454 return;
455 }
456
457 FlowId flowId = fTag.GetFlowId();
458 FlowPacketId packetId = fTag.GetPacketId();
459 uint32_t size = fTag.GetPacketSize();
460
461 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
462 << DROP_QUEUE_DISC << "); ");
463
464 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE_DISC);
465}
466
467} // namespace ns3
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition: flow-probe.h:41
void DoDispose() override
Destructor implementation.
Definition: flow-probe.cc:49
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition: flow-probe.h:109
Describes an IPv6 address.
Definition: ipv6-address.h:49
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:35
Ipv6Address GetDestination() const
Get the "Destination address" field.
Definition: ipv6-header.cc:124
uint32_t GetSerializedSize() const override
Get the serialized size of the packet.
Definition: ipv6-header.cc:159
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.
Definition: ptr.h:77
read and write tag data
Definition: tag-buffer.h:52
TAG_BUFFER_INLINE uint32_t ReadU32()
Definition: tag-buffer.h:217
TAG_BUFFER_INLINE void WriteU32(uint32_t v)
Definition: tag-buffer.h:187
tag a set of bytes in a packet
Definition: tag.h:39
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:964
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#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:704
static const uint32_t packetSize
Packet size generated at the AP.