LCOV - code coverage report
Current view: top level - vnsw/agent/oper - vm_interface_utils.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 348 887 39.2 %
Date: 2026-08-03 02:19:58 Functions: 44 69 63.8 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14