View | Details | Raw Unified | Return to bug 1818
Collapse All | Expand All

(-)a/src/flow-monitor/helper/flow-monitor-helper.cc (-8 / +33 lines)
 Lines 24-29    Link Here 
24
#include "ns3/ipv4-flow-classifier.h"
24
#include "ns3/ipv4-flow-classifier.h"
25
#include "ns3/ipv4-flow-probe.h"
25
#include "ns3/ipv4-flow-probe.h"
26
#include "ns3/ipv4-l3-protocol.h"
26
#include "ns3/ipv4-l3-protocol.h"
27
#include "ns3/ipv6-flow-classifier.h"
28
#include "ns3/ipv6-flow-probe.h"
29
#include "ns3/ipv6-l3-protocol.h"
27
#include "ns3/node.h"
30
#include "ns3/node.h"
28
#include "ns3/node-list.h"
31
#include "ns3/node-list.h"
29
32
 Lines 41-47    Link Here 
41
    {
44
    {
42
      m_flowMonitor->Dispose ();
45
      m_flowMonitor->Dispose ();
43
      m_flowMonitor = 0;
46
      m_flowMonitor = 0;
44
      m_flowClassifier = 0;
47
      m_flowClassifier4 = 0;
48
      m_flowClassifier6 = 0;
45
    }
49
    }
46
}
50
}
47
51
 Lines 58-65    Link Here 
58
  if (!m_flowMonitor)
62
  if (!m_flowMonitor)
59
    {
63
    {
60
      m_flowMonitor = m_monitorFactory.Create<FlowMonitor> ();
64
      m_flowMonitor = m_monitorFactory.Create<FlowMonitor> ();
61
      m_flowClassifier = Create<Ipv4FlowClassifier> ();
65
      m_flowClassifier4 = Create<Ipv4FlowClassifier> ();
62
      m_flowMonitor->SetFlowClassifier (m_flowClassifier);
66
      m_flowMonitor->AddFlowClassifier (m_flowClassifier4);
67
      m_flowClassifier6 = Create<Ipv6FlowClassifier> ();
68
      m_flowMonitor->AddFlowClassifier (m_flowClassifier6);
63
    }
69
    }
64
  return m_flowMonitor;
70
  return m_flowMonitor;
65
}
71
}
 Lines 68-78    Link Here 
68
Ptr<FlowClassifier>
74
Ptr<FlowClassifier>
69
FlowMonitorHelper::GetClassifier ()
75
FlowMonitorHelper::GetClassifier ()
70
{
76
{
71
  if (!m_flowClassifier)
77
  if (!m_flowClassifier4)
72
    {
78
    {
73
      m_flowClassifier = Create<Ipv4FlowClassifier> ();
79
      m_flowClassifier4 = Create<Ipv4FlowClassifier> ();
74
    }
80
    }
75
  return m_flowClassifier;
81
  return m_flowClassifier4;
82
}
83
84
85
Ptr<FlowClassifier>
86
FlowMonitorHelper::GetClassifier6 ()
87
{
88
  if (!m_flowClassifier6)
89
    {
90
      m_flowClassifier6 = Create<Ipv6FlowClassifier> ();
91
    }
92
  return m_flowClassifier6;
76
}
93
}
77
94
78
95
 Lines 88-93    Link Here 
88
                                                        DynamicCast<Ipv4FlowClassifier> (classifier),
105
                                                        DynamicCast<Ipv4FlowClassifier> (classifier),
89
                                                        node);
106
                                                        node);
90
    }
107
    }
108
  Ptr<FlowClassifier> classifier6 = GetClassifier6 ();
109
  Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol> ();
110
  if (ipv6)
111
    {
112
      Ptr<Ipv6FlowProbe> probe6 = Create<Ipv6FlowProbe> (monitor,
113
                                                         DynamicCast<Ipv6FlowClassifier> (classifier6),
114
                                                         node);
115
    }
91
  return m_flowMonitor;
116
  return m_flowMonitor;
92
}
117
}
93
118
 Lines 98-104    Link Here 
98
  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
123
  for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)
99
    {
124
    {
100
      Ptr<Node> node = *i;
125
      Ptr<Node> node = *i;
101
      if (node->GetObject<Ipv4L3Protocol> ())
126
      if (node->GetObject<Ipv4L3Protocol> () || node->GetObject<Ipv6L3Protocol> ())
102
        {
127
        {
103
          Install (node);
128
          Install (node);
104
        }
129
        }
 Lines 112-118    Link Here 
112
  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
137
  for (NodeList::Iterator i = NodeList::Begin (); i != NodeList::End (); ++i)
113
    {
138
    {
114
      Ptr<Node> node = *i;
139
      Ptr<Node> node = *i;
115
      if (node->GetObject<Ipv4L3Protocol> ())
140
      if (node->GetObject<Ipv4L3Protocol> () || node->GetObject<Ipv6L3Protocol> ())
116
        {
141
        {
117
          Install (node);
142
          Install (node);
118
        }
143
        }
(-)a/src/flow-monitor/helper/flow-monitor-helper.h (-5 / +13 lines)
 Lines 30-39    Link Here 
30
30
31
class AttributeValue;
31
class AttributeValue;
32
class Ipv4FlowClassifier;
32
class Ipv4FlowClassifier;
33
class Ipv6FlowClassifier;
33
34
34
/**
35
/**
35
 * \ingroup flow-monitor
36
 * \ingroup flow-monitor
36
 * \brief Helper to enable IPv4 flow monitoring on a set of Nodes
37
 * \brief Helper to enable IP flow monitoring on a set of Nodes
37
 */
38
 */
38
class FlowMonitorHelper
39
class FlowMonitorHelper
39
{
40
{
 Lines 74-84    Link Here 
74
  Ptr<FlowMonitor> GetMonitor ();
75
  Ptr<FlowMonitor> GetMonitor ();
75
76
76
  /**
77
  /**
77
   * \brief Retrieve the FlowClassifier object created by the Install* methods
78
   * \brief Retrieve the FlowClassifier object for IPv4 created by the Install* methods
78
   * \returns a pointer to the FlowClassifier object
79
   * \returns a pointer to the FlowClassifier object
79
   */
80
   */
80
  Ptr<FlowClassifier> GetClassifier ();
81
  Ptr<FlowClassifier> GetClassifier ();
81
82
83
  /**
84
   * \brief Retrieve the FlowClassifier object for IPv6 created by the Install* methods
85
   * \returns a pointer to the FlowClassifier object
86
   */
87
  Ptr<FlowClassifier> GetClassifier6 ();
88
82
private:
89
private:
83
  /**
90
  /**
84
   * \brief Copy constructor
91
   * \brief Copy constructor
 Lines 94-102    Link Here 
94
   */
101
   */
95
  FlowMonitorHelper& operator= (const FlowMonitorHelper&);
102
  FlowMonitorHelper& operator= (const FlowMonitorHelper&);
96
103
97
  ObjectFactory m_monitorFactory;       //!< Object factory
104
  ObjectFactory m_monitorFactory;        //!< Object factory
98
  Ptr<FlowMonitor> m_flowMonitor;       //!< the FlowMonitor object
105
  Ptr<FlowMonitor> m_flowMonitor;        //!< the FlowMonitor object
99
  Ptr<FlowClassifier> m_flowClassifier; //!< the FlowClassifier object
106
  Ptr<FlowClassifier> m_flowClassifier4; //!< the FlowClassifier object for IPv4
107
  Ptr<FlowClassifier> m_flowClassifier6; //!< the FlowClassifier object for IPv6
100
};
108
};
101
109
102
} // namespace ns3
110
} // namespace ns3
(-)a/src/flow-monitor/model/flow-monitor.cc (-4 / +14 lines)
 Lines 92-98    Link Here 
92
void
92
void
93
FlowMonitor::DoDispose (void)
93
FlowMonitor::DoDispose (void)
94
{
94
{
95
  m_classifier = 0;
95
  for (std::list<Ptr<FlowClassifier> >::iterator iter = m_classifiers.begin ();
96
      iter != m_classifiers.end ();
97
      iter ++)
98
    {
99
      *iter = 0;
100
    }
96
  for (uint32_t i = 0; i < m_flowProbes.size (); i++)
101
  for (uint32_t i = 0; i < m_flowProbes.size (); i++)
97
    {
102
    {
98
      m_flowProbes[i]->Dispose ();
103
      m_flowProbes[i]->Dispose ();
 Lines 391-399    Link Here 
391
}
396
}
392
397
393
void
398
void
394
FlowMonitor::SetFlowClassifier (Ptr<FlowClassifier> classifier)
399
FlowMonitor::AddFlowClassifier (Ptr<FlowClassifier> classifier)
395
{
400
{
396
  m_classifier = classifier;
401
  m_classifiers.push_back (classifier);
397
}
402
}
398
403
399
void
404
void
 Lines 458-464    Link Here 
458
  indent -= 2;
463
  indent -= 2;
459
  INDENT (indent); os << "</FlowStats>\n";
464
  INDENT (indent); os << "</FlowStats>\n";
460
465
461
  m_classifier->SerializeToXmlStream (os, indent);
466
  for (std::list<Ptr<FlowClassifier> >::iterator iter = m_classifiers.begin ();
467
      iter != m_classifiers.end ();
468
      iter ++)
469
    {
470
      (*iter)->SerializeToXmlStream (os, indent);
471
    }
462
472
463
  if (enableProbes)
473
  if (enableProbes)
464
    {
474
    {
(-)a/src/flow-monitor/model/flow-monitor.h (-3 / +3 lines)
 Lines 146-154    Link Here 
146
  TypeId GetInstanceTypeId () const;
146
  TypeId GetInstanceTypeId () const;
147
  FlowMonitor ();
147
  FlowMonitor ();
148
148
149
  /// Set the FlowClassifier to be used by the flow monitor.
149
  /// Add a FlowClassifier to be used by the flow monitor.
150
  /// \param classifier the FlowClassifier
150
  /// \param classifier the FlowClassifier
151
  void SetFlowClassifier (Ptr<FlowClassifier> classifier);
151
  void AddFlowClassifier (Ptr<FlowClassifier> classifier);
152
152
153
  /// Set the time, counting from the current time, from which to start monitoring flows.
153
  /// Set the time, counting from the current time, from which to start monitoring flows.
154
  /// \param time delta time to start
154
  /// \param time delta time to start
 Lines 266-272    Link Here 
266
  std::vector< Ptr<FlowProbe> > m_flowProbes; //!< all the FlowProbes
266
  std::vector< Ptr<FlowProbe> > m_flowProbes; //!< all the FlowProbes
267
267
268
  // note: this is needed only for serialization
268
  // note: this is needed only for serialization
269
  Ptr<FlowClassifier> m_classifier; //!< the FlowClassifier
269
  std::list<Ptr<FlowClassifier> > m_classifiers; //!< the FlowClassifiers
270
270
271
  EventId m_startEvent;     //!< Start event
271
  EventId m_startEvent;     //!< Start event
272
  EventId m_stopEvent;      //!< Stop event
272
  EventId m_stopEvent;      //!< Stop event
(-)a/src/flow-monitor/model/ipv6-flow-classifier.cc (+218 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2009 INESC Porto
4
//
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License version 2 as
7
// published by the Free Software Foundation;
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
//
18
// Author: Gustavo J. A. M. Carneiro  <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19
// Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
20
//
21
22
#include "ns3/packet.h"
23
24
#include "ipv6-flow-classifier.h"
25
#include "ns3/udp-header.h"
26
#include "ns3/tcp-header.h"
27
28
namespace ns3 {
29
30
/* see http://www.iana.org/assignments/protocol-numbers */
31
const uint8_t TCP_PROT_NUMBER = 6;  //!< TCP Protocol number
32
const uint8_t UDP_PROT_NUMBER = 17; //!< UDP Protocol number
33
34
35
36
bool operator < (const Ipv6FlowClassifier::FiveTuple &t1,
37
                 const Ipv6FlowClassifier::FiveTuple &t2)
38
{
39
  if (t1.sourceAddress < t2.sourceAddress)
40
    {
41
      return true;
42
    }
43
  if (t1.sourceAddress != t2.sourceAddress)
44
    {
45
      return false;
46
    }
47
48
  if (t1.destinationAddress < t2.destinationAddress)
49
    {
50
      return true;
51
    }
52
  if (t1.destinationAddress != t2.destinationAddress)
53
    {
54
      return false;
55
    }
56
57
  if (t1.protocol < t2.protocol)
58
    {
59
      return true;
60
    }
61
  if (t1.protocol != t2.protocol)
62
    {
63
      return false;
64
    }
65
66
  if (t1.sourcePort < t2.sourcePort)
67
    {
68
      return true;
69
    }
70
  if (t1.sourcePort != t2.sourcePort)
71
    {
72
      return false;
73
    }
74
75
  if (t1.destinationPort < t2.destinationPort)
76
    {
77
      return true;
78
    }
79
  if (t1.destinationPort != t2.destinationPort)
80
    {
81
      return false;
82
    }
83
84
  return false;
85
}
86
87
bool operator == (const Ipv6FlowClassifier::FiveTuple &t1,
88
                  const Ipv6FlowClassifier::FiveTuple &t2)
89
{
90
  return (t1.sourceAddress      == t2.sourceAddress &&
91
          t1.destinationAddress == t2.destinationAddress &&
92
          t1.protocol           == t2.protocol &&
93
          t1.sourcePort         == t2.sourcePort &&
94
          t1.destinationPort    == t2.destinationPort);
95
}
96
97
98
99
Ipv6FlowClassifier::Ipv6FlowClassifier ()
100
{
101
}
102
103
bool
104
Ipv6FlowClassifier::Classify (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload,
105
                              uint32_t *out_flowId, uint32_t *out_packetId)
106
{
107
  if (ipHeader.GetDestinationAddress ().IsMulticast ())
108
    {
109
      // we are not prepared to handle multicast yet
110
      return false;
111
    }
112
113
  FiveTuple tuple;
114
  tuple.sourceAddress = ipHeader.GetSourceAddress ();
115
  tuple.destinationAddress = ipHeader.GetDestinationAddress ();
116
  tuple.protocol = ipHeader.GetNextHeader ();
117
118
  if ((tuple.protocol != UDP_PROT_NUMBER) && (tuple.protocol != TCP_PROT_NUMBER))
119
    {
120
      return false;
121
    }
122
123
  if (ipPayload->GetSize () < 4)
124
    {
125
      // the packet doesn't carry enough bytes
126
      return false;
127
    }
128
129
  // we rely on the fact that for both TCP and UDP the ports are
130
  // carried in the first 4 octects.
131
  // This allows to read the ports even on fragmented packets
132
  // not carrying a full TCP or UDP header.
133
134
  uint8_t data[4];
135
  ipPayload->CopyData (data, 4);
136
137
  uint16_t srcPort = 0;
138
  srcPort |= data[0];
139
  srcPort <<= 8;
140
  srcPort |= data[1];
141
142
  uint16_t dstPort = 0;
143
  dstPort |= data[2];
144
  dstPort <<= 8;
145
  dstPort |= data[3];
146
147
  tuple.sourcePort = srcPort;
148
  tuple.destinationPort = dstPort;
149
150
  // try to insert the tuple, but check if it already exists
151
  std::pair<std::map<FiveTuple, FlowId>::iterator, bool> insert
152
    = m_flowMap.insert (std::pair<FiveTuple, FlowId> (tuple, 0));
153
154
  // if the insertion succeeded, we need to assign this tuple a new flow identifier
155
  if (insert.second)
156
    {
157
      FlowId newFlowId = GetNewFlowId ();
158
      insert.first->second = newFlowId;
159
      m_flowPktIdMap[newFlowId] = 0;
160
    }
161
  else
162
    {
163
      m_flowPktIdMap[insert.first->second] ++;
164
    }
165
166
  *out_flowId = insert.first->second;
167
  *out_packetId = m_flowPktIdMap[*out_flowId];
168
169
  return true;
170
}
171
172
173
Ipv6FlowClassifier::FiveTuple
174
Ipv6FlowClassifier::FindFlow (FlowId flowId) const
175
{
176
  for (std::map<FiveTuple, FlowId>::const_iterator
177
       iter = m_flowMap.begin (); iter != m_flowMap.end (); iter++)
178
    {
179
      if (iter->second == flowId)
180
        {
181
          return iter->first;
182
        }
183
    }
184
  NS_FATAL_ERROR ("Could not find the flow with ID " << flowId);
185
  FiveTuple retval = { Ipv6Address::GetZero (), Ipv6Address::GetZero (), 0, 0, 0 };
186
  return retval;
187
}
188
189
void
190
Ipv6FlowClassifier::SerializeToXmlStream (std::ostream &os, int indent) const
191
{
192
#define INDENT(level) for (int __xpto = 0; __xpto < level; __xpto++) os << ' ';
193
194
  INDENT (indent); os << "<Ipv6FlowClassifier>\n";
195
196
  indent += 2;
197
  for (std::map<FiveTuple, FlowId>::const_iterator
198
       iter = m_flowMap.begin (); iter != m_flowMap.end (); iter++)
199
    {
200
      INDENT (indent);
201
      os << "<Flow flowId=\"" << iter->second << "\""
202
         << " sourceAddress=\"" << iter->first.sourceAddress << "\""
203
         << " destinationAddress=\"" << iter->first.destinationAddress << "\""
204
         << " protocol=\"" << int(iter->first.protocol) << "\""
205
         << " sourcePort=\"" << iter->first.sourcePort << "\""
206
         << " destinationPort=\"" << iter->first.destinationPort << "\""
207
         << " />\n";
208
    }
209
210
  indent -= 2;
211
  INDENT (indent); os << "</Ipv6FlowClassifier>\n";
212
213
#undef INDENT
214
}
215
216
217
} // namespace ns3
218
(-)a/src/flow-monitor/model/ipv6-flow-classifier.h (+104 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2009 INESC Porto
4
//
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License version 2 as
7
// published by the Free Software Foundation;
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
//
18
// Author: Gustavo J. A. M. Carneiro  <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19
// Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
20
//
21
22
#ifndef IPV6_FLOW_CLASSIFIER_H
23
#define IPV6_FLOW_CLASSIFIER_H
24
25
#include <stdint.h>
26
#include <map>
27
28
#include "ns3/ipv6-header.h"
29
#include "ns3/flow-classifier.h"
30
31
namespace ns3 {
32
33
class Packet;
34
35
/// Classifies packets by looking at their IP and TCP/UDP headers.
36
/// From these packet headers, a tuple (source-ip, destination-ip,
37
/// protocol, source-port, destination-port) is created, and a unique
38
/// flow identifier is assigned for each different tuple combination
39
class Ipv6FlowClassifier : public FlowClassifier
40
{
41
public:
42
43
  /// Structure to classify a packet
44
  struct FiveTuple
45
  {
46
    Ipv6Address sourceAddress;      //!< Source address
47
    Ipv6Address destinationAddress; //!< Destination address
48
    uint8_t protocol;               //!< Protocol
49
    uint16_t sourcePort;            //!< Source port
50
    uint16_t destinationPort;       //!< Destination port
51
  };
52
53
  Ipv6FlowClassifier ();
54
55
  /// \brief try to classify the packet into flow-id and packet-id
56
  ///
57
  /// \warning: it must be called only once per packet, from SendOutgoingLogger.
58
  ///
59
  /// \return true if the packet was classified, false if not (i.e. it
60
  /// does not appear to be part of a flow).
61
  /// \param ipHeader packet's IP header
62
  /// \param ipPayload packet's IP payload
63
  /// \param out_flowId packet's FlowId
64
  /// \param out_packetId packet's identifier
65
  bool Classify (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload,
66
                 uint32_t *out_flowId, uint32_t *out_packetId);
67
68
  /// Searches for the FiveTuple corresponding to the given flowId
69
  /// \param flowId the FlowId to search for
70
  /// \returns the FiveTuple corresponding to flowId
71
  FiveTuple FindFlow (FlowId flowId) const;
72
73
  virtual void SerializeToXmlStream (std::ostream &os, int indent) const;
74
75
private:
76
77
  /// Map to Flows Identifiers to FlowIds
78
  std::map<FiveTuple, FlowId> m_flowMap;
79
  std::map<FlowId, FlowPacketId> m_flowPktIdMap;
80
81
};
82
83
/**
84
 * \brief Less than operator.
85
 *
86
 * \param t1 the first operand
87
 * \param t2 the first operand
88
 * \returns true if the operands are equal
89
 */
90
bool operator < (const Ipv6FlowClassifier::FiveTuple &t1, const Ipv6FlowClassifier::FiveTuple &t2);
91
92
/**
93
 * \brief Equal to operator.
94
 *
95
 * \param t1 the first operand
96
 * \param t2 the first operand
97
 * \returns true if the operands are equal
98
 */
99
bool operator == (const Ipv6FlowClassifier::FiveTuple &t1, const Ipv6FlowClassifier::FiveTuple &t2);
100
101
102
} // namespace ns3
103
104
#endif /* IPV6_FLOW_CLASSIFIER_H */
(-)a/src/flow-monitor/model/ipv6-flow-probe.cc (+409 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2009 INESC Porto
4
//
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License version 2 as
7
// published by the Free Software Foundation;
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
//
18
// Author: Gustavo J. A. M. Carneiro  <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19
// Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
20
//
21
22
#include "ns3/ipv6-flow-probe.h"
23
#include "ns3/ipv6-flow-classifier.h"
24
#include "ns3/node.h"
25
#include "ns3/packet.h"
26
#include "ns3/flow-monitor.h"
27
#include "ns3/log.h"
28
#include "ns3/pointer.h"
29
#include "ns3/config.h"
30
#include "ns3/flow-id-tag.h"
31
32
namespace ns3 {
33
34
NS_LOG_COMPONENT_DEFINE ("Ipv6FlowProbe")
35
  ;
36
37
//////////////////////////////////////
38
// Ipv6FlowProbeTag class implementation //
39
//////////////////////////////////////
40
41
/**
42
 * \ingroup flow-monitor
43
 *
44
 * \brief Tag used to allow a fast identification of the packet
45
 *
46
 * This tag is added by FlowMonitor when a packet is seen for
47
 * the first time, and it is then used to classify the packet in
48
 * the following hops.
49
 */
50
class Ipv6FlowProbeTag : public Tag
51
{
52
public:
53
  /**
54
   * \brief Get the type ID.
55
   * \return the object TypeId
56
   */
57
  static TypeId GetTypeId (void);
58
  virtual TypeId GetInstanceTypeId (void) const;
59
  virtual uint32_t GetSerializedSize (void) const;
60
  virtual void Serialize (TagBuffer buf) const;
61
  virtual void Deserialize (TagBuffer buf);
62
  virtual void Print (std::ostream &os) const;
63
  Ipv6FlowProbeTag ();
64
  /**
65
   * \brief Consructor
66
   * \param flowId the flow identifier
67
   * \param packetId the packet identifier
68
   * \param packetSize the packet size
69
   */
70
  Ipv6FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize);
71
  /**
72
   * \brief Set the flow identifier
73
   * \param flowId the flow identifier
74
   */
75
  void SetFlowId (uint32_t flowId);
76
  /**
77
   * \brief Set the packet identifier
78
   * \param packetId the packet identifier
79
   */
80
  void SetPacketId (uint32_t packetId);
81
  /**
82
   * \brief Set the packet size
83
   * \param packetSize the packet size
84
   */
85
  void SetPacketSize (uint32_t packetSize);
86
  /**
87
   * \brief Set the flow identifier
88
   * \returns the flow identifier
89
   */
90
  uint32_t GetFlowId (void) const;
91
  /**
92
   * \brief Set the packet identifier
93
   * \returns the packet identifier
94
   */
95
  uint32_t GetPacketId (void) const;
96
  /**
97
   * \brief Get the packet size
98
   * \returns the packet size
99
   */
100
  uint32_t GetPacketSize (void) const;
101
private:
102
  uint32_t m_flowId;      //!< flow identifier
103
  uint32_t m_packetId;    //!< packet identifier
104
  uint32_t m_packetSize;  //!< packet size
105
106
};
107
108
TypeId 
109
Ipv6FlowProbeTag::GetTypeId (void)
110
{
111
  static TypeId tid = TypeId ("ns3::Ipv6FlowProbeTag")
112
    .SetParent<Tag> ()
113
    .AddConstructor<Ipv6FlowProbeTag> ()
114
  ;
115
  return tid;
116
}
117
TypeId 
118
Ipv6FlowProbeTag::GetInstanceTypeId (void) const
119
{
120
  return GetTypeId ();
121
}
122
uint32_t 
123
Ipv6FlowProbeTag::GetSerializedSize (void) const
124
{
125
  return 4 + 4 + 4;
126
}
127
void 
128
Ipv6FlowProbeTag::Serialize (TagBuffer buf) const
129
{
130
  buf.WriteU32 (m_flowId);
131
  buf.WriteU32 (m_packetId);
132
  buf.WriteU32 (m_packetSize);
133
}
134
void 
135
Ipv6FlowProbeTag::Deserialize (TagBuffer buf)
136
{
137
  m_flowId = buf.ReadU32 ();
138
  m_packetId = buf.ReadU32 ();
139
  m_packetSize = buf.ReadU32 ();
140
}
141
void 
142
Ipv6FlowProbeTag::Print (std::ostream &os) const
143
{
144
  os << "FlowId=" << m_flowId;
145
  os << "PacketId=" << m_packetId;
146
  os << "PacketSize=" << m_packetSize;
147
}
148
Ipv6FlowProbeTag::Ipv6FlowProbeTag ()
149
  : Tag () 
150
{
151
}
152
153
Ipv6FlowProbeTag::Ipv6FlowProbeTag (uint32_t flowId, uint32_t packetId, uint32_t packetSize)
154
  : Tag (), m_flowId (flowId), m_packetId (packetId), m_packetSize (packetSize)
155
{
156
}
157
158
void
159
Ipv6FlowProbeTag::SetFlowId (uint32_t id)
160
{
161
  m_flowId = id;
162
}
163
void
164
Ipv6FlowProbeTag::SetPacketId (uint32_t id)
165
{
166
  m_packetId = id;
167
}
168
void
169
Ipv6FlowProbeTag::SetPacketSize (uint32_t size)
170
{
171
  m_packetSize = size;
172
}
173
uint32_t
174
Ipv6FlowProbeTag::GetFlowId (void) const
175
{
176
  return m_flowId;
177
}
178
uint32_t
179
Ipv6FlowProbeTag::GetPacketId (void) const
180
{
181
  return m_packetId;
182
} 
183
uint32_t
184
Ipv6FlowProbeTag::GetPacketSize (void) const
185
{
186
  return m_packetSize;
187
} 
188
189
////////////////////////////////////////
190
// Ipv6FlowProbe class implementation //
191
////////////////////////////////////////
192
193
Ipv6FlowProbe::Ipv6FlowProbe (Ptr<FlowMonitor> monitor,
194
                              Ptr<Ipv6FlowClassifier> classifier,
195
                              Ptr<Node> node)
196
  : FlowProbe (monitor),
197
    m_classifier (classifier)
198
{
199
  NS_LOG_FUNCTION (this << node->GetId ());
200
201
  Ptr<Ipv6L3Protocol> ipv6 = node->GetObject<Ipv6L3Protocol> ();
202
203
  if (!ipv6->TraceConnectWithoutContext ("SendOutgoing",
204
                                         MakeCallback (&Ipv6FlowProbe::SendOutgoingLogger, Ptr<Ipv6FlowProbe> (this))))
205
    {
206
      NS_FATAL_ERROR ("trace fail");
207
    }
208
  if (!ipv6->TraceConnectWithoutContext ("UnicastForward",
209
                                         MakeCallback (&Ipv6FlowProbe::ForwardLogger, Ptr<Ipv6FlowProbe> (this))))
210
    {
211
      NS_FATAL_ERROR ("trace fail");
212
    }
213
  if (!ipv6->TraceConnectWithoutContext ("LocalDeliver",
214
                                         MakeCallback (&Ipv6FlowProbe::ForwardUpLogger, Ptr<Ipv6FlowProbe> (this))))
215
    {
216
      NS_FATAL_ERROR ("trace fail");
217
    }
218
219
  if (!ipv6->TraceConnectWithoutContext ("Drop",
220
                                         MakeCallback (&Ipv6FlowProbe::DropLogger, Ptr<Ipv6FlowProbe> (this))))
221
    {
222
      NS_FATAL_ERROR ("trace fail");
223
    }
224
225
  // code copied from point-to-point-helper.cc
226
  std::ostringstream oss;
227
  oss << "/NodeList/" << node->GetId () << "/DeviceList/*/TxQueue/Drop";
228
  Config::ConnectWithoutContext (oss.str (), MakeCallback (&Ipv6FlowProbe::QueueDropLogger, Ptr<Ipv6FlowProbe> (this)));
229
}
230
231
Ipv6FlowProbe::~Ipv6FlowProbe ()
232
{
233
}
234
235
void
236
Ipv6FlowProbe::DoDispose ()
237
{
238
  FlowProbe::DoDispose ();
239
}
240
241
void
242
Ipv6FlowProbe::SendOutgoingLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
243
{
244
  FlowId flowId;
245
  FlowPacketId packetId;
246
247
  if (m_classifier->Classify (ipHeader, ipPayload, &flowId, &packetId))
248
    {
249
      uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
250
      NS_LOG_DEBUG ("ReportFirstTx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<"); "
251
                                     << ipHeader << *ipPayload);
252
      m_flowMonitor->ReportFirstTx (this, flowId, packetId, size);
253
254
      // tag the packet with the flow id and packet id, so that the packet can be identified even
255
      // when Ipv6Header is not accessible at some non-IPv6 protocol layer
256
      Ipv6FlowProbeTag fTag (flowId, packetId, size);
257
      ipPayload->AddPacketTag (fTag);
258
    }
259
}
260
261
void
262
Ipv6FlowProbe::ForwardLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
263
{
264
  // peek the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
265
  Ipv6FlowProbeTag fTag;
266
267
  bool found = ipPayload->PeekPacketTag (fTag);
268
269
  if (found)
270
    {
271
      FlowId flowId = fTag.GetFlowId ();
272
      FlowPacketId packetId = fTag.GetPacketId ();
273
274
      uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
275
      NS_LOG_DEBUG ("ReportForwarding ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
276
      m_flowMonitor->ReportForwarding (this, flowId, packetId, size);
277
    }
278
}
279
280
void
281
Ipv6FlowProbe::ForwardUpLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface)
282
{
283
  // remove the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
284
  Ipv6FlowProbeTag fTag;
285
286
  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
287
  bool found = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
288
289
  if (found)
290
    {
291
      FlowId flowId = fTag.GetFlowId ();
292
      FlowPacketId packetId = fTag.GetPacketId ();
293
294
      uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
295
      NS_LOG_DEBUG ("ReportLastRx ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<");");
296
      m_flowMonitor->ReportLastRx (this, flowId, packetId, size);
297
    }
298
}
299
300
void
301
Ipv6FlowProbe::DropLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload,
302
                           Ipv6L3Protocol::DropReason reason, Ptr<Ipv6> ipv6, uint32_t ifIndex)
303
{
304
#if 0
305
  switch (reason)
306
    {
307
    case Ipv6L3Protocol::DROP_NO_ROUTE:
308
      break;
309
310
    case Ipv6L3Protocol::DROP_TTL_EXPIRED:
311
    case Ipv6L3Protocol::DROP_BAD_CHECKSUM:
312
      Ipv6Address addri = m_ipv6->GetAddress (ifIndex);
313
      Ipv6Mask maski = m_ipv6->GetNetworkMask (ifIndex);
314
      Ipv6Address bcast = addri.GetSubnetDirectedBroadcast (maski);
315
      if (ipHeader.GetDestination () == bcast) // we don't want broadcast packets
316
        {
317
          return;
318
        }
319
    }
320
#endif
321
322
  // remove the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
323
  Ipv6FlowProbeTag fTag;
324
325
  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
326
  bool found = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
327
328
  if (found)
329
    {
330
      FlowId flowId = fTag.GetFlowId ();
331
      FlowPacketId packetId = fTag.GetPacketId ();
332
333
      uint32_t size = (ipPayload->GetSize () + ipHeader.GetSerializedSize ());
334
      NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << reason 
335
                            << ", destIp=" << ipHeader.GetDestinationAddress () << "); "
336
                            << "HDR: " << ipHeader << " PKT: " << *ipPayload);
337
338
      DropReason myReason;
339
340
341
      switch (reason)
342
        {
343
        case Ipv6L3Protocol::DROP_TTL_EXPIRED:
344
          myReason = DROP_TTL_EXPIRE;
345
          NS_LOG_DEBUG ("DROP_TTL_EXPIRE");
346
          break;
347
        case Ipv6L3Protocol::DROP_NO_ROUTE:
348
          myReason = DROP_NO_ROUTE;
349
          NS_LOG_DEBUG ("DROP_NO_ROUTE");
350
          break;
351
        case Ipv6L3Protocol::DROP_INTERFACE_DOWN:
352
          myReason = DROP_INTERFACE_DOWN;
353
          NS_LOG_DEBUG ("DROP_INTERFACE_DOWN");
354
          break;
355
        case Ipv6L3Protocol::DROP_ROUTE_ERROR:
356
           myReason = DROP_ROUTE_ERROR;
357
           NS_LOG_DEBUG ("DROP_ROUTE_ERROR");
358
           break;
359
        case Ipv6L3Protocol::DROP_UNKNOWN_PROTOCOL:
360
           myReason = DROP_UNKNOWN_PROTOCOL;
361
           NS_LOG_DEBUG ("DROP_UNKNOWN_PROTOCOL");
362
           break;
363
        case Ipv6L3Protocol::DROP_UNKNOWN_OPTION:
364
           myReason = DROP_UNKNOWN_OPTION;
365
           NS_LOG_DEBUG ("DROP_UNKNOWN_OPTION");
366
           break;
367
        case Ipv6L3Protocol::DROP_MALFORMED_HEADER:
368
           myReason = DROP_MALFORMED_HEADER;
369
           NS_LOG_DEBUG ("DROP_MALFORMED_HEADER");
370
           break;
371
        case Ipv6L3Protocol::DROP_FRAGMENT_TIMEOUT:
372
          myReason = DROP_FRAGMENT_TIMEOUT;
373
          NS_LOG_DEBUG ("DROP_FRAGMENT_TIMEOUT");
374
          break;
375
        default:
376
          myReason = DROP_INVALID_REASON;
377
          NS_FATAL_ERROR ("Unexpected drop reason code " << reason);
378
        }
379
380
      m_flowMonitor->ReportDrop (this, flowId, packetId, size, myReason);
381
    }
382
}
383
384
void 
385
Ipv6FlowProbe::QueueDropLogger (Ptr<const Packet> ipPayload)
386
{
387
  // remove the tags that are added by Ipv6FlowProbe::SendOutgoingLogger ()
388
  Ipv6FlowProbeTag fTag;
389
390
  // ConstCast: see http://www.nsnam.org/bugzilla/show_bug.cgi?id=904
391
  bool tagFound = ConstCast<Packet> (ipPayload)->RemovePacketTag (fTag);
392
  if (!tagFound)
393
    {
394
      return;
395
    }
396
397
  FlowId flowId = fTag.GetFlowId ();
398
  FlowPacketId packetId = fTag.GetPacketId ();
399
  uint32_t size = fTag.GetPacketSize ();
400
401
  NS_LOG_DEBUG ("Drop ("<<this<<", "<<flowId<<", "<<packetId<<", "<<size<<", " << DROP_QUEUE 
402
                        << "); ");
403
404
  m_flowMonitor->ReportDrop (this, flowId, packetId, size, DROP_QUEUE);
405
}
406
407
} // namespace ns3
408
409
(-)a/src/flow-monitor/model/ipv6-flow-probe.h (+120 lines)
Line 0    Link Here 
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
//
3
// Copyright (c) 2009 INESC Porto
4
//
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License version 2 as
7
// published by the Free Software Foundation;
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
//
18
// Author: Gustavo J. A. M. Carneiro  <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19
// Modifications: Tommaso Pecorella <tommaso.pecorella@unifi.it>
20
//
21
22
#ifndef IPV6_FLOW_PROBE_H
23
#define IPV6_FLOW_PROBE_H
24
25
#include "ns3/flow-probe.h"
26
#include "ns3/ipv6-flow-classifier.h"
27
#include "ns3/ipv6-l3-protocol.h"
28
29
namespace ns3 {
30
31
class FlowMonitor;
32
class Node;
33
34
/// \ingroup flow-monitor
35
/// \brief Class that monitors flows at the IPv6 layer of a Node
36
///
37
/// For each node in the simulation, one instance of the class
38
/// Ipv4FlowProbe is created to monitor that node.  Ipv4FlowProbe
39
/// accomplishes this by connecting callbacks to trace sources in the
40
/// Ipv6L3Protocol interface of the node.
41
class Ipv6FlowProbe : public FlowProbe
42
{
43
44
public:
45
  /// \brief Constructor
46
  /// \param monitor the FlowMonitor this probe is associated with
47
  /// \param classifier the Ipv4FlowClassifier this probe is associated with
48
  /// \param node the Node this probe is associated with
49
  Ipv6FlowProbe (Ptr<FlowMonitor> monitor, Ptr<Ipv6FlowClassifier> classifier, Ptr<Node> node);
50
  virtual ~Ipv6FlowProbe ();
51
52
  /// \brief enumeration of possible reasons why a packet may be dropped
53
  enum DropReason 
54
  {
55
    /// Packet dropped due to missing route to the destination
56
    DROP_NO_ROUTE = 0,
57
58
    /// Packet dropped due to TTL decremented to zero during IPv4 forwarding
59
    DROP_TTL_EXPIRE,
60
61
    /// Packet dropped due to invalid checksum in the IPv4 header
62
    DROP_BAD_CHECKSUM,
63
64
    /// Packet dropped due to queue overflow.  Note: only works for
65
    /// NetDevices that provide a TxQueue attribute of type Queue
66
    /// with a Drop trace source.  It currently works with Csma and
67
    /// PointToPoint devices, but not with WiFi or WiMax.
68
    DROP_QUEUE,
69
70
    DROP_INTERFACE_DOWN,   /**< Interface is down so can not send packet */
71
    DROP_ROUTE_ERROR,   /**< Route error */
72
73
    DROP_UNKNOWN_PROTOCOL, /**< Unknown L4 protocol */
74
    DROP_UNKNOWN_OPTION, /**< Unknown option */
75
    DROP_MALFORMED_HEADER, /**< Malformed header */
76
77
    DROP_FRAGMENT_TIMEOUT, /**< Fragment timeout exceeded */
78
79
    DROP_INVALID_REASON, /**< Fallback reason (no known reason) */
80
  };
81
82
protected:
83
84
  virtual void DoDispose (void);
85
86
private:
87
  /// Log a packet being sent
88
  /// \param ipHeader IP header
89
  /// \param ipPayload IP payload
90
  /// \param interface outgoing interface
91
  void SendOutgoingLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface);
92
  /// Log a packet being forwarded
93
  /// \param ipHeader IP header
94
  /// \param ipPayload IP payload
95
  /// \param interface incoming interface
96
  void ForwardLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface);
97
  /// Log a packet being received by the destination
98
  /// \param ipHeader IP header
99
  /// \param ipPayload IP payload
100
  /// \param interface incoming interface
101
  void ForwardUpLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload, uint32_t interface);
102
  /// Log a packet being dropped
103
  /// \param ipHeader IP header
104
  /// \param ipPayload IP payload
105
  /// \param reason drop reason
106
  /// \param ipv6 pointer to the IP object dropping the packet
107
  /// \param ifIndex interface index
108
  void DropLogger (const Ipv6Header &ipHeader, Ptr<const Packet> ipPayload,
109
                   Ipv6L3Protocol::DropReason reason, Ptr<Ipv6> ipv6, uint32_t ifIndex);
110
  /// Log a packet being dropped by a queue
111
  /// \param ipPayload IP payload
112
  void QueueDropLogger (Ptr<const Packet> ipPayload);
113
114
  Ptr<Ipv6FlowClassifier> m_classifier; //!< the Ipv6FlowClassifier this probe is associated with
115
};
116
117
118
} // namespace ns3
119
120
#endif /* IPV6_FLOW_PROBE_H */
(-)a/src/flow-monitor/wscript (+4 lines)
 Lines 8-13    Link Here 
8
       'flow-probe.cc',
8
       'flow-probe.cc',
9
       'ipv4-flow-classifier.cc',
9
       'ipv4-flow-classifier.cc',
10
       'ipv4-flow-probe.cc',
10
       'ipv4-flow-probe.cc',
11
       'ipv6-flow-classifier.cc',
12
       'ipv6-flow-probe.cc',
11
       'histogram.cc',	
13
       'histogram.cc',	
12
        ]]
14
        ]]
13
    obj.source.append("helper/flow-monitor-helper.cc")
15
    obj.source.append("helper/flow-monitor-helper.cc")
 Lines 25-30    Link Here 
25
       'flow-classifier.h',
27
       'flow-classifier.h',
26
       'ipv4-flow-classifier.h',
28
       'ipv4-flow-classifier.h',
27
       'ipv4-flow-probe.h',
29
       'ipv4-flow-probe.h',
30
       'ipv6-flow-classifier.h',
31
       'ipv6-flow-probe.h',
28
       'histogram.h',
32
       'histogram.h',
29
        ]]
33
        ]]
30
    headers.source.append("helper/flow-monitor-helper.h")
34
    headers.source.append("helper/flow-monitor-helper.h")
(-)a/src/internet/model/ipv6-l3-protocol.cc (-1 / +18 lines)
 Lines 85-90    Link Here 
85
                     MakeTraceSourceAccessor (&Ipv6L3Protocol::m_rxTrace))
85
                     MakeTraceSourceAccessor (&Ipv6L3Protocol::m_rxTrace))
86
    .AddTraceSource ("Drop", "Drop IPv6 packet",
86
    .AddTraceSource ("Drop", "Drop IPv6 packet",
87
                     MakeTraceSourceAccessor (&Ipv6L3Protocol::m_dropTrace))
87
                     MakeTraceSourceAccessor (&Ipv6L3Protocol::m_dropTrace))
88
89
    .AddTraceSource ("SendOutgoing", "A newly-generated packet by this node is about to be queued for transmission",
90
                     MakeTraceSourceAccessor (&Ipv6L3Protocol::m_sendOutgoingTrace))
91
    .AddTraceSource ("UnicastForward", "A unicast IPv6 packet was received by this node and is being forwarded to another node",
92
                     MakeTraceSourceAccessor (&Ipv6L3Protocol::m_unicastForwardTrace))
93
    .AddTraceSource ("LocalDeliver", "An IPv6 packet was received by/for this node, and it is being forward up the stack",
94
                     MakeTraceSourceAccessor (&Ipv6L3Protocol::m_localDeliverTrace))
88
  ;
95
  ;
89
  return tid;
96
  return tid;
90
}
97
}
 Lines 747-752    Link Here 
747
    {
754
    {
748
      NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
755
      NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: passed in with a route");
749
      hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
756
      hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
757
      int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
758
      m_sendOutgoingTrace (hdr, packet, interface);
750
      SendRealOut (route, packet, hdr);
759
      SendRealOut (route, packet, hdr);
751
      return;
760
      return;
752
    }
761
    }
 Lines 757-762    Link Here 
757
      NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: probably sent to machine on same IPv6 network");
766
      NS_LOG_LOGIC ("Ipv6L3Protocol::Send case 1: probably sent to machine on same IPv6 network");
758
      /* NS_FATAL_ERROR ("This case is not yet implemented"); */
767
      /* NS_FATAL_ERROR ("This case is not yet implemented"); */
759
      hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
768
      hdr = BuildHeader (source, destination, protocol, packet->GetSize (), ttl, tclass);
769
      int32_t interface = GetInterfaceForDevice (route->GetOutputDevice ());
770
      m_sendOutgoingTrace (hdr, packet, interface);
760
      SendRealOut (route, packet, hdr);
771
      SendRealOut (route, packet, hdr);
761
      return;
772
      return;
762
    }
773
    }
 Lines 786-791    Link Here 
786
797
787
  if (newRoute)
798
  if (newRoute)
788
    {
799
    {
800
      int32_t interface = GetInterfaceForDevice (newRoute->GetOutputDevice ());
801
      m_sendOutgoingTrace (hdr, packet, interface);
789
      SendRealOut (newRoute, packet, hdr);
802
      SendRealOut (newRoute, packet, hdr);
790
    }
803
    }
791
  else
804
  else
 Lines 1076-1082    Link Here 
1076
          icmpv6->SendRedirection (copy, linkLocal, src, target, dst, Address ());
1089
          icmpv6->SendRedirection (copy, linkLocal, src, target, dst, Address ());
1077
        }
1090
        }
1078
    }
1091
    }
1079
1092
  int32_t interface = GetInterfaceForDevice (rtentry->GetOutputDevice ());
1093
  m_unicastForwardTrace (ipHeader, packet, interface);
1080
  SendRealOut (rtentry, packet, ipHeader);
1094
  SendRealOut (rtentry, packet, ipHeader);
1081
}
1095
}
1082
1096
 Lines 1187-1192    Link Here 
1187
1201
1188
              /* L4 protocol */
1202
              /* L4 protocol */
1189
              Ptr<Packet> copy = p->Copy ();
1203
              Ptr<Packet> copy = p->Copy ();
1204
1205
              m_localDeliverTrace (ip, p, iif);
1206
1190
              enum IpL4Protocol::RxStatus status = protocol->Receive (p, ip, GetInterface (iif));
1207
              enum IpL4Protocol::RxStatus status = protocol->Receive (p, ip, GetInterface (iif));
1191
1208
1192
              switch (status)
1209
              switch (status)
(-)a/src/internet/model/ipv6-l3-protocol.h (+7 lines)
 Lines 427-432    Link Here 
427
   */ 
427
   */ 
428
  TracedCallback<const Ipv6Header &, Ptr<const Packet>, DropReason, Ptr<Ipv6>, uint32_t> m_dropTrace;
428
  TracedCallback<const Ipv6Header &, Ptr<const Packet>, DropReason, Ptr<Ipv6>, uint32_t> m_dropTrace;
429
429
430
  /// Trace of sent packets
431
  TracedCallback<const Ipv6Header &, Ptr<const Packet>, uint32_t> m_sendOutgoingTrace;
432
  /// Trace of unicast forwarded packets
433
  TracedCallback<const Ipv6Header &, Ptr<const Packet>, uint32_t> m_unicastForwardTrace;
434
  /// Trace of locally delivered packets
435
  TracedCallback<const Ipv6Header &, Ptr<const Packet>, uint32_t> m_localDeliverTrace;
436
430
  /**
437
  /**
431
   * \brief Copy constructor.
438
   * \brief Copy constructor.
432
   *
439
   *

Return to bug 1818