OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
controller_peer.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <base/os.h>
6 #include <base/util.h>
7 #include <base/logging.h>
8 #include <base/connection_info.h>
9 #include "base/address_util.h"
10 #include <net/bgp_af.h>
11 #include "cmn/agent_cmn.h"
12 #include "init/agent_param.h"
18 #include "oper/operdb_init.h"
19 #include "oper/vrf.h"
20 #include "oper/nexthop.h"
21 #include "oper/tunnel_nh.h"
22 #include "oper/mirror_table.h"
23 #include "oper/multicast.h"
24 #include "oper/peer.h"
25 #include "oper/vxlan.h"
26 #include "oper/agent_path.h"
27 #include "oper/ecmp_load_balance.h"
29 #include "cmn/agent_stats.h"
30 #include <pugixml/pugixml.hpp>
31 #include "xml/xml_pugi.h"
33 #include "controller/controller_types.h"
35 #include "xmpp/xmpp_init.h"
36 #include <xmpp_enet_types.h>
37 #include <xmpp_unicast_types.h>
38 #include <xmpp_multicast_types.h>
39 #include <xmpp_mvpn_types.h>
40 #include <assert.h>
41 #include <oper/nexthop.h>
42 
43 using namespace boost::asio;
44 using namespace autogen;
45 
46 using std::unique_ptr;
47 using std::stringstream;
48 
49 using process::ConnectionType;
50 using process::ConnectionStatus;
52 
53 // Parses string ipv4-addr/plen or ipv6-addr/plen
54 // Stores address in addr and returns plen
55 static int ParseEvpnAddress(const string &str, IpAddress *addr,
56  const MacAddress &mac) {
57  bool is_type5 = mac.IsZero();
58  size_t pos = str.find('/');
59  if (pos == string::npos) {
60  return -1;
61  }
62 
63  int plen = 0;
64  boost::system::error_code ec;
65  string plen_str = str.substr(pos + 1);
66  if (is_type5) {
67  //IpAddress::from_string
68  string addrstr = str.substr(0, pos);
69  boost::system::error_code ec1;
70  *addr = IpAddress::from_string(addrstr, ec1);
71  if (ec1)
72  return -1;
73  return atoi(plen_str.c_str());
74  } else {
75  if (plen_str == "32") {
76  Ip4Address ip4_addr;
77  ec = Ip4PrefixParse(str, &ip4_addr, &plen);
78  if (ec || plen != 32) {
79  return -1;
80  }
81  *addr = ip4_addr;
82  } else if (plen_str == "128") {
83  Ip6Address ip6_addr;
84  ec = Inet6PrefixParse(str, &ip6_addr, &plen);
85  if (ec || plen != 128) {
86  return -1;
87  }
88  *addr = ip6_addr;
89  } else {
90  return -1;
91  }
92  }
93  return plen;
94 }
95 
97  const std::string &xmpp_server,
98  const std::string &label_range,
99  uint8_t xs_idx)
100  : channel_(NULL), channel_str_(),
101  xmpp_server_(xmpp_server), label_range_(label_range),
102  xs_idx_(xs_idx), route_published_time_(0), agent_(agent) {
103  bgp_peer_id_.reset();
104  end_of_rib_tx_timer_.reset(new EndOfRibTxTimer(agent));
105  end_of_rib_rx_timer_.reset(new EndOfRibRxTimer(agent));
106  llgr_stale_timer_.reset(new LlgrStaleTimer(agent));
107  CreateBgpPeer();
108 }
109 
111  end_of_rib_tx_timer_.reset();
112  end_of_rib_rx_timer_.reset();
113  llgr_stale_timer_.reset();
114 }
115 
117  if (bgp_peer_id()) {
119  }
122  channel_ = NULL;
123 }
124 
126  (const std::string &vrf_name, const IpAddress &prefix_addr) {
127  InetUnicastAgentRouteTable *rt_table = NULL;
128 
129  if (prefix_addr.is_v4()) {
130  rt_table = agent_->vrf_table()->GetInet4UnicastRouteTable(vrf_name);
131  } else if (prefix_addr.is_v6()) {
132  rt_table = agent_->vrf_table()->GetInet6UnicastRouteTable(vrf_name);
133  }
134  if (rt_table == NULL) {
135  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
136  "Unable to fetch route table for prefix " +
137  prefix_addr.to_string());
138  }
139  return rt_table;
140 }
141 
143  (const std::string &vrf_name, const IpAddress &prefix_addr) {
144  InetUnicastAgentRouteTable *rt_table = NULL;
145 
146  if (prefix_addr.is_v4()) {
147  rt_table = agent_->vrf_table()->GetInet4MplsUnicastRouteTable(vrf_name);
148  }
149  if (rt_table == NULL) {
150  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
151  "Unable to fetch route table for prefix " +
152  prefix_addr.to_string());
153  }
154  return rt_table;
155 }
157  if (channel == NULL)
158  return;
159 
160  channel_ = channel;
162  channel->RegisterReceive(xmps::BGP,
164  this, _1));
165 }
166 
167 std::string AgentXmppChannel::GetBgpPeerName() const {
168  if (bgp_peer_id_.get() == NULL)
169  return "No BGP peer";
170 
171  return bgp_peer_id_.get()->GetName();
172 }
173 
175  assert(bgp_peer_id_.get() == NULL);
177  agent_->vrf_table()->Register(boost::bind(&VrfExport::Notify,
178  agent_, this, _1, _2));
179  boost::system::error_code ec;
180  const string &addr = agent_->controller_ifmap_xmpp_server(xs_idx_);
181  IpAddress ip = AddressFromString(addr, &ec);
182  assert(ec.value() == 0);
183  bgp_peer_id_.reset(new BgpPeer(this, ip.to_v4(), addr, id, Peer::BGP_PEER));
184 }
185 
186 void InetRequestDelete(const IpAddress& ip_address,
187  const int prefix_len,
188  std::string vrf_name,
189  const Peer* bgp_peer) {
190 
191  InetUnicastAgentRouteTable::DeleteReq(bgp_peer, vrf_name,
192  ip_address, prefix_len,
193  NULL);
194 }
195 
196 bool AgentXmppChannel::SendUpdate(const uint8_t *msg, size_t size) {
197 
198  if (agent_->stats())
200 
201  return channel_->Send(msg, size, xmps::BGP,
202  boost::bind(&AgentXmppChannel::WriteReadyCb, this, _1));
203 }
204 
206  pugi::xml_node node = pugi->FindNode("items");
207  pugi::xml_attribute attr = node.attribute("node");
208 
209  char *saveptr;
210  strtok_r(const_cast<char *>(attr.value()), "/", &saveptr);
211  strtok_r(NULL, "/", &saveptr);
212  char *vrf_name = strtok_r(NULL, "", &saveptr);
213  const std::string vrf(vrf_name);
214  EvpnAgentRouteTable *rt_table =
215  static_cast<EvpnAgentRouteTable *>
216  (agent_->vrf_table()->GetEvpnRouteTable(vrf_name));
217  if (rt_table == NULL) {
219  "Invalid VRF. Ignoring route retract" +
220  string(attr.value()));
221  return;
222  }
223 
224  pugi::xml_node node_check = pugi->FindNode("retract");
225  if (!pugi->IsNull(node_check)) {
226  for (node = node.first_child(); node; node = node.next_sibling()) {
227  if (strcmp(node.name(), "retract") == 0) {
228  std::string id = node.first_attribute().value();
230  "EVPN Delete Node id:" + id);
231 
232  boost::scoped_array<char> buff(new char[id.length() + 1]);
233  strcpy(buff.get(), id.c_str());
234 
235  // retract does not have nlri. Need to decode key fields from
236  // retract id. Format of retract-id expected are:
237  // 00:00:00:01:01:01,1.1.1.1/32 - Mac and IP for Non-VXLAN Encap
238  // 10-00:00:00:01:01:01,1.1.1.1/32 - VXLAN, mac, ip.
239  //
240  // In case of not finding pattern "-" whole string will be
241  // returned in token. So dont use it for ethernet_tag.
242  // Check for string length of saveptr to know if string was
243  // tokenised.
244 
245  uint16_t offset = 0;
246  uint32_t ethernet_tag = 0;
247  saveptr = NULL;
248 
249  // If id has "-", the value before "-" is treated as
250  // ethernet-tag
251  char *token = strtok_r(buff.get() + offset, "-", &saveptr);
252  if ((strlen(saveptr) != 0) && token) {
253  ethernet_tag = atoi(token);
254  offset += strlen(token) + 1;
255  }
256 
257  // Get MAC address. Its delimited by ","
258  token = strtok_r(buff.get() + offset, ",", &saveptr);
259  if ((strlen(saveptr) == 0) || (token == NULL)) {
261  "Error parsing MAC from retract-id: " +id);
262  continue;
263  }
264 
265  boost::system::error_code ec;
266  MacAddress mac(token, &ec);
267  if (ec) {
269  "Error decoding MAC from retract-id: "+id);
270  continue;
271  }
272 
273  offset += strlen(token) + 1;
274  IpAddress ip_addr, group, source;
275 
276  string str = buff.get() + offset;
277  size_t pos = str.find(',');
278  if (pos != string::npos) {
279  string group_str = str.substr(pos + 1);
280  pos = group_str.find(',');
281  if (pos == string::npos) {
282  continue;
283  }
284  string addrstr = group_str.substr(0, pos);
285  group = IpAddress::from_string(group_str, ec);
286  if (ec) {
287  continue;
288  }
289 
290  string source_str = str.substr(pos + 1);
291  source = IpAddress::from_string(source_str, ec);
292  if (ec) {
293  continue;
294  }
295  }
296 
297  uint32_t plen = ParseEvpnAddress(buff.get() + offset,
298  &ip_addr, mac);
299  if (plen < 0) {
301  "Error decoding IP address from "
302  "retract-id: "+id);
303  continue;
304  }
305 
306  if (mac.IsMulticast()) {
307  TunnelOlist olist;
308  agent_->oper_db()->multicast()->
309  ModifyEvpnMembers(bgp_peer_id(), vrf_name,
310  group.to_v4(), source.to_v4(),
311  olist, ethernet_tag,
313  continue;
314  } else if (mac == MacAddress::BroadcastMac()) {
315  //Deletes the peer path for all boradcast and
316  //traverses the subnet route in VRF to issue delete of peer
317  //for them as well.
318  TunnelOlist olist;
319  agent_->oper_db()->multicast()->
320  ModifyEvpnMembers(bgp_peer_id(),
321  vrf_name, olist,
322  ethernet_tag,
324 
325  //Ideally in non TSN node leaf olist is not to be
326  //present
327  if (agent_->tsn_enabled() == false)
328  return;
329  agent_->oper_db()->multicast()->
330  ModifyTorMembers(bgp_peer_id(),
331  vrf_name, olist,
332  ethernet_tag,
334  } else {
335  const Peer *bgp_peer = bgp_peer_id();
336  AgentRouteData *rt_data =
338  rt_table->DeleteReq(bgp_peer, vrf_name, mac,
339  ip_addr, plen, ethernet_tag,
340  rt_data);
341 
344  bgp_peer =
346  InetRequestDelete(ip_addr,
347  plen, vrf_name, bgp_peer);
348  }
349  }
350  }
351  }
352  return;
353  }
354 
355  //Call Auto-generated Code to return struct
356  std::unique_ptr<AutogenProperty> xparser(new AutogenProperty());
357  if (EnetItemsType::XmlParseProperty(node, &xparser) == false) {
359  "Xml Parsing for evpn Failed");
360  return;
361  }
362 
363  EnetItemsType *items;
364  EnetItemType *item;
365 
366  items = (static_cast<EnetItemsType *>(xparser.get()));
367  std::vector<EnetItemType>::iterator iter;
368  for (vector<EnetItemType>::iterator iter =items->item.begin();
369  iter != items->item.end(); iter++) {
370  item = &*iter;
371 
372  boost::system::error_code ec;
373  MacAddress mac = MacAddress(item->entry.nlri.mac);
374  IpAddress ip_addr, group, source;
375  group = IpAddress::from_string(item->entry.nlri.group, ec);
376  source = IpAddress::from_string(item->entry.nlri.source, ec);
377 
378  uint32_t plen = ParseEvpnAddress(item->entry.nlri.address, &ip_addr,
379  mac);
380  if (plen < 0) {
382  "Error parsing address : " + item->entry.nlri.address);
383  return;
384  }
385 
386  if (mac.IsMulticast()) {
387  // Requires changes for case when multicast source
388  // is inside contrail.
389  AddMulticastEvpnRoute(vrf_name, source, group, item);
390  continue;
391  }
392 
393  if (IsEcmp(item->entry.next_hops.next_hop)) {
394  VnListType vn_list;
395  vn_list.insert(item->entry.virtual_network);
396  AddEvpnEcmpRoute(vrf_name, mac, ip_addr, plen, item, vn_list);
397  } else {
398  AddEvpnRoute(vrf_name, item->entry.nlri.mac, ip_addr, plen, item);
399  }
400  }
401 }
402 
404 
405  pugi::xml_node node = pugi->FindNode("items");
406  pugi::xml_attribute attr = node.attribute("node");
407 
408  char *saveptr;
409  strtok_r(const_cast<char *>(attr.value()), "/", &saveptr);
410  strtok_r(NULL, "/", &saveptr);
411  char *vrf_name = strtok_r(NULL, "", &saveptr);
412  const std::string vrf(vrf_name);
413 
414  pugi::xml_node node_check = pugi->FindNode("retract");
415  if (!pugi->IsNull(node_check)) {
416  pugi->ReadNode("retract"); //sets the context
417  std::string retract_id = pugi->ReadAttrib("id");
418  if (bgp_peer_id() != agent_->mulitcast_builder()->
419  bgp_peer_id()) {
421  "Ignore retract request from non multicast tree "
422  "builder peer; Multicast Delete Node id:" + retract_id);
423  return;
424  }
425 
426  for (node = node.first_child(); node; node = node.next_sibling()) {
427  if (strcmp(node.name(), "retract") == 0) {
428  std::string id = node.first_attribute().value();
430  "Multicast Delete Node id:" + id);
431 
432  // Parse identifier to obtain group,source
433  // <addr:VRF:Group,Source)
434  strtok_r(const_cast<char *>(id.c_str()), ":", &saveptr);
435  strtok_r(NULL, ":", &saveptr);
436  char *group = strtok_r(NULL, ",", &saveptr);
437  char *source = strtok_r(NULL, "", &saveptr);
438  if (group == NULL || source == NULL) {
440  "Error parsing multicast group address from retract id");
441  return;
442  }
443 
444  boost::system::error_code ec;
445  IpAddress g_address = IpAddress::from_string(group, ec);
446  if (ec.value() != 0) {
448  "Error parsing multicast group address");
449  return;
450  }
451 
452  IpAddress s_address = IpAddress::from_string(source, ec);
453  if (ec.value() != 0) {
455  "Error parsing multicast source address");
456  return;
457  }
458 
459  TunnelOlist olist;
460  //Retract with invalid identifier
461  agent_->oper_db()->multicast()->
462  ModifyFabricMembers(agent_->multicast_tree_builder_peer(),
463  vrf, g_address.to_v4(),
464  s_address.to_v4(), 0, olist,
466  }
467  }
468  return;
469  }
470 
471  pugi::xml_node items_node = pugi->FindNode("item");
472  if (!pugi->IsNull(items_node)) {
473  pugi->ReadNode("item"); //sets the context
474  std::string item_id = pugi->ReadAttrib("id");
475  if (!(agent_->mulitcast_builder()) || (bgp_peer_id() !=
478  "Ignore request from non multicast tree "
479  "builder peer; Multicast Delete Node:" + item_id);
480  return;
481  }
482  }
483 
484  //Call Auto-generated Code to return struct
485  std::unique_ptr<AutogenProperty> xparser(new AutogenProperty());
486  if (McastItemsType::XmlParseProperty(node, &xparser) == false) {
488  "Xml Parsing for Multicast Message Failed");
489  return;
490  }
491 
492  McastItemsType *items;
493  McastItemType *item;
494 
495  items = (static_cast<McastItemsType *>(xparser.get()));
496  std::vector<McastItemType>::iterator items_iter;
497  boost::system::error_code ec;
498  for (items_iter = items->item.begin(); items_iter != items->item.end();
499  items_iter++) {
500 
501  item = &*items_iter;
502 
503  IpAddress g_address = IpAddress::from_string(item->entry.nlri.group, ec);
504  if (ec.value() != 0) {
506  "Error parsing multicast group address");
507  return;
508  }
509 
510  IpAddress s_address = IpAddress::from_string(item->entry.nlri.source, ec);
511  if (ec.value() != 0) {
513  "Error parsing multicast source address");
514  return;
515  }
516 
517  TunnelOlist olist;
518  std::vector<McastNextHopType>::iterator iter;
519  for (iter = item->entry.olist.next_hop.begin();
520  iter != item->entry.olist.next_hop.end(); iter++) {
521 
522  McastNextHopType nh = *iter;
523  IpAddress addr = IpAddress::from_string(nh.address, ec);
524  if (ec.value() != 0) {
526  "Error parsing next-hop address");
527  return;
528  }
529 
530  int label;
531  stringstream nh_label(nh.label);
532  nh_label >> label;
534  GetTypeBitmap(nh.tunnel_encapsulation_list);
535  olist.push_back(OlistTunnelEntry(boost::uuids::nil_uuid(), label,
536  addr.to_v4(), encap));
537  }
538 
539  IpAddress source_address =
540  IpAddress::from_string(item->entry.nlri.source_address, ec);
541  if ((ec.value() == 0) && (source_address != IpAddress(Ip4Address()))) {
542  olist.push_back(OlistTunnelEntry(boost::uuids::nil_uuid(), 0,
543  source_address.to_v4(),
545  }
546 
549  vrf, g_address.to_v4(), s_address.to_v4(),
550  item->entry.nlri.source_label, olist,
552  }
553 }
554 
556 
557  pugi::xml_node node = pugi->FindNode("items");
558  pugi::xml_attribute attr = node.attribute("node");
559 
560  char *saveptr;
561  strtok_r(const_cast<char *>(attr.value()), "/", &saveptr);
562  strtok_r(NULL, "/", &saveptr);
563  char *vrf_name = strtok_r(NULL, "", &saveptr);
564  const std::string vrf(vrf_name);
565 
566  pugi::xml_node node_check = pugi->FindNode("retract");
567  if (!pugi->IsNull(node_check)) {
568  pugi->ReadNode("retract"); //sets the context
569  std::string retract_id = pugi->ReadAttrib("id");
570 
571  for (node = node.first_child(); node; node = node.next_sibling()) {
572  if (strcmp(node.name(), "retract") == 0) {
573  std::string id = node.first_attribute().value();
575  "Multicast Delete Node id:" + id);
576 
577  // Parse identifier to obtain group,source
578  // <addr:VRF:Group,Source)
579  strtok_r(const_cast<char *>(id.c_str()), ":", &saveptr);
580  strtok_r(NULL, ":", &saveptr);
581  char *group = strtok_r(NULL, ",", &saveptr);
582  char *source = strtok_r(NULL, "", &saveptr);
583  if (group == NULL || source == NULL) {
585  "Error parsing multicast group address from retract id");
586  return;
587  }
588 
589  boost::system::error_code ec;
590  IpAddress g_address = IpAddress::from_string(group, ec);
591  if (ec.value() != 0) {
593  "Error parsing multicast group address");
594  return;
595  }
596 
597  IpAddress s_address = IpAddress::from_string(source, ec);
598  if (ec.value() != 0) {
600  "Error parsing multicast source address");
601  return;
602  }
603 
604  //Retract with invalid identifier
606  bgp_peer_id(), vrf, g_address.to_v4(),
607  s_address.to_v4(),
609  }
610  }
611  return;
612  }
613 
614  pugi::xml_node items_node = pugi->FindNode("item");
615  if (!pugi->IsNull(items_node)) {
616  pugi->ReadNode("item"); //sets the context
617  std::string item_id = pugi->ReadAttrib("id");
618  if (!(agent_->mulitcast_builder()) || (bgp_peer_id() !=
621  "Ignore request from non multicast tree "
622  "builder peer; Multicast Delete Node:" + item_id);
623  return;
624  }
625  }
626 
627  //Call Auto-generated Code to return struct
628  std::unique_ptr<AutogenProperty> xparser(new AutogenProperty());
629  if (MvpnItemsType::XmlParseProperty(node, &xparser) == false) {
631  "Xml Parsing for Multicast Message Failed");
632  return;
633  }
634 
635  MvpnItemsType *items;
636  MvpnItemType *item;
637 
638  items = (static_cast<MvpnItemsType *>(xparser.get()));
639  std::vector<MvpnItemType>::iterator items_iter;
640  boost::system::error_code ec;
641  for (items_iter = items->item.begin(); items_iter != items->item.end();
642  items_iter++) {
643 
644  item = &*items_iter;
645 
646  IpAddress g_address = IpAddress::from_string(item->entry.nlri.group, ec);
647  if (ec.value() != 0) {
649  "Error parsing multicast group address");
650  return;
651  }
652 
653  IpAddress s_address = IpAddress::from_string(item->entry.nlri.source, ec);
654  if (ec.value() != 0) {
656  "Error parsing multicast source address");
657  return;
658  }
659 
660  int route_type = item->entry.nlri.route_type;
661  if (route_type != 7) {
662  continue;
663  }
664 
666  bgp_peer_id(), vrf, g_address.to_v4(),
667  s_address.to_v4(),
668  agent_->controller()->
669  multicast_sequence_number());
670  }
671 }
672 
674 
675  pugi::xml_node node = pugi->FindNode("items");
676  pugi::xml_attribute attr = node.attribute("node");
677 
678  const char *af = NULL;
679  char *saveptr;
680  af = strtok_r(const_cast<char *>(attr.value()), "/", &saveptr);
681  strtok_r(NULL, "/", &saveptr);
682  char *vrf_name = strtok_r(NULL, "", &saveptr);
683 
684  VrfKey vrf_key(vrf_name);
685  VrfEntry *vrf =
686  static_cast<VrfEntry *>(agent_->vrf_table()->
687  FindActiveEntry(&vrf_key));
688  if (!vrf) {
690  "VRF not found");
691  return;
692  }
693 
694  InetUnicastAgentRouteTable *rt_table = NULL;
695  if (atoi(af) == BgpAf::IPv4) {
696  rt_table = vrf->GetInet4UnicastRouteTable();
697  } else if (atoi(af) == BgpAf::IPv6) {
698  rt_table = vrf->GetInet6UnicastRouteTable();
699  }
700 
701  if (!rt_table) {
703  "VRF not found");
704  return;
705  }
706 
707  if (!pugi->IsNull(node)) {
708  pugi::xml_node node_check = pugi->FindNode("retract");
709  if (!pugi->IsNull(node_check)) {
710  for (node = node.first_child(); node; node = node.next_sibling()) {
711  if (strcmp(node.name(), "retract") == 0) {
712  std::string id = node.first_attribute().value();
714  "Delete Node id:" + id);
715 
716  boost::system::error_code ec;
717  int prefix_len;
718 
721  return;
722  }
723  if (atoi(af) == BgpAf::IPv4) {
724  Ip4Address prefix_addr;
725  ec = Ip4PrefixParse(id, &prefix_addr, &prefix_len);
726  if (ec.value() != 0) {
728  "Error parsing v4 prefix for delete");
729  return;
730  }
731  rt_table->DeleteReq(bgp_peer_id(), vrf_name,
732  prefix_addr, prefix_len,
734 
735  } else if (atoi(af) == BgpAf::IPv6) {
736  Ip6Address prefix_addr;
737  ec = Inet6PrefixParse(id, &prefix_addr, &prefix_len);
738  if (ec.value() != 0) {
740  "Error parsing v6 prefix for delete");
741  return;
742  }
743  rt_table->DeleteReq(bgp_peer_id(), vrf_name,
744  prefix_addr, prefix_len,
746  }
747  }
748  }
749  return;
750  }
751 
752  //Call Auto-generated Code to return struct
753  std::unique_ptr<AutogenProperty> xparser(new AutogenProperty());
754  if (ItemsType::XmlParseProperty(node, &xparser) == false) {
756  "Xml Parsing Failed");
757  return;
758  }
759  ItemsType *items;
760  ItemType *item;
761 
762  items = (static_cast<ItemsType *>(xparser.get()));
763  for (vector<ItemType>::iterator iter =items->item.begin();
764  iter != items->item.end();
765  ++iter) {
766  item = &*iter;
767  boost::system::error_code ec;
768  int prefix_len;
769 
770  if (atoi(af) == BgpAf::IPv4) {
771  Ip4Address prefix_addr;
772  ec = Ip4PrefixParse(item->entry.nlri.address, &prefix_addr,
773  &prefix_len);
774  if (ec.value() != 0) {
776  "Error parsing v4 route address");
777  return;
778  }
779  AddRoute(vrf_name, prefix_addr, prefix_len, item);
780  } else if (atoi(af) == BgpAf::IPv6) {
781  Ip6Address prefix_addr;
782  ec = Inet6PrefixParse(item->entry.nlri.address, &prefix_addr,
783  &prefix_len);
784  if (ec.value() != 0) {
786  "Error parsing v6 route address");
787  return;
788  }
789  AddRoute(vrf_name, prefix_addr, prefix_len, item);
790  } else {
792  "Error updating route, Unknown IP family");
793  }
794  }
795  }
796 }
797 
798 
800 
801  pugi::xml_node node = pugi->FindNode("items");
802  pugi::xml_attribute attr = node.attribute("node");
803 
804  const char *af = NULL;
805  char *saveptr;
806  af = strtok_r(const_cast<char *>(attr.value()), "/", &saveptr);
807  strtok_r(NULL, "/", &saveptr);
808  char *vrf_name = strtok_r(NULL, "", &saveptr);
809 
810  VrfKey vrf_key(vrf_name);
811  VrfEntry *vrf =
812  static_cast<VrfEntry *>(agent_->vrf_table()->
813  FindActiveEntry(&vrf_key));
814  if (!vrf) {
816  "VRF not found");
817  return;
818  }
819 
820  InetUnicastAgentRouteTable *rt_table = NULL;
821  if (atoi(af) == BgpAf::IPv4) {
822  rt_table = vrf->GetInet4MplsUnicastRouteTable();
823  }
824 
825  if (!rt_table) {
827  "Route Table not found");
828  return;
829  }
830 
831  if (!pugi->IsNull(node)) {
832 
833  pugi::xml_node node_check = pugi->FindNode("retract");
834  if (!pugi->IsNull(node_check)) {
835  for (node = node.first_child(); node; node = node.next_sibling()) {
836  if (strcmp(node.name(), "retract") == 0) {
837  std::string id = node.first_attribute().value();
839  "Delete Node id:" + id);
840 
841  boost::system::error_code ec;
842  int prefix_len;
843  if (atoi(af) == BgpAf::IPv4) {
844  Ip4Address prefix_addr;
845  ec = Ip4PrefixParse(id, &prefix_addr, &prefix_len);
846  if (ec.value() != 0) {
848  "Error parsing v4 prefix for delete");
849  return;
850  }
851 
852  rt_table->DeleteMplsRouteReq(bgp_peer_id(), vrf_name,
853  prefix_addr, prefix_len,
855 
856  }
857  }
858  }
859  return;
860  }
861 
862  //Call Auto-generated Code to return struct
863  std::unique_ptr<AutogenProperty> xparser(new AutogenProperty());
864  if (ItemsType::XmlParseProperty(node, &xparser) == false) {
866  "Xml Parsing Failed");
867  return;
868  }
869  ItemsType *items;
870  ItemType *item;
871 
872  items = (static_cast<ItemsType *>(xparser.get()));
873  for (vector<ItemType>::iterator iter =items->item.begin();
874  iter != items->item.end();
875  ++iter) {
876  item = &*iter;
877  boost::system::error_code ec;
878  int prefix_len;
879 
880  if (atoi(af) == BgpAf::IPv4) {
881  Ip4Address prefix_addr;
882  ec = Ip4PrefixParse(item->entry.nlri.address, &prefix_addr,
883  &prefix_len);
884  if (ec.value() != 0) {
886  "Error parsing v4 route address");
887  return;
888  }
889  AddMplsRoute(vrf_name, prefix_addr, prefix_len, item);
890  } else {
892  "Error updating route, Unknown IP family");
893  }
894  }
895  }
896 }
897 
898 template <typename TYPE>
899 static void GetEcmpHashFieldsToUse(TYPE *item,
900  EcmpLoadBalance &ecmp_load_balance) {
901  ecmp_load_balance.ResetAll();
902  if (item->entry.load_balance.load_balance_decision.empty() ||
903  item->entry.load_balance.load_balance_decision !=
905  ecmp_load_balance.SetAll();
906 
907  uint8_t field_list_size = item->entry.
908  load_balance.load_balance_fields.load_balance_field_list.size();
909  if (field_list_size == 0)
910  ecmp_load_balance.SetAll();
911 
912  for (uint32_t i = 0; i < field_list_size; i++) {
913  std::string field_type = item->entry.
914  load_balance.load_balance_fields.load_balance_field_list[i];
915  if (field_type == ecmp_load_balance.source_ip_str())
916  ecmp_load_balance.set_source_ip();
917  if (field_type == ecmp_load_balance.destination_ip_str())
918  ecmp_load_balance.set_destination_ip();
919  if (field_type == ecmp_load_balance.ip_protocol_str())
920  ecmp_load_balance.set_ip_protocol();
921  if (field_type == ecmp_load_balance.source_port_str())
922  ecmp_load_balance.set_source_port();
923  if (field_type == ecmp_load_balance.destination_port_str())
924  ecmp_load_balance.set_destination_port();
925  }
926 }
927 
928 void AgentXmppChannel::AddInetEcmpRoute(string vrf_name, IpAddress prefix_addr,
929  uint32_t prefix_len, ItemType *item,
930  const VnListType &vn_list) {
931  const Peer *bgp_peer = bgp_peer_id();
934  return;
935  }
936  InetUnicastAgentRouteTable *rt_table = PrefixToRouteTable(vrf_name,
937  prefix_addr);
938  if (rt_table == NULL) {
939  return;
940  }
941 
942  std::stringstream str;
943  str << prefix_addr.to_string();
944  str << "/";
945  str << prefix_len;
946 
947  EcmpLoadBalance ecmp_load_balance;
948  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
949  ControllerEcmpRoute *data = BuildEcmpData(item, vn_list, ecmp_load_balance,
950  rt_table, str.str());
952  data->cloned_local_path_list().begin();
953  while (iter != data->cloned_local_path_list().end()) {
954  rt_table->AddClonedLocalPathReq(bgp_peer, vrf_name,
955  prefix_addr, prefix_len,
956  (*iter));
957  iter++;
958  }
959  // ECMP create component NH
960  rt_table->AddRemoteVmRouteReq(bgp_peer, vrf_name,
961  prefix_addr, prefix_len, data);
962 }
963 
965  const MacAddress &mac,
966  const IpAddress &prefix_addr,
967  uint32_t plen,
968  EnetItemType *item,
969  const VnListType &vn_list) {
970  // Verify that vrf is present and active
971  VrfKey vrf_key(vrf_name);
972  VrfEntry *vrf =
973  static_cast<VrfEntry *>(agent_->vrf_table()->
974  FindActiveEntry(&vrf_key));
975  if (!vrf) {
977  "VRF not found");
978  return;
979  }
980 
981  const Peer *bgp_peer = bgp_peer_id();
982 
983  EvpnAgentRouteTable *rt_table = static_cast<EvpnAgentRouteTable *>
984  (agent_->vrf_table()->GetEvpnRouteTable(vrf_name));
985  if (rt_table == NULL || rt_table->vrf_entry() == NULL) {
986  return;
987  }
988 
989  std::stringstream str;
990  str << item->entry.nlri.ethernet_tag;
991  str << ":";
992  str << mac.ToString();
993  str << ":";
994  str << prefix_addr.to_string();
995 
996  ControllerEcmpRoute *data = BuildEcmpData(item, vn_list, EcmpLoadBalance(),
997  rt_table, str.str());
999  data->cloned_local_path_list().begin();
1000  while (iter != data->cloned_local_path_list().end()) {
1001  rt_table->AddClonedLocalPathReq(bgp_peer, vrf_name,
1002  mac, prefix_addr,
1003  item->entry.nlri.ethernet_tag,
1004  (*iter));
1005  iter++;
1006  }
1007  //ECMP create component NH
1008  rt_table->AddRemoteVmRouteReq(bgp_peer, vrf_name, mac, prefix_addr,
1009  plen, item->entry.nlri.ethernet_tag, data);
1010 }
1011 
1012 template <typename TYPE>
1014  const VnListType &vn_list,
1015  const EcmpLoadBalance &ecmp_load_balance,
1016  const AgentRouteTable *rt_table,
1017  const std::string &prefix_str) {
1018  TagList tag_list;
1019  BuildTagList(item, &tag_list);
1020 
1022  vn_list, ecmp_load_balance, tag_list,
1023  item, rt_table, prefix_str);
1024  return data;
1025 }
1026 
1027 static bool FillEvpnOlist(Agent *agent,
1028  EnetOlistType &olist,
1029  TunnelOlist *tunnel_olist) {
1030  for (uint32_t i = 0; i < olist.next_hop.size(); i++) {
1031  boost::system::error_code ec;
1032  IpAddress addr =
1033  IpAddress::from_string(olist.next_hop[i].address,
1034  ec);
1035  if (ec.value() != 0) {
1036  return false;
1037  }
1038 
1039  int label = olist.next_hop[i].label;
1040  TunnelType::TypeBmap encap = agent->controller()->
1041  GetTypeBitmap(olist.next_hop[i].tunnel_encapsulation_list);
1042  tunnel_olist->push_back(OlistTunnelEntry(boost::uuids::nil_uuid(), label,
1043  addr.to_v4(), encap));
1044  }
1045  return true;
1046 }
1047 
1048 void AgentXmppChannel::AddMulticastEvpnRoute(const std::string &vrf_name,
1049  const IpAddress &source,
1050  const IpAddress &group,
1051  EnetItemType *item) {
1052 
1053  //Traverse Leaf Olist
1054  TunnelOlist leaf_olist;
1055  TunnelOlist olist;
1056  //Fill leaf olist and olist
1057  //TODO can check for item->entry.assisted_replication_supported
1058  //and then populate leaf_olist
1059  CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), "Composite",
1060  "add leaf evpn multicast route");
1061  if (FillEvpnOlist(agent_, item->entry.leaf_olist, &leaf_olist) == false) {
1062  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1063  "Error parsing next-hop address");
1064  return;
1065  }
1066  CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), "Composite",
1067  "add evpn multicast route");
1068  if (FillEvpnOlist(agent_, item->entry.olist, &olist) == false) {
1069  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1070  "Error parsing next-hop address");
1071  return;
1072  }
1073 
1074  agent_->oper_db()->multicast()->
1075  ModifyEvpnMembers(bgp_peer_id(), vrf_name, group.to_v4(),
1076  source.to_v4(), leaf_olist,
1077  item->entry.nlri.ethernet_tag,
1078  agent_->controller()->
1079  multicast_sequence_number());
1080 }
1081 
1082 void AgentXmppChannel::AddMulticastEvpnRoute(const string &vrf_name,
1083  const MacAddress &mac,
1084  EnetItemType *item) {
1085  //Traverse Leaf Olist
1086  TunnelOlist leaf_olist;
1087  TunnelOlist olist;
1088  //Fill leaf olist and olist
1089  //TODO can check for item->entry.assisted_replication_supported
1090  //and then populate leaf_olist
1091  CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), "Composite",
1092  "add leaf evpn multicast route");
1093  if (FillEvpnOlist(agent_, item->entry.leaf_olist, &leaf_olist) == false) {
1094  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1095  "Error parsing next-hop address");
1096  return;
1097  }
1098  CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), "Composite",
1099  "add evpn multicast route");
1100  if (FillEvpnOlist(agent_, item->entry.olist, &olist) == false) {
1101  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1102  "Error parsing next-hop address");
1103  return;
1104  }
1105 
1106  agent_->oper_db()->multicast()->
1107  ModifyTorMembers(bgp_peer_id(), vrf_name, leaf_olist,
1108  item->entry.nlri.ethernet_tag,
1109  agent_->controller()->
1110  multicast_sequence_number());
1111 
1112  agent_->oper_db()->multicast()->
1113  ModifyEvpnMembers(bgp_peer_id(), vrf_name, olist,
1114  item->entry.nlri.ethernet_tag,
1115  agent_->controller()->
1116  multicast_sequence_number());
1117 }
1118 
1120  uint32_t prefix_len,
1121  const Ip4Address &addr,
1122  const VnListType &vn_list,
1123  const SecurityGroupList &sg_list,
1124  const TagList &tag_list) {
1127 
1128  if (prefix_addr == agent_->router_id() && prefix_len == 32) {
1129  return;
1130  }
1131 
1132  if (addr == agent_->router_id()) {
1133  ClonedLocalPath *data =
1135  vn_list, sg_list, tag_list, sequence_number());
1137  prefix_addr, prefix_len, data);
1138  return;
1139  }
1140 
1141  AddressList nh;
1142  nh.push_back(addr);
1143 
1144  if (table->FindResolveRoute(addr) == NULL) {
1145  nh = agent_->vhost_default_gateway();
1146  }
1147 
1148  if (prefix_addr == addr && prefix_len == 32 &&
1149  table->FindResolveRoute(addr)) {
1150  //Route is resolvable dont add any entry
1151  return;
1152  }
1153 
1154  InetUnicastRouteEntry *rt = table->FindResolveRoute(prefix_addr);
1155  if (rt && rt->prefix_address() == prefix_addr && rt->prefix_length() == prefix_len) {
1156  //Dont overwrite resolve route
1157  return;
1158  }
1159 
1160  CommunityList cl;
1162  prefix_addr, prefix_len, nh,
1164  sg_list, tag_list, cl, true);
1165 }
1166 
1167 void AgentXmppChannel::AddEvpnRoute(const std::string &vrf_name,
1168  std::string mac_str,
1169  const IpAddress &ip_addr,
1170  uint32_t plen,
1171  EnetItemType *item) {
1172  // Verify that vrf is present and active
1173  VrfKey vrf_key(vrf_name);
1174  VrfEntry *vrf =
1175  static_cast<VrfEntry *>(agent_->vrf_table()->
1176  FindActiveEntry(&vrf_key));
1177  if (!vrf) {
1179  "VRF not found, ignoring request");
1180  return;
1181  }
1182 
1183  // Validate VRF first
1184  EvpnAgentRouteTable *rt_table =
1185  static_cast<EvpnAgentRouteTable *>
1186  (agent_->vrf_table()->GetEvpnRouteTable(vrf_name));
1187  if (rt_table == NULL || rt_table->vrf_entry() == NULL) {
1188  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1189  "Invalid VRF. Ignoring route");
1190  return;
1191  }
1192 
1193  boost::system::error_code ec;
1194  MacAddress mac(mac_str);
1195  if (mac == MacAddress::BroadcastMac()) {
1196  AddMulticastEvpnRoute(vrf_name, mac, item);
1197  return;
1198  }
1199 
1200  string nexthop_addr = item->entry.next_hops.next_hop[0].address;
1201  IpAddress nh_ip = IpAddress::from_string(nexthop_addr, ec);
1202  uint32_t label = item->entry.next_hops.next_hop[0].label;
1204  (item->entry.next_hops.next_hop[0].tunnel_encapsulation_list);
1205  // use LOW PathPreference if local preference attribute is not set
1206  uint32_t preference = PathPreference::LOW;
1207  if (item->entry.local_preference != 0) {
1208  preference = item->entry.local_preference;
1209  }
1210  PathPreference path_preference(item->entry.sequence_number, preference,
1211  false, false);
1212 
1213  TagList tag_list;
1214  BuildTagList(item, &tag_list);
1215 
1216  CONTROLLER_INFO_TRACE(RouteImport, GetBgpPeerName(), vrf_name,
1217  mac.ToString(), 0, nexthop_addr, label, "");
1218 
1219  // Check that VxLAN message is not destined to service-chained VRF instance
1220  VnEntry *si_ref_vn = vrf->si_vn_ref();
1221 
1224  si_ref_vn == NULL) {
1225 
1226  EcmpLoadBalance ecmp_load_balance;
1227  VnListType vn_list;
1228  vn_list.insert(item->entry.virtual_network);
1230  ip_addr,
1231  plen,
1232  label, // vrf->vxlan_id(), // VxLAN ID
1233  vrf_name,
1234  RouteParameters(nh_ip,
1235  MacAddress(item->entry.next_hops.next_hop[0].mac),
1236  vn_list,
1237  item->entry.security_group_list.security_group,
1238  CommunityList(),
1239  tag_list,
1240  path_preference,
1241  ecmp_load_balance,
1242  sequence_number()),
1243  bgp_peer_id());
1244  return;
1245  }
1246 
1247  if (agent_->router_id() != nh_ip.to_v4()) {
1248  CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), nexthop_addr,
1249  "add remote evpn route");
1250  VnListType vn_list;
1251  vn_list.insert(item->entry.virtual_network);
1252  // for number of nexthops more than 1, carry flag ecmp suppressed
1253  // to indicate the same to all modules, till we handle L2 ecmp
1254  ControllerVmRoute *data =
1257  agent_->router_id(),
1258  vrf_name, nh_ip.to_v4(),
1259  encap, label,
1260  MacAddress(item->entry.next_hops.next_hop[0].mac),
1261  vn_list,
1262  item->entry.security_group_list.security_group,
1263  tag_list,
1264  path_preference,
1265  (item->entry.next_hops.next_hop.size() > 1),
1266  EcmpLoadBalance(),
1267  item->entry.etree_leaf);
1268  rt_table->AddRemoteVmRouteReq(bgp_peer_id(), vrf_name, mac, ip_addr,
1269  plen, item->entry.nlri.ethernet_tag, data);
1270  return;
1271  }
1272 
1273  // In EVPN VNF service chaining, control-node sends the route originated
1274  // by us for the routing-vrf in the service-chain vrf as well.
1275  // When encapsulation used is VXLAN, nexthop cannot be found from the
1276  // message. Since EVPN Type5 local-route is not available in the
1277  // serivce-chain vrf evpn table, set the next-hop for the local route
1278  // (in the serice-chain's vrf) to primary-routing-vrf to have the common
1279  // design for the EVPN Type5.
1280 
1281  // Checking if the vrf received is service-chain vrf that belongs to
1282  // Vxlan routing VN (service-chaining between LRs).
1283  if (si_ref_vn && (si_ref_vn->vxlan_routing_vn() == true)) {
1284  // Vxlan routing VN (service-chaining between LRs). Local EVPN routes
1285  // for service-chain VRF's will be allowed for the service-chain between
1286  // Internal-VN (IVN) of the Vxlan Logiical Router (LR).
1287 
1288  // service-chain vrf will have si_vn_ref set to primary vrf,
1289  // in EVPN VNF service chaining, this vrf is to routing vrf
1290  VrfEntry *routing_vrf = si_ref_vn->GetVrf();
1291  assert(routing_vrf != vrf);
1292 
1293  // service instance vrf received, adding evpn type5 route for
1294  // that have local path
1295  if (!(routing_vrf->vn() && routing_vrf->vn()->vxlan_routing_vn())) {
1296  // primary vrf is not a routing vrf
1297  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1298  "Not a Routing VRF. Ignoring route");
1299  return;
1300  }
1301 
1302  // getting the local export path from the routing vrf
1303  EvpnAgentRouteTable *evpn_rt_table =
1304  static_cast<EvpnAgentRouteTable *>
1305  (agent_->vrf_table()->GetEvpnRouteTable(routing_vrf->GetName()));
1306  if (evpn_rt_table == NULL || evpn_rt_table->vrf_entry() == NULL) {
1307  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1308  "Invalid Routing VRF. Ignoring route");
1309  return;
1310  }
1311 
1313  routing_vrf->GetName(), MacAddress(), ip_addr,
1314  plen, 0); // Ethernet tag is zero in Type5
1315  const EvpnRouteEntry *evpn_rt = static_cast<EvpnRouteEntry *>
1316  (evpn_rt_table->FindActiveEntry(&rt_key));
1317  if (evpn_rt == NULL) {
1319  "Local EVPN route not found, ignoring request");
1320  return;
1321  }
1322 
1323  // Local port available, Add EVPN type5 route to service-chain vrf
1324  VnListType vn_list;
1325  vn_list.insert(item->entry.virtual_network);
1326 
1328  nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
1329  nh_req.data.reset(new VrfNHData(false, false, false));
1330 
1331  EvpnRoutingData *data = new EvpnRoutingData(nh_req,
1332  item->entry.security_group_list.security_group,
1333  CommunityList(),
1334  path_preference,
1335  EcmpLoadBalance(),
1336  tag_list,
1337  routing_vrf,
1338  routing_vrf->vxlan_id(), vn_list);
1339 
1340  // adding local type5 route to service-chain vrf
1341  rt_table->AddType5Route(bgp_peer_id(),
1342  vrf_name,
1343  ip_addr,
1344  0, // item->entry.nlri.ethernet_tag, is 0
1345  data);
1346 
1347  return;
1348  }
1349 
1350 
1351  // Route originated by us and reflected back by control-node
1352  // When encap is MPLS based, the nexthop can be found by label lookup
1353  // When encapsulation used is VXLAN, nexthop cannot be found from message
1354  // To have common design, get nexthop from the route already present.
1355  // VxLAN routes destined to a Routing VRF instance are handled
1356  // above
1357 
1358  EvpnRouteKey key(agent_->local_vm_peer(), vrf_name, mac,
1359  ip_addr, plen, item->entry.nlri.ethernet_tag);
1360  EvpnRouteEntry *route = static_cast<EvpnRouteEntry *>
1361  (rt_table->FindActiveEntry(&key));
1362  if (route == NULL) {
1364  "route not found, ignoring request");
1365  return;
1366  }
1367 
1368  AgentPath *local_path = route->FindLocalVmPortPath();
1369  const NextHop *nh = local_path ? local_path->nexthop() : NULL;
1370  if (nh == NULL) {
1372  "nexthop not found, ignoring request");
1373  return;
1374  }
1375 
1376  //In EVPN, if interface IP is not same as IP received in Evpn route
1377  //then use receive NH. This is done because this received evpn ip is
1378  //a floating IP associated with VM and it shoul be routed.
1379  if (nh->GetType() == NextHop::L2_RECEIVE) {
1380  rt_table->AddControllerReceiveRouteReq(bgp_peer_id(), vrf_name,
1381  label, mac, ip_addr,
1382  item->entry.nlri.ethernet_tag,
1383  item->entry.virtual_network,
1384  path_preference, sequence_number());
1385  return;
1386  }
1387 
1388  // We expect only INTERFACE nexthop for evpn routes
1389  const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>(nh);
1390  if (nh->GetType() != NextHop::INTERFACE) {
1392  "Invalid nexthop in evpn route");
1393  return;
1394  }
1395 
1396  SecurityGroupList sg_list = item->entry.security_group_list.security_group;
1397  VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf_nh->GetIfUuid(),
1398  intf_nh->GetInterface()->name());
1399  LocalVmRoute *local_vm_route = NULL;
1400  VnListType vn_list;
1401  vn_list.insert(item->entry.virtual_network);
1402  EcmpLoadBalance ecmp_load_balance;
1403 
1404  if (encap == TunnelType::VxlanType()) {
1405  local_vm_route =
1406  new LocalVmRoute(intf_key,
1408  label, false, vn_list,
1409  intf_nh->GetFlags(),
1410  sg_list, tag_list, CommunityList(), path_preference,
1411  Ip4Address(0), ecmp_load_balance, false, false,
1412  sequence_number(), item->entry.etree_leaf,
1413  false);
1414  } else {
1415  local_vm_route =
1416  new LocalVmRoute(intf_key,
1417  label,
1419  false, vn_list,
1420  intf_nh->GetFlags(),
1421  sg_list, tag_list, CommunityList(), path_preference,
1422  Ip4Address(0), ecmp_load_balance, false, false,
1423  sequence_number(), item->entry.etree_leaf,
1424  false);
1425  }
1426  rt_table->AddLocalVmRouteReq(bgp_peer_id(), vrf_name, mac,
1427  ip_addr, item->entry.nlri.ethernet_tag,
1428  static_cast<LocalVmRoute *>(local_vm_route));
1429 }
1430 
1431 void AgentXmppChannel::AddRemoteRoute(string vrf_name, IpAddress prefix_addr,
1432  uint32_t prefix_len, ItemType *item,
1433  const VnListType &vn_list) {
1434  InetUnicastAgentRouteTable *rt_table = PrefixToRouteTable(vrf_name,
1435  prefix_addr);
1436 
1437  if (rt_table == NULL) {
1438  return;
1439  }
1440 
1441  boost::system::error_code ec;
1442  string nexthop_addr = item->entry.next_hops.next_hop[0].address;
1443  uint32_t label = item->entry.next_hops.next_hop[0].label;
1444  IpAddress addr = IpAddress::from_string(nexthop_addr, ec);
1446  (item->entry.next_hops.next_hop[0].tunnel_encapsulation_list);
1447  if (ec.value() != 0) {
1448  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1449  "Error parsing nexthop ip address");
1450  return;
1451  }
1452 
1453  // use LOW PathPreference if local preference attribute is not set
1454  uint32_t preference = PathPreference::LOW;
1455  if (item->entry.local_preference != 0) {
1456  preference = item->entry.local_preference;
1457  }
1458  PathPreference path_preference(item->entry.sequence_number, preference,
1459  false, false);
1460 
1461  TagList tag_list;
1462  BuildTagList(item, &tag_list);
1463 
1464  std::string vn_string;
1465  for (VnListType::const_iterator vnit = vn_list.begin();
1466  vnit != vn_list.end(); ++vnit) {
1467  vn_string += *vnit + " ";
1468  }
1469  CONTROLLER_INFO_TRACE(RouteImport, GetBgpPeerName(), vrf_name,
1470  prefix_addr.to_string(), prefix_len,
1471  addr.to_v4().to_string(), label, vn_string);
1472 
1473  if (item->entry.next_hops.next_hop[0].label ==
1475  vrf_name == agent_->fabric_vrf_name() && prefix_addr.is_v4()) {
1476  AddFabricVrfRoute(prefix_addr.to_v4(), prefix_len, addr.to_v4(),
1477  vn_list,
1478  item->entry.security_group_list.security_group,
1479  tag_list);
1480  return;
1481  }
1482 
1483  if (vrf_name == agent_->fabric_policy_vrf_name() && prefix_addr.is_v4()) {
1484  //Dont override the below routes in ip_fabric vrf
1485  //default route
1486  //vhost route
1487  //vhost subnet routes
1488  if (prefix_addr.to_v4() == Ip4Address(0) && prefix_len == 0) {
1489  return;
1490  }
1491  if (prefix_addr == agent_->router_id() && prefix_len == 32) {
1492  return;
1493  }
1494  if (prefix_addr == agent_->vhost_prefix() &&
1495  prefix_len >= agent_->vhost_prefix_len()) {
1496  return;
1497  }
1498  }
1499 
1500 
1504  VrfEntry* vrf = agent_->vrf_table()->FindVrfFromName(vrf_name);
1507  // Inet routes are now handled inside the VxlanRoutingManager
1508  return;
1509  }
1510 
1511  if (agent_->router_id() != addr.to_v4()) {
1512  EcmpLoadBalance ecmp_load_balance;
1513  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1514  ControllerVmRoute *data =
1517  vrf_name, addr.to_v4(), encap, label,
1518  MacAddress(), vn_list,
1519  item->entry.security_group_list.security_group,
1520  tag_list,
1521  path_preference, false, ecmp_load_balance,
1522  false);
1523  rt_table->AddRemoteVmRouteReq(bgp_peer_id(), vrf_name, prefix_addr,
1524  prefix_len, data);
1525  return;
1526  }
1527 
1528  bool native_encap = false;
1529  if (encap & TunnelType::NativeType()) {
1530  native_encap = true;
1531  }
1532 
1533  MplsLabel *mpls = agent_->mpls_table()->FindMplsLabel(label);
1534  // When llgr and xmpp helper mode is enabled for agent
1535  // llgr route update from bgp peer can have stale mpls label on agent restart
1536  // do route lookup and add route with correct label if rt update is for local vm port
1537  if ((mpls == NULL) || (mpls->nexthop()
1538  && mpls->nexthop()->GetType() != NextHop::VLAN && mpls->nexthop()->GetType() != NextHop::COMPOSITE)) {
1539  if (agent_->oper_db()->global_system_config()->
1540  gres_parameters().IsEnabled()) {
1541  InetUnicastRouteEntry local_vm_route_key(NULL, prefix_addr, prefix_len, false);
1542  InetUnicastRouteEntry *local_vm_route =
1543  static_cast<InetUnicastRouteEntry *>
1544  (rt_table->FindLPM(local_vm_route_key));
1545  if (local_vm_route && local_vm_route->GetLocalVmPortPath() &&
1546  local_vm_route->GetLocalVmPortPath()->nexthop() && local_vm_route->GetLocalVmPortPath()->nexthop()->GetType() == NextHop::INTERFACE) {
1547  const AgentPath* local_vm_port_path = local_vm_route->GetLocalVmPortPath();
1548  const NextHop *vm_nh = local_vm_port_path->nexthop();
1549  const InterfaceNH *vm_intf_nh = static_cast<const InterfaceNH *>(vm_nh);
1550  const Interface *intrface = vm_intf_nh->GetInterface();
1551  if (intrface && intrface->type() == Interface::VM_INTERFACE) {
1552  LOG(DEBUG, "Mpls lablel picked from interface nh for local vm route, received label: " << label);
1553  label = local_vm_port_path->GetActiveLabel();
1555  vm_intf_nh->GetIfUuid(), intrface->name());
1556  // Enqueue rt update with correct mpls label and sequence number for bgp peer path
1557  EcmpLoadBalance ecmp_load_balance;
1558  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1559  BgpPeer *bgp_peer = bgp_peer_id();
1560  LocalVmRoute *local_vm_rt_update =
1561  new LocalVmRoute(intf_key, label,
1563  false, vn_list,
1565  item->entry.security_group_list.security_group,
1566  tag_list,
1567  CommunityList(),
1568  path_preference,
1569  Ip4Address(0),
1570  ecmp_load_balance, false, false,
1571  sequence_number(), false, native_encap);
1572  rt_table->AddLocalVmRouteReq(bgp_peer, vrf_name,
1573  prefix_addr, prefix_len,
1574  static_cast<LocalVmRoute *>(local_vm_rt_update));
1575  return;
1576  }
1577  }
1578  }
1579  }
1580  if (mpls != NULL) {
1581  const NextHop *nh = mpls->nexthop();
1582  switch(nh->GetType()) {
1583  case NextHop::INTERFACE: {
1584  const InterfaceNH *intf_nh = static_cast<const InterfaceNH *>(nh);
1585  const Interface *intrface = intf_nh->GetInterface();
1586  if (intrface == NULL) {
1587  break;
1588  }
1589 
1591  intf_nh->GetIfUuid(), intrface->name());
1592  EcmpLoadBalance ecmp_load_balance;
1593  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1594  BgpPeer *bgp_peer = bgp_peer_id();
1595  if (intrface->type() == Interface::VM_INTERFACE) {
1596  LocalVmRoute *local_vm_route =
1597  new LocalVmRoute(intf_key, label,
1599  false, vn_list,
1601  item->entry.security_group_list.security_group,
1602  tag_list,
1603  CommunityList(),
1604  path_preference,
1605  Ip4Address(0),
1606  ecmp_load_balance, false, false,
1607  sequence_number(), false, native_encap);
1608  rt_table->AddLocalVmRouteReq(bgp_peer, vrf_name,
1609  prefix_addr, prefix_len,
1610  static_cast<LocalVmRoute *>(local_vm_route));
1611  } else if (intrface->type() == Interface::INET) {
1612 
1613  if (!prefix_addr.is_v4()) {
1614  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1615  "MPLS label inet interface type not supported for non IPv4");
1616  return;
1617  }
1618  InetInterfaceKey intf_key(intrface->name());
1619  InetInterfaceRoute *inet_interface_route =
1620  new InetInterfaceRoute(intf_key, label,
1622  vn_list, sequence_number());
1623 
1624  rt_table->AddInetInterfaceRouteReq(bgp_peer, vrf_name,
1625  prefix_addr.to_v4(), prefix_len,
1626  inet_interface_route);
1627  } else {
1628  // Unsupported scenario
1629  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1630  "MPLS label points to invalid interface type");
1631  break;
1632  }
1633 
1634  break;
1635  }
1636 
1637  case NextHop::VLAN: {
1638  const VlanNH *vlan_nh = static_cast<const VlanNH *>(nh);
1640  vlan_nh->GetIfUuid(), "");
1641  BgpPeer *bgp_peer = bgp_peer_id();
1642  VlanNhRoute *data =
1643  new VlanNhRoute(intf_key, vlan_nh->GetVlanTag(),
1644  label, vn_list,
1645  item->entry.security_group_list.security_group,
1646  tag_list,
1647  path_preference, sequence_number());
1648  rt_table->AddVlanNHRouteReq(bgp_peer, vrf_name, prefix_addr,
1649  prefix_len, data);
1650  break;
1651  }
1652  case NextHop::COMPOSITE: {
1653  AddInetEcmpRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1654  break;
1655  }
1656  case NextHop::VRF: {
1657  //In case of gateway interface with example subnet
1658  //1.1.1.0/24 may be reachable on this gateway inteface,
1659  //Path added by local vm peer would point to
1660  //resolve NH, so that if any path hits this route, ARP resolution
1661  //can begin, and the label exported for this route would point to
1662  //table nexthop.
1663  //Hence existing logic of picking up nexthop from mpls label to
1664  //nexthop, will not work. We have added a special path where we
1665  //pick nexthop from local vm path, instead of BGP
1666  if (!prefix_addr.is_v4()) {
1667  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1668  "VRF nexthop is not supported for non IPv4");
1669  return;
1670  }
1671  BgpPeer *bgp_peer = bgp_peer_id();
1672  ClonedLocalPath *data =
1673  new ClonedLocalPath(label, vn_list,
1674  item->entry.security_group_list.security_group,
1675  tag_list,
1676  sequence_number());
1677  rt_table->AddClonedLocalPathReq(bgp_peer, vrf_name,
1678  prefix_addr.to_v4(),
1679  prefix_len, data);
1680  break;
1681  }
1682 
1683  default:
1684  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1685  "MPLS label points to invalid NH");
1686  }
1687  }
1688 }
1689 void AgentXmppChannel::AddRemoteMplsRoute(string vrf_name, IpAddress prefix_addr,
1690  uint32_t prefix_len, ItemType *item,
1691  const VnListType &vn_list) {
1693  prefix_addr);
1694 
1695  if (rt_table == NULL) {
1696  return;
1697  }
1698  if (prefix_addr == agent_->router_id() && prefix_len == 32) {
1699  rt_table->AddVhostMplsRoute(prefix_addr, bgp_peer_id());
1700  return;
1701  }
1702 
1703  boost::system::error_code ec;
1704  string nexthop_addr = item->entry.next_hops.next_hop[0].address;
1705  uint32_t label = item->entry.next_hops.next_hop[0].label;
1706  IpAddress addr = IpAddress::from_string(nexthop_addr, ec);
1707 
1708  if (ec.value() != 0) {
1709  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1710  "Error parsing nexthop ip address");
1711  return;
1712  }
1713 
1714  // use LOW PathPreference if local preference attribute is not set
1715  uint32_t preference = PathPreference::LOW;
1716  if (item->entry.local_preference != 0) {
1717  preference = item->entry.local_preference;
1718  }
1719  PathPreference path_preference(item->entry.sequence_number, preference,
1720  false, false);
1721 
1722  TagList tag_list;
1723  BuildTagList(item, &tag_list);
1724 
1725  std::string vn_string;
1726  for (VnListType::const_iterator vnit = vn_list.begin();
1727  vnit != vn_list.end(); ++vnit) {
1728  vn_string += *vnit + " ";
1729  }
1730  CONTROLLER_INFO_TRACE(RouteImport, GetBgpPeerName(), vrf_name,
1731  prefix_addr.to_string(), prefix_len,
1732  addr.to_v4().to_string(), label, vn_string);
1733 
1734  CommunityList cl;
1735 
1736  EcmpLoadBalance ecmp_load_balance;
1737  ControllerMplsRoute *data =
1740  vrf_name, addr.to_v4(),
1741  TunnelType::MplsoMplsType(), label,
1742  MacAddress(), vn_list,
1743  item->entry.security_group_list.security_group,
1744  tag_list,
1745  path_preference, false, ecmp_load_balance,
1746  false);
1747  rt_table->AddMplsRouteReq(bgp_peer_id(), vrf_name, prefix_addr,
1748  prefix_len, data);
1749  return;
1750 }
1751 
1752 template <typename TYPE>
1753 bool AgentXmppChannel::IsEcmp(const TYPE &nexthops) {
1754  if (nexthops.size() == 0)
1755  return false;
1756 
1757  std::string address = nexthops[0].address;
1758  uint32_t label = nexthops[0].label;
1759  for (uint32_t index = 1; index < nexthops.size(); index++) {
1760  if (nexthops[index].address != address ||
1761  (uint32_t)nexthops[index].label != label) {
1762  return true;
1763  }
1764  }
1765 
1766  return false;
1767 }
1768 
1769 template <typename TYPE>
1770 void AgentXmppChannel::GetVnList(const TYPE &nexthops, VnListType *vn_list) {
1771  for (uint32_t index = 0; index < nexthops.size(); index++) {
1772  vn_list->insert(nexthops[index].virtual_network);
1773  }
1774 }
1775 
1776 void AgentXmppChannel::AddRoute(string vrf_name, IpAddress prefix_addr,
1777  uint32_t prefix_len, ItemType *item) {
1778  if ((item->entry.next_hops.next_hop[0].label ==
1780  (vrf_name != agent_->fabric_vrf_name())) {
1781  return;
1782  }
1783 
1784  VnListType vn_list;
1785  GetVnList(item->entry.next_hops.next_hop, &vn_list);
1786  if (IsEcmp(item->entry.next_hops.next_hop)) {
1787  AddInetEcmpRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1788  } else {
1789  AddRemoteRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1790  }
1791 }
1792 
1793 void AgentXmppChannel::AddInetMplsEcmpRoute(string vrf_name, IpAddress prefix_addr,
1794  uint32_t prefix_len, ItemType *item,
1795  const VnListType &vn_list) {
1796 
1798  prefix_addr);
1799 
1800  if (rt_table == NULL) {
1801  return;
1802  }
1803 
1804  std::stringstream str;
1805  str << prefix_addr.to_string();
1806  str << "/";
1807  str << prefix_len;
1808 
1809  EcmpLoadBalance ecmp_load_balance;
1810  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1811  ControllerEcmpRoute *data = BuildEcmpData(item, vn_list, ecmp_load_balance,
1812  rt_table, str.str());
1813  //ECMP create component NH
1814  rt_table->AddMplsRouteReq(bgp_peer_id(), vrf_name,
1815  prefix_addr, prefix_len, data);
1816 }
1817 void AgentXmppChannel::AddMplsRoute(string vrf_name, IpAddress prefix_addr,
1818  uint32_t prefix_len, ItemType *item) {
1819 
1820  VnListType vn_list;
1821  GetVnList(item->entry.next_hops.next_hop, &vn_list);
1822  if (IsEcmp(item->entry.next_hops.next_hop)) {
1823  AddInetMplsEcmpRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1824  } else {
1825  AddRemoteMplsRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1826  }
1827 }
1829  if (msg && msg->type == XmppStanza::MESSAGE_STANZA) {
1830  unique_ptr<XmlBase> impl(XmppXmlImplFactory::Instance()->GetXmlImpl());
1831  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
1832  XmlPugi *msg_pugi = reinterpret_cast<XmlPugi *>(msg->dom.get());
1833  pugi->LoadXmlDoc(msg_pugi->doc());
1834  boost::shared_ptr<ControllerXmppData> data(new ControllerXmppData(xmps::BGP,
1835  xmps::UNKNOWN,
1836  xs_idx_,
1837  std::move(impl),
1838  true));
1839  agent_->controller()->Enqueue(data);
1840  }
1841 }
1842 
1843 void AgentXmppChannel::ReceiveBgpMessage(std::unique_ptr<XmlBase> impl) {
1844  if (agent_->stats())
1846 
1847  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
1848  pugi::xml_node node = pugi->FindNode("items");
1849  if (node == 0) {
1851  EndOfRibRx();
1852  return;
1853  }
1854 
1855  pugi->ReadNode("items"); //sets the context
1856  std::string nodename = pugi->ReadAttrib("node");
1857 
1858  const char *af = NULL, *safi = NULL, *vrf_name;
1859  char *str = const_cast<char *>(nodename.c_str());
1860  char *saveptr;
1861  af = strtok_r(str, "/", &saveptr);
1862  safi = strtok_r(NULL, "/", &saveptr);
1863  vrf_name = saveptr;
1864 
1865  // No BGP peer
1866  if (bgp_peer_id() == NULL) {
1867  CONTROLLER_TRACE (Trace, GetBgpPeerName(), vrf_name,
1868  "BGP peer not present, agentxmppchannel is inactive");
1869  return;
1870  }
1871 
1872  // If EndOfRib marker is received, process it accordingly.
1873  if (nodename == XmppInit::kEndOfRibMarker) {
1874  return;
1875  }
1876 
1877  if (atoi(af) == BgpAf::IPv4 && atoi(safi) == BgpAf::MVpn) {
1878  ReceiveMvpnUpdate(pugi);
1879  return;
1880  }
1881  if (atoi(af) == BgpAf::IPv4 && atoi(safi) == BgpAf::Mcast) {
1882  ReceiveMulticastUpdate(pugi);
1883  return;
1884  }
1885  if (atoi(af) == BgpAf::L2Vpn && atoi(safi) == BgpAf::Enet) {
1886  ReceiveEvpnUpdate(pugi);
1887  return;
1888  }
1889  if(atoi(af) == BgpAf::IPv4 && atoi(safi) == BgpAf::Mpls) {
1890  ReceiveInet4MplsUpdate(pugi);
1891  return;
1892  }
1893 
1894  if (atoi(safi) == BgpAf::Unicast) {
1895  ReceiveV4V6Update(pugi);
1896  return;
1897  }
1898  CONTROLLER_TRACE (Trace, GetBgpPeerName(), vrf_name,
1899  "Error Route update, Unknown Address Family or safi");
1900 }
1901 
1903  ReceiveUpdate(msg);
1904 }
1905 
1906 std::string AgentXmppChannel::ToString() const {
1907  return channel_str_;
1908 }
1909 
1910 void AgentXmppChannel::WriteReadyCb(const boost::system::error_code &ec) {
1911 }
1912 
1914  assert(agent_xmpp_channel);
1915  const Agent *agent = agent_xmpp_channel->agent();
1916 
1917  //Start a timer to flush off all old configs
1918  if (agent->ifmap_xmpp_channel(agent_xmpp_channel->GetXmppServerIdx())) {
1919  agent->ifmap_xmpp_channel(agent_xmpp_channel->GetXmppServerIdx())->
1920  StartConfigCleanupTimer();
1921  }
1922 }
1923 
1925  AgentXmppChannel *peer) {
1926  bool xmpp_channel_found = false;
1927  //Verify if channel registered is stiil active or has been deleted
1928  //after bgp peer was down. This is checked under existing agent
1929  //xmpp channels in agent.
1930  for (uint8_t idx = 0; idx < MAX_XMPP_SERVERS; idx++) {
1931  if (agent->controller_xmpp_channel(idx) == peer) {
1932  xmpp_channel_found = true;
1933  break;
1934  }
1935  }
1936  return xmpp_channel_found;
1937 }
1938 
1939 /*
1940  * AgentXmppChannel is active when:
1941  * 1) bgp peer is not null(bgp_peer_id)
1942  * 2) xmpp channel is in READY state
1943  * 3) Valid XMPP channel
1944  */
1946  AgentXmppChannel *peer) {
1947  if (!IsXmppChannelActive(agent, peer))
1948  return false;
1949 
1950  //Reach here if channel is present. Now check for BGP peer
1951  //as channel may have come up and created another BGP peer.
1952  //Also check for the state of channel.
1953  if (peer && peer->GetXmppChannel() && peer->bgp_peer_id() &&
1954  (peer->GetXmppChannel()->GetPeerState() == xmps::READY)) {
1955  return true;
1956  }
1957  return false;
1958 }
1959 
1960 /*
1961  * New peer is config peer. Increment the global config sequence number,
1962  * Notify for new config peer, set it in agent xmppcfg
1963  */
1965  Agent *agent = peer->agent();
1968  peer->GetXmppServerIdx());
1969  //Generate a new sequence number for the configuration
1971  agent->ifmap_parser()->reset_statistics();
1972  agent->controller()->agent_ifmap_vm_export()->NotifyAll(peer);
1973  if (agent->ifmap_xmpp_channel(peer->GetXmppServerIdx())) {
1974  agent->ifmap_xmpp_channel(peer->GetXmppServerIdx())->
1975  end_of_config_timer()->Start(peer);
1976  }
1977  return true;
1978  }
1979  return false;
1980 }
1981 
1982 /*
1983  * New multicast peer found - either first one or a lower one got selected.
1984  * Increment peer identifier so that new peer can update using incremented seq
1985  * number and multicast entries which didnt get updated can be removed via stale
1986  * cleanup.
1987  */
1989  AgentXmppChannel *new_peer) {
1991  old_peer->agent()->set_cn_mcast_builder(new_peer);
1992 }
1993 
1995  xmps::PeerState state) {
1996  std::unique_ptr<XmlBase> dummy_dom;
1997  boost::shared_ptr<ControllerXmppData> data(new ControllerXmppData(xmps::BGP,
1998  state,
1999  peer->GetXmppServerIdx(),
2000  std::move(dummy_dom),
2001  false));
2002  peer->agent()->controller()->Enqueue(data);
2003 }
2004 
2006  return (static_cast<BgpPeer *>(bgp_peer_id_.get()))->sequence_number();
2007 }
2008 
2009 /*
2010  * AgentXmppChanel state - READY
2011  *
2012  * - Bump up the sequence number to identify updates of routes on this channel
2013  * after connection is in ready state and later at the end of EOR TX timer,
2014  * flush out all the stales(which never got updated after READY state is seen).
2015  * - Config server selection is done if no config server is present. This can
2016  * happen when this is the first active channel or is becoming active after
2017  * other channel has become inactive.
2018  * - Multicast builder - Same explanation as of config server. If there is no
2019  * mcast builder, take the ownership.
2020  * - Notify all routes only if this channel is not becoming config peer. Reason
2021  * for same is that config peer selection, runs end of config timer which in
2022  * turn runs route walker to notify. So notification is deferred till end of
2023  * config is computed. For more explanation on timer check controller_timer.cc
2024  * - End of Rib Rx timer is started to handle the fallback when EOR from control
2025  * node is not seen within fallback time.
2026  */
2029  CONTROLLER_TRACE(Session, GetXmppServer(), "READY",
2030  "NULL", "BGP peer ready.");
2031  //Increment sequence number, all new updates should use this sequence
2032  //number.
2034 
2035  //Stop LLGR stale timer
2036  llgr_stale_timer()->Cancel();
2037 
2038  // Switch-over Config Control-node
2039  if (agent_->ifmap_active_xmpp_server().empty()) {
2041  CONTROLLER_TRACE(Session, GetXmppServer(), "READY",
2042  "NULL", "BGP peer set as config server.");
2043  } else {
2044  //Notify all routes to channel, if channel is not selected as config.
2045  //Config selection results in end of config computation which internally
2046  //will start the route notification. So notify is delayed till end of
2047  //config is computed.
2049  }
2050 
2051  AgentXmppChannel *agent_mcast_builder = agent_->mulitcast_builder();
2052  //Mcast builder was not set it, use the new peer
2053  if (agent_mcast_builder == NULL) {
2054  //Since this is first time mcast peer so old and new peer are same
2056  CONTROLLER_TRACE(Session, GetXmppServer(), "READY",
2058  GetBgpPeerName(), "Peer elected Mcast builder");
2059  }
2060 
2061  //Timer to delete stale paths in case EOR is not seen fro CN.
2062  //If EOR is seen it will cancel this timer.
2063  end_of_rib_rx_timer()->Start(this);
2064 
2065  if (agent_->stats())
2067 }
2068 
2069 /*
2070  * AgentXmppChanel state - NotREADY
2071  *
2072  * - Firstly stop all timers and walkers. No stale cleanup is to be
2073  * done. Caveat: if channel is not config channel then it should not stop any
2074  * config timers/walker.
2075  * By default end of rib rx timer is stopped and delete of stale walker is
2076  * stopped.
2077  * If channel is config server then stop end of config and config
2078  * cleanup(PeerIsNotConfig).
2079  * If channel is config server and there is another active config server
2080  * select the other channel as config and stop any timer from this channel.
2081  * - If its a mcast builder, try finding other if any.
2082  */
2084  CONTROLLER_TRACE(Session, GetXmppServer(), "NOT_READY",
2085  "NULL", "BGP peer decommissioned for xmpp channel.");
2086  //Stop stale cleanup if its running
2088  //Also stop notify as there is no CN for this peer.
2090  //Also stop end-of-rib rx fallback and retain.
2092  //State llgr stale timer to clean stales if CN has issues with getting ready.
2093  llgr_stale_timer()->Start(this);
2094 
2095  // evaluate peer change for config and multicast
2096  AgentXmppChannel *agent_mcast_builder =
2098  bool peer_is_config_server = (agent_->
2099  ifmap_active_xmpp_server().compare(GetXmppServer()) == 0);
2100  bool peer_is_agent_mcast_builder = (agent_mcast_builder == this);
2101 
2102  // Switch-over Config Control-node
2103  if (peer_is_config_server) {
2104  //stop all config clean timer, retain old config,
2105  //if there is a new config selected, it will take care of flushing
2106  //stale.
2107  PeerIsNotConfig();
2108  //send cfg subscribe to other peer if exists
2109  uint8_t idx = ((agent_->ifmap_active_xmpp_server_index() == 0) ? 1: 0);
2111  AgentXmppChannel *new_cfg_peer = agent_->controller_xmpp_channel(idx);
2112 
2113  if (AgentXmppChannel::IsBgpPeerActive(agent_, new_cfg_peer) &&
2114  AgentXmppChannel::SetConfigPeer(new_cfg_peer)) {
2115  CONTROLLER_TRACE(Session, new_cfg_peer->GetXmppServer(),
2116  "NOT_READY", "NULL", "BGP peer selected as"
2117  "config peer on decommission of old config "
2118  "peer.");
2119  }
2120  }
2121 
2122  // Switch-over Multicast Tree Builder
2123  if (peer_is_agent_mcast_builder) {
2124  uint8_t idx = ((agent_mcast_builder->GetXmppServerIdx() == 0)
2125  ? 1: 0);
2126  AgentXmppChannel *new_mcast_builder =
2128 
2129  // Selection of new peer as mcast builder is dependant on following
2130  // criterias:
2131  // 1) Channel is present (new_mcast_builder is not null)
2132  // 2) Channel is in READY state
2133  // 3) BGP peer is commissioned for channel
2134  bool evaluate_new_mcast_builder =
2135  AgentXmppChannel::IsBgpPeerActive(agent_, new_mcast_builder);
2136 
2137  if (!evaluate_new_mcast_builder) {
2138  new_mcast_builder = NULL;
2139  CONTROLLER_TRACE(Session, GetXmppServer(), "NOT_READY",
2140  "NULL", "No elected Multicast Tree Builder");
2141  }
2142  AgentXmppChannel::SetMulticastPeer(this, new_mcast_builder);
2143  if (evaluate_new_mcast_builder) {
2144  //Advertise subnet and all broadcast routes to
2145  //the new multicast tree builder
2146  new_mcast_builder->StartEndOfRibTxWalker();
2147  CONTROLLER_TRACE(Session, GetXmppServer(), "NOT_READY",
2149  GetBgpPeerName(),
2150  "Peer elected Multicast Tree Builder");
2151  }
2152  }
2153 }
2154 
2155 /*
2156  * AgentXmppChannel state TimedOut
2157  *
2158  * Injects NotReady event for this channel.
2159  *
2160  * If there are more than two channels available in config, then try picking
2161  * other channel to replace this timed out channel. And push this channel at the
2162  * end of the channel list so that it is picked only in worst case.
2163  * Also this channel gets moved to timed out list where it waits for any other
2164  * channel to take up the slot(xs_idx_) and is stable(Done to retain
2165  * config/routes till new channel is stable).
2166  *
2167  * If there are only two channels configured, no action to be taken.
2168  */
2170  CONTROLLER_TRACE(Session, GetXmppServer(), "TIMEDOUT",
2171  "NULL", "Connection to Xmpp Server, Timed out");
2172  {
2173  bool update_list = false;
2174  std::vector<string>::iterator iter = agent_->GetControllerlist().begin();
2175  std::vector<string>::iterator end = agent_->GetControllerlist().end();
2176  for (; iter != end; iter++) {
2177  std::vector<string> server;
2178  boost::split(server, *iter, boost::is_any_of(":"));
2179  if (GetXmppServer().compare(server[0]) == 0) {
2180  // Add the TIMEDOUT server to the end.
2181  if (iter+1 == end) break;
2182  std::rotate(iter, iter+1, end);
2183  update_list = true;
2184  break;
2185  }
2186  }
2187  if (update_list) {
2189  }
2190  }
2191 }
2192 
2194  xmps::PeerState state) {
2195  peer->UpdateConnectionInfo(state);
2196  if (state == xmps::READY) {
2197  peer->Ready();
2198  } else if (state == xmps::NOT_READY) {
2199  peer->NotReady();
2200  } else if (state == xmps::TIMEDOUT) {
2201  peer->TimedOut();
2202  }
2203 }
2204 
2206  return end_of_rib_tx_timer_.get();
2207 }
2208 
2210  return end_of_rib_rx_timer_.get();
2211 }
2212 
2214  return llgr_stale_timer_.get();
2215 }
2216 
2221  }
2222 }
2223 
2225  const boost::uuids::uuid &vm_id,
2226  bool subscribe) {
2227  string repr;
2228  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2229 
2230  if (!peer) {
2231  return false;
2232  }
2233 
2234  //Build the DOM tree
2235  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2236  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2237 
2238  pugi->AddNode("iq", "");
2239  pugi->AddAttribute("type", "set");
2240  pugi->AddAttribute("from", peer->channel_->FromString());
2241  std::string to(peer->channel_->ToString());
2242  to += "/";
2243  to += XmppInit::kConfigPeer;
2244  pugi->AddAttribute("to", to);
2245 
2246  pugi->AddChildNode("pubsub", "");
2247  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2248  if (subscribe == true) {
2249  pugi->AddChildNode("subscribe", "");
2250  } else {
2251  pugi->AddChildNode("unsubscribe", "");
2252  }
2253  std::string vm("virtual-machine:");
2254  stringstream vmid;
2255  vmid << vm_id;
2256  vm += vmid.str();
2257  pugi->AddAttribute("node", vm);
2258 
2259  pugi->doc().print(*xml_writer, "", pugi::format_default,
2260  pugi::encoding_utf8);
2262  peer->GetBgpPeerName(), "", repr);
2263  // send data
2264  if (peer->SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()),
2265  repr.length()) == false) {
2266  CONTROLLER_TRACE(Session, peer->GetXmppServer(),
2267  "VM subscribe Send Update deferred", vm, "");
2268  }
2269 
2270  return true;
2271 }
2272 
2274 
2275  string repr;
2276  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2277 
2278  if (!peer) {
2279  return false;
2280  }
2281 
2282  //Build the DOM tree
2283  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2284  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2285 
2286  pugi->AddNode("iq", "");
2287  pugi->AddAttribute("type", "set");
2288  pugi->AddAttribute("from", peer->channel_->FromString());
2289  std::string to(peer->channel_->ToString());
2290  to += "/";
2291  to += XmppInit::kConfigPeer;
2292  pugi->AddAttribute("to", to);
2293 
2294  pugi->AddChildNode("pubsub", "");
2295  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2296  pugi->AddChildNode("subscribe", "");
2297  string node("virtual-router:");
2298  node = node + XmppInit::kFqnPrependAgentNodeJID + peer->channel_->FromString();
2299  pugi->AddAttribute("node", node);
2300 
2301  pugi->doc().print(*xml_writer, "", pugi::format_default,
2302  pugi::encoding_utf8);
2304  peer->GetBgpPeerName(), "", repr);
2305  // send data
2306  if (peer->SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()),
2307  repr.length()) == false) {
2308  CONTROLLER_TRACE(Session, peer->GetXmppServer(),
2309  "Config subscribe Send Update deferred", node, "");
2310  }
2311  return true;
2312 }
2313 
2315  VrfEntry *vrf,
2316  bool subscribe) {
2317  static int req_id = 0;
2318  string repr;
2319  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2320 
2321  if (!peer) {
2322  return false;
2323  }
2325  subscribe ? "Subscribe" : "Unsubscribe");
2326  //Build the DOM tree
2327  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2328  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2329 
2330  pugi->AddNode("iq", "");
2331  pugi->AddAttribute("type", "set");
2332  pugi->AddAttribute("from", peer->channel_->FromString());
2333  std::string to(peer->channel_->ToString());
2334  to += "/";
2335  to += XmppInit::kBgpPeer;
2336  pugi->AddAttribute("to", to);
2337 
2338  stringstream request_id;
2339  request_id << "subscribe" << req_id++;
2340  pugi->AddAttribute("id", request_id.str());
2341  pugi->AddChildNode("pubsub", "");
2342  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2343  if (subscribe) {
2344  pugi->AddChildNode("subscribe", "");
2345  } else {
2346  pugi->AddChildNode("unsubscribe", "");
2347  }
2348  pugi->AddAttribute("node", vrf->GetName());
2349  pugi->AddChildNode("options", "" );
2350  stringstream vrf_id;
2351  vrf_id << vrf->rd();
2352  pugi->AddChildNode("instance-id", vrf_id.str());
2353 
2354  pugi->doc().print(*xml_writer, "", pugi::format_default,
2355  pugi::encoding_utf8);
2356  // send data
2357  if (peer->SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()),
2358  repr.length()) == false) {
2359  CONTROLLER_TRACE(Session, peer->GetXmppServer(),
2360  "Vrf subscribe Send Update deferred", vrf_id.str(), "");
2361  }
2362  return true;
2363 }
2364 
2365 void PopulateEcmpHashFieldsToUse(ItemType &item,
2366  const EcmpLoadBalance &ecmp_load_balance) {
2367  item.entry.load_balance.load_balance_decision = LoadBalanceDecision;
2368 
2369  if (ecmp_load_balance.AllSet())
2370  return;
2371 
2372  ecmp_load_balance.GetStringVector(
2373  item.entry.load_balance.load_balance_fields.load_balance_field_list);
2374 }
2375 
2377  const VnListType &vn_list,
2378  const SecurityGroupList *sg_list,
2379  const TagList *tag_list,
2380  const CommunityList *communities,
2381  uint32_t mpls_label,
2382  TunnelType::TypeBmap bmap,
2383  const PathPreference &path_preference,
2384  bool associate,
2386  const EcmpLoadBalance &ecmp_load_balance,
2387  uint32_t native_vrf_id) {
2388  if (route->vrf()) {
2389  const std::string vrf_name = route->vrf()->GetName();
2392  return true;
2393  }
2394  }
2395 
2396  static int id = 0;
2397  ItemType item;
2398  string repr;
2399  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2400 
2401  //Build the DOM tree
2402  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2403  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2404 
2405  if ((type == Agent::INET4_UNICAST) ||
2406  (type == Agent::INET4_MPLS)) {
2407  item.entry.nlri.af = BgpAf::IPv4;
2408  } else if (type == Agent::INET6_UNICAST) {
2409  item.entry.nlri.af = BgpAf::IPv6;
2410  }
2411  if (type == Agent::INET4_MPLS) {
2412  item.entry.nlri.safi = BgpAf::Mpls;
2413  } else {
2414  item.entry.nlri.safi = BgpAf::Unicast;
2415  }
2416 
2417  stringstream rstr;
2418  rstr << route->ToString();
2419  item.entry.nlri.address = rstr.str();
2420 
2421  string rtr(agent_->router_id().to_string());
2422 
2423  PopulateEcmpHashFieldsToUse(item, ecmp_load_balance);
2424  autogen::NextHopType nh;
2425  nh.af = BgpAf::IPv4;
2426  nh.address = rtr;
2427  nh.label = mpls_label;
2428 
2429  // EVPN (VNF) service chaining requires router MAC address advertisement.
2430  if (agent_->vhost_interface()) {
2431  nh.mac = agent_->vhost_interface()->mac().ToString();
2432  }
2433  if (bmap & TunnelType::GREType()) {
2434  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2435  }
2436  if (bmap & TunnelType::UDPType()) {
2437  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2438  }
2439  if (bmap & TunnelType::VxlanType()) {
2440  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2441  const AgentPath *loc_vm_path = route->FindIntfOrCompLocalVmPortPath();
2442  if (loc_vm_path && route->vrf() && route->vrf()->routing_vrf()) {
2443  nh.label = loc_vm_path->vxlan_id();
2444  }
2445  }
2446  if (bmap & TunnelType::NativeType()) {
2447  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("native");
2448  }
2449 
2450  if (tag_list && tag_list->size()) {
2451  nh.tag_list.tag = *tag_list;
2452  }
2453 
2454  if (path_preference.loc_sequence()) {
2455  nh.local_sequence_number = path_preference.loc_sequence();
2456  }
2457 
2458  for (VnListType::const_iterator vnit = vn_list.begin();
2459  vnit != vn_list.end(); ++vnit) {
2460  nh.virtual_network = *vnit;
2461  item.entry.next_hops.next_hop.push_back(nh);
2462  }
2463 
2464  if (sg_list && sg_list->size()) {
2465  item.entry.security_group_list.security_group = *sg_list;
2466  }
2467 
2468  if (communities && !communities->empty()) {
2469  item.entry.community_tag_list.community_tag = *communities;
2470  }
2471 
2472  item.entry.sub_protocol = route->intf_route_type();
2473  item.entry.version = 1; //TODO
2474  item.entry.med = 0;
2475 
2476  //Set sequence number and preference of route
2477  item.entry.sequence_number = path_preference.sequence();
2478  item.entry.local_preference = path_preference.preference();
2479 
2480  pugi->AddNode("iq", "");
2481  pugi->AddAttribute("type", "set");
2482 
2483  pugi->AddAttribute("from", channel_->FromString());
2484  std::string to(channel_->ToString());
2485  to += "/";
2486  to += XmppInit::kBgpPeer;
2487  pugi->AddAttribute("to", to);
2488 
2489  stringstream pubsub_id;
2490  pubsub_id << "pubsub" << id;
2491  pugi->AddAttribute("id", pubsub_id.str());
2492 
2493  pugi->AddChildNode("pubsub", "");
2494  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2495  pugi->AddChildNode("publish", "");
2496 
2497  //Catering for inet4 and evpn unicast routes
2498  stringstream ss_node;
2499  ss_node << item.entry.nlri.af << "/"
2500  << item.entry.nlri.safi << "/"
2501  << route->vrf()->GetName() << "/"
2502  << route->ToString();
2503  if (native_vrf_id != VrfEntry::kInvalidIndex) {
2504  ss_node << "/" << native_vrf_id;
2505  }
2506  std::string node_id(ss_node.str());
2507  pugi->AddAttribute("node", node_id);
2508  pugi->AddChildNode("item", "");
2509 
2510  pugi::xml_node node = pugi->FindNode("item");
2511 
2512  //Call Auto-generated Code to encode the struct
2513  item.Encode(&node);
2514 
2515  pugi->doc().print(*xml_writer, "", pugi::format_default,
2516  pugi::encoding_utf8);
2517  // send data
2518  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2519  repr.clear();
2520 
2521  pugi->DeleteNode("pubsub");
2522  pugi->ReadNode("iq");
2523 
2524  stringstream collection_id;
2525  collection_id << "collection" << id++;
2526  pugi->ModifyAttribute("id", collection_id.str());
2527  pugi->AddChildNode("pubsub", "");
2528  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2529  pugi->AddChildNode("collection", "");
2530 
2531  pugi->AddAttribute("node", route->vrf()->GetName());
2532  if (associate) {
2533  pugi->AddChildNode("associate", "");
2534  } else {
2535  pugi->AddChildNode("dissociate", "");
2536  }
2537  pugi->AddAttribute("node", node_id);
2538 
2539  pugi->doc().print(*xml_writer, "", pugi::format_default,
2540  pugi::encoding_utf8);
2541  // send data
2542  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2544  return true;
2545 }
2546 
2548  stringstream &node_id,
2549  AgentRoute *route,
2550  const Ip4Address *nh_ip,
2551  const std::string &vn,
2552  const SecurityGroupList *sg_list,
2553  const TagList *tag_list,
2554  const CommunityList *communities,
2555  uint32_t label,
2556  uint32_t tunnel_bmap,
2557  const std::string &destination,
2558  const std::string &source,
2559  bool associate) {
2560  assert(route->GetTableType() == Agent::EVPN);
2561  const AgentPath *path = NULL;
2562  EvpnRouteEntry *evpn_route =
2563  dynamic_cast<EvpnRouteEntry *>(route);
2564  path = evpn_route->FindOvsPath();
2565  if ((path == NULL) && (associate)) {
2567  route->vrf()->GetName(),
2568  "OVS path not found for ff:ff:ff:ff:ff:ff, skip send");
2569  return false;
2570  }
2571 
2572  item.entry.local_preference = PathPreference::LOW;
2573  item.entry.sequence_number = 0;
2574  item.entry.replicator_address = source;
2575  item.entry.nlri.af = BgpAf::L2Vpn;
2576  item.entry.nlri.safi = BgpAf::Enet;
2577  stringstream rstr;
2578  rstr << route->ToString();
2579  item.entry.nlri.mac = rstr.str();
2580  item.entry.assisted_replication_supported = false;
2581  item.entry.edge_replication_not_supported = false;
2582 
2583  rstr.str("");
2584  //TODO fix this when multicast moves to evpn
2585  assert(evpn_route->is_multicast());
2586  rstr << destination;
2587  rstr << "/32";
2588  item.entry.nlri.ethernet_tag = 0;
2589  if (associate == false)
2590  item.entry.nlri.ethernet_tag = label;
2591 
2592  item.entry.nlri.address = rstr.str();
2593  assert(item.entry.nlri.address != "0.0.0.0");
2594 
2595  autogen::EnetNextHopType nh;
2596  nh.af = Address::INET;
2597  nh.address = destination;
2598  nh.label = label;
2599 
2600  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2601  << route->ToString() << "," << item.entry.nlri.address;
2602  TunnelType::Type tunnel_type = TunnelType::ComputeType(tunnel_bmap);
2603 
2604  if (path) {
2605  tunnel_type = path->tunnel_type();
2606  }
2607  if (associate) {
2608  if (tunnel_type != TunnelType::VXLAN) {
2609  if (tunnel_bmap & TunnelType::GREType()) {
2610  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2611  }
2612  if (tunnel_bmap & TunnelType::UDPType()) {
2613  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2614  }
2615  } else {
2616  if (path) {
2617  nh.label = path->vxlan_id();
2618  item.entry.nlri.ethernet_tag = nh.label;
2619  } else {
2620  nh.label = 0;
2621  }
2622  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2623  }
2624 
2625  if (sg_list && sg_list->size()) {
2626  item.entry.security_group_list.security_group = *sg_list;
2627  }
2628 
2629  if (tag_list && tag_list->size()) {
2630  nh.tag_list.tag = *tag_list;
2631  }
2632  }
2633 
2634  item.entry.next_hops.next_hop.push_back(nh);
2635  item.entry.med = 0;
2636  //item.entry.version = 1; //TODO
2637  //item.entry.virtual_network = vn;
2638  return true;
2639 }
2640 
2641 //TODO simplify label selection below.
2643  stringstream &node_id,
2644  AgentRoute *route,
2645  const Ip4Address *nh_ip,
2646  const std::string &vn,
2647  const SecurityGroupList *sg_list,
2648  const TagList *tag_list,
2649  const CommunityList *communities,
2650  uint32_t label,
2651  uint32_t tunnel_bmap,
2652  bool associate,
2653  const AgentPath *path,
2654  bool assisted_replication) {
2655  assert(route->is_multicast() == true);
2656  item.entry.local_preference = PathPreference::LOW;
2657  item.entry.sequence_number = 0;
2658  if (agent_->simulate_evpn_tor()) {
2659  item.entry.edge_replication_not_supported = true;
2660  } else {
2661  item.entry.edge_replication_not_supported = false;
2662  }
2663  item.entry.nlri.af = BgpAf::L2Vpn;
2664  item.entry.nlri.safi = BgpAf::Enet;
2665  stringstream rstr;
2666  //TODO fix this when multicast moves to evpn
2667  rstr << "0.0.0.0/32";
2668  item.entry.nlri.address = rstr.str();
2669  assert(item.entry.nlri.address != "0.0.0.0");
2670 
2671  rstr.str("");
2672  if (assisted_replication) {
2673  rstr << route->ToString();
2674  item.entry.assisted_replication_supported = true;
2675  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2676  << route->ToString() << "," << item.entry.nlri.address
2677  << "," << route->GetAddressString()
2678  << "," << route->GetSourceAddressString();
2679  } else {
2680  rstr << route->GetAddressString();
2681  item.entry.assisted_replication_supported = false;
2682  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2683  << route->GetAddressString() << "," << item.entry.nlri.address
2684  << "," << route->GetAddressString()
2685  << "," << route->GetSourceAddressString();
2686  }
2687 
2688  if (route->GetTableType() == Agent::INET4_MULTICAST) {
2689  Inet4MulticastRouteEntry *m_route =
2690  static_cast<Inet4MulticastRouteEntry *>(route);
2691 
2692  const Ip4Address group = m_route->dest_ip_addr();
2693  MacAddress mac;
2694  agent_->oper_db()->multicast()->GetMulticastMacFromIp(group, mac);
2695 
2696  item.entry.nlri.mac = mac.ToString();
2697  item.entry.nlri.group = route->GetAddressString();
2698  item.entry.nlri.source = route->GetSourceAddressString();
2699  item.entry.nlri.flags =
2701  m_route->vrf()->GetName(),
2702  m_route->src_ip_addr(),
2703  m_route->dest_ip_addr());
2704  } else {
2705  item.entry.nlri.mac = route->ToString();
2706  }
2707 
2708  autogen::EnetNextHopType nh;
2709  nh.af = Address::INET;
2710  nh.address = nh_ip->to_string();
2711  nh.label = label;
2712 
2713  TunnelType::Type tunnel_type = TunnelType::ComputeType(tunnel_bmap);
2714  item.entry.nlri.ethernet_tag = route->vrf()->isid();
2715  if (associate == false) {
2716  //In case of VXLAN ethernet tag is set to vxlan ID.
2717  //Upon withdraw or encap change label holds the VN ID
2718  //which is used to withdraw route
2719  item.entry.nlri.ethernet_tag = label;
2720  }
2721 
2722  if (path) {
2723  tunnel_type = path->tunnel_type();
2724  }
2725  if (associate) {
2726  if (tunnel_type != TunnelType::VXLAN) {
2727  if (tunnel_bmap & TunnelType::GREType()) {
2728  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2729  }
2730  if (tunnel_bmap & TunnelType::UDPType()) {
2731  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2732  }
2733  } else {
2734  if (path == NULL)
2735  path = route->FindPath(agent_->local_peer());
2736 
2737  if (path) {
2738  nh.label = path->vxlan_id();
2739  item.entry.nlri.ethernet_tag = nh.label;
2740  } else {
2741  nh.label = 0;
2742  }
2743  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2744  }
2745 
2746  if (sg_list && sg_list->size()) {
2747  item.entry.security_group_list.security_group = *sg_list;
2748  }
2749  }
2750 
2751  item.entry.next_hops.next_hop.push_back(nh);
2752  item.entry.med = 0;
2753  //item.entry.version = 1; //TODO
2754  //item.entry.virtual_network = vn;
2755  return true;
2756 }
2757 
2759  stringstream &node_id,
2760  AgentRoute *route,
2761  const Ip4Address *nh_ip,
2762  const std::string &vn,
2763  const SecurityGroupList *sg_list,
2764  const TagList *tag_list,
2765  const CommunityList *communities,
2766  uint32_t label,
2767  uint32_t tunnel_bmap,
2768  const PathPreference
2769  &path_preference,
2770  bool associate) {
2771  assert(route->is_multicast() == false);
2772  assert(route->GetTableType() == Agent::EVPN);
2773  item.entry.local_preference = path_preference.preference();
2774  item.entry.sequence_number = path_preference.sequence();
2775  item.entry.assisted_replication_supported = false;
2776  item.entry.edge_replication_not_supported = false;
2777  item.entry.nlri.af = BgpAf::L2Vpn;
2778  item.entry.nlri.safi = BgpAf::Enet;
2779 
2780  stringstream rstr;
2781  rstr << route->GetAddressString();
2782  item.entry.nlri.mac = rstr.str();
2783 
2784  const AgentPath *active_path = NULL;
2785  rstr.str("");
2786  EvpnRouteEntry *evpn_route = static_cast<EvpnRouteEntry *>(route);
2787  rstr << evpn_route->prefix_address().to_string() << "/"
2788  << static_cast<int>(evpn_route->prefix_length());
2789  active_path = evpn_route->FindLocalVmPortPath();
2790  item.entry.nlri.ethernet_tag = evpn_route->ethernet_tag();
2791 
2792  item.entry.nlri.address = rstr.str();
2793  assert(item.entry.nlri.address != "0.0.0.0");
2794 
2795  item.entry.etree_leaf = true;
2796  if (active_path) {
2797  item.entry.etree_leaf = active_path->etree_leaf();
2798  }
2799 
2800  autogen::EnetNextHopType nh;
2801  nh.af = Address::INET;
2802  nh.address = nh_ip->to_string();
2803  nh.label = label;
2804  if (evpn_route->mac().IsZero()) {
2805  nh.mac = agent_->vhost_interface()->mac().ToString();
2806  }
2807  TunnelType::Type tunnel_type = TunnelType::ComputeType(tunnel_bmap);
2808  if (active_path) {
2809  tunnel_type = active_path->tunnel_type();
2810  }
2811  if (associate) {
2812  if (tunnel_type != TunnelType::VXLAN) {
2813  if (tunnel_bmap & TunnelType::GREType()) {
2814  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2815  }
2816  if (tunnel_bmap & TunnelType::UDPType()) {
2817  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2818  }
2819  } else {
2820  if (active_path) {
2821  nh.label = active_path->vxlan_id();
2822  } else {
2823  nh.label = 0;
2824  }
2825  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2826  }
2827 
2828  if (sg_list && sg_list->size()) {
2829  item.entry.security_group_list.security_group = *sg_list;
2830  }
2831 
2832  if (tag_list && tag_list->size()) {
2833  nh.tag_list.tag = *tag_list;
2834  }
2835 
2836  if (path_preference.loc_sequence()) {
2837  nh.local_sequence_number = path_preference.loc_sequence();
2838  }
2839  }
2840 
2841  item.entry.next_hops.next_hop.push_back(nh);
2842  item.entry.med = 0;
2843  //item.entry.version = 1; //TODO
2844  //item.entry.virtual_network = vn;
2845 
2846  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2847  << route->GetAddressString() << "," << item.entry.nlri.address;
2848  return true;
2849 }
2850 
2852  stringstream &ss_node,
2853  const AgentRoute *route,
2854  bool associate) {
2855  static int id = 0;
2856  string repr;
2857  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2858 
2859  //Build the DOM tree
2860  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2861  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2862 
2863  pugi->AddNode("iq", "");
2864  pugi->AddAttribute("type", "set");
2865 
2866  pugi->AddAttribute("from", channel_->FromString());
2867  std::string to(channel_->ToString());
2868  to += "/";
2869  to += XmppInit::kBgpPeer;
2870  pugi->AddAttribute("to", to);
2871 
2872  stringstream pubsub_id;
2873  pubsub_id << "pubsub_l2" << id;
2874  pugi->AddAttribute("id", pubsub_id.str());
2875 
2876  pugi->AddChildNode("pubsub", "");
2877  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2878  pugi->AddChildNode("publish", "");
2879 
2880  std::string node_id(ss_node.str());
2881  pugi->AddAttribute("node", node_id);
2882  pugi->AddChildNode("item", "");
2883 
2884  pugi::xml_node node = pugi->FindNode("item");
2885 
2886  //Call Auto-generated Code to encode the struct
2887  item.Encode(&node);
2888 
2889  pugi->doc().print(*xml_writer, "", pugi::format_default,
2890  pugi::encoding_utf8);
2891  // send data
2892  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2893  repr.clear();
2894 
2895  pugi->DeleteNode("pubsub");
2896  pugi->ReadNode("iq");
2897 
2898  stringstream collection_id;
2899  collection_id << "collection_l2" << id++;
2900  pugi->ModifyAttribute("id", collection_id.str());
2901  pugi->AddChildNode("pubsub", "");
2902  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2903  pugi->AddChildNode("collection", "");
2904 
2905  pugi->AddAttribute("node", route->vrf()->GetExportName());
2906  if (associate) {
2907  pugi->AddChildNode("associate", "");
2908  } else {
2909  pugi->AddChildNode("dissociate", "");
2910  }
2911  pugi->AddAttribute("node", node_id);
2912 
2913  pugi->doc().print(*xml_writer, "", pugi::format_default,
2914  pugi::encoding_utf8);
2915  // send data
2916  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2918  return true;
2919 }
2920 
2922  const Ip4Address *nh_ip,
2923  std::string vn,
2924  const SecurityGroupList *sg_list,
2925  const TagList *tag_list,
2926  const CommunityList *communities,
2927  uint32_t label,
2928  uint32_t tunnel_bmap,
2929  const std::string &destination,
2930  const std::string &source,
2931  const PathPreference
2932  &path_preference,
2933  bool associate) {
2934  EnetItemType item;
2935  stringstream ss_node;
2936  bool ret = true;
2937 
2938  if (label == MplsTable::kInvalidLabel) return false;
2939 
2940  if (route->is_multicast()) {
2941  BridgeRouteEntry *l2_route =
2942  dynamic_cast<BridgeRouteEntry *>(route);
2943  if (agent_->tsn_enabled()) {
2944  //Second subscribe for TSN assited replication
2945  if (BuildEvpnMulticastMessage(item, ss_node, route, nh_ip, vn,
2946  sg_list, tag_list, communities,
2947  label, tunnel_bmap, associate,
2948  l2_route->FindPath(agent_->
2949  local_peer()),
2950  true) == false)
2951  return false;
2952  ret |= BuildAndSendEvpnDom(item, ss_node,
2953  route, associate);
2954  } else if (agent_->tor_agent_enabled()) {
2955  if (BuildTorMulticastMessage(item, ss_node, route, nh_ip, vn,
2956  sg_list, tag_list, communities, label,
2957  tunnel_bmap, destination, source,
2958  associate) == false)
2959  return false;;
2960  ret = BuildAndSendEvpnDom(item, ss_node, route, associate);
2961  } else {
2962  const AgentPath *path;
2963  if (route->GetTableType() == Agent::BRIDGE) {
2964  path = l2_route->FindPath(agent_->multicast_peer());
2965  } else if (route->GetTableType() == Agent::INET4_MULTICAST) {
2966  Inet4MulticastRouteEntry *m_route =
2967  static_cast<Inet4MulticastRouteEntry *>(route);
2968  path = m_route->FindPath(agent_->multicast_peer());
2969  } else {
2970  return false;
2971  }
2972  if (BuildEvpnMulticastMessage(item, ss_node, route, nh_ip, vn,
2973  sg_list, tag_list, communities, label,
2974  tunnel_bmap, associate,
2975  path,
2976  false) == false)
2977  return false;
2978  ret = BuildAndSendEvpnDom(item, ss_node, route, associate);
2979  }
2980  } else {
2981  if (BuildEvpnUnicastMessage(item, ss_node, route, nh_ip, vn, sg_list,
2982  tag_list, communities, label, tunnel_bmap,
2983  path_preference, associate) == false)
2984  return false;;
2985  ret = BuildAndSendEvpnDom(item, ss_node, route, associate);
2986  }
2987  return ret;
2988 }
2989 
2991  bool add_route) {
2992  static int id = 0;
2993  autogen::McastItemType item;
2994  string repr;
2995  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2996 
2997  if (add_route && (agent_->mulitcast_builder() != this)) {
2999  route->vrf()->GetName(),
3000  "Peer not elected Multicast Tree Builder");
3001  return false;
3002  }
3003 
3004  CONTROLLER_INFO_TRACE(McastSubscribe, GetBgpPeerName(),
3005  route->vrf()->GetName(), " ",
3006  route->ToString());
3007 
3008  //Build the DOM tree
3009  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
3010  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
3011 
3012  item.entry.nlri.af = BgpAf::IPv4;
3013  item.entry.nlri.safi = BgpAf::Mcast;
3014  item.entry.nlri.group = route->GetAddressString();
3015  item.entry.nlri.source = route->GetSourceAddressString();
3016 
3017  autogen::McastNextHopType item_nexthop;
3018  item_nexthop.af = BgpAf::IPv4;
3019  string rtr(agent_->router_id().to_string());
3020  item_nexthop.address = rtr;
3021  item_nexthop.label = GetMcastLabelRange();
3022  item_nexthop.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
3023  item_nexthop.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
3024  item.entry.next_hops.next_hop.push_back(item_nexthop);
3025 
3026  //Build the pugi tree
3027  pugi->AddNode("iq", "");
3028  pugi->AddAttribute("type", "set");
3029  pugi->AddAttribute("from", channel_->FromString());
3030  std::string to(channel_->ToString());
3031  to += "/";
3032  to += XmppInit::kBgpPeer;
3033  pugi->AddAttribute("to", to);
3034 
3035  std::string pubsub_id("pubsub_b");
3036  stringstream str_id;
3037  str_id << id;
3038  pubsub_id += str_id.str();
3039  pugi->AddAttribute("id", pubsub_id);
3040 
3041  pugi->AddChildNode("pubsub", "");
3042  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3043  pugi->AddChildNode("publish", "");
3044  stringstream ss_node;
3045  ss_node << item.entry.nlri.af << "/"
3046  << item.entry.nlri.safi << "/"
3047  << route->vrf()->GetExportName() << "/"
3048  << route->GetAddressString();
3049  std::string node_id(ss_node.str());
3050  pugi->AddAttribute("node", node_id);
3051  pugi->AddChildNode("item", "");
3052 
3053  pugi::xml_node node = pugi->FindNode("item");
3054 
3055  //Call Auto-generated Code to encode the struct
3056  item.Encode(&node);
3057 
3058  pugi->doc().print(*xml_writer, "", pugi::format_default,
3059  pugi::encoding_utf8);
3060  // send data
3061  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3062  repr.clear();
3063 
3064  pugi->DeleteNode("pubsub");
3065  pugi->ReadNode("iq");
3066 
3067  stringstream collection_id;
3068  collection_id << "collection" << id++;
3069  pugi->ModifyAttribute("id", collection_id.str());
3070  pugi->AddChildNode("pubsub", "");
3071  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3072  pugi->AddChildNode("collection", "");
3073 
3074  pugi->AddAttribute("node", route->vrf()->GetName());
3075  if (add_route) {
3076  pugi->AddChildNode("associate", "");
3077  } else {
3078  pugi->AddChildNode("dissociate", "");
3079  }
3080  pugi->AddAttribute("node", node_id);
3081 
3082  pugi->doc().print(*xml_writer, "", pugi::format_default,
3083  pugi::encoding_utf8);
3084  // send data
3085  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3087  return true;
3088 }
3089 
3091  bool associate) {
3092 
3093  if (agent_->params()->mvpn_ipv4_enable()) {
3094  if (agent_->fabric_policy_vrf_name() != route->vrf()->GetName()) {
3095  return ControllerSendMvpnRouteCommon(route, associate);
3096  }
3097  }
3098  return ControllerSendMcastRouteCommon(route, associate);
3099 }
3100 
3102  bool associate) {
3103  static int id = 0;
3104  MvpnItemType item;
3105  string repr;
3106  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
3107 
3108  CONTROLLER_INFO_TRACE(McastSubscribe, GetBgpPeerName(),
3109  route->vrf()->GetName(), " ",
3110  route->ToString());
3111 
3112  //Build the DOM tree
3113  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
3114  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
3115 
3116  item.entry.nlri.af = BgpAf::IPv4;
3117  item.entry.nlri.safi = BgpAf::MVpn;
3118  item.entry.nlri.group = route->GetAddressString();
3119  item.entry.nlri.source = route->GetSourceAddressString();
3120  item.entry.nlri.route_type = 7;
3121 
3122  item.entry.next_hop.af = BgpAf::IPv4;
3123  string rtr(agent_->router_id().to_string());
3124  item.entry.next_hop.address = rtr;
3125  item.entry.next_hop.label = 0;
3126 
3127  //Build the pugi tree
3128  pugi->AddNode("iq", "");
3129  pugi->AddAttribute("type", "set");
3130  pugi->AddAttribute("from", channel_->FromString());
3131  std::string to(channel_->ToString());
3132  to += "/";
3133  to += XmppInit::kBgpPeer;
3134  pugi->AddAttribute("to", to);
3135 
3136  std::string pubsub_id("pubsub_b");
3137  stringstream str_id;
3138  str_id << id;
3139  pubsub_id += str_id.str();
3140  pugi->AddAttribute("id", pubsub_id);
3141 
3142  pugi->AddChildNode("pubsub", "");
3143  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3144  pugi->AddChildNode("publish", "");
3145  stringstream ss_node;
3146  ss_node << item.entry.nlri.af << "/"
3147  << item.entry.nlri.safi << "/"
3148  << route->vrf()->GetExportName() << "/"
3149  << route->GetAddressString();
3150  std::string node_id(ss_node.str());
3151  pugi->AddAttribute("node", node_id);
3152  pugi->AddChildNode("item", "");
3153 
3154  pugi::xml_node node = pugi->FindNode("item");
3155 
3156  //Call Auto-generated Code to encode the struct
3157  item.Encode(&node);
3158 
3159  pugi->doc().print(*xml_writer, "", pugi::format_default,
3160  pugi::encoding_utf8);
3161  // send data
3162  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3163  repr.clear();
3164 
3165  pugi->DeleteNode("pubsub");
3166  pugi->ReadNode("iq");
3167 
3168  stringstream collection_id;
3169  collection_id << "collection" << id++;
3170  pugi->ModifyAttribute("id", collection_id.str());
3171  pugi->AddChildNode("pubsub", "");
3172  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3173  pugi->AddChildNode("collection", "");
3174 
3175  pugi->AddAttribute("node", route->vrf()->GetName());
3176  if (associate) {
3177  pugi->AddChildNode("associate", "");
3178  } else {
3179  pugi->AddChildNode("dissociate", "");
3180  }
3181  pugi->AddAttribute("node", node_id);
3182 
3183  pugi->doc().print(*xml_writer, "", pugi::format_default,
3184  pugi::encoding_utf8);
3185  // send data for BgpAf::Mvpn
3186  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3188  return true;
3189 }
3190 
3192  AgentRoute *route,
3193  const Ip4Address *nh_ip,
3194  std::string vn,
3195  uint32_t label,
3196  uint32_t tunnel_bmap,
3197  const SecurityGroupList *sg_list,
3198  const TagList *tag_list,
3199  const CommunityList *communities,
3200  const std::string &destination,
3201  const std::string &source,
3202  const PathPreference
3203  &path_preference) {
3204  if (!peer) return false;
3205 
3207  route->vrf()->GetName(),
3208  route->ToString(), true, label);
3209  return (peer->ControllerSendEvpnRouteCommon(route,
3210  nh_ip,
3211  vn,
3212  sg_list,
3213  tag_list,
3214  communities,
3215  label,
3216  tunnel_bmap,
3217  destination,
3218  source,
3219  path_preference,
3220  true));
3221 }
3222 
3224  AgentRoute *route,
3225  std::string vn,
3226  uint32_t label,
3227  const std::string &destination,
3228  const std::string &source,
3229  uint32_t tunnel_bmap) {
3230  if (!peer) return false;
3231 
3233  route->vrf()->GetName(),
3234  route->ToString(), false, label);
3235  Ip4Address nh_ip = Ip4Address(0);
3236  return (peer->ControllerSendEvpnRouteCommon(route,
3237  &nh_ip,
3238  vn,
3239  NULL,
3240  NULL,
3241  NULL,
3242  label,
3243  tunnel_bmap,
3244  destination,
3245  source,
3246  PathPreference(),
3247  false));
3248 }
3249 
3251  AgentRoute *route,
3252  const Ip4Address *nexthop_ip,
3253  const VnListType &vn_list,
3254  uint32_t label,
3255  TunnelType::TypeBmap bmap,
3256  const SecurityGroupList *sg_list,
3257  const TagList *tag_list,
3258  const CommunityList *communities,
3260  const PathPreference &path_preference,
3261  const EcmpLoadBalance &ecmp_load_balance,
3262  uint32_t native_vrf_id)
3263 {
3264  if (!peer) return false;
3265 
3267  peer->GetBgpPeerName(),
3268  route->vrf()->GetName(),
3269  route->ToString(),
3270  true, label);
3271  bool ret = false;
3272  if (((type == Agent::INET4_UNICAST) || (type == Agent::INET6_UNICAST)
3273  ||(type == Agent::INET4_MPLS)) &&
3274  (peer->agent()->simulate_evpn_tor() == false)) {
3275  ret = peer->ControllerSendV4V6UnicastRouteCommon(route, vn_list,
3276  sg_list, tag_list, communities, label,
3277  bmap, path_preference, true,
3278  type, ecmp_load_balance, native_vrf_id);
3279  }
3280  if (type == Agent::EVPN) {
3281  std::string vn;
3282  if (vn_list.size())
3283  vn = *vn_list.begin();
3284  ret = peer->ControllerSendEvpnRouteCommon(route, nexthop_ip, vn,
3285  sg_list, tag_list, communities, label,
3286  bmap, "", "",
3287  path_preference, true);
3288  }
3289  return ret;
3290 }
3291 
3293  AgentRoute *route,
3294  const VnListType &vn_list,
3295  uint32_t label,
3296  TunnelType::TypeBmap bmap,
3297  const SecurityGroupList *sg_list,
3298  const TagList *tag_list,
3299  const CommunityList *communities,
3301  const PathPreference
3302  &path_preference)
3303 {
3304  if (!peer) return false;
3305 
3307  peer->GetBgpPeerName(),
3308  route->vrf()->GetName(),
3309  route->ToString(),
3310  false, 0);
3311  bool ret = false;
3312  if (((type == Agent::INET4_UNICAST) || (type == Agent::INET6_UNICAST)) &&
3313  (peer->agent()->simulate_evpn_tor() == false)) {
3314  EcmpLoadBalance ecmp_load_balance;
3315  ret = peer->ControllerSendV4V6UnicastRouteCommon(route, vn_list,
3316  sg_list, tag_list, communities,
3317  label,
3318  bmap,
3319  path_preference,
3320  false,
3321  type,
3322  ecmp_load_balance,
3324  }
3325  if (type == Agent::EVPN) {
3326  Ip4Address nh_ip(0);
3327  std::string vn;
3328  if (vn_list.size())
3329  vn = *vn_list.begin();
3330  ret = peer->ControllerSendEvpnRouteCommon(route, &nh_ip,
3331  vn, NULL, NULL, NULL,
3332  label, bmap, "", "",
3333  path_preference, false);
3334  }
3335  return ret;
3336 }
3337 
3339  AgentRoute *route) {
3340  if (!peer) return false;
3341 
3343  route->vrf()->GetName(),
3344  route->ToString(), true, 0);
3345 
3346  if (route->GetTableType() == Agent::INET4_MULTICAST) {
3347  return peer->ControllerSendIPMcastRouteCommon(route, true);
3348  }
3349 
3350  return peer->ControllerSendMcastRouteCommon(route, true);
3351 }
3352 
3354  AgentRoute *route) {
3355  if (!peer) return false;
3356 
3358  route->vrf()->GetName(),
3359  route->ToString(), false, 0);
3360 
3361  if (route->GetTableType() == Agent::INET4_MULTICAST) {
3362  return peer->ControllerSendIPMcastRouteCommon(route, false);
3363  }
3364 
3365  return peer->ControllerSendMcastRouteCommon(route, false);
3366 }
3367 
3370  bgp_peer_id()->DeleteStale();
3372  if (agent()->mulitcast_builder() == this) {
3374  controller()->multicast_sequence_number());
3375  }
3376 }
3377 
3379  //This is a callback from walker for bgp peer.
3380  //It may happen that channel went down and stop of this walk was executed.
3381  //However stop of the walk is enqueued and by that time, walk done for
3382  //previously started walk for this peer gets executed.
3383  //This can result in channel_ being NULL on walk done call.
3384  if (channel_ == NULL) {
3385  return;
3386  }
3387 
3388  string msg;
3389  msg += "\n<message from=\"";
3390  msg += channel_->FromString();
3391  msg += "\" to=\"";
3392  msg += channel_->ToString();
3393  msg += "/";
3394  msg += XmppInit::kBgpPeer;
3395  msg += "\">";
3396  msg += "\n\t<event xmlns=\"http://jabber.org/protocol/pubsub\">";
3397  msg = (msg + "\n<items node=\"") + XmppInit::kEndOfRibMarker +
3398  "\"></items>";
3399  msg += "\n\t</event>\n</message>\n";
3400 
3401  if (channel_->connection()) {
3402  channel_->connection()->Send((const uint8_t *) msg.data(), msg.size());
3404  }
3405 }
3406 
3408 
3409  if (agent_->connection_state() == NULL)
3410  return;
3411 
3412  boost::asio::ip::tcp::endpoint ep;
3413  boost::system::error_code ec;
3414  string last_state_name;
3415  ep.address(AddressFromString(
3417  uint16_t port = agent_->controller_ifmap_xmpp_port(xs_idx_);
3418  ep.port(port);
3419  const string name = agent_->xmpp_control_node_prefix() +
3420  ep.address().to_string();
3421  XmppChannel *xc = GetXmppChannel();
3422  if (xc) {
3423  last_state_name = xc->LastStateName();
3424  }
3425  if (state == xmps::READY) {
3426  agent_->connection_state()->Update(ConnectionType::XMPP, name,
3427  ConnectionStatus::UP, ep,
3428  last_state_name);
3429  } else {
3430  agent_->connection_state()->Update(ConnectionType::XMPP, name,
3431  ConnectionStatus::DOWN, ep,
3432  last_state_name);
3433  }
3434 }
3435 
3437  if (bgp_peer_id()) {
3439  boost::bind(&AgentXmppChannel::EndOfRibTx, this));
3440  }
3441 }
3442 
3444  if (bgp_peer_id()) {
3446  }
3447 }
3448 
3449 template <typename TYPE>
3450 void AgentXmppChannel::BuildTagList(const TYPE *item,
3451  TagList *tag_list) {
3452  *tag_list = item->entry.next_hops.next_hop[0].tag_list.tag;
3453  std::sort(tag_list->begin(), tag_list->end());
3454 }
MulticastHandler * multicast() const
Definition: operdb_init.h:53
AgentIfMapVmExport * agent_ifmap_vm_export() const
void StopDeleteStale()
Definition: peer.cc:235
IFMapAgentParser * ifmap_parser() const
Definition: agent.h:1172
void AddType5Route(const Peer *peer, const std::string &vrf_name, const IpAddress &ip_addr, uint32_t ethernet_tag, EvpnRoutingData *data, uint8_t plen=0)
uint8_t prefix_length() const
!
virtual const XmppConnection * connection() const =0
uint32_t TypeBmap
Definition: nexthop.h:248
AgentPath * FindLocalVmPortPath() const
Definition: agent_route.cc:742
pugi::xml_node FindNode(const std::string &name)
Definition: xml_pugi.cc:51
const Interface * GetInterface() const
Definition: nexthop.h:1293
static void DeleteMplsRouteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
void ModifyMvpnVrfRegistration(const Peer *peer, const std::string &vrf_name, const Ip4Address &group, const Ip4Address &source, uint64_t peer_identifier)
Definition: multicast.cc:1348
XmppChannel * GetXmppChannel()
Type type() const
Definition: interface.h:112
XmppMessageType type
Definition: xmpp_proto.h:57
bool BuildAndSendEvpnDom(autogen::EnetItemType &item, std::stringstream &ss_node, const AgentRoute *route, bool associate)
bool tsn_enabled() const
Definition: agent.h:1162
virtual std::string ToString() const
const Peer * local_vm_export_peer() const
Definition: agent.h:1040
void AddRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item)
uint64_t end_of_rib_tx_time_
Definition: vrf.h:86
void incr_xmpp_reconnects(uint8_t idx)
Definition: agent_stats.h:58
boost::system::error_code Ip4PrefixParse(const string &str, Ip4Address *addr, int *plen)
Definition: address.cc:107
InetUnicastRouteEntry * FindLPM(const IpAddress &ip)
const uint16_t controller_ifmap_xmpp_port(uint8_t idx) const
Definition: agent.h:757
void AddLocalVmRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, LocalVmRoute *data)
VrfEntry * fabric_vrf() const
Definition: agent.h:915
const std::string & source_ip_str() const
bool tor_agent_enabled() const
Definition: agent.h:1164
uint64_t last_route_published_time_
virtual void RegisterReceive(xmps::PeerId, ReceiveCb)=0
virtual const std::string GetAddressString() const =0
AgentXmppChannel * mulitcast_builder()
Definition: agent.h:895
VrfEntry * FindVrfFromName(const string &name)
Definition: vrf.cc:873
void DeleteStale()
Definition: peer.cc:224
std::string GetMcastLabelRange()
AgentRouteTable * GetEvpnRouteTable(const std::string &vrf_name)
Definition: vrf.cc:913
virtual void Start(AgentXmppChannel *agent_xmpp_channel)
bool FlushPeerInfo(uint64_t peer_sequence)
Definition: multicast.cc:1408
TunnelType::Type tunnel_type() const
Definition: agent_path.h:266
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 ReceiveInet4MplsUpdate(XmlPugi *pugi)
void AddClonedLocalPathReq(const Peer *peer, const string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t ethernet_tag, ClonedLocalPath *data)
const Ip4Address & dest_ip_addr() const
uint32_t preference() const
Definition: agent_path.h:41
static XmlBase * AllocXmppXmlImpl(const char *doc=NULL)
Definition: xmpp_proto.h:167
const Interface * vhost_interface() const
Definition: agent.h:935
const std::string & intf_route_type() const
Definition: agent_route.h:277
void GetVnList(const TYPE &nexthops, VnListType *vn_list)
uint32_t vhost_prefix_len() const
Definition: agent.h:653
bool IsEcmp(const TYPE &nexthops)
static void GetEcmpHashFieldsToUse(TYPE *item, EcmpLoadBalance &ecmp_load_balance)
const NextHop * nexthop() const
Definition: mpls.h:80
bool simulate_evpn_tor() const
Definition: agent.h:1155
void ReceiveInternal(const XmppStanza::XmppMessage *msg)
static int ParseEvpnAddress(const string &str, IpAddress *addr, const MacAddress &mac)
boost::asio::ip::address IpAddress
Definition: address.h:13
static void DeleteReq(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t plen, uint32_t ethernet_tag, AgentRouteData *data)
static bool ControllerSendRouteAdd(AgentXmppChannel *peer, AgentRoute *route, const Ip4Address *nexthop_ip, const VnListType &vn_list, uint32_t label, uint32_t tunnel_bmap, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, Agent::RouteTableType type, const PathPreference &path_preference, const EcmpLoadBalance &ecmp_load_balance, uint32_t native_vrf_id)
EndOfRibTxTimer * end_of_rib_tx_timer()
InetUnicastAgentRouteTable * PrefixToRouteMplsTable(const std::string &vrf_name, const IpAddress &prefix_addr)
void AddMplsRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item)
std::vector< int > SecurityGroupList
Definition: agent.h:201
EndOfRibRxTimer * end_of_rib_rx_timer()
AgentStats * stats() const
Definition: agent.cc:881
static const uint32_t kInvalidExportLabel
Definition: mpls.h:102
int ListenerId
Definition: db_table.h:62
bool is_multicast() const
Definition: agent_route.h:274
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
void AddRemoteMplsRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item, const VnListType &vn_list)
void set_ifmap_active_xmpp_server(const std::string &addr, uint8_t xs_idx)
Definition: agent.h:782
void set_controller_xmpp_channel_setup_time(uint64_t time, uint8_t idx)
Definition: agent.h:804
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
static const uint64_t kInvalidPeerIdentifier
boost::uuids::uuid uuid
static TypeBmap MplsType()
Definition: nexthop.h:312
InetUnicastAgentRouteTable * GetInet4MplsUnicastRouteTable() const
Definition: vrf.cc:323
const pugi::xml_document & doc()
Definition: xml_pugi.h:68
void UpdateConnectionInfo(xmps::PeerState state)
const std::string & GetExportName()
Definition: vrf.h:121
boost::scoped_ptr< EndOfRibRxTimer > end_of_rib_rx_timer_
bool ControllerSendMvpnRouteCommon(AgentRoute *route, bool associate)
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable() const
Definition: vrf.cc:338
const string & GetName() const
Definition: vrf.h:100
static void GetMulticastMacFromIp(const Ip4Address &ip, MacAddress &mac)
Definition: multicast.h:483
const MacAddress & mac() const
Definition: interface.h:131
boost::scoped_ptr< LlgrStaleTimer > llgr_stale_timer_
AddressList vhost_default_gateway() const
Definition: agent.h:656
static bool ControllerSendVmCfgSubscribe(AgentXmppChannel *peer, const boost::uuids::uuid &vm_id, bool subscribe)
uint16_t GetVlanTag() const
Definition: nexthop.h:1544
A structure to hold path parameters during the transfer (routes leaking) of data between VRF instance...
AgentXmppChannel * controller_xmpp_channel(uint8_t idx) const
Definition: agent.h:809
MplsTable * mpls_table() const
Definition: agent.h:510
static void SetMulticastPeer(AgentXmppChannel *old_peer, AgentXmppChannel *new_peer)
VxlanRoutingManager * vxlan_routing_manager() const
Definition: operdb_init.h:98
void Enqueue(ControllerWorkQueueDataType data)
uint64_t multicast_sequence_number()
Type GetType() const
Definition: nexthop.h:405
Base class for all Route entries in agent.
Definition: agent_route.h:224
static bool ControllerSendMcastRouteAdd(AgentXmppChannel *peer, AgentRoute *route)
static void HandleAgentXmppClientChannelEvent(AgentXmppChannel *peer, xmps::PeerState state)
virtual xmps::PeerState GetPeerState() const =0
Ip4Address vhost_prefix() const
Definition: agent.h:648
static const char * kFqnPrependAgentNodeJID
Definition: xmpp_init.h:28
OperDB * oper_db() const
Definition: agent.cc:1013
virtual const std::string GetSourceAddressString() const =0
std::string ToString() const
Definition: mac_address.cc:53
uint32_t ethernet_tag() const
static TypeBmap MplsoMplsType()
Definition: nexthop.h:313
AgentIfMapXmppChannel * ifmap_xmpp_channel(uint8_t idx) const
Definition: agent.h:792
EndOfConfigTimer * end_of_config_timer()
virtual int AddAttribute(const std::string &key, const std::string &value)
Definition: xml_pugi.cc:282
void InetRequestDelete(const IpAddress &ip_address, const int prefix_len, std::string vrf_name, const Peer *bgp_peer)
AgentRoute * FindActiveEntry(const AgentRouteKey *key)
Definition: agent_route.cc:417
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
void GetStringVector(std::vector< std::string > &string_vector) const
const AgentPath * FindOvsPath() const
const std::string & fabric_vrf_name() const
Definition: agent.h:903
void ReceiveBgpMessage(std::unique_ptr< XmlBase > impl)
void AddClonedLocalPathReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, ClonedLocalPath *data)
NextHop * nexthop() const
Definition: agent_path.cc:87
uint8_t GetFlags() const
Definition: nexthop.h:1300
bool mvpn_ipv4_enable() const
Definition: agent_param.h:565
ControllerEcmpRoute * BuildEcmpData(TYPE *item, const VnListType &vn_list, const EcmpLoadBalance &ecmp_load_balance, const AgentRouteTable *rt_table, const std::string &prefix_str)
virtual Agent::RouteTableType GetTableType() const =0
virtual void ReceiveV4V6Update(XmlPugi *pugi)
bool ControllerSendV4V6UnicastRouteCommon(AgentRoute *route, const VnListType &vn_list, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, uint32_t mpls_label, uint32_t tunnel_bmap, const PathPreference &path_preference, bool associate, Agent::RouteTableType type, const EcmpLoadBalance &ecmp_load_balance, uint32_t native_vrf_id)
void StopPeerNotifyRoutes()
Definition: peer.cc:155
virtual int AddChildNode(const std::string &key, const std::string &value)
Definition: xml_pugi.cc:250
virtual bool Send(const uint8_t *, size_t, xmps::PeerId, SendReadyCb)=0
VrfEntry * vrf_entry() const
Definition: agent_route.cc:459
bool Send(const uint8_t *data, size_t size, const std::string *msg_str=NULL)
static bool FillEvpnOlist(Agent *agent, EnetOlistType &olist, TunnelOlist *tunnel_olist)
static bool IsRoutingVrf(const VrfEntry *vrf)
Determines whether the pointer to the VRF instance is of routing type.
std::unique_ptr< XmlBase > dom
Definition: xmpp_proto.h:62
bool IsZero() const
Definition: mac_address.cc:29
bool IsNull(pugi::xml_node &node)
Definition: xml_pugi.h:63
static const uint32_t kInvalidvxlan_id
Definition: vxlan.h:141
void AddInetEcmpRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item, const VnListType &vn_list)
uint8_t type
Definition: load_balance.h:109
static ControllerVmRoute * MakeControllerVmRoute(const BgpPeer *peer, const string &default_vrf, const Ip4Address &router_id, const string &vrf_name, const Ip4Address &tunnel_dest, TunnelType::TypeBmap bmap, uint32_t label, MacAddress rewrite_dmac, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list, const PathPreference &path_preference, bool ecmp_suppressed, const EcmpLoadBalance &ecmp_load_balance, bool etree_leaf)
void AddVhostMplsRoute(const IpAddress &vhost_addr, const Peer *peer)
TunnelType::TypeBmap GetTypeBitmap(const autogen::EnetTunnelEncapsulationListType &encap)
const std::string & source_port_str() const
static const char * kEndOfRibMarker
Definition: xmpp_init.h:26
Definition: agent.h:358
static bool IsXmppChannelActive(const Agent *agent, AgentXmppChannel *peer)
bool AllSet() const
void NotifyAll(AgentXmppChannel *peer)
bool IsMulticast() const
Definition: mac_address.cc:37
Definition: vrf.h:22
LlgrStaleTimer * llgr_stale_timer()
void PeerNotifyRoutes(WalkDoneCb cb)
Definition: peer.cc:149
uint64_t sequence_number() const
uint32_t label() const
Definition: agent_path.h:264
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
Ip4Address router_id() const
Definition: agent.h:666
VNController * controller() const
Definition: agent.cc:981
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
void AddLocalVmRouteReq(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t ethernet_tag, LocalVmRoute *data)
bool vxlan_routing_vn() const
Definition: vn.h:255
static void AddMplsRouteReq(const Peer *peer, const string &vrf_name, const IpAddress &dst_addr, uint8_t plen, AgentRouteData *data)
uint32_t loc_sequence() const
Definition: agent_path.h:39
bool ControllerSendMcastRouteCommon(AgentRoute *route, bool associate)
Definition: trace.h:220
void LoadXmlDoc(const pugi::xml_document &doc)
Definition: xml_pugi.h:67
const Peer * multicast_peer() const
Definition: agent.h:1030
virtual int ModifyAttribute(const std::string &key, const std::string &value)
Definition: xml_pugi.cc:315
const Peer * local_peer() const
Definition: agent.h:1022
virtual void ReceiveMvpnUpdate(XmlPugi *pugi)
AgentXmppChannel(Agent *agent, const std::string &xmpp_server, const std::string &label_range, uint8_t xs_idx)
ClonedLocalPathList & cloned_local_path_list()
static const MacAddress & BroadcastMac()
Definition: mac_address.h:152
static void CleanConfigStale(AgentXmppChannel *agent_xmpp_channel)
virtual const std::string & ToString() const =0
bool etree_leaf() const
Definition: agent_path.h:388
void AddControllerReceiveRouteReq(const Peer *peer, const std::string &vrf_name, uint32_t label, const MacAddress &mac, const IpAddress &ip_addr, uint32_t ethernet_tag, const std::string &vn_name, const PathPreference &pref, uint64_t sequence_number)
std::vector< std::string > CommunityList
Definition: bgp_config.h:347
virtual void UnRegisterReceive(xmps::PeerId)=0
uint8_t GetXmppServerIdx()
std::vector< Ip4Address > AddressList
Definition: agent.h:217
static void XmppClientChannelEvent(AgentXmppChannel *peer, xmps::PeerState state)
InetUnicastAgentRouteTable * PrefixToRouteTable(const std::string &vrf_name, const IpAddress &prefix_addr)
virtual std::string LastStateName() const =0
AgentParam * params() const
Definition: agent.h:1218
void incr_sequence_number()
Definition: peer.h:95
bool ControllerSendIPMcastRouteCommon(AgentRoute *route, bool associate)
virtual const char * ReadAttrib(const std::string &str)
Definition: xml_pugi.cc:114
const std::string & controller_ifmap_xmpp_server(uint8_t idx) const
Definition: agent.h:730
std::vector< string > & GetControllerlist()
Definition: agent.h:692
Definition: peer.h:44
static bool ControllerSendCfgSubscribe(AgentXmppChannel *peer)
virtual const char * ReadNode(const std::string &name)
Definition: xml_pugi.cc:28
std::set< std::string > VnListType
Definition: agent.h:212
static void DeleteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
virtual const std::string & FromString() const =0
static TypeBmap NativeType()
Definition: nexthop.h:325
static const std::string LoadBalanceDecision
const MacAddress & mac() const
static Type ComputeType(TypeBmap bmap)
Definition: nexthop.cc:33
static TypeBmap UDPType()
Definition: nexthop.h:324
#define CONTROLLER_TX_CONFIG_TRACE(obj, index,...)
virtual void ReceiveUpdate(const XmppStanza::XmppMessage *msg)
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:375
virtual int AddNode(const std::string &key, const std::string &value)
Definition: xml_pugi.cc:212
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
uint32_t isid() const
Definition: vrf.h:197
virtual void Start(AgentXmppChannel *agent_xmpp_channel)
Definition: vn.h:151
uint32_t GetActiveLabel() const
Definition: agent_path.cc:79
#define MAX_XMPP_SERVERS
Definition: agent.h:291
static const uint32_t kInvalidLabel
Definition: mpls.h:101
const AgentPath * FindIntfOrCompLocalVmPortPath() const
Finds path to an interface or a composite of interfaces and returns it. The priority is given to comp...
Definition: agent_route.cc:816
VrfTable * vrf_table() const
Definition: agent.h:485
AgentPath * GetLocalVmPortPath() const
Definition: agent_route.cc:844
std::string GetXmppServer()
const std::string & destination_port_str() const
virtual ~AgentXmppChannel()
void AddVlanNHRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, VlanNhRoute *data)
uint32_t GetEvpnMulticastSGFlags(const std::string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1986
void AddFabricVrfRoute(const Ip4Address &prefix_addr, uint32_t prefix_len, const Ip4Address &addr, const VnListType &vn_list, const SecurityGroupList &sg_list, const TagList &tag_list)
void AddEvpnRoute(const std::string &vrf_name, std::string mac_addr, const IpAddress &ip, uint32_t plen, autogen::EnetItemType *item)
const std::string & destination_ip_str() const
bool routing_vrf() const
Definition: vrf.h:223
bool BuildEvpnUnicastMessage(autogen::EnetItemType &item, std::stringstream &node_id, AgentRoute *route, const Ip4Address *nh_ip, const std::string &vn, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, uint32_t label, uint32_t tunnel_bmap, const PathPreference &path_prefernce, bool associate)
IpAddress AddressFromString(const std::string &ip_address_str, boost::system::error_code *ec)
boost::scoped_ptr< EndOfRibTxTimer > end_of_rib_tx_timer_
const std::string & ip_protocol_str() const
uint8_t prefix_length() const
!
const Peer * multicast_tree_builder_peer() const
Definition: agent.h:1032
virtual std::string ToString() const =0
static ControllerMplsRoute * MakeControllerMplsRoute(const BgpPeer *peer, const string &default_vrf, const Ip4Address &router_id, const string &vrf_name, const Ip4Address &tunnel_dest, TunnelType::TypeBmap bmap, uint32_t label, MacAddress rewrite_dmac, const VnListType &dest_vn_list, const SecurityGroupList &sg_list, const TagList &tag_list, const PathPreference &path_preference, bool ecmp_suppressed, const EcmpLoadBalance &ecmp_load_balance, bool etree_leaf)
void FlushTimedOutChannels(uint8_t index)
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13
uint32_t vxlan_id() const
Definition: vrf.h:165
ClonedLocalPathList::iterator ClonedLocalPathListIter
static TypeBmap GREType()
Definition: nexthop.h:323
void AddEvpnEcmpRoute(std::string vrf_name, const MacAddress &mac, const IpAddress &ip, uint32_t plen, autogen::EnetItemType *item, const VnListType &vn_list)
void set_cn_mcast_builder(AgentXmppChannel *peer)
Definition: agent.cc:579
uint64_t end_of_rib_rx_time_
boost::system::error_code Inet6PrefixParse(const string &str, Ip6Address *addr, int *plen)
Definition: address.cc:144
void AddMulticastEvpnRoute(const std::string &vrf_name, const IpAddress &source, const IpAddress &group, autogen::EnetItemType *item)
static int compare(const Type &lhs, const Type &rhs)
Definition: mpls.h:52
virtual int DeleteNode(const std::string &key)
Definition: xml_pugi.cc:228
bool BuildTorMulticastMessage(autogen::EnetItemType &item, std::stringstream &node_id, AgentRoute *route, const Ip4Address *nh_ip, const std::string &vn, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, uint32_t label, uint32_t tunnel_bmap, const std::string &destination, const std::string &source, bool associate)
static bool ControllerSendRouteDelete(AgentXmppChannel *peer, AgentRoute *route, const VnListType &vn_list, uint32_t label, uint32_t tunnel_bmap, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, Agent::RouteTableType type, const PathPreference &path_preference)
VnEntry * vn() const
Definition: vrf.h:101
static void AddGatewayRoute(const Peer *peer, const string &vrf_name, const Ip4Address &dst_addr, uint8_t plen, const AddressList &gw_list, const VnListType &vn_name, uint32_t label, const SecurityGroupList &sg_list, const TagList &tag_list, const CommunityList &communities, bool native_encap)
void RegisterXmppChannel(XmppChannel *channel)
void BuildTagList(const TYPE *item, TagList *tag_list)
static bool IsVxlanAvailable(const Agent *agent)
Checks whether VxLAN routing manager is enabled or not.
static const std::string & xmpp_control_node_prefix()
Definition: agent.h:447
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:730
XmppChannel * channel_
void XmppAdvertiseEvpnRoute(const IpAddress &prefix_ip, const int prefix_len, uint32_t vxlan_id, const std::string vrf_name, const RouteParameters &params, const Peer *bgp_peer)
Advertises an EVPN route received using XMPP channel.
void AddInetInterfaceRouteReq(const Peer *peer, const string &vm_vrf, const Ip4Address &addr, uint8_t plen, InetInterfaceRoute *data)
static const uint32_t kInvalidIndex
Definition: vrf.h:88
#define LOG(_Level, _Msg)
Definition: logging.h:33
VrfEntry * vrf() const
Definition: agent_route.h:275
MplsLabel * FindMplsLabel(uint32_t label)
Definition: mpls.cc:399
static const char * kConfigPeer
Definition: xmpp_init.h:23
const std::string & name() const
Definition: interface.h:114
const Peer * local_vm_peer() const
Definition: agent.h:1023
void ModifyFabricMembers(const Peer *peer, const std::string &vrf_name, const Ip4Address &group, const Ip4Address &source, uint32_t source_label, const TunnelOlist &olist, uint64_t peer_identifier=0)
Definition: multicast.cc:1174
virtual void UnRegisterWriteReady(xmps::PeerId id)=0
static bool ControllerSendMcastRouteDelete(AgentXmppChannel *peer, AgentRoute *route)
BgpPeer * bgp_peer_id()
int rd() const
Definition: vrf.h:220
virtual void ReceiveMulticastUpdate(XmlPugi *pugi)
#define CONTROLLER_INFO_TRACE(obj,...)
static bool SetConfigPeer(AgentXmppChannel *peer)
static MulticastHandler * GetInstance()
Definition: multicast.h:369
void incr_xmpp_in_msgs(uint8_t idx)
Definition: agent_stats.h:63
RouteTableType
Definition: agent.h:415
static bool ControllerSendEvpnRouteAdd(AgentXmppChannel *peer, AgentRoute *route, const Ip4Address *nexthop_ip, std::string vn, uint32_t mpls_label, uint32_t tunnel_bmap, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, const std::string &destination, const std::string &source, const PathPreference &path_preference)
static void Notify(const Agent *agent, AgentXmppChannel *, DBTablePartBase *partition, DBEntryBase *e)
static XmppXmlImplFactory * Instance()
Definition: xml_base.cc:18
virtual AgentPath * FindPath(const Peer *peer) const
Definition: agent_route.cc:864
std::string channel_str_
VnEntry * si_vn_ref() const
Definition: vrf.h:102
bool BuildEvpnMulticastMessage(autogen::EnetItemType &item, std::stringstream &node_id, AgentRoute *route, const Ip4Address *nh_ip, const std::string &vn, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, uint32_t label, uint32_t tunnel_bmap, bool associate, const AgentPath *path, bool assisted_replication)
std::vector< OlistTunnelEntry > TunnelOlist
Definition: multicast.h:68
virtual void ReceiveEvpnUpdate(XmlPugi *pugi)
static void AddRemoteVmRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &vm_addr, uint8_t plen, AgentRouteData *data)
Agent * agent() const
void increment_multicast_sequence_number()
void AddInetMplsEcmpRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item, const VnListType &vn_list)
virtual void WriteReadyCb(const boost::system::error_code &ec)
process::ConnectionState * connection_state() const
Definition: agent.h:953
GlobalSystemConfig * global_system_config() const
Definition: operdb_init.h:85
static const Peer * routing_vrf_vxlan_bgp_peer_
A pointer to the Peer where all BGP routes are stored.
InetUnicastRouteEntry * FindResolveRoute(const Ip4Address &ip)
uint32_t sequence() const
Definition: agent_path.h:40
static uint64_t NewSeqNumber()
static TypeBmap VxlanType()
Definition: nexthop.h:311
static const char * kBgpPeer
Definition: xmpp_init.h:24
#define CONTROLLER_TRACE(obj,...)
uint32_t vxlan_id() const
Definition: agent_path.h:265
void ReConnectXmppServer()
static bool ControllerSendSubscribe(AgentXmppChannel *peer, VrfEntry *vrf, bool subscribe)
virtual bool SendUpdate(const uint8_t *msg, size_t msgsize)
const int8_t & ifmap_active_xmpp_server_index() const
Definition: agent.h:780
static bool ControllerSendEvpnRouteDelete(AgentXmppChannel *peer, AgentRoute *route, std::string vn, uint32_t mpls_label, const std::string &destination, const std::string &source, uint32_t tunnel_bmap)
bool ControllerSendEvpnRouteCommon(AgentRoute *route, const Ip4Address *nexthop_ip, std::string vn, const SecurityGroupList *sg_list, const TagList *tag_list, const CommunityList *communities, uint32_t mpls_label, uint32_t tunnel_bmap, const std::string &destination, const std::string &source, const PathPreference &path_preference, bool associate)
void StopRouteExports()
Definition: peer.h:137
void reset_ifmap_active_xmpp_server()
Definition: agent.h:787
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:1698
const std::string & ifmap_active_xmpp_server() const
Definition: agent.h:781
static bool IsBgpPeerActive(const Agent *agent, AgentXmppChannel *peer)
std::vector< int > TagList
Definition: agent.h:202
ConfigCleanupTimer * config_cleanup_timer()
std::string GetBgpPeerName() const
static void AddRemoteVmRouteReq(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t plen, uint32_t ethernet_tag, AgentRouteData *data)
void PopulateEcmpHashFieldsToUse(ItemType &item, const EcmpLoadBalance &ecmp_load_balance)
void incr_xmpp_out_msgs(uint8_t idx)
Definition: agent_stats.h:66
const std::string & fabric_policy_vrf_name() const
Definition: agent.h:908
const Ip4Address & src_ip_addr() const
void AddRemoteRoute(std::string vrf_name, IpAddress prefix_addr, uint32_t prefix_len, autogen::ItemType *item, const VnListType &vn_list)