OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vm_interface_utils.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <cmn/agent_cmn.h>
6 #include <init/agent_param.h>
7 #include <base/address_util.h>
8 #include <oper/operdb_init.h>
9 #include <oper/route_common.h>
10 #include <oper/vm.h>
11 #include <oper/vn.h>
12 #include <oper/vrf.h>
13 #include <oper/nexthop.h>
14 #include <oper/mpls.h>
15 #include <oper/mirror_table.h>
16 #include <oper/metadata_ip.h>
17 #include <oper/interface_common.h>
18 #include <oper/health_check.h>
19 #include <oper/vrf_assign.h>
20 #include <oper/vxlan.h>
21 #include <oper/oper_dhcp_options.h>
23 #include <oper/global_vrouter.h>
24 #include <oper/qos_config.h>
25 #include <oper/bridge_domain.h>
26 #include <oper/sg.h>
27 #include <oper/bgp_as_service.h>
28 
29 #include <filter/acl.h>
35 
38 
39 using namespace std;
40 using namespace boost::uuids;
41 using namespace autogen;
42 
43 static IpAddress ipv4_empty_addr = IpAddress::from_string("0.0.0.0");
44 static IpAddress ipv6_empty_addr = IpAddress::from_string("0::0");
45 static IpAddress ipv4_max_addr = IpAddress::from_string("255.255.255.255");
47  IpAddress::from_string("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF");
48 
50 // Routines to manage VmiToPhysicalDeviceVnTree
53 (const boost::uuids::uuid &dev, const boost::uuids::uuid &vn) :
54  dev_(dev), vn_(vn) {
55 }
56 
58 }
59 
61  boost::uuids::uuid &dev,
63  IFMapNode *vn_node) {
64  VmiToPhysicalDeviceVnTree::iterator iter =
65  vmi_to_physical_device_vn_tree_.find(vmi);
66  if (iter == vmi_to_physical_device_vn_tree_.end()) {
67  vmi_to_physical_device_vn_tree_.insert
68  (make_pair(vmi,VmiToPhysicalDeviceVnData(nil_uuid(), nil_uuid())));
69  iter = vmi_to_physical_device_vn_tree_.find(vmi);
70  }
71 
72  if (iter->second.dev_ != dev || iter->second.vn_ != vn) {
73  agent()->physical_device_vn_table()->DeleteConfigEntry
74  (vmi, iter->second.dev_, iter->second.vn_);
75  }
76 
77  iter->second.dev_ = dev;
78  iter->second.vn_ = vn;
79  agent()->physical_device_vn_table()->AddConfigEntry(vmi, dev, vn);
80 }
81 
83  VmiToPhysicalDeviceVnTree::iterator iter =
84  vmi_to_physical_device_vn_tree_.find(vmi);
85  if (iter == vmi_to_physical_device_vn_tree_.end())
86  return;
87 
88  agent()->physical_device_vn_table()->DeleteConfigEntry
89  (vmi, iter->second.dev_, iter->second.vn_);
90  vmi_to_physical_device_vn_tree_.erase(iter);
91 }
92 
94 // VM Port active status related methods
96 // Does the VMInterface need a physical device to be present
98  bool ret = true;
99 
100  if (device_type_ == TOR)
101  ret = false;
102 
103  if (device_type_ == VM_VLAN_ON_VMI)
104  ret = false;
105 
106  if (vmi_type_ != VHOST && subnet_.is_unspecified() == false) {
107  ret = false;
108  }
109 
110  if (transport_ != TRANSPORT_ETHERNET) {
111  ret = false;
112  }
113 
114  if (rx_vlan_id_ != VmInterface::kInvalidVlanId) {
115  ret = false;
116  } else {
117  // Sanity check. rx_vlan_id is set, make sure tx_vlan_id is also set
118  assert(tx_vlan_id_ == VmInterface::kInvalidVlanId);
119  }
120 
121  return ret;
122 }
123 
125  /* For TRANSPORT_PMD (in dpdk mode) interfaces, the link state is updated
126  * as part of netlink message sent by vrouter to agent. This state is
127  * updated in os_oper_state_ field */
128  if (transport_ == TRANSPORT_PMD) {
129  return true;
130  }
131  InterfaceTable *table = static_cast<InterfaceTable *>(get_table());
132  if (table) {
133  return NeedDefaultOsOperStateDisabled(table->agent());
134  }
135  return false;
136 }
137 
139  if (NeedDevice() || NeedOsStateWithoutDevice()) {
140  Interface::GetOsParams(agent);
141  return;
142  }
143 
144  os_params_.os_index_ = Interface::kInvalidIndex;
145  os_params_.mac_ = agent->vrrp_mac();
146  /* In VmWare mode, the default os_oper_state of VMI is false. It needs to be
147  * explicitly enabled via REST request to agent. This needs to be done
148  * only for interfaces which are not of transport_ TRANSPORT_ETHERNET */
149  if (!NeedDefaultOsOperStateDisabled(agent)) {
150  os_params_.os_oper_state_ = true;
151  }
152 }
153 
154 // A VM Interface is L3 active under following conditions,
155 // - If interface is deleted, it is inactive
156 // - VN, VRF are set
157 // - If sub_interface VMIs, parent_ should be set
158 // (We dont track parent_ and activate sub-interfaces. So, we only check
159 // parent_ is present and not necessarily active)
160 // - For non-VMWARE hypervisors,
161 // The tap interface must be created. This is verified by os_index_
162 // - MAC address set for the interface
163 bool VmInterface::IsActive() const {
164  if (IsDeleted()) {
165  return false;
166  }
167 
168  if (!admin_state_) {
169  return false;
170  }
171 
172  // If sub_interface VMIs, parent_vmi_ should be set
173  // (We dont track parent_ and activate sub-interfaces. So, we only check
174  // paremt_vmi is present and not necessarily active)
175  // Check if parent is not active set the SubInterface also not active
176  const VmInterface *parentIntf = static_cast<const VmInterface *>(parent());
177  if (device_type_ == VM_VLAN_ON_VMI) {
178  if (parentIntf == NULL)
179  return false;
180  else if (parentIntf->IsActive() == false) {
181  return false;
182  }
183  }
184 
185  if (device_type_ == REMOTE_VM_VLAN_ON_VMI) {
186  if (tx_vlan_id_ == VmInterface::kInvalidVlanId ||
187  rx_vlan_id_ == VmInterface::kInvalidVlanId ||
188  parent_.get() == NULL)
189  return false;
190  }
191 
192  if (vmi_type_ == VHOST) {
193  //In case of vhost interface, upon interface
194  //addition we dont have corresponding VN, hence
195  //ignore VN name check for ip active
196  if (vrf_.get() == NULL) {
197  return false;
198  }
199  } else if ((vn_.get() == NULL) || (vrf_.get() == NULL)) {
200  return false;
201  }
202 
203  if (vn_.get() && !vn_.get()->admin_state()) {
204  return false;
205  }
206 
207  if (NeedOsStateWithoutDevice() && os_oper_state() == false) {
208  VnswInterfaceListener *vnswif =
209  agent()->ksync()->vnsw_interface_listner();
210  bool link_status = vnswif->IsHostLinkStateUp(name());
211  if ((transport_ == TRANSPORT_PMD) && link_status &&
212  (os_index() != Interface::kInvalidIndex) && (!agent()->test_mode())) {
214  req.key.reset(new VmInterfaceKey(AgentKey::RESYNC, GetUuid(),
215  name()));
216  req.data.reset(new VmInterfaceOsOperStateData(link_status));
217  agent()->interface_table()->Enqueue(&req);
218  return true;
219  }
220  return false;
221  }
222 
223  if (NeedDevice() == false) {
224  return true;
225  }
226 
227  if (os_index() == kInvalidIndex)
228  return false;
229 
230  if (os_oper_state() == false)
231  return false;
232 
233  return mac_set_;
234 }
235 
237  if (vmi_type_ == VHOST) {
238  return IsActive();
239  }
240 
241  if (!layer3_forwarding()) {
242  return false;
243  }
244 
245  if (primary_ip6_addr_.is_unspecified()) {
246  if (subnet_.is_unspecified() && primary_ip_addr_.to_ulong() == 0) {
247  return false;
248  }
249 
250  if (subnet_.is_unspecified() == false && parent_ == NULL) {
251  return false;
252  }
253  }
254 
255  return IsActive();
256 }
257 
259  if (!bridging()) {
260  return false;
261  }
262 
263  return IsActive();
264 }
265 
267  if (vmi_type_ == VHOST) {
268  return IsActive();
269  }
270 
271  if (!layer3_forwarding()) {
272  return false;
273  }
274 
275  if (subnet_.is_unspecified() && primary_ip_addr_.to_ulong() == 0) {
276  return false;
277  }
278 
279  if (subnet_.is_unspecified() == false && parent_ == NULL) {
280  return false;
281  }
282 
283  if (!is_hc_active_) {
284  return false;
285  }
286 
287  return IsActive();
288 }
289 
291  if (vmi_type_ == VHOST) {
292  return IsActive();
293  }
294 
295  if (!layer3_forwarding() || (primary_ip6_addr_.is_unspecified())) {
296  return false;
297  }
298 
299  if (!is_hc_active_) {
300  return false;
301  }
302 
303  return IsActive();
304 }
305 
307  if (vmi_type_ == VHOST) {
308  return IsActive();
309  }
310 
311  if (!bridging()) {
312  return false;
313  }
314 
315  if (!is_hc_active_) {
316  return false;
317  }
318 
319  return IsActive();
320 }
321 
323 // Path preference utility methods
325 // Set path-preference information for the route
327  const IpAddress &dependent_ip) const {
328  pref->set_ecmp(ecmp);
329  if (local_preference_ != 0) {
330  pref->set_static_preference(true);
331  pref->set_preference(local_preference_);
332  } else if (ecmp == true) {
334  }
335  pref->set_dependent_ip(dependent_ip);
336  pref->set_vrf(vrf()->GetName());
337 }
338 
340  const IpAddress &service_ip) const {
341 
342  bool ecmp_mode = false;
343  IpAddress dependent_ip;
344 
345  //Logic for setting ecmp and tracking IP on Service chain route
346  //Service vlan route can be active when interface is either
347  //IPV4 active or IPV6 active, hence we have to consider both
348  //IPV6 and IPV4 IP
349  //If Service vlan is for Ipv4 route, then priority is as below
350  //1> Service IP for v4
351  //3> Primary IP for v4
352  if (service_ip.is_v4()) {
353  if (service_ip_ != Ip4Address(0)) {
354  dependent_ip = service_ip_;
355  ecmp_mode = service_ip_ecmp_;
356  } else {
357  dependent_ip = primary_ip_addr_;
358  ecmp_mode = ecmp_;
359  }
360  }
361 
362  //If Service vlan is for Ipv6 route, then priority is as below
363  //1> Service IP for v6
364  //3> Primary IP for v6
365  if (service_ip.is_v6()) {
366  if (service_ip6_ != Ip6Address()) {
367  dependent_ip = service_ip6_;
368  ecmp_mode = service_ip_ecmp6_;
369  } else {
370  dependent_ip = primary_ip6_addr_;
371  ecmp_mode = ecmp6_;
372  }
373  }
374 
375  pref->set_ecmp(ecmp_mode);
376  if (local_preference_ != 0) {
377  pref->set_static_preference(true);
378  pref->set_preference(local_preference_);
379  } else if (ecmp_mode == true) {
381  }
382 
383  pref->set_dependent_ip(dependent_ip);
384  pref->set_vrf(vrf()->GetName());
385 }
386 
388  if (ecmp_load_balance_.use_global_vrouter() == false)
389  return ecmp_load_balance.Copy(ecmp_load_balance_);
390  return ecmp_load_balance.Copy(agent()->oper_db()->global_vrouter()->
391  ecmp_load_balance());
392 }
393 
395 // Route utility methods
397 
398 // Add EVPN route of type <ip, mac>
400  const MacAddress &mac,
401  const IpAddress &dependent_ip) const {
402  assert(peer_.get());
403  EvpnAgentRouteTable *table =
404  static_cast<EvpnAgentRouteTable *>(vrf_->GetEvpnRouteTable());
405 
406  SecurityGroupList sg_id_list;
407  CopySgIdList(&sg_id_list);
408 
409  TagList tag_list;
410  CopyTagIdList(&tag_list);
411 
412  PathPreference path_preference;
413  SetPathPreference(&path_preference, false, dependent_ip);
414 
415  uint32_t label = l2_label_;
416  if (pbb_interface()) {
417  label = GetPbbLabel();
418  }
419 
420  std::string vn_name = Agent::NullString();
421  if (vn() != NULL) {
422  vn_name = vn()->GetName();
423  }
424 
425  table->AddLocalVmRoute(peer_.get(), vrf_->GetName(), mac, this, ip,
426  label, vn_name, sg_id_list,
427  tag_list, path_preference,
428  ethernet_tag_, etree_leaf_, name());
429 }
430 
431 // Delete EVPN route
433  uint32_t ethernet_tag,
434  const IpAddress &ip,
435  const MacAddress &mac) const {
436  EvpnAgentRouteTable *table =
437  static_cast<EvpnAgentRouteTable *>(vrf->GetEvpnRouteTable());
438  if (table == NULL)
439  return;
440 
441  table->DelLocalVmRoute(peer_.get(), vrf->GetName(), mac, this,
442  ip, ethernet_tag);
443 }
444 
445 //Add a route for VM port
446 //If ECMP route, add new composite NH and mpls label for same
447 void VmInterface::AddRoute(const std::string &vrf_name, const IpAddress &addr,
448  uint32_t plen, const std::string &dest_vn,
449  bool force_policy, bool ecmp, bool is_local,
450  bool is_health_check_service,
451  const IpAddress &service_ip,
452  const IpAddress &dependent_rt,
453  const CommunityList &communities, uint32_t label,
454  const std::string &intf_route_type,
455  bool is_learnt_route) {
456 
457  SecurityGroupList sg_id_list;
458  CopySgIdList(&sg_id_list);
459 
460  TagList tag_list;
461  CopyTagIdList(&tag_list);
462 
463  PathPreference path_preference;
464  SetPathPreference(&path_preference, ecmp, dependent_rt);
465 
466  InterfaceTable *table = static_cast<InterfaceTable *>(get_table());
467  bool native_encap = false;
468  VrfEntry *vrf = table->FindVrfRef(vrf_name);
469  if (addr.is_v4() &&
470  vrf && vrf->forwarding_vrf() == table->agent()->fabric_vrf()) {
471  native_encap = true;
472  }
473 
474  VnListType vn_list;
475  vn_list.insert(dest_vn);
476  EcmpLoadBalance ecmp_load_balance;
477  CopyEcmpLoadBalance(ecmp_load_balance);
479  (peer_.get(), vrf_name, addr, plen, GetUuid(), vn_list, label,
480  sg_id_list, tag_list, communities, force_policy, path_preference,
481  service_ip, ecmp_load_balance, is_local, is_health_check_service,
482  name(), native_encap, intf_route_type, is_learnt_route);
483  return;
484 }
485 
486 void VmInterface::DeleteRoute(const std::string &vrf_name,
487  const IpAddress &addr, uint32_t plen) {
488  InetUnicastAgentRouteTable::Delete(peer_.get(), vrf_name, addr, plen);
489  return;
490 }
491 
493 // Utility methods
495 // DHCP options applicable to the Interface
497 (std::vector<autogen::DhcpOptionType> *options) const {
498  if (oper_dhcp_options().are_dhcp_options_set()) {
499  *options = oper_dhcp_options().dhcp_options();
500  return true;
501  }
502 
503  return false;
504 }
505 
506 // DHCP options applicable to the Subnet to which the interface belongs
508 (std::vector<autogen::DhcpOptionType> *options, bool ipv6) const {
509  if (vn()) {
510  const std::vector<VnIpam> &vn_ipam = vn()->GetVnIpam();
511  uint32_t index;
512  for (index = 0; index < vn_ipam.size(); ++index) {
513  if (!ipv6 && vn_ipam[index].IsSubnetMember(primary_ip_addr())) {
514  break;
515  }
516  if (ipv6 && vn_ipam[index].IsSubnetMember(primary_ip6_addr())) {
517  break;
518  }
519  }
520  if (index < vn_ipam.size() &&
521  vn_ipam[index].oper_dhcp_options.are_dhcp_options_set()) {
522  *options = vn_ipam[index].oper_dhcp_options.dhcp_options();
523  return true;
524  }
525  }
526 
527  return false;
528 }
529 
530 // DHCP options applicable to the Ipam to which the interface belongs
532 (std::vector<autogen::DhcpOptionType> *options, bool ipv6) const {
533  if (vn()) {
534  std::string ipam_name;
535  autogen::IpamType ipam_type;
536  if (!ipv6 &&
537  vn()->GetIpamData(primary_ip_addr(), &ipam_name, &ipam_type)) {
538  *options = ipam_type.dhcp_option_list.dhcp_option;
539  return true;
540  }
541  if (ipv6 &&
542  vn()->GetIpamData(primary_ip6_addr(), &ipam_name, &ipam_type)) {
543  *options = ipam_type.dhcp_option_list.dhcp_option;
544  return true;
545  }
546  }
547 
548  return false;
549 }
550 
551 const MacAddress&
552 VmInterface::GetIpMac(const IpAddress &ip, uint8_t plen) const {
553  AllowedAddressPairSet::const_iterator it =
554  allowed_address_pair_list_.list_.begin();
555  while (it != allowed_address_pair_list_.list_.end()) {
556  if (it->addr_ == ip && it->plen_ == plen &&
557  it->mac_ != MacAddress::kZeroMac) {
558  return it->mac_;
559  }
560  it++;
561  }
562  LearntMacIpSet::const_iterator mac_ip_it =
563  learnt_mac_ip_list_.list_.begin();
564  while (mac_ip_it != learnt_mac_ip_list_.list_.end()) {
565  if (mac_ip_it->ip_ == ip &&
566  mac_ip_it->mac_ != MacAddress::kZeroMac) {
567  return mac_ip_it->mac_;
568  }
569  mac_ip_it++;
570  }
571  return vm_mac_;
572 }
573 
574 /*
575  * Check if the passed IP is in the AAP IP list on this interface;
576  * If so, return true, else return false
577  */
578 bool
579 VmInterface::MatchAapIp(const IpAddress &ip, uint8_t plen) const {
580  AllowedAddressPairSet::const_iterator it =
581  allowed_address_pair_list_.list_.begin();
582  while (it != allowed_address_pair_list_.list_.end()) {
583  if (it->addr_ == ip && it->plen_ == plen) {
584  return true;
585  }
586  it++;
587  }
588  return false;
589 }
590 
592  // do not continue if the interface is inactive or if the VRF is deleted
593  if (IsActive() == false || vrf_->IsDeleted()) {
594  return false;
595  }
596 
597  //Get the instance ip route and its corresponding traffic seen status
598  InetUnicastRouteKey rt_key(peer_.get(), vrf_->GetName(),
599  primary_ip_addr_, 32);
600  const InetUnicastRouteEntry *rt = static_cast<const InetUnicastRouteEntry *>
601  (vrf_->GetInet4UnicastRouteTable()->FindActiveEntry(&rt_key));
602  if (!rt) {
603  return false;
604  }
605 
606  if (rt->FindPath(peer_.get()) == NULL) {
607  return false;
608  }
609 
610  return rt->FindPath(peer_.get())->path_preference().wait_for_traffic();
611 }
612 
614  IpAddress ip;
615  if (vm_ip.is_v4()) {
616  ip = Ip4Address(0);
617  } else if (vm_ip.is_v6()) {
618  ip = Ip6Address();
619  }
620  if (vn_.get() == NULL) {
621  return ip;
622  }
623 
624  const VnIpam *ipam = NULL;
625  if (subnet_.is_unspecified()) {
626  ipam = vn_->GetIpam(vm_ip);
627  } else {
628  ipam = vn_->GetIpam(subnet_);
629  }
630 
631  if (ipam) {
632  if ((vm_ip.is_v4() && ipam->dns_server.is_v4()) ||
633  (vm_ip.is_v6() && ipam->dns_server.is_v6())) {
634  return ipam->dns_server;
635  }
636  }
637  return ip;
638 }
639 
641  IpAddress ip;
642  if (vn_.get() == NULL) {
643  return ip;
644  }
645 
646  const VnIpam *ipam = NULL;
647  if (subnet_.is_unspecified()) {
648  ipam = vn_->GetIpam(vm_ip);
649  } else {
650  ipam = vn_->GetIpam(subnet_);
651  }
652 
653  if (ipam) {
654  if ((vm_ip.is_v4() && ipam->default_gw.is_v4()) ||
655  (vm_ip.is_v6() && ipam->default_gw.is_v6())) {
656  return ipam->default_gw;
657  }
658  }
659  return ip;
660 }
661 
662 // Copy the SG List for VM Interface. Used to add route for interface
664  SecurityGroupEntrySet::const_iterator it;
665  for (it = sg_list_.list_.begin(); it != sg_list_.list_.end(); ++it) {
666  if (it->del_pending_)
667  continue;
668  if (it->sg_.get() == NULL)
669  continue;
670  sg_id_list->push_back(it->sg_->GetSgId());
671  }
672 }
673 
674 uint32_t VmInterface::GetServiceVlanLabel(const VrfEntry *vrf) const {
675  ServiceVlanSet::const_iterator it = service_vlan_list_.list_.begin();
676  while (it != service_vlan_list_.list_.end()) {
677  if (it->vrf_.get() == vrf) {
678  return it->label_;
679  }
680  it++;
681  }
682  return 0;
683 }
684 
685 const VrfEntry* VmInterface::GetServiceVlanVrf(uint16_t vlan_tag) const {
686  ServiceVlanSet::const_iterator it = service_vlan_list_.list_.begin();
687  while (it != service_vlan_list_.list_.end()) {
688  if (it->tag_ == vlan_tag) {
689  return it->vrf_.get();
690  }
691  it++;
692  }
693  return NULL;
694 }
695 
697  if (family == Address::INET) {
698  return floating_ip_list_.v4_count_ > 0;
699  } else {
700  return floating_ip_list_.v6_count_ > 0;
701  }
702 }
703 
705  return floating_ip_list_.list_.size() != 0;
706 }
707 
708 bool VmInterface::IsFloatingIp(const IpAddress &ip) const {
709  VmInterface::FloatingIpSet::const_iterator it =
710  floating_ip_list_.list_.begin();
711  while(it != floating_ip_list_.list_.end()) {
712  if ((*it).floating_ip_ == ip) {
713  return true;
714  }
715  it++;
716  }
717  return false;
718 }
719 
721  // Look for matching Alias IP
722  VmInterface::AliasIpSet::const_iterator it =
723  alias_ip_list_.list_.begin();
724  for (; it != alias_ip_list_.list_.end(); ++it) {
725  if (it->vrf_.get() == NULL) {
726  continue;
727  }
728 
729  if (ip == it->alias_ip_) {
730  return it->vrf_.get();
731  }
732  }
733  return NULL;
734 }
735 
737  std::pair<HealthCheckInstanceSet::iterator, bool> ret;
738  ret = hc_instance_set_.insert(hc_inst);
739  assert(ret.second);
740 }
741 
743  //[CEM-29104 for reference]If service_type of HealthCheck instance is "vn-ip-list"
744  //while creating the BFD HealthCheck and if it is modified before deleting
745  //the HealthCheck object, then object hc_inst will not present in hc_instance_set
746  //and assert will fail while erasing hc_inst from hc_instance_set. So,
747  //added a check to see if hc_inst is present in the set.
748  if(hc_instance_set_.find(hc_inst) != hc_instance_set_.end()) {
749  std::size_t ret = hc_instance_set_.erase(hc_inst);
750  assert(ret != 0);
751  }
752 }
753 
756  return hc_instance_set_;
757 }
758 
760  return hc_instance_set_.size() != 0;
761 }
762 
763 // Check if the interface requires to resync the health check service instance
764 // Resync will be applied for healthcheck types BFD or Segment.
766 {
767  if (!IsHealthCheckEnabled() || !is_hc_active()) {
768  return;
769  }
770 
771  HealthCheckInstanceSet::const_iterator it = hc_instance_set_.begin();
772  while (it != hc_instance_set_.end()) {
773  const HealthCheckInstanceBase *hc_instance = *it;
774  it++;
775  HealthCheckService *hc_service = hc_instance->service();
776  if (hc_service == NULL)
777  continue;
778 
779  // resync will be applied healthcheck type is either BFD or Segment.
781  hc_service->health_check_type();
782  if (type != HealthCheckService::BFD &&
783  type != HealthCheckService::SEGMENT) {
784  continue;
785  }
786 
787  // if either source_ip or destination_ip unspecified,
788  // resync the healtcheckservice
789  if ((hc_instance->destination_ip().is_unspecified() == false) &&
790  (hc_instance->get_source_ip().is_unspecified() == false)) {
791  continue;
792  }
793  hc_service->ResyncHealthCheckInterface(hc_service, this);
794  }
795 }
796 
797 const string VmInterface::GetAnalyzer() const {
798  if (mirror_entry()) {
799  return mirror_entry()->GetAnalyzerName();
800  } else {
801  return std::string();
802  }
803 }
804 
805 const Peer *VmInterface::peer() const {
806  return peer_.get();
807 }
808 
809 bool VmInterface::IsFatFlowPortBased(uint8_t protocol, uint16_t port,
810  FatFlowIgnoreAddressType *ignore_addr) const {
811 
812  FatFlowEntrySet::iterator start = fat_flow_list_.list_.lower_bound(
813  FatFlowEntry(protocol, port,
814  IGNORE_ADDRESS_MIN_VAL,
815  AGGREGATE_PREFIX_MIN_VAL));
816  FatFlowEntrySet::iterator end = fat_flow_list_.list_.upper_bound(
817  FatFlowEntry(protocol, port,
818  IGNORE_ADDRESS_MAX_VAL,
819  AGGREGATE_PREFIX_MIN_VAL));
820 
821  if (start != fat_flow_list_.list_.end()) {
822  while (start != end) {
823  if ((start->protocol == protocol) && (start->port == port) &&
824  (start->prefix_aggregate == AGGREGATE_NONE)) {
825  *ignore_addr = start->ignore_address;
826  return true;
827  }
828  start++;
829  }
830  }
831  return false;
832 }
833 
834 bool VmInterface::MatchSrcPrefixPort(uint8_t protocol, uint16_t port,
835  IpAddress *src_ip,
836  FatFlowIgnoreAddressType *ignore_addr) const
837 {
838  FatFlowPrefixAggregateType prefix_type, max_prefix_type;
839  Ip4Address Ipv4_subnet, Ipv4_ret_subnet;
840  Ip6Address Ipv6_subnet, Ipv6_ret_subnet;
841  uint8_t max_mask, max_plen;
842  const FatFlowEntry *match_ffe = NULL;
843 
844  *ignore_addr = VmInterface::IGNORE_NONE;
845 
846  if (src_ip->is_v4()) {
847  prefix_type = AGGREGATE_SRC_IPV4;
848  // set max_prefixtype to src_dst_ipv4 so that we can do LPM on src prefix
849  max_prefix_type = AGGREGATE_SRC_DST_IPV4;
850  Ipv4_subnet = Address::GetIp4SubnetAddress(src_ip->to_v4(),
852  max_mask = 32;
853  max_plen = 32;
854  } else {
855  prefix_type = AGGREGATE_SRC_IPV6;
856  max_prefix_type = AGGREGATE_SRC_DST_IPV6;
857  Ipv6_subnet = Address::GetIp6SubnetAddress(src_ip->to_v6(),
859  max_mask = 128;
860  max_plen = 128;
861  }
862 
863  const FatFlowEntry lbffe = FatFlowEntry(protocol, port, "destination",
864  prefix_type,
865  (src_ip->is_v4()?
866  IpAddress(Ipv4_subnet):
867  IpAddress(Ipv6_subnet)),
870  (src_ip->is_v4()?
872  ),
873  0, 0);
874 
875  FatFlowEntrySet::iterator start = fat_flow_list_.list_.lower_bound(lbffe);
876 
877  const FatFlowEntry ubffe =
878  FatFlowEntry(protocol, port, "none",
879  max_prefix_type,
880  *src_ip, max_mask, max_plen,
881  (src_ip->is_v4()?
883  ),
884  max_mask, max_plen);
885 
886  FatFlowEntrySet::iterator end = fat_flow_list_.list_.upper_bound(ubffe);
887 
888  if ((start != fat_flow_list_.list_.end()) &&
889  (start->protocol == protocol) && (start->port == port)) {
890  while (start != end) {
891  if (src_ip->is_v4() && start->src_prefix.is_v4() &&
892  IsIp4SubnetMember(src_ip->to_v4(), start->src_prefix.to_v4(),
893  start->src_prefix_mask) &&
894  (start->protocol == protocol) && (start->port == port)) {
895  if ((!match_ffe) ||
896  (start->src_prefix_mask > match_ffe->src_prefix_mask)) {
897  match_ffe = &(*start);
898  }
899  } else if (src_ip->is_v6() && start->src_prefix.is_v6() &&
900  IsIp6SubnetMember(src_ip->to_v6(), start->src_prefix.to_v6(),
901  start->src_prefix_mask) &&
902  (start->protocol == protocol) && (start->port == port)) {
903  if ((!match_ffe) ||
904  (start->src_prefix_mask > match_ffe->src_prefix_mask)) {
905  match_ffe = &(*start);
906  }
907  }
908  start++;
909  }
910  }
911  if (match_ffe && (match_ffe->prefix_aggregate == prefix_type)) {
912  if (src_ip->is_v4()) {
913  Ipv4_ret_subnet = Address::GetIp4SubnetAddress(src_ip->to_v4(),
914  match_ffe->src_aggregate_plen);
915  *src_ip = IpAddress(Ipv4_ret_subnet);
916  *ignore_addr = match_ffe->ignore_address;
917  } else {
918  Ipv6_ret_subnet = Address::GetIp6SubnetAddress(src_ip->to_v6(),
919  match_ffe->src_aggregate_plen);
920  *src_ip = IpAddress(Ipv6_ret_subnet);
921  *ignore_addr = match_ffe->ignore_address;
922  }
923  return true;
924  }
925  return false;
926 }
927 
928 bool VmInterface::MatchSrcPrefixRule(uint8_t protocol, uint16_t *sport,
929  uint16_t *dport, bool *same_port_num,
930  IpAddress *SrcIP,
931  FatFlowIgnoreAddressType *ignore_addr) const
932 {
933  if ((*sport) < (*dport)) {
934  if (MatchSrcPrefixPort(protocol, *sport, SrcIP, ignore_addr)) {
935  *dport = 0;
936  return true;
937  }
938  if (MatchSrcPrefixPort(protocol, *dport, SrcIP, ignore_addr)) {
939  *sport = 0;
940  return true;
941  }
942  } else {
943  if (MatchSrcPrefixPort(protocol, *dport, SrcIP, ignore_addr)) {
944  if ((*sport) == (*dport)) {
945  *same_port_num = true;
946  }
947  *sport = 0;
948  return true;
949  }
950  if (MatchSrcPrefixPort(protocol, *sport, SrcIP, ignore_addr)) {
951  *dport = 0;
952  return true;
953  }
954  }
955  if (MatchSrcPrefixPort(protocol, 0, SrcIP, ignore_addr)) {
956  *sport = *dport = 0;
957  return true;
958  }
959  return false;
960 }
961 
962 bool VmInterface::MatchDstPrefixPort(uint8_t protocol, uint16_t port,
963  IpAddress *dst_ip,
964  FatFlowIgnoreAddressType *ignore_addr) const
965 {
966  FatFlowPrefixAggregateType prefix_type;
967  Ip4Address Ipv4_subnet, Ipv4_ret_subnet;
968  Ip6Address Ipv6_subnet, Ipv6_ret_subnet;
969  uint8_t max_mask, max_plen;
970  const FatFlowEntry *match_ffe = NULL;
971 
972  *ignore_addr = VmInterface::IGNORE_NONE;
973 
974  if (dst_ip->is_v4()) {
975  prefix_type = AGGREGATE_DST_IPV4;
976  Ipv4_subnet = Address::GetIp4SubnetAddress(dst_ip->to_v4(),
978  max_mask = 32;
979  max_plen = 32;
980  } else {
981  prefix_type = AGGREGATE_DST_IPV6;
982  Ipv6_subnet = Address::GetIp6SubnetAddress(dst_ip->to_v6(),
984  max_mask = 128;
985  max_plen = 128;
986  }
987 
988  const FatFlowEntry lbffe =
989  FatFlowEntry(protocol, port, "source", prefix_type,
990  (dst_ip->is_v4()?
993  ), 0, 0,
994  (dst_ip->is_v4()?
995  IpAddress(Ipv4_subnet):
996  IpAddress(Ipv6_subnet)),
999 
1000  FatFlowEntrySet::iterator start = fat_flow_list_.list_.lower_bound(lbffe);
1001 
1002  const FatFlowEntry ubffe = FatFlowEntry(protocol, port, "none",
1003  prefix_type,
1004  (dst_ip->is_v4()?
1007  ), 0, 0,
1008  *dst_ip, max_mask, max_plen);
1009 
1010  FatFlowEntrySet::iterator end = fat_flow_list_.list_.upper_bound(ubffe);
1011 
1012  if ((start != fat_flow_list_.list_.end()) &&
1013  (start->protocol == protocol) && (start->port == port)) {
1014  while (start != end) {
1015  if (dst_ip->is_v4() && start->dst_prefix.is_v4() &&
1016  IsIp4SubnetMember(dst_ip->to_v4(), start->dst_prefix.to_v4(),
1017  start->dst_prefix_mask) &&
1018  (start->protocol == protocol) && (start->port == port)) {
1019  if ((!match_ffe) ||
1020  (start->dst_prefix_mask > match_ffe->dst_prefix_mask)) {
1021  match_ffe = &(*start);
1022  }
1023  } else if (dst_ip->is_v6() && start->dst_prefix.is_v6() &&
1024  IsIp6SubnetMember(dst_ip->to_v6(), start->dst_prefix.to_v6(),
1025  start->dst_prefix_mask) &&
1026  (start->protocol == protocol) && (start->port == port)) {
1027  if ((!match_ffe) ||
1028  (start->dst_prefix_mask > match_ffe->dst_prefix_mask)) {
1029  match_ffe = &(*start);
1030  }
1031  }
1032  start++;
1033  }
1034  }
1035  if (match_ffe && (match_ffe->prefix_aggregate == prefix_type)) {
1036  if (dst_ip->is_v4()) {
1037  Ipv4_ret_subnet = Address::GetIp4SubnetAddress(dst_ip->to_v4(),
1038  match_ffe->dst_aggregate_plen);
1039  *dst_ip = IpAddress(Ipv4_ret_subnet);
1040  *ignore_addr = match_ffe->ignore_address;
1041  } else {
1042  Ipv6_ret_subnet = Address::GetIp6SubnetAddress(dst_ip->to_v6(),
1043  match_ffe->dst_aggregate_plen);
1044  *dst_ip = IpAddress(Ipv6_ret_subnet);
1045  *ignore_addr = match_ffe->ignore_address;
1046  }
1047  return true;
1048  }
1049  return false;
1050 }
1051 
1052 
1053 bool VmInterface::MatchDstPrefixRule(uint8_t protocol, uint16_t *sport,
1054  uint16_t *dport, bool *same_port_num,
1055  IpAddress *DstIP,
1056  FatFlowIgnoreAddressType *ignore_addr) const
1057 {
1058  if ((*sport) < (*dport)) {
1059  if (MatchDstPrefixPort(protocol, *sport, DstIP, ignore_addr)) {
1060  *dport = 0;
1061  return true;
1062  }
1063  if (MatchDstPrefixPort(protocol, *dport, DstIP, ignore_addr)) {
1064  *sport = 0;
1065  return true;
1066  }
1067  } else {
1068  if (MatchDstPrefixPort(protocol, *dport, DstIP, ignore_addr)) {
1069  if ((*sport) == (*dport)) {
1070  *same_port_num = true;
1071  }
1072  *sport = 0;
1073  return true;
1074  }
1075  if (MatchDstPrefixPort(protocol, *sport, DstIP, ignore_addr)) {
1076  *dport = 0;
1077  return true;
1078  }
1079  }
1080  if (MatchDstPrefixPort(protocol, 0, DstIP, ignore_addr)) {
1081  *sport = *dport = 0;
1082  return true;
1083  }
1084  return false;
1085 }
1086 
1087 
1088 bool VmInterface::MatchSrcDstPrefixPort(uint8_t protocol, uint16_t port,
1089  IpAddress *src_ip,
1090  IpAddress *dst_ip) const
1091 {
1092  FatFlowPrefixAggregateType prefix_type;
1093  Ip4Address Ipv4_src_subnet, Ipv4_src_ret_subnet;
1094  Ip4Address Ipv4_dst_subnet, Ipv4_dst_ret_subnet;
1095  Ip6Address Ipv6_src_subnet, Ipv6_src_ret_subnet;
1096  Ip6Address Ipv6_dst_subnet, Ipv6_dst_ret_subnet;
1097  uint8_t max_mask, max_plen;
1098  const FatFlowEntry *match_ffe = NULL;
1099 
1100  if (src_ip->is_v4()) {
1101  prefix_type = AGGREGATE_SRC_DST_IPV4;
1102  Ipv4_src_subnet = Address::GetIp4SubnetAddress(src_ip->to_v4(),
1104  Ipv4_dst_subnet = Address::GetIp4SubnetAddress(dst_ip->to_v4(),
1106  max_mask = 32;
1107  max_plen = 32;
1108  } else {
1109  prefix_type = AGGREGATE_SRC_DST_IPV6;
1110  Ipv6_src_subnet = Address::GetIp6SubnetAddress(src_ip->to_v6(),
1112  Ipv6_dst_subnet = Address::GetIp6SubnetAddress(dst_ip->to_v6(),
1114  max_mask = 128;
1115  max_plen = 128;
1116  }
1117 
1118  const FatFlowEntry lbffe =
1119  FatFlowEntry(protocol, port, "none",
1120  prefix_type,
1121  (src_ip->is_v4()?
1122  IpAddress(Ipv4_src_subnet):
1123  IpAddress(Ipv6_src_subnet)),
1126  (dst_ip->is_v4()?
1127  IpAddress(Ipv4_dst_subnet):
1128  IpAddress(Ipv6_dst_subnet)),
1131 
1132  FatFlowEntrySet::iterator start = fat_flow_list_.list_.lower_bound(lbffe);
1133 
1134  const FatFlowEntry ubffe = FatFlowEntry(protocol, port, "none", prefix_type,
1135  *src_ip, max_mask, max_plen,
1136  *dst_ip, max_mask, max_plen);
1137 
1138  FatFlowEntrySet::iterator end = fat_flow_list_.list_.upper_bound(ubffe);
1139 
1140  if ((start != fat_flow_list_.list_.end()) &&
1141  (start->protocol == protocol) && (start->port == port)) {
1142  while (start != end) {
1143  if (src_ip->is_v4() && start->src_prefix.is_v4() &&
1144  start->dst_prefix.is_v4() &&
1145  IsIp4SubnetMember(src_ip->to_v4(), start->src_prefix.to_v4(),
1146  start->src_prefix_mask) &&
1147  IsIp4SubnetMember(dst_ip->to_v4(), start->dst_prefix.to_v4(),
1148  start->dst_prefix_mask) &&
1149  (start->protocol == protocol) && (start->port == port)) {
1150  match_ffe = &(*start);
1151  } else if (src_ip->is_v6() && start->src_prefix.is_v6() &&
1152  start->dst_prefix.is_v6() &&
1153  IsIp6SubnetMember(src_ip->to_v6(), start->src_prefix.to_v6(),
1154  start->src_prefix_mask) &&
1155  IsIp6SubnetMember(dst_ip->to_v6(), start->dst_prefix.to_v6(),
1156  start->dst_prefix_mask) &&
1157  (start->protocol == protocol) && (start->port == port)) {
1158  match_ffe = &(*start);
1159  }
1160  start++;
1161  }
1162  }
1163  if (match_ffe && (match_ffe->prefix_aggregate == prefix_type)) {
1164  if (src_ip->is_v4()) {
1165  Ipv4_src_ret_subnet =
1166  Address::GetIp4SubnetAddress(src_ip->to_v4(),
1167  match_ffe->src_aggregate_plen);
1168  Ipv4_dst_ret_subnet =
1169  Address::GetIp4SubnetAddress(dst_ip->to_v4(),
1170  match_ffe->dst_aggregate_plen);
1171  *src_ip = IpAddress(Ipv4_src_ret_subnet);
1172  *dst_ip = IpAddress(Ipv4_dst_ret_subnet);
1173  } else {
1174  Ipv6_src_ret_subnet =
1175  Address::GetIp6SubnetAddress(src_ip->to_v6(),
1176  match_ffe->src_aggregate_plen);
1177  Ipv6_dst_ret_subnet =
1178  Address::GetIp6SubnetAddress(dst_ip->to_v6(),
1179  match_ffe->dst_aggregate_plen);
1180  *src_ip = IpAddress(Ipv6_src_ret_subnet);
1181  *dst_ip = IpAddress(Ipv6_dst_ret_subnet);
1182  }
1183  return true;
1184  }
1185  return false;
1186 }
1187 
1188 
1189 bool VmInterface::MatchSrcDstPrefixRule(uint8_t protocol, uint16_t *sport,
1190  uint16_t *dport, bool *same_port_num,
1191  IpAddress *SrcIP, IpAddress *DstIP) const
1192 {
1193  if ((*sport) < (*dport)) {
1194  if (MatchSrcDstPrefixPort(protocol, *sport, SrcIP, DstIP)) {
1195  *dport = 0;
1196  return true;
1197  }
1198  if (MatchSrcDstPrefixPort(protocol, *dport, SrcIP, DstIP)) {
1199  *sport = 0;
1200  return true;
1201  }
1202  } else {
1203  if (MatchSrcDstPrefixPort(protocol, *dport, SrcIP, DstIP)) {
1204  if ((*sport) == (*dport)) {
1205  *same_port_num = true;
1206  }
1207  *sport = 0;
1208  return true;
1209  }
1210  if (MatchSrcDstPrefixPort(protocol, *sport, SrcIP, DstIP)) {
1211  *dport = 0;
1212  return true;
1213  }
1214  }
1215  if (MatchSrcDstPrefixPort(protocol, 0, SrcIP, DstIP)) {
1216  *sport = *dport = 0;
1217  return true;
1218  }
1219  return false;
1220 }
1221 
1222 
1223 bool VmInterface::IsFatFlowPrefixAggregation(bool ingress, uint8_t protocol,
1224  uint16_t *sport, uint16_t *dport,
1225  bool *same_port_num,
1226  IpAddress *SrcIP, IpAddress *DstIP,
1227  bool *is_fat_flow_src_prefix,
1228  bool *is_fat_flow_dst_prefix,
1230  *ignore_addr) const
1231 {
1232  uint16_t *src_port = sport,
1233  *dst_port = dport;
1234  IpAddress *src_ip = (ingress? SrcIP: DstIP),
1235  *dst_ip = (ingress? DstIP: SrcIP);
1236  bool *is_src_prefix = (ingress? is_fat_flow_src_prefix : is_fat_flow_dst_prefix);
1237  bool *is_dst_prefix = (ingress? is_fat_flow_dst_prefix : is_fat_flow_src_prefix);
1238  bool ret;
1239  FatFlowIgnoreAddressType ign_addr;
1240 
1241  *is_src_prefix = false;
1242  *is_dst_prefix = false;
1243 
1244  /* Match Src prefix rule first */
1245  if (MatchSrcPrefixRule(protocol, src_port, dst_port, same_port_num,
1246  src_ip, &ign_addr)) {
1247  *is_src_prefix = true;
1248  *ignore_addr = ign_addr;
1249  return true;
1250  }
1251  /* Match Dst prefix rule */
1252  if (MatchDstPrefixRule(protocol, src_port, dst_port, same_port_num,
1253  dst_ip, &ign_addr)) {
1254  *is_dst_prefix = true;
1255  *ignore_addr = ign_addr;
1256  return true;
1257  }
1258  /* Match Src+Dst prefix rule */
1259  ret = MatchSrcDstPrefixRule(protocol, src_port, dst_port, same_port_num,
1260  src_ip, dst_ip);
1261  if (ret) {
1262  *is_src_prefix = true;
1263  *is_dst_prefix = true;
1264  }
1265 
1266  return ret;
1267 }
1268 
1269 
1271  const IpAddress &sip,
1272  const IpAddress &dip) const {
1273  if (family == Address::INET) {
1274  IpAddress gw_ip = GetGatewayIp(primary_ip_addr_);
1275  if ((sip == gw_ip) || (dip == gw_ip)) {
1276  return true;
1277  }
1278  IpAddress service_ip = GetServiceIp(primary_ip_addr_);
1279  if ((sip == service_ip) || (dip == service_ip)) {
1280  return true;
1281  }
1282  boost::system::error_code ec;
1283  Ip4Address ll_subnet = Ip4Address::from_string
1284  (agent()->v4_link_local_subnet(), ec);
1285  if (IsIp4SubnetMember(sip.to_v4(), ll_subnet,
1286  agent()->v4_link_local_plen())) {
1287  return true;
1288  }
1289  if (IsIp4SubnetMember(dip.to_v4(), ll_subnet,
1290  agent()->v4_link_local_plen())) {
1291  return true;
1292  }
1293  } else if (family == Address::INET6){
1294  IpAddress gw_ip = GetGatewayIp(primary_ip6_addr_);
1295  if ((sip == gw_ip) || (dip == gw_ip)) {
1296  return true;
1297  }
1298  IpAddress service_ip = GetServiceIp(primary_ip6_addr_);
1299  if ((sip == service_ip) || (dip == service_ip)) {
1300  return true;
1301  }
1302  boost::system::error_code ec;
1303  Ip6Address ll6_subnet = Ip6Address::from_string
1304  (agent()->v6_link_local_subnet(), ec);
1305  if (IsIp6SubnetMember(sip.to_v6(), ll6_subnet,
1306  agent()->v6_link_local_plen())) {
1307  return true;
1308  }
1309  if (IsIp6SubnetMember(dip.to_v6(), ll6_subnet,
1310  agent()->v6_link_local_plen())) {
1311  return true;
1312  }
1313  }
1314  return false;
1315 }
1316 
1317 void VmInterface::FillV4ExcludeIp(uint64_t plen, const Ip4Address &ip,
1318  VmInterface::FatFlowExcludeList *list) const {
1319  uint64_t value = 0;
1320  if (!ip.is_unspecified()) {
1321  value = plen | htonl(ip.to_ulong());
1322  list->fat_flow_v4_exclude_list_.push_back(value);
1323  }
1324 }
1325 
1326 void VmInterface::FillV6ExcludeIp(uint16_t plen, const IpAddress &ip,
1327  VmInterface::FatFlowExcludeList *list) const {
1328  if (ip.is_v6() && !ip.is_unspecified()) {
1329  uint64_t ip_arr[2];
1330  Ip6AddressToU64Array(ip.to_v6(), ip_arr, 2);
1331  list->fat_flow_v6_exclude_upper_list_.push_back(ip_arr[0]);
1332  list->fat_flow_v6_exclude_lower_list_.push_back(ip_arr[1]);
1333  list->fat_flow_v6_exclude_plen_list_.push_back(plen);
1334  }
1335 }
1336 
1339  /* Build the list afresh each time. So clear the list */
1340  list->Clear();
1341 
1342  /* Build IPv4 exclude-list */
1343  IpAddress gw_ip = GetGatewayIp(primary_ip_addr_);
1344  uint64_t plen = (uint64_t(Address::kMaxV4PrefixLen) << 32);
1345  FillV4ExcludeIp(plen, gw_ip.to_v4(), list);
1346  IpAddress service_ip = GetServiceIp(primary_ip_addr_);
1347  FillV4ExcludeIp(plen, service_ip.to_v4(), list);
1348  boost::system::error_code ec;
1349  Ip4Address ll_subnet = Ip4Address::from_string
1350  (agent()->v4_link_local_subnet(), ec);
1351  plen = (uint64_t(agent()->v4_link_local_plen()) << 32);
1352  FillV4ExcludeIp(plen, ll_subnet, list);
1353 
1354  /* Build IPv6 exclude-list */
1355  IpAddress gw6_ip = GetGatewayIp(primary_ip6_addr_);
1356  FillV6ExcludeIp(128, gw6_ip, list);
1357  IpAddress service6_ip = GetServiceIp(primary_ip6_addr_);
1358  FillV6ExcludeIp(128, service6_ip, list);
1359  Ip6Address ll6_subnet = Ip6Address::from_string
1360  (agent()->v6_link_local_subnet(), ec);
1361  FillV6ExcludeIp(agent()->v6_link_local_plen(), ll6_subnet, list);
1362 }
1363 
1364 const MacAddress& VmInterface::GetVifMac(const Agent *agent) const {
1365  if (parent()) {
1366  if (device_type_ == VM_VLAN_ON_VMI) {
1367  const VmInterface *vmi =
1368  static_cast<const VmInterface *>(parent_.get());
1369  return vmi->GetVifMac(agent);
1370  }
1371  return parent()->mac();
1372  } else {
1373  return agent->vrrp_mac();
1374  }
1375 }
1376 
1378  return (l2_active_ & is_hc_active_);
1379 }
1380 
1381 // Policy is disabled only if user explicitly sets disable policy.
1382 // If user changes to disable policy. only policy will be enabled in case of
1383 // link local services & BGP as a service.
1385  if (disable_policy_) {
1386  return false;
1387  }
1388 
1389  /* For a l2-only VN's VMI, policy should be implicitly disabled */
1390  if (layer3_forwarding_ == false) {
1391  return false;
1392  }
1393  return true;
1394 }
1395 
1396 // VN is in VXLAN mode if,
1397 // - Tunnel type computed is VXLAN and
1398 // - vxlan_id_ set in VN is non-zero
1401  return false;
1402 
1403  return vxlan_id_ != 0;
1404 }
1405 
1407  std::vector<std::string> *vect) const {
1408  InstanceIpSet list;
1409  if (family == Address::INET) {
1410  list = instance_ipv4_list_.list_;
1411  } else {
1412  list = instance_ipv6_list_.list_;
1413  }
1414  InstanceIpSet::iterator it = list.begin();
1415  while (it != list.end()) {
1416  const VmInterface::InstanceIp &rt = *it;
1417  it++;
1418  vect->push_back(rt.ip_.to_string());
1419  }
1420 }
1421 
1422 uint32_t VmInterface::GetIsid() const {
1423  BridgeDomainEntrySet::const_iterator it = bridge_domain_list_.list_.begin();
1424  for (; it != bridge_domain_list_.list_.end(); it++) {
1425  return it->bridge_domain_->isid();
1426  }
1427  return kInvalidIsid;
1428 }
1429 
1430 uint32_t VmInterface::GetPbbVrf() const {
1431  BridgeDomainEntrySet::const_iterator it = bridge_domain_list_.list_.begin();
1432  for (; it != bridge_domain_list_.list_.end(); it++) {
1433  if (it->bridge_domain_->vrf()) {
1434  return it->bridge_domain_->vrf()->vrf_id();
1435  }
1436  }
1437  return VrfEntry::kInvalidIndex;
1438 }
1439 
1440 uint32_t VmInterface::GetPbbLabel() const {
1441  BridgeDomainEntrySet::const_iterator it = bridge_domain_list_.list_.begin();
1442  for (; it != bridge_domain_list_.list_.end(); it++) {
1443  if (it->bridge_domain_->vrf()) {
1444  return it->bridge_domain_->vrf()->table_label();
1445  }
1446  }
1447  return MplsTable::kInvalidLabel;
1448 }
1449 
1451 // Metadata related routines
1454  MetaDataIpMap::const_iterator it = metadata_ip_map_.find(ip);
1455  if (it != metadata_ip_map_.end()) {
1456  return it->second;
1457  }
1458 
1459  return NULL;
1460 }
1461 
1463  std::pair<MetaDataIpMap::iterator, bool> ret;
1464  ret = metadata_ip_map_.insert(std::pair<IpAddress, MetaDataIp*>
1465  (mip->GetLinkLocalIp(), mip));
1466  assert(ret.second);
1467 }
1468 
1470  std::size_t ret = metadata_ip_map_.erase(mip->GetLinkLocalIp());
1471  if (ret == 0) {
1472  LOG(DEBUG, "Return code for Metadata IP Map Erase: " <<ret<< " for MetaDataIp: " <<mip->GetLinkLocalIp());
1473  }
1474 }
1475 
1477  MetaDataIpMap::iterator it = metadata_ip_map_.begin();
1478  while (it != metadata_ip_map_.end()) {
1479  it->second->UpdateInterfaceCb();
1480  it++;
1481  }
1482 }
1483 
1485  bool ret = false;
1486  InterfaceTable *table = static_cast<InterfaceTable *>(get_table());
1487 
1488  // Support DHCP relay for fabric-ports if IP address is not configured
1489  do_dhcp_relay_ = (fabric_port_ && addr.to_ulong() == 0 && vrf() &&
1490  vrf()->GetName() == table->agent()->fabric_vrf_name());
1491 
1492  if (do_dhcp_relay_) {
1493  // Set config_seen flag on DHCP SNoop entry
1494  table->DhcpSnoopSetConfigSeen(name());
1495  // IP Address not know. Get DHCP Snoop entry.
1496  // Also sets the config_seen_ flag for DHCP Snoop entry
1497  addr = table->GetDhcpSnoopEntry(name());
1498  dhcp_addr_ = addr;
1499  }
1500 
1501  // Retain the old if new IP could not be got
1502  if (addr.to_ulong() == 0) {
1503  addr = primary_ip_addr_;
1504  }
1505 
1506  if (primary_ip_addr_ != addr) {
1507  primary_ip_addr_ = addr;
1508  ret = true;
1509  }
1510 
1511  return ret;
1512 }
1513 
1515  if (si_other_end_vmi_ == nil_uuid()) {
1516  return NULL;
1517  }
1518  InterfaceTable *table = static_cast<InterfaceTable *>(get_table());
1519  VmInterfaceKey key(AgentKey::ADD_DEL_CHANGE, si_other_end_vmi_, "");
1520  VmInterface *intf = static_cast<VmInterface *>(table->Find(&key, false));
1521  return intf;
1522 }
1523 
1524 void VmInterface::SendTrace(const AgentDBTable *table, Trace event) const {
1525  InterfaceInfo intf_info;
1526  intf_info.set_name(name());
1527  intf_info.set_index(id_);
1528 
1529  switch(event) {
1530  case ACTIVATED_IPV4:
1531  intf_info.set_op("IPV4 Activated");
1532  break;
1533  case DEACTIVATED_IPV4:
1534  intf_info.set_op("IPV4 Deactivated");
1535  break;
1536  case ACTIVATED_IPV6:
1537  intf_info.set_op("IPV6 Activated");
1538  break;
1539  case DEACTIVATED_IPV6:
1540  intf_info.set_op("IPV6 Deactivated");
1541  break;
1542  case ACTIVATED_L2:
1543  intf_info.set_op("L2 Activated");
1544  break;
1545  case DEACTIVATED_L2:
1546  intf_info.set_op("L2 Deactivated");
1547  break;
1548  case ADD:
1549  intf_info.set_op("Add");
1550  break;
1551  case DEL:
1552  intf_info.set_op("Delete");
1553  break;
1554 
1555  case FLOATING_IP_CHANGE: {
1556  intf_info.set_op("Floating IP change");
1557  std::vector<FloatingIPInfo> fip_list;
1558  FloatingIpSet::iterator it = floating_ip_list_.list_.begin();
1559  while (it != floating_ip_list_.list_.end()) {
1560  const FloatingIp &ip = *it;
1561  FloatingIPInfo fip;
1562  fip.set_ip_address(ip.floating_ip_.to_string());
1563  fip.set_vrf_name(ip.vrf_->GetName());
1564  fip_list.push_back(fip);
1565  it++;
1566  }
1567  intf_info.set_fip(fip_list);
1568  break;
1569  }
1570  case SERVICE_CHANGE:
1571  break;
1572 
1573  case VMI_REUSE:
1574  intf_info.set_op("VMI reuse");
1575  intf_info.set_vrf_on_delete(vrf_name_);
1576  break;
1577 
1578  case VRF_REUSE:
1579  intf_info.set_op("VRF reuse");
1580  intf_info.set_vrf_on_delete(vrf_name_);
1581  break;
1582  }
1583 
1584  intf_info.set_ip_address(primary_ip_addr_.to_string());
1585  if (vm_) {
1586  intf_info.set_vm(UuidToString(vm_->GetUuid()));
1587  }
1588  if (vn_) {
1589  intf_info.set_vn(vn_->GetName());
1590  }
1591  if (vrf_) {
1592  intf_info.set_vrf(vrf_->GetName());
1593  }
1594  intf_info.set_vm_project(UuidToString(vm_project_uuid_));
1596  table,
1597  intf_info);
1598 }
bool IsHealthCheckEnabled() const
bool GetIpamDhcpOptions(std::vector< autogen::DhcpOptionType > *options, bool ipv6) const
VrfEntry * GetAliasIpVrf(const IpAddress &ip) const
void BuildFatFlowExcludeList(FatFlowExcludeList *list) const
void ResyncHealthCheckInterface(const HealthCheckService *service, const VmInterface *intf)
#define FAT_FLOW_ENTRY_MIN_PREFIX_LEN
void SetPathPreference(PathPreference *pref, bool ecmp, const IpAddress &dependent_ip) const
Definition: vrf.h:86
std::set< InstanceIp, InstanceIp > InstanceIpSet
Definition: vm_interface.h:933
bool IsFloatingIp(const IpAddress &ip) const
AgentRouteTable * GetEvpnRouteTable() const
Definition: vrf.cc:330
VrfEntry * fabric_vrf() const
Definition: agent.h:915
void SendTrace(const AgentDBTable *table, Trace event) const
std::vector< uint16_t > fat_flow_v6_exclude_plen_list_
HealthCheckService * service() const
Definition: health_check.h:146
bool IsVxlanMode() const
bool GetSubnetDhcpOptions(std::vector< autogen::DhcpOptionType > *options, bool ipv6) const
bool MatchSrcPrefixPort(uint8_t protocol, uint16_t port, IpAddress *src_ip, FatFlowIgnoreAddressType *ignore_addr) const
Definition: vn.h:28
IpAddress destination_ip() const
bool IsIp4SubnetMember(const Ip4Address &ip, const Ip4Address &prefix_ip, uint16_t plen)
Definition: address_util.cc:19
static IpAddress ipv4_max_addr
void DelLocalVmRoute(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const VmInterface *intf, const IpAddress &ip, uint32_t ethernet_tag)
Family
Definition: address.h:24
void InsertHealthCheckInstance(HealthCheckInstanceBase *hc_inst)
static IpAddress ipv4_empty_addr
uint32_t GetServiceVlanLabel(const VrfEntry *vrf) const
std::vector< uint64_t > fat_flow_v4_exclude_list_
boost::asio::ip::address IpAddress
Definition: address.h:13
static const MacAddress & vrrp_mac()
Definition: agent.h:439
const MacAddress & GetVifMac(const Agent *) const
static const MacAddress kZeroMac
Definition: mac_address.h:149
bool InstallBridgeRoutes() const
bool GetInterfaceDhcpOptions(std::vector< autogen::DhcpOptionType > *options) const
void BuildIpStringList(Address::Family family, std::vector< std::string > *vect) const
void DelPhysicalDeviceVnEntry(const boost::uuids::uuid &vmi)
std::vector< int > SecurityGroupList
Definition: agent.h:201
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
void FillV4ExcludeIp(uint64_t plen, const Ip4Address &ip, FatFlowExcludeList *list) const
boost::uuids::uuid uuid
void CopyEcmpLoadBalance(EcmpLoadBalance &ecmp_load_balance)
static const uint8_t kMaxV4PrefixLen
Definition: address.h:20
VmiToPhysicalDeviceVnData(const boost::uuids::uuid &dev, const boost::uuids::uuid &vn)
const string & GetName() const
Definition: vrf.h:100
uint32_t GetPbbLabel() const
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:138
void set_vrf(const std::string &vrf)
Definition: agent_path.h:100
bool IsHostLinkStateUp(const std::string &name) const
const Peer * peer() const
IpAddress GetServiceIp(const IpAddress &ip) const
FatFlowPrefixAggregateType prefix_aggregate
static IpAddress ipv6_max_addr
Agent * agent() const
Definition: interface.h:447
static Ip4Address GetIp4SubnetAddress(const Ip4Address &prefix, uint16_t plen)
Definition: address.cc:179
static Ip6Address GetIp6SubnetAddress(const Ip6Address &prefix, uint16_t plen)
Definition: address.cc:200
void SetServiceVlanPathPreference(PathPreference *pref, const IpAddress &service_ip) const
const IpAddress ip_
Definition: vm_interface.h:922
const std::string & fabric_vrf_name() const
Definition: agent.h:903
std::vector< uint64_t > fat_flow_v6_exclude_upper_list_
bool WaitForTraffic() const
FatFlowPrefixAggregateType
Definition: vm_interface.h:446
bool IsActive() const
static void Delete(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen)
void set_dependent_ip(const IpAddress &ip)
Definition: agent_path.h:96
uint8_t type
Definition: load_balance.h:109
IpAddress default_gw
Definition: vn.h:31
static const uint32_t kInvalidVlanId
Definition: vm_interface.h:360
Definition: agent.h:358
const std::string GetAnalyzer() const
void DhcpSnoopSetConfigSeen(const std::string &ifname)
Definition: interface.cc:739
static Options options
const HealthCheckInstanceSet & hc_instance_set() const
virtual void GetOsParams(Agent *agent)
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
bool NeedOsStateWithoutDevice() const
Definition: trace.h:220
bool IsIpv4Active() const
std::set< HealthCheckInstanceBase * > HealthCheckInstanceSet
Definition: vm_interface.h:466
static const std::string & NullString()
Definition: agent.h:437
static TypeBmap AllType()
Definition: nexthop.h:321
void DeleteRoute(const std::string &vrf_name, const IpAddress &ip, uint32_t plen)
uint32_t GetPbbVrf() const
IpAddress GetLinkLocalIp() const
Definition: metadata_ip.cc:79
#define OPER_TRACE_ENTRY(obj, table,...)
Definition: agent_db.h:234
VrfEntry * FindVrfRef(const std::string &name) const
Definition: interface.cc:295
void set_preference(uint32_t preference)
Definition: agent_path.h:82
IpAddress get_source_ip() const
Definition: health_check.h:152
void UpdatePhysicalDeviceVnEntry(const boost::uuids::uuid &vmi, boost::uuids::uuid &dev, boost::uuids::uuid &vn, IFMapNode *vn_node)
std::vector< std::string > CommunityList
Definition: bgp_config.h:347
void Ip6AddressToU64Array(const Ip6Address &addr, uint64_t *arr, int size)
AgentDBEntry * Find(const DBEntry *key, bool ret_del)
Definition: agent_db.cc:134
uint32_t GetIsid() const
Definition: peer.h:44
FatFlowIgnoreAddressType ignore_address
void AddRoute(const std::string &vrf_name, const IpAddress &ip, uint32_t plen, const std::string &vn_name, bool force_policy, bool ecmp, bool is_local, bool proxy_arp, const IpAddress &service_ip, const IpAddress &dependent_ip, const CommunityList &communties, uint32_t label, const string &intf_route_type, bool is_learnt_route=false)
std::set< std::string > VnListType
Definition: agent.h:212
bool PolicyEnabled() const
void UpdateInterfaceHealthCheckService()
static Type ComputeType(TypeBmap bmap)
Definition: nexthop.cc:33
IpAddress dns_server
Definition: vn.h:33
bool ExcludeFromFatFlow(Address::Family family, const IpAddress &sip, const IpAddress &dip) const
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
static const uint32_t kInvalidLabel
Definition: mpls.h:101
void DeleteMetaDataIpInfo(MetaDataIp *mip)
bool CopyIpAddress(Ip4Address &addr)
void DeleteHealthCheckInstance(HealthCheckInstanceBase *hc_inst)
static IpAddress ipv6_empty_addr
virtual void Copy(const EcmpLoadBalance &rhs)
std::vector< uint64_t > fat_flow_v6_exclude_lower_list_
const MacAddress & GetIpMac(const IpAddress &, const uint8_t plen) const
bool MatchSrcDstPrefixRule(uint8_t protocol, uint16_t *sport, uint16_t *dport, bool *same_port_num, IpAddress *SrcIP, IpAddress *DstIP) const
bool MatchDstPrefixPort(uint8_t protocol, uint16_t port, IpAddress *dst_ip, FatFlowIgnoreAddressType *ignore_addr) const
void InsertMetaDataIpInfo(MetaDataIp *mip)
bool MatchSrcPrefixRule(uint8_t protocol, uint16_t *sport, uint16_t *dport, bool *same_port_num, IpAddress *SrcIP, FatFlowIgnoreAddressType *ignore_addr) const
bool MatchDstPrefixRule(uint8_t protocol, uint16_t *sport, uint16_t *dport, bool *same_port_num, IpAddress *DstIP, FatFlowIgnoreAddressType *ignore_addr) const
HealthCheckType health_check_type() const
Definition: health_check.h:341
static const uint32_t kInvalidIndex
Definition: interface.h:70
bool IsMetaDataIPActive() const
void set_static_preference(bool static_pref)
Definition: agent_path.h:92
VrfEntry * forwarding_vrf() const
Definition: vrf.h:217
static const uint32_t kInvalidIndex
Definition: vrf.h:88
static void AddLocalVmRoute(const Peer *peer, const string &vm_vrf, const IpAddress &addr, uint8_t plen, const boost::uuids::uuid &intf_uuid, const VnListType &vn_list, uint32_t label, const SecurityGroupList &sg_list, const TagList &tag_list, const CommunityList &communities, bool force_policy, const PathPreference &path_preference, const IpAddress &subnet_service_ip, const EcmpLoadBalance &ecmp_load_balance, bool is_local, bool is_health_check_service, const std::string &intf_name, bool native_encap, const std::string &intf_route_type=VmInterface::kInterface, bool is_learnt_route=false)
#define LOG(_Level, _Msg)
Definition: logging.h:33
void AddL2InterfaceRoute(const IpAddress &ip, const MacAddress &mac, const IpAddress &dependent_ip) const
bool IsFatFlowPrefixAggregation(bool ingress, uint8_t protocol, uint16_t *sport, uint16_t *dport, bool *same_port_num, IpAddress *SrcIP, IpAddress *DstIP, bool *is_src_prefix, bool *is_dst_prefix, FatFlowIgnoreAddressType *ignore_addr) const
bool HasFloatingIp() const
bool IsMetaDataL2Active() const
bool IsFatFlowPortBased(uint8_t protocol, uint16_t port, FatFlowIgnoreAddressType *ignore_addr) const
VmInterface * PortTuplePairedInterface() const
IpAddress GetGatewayIp(const IpAddress &ip) const
void set_ecmp(bool ecmp)
Definition: agent_path.h:88
bool IsL2Active() const
virtual AgentPath * FindPath(const Peer *peer) const
Definition: agent_route.cc:864
void DeleteL2InterfaceRoute(const VrfEntry *vrf, uint32_t ethernet_tag, const IpAddress &ip, const MacAddress &mac) const
bool MatchAapIp(const IpAddress &ip, uint8_t plen) const
bool MatchSrcDstPrefixPort(uint8_t protocol, uint16_t port, IpAddress *src_ip, IpAddress *dst_ip) const
virtual void GetOsParams(Agent *agent)
Definition: interface.cc:536
const Ip4Address GetDhcpSnoopEntry(const std::string &ifname)
Definition: interface.cc:717
void CopySgIdList(SecurityGroupList *sg_id_list) const
bool IsIp6SubnetMember(const Ip6Address &ip, const Ip6Address &subnet, uint8_t plen)
Definition: address_util.cc:29
bool IsIpv6Active() const
MetaDataIp * GetMetaDataIp(const IpAddress &ip) const
bool NeedDevice() const
const VrfEntry * GetServiceVlanVrf(uint16_t vlan_tag) const
void FillV6ExcludeIp(uint16_t plen, const IpAddress &ip, FatFlowExcludeList *list) const
std::vector< int > TagList
Definition: agent.h:202