LCOV - code coverage report
Current view: top level - vnsw/agent/oper - vm_interface_request.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 465 761 61.1 %
Date: 2026-08-03 02:19:58 Functions: 20 49 40.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : #include <cmn/agent_cmn.h>
       5             : #include <init/agent_param.h>
       6             : #include <oper/operdb_init.h>
       7             : #include <oper/route_common.h>
       8             : #include <oper/vm.h>
       9             : #include <oper/vn.h>
      10             : #include <oper/vrf.h>
      11             : #include <oper/nexthop.h>
      12             : #include <oper/mpls.h>
      13             : #include <oper/mirror_table.h>
      14             : #include <oper/metadata_ip.h>
      15             : #include <oper/interface_common.h>
      16             : #include <oper/health_check.h>
      17             : #include <oper/vrf_assign.h>
      18             : #include <oper/vxlan.h>
      19             : #include <oper/oper_dhcp_options.h>
      20             : #include <oper/physical_device_vn.h>
      21             : #include <oper/global_vrouter.h>
      22             : #include <oper/qos_config.h>
      23             : #include <oper/bridge_domain.h>
      24             : #include <oper/sg.h>
      25             : #include <oper/bgp_as_service.h>
      26             : #include <oper/tag.h>
      27             : 
      28             : #include <filter/acl.h>
      29             : #include <port_ipc/port_ipc_handler.h>
      30             : #include <port_ipc/port_subscribe_table.h>
      31             : #include <resource_manager/resource_manager.h>
      32             : #include <resource_manager/resource_table.h>
      33             : #include <resource_manager/mpls_index.h>
      34             : 
      35             : using namespace std;
      36             : using namespace boost::uuids;
      37             : using namespace autogen;
      38             : 
      39             : /////////////////////////////////////////////////////////////////////////////
      40             : // VM Port Key routines
      41             : /////////////////////////////////////////////////////////////////////////////
      42       46211 : VmInterfaceKey::VmInterfaceKey(AgentKey::DBSubOperation sub_op,
      43       46211 :                    const boost::uuids::uuid &uuid, const std::string &name) :
      44       46211 :     InterfaceKey(sub_op, Interface::VM_INTERFACE, uuid, name, false) {
      45       46211 : }
      46             : 
      47        1089 : Interface *VmInterfaceKey::AllocEntry(const InterfaceTable *table) const {
      48        1089 :     Agent *agent = table->agent();
      49             :     /* OS oper state is disabled by default in Vmware mode */
      50        1089 :     bool os_oper_state = !agent->isVmwareMode();
      51        1089 :     return new VmInterface(uuid_, name_, os_oper_state, nil_uuid());
      52             : }
      53             : 
      54          17 : Interface *VmInterfaceKey::AllocEntry(const InterfaceTable *table,
      55             :                                       const InterfaceData *data) const {
      56          17 :     const VmInterfaceData *vm_data =
      57             :         static_cast<const VmInterfaceData *>(data);
      58             : 
      59          17 :     VmInterface *vmi = vm_data->OnAdd(table, this);
      60          17 :     return vmi;
      61             : }
      62             : 
      63         353 : InterfaceKey *VmInterfaceKey::Clone() const {
      64         353 :     return new VmInterfaceKey(*this);
      65             : }
      66             : 
      67             : /////////////////////////////////////////////////////////////////////////////
      68             : // VmInterfaceConfigData routines
      69             : /////////////////////////////////////////////////////////////////////////////
      70          98 : VmInterfaceConfigData::VmInterfaceConfigData(Agent *agent, IFMapNode *node) :
      71             :     VmInterfaceData(agent, node, CONFIG, Interface::TRANSPORT_INVALID),
      72          98 :     addr_(0), ip6_addr_(), vm_mac_(""),
      73          98 :     cfg_name_(""), vm_uuid_(), vm_name_(), vn_uuid_(), vrf_name_(""),
      74          98 :     fabric_port_(true), need_linklocal_ip_(false), bridging_(true),
      75          98 :     layer3_forwarding_(true), mirror_enable_(false), ecmp_(false),
      76          98 :     ecmp6_(false), dhcp_enable_(true), dhcp_enable_v6_(false),
      77          98 :     proxy_arp_mode_(VmInterface::PROXY_ARP_NONE), admin_state_(true),
      78          98 :     disable_policy_(false), analyzer_name_(""),
      79          98 :     local_preference_(0), oper_dhcp_options_(),
      80          98 :     mirror_direction_(Interface::UNKNOWN),
      81          98 :     cfg_igmp_enable_(false), igmp_enabled_(false),
      82          98 :     mac_ip_learning_enable_(false), max_flows_(0), sg_list_(),
      83          98 :     floating_ip_list_(), alias_ip_list_(), service_vlan_list_(),
      84         196 :     static_route_list_(), allowed_address_pair_list_(),
      85          98 :     instance_ipv4_list_(true), instance_ipv6_list_(false),
      86          98 :     bridge_domain_list_(),
      87          98 :     device_type_(VmInterface::DEVICE_TYPE_INVALID),
      88          98 :     vmi_type_(VmInterface::VMI_TYPE_INVALID), hbs_intf_type_(VmInterface::HBS_INTF_INVALID),
      89          98 :     physical_interface_(""), parent_vmi_(), subnet_(0), subnet_plen_(0),
      90          98 :     rx_vlan_id_(VmInterface::kInvalidVlanId),
      91          98 :     tx_vlan_id_(VmInterface::kInvalidVlanId),
      92          98 :     logical_interface_(nil_uuid()), ecmp_load_balance_(),
      93          98 :     service_health_check_ip_(), service_ip_(0),
      94          98 :     service_ip_ecmp_(false), service_ip6_(), service_ip_ecmp6_(false),
      95          98 :     qos_config_uuid_(), learning_enabled_(false),
      96          98 :     vhostuser_mode_(VmInterface::vHostUserClient), is_left_si_(false), service_mode_(VmInterface::SERVICE_MODE_ERROR),
      97          98 :     si_other_end_vmi_(nil_uuid()), vmi_cfg_uuid_(nil_uuid()),
      98         686 :     service_intf_type_(""), physical_interface_list_() {
      99          98 : }
     100             : 
     101           5 : VmInterface *VmInterfaceConfigData::OnAdd(const InterfaceTable *table,
     102             :                                           const VmInterfaceKey *key) const {
     103             : 
     104           5 :     Interface *parent = NULL;
     105           5 :     if (device_type_ == VmInterface::REMOTE_VM_VLAN_ON_VMI) {
     106           0 :         if (rx_vlan_id_ == VmInterface::kInvalidVlanId ||
     107           0 :             tx_vlan_id_ == VmInterface::kInvalidVlanId)
     108           0 :             return NULL;
     109             : 
     110           0 :         if (physical_interface_ != Agent::NullString()) {
     111           0 :             PhysicalInterfaceKey key_1(physical_interface_);
     112           0 :             parent = static_cast<Interface *>
     113           0 :                 (table->agent()->interface_table()->FindActiveEntry(&key_1));
     114           0 :         }
     115             : 
     116           0 :         if (parent == NULL)
     117           0 :             return NULL;
     118             :     }
     119             : 
     120           5 :     boost::system::error_code ec;
     121           5 :     MacAddress mac = MacAddress::FromString(vm_mac_, &ec);
     122           5 :     if (ec.value() != 0) {
     123           2 :         mac.Zero();
     124             :     }
     125             : 
     126           5 :     Agent *agent = table->agent();
     127             :     /* OS oper state is disabled by default in Vmware mode */
     128           5 :     bool os_oper_state = !agent->isVmwareMode();
     129             :     VmInterface *vmi =
     130           5 :         new VmInterface(key->uuid_, key->name_, addr_, mac, vm_name_,
     131           5 :                         nil_uuid(), tx_vlan_id_, rx_vlan_id_, parent,
     132           5 :                         ip6_addr_, device_type_, vmi_type_, vhostuser_mode_,
     133           5 :                         os_oper_state, logical_router_uuid_);
     134           5 :     vmi->SetConfigurer(VmInterface::CONFIG);
     135           5 :     vmi->set_hbs_intf_type(hbs_intf_type_);
     136           5 :     return vmi;
     137             : }
     138             : 
     139           5 : bool VmInterfaceConfigData::OnDelete(const InterfaceTable *table,
     140             :                                      VmInterface *vmi) const {
     141           5 :     if (vmi->IsConfigurerSet(VmInterface::CONFIG) == false)
     142           0 :         return true;
     143             : 
     144           5 :     VmInterfaceConfigData data(NULL, NULL);
     145           5 :     vmi->Resync(table, &data);
     146           5 :     vmi->ResetConfigurer(VmInterface::CONFIG);
     147           5 :     return true;
     148           5 : }
     149             : 
     150          60 : bool VmInterfaceConfigData::OnResync(const InterfaceTable *table,
     151             :                                      VmInterface *vmi,
     152             :                                      bool *force_update) const {
     153          60 :     bool sg_changed = false;
     154          60 :     bool ecmp_changed = false;
     155          60 :     bool local_pref_changed = false;
     156          60 :     bool ecmp_load_balance_changed = false;
     157          60 :     bool static_route_config_changed = false;
     158          60 :     bool etree_leaf_mode_changed = false;
     159          60 :     bool tag_changed = false;
     160          60 :     bool ret = false;
     161             : 
     162          60 :     ret = vmi->CopyConfig(table, this, &sg_changed, &ecmp_changed,
     163             :                           &local_pref_changed, &ecmp_load_balance_changed,
     164             :                           &static_route_config_changed,
     165             :                           &etree_leaf_mode_changed, &tag_changed);
     166          60 :     if (sg_changed || ecmp_changed || local_pref_changed ||
     167          22 :         ecmp_load_balance_changed || static_route_config_changed
     168          19 :         || etree_leaf_mode_changed || tag_changed )
     169          41 :         *force_update = true;
     170             : 
     171          60 :     vmi->SetConfigurer(VmInterface::CONFIG);
     172          60 :     return ret;
     173             : }
     174             : 
     175          70 : autogen::VirtualMachineInterface *VmInterfaceConfigData::GetVmiCfg() const {
     176          70 :     IFMapNode *node = ifmap_node();
     177          70 :     if (node != NULL) {
     178          70 :         if (node->GetObject() != NULL) {
     179             :             return static_cast <autogen::VirtualMachineInterface *>
     180          70 :                         (node->GetObject());
     181             :         }
     182             :     }
     183           0 :     return NULL;
     184             : }
     185             : 
     186             : //Configuration of vhost interface to be filled from
     187             : //config file. This include
     188             : //1> IP of vhost
     189             : //2> Default route to be populated if any
     190             : //3> Resolve route to be added
     191             : //4> Multicast receive route
     192           6 : void VmInterfaceConfigData::CopyVhostData(const Agent *agent) {
     193           6 :     transport_ = static_cast<Interface::Transport>
     194           6 :         (agent->GetInterfaceTransport());
     195             : 
     196           6 :     proxy_arp_mode_ = VmInterface::PROXY_ARP_NONE;
     197           6 :     device_type_ = VmInterface::LOCAL_DEVICE;
     198           6 :     vmi_type_ = VmInterface::VHOST;
     199             : 
     200           6 :     vrf_name_ = agent->fabric_policy_vrf_name();
     201           6 :     if (agent->router_id() != Ip4Address(0) && agent->is_l3mh() == false) {
     202           6 :         addr_ = agent->router_id();
     203           6 :         instance_ipv4_list_.list_.insert(
     204          12 :                 VmInterface::InstanceIp(agent->router_id(), 32, false, true,
     205          12 :                     false, false, false, Ip4Address(0)));
     206             :     }
     207             : 
     208           6 :     boost::system::error_code ec;
     209             :     IpAddress mc_addr =
     210           6 :         Ip4Address::from_string(IPV4_MULTICAST_BASE_ADDRESS, ec);
     211           6 :     receive_route_list_.list_.insert(
     212          12 :             VmInterface::VmiReceiveRoute(mc_addr, MULTICAST_BASE_ADDRESS_PLEN,
     213             :                                          false));
     214             : 
     215           6 :     mc_addr = Ip6Address::from_string(IPV6_MULTICAST_BASE_ADDRESS, ec);
     216           6 :     receive_route_list_.list_.insert(
     217          12 :             VmInterface::VmiReceiveRoute(mc_addr, MULTICAST_BASE_ADDRESS_PLEN,
     218             :                                          false));
     219             : 
     220           6 :     if (agent->params()->subnet_hosts_resolvable() == true) {
     221             :         //Add resolve route
     222           6 :         subnet_ = agent->router_id();
     223           6 :         subnet_plen_ = agent->vhost_prefix_len();
     224             :     }
     225             : 
     226           6 :     physical_interface_list_ = agent->fabric_interface_name_list();
     227             : 
     228           6 :     PhysicalInterfaceKey physical_key(agent->fabric_interface_name());
     229             :     const Interface *pif =
     230          12 :         static_cast<const Interface *>(agent->interface_table()->
     231           6 :                                            FindActiveEntry(&physical_key));
     232           6 :     vm_mac_ = pif->mac().ToString();
     233           6 :     if (agent->is_l3mh()) {
     234           0 :         vm_mac_ = agent->vrrp_mac().ToString();
     235             :     }
     236             : 
     237             :     //Add default route pointing to gateway
     238           6 :     static_route_list_.list_.insert(
     239          12 :             VmInterface::StaticRoute(Ip4Address(0), 0,
     240           6 :                                      agent->params()->gateway_list(),
     241          12 :                                      CommunityList()));
     242           6 : }
     243             : 
     244             : 
     245          60 : bool VmInterface::CopyIp6Address(const Ip6Address &addr) {
     246          60 :     bool ret = false;
     247             : 
     248             :     // Retain the old if new IP could not be got
     249          60 :     if (addr.is_unspecified()) {
     250          10 :         return false;
     251             :     }
     252             : 
     253          50 :     if (primary_ip6_addr_ != addr) {
     254           0 :         primary_ip6_addr_ = addr;
     255           0 :         ret = true;
     256             :     }
     257             : 
     258          50 :     return ret;
     259             : }
     260             : 
     261             : // Copies configuration from DB-Request data. The actual applying of
     262             : // configuration, like adding/deleting routes must be done with ApplyConfig()
     263          60 : bool VmInterface::CopyConfig(const InterfaceTable *table,
     264             :                              const VmInterfaceConfigData *data,
     265             :                              bool *sg_changed,
     266             :                              bool *ecmp_changed,
     267             :                              bool *local_pref_changed,
     268             :                              bool *ecmp_load_balance_changed,
     269             :                              bool *static_route_config_changed,
     270             :                              bool *etree_leaf_mode_changed,
     271             :                              bool *tag_changed) {
     272          60 :     bool ret = false;
     273          60 :     if (table) {
     274          60 :         VmEntry *vm = table->FindVmRef(data->vm_uuid_);
     275          60 :         if (vm_.get() != vm) {
     276          28 :             vm_ = vm;
     277          28 :             ret = true;
     278             :         }
     279             : 
     280             :         bool drop_new_flows =
     281          60 :             (vm_.get() != NULL) ? vm_->drop_new_flows() : false;
     282          60 :         if (drop_new_flows_ != drop_new_flows) {
     283           0 :             drop_new_flows_ = drop_new_flows;
     284           0 :             ret = true;
     285             :         }
     286             : 
     287          60 :         VrfEntry *vrf = table->FindVrfRef(data->vrf_name_);
     288          60 :         if (vrf_.get() != vrf) {
     289          34 :             vrf_ = vrf;
     290          34 :             ret = true;
     291             :         }
     292             : 
     293          60 :         VrfEntry *forwarding_vrf = vrf;
     294          60 :         if (vrf && vrf_->forwarding_vrf()) {
     295           3 :             forwarding_vrf = vrf_->forwarding_vrf();
     296             :         }
     297             : 
     298          60 :         if (forwarding_vrf != forwarding_vrf_) {
     299          34 :             forwarding_vrf_ = forwarding_vrf;
     300          34 :             ret = true;
     301             :         }
     302             : 
     303          60 :         MirrorEntry *mirror = table->FindMirrorRef(data->analyzer_name_);
     304          60 :         if (mirror_entry_.get() != mirror) {
     305           0 :             mirror_entry_ = mirror;
     306           0 :             ret = true;
     307             :         }
     308             :     }
     309             : 
     310          60 :     if (vmi_type_ != data->vmi_type_) {
     311          17 :         *etree_leaf_mode_changed = true;
     312          17 :         vmi_type_ = data->vmi_type_;
     313          17 :         ret = true;
     314             :     }
     315             : 
     316          60 :     if (vmi_cfg_uuid_ != data->vmi_cfg_uuid_) {
     317          28 :         vmi_cfg_uuid_ = data->vmi_cfg_uuid_;
     318          28 :         ret = true;
     319             :     }
     320             : 
     321          60 :     if (vhostuser_mode_ != data->vhostuser_mode_) {
     322           0 :         vhostuser_mode_ = data->vhostuser_mode_;
     323           0 :         ret = true;
     324             :     }
     325             : 
     326          60 :     MirrorDirection mirror_direction = data->mirror_direction_;
     327          60 :     if (mirror_direction_ != mirror_direction) {
     328          17 :         mirror_direction_ = mirror_direction;
     329          17 :         ret = true;
     330             :     }
     331             : 
     332          60 :     string cfg_name = data->cfg_name_;
     333          60 :     if (cfg_name_ != cfg_name) {
     334          28 :         cfg_name_ = cfg_name;
     335          28 :         ret = true;
     336             :     }
     337             : 
     338             :     // Read ifindex for the interface
     339          60 :     if (table) {
     340          60 :         VnEntry *vn = table->FindVnRef(data->vn_uuid_);
     341          60 :         if (vn_.get() != vn) {
     342          28 :             vn_ = vn;
     343          28 :             ret = true;
     344             :         }
     345             : 
     346          60 :         bool val = vn ? vn->layer3_forwarding() : false;
     347          60 :         if (vmi_type_ == VHOST) {
     348           3 :             val = true;
     349             :         }
     350             : 
     351          60 :         if (layer3_forwarding_ != val) {
     352          17 :             layer3_forwarding_ = val;
     353          17 :             ret = true;
     354             :         }
     355             : 
     356          60 :         val = vn ? vn->bridging() : false;
     357          60 :         if (vmi_type_ == VHOST) {
     358             :             //Bridging not supported on VHOST vmi
     359           3 :             val = false;
     360             :         }
     361             : 
     362          60 :         if (bridging_ != val) {
     363          28 :             bridging_ = val;
     364          28 :             ret = true;
     365             :         }
     366             : 
     367          60 :         int vxlan_id = vn ? vn->GetVxLanId() : 0;
     368          60 :         if (vxlan_id_ != vxlan_id) {
     369          12 :             vxlan_id_ = vxlan_id;
     370          12 :             ret = true;
     371             :         }
     372             : 
     373          60 :         bool is_etree_leaf = false;
     374          60 :         if (vn) {
     375          40 :             is_etree_leaf = vn->pbb_etree_enable();
     376             :         }
     377             : 
     378          60 :         if (etree_leaf_ != is_etree_leaf) {
     379           0 :             etree_leaf_ = is_etree_leaf;
     380           0 :             *etree_leaf_mode_changed = true;
     381           0 :             ret = true;
     382             :         }
     383             : 
     384             :         bool flood_unknown_unicast =
     385          60 :             vn ? vn->flood_unknown_unicast(): false;
     386          60 :         if (flood_unknown_unicast_ != flood_unknown_unicast) {
     387           0 :             flood_unknown_unicast_ = flood_unknown_unicast;
     388           0 :             ret = true;
     389             :         }
     390             : 
     391          60 :         bool layer2_control_word = false;
     392          60 :         if (vn) {
     393          40 :             layer2_control_word = vn->layer2_control_word();
     394             :         }
     395          60 :         if (layer2_control_word_ != layer2_control_word) {
     396           0 :             layer2_control_word_ = layer2_control_word;
     397           0 :             *etree_leaf_mode_changed = true;
     398           0 :             ret = true;
     399             :         }
     400             : 
     401             :         //  global_qos_config is applicable for vmi of VHOST type.
     402             :         //  Skip checking for qos for vmi of VHOST type, since cfg_qos_table
     403             :         //  is not applicable.
     404          60 :         if (vmi_type_ != VHOST) {
     405          57 :             AgentQosConfigTable *qos_table = table->agent()->qos_config_table();
     406          57 :             AgentQosConfigKey qos_key(data->qos_config_uuid_);
     407          57 :             const AgentQosConfig *qos_config =  static_cast<AgentQosConfig *>
     408          57 :                 (qos_table->FindActiveEntry(&qos_key));
     409          57 :             bool is_vn_qos_config = false;
     410             : 
     411          57 :             if (qos_config == NULL) {
     412          57 :                 if (vn && vn->qos_config()) {
     413           0 :                     qos_config = vn->qos_config();
     414           0 :                     is_vn_qos_config = true;
     415             :                 }
     416             :             }
     417             : 
     418          57 :             if (qos_config_ != qos_config) {
     419           0 :                 qos_config_ = qos_config;
     420           0 :                 ret = true;
     421             :             }
     422             : 
     423          57 :             if (is_vn_qos_config != is_vn_qos_config_) {
     424           0 :                 is_vn_qos_config_ = is_vn_qos_config;
     425           0 :                 ret = true;
     426             :             }
     427          57 :         }
     428             : 
     429          60 :         if (max_flows_ != data->max_flows_) {
     430           0 :             if(data->max_flows_ != 0) {
     431           0 :                 max_flows_ = data->max_flows_;
     432             :             } else {
     433           0 :                 uint32_t max_flow = 0;
     434           0 :                 if (vn) {
     435           0 :                     max_flow = vn->vn_max_flows();
     436             :                 }
     437           0 :                 max_flows_ = max_flow;
     438             :             }
     439           0 :             ret = true;
     440             :         }
     441             : 
     442             :     }
     443             : 
     444          60 :     if (local_preference_ != data->local_preference_) {
     445           0 :         local_preference_ = data->local_preference_;
     446           0 :         *local_pref_changed = true;
     447           0 :         ret = true;
     448             :     }
     449             : 
     450          60 :     if (need_linklocal_ip_ != data->need_linklocal_ip_) {
     451          28 :         need_linklocal_ip_ = data->need_linklocal_ip_;
     452          28 :         ret = true;
     453             :     }
     454             : 
     455             :     // CopyIpAddress uses fabric_port_. So, set it before CopyIpAddresss
     456          60 :     if (fabric_port_ != data->fabric_port_) {
     457          28 :         fabric_port_ = data->fabric_port_;
     458          28 :         ret = true;
     459             :     }
     460             : 
     461          60 :     if (service_health_check_ip_ != data->service_health_check_ip_) {
     462           0 :         service_health_check_ip_ = data->service_health_check_ip_;
     463           0 :         ret = true;
     464             :     }
     465             : 
     466             :     //If nova gives a instance-ip then retain that
     467             :     //ip address as primary ip address
     468             :     //Else choose the ip address to be old
     469             :     //primary ip address as long as its present in
     470             :     //new configuration also
     471          60 :     Ip4Address ipaddr = data->addr_;
     472          60 :     if (nova_ip_addr_ != Ip4Address(0)) {
     473          50 :         ipaddr = nova_ip_addr_;
     474             :     }
     475          60 :     if (CopyIpAddress(ipaddr)) {
     476           0 :         ret = true;
     477             :     }
     478             : 
     479          60 :     Ip6Address ip6_addr = data->ip6_addr_;
     480          60 :     if (nova_ip6_addr_ != Ip6Address()) {
     481          50 :         ip6_addr = nova_ip6_addr_;
     482             :     }
     483             : 
     484          60 :     if (CopyIp6Address(ip6_addr)) {
     485           0 :         ret = true;
     486             :     }
     487             : 
     488          60 :     if (dhcp_enable_ != data->dhcp_enable_) {
     489           4 :         dhcp_enable_ = data->dhcp_enable_;
     490           4 :         ret = true;
     491             :     }
     492             : 
     493          60 :     if (dhcp_enable_v6_ != data->dhcp_enable_v6_){
     494           0 :         dhcp_enable_v6_ = data->dhcp_enable_v6_;
     495           0 :         ret = true;
     496             :     }
     497             : 
     498          60 :     if (cfg_igmp_enable_ != data->cfg_igmp_enable_) {
     499           0 :         cfg_igmp_enable_ = data->cfg_igmp_enable_;
     500           0 :         ret = true;
     501             :     }
     502             : 
     503          60 :     if (igmp_enabled_ != data->igmp_enabled_) {
     504           0 :         igmp_enabled_ = data->igmp_enabled_;
     505           0 :         ret = true;
     506             :     }
     507             : 
     508          60 :     if (mac_ip_learning_enable_ != data->mac_ip_learning_enable_) {
     509           0 :         mac_ip_learning_enable_ = data->mac_ip_learning_enable_;
     510           0 :         ret = true;
     511             :     }
     512             : 
     513          60 :     if (proxy_arp_mode_ != data->proxy_arp_mode_) {
     514           0 :         proxy_arp_mode_ = data->proxy_arp_mode_;
     515           0 :         ret = true;
     516             :     }
     517             : 
     518          60 :     if (disable_policy_ != data->disable_policy_) {
     519           6 :         disable_policy_ = data->disable_policy_;
     520           6 :         ret = true;
     521             :     }
     522             : 
     523          60 :     if (is_left_si_ != data->is_left_si_) {
     524           0 :         is_left_si_ = data->is_left_si_;
     525           0 :         ret = true;
     526             :     }
     527             : 
     528          60 :     if (service_mode_ != data->service_mode_) {
     529           0 :         service_mode_ = data->service_mode_;
     530           0 :         ret = true;
     531             :     }
     532             : 
     533          60 :     if (si_other_end_vmi_ != data->si_other_end_vmi_) {
     534           0 :         si_other_end_vmi_ = data->si_other_end_vmi_;
     535           0 :         ret = true;
     536             :     }
     537             : 
     538             :     // Update MAC address if not set already. We dont allow modification
     539             :     // of mac-address
     540          60 :     bool mac_set = true;
     541          60 :     if (vm_mac_ == MacAddress::kZeroMac) {
     542           4 :         mac_set = false;
     543             :     }
     544          60 :     if (mac_set_ != mac_set) {
     545          15 :         mac_set_ = mac_set;
     546             :     }
     547             : 
     548          60 :     if (mac_set_ == false) {
     549           4 :         boost::system::error_code ec;
     550           4 :         mac_set_ = true;
     551           4 :         vm_mac_ = MacAddress::FromString(data->vm_mac_, &ec);
     552           4 :         if (ec.value() != 0) {
     553           4 :             vm_mac_ = MacAddress();
     554           4 :             mac_set_ = false;
     555             :         }
     556             : 
     557           4 :         if (vmi_type_ == VHOST) {
     558           0 :             vm_mac_ = GetVifMac(table->agent());
     559           0 :             if (vm_mac_ != MacAddress()) {
     560           0 :                 mac_set_ = true;
     561             :             }
     562             :         }
     563           4 :         ret = true;
     564             :     }
     565             : 
     566          60 :     if (admin_state_ != data->admin_state_) {
     567           0 :         admin_state_ = data->admin_state_;
     568           0 :         ret = true;
     569             :     }
     570             : 
     571          60 :     if (subnet_ != data->subnet_ || subnet_plen_ != data->subnet_plen_) {
     572           6 :         subnet_ = data->subnet_;
     573           6 :         subnet_plen_ = data->subnet_plen_;
     574             :     }
     575             : 
     576          60 :     if (learning_enabled_ != data->learning_enabled_) {
     577           0 :         learning_enabled_ = data->learning_enabled_;
     578           0 :         *etree_leaf_mode_changed = true;
     579           0 :         ret = true;
     580             :     }
     581             : 
     582          60 :     if (service_intf_type_ != data->service_intf_type_) {
     583           0 :         service_intf_type_ = data->service_intf_type_;
     584           0 :         ret = true;
     585             :     }
     586             :     // Copy DHCP options; ret is not modified as there is no dependent action
     587          60 :     oper_dhcp_options_ = data->oper_dhcp_options_;
     588             : 
     589             :     // Audit operational and config floating-ip list
     590          60 :     FloatingIpSet &old_fip_list = floating_ip_list_.list_;
     591          60 :     const FloatingIpSet &new_fip_list = data->floating_ip_list_.list_;
     592          60 :     if (AuditList<FloatingIpList, FloatingIpSet::iterator>
     593          60 :         (floating_ip_list_, old_fip_list.begin(), old_fip_list.end(),
     594             :          new_fip_list.begin(), new_fip_list.end())) {
     595           0 :         ret = true;
     596           0 :         assert(floating_ip_list_.list_.size() ==
     597             :                (floating_ip_list_.v4_count_ + floating_ip_list_.v6_count_));
     598             :     }
     599             : 
     600             :     // Audit operational and config alias-ip list
     601          60 :     AliasIpSet &old_aip_list = alias_ip_list_.list_;
     602          60 :     const AliasIpSet &new_aip_list = data->alias_ip_list_.list_;
     603          60 :     if (AuditList<AliasIpList, AliasIpSet::iterator>
     604          60 :         (alias_ip_list_, old_aip_list.begin(), old_aip_list.end(),
     605             :          new_aip_list.begin(), new_aip_list.end())) {
     606           0 :         ret = true;
     607           0 :         assert(alias_ip_list_.list_.size() ==
     608             :                (alias_ip_list_.v4_count_ + alias_ip_list_.v6_count_));
     609             :     }
     610             : 
     611             :     // Audit operational and config Service VLAN list
     612          60 :     ServiceVlanSet &old_service_list = service_vlan_list_.list_;
     613          60 :     const ServiceVlanSet &new_service_list = data->service_vlan_list_.list_;
     614          60 :     if (AuditList<ServiceVlanList, ServiceVlanSet::iterator>
     615          60 :         (service_vlan_list_, old_service_list.begin(), old_service_list.end(),
     616             :          new_service_list.begin(), new_service_list.end())) {
     617           0 :         ret = true;
     618             :     }
     619             : 
     620             :     // Audit operational and config Static Route list
     621          60 :     StaticRouteSet &old_route_list = static_route_list_.list_;
     622          60 :     const StaticRouteSet &new_route_list = data->static_route_list_.list_;
     623          60 :     if (AuditList<StaticRouteList, StaticRouteSet::iterator>
     624          60 :         (static_route_list_, old_route_list.begin(), old_route_list.end(),
     625             :          new_route_list.begin(), new_route_list.end())) {
     626           6 :         *static_route_config_changed = true;
     627           6 :         ret = true;
     628             :     }
     629             : 
     630             :     // Audit operational and config allowed address pair
     631          60 :     AllowedAddressPairSet &old_aap_list = allowed_address_pair_list_.list_;
     632          60 :     const AllowedAddressPairSet &new_aap_list = data->
     633             :         allowed_address_pair_list_.list_;
     634          60 :     if (AuditList<AllowedAddressPairList, AllowedAddressPairSet::iterator>
     635          60 :        (allowed_address_pair_list_, old_aap_list.begin(), old_aap_list.end(),
     636             :         new_aap_list.begin(), new_aap_list.end())) {
     637           0 :         ret = true;
     638             :     }
     639             : 
     640             :     // Audit operational and config Security Group list
     641          60 :     SecurityGroupEntrySet &old_sg_list = sg_list_.list_;
     642          60 :     const SecurityGroupEntrySet &new_sg_list = data->sg_list_.list_;
     643          60 :     *sg_changed =
     644             :         AuditList<SecurityGroupEntryList, SecurityGroupEntrySet::iterator>
     645          60 :         (sg_list_, old_sg_list.begin(), old_sg_list.end(),
     646             :          new_sg_list.begin(), new_sg_list.end());
     647          60 :     if (*sg_changed) {
     648           6 :         ret = true;
     649             :     }
     650             : 
     651          60 :     VrfAssignRuleSet &old_vrf_assign_list = vrf_assign_rule_list_.list_;
     652          60 :     const VrfAssignRuleSet &new_vrf_assign_list = data->
     653             :         vrf_assign_rule_list_.list_;
     654          60 :     if (AuditList<VrfAssignRuleList, VrfAssignRuleSet::iterator>
     655          60 :         (vrf_assign_rule_list_, old_vrf_assign_list.begin(),
     656             :          old_vrf_assign_list.end(), new_vrf_assign_list.begin(),
     657             :          new_vrf_assign_list.end())) {
     658           0 :         ret = true;
     659             :      }
     660             : 
     661          60 :     FatFlowEntrySet &old_fat_flow_entry_list = fat_flow_list_.list_;
     662          60 :     const FatFlowEntrySet &new_fat_flow_entry_list =
     663             :         data->fat_flow_list_.list_;
     664          60 :     if (AuditList<FatFlowList, FatFlowEntrySet::iterator>
     665          60 :         (fat_flow_list_, old_fat_flow_entry_list.begin(),
     666             :          old_fat_flow_entry_list.end(), new_fat_flow_entry_list.begin(),
     667             :          new_fat_flow_entry_list.end())) {
     668           8 :         ret = true;
     669             :     }
     670             : 
     671          60 :     InstanceIpSet &old_ipv4_list = instance_ipv4_list_.list_;
     672          60 :     InstanceIpSet new_ipv4_list = data->instance_ipv4_list_.list_;
     673             :     //Native ip of instance should be advertised even if
     674             :     //config is not present, so manually add that entry
     675         110 :     if (nova_ip_addr_ != Ip4Address(0) &&
     676          50 :         data->vrf_name_ != Agent::NullString()) {
     677          26 :         new_ipv4_list.insert(
     678          78 :             VmInterface::InstanceIp(nova_ip_addr_, Address::kMaxV4PrefixLen,
     679          26 :                                     data->ecmp_, true, false, false, false,
     680          52 :                                     Ip4Address(0)));
     681             :     }
     682          60 :     if (AuditList<InstanceIpList, InstanceIpSet::iterator>
     683          60 :         (instance_ipv4_list_, old_ipv4_list.begin(), old_ipv4_list.end(),
     684             :          new_ipv4_list.begin(), new_ipv4_list.end())) {
     685          50 :         ret = true;
     686             :     }
     687             : 
     688          60 :     InstanceIpSet &old_ipv6_list = instance_ipv6_list_.list_;
     689          60 :     InstanceIpSet new_ipv6_list = data->instance_ipv6_list_.list_;
     690         110 :     if (nova_ip6_addr_ != Ip6Address() &&
     691          50 :             data->vrf_name_ != Agent::NullString()) {
     692          26 :         new_ipv6_list.insert(
     693          78 :             VmInterface::InstanceIp(nova_ip6_addr_, Address::kMaxV6PrefixLen,
     694          26 :                                     data->ecmp6_, true, false, false, false,
     695          52 :                                     Ip4Address(0)));
     696             :     }
     697             : 
     698          60 :     if (AuditList<InstanceIpList, InstanceIpSet::iterator>
     699          60 :         (instance_ipv6_list_, old_ipv6_list.begin(), old_ipv6_list.end(),
     700             :          new_ipv6_list.begin(), new_ipv6_list.end())) {
     701          38 :         ret = true;
     702             :     }
     703             : 
     704          60 :     BridgeDomainEntrySet &old_bd_list = bridge_domain_list_.list_;
     705          60 :     const BridgeDomainEntrySet &new_bd_list = data->bridge_domain_list_.list_;
     706          60 :     if (AuditList<BridgeDomainList, BridgeDomainEntrySet::iterator>
     707          60 :             (bridge_domain_list_, old_bd_list.begin(), old_bd_list.end(),
     708             :              new_bd_list.begin(), new_bd_list.end())) {
     709           0 :         ret = true;
     710             :     }
     711             : 
     712             : 
     713          60 :     TagEntrySet &old_tag_list = tag_list_.list_;
     714          60 :     const TagEntrySet &new_tag_list = data->tag_list_.list_;
     715          60 :     *tag_changed = AuditList<TagEntryList, TagEntrySet::iterator>(tag_list_,
     716             :                                                            old_tag_list.begin(),
     717             :                                                            old_tag_list.end(),
     718             :                                                            new_tag_list.begin(),
     719             :                                                            new_tag_list.end());
     720          60 :     if (*tag_changed) {
     721           0 :         ret = true;
     722             :     }
     723             : 
     724          60 :     VmiReceiveRouteSet &old_recv_list = receive_route_list_.list_;
     725          60 :     const VmiReceiveRouteSet &new_recv_list = data->receive_route_list_.list_;
     726          60 :     *tag_changed = AuditList<VmiReceiveRouteList,
     727          60 :                              VmiReceiveRouteSet::iterator>(receive_route_list_,
     728             :                                                            old_recv_list.begin(),
     729             :                                                            old_recv_list.end(),
     730             :                                                            new_recv_list.begin(),
     731             :                                                            new_recv_list.end());
     732          60 :     if (*tag_changed) {
     733           6 :         ret = true;
     734             :     }
     735          60 :     bool pbb_interface = new_bd_list.size() ? true: false;
     736          60 :     if (pbb_interface_ != pbb_interface) {
     737           0 :         pbb_interface_ = pbb_interface;
     738           0 :         *etree_leaf_mode_changed = true;
     739           0 :         ret = true;
     740             :     }
     741             : 
     742          60 :     if (data->addr_ != Ip4Address(0) && ecmp_ != data->ecmp_) {
     743           2 :         ecmp_ = data->ecmp_;
     744           2 :         *ecmp_changed = true;
     745             :     }
     746             : 
     747          60 :     if (!data->ip6_addr_.is_unspecified() && ecmp6_ != data->ecmp6_) {
     748           0 :         ecmp6_ = data->ecmp6_;
     749           0 :         *ecmp_changed = true;
     750             :     }
     751             : 
     752         116 :     if (service_ip_ecmp_ != data->service_ip_ecmp_ ||
     753          56 :         service_ip_ != data->service_ip_) {
     754           4 :         service_ip_ecmp_ = data->service_ip_ecmp_;
     755           4 :         service_ip_ = data->service_ip_;
     756           4 :         *ecmp_changed = true;
     757           4 :         ret = true;
     758             :     }
     759             : 
     760         117 :     if (service_ip_ecmp6_ != data->service_ip_ecmp6_ ||
     761          57 :         service_ip6_ != data->service_ip6_) {
     762           3 :         service_ip_ecmp6_ = data->service_ip_ecmp6_;
     763           3 :         service_ip6_ = data->service_ip6_;
     764           3 :         *ecmp_changed = true;
     765           3 :         ret = true;
     766             :     }
     767             : 
     768          60 :     if (data->device_type_ !=  VmInterface::DEVICE_TYPE_INVALID &&
     769          43 :         device_type_ != data->device_type_) {
     770           0 :         device_type_= data->device_type_;
     771           0 :         ret = true;
     772             :     }
     773             : 
     774          60 :     if (device_type_ == LOCAL_DEVICE || device_type_ == REMOTE_VM_VLAN_ON_VMI ||
     775          54 :         device_type_ == VM_VLAN_ON_VMI) {
     776           6 :         if (rx_vlan_id_ != data->rx_vlan_id_) {
     777           0 :             rx_vlan_id_ = data->rx_vlan_id_;
     778           0 :             ret = true;
     779             :         }
     780           6 :         if (tx_vlan_id_ != data->tx_vlan_id_) {
     781           0 :             tx_vlan_id_ = data->tx_vlan_id_;
     782           0 :             ret = true;
     783             :         }
     784             :     }
     785             : 
     786          60 :     if (hbs_intf_type_ != data->hbs_intf_type_) {
     787           0 :         hbs_intf_type_ = data->hbs_intf_type_;
     788           0 :         ret = true;
     789             :     }
     790             : 
     791          60 :     if (logical_interface_ != data->logical_interface_) {
     792           4 :         logical_interface_ = data->logical_interface_;
     793           4 :         ret = true;
     794             :     }
     795          60 :     Interface *new_parent = NULL;
     796          60 :     InterfaceList new_parent_list;
     797          60 :     if (data->physical_interface_list_.empty() == false) {
     798           3 :         std::vector<std::string>::const_iterator ptr;
     799           3 :         for (ptr = data->physical_interface_list_.begin();
     800           6 :              ptr < data->physical_interface_list_.end(); ptr++) {
     801           3 :             PhysicalInterfaceKey key(*ptr);
     802           3 :             new_parent_list.push_back(static_cast<Interface *>
     803           3 :                    (table->agent()->interface_table()->FindActiveEntry(&key)));
     804           3 :         }
     805          57 :     } else if (data->physical_interface_.empty() == false) {
     806           2 :         PhysicalInterfaceKey key(data->physical_interface_);
     807           2 :         new_parent = static_cast<Interface *>
     808           2 :             (table->agent()->interface_table()->FindActiveEntry(&key));
     809          57 :     } else if (data->parent_vmi_.is_nil() == false) {
     810           0 :         VmInterfaceKey key(AgentKey::RESYNC, data->parent_vmi_, "");
     811           0 :         new_parent = static_cast<Interface *>
     812           0 :             (table->agent()->interface_table()->FindActiveEntry(&key));
     813           0 :     } else {
     814          55 :         new_parent = parent_.get();
     815             :     }
     816             : 
     817          60 :     if (parent_list_ != new_parent_list) {
     818           6 :         parent_list_ = new_parent_list;
     819           6 :         ret = true;
     820             :     }
     821             : 
     822          60 :     if (parent_ != new_parent) {
     823           2 :         parent_ = new_parent;
     824           2 :         ret = true;
     825             :     }
     826             : 
     827          60 :     if (table) {
     828          60 :         if (os_index() == kInvalidIndex) {
     829           4 :             GetOsParams(table->agent());
     830           4 :             if (os_index() != kInvalidIndex)
     831           0 :                 ret = true;
     832             :         }
     833             :     }
     834             : 
     835          60 :     if (ecmp_load_balance_ != data->ecmp_load_balance_) {
     836          28 :         ecmp_load_balance_.Copy(data->ecmp_load_balance_);
     837          28 :         *ecmp_load_balance_changed = true;
     838          28 :         ret = true;
     839             :     }
     840             : 
     841          60 :     if (slo_list_ != data->slo_list_) {
     842           0 :         slo_list_ = data->slo_list_;
     843             :     }
     844             : 
     845          60 :     if (logical_router_uuid() != data->logical_router_uuid_) {
     846           0 :         set_logical_router_uuid(data->logical_router_uuid_);
     847           0 :         ret = true;
     848             :     }
     849          60 :     return ret;
     850          60 : }
     851             : 
     852             : /////////////////////////////////////////////////////////////////////////////
     853             : // VmInterfaceNovaData routines
     854             : /////////////////////////////////////////////////////////////////////////////
     855          12 : VmInterfaceNovaData::VmInterfaceNovaData() :
     856             :     VmInterfaceData(NULL, NULL, INSTANCE_MSG, Interface::TRANSPORT_INVALID),
     857          12 :     ipv4_addr_(),
     858          12 :     ipv6_addr_(),
     859          12 :     mac_addr_(),
     860          12 :     vm_name_(),
     861          12 :     vm_uuid_(),
     862          12 :     vm_project_uuid_(),
     863          12 :     physical_interface_(),
     864          12 :     tx_vlan_id_(),
     865          12 :     rx_vlan_id_(),
     866          12 :     vhostuser_mode_() {
     867          12 : }
     868             : 
     869          12 : VmInterfaceNovaData::VmInterfaceNovaData(const Ip4Address &ipv4_addr,
     870             :                                          const Ip6Address &ipv6_addr,
     871             :                                          const std::string &mac_addr,
     872             :                                          const std::string vm_name,
     873             :                                          boost::uuids::uuid vm_uuid,
     874             :                                          boost::uuids::uuid vm_project_uuid,
     875             :                                          const std::string &physical_interface,
     876             :                                          uint16_t tx_vlan_id,
     877             :                                          uint16_t rx_vlan_id,
     878             :                                          VmInterface::DeviceType device_type,
     879             :                                          VmInterface::VmiType vmi_type,
     880             :                                          uint8_t vhostuser_mode,
     881             :                                          Interface::Transport transport,
     882          12 :                                          uint8_t link_state) :
     883             :     VmInterfaceData(NULL, NULL, INSTANCE_MSG, transport),
     884          12 :     ipv4_addr_(ipv4_addr),
     885          12 :     ipv6_addr_(ipv6_addr),
     886          12 :     mac_addr_(mac_addr),
     887          12 :     vm_name_(vm_name),
     888          12 :     vm_uuid_(vm_uuid),
     889          12 :     vm_project_uuid_(vm_project_uuid),
     890          12 :     physical_interface_(physical_interface),
     891          12 :     tx_vlan_id_(tx_vlan_id),
     892          12 :     rx_vlan_id_(rx_vlan_id),
     893          12 :     device_type_(device_type),
     894          12 :     vmi_type_(vmi_type),
     895          12 :     vhostuser_mode_(vhostuser_mode), link_state_(link_state) {
     896          12 : }
     897             : 
     898          48 : VmInterfaceNovaData::~VmInterfaceNovaData() {
     899          48 : }
     900             : 
     901          12 : VmInterface *VmInterfaceNovaData::OnAdd(const InterfaceTable *table,
     902             :                                         const VmInterfaceKey *key) const {
     903          12 :     Interface *parent = NULL;
     904          24 :     if (tx_vlan_id_ != VmInterface::kInvalidVlanId &&
     905          12 :         rx_vlan_id_ != VmInterface::kInvalidVlanId &&
     906           0 :         physical_interface_ != Agent::NullString()) {
     907           0 :         PhysicalInterfaceKey key_1(physical_interface_);
     908           0 :         parent = static_cast<Interface *>
     909           0 :             (table->agent()->interface_table()->FindActiveEntry(&key_1));
     910           0 :         assert(parent != NULL);
     911           0 :     }
     912             : 
     913          12 :     boost::system::error_code ec;
     914          12 :     MacAddress mac = MacAddress::FromString(mac_addr_, &ec);
     915          12 :     if (ec.value() != 0) {
     916           0 :         mac.Zero();
     917             :     }
     918             : 
     919             :     /* OS oper state is passed by PortIpc module (VmiSubscribeEntry) which
     920             :      * invokes NovaAdd in case of vmware */
     921          12 :     bool os_oper_state = link_state_;
     922             :     VmInterface *vmi =
     923          12 :         new VmInterface(key->uuid_, key->name_, ipv4_addr_, mac, vm_name_,
     924          12 :                         vm_project_uuid_, tx_vlan_id_, rx_vlan_id_,
     925          12 :                         parent, ipv6_addr_, device_type_, vmi_type_,
     926          12 :                         vhostuser_mode_, os_oper_state, logical_router_uuid_);
     927          12 :     vmi->SetConfigurer(VmInterface::INSTANCE_MSG);
     928          12 :     vmi->nova_ip_addr_ = ipv4_addr_;
     929          12 :     vmi->nova_ip6_addr_ = ipv6_addr_;
     930             : 
     931          12 :     return vmi;
     932             : }
     933             : 
     934          12 : bool VmInterfaceNovaData::OnDelete(const InterfaceTable *table,
     935             :                                    VmInterface *vmi) const {
     936          12 :     if (vmi->IsConfigurerSet(VmInterface::INSTANCE_MSG) == false)
     937           0 :         return true;
     938             : 
     939          12 :     VmInterfaceConfigData data(NULL, NULL);
     940          12 :     vmi->Resync(table, &data);
     941          12 :     vmi->ResetConfigurer(VmInterface::CONFIG);
     942          12 :     vmi->ResetConfigurer(VmInterface::INSTANCE_MSG);
     943          12 :     table->operdb()->bgp_as_a_service()->DeleteVmInterface(vmi->GetUuid());
     944          12 :     table->agent()->interface_table()->DelPhysicalDeviceVnEntry(vmi->GetUuid());
     945          12 :     return true;
     946          12 : }
     947             : 
     948           0 : bool VmInterfaceNovaData::OnResync(const InterfaceTable *table,
     949             :                                    VmInterface *vmi,
     950             :                                    bool *force_update) const {
     951           0 :     bool ret = false;
     952             : 
     953           0 :     if (vmi->vm_project_uuid_ != vm_project_uuid_) {
     954           0 :         vmi->vm_project_uuid_ = vm_project_uuid_;
     955           0 :         ret = true;
     956             :     }
     957             : 
     958           0 :     if (vmi->tx_vlan_id_ != tx_vlan_id_) {
     959           0 :         vmi->tx_vlan_id_ = tx_vlan_id_;
     960           0 :         ret = true;
     961             :     }
     962             : 
     963           0 :     if (vmi->rx_vlan_id_ != rx_vlan_id_) {
     964           0 :         vmi->rx_vlan_id_ = rx_vlan_id_;
     965           0 :         ret = true;
     966             :     }
     967             : 
     968           0 :     if (vmi->nova_ip_addr_ != ipv4_addr_) {
     969           0 :         vmi->nova_ip_addr_ = ipv4_addr_;
     970           0 :         ret = true;
     971             :     }
     972             : 
     973           0 :     if (vmi->nova_ip6_addr_ != ipv6_addr_) {
     974           0 :         vmi->nova_ip6_addr_ = ipv6_addr_;
     975           0 :         ret = true;
     976             :     }
     977             : 
     978           0 :     vmi->SetConfigurer(VmInterface::INSTANCE_MSG);
     979             : 
     980           0 :     return ret;
     981             : }
     982             : 
     983             : // Add a VM-Interface
     984          12 : void VmInterface::NovaAdd(InterfaceTable *table, const uuid &intf_uuid,
     985             :                           const string &os_name, const Ip4Address &addr,
     986             :                           const string &mac, const string &vm_name,
     987             :                           const uuid &vm_project_uuid, uint16_t tx_vlan_id,
     988             :                           uint16_t rx_vlan_id, const std::string &parent,
     989             :                           const Ip6Address &ip6,
     990             :                           uint8_t vhostuser_mode,
     991             :                           Interface::Transport transport,
     992             :                           uint8_t link_state) {
     993          12 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     994          12 :     req.key.reset(new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, intf_uuid,
     995          12 :                                      os_name));
     996             : 
     997          24 :     req.data.reset(new VmInterfaceNovaData(addr, ip6, mac, vm_name,
     998          24 :                                            nil_uuid(), vm_project_uuid, parent,
     999             :                                            tx_vlan_id, rx_vlan_id,
    1000             :                                            VmInterface::VM_ON_TAP,
    1001             :                                            VmInterface::INSTANCE,
    1002             :                                            vhostuser_mode,
    1003          12 :                                            transport, link_state));
    1004          12 :     table->Enqueue(&req);
    1005          12 : }
    1006             : 
    1007             : // Delete a VM-Interface
    1008          14 : void VmInterface::Delete(InterfaceTable *table, const uuid &intf_uuid,
    1009             :                          VmInterface::Configurer configurer) {
    1010          14 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
    1011          14 :     req.key.reset(new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, intf_uuid, ""));
    1012             : 
    1013          14 :     if (configurer == VmInterface::CONFIG) {
    1014           2 :         req.data.reset(new VmInterfaceConfigData(NULL, NULL));
    1015          12 :     } else if (configurer == VmInterface::INSTANCE_MSG) {
    1016          12 :         req.data.reset(new VmInterfaceNovaData());
    1017             :     } else {
    1018           0 :         assert(0);
    1019             :     }
    1020          14 :     table->Enqueue(&req);
    1021          14 : }
    1022             : 
    1023             : /////////////////////////////////////////////////////////////////////////////
    1024             : // VmInterfaceMirrorData routines
    1025             : /////////////////////////////////////////////////////////////////////////////
    1026           0 : bool VmInterfaceMirrorData::OnResync(const InterfaceTable *table,
    1027             :                                      VmInterface *vmi,
    1028             :                                      bool *force_update) const {
    1029           0 :     bool ret = false;
    1030             : 
    1031           0 :     MirrorEntry *mirror_entry = NULL;
    1032           0 :     if (mirror_enable_ == true) {
    1033           0 :         mirror_entry = table->FindMirrorRef(analyzer_name_);
    1034             :     }
    1035             : 
    1036           0 :     if (vmi->mirror_entry_ != mirror_entry) {
    1037           0 :         vmi->mirror_entry_ = mirror_entry;
    1038           0 :         ret = true;
    1039             :     }
    1040             : 
    1041           0 :     return ret;
    1042             : }
    1043             : 
    1044             : /////////////////////////////////////////////////////////////////////////////
    1045             : // VmInterfaceIpAddressData routines
    1046             : /////////////////////////////////////////////////////////////////////////////
    1047             : // Update for VM IP address only
    1048             : // For interfaces in IP Fabric VRF, we send DHCP requests to external servers
    1049             : // if config doesnt provide an address. This address is updated here.
    1050           0 : bool VmInterfaceIpAddressData::OnResync(const InterfaceTable *table,
    1051             :                                         VmInterface *vmi,
    1052             :                                         bool *force_update) const {
    1053           0 :     bool ret = false;
    1054             : 
    1055           0 :     if (vmi->os_index() == VmInterface::kInvalidIndex) {
    1056           0 :         vmi->GetOsParams(table->agent());
    1057           0 :         if (vmi->os_index() != VmInterface::kInvalidIndex)
    1058           0 :             ret = true;
    1059             :     }
    1060             : 
    1061             :     // Ignore IP address change if L3 Forwarding not enabled
    1062           0 :     if (!vmi->layer3_forwarding_) {
    1063           0 :         return ret;
    1064             :     }
    1065             : 
    1066           0 :     Ip4Address addr = Ip4Address(0);
    1067           0 :     if (vmi->CopyIpAddress(addr)) {
    1068           0 :         ret = true;
    1069             :     }
    1070             : 
    1071           0 :     return ret;
    1072             : }
    1073             : 
    1074             : /////////////////////////////////////////////////////////////////////////////
    1075             : // VmInterfaceOsOperStateData routines
    1076             : /////////////////////////////////////////////////////////////////////////////
    1077             : // Resync oper-state for the interface
    1078           0 : bool VmInterfaceOsOperStateData::OnResync(const InterfaceTable *table,
    1079             :                                           VmInterface *vmi,
    1080             :                                           bool *force_update) const {
    1081           0 :     bool ret = false;
    1082           0 :     Agent *agent = table->agent();
    1083             : 
    1084           0 :     uint32_t old_os_index = vmi->os_index();
    1085           0 :     bool old_ipv4_active = vmi->ipv4_active_;
    1086           0 :     bool old_ipv6_active = vmi->ipv6_active_;
    1087             : 
    1088           0 :     vmi->GetOsParams(agent);
    1089             :     /* In DPDK mode (where we have interfaces of type TRANSPORT_PMD), oper_state
    1090             :      * is updated based on Netlink notification received from vrouter */
    1091           0 :     if ((vmi->transport_ == Interface::TRANSPORT_PMD) ||
    1092           0 :         vmi->NeedDefaultOsOperStateDisabled(agent)) {
    1093           0 :         if (vmi->os_params_.os_oper_state_ != oper_state_) {
    1094           0 :             vmi->os_params_.os_oper_state_ = oper_state_;
    1095           0 :             ret = true;
    1096             :         }
    1097             :     }
    1098           0 :     if (vmi->os_index() != old_os_index)
    1099           0 :         ret = true;
    1100             : 
    1101           0 :     vmi->ipv4_active_ = vmi->IsIpv4Active();
    1102           0 :     if (vmi->ipv4_active_ != old_ipv4_active)
    1103           0 :         ret = true;
    1104             : 
    1105           0 :     vmi->ipv6_active_ = vmi->IsIpv6Active();
    1106           0 :     if (vmi->ipv6_active_ != old_ipv6_active)
    1107           0 :         ret = true;
    1108             :     // Update the Oper data for SubInterfaces if attached to parent interface.
    1109           0 :     if (ret == true)
    1110           0 :         vmi->UpdateOperStateOfSubIntf(table);
    1111             : 
    1112           0 :     return ret;
    1113             : }
    1114             : 
    1115             : /////////////////////////////////////////////////////////////////////////////
    1116             : // Global VRouter config update
    1117             : /////////////////////////////////////////////////////////////////////////////
    1118           0 : bool VmInterfaceGlobalVrouterData::OnResync(const InterfaceTable *table,
    1119             :                                             VmInterface *vmi,
    1120             :                                             bool *force_update) const {
    1121           0 :     bool ret = false;
    1122             : 
    1123           0 :     if (layer3_forwarding_ != vmi->layer3_forwarding_) {
    1124           0 :         vmi->layer3_forwarding_ = layer3_forwarding_;
    1125           0 :         *force_update = true;
    1126           0 :         ret = true;
    1127             :     }
    1128             : 
    1129           0 :     if (bridging_ != vmi->bridging_) {
    1130           0 :         vmi->bridging_= bridging_;
    1131           0 :         *force_update = true;
    1132           0 :         ret = true;
    1133             :     }
    1134             : 
    1135           0 :     if (vxlan_id_ != vmi->vxlan_id_)
    1136           0 :         ret = true;
    1137             : 
    1138           0 :     if (vmi->ecmp_load_balance().use_global_vrouter()) {
    1139           0 :         *force_update = true;
    1140           0 :         ret = true;
    1141             :     }
    1142             : 
    1143           0 :     return ret;
    1144             : }
    1145             : 
    1146             : /////////////////////////////////////////////////////////////////////////////
    1147             : // Health Check update
    1148             : /////////////////////////////////////////////////////////////////////////////
    1149           0 : VmInterfaceHealthCheckData::VmInterfaceHealthCheckData() :
    1150           0 :     VmInterfaceData(NULL, NULL, HEALTH_CHECK, Interface::TRANSPORT_INVALID) {
    1151           0 : }
    1152             : 
    1153           0 : VmInterfaceHealthCheckData::~VmInterfaceHealthCheckData() {
    1154           0 : }
    1155             : 
    1156           0 : bool VmInterfaceHealthCheckData::OnResync(const InterfaceTable *table,
    1157             :                                           VmInterface *vmi,
    1158             :                                           bool *force_update) const {
    1159           0 :     return vmi->UpdateIsHealthCheckActive();
    1160             : }
    1161             : 
    1162           0 : VmInterfaceNewFlowDropData::VmInterfaceNewFlowDropData(bool drop_new_flows) :
    1163             :     VmInterfaceData(NULL, NULL, DROP_NEW_FLOWS, Interface::TRANSPORT_INVALID),
    1164           0 :     drop_new_flows_(drop_new_flows) {
    1165           0 : }
    1166             : 
    1167           0 : VmInterfaceNewFlowDropData::~VmInterfaceNewFlowDropData() {
    1168           0 : }
    1169             : 
    1170           0 : bool VmInterfaceNewFlowDropData::OnResync(const InterfaceTable *table,
    1171             :                                           VmInterface *vmi,
    1172             :                                           bool *force_update) const {
    1173           0 :     if (vmi->drop_new_flows_ != drop_new_flows_) {
    1174           0 :         vmi->drop_new_flows_ = drop_new_flows_;
    1175           0 :         return true;
    1176             :     }
    1177             : 
    1178           0 :     return false;
    1179             : }
    1180             : 
    1181           0 : bool VmInterface::UpdateIsHealthCheckActive() {
    1182           0 :     bool is_hc_active = true;
    1183           0 :     HealthCheckInstanceSet::iterator it = hc_instance_set_.begin();
    1184           0 :     while (it != hc_instance_set_.end()) {
    1185           0 :         if ((*it)->active() == false) {
    1186             :             // if any of the health check instance reports not active
    1187             :             // status mark interface health check status inactive
    1188           0 :             is_hc_active = false;
    1189           0 :             break;
    1190             :         }
    1191           0 :         it++;
    1192             :     }
    1193             : 
    1194           0 :     if (is_hc_active_ != is_hc_active) {
    1195           0 :         is_hc_active_ = is_hc_active;
    1196           0 :         return true;
    1197             :     }
    1198           0 :     return false;
    1199             : }
    1200             : 
    1201             : /////////////////////////////////////////////////////////////////////////////
    1202             : // VmInterfaceIfNameData routines
    1203             : // The request is used to add/delete interface with only ifname as data
    1204             : /////////////////////////////////////////////////////////////////////////////
    1205           0 : VmInterfaceIfNameData::VmInterfaceIfNameData() :
    1206             :     VmInterfaceData(NULL, NULL, INSTANCE_MSG, Interface::TRANSPORT_INVALID),
    1207           0 :     ifname_() {
    1208           0 : }
    1209             : 
    1210           0 : VmInterfaceIfNameData::VmInterfaceIfNameData
    1211           0 : (const std::string &ifname):
    1212             :     VmInterfaceData(NULL, NULL, INSTANCE_MSG, Interface::TRANSPORT_ETHERNET),
    1213           0 :     ifname_(ifname) {
    1214           0 : }
    1215             : 
    1216           0 : VmInterfaceIfNameData::~VmInterfaceIfNameData() {
    1217           0 : }
    1218             : 
    1219           0 : VmInterface *VmInterfaceIfNameData::OnAdd(const InterfaceTable *table,
    1220             :                                           const VmInterfaceKey *key) const {
    1221           0 :     Agent *agent = table->agent();
    1222             :     /* OS oper state is disabled by default in Vmware mode */
    1223           0 :     bool os_oper_state = !agent->isVmwareMode();
    1224             :     VmInterface *vmi =
    1225           0 :         new VmInterface(key->uuid_, key->name_, Ip4Address(), MacAddress(), "",
    1226           0 :                         nil_uuid(), VmInterface::kInvalidVlanId,
    1227           0 :                         VmInterface::kInvalidVlanId, NULL, Ip6Address(),
    1228             :                         VmInterface::VM_ON_TAP, VmInterface::INSTANCE,
    1229             :                         VmInterface::vHostUserClient, os_oper_state,
    1230           0 :                         logical_router_uuid_);
    1231           0 :     vmi->SetConfigurer(VmInterface::INSTANCE_MSG);
    1232           0 :     return vmi;
    1233             : }
    1234             : 
    1235           0 : bool VmInterfaceIfNameData::OnDelete(const InterfaceTable *table,
    1236             :                                      VmInterface *vmi) const {
    1237           0 :     if (vmi->IsConfigurerSet(VmInterface::INSTANCE_MSG) == false)
    1238           0 :         return true;
    1239             : 
    1240           0 :     VmInterfaceConfigData data(NULL, NULL);
    1241           0 :     vmi->Resync(table, &data);
    1242           0 :     vmi->ResetConfigurer(VmInterface::CONFIG);
    1243           0 :     vmi->ResetConfigurer(VmInterface::INSTANCE_MSG);
    1244           0 :     table->operdb()->bgp_as_a_service()->DeleteVmInterface(vmi->GetUuid());
    1245           0 :     table->agent()->interface_table()->DelPhysicalDeviceVnEntry(vmi->GetUuid());
    1246           0 :     return true;
    1247           0 : }
    1248             : 
    1249           0 : bool VmInterfaceIfNameData::OnResync(const InterfaceTable *table,
    1250             :                                    VmInterface *vmi,
    1251             :                                    bool *force_update) const {
    1252           0 :     bool ret = false;
    1253           0 :     vmi->SetConfigurer(VmInterface::INSTANCE_MSG);
    1254           0 :     return ret;
    1255             : }
    1256           0 : VmInterfaceLearntMacIpData::VmInterfaceLearntMacIpData() :
    1257             :     VmInterfaceData(NULL, NULL, HEALTH_CHECK, Interface::TRANSPORT_INVALID),
    1258           0 :     is_add(true), mac_ip_list_() {
    1259           0 : }
    1260           0 : VmInterfaceLearntMacIpData::~VmInterfaceLearntMacIpData() {}
    1261             : 
    1262           0 : bool VmInterface::copyMacIpData(const VmInterfaceLearntMacIpData *data) {
    1263           0 :     LearntMacIpSet::iterator it = data->mac_ip_list_.list_.begin();
    1264           0 :     while (it != data->mac_ip_list_.list_.end()) {
    1265           0 :         if (data->is_add) {
    1266           0 :             learnt_mac_ip_list_.Insert(it.operator->());
    1267             :         } else {
    1268           0 :             learnt_mac_ip_list_.Remove(it.operator->());
    1269             :         }
    1270           0 :         it++;
    1271             :     }
    1272           0 :     return true;
    1273             : }
    1274           0 : bool VmInterfaceLearntMacIpData::OnResync(const InterfaceTable *table,
    1275             :                                     VmInterface *vmi,
    1276             :                                     bool *force_update) const {
    1277           0 :     return vmi->copyMacIpData(this);
    1278             : }
    1279             : 
    1280             : // Utility methods to enqueue add/delete requests
    1281           0 : void VmInterface::SetIfNameReq(InterfaceTable *table, const uuid &uuid,
    1282             :                                const string &ifname) {
    1283           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
    1284           0 :     req.key.reset(new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, uuid,
    1285           0 :                                      ifname));
    1286             : 
    1287           0 :     req.data.reset(new VmInterfaceIfNameData(ifname));
    1288           0 :     table->Enqueue(&req);
    1289           0 : }
    1290             : 
    1291           0 : void VmInterface::DeleteIfNameReq(InterfaceTable *table, const uuid &uuid) {
    1292           0 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
    1293           0 :     req.key.reset(new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, uuid, ""));
    1294           0 :     req.data.reset(new VmInterfaceIfNameData());
    1295           0 :     table->Enqueue(&req);
    1296           0 : }
    1297             : 
    1298             : /////////////////////////////////////////////////////////////////////////////
    1299             : // QoS Config change - used from introspect
    1300             : /////////////////////////////////////////////////////////////////////////////
    1301           0 : void AddVmiQosConfig::HandleRequest() const {
    1302           0 :     QosResponse *resp = new QosResponse();
    1303           0 :     resp->set_context(context());
    1304             : 
    1305           0 :     boost::uuids::uuid vmi_uuid = StringToUuid(std::string(get_vmi_uuid()));
    1306             :     boost::uuids::uuid qos_config_uuid =
    1307           0 :         StringToUuid(std::string(get_qos_config_uuid()));
    1308           0 :     DBTable *table = Agent::GetInstance()->interface_table();
    1309             : 
    1310           0 :     DBRequest req;
    1311           0 :     req.oper =  DBRequest::DB_ENTRY_ADD_CHANGE;
    1312           0 :     req.key.reset(new VmInterfaceKey(AgentKey::RESYNC, vmi_uuid, ""));
    1313           0 :     req.data.reset(new InterfaceQosConfigData(NULL, NULL, qos_config_uuid));
    1314           0 :     table->Enqueue(&req);
    1315           0 :     resp->set_resp("Success");
    1316           0 :     resp->Response();
    1317           0 : }

Generated by: LCOV version 1.14