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

Generated by: LCOV version 1.14