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