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

Generated by: LCOV version 1.14