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 "ns3/ipv6-flow-probe.h"
22
23#include "ns3/config.h"
24#include "ns3/flow-id-tag.h"
25#include "ns3/flow-monitor.h"
26#include "ns3/ipv6-flow-classifier.h"
27#include "ns3/log.h"
28#include "ns3/node.h"
29#include "ns3/packet.h"
30#include "ns3/pointer.h"
31
32namespace ns3
33{
34
35NS_LOG_COMPONENT_DEFINE("Ipv6FlowProbe");
36
38// Ipv6FlowProbeTag class implementation //
40
50class Ipv6FlowProbeTag : public Tag
51{
52 public:
57 static TypeId GetTypeId();
58 TypeId GetInstanceTypeId() const override;
59 uint32_t GetSerializedSize() const override;
60 void Serialize(TagBuffer buf) const override;
61 void Deserialize(TagBuffer buf) override;
62 void Print(std::ostream& os) const override;
75 void SetFlowId(uint32_t flowId);
80 void SetPacketId(uint32_t packetId);
90 uint32_t GetFlowId() const;
95 uint32_t GetPacketId() const;
100 uint32_t GetPacketSize() const;
101
102 private:
106};
107
108TypeId
110{
111 static TypeId tid = TypeId("ns3::Ipv6FlowProbeTag")
112 .SetParent<Tag>()
113 .SetGroupName("FlowMonitor")
114 .AddConstructor<Ipv6FlowProbeTag>();
115 return tid;
116}
117
118TypeId
120{
121 return GetTypeId();
122}
123
126{
127 return 4 + 4 + 4;
128}
129
130void
132{
133 buf.WriteU32(m_flowId);
134 buf.WriteU32(m_packetId);
136}
137
138void
140{
141 m_flowId = buf.ReadU32();
142 m_packetId = buf.ReadU32();
143 m_packetSize = buf.ReadU32();
144}
145
146void
147Ipv6FlowProbeTag::Print(std::ostream& os) const
148{
149 os << "FlowId=" << m_flowId;
150 os << "PacketId=" << m_packetId;
151 os << "PacketSize=" << m_packetSize;
152}
153
155 : Tag()
156{
157}
158
160 : Tag(),
161 m_flowId(flowId),
162 m_packetId(packetId),
163 m_packetSize(packetSize)
164{
165}
166
167void
169{
170 m_flowId = id;
171}
172
173void
175{
176 m_packetId = id;
177}
178
179void
181{
182 m_packetSize = size;
183}
184
187{
188 return m_flowId;
189}
190
193{
194 return m_packetId;
195}
196
199{
200 return m_packetSize;
201}
202
204// Ipv6FlowProbe class implementation //
206
208 Ptr<Ipv6FlowClassifier> classifier,
209 Ptr<Node> node)
210 : FlowProbe(monitor),
211 m_classifier(classifier)
212{
213 NS_LOG_FUNCTION(this << node->GetId());
214
215 Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol>();
216
217 if (!ipv6->TraceConnectWithoutContext(
218 "SendOutgoing",
220 {
221 NS_FATAL_ERROR("trace fail");
222 }
223 if (!ipv6->TraceConnectWithoutContext(
224 "UnicastForward",
226 {
227 NS_FATAL_ERROR("trace fail");
228 }
229 if (!ipv6->TraceConnectWithoutContext(
230 "LocalDeliver",
232 {
233 NS_FATAL_ERROR("trace fail");
234 }
235
236 if (!ipv6->TraceConnectWithoutContext(
237 "Drop",
239 {
240 NS_FATAL_ERROR("trace fail");
241 }
242
243 std::ostringstream qd;
244 qd << "/NodeList/" << node->GetId() << "/$ns3::TrafficControlLayer/RootQueueDiscList/*/Drop";
246 qd.str(),
248
249 // code copied from point-to-point-helper.cc
250 std::ostringstream oss;
251 oss << "/NodeList/" << node->GetId() << "/DeviceList/*/TxQueue/Drop";
253 oss.str(),
255}
256
257/* static */
258TypeId
260{
261 static TypeId tid =
262 TypeId("ns3::Ipv6FlowProbe").SetParent<FlowProbe>().SetGroupName("FlowMonitor")
263 // No AddConstructor because this class has no default constructor.
264 ;
265
266 return tid;
267}
268
270{
271}
272
273void
275{
277}
278
279void
281 Ptr<const Packet> ipPayload,
282 uint32_t interface)
283{
284 FlowId flowId;
285 FlowPacketId packetId;
286
287 if (m_classifier->Classify(ipHeader, ipPayload, &flowId, &packetId))
288 {
289 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
290 NS_LOG_DEBUG("ReportFirstTx (" << this << ", " << flowId << ", " << packetId << ", " << size
291 << "); " << ipHeader << *ipPayload);
292 m_flowMonitor->ReportFirstTx(this, flowId, packetId, size);
293
294 // tag the packet with the flow id and packet id, so that the packet can be identified even
295 // when Ipv6Header is not accessible at some non-IPv6 protocol layer
296 Ipv6FlowProbeTag fTag(flowId, packetId, size);
297 ipPayload->AddByteTag(fTag);
298 }
299}
300
301void
303 Ptr<const Packet> ipPayload,
304 uint32_t interface)
305{
306 Ipv6FlowProbeTag fTag;
307 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
308
309 if (found)
310 {
311 FlowId flowId = fTag.GetFlowId();
312 FlowPacketId packetId = fTag.GetPacketId();
313
314 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
315 NS_LOG_DEBUG("ReportForwarding (" << this << ", " << flowId << ", " << packetId << ", "
316 << size << ");");
317 m_flowMonitor->ReportForwarding(this, flowId, packetId, size);
318 }
319}
320
321void
323 Ptr<const Packet> ipPayload,
324 uint32_t interface)
325{
326 Ipv6FlowProbeTag fTag;
327 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
328
329 if (found)
330 {
331 FlowId flowId = fTag.GetFlowId();
332 FlowPacketId packetId = fTag.GetPacketId();
333
334 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
335 NS_LOG_DEBUG("ReportLastRx (" << this << ", " << flowId << ", " << packetId << ", " << size
336 << ");");
337 m_flowMonitor->ReportLastRx(this, flowId, packetId, size);
338 }
339}
340
341void
343 Ptr<const Packet> ipPayload,
345 Ptr<Ipv6> ipv6,
346 uint32_t ifIndex)
347{
348#if 0
349 switch (reason)
350 {
352 break;
353
355 case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
356 Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
357 Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
358 Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
359 if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
360 {
361 return;
362 }
363 }
364#endif
365
366 Ipv6FlowProbeTag fTag;
367 bool found = ipPayload->FindFirstMatchingByteTag(fTag);
368
369 if (found)
370 {
371 FlowId flowId = fTag.GetFlowId();
372 FlowPacketId packetId = fTag.GetPacketId();
373
374 uint32_t size = (ipPayload->GetSize() + ipHeader.GetSerializedSize());
375 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
376 << reason << ", destIp=" << ipHeader.GetDestination() << "); "
377 << "HDR: " << ipHeader << " PKT: " << *ipPayload);
378
379 DropReason myReason;
380
381 switch (reason)
382 {
384 myReason = DROP_TTL_EXPIRE;
385 NS_LOG_DEBUG("DROP_TTL_EXPIRE");
386 break;
388 myReason = DROP_NO_ROUTE;
389 NS_LOG_DEBUG("DROP_NO_ROUTE");
390 break;
392 myReason = DROP_INTERFACE_DOWN;
393 NS_LOG_DEBUG("DROP_INTERFACE_DOWN");
394 break;
396 myReason = DROP_ROUTE_ERROR;
397 NS_LOG_DEBUG("DROP_ROUTE_ERROR");
398 break;
400 myReason = DROP_UNKNOWN_PROTOCOL;
401 NS_LOG_DEBUG("DROP_UNKNOWN_PROTOCOL");
402 break;
404 myReason = DROP_UNKNOWN_OPTION;
405 NS_LOG_DEBUG("DROP_UNKNOWN_OPTION");
406 break;
408 myReason = DROP_MALFORMED_HEADER;
409 NS_LOG_DEBUG("DROP_MALFORMED_HEADER");
410 break;
412 myReason = DROP_FRAGMENT_TIMEOUT;
413 NS_LOG_DEBUG("DROP_FRAGMENT_TIMEOUT");
414 break;
415 default:
416 myReason = DROP_INVALID_REASON;
417 NS_FATAL_ERROR("Unexpected drop reason code " << reason);
418 }
419
420 m_flowMonitor->ReportDrop(this, flowId, packetId, size, myReason);
421 }
422}
423
424void
426{
427 Ipv6FlowProbeTag fTag;
428 bool tagFound = ipPayload->FindFirstMatchingByteTag(fTag);
429
430 if (!tagFound)
431 {
432 return;
433 }
434
435 FlowId flowId = fTag.GetFlowId();
436 FlowPacketId packetId = fTag.GetPacketId();
437 uint32_t size = fTag.GetPacketSize();
438
439 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
440 << DROP_QUEUE << "); ");
441
442 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE);
443}
444
445void
447{
448 Ipv6FlowProbeTag fTag;
449 bool tagFound = item->GetPacket()->FindFirstMatchingByteTag(fTag);
450
451 if (!tagFound)
452 {
453 return;
454 }
455
456 FlowId flowId = fTag.GetFlowId();
457 FlowPacketId packetId = fTag.GetPacketId();
458 uint32_t size = fTag.GetPacketSize();
459
460 NS_LOG_DEBUG("Drop (" << this << ", " << flowId << ", " << packetId << ", " << size << ", "
461 << DROP_QUEUE_DISC << "); ");
462
463 m_flowMonitor->ReportDrop(this, flowId, packetId, size, DROP_QUEUE_DISC);
464}
465
466} // namespace ns3
The FlowProbe class is responsible for listening for packet events in a specific point of the simulat...
Definition: flow-probe.h:40
void DoDispose() override
Destructor implementation.
Definition: flow-probe.cc:49
Ptr< FlowMonitor > m_flowMonitor
the FlowMonitor instance
Definition: flow-probe.h:108
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:78
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:936
bool ConnectWithoutContextFailSafe(std::string path, const CallbackBase &cb)
Definition: config.cc:961
#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:702
static const uint32_t packetSize
Packet size generated at the AP.