OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bridge_route.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/uuid/uuid_io.hpp>
6 
7 #include <cmn/agent_cmn.h>
8 #include <route/route.h>
9 
10 #include <oper/route_common.h>
11 #include <oper/vrf.h>
12 #include <oper/tunnel_nh.h>
13 #include <oper/mpls.h>
14 #include <oper/mirror_table.h>
18 #include <oper/agent_sandesh.h>
19 
20 using namespace std;
21 using namespace boost::asio;
22 
24 // Utility functions
26 static void BridgeTableEnqueue(Agent *agent, DBRequest *req) {
27  AgentRouteTable *table = agent->fabric_l2_unicast_table();
28  if (table) {
29  table->Enqueue(req);
30  }
31 }
32 
33 static void BridgeTableProcess(Agent *agent, const string &vrf_name,
34  DBRequest &req) {
35  AgentRouteTable *table =
36  agent->vrf_table()->GetBridgeRouteTable(vrf_name);
37  if (table) {
38  table->Process(req);
39  }
40 }
41 
43 // BridgeRouteKey methods
45 string BridgeRouteKey::ToString() const {
46  return dmac_.ToString();
47 }
48 
50  return new BridgeRouteKey(peer(), vrf_name_, dmac_);
51 }
52 
53 AgentRoute *
54 BridgeRouteKey::AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const
55 {
56  BridgeRouteEntry *entry = new BridgeRouteEntry(vrf, dmac_,
57  peer()->GetType(),
58  is_multicast);
59  return static_cast<AgentRoute *>(entry);
60 }
61 
63 // BridgeAgentRouteTable methods
66  const std::string &name) {
67  AgentRouteTable *table = new BridgeAgentRouteTable(db, name);
68  table->Init();
69  return table;
70 }
71 
73  BridgeRouteEntry entry(vrf_entry(), mac, Peer::LOCAL_PEER, false);
74  return static_cast<BridgeRouteEntry *>(FindActiveEntry(&entry));
75 }
76 
78  BridgeRouteEntry entry(vrf_entry(), mac, Peer::LOCAL_PEER, false);
79  return static_cast<BridgeRouteEntry *>(FindActiveEntryNoLock(&entry));
80 }
81 
83  Peer::Type peer) {
84  BridgeRouteEntry entry(vrf_entry(), mac, peer, false);
85  return static_cast<BridgeRouteEntry *>(FindActiveEntry(&entry));
86 }
87 
89 // BridgeAgentRouteTable utility methods to add/delete routes
92  const string &vrf_name,
93  const MacAddress &mac,
94  const string &vn_name,
95  const string &interface,
96  bool policy) {
97  Agent *agent = Agent::GetInstance();
99  req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, 0));
100 
101  PacketInterfaceKey intf_key(boost::uuids::nil_uuid(),
102  agent->pkt_interface_name());
103  req.data.reset(new HostRoute(intf_key, vn_name));
104 
105  BridgeTableEnqueue(agent, &req);
106 }
107 
109  const string &vrf_name,
110  uint32_t vxlan_id,
111  const MacAddress &mac,
112  const string &vn_name) {
114  req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, vxlan_id));
115  req.data.reset(new L2ReceiveRoute(vn_name, vxlan_id, 0, PathPreference(),
116  peer->sequence_number()));
117  Process(req);
118 }
119 
121  const EvpnRouteEntry *evpn_rt =
122  static_cast<const EvpnRouteEntry *>(rt);
124  req.key.reset(new BridgeRouteKey(agent()->evpn_peer(),
125  evpn_rt->vrf()->GetName(),
126  evpn_rt->mac(), 0));
127  req.data.reset(new EvpnDerivedPathData(evpn_rt));
128  BridgeTableProcess(agent(), vrf_name(), req);
129 }
130 
131 
133  const std::string &vrf_name,
134  const MacAddress &mac,
135  const VmInterface *vm_intf,
136  bool flood_dhcp) {
138  req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, 0));
139  req.data.reset(new MacVmBindingPathData(vm_intf, flood_dhcp));
140  BridgeTableProcess(agent(), vrf_name, req);
141 }
142 
144  const std::string &vrf_name,
145  const MacAddress &mac,
146  const VmInterface *vm_intf) {
148  req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, 0));
149  req.data.reset(new MacVmBindingPathData(vm_intf, false));
150  BridgeTableProcess(agent(), vrf_name, req);
151 }
152 
154  const EvpnRouteEntry *evpn_rt =
155  static_cast<const EvpnRouteEntry *>(rt);
157  req.key.reset(new BridgeRouteKey(agent()->evpn_peer(),
158  evpn_rt->vrf()->GetName(),
159  evpn_rt->mac(), 0));
160  req.data.reset(new EvpnDerivedPathData(evpn_rt));
161  BridgeTableProcess(Agent::GetInstance(), evpn_rt->vrf()->GetName(), req);
162 }
163 
164 void BridgeAgentRouteTable::Delete(const Peer *peer, const string &vrf_name,
165  const MacAddress &mac,
166  uint32_t ethernet_tag) {
168  req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, ethernet_tag));
169  req.data.reset(NULL);
170  BridgeTableProcess(Agent::GetInstance(), vrf_name, req);
171 }
172 
174  const std::string &vn_name,
175  uint32_t label,
176  int vxlan_id,
177  uint32_t tunnel_type,
180  &component_nh_key_list,
181  bool pbb_nh,
182  bool learning_enabled) {
184  nh_req.key.reset(new CompositeNHKey(type, false, component_nh_key_list,
185  vrf_name));
186  nh_req.data.reset(new CompositeNHData(pbb_nh, learning_enabled, false));
187  return (new MulticastRoute(vn_name, label,
188  vxlan_id, tunnel_type,
189  nh_req, type, 0));
190 }
191 
193  const string &vrf_name,
194  const std::string &vn_name,
195  uint32_t label,
196  int vxlan_id,
197  uint32_t ethernet_tag,
198  uint32_t tunnel_type,
201  &component_nh_key_list,
202  bool pbb_nh,
203  bool learning_enabled) {
204  const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer *>(peer);
205  assert(bgp_peer != NULL);
207  nh_req.key.reset(new CompositeNHKey(type, false, component_nh_key_list,
208  vrf_name));
209  nh_req.data.reset(new CompositeNHData(pbb_nh, learning_enabled, false));
210  return (new MulticastRoute(vn_name, label, ethernet_tag, tunnel_type,
211  nh_req, type, bgp_peer->sequence_number()));
212 }
213 
215  const string &vrf_name,
216  const MacAddress &mac,
217  uint32_t ethernet_tag,
218  AgentRouteData *data) {
219 
221  req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, ethernet_tag));
222  req.data.reset(data);
224 }
225 
227  const string &vrf_name,
228  const MacAddress &mac,
229  uint32_t ethernet_tag,
231 
233  req.key.reset(new BridgeRouteKey(peer, vrf_name, mac, ethernet_tag));
234  DBRequest nh_req;
235 
236  //For same BGP peer type comp type helps in identifying if its a delete
237  //for TOR or EVPN path.
238  //Only ethernet tag is required, rest are dummy.
239  const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer *>(peer);
240  if (bgp_peer) {
241  req.data.reset(new MulticastRoute("", 0,
242  ethernet_tag, TunnelType::AllType(),
243  nh_req, type,
244  bgp_peer->sequence_number()));
245  } else {
246  req.data.reset(new MulticastRoute("", 0, ethernet_tag,
248  nh_req, type, 0));
249  }
250 
252 }
253 
255  const string &vrf_name,
256  uint32_t ethernet_tag,
257  AgentRouteData *data) {
258 
260  req.key.reset(new BridgeRouteKey(peer, vrf_name,
261  MacAddress::BroadcastMac(), ethernet_tag));
262  req.data.reset(data);
264 }
265 
267  const string &vrf_name,
268  uint32_t ethernet_tag,
271  req.key.reset(new BridgeRouteKey(peer, vrf_name,
272  MacAddress::BroadcastMac(), ethernet_tag));
273  DBRequest nh_req;
274  //For same BGP peer type comp type helps in identifying if its a delete
275  //for TOR or EVPN path.
276  //Only ethernet tag is required, rest are dummy.
277  const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer *>(peer);
278  if (bgp_peer) {
279  req.data.reset(new MulticastRoute("", 0,
280  ethernet_tag, TunnelType::AllType(),
281  nh_req, type,
282  bgp_peer->sequence_number()));
283  } else {
284  req.data.reset(new MulticastRoute("", 0, ethernet_tag,
286  nh_req, type, 0));
287  }
288 
290 }
291 
293 (const MacAddress &mac) {
294  const BridgeRouteEntry *l2_rt = FindRoute(mac);
295  if (l2_rt == NULL)
296  return NULL;
297 
298  const MacVmBindingPath *dhcp_path = l2_rt->FindMacVmBindingPath();
299  if (dhcp_path == NULL)
300  return NULL;
301  return dhcp_path->vm_interface();
302 }
303 
305 // BridgeRouteEntry methods
307 const std::string BridgeRouteEntry::GetAddressString() const {
308  //For broadcast, xmpp message is sent with address as 255.255.255.255
309  if (prefix_address_ == MacAddress::BroadcastMac()) {
310  return "255.255.255.255";
311  }
312  return ToString();
313 }
314 
315 const std::string BridgeRouteEntry::GetSourceAddressString() const {
316  if (prefix_address_ == MacAddress::BroadcastMac()) {
317  return "0.0.0.0";
318  }
319  return (MacAddress::kZeroMac).ToString();
320 }
321 
323  return prefix_address_.ToString();
324 }
325 
326 int BridgeRouteEntry::CompareTo(const Route &rhs) const {
327  const BridgeRouteEntry &a = static_cast<const BridgeRouteEntry &>(rhs);
328 
329  return prefix_address_.CompareTo(a.prefix_address_);
330 }
331 
333  BridgeRouteKey *key =
334  new BridgeRouteKey(Agent::GetInstance()->local_vm_peer(),
335  vrf()->GetName(), prefix_address_);
336  return DBEntryBase::KeyPtr(key);
337 }
338 
340  const BridgeRouteKey *k = static_cast<const BridgeRouteKey *>(key);
341  SetVrf(Agent::GetInstance()->vrf_table()->FindVrfFromName(k->vrf_name()));
342  prefix_address_ = k->GetMac();
343 }
344 
346  uint32_t label = 0;
347 
348  if (is_multicast()) {
350  (1 << TunnelType::VXLAN)) {
351  label = GetActivePath()->vxlan_id();
352  } else {
353  label = GetActivePath()->label();
354  }
355  } else {
356  label = GetActivePath()->GetActiveLabel();
357  }
358  return label;
359 }
360 
362 (const AgentRouteKey *key, const AgentRouteData *data) const {
363  const Peer *peer = key->peer();
364  if (is_multicast())
365  return FindMulticastPathUsingKeyData(key, data);
366  const EvpnPeer *evpn_peer = dynamic_cast<const EvpnPeer*>(peer);
367  if (evpn_peer != NULL)
368  return FindEvpnPathUsingKeyData(key, data);
369 
370  return FindPath(peer);
371 }
372 
374 (const AgentRouteKey *key, const AgentRouteData *data) const {
375  assert(is_multicast());
376 
377  Route::PathList::const_iterator it;
378  for (it = GetPathList().begin(); it != GetPathList().end();
379  it++) {
380  const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
381  if (path->peer() != key->peer())
382  continue;
383 
384  //Handle multicast peer matching,
385  //In case of BGP peer also match VXLAN id.
386  if (path->peer()->GetType() != Peer::BGP_PEER)
387  return const_cast<AgentPath *>(path);
388 
389  const MulticastRoute *multicast_data =
390  dynamic_cast<const MulticastRoute *>(data);
391  assert(multicast_data != NULL);
392  if (multicast_data->vxlan_id() != path->vxlan_id())
393  continue;
394 
395  //In multicast from same peer, TOR and EVPN comp can
396  //come. These should not overlap and be installed as
397  //different path.
398  const CompositeNH *cnh = dynamic_cast<CompositeNH *>(path->nexthop());
399  if ((cnh != NULL) &&
400  (multicast_data->comp_nh_type() != cnh->composite_nh_type()))
401  continue;
402 
403  return const_cast<AgentPath *>(path);
404  }
405  return NULL;
406 }
407 
409 (const AgentRouteKey *key, const AgentRouteData *data) const {
410  const Peer *peer = key->peer();
411  const EvpnPeer *evpn_peer = dynamic_cast<const EvpnPeer*>(peer);
412  assert(evpn_peer != NULL);
413 
414  Route::PathList::const_iterator it;
415  for (it = GetPathList().begin(); it != GetPathList().end(); it++) {
416  const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
417  if (path->peer() != key->peer())
418  continue;
419 
420  //Handle mac route added via evpn route.
421  const EvpnDerivedPath *evpn_path =
422  dynamic_cast<const EvpnDerivedPath *>(path);
423  const EvpnDerivedPathData *evpn_data =
424  dynamic_cast<const EvpnDerivedPathData *>(data);
425  assert(evpn_path != NULL);
426  assert(evpn_data != NULL);
427  if (evpn_path->ethernet_tag() != evpn_data->ethernet_tag())
428  continue;
429  if (evpn_path->ip_addr() != evpn_data->ip_addr())
430  continue;
431  return const_cast<AgentPath *>(path);
432  }
433  return NULL;
434 }
435 
437  Agent *agent = (static_cast<AgentRouteTable *> (get_table()))->agent();
438  return dynamic_cast<MacVmBindingPath*>(FindPath(agent->mac_vm_binding_peer()));
439 }
440 
442  if (is_multicast()) {
443  //evaluate add of path
444  return ReComputeMulticastPaths(path, false);
445  }
446  return false;
447 }
448 
450  if (is_multicast()) {
451  //evaluate delete of path
452  return ReComputeMulticastPaths(path, true);
453  }
454  return false;
455 }
456 
458 // Sandesh related methods
460 void BridgeRouteReq::HandleRequest() const {
461  VrfEntry *vrf =
462  Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
463  if (!vrf) {
464  ErrorResp *resp = new ErrorResp();
465  resp->set_context(context());
466  resp->Response();
467  return;
468  }
469 
470  AgentSandeshPtr sand(new AgentBridgeRtSandesh(vrf, context(), "",
471  get_stale(), get_mac()));
472  sand->DoSandesh(sand);
473 }
474 
476 (const AgentSandeshArguments *args, const std::string &context) {
477  return AgentSandeshPtr(new AgentBridgeRtSandesh(vrf_entry(), context, "",
478  false, args->GetString("mac")));
479 }
480 
481 bool BridgeRouteEntry::DBEntrySandesh(Sandesh *sresp, bool stale) const {
482  BridgeRouteResp *resp = static_cast<BridgeRouteResp *>(sresp);
483  RouteL2SandeshData data;
484  data.set_mac(ToString());
485  data.set_src_vrf(vrf()->GetName());
486 
487  for (Route::PathList::const_iterator it = GetPathList().begin();
488  it != GetPathList().end(); it++) {
489  const AgentPath *path = static_cast<const AgentPath *>(it.operator->());
490  if (path) {
491  PathSandeshData pdata;
492  path->SetSandeshData(pdata);
493  if (is_multicast()) {
494  pdata.set_vxlan_id(path->vxlan_id());
495  }
496  const EvpnDerivedPath *evpn_path = dynamic_cast<const EvpnDerivedPath *>(path);
497  if (evpn_path) {
498  pdata.set_info(evpn_path->parent());
499  }
500  data.path_list.push_back(pdata);
501  }
502  }
503  std::vector<RouteL2SandeshData> &list =
504  const_cast<std::vector<RouteL2SandeshData>&>(resp->get_route_list());
505  list.push_back(data);
506  return true;
507 }
508 
509 //Supporting deprecated layer2 requests
510 void Layer2RouteReq::HandleRequest() const {
511  VrfEntry *vrf =
512  Agent::GetInstance()->vrf_table()->FindVrfFromId(get_vrf_index());
513  if (!vrf) {
514  ErrorResp *resp = new ErrorResp();
515  resp->set_context(context());
516  resp->Response();
517  return;
518  }
519 
520  AgentSandeshPtr sand(new AgentLayer2RtSandesh(vrf, context(), "",
521  get_stale()));
522  sand->DoSandesh(sand);
523 }
uint32_t ethernet_tag() const
Definition: agent_path.h:565
BridgeAgentRouteTable * fabric_l2_unicast_table() const
Definition: agent.h:618
static Agent * GetInstance()
Definition: agent.h:436
Definition: vrf.h:86
void DeleteBridgeRoute(const AgentRoute *rt)
static void Delete(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, uint32_t ethernet_tag)
static DBTableBase * CreateTable(DB *db, const std::string &name)
Definition: bridge_route.cc:65
const IpAddress & ip_addr() const
Definition: agent_path.h:561
std::string GetString(const std::string &key) const
static AgentRouteData * BuildBgpPeerData(const Peer *peer, const string &vrf_name, const std::string &vn_name, uint32_t label, int vxlan_id, uint32_t ethernet_tag, uint32_t tunnel_type, Composite::Type type, ComponentNHKeyList &component_nh_key_list, bool pbb_nh, bool learning_enabled)
static void DeleteBroadcastReq(const Peer *peer, const std::string &vrf_name, uint32_t ethernet_tag, COMPOSITETYPE type)
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge, EVPN (Type2/Type5). This base class contains common code for all types of route tables.
Definition: agent_route.h:109
virtual void SetKey(const DBRequestKey *key)
static const MacAddress kZeroMac
Definition: mac_address.h:149
Definition: route.h:14
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
virtual BridgeRouteKey * Clone() const
Definition: bridge_route.cc:49
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
AgentPath * FindEvpnPathUsingKeyData(const AgentRouteKey *key, const AgentRouteData *data) const
const string & GetName() const
Definition: vrf.h:100
const VmInterface * FindVmFromDhcpBinding(const MacAddress &mac)
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:25
Base class for all Route entries in agent.
Definition: agent_route.h:224
BridgeRouteEntry * FindRouteNoLock(const MacAddress &mac)
Definition: bridge_route.cc:77
virtual std::string ToString() const
Definition: bridge_route.cc:45
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
Definition: nexthop.h:1641
void AddBridgeRoute(const AgentRoute *rt)
virtual AgentPath * FindPathUsingKeyData(const AgentRouteKey *key, const AgentRouteData *data) const
Definition: db.h:24
static string ToString(PhysicalDevice::ManagementProtocol proto)
const Type GetType() const
Definition: peer.h:87
NextHop * nexthop() const
Definition: agent_path.cc:87
COMPOSITETYPE comp_nh_type() const
Definition: agent_path.h:892
void Init()
Definition: db_table.cc:387
PrefixType prefix_address_
The prefix address.
Definition: agent_route.h:385
BridgeRouteEntry * FindRoute(const MacAddress &mac)
Definition: bridge_route.cc:72
VrfEntry * FindVrfFromId(size_t index)
Definition: vrf.cc:884
const std::string & pkt_interface_name() const
Definition: agent.h:944
uint8_t type
Definition: load_balance.h:109
virtual AgentRoute * AllocRouteEntry(VrfEntry *vrf, bool is_multicast) const
Definition: bridge_route.cc:54
Definition: agent.h:358
virtual bool ReComputePathAdd(AgentPath *path)
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
AgentRouteTable * GetBridgeRouteTable(const std::string &vrf_name)
Definition: vrf.cc:917
static void BridgeTableEnqueue(Agent *agent, DBRequest *req)
Definition: bridge_route.cc:26
static TypeBmap AllType()
Definition: nexthop.h:321
const Peer * peer() const
Definition: agent_path.h:263
const VmInterface * vm_interface() const
Definition: agent_path.h:1088
uint64_t sequence_number() const
Definition: peer.h:94
static const MacAddress & BroadcastMac()
Definition: mac_address.h:152
class boost::shared_ptr< AgentSandesh > AgentSandeshPtr
Definition: agent_db.h:18
void SetSandeshData(PathSandeshData &data) const
Definition: agent_path.cc:1720
COMPOSITETYPE composite_nh_type() const
Definition: nexthop.h:1842
Definition: peer.h:44
const MacAddress & mac() const
static Type ComputeType(TypeBmap bmap)
Definition: nexthop.cc:33
virtual const std::string GetAddressString() const
VrfTable * vrf_table() const
Definition: agent.h:485
static void AddBridgeBroadcastRoute(const Peer *peer, const string &vrf_name, uint32_t ethernet_tag, AgentRouteData *data)
virtual AgentSandeshPtr GetAgentSandesh(const AgentSandeshArguments *args, const std::string &context)
const Peer * mac_vm_binding_peer() const
Definition: agent.h:1034
virtual std::string ToString() const
void DeleteMacVmBindingRoute(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const VmInterface *vm_intf)
const Peer * peer() const
Definition: agent_route.h:47
#define COMPOSITETYPE
Definition: nexthop.h:1600
static void AddBridgeReceiveRoute(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const std::string &vn_name, const std::string &interface, bool policy)
const std::string & vrf_name() const
Definition: agent_route.h:46
VrfEntry * vrf() const
Definition: agent_route.h:275
virtual bool DBEntrySandesh(Sandesh *sresp, bool stale) const
uint32_t vxlan_id() const
Definition: agent_path.h:891
const MacVmBindingPath * FindMacVmBindingPath() const
const std::string & parent() const
Definition: agent_path.h:563
void Process(DBRequest &req)
Definition: agent_route.cc:186
static void BridgeTableProcess(Agent *agent, const string &vrf_name, DBRequest &req)
Definition: bridge_route.cc:33
virtual int CompareTo(const Route &rhs) const
static AgentRouteData * BuildNonBgpPeerData(const string &vrf_name, const std::string &vn_name, uint32_t label, int vxlan_id, uint32_t tunnel_type, Composite::Type type, ComponentNHKeyList &component_nh_key_list, bool pbb_nh, bool learning_enabled)
uint32_t ethernet_tag() const
Definition: agent_path.h:599
void AddMacVmBindingRoute(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const VmInterface *vm_intf, bool flood_dhcp)
virtual bool ReComputePathDeletion(AgentPath *path)
Definition: peer.h:257
virtual const std::string GetSourceAddressString() const
virtual KeyPtr GetDBRequestKey() const
AgentPath * FindMulticastPathUsingKeyData(const AgentRouteKey *key, const AgentRouteData *data) const
const IpAddress & ip_addr() const
Definition: agent_path.h:595
const MacAddress & GetMac() const
Definition: bridge_route.h:155
uint32_t vxlan_id() const
Definition: agent_path.h:265
Type
Definition: peer.h:48
virtual uint32_t GetActiveLabel() const