ns3-bgp  0.2
BGP module for ns-3.
bgp-routing.cc
Go to the documentation of this file.
1 
11 #include <arpa/inet.h>
12 #include "bgp-routing.h"
13 #include "ns3/log.h"
14 #include "ns3/node.h"
15 #include "ns3/simulator.h"
16 
17 namespace ns3 {
18 
19 NS_LOG_COMPONENT_DEFINE("BgpRouting");
20 NS_OBJECT_ENSURE_REGISTERED(BgpRouting);
21 
22 BgpRouting::BgpRouting() {
23  _ipv4 = nullptr;
24  _rib = nullptr;
25 }
26 
27 TypeId BgpRouting::GetTypeId (void) {
28  static TypeId tid = TypeId ("ns3::BgpRouting")
29  .SetParent<Ipv4RoutingProtocol>()
30  .SetGroupName ("Internet")
31  .AddConstructor<BgpRouting>();
32 
33  return tid;
34 }
35 
36 Ptr<Ipv4Route> BgpRouting::RouteOutput (Ptr<Packet> p, const Ipv4Header &header,
37  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr) {
38  NS_ASSERT(_ipv4 != nullptr);
39  Ipv4Address dst = header.GetDestination();
40 
41  if (dst.IsMulticast()) {
42  NS_LOG_INFO("multicast destination " << dst << " not supported by BgpRouting.");
43  return nullptr;
44  }
45 
46  NS_LOG_DEBUG("looking for destination " << dst << " in rib.");
47 
48  const libbgp::BgpRib4Entry *rslt = _rib->lookup(htonl(dst.Get()));
49 
50  if (rslt == nullptr) {
51  NS_LOG_INFO("no matching entry in rib for destination " << dst << ".");
52  return nullptr;
53  }
54 
55  uint32_t nexthop = ntohl(rslt->getNexthop());
56  Ipv4Address gateway (nexthop);
57 
58  // oif not bonded, we need to find it ourself.
59  Ptr<NetDevice> dev = (oif == nullptr) ? GetDeviceByNexthop(gateway) : oif;
60 
61  if (dev == nullptr) {
62  NS_LOG_WARN("no device found for nexthop " << gateway << ", and not bonded.");
63  return nullptr;
64  }
65 
66  Ptr<Ipv4Route> route = Create<Ipv4Route>();
67  route->SetDestination(dst);
68  route->SetGateway(gateway);
69  route->SetOutputDevice(dev);
70 
71  Ipv4Address source = header.GetSource();
72  if (source.IsAny() || source == Ipv4Address(0x66666666)) source = _ipv4->GetAddress(_ipv4->GetInterfaceForDevice(dev), 0).GetLocal();
73  route->SetSource(source);
74 
75  return route;
76 }
77 
78 bool BgpRouting::RouteInput (Ptr<const Packet> p, const Ipv4Header &header, Ptr<const NetDevice> idev,
79  UnicastForwardCallback ucb, MulticastForwardCallback mcb, LocalDeliverCallback lcb,
80  ErrorCallback ecb) {
81  NS_ASSERT(_ipv4 != nullptr);
82  NS_ASSERT(_ipv4->GetInterfaceForDevice (idev) >= 0);
83 
84  Ipv4Address dst = header.GetDestination();
85  uint32_t iface = _ipv4->GetInterfaceForDevice(idev);
86 
87  // we don't do multicast
88  if (dst.IsMulticast()) {
89  NS_LOG_LOGIC("ignoring multicast destination " << dst << " .");
90  return false;
91  }
92 
93  // to local?
94  if (_ipv4->IsDestinationAddress(dst, iface)) {
95  NS_LOG_LOGIC("destination " << dst << " is local.");
96  lcb(p, header, iface);
97  return true;
98  }
99 
100  const libbgp::BgpRib4Entry *rslt = _rib->lookup(htonl(dst.Get()));
101 
102  if (rslt == nullptr) {
103  NS_LOG_INFO("no matching entry in rib for destination " << dst << ".");
104  return false;
105  }
106 
107  uint32_t nexthop = ntohl(rslt->getNexthop());
108  Ipv4Address gateway (nexthop);
109  NS_LOG_LOGIC("nexthop of " << dst << " is at " << gateway << ".");
110 
111  Ptr<NetDevice> dev = GetDeviceByNexthop(gateway);
112 
113  if (dev == nullptr) {
114  NS_LOG_WARN("no device found for nexthop " << gateway << ".");
115  return false;
116  }
117 
118  Ptr<Ipv4Route> route = Create<Ipv4Route>();
119  route->SetDestination(dst);
120  route->SetGateway(gateway);
121  route->SetOutputDevice(dev);
122  route->SetSource(header.GetSource());
123 
124  ucb(route, p, header);
125  return true;
126 }
127 
136 Ptr<NetDevice> BgpRouting::GetDeviceByNexthop(const Ipv4Address &nexthop) const {
137  uint32_t n_ifaces = _ipv4->GetNInterfaces();
138 
139  for (uint32_t iface_id = 0; iface_id < n_ifaces; iface_id++) {
140  uint32_t n_addrs = _ipv4->GetNAddresses(iface_id);
141  for (uint32_t addr_id = 0; addr_id < n_addrs; addr_id++) {
142  Ipv4InterfaceAddress addr = _ipv4->GetAddress(iface_id, addr_id);
143  Ipv4Mask mask = addr.GetMask();
144  if (addr.GetLocal().CombineMask(mask) == nexthop.CombineMask(mask)) {
145  if (_ipv4->IsForwarding(iface_id) && _ipv4->IsUp(iface_id)) {
146  return _ipv4->GetNetDevice(iface_id);
147  } else NS_LOG_INFO("interface " << iface_id << " has matching address but not up or not in forwarding mode.");
148  }
149  }
150  }
151 
152  return nullptr;
153 }
154 
164 Ipv4InterfaceAddress BgpRouting::GetAddressByNexthop(const Ipv4Address &nexthop) const {
165  uint32_t n_ifaces = _ipv4->GetNInterfaces();
166 
167  for (uint32_t iface_id = 0; iface_id < n_ifaces; iface_id++) {
168  uint32_t n_addrs = _ipv4->GetNAddresses(iface_id);
169  for (uint32_t addr_id = 0; addr_id < n_addrs; addr_id++) {
170  Ipv4InterfaceAddress addr = _ipv4->GetAddress(iface_id, addr_id);
171  Ipv4Mask mask = addr.GetMask();
172  if (addr.GetLocal().CombineMask(mask) == nexthop.CombineMask(mask)) {
173  return addr;
174  }
175  }
176  }
177 
178  return Ipv4InterfaceAddress(Ipv4Address((uint32_t) 0), Ipv4Mask((uint32_t) 0));
179 }
180 
187  _rib = rib;
188 }
189 
190 /* things we don't care */
191 void BgpRouting::NotifyInterfaceUp (uint32_t interface) {}
192 void BgpRouting::NotifyInterfaceDown (uint32_t interface) {}
193 void BgpRouting::NotifyAddAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
194 void BgpRouting::NotifyRemoveAddress (uint32_t interface, Ipv4InterfaceAddress address) {}
195 
196 /* this one we do care */
197 void BgpRouting::SetIpv4 (Ptr<Ipv4> ipv4) {
198  _ipv4 = ipv4;
199 }
200 
201 void BgpRouting::PrintRoutingTable (Ptr<OutputStreamWrapper> stream, Time::Unit unit) const {
202  std::ostream* os = stream->GetStream();
203 
204  *os << "BGP routing table for node" << _ipv4->GetObject<Node>()->GetId()
205  << ", time: " << Simulator::Now().As(unit) << std::endl;
206 
207  uint8_t print_buffer[4096];
208 
209  for (const std::pair<libbgp::BgpRib4EntryKey, libbgp::BgpRib4Entry> &entry_pair : _rib->get()) {
210  const libbgp::BgpRib4Entry entry = entry_pair.second;
211  *os << Ipv4Address(ntohl(entry.route.getPrefix())) << "/" << (int) entry.route.getLength()
212  << " from " << Ipv4Address(ntohl(entry.src_router_id)) << std::endl
213  << "Attribues: " << std::endl;
214  for (const std::shared_ptr<libbgp::BgpPathAttrib> &attr : entry.attribs) {
215  attr->print(1, print_buffer, 4096);
216  *os << print_buffer;
217  }
218  }
219 }
220 
221 }
uint32_t getPrefix() const
std::vector< std::shared_ptr< BgpPathAttrib > > attribs
Ipv4InterfaceAddress GetAddressByNexthop(const Ipv4Address &nexthop) const
Look for the interface address that can reach a given nexthop.
Definition: bgp-routing.cc:164
ns3 BGP module: routing protocol (Ipv4RoutingProtocol)
uint8_t getLength() const
Definition: bgp-log.cc:15
void SetRib(const libbgp::BgpRib4 *rib)
Set the libbgp Routing Information Base to use.
Definition: bgp-routing.cc:186
const std::vector< BgpRib4Entry > & get() const
uint32_t getNexthop() const
Ptr< NetDevice > GetDeviceByNexthop(const Ipv4Address &nexthop) const
Look for device to output/forward packet by nexthop.
Definition: bgp-routing.cc:136
const BgpRib4Entry * lookup(uint32_t dest) const