OpenSDN source code
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();
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) {
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) {
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);
1229  std::vector<std::string> peer_sources;
1230  for (const auto &peer_addr : item->entry.peers.peer) {
1231  peer_sources.push_back(peer_addr);
1232  }
1234  ip_addr,
1235  plen,
1236  label, // vrf->vxlan_id(), // VxLAN ID
1237  vrf_name,
1238  RouteParameters(nh_ip,
1239  MacAddress(item->entry.next_hops.next_hop[0].mac),
1240  vn_list,
1241  item->entry.security_group_list.security_group,
1242  CommunityList(),
1243  tag_list,
1244  path_preference,
1245  ecmp_load_balance,
1246  sequence_number()),
1247  bgp_peer_id(),
1248  peer_sources);
1249  return;
1250  }
1251 
1252  if (agent_->router_id() != nh_ip.to_v4()) {
1253  CONTROLLER_INFO_TRACE(Trace, GetBgpPeerName(), nexthop_addr,
1254  "add remote evpn route");
1255  VnListType vn_list;
1256  vn_list.insert(item->entry.virtual_network);
1257  // for number of nexthops more than 1, carry flag ecmp suppressed
1258  // to indicate the same to all modules, till we handle L2 ecmp
1259  ControllerVmRoute *data =
1262  agent_->router_id(),
1263  vrf_name, nh_ip.to_v4(),
1264  encap, label,
1265  MacAddress(item->entry.next_hops.next_hop[0].mac),
1266  vn_list,
1267  item->entry.security_group_list.security_group,
1268  tag_list,
1269  path_preference,
1270  (item->entry.next_hops.next_hop.size() > 1),
1271  EcmpLoadBalance(),
1272  item->entry.etree_leaf);
1273  rt_table->AddRemoteVmRouteReq(bgp_peer_id(), vrf_name, mac, ip_addr,
1274  plen, item->entry.nlri.ethernet_tag, data);
1275  return;
1276  }
1277 
1278  // In EVPN VNF service chaining, control-node sends the route originated
1279  // by us for the routing-vrf in the service-chain vrf as well.
1280  // When encapsulation used is VXLAN, nexthop cannot be found from the
1281  // message. Since EVPN Type5 local-route is not available in the
1282  // serivce-chain vrf evpn table, set the next-hop for the local route
1283  // (in the serice-chain's vrf) to primary-routing-vrf to have the common
1284  // design for the EVPN Type5.
1285 
1286  // Checking if the vrf received is service-chain vrf that belongs to
1287  // Vxlan routing VN (service-chaining between LRs).
1288  if (si_ref_vn && (si_ref_vn->vxlan_routing_vn() == true)) {
1289  // Vxlan routing VN (service-chaining between LRs). Local EVPN routes
1290  // for service-chain VRF's will be allowed for the service-chain between
1291  // Internal-VN (IVN) of the Vxlan Logiical Router (LR).
1292 
1293  // service-chain vrf will have si_vn_ref set to primary vrf,
1294  // in EVPN VNF service chaining, this vrf is to routing vrf
1295  VrfEntry *routing_vrf = si_ref_vn->GetVrf();
1296  assert(routing_vrf != vrf);
1297 
1298  // service instance vrf received, adding evpn type5 route for
1299  // that have local path
1300  if (!(routing_vrf->vn() && routing_vrf->vn()->vxlan_routing_vn())) {
1301  // primary vrf is not a routing vrf
1302  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1303  "Not a Routing VRF. Ignoring route");
1304  return;
1305  }
1306 
1307  // getting the local export path from the routing vrf
1308  EvpnAgentRouteTable *evpn_rt_table =
1309  static_cast<EvpnAgentRouteTable *>
1310  (agent_->vrf_table()->GetEvpnRouteTable(routing_vrf->GetName()));
1311  if (evpn_rt_table == NULL || evpn_rt_table->vrf_entry() == NULL) {
1312  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1313  "Invalid Routing VRF. Ignoring route");
1314  return;
1315  }
1316 
1318  routing_vrf->GetName(), MacAddress(), ip_addr,
1319  plen, 0); // Ethernet tag is zero in Type5
1320  const EvpnRouteEntry *evpn_rt = static_cast<EvpnRouteEntry *>
1321  (evpn_rt_table->FindActiveEntry(&rt_key));
1322  if (evpn_rt == NULL) {
1324  "Local EVPN route not found, ignoring request");
1325  return;
1326  }
1327 
1328  // Local port available, Add EVPN type5 route to service-chain vrf
1329  VnListType vn_list;
1330  vn_list.insert(item->entry.virtual_network);
1331 
1333  nh_req.key.reset(new VrfNHKey(routing_vrf->GetName(), false, false));
1334  nh_req.data.reset(new VrfNHData(false, false, false));
1335 
1336  EvpnRoutingData *data = new EvpnRoutingData(nh_req,
1337  item->entry.security_group_list.security_group,
1338  CommunityList(),
1339  path_preference,
1340  EcmpLoadBalance(),
1341  tag_list,
1342  routing_vrf,
1343  routing_vrf->vxlan_id(), vn_list);
1344 
1345  // adding local type5 route to service-chain vrf
1346  rt_table->AddType5Route(bgp_peer_id(),
1347  vrf_name,
1348  ip_addr,
1349  0, // item->entry.nlri.ethernet_tag, is 0
1350  data);
1351 
1352  return;
1353  }
1354 
1355 
1356  // Route originated by us and reflected back by control-node
1357  // When encap is MPLS based, the nexthop can be found by label lookup
1358  // When encapsulation used is VXLAN, nexthop cannot be found from message
1359  // To have common design, get nexthop from the route already present.
1360  // VxLAN routes destined to a Routing VRF instance are handled
1361  // above
1362 
1363  EvpnRouteKey key(agent_->local_vm_peer(), vrf_name, mac,
1364  ip_addr, plen, item->entry.nlri.ethernet_tag);
1365  EvpnRouteEntry *route = static_cast<EvpnRouteEntry *>
1366  (rt_table->FindActiveEntry(&key));
1367  if (route == NULL) {
1369  "route not found, ignoring request");
1370  return;
1371  }
1372 
1373  AgentPath *local_path = route->FindLocalVmPortPath();
1374  const NextHop *nh = local_path ? local_path->nexthop() : NULL;
1375  if (nh == NULL) {
1377  "nexthop not found, ignoring request");
1378  return;
1379  }
1380 
1381  //In EVPN, if interface IP is not same as IP received in Evpn route
1382  //then use receive NH. This is done because this received evpn ip is
1383  //a floating IP associated with VM and it shoul be routed.
1384  if (nh->GetType() == NextHop::L2_RECEIVE) {
1385  rt_table->AddControllerReceiveRouteReq(bgp_peer_id(), vrf_name,
1386  label, mac, ip_addr,
1387  item->entry.nlri.ethernet_tag,
1388  item->entry.virtual_network,
1389  path_preference, sequence_number());
1390  return;
1391  }
1392 
1393  // We expect only INTERFACE nexthop for evpn routes
1394  const InterfaceNH *intf_nh = dynamic_cast<const InterfaceNH *>(nh);
1395  if (nh->GetType() != NextHop::INTERFACE) {
1397  "Invalid nexthop in evpn route");
1398  return;
1399  }
1400 
1401  SecurityGroupList sg_list = item->entry.security_group_list.security_group;
1402  VmInterfaceKey intf_key(AgentKey::ADD_DEL_CHANGE, intf_nh->GetIfUuid(),
1403  intf_nh->GetInterface()->name());
1404  LocalVmRoute *local_vm_route = NULL;
1405  VnListType vn_list;
1406  vn_list.insert(item->entry.virtual_network);
1407  EcmpLoadBalance ecmp_load_balance;
1408 
1409  if (encap == TunnelType::VxlanType()) {
1410  local_vm_route =
1411  new LocalVmRoute(intf_key,
1413  label, false, vn_list,
1414  intf_nh->GetFlags(),
1415  sg_list, tag_list, CommunityList(), path_preference,
1416  Ip4Address(0), ecmp_load_balance, false, false,
1417  sequence_number(), item->entry.etree_leaf,
1418  false);
1419  } else {
1420  local_vm_route =
1421  new LocalVmRoute(intf_key,
1422  label,
1424  false, vn_list,
1425  intf_nh->GetFlags(),
1426  sg_list, tag_list, CommunityList(), path_preference,
1427  Ip4Address(0), ecmp_load_balance, false, false,
1428  sequence_number(), item->entry.etree_leaf,
1429  false);
1430  }
1431  rt_table->AddLocalVmRouteReq(bgp_peer_id(), vrf_name, mac,
1432  ip_addr, item->entry.nlri.ethernet_tag,
1433  static_cast<LocalVmRoute *>(local_vm_route));
1434 }
1435 
1436 void AgentXmppChannel::AddRemoteRoute(string vrf_name, IpAddress prefix_addr,
1437  uint32_t prefix_len, ItemType *item,
1438  const VnListType &vn_list) {
1439  InetUnicastAgentRouteTable *rt_table = PrefixToRouteTable(vrf_name,
1440  prefix_addr);
1441 
1442  if (rt_table == NULL) {
1443  return;
1444  }
1445 
1446  boost::system::error_code ec;
1447  string nexthop_addr = item->entry.next_hops.next_hop[0].address;
1448  uint32_t label = item->entry.next_hops.next_hop[0].label;
1449  IpAddress addr = IpAddress::from_string(nexthop_addr, ec);
1451  (item->entry.next_hops.next_hop[0].tunnel_encapsulation_list);
1452  if (ec.value() != 0) {
1453  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1454  "Error parsing nexthop ip address");
1455  return;
1456  }
1457 
1458  // use LOW PathPreference if local preference attribute is not set
1459  uint32_t preference = PathPreference::LOW;
1460  if (item->entry.local_preference != 0) {
1461  preference = item->entry.local_preference;
1462  }
1463  PathPreference path_preference(item->entry.sequence_number, preference,
1464  false, false);
1465 
1466  TagList tag_list;
1467  BuildTagList(item, &tag_list);
1468 
1469  std::string vn_string;
1470  for (VnListType::const_iterator vnit = vn_list.begin();
1471  vnit != vn_list.end(); ++vnit) {
1472  vn_string += *vnit + " ";
1473  }
1474  CONTROLLER_INFO_TRACE(RouteImport, GetBgpPeerName(), vrf_name,
1475  prefix_addr.to_string(), prefix_len,
1476  addr.to_v4().to_string(), label, vn_string);
1477 
1478  if (item->entry.next_hops.next_hop[0].label ==
1480  vrf_name == agent_->fabric_vrf_name() && prefix_addr.is_v4()) {
1481  AddFabricVrfRoute(prefix_addr.to_v4(), prefix_len, addr.to_v4(),
1482  vn_list,
1483  item->entry.security_group_list.security_group,
1484  tag_list);
1485  return;
1486  }
1487 
1488  if (vrf_name == agent_->fabric_policy_vrf_name() && prefix_addr.is_v4()) {
1489  //Dont override the below routes in ip_fabric vrf
1490  //default route
1491  //vhost route
1492  //vhost subnet routes
1493  if (prefix_addr.to_v4() == Ip4Address(0) && prefix_len == 0) {
1494  return;
1495  }
1496  if (prefix_addr == agent_->router_id() && prefix_len == 32) {
1497  return;
1498  }
1499  if (prefix_addr == agent_->vhost_prefix() &&
1500  prefix_len >= agent_->vhost_prefix_len()) {
1501  return;
1502  }
1503  }
1504 
1505 
1509  VrfEntry* vrf = agent_->vrf_table()->FindVrfFromName(vrf_name);
1512  // Inet routes are now handled inside the VxlanRoutingManager
1513  return;
1514  }
1515 
1516  if (agent_->router_id() != addr.to_v4()) {
1517  EcmpLoadBalance ecmp_load_balance;
1518  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1519  ControllerVmRoute *data =
1522  vrf_name, addr.to_v4(), encap, label,
1523  MacAddress(), vn_list,
1524  item->entry.security_group_list.security_group,
1525  tag_list,
1526  path_preference, false, ecmp_load_balance,
1527  false);
1528  rt_table->AddRemoteVmRouteReq(bgp_peer_id(), vrf_name, prefix_addr,
1529  prefix_len, data);
1530  return;
1531  }
1532 
1533  bool native_encap = false;
1534  if (encap & TunnelType::NativeType()) {
1535  native_encap = true;
1536  }
1537 
1538  MplsLabel *mpls = agent_->mpls_table()->FindMplsLabel(label);
1539  // When llgr and xmpp helper mode is enabled for agent
1540  // llgr route update from bgp peer can have stale mpls label on agent restart
1541  // do route lookup and add route with correct label if rt update is for local vm port
1542  if ((mpls == NULL) || (mpls->nexthop()
1543  && mpls->nexthop()->GetType() != NextHop::VLAN && mpls->nexthop()->GetType() != NextHop::COMPOSITE)) {
1544  if (agent_->oper_db()->global_system_config()->
1545  gres_parameters().IsEnabled()) {
1546  InetUnicastRouteEntry local_vm_route_key(NULL, prefix_addr, prefix_len, false);
1547  InetUnicastRouteEntry *local_vm_route =
1548  static_cast<InetUnicastRouteEntry *>
1549  (rt_table->FindLPM(local_vm_route_key));
1550  if (local_vm_route && local_vm_route->GetLocalVmPortPath() &&
1551  local_vm_route->GetLocalVmPortPath()->nexthop() && local_vm_route->GetLocalVmPortPath()->nexthop()->GetType() == NextHop::INTERFACE) {
1552  const AgentPath* local_vm_port_path = local_vm_route->GetLocalVmPortPath();
1553  const NextHop *vm_nh = local_vm_port_path->nexthop();
1554  const InterfaceNH *vm_intf_nh = static_cast<const InterfaceNH *>(vm_nh);
1555  const Interface *intrface = vm_intf_nh->GetInterface();
1556  if (intrface && intrface->type() == Interface::VM_INTERFACE) {
1557  LOG(DEBUG, "Mpls lablel picked from interface nh for local vm route, received label: " << label);
1558  label = local_vm_port_path->GetActiveLabel();
1560  vm_intf_nh->GetIfUuid(), intrface->name());
1561  // Enqueue rt update with correct mpls label and sequence number for bgp peer path
1562  EcmpLoadBalance ecmp_load_balance;
1563  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1564  BgpPeer *bgp_peer = bgp_peer_id();
1565  LocalVmRoute *local_vm_rt_update =
1566  new LocalVmRoute(intf_key, label,
1568  false, vn_list,
1570  item->entry.security_group_list.security_group,
1571  tag_list,
1572  CommunityList(),
1573  path_preference,
1574  Ip4Address(0),
1575  ecmp_load_balance, false, false,
1576  sequence_number(), false, native_encap);
1577  rt_table->AddLocalVmRouteReq(bgp_peer, vrf_name,
1578  prefix_addr, prefix_len,
1579  static_cast<LocalVmRoute *>(local_vm_rt_update));
1580  return;
1581  }
1582  }
1583  }
1584  }
1585  if (mpls != NULL) {
1586  const NextHop *nh = mpls->nexthop();
1587  switch(nh->GetType()) {
1588  case NextHop::INTERFACE: {
1589  const InterfaceNH *intf_nh = static_cast<const InterfaceNH *>(nh);
1590  const Interface *intrface = intf_nh->GetInterface();
1591  if (intrface == NULL) {
1592  break;
1593  }
1594 
1596  intf_nh->GetIfUuid(), intrface->name());
1597  EcmpLoadBalance ecmp_load_balance;
1598  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1599  BgpPeer *bgp_peer = bgp_peer_id();
1600  if (intrface->type() == Interface::VM_INTERFACE) {
1601  LocalVmRoute *local_vm_route =
1602  new LocalVmRoute(intf_key, label,
1604  false, vn_list,
1606  item->entry.security_group_list.security_group,
1607  tag_list,
1608  CommunityList(),
1609  path_preference,
1610  Ip4Address(0),
1611  ecmp_load_balance, false, false,
1612  sequence_number(), false, native_encap);
1613  rt_table->AddLocalVmRouteReq(bgp_peer, vrf_name,
1614  prefix_addr, prefix_len,
1615  static_cast<LocalVmRoute *>(local_vm_route));
1616  } else if (intrface->type() == Interface::INET) {
1617 
1618  if (!prefix_addr.is_v4()) {
1619  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1620  "MPLS label inet interface type not supported for non IPv4");
1621  return;
1622  }
1623  InetInterfaceKey intf_key(intrface->name());
1624  InetInterfaceRoute *inet_interface_route =
1625  new InetInterfaceRoute(intf_key, label,
1627  vn_list, sequence_number());
1628 
1629  rt_table->AddInetInterfaceRouteReq(bgp_peer, vrf_name,
1630  prefix_addr.to_v4(), prefix_len,
1631  inet_interface_route);
1632  } else {
1633  // Unsupported scenario
1634  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1635  "MPLS label points to invalid interface type");
1636  break;
1637  }
1638 
1639  break;
1640  }
1641 
1642  case NextHop::VLAN: {
1643  const VlanNH *vlan_nh = static_cast<const VlanNH *>(nh);
1645  vlan_nh->GetIfUuid(), "");
1646  BgpPeer *bgp_peer = bgp_peer_id();
1647  VlanNhRoute *data =
1648  new VlanNhRoute(intf_key, vlan_nh->GetVlanTag(),
1649  label, vn_list,
1650  item->entry.security_group_list.security_group,
1651  tag_list,
1652  path_preference, sequence_number());
1653  rt_table->AddVlanNHRouteReq(bgp_peer, vrf_name, prefix_addr,
1654  prefix_len, data);
1655  break;
1656  }
1657  case NextHop::COMPOSITE: {
1658  AddInetEcmpRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1659  break;
1660  }
1661  case NextHop::VRF: {
1662  //In case of gateway interface with example subnet
1663  //1.1.1.0/24 may be reachable on this gateway inteface,
1664  //Path added by local vm peer would point to
1665  //resolve NH, so that if any path hits this route, ARP resolution
1666  //can begin, and the label exported for this route would point to
1667  //table nexthop.
1668  //Hence existing logic of picking up nexthop from mpls label to
1669  //nexthop, will not work. We have added a special path where we
1670  //pick nexthop from local vm path, instead of BGP
1671  if (!prefix_addr.is_v4()) {
1672  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1673  "VRF nexthop is not supported for non IPv4");
1674  return;
1675  }
1676  BgpPeer *bgp_peer = bgp_peer_id();
1677  ClonedLocalPath *data =
1678  new ClonedLocalPath(label, vn_list,
1679  item->entry.security_group_list.security_group,
1680  tag_list,
1681  sequence_number());
1682  rt_table->AddClonedLocalPathReq(bgp_peer, vrf_name,
1683  prefix_addr.to_v4(),
1684  prefix_len, data);
1685  break;
1686  }
1687 
1688  default:
1689  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1690  "MPLS label points to invalid NH");
1691  }
1692  }
1693 }
1694 void AgentXmppChannel::AddRemoteMplsRoute(string vrf_name, IpAddress prefix_addr,
1695  uint32_t prefix_len, ItemType *item,
1696  const VnListType &vn_list) {
1698  prefix_addr);
1699 
1700  if (rt_table == NULL) {
1701  return;
1702  }
1703  if (prefix_addr == agent_->router_id() && prefix_len == 32) {
1704  rt_table->AddVhostMplsRoute(prefix_addr, bgp_peer_id());
1705  return;
1706  }
1707 
1708  boost::system::error_code ec;
1709  string nexthop_addr = item->entry.next_hops.next_hop[0].address;
1710  uint32_t label = item->entry.next_hops.next_hop[0].label;
1711  IpAddress addr = IpAddress::from_string(nexthop_addr, ec);
1712 
1713  if (ec.value() != 0) {
1714  CONTROLLER_TRACE(Trace, GetBgpPeerName(), vrf_name,
1715  "Error parsing nexthop ip address");
1716  return;
1717  }
1718 
1719  // use LOW PathPreference if local preference attribute is not set
1720  uint32_t preference = PathPreference::LOW;
1721  if (item->entry.local_preference != 0) {
1722  preference = item->entry.local_preference;
1723  }
1724  PathPreference path_preference(item->entry.sequence_number, preference,
1725  false, false);
1726 
1727  TagList tag_list;
1728  BuildTagList(item, &tag_list);
1729 
1730  std::string vn_string;
1731  for (VnListType::const_iterator vnit = vn_list.begin();
1732  vnit != vn_list.end(); ++vnit) {
1733  vn_string += *vnit + " ";
1734  }
1735  CONTROLLER_INFO_TRACE(RouteImport, GetBgpPeerName(), vrf_name,
1736  prefix_addr.to_string(), prefix_len,
1737  addr.to_v4().to_string(), label, vn_string);
1738 
1739  CommunityList cl;
1740 
1741  EcmpLoadBalance ecmp_load_balance;
1742  ControllerMplsRoute *data =
1745  vrf_name, addr.to_v4(),
1746  TunnelType::MplsoMplsType(), label,
1747  MacAddress(), vn_list,
1748  item->entry.security_group_list.security_group,
1749  tag_list,
1750  path_preference, false, ecmp_load_balance,
1751  false);
1752  rt_table->AddMplsRouteReq(bgp_peer_id(), vrf_name, prefix_addr,
1753  prefix_len, data);
1754  return;
1755 }
1756 
1757 template <typename TYPE>
1758 bool AgentXmppChannel::IsEcmp(const TYPE &nexthops) {
1759  if (nexthops.size() == 0)
1760  return false;
1761 
1762  std::string address = nexthops[0].address;
1763  uint32_t label = nexthops[0].label;
1764  for (uint32_t index = 1; index < nexthops.size(); index++) {
1765  if (nexthops[index].address != address ||
1766  (uint32_t)nexthops[index].label != label) {
1767  return true;
1768  }
1769  }
1770 
1771  return false;
1772 }
1773 
1774 template <typename TYPE>
1775 void AgentXmppChannel::GetVnList(const TYPE &nexthops, VnListType *vn_list) {
1776  for (uint32_t index = 0; index < nexthops.size(); index++) {
1777  vn_list->insert(nexthops[index].virtual_network);
1778  }
1779 }
1780 
1781 void AgentXmppChannel::AddRoute(string vrf_name, IpAddress prefix_addr,
1782  uint32_t prefix_len, ItemType *item) {
1783  if ((item->entry.next_hops.next_hop[0].label ==
1785  (vrf_name != agent_->fabric_vrf_name())) {
1786  return;
1787  }
1788 
1789  VnListType vn_list;
1790  GetVnList(item->entry.next_hops.next_hop, &vn_list);
1791  if (IsEcmp(item->entry.next_hops.next_hop)) {
1792  AddInetEcmpRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1793  } else {
1794  AddRemoteRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1795  }
1796 }
1797 
1798 void AgentXmppChannel::AddInetMplsEcmpRoute(string vrf_name, IpAddress prefix_addr,
1799  uint32_t prefix_len, ItemType *item,
1800  const VnListType &vn_list) {
1801 
1803  prefix_addr);
1804 
1805  if (rt_table == NULL) {
1806  return;
1807  }
1808 
1809  std::stringstream str;
1810  str << prefix_addr.to_string();
1811  str << "/";
1812  str << prefix_len;
1813 
1814  EcmpLoadBalance ecmp_load_balance;
1815  GetEcmpHashFieldsToUse(item, ecmp_load_balance);
1816  ControllerEcmpRoute *data = BuildEcmpData(item, vn_list, ecmp_load_balance,
1817  rt_table, str.str());
1818  //ECMP create component NH
1819  rt_table->AddMplsRouteReq(bgp_peer_id(), vrf_name,
1820  prefix_addr, prefix_len, data);
1821 }
1822 void AgentXmppChannel::AddMplsRoute(string vrf_name, IpAddress prefix_addr,
1823  uint32_t prefix_len, ItemType *item) {
1824 
1825  VnListType vn_list;
1826  GetVnList(item->entry.next_hops.next_hop, &vn_list);
1827  if (IsEcmp(item->entry.next_hops.next_hop)) {
1828  AddInetMplsEcmpRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1829  } else {
1830  AddRemoteMplsRoute(vrf_name, prefix_addr, prefix_len, item, vn_list);
1831  }
1832 }
1834  if (msg && msg->type == XmppStanza::MESSAGE_STANZA) {
1835  unique_ptr<XmlBase> impl(XmppXmlImplFactory::Instance()->GetXmlImpl());
1836  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
1837  XmlPugi *msg_pugi = reinterpret_cast<XmlPugi *>(msg->dom.get());
1838  pugi->LoadXmlDoc(msg_pugi->doc());
1839  boost::shared_ptr<ControllerXmppData> data(new ControllerXmppData(xmps::BGP,
1840  xmps::UNKNOWN,
1841  xs_idx_,
1842  std::move(impl),
1843  true));
1844  agent_->controller()->Enqueue(data);
1845  }
1846 }
1847 
1848 void AgentXmppChannel::ReceiveBgpMessage(std::unique_ptr<XmlBase> impl) {
1849  if (agent_->stats())
1851 
1852  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
1853  pugi::xml_node node = pugi->FindNode("items");
1854  if (node == 0) {
1856  EndOfRibRx();
1857  return;
1858  }
1859 
1860  pugi->ReadNode("items"); //sets the context
1861  std::string nodename = pugi->ReadAttrib("node");
1862 
1863  const char *af = NULL, *safi = NULL, *vrf_name;
1864  char *str = const_cast<char *>(nodename.c_str());
1865  char *saveptr;
1866  af = strtok_r(str, "/", &saveptr);
1867  safi = strtok_r(NULL, "/", &saveptr);
1868  vrf_name = saveptr;
1869 
1870  // No BGP peer
1871  if (bgp_peer_id() == NULL) {
1872  CONTROLLER_TRACE (Trace, GetBgpPeerName(), vrf_name,
1873  "BGP peer not present, agentxmppchannel is inactive");
1874  return;
1875  }
1876 
1877  // If EndOfRib marker is received, process it accordingly.
1878  if (nodename == XmppInit::kEndOfRibMarker) {
1879  return;
1880  }
1881 
1882  if (atoi(af) == BgpAf::IPv4 && atoi(safi) == BgpAf::MVpn) {
1884  return;
1885  }
1886  if (atoi(af) == BgpAf::IPv4 && atoi(safi) == BgpAf::Mcast) {
1888  return;
1889  }
1890  if (atoi(af) == BgpAf::L2Vpn && atoi(safi) == BgpAf::Enet) {
1892  return;
1893  }
1894  if(atoi(af) == BgpAf::IPv4 && atoi(safi) == BgpAf::Mpls) {
1896  return;
1897  }
1898 
1899  if (atoi(safi) == BgpAf::Unicast) {
1901  return;
1902  }
1903  CONTROLLER_TRACE (Trace, GetBgpPeerName(), vrf_name,
1904  "Error Route update, Unknown Address Family or safi");
1905 }
1906 
1908  ReceiveUpdate(msg);
1909 }
1910 
1911 std::string AgentXmppChannel::ToString() const {
1912  return channel_str_;
1913 }
1914 
1915 void AgentXmppChannel::WriteReadyCb(const boost::system::error_code &ec) {
1916 }
1917 
1919  assert(agent_xmpp_channel);
1920  const Agent *agent = agent_xmpp_channel->agent();
1921 
1922  //Start a timer to flush off all old configs
1923  if (agent->ifmap_xmpp_channel(agent_xmpp_channel->GetXmppServerIdx())) {
1924  agent->ifmap_xmpp_channel(agent_xmpp_channel->GetXmppServerIdx())->
1925  StartConfigCleanupTimer();
1926  }
1927 }
1928 
1930  AgentXmppChannel *peer) {
1931  bool xmpp_channel_found = false;
1932  //Verify if channel registered is stiil active or has been deleted
1933  //after bgp peer was down. This is checked under existing agent
1934  //xmpp channels in agent.
1935  for (uint8_t idx = 0; idx < MAX_XMPP_SERVERS; idx++) {
1936  if (agent->controller_xmpp_channel(idx) == peer) {
1937  xmpp_channel_found = true;
1938  break;
1939  }
1940  }
1941  return xmpp_channel_found;
1942 }
1943 
1944 /*
1945  * AgentXmppChannel is active when:
1946  * 1) bgp peer is not null(bgp_peer_id)
1947  * 2) xmpp channel is in READY state
1948  * 3) Valid XMPP channel
1949  */
1951  AgentXmppChannel *peer) {
1952  if (!IsXmppChannelActive(agent, peer))
1953  return false;
1954 
1955  //Reach here if channel is present. Now check for BGP peer
1956  //as channel may have come up and created another BGP peer.
1957  //Also check for the state of channel.
1958  if (peer && peer->GetXmppChannel() && peer->bgp_peer_id() &&
1959  (peer->GetXmppChannel()->GetPeerState() == xmps::READY)) {
1960  return true;
1961  }
1962  return false;
1963 }
1964 
1965 /*
1966  * New peer is config peer. Increment the global config sequence number,
1967  * Notify for new config peer, set it in agent xmppcfg
1968  */
1970  Agent *agent = peer->agent();
1973  peer->GetXmppServerIdx());
1974  //Generate a new sequence number for the configuration
1978  if (agent->ifmap_xmpp_channel(peer->GetXmppServerIdx())) {
1980  end_of_config_timer()->Start(peer);
1981  }
1982  return true;
1983  }
1984  return false;
1985 }
1986 
1987 /*
1988  * New multicast peer found - either first one or a lower one got selected.
1989  * Increment peer identifier so that new peer can update using incremented seq
1990  * number and multicast entries which didnt get updated can be removed via stale
1991  * cleanup.
1992  */
1994  AgentXmppChannel *new_peer) {
1996  old_peer->agent()->set_cn_mcast_builder(new_peer);
1997 }
1998 
2000  xmps::PeerState state) {
2001  std::unique_ptr<XmlBase> dummy_dom;
2002  boost::shared_ptr<ControllerXmppData> data(new ControllerXmppData(xmps::BGP,
2003  state,
2004  peer->GetXmppServerIdx(),
2005  std::move(dummy_dom),
2006  false));
2007  peer->agent()->controller()->Enqueue(data);
2008 }
2009 
2011  return (static_cast<BgpPeer *>(bgp_peer_id_.get()))->sequence_number();
2012 }
2013 
2014 /*
2015  * AgentXmppChanel state - READY
2016  *
2017  * - Bump up the sequence number to identify updates of routes on this channel
2018  * after connection is in ready state and later at the end of EOR TX timer,
2019  * flush out all the stales(which never got updated after READY state is seen).
2020  * - Config server selection is done if no config server is present. This can
2021  * happen when this is the first active channel or is becoming active after
2022  * other channel has become inactive.
2023  * - Multicast builder - Same explanation as of config server. If there is no
2024  * mcast builder, take the ownership.
2025  * - Notify all routes only if this channel is not becoming config peer. Reason
2026  * for same is that config peer selection, runs end of config timer which in
2027  * turn runs route walker to notify. So notification is deferred till end of
2028  * config is computed. For more explanation on timer check controller_timer.cc
2029  * - End of Rib Rx timer is started to handle the fallback when EOR from control
2030  * node is not seen within fallback time.
2031  */
2034  CONTROLLER_TRACE(Session, GetXmppServer(), "READY",
2035  "NULL", "BGP peer ready.");
2036  //Increment sequence number, all new updates should use this sequence
2037  //number.
2039 
2040  //Stop LLGR stale timer
2041  llgr_stale_timer()->Cancel();
2042 
2043  // Switch-over Config Control-node
2044  if (agent_->ifmap_active_xmpp_server().empty()) {
2046  CONTROLLER_TRACE(Session, GetXmppServer(), "READY",
2047  "NULL", "BGP peer set as config server.");
2048  } else {
2049  //Notify all routes to channel, if channel is not selected as config.
2050  //Config selection results in end of config computation which internally
2051  //will start the route notification. So notify is delayed till end of
2052  //config is computed.
2054  }
2055 
2056  AgentXmppChannel *agent_mcast_builder = agent_->mulitcast_builder();
2057  //Mcast builder was not set it, use the new peer
2058  if (agent_mcast_builder == NULL) {
2059  //Since this is first time mcast peer so old and new peer are same
2061  CONTROLLER_TRACE(Session, GetXmppServer(), "READY",
2063  GetBgpPeerName(), "Peer elected Mcast builder");
2064  }
2065 
2066  //Timer to delete stale paths in case EOR is not seen fro CN.
2067  //If EOR is seen it will cancel this timer.
2068  end_of_rib_rx_timer()->Start(this);
2069 
2070  if (agent_->stats())
2072 }
2073 
2074 /*
2075  * AgentXmppChanel state - NotREADY
2076  *
2077  * - Firstly stop all timers and walkers. No stale cleanup is to be
2078  * done. Caveat: if channel is not config channel then it should not stop any
2079  * config timers/walker.
2080  * By default end of rib rx timer is stopped and delete of stale walker is
2081  * stopped.
2082  * If channel is config server then stop end of config and config
2083  * cleanup(PeerIsNotConfig).
2084  * If channel is config server and there is another active config server
2085  * select the other channel as config and stop any timer from this channel.
2086  * - If its a mcast builder, try finding other if any.
2087  */
2089  CONTROLLER_TRACE(Session, GetXmppServer(), "NOT_READY",
2090  "NULL", "BGP peer decommissioned for xmpp channel.");
2091  //Stop stale cleanup if its running
2093  //Also stop notify as there is no CN for this peer.
2095  //Also stop end-of-rib rx fallback and retain.
2097  //State llgr stale timer to clean stales if CN has issues with getting ready.
2098  llgr_stale_timer()->Start(this);
2099 
2100  // evaluate peer change for config and multicast
2101  AgentXmppChannel *agent_mcast_builder =
2103  bool peer_is_config_server = (agent_->
2104  ifmap_active_xmpp_server().compare(GetXmppServer()) == 0);
2105  bool peer_is_agent_mcast_builder = (agent_mcast_builder == this);
2106 
2107  // Switch-over Config Control-node
2108  if (peer_is_config_server) {
2109  //stop all config clean timer, retain old config,
2110  //if there is a new config selected, it will take care of flushing
2111  //stale.
2112  PeerIsNotConfig();
2113  //send cfg subscribe to other peer if exists
2114  uint8_t idx = ((agent_->ifmap_active_xmpp_server_index() == 0) ? 1: 0);
2116  AgentXmppChannel *new_cfg_peer = agent_->controller_xmpp_channel(idx);
2117 
2118  if (AgentXmppChannel::IsBgpPeerActive(agent_, new_cfg_peer) &&
2119  AgentXmppChannel::SetConfigPeer(new_cfg_peer)) {
2120  CONTROLLER_TRACE(Session, new_cfg_peer->GetXmppServer(),
2121  "NOT_READY", "NULL", "BGP peer selected as"
2122  "config peer on decommission of old config "
2123  "peer.");
2124  }
2125  }
2126 
2127  // Switch-over Multicast Tree Builder
2128  if (peer_is_agent_mcast_builder) {
2129  uint8_t idx = ((agent_mcast_builder->GetXmppServerIdx() == 0)
2130  ? 1: 0);
2131  AgentXmppChannel *new_mcast_builder =
2133 
2134  // Selection of new peer as mcast builder is dependant on following
2135  // criterias:
2136  // 1) Channel is present (new_mcast_builder is not null)
2137  // 2) Channel is in READY state
2138  // 3) BGP peer is commissioned for channel
2139  bool evaluate_new_mcast_builder =
2140  AgentXmppChannel::IsBgpPeerActive(agent_, new_mcast_builder);
2141 
2142  if (!evaluate_new_mcast_builder) {
2143  new_mcast_builder = NULL;
2144  CONTROLLER_TRACE(Session, GetXmppServer(), "NOT_READY",
2145  "NULL", "No elected Multicast Tree Builder");
2146  }
2147  AgentXmppChannel::SetMulticastPeer(this, new_mcast_builder);
2148  if (evaluate_new_mcast_builder) {
2149  //Advertise subnet and all broadcast routes to
2150  //the new multicast tree builder
2151  new_mcast_builder->StartEndOfRibTxWalker();
2152  CONTROLLER_TRACE(Session, GetXmppServer(), "NOT_READY",
2154  GetBgpPeerName(),
2155  "Peer elected Multicast Tree Builder");
2156  }
2157  }
2158 }
2159 
2160 /*
2161  * AgentXmppChannel state TimedOut
2162  *
2163  * Injects NotReady event for this channel.
2164  *
2165  * If there are more than two channels available in config, then try picking
2166  * other channel to replace this timed out channel. And push this channel at the
2167  * end of the channel list so that it is picked only in worst case.
2168  * Also this channel gets moved to timed out list where it waits for any other
2169  * channel to take up the slot(xs_idx_) and is stable(Done to retain
2170  * config/routes till new channel is stable).
2171  *
2172  * If there are only two channels configured, no action to be taken.
2173  */
2175  CONTROLLER_TRACE(Session, GetXmppServer(), "TIMEDOUT",
2176  "NULL", "Connection to Xmpp Server, Timed out");
2177  {
2178  bool update_list = false;
2179  std::vector<string>::iterator iter = agent_->GetControllerlist().begin();
2180  std::vector<string>::iterator end = agent_->GetControllerlist().end();
2181  for (; iter != end; iter++) {
2182  std::vector<string> server;
2183  boost::split(server, *iter, boost::is_any_of(":"));
2184  if (GetXmppServer().compare(server[0]) == 0) {
2185  // Add the TIMEDOUT server to the end.
2186  if (iter+1 == end) break;
2187  std::rotate(iter, iter+1, end);
2188  update_list = true;
2189  break;
2190  }
2191  }
2192  if (update_list) {
2194  }
2195  }
2196 }
2197 
2199  xmps::PeerState state) {
2200  peer->UpdateConnectionInfo(state);
2201  if (state == xmps::READY) {
2202  peer->Ready();
2203  } else if (state == xmps::NOT_READY) {
2204  peer->NotReady();
2205  } else if (state == xmps::TIMEDOUT) {
2206  peer->TimedOut();
2207  }
2208 }
2209 
2211  return end_of_rib_tx_timer_.get();
2212 }
2213 
2215  return end_of_rib_rx_timer_.get();
2216 }
2217 
2219  return llgr_stale_timer_.get();
2220 }
2221 
2226  }
2227 }
2228 
2230  const boost::uuids::uuid &vm_id,
2231  bool subscribe) {
2232  string repr;
2233  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2234 
2235  if (!peer) {
2236  return false;
2237  }
2238 
2239  //Build the DOM tree
2240  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2241  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2242 
2243  pugi->AddNode("iq", "");
2244  pugi->AddAttribute("type", "set");
2245  pugi->AddAttribute("from", peer->channel_->FromString());
2246  std::string to(peer->channel_->ToString());
2247  to += "/";
2248  to += XmppInit::kConfigPeer;
2249  pugi->AddAttribute("to", to);
2250 
2251  pugi->AddChildNode("pubsub", "");
2252  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2253  if (subscribe == true) {
2254  pugi->AddChildNode("subscribe", "");
2255  } else {
2256  pugi->AddChildNode("unsubscribe", "");
2257  }
2258  std::string vm("virtual-machine:");
2259  stringstream vmid;
2260  vmid << vm_id;
2261  vm += vmid.str();
2262  pugi->AddAttribute("node", vm);
2263 
2264  pugi->doc().print(*xml_writer, "", pugi::format_default,
2265  pugi::encoding_utf8);
2267  peer->GetBgpPeerName(), "", repr);
2268  // send data
2269  if (peer->SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()),
2270  repr.length()) == false) {
2271  CONTROLLER_TRACE(Session, peer->GetXmppServer(),
2272  "VM subscribe Send Update deferred", vm, "");
2273  }
2274 
2275  return true;
2276 }
2277 
2279 
2280  string repr;
2281  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2282 
2283  if (!peer) {
2284  return false;
2285  }
2286 
2287  //Build the DOM tree
2288  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2289  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2290 
2291  pugi->AddNode("iq", "");
2292  pugi->AddAttribute("type", "set");
2293  pugi->AddAttribute("from", peer->channel_->FromString());
2294  std::string to(peer->channel_->ToString());
2295  to += "/";
2296  to += XmppInit::kConfigPeer;
2297  pugi->AddAttribute("to", to);
2298 
2299  pugi->AddChildNode("pubsub", "");
2300  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2301  pugi->AddChildNode("subscribe", "");
2302  string node("virtual-router:");
2303  node = node + XmppInit::kFqnPrependAgentNodeJID + peer->channel_->FromString();
2304  pugi->AddAttribute("node", node);
2305 
2306  pugi->doc().print(*xml_writer, "", pugi::format_default,
2307  pugi::encoding_utf8);
2309  peer->GetBgpPeerName(), "", repr);
2310  // send data
2311  if (peer->SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()),
2312  repr.length()) == false) {
2313  CONTROLLER_TRACE(Session, peer->GetXmppServer(),
2314  "Config subscribe Send Update deferred", node, "");
2315  }
2316  return true;
2317 }
2318 
2320  VrfEntry *vrf,
2321  bool subscribe) {
2322  static int req_id = 0;
2323  string repr;
2324  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2325 
2326  if (!peer) {
2327  return false;
2328  }
2330  subscribe ? "Subscribe" : "Unsubscribe");
2331  //Build the DOM tree
2332  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2333  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2334 
2335  pugi->AddNode("iq", "");
2336  pugi->AddAttribute("type", "set");
2337  pugi->AddAttribute("from", peer->channel_->FromString());
2338  std::string to(peer->channel_->ToString());
2339  to += "/";
2340  to += XmppInit::kBgpPeer;
2341  pugi->AddAttribute("to", to);
2342 
2343  stringstream request_id;
2344  request_id << "subscribe" << req_id++;
2345  pugi->AddAttribute("id", request_id.str());
2346  pugi->AddChildNode("pubsub", "");
2347  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2348  if (subscribe) {
2349  pugi->AddChildNode("subscribe", "");
2350  } else {
2351  pugi->AddChildNode("unsubscribe", "");
2352  }
2353  pugi->AddAttribute("node", vrf->GetName());
2354  pugi->AddChildNode("options", "" );
2355  stringstream vrf_id;
2356  vrf_id << vrf->rd();
2357  pugi->AddChildNode("instance-id", vrf_id.str());
2358 
2359  pugi->doc().print(*xml_writer, "", pugi::format_default,
2360  pugi::encoding_utf8);
2361  // send data
2362  if (peer->SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()),
2363  repr.length()) == false) {
2364  CONTROLLER_TRACE(Session, peer->GetXmppServer(),
2365  "Vrf subscribe Send Update deferred", vrf_id.str(), "");
2366  }
2367  return true;
2368 }
2369 
2370 void PopulateEcmpHashFieldsToUse(ItemType &item,
2371  const EcmpLoadBalance &ecmp_load_balance) {
2372  item.entry.load_balance.load_balance_decision = LoadBalanceDecision;
2373 
2374  if (ecmp_load_balance.AllSet())
2375  return;
2376 
2377  ecmp_load_balance.GetStringVector(
2378  item.entry.load_balance.load_balance_fields.load_balance_field_list);
2379 }
2380 
2382  const VnListType &vn_list,
2383  const SecurityGroupList *sg_list,
2384  const TagList *tag_list,
2385  const CommunityList *communities,
2386  uint32_t mpls_label,
2387  TunnelType::TypeBmap bmap,
2388  const PathPreference &path_preference,
2389  bool associate,
2391  const EcmpLoadBalance &ecmp_load_balance,
2392  uint32_t native_vrf_id) {
2393  if (route->vrf()) {
2394  const std::string vrf_name = route->vrf()->GetName();
2397  return true;
2398  }
2399  }
2400 
2401  static int id = 0;
2402  ItemType item;
2403  string repr;
2404  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2405 
2406  //Build the DOM tree
2407  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2408  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2409 
2410  if ((type == Agent::INET4_UNICAST) ||
2411  (type == Agent::INET4_MPLS)) {
2412  item.entry.nlri.af = BgpAf::IPv4;
2413  } else if (type == Agent::INET6_UNICAST) {
2414  item.entry.nlri.af = BgpAf::IPv6;
2415  }
2416  if (type == Agent::INET4_MPLS) {
2417  item.entry.nlri.safi = BgpAf::Mpls;
2418  } else {
2419  item.entry.nlri.safi = BgpAf::Unicast;
2420  }
2421 
2422  stringstream rstr;
2423  rstr << route->ToString();
2424  item.entry.nlri.address = rstr.str();
2425 
2426  string rtr(agent_->router_id().to_string());
2427 
2428  PopulateEcmpHashFieldsToUse(item, ecmp_load_balance);
2429  autogen::NextHopType nh;
2430  nh.af = BgpAf::IPv4;
2431  nh.address = rtr;
2432  nh.label = mpls_label;
2433 
2434  // EVPN (VNF) service chaining requires router MAC address advertisement.
2435  if (agent_->vhost_interface()) {
2436  nh.mac = agent_->vhost_interface()->mac().ToString();
2437  }
2438  if (bmap & TunnelType::GREType()) {
2439  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2440  }
2441  if (bmap & TunnelType::UDPType()) {
2442  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2443  }
2444  if (bmap & TunnelType::VxlanType()) {
2445  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2446  const AgentPath *loc_vm_path = route->FindIntfOrCompLocalVmPortPath();
2447  if (loc_vm_path && route->vrf() && route->vrf()->routing_vrf()) {
2448  nh.label = loc_vm_path->vxlan_id();
2449  }
2450  }
2451  if (bmap & TunnelType::NativeType()) {
2452  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("native");
2453  }
2454 
2455  if (tag_list && tag_list->size()) {
2456  nh.tag_list.tag = *tag_list;
2457  }
2458 
2459  if (path_preference.loc_sequence()) {
2460  nh.local_sequence_number = path_preference.loc_sequence();
2461  }
2462 
2463  for (VnListType::const_iterator vnit = vn_list.begin();
2464  vnit != vn_list.end(); ++vnit) {
2465  nh.virtual_network = *vnit;
2466  item.entry.next_hops.next_hop.push_back(nh);
2467  }
2468 
2469  if (sg_list && sg_list->size()) {
2470  item.entry.security_group_list.security_group = *sg_list;
2471  }
2472 
2473  if (communities && !communities->empty()) {
2474  item.entry.community_tag_list.community_tag = *communities;
2475  }
2476 
2477  item.entry.sub_protocol = route->intf_route_type();
2478  item.entry.version = 1; //TODO
2479  item.entry.med = 0;
2480 
2481  //Set sequence number and preference of route
2482  item.entry.sequence_number = path_preference.sequence();
2483  item.entry.local_preference = path_preference.preference();
2484 
2485  pugi->AddNode("iq", "");
2486  pugi->AddAttribute("type", "set");
2487 
2488  pugi->AddAttribute("from", channel_->FromString());
2489  std::string to(channel_->ToString());
2490  to += "/";
2491  to += XmppInit::kBgpPeer;
2492  pugi->AddAttribute("to", to);
2493 
2494  stringstream pubsub_id;
2495  pubsub_id << "pubsub" << id;
2496  pugi->AddAttribute("id", pubsub_id.str());
2497 
2498  pugi->AddChildNode("pubsub", "");
2499  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2500  pugi->AddChildNode("publish", "");
2501 
2502  //Catering for inet4 and evpn unicast routes
2503  stringstream ss_node;
2504  ss_node << item.entry.nlri.af << "/"
2505  << item.entry.nlri.safi << "/"
2506  << route->vrf()->GetName() << "/"
2507  << route->ToString();
2508  if (native_vrf_id != VrfEntry::kInvalidIndex) {
2509  ss_node << "/" << native_vrf_id;
2510  }
2511  std::string node_id(ss_node.str());
2512  pugi->AddAttribute("node", node_id);
2513  pugi->AddChildNode("item", "");
2514 
2515  pugi::xml_node node = pugi->FindNode("item");
2516 
2517  //Call Auto-generated Code to encode the struct
2518  item.Encode(&node);
2519 
2520  pugi->doc().print(*xml_writer, "", pugi::format_default,
2521  pugi::encoding_utf8);
2522  // send data
2523  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2524  repr.clear();
2525 
2526  pugi->DeleteNode("pubsub");
2527  pugi->ReadNode("iq");
2528 
2529  stringstream collection_id;
2530  collection_id << "collection" << id++;
2531  pugi->ModifyAttribute("id", collection_id.str());
2532  pugi->AddChildNode("pubsub", "");
2533  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2534  pugi->AddChildNode("collection", "");
2535 
2536  pugi->AddAttribute("node", route->vrf()->GetName());
2537  if (associate) {
2538  pugi->AddChildNode("associate", "");
2539  } else {
2540  pugi->AddChildNode("dissociate", "");
2541  }
2542  pugi->AddAttribute("node", node_id);
2543 
2544  pugi->doc().print(*xml_writer, "", pugi::format_default,
2545  pugi::encoding_utf8);
2546  // send data
2547  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2549  return true;
2550 }
2551 
2553  stringstream &node_id,
2554  AgentRoute *route,
2555  const Ip4Address *nh_ip,
2556  const std::string &vn,
2557  const SecurityGroupList *sg_list,
2558  const TagList *tag_list,
2559  const CommunityList *communities,
2560  uint32_t label,
2561  uint32_t tunnel_bmap,
2562  const std::string &destination,
2563  const std::string &source,
2564  bool associate) {
2565  assert(route->GetTableType() == Agent::EVPN);
2566  const AgentPath *path = NULL;
2567  EvpnRouteEntry *evpn_route =
2568  dynamic_cast<EvpnRouteEntry *>(route);
2569  path = evpn_route->FindOvsPath();
2570  if ((path == NULL) && (associate)) {
2572  route->vrf()->GetName(),
2573  "OVS path not found for ff:ff:ff:ff:ff:ff, skip send");
2574  return false;
2575  }
2576 
2577  item.entry.local_preference = PathPreference::LOW;
2578  item.entry.sequence_number = 0;
2579  item.entry.replicator_address = source;
2580  item.entry.nlri.af = BgpAf::L2Vpn;
2581  item.entry.nlri.safi = BgpAf::Enet;
2582  stringstream rstr;
2583  rstr << route->ToString();
2584  item.entry.nlri.mac = rstr.str();
2585  item.entry.assisted_replication_supported = false;
2586  item.entry.edge_replication_not_supported = false;
2587 
2588  rstr.str("");
2589  //TODO fix this when multicast moves to evpn
2590  assert(evpn_route->is_multicast());
2591  rstr << destination;
2592  rstr << "/32";
2593  item.entry.nlri.ethernet_tag = 0;
2594  if (associate == false)
2595  item.entry.nlri.ethernet_tag = label;
2596 
2597  item.entry.nlri.address = rstr.str();
2598  assert(item.entry.nlri.address != "0.0.0.0");
2599 
2600  autogen::EnetNextHopType nh;
2601  nh.af = Address::INET;
2602  nh.address = destination;
2603  nh.label = label;
2604 
2605  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2606  << route->ToString() << "," << item.entry.nlri.address;
2607  TunnelType::Type tunnel_type = TunnelType::ComputeType(tunnel_bmap);
2608 
2609  if (path) {
2610  tunnel_type = path->tunnel_type();
2611  }
2612  if (associate) {
2613  if (tunnel_type != TunnelType::VXLAN) {
2614  if (tunnel_bmap & TunnelType::GREType()) {
2615  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2616  }
2617  if (tunnel_bmap & TunnelType::UDPType()) {
2618  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2619  }
2620  } else {
2621  if (path) {
2622  nh.label = path->vxlan_id();
2623  item.entry.nlri.ethernet_tag = nh.label;
2624  } else {
2625  nh.label = 0;
2626  }
2627  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2628  }
2629 
2630  if (sg_list && sg_list->size()) {
2631  item.entry.security_group_list.security_group = *sg_list;
2632  }
2633 
2634  if (tag_list && tag_list->size()) {
2635  nh.tag_list.tag = *tag_list;
2636  }
2637  }
2638 
2639  item.entry.next_hops.next_hop.push_back(nh);
2640  item.entry.med = 0;
2641  //item.entry.version = 1; //TODO
2642  //item.entry.virtual_network = vn;
2643  return true;
2644 }
2645 
2646 //TODO simplify label selection below.
2648  stringstream &node_id,
2649  AgentRoute *route,
2650  const Ip4Address *nh_ip,
2651  const std::string &vn,
2652  const SecurityGroupList *sg_list,
2653  const TagList *tag_list,
2654  const CommunityList *communities,
2655  uint32_t label,
2656  uint32_t tunnel_bmap,
2657  bool associate,
2658  const AgentPath *path,
2659  bool assisted_replication) {
2660  assert(route->is_multicast() == true);
2661  item.entry.local_preference = PathPreference::LOW;
2662  item.entry.sequence_number = 0;
2663  if (agent_->simulate_evpn_tor()) {
2664  item.entry.edge_replication_not_supported = true;
2665  } else {
2666  item.entry.edge_replication_not_supported = false;
2667  }
2668  item.entry.nlri.af = BgpAf::L2Vpn;
2669  item.entry.nlri.safi = BgpAf::Enet;
2670  stringstream rstr;
2671  //TODO fix this when multicast moves to evpn
2672  rstr << "0.0.0.0/32";
2673  item.entry.nlri.address = rstr.str();
2674  assert(item.entry.nlri.address != "0.0.0.0");
2675 
2676  rstr.str("");
2677  if (assisted_replication) {
2678  rstr << route->ToString();
2679  item.entry.assisted_replication_supported = true;
2680  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2681  << route->ToString() << "," << item.entry.nlri.address
2682  << "," << route->GetAddressString()
2683  << "," << route->GetSourceAddressString();
2684  } else {
2685  rstr << route->GetAddressString();
2686  item.entry.assisted_replication_supported = false;
2687  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2688  << route->GetAddressString() << "," << item.entry.nlri.address
2689  << "," << route->GetAddressString()
2690  << "," << route->GetSourceAddressString();
2691  }
2692 
2693  if (route->GetTableType() == Agent::INET4_MULTICAST) {
2694  Inet4MulticastRouteEntry *m_route =
2695  static_cast<Inet4MulticastRouteEntry *>(route);
2696 
2697  const Ip4Address group = m_route->dest_ip_addr();
2698  MacAddress mac;
2699  agent_->oper_db()->multicast()->GetMulticastMacFromIp(group, mac);
2700 
2701  item.entry.nlri.mac = mac.ToString();
2702  item.entry.nlri.group = route->GetAddressString();
2703  item.entry.nlri.source = route->GetSourceAddressString();
2704  item.entry.nlri.flags =
2706  m_route->vrf()->GetName(),
2707  m_route->src_ip_addr(),
2708  m_route->dest_ip_addr());
2709  } else {
2710  item.entry.nlri.mac = route->ToString();
2711  }
2712 
2713  autogen::EnetNextHopType nh;
2714  nh.af = Address::INET;
2715  nh.address = nh_ip->to_string();
2716  nh.label = label;
2717 
2718  TunnelType::Type tunnel_type = TunnelType::ComputeType(tunnel_bmap);
2719  item.entry.nlri.ethernet_tag = route->vrf()->isid();
2720  if (associate == false) {
2721  //In case of VXLAN ethernet tag is set to vxlan ID.
2722  //Upon withdraw or encap change label holds the VN ID
2723  //which is used to withdraw route
2724  item.entry.nlri.ethernet_tag = label;
2725  }
2726 
2727  if (path) {
2728  tunnel_type = path->tunnel_type();
2729  }
2730  if (associate) {
2731  if (tunnel_type != TunnelType::VXLAN) {
2732  if (tunnel_bmap & TunnelType::GREType()) {
2733  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2734  }
2735  if (tunnel_bmap & TunnelType::UDPType()) {
2736  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2737  }
2738  } else {
2739  if (path == NULL)
2740  path = route->FindPath(agent_->local_peer());
2741 
2742  if (path) {
2743  nh.label = path->vxlan_id();
2744  item.entry.nlri.ethernet_tag = nh.label;
2745  } else {
2746  nh.label = 0;
2747  }
2748  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2749  }
2750 
2751  if (sg_list && sg_list->size()) {
2752  item.entry.security_group_list.security_group = *sg_list;
2753  }
2754  }
2755 
2756  item.entry.next_hops.next_hop.push_back(nh);
2757  item.entry.med = 0;
2758  //item.entry.version = 1; //TODO
2759  //item.entry.virtual_network = vn;
2760  return true;
2761 }
2762 
2764  stringstream &node_id,
2765  AgentRoute *route,
2766  const Ip4Address *nh_ip,
2767  const std::string &vn,
2768  const SecurityGroupList *sg_list,
2769  const TagList *tag_list,
2770  const CommunityList *communities,
2771  uint32_t label,
2772  uint32_t tunnel_bmap,
2773  const PathPreference
2774  &path_preference,
2775  bool associate) {
2776  assert(route->is_multicast() == false);
2777  assert(route->GetTableType() == Agent::EVPN);
2778  item.entry.local_preference = path_preference.preference();
2779  item.entry.sequence_number = path_preference.sequence();
2780  item.entry.assisted_replication_supported = false;
2781  item.entry.edge_replication_not_supported = false;
2782  item.entry.nlri.af = BgpAf::L2Vpn;
2783  item.entry.nlri.safi = BgpAf::Enet;
2784 
2785  stringstream rstr;
2786  rstr << route->GetAddressString();
2787  item.entry.nlri.mac = rstr.str();
2788 
2789  const AgentPath *active_path = NULL;
2790  rstr.str("");
2791  EvpnRouteEntry *evpn_route = static_cast<EvpnRouteEntry *>(route);
2792  rstr << evpn_route->prefix_address().to_string() << "/"
2793  << static_cast<int>(evpn_route->prefix_length());
2794  active_path = evpn_route->FindLocalVmPortPath();
2795  item.entry.nlri.ethernet_tag = evpn_route->ethernet_tag();
2796 
2797  item.entry.nlri.address = rstr.str();
2798  assert(item.entry.nlri.address != "0.0.0.0");
2799 
2800  item.entry.etree_leaf = true;
2801  if (active_path) {
2802  item.entry.etree_leaf = active_path->etree_leaf();
2803  }
2804 
2805  autogen::EnetNextHopType nh;
2806  nh.af = Address::INET;
2807  nh.address = nh_ip->to_string();
2808  nh.label = label;
2809  if (evpn_route->mac().IsZero()) {
2810  nh.mac = agent_->vhost_interface()->mac().ToString();
2811  }
2812  TunnelType::Type tunnel_type = TunnelType::ComputeType(tunnel_bmap);
2813  if (active_path) {
2814  tunnel_type = active_path->tunnel_type();
2815  }
2816  if (associate) {
2817  if (tunnel_type != TunnelType::VXLAN) {
2818  if (tunnel_bmap & TunnelType::GREType()) {
2819  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
2820  }
2821  if (tunnel_bmap & TunnelType::UDPType()) {
2822  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
2823  }
2824  } else {
2825  if (active_path) {
2826  nh.label = active_path->vxlan_id();
2827  } else {
2828  nh.label = 0;
2829  }
2830  nh.tunnel_encapsulation_list.tunnel_encapsulation.push_back("vxlan");
2831  }
2832 
2833  if (sg_list && sg_list->size()) {
2834  item.entry.security_group_list.security_group = *sg_list;
2835  }
2836 
2837  if (tag_list && tag_list->size()) {
2838  nh.tag_list.tag = *tag_list;
2839  }
2840 
2841  if (path_preference.loc_sequence()) {
2842  nh.local_sequence_number = path_preference.loc_sequence();
2843  }
2844  }
2845 
2846  item.entry.next_hops.next_hop.push_back(nh);
2847  item.entry.med = 0;
2848  //item.entry.version = 1; //TODO
2849  //item.entry.virtual_network = vn;
2850 
2851  node_id << item.entry.nlri.af << "/" << item.entry.nlri.safi << "/"
2852  << route->GetAddressString() << "," << item.entry.nlri.address;
2853  return true;
2854 }
2855 
2857  stringstream &ss_node,
2858  const AgentRoute *route,
2859  bool associate) {
2860  static int id = 0;
2861  string repr;
2862  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
2863 
2864  //Build the DOM tree
2865  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
2866  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
2867 
2868  pugi->AddNode("iq", "");
2869  pugi->AddAttribute("type", "set");
2870 
2871  pugi->AddAttribute("from", channel_->FromString());
2872  std::string to(channel_->ToString());
2873  to += "/";
2874  to += XmppInit::kBgpPeer;
2875  pugi->AddAttribute("to", to);
2876 
2877  stringstream pubsub_id;
2878  pubsub_id << "pubsub_l2" << id;
2879  pugi->AddAttribute("id", pubsub_id.str());
2880 
2881  pugi->AddChildNode("pubsub", "");
2882  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2883  pugi->AddChildNode("publish", "");
2884 
2885  std::string node_id(ss_node.str());
2886  pugi->AddAttribute("node", node_id);
2887  pugi->AddChildNode("item", "");
2888 
2889  pugi::xml_node node = pugi->FindNode("item");
2890 
2891  //Call Auto-generated Code to encode the struct
2892  item.Encode(&node);
2893 
2894  pugi->doc().print(*xml_writer, "", pugi::format_default,
2895  pugi::encoding_utf8);
2896  // send data
2897  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2898  repr.clear();
2899 
2900  pugi->DeleteNode("pubsub");
2901  pugi->ReadNode("iq");
2902 
2903  stringstream collection_id;
2904  collection_id << "collection_l2" << id++;
2905  pugi->ModifyAttribute("id", collection_id.str());
2906  pugi->AddChildNode("pubsub", "");
2907  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
2908  pugi->AddChildNode("collection", "");
2909 
2910  pugi->AddAttribute("node", route->vrf()->GetExportName());
2911  if (associate) {
2912  pugi->AddChildNode("associate", "");
2913  } else {
2914  pugi->AddChildNode("dissociate", "");
2915  }
2916  pugi->AddAttribute("node", node_id);
2917 
2918  pugi->doc().print(*xml_writer, "", pugi::format_default,
2919  pugi::encoding_utf8);
2920  // send data
2921  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
2923  return true;
2924 }
2925 
2927  const Ip4Address *nh_ip,
2928  std::string vn,
2929  const SecurityGroupList *sg_list,
2930  const TagList *tag_list,
2931  const CommunityList *communities,
2932  uint32_t label,
2933  uint32_t tunnel_bmap,
2934  const std::string &destination,
2935  const std::string &source,
2936  const PathPreference
2937  &path_preference,
2938  bool associate) {
2939  EnetItemType item;
2940  stringstream ss_node;
2941  bool ret = true;
2942 
2943  if (label == MplsTable::kInvalidLabel) return false;
2944 
2945  if (route->is_multicast()) {
2946  BridgeRouteEntry *l2_route =
2947  dynamic_cast<BridgeRouteEntry *>(route);
2948  if (agent_->tsn_enabled()) {
2949  //Second subscribe for TSN assited replication
2950  if (BuildEvpnMulticastMessage(item, ss_node, route, nh_ip, vn,
2951  sg_list, tag_list, communities,
2952  label, tunnel_bmap, associate,
2953  l2_route->FindPath(agent_->
2954  local_peer()),
2955  true) == false)
2956  return false;
2957  ret |= BuildAndSendEvpnDom(item, ss_node,
2958  route, associate);
2959  } else if (agent_->tor_agent_enabled()) {
2960  if (BuildTorMulticastMessage(item, ss_node, route, nh_ip, vn,
2961  sg_list, tag_list, communities, label,
2962  tunnel_bmap, destination, source,
2963  associate) == false)
2964  return false;;
2965  ret = BuildAndSendEvpnDom(item, ss_node, route, associate);
2966  } else {
2967  const AgentPath *path;
2968  if (route->GetTableType() == Agent::BRIDGE) {
2969  path = l2_route->FindPath(agent_->multicast_peer());
2970  } else if (route->GetTableType() == Agent::INET4_MULTICAST) {
2971  Inet4MulticastRouteEntry *m_route =
2972  static_cast<Inet4MulticastRouteEntry *>(route);
2973  path = m_route->FindPath(agent_->multicast_peer());
2974  } else {
2975  return false;
2976  }
2977  if (BuildEvpnMulticastMessage(item, ss_node, route, nh_ip, vn,
2978  sg_list, tag_list, communities, label,
2979  tunnel_bmap, associate,
2980  path,
2981  false) == false)
2982  return false;
2983  ret = BuildAndSendEvpnDom(item, ss_node, route, associate);
2984  }
2985  } else {
2986  if (BuildEvpnUnicastMessage(item, ss_node, route, nh_ip, vn, sg_list,
2987  tag_list, communities, label, tunnel_bmap,
2988  path_preference, associate) == false)
2989  return false;;
2990  ret = BuildAndSendEvpnDom(item, ss_node, route, associate);
2991  }
2992  return ret;
2993 }
2994 
2996  bool add_route) {
2997  static int id = 0;
2998  autogen::McastItemType item;
2999  string repr;
3000  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
3001 
3002  if (add_route && (agent_->mulitcast_builder() != this)) {
3004  route->vrf()->GetName(),
3005  "Peer not elected Multicast Tree Builder");
3006  return false;
3007  }
3008 
3009  CONTROLLER_INFO_TRACE(McastSubscribe, GetBgpPeerName(),
3010  route->vrf()->GetName(), " ",
3011  route->ToString());
3012 
3013  //Build the DOM tree
3014  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
3015  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
3016 
3017  item.entry.nlri.af = BgpAf::IPv4;
3018  item.entry.nlri.safi = BgpAf::Mcast;
3019  item.entry.nlri.group = route->GetAddressString();
3020  item.entry.nlri.source = route->GetSourceAddressString();
3021 
3022  autogen::McastNextHopType item_nexthop;
3023  item_nexthop.af = BgpAf::IPv4;
3024  string rtr(agent_->router_id().to_string());
3025  item_nexthop.address = rtr;
3026  item_nexthop.label = GetMcastLabelRange();
3027  item_nexthop.tunnel_encapsulation_list.tunnel_encapsulation.push_back("gre");
3028  item_nexthop.tunnel_encapsulation_list.tunnel_encapsulation.push_back("udp");
3029  item.entry.next_hops.next_hop.push_back(item_nexthop);
3030 
3031  //Build the pugi tree
3032  pugi->AddNode("iq", "");
3033  pugi->AddAttribute("type", "set");
3034  pugi->AddAttribute("from", channel_->FromString());
3035  std::string to(channel_->ToString());
3036  to += "/";
3037  to += XmppInit::kBgpPeer;
3038  pugi->AddAttribute("to", to);
3039 
3040  std::string pubsub_id("pubsub_b");
3041  stringstream str_id;
3042  str_id << id;
3043  pubsub_id += str_id.str();
3044  pugi->AddAttribute("id", pubsub_id);
3045 
3046  pugi->AddChildNode("pubsub", "");
3047  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3048  pugi->AddChildNode("publish", "");
3049  stringstream ss_node;
3050  ss_node << item.entry.nlri.af << "/"
3051  << item.entry.nlri.safi << "/"
3052  << route->vrf()->GetExportName() << "/"
3053  << route->GetAddressString();
3054  std::string node_id(ss_node.str());
3055  pugi->AddAttribute("node", node_id);
3056  pugi->AddChildNode("item", "");
3057 
3058  pugi::xml_node node = pugi->FindNode("item");
3059 
3060  //Call Auto-generated Code to encode the struct
3061  item.Encode(&node);
3062 
3063  pugi->doc().print(*xml_writer, "", pugi::format_default,
3064  pugi::encoding_utf8);
3065  // send data
3066  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3067  repr.clear();
3068 
3069  pugi->DeleteNode("pubsub");
3070  pugi->ReadNode("iq");
3071 
3072  stringstream collection_id;
3073  collection_id << "collection" << id++;
3074  pugi->ModifyAttribute("id", collection_id.str());
3075  pugi->AddChildNode("pubsub", "");
3076  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3077  pugi->AddChildNode("collection", "");
3078 
3079  pugi->AddAttribute("node", route->vrf()->GetName());
3080  if (add_route) {
3081  pugi->AddChildNode("associate", "");
3082  } else {
3083  pugi->AddChildNode("dissociate", "");
3084  }
3085  pugi->AddAttribute("node", node_id);
3086 
3087  pugi->doc().print(*xml_writer, "", pugi::format_default,
3088  pugi::encoding_utf8);
3089  // send data
3090  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3092  return true;
3093 }
3094 
3096  bool associate) {
3097 
3098  if (agent_->params()->mvpn_ipv4_enable()) {
3099  if (agent_->fabric_policy_vrf_name() != route->vrf()->GetName()) {
3100  return ControllerSendMvpnRouteCommon(route, associate);
3101  }
3102  }
3103  return ControllerSendMcastRouteCommon(route, associate);
3104 }
3105 
3107  bool associate) {
3108  static int id = 0;
3109  MvpnItemType item;
3110  string repr;
3111  boost::scoped_ptr<XmlWriter> xml_writer(new XmlWriter(&repr));
3112 
3113  CONTROLLER_INFO_TRACE(McastSubscribe, GetBgpPeerName(),
3114  route->vrf()->GetName(), " ",
3115  route->ToString());
3116 
3117  //Build the DOM tree
3118  unique_ptr<XmlBase> impl(XmppStanza::AllocXmppXmlImpl());
3119  XmlPugi *pugi = reinterpret_cast<XmlPugi *>(impl.get());
3120 
3121  item.entry.nlri.af = BgpAf::IPv4;
3122  item.entry.nlri.safi = BgpAf::MVpn;
3123  item.entry.nlri.group = route->GetAddressString();
3124  item.entry.nlri.source = route->GetSourceAddressString();
3125  item.entry.nlri.route_type = 7;
3126 
3127  item.entry.next_hop.af = BgpAf::IPv4;
3128  string rtr(agent_->router_id().to_string());
3129  item.entry.next_hop.address = rtr;
3130  item.entry.next_hop.label = 0;
3131 
3132  //Build the pugi tree
3133  pugi->AddNode("iq", "");
3134  pugi->AddAttribute("type", "set");
3135  pugi->AddAttribute("from", channel_->FromString());
3136  std::string to(channel_->ToString());
3137  to += "/";
3138  to += XmppInit::kBgpPeer;
3139  pugi->AddAttribute("to", to);
3140 
3141  std::string pubsub_id("pubsub_b");
3142  stringstream str_id;
3143  str_id << id;
3144  pubsub_id += str_id.str();
3145  pugi->AddAttribute("id", pubsub_id);
3146 
3147  pugi->AddChildNode("pubsub", "");
3148  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3149  pugi->AddChildNode("publish", "");
3150  stringstream ss_node;
3151  ss_node << item.entry.nlri.af << "/"
3152  << item.entry.nlri.safi << "/"
3153  << route->vrf()->GetExportName() << "/"
3154  << route->GetAddressString();
3155  std::string node_id(ss_node.str());
3156  pugi->AddAttribute("node", node_id);
3157  pugi->AddChildNode("item", "");
3158 
3159  pugi::xml_node node = pugi->FindNode("item");
3160 
3161  //Call Auto-generated Code to encode the struct
3162  item.Encode(&node);
3163 
3164  pugi->doc().print(*xml_writer, "", pugi::format_default,
3165  pugi::encoding_utf8);
3166  // send data
3167  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3168  repr.clear();
3169 
3170  pugi->DeleteNode("pubsub");
3171  pugi->ReadNode("iq");
3172 
3173  stringstream collection_id;
3174  collection_id << "collection" << id++;
3175  pugi->ModifyAttribute("id", collection_id.str());
3176  pugi->AddChildNode("pubsub", "");
3177  pugi->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
3178  pugi->AddChildNode("collection", "");
3179 
3180  pugi->AddAttribute("node", route->vrf()->GetName());
3181  if (associate) {
3182  pugi->AddChildNode("associate", "");
3183  } else {
3184  pugi->AddChildNode("dissociate", "");
3185  }
3186  pugi->AddAttribute("node", node_id);
3187 
3188  pugi->doc().print(*xml_writer, "", pugi::format_default,
3189  pugi::encoding_utf8);
3190  // send data for BgpAf::Mvpn
3191  SendUpdate(reinterpret_cast<const uint8_t *>(repr.c_str()), repr.length());
3193  return true;
3194 }
3195 
3197  AgentRoute *route,
3198  const Ip4Address *nh_ip,
3199  std::string vn,
3200  uint32_t label,
3201  uint32_t tunnel_bmap,
3202  const SecurityGroupList *sg_list,
3203  const TagList *tag_list,
3204  const CommunityList *communities,
3205  const std::string &destination,
3206  const std::string &source,
3207  const PathPreference
3208  &path_preference) {
3209  if (!peer) return false;
3210 
3212  route->vrf()->GetName(),
3213  route->ToString(), true, label);
3214  return (peer->ControllerSendEvpnRouteCommon(route,
3215  nh_ip,
3216  vn,
3217  sg_list,
3218  tag_list,
3219  communities,
3220  label,
3221  tunnel_bmap,
3222  destination,
3223  source,
3224  path_preference,
3225  true));
3226 }
3227 
3229  AgentRoute *route,
3230  std::string vn,
3231  uint32_t label,
3232  const std::string &destination,
3233  const std::string &source,
3234  uint32_t tunnel_bmap) {
3235  if (!peer) return false;
3236 
3238  route->vrf()->GetName(),
3239  route->ToString(), false, label);
3240  Ip4Address nh_ip = Ip4Address(0);
3241  return (peer->ControllerSendEvpnRouteCommon(route,
3242  &nh_ip,
3243  vn,
3244  NULL,
3245  NULL,
3246  NULL,
3247  label,
3248  tunnel_bmap,
3249  destination,
3250  source,
3251  PathPreference(),
3252  false));
3253 }
3254 
3256  AgentRoute *route,
3257  const Ip4Address *nexthop_ip,
3258  const VnListType &vn_list,
3259  uint32_t label,
3260  TunnelType::TypeBmap bmap,
3261  const SecurityGroupList *sg_list,
3262  const TagList *tag_list,
3263  const CommunityList *communities,
3265  const PathPreference &path_preference,
3266  const EcmpLoadBalance &ecmp_load_balance,
3267  uint32_t native_vrf_id)
3268 {
3269  if (!peer) return false;
3270 
3272  peer->GetBgpPeerName(),
3273  route->vrf()->GetName(),
3274  route->ToString(),
3275  true, label);
3276  bool ret = false;
3278  ||(type == Agent::INET4_MPLS)) &&
3279  (peer->agent()->simulate_evpn_tor() == false)) {
3280  ret = peer->ControllerSendV4V6UnicastRouteCommon(route, vn_list,
3281  sg_list, tag_list, communities, label,
3282  bmap, path_preference, true,
3283  type, ecmp_load_balance, native_vrf_id);
3284  }
3285  if (type == Agent::EVPN) {
3286  std::string vn;
3287  if (vn_list.size())
3288  vn = *vn_list.begin();
3289  ret = peer->ControllerSendEvpnRouteCommon(route, nexthop_ip, vn,
3290  sg_list, tag_list, communities, label,
3291  bmap, "", "",
3292  path_preference, true);
3293  }
3294  return ret;
3295 }
3296 
3298  AgentRoute *route,
3299  const VnListType &vn_list,
3300  uint32_t label,
3301  TunnelType::TypeBmap bmap,
3302  const SecurityGroupList *sg_list,
3303  const TagList *tag_list,
3304  const CommunityList *communities,
3306  const PathPreference
3307  &path_preference)
3308 {
3309  if (!peer) return false;
3310 
3312  peer->GetBgpPeerName(),
3313  route->vrf()->GetName(),
3314  route->ToString(),
3315  false, 0);
3316  bool ret = false;
3317  if (((type == Agent::INET4_UNICAST) || (type == Agent::INET6_UNICAST)) &&
3318  (peer->agent()->simulate_evpn_tor() == false)) {
3319  EcmpLoadBalance ecmp_load_balance;
3320  ret = peer->ControllerSendV4V6UnicastRouteCommon(route, vn_list,
3321  sg_list, tag_list, communities,
3322  label,
3323  bmap,
3324  path_preference,
3325  false,
3326  type,
3327  ecmp_load_balance,
3329  }
3330  if (type == Agent::EVPN) {
3331  Ip4Address nh_ip(0);
3332  std::string vn;
3333  if (vn_list.size())
3334  vn = *vn_list.begin();
3335  ret = peer->ControllerSendEvpnRouteCommon(route, &nh_ip,
3336  vn, NULL, NULL, NULL,
3337  label, bmap, "", "",
3338  path_preference, false);
3339  }
3340  return ret;
3341 }
3342 
3344  AgentRoute *route) {
3345  if (!peer) return false;
3346 
3348  route->vrf()->GetName(),
3349  route->ToString(), true, 0);
3350 
3351  if (route->GetTableType() == Agent::INET4_MULTICAST) {
3352  return peer->ControllerSendIPMcastRouteCommon(route, true);
3353  }
3354 
3355  return peer->ControllerSendMcastRouteCommon(route, true);
3356 }
3357 
3359  AgentRoute *route) {
3360  if (!peer) return false;
3361 
3363  route->vrf()->GetName(),
3364  route->ToString(), false, 0);
3365 
3366  if (route->GetTableType() == Agent::INET4_MULTICAST) {
3367  return peer->ControllerSendIPMcastRouteCommon(route, false);
3368  }
3369 
3370  return peer->ControllerSendMcastRouteCommon(route, false);
3371 }
3372 
3375  bgp_peer_id()->DeleteStale();
3377  if (agent()->mulitcast_builder() == this) {
3379  controller()->multicast_sequence_number());
3380  }
3381 }
3382 
3384  //This is a callback from walker for bgp peer.
3385  //It may happen that channel went down and stop of this walk was executed.
3386  //However stop of the walk is enqueued and by that time, walk done for
3387  //previously started walk for this peer gets executed.
3388  //This can result in channel_ being NULL on walk done call.
3389  if (channel_ == NULL) {
3390  return;
3391  }
3392 
3393  string msg;
3394  msg += "\n<message from=\"";
3395  msg += channel_->FromString();
3396  msg += "\" to=\"";
3397  msg += channel_->ToString();
3398  msg += "/";
3399  msg += XmppInit::kBgpPeer;
3400  msg += "\">";
3401  msg += "\n\t<event xmlns=\"http://jabber.org/protocol/pubsub\">";
3402  msg = (msg + "\n<items node=\"") + XmppInit::kEndOfRibMarker +
3403  "\"></items>";
3404  msg += "\n\t</event>\n</message>\n";
3405 
3406  if (channel_->connection()) {
3407  channel_->connection()->Send((const uint8_t *) msg.data(), msg.size());
3409  }
3410 }
3411 
3413 
3414  if (agent_->connection_state() == NULL)
3415  return;
3416 
3417  boost::asio::ip::tcp::endpoint ep;
3418  boost::system::error_code ec;
3419  string last_state_name;
3420  ep.address(AddressFromString(
3422  uint16_t port = agent_->controller_ifmap_xmpp_port(xs_idx_);
3423  ep.port(port);
3424  const string name = agent_->xmpp_control_node_prefix() +
3425  ep.address().to_string();
3426  XmppChannel *xc = GetXmppChannel();
3427  if (xc) {
3428  last_state_name = xc->LastStateName();
3429  }
3430  if (state == xmps::READY) {
3431  agent_->connection_state()->Update(ConnectionType::XMPP, name,
3432  ConnectionStatus::UP, ep,
3433  last_state_name);
3434  } else {
3435  agent_->connection_state()->Update(ConnectionType::XMPP, name,
3436  ConnectionStatus::DOWN, ep,
3437  last_state_name);
3438  }
3439 }
3440 
3442  if (bgp_peer_id()) {
3444  boost::bind(&AgentXmppChannel::EndOfRibTx, this));
3445  }
3446 }
3447 
3449  if (bgp_peer_id()) {
3451  }
3452 }
3453 
3454 template <typename TYPE>
3455 void AgentXmppChannel::BuildTagList(const TYPE *item,
3456  TagList *tag_list) {
3457  *tag_list = item->entry.next_hops.next_hop[0].tag_list.tag;
3458  std::sort(tag_list->begin(), tag_list->end());
3459 }
boost::system::error_code Inet6PrefixParse(const string &str, Ip6Address *addr, int *plen)
Definition: address.cc:144
boost::system::error_code Ip4PrefixParse(const string &str, Ip4Address *addr, int *plen)
Definition: address.cc:107
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
boost::asio::ip::address IpAddress
Definition: address.h:13
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
IpAddress AddressFromString(const std::string &ip_address_str, boost::system::error_code *ec)
std::vector< int > TagList
Definition: agent.h:202
#define MAX_XMPP_SERVERS
Definition: agent.h:291
std::vector< int > SecurityGroupList
Definition: agent.h:201
std::vector< Ip4Address > AddressList
Definition: agent.h:217
std::set< std::string > VnListType
Definition: agent.h:212
std::vector< std::string > CommunityList
Definition: bgp_config.h:347
@ INET
Definition: address.h:26
void NotifyAll(AgentXmppChannel *peer)
static uint64_t NewSeqNumber()
ConfigCleanupTimer * config_cleanup_timer()
EndOfConfigTimer * end_of_config_timer()
bool mvpn_ipv4_enable() const
Definition: agent_param.h:564
TunnelType::Type tunnel_type() const
Definition: agent_path.h:266
NextHop * nexthop() const
Definition: agent_path.cc:87
uint32_t GetActiveLabel() const
Definition: agent_path.cc:79
uint32_t vxlan_id() const
Definition: agent_path.h:265
uint32_t label() const
Definition: agent_path.h:264
bool etree_leaf() const
Definition: agent_path.h:388
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:389
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge,...
Definition: agent_route.h:109
VrfEntry * vrf_entry() const
Definition: agent_route.cc:459
AgentRoute * FindActiveEntry(const AgentRouteKey *key)
Definition: agent_route.cc:417
Base class for all Route entries in agent.
Definition: agent_route.h:224
AgentPath * GetLocalVmPortPath() const
Definition: agent_route.cc:845
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:817
virtual const std::string GetSourceAddressString() const =0
VrfEntry * vrf() const
Definition: agent_route.h:275
virtual const std::string GetAddressString() const =0
virtual std::string ToString() const =0
bool is_multicast() const
Definition: agent_route.h:274
virtual AgentPath * FindPath(const Peer *peer) const
Definition: agent_route.cc:865
const std::string & intf_route_type() const
Definition: agent_route.h:277
virtual Agent::RouteTableType GetTableType() const =0
AgentPath * FindLocalVmPortPath() const
Definition: agent_route.cc:743
void incr_xmpp_in_msgs(uint8_t idx)
Definition: agent_stats.h:63
void incr_xmpp_reconnects(uint8_t idx)
Definition: agent_stats.h:58
void incr_xmpp_out_msgs(uint8_t idx)
Definition: agent_stats.h:66
Agent * agent() const
static bool ControllerSendMcastRouteDelete(AgentXmppChannel *peer, AgentRoute *route)
void AddEvpnEcmpRoute(std::string vrf_name, const MacAddress &mac, const IpAddress &ip, uint32_t plen, autogen::EnetItemType *item, const VnListType &vn_list)
std::string channel_str_
LlgrStaleTimer * llgr_stale_timer()
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)
ControllerEcmpRoute * BuildEcmpData(TYPE *item, const VnListType &vn_list, const EcmpLoadBalance &ecmp_load_balance, const AgentRouteTable *rt_table, const std::string &prefix_str)
virtual bool SendUpdate(const uint8_t *msg, size_t msgsize)
bool ControllerSendIPMcastRouteCommon(AgentRoute *route, bool associate)
virtual void ReceiveV4V6Update(XmlPugi *pugi)
void AddMulticastEvpnRoute(const std::string &vrf_name, const IpAddress &source, const IpAddress &group, autogen::EnetItemType *item)
bool ControllerSendMvpnRouteCommon(AgentRoute *route, bool associate)
void AddMplsRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item)
static bool ControllerSendCfgSubscribe(AgentXmppChannel *peer)
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)
uint8_t GetXmppServerIdx()
static void XmppClientChannelEvent(AgentXmppChannel *peer, xmps::PeerState state)
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)
virtual void ReceiveMulticastUpdate(XmlPugi *pugi)
EndOfRibRxTimer * end_of_rib_rx_timer()
void AddRemoteMplsRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item, const VnListType &vn_list)
uint64_t sequence_number() const
virtual std::string ToString() const
void AddRemoteRoute(std::string vrf_name, IpAddress prefix_addr, uint32_t prefix_len, autogen::ItemType *item, const VnListType &vn_list)
XmppChannel * GetXmppChannel()
static bool SetConfigPeer(AgentXmppChannel *peer)
static bool IsBgpPeerActive(const Agent *agent, AgentXmppChannel *peer)
void AddInetMplsEcmpRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item, const VnListType &vn_list)
static void CleanConfigStale(AgentXmppChannel *agent_xmpp_channel)
bool BuildAndSendEvpnDom(autogen::EnetItemType &item, std::stringstream &ss_node, const AgentRoute *route, 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)
virtual void ReceiveUpdate(const XmppStanza::XmppMessage *msg)
void AddEvpnRoute(const std::string &vrf_name, std::string mac_addr, const IpAddress &ip, uint32_t plen, autogen::EnetItemType *item)
std::string GetMcastLabelRange()
static bool IsXmppChannelActive(const Agent *agent, AgentXmppChannel *peer)
void UpdateConnectionInfo(xmps::PeerState state)
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)
void GetVnList(const TYPE &nexthops, VnListType *vn_list)
static bool ControllerSendMcastRouteAdd(AgentXmppChannel *peer, AgentRoute *route)
void ReceiveInternal(const XmppStanza::XmppMessage *msg)
void BuildTagList(const TYPE *item, TagList *tag_list)
virtual void WriteReadyCb(const boost::system::error_code &ec)
boost::scoped_ptr< EndOfRibRxTimer > end_of_rib_rx_timer_
AgentXmppChannel(Agent *agent, const std::string &xmpp_server, const std::string &label_range, uint8_t xs_idx)
static bool ControllerSendSubscribe(AgentXmppChannel *peer, VrfEntry *vrf, bool subscribe)
virtual void ReceiveMvpnUpdate(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)
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)
static bool ControllerSendVmCfgSubscribe(AgentXmppChannel *peer, const boost::uuids::uuid &vm_id, bool subscribe)
BgpPeer * bgp_peer_id()
std::string GetXmppServer()
virtual void ReceiveInet4MplsUpdate(XmlPugi *pugi)
bool ControllerSendMcastRouteCommon(AgentRoute *route, bool associate)
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)
boost::scoped_ptr< EndOfRibTxTimer > end_of_rib_tx_timer_
EndOfRibTxTimer * end_of_rib_tx_timer()
boost::scoped_ptr< LlgrStaleTimer > llgr_stale_timer_
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)
InetUnicastAgentRouteTable * PrefixToRouteMplsTable(const std::string &vrf_name, const IpAddress &prefix_addr)
void RegisterXmppChannel(XmppChannel *channel)
void AddInetEcmpRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item, const VnListType &vn_list)
void ReceiveBgpMessage(std::unique_ptr< XmlBase > impl)
virtual ~AgentXmppChannel()
InetUnicastAgentRouteTable * PrefixToRouteTable(const std::string &vrf_name, const IpAddress &prefix_addr)
virtual void ReceiveEvpnUpdate(XmlPugi *pugi)
static void SetMulticastPeer(AgentXmppChannel *old_peer, AgentXmppChannel *new_peer)
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)
XmppChannel * channel_
bool IsEcmp(const TYPE &nexthops)
static void HandleAgentXmppClientChannelEvent(AgentXmppChannel *peer, xmps::PeerState state)
std::string GetBgpPeerName() const
void AddRoute(std::string vrf_name, IpAddress ip, uint32_t plen, autogen::ItemType *item)
Definition: agent.h:360
void set_ifmap_active_xmpp_server(const std::string &addr, uint8_t xs_idx)
Definition: agent.h:784
AgentXmppChannel * mulitcast_builder()
Definition: agent.h:897
AgentXmppChannel * controller_xmpp_channel(uint8_t idx) const
Definition: agent.h:811
const std::string & ifmap_active_xmpp_server() const
Definition: agent.h:783
std::vector< string > & GetControllerlist()
Definition: agent.h:694
VNController * controller() const
Definition: agent.cc:984
OperDB * oper_db() const
Definition: agent.cc:1016
AddressList vhost_default_gateway() const
Definition: agent.h:658
Ip4Address vhost_prefix() const
Definition: agent.h:650
AgentParam * params() const
Definition: agent.h:1226
RouteTableType
Definition: agent.h:417
@ INET4_MULTICAST
Definition: agent.h:420
@ INET6_UNICAST
Definition: agent.h:423
@ BRIDGE
Definition: agent.h:422
@ INET4_MPLS
Definition: agent.h:424
@ INET4_UNICAST
Definition: agent.h:419
@ EVPN
Definition: agent.h:421
const std::string & fabric_policy_vrf_name() const
Definition: agent.h:910
VrfTable * vrf_table() const
Definition: agent.h:487
const Peer * local_peer() const
Definition: agent.h:1024
const Peer * local_vm_export_peer() const
Definition: agent.h:1042
bool tsn_enabled() const
Definition: agent.h:1164
uint32_t vhost_prefix_len() const
Definition: agent.h:655
bool simulate_evpn_tor() const
Definition: agent.h:1157
const Peer * local_vm_peer() const
Definition: agent.h:1025
IFMapAgentParser * ifmap_parser() const
Definition: agent.h:1174
const Peer * multicast_peer() const
Definition: agent.h:1032
const std::string & controller_ifmap_xmpp_server(uint8_t idx) const
Definition: agent.h:732
const uint16_t controller_ifmap_xmpp_port(uint8_t idx) const
Definition: agent.h:759
void set_controller_xmpp_channel_setup_time(uint64_t time, uint8_t idx)
Definition: agent.h:806
VrfEntry * fabric_vrf() const
Definition: agent.h:917
static const std::string & xmpp_control_node_prefix()
Definition: agent.h:449
void set_cn_mcast_builder(AgentXmppChannel *peer)
Definition: agent.cc:579
bool tor_agent_enabled() const
Definition: agent.h:1166
const Interface * vhost_interface() const
Definition: agent.h:937
AgentStats * stats() const
Definition: agent.cc:884
process::ConnectionState * connection_state() const
Definition: agent.h:955
AgentIfMapXmppChannel * ifmap_xmpp_channel(uint8_t idx) const
Definition: agent.h:794
void reset_ifmap_active_xmpp_server()
Definition: agent.h:789
const std::string & fabric_vrf_name() const
Definition: agent.h:905
Ip4Address router_id() const
Definition: agent.h:668
const int8_t & ifmap_active_xmpp_server_index() const
Definition: agent.h:782
const Peer * multicast_tree_builder_peer() const
Definition: agent.h:1034
MplsTable * mpls_table() const
Definition: agent.h:512
@ Enet
Definition: bgp_af.h:32
@ Unicast
Definition: bgp_af.h:25
@ MVpn
Definition: bgp_af.h:27
@ Mcast
Definition: bgp_af.h:31
@ Mpls
Definition: bgp_af.h:26
@ L2Vpn
Definition: bgp_af.h:21
@ IPv4
Definition: bgp_af.h:19
@ IPv6
Definition: bgp_af.h:20
void StopDeleteStale()
Definition: peer.cc:235
void StopPeerNotifyRoutes()
Definition: peer.cc:155
void PeerNotifyRoutes(WalkDoneCb cb)
Definition: peer.cc:149
void DeleteStale()
Definition: peer.cc:224
ClonedLocalPathList::iterator ClonedLocalPathListIter
ClonedLocalPathList & cloned_local_path_list()
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)
static const uint64_t kInvalidPeerIdentifier
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)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
int ListenerId
Definition: db_table.h:62
void StopRouteExports()
Definition: peer.h:137
bool AllSet() const
const std::string & destination_port_str() const
const std::string & source_port_str() const
const std::string & ip_protocol_str() const
const std::string & source_ip_str() const
const std::string & destination_ip_str() const
void GetStringVector(std::vector< std::string > &string_vector) const
void AddLocalVmRouteReq(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t ethernet_tag, LocalVmRoute *data)
void AddClonedLocalPathReq(const Peer *peer, const string &vrf_name, const MacAddress &mac, const IpAddress &ip_addr, uint32_t ethernet_tag, ClonedLocalPath *data)
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 AddType5Route(const Peer *peer, const std::string &vrf_name, const IpAddress &ip_addr, uint32_t ethernet_tag, EvpnRoutingData *data, uint8_t plen=0)
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)
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)
uint32_t ethernet_tag() const
uint8_t prefix_length() const
!
const MacAddress & mac() const
const AgentPath * FindOvsPath() const
const Ip4Address & src_ip_addr() const
const Ip4Address & dest_ip_addr() const
InetUnicastRouteEntry * FindResolveRoute(const Ip4Address &ip)
static void AddMplsRouteReq(const Peer *peer, const string &vrf_name, const IpAddress &dst_addr, uint8_t plen, AgentRouteData *data)
static void AddRemoteVmRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &vm_addr, uint8_t plen, AgentRouteData *data)
InetUnicastRouteEntry * FindLPM(const IpAddress &ip)
void AddClonedLocalPathReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, ClonedLocalPath *data)
void AddInetInterfaceRouteReq(const Peer *peer, const string &vm_vrf, const Ip4Address &addr, uint8_t plen, InetInterfaceRoute *data)
void AddLocalVmRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, LocalVmRoute *data)
static void DeleteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
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)
static void DeleteMplsRouteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
void AddVlanNHRouteReq(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, VlanNhRoute *data)
void AddVhostMplsRoute(const IpAddress &vhost_addr, const Peer *peer)
uint8_t prefix_length() const
!
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:730
const Interface * GetInterface() const
Definition: nexthop.h:1293
uint8_t GetFlags() const
Definition: nexthop.h:1300
@ VM_INTERFACE
Definition: interface.h:35
const MacAddress & mac() const
Definition: interface.h:131
const std::string & name() const
Definition: interface.h:114
Type type() const
Definition: interface.h:112
std::string ToString() const
Definition: mac_address.cc:53
bool IsMulticast() const
Definition: mac_address.cc:37
static const MacAddress & BroadcastMac()
Definition: mac_address.h:152
bool IsZero() const
Definition: mac_address.cc:29
Definition: mpls.h:52
const NextHop * nexthop() const
Definition: mpls.h:80
static const uint32_t kInvalidLabel
Definition: mpls.h:101
MplsLabel * FindMplsLabel(uint32_t label)
Definition: mpls.cc:399
static const uint32_t kInvalidExportLabel
Definition: mpls.h:102
bool FlushPeerInfo(uint64_t peer_sequence)
Definition: multicast.cc:1408
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
static void GetMulticastMacFromIp(const Ip4Address &ip, MacAddress &mac)
Definition: multicast.h:483
uint32_t GetEvpnMulticastSGFlags(const std::string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1986
void ModifyMvpnVrfRegistration(const Peer *peer, const std::string &vrf_name, const Ip4Address &group, const Ip4Address &source, uint64_t peer_identifier)
Definition: multicast.cc:1348
static MulticastHandler * GetInstance()
Definition: multicast.h:369
@ L2_RECEIVE
Definition: nexthop.h:346
@ VLAN
Definition: nexthop.h:355
@ COMPOSITE
Definition: nexthop.h:354
@ INTERFACE
Definition: nexthop.h:351
@ VRF
Definition: nexthop.h:350
Type GetType() const
Definition: nexthop.h:405
VxlanRoutingManager * vxlan_routing_manager() const
Definition: operdb_init.h:98
MulticastHandler * multicast() const
Definition: operdb_init.h:53
GlobalSystemConfig * global_system_config() const
Definition: operdb_init.h:85
uint32_t loc_sequence() const
Definition: agent_path.h:39
uint32_t preference() const
Definition: agent_path.h:41
uint32_t sequence() const
Definition: agent_path.h:40
Definition: peer.h:44
@ BGP_PEER
Definition: peer.h:51
void incr_sequence_number()
Definition: peer.h:95
Definition: trace.h:220
static TypeBmap MplsoMplsType()
Definition: nexthop.h:313
static TypeBmap VxlanType()
Definition: nexthop.h:311
static TypeBmap NativeType()
Definition: nexthop.h:325
static TypeBmap UDPType()
Definition: nexthop.h:324
static TypeBmap GREType()
Definition: nexthop.h:323
static Type ComputeType(TypeBmap bmap)
Definition: nexthop.cc:33
uint32_t TypeBmap
Definition: nexthop.h:248
static TypeBmap MplsType()
Definition: nexthop.h:312
AgentIfMapVmExport * agent_ifmap_vm_export() const
void FlushTimedOutChannels(uint8_t index)
TunnelType::TypeBmap GetTypeBitmap(const autogen::EnetTunnelEncapsulationListType &encap)
void Enqueue(ControllerWorkQueueDataType data)
void ReConnectXmppServer()
uint64_t multicast_sequence_number()
void increment_multicast_sequence_number()
uint16_t GetVlanTag() const
Definition: nexthop.h:1544
const boost::uuids::uuid & GetIfUuid() const
Definition: nexthop.cc:1698
Definition: vn.h:151
VrfEntry * GetVrf() const
Definition: vn.h:170
bool vxlan_routing_vn() const
Definition: vn.h:256
Definition: vrf.h:86
const std::string & GetExportName()
Definition: vrf.h:121
const string & GetName() const
Definition: vrf.h:100
int rd() const
Definition: vrf.h:220
InetUnicastAgentRouteTable * GetInet4MplsUnicastRouteTable() const
Definition: vrf.cc:323
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
static const uint32_t kInvalidIndex
Definition: vrf.h:88
uint32_t isid() const
Definition: vrf.h:197
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable() const
Definition: vrf.cc:338
bool routing_vrf() const
Definition: vrf.h:223
uint32_t vxlan_id() const
Definition: vrf.h:165
VnEntry * si_vn_ref() const
Definition: vrf.h:102
VnEntry * vn() const
Definition: vrf.h:101
static void Notify(const Agent *agent, AgentXmppChannel *, DBTablePartBase *partition, DBEntryBase *e)
VrfEntry * FindVrfFromName(const string &name)
Definition: vrf.cc:873
InetUnicastAgentRouteTable * GetInet6UnicastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:922
AgentRouteTable * GetEvpnRouteTable(const std::string &vrf_name)
Definition: vrf.cc:913
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:898
InetUnicastAgentRouteTable * GetInet4MplsUnicastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:904
static const uint32_t kInvalidvxlan_id
Definition: vxlan.h:141
static bool IsVxlanAvailable(const Agent *agent)
Checks whether VxLAN routing manager is enabled or not.
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, const std::vector< std::string > &peer_sources)
Advertises an EVPN route received using XMPP channel.
static const Peer * routing_vrf_vxlan_bgp_peer_
A pointer to the Peer where all BGP routes are stored.
static bool IsRoutingVrf(const VrfEntry *vrf)
Determines whether the pointer to the VRF instance is of routing type.
const pugi::xml_document & doc()
Definition: xml_pugi.h:68
virtual void RegisterReceive(xmps::PeerId, ReceiveCb)=0
virtual void UnRegisterReceive(xmps::PeerId)=0
virtual const XmppConnection * connection() const =0
virtual const std::string & ToString() const =0
virtual xmps::PeerState GetPeerState() const =0
virtual std::string LastStateName() const =0
virtual const std::string & FromString() const =0
virtual void UnRegisterWriteReady(xmps::PeerId id)=0
virtual bool Send(const uint8_t *, size_t, xmps::PeerId, SendReadyCb)=0
bool Send(const uint8_t *data, size_t size, const std::string *msg_str=NULL)
static const char * kConfigPeer
Definition: xmpp_init.h:23
static const char * kBgpPeer
Definition: xmpp_init.h:24
static const char * kFqnPrependAgentNodeJID
Definition: xmpp_init.h:28
static const char * kEndOfRibMarker
Definition: xmpp_init.h:26
XmppMessageType type
Definition: xmpp_proto.h:57
std::unique_ptr< XmlBase > dom
Definition: xmpp_proto.h:62
@ MESSAGE_STANZA
Definition: xmpp_proto.h:18
static XmlBase * AllocXmppXmlImpl(const char *doc=NULL)
Definition: xmpp_proto.h:167
#define CONTROLLER_TRACE(obj,...)
#define CONTROLLER_INFO_TRACE(obj,...)
#define CONTROLLER_TX_CONFIG_TRACE(obj, index,...)
static int ParseEvpnAddress(const string &str, IpAddress *addr, const MacAddress &mac)
void PopulateEcmpHashFieldsToUse(ItemType &item, const EcmpLoadBalance &ecmp_load_balance)
void InetRequestDelete(const IpAddress &ip_address, const int prefix_len, std::string vrf_name, const Peer *bgp_peer)
static bool FillEvpnOlist(Agent *agent, EnetOlistType &olist, TunnelOlist *tunnel_olist)
static void GetEcmpHashFieldsToUse(TYPE *item, EcmpLoadBalance &ecmp_load_balance)
static const std::string LoadBalanceDecision
uint8_t type
Definition: load_balance.h:2
#define LOG(_Level, _Msg)
Definition: logging.h:33
std::vector< OlistTunnelEntry > TunnelOlist
Definition: multicast.h:68
@ READY
Definition: xmpp_channel.h:17
@ TIMEDOUT
Definition: xmpp_channel.h:19
@ UNKNOWN
Definition: xmpp_channel.h:16
@ NOT_READY
Definition: xmpp_channel.h:18
static int compare(const Type &lhs, const Type &rhs)
@ ADD_DEL_CHANGE
Definition: agent_db.h:98
@ DB_ENTRY_ADD_CHANGE
Definition: db_table.h:38
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
virtual void Start(AgentXmppChannel *agent_xmpp_channel)
uint64_t end_of_rib_rx_time_
uint64_t last_route_published_time_
uint64_t end_of_rib_tx_time_
virtual void Start(AgentXmppChannel *agent_xmpp_channel)
A structure to hold path parameters during the transfer (routes leaking) of data between VRF instance...
Definition: vrf.h:22
static XmppXmlImplFactory * Instance()
Definition: xml_base.cc:18
static uint64_t UTCTimestampUsec()
Definition: time_util.h:13
boost::uuids::uuid uuid