OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bgp_as_service.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <string>
6 #include <vector>
7 #include <boost/uuid/uuid_io.hpp>
8 
9 #include <vnc_cfg_types.h>
10 #include <base/logging.h>
11 #include <base/string_util.h>
13 #include <base/address_util.h>
14 #include <cmn/agent_cmn.h>
15 #include <init/agent_param.h>
16 #include <ifmap/ifmap_node.h>
17 #include <ifmap/ifmap_link.h>
18 #include <cfg/cfg_init.h>
19 #include <cmn/agent.h>
20 #include <oper/operdb_init.h>
21 #include <oper/bgp_as_service.h>
22 #include <oper/bgp_router.h>
23 #include <oper/audit_list.h>
24 #include <oper/agent_sandesh.h>
25 #include <oper/config_manager.h>
26 #include <oper/vn.h>
27 #include <bgp_schema_types.h>
28 
29 #include <arpa/inet.h>
30 #include <netinet/in.h>
31 #include <fcntl.h>
36 
38  ("BgpAsAService", 500));
39 
41  agent_(agent),
42  bgp_as_a_service_entry_map_(),
43  bgp_as_a_service_port_map_(),
44  service_delete_cb_list_(), health_check_cb_list_() {
45 }
46 
48 }
49 
52 }
53 
56 }
57 
59  if (rhs->health_check_configured_)
60  rhs->new_health_check_add_ = true;
61  list_.insert(*rhs);
62 }
63 
65  const BgpAsAServiceEntry *rhs) {
66  lhs->dest_port_ = rhs->dest_port_;
69  if (rhs->health_check_configured_) {
70  if (lhs->hc_delay_usecs_ != rhs->hc_delay_usecs_ ||
71  lhs->hc_timeout_usecs_ != rhs->hc_timeout_usecs_ ||
72  lhs->hc_retries_ != rhs->hc_retries_) {
73  // if HC properties change, trigger update
74  lhs->new_health_check_add_ = true;
75  lhs->hc_delay_usecs_ = rhs->hc_delay_usecs_;
77  lhs->hc_retries_ = rhs->hc_retries_;
78  }
79  }
82  if (lhs->health_check_configured_) {
83  lhs->old_health_check_delete_ = false;
84  lhs->new_health_check_add_ = true;
85  lhs->old_health_check_uuid_ = boost::uuids::nil_uuid();
87  } else {
88  lhs->old_health_check_delete_ = true;
89  lhs->new_health_check_add_ = false;
91  lhs->health_check_uuid_ = boost::uuids::nil_uuid();
92  }
93  return;
94  }
95  if (lhs->health_check_uuid_ != rhs->health_check_uuid_) {
96  // delete old health check and add new
97  lhs->new_health_check_add_ = true;
98  lhs->old_health_check_delete_ = true;
101  }
102 }
103 
105  it->set_del_pending(true);
106 }
107 
109  list_.clear();
110 }
111 
113  const BgpAsAServiceEntryList &list) {
114  for (BgpAsAServiceEntryListConstIterator iter = list.begin();
115  iter != list.end(); ++iter) {
116  if (!health_check_cb_list_.empty() && iter->new_health_check_add_ &&
117  iter->health_check_uuid_ != boost::uuids::nil_uuid()) {
118  std::vector<HealthCheckCb>::iterator hcb_it =
119  health_check_cb_list_.begin();
120  while (hcb_it != health_check_cb_list_.end()) {
121  (*hcb_it)(vm_uuid, iter->source_port_,
122  iter->health_check_uuid_, true);
123  hcb_it++;
124  }
125  }
126  iter->new_health_check_add_ = false;
127  }
128 }
129 
130 static const std::string GetBgpRouterVrfName(const Agent *agent,
131  IFMapNode *node) {
132  IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
133  for (DBGraphVertex::adjacency_iterator it = node->begin(table->GetGraph());
134  it != node->end(table->GetGraph()); ++it) {
135  IFMapNode *vrf_node = static_cast<IFMapNode *>(it.operator->());
136  if (agent->config_manager()->SkipNode
137  (vrf_node, agent->cfg()->cfg_vrf_table())) {
138  continue;
139  }
140  return vrf_node->name();
141  }
142  return std::string();
143 }
144 
145 static const std::string GetControlNodeZoneName(IFMapNode *node) {
146  IFMapAgentTable *table =
147  static_cast<IFMapAgentTable *>(node->table());
148  for (DBGraphVertex::adjacency_iterator it = node->begin(table->GetGraph());
149  it != node->end(table->GetGraph()); ++it) {
150  IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
151  if (strcmp(adj_node->table()->Typename(),
153  return adj_node->name();
154  }
155  }
156  return std::string();
157 }
158 
160  std::list<IFMapNode *> &bgp_router_nodes,
161  BgpAsAServiceEntryList &new_list,
162  const std::string &vm_vrf_name,
163  const boost::uuids::uuid &vm_uuid) {
164  IFMapAgentTable *table =
165  static_cast<IFMapAgentTable *>(bgp_as_a_service_node->table());
166  autogen::BgpAsAService *bgp_as_a_service =
167  dynamic_cast<autogen::BgpAsAService *>(bgp_as_a_service_node->GetObject());
168  assert(bgp_as_a_service);
169 
170  IpAddress peer_ip;
171  uint32_t source_port = 0;
172  bool health_check_configured = false;
173  boost::uuids::uuid health_check_uuid = boost::uuids::nil_uuid();
174  uint64_t hc_delay_usecs = 0;
175  uint64_t hc_timeout_usecs = 0;
176  uint32_t hc_retries = 0;
177  std::string primary_control_node_zone;
178  std::string secondary_control_node_zone;
179 
180  // Find the health check config first
181  for (DBGraphVertex::adjacency_iterator it = bgp_as_a_service_node->begin(table->GetGraph());
182  it != bgp_as_a_service_node->end(table->GetGraph()); ++it) {
183  IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
184 
185  if (adj_node->table() == agent_->cfg()->cfg_health_check_table()) {
186  if (agent_->config_manager()->SkipNode(adj_node)) {
187  continue;
188  }
189  autogen::ServiceHealthCheck *hc =
190  static_cast<autogen::ServiceHealthCheck *> (adj_node->GetObject());
191  assert(hc);
192  // consider only BFD health check for BGPaaS
193  if (hc->properties().monitor_type.find("BFD") == std::string::npos)
194  continue;
195  health_check_configured = true;
196  autogen::IdPermsType id_perms = hc->id_perms();
197  CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
198  health_check_uuid);
199  hc_delay_usecs = hc->properties().delay * 1000000 +
200  hc->properties().delayUsecs;
201  hc_timeout_usecs = hc->properties().timeout * 1000000 +
202  hc->properties().timeoutUsecs;
203  hc_retries = hc->properties().max_retries;
204  }
205 
206  if (strcmp(adj_node->table()->Typename(),
208  autogen::BgpaasControlNodeZone
209  *bgpaas_cnz = static_cast<autogen::BgpaasControlNodeZone *>
210  (adj_node->GetObject());
211  const autogen::BGPaaSControlNodeZoneAttributes &attr =
212  static_cast<autogen::BGPaaSControlNodeZoneAttributes>
213  (bgpaas_cnz->data());
214  const std::string cnz_name = GetControlNodeZoneName(adj_node);
215  if (cnz_name.size()) {
216  if (strcmp(attr.bgpaas_control_node_zone_type.c_str(),
217  "primary") == 0) {
218  primary_control_node_zone = cnz_name;
219  continue;
220  }
221  if (strcmp(attr.bgpaas_control_node_zone_type.c_str(),
222  "secondary") == 0) {
223  secondary_control_node_zone = cnz_name;
224  continue;
225  }
226  }
227  }
228  }
229 
230  //Look for neighbour bgp-router to take the source port
231  for (DBGraphVertex::adjacency_iterator it = bgp_as_a_service_node->begin(table->GetGraph());
232  it != bgp_as_a_service_node->end(table->GetGraph()); ++it) {
233  IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
234  if (strcmp(adj_node->table()->Typename(), BGP_ROUTER_CONFIG_NAME) == 0) {
235  //Verify that bgp-router object is of use for this VMI.
236  //List of valid bgp-router for vmi is in bgp_router_nodes.
237  if (std::find(bgp_router_nodes.begin(), bgp_router_nodes.end(),
238  adj_node) == bgp_router_nodes.end()) {
239  continue;
240  }
241  autogen::BgpRouter *bgp_router=
242  dynamic_cast<autogen::BgpRouter *>(adj_node->GetObject());
243  const std::string &vrf_name =
244  GetBgpRouterVrfName(agent_, adj_node);
245  if (vrf_name.empty() || (vrf_name != vm_vrf_name) ||
246  (strcmp(bgp_router->parameters().router_type.c_str(),
247  VALID_BGP_ROUTER_TYPE) != 0))
248  continue; //Skip the node with no VRF, notification will come.
249  boost::system::error_code ec;
250  peer_ip =
251  IpAddress::from_string(bgp_router->parameters().address, ec);
252  if (ec.value() != 0) {
253  std::stringstream ss;
254  ss << "Ip address parsing failed for ";
255  ss << bgp_router->parameters().address;
256  BGPASASERVICETRACE(Trace, ss.str().c_str());
257  continue;
258  }
259 
260  BgpAsAServiceEntryMapIterator old_bgp_as_a_service_entry_list_iter =
261  bgp_as_a_service_entry_map_.find(vm_uuid);
262  source_port = 0;
263  /*
264  * verify the same session is added again here
265  */
266  if (old_bgp_as_a_service_entry_list_iter !=
268  BgpAsAServiceEntryList temp_bgp_as_a_service_entry_list;
269  temp_bgp_as_a_service_entry_list.insert(
270  BgpAsAServiceEntry(peer_ip,
271  bgp_router->parameters().source_port,
272  bgp_router->parameters().port,
273  health_check_configured,
274  health_check_uuid,
275  bgp_as_a_service->bgpaas_shared(),
276  hc_delay_usecs,
277  hc_timeout_usecs,
278  hc_retries,
279  primary_control_node_zone,
280  secondary_control_node_zone));
281  /*
282  * if it is same session then retain original source port
283  */
284  if (temp_bgp_as_a_service_entry_list ==
285  old_bgp_as_a_service_entry_list_iter->second->list_) {
286  source_port = bgp_router->parameters().source_port;
287  }
288  }
289  if (!source_port) {
290  if (bgp_as_a_service->bgpaas_shared()) {
291  source_port = AddBgpVmiServicePortIndex(
292  bgp_router->parameters().source_port,
293  vm_uuid);
294  } else {
295  source_port = bgp_router->parameters().source_port;
296  }
297  }
298  if (source_port) {
299  new_list.insert(BgpAsAServiceEntry(peer_ip, source_port,
300  bgp_router->parameters().port,
301  health_check_configured,
302  health_check_uuid,
303  bgp_as_a_service->bgpaas_shared(),
304  hc_delay_usecs,
305  hc_timeout_usecs,
306  hc_retries,
307  primary_control_node_zone,
308  secondary_control_node_zone));
309  }
310  }
311  }
312 
313 }
314 
315 void BgpAsAService::ProcessConfig(const std::string &vrf_name,
316  std::list<IFMapNode *> &bgp_router_node_map,
317  std::list<IFMapNode *> &bgp_as_service_node_map,
318  const boost::uuids::uuid &vm_uuid) {
319  std::list<IFMapNode *>::const_iterator it =
320  bgp_as_service_node_map.begin();
321  BgpAsAServiceEntryList new_bgp_as_a_service_entry_list;
322 
323  while (it != bgp_as_service_node_map.end()) {
324  BuildBgpAsAServiceInfo(*it, bgp_router_node_map,
325  new_bgp_as_a_service_entry_list,
326  vrf_name, vm_uuid);
327  it++;
328  }
329 
330  //Audit and enqueue updates/deletes of flow
331  BgpAsAServiceEntryMapIterator old_bgp_as_a_service_entry_list_iter =
332  bgp_as_a_service_entry_map_.find(vm_uuid);
333  bool changed = false;
334  if (old_bgp_as_a_service_entry_list_iter !=
336  //Audit
337  changed = AuditList<BgpAsAServiceList, BgpAsAServiceEntryListIterator>
338  (*(old_bgp_as_a_service_entry_list_iter->second),
339  old_bgp_as_a_service_entry_list_iter->second->list_.begin(),
340  old_bgp_as_a_service_entry_list_iter->second->list_.end(),
341  new_bgp_as_a_service_entry_list.begin(),
342  new_bgp_as_a_service_entry_list.end());
343  } else if (new_bgp_as_a_service_entry_list.size() != 0) {
344  StartHealthCheck(vm_uuid, new_bgp_as_a_service_entry_list);
345  bgp_as_a_service_entry_map_[vm_uuid] =
346  new BgpAsAServiceList(new_bgp_as_a_service_entry_list);
347  }
348 
349  if (changed && !service_delete_cb_list_.empty()) {
350  //Enqueue flow handler request.
352  old_bgp_as_a_service_entry_list_iter->second->list_.begin();
353  while (iter !=
354  old_bgp_as_a_service_entry_list_iter->second->list_.end()) {
355  BgpAsAServiceEntryListIterator prev = iter++;
356  if (prev->del_pending_) {
357  std::vector<ServiceDeleteCb>::iterator scb_it =
358  service_delete_cb_list_.begin();
359  while (scb_it != service_delete_cb_list_.end()) {
360  (*scb_it)(vm_uuid, prev->source_port_);
361  scb_it++;
362  }
363  InterfaceConstRef vm_intf = agent_->interface_table()->FindVmi(vm_uuid);
364  const VmInterface *vmi = dynamic_cast<const VmInterface *>(vm_intf.get());
365  if ((prev->is_shared_ && vmi==NULL) || (prev->is_shared_ && vmi && vmi->IsDeleted())) {
366  FreeBgpVmiServicePortIndex(prev->source_port_);
367  }
368  else if(vmi && !(vmi->IsDeleted())){
369  LOG(DEBUG, "Undeleted vmi might have active bgp session with source port");
370  }
371 
372  old_bgp_as_a_service_entry_list_iter->second->list_.erase(prev);
373  continue;
374  }
375  if (prev->old_health_check_delete_) {
376  if (!health_check_cb_list_.empty() &&
377  prev->old_health_check_uuid_ != boost::uuids::nil_uuid()) {
378  std::vector<HealthCheckCb>::iterator hcb_it =
379  health_check_cb_list_.begin();
380  while (hcb_it != health_check_cb_list_.end()) {
381  (*hcb_it)(vm_uuid, prev->source_port_,
382  prev->old_health_check_uuid_, false);
383  hcb_it++;
384  }
385  }
386  prev->old_health_check_delete_ = false;
387  prev->old_health_check_uuid_ = boost::uuids::nil_uuid();
388  }
389  if (prev->new_health_check_add_) {
390  if (!health_check_cb_list_.empty() &&
391  prev->health_check_uuid_ != boost::uuids::nil_uuid()) {
392  std::vector<HealthCheckCb>::iterator hcb_it =
393  health_check_cb_list_.begin();
394  while (hcb_it != health_check_cb_list_.end()) {
395  (*hcb_it)(vm_uuid, prev->source_port_,
396  prev->health_check_uuid_, true);
397  hcb_it++;
398  }
399  }
400  prev->new_health_check_add_ = false;
401  }
402  }
403  }
404 }
405 
407  if (service_delete_cb_list_.empty())
408  return;
409 
411  bgp_as_a_service_entry_map_.find(vm_uuid);
412  if (iter == bgp_as_a_service_entry_map_.end())
413  return;
414 
415  BgpAsAServiceEntryList list = iter->second->list_;
416  BgpAsAServiceEntryListIterator list_iter = list.begin();
417  while (list_iter != list.end()) {
418  std::vector<ServiceDeleteCb>::iterator scb_it =
419  service_delete_cb_list_.begin();
420  while (scb_it != service_delete_cb_list_.end()) {
421  (*scb_it)(vm_uuid, (*list_iter).source_port_);
422  scb_it++;
423  }
424  if ((*list_iter).is_shared_) {
425  FreeBgpVmiServicePortIndex((*list_iter).source_port_);
426  }
427  list_iter++;
428  }
429  delete iter->second;
430  bgp_as_a_service_entry_map_.erase(iter);
431 }
432 
433 
435  const IpAddress &source_ip,
436  const IpAddress &dest_ip) const {
437  bool ret = false;
439  bgp_as_a_service_entry_map_.find(vm_intf->GetUuid());
440  if (iter == bgp_as_a_service_entry_map_.end()) {
441  return false;
442  }
443 
444  while (iter != bgp_as_a_service_entry_map_.end()) {
446  iter->second->list_.begin();
447  while (it != iter->second->list_.end()) {
448  if ((*it).local_peer_ip_ == source_ip)
449  return true;
450  it++;
451  }
452  iter++;
453  }
454 
455  const VnEntry *vn = vm_intf->vn();
456  if (vn == NULL) return false;
457 
458  const IpAddress &vm_ip = vm_intf->primary_ip_addr();
459  if ((vn->GetGatewayFromIpam(vm_ip) == dest_ip) ||
460  (vn->GetDnsFromIpam(vm_ip) == dest_ip)) {
461  ret = true;
462  }
463  return ret;
464 }
465 
466 void BgpAsAService::FreeBgpVmiServicePortIndex(const uint32_t sport) {
471  ports.first, ports.second);
472 
473  BgpAsAServicePortMapIterator port_map_it =
474  bgp_as_a_service_port_map_.find(portinfo.first);
475  if (port_map_it == bgp_as_a_service_port_map_.end()) {
476  return;
477  }
478 
479  size_t vmi_service_port_index = portinfo.second;
481  vmi_service_port_index);
482  port_map_it->second->Remove(vmi_service_port_index);
483 
484  if (port_map_it->second->NoneIndexSet()) {
485  delete port_map_it->second;
486  bgp_as_a_service_port_map_.erase(port_map_it);
487  }
488 }
489 
491  const boost::uuids::uuid vm_uuid) {
492  BgpAsAServicePortMapIterator port_map_it =
493  bgp_as_a_service_port_map_.find(sport);
494  if (port_map_it == bgp_as_a_service_port_map_.end()) {
496  }
498  (agent_->resource_manager(), vm_uuid));
499  uint32_t index = static_cast<IndexResourceData *>
500  (agent_->resource_manager()->Allocate(rkey).get())->index();
501  bgp_as_a_service_port_map_[sport]->InsertAtIndex(index, vm_uuid);
502  return index;
503 }
504 
505 uint32_t BgpAsAService::AddBgpVmiServicePortIndex(const uint32_t source_port,
506  const boost::uuids::uuid vm_uuid) {
509 
510  size_t vmi_service_port_index = AllocateBgpVmiServicePortIndex(source_port,
511  vm_uuid);
512  if (vmi_service_port_index == BitSet::npos) {
513  std::stringstream ss;
514  ss << "Service Port Index is not available for ";
515  ss << source_port;
516  BGPASASERVICETRACE(Trace, ss.str().c_str());
517  return 0;
518  }
520  source_port,
521  vmi_service_port_index,
522  ports.first, ports.second);
523 }
524 
526  const VmInterface *vm_intf, const IpAddress &source_ip,
527  const IpAddress &dest, IpAddress *nat_server,
528  uint32_t *sport, uint32_t *dport) const {
529  const VnEntry *vn = vm_intf->vn();
530  if (vn == NULL) return false;
531 
532  const IpAddress &vm_ip = vm_intf->primary_ip_addr();
533  const IpAddress &gw = vn->GetGatewayFromIpam(vm_ip);
534  const IpAddress &dns = vn->GetDnsFromIpam(vm_ip);
535 
536  std::stringstream ss;
538  bgp_as_a_service_entry_map_.find(vm_intf->GetUuid());
539  if (map_it == bgp_as_a_service_entry_map_.end()) {
540  ss << "vmi-uuid:" << vm_intf->GetUuid() << " not found";
541  BGPASASERVICETRACE(Trace, ss.str().c_str());
542  return false;
543  }
544 
545  BgpRouterConfig *bgp_router_cfg = agent_->oper_db()->bgp_router_config();
546  BgpAsAServiceEntryListConstIterator it = map_it->second->list_.begin();
547  while (it != map_it->second->list_.end()) {
548  bool cnz_configured = it->IsControlNodeZoneConfigured();
549  BgpRouterPtr bgp_router;
550  IpAddress ip_address;
551  std::string xmpp_server;
552  std::string control_node_zone;
553  std::string *bgp_router_name;
554  if (dest == gw) {
555  if (cnz_configured) {
556  bgp_router = bgp_router_cfg->
557  GetBgpRouterFromControlNodeZone(
558  it->primary_control_node_zone_);
559  control_node_zone = it->primary_control_node_zone_;
560  } else {
561  xmpp_server = agent_->controller_ifmap_xmpp_server(0);
562  if (xmpp_server.size())
563  bgp_router = bgp_router_cfg->
564  GetBgpRouterFromXmppServer(xmpp_server);
565  }
566  bgp_router_name = &it->primary_bgp_peer_;
567  } else if (dest == dns) {
568  if (cnz_configured) {
569  bgp_router = bgp_router_cfg->
570  GetBgpRouterFromControlNodeZone(
571  it->secondary_control_node_zone_);
572  control_node_zone = it->secondary_control_node_zone_;
573  } else {
574  xmpp_server = agent_->controller_ifmap_xmpp_server(1);
575  if (xmpp_server.size())
576  bgp_router = bgp_router_cfg->
577  GetBgpRouterFromXmppServer(xmpp_server);
578  }
579  bgp_router_name = &it->secondary_bgp_peer_;
580  } else {
581  it++;
582  continue;
583  }
584  if (bgp_router.get() == NULL) {
585  ss << "BgpRouter not found.";
586  ss << " bgpaas-source-ip:" << source_ip.to_string();
587  ss << " bgpaas-destination-ip:" << dest.to_string();
588  ss << " control-node-zone:" << control_node_zone;
589  ss << " xmpp-server:" << xmpp_server;
590  BGPASASERVICETRACE(Trace, ss.str().c_str());
591  //reset bgp_router for sandesh
592  *bgp_router_name = "";
593  return false;
594  }
595  *nat_server = bgp_router->ipv4_address();
596  *sport = it->source_port_;
597  *dport = it->dest_port_?it->dest_port_:bgp_router->port();
598  //update bgp_router for sandesh
599  *bgp_router_name = bgp_router->name();
600  return true;
601  }
602  ss << "BgpRouter not found ";
603  ss << " bgpaas-source-ip:" << source_ip.to_string();
604  ss << " bgpaas-destination-ip" << dest.to_string();
605  BGPASASERVICETRACE(Trace, ss.str().c_str());
606  return false;
607 }
608 
610  boost::uuids::uuid *health_check_uuid) const {
612  bgp_as_a_service_entry_map_.find(vm_intf->GetUuid());
613 
614  if (found != bgp_as_a_service_entry_map_.end()) {
616  found->second->list_.begin();
617  while (it != found->second->list_.end()) {
618  if (it->health_check_configured_) {
619  *health_check_uuid = it->health_check_uuid_;
620  std::ostringstream ss;
621  ss<<"searched for vm_intf_uuid: "<<boost::uuids::to_string(vm_intf->GetUuid())
622  <<" - found: "<<boost::uuids::to_string(*health_check_uuid);
623  BGPASASERVICETRACE(Trace, ss.str().c_str());
624  return true;
625  }
626  it++;
627  }
628  }
629  std::ostringstream ss;
630  ss<<"vm_intf_uuid: "<<boost::uuids::to_string(vm_intf->GetUuid())+" - not found in BgpAaS entry map";
631  BGPASASERVICETRACE(Trace, ss.str().c_str());
632  return false;
633 }
634 
636  if (service_delete_cb_list_.empty())
637  return;
638  unsigned int source_port = 0;
639  unsigned int index = 0;
644  std::pair<BgpAsAServiceEntryListIterator, bool> ret;
647  while (iter != bgp_as_a_service_entry_map_.end()) {
648  BgpAsAServiceEntryList list = iter->second->list_;
649  BgpAsAServiceEntryListIterator list_iter = list.begin();
650  while (list_iter != list.end()) {
653  list_iter->source_port_,
654  old_ports.first,
655  old_ports.second);
656  source_port = portinfo.first;
657  index = portinfo.second;
658  // encode source port with new port range
659  source_port =
661  index,
662  new_ports.first,
663  new_ports.second);
664  // if old source port is not same as new source pott
665  // delte the flow and entry from the list
666  // and then insert the entry with the new source port
667  if (list_iter->source_port_ != source_port) {
668  BgpAsAServiceEntry temp(list_iter->local_peer_ip_,
669  source_port,
670  list_iter->dest_port_,
671  list_iter->health_check_configured_,
672  list_iter->health_check_uuid_,
673  list_iter->is_shared_,
674  list_iter->hc_delay_usecs_,
675  list_iter->hc_timeout_usecs_,
676  list_iter->hc_retries_,
677  list_iter->primary_control_node_zone_,
678  list_iter->secondary_control_node_zone_);
679  std::vector<ServiceDeleteCb>::iterator scb_it =
680  service_delete_cb_list_.begin();
681  while (scb_it != service_delete_cb_list_.end()) {
682  (*scb_it)(iter->first, list_iter->source_port_);
683  scb_it++;
684  }
685  iter->second->list_.erase(*list_iter);
686  iter->second->list_.insert(temp);
687  }
688  list_iter++;
689  }
690  iter++;
691  }
692  //update BgpaaS port range
693  bgp_as_a_service_parameters_.port_start = new_ports.first;
694  bgp_as_a_service_parameters_.port_end = new_ports.second;
695 }
696 
698 // BGP as a service routines.
701  VmInterface::ListEntry(), installed_(false),
702  local_peer_ip_(), source_port_(0), dest_port_(0),
703  health_check_configured_(false), health_check_uuid_(),
704  new_health_check_add_(false),old_health_check_delete_(false),
705  old_health_check_uuid_(),hc_delay_usecs_(0),
706  hc_timeout_usecs_(0), hc_retries_(0), is_shared_(false),
707  primary_control_node_zone_(), secondary_control_node_zone_() {
708 }
709 
713  installed_(rhs.installed_),
714  local_peer_ip_(rhs.local_peer_ip_),
715  source_port_(rhs.source_port_),
716  dest_port_(rhs.dest_port_),
717  health_check_configured_(rhs.health_check_configured_),
718  health_check_uuid_(rhs.health_check_uuid_),
719  new_health_check_add_(rhs.new_health_check_add_),
720  old_health_check_delete_(rhs.old_health_check_delete_),
721  old_health_check_uuid_(rhs.old_health_check_uuid_),
722  hc_delay_usecs_(rhs.hc_delay_usecs_),
723  hc_timeout_usecs_(rhs.hc_timeout_usecs_),
724  hc_retries_(rhs.hc_retries_), is_shared_(rhs.is_shared_),
725  primary_control_node_zone_(rhs.primary_control_node_zone_),
726  secondary_control_node_zone_(rhs.secondary_control_node_zone_) {
727 }
728 
730 (const IpAddress &local_peer_ip, uint32_t source_port, uint32_t dest_port,
731  bool health_check_configured, const boost::uuids::uuid &health_check_uuid,
732  bool is_shared, uint64_t hc_delay_usecs, uint64_t hc_timeout_usecs,
733  uint32_t hc_retries, const std::string &primary_control_node_zone,
734  const std::string &secondary_control_node_zone) :
736  installed_(false),
737  local_peer_ip_(local_peer_ip),
738  source_port_(source_port),
739  dest_port_(dest_port),
740  health_check_configured_(health_check_configured),
741  health_check_uuid_(health_check_uuid),
742  new_health_check_add_(health_check_configured),
743  old_health_check_delete_(false), old_health_check_uuid_(),
744  hc_delay_usecs_(hc_delay_usecs), hc_timeout_usecs_(hc_timeout_usecs),
745  hc_retries_(hc_retries), is_shared_(is_shared),
746  primary_control_node_zone_(primary_control_node_zone),
747  secondary_control_node_zone_(secondary_control_node_zone) {
748 }
749 
751 }
752 
753 bool BgpAsAService::BgpAsAServiceEntry::operator ==
754  (const BgpAsAServiceEntry &rhs) const {
755  return ((source_port_ == rhs.source_port_) &&
756  (local_peer_ip_ == rhs.local_peer_ip_) &&
757  (is_shared_ == rhs.is_shared_));
758 }
759 
760 bool BgpAsAService::BgpAsAServiceEntry::operator()
761  (const BgpAsAServiceEntry &lhs, const BgpAsAServiceEntry &rhs) const {
762  return lhs.IsLess(&rhs);
763 }
764 
766  (const BgpAsAServiceEntry *rhs) const {
767  if (source_port_ != rhs->source_port_)
768  return source_port_ < rhs->source_port_;
769  if (local_peer_ip_ != rhs->local_peer_ip_)
770  return local_peer_ip_ < rhs->local_peer_ip_;
771  if (primary_control_node_zone_ != rhs->primary_control_node_zone_)
772  return primary_control_node_zone_ < rhs->primary_control_node_zone_;
773  if (secondary_control_node_zone_ != rhs->secondary_control_node_zone_)
774  return secondary_control_node_zone_ < rhs->secondary_control_node_zone_;
775  return is_shared_ < rhs->is_shared_;
776 }
777 
778 void BgpAsAServiceSandeshReq::HandleRequest() const {
779  BgpAsAServiceSandeshResp *resp = new BgpAsAServiceSandeshResp();
780  resp->set_context(context());
781 
782  Agent *agent = Agent::GetInstance();
783 
787  map_entry.begin();
788  std::vector<BgpAsAServiceSandeshList> bgpaas_map;
789  std::string vmi_uuid_str = get_vmi_uuid();
790  while (map_it != map_entry.end()) {
791  if (vmi_uuid_str.empty() == false) {
792  boost::uuids::uuid vmi_uuid = StringToUuid(vmi_uuid_str);
793  if (vmi_uuid != map_it->first) {
794  map_it++;
795  continue;
796  }
797  }
799  map_it->second->list_.begin();
800  while (it != map_it->second->list_.end()) {
801  BgpAsAServiceSandeshList entry;
802  entry.set_vm_bgp_peer_ip((*it).local_peer_ip_.to_string());
803  entry.set_vm_nat_source_port((*it).source_port_);
804  entry.set_vmi_uuid(UuidToString(map_it->first));
805  entry.set_health_check_configured((*it).health_check_configured_);
806  entry.set_health_check_uuid(UuidToString((*it).health_check_uuid_));
807  entry.set_health_check_delay_usecs((*it).hc_delay_usecs_);
808  entry.set_health_check_timeout_usecs((*it).hc_timeout_usecs_);
809  entry.set_health_check_retries((*it).hc_retries_);
810  entry.set_is_shared((*it).is_shared_);
811  entry.set_primary_control_node_zone(
812  (*it).primary_control_node_zone_);
813  entry.set_secondary_control_node_zone(
814  (*it).secondary_control_node_zone_);
815  entry.set_primary_bgp_peer((*it).primary_bgp_peer_);
816  entry.set_secondary_bgp_peer((*it).secondary_bgp_peer_);
817  bgpaas_map.push_back(entry);
818  it++;
819  }
820  map_it++;
821  }
822  resp->set_bgp_as_a_service_list(bgpaas_map);
823  resp->Response();
824 }
bool GetBgpRouterServiceDestination(const VmInterface *vm_intf, const IpAddress &source, const IpAddress &dest, IpAddress *nat_server, uint32_t *sport, uint32_t *dport) const
IpAddress GetDnsFromIpam(const IpAddress &ip) const
Definition: vn.cc:668
static Agent * GetInstance()
Definition: agent.h:436
static boost::uuids::uuid StringToUuid(const std::string &str)
Definition: string_util.h:145
static void CfgUuidSet(uint64_t ms_long, uint64_t ls_long, boost::uuids::uuid &u)
Definition: agent_cmn.h:67
const boost::uuids::uuid & GetUuid() const
Definition: interface.h:113
bool IsLess(const BgpAsAServiceEntry *rhs) const
std::pair< uint32_t, size_t > BgpAsServicePortIndexPair
BgpAsAServiceEntryList::iterator BgpAsAServiceEntryListIterator
void Release(KeyPtr key)
BGPaaServiceParameters bgp_as_a_service_parameters_
const BgpAsAService::BgpAsAServiceEntryMap & bgp_as_a_service_map() const
std::map< boost::uuids::uuid, BgpAsAServiceList * > BgpAsAServiceEntryMap
bool IsDeleted() const
Definition: db_entry.h:49
ConfigManager * config_manager() const
Definition: agent.cc:889
boost::asio::ip::address IpAddress
Definition: address.h:13
SandeshTraceBufferPtr BgpAsAServiceTraceBuf
boost::shared_ptr< ResourceKey > KeyPtr
virtual const char * Typename() const =0
static const std::string GetControlNodeZoneName(IFMapNode *node)
boost::shared_ptr< BgpRouter > BgpRouterPtr
Definition: bgp_router.h:19
InterfaceTable * interface_table() const
Definition: agent.h:465
boost::uuids::uuid uuid
adjacency_iterator end(DBGraph *graph)
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
IFMapTable * table()
Definition: ifmap_node.h:29
std::map< uint32_t, IndexVector< boost::uuids::uuid > * > BgpAsAServicePortMap
boost::uuids::uuid health_check_uuid_
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
static const std::string GetBgpRouterVrfName(const Agent *agent, IFMapNode *node)
BGPaaServiceParameters::BGPaaServicePortRangePair bgp_as_a_service_port_range() const
#define BGPASASERVICETRACE(obj,...)
OperDB * oper_db() const
Definition: agent.cc:1013
BgpAsAServiceEntryList list_
InterfaceConstRef FindVmi(const boost::uuids::uuid &u)
Definition: interface.cc:419
BgpAsAServiceEntryMap::const_iterator BgpAsAServiceEntryMapConstIterator
const DBGraph * GetGraph() const
BgpRouterConfig * bgp_router_config() const
Definition: operdb_init.h:55
BgpAsAService * bgp_as_a_service() const
Definition: operdb_init.h:77
BgpAsAServiceEntryMap bgp_as_a_service_entry_map_
static const size_t npos
Definition: bitset.h:19
Definition: agent.h:358
boost::uuids::uuid old_health_check_uuid_
std::vector< ServiceDeleteCb > service_delete_cb_list_
void UpdateBgpAsAServiceSessionInfo()
BgpAsAServicePortMap bgp_as_a_service_port_map_
Definition: trace.h:220
boost::intrusive_ptr< const Interface > InterfaceConstRef
Definition: agent.h:51
bool GetBgpHealthCheck(const VmInterface *vm_intf, boost::uuids::uuid *health_check_uuid) const
const Agent * agent_
const VnEntry * vn() const
const std::string & controller_ifmap_xmpp_server(uint8_t idx) const
Definition: agent.h:730
const std::string & name() const
Definition: ifmap_node.h:48
ResourceManager::DataPtr Allocate(KeyPtr key)
std::vector< HealthCheckCb > health_check_cb_list_
void ProcessConfig(const std::string &vrf_name, std::list< IFMapNode * > &bgp_router_node_list, std::list< IFMapNode * > &bgp_as_service_node_list, const boost::uuids::uuid &vmi_uuid)
#define VALID_BGP_ROUTER_TYPE
const BgpAsAService::BgpAsAServicePortMap & bgp_as_a_service_port_map() const
IFMapAgentTable * cfg_health_check_table() const
Definition: cfg_init.h:106
Definition: vn.h:151
const Ip4Address & primary_ip_addr() const
IFMapObject * GetObject()
Definition: ifmap_node.cc:63
static uint32_t EncodeBgpaasServicePort(const uint32_t sport, const size_t index, const uint16_t port_range_start, const uint16_t port_range_end)
BgpAsAServicePortMap::iterator BgpAsAServicePortMapIterator
BgpAsAService(const Agent *agent)
void Remove(BgpAsAServiceEntryListIterator &it)
static BgpAsServicePortIndexPair DecodeBgpaasServicePort(const uint32_t sport, const uint16_t port_range_start, const uint16_t port_range_end)
#define LOG(_Level, _Msg)
Definition: logging.h:33
IFMapAgentTable * cfg_vrf_table() const
Definition: cfg_init.h:29
void Update(const BgpAsAServiceEntry *lhs, const BgpAsAServiceEntry *rhs)
std::pair< uint16_t, uint16_t > BGPaaServicePortRangePair
void StartHealthCheck(const boost::uuids::uuid &vm_uuid, const BgpAsAServiceEntryList &list)
void Insert(const BgpAsAServiceEntry *rhs)
size_t AllocateBgpVmiServicePortIndex(const uint32_t sport, const boost::uuids::uuid vm_uuid)
bool IsBgpService(const VmInterface *vm_intf, const IpAddress &source_ip, const IpAddress &dest_ip) const
BgpAsAServiceEntryMap::iterator BgpAsAServiceEntryMapIterator
void BuildBgpAsAServiceInfo(IFMapNode *bgp_as_a_service_node, std::list< IFMapNode * > &bgp_router_nodes, BgpAsAServiceEntryList &new_list, const std::string &vrf_name, const boost::uuids::uuid &vm_uuid)
#define CONTROL_NODE_ZONE_CONFIG_NAME
Definition: bgp_router.h:14
AgentConfig * cfg() const
Definition: agent.cc:865
bool SkipNode(IFMapNode *node)
#define BGPAAS_CONTROL_NODE_ZONE_CONFIG_NAME
void DeleteVmInterface(const boost::uuids::uuid &vmi_uuid)
uint32_t AddBgpVmiServicePortIndex(const uint32_t source_port, const boost::uuids::uuid vm_uuid)
std::set< BgpAsAServiceEntry, BgpAsAServiceEntry > BgpAsAServiceEntryList
adjacency_iterator begin(DBGraph *graph)
GlobalSystemConfig * global_system_config() const
Definition: operdb_init.h:85
BGPaaServiceParameters::BGPaaServicePortRangePair bgpaas_port_range() const
#define BGP_ROUTER_CONFIG_NAME
BgpAsAServiceEntryList::const_iterator BgpAsAServiceEntryListConstIterator
void FreeBgpVmiServicePortIndex(const uint32_t sport)
ResourceManager * resource_manager() const
Definition: agent.cc:1021
IpAddress GetGatewayFromIpam(const IpAddress &ip) const
Definition: vn.cc:660
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:46