OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
multicast.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/uuid/uuid_io.hpp>
6 #include <cmn/agent_cmn.h>
7 #include <init/agent_param.h>
8 
9 #include <base/logging.h>
10 #include <oper/operdb_init.h>
11 #include <oper/route_common.h>
12 #include <oper/interface_common.h>
13 #include <oper/nexthop.h>
14 #include <oper/tunnel_nh.h>
15 #include <oper/vrf.h>
16 #include <oper/agent_sandesh.h>
17 #include <oper/multicast.h>
18 #include <oper/mirror_table.h>
19 #include <oper/mpls.h>
20 #include <oper/bridge_domain.h>
22 #include <oper/physical_device.h>
24 #include <oper/tsn_elector.h>
25 #include <xmpp/xmpp_channel.h>
29 
30 #include <sandesh/sandesh_types.h>
31 #include <sandesh/sandesh_constants.h>
32 #include <sandesh/sandesh.h>
33 #include <sandesh/sandesh_trace.h>
34 
35 using namespace std;
36 using namespace boost::uuids;
37 
38 #define INVALID_PEER_IDENTIFIER ControllerPeerPath::kInvalidPeerIdentifier
39 
42  1000));
44 /*
45  * Registeration for notification
46  * VM - Looking for local VM added
47  * VN - Looking for subnet information from VN
48  * Enable trace print messages
49  */
51  vn_listener_id_ = agent_->vn_table()->Register(
52  boost::bind(&MulticastHandler::ModifyVN, this, _1, _2));
53  vrf_listener_id_ = agent_->vrf_table()->Register(
54  boost::bind(&MulticastHandler::ModifyVRF, this, _1, _2));
55  interface_listener_id_ = agent_->interface_table()->Register(
56  boost::bind(&MulticastHandler::ModifyVmInterface, this, _1, _2));
57  bridge_domain_id_ = agent_->bridge_domain_table()->Register(
58  boost::bind(&MulticastHandler::AddBridgeDomain, this, _1, _2));
59  physical_device_listener_id_ = DBTable::kInvalidId;
60  if (agent_->tsn_no_forwarding_enabled()) {
61  physical_device_listener_id_ = agent_->physical_device_table()->
62  Register(boost::bind(&MulticastHandler::NotifyPhysicalDevice,
63  this, _1, _2));
64  agent_->oper_db()->agent_route_walk_manager()->
65  RegisterWalker(static_cast<AgentRouteWalker *>(te_walker_.get()));
66  }
67 
68  GetMulticastObjList().clear();
69 }
70 
72  agent_->vn_table()->Unregister(vn_listener_id_);
73  agent_->interface_table()->Unregister(interface_listener_id_);
74  agent_->vrf_table()->Unregister(vrf_listener_id_);
75  agent_->bridge_domain_table()->Unregister(bridge_domain_id_);
76  if (physical_device_listener_id_ != DBTable::kInvalidId) {
77  agent_->physical_device_table()->
78  Unregister(physical_device_listener_id_);
79  }
80  if (te_walker_.get()) {
81  agent_->oper_db()->agent_route_walk_manager()->
82  ReleaseWalker(te_walker_.get());
83  te_walker_.reset();
84  }
85 }
86 
88  const string &vrf_name,
89  const string &vn_name,
90  const Ip4Address &addr,
91  uint32_t label,
92  int vxlan_id,
93  uint32_t ethernet_tag)
94 {
95  if (obj->pbb_vrf() && obj->dependent_mg() == NULL) {
96  return;
97  }
98 
99  boost::system::error_code ec;
100  MCTRACE(Log, "add L2 bcast route ", vrf_name, addr.to_string(), 0);
101  //Add Bridge FF:FF:FF:FF:FF:FF
102  ComponentNHKeyList component_nh_key_list =
103  GetInterfaceComponentNHKeyList(obj, InterfaceNHFlags::BRIDGE);
104  if (component_nh_key_list.size() == 0)
105  return;
106  uint32_t route_tunnel_bmap = TunnelType::AllType();
107  AgentRouteData *data =
109  vn_name,
110  label,
111  vxlan_id,
112  route_tunnel_bmap,
114  component_nh_key_list,
115  obj->pbb_vrf(),
116  obj->learning_enabled());
117  BridgeAgentRouteTable::AddBridgeBroadcastRoute(agent_->local_vm_peer(),
118  vrf_name,
119  ethernet_tag,
120  data);
121 }
122 
123 /*
124  * Route address 255.255.255.255 deletion from last VM in VN del
125  */
127  const std::string &vrf_name,
128  uint32_t ethernet_tag,
130 {
131  boost::system::error_code ec;
132  MCTRACE(Log, "delete bcast route ", vrf_name, "255.255.255.255", 0);
133  BridgeAgentRouteTable::DeleteBroadcastReq(peer, vrf_name, ethernet_tag,
134  type);
135  ComponentNHKeyList component_nh_key_list; //dummy list
136 }
137 
139  if (vn->IsDeleted() || !vn->GetVrf())
140  return;
141 
142  MulticastGroupObject *obj =
143  FindFloodGroupObject(vn->GetVrf()->GetName());
144  if (!obj || obj->IsDeleted())
145  return;
146 
147  uint32_t new_vxlan_id = vn->GetVxLanId();
148 
149  if (new_vxlan_id != obj->vxlan_id()) {
150  boost::system::error_code ec;
151  Ip4Address broadcast = IpAddress::from_string("255.255.255.255",
152  ec).to_v4();
153  obj->set_vxlan_id(new_vxlan_id);
154  //Rebake new vxlan id in mcast route
155  AddL2BroadcastRoute(obj, vn->GetVrf()->GetName(), vn->GetName(),
156  broadcast, MplsTable::kInvalidLabel, new_vxlan_id, 0);
157  }
158 }
159 
161  DBEntryBase *e) {
162  VnEntry *vn = static_cast<VnEntry *>(e);
163  bool deleted = false;
164 
165  //Extract paramters from VN.
166  const VrfEntry *vrf = vn->GetVrf();
167  uint32_t vn_vxlan_id = vn->GetVxLanId();
168 
169  MulticastDBState *state = static_cast<MulticastDBState *>
170  (vn->GetState(partition->parent(), vn_listener_id_));
171 
172  deleted = vn->IsDeleted() || !(vrf);
173  //Extract old parameters from state
174  uint32_t old_vxlan_id = state ? state->vxlan_id_ : 0;
175 
176  boost::system::error_code ec;
177  Ip4Address broadcast = IpAddress::from_string("255.255.255.255",
178  ec).to_v4();
179  //Add operation
180  if (!deleted) {
181  MulticastGroupObject *all_broadcast =
182  FindFloodGroupObject(vn->GetVrf()->GetName());
183 
184  if (!state) {
185  state = new MulticastDBState(vn->GetVrf()->GetName(),
186  vn_vxlan_id);
187  vn->SetState(partition->parent(), vn_listener_id_, state);
188  //Also create multicast object
189  if (all_broadcast == NULL) {
190  all_broadcast = CreateMulticastGroupObject(state->vrf_name_,
191  vn->GetName(), Ip4Address(), broadcast,
192  state->vxlan_id_);
193  }
194  all_broadcast->set_vn(vn);
195  } else {
196  if (old_vxlan_id != vn_vxlan_id) {
197  state->vxlan_id_ = vn_vxlan_id;
198  if (all_broadcast) {
199  all_broadcast->set_vxlan_id(state->vxlan_id_);
200  }
201  }
202  }
203  ComponentNHKeyList component_nh_key_list;
204  AgentRouteData *data =
206  vn->GetName(),
207  0,
208  state->vxlan_id_,
211  component_nh_key_list,
212  all_broadcast->pbb_vrf(),
213  all_broadcast->
214  learning_enabled());
216  state->vrf_name_,
217  state->vxlan_id_,
218  data);
219  Ip4Address broadcast = IpAddress::from_string("255.255.255.255",
220  ec).to_v4();
221  AddL2BroadcastRoute(all_broadcast, state->vrf_name_, vn->GetName(),
222  broadcast, MplsTable::kInvalidLabel,
223  state->vxlan_id_, 0);
224  }
225 
226  //Delete or withdraw old vxlan id
227  if (deleted) {
228  if (!state)
229  return;
230 
231  MulticastGroupObject *all_broadcast =
232  FindFloodGroupObject(state->vrf_name_);
233  if (all_broadcast) {
234  all_broadcast->reset_vn();
235  }
236 
237  DeleteMulticastObject(state->vrf_name_, Ip4Address(), broadcast);
238  BridgeAgentRouteTable::DeleteBroadcastReq(agent_->local_peer(),
239  state->vrf_name_,
240  old_vxlan_id,
242 
243  vn->ClearState(partition->parent(), vn_listener_id_);
244  delete state;
245  }
246 }
247 
248 /* Regsitered call for VN */
250 {
251  const VnEntry *vn = static_cast<const VnEntry *>(e);
252 
253  HandleIpam(vn);
254  HandleVnParametersChange(partition, e);
255 }
256 
258  DBEntryBase *e) {
259 
260  AgentRoute *route = static_cast<AgentRoute *>(e);
261  if (route->GetTableType() != Agent::INET4_MULTICAST) {
262  return;
263  }
264  Inet4MulticastRouteEntry *mc_entry =
265  static_cast<Inet4MulticastRouteEntry*>(route);
266  VrfEntry *vrf = mc_entry->vrf();
267  Ip4Address src = mc_entry->src_ip_addr();
268  Ip4Address grp = mc_entry->dest_ip_addr();
269 
270  MulticastGroupObject *sg_object = NULL;
271  sg_object = FindGroupObject(vrf->GetName(), src, grp);
272  if (!sg_object) {
273  return;
274  }
275 
276  bool add = false;
277  const AgentPath *path = NULL;
278  AgentXmppChannel *channel = NULL;
279  for (uint32_t i = 0; i < MAX_XMPP_SERVERS; i++) {
280  channel = agent_->controller_xmpp_channel(i);
281  if (channel && channel->bgp_peer_id() != NULL) {
282  path = route->FindPath(channel->bgp_peer_id());
283  if (path) {
284  add = true;
285  break;
286  }
287  }
288  }
289 
290  if (sg_object->mvpn_registered() == add) {
291  return;
292  }
293 
294  if (sg_object->GetLocalListSize() == 0) {
295  return;
296  }
297 
298  MulticastGroupObject *target_object = NULL;
299  target_object = FindGroupObject(agent_->fabric_policy_vrf_name(),
300  sg_object->GetSourceAddress(),
301  sg_object->GetGroupAddress());
302  if (!target_object) {
303  return;
304  }
305 
306  std::map<uuid, MacAddress>::const_iterator it;
307  for (it = sg_object->GetLocalList().begin();
308  it != sg_object->GetLocalList().end(); it++) {
309  if (add) {
310  if (target_object->AddLocalMember(it->first, it->second) == true) {
311  AddVmToMulticastObjMap(it->first, target_object);
312  }
313  } else {
314  if (target_object->DeleteLocalMember(it->first) == true) {
315  DeleteVmToMulticastObjMap(it->first, target_object);
316  }
317  }
318  }
319 
320  if (target_object->GetLocalListSize() == 0) {
322  DeleteMulticastRoute(agent_->local_vm_peer(), target_object->vrf_name(),
323  target_object->GetSourceAddress(),
324  target_object->GetGroupAddress(),
325  0, comp_type);
326  DeleteMulticastObject(target_object->vrf_name(),
327  target_object->GetSourceAddress(),
328  target_object->GetGroupAddress());
329  } else {
330  TriggerLocalRouteChange(target_object, agent_->local_vm_peer());
331  }
332 
333  sg_object->set_mvpn_registered(add);
334 
335  return;
336 }
337 
339 
340  if (!agent_->params()->mvpn_ipv4_enable()) {
341  return;
342  }
343 
344  VrfEntry *vrf = static_cast<VrfEntry *>(e);
345  MulticastVrfDBState *state = static_cast<MulticastVrfDBState *>
346  (vrf->GetState(partition->parent(), vrf_listener_id_));
347  if (!vrf) {
348  return;
349  }
350 
351  //Add operation
352  if (!vrf->IsDeleted()) {
353  if (!state) {
354  state = new MulticastVrfDBState();
355  AgentRouteTable *table = static_cast<AgentRouteTable *>
357  state->id_ = table->Register(
359  this, _1, _2));
360  vrf->SetState(partition->parent(), vrf_listener_id_, state);
361  }
362  state->vrf_name_ = vrf->GetName();
363  } else {
364  if (!state) {
365  return;
366  }
367  AgentRouteTable *table = static_cast<AgentRouteTable *>
369  table->Unregister(state->id_);
370  vrf->ClearState(partition->parent(), vrf_listener_id_);
371  delete state;
372  }
373 }
374 
377  BridgeDomainEntry *bd) {
378  MulticastDBState *state = new MulticastDBState(bd->vrf()->GetName(),
379  bd->isid());
380 
381  MulticastGroupObject *obj = FindFloodGroupObject(bd->vrf()->GetName());
382  if (obj == NULL) {
383  obj = CreateMulticastGroupObject(state->vrf_name_, bd->vn()->GetName(),
384  Ip4Address(), kBroadcast,
385  state->vxlan_id_);
386  //Add a mutlicast route point to empty composite list
387  AddL2BroadcastRoute(obj, state->vrf_name_,
388  bd->vn()->GetName(), kBroadcast,
390  state->vxlan_id_);
391  }
392 
393  obj->set_bridge_domain(bd);
394  obj->set_vxlan_id(bd->isid());
395  bd->SetState(partition->parent(), bridge_domain_id_, state);
396  return state;
397 }
398 
400  DBEntryBase *e) {
401  BridgeDomainEntry *bd = static_cast<BridgeDomainEntry *>(e);
402 
403  MulticastDBState *state = static_cast<MulticastDBState *>(
404  bd->GetState(partition->parent(), bridge_domain_id_));
405 
406  if (e->IsDeleted() || bd->vrf() == NULL || bd->vn() == NULL) {
407  if (state) {
408  MulticastGroupObject *obj =
409  FindFloodGroupObject(state->vrf_name_);
410  assert(obj);
411  obj->reset_bridge_domain();
412  bd->ClearState(partition->parent(), bridge_domain_id_);
413  DeleteBroadcast(agent_->local_vm_peer(),
414  state->vrf_name_, 0, Composite::L2INTERFACE);
415  DeleteMulticastObject(state->vrf_name_, Ip4Address(), kBroadcast);
416  delete state;
417  }
418  return;
419  }
420 
421  if (state == NULL) {
422  state = CreateBridgeDomainMG(partition, bd);
423  }
424 
425  MulticastGroupObject *obj = FindFloodGroupObject(bd->vrf()->GetName());
426  if (obj == NULL) {
427  obj = CreateMulticastGroupObject(state->vrf_name_, bd->vn()->GetName(),
428  Ip4Address(), kBroadcast,
429  state->vxlan_id_);
430  }
431 
432  if (state->vxlan_id_ != bd->isid()) {
433  DeleteEvpnPath(obj);
434  state->vxlan_id_ = bd->isid();
435  obj->set_vxlan_id(state->vxlan_id_);
436  Resync(obj);
437  }
438 
439  if (state->learning_enabled_ != bd->learning_enabled()) {
440  state->learning_enabled_ = bd->learning_enabled();
441  ChangeLearningMode(obj, state->learning_enabled_);
442  }
443 
444  if (state->pbb_etree_enabled_ != bd->pbb_etree_enabled()) {
445  state->pbb_etree_enabled_ = bd->pbb_etree_enabled();
446  ChangePbbEtreeMode(obj, state->pbb_etree_enabled_);
447  }
448 
449  if (state->layer2_control_word_ != bd->layer2_control_word()) {
451  Resync(obj);
452  }
453 }
454 
456  bool learning_enabled) {
457  if (obj->learning_enabled_ == learning_enabled) {
458  return;
459  }
460 
461  obj->set_learning_enabled(learning_enabled);
462  Resync(obj);
463 }
464 
466  bool pbb_etree_enabled) {
467  if (obj->pbb_etree_enabled_ == pbb_etree_enabled) {
468  return;
469  }
470 
471  obj->set_pbb_etree_enabled(pbb_etree_enabled);
472  Resync(obj);
473 }
474 
476  if ((local_olist_.size() == 0) && (vn_.get() == NULL) &&
477  bridge_domain_.get() == NULL)
478  return true;
479  return false;
480 }
481 
484  for (MGList::iterator it = mg_list_.begin();
485  it != mg_list_.end(); it++) {
486  if (it->vxlan_id_ == isid) {
487  return it.operator->();
488  }
489  }
490  return NULL;
491 }
492 
495  const string &vn_name,
496  const Ip4Address &src_addr,
497  const Ip4Address &grp_addr,
498  uint32_t vxlan_id) {
499  MulticastGroupObject *obj =
500  new MulticastGroupObject(vrf_name, vn_name, grp_addr, src_addr);
501  AddToMulticastObjList(obj);
502  obj->set_vxlan_id(vxlan_id);
503 
504  boost::system::error_code ec;
505  Ip4Address bcast_addr =
506  IpAddress::from_string("255.255.255.255", ec).to_v4();
507  if (obj->GetGroupAddress() == bcast_addr) {
508  UpdateReference(obj);
509  }
510  return obj;
511 }
512 
514  const uuid &vn_uuid = vn->GetUuid();
515  const std::vector<VnIpam> &ipam = vn->GetVnIpam();
516  bool delete_ipam = false;
517  std::map<uuid, string>::iterator it;
518  string vrf_name;
519 
520  if (!(vn->layer3_forwarding()) || vn->IsDeleted() || (ipam.size() == 0) ||
521  (vn->GetVrf() == NULL)) {
522  delete_ipam = true;
523  }
524 
525  it = vn_vrf_mapping_.find(vn_uuid);
526  if (it != vn_vrf_mapping_.end()) {
527  vrf_name = it->second;
528  vrf_ipam_mapping_.erase(vrf_name);
529  if (delete_ipam) {
530  vn_vrf_mapping_.erase(vn_uuid);
531  return;
532  }
533  } else {
534  if (delete_ipam == false) {
535  vrf_name = vn->GetVrf()->GetName();
536  vn_vrf_mapping_.insert(std::pair<uuid, string>(vn_uuid, vrf_name));
537  }
538  }
539 
540  if (delete_ipam)
541  return;
542 
543  vrf_ipam_mapping_.insert(std::pair<string, std::vector<VnIpam> >(vrf_name,
544  ipam));
545 }
546 
548  DBEntryBase *e)
549 {
550  PhysicalDevice *dev = static_cast<PhysicalDevice *>(e);
551  IpAddress dev_ip = dev->ip();
552  ManagedPhysicalDevicesList::iterator pd_it =
553  std::find(physical_devices_.begin(), physical_devices_.end(),
554  dev_ip.to_string());
555  if (dev->IsDeleted()) {
556  if (pd_it == physical_devices_.end())
557  return;
558  physical_devices_.erase(pd_it);
559  } else {
560  if (pd_it != physical_devices_.end())
561  return;
562  physical_devices_.push_back(dev_ip.to_string());
563  }
564  std::sort(physical_devices_.begin(), physical_devices_.end());
565  //Start walk to update evpn nh
566  if (te_walker_.get()) {
567  te_walker_.get()->StartVrfWalk();
568  }
569 }
570 
572  if (vm_itf->device_type() == VmInterface::TOR) {
573  //Ignore TOR VMI, they are not active VMI.
574  return true;
575  }
576 
577  if (vm_itf->vmi_type() == VmInterface::VHOST) {
578  return true;
579  }
580 
581  if (vm_itf->device_type() == VmInterface::VMI_ON_LR) {
582  return true;
583  }
584 
585  if (vm_itf->device_type() == VmInterface::VM_SRIOV) {
586  return true;
587  }
588 
589  return false;
590 }
591 
592 /* Registered call for VM */
594  DBEntryBase *e)
595 {
596  Interface *intf = static_cast<Interface *>(e);
597  VmInterface *vm_itf;
598 
599  if (intf->type() != Interface::VM_INTERFACE) {
600  return;
601  }
602 
603  vm_itf = static_cast<VmInterface *>(intf);
604  if (FilterVmi(vm_itf)) {
605  return;
606  }
607 
608  MulticastIntfDBState *state = static_cast<MulticastIntfDBState *>(
609  vm_itf->GetState(partition->parent(), interface_listener_id_));
610 
611  if (intf->IsDeleted() || ((vm_itf->l2_active() == false) &&
612  (vm_itf->ipv4_active() == false) &&
613  (vm_itf->ipv6_active() == false))) {
614  if (state) {
615  DeleteVmInterface(vm_itf, state);
616  if (intf->IsDeleted()) {
617  vm_itf->ClearState(partition->parent(), interface_listener_id_);
618  delete state;
619  }
620  }
621  return;
622  }
623  assert(vm_itf->vn() != NULL);
624 
625  if (state == NULL) {
626  state = new MulticastIntfDBState();
627  vm_itf->SetState(partition->parent(), interface_listener_id_, state);
628  }
629 
630  //Build all the VRF group interface belong to
631  AddVmInterfaceInFloodGroup(vm_itf, state);
632  return;
633 }
634 
636  MulticastIntfDBState *state) {
637  std::set<std::string> new_vrf_list;
638  new_vrf_list.insert(vm_intf->vrf()->GetName());
639 
640  //Build all PBB VRF
641  VmInterface::BridgeDomainEntrySet::const_iterator it =
642  vm_intf->bridge_domain_list().list_.begin();
643  for (;it != vm_intf->bridge_domain_list().list_.end(); it++) {
644  if (it->bridge_domain_.get() && it->bridge_domain_->vrf()) {
645  new_vrf_list.insert(it->bridge_domain_->vrf()->GetName());
646  }
647  }
648 
649  //Delete interface multicast group, if bridge domain is deleted
650  for (std::set<std::string>::const_iterator it = new_vrf_list.begin();
651  it != new_vrf_list.end(); it++) {
652  AddVmInterfaceInFloodGroup(vm_intf, *it);
653  state->vrf_list_.erase(*it);
654  }
655 
656  for (std::set<std::string>::const_iterator it = state->vrf_list_.begin();
657  it != state->vrf_list_.end(); it++) {
658  DeleteVmInterface(vm_intf, *it);
659  }
660 
661  state->vrf_list_ = new_vrf_list;
662 }
663 
665  MulticastIntfDBState *state) {
666  for (std::set<std::string>::const_iterator it = state->vrf_list_.begin();
667  it != state->vrf_list_.end(); it++) {
668  DeleteVmInterface(intf, *it);
669  }
670 }
671 
672 /*
673  * Delete VM interface
674  * Traverse the multicast obj list of which this VM is a member.
675  * Delete the VM from them and check if local VM list size is zero.
676  * If it is zero then delete the route and mpls.
677  */
679  const std::string &vrf_name) {
680 
681  const VmInterface *vm_itf = static_cast<const VmInterface *>(intf);
682  boost::system::error_code ec;
683  Ip4Address bcast_addr =
684  IpAddress::from_string("255.255.255.255", ec).to_v4();
685  std::set<MulticastGroupObject *> &obj_list = GetVmToMulticastObjMap(
686  vm_itf->GetUuid());
687  for (std::set<MulticastGroupObject *>::iterator it = obj_list.begin();
688  it != obj_list.end(); it++) {
689 
690  if (((*it)->vrf_name() != vrf_name) ||
691  ((*it)->GetGroupAddress() != bcast_addr)) {
692  continue;
693  }
694  // When IPAM/VN goes off first than VM then it marks mc obj
695  // for deletion. Cleanup of related data structures like vm-mcobj
696  // happens when VM goes off. So dont trigger any notify at same time.
697  // However if all local VMs are gone then route will be deleted only
698  // when VN/IPAM goes off. At that time notify xmpp to unsubscribe
699  //Deletelocalmember removes vm from mc obj
700  if (((*it)->DeleteLocalMember(vm_itf->GetUuid()) == true) &&
701  ((*it)->IsDeleted() == false) &&
702  ((*it)->GetLocalListSize() != 0)) {
703  TriggerLocalRouteChange(*it, agent_->local_vm_peer());
704  MCTRACE(LogSG, "modify route, vm is deleted ", (*it)->vrf_name(),
705  (*it)->GetSourceAddress().to_string(),
706  (*it)->GetGroupAddress().to_string(), 0);
707  }
708 
709  if((*it)->GetLocalListSize() == 0) {
710  MCTRACE(Info, "Del route for multicast address",
711  vm_itf->primary_ip_addr().to_string());
712  //Time to delete route(for mcast address) and mpls
713  DeleteBroadcast(agent_->local_vm_peer(),
714  (*it)->vrf_name_, 0, Composite::L2INTERFACE);
715  /* delete mcast object */
716  // TODO : delete only when all creators are gone
717  DeleteMulticastObject((*it)->vrf_name_, Ip4Address(), bcast_addr);
718  }
719  DeleteVmToMulticastObjMap(vm_itf->GetUuid(), *it);
720  break;
721  }
722  MCTRACE(Info, "Del vm notify done ", vm_itf->primary_ip_addr().to_string());
723 }
724 
725 //Delete multicast object for vrf/S/G
726 void MulticastHandler::DeleteMulticastObject(const std::string &vrf_name,
727  const Ip4Address &src_addr,
728  const Ip4Address &grp_addr) {
729 
730  for (std::set<MulticastGroupObject *>::iterator it =
731  this->GetMulticastObjList().begin();
732  it != this->GetMulticastObjList().end(); it++) {
733 
734  if (((*it)->vrf_name() == vrf_name) &&
735  ((*it)->GetGroupAddress() == grp_addr) &&
736  ((*it)->GetSourceAddress() == src_addr)) {
737 
738  if (!((*it)->CanBeDeleted())) {
739  return;
740  }
741 
742  if ((*it)->dependent_mg() != NULL) {
743  MulticastGroupObject *dp_obj = (*it)->dependent_mg();
744  (*it)->set_dependent_mg(NULL);
745  ModifyFabricMembers(dp_obj->peer(), dp_obj->vrf_name(),
746  dp_obj->GetGroupAddress(),
747  dp_obj->GetSourceAddress(),
748  dp_obj->fabric_label(),
749  dp_obj->fabric_olist(),
750  dp_obj->peer_identifier());
751  }
752 
753  MCTRACE(LogSG, "delete obj vrf/source/grp/size ", vrf_name,
754  src_addr.to_string(),
755  grp_addr.to_string(),
756  this->GetMulticastObjList().size());
757  delete (*it);
758  this->GetMulticastObjList().erase(it);
759  break;
760  }
761  }
762 }
763 
765  boost::system::error_code ec;
766  Ip4Address broadcast = IpAddress::from_string("255.255.255.255",
767  ec).to_v4();
768  return (FindGroupObject(vrf_name, Ip4Address(), broadcast));
769 }
770 
771 //Helper to find object for VRF/S/G
773  const std::string &vrf_name,
774  const Ip4Address &sip,
775  const Ip4Address &dip) {
776  for(std::set<MulticastGroupObject *>::iterator it =
777  this->GetMulticastObjList().begin();
778  it != this->GetMulticastObjList().end(); it++) {
779  if (((*it)->vrf_name() == vrf_name) &&
780  ((*it)->GetGroupAddress() == dip) &&
781  ((*it)->GetSourceAddress() == sip)) {
782  return (*it);
783  }
784  }
785  MCTRACE(LogSG, "mcast obj size ", vrf_name, sip.to_string(),
786  dip.to_string(), this->GetMulticastObjList().size());
787  return NULL;
788 }
789 
791  const std::string &vrf_name,
792  const Ip4Address &sip,
793  const Ip4Address &dip) {
794  MulticastGroupObject *obj = FindGroupObject(vrf_name, sip, dip);
795  if ((obj == NULL) || obj->IsDeleted()) {
796  MCTRACE(LogSG, "Multicast object deleted ", vrf_name,
797  sip.to_string(), dip.to_string(), 0);
798  return NULL;
799  }
800 
801  return obj;
802 }
803 
805  vn_.reset(vn);
806 }
807 
809  vn_.reset();
810 }
811 
814 
815  ComponentNHKeyList component_nh_key_list;
816  for (std::map<uuid, MacAddress>::iterator it = local_olist_.begin();
817  it != local_olist_.end(); it++) {
818  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(0, it->first,
819  interface_flags,
820  it->second));
821  component_nh_key_list.push_back(component_nh_key);
822  }
823  return component_nh_key_list;
824 }
825 
828  uint8_t interface_flags) {
829 
830  ComponentNHKeyList component_nh_key_list =
831  obj->GetInterfaceComponentNHKeyList(interface_flags);
832  return component_nh_key_list;
833 }
834 
835 // For MVPN: <S,G> entry is added to the multicast table only.
836 // For EVPN-multicast: <*,G> entry is added to the multicast table.
837 // Currently support is for multicast source outside of the contrail
838 // Also, the vrouter does lookup not using the <S,G> of the multicast
839 // data packet, but using the multicast MAC DA.
840 // With this as design choice, route entry corresponding to the
841 // multicast MAC dervied from the G of <*,G> is added as entry to the
842 // bridge table.
844  const Peer *peer) {
845  DBRequest req;
846  ComponentNHKeyList component_nh_key_list;
847 
848  if (obj->pbb_vrf() && obj->dependent_mg() == NULL) {
849  return;
850  }
851 
852  uint8_t intf_flags = InterfaceNHFlags::BRIDGE;
854  uint32_t route_tunnel_bmap = TunnelType::AllType();
855  boost::system::error_code ec;
856  Ip4Address bcast_addr =
857  IpAddress::from_string("255.255.255.255", ec).to_v4();
858  if (obj->GetGroupAddress() != bcast_addr) {
860  comp_type = Composite::L3INTERFACE;
861  route_tunnel_bmap = agent_->params()->mvpn_ipv4_enable() ?
863  }
864  component_nh_key_list =
865  GetInterfaceComponentNHKeyList(obj, intf_flags);
866 
867  MCTRACE(LogSG, "enqueue route change with local peer",
868  obj->vrf_name(),
869  obj->GetSourceAddress().to_string(),
870  obj->GetGroupAddress().to_string(),
871  component_nh_key_list.size());
872 
873  AgentRouteData *data =
876  obj->vxlan_id(), route_tunnel_bmap,
877  comp_type, component_nh_key_list,
878  obj->pbb_vrf(),
879  obj->learning_enabled());
880 
881  if (obj->GetGroupAddress() != bcast_addr) {
883  obj->vrf_name(), obj->GetSourceAddress(),
884  obj->GetGroupAddress(), 0,
885  data);
886 
887  if (!agent_->params()->mvpn_ipv4_enable()) {
888  intf_flags = InterfaceNHFlags::BRIDGE;
889  comp_type = Composite::L2INTERFACE;
890  component_nh_key_list =
891  GetInterfaceComponentNHKeyList(obj, intf_flags);
892 
893  MacAddress mac;
894  GetMulticastMacFromIp(obj->GetGroupAddress(), mac);
895 
896  AgentRouteData *bridge_data =
899  obj->vxlan_id(), route_tunnel_bmap,
900  comp_type,component_nh_key_list,
901  obj->pbb_vrf(),
902  obj->learning_enabled());
904  0, bridge_data);
905  }
906  } else {
907  //Add Bridge FF:FF:FF:FF:FF:FF, local_vm_peer
909  obj->vrf_name(),
910  0,
911  data);
912  }
913 }
914 
916  const Peer *peer,
917  uint32_t ethernet_tag,
918  AgentRouteData *data,
919  AgentRouteData *bridge_data) {
920 
921  boost::system::error_code ec;
922  Ip4Address bcast_addr =
923  IpAddress::from_string("255.255.255.255", ec).to_v4();
924 
925  if (obj->GetGroupAddress() != bcast_addr) {
927  obj->vrf_name(), obj->GetSourceAddress(),
928  obj->GetGroupAddress(), ethernet_tag, data);
929 
930  if (!agent_->params()->mvpn_ipv4_enable()) {
931  MacAddress mac;
932  GetMulticastMacFromIp(obj->GetGroupAddress(), mac);
933 
935  ethernet_tag, bridge_data);
936  }
937  } else {
939  obj->vrf_name(), ethernet_tag, data);
940  }
941 }
942 
944  const string &vrf_name,
945  const Ip4Address &src,
946  const Ip4Address &grp,
947  uint32_t ethernet_tag,
948  COMPOSITETYPE comp_type) {
949 
950  boost::system::error_code ec;
951  Ip4Address bcast_addr =
952  IpAddress::from_string("255.255.255.255", ec).to_v4();
953 
954  if (grp != bcast_addr) {
956  src, grp, ethernet_tag, comp_type);
957 
958  if (!agent_->params()->mvpn_ipv4_enable()) {
959  MacAddress mac;
960  GetMulticastMacFromIp(grp, mac);
961 
962  COMPOSITETYPE l2_comp_type;
963  if (comp_type == Composite::L3FABRIC) {
964  l2_comp_type = Composite::FABRIC;
965  } else {
966  l2_comp_type = Composite::L2INTERFACE;
967  }
968  BridgeAgentRouteTable::DeleteBridgeRoute(peer, vrf_name, mac,
969  ethernet_tag, l2_comp_type);
970  }
971  } else {
972  BridgeAgentRouteTable::DeleteBroadcastReq(peer, vrf_name, ethernet_tag,
973  comp_type);
974  }
975 }
976 
978  const Peer *peer,
979  const string &vrf_name,
980  const Ip4Address &src,
981  const Ip4Address &grp,
982  const TunnelOlist &olist,
983  uint64_t peer_identifier,
984  bool delete_op,
985  COMPOSITETYPE comp_type,
986  uint32_t label,
987  bool fabric,
988  uint32_t ethernet_tag) {
989  uint64_t obj_peer_identifier = obj ? obj->peer_identifier()
991 
992  // Peer identifier cases
993  // if its a delete operation -
994  // 1) Internal delete (invalid peer identifier), dont update peer identifier
995  // as it is a forced removal.
996  // 2) Control node removing stales i.e. delete if local peer identifier is
997  // less than global peer identifier.
998  //
999  // if its not a delete operation -
1000  // 1) Update only if local peer identifier is less than or equal to sent
1001  // global peer identifier.
1002 
1003  // if its internal delete then peer_identifier will be 0xFFFFFFFF;
1004  // if external delete(via control node) then its stale cleanup so delete
1005  // only when local peer identifier is less than global multicast sequence.
1006  if (delete_op) {
1007  if ((peer_identifier != ControllerPeerPath::kInvalidPeerIdentifier) &&
1008  (peer_identifier <= obj_peer_identifier))
1009  return;
1010 
1011  // After resetting tunnel and mpls label return if it was a delete call,
1012  // dont update peer_identifier. Let it get updated via update operation only
1013  MCTRACE(LogSG, "delete bcast path from remote peer", vrf_name,
1014  src.to_string(), grp.to_string(), 0);
1015  DeleteMulticastRoute(peer, vrf_name, src, grp, ethernet_tag, comp_type);
1016  ComponentNHKeyList component_nh_key_list; //dummy list
1017  return;
1018  }
1019 
1020  // - Update operation with lower sequence number sent compared to
1021  // local identifier, ignore
1022  if ((peer_identifier < obj_peer_identifier) &&
1023  (comp_type != Composite::TOR)) {
1024  return;
1025  }
1026 
1027  // Ideally wrong update call
1028  if (peer_identifier == INVALID_PEER_IDENTIFIER) {
1029  MCTRACE(LogSG, "Invalid peer identifier sent for modification",
1030  vrf_name, src.to_string(), grp.to_string(), 0);
1031  return;
1032  }
1033 
1034  obj->set_peer_identifier(peer_identifier);
1035  ComponentNHKeyList component_nh_key_list;
1036 
1037  uint32_t route_tunnel_bmap = TunnelType::AllType();
1038  for (TunnelOlist::const_iterator it = olist.begin();
1039  it != olist.end(); it++) {
1040  TunnelNHKey *key =
1041  new TunnelNHKey(agent_->fabric_vrf_name(),
1042  agent_->router_id(),
1043  it->daddr_, false,
1044  TunnelType::ComputeType(it->tunnel_bmap_));
1045  TunnelNHData *tnh_data = new TunnelNHData();
1046  DBRequest req;
1048  req.key.reset(key);
1049  req.data.reset(tnh_data);
1050  agent_->nexthop_table()->Enqueue(&req);
1051 
1052  MCTRACE(Log, "Enqueue add TOR TUNNEL ",
1053  agent_->fabric_vrf_name(),
1054  it->daddr_.to_string(), it->label_);
1055 
1056  ComponentNHKeyPtr component_key_ptr(new ComponentNHKey(it->label_,
1057  agent_->fabric_vrf_name(),
1058  agent_->router_id(), it->daddr_,
1059  false, it->tunnel_bmap_));
1060  component_nh_key_list.push_back(component_key_ptr);
1061  route_tunnel_bmap = it->tunnel_bmap_;
1062  }
1063 
1064  MCTRACE(LogSG, "enqueue route change with remote peer",
1065  obj->vrf_name(),
1066  obj->GetSourceAddress().to_string(),
1067  obj->GetGroupAddress().to_string(),
1068  component_nh_key_list.size());
1069 
1070  //Delete fabric path, so that only PBB route points
1071  //to MPLS route
1072  if (comp_type == Composite::FABRIC &&
1073  ((obj->mg_list_.empty() == false || obj->pbb_etree_enabled() == true))) {
1074  DeleteMulticastRoute(peer, vrf_name, src, grp, ethernet_tag, comp_type);
1075  return;
1076  }
1077 
1078  //Add Bridge FF:FF:FF:FF:FF:FF for L2 Multicast
1079  if (comp_type == Composite::TOR)
1080  route_tunnel_bmap = TunnelType::VxlanType();
1081  const BgpPeer *bgp_peer = dynamic_cast<const BgpPeer *>(peer);
1082  AgentRouteData *data = NULL;
1083  AgentRouteData *bridge_data = NULL;
1084  if (bgp_peer) {
1086  obj->vrf_name(),
1087  obj->GetVnName(),
1088  label,
1089  obj->vxlan_id(),
1090  ethernet_tag,
1091  route_tunnel_bmap,
1092  comp_type,
1093  component_nh_key_list,
1094  obj->pbb_vrf(), false);
1095  } else {
1097  obj->GetVnName(),
1098  label,
1099  obj->vxlan_id(),
1100  route_tunnel_bmap,
1101  comp_type,
1102  component_nh_key_list,
1103  obj->pbb_vrf(), false);
1104  }
1105 
1106  boost::system::error_code ec;
1107  Ip4Address bcast_addr =
1108  IpAddress::from_string("255.255.255.255", ec).to_v4();
1109  if ((grp != bcast_addr) && !agent_->params()->mvpn_ipv4_enable()) {
1110  if (bgp_peer) {
1111  bridge_data = BridgeAgentRouteTable::BuildBgpPeerData(peer,
1112  obj->vrf_name(), obj->GetVnName(), label,
1113  obj->vxlan_id(), ethernet_tag,
1114  route_tunnel_bmap, Composite::FABRIC,
1115  component_nh_key_list,
1116  obj->pbb_vrf(), false);
1117  } else {
1119  obj->vrf_name(), obj->GetVnName(), label,
1120  obj->vxlan_id(), route_tunnel_bmap,
1121  Composite::FABRIC, component_nh_key_list,
1122  obj->pbb_vrf(), false);
1123  }
1124  }
1125 
1126  AddMulticastRoute(obj, peer, ethernet_tag, data, bridge_data);
1127  MCTRACE(LogSG, "rebake subnet peer for subnet", vrf_name,
1128  obj->GetSourceAddress().to_string(),
1129  obj->GetGroupAddress().to_string(), comp_type);
1130 }
1131 
1133  const std::string &vrf_name) {
1134  const uuid intf_uuid = vm_itf->GetUuid();
1135  const VnEntry *vn = vm_itf->vn();
1136  MulticastGroupObject *all_broadcast = NULL;
1137  boost::system::error_code ec;
1138  Ip4Address broadcast = IpAddress::from_string("255.255.255.255",
1139  ec).to_v4();
1140  bool add_route = false;
1141  std::string vn_name = vn->GetName();
1142 
1143  //TODO Push every thing via multi proto and remove multi proto check
1144  //All broadcast addition 255.255.255.255
1145  all_broadcast = this->FindGroupObject(vrf_name, Ip4Address(), broadcast);
1146  if (all_broadcast == NULL) {
1147  all_broadcast = CreateMulticastGroupObject(vrf_name, vn->GetName(),
1148  Ip4Address(), broadcast,
1149  vn->GetVxLanId());
1150  add_route = true;
1151  }
1152 
1153  //Modify Nexthops
1154  if (all_broadcast->AddLocalMember(intf_uuid, vm_itf->vm_mac()) == true) {
1155  TriggerLocalRouteChange(all_broadcast, agent_->local_vm_peer());
1156  AddVmToMulticastObjMap(intf_uuid, all_broadcast);
1157  }
1158  //Modify routes
1159  if (add_route) {
1162  all_broadcast->set_vxlan_id(vn->GetVxLanId());
1163  }
1164  TriggerLocalRouteChange(all_broadcast, agent_->local_vm_peer());
1165  }
1166 }
1167 
1168 /*
1169  * Static funtion to be called to handle XMPP info from ctrl node
1170  * Key is VRF/G/S
1171  * Info has label (for source to vrouter) and
1172  * OLIST of NH (server IP + label for that server)
1173  */
1175  const std::string &vrf_name,
1176  const Ip4Address &grp,
1177  const Ip4Address &src,
1178  uint32_t label,
1179  const TunnelOlist &olist,
1180  uint64_t peer_identifier)
1181 {
1182  boost::system::error_code ec;
1183  MulticastGroupObject *obj = NULL;
1184  obj = FindActiveGroupObject(vrf_name, src, grp);
1185  MCTRACE(LogSG, "XMPP call(edge replicate) multicast handler ", vrf_name,
1186  src.to_string(), grp.to_string(), label);
1187 
1188  bool delete_op = false;
1189 
1190  //Invalid peer identifier signifies delete.
1191  //If add operation, obj should exist, else return.
1192  if (peer_identifier == ControllerPeerPath::kInvalidPeerIdentifier) {
1193  delete_op = true;
1194  } else if (obj == NULL) {
1195  return;
1196  }
1197 
1198  if (peer == NULL) {
1199  return;
1200  }
1201 
1202  if (obj) {
1203  if (delete_op) {
1204  obj->set_peer(NULL);
1205  TunnelOlist empty_list;
1206  obj->set_fabric_olist(empty_list);
1207  obj->set_fabric_label(label);
1208  } else {
1209  obj->set_peer(peer);
1210  obj->set_fabric_olist(olist);
1211  obj->set_fabric_label(label);
1212  }
1213  }
1214 
1215  Ip4Address bcast_addr =
1216  IpAddress::from_string("255.255.255.255", ec).to_v4();
1217  Composite::Type comp_type = Composite::FABRIC;
1218  if (grp != bcast_addr) {
1219  comp_type = Composite::L3FABRIC;
1220  }
1221 
1222  TriggerRemoteRouteChange(obj, peer, vrf_name, src, grp, olist,
1223  peer_identifier,
1224  delete_op, comp_type,
1225  label, true, 0);
1226 
1227  if (obj == NULL) {
1228  return;
1229  }
1230 
1232  iter != obj->mg_list_end(); iter++) {
1233  MulticastGroupObject *mg =
1234  static_cast<MulticastGroupObject *>(iter.operator->());
1235  TriggerRemoteRouteChange(mg, peer, iter->vrf_name(), src, grp,
1236  olist, peer_identifier,
1237  delete_op, comp_type,
1238  label, true, 0);
1239  }
1240 
1241  MCTRACE(LogSG, "Add fabric grp label ", vrf_name, src.to_string(),
1242  grp.to_string(), label);
1243 }
1244 
1246  const std::string &vrf_name,
1247  const Ip4Address &grp,
1248  const Ip4Address &src,
1249  const TunnelOlist &olist,
1250  uint32_t ethernet_tag,
1251  uint64_t peer_identifier) {
1252 
1253  boost::system::error_code ec;
1254  MulticastGroupObject *obj = FindActiveGroupObject(vrf_name, src, grp);
1255 
1256  MCTRACE(LogSG, "XMPP call(EVPN) multicast handler ", vrf_name, src.to_string(),
1257  grp.to_string(), 0);
1258 
1259  bool delete_op = false;
1260  if (peer_identifier == ControllerPeerPath::kInvalidPeerIdentifier) {
1261  delete_op = true;
1262  } else if (obj == NULL) {
1263  return;
1264  }
1265 
1266  TriggerRemoteRouteChange(obj, peer, vrf_name, src, grp, olist,
1267  peer_identifier, delete_op,
1269  false, ethernet_tag);
1270 
1271  MCTRACE(LogSG, "Add EVPN TOR Olist ", vrf_name, src.to_string(),
1272  grp.to_string(), 0);
1273 
1274  return;
1275 }
1276 
1277 /*
1278  * Request to populate evpn olist by list of TOR NH seen by control node
1279  * Currently this is done only for TOR/Gateway(outside contrail vrouter network)
1280  * Source label is ignored as it is used by non-vrouters.
1281  * Olist consists of TOR/Gateway endpoints with label advertised or use VXLAN.
1282  * Note: Non Vrouter can talk in VXLAN/MPLS. Encap received in XMPP will
1283  * convey the same.
1284  */
1286  const std::string &vrf_name,
1287  const TunnelOlist &olist,
1288  uint32_t ethernet_tag,
1289  uint64_t peer_identifier)
1290 {
1291  boost::system::error_code ec;
1292  Ip4Address grp = Ip4Address::from_string("255.255.255.255", ec);
1293  MulticastGroupObject *obj = FindActiveGroupObject(vrf_name,
1294  Ip4Address(), grp);
1295  std::string derived_vrf_name = vrf_name;
1296 
1297  if (ethernet_tag && obj) {
1298  MulticastGroupObject *dependent_mg =
1299  obj->GetDependentMG(ethernet_tag);
1300  if (dependent_mg) {
1301  obj = dependent_mg;
1302  derived_vrf_name = obj->vrf_name();
1303  }
1304  }
1305 
1306  MCTRACE(Log, "XMPP call(EVPN) multicast handler ", derived_vrf_name,
1307  grp.to_string(), 0);
1308 
1309  bool delete_op = false;
1310  if (peer_identifier == ControllerPeerPath::kInvalidPeerIdentifier) {
1311  delete_op = true;
1312  } else if (obj == NULL) {
1313  return;
1314  }
1315 
1316  TriggerRemoteRouteChange(obj, peer, derived_vrf_name, Ip4Address(), grp,
1317  olist, peer_identifier, delete_op, Composite::EVPN,
1318  MplsTable::kInvalidLabel, false, ethernet_tag);
1319  MCTRACE(Log, "Add EVPN TOR Olist ", derived_vrf_name, grp.to_string(), 0);
1320 }
1321 
1323  const std::string &vrf_name,
1324  const TunnelOlist &olist,
1325  uint32_t ethernet_tag,
1326  uint64_t peer_identifier)
1327 {
1328  boost::system::error_code ec;
1329 
1330  Ip4Address grp = Ip4Address::from_string("255.255.255.255", ec);
1331  MulticastGroupObject *obj = FindActiveGroupObject(vrf_name, Ip4Address(),
1332  grp);
1333  MCTRACE(Log, "TOR multicast handler ", vrf_name, grp.to_string(), 0);
1334 
1335  bool delete_op = false;
1336  if (peer_identifier == ControllerPeerPath::kInvalidPeerIdentifier) {
1337  delete_op = true;
1338  } else if (obj == NULL) {
1339  return;
1340  }
1341 
1342  TriggerRemoteRouteChange(obj, peer, vrf_name, Ip4Address(), grp, olist,
1343  peer_identifier, delete_op, Composite::TOR,
1344  MplsTable::kInvalidLabel, false, ethernet_tag);
1345  MCTRACE(Log, "Add external TOR Olist ", vrf_name, grp.to_string(), 0);
1346 }
1347 
1349  const std::string &vrf_name,
1350  const Ip4Address &grp,
1351  const Ip4Address &src,
1352  uint64_t peer_identifier) {
1353 
1354  MulticastGroupObject *obj = NULL;
1355  obj = FindGroupObject(vrf_name, src, grp);
1356 
1357  bool delete_op = false;
1358  if (peer_identifier == ControllerPeerPath::kInvalidPeerIdentifier) {
1359  delete_op = true;
1360  } if (!obj) {
1361  return;
1362  }
1363 
1364  TunnelOlist olist;
1365  TriggerRemoteRouteChange(obj, peer, vrf_name, src, grp, olist,
1366  peer_identifier, delete_op, Composite::L3FABRIC, 0,
1367  true, 0);
1368  return;
1369 }
1370 
1371 // Helper to delete fabric nh
1372 // For internal delete it uses invalid identifier.
1373 // For delete via control node it uses the sequence sent.
1375  const Peer *peer,
1376  uint64_t peer_identifier) {
1377  if ((peer_identifier != peer_identifier_) ||
1378  (peer_identifier == INVALID_PEER_IDENTIFIER)) {
1379  boost::system::error_code ec;
1380  Ip4Address bcast_addr = IpAddress::from_string("255.255.255.255",
1381  ec).to_v4();
1382  if (GetGroupAddress() != bcast_addr) {
1383  agent->oper_db()->multicast()->DeleteMulticastRoute(peer,
1384  vrf_name_, src_address_,
1385  grp_address_, 0,
1387  } else {
1388  agent->oper_db()->multicast()->DeleteBroadcast(peer, vrf_name_, 0,
1390  MCTRACE(Log, "Delete broadcast route", vrf_name_,
1391  grp_address_.to_string(), 0);
1392  }
1393  }
1394 }
1395 
1397  agent_(agent),
1398  vn_listener_id_(DBTable::kInvalidId),
1399  interface_listener_id_(DBTable::kInvalidId),
1400  physical_device_listener_id_(DBTable::kInvalidId),
1401  physical_devices_() {
1403  te_walker_.reset(new MulticastTEWalker("MulticastTorElectorWalker", agent));
1404  }
1405  obj_ = this;
1406 }
1407 
1408 bool MulticastHandler::FlushPeerInfo(uint64_t peer_sequence) {
1409  for (std::set<MulticastGroupObject *>::iterator it =
1410  GetMulticastObjList().begin(); it != GetMulticastObjList().end();
1411  it++) {
1412  //Delete all control node given paths
1413  (*it)->FlushAllPeerInfo(agent_, agent_->multicast_tree_builder_peer(),
1414  peer_sequence);
1415  }
1416  return false;
1417 }
1418 
1419 /*
1420  * Shutdown for clearing all stuff related to multicast
1421  */
1423 
1424  boost::system::error_code ec;
1425  Ip4Address bcast_addr = IpAddress::from_string("255.255.255.255",
1426  ec).to_v4();
1427  //Delete all route mpls and trigger cnh change
1428  for (std::set<MulticastGroupObject *>::iterator it =
1429  GetMulticastObjList().begin(); it != GetMulticastObjList().end();
1430  it++) {
1431  MulticastGroupObject *obj = (*it);
1432 
1433  AgentRoute *route = NULL;
1434  if (obj->GetGroupAddress() != bcast_addr) {
1436  dynamic_cast<Inet4MulticastAgentRouteTable *>
1438  if (mtable) {
1439  route = mtable->FindRoute(obj->GetGroupAddress(),
1440  obj->GetSourceAddress());
1441  }
1442  } else {
1443  BridgeAgentRouteTable *bridge_table =
1444  static_cast<BridgeAgentRouteTable *>
1446  if (bridge_table) {
1447  route = bridge_table->FindRoute(MacAddress::BroadcastMac());
1448  }
1449  }
1450 
1451  if (route == NULL) {
1452  delete (obj);
1453  this->GetMulticastObjList().erase(obj);
1454  continue;
1455  }
1456 
1457  for(Route::PathList::iterator it = route->GetPathList().begin();
1458  it != route->GetPathList().end(); it++) {
1459  const AgentPath *path =
1460  static_cast<const AgentPath *>(it.operator->());
1461  //Delete the tunnel OLIST
1462  (obj)->FlushAllPeerInfo(agent_,
1463  path->peer(),
1465  }
1466  //Delete the multicast object
1467  delete (obj);
1468  this->GetMulticastObjList().erase(obj);
1469  }
1470 }
1471 
1473  std::set<MulticastGroupObject *>::iterator it =
1474  multicast_obj_list_.begin();
1475  for (; it != multicast_obj_list_.end(); it++) {
1476  MulticastGroupObject *mg =
1477  static_cast<MulticastGroupObject *>(*it);
1478  if (mg->pbb_vrf() && mg->pbb_vrf_name() == obj->vrf_name()) {
1479  //Since reference is getting added on
1480  //addition, any eventual fabric notification
1481  //will result in ISID VRF also getting updated
1482  mg->set_dependent_mg(obj);
1484  }
1485  }
1486 }
1487 
1489  VrfKey key(obj->vrf_name());
1490  VrfEntry *vrf =
1491  static_cast<VrfEntry *>(agent_->vrf_table()->FindActiveEntry(&key));
1492  if (vrf && vrf->IsPbbVrf()) {
1493  //ISID VRF are dependent on BMAC VRF to build egde replication
1494  //tree, take a reference on BMAC VRF so that every time
1495  //BMAC VRF fabric list changes, ISID VRF can also be updated
1496  obj->set_pbb_vrf(true);
1497  obj->set_pbb_vrf_name(vrf->bmac_vrf_name());
1498 
1499  //Set dependent VRF
1500  MulticastGroupObject *dependent_mg =
1501  FindFloodGroupObject(vrf->bmac_vrf_name());
1502  obj->set_dependent_mg(dependent_mg);
1503  Resync(obj);
1504  } else {
1505  //If this a BMAC VRF, there may be ISID VRF dependent
1506  //on this new BMAC VRF
1507  //Evaulate them
1508  ResyncDependentVrf(obj);
1509  }
1510 }
1511 
1513  MulticastGroupObject *dependent_mg = obj->dependent_mg();
1514  if (dependent_mg && dependent_mg->peer()) {
1515  ModifyFabricMembers(dependent_mg->peer(),
1516  dependent_mg->vrf_name(),
1517  dependent_mg->GetGroupAddress(),
1518  dependent_mg->GetSourceAddress(),
1519  dependent_mg->fabric_label(),
1520  dependent_mg->fabric_olist(),
1521  dependent_mg->peer_identifier());
1522  }
1524 }
1525 
1527  VrfKey key(obj->vrf_name());
1528  VrfEntry *vrf =
1529  static_cast <VrfEntry *>(agent_->vrf_table()->FindActiveEntry(&key));
1530  if (vrf == NULL) {
1531  return;
1532  }
1533 
1534  BridgeAgentRouteTable *br_table =
1535  static_cast<BridgeAgentRouteTable *>(vrf->GetBridgeRouteTable());
1536  BridgeRouteEntry *bridge_route =
1537  br_table->FindRoute(MacAddress::BroadcastMac());
1538  if (bridge_route == NULL){
1539  return;
1540  }
1541 
1542  for(Route::PathList::iterator it = bridge_route->GetPathList().begin();
1543  it != bridge_route->GetPathList().end();it++) {
1544  AgentPath *path =
1545  static_cast<AgentPath *>(it.operator->());
1546  const Peer *peer = path->peer();
1547  if (peer && peer->GetType() == Peer::BGP_PEER) {
1548  DeleteBroadcast(peer, obj->vrf_name(), obj->vxlan_id(),
1549  Composite::EVPN);
1550  }
1551  }
1552 }
1553 
1555 
1556  ComponentNHKeyList component_nh_key_list;
1557 
1558  uint32_t route_tunnel_bmap;
1559  route_tunnel_bmap = agent_->params()->mvpn_ipv4_enable() ?
1561 
1562  AgentRouteData *data =
1564  sg_object->GetVnName(), 0,
1565  sg_object->vxlan_id(),
1566  route_tunnel_bmap, Composite::L3COMP,
1567  component_nh_key_list, sg_object->pbb_vrf(),
1568  sg_object->learning_enabled());
1570  sg_object->vrf_name(),
1571  sg_object->GetSourceAddress(),
1572  sg_object->GetGroupAddress(),
1573  sg_object->vxlan_id(), data);
1574 
1575  if (!agent_->params()->mvpn_ipv4_enable()) {
1576  MacAddress mac;
1577  GetMulticastMacFromIp(sg_object->GetGroupAddress(), mac);
1578 
1579  AgentRouteData *bridge_data =
1581  sg_object->GetVnName(), 0,
1582  sg_object->vxlan_id(),
1583  route_tunnel_bmap, Composite::L2COMP,
1584  component_nh_key_list, sg_object->pbb_vrf(),
1585  sg_object->learning_enabled());
1587  sg_object->vrf_name(), mac,
1588  sg_object->vxlan_id(), bridge_data);
1589  }
1590 
1591  return;
1592 }
1593 
1595 
1597  sg_object->vrf_name(),
1598  sg_object->GetSourceAddress(),
1599  sg_object->GetGroupAddress(),
1600  sg_object->vxlan_id(), Composite::L3COMP);
1601 
1602  MacAddress mac;
1603  GetMulticastMacFromIp(sg_object->GetGroupAddress(), mac);
1604 
1606  sg_object->vrf_name(), mac,
1607  sg_object->vxlan_id(), Composite::L2COMP);
1608 }
1609 
1610 // Create MulticastGroupObject on learning new <S,G>
1611 //
1612 // Note :
1613 // For EVPN: Routes are added to both Inet Multicast table
1614 // and Bridge table in the native VRF only.
1615 // For MVPN: Routes are added to Inet Multicast table only
1616 // but in both the native VRF and ip-fabric VRF.
1617 // However, API CreateMulticastVrfSourceGroup is used only for
1618 // EVPN for now.
1619 //
1621  const std::string &vrf_name,
1622  const std::string &vn_name,
1623  const Ip4Address &src_addr,
1624  const Ip4Address &grp_addr) {
1625 
1626  VrfEntry *vrf = agent_->vrf_table()->FindVrfFromName(vrf_name);
1627  if (!vrf || vrf->IsDeleted()) return;
1628 
1629  MCTRACE(LogSG, "Add SG ", vrf_name, src_addr.to_string(),
1630  grp_addr.to_string(), 0);
1631 
1632  bool created = false;
1633  MulticastGroupObject *sg_object = NULL;
1634  sg_object = FindGroupObject(vrf_name, src_addr, grp_addr);
1635  if (sg_object == NULL) {
1636  sg_object = CreateMulticastGroupObject(vrf_name, vn_name,
1637  src_addr, grp_addr, vrf->vxlan_id());
1638  AddLocalPeerRoute(sg_object);
1639  created = true;
1640  }
1641 
1642  if (created) {
1644  }
1645 
1646  MCTRACE(LogSG, "Add SG done ", vrf_name, src_addr.to_string(),
1647  grp_addr.to_string(), 0);
1648 
1649  return;
1650 }
1651 
1652 // Delete VM-Interface from a MulticastGroupObject
1653 // Delete of VMI will trigger route change for the <S,G>
1654 // Last VMI to go will also trigger cleaning up of route
1655 // and also the VRF,<S,G> data structure.
1656 // API used in case of EVPN
1658  MulticastGroupObject *sg_object,
1659  boost::uuids::uuid vm_itf_uuid) {
1660 
1661  if (!sg_object) {
1662  return;
1663  }
1664 
1666 
1667  if ((sg_object->DeleteLocalMember(vm_itf_uuid) == true) &&
1668  (sg_object->IsDeleted() == false) &&
1669  (sg_object->GetLocalListSize() != 0)) {
1670 
1672  MCTRACE(LogSG, "modify route, vm is deleted for <S,G> ",
1673  sg_object->vrf_name(),
1674  sg_object->GetSourceAddress().to_string(),
1675  sg_object->GetGroupAddress().to_string(), 0);
1676  }
1677 
1678  if (sg_object->GetLocalListSize() == 0) {
1679  if (sg_object->vrf_name() != agent_->fabric_policy_vrf_name()) {
1680  MulticastGroupObject *mvpn_sg_object = NULL;
1681  mvpn_sg_object = FindGroupObject(
1683  sg_object->GetSourceAddress(),
1684  sg_object->GetGroupAddress());
1685  if (mvpn_sg_object)
1686  mvpn_sg_object->decr_vn_count();
1687  }
1688  }
1689 
1690  if ((sg_object->GetLocalListSize() == 0) &&
1691  (sg_object->vn_count() == 0)) {
1692 
1693  //Time to delete route(for mcast address) and mpls
1695  sg_object->vrf_name(),
1696  sg_object->GetSourceAddress(),
1697  sg_object->GetGroupAddress(), 0, comp_type);
1698  DeleteLocalPeerRoute(sg_object);
1699  DeleteMulticastObject(sg_object->vrf_name(),
1700  sg_object->GetSourceAddress(),
1701  sg_object->GetGroupAddress());
1702  }
1703 
1704  return;
1705 }
1706 
1707 // Delete all VM-Interfaces for a particular <S,G> for a particular VRF
1708 // API used in case of EVPN
1710  const std::string &vrf_name,
1711  const Ip4Address &src_addr,
1712  const Ip4Address &grp_addr) {
1713 
1714  MulticastGroupObject *sg_object = NULL;
1715 
1716  MCTRACE(LogSG, "Delete SG ", vrf_name, src_addr.to_string(),
1717  grp_addr.to_string(), 0);
1718 
1719  sg_object = FindGroupObject(vrf_name, src_addr, grp_addr);
1720  if (!sg_object) {
1721  return;
1722  }
1723 
1724  std::map<uuid, MacAddress>::const_iterator it;
1725  it = sg_object->GetLocalList().begin();
1726  while (it != sg_object->GetLocalList().end()) {
1727 
1728  boost::uuids::uuid vm_itf_uuid = it->first;
1729  HandleRouteChangeAndMulticastObject(sg_object, vm_itf_uuid);
1730 
1731  DeleteVmToMulticastObjMap(vm_itf_uuid, sg_object);
1732 
1733  MCTRACE(LogSG, "VMI delete notify done for <S,G> ", vrf_name,
1734  src_addr.to_string(), grp_addr.to_string(), 0);
1735 
1736  sg_object = FindGroupObject(vrf_name, src_addr, grp_addr);
1737  if (sg_object) {
1738  it = sg_object->GetLocalList().begin();
1739  } else {
1740  break;
1741  }
1742  }
1743 
1744  MCTRACE(LogSG, "Delete SG done ", vrf_name, src_addr.to_string(),
1745  grp_addr.to_string(), 0);
1746 
1747  return;
1748 }
1749 
1750 // Add VM-Interface for a particular <S,G> for a particular VRF
1751 // API used in case of MVPN and also EVPN
1753  const std::string &vrf_name,
1754  const std::string &vn_name,
1755  const VmInterface *vm_itf,
1756  const Ip4Address &src_addr,
1757  const Ip4Address &grp_addr) {
1758 
1759  VrfEntry *vrf = agent_->vrf_table()->FindVrfFromName(vrf_name);
1760  if (!vrf || vrf->IsDeleted()) return false;
1761 
1762  MCTRACE(LogSG, "VMI add notify ", vrf_name, src_addr.to_string(),
1763  grp_addr.to_string(), 0);
1764 
1765  const uuid intf_uuid = vm_itf->GetUuid();
1766  MulticastGroupObject *sg_object = NULL;
1767 
1768  bool created = false;
1769 
1770  sg_object = FindGroupObject(vrf_name, src_addr, grp_addr);
1771  if (sg_object == NULL) {
1772  sg_object = CreateMulticastGroupObject(vrf_name, vn_name, src_addr,
1773  grp_addr, vrf->vxlan_id());
1774  AddLocalPeerRoute(sg_object);
1775  created = true;
1776  }
1777 
1778  //Modify Nexthops
1779  if (sg_object->AddLocalMember(intf_uuid, vm_itf->vm_mac()) == true) {
1781  AddVmToMulticastObjMap(intf_uuid, sg_object);
1782  } else if (created) {
1783  //Modify routes
1785  }
1786 
1787  MCTRACE(LogSG, "VMI add notify done ", vrf_name, src_addr.to_string(),
1788  grp_addr.to_string(), 0);
1789 
1790  return created;
1791 }
1792 
1793 // Add VM-Interface for a particular <S,G>
1794 // API used in case of MVPN
1796  const std::string &mc_vrf_name,
1797  const std::string &vn_name,
1798  const VmInterface *vm_itf,
1799  const Ip4Address &src_addr,
1800  const Ip4Address &grp_addr) {
1801 
1802  VrfEntry *vrf = agent_->vrf_table()->FindVrfFromName(mc_vrf_name);
1803  if (!vrf || vrf->IsDeleted()) return;
1804 
1805  MCTRACE(LogSG, "VMI add notify ", mc_vrf_name, src_addr.to_string(),
1806  grp_addr.to_string(), 0);
1807 
1808  bool created = false;
1809  created = AddVmInterfaceToVrfSourceGroup(vm_itf->vrf()->GetName(), vn_name,
1810  vm_itf, src_addr, grp_addr);
1811 
1812  MulticastGroupObject *mvpn_sg_object = NULL;
1813 
1814  MulticastGroupObject *sg_object = NULL;
1815  sg_object = FindGroupObject(vm_itf->vrf()->GetName(), src_addr, grp_addr);
1816  if (sg_object) {
1817  if (sg_object->mvpn_registered()) {
1818  AddVmInterfaceToVrfSourceGroup(mc_vrf_name,
1819  vn_name, vm_itf, src_addr, grp_addr);
1820  mvpn_sg_object = FindGroupObject(mc_vrf_name, src_addr, grp_addr);
1821  } else {
1822  mvpn_sg_object = FindGroupObject(mc_vrf_name, src_addr, grp_addr);
1823  if (mvpn_sg_object == NULL) {
1824  mvpn_sg_object = CreateMulticastGroupObject(mc_vrf_name,
1825  vn_name, src_addr, grp_addr, vrf->vxlan_id());
1826  AddLocalPeerRoute(sg_object);
1827  TriggerLocalRouteChange(mvpn_sg_object, agent_->local_vm_peer());
1828  }
1829  }
1830  }
1831  if (created) {
1832  mvpn_sg_object->incr_vn_count();
1833  }
1834 
1835  MCTRACE(LogSG, "VMI add notify done ", mc_vrf_name, src_addr.to_string(),
1836  grp_addr.to_string(), 0);
1837 
1838  return;
1839 }
1840 
1841 // Delete VM-Interface from a particular <S,G> for the specified VRF.
1842 // API used in case of MVPN and also EVPN
1844  const std::string &vrf_name,
1845  const VmInterface *vm_itf,
1846  const Ip4Address &src_addr,
1847  const Ip4Address &grp_addr) {
1848 
1849  MulticastGroupObject *sg_object = NULL;
1850 
1851  sg_object = FindGroupObject(vrf_name, src_addr, grp_addr);
1852  if (!sg_object) {
1853  return;
1854  }
1855 
1856  MCTRACE(LogSG, "VMI delete notify ", vrf_name, src_addr.to_string(),
1857  grp_addr.to_string(), 0);
1858 
1859  boost::uuids::uuid vm_itf_uuid = vm_itf->GetUuid();
1860  HandleRouteChangeAndMulticastObject(sg_object, vm_itf_uuid);
1861 
1862  DeleteVmToMulticastObjMap(vm_itf->GetUuid(), sg_object);
1863 
1864  MCTRACE(LogSG, "VMI delete notify done ", vrf_name, src_addr.to_string(),
1865  grp_addr.to_string(), 0);
1866 
1867  return;
1868 }
1869 
1870 // Delete VM-Interface from a particular <S,G>
1871 // API used in case of MVPN
1873  const std::string &mc_vrf_name,
1874  const VmInterface *vm_itf,
1875  const Ip4Address &src_addr,
1876  const Ip4Address &grp_addr) {
1877 
1879  vm_itf, src_addr, grp_addr);
1880  DeleteVmInterfaceFromVrfSourceGroup(mc_vrf_name, vm_itf, src_addr,
1881  grp_addr);
1882 }
1883 
1884 // Delete VM-Interface from all the learnt <S,G>s belonging
1885 // to a particular group for the specified VRF.
1886 // API used in case of MVPN and also EVPN
1887 // grp_addr, when default, indicate all <S,G>s except broadcast.
1889  const std::string &vrf_name,
1890  const VmInterface *vm_itf,
1891  const Ip4Address &grp_addr) {
1892 
1893  MulticastGroupObjectList objList;
1894 
1895  if (!FindVmToMulticastObjMap(vm_itf->GetUuid(), objList)) {
1896  return;
1897  }
1898 
1899  MCTRACE(LogSG, "VMI delete notify ", vrf_name, Ip4Address().to_string(),
1900  grp_addr.to_string(), 0);
1901 
1902  std::set<MulticastGroupObject *> sg_to_delete;
1903  boost::system::error_code ec;
1904  Ip4Address bcast_addr =
1905  IpAddress::from_string("255.255.255.255", ec).to_v4();
1906  for(std::set<MulticastGroupObject *>::iterator sg_it = objList.begin();
1907  sg_it != objList.end(); sg_it++) {
1908 
1909  if ((*sg_it)->vrf_name() != vrf_name) {
1910 
1911  continue;
1912  }
1913 
1914  if ((grp_addr.is_unspecified() &&
1915  (*sg_it)->GetGroupAddress() == bcast_addr)) {
1916 
1917  continue;
1918  }
1919 
1920  if ((!grp_addr.is_unspecified() &&
1921  (*sg_it)->GetGroupAddress() != grp_addr)) {
1922 
1923  continue;
1924  }
1925 
1926  boost::uuids::uuid vm_itf_uuid = vm_itf->GetUuid();
1927  HandleRouteChangeAndMulticastObject((*sg_it), vm_itf_uuid);
1928 
1929  sg_to_delete.insert(*sg_it);
1930  }
1931 
1932  for(std::set<MulticastGroupObject *>::iterator sg_it = sg_to_delete.begin();
1933  sg_it != sg_to_delete.end(); sg_it++) {
1934  DeleteVmToMulticastObjMap(vm_itf->GetUuid(), *sg_it);
1935  }
1936 
1937  MCTRACE(LogSG, "VMI delete notify done ", vrf_name,
1938  Ip4Address().to_string(),
1939  grp_addr.to_string(), 0);
1940 
1941  return;
1942 }
1943 
1944 // Delete VM-Interface from all the learnt <S,G>s belonging
1945 // to a particular group
1946 // API used in case of MVPN
1948  const std::string &mc_vrf_name,
1949  const VmInterface *vm_itf,
1950  const Ip4Address &grp_addr) {
1951 
1952  DeleteVmInterfaceFromVrfSourceGroup(vm_itf->vrf()->GetName(), vm_itf,
1953  grp_addr);
1954  DeleteVmInterfaceFromVrfSourceGroup(mc_vrf_name, vm_itf, grp_addr);
1955 }
1956 
1957 // Delete VM-Interface from all the learnt <S,G>s
1958 // API used in case of MVPN
1960  const std::string &mc_vrf_name,
1961  const std::string &vm_vrf_name,
1962  const VmInterface *vm_itf) {
1963 
1964  DeleteVmInterfaceFromVrfSourceGroup(vm_vrf_name, vm_itf);
1965  DeleteVmInterfaceFromVrfSourceGroup(mc_vrf_name, vm_itf);
1966 }
1967 
1968 // Flags set to for use in SMET routes. Flags sent in XMPP message
1969 // to the control BGP
1971  const std::string &vrf_name,
1972  const Ip4Address &src_addr,
1973  const Ip4Address &grp_addr,
1974  uint32_t flags) {
1975 
1976  MulticastGroupObject *sg_object = NULL;
1977  sg_object = FindGroupObject(vrf_name, src_addr, grp_addr);
1978 
1979  if (sg_object) sg_object->set_evpn_igmp_flags(flags);
1980 
1981  return;
1982 }
1983 
1984 // Flags Get API for use of flags in SMET routes. Flags sent in XMPP
1985 // message to the control BGP
1987  const std::string &vrf_name,
1988  const Ip4Address &src_addr,
1989  const Ip4Address &grp_addr) {
1990 
1991  MulticastGroupObject *sg_object = NULL;
1992  sg_object = FindGroupObject(vrf_name, src_addr, grp_addr);
1993 
1994  return (sg_object ? sg_object->evpn_igmp_flags() : 0);
1995 }
1996 
1997 MulticastTEWalker::MulticastTEWalker(const std::string &name, Agent *agent) :
1998  AgentRouteWalker(name, agent) {
1999 }
2000 
2002 }
2003 
2005  DBEntryBase *e) {
2006  Agent *agent = (static_cast<AgentRouteTable *>
2007  (partition->parent()))->agent();
2008  BridgeRouteEntry *bridge_route = static_cast<BridgeRouteEntry *>(e);
2009  bool notify = false;
2010  for(Route::PathList::iterator it = bridge_route->GetPathList().begin();
2011  it != bridge_route->GetPathList().end();it++) {
2012  MulticastRoutePath *path = dynamic_cast<MulticastRoutePath *>
2013  (it.operator->());
2014  if (!path)
2015  continue;
2016 
2017  const Peer *peer = path->peer();
2018  if (!peer)
2019  continue;
2020 
2021  if (peer->GetType() != Peer::BGP_PEER)
2022  continue;
2023 
2024  const CompositeNH *cnh = dynamic_cast<const CompositeNH *>
2025  (path->nexthop());
2026  if (!cnh)
2027  continue;
2028 
2029  if (cnh->composite_nh_type() != Composite::EVPN)
2030  continue;
2031  NextHop *nh = path->UpdateNH(agent,
2032  static_cast<CompositeNH *>(path->original_nh().get()),
2033  agent->oper_db()->tsn_elector());
2034  if (path->ChangeNH(agent, nh) && bridge_route->ReComputePathAdd(path))
2035  notify = true;
2036  }
2037  if (notify)
2038  partition->Notify(bridge_route);
2039  return true;
2040 }
void DeleteVmInterface(const VmInterface *intf, const std::string &vrf_name)
Definition: multicast.cc:678
int GetVxLanId() const
Definition: vn.cc:727
MulticastHandler * multicast() const
Definition: operdb_init.h:53
NextHopRef original_nh() const
Definition: agent_path.h:857
void AddVmInterfaceToSourceGroup(const std::string &mvpn_vrf_name, const std::string &vn_name, const VmInterface *vm_itf, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1795
std::set< std::string > vrf_list_
Definition: multicast.h:65
void Terminate()
Definition: multicast.cc:71
BridgeDomainEntrySet list_
bool layer2_control_word_
Definition: multicast.h:53
bool layer2_control_word() const
Definition: bridge_domain.h:85
void ModifyMvpnVrfRegistration(const Peer *peer, const std::string &vrf_name, const Ip4Address &group, const Ip4Address &source, uint64_t peer_identifier)
Definition: multicast.cc:1348
uint32_t GetLocalListSize()
Definition: multicast.h:124
void TriggerLocalRouteChange(MulticastGroupObject *obj, const Peer *peer)
Definition: multicast.cc:843
const VnEntry * vn() const
Definition: bridge_domain.h:57
const MacAddress & vm_mac() const
Type type() const
Definition: interface.h:112
bool ChangeNH(Agent *agent, NextHop *nh)
Definition: agent_path.cc:119
static MulticastHandler * obj_
Definition: multicast.h:578
MulticastGroupObject * FindGroupObject(const std::string &vrf_name, const Ip4Address &sip, const Ip4Address &dip)
Definition: multicast.cc:772
TsnElector * tsn_elector() const
Definition: operdb_init.h:94
Agent * agent() const
const std::string & vrf_name() const
Definition: multicast.h:133
void ChangePbbEtreeMode(MulticastGroupObject *obj, bool pbb_etree_enabled)
Definition: multicast.cc:465
void set_learning_enabled(bool learning_enabled)
Definition: multicast.h:216
Definition: vrf.h:86
void DeleteBridgeRoute(const AgentRoute *rt)
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:37
MulticastDBState * CreateBridgeDomainMG(DBTablePartBase *p, BridgeDomainEntry *bd)
Definition: multicast.cc:376
const boost::uuids::uuid & GetUuid() const
Definition: interface.h:113
VrfEntry * FindVrfFromName(const string &name)
Definition: vrf.cc:873
static AgentRouteData * BuildBgpPeerData(const Peer *peer, const string &vrf_name, const std::string &vn_name, uint32_t label, int vxlan_id, uint32_t ethernet_tag, uint32_t tunnel_type, Composite::Type type, ComponentNHKeyList &component_nh_key_list, bool pbb_nh, bool learning_enabled)
bool FlushPeerInfo(uint64_t peer_sequence)
Definition: multicast.cc:1408
static void DeleteBroadcastReq(const Peer *peer, const std::string &vrf_name, uint32_t ethernet_tag, COMPOSITETYPE type)
#define INVALID_PEER_IDENTIFIER
Definition: multicast.cc:38
uint32_t fabric_label() const
Definition: multicast.h:204
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge, EVPN (Type2/Type5). This base class contains common code for all types of route tables.
Definition: agent_route.h:109
void set_pbb_etree_enabled(bool pbb_etree_enabled)
Definition: multicast.h:224
const Peer * peer()
Definition: multicast.h:196
const Ip4Address & dest_ip_addr() const
void AddVmToMulticastObjMap(const boost::uuids::uuid &vm_itf_uuid, MulticastGroupObject *obj)
Definition: multicast.h:525
#define MCTRACE(obj,...)
Definition: multicast.h:18
VmInterface::DeviceType device_type() const
const Ip4Address & GetSourceAddress()
Definition: multicast.h:135
std::set< MulticastGroupObject * > MulticastGroupObjectList
Definition: multicast.h:307
bool IsDeleted() const
Definition: db_entry.h:49
bool pbb_vrf() const
Definition: multicast.h:160
void ModifyTorMembers(const Peer *peer, const std::string &vrf_name, const TunnelOlist &olist, uint32_t ethernet_tag, uint64_t peer_identifier=0)
Definition: multicast.cc:1322
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
SandeshTraceBufferPtr MulticastTraceBuf
bool CanBeDeleted() const
Definition: multicast.cc:475
boost::asio::ip::address IpAddress
Definition: address.h:13
void HandleVnParametersChange(DBTablePartBase *partition, DBEntryBase *e)
Definition: multicast.cc:160
bool l2_active() const
Definition: interface.h:122
std::string vrf_name_
Definition: multicast.h:59
ComponentNHKeyList GetInterfaceComponentNHKeyList(MulticastGroupObject *obj, uint8_t flags)
Definition: multicast.cc:827
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
DBTableBase * parent()
AgentRouteWalkerPtr te_walker_
Definition: multicast.h:596
static const uint64_t kInvalidPeerIdentifier
AgentDBEntry * FindActiveEntry(const DBEntry *key)
Definition: agent_db.cc:110
boost::uuids::uuid uuid
void set_pbb_vrf_name(std::string name)
Definition: multicast.h:188
void CreateMulticastVrfSourceGroup(const std::string &vrf_name, const std::string &vn_name, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1620
void AddL2BroadcastRoute(MulticastGroupObject *obj, const std::string &vrf_name, const std::string &vn_name, const Ip4Address &addr, uint32_t label, int vxlan_id, uint32_t ethernet_tag)
Definition: multicast.cc:87
void AddMulticastRoute(MulticastGroupObject *obj, const Peer *peer, uint32_t ethernet_tag, AgentRouteData *data, AgentRouteData *bridge_data)
Definition: multicast.cc:915
void DeleteVmInterfaceFromVrfSourceGroup(const std::string &vrf_name, const VmInterface *vm_itf, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1843
boost::shared_ptr< const ComponentNHKey > ComponentNHKeyPtr
Definition: nexthop.h:1639
bool pbb_etree_enabled() const
Definition: multicast.h:220
const string & GetName() const
Definition: vrf.h:100
static void GetMulticastMacFromIp(const Ip4Address &ip, MacAddress &mac)
Definition: multicast.h:483
MulticastGroupObject * FindFloodGroupObject(const std::string &vrf_name)
Definition: multicast.cc:764
void SetEvpnMulticastSGFlags(const std::string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr, uint32_t flags)
Definition: multicast.cc:1970
bool pbb_etree_enabled_
Definition: multicast.h:52
boost::shared_ptr< TraceBuffer< SandeshTrace > > SandeshTraceBufferPtr
Definition: sandesh_trace.h:18
void Resync(MulticastGroupObject *obj)
Definition: multicast.cc:1512
VrfEntry * vrf() const
Definition: interface.h:115
MulticastTEWalker(const std::string &name, Agent *agent)
Definition: multicast.cc:1997
DBTableBase::ListenerId id_
Definition: multicast.h:60
const VrfEntry * vrf() const
Definition: bridge_domain.h:69
bool learning_enabled() const
Definition: multicast.h:212
Base class for all Route entries in agent.
Definition: agent_route.h:224
void DeleteMulticastVrfSourceGroup(const std::string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1709
MulticastGroupObjectList multicast_obj_list_
Definition: multicast.h:586
const IpAddress & ip() const
void Unregister(ListenerId listener)
Definition: db_table.cc:186
bool pbb_etree_enabled() const
Definition: bridge_domain.h:77
OperDB * oper_db() const
Definition: agent.cc:1013
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
Definition: nexthop.h:1641
Agent * agent_
Definition: multicast.h:580
Inet4MulticastRouteEntry * FindRoute(const Ip4Address &grp_addr, const Ip4Address &src_addr)
MulticastGroupObject * FindActiveGroupObject(const std::string &vrf_name, const Ip4Address &dip)
void AddBridgeRoute(const AgentRoute *rt)
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
const Type GetType() const
Definition: peer.h:87
NextHop * nexthop() const
Definition: agent_path.cc:87
bool mvpn_ipv4_enable() const
Definition: agent_param.h:565
bool AddLocalMember(const boost::uuids::uuid &intf_uuid, const MacAddress &mac)
Definition: multicast.h:104
virtual Agent::RouteTableType GetTableType() const =0
bool tsn_no_forwarding_enabled() const
Definition: agent.h:1158
bool AddVmInterfaceToVrfSourceGroup(const std::string &vrf_name, const std::string &vn_name, const VmInterface *vm_itf, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1752
BridgeRouteEntry * FindRoute(const MacAddress &mac)
Definition: bridge_route.cc:72
uint8_t type
Definition: load_balance.h:109
Definition: agent.h:358
void set_peer_identifier(uint64_t peer_id)
Definition: multicast.h:143
Definition: vrf.h:22
virtual bool ReComputePathAdd(AgentPath *path)
void AddLocalPeerRoute(MulticastGroupObject *sg_object)
Definition: multicast.cc:1554
void NotifyPhysicalDevice(DBTablePartBase *partition, DBEntryBase *e)
Definition: multicast.cc:547
bool ipv4_active() const
Definition: interface.h:116
uint32_t evpn_igmp_flags() const
Definition: multicast.h:248
bool DeleteLocalMember(const boost::uuids::uuid &intf_uuid)
Definition: multicast.h:111
void ModifyVmInterface(DBTablePartBase *partition, DBEntryBase *e)
Definition: multicast.cc:593
void FlushAllPeerInfo(const Agent *agent, const Peer *peer, uint64_t peer_identifier)
Definition: multicast.cc:1374
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
void set_dependent_mg(MulticastGroupObject *obj)
Definition: multicast.h:172
DBOperation oper
Definition: db_table.h:42
AgentRouteTable * GetBridgeRouteTable(const std::string &vrf_name)
Definition: vrf.cc:917
static TypeBmap AllType()
Definition: nexthop.h:321
const Peer * peer() const
Definition: agent_path.h:263
static void DeleteMulticastRoute(const string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr)
MGList::iterator mg_list_begin()
Definition: multicast.h:164
void ResyncDependentVrf(MulticastGroupObject *obj)
Definition: multicast.cc:1472
const Peer * local_peer() const
Definition: agent.h:1022
void DeleteVmToMulticastObjMap(const boost::uuids::uuid &vm_itf_uuid, const MulticastGroupObject *obj)
Definition: multicast.h:547
const std::vector< VnIpam > & GetVnIpam() const
Definition: vn.h:171
uint32_t vn_count()
Definition: multicast.h:244
static const MacAddress & BroadcastMac()
Definition: mac_address.h:152
const VnEntry * vn() const
const Ip4Address & GetGroupAddress()
Definition: multicast.h:134
MulticastGroupObject * CreateMulticastGroupObject(const string &vrf_name, const string &vn_name, const Ip4Address &src_addr, const Ip4Address &grp_addr, uint32_t vxlan_id)
Definition: multicast.cc:494
COMPOSITETYPE composite_nh_type() const
Definition: nexthop.h:1842
void DeleteMulticastRoute(const Peer *peer, const string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr, uint32_t ethernet_tag, COMPOSITETYPE comp_type)
Definition: multicast.cc:943
AgentParam * params() const
Definition: agent.h:1218
void set_vxlan_id(uint32_t vxlan_id)
Definition: multicast.h:141
const std::map< boost::uuids::uuid, MacAddress > & GetLocalList()
Definition: multicast.h:120
std::string vrf_name_
Definition: multicast.h:49
Definition: peer.h:44
bool learning_enabled() const
Definition: bridge_domain.h:73
void HandleVxLanChange(const VnEntry *vn)
Definition: multicast.cc:138
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
void set_fabric_label(uint32_t label)
Definition: multicast.h:208
static Type ComputeType(TypeBmap bmap)
Definition: nexthop.cc:33
void set_vn(const VnEntry *vn)
Definition: multicast.cc:804
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
Definition: vn.h:151
bool FilterVmi(const VmInterface *vmi)
Definition: multicast.cc:571
ComponentNHKeyList GetInterfaceComponentNHKeyList(uint8_t interface_flags)
Definition: multicast.cc:813
#define MAX_XMPP_SERVERS
Definition: agent.h:291
void DeleteEvpnPath(MulticastGroupObject *obj)
Definition: multicast.cc:1526
static const uint32_t kInvalidLabel
Definition: mpls.h:101
const BridgeDomainList & bridge_domain_list() const
VrfTable * vrf_table() const
Definition: agent.h:485
void DeleteBroadcast(const Peer *peer, const std::string &vrf_name, uint32_t ethernet_tag, COMPOSITETYPE type)
Definition: multicast.cc:126
const Ip4Address & primary_ip_addr() const
static void AddBridgeBroadcastRoute(const Peer *peer, const string &vrf_name, uint32_t ethernet_tag, AgentRouteData *data)
void McastTableNotify(DBTablePartBase *partition, DBEntryBase *e)
Definition: multicast.cc:257
void HandleIpam(const VnEntry *vn)
Definition: multicast.cc:513
uint32_t GetEvpnMulticastSGFlags(const std::string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1986
void set_bridge_domain(const BridgeDomainEntry *bd)
Definition: multicast.h:147
void TriggerRemoteRouteChange(MulticastGroupObject *obj, const Peer *peer, const string &vrf_name, const Ip4Address &src, const Ip4Address &grp, const TunnelOlist &olist, uint64_t peer_identifier, bool delete_op, COMPOSITETYPE comp_type, uint32_t label, bool fabric, uint32_t ethernet_tag)
Definition: multicast.cc:977
const TunnelOlist & fabric_olist() const
Definition: multicast.h:184
VrfEntry * GetVrf() const
Definition: vn.h:170
const Peer * multicast_tree_builder_peer() const
Definition: agent.h:1032
void DeleteMulticastObject(const std::string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:726
const std::string & GetVnName()
Definition: multicast.h:137
bool layer3_forwarding() const
Definition: vn.h:192
VmInterface::VmiType vmi_type() const
uint32_t vxlan_id() const
Definition: vrf.h:165
MulticastHandler(Agent *agent)
Definition: multicast.cc:1396
void UpdateReference(MulticastGroupObject *obj)
Definition: multicast.cc:1488
bool learning_enabled_
Definition: multicast.h:51
void AddBridgeDomain(DBTablePartBase *paritition, DBEntryBase *e)
Definition: multicast.cc:399
uint64_t peer_identifier()
Definition: multicast.h:144
static const int kInvalidId
Definition: db_table.h:64
void ModifyVN(DBTablePartBase *partition, DBEntryBase *e)
Definition: multicast.cc:249
AgentRouteTable * GetInet4MulticastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:909
#define COMPOSITETYPE
Definition: nexthop.h:1600
uint32_t vxlan_id_
Definition: multicast.h:50
void set_mvpn_registered(bool mvpn_registered)
Definition: multicast.h:232
VrfEntry * vrf() const
Definition: agent_route.h:275
AgentRouteTable * GetRouteTable(uint8_t table_type) const
Definition: vrf.cc:285
static void AddMulticastRoute(const string &vn_name, const string &vrf_name, const Ip4Address &src_addr, const Ip4Address &grp_addr, ComponentNHKeyList &component_nh_key_list)
uint32_t vxlan_id() const
Definition: multicast.h:142
const Peer * local_vm_peer() const
Definition: agent.h:1023
void ModifyFabricMembers(const Peer *peer, const std::string &vrf_name, const Ip4Address &group, const Ip4Address &source, uint32_t source_label, const TunnelOlist &olist, uint64_t peer_identifier=0)
Definition: multicast.cc:1174
std::set< MulticastGroupObject * > & GetMulticastObjList()
Definition: multicast.h:398
void AddVmInterfaceInFloodGroup(const VmInterface *vm_itf, MulticastIntfDBState *state)
Definition: multicast.cc:635
const boost::uuids::uuid & GetUuid() const
Definition: vn.h:161
BgpPeer * bgp_peer_id()
const string & GetName() const
Definition: vn.h:162
void reset_bridge_domain()
Definition: multicast.h:151
void DeleteLocalPeerRoute(MulticastGroupObject *sg_object)
Definition: multicast.cc:1594
uint32_t isid() const
Definition: bridge_domain.h:61
static AgentRouteData * BuildNonBgpPeerData(const string &vrf_name, const std::string &vn_name, uint32_t label, int vxlan_id, uint32_t tunnel_type, Composite::Type type, ComponentNHKeyList &component_nh_key_list, bool pbb_nh, bool learning_enabled)
void Notify(DBEntryBase *entry)
void set_peer(const Peer *peer)
Definition: multicast.h:200
void HandleRouteChangeAndMulticastObject(MulticastGroupObject *sg_object, boost::uuids::uuid vm_itf_uuid)
Definition: multicast.cc:1657
void set_pbb_vrf(bool is_pbb_vrf)
Definition: multicast.h:157
MulticastGroupObject * GetDependentMG(uint32_t isid)
Definition: multicast.cc:483
static const Ip4Address kBroadcast
Definition: multicast.h:306
void ChangeLearningMode(MulticastGroupObject *obj, bool learning_enabled)
Definition: multicast.cc:455
virtual AgentPath * FindPath(const Peer *peer) const
Definition: agent_route.cc:864
void ModifyVRF(DBTablePartBase *partition, DBEntryBase *e)
Definition: multicast.cc:338
std::vector< OlistTunnelEntry > TunnelOlist
Definition: multicast.h:68
bool FindVmToMulticastObjMap(const boost::uuids::uuid &vm_itf_uuid, MulticastGroupObjectList &objList)
Definition: multicast.h:534
void ModifyEvpnMembers(const Peer *peer, const std::string &vrf_name, const Ip4Address &grp, const Ip4Address &src, const TunnelOlist &olist, uint32_t ethernet_tag, uint64_t peer_identifier=0)
Definition: multicast.cc:1245
void set_evpn_igmp_flags(uint32_t evpn_igmp_flags)
Definition: multicast.h:252
static TypeBmap VxlanType()
Definition: nexthop.h:311
MGList::iterator mg_list_end()
Definition: multicast.h:168
bool ipv6_active() const
Definition: interface.h:117
const std::string & pbb_vrf_name()
Definition: multicast.h:192
bool mvpn_registered() const
Definition: multicast.h:228
NextHop * UpdateNH(Agent *agent, CompositeNH *cnh, const TsnElector *te)
Definition: agent_path.cc:1347
MulticastGroupObject * dependent_mg()
Definition: multicast.h:176
virtual bool RouteWalkNotify(DBTablePartBase *partition, DBEntryBase *e)
Definition: multicast.cc:2004
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:46
const PathList & GetPathList() const
Definition: route.h:46
virtual ~MulticastTEWalker()
Definition: multicast.cc:2001
void DeleteVmInterfaceFromSourceGroup(const std::string &mvpn_vrf_name, const VmInterface *vm_itf, const Ip4Address &src_addr, const Ip4Address &grp_addr)
Definition: multicast.cc:1872
void set_fabric_olist(const TunnelOlist &olist)
Definition: multicast.h:180
const std::string & fabric_policy_vrf_name() const
Definition: agent.h:908
const Ip4Address & src_ip_addr() const