A Discrete-Event Network Simulator
QKDNetSim v2.0 (NS-3 v3.41) @ (+)
API
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ipv4-list-routing.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 University of Washington
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  */
18 
19 #include "ipv4-list-routing.h"
20 
21 #include "ipv4-route.h"
22 #include "ipv4.h"
23 
24 #include "ns3/log.h"
25 #include "ns3/node.h"
26 
27 namespace ns3
28 {
29 
30 NS_LOG_COMPONENT_DEFINE("Ipv4ListRouting");
31 
32 NS_OBJECT_ENSURE_REGISTERED(Ipv4ListRouting);
33 
34 TypeId
36 {
37  static TypeId tid = TypeId("ns3::Ipv4ListRouting")
39  .SetGroupName("Internet")
40  .AddConstructor<Ipv4ListRouting>();
41  return tid;
42 }
43 
45  : m_ipv4(nullptr)
46 {
47  NS_LOG_FUNCTION(this);
48 }
49 
51 {
52  NS_LOG_FUNCTION(this);
53 }
54 
55 void
57 {
58  NS_LOG_FUNCTION(this);
59  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
60  rprotoIter++)
61  {
62  // Note: Calling dispose on these protocols causes memory leak
63  // The routing protocols should not maintain a pointer to
64  // this object, so Dispose() shouldn't be necessary.
65  (*rprotoIter).second = nullptr;
66  }
67  m_routingProtocols.clear();
68  m_ipv4 = nullptr;
69 }
70 
71 void
73 {
74  NS_LOG_FUNCTION(this << stream);
75  *stream->GetStream() << "Node: " << m_ipv4->GetObject<Node>()->GetId()
76  << ", Time: " << Now().As(unit)
77  << ", Local time: " << m_ipv4->GetObject<Node>()->GetLocalTime().As(unit)
78  << ", Ipv4ListRouting table" << std::endl;
79  for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
80  {
81  *stream->GetStream() << " Priority: " << (*i).first
82  << " Protocol: " << (*i).second->GetInstanceTypeId() << std::endl;
83  (*i).second->PrintRoutingTable(stream, unit);
84  }
85 }
86 
87 void
89 {
90  NS_LOG_FUNCTION(this);
91  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
92  rprotoIter++)
93  {
94  Ptr<Ipv4RoutingProtocol> protocol = (*rprotoIter).second;
95  protocol->Initialize();
96  }
98 }
99 
102  const Ipv4Header& header,
103  Ptr<NetDevice> oif,
104  Socket::SocketErrno& sockerr)
105 {
106  NS_LOG_FUNCTION(this << p << header.GetDestination() << header.GetSource() << oif << sockerr);
107  Ptr<Ipv4Route> route;
108 
109  for (auto i = m_routingProtocols.begin(); i != m_routingProtocols.end(); i++)
110  {
111  NS_LOG_LOGIC("Checking protocol " << (*i).second->GetInstanceTypeId() << " with priority "
112  << (*i).first);
113  NS_LOG_LOGIC("Requesting source address for destination " << header.GetDestination());
114  route = (*i).second->RouteOutput(p, header, oif, sockerr);
115  if (route)
116  {
117  NS_LOG_LOGIC("Found route " << route);
118  sockerr = Socket::ERROR_NOTERROR;
119  return route;
120  }
121  }
122  NS_LOG_LOGIC("Done checking " << GetTypeId());
123  NS_LOG_LOGIC("");
124  sockerr = Socket::ERROR_NOROUTETOHOST;
125  return nullptr;
126 }
127 
128 // Patterned after Linux ip_route_input and ip_route_input_slow
129 bool
131  const Ipv4Header& header,
133  const UnicastForwardCallback& ucb,
134  const MulticastForwardCallback& mcb,
135  const LocalDeliverCallback& lcb,
136  const ErrorCallback& ecb)
137 {
138  NS_LOG_FUNCTION(this << p << header << idev << &ucb << &mcb << &lcb << &ecb);
139  bool retVal = false;
140  NS_LOG_LOGIC("RouteInput logic for node: " << m_ipv4->GetObject<Node>()->GetId());
141 
142  NS_ASSERT(m_ipv4);
143  // Check if input device supports IP
144  NS_ASSERT(m_ipv4->GetInterfaceForDevice(idev) >= 0);
145  uint32_t iif = m_ipv4->GetInterfaceForDevice(idev);
146 
147  retVal = m_ipv4->IsDestinationAddress(header.GetDestination(), iif);
148  if (retVal)
149  {
150  NS_LOG_LOGIC("Address " << header.GetDestination() << " is a match for local delivery");
151  if (header.GetDestination().IsMulticast())
152  {
153  Ptr<Packet> packetCopy = p->Copy();
154  lcb(packetCopy, header, iif);
155  retVal = true;
156  // Fall through
157  }
158  else
159  {
160  lcb(p, header, iif);
161  return true;
162  }
163  }
164  // Check if input device supports IP forwarding
165  if (!m_ipv4->IsForwarding(iif))
166  {
167  NS_LOG_LOGIC("Forwarding disabled for this interface");
168  ecb(p, header, Socket::ERROR_NOROUTETOHOST);
169  return true;
170  }
171  // Next, try to find a route
172  // If we have already delivered a packet locally (e.g. multicast)
173  // we suppress further downstream local delivery by nulling the callback
174  LocalDeliverCallback downstreamLcb = lcb;
175  if (retVal)
176  {
177  downstreamLcb = MakeNullCallback<void, Ptr<const Packet>, const Ipv4Header&, uint32_t>();
178  }
179  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
180  rprotoIter++)
181  {
182  if ((*rprotoIter).second->RouteInput(p, header, idev, ucb, mcb, downstreamLcb, ecb))
183  {
184  NS_LOG_LOGIC("Route found to forward packet in protocol "
185  << (*rprotoIter).second->GetInstanceTypeId().GetName());
186  return true;
187  }
188  }
189  // No routing protocol has found a route.
190  return retVal;
191 }
192 
193 void
195 {
196  NS_LOG_FUNCTION(this << interface);
197  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
198  rprotoIter++)
199  {
200  (*rprotoIter).second->NotifyInterfaceUp(interface);
201  }
202 }
203 
204 void
206 {
207  NS_LOG_FUNCTION(this << interface);
208  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
209  rprotoIter++)
210  {
211  (*rprotoIter).second->NotifyInterfaceDown(interface);
212  }
213 }
214 
215 void
217 {
218  NS_LOG_FUNCTION(this << interface << address);
219  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
220  rprotoIter++)
221  {
222  (*rprotoIter).second->NotifyAddAddress(interface, address);
223  }
224 }
225 
226 void
228 {
229  NS_LOG_FUNCTION(this << interface << address);
230  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
231  rprotoIter++)
232  {
233  (*rprotoIter).second->NotifyRemoveAddress(interface, address);
234  }
235 }
236 
237 void
239 {
240  NS_LOG_FUNCTION(this << ipv4);
241  NS_ASSERT(!m_ipv4);
242  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
243  rprotoIter++)
244  {
245  (*rprotoIter).second->SetIpv4(ipv4);
246  }
247  m_ipv4 = ipv4;
248 }
249 
250 void
252 {
253  NS_LOG_FUNCTION(this << routingProtocol->GetInstanceTypeId() << priority);
254  m_routingProtocols.emplace_back(priority, routingProtocol);
256  if (m_ipv4)
257  {
258  routingProtocol->SetIpv4(m_ipv4);
259  }
260 }
261 
262 uint32_t
264 {
265  NS_LOG_FUNCTION(this);
266  return m_routingProtocols.size();
267 }
268 
270 Ipv4ListRouting::GetRoutingProtocol(uint32_t index, int16_t& priority) const
271 {
272  NS_LOG_FUNCTION(this << index << priority);
273  if (index >= m_routingProtocols.size())
274  {
275  NS_FATAL_ERROR("Ipv4ListRouting::GetRoutingProtocol(): index " << index
276  << " out of range");
277  }
278  uint32_t i = 0;
279  for (auto rprotoIter = m_routingProtocols.begin(); rprotoIter != m_routingProtocols.end();
280  rprotoIter++, i++)
281  {
282  if (i == index)
283  {
284  priority = (*rprotoIter).first;
285  return (*rprotoIter).second;
286  }
287  }
288  return nullptr;
289 }
290 
291 bool
293 {
294  NS_LOG_FUNCTION(a.first << a.second << b.first << b.second);
295  return a.first > b.first;
296 }
297 
298 } // namespace ns3
bool IsMulticast() const
Packet header for IPv4.
Definition: ipv4-header.h:34
Ipv4Address GetSource() const
Definition: ipv4-header.cc:302
Ipv4Address GetDestination() const
Definition: ipv4-header.cc:316
a class to store IPv4 address information on an interface
IPv4 list routing.
std::pair< int16_t, Ptr< Ipv4RoutingProtocol > > Ipv4RoutingProtocolEntry
Container identifying an IPv4 Routing Protocol entry in the list.
static TypeId GetTypeId()
Get the type ID of this class.
void DoDispose() override
Destructor implementation.
Ipv4RoutingProtocolList m_routingProtocols
List of routing protocols.
void NotifyRemoveAddress(uint32_t interface, Ipv4InterfaceAddress address) override
Ptr< Ipv4Route > RouteOutput(Ptr< Packet > p, const Ipv4Header &header, Ptr< NetDevice > oif, Socket::SocketErrno &sockerr) override
Query routing cache for an existing route, for an outbound packet.
void SetIpv4(Ptr< Ipv4 > ipv4) override
virtual uint32_t GetNRoutingProtocols() const
void PrintRoutingTable(Ptr< OutputStreamWrapper > stream, Time::Unit unit=Time::S) const override
Print the Routing Table entries.
bool RouteInput(Ptr< const Packet > p, const Ipv4Header &header, Ptr< const NetDevice > idev, const UnicastForwardCallback &ucb, const MulticastForwardCallback &mcb, const LocalDeliverCallback &lcb, const ErrorCallback &ecb) override
Route an input packet (to be forwarded or locally delivered)
virtual void AddRoutingProtocol(Ptr< Ipv4RoutingProtocol > routingProtocol, int16_t priority)
Register a new routing protocol to be used in this IPv4 stack.
Ptr< Ipv4 > m_ipv4
Ipv4 this protocol is associated with.
static bool Compare(const Ipv4RoutingProtocolEntry &a, const Ipv4RoutingProtocolEntry &b)
Compare two routing protocols.
void NotifyInterfaceDown(uint32_t interface) override
void DoInitialize() override
Initialize() implementation.
virtual Ptr< Ipv4RoutingProtocol > GetRoutingProtocol(uint32_t index, int16_t &priority) const
Return pointer to routing protocol stored at index, with the first protocol (index 0) the highest pri...
void NotifyAddAddress(uint32_t interface, Ipv4InterfaceAddress address) override
void NotifyInterfaceUp(uint32_t interface) override
Abstract base class for IPv4 routing protocols.
A network Node.
Definition: node.h:57
uint32_t GetId() const
Definition: node.cc:117
virtual void DoInitialize()
Initialize() implementation.
Definition: object.cc:359
std::ostream * GetStream()
Return a pointer to an ostream previously set in the wrapper.
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_NOROUTETOHOST
Definition: socket.h:95
@ ERROR_NOTERROR
Definition: socket.h:85
TimeWithUnit As(const Unit unit=Time::AUTO) const
Attach a unit to a Time, to facilitate output in a specific unit.
Definition: time.cc:415
Unit
The unit to use to interpret a number representing time.
Definition: nstime.h:111
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Now()
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:305
address
Definition: first.py:47
Every class exported by the ns3 library is enclosed in the ns3 namespace.