LCOV - code coverage report
Current view: top level - vnsw/agent/oper - vm_interface_config.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 439 1134 38.7 %
Date: 2026-08-03 02:19:58 Functions: 31 48 64.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : #include <bgp_schema_types.h>
       5             : #include <base/address_util.h>
       6             : 
       7             : #include <cmn/agent_cmn.h>
       8             : #include <cfg/cfg_init.h>
       9             : #include <oper/bridge_domain.h>
      10             : #include <oper/config_manager.h>
      11             : #include <oper/interface_common.h>
      12             : #include <oper/mirror_table.h>
      13             : #include <oper/sg.h>
      14             : #include <oper/tag.h>
      15             : #include <oper/bgp_as_service.h>
      16             : #include <init/agent_param.h>
      17             : #include "ifmap/ifmap_link.h"
      18             : 
      19             : #include <port_ipc/port_ipc_handler.h>
      20             : #include <port_ipc/port_subscribe_table.h>
      21             : 
      22             : #define LOGICAL_ROUTER_NAME "logical-router"
      23             : #define VIRTUAL_PORT_GROUP_CONFIG_NAME "virtual-port-group"
      24             : 
      25             : #define VMI_NETWORK_ROUTER_INTERFACE "network:router_interface"
      26             : 
      27             : using namespace std;
      28             : using namespace boost::uuids;
      29             : using namespace autogen;
      30             : 
      31           0 : static void AddFabricFloatingIp(Agent *agent, VmInterfaceConfigData *data,
      32             :                                 IpAddress src_ip) {
      33           0 :     if (agent->fabric_vn_uuid() == nil_uuid()) {
      34           0 :         return;
      35             :     }
      36             : 
      37           0 :     VmInterface::FloatingIp::PortMap src_port_map;
      38           0 :     VmInterface::FloatingIp::PortMap dst_port_map;
      39             :     data->floating_ip_list_.list_.insert
      40           0 :         (VmInterface::FloatingIp(agent->router_id(),
      41             :                                  agent->fabric_policy_vrf_name(),
      42             :                                  agent->fabric_vn_uuid(), src_ip,
      43             :                                  VmInterface::FloatingIp::DIRECTION_EGRESS,
      44             :                                  false, src_port_map, dst_port_map, true));
      45           0 : }
      46             : 
      47             : // Build one VN and VRF for a floating-ip. Can reach here from 2 paths,
      48             : // 1. floating-ip <-> floating-ip-pool <-> virtual-network <-> routing-instance
      49             : // 2. floating-ip <-> instance-ip <-> virtual-network <-> routing-instance
      50           0 : static bool BuildFloatingIpVnVrf(Agent *agent, VmInterfaceConfigData *data,
      51             :                                  IFMapNode *node, IFMapNode *vn_node) {
      52           0 :     ConfigManager *cfg_manager= agent->config_manager();
      53           0 :     if (cfg_manager->SkipNode(vn_node, agent->cfg()->cfg_vn_table())) {
      54           0 :         return false;
      55             :     }
      56             : 
      57           0 :     VirtualNetwork *cfg = static_cast<VirtualNetwork *>(vn_node->GetObject());
      58           0 :     assert(cfg);
      59           0 :     autogen::IdPermsType id_perms = cfg->id_perms();
      60             :     boost::uuids::uuid vn_uuid;
      61           0 :     CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, vn_uuid);
      62             : 
      63             :     IFMapAgentTable *vn_table = static_cast<IFMapAgentTable *>
      64           0 :         (vn_node->table());
      65           0 :     DBGraph *vn_graph = vn_table->GetGraph();
      66             :     // Iterate thru links for virtual-network looking for routing-instance
      67           0 :     for (DBGraphVertex::adjacency_iterator vn_iter = vn_node->begin(vn_graph);
      68           0 :          vn_iter != vn_node->end(vn_graph); ++vn_iter) {
      69             : 
      70           0 :         IFMapNode *vrf_node = static_cast<IFMapNode *>(vn_iter.operator->());
      71           0 :         if (cfg_manager->SkipNode(vrf_node, agent->cfg()->cfg_vrf_table())) {
      72           0 :             continue;
      73             :         }
      74             :         // We are interested only in default-vrf
      75             :         RoutingInstance *ri = static_cast<RoutingInstance *>
      76           0 :             (vrf_node->GetObject());
      77           0 :         if(!(ri->is_default())) {
      78           0 :             continue;
      79             :         }
      80           0 :         FloatingIp *fip = static_cast<FloatingIp *>(node->GetObject());
      81           0 :         assert(fip != NULL);
      82             : 
      83           0 :         boost::system::error_code ec;
      84           0 :         IpAddress addr = IpAddress::from_string(fip->address(), ec);
      85           0 :         if (ec.value() != 0) {
      86           0 :             LOG(ERROR, "Error decoding Floating IP address " << fip->address());
      87           0 :             OPER_TRACE_ENTRY(Trace, agent->interface_table(),
      88             :                              "Error decoding Floating IP address " +
      89             :                              fip->address());
      90             :         } else {
      91             :             IpAddress fixed_ip_addr =
      92           0 :                 IpAddress::from_string(fip->fixed_ip_address(), ec);
      93           0 :             if (ec.value() != 0) {
      94           0 :                 fixed_ip_addr = IpAddress();
      95             :             }
      96           0 :             if (!fixed_ip_addr.is_unspecified()) {
      97           0 :                 if ((addr.is_v4() && !fixed_ip_addr.is_v4()) ||
      98           0 :                     (addr.is_v6() && !fixed_ip_addr.is_v6())) {
      99           0 :                     string msg = "Invalid fixed-ip " + fip->fixed_ip_address() +
     100           0 :                                  " for FloatingIP " + fip->address();
     101           0 :                     LOG(ERROR, msg);
     102           0 :                     OPER_TRACE_ENTRY(Trace, agent->interface_table(), msg);
     103             : 
     104           0 :                     return true;
     105           0 :                 }
     106             :             }
     107             : 
     108           0 :             if (ri->fabric_snat()) {
     109           0 :                 AddFabricFloatingIp(agent, data, fixed_ip_addr);
     110             :             }
     111             : 
     112           0 :             VmInterface::FloatingIp::Direction dir =
     113             :                 VmInterface::FloatingIp::DIRECTION_BOTH;
     114             :             // Get direction
     115           0 :             if (boost::iequals(fip->traffic_direction(), "ingress"))
     116           0 :                 dir = VmInterface::FloatingIp::DIRECTION_INGRESS;
     117           0 :             else if (boost::iequals(fip->traffic_direction(), "egress"))
     118           0 :                 dir = VmInterface::FloatingIp::DIRECTION_EGRESS;
     119             : 
     120             :             // Make port-map
     121           0 :             VmInterface::FloatingIp::PortMap src_port_map;
     122           0 :             VmInterface::FloatingIp::PortMap dst_port_map;
     123           0 :             for (PortMappings::const_iterator it = fip->port_mappings().begin();
     124           0 :                  it != fip->port_mappings().end(); it++) {
     125           0 :                 uint16_t protocol = Agent::ProtocolStringToInt(it->protocol);
     126             :                 VmInterface::FloatingIp::PortMapKey dst(protocol,
     127           0 :                                                         it->src_port);
     128           0 :                 dst_port_map.insert(std::make_pair(dst, it->dst_port));
     129             :                 VmInterface::FloatingIp::PortMapKey src(protocol,
     130           0 :                                                         it->dst_port);
     131           0 :                 src_port_map.insert(std::make_pair(src, it->src_port));
     132           0 :             }
     133             :             data->floating_ip_list_.list_.insert
     134           0 :                 (VmInterface::FloatingIp (addr, vrf_node->name(), vn_uuid,
     135             :                                           fixed_ip_addr, dir,
     136           0 :                                           fip->port_mappings_enable(),
     137             :                                           src_port_map,
     138             :                                           dst_port_map, false));
     139           0 :             if (addr.is_v4()) {
     140           0 :                 data->floating_ip_list_.v4_count_++;
     141             :             } else {
     142           0 :                 data->floating_ip_list_.v6_count_++;
     143             :             }
     144           0 :         }
     145           0 :         return true;
     146             :     }
     147           0 :     return false;
     148           0 : }
     149             : 
     150             : // Build one Floating IP entry for a virtual-machine-interface
     151           0 : static void BuildFloatingIpList(Agent *agent, VmInterfaceConfigData *data,
     152             :                                 IFMapNode *node) {
     153           0 :     ConfigManager *cfg_manager= agent->config_manager();
     154           0 :     if (cfg_manager->SkipNode(node)) {
     155           0 :         return;
     156             :     }
     157             : 
     158             :     // Find VRF for the floating-ip. Following paths leads to VRF
     159             :     // 1. virtual-machine-port <-> floating-ip <-> floating-ip-pool
     160             :     //    <-> virtual-network <-> routing-instance
     161             :     // 2. virtual-machine-port <-> floating-ip <-> instance-ip
     162             :     //    <-> virtual-network <-> routing-instance
     163           0 :     IFMapAgentTable *fip_table = static_cast<IFMapAgentTable *>(node->table());
     164           0 :     DBGraph *fip_graph = fip_table->GetGraph();
     165             : 
     166             :     // Iterate thru links for floating-ip looking for floating-ip-pool or
     167             :     // instance-ip node
     168           0 :     for (DBGraphVertex::adjacency_iterator fip_iter = node->begin(fip_graph);
     169           0 :          fip_iter != node->end(fip_graph); ++fip_iter) {
     170           0 :         IFMapNode *node1 = static_cast<IFMapNode *>(fip_iter.operator->());
     171           0 :         if (cfg_manager->SkipNode(node1)) {
     172           0 :             continue;
     173             :         }
     174             :         IFMapAgentTable *table1 =
     175           0 :             static_cast<IFMapAgentTable *> (node1->table());
     176             : 
     177             :         // We are interested in floating-ip-pool or instance-ip neighbours
     178           0 :         if (table1 == agent->cfg()->cfg_floatingip_pool_table() ||
     179           0 :             table1 == agent->cfg()->cfg_instanceip_table()) {
     180             :             // Iterate thru links for floating-ip-pool/instance-ip looking for
     181             :             // virtual-network and routing-instance
     182           0 :             DBGraph *pool_graph = table1->GetGraph();
     183           0 :             for (DBGraphVertex::adjacency_iterator node1_iter =
     184           0 :                  node1->begin(pool_graph);
     185           0 :                  node1_iter != node1->end(pool_graph); ++node1_iter) {
     186             : 
     187             :                 IFMapNode *vn_node =
     188           0 :                     static_cast<IFMapNode *>(node1_iter.operator->());
     189           0 :                 if (BuildFloatingIpVnVrf(agent, data, node, vn_node) == true)
     190           0 :                     break;
     191             :             }
     192           0 :             break;
     193             :         }
     194             :     }
     195           0 :     return;
     196             : }
     197             : 
     198             : // Build one Alias IP entry for a virtual-machine-interface
     199           0 : static void BuildAliasIpList(InterfaceTable *intf_table,
     200             :                              VmInterfaceConfigData *data,
     201             :                              IFMapNode *node) {
     202           0 :     Agent *agent = intf_table->agent();
     203           0 :     ConfigManager *cfg_manager= agent->config_manager();
     204           0 :     if (cfg_manager->SkipNode(node)) {
     205           0 :         return;
     206             :     }
     207             : 
     208             :     // Find VRF for the alias-ip. Following path in graphs leads to VRF
     209             :     // virtual-machine-port <-> alias-ip <-> alias-ip-pool
     210             :     // <-> virtual-network <-> routing-instance
     211           0 :     IFMapAgentTable *aip_table = static_cast<IFMapAgentTable *>(node->table());
     212           0 :     DBGraph *aip_graph = aip_table->GetGraph();
     213             : 
     214             :     // Iterate thru links for alias-ip looking for alias-ip-pool node
     215           0 :     for (DBGraphVertex::adjacency_iterator aip_iter = node->begin(aip_graph);
     216           0 :          aip_iter != node->end(aip_graph); ++aip_iter) {
     217           0 :         IFMapNode *pool_node = static_cast<IFMapNode *>(aip_iter.operator->());
     218           0 :         if (cfg_manager->SkipNode
     219           0 :             (pool_node, agent->cfg()->cfg_aliasip_pool_table())) {
     220           0 :             continue;
     221             :         }
     222             : 
     223             :         // Iterate thru links for alias-ip-pool looking for virtual-network
     224             :         IFMapAgentTable *pool_table =
     225           0 :             static_cast<IFMapAgentTable *> (pool_node->table());
     226           0 :         DBGraph *pool_graph = pool_table->GetGraph();
     227           0 :         for (DBGraphVertex::adjacency_iterator pool_iter =
     228           0 :              pool_node->begin(pool_graph);
     229           0 :              pool_iter != pool_node->end(pool_graph); ++pool_iter) {
     230             : 
     231             :             IFMapNode *vn_node =
     232           0 :                 static_cast<IFMapNode *>(pool_iter.operator->());
     233           0 :             if (cfg_manager->SkipNode
     234           0 :                 (vn_node, agent->cfg()->cfg_vn_table())) {
     235           0 :                 continue;
     236             :             }
     237             : 
     238             :             VirtualNetwork *cfg = static_cast <VirtualNetwork *>
     239           0 :                 (vn_node->GetObject());
     240           0 :             assert(cfg);
     241           0 :             autogen::IdPermsType id_perms = cfg->id_perms();
     242             :             boost::uuids::uuid vn_uuid;
     243           0 :             CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
     244             :                        vn_uuid);
     245             : 
     246             :             IFMapAgentTable *vn_table =
     247           0 :                 static_cast<IFMapAgentTable *> (vn_node->table());
     248           0 :             DBGraph *vn_graph = vn_table->GetGraph();
     249             :             // Iterate thru links for virtual-network looking for
     250             :             // routing-instance
     251           0 :             for (DBGraphVertex::adjacency_iterator vn_iter =
     252           0 :                  vn_node->begin(vn_graph);
     253           0 :                  vn_iter != vn_node->end(vn_graph); ++vn_iter) {
     254             : 
     255             :                 IFMapNode *vrf_node =
     256           0 :                     static_cast<IFMapNode *>(vn_iter.operator->());
     257           0 :                 if (cfg_manager->SkipNode
     258           0 :                     (vrf_node, agent->cfg()->cfg_vrf_table())){
     259           0 :                     continue;
     260             :                 }
     261             :                 // Checking whether it is default vrf of not
     262             :                 RoutingInstance *ri =
     263           0 :                     static_cast<RoutingInstance *>(vrf_node->GetObject());
     264           0 :                 if(!(ri->is_default())) {
     265           0 :                     continue;
     266             :                 }
     267           0 :                 AliasIp *aip = static_cast<AliasIp *>(node->GetObject());
     268           0 :                 assert(aip != NULL);
     269             : 
     270           0 :                 boost::system::error_code ec;
     271           0 :                 IpAddress addr = IpAddress::from_string(aip->address(), ec);
     272           0 :                 if (ec.value() != 0) {
     273           0 :                     OPER_TRACE_ENTRY(Trace, intf_table,
     274             :                                      "Error decoding Alias IP address " +
     275             :                                      aip->address());
     276             :                 } else {
     277             :                     data->alias_ip_list_.list_.insert
     278           0 :                         (VmInterface::AliasIp(addr, vrf_node->name(), vn_uuid));
     279           0 :                     if (addr.is_v4()) {
     280           0 :                         data->alias_ip_list_.v4_count_++;
     281             :                     } else {
     282           0 :                         data->alias_ip_list_.v6_count_++;
     283             :                     }
     284             :                 }
     285           0 :                 break;
     286             :             }
     287           0 :             break;
     288           0 :         }
     289           0 :         break;
     290             :     }
     291           0 :     return;
     292             : }
     293             : 
     294             : // Build list of static-routes on virtual-machine-interface
     295           0 : static void BuildStaticRouteList(VmInterfaceConfigData *data, IFMapNode *node) {
     296             :     InterfaceRouteTable *entry =
     297           0 :         static_cast<InterfaceRouteTable*>(node->GetObject());
     298           0 :     assert(entry);
     299             : 
     300           0 :     for (std::vector<RouteType>::const_iterator it = entry->routes().begin();
     301           0 :          it != entry->routes().end(); it++) {
     302             :         int plen;
     303           0 :         boost::system::error_code ec;
     304           0 :         IpAddress ip;
     305           0 :         bool add = false;
     306             : 
     307           0 :         Ip4Address ip4;
     308           0 :         ec = Ip4PrefixParse(it->prefix, &ip4, &plen);
     309           0 :         if (ec.value() == 0) {
     310           0 :             ip = ip4;
     311           0 :             add = true;
     312             :         } else {
     313           0 :             Ip6Address ip6;
     314           0 :             ec = Inet6PrefixParse(it->prefix, &ip6, &plen);
     315           0 :             if (ec.value() == 0) {
     316           0 :                 ip = ip6;
     317           0 :                 add = true;
     318             :             } else {
     319           0 :                 LOG(DEBUG, "Error decoding v4/v6 Static Route address " <<
     320             :                     it->prefix);
     321             :             }
     322             :         }
     323             : 
     324           0 :         IpAddress gw = IpAddress::from_string(it->next_hop, ec);
     325           0 :         if (ec) {
     326           0 :             gw = IpAddress::from_string("0.0.0.0", ec);
     327             :         }
     328             : 
     329           0 :         if (add) {
     330             :             data->static_route_list_.list_.insert
     331           0 :                 (VmInterface::StaticRoute
     332           0 :                  (ip, plen, AddressList(1, gw.to_v4()),
     333           0 :                   it->community_attributes.community_attribute));
     334             :         }
     335             :     }
     336           0 : }
     337             : 
     338           0 : static void BuildResolveRoute(VmInterfaceConfigData *data, IFMapNode *node) {
     339             :     Subnet *entry =
     340           0 :         static_cast<Subnet *>(node->GetObject());
     341           0 :     assert(entry);
     342           0 :     Ip4Address ip;
     343           0 :     boost::system::error_code ec;
     344           0 :     ip = Ip4Address::from_string(entry->ip_prefix().ip_prefix, ec);
     345           0 :     if (ec.value() == 0) {
     346           0 :         data->subnet_ = ip;
     347           0 :         data->subnet_plen_ = entry->ip_prefix().ip_prefix_len;
     348             :     }
     349           0 : }
     350             : 
     351             : // Check if VMI is a sub-interface. Sub-interface will have
     352             : // sub_interface_vlan_tag property set to non-zero
     353          66 : static bool IsVlanSubInterface(VirtualMachineInterface *cfg) {
     354          66 :     if (cfg->IsPropertySet(VirtualMachineInterface::PROPERTIES) == false)
     355          66 :         return false;
     356             : 
     357           0 :     if (cfg->properties().sub_interface_vlan_tag == 0)
     358           0 :         return false;
     359             : 
     360           0 :     return true;
     361             : }
     362             : 
     363             : // Get VLAN if linked to physical interface and router
     364           4 : static void BuildInterfaceConfigurationData(Agent *agent,
     365             :                                             IFMapNode *node,
     366             :                                             uint16_t *rx_vlan_id,
     367             :                                             uint16_t *tx_vlan_id,
     368             :                                             IFMapNode **li_node,
     369             :                                             IFMapNode **phy_interface,
     370             :                                             IFMapNode **phy_device) {
     371           4 :     if (*li_node == NULL) {
     372           4 :         *li_node = node;
     373             :     }
     374             : 
     375           4 :     if (*phy_interface == NULL) {
     376           4 :         *phy_interface = agent->config_manager()->
     377           4 :             FindAdjacentIFMapNode(node, "physical-interface");
     378             :         // Update li_node if phy_interface is set
     379           4 :         if (*phy_interface) {
     380           4 :             *li_node = node;
     381             :         }
     382             :     }
     383           4 :     if (!(*phy_interface)) {
     384           0 :         *rx_vlan_id = VmInterface::kInvalidVlanId;
     385           0 :         *tx_vlan_id = VmInterface::kInvalidVlanId;
     386           0 :         return;
     387             :     }
     388             : 
     389           4 :     if (*phy_device == NULL) {
     390           4 :         *phy_device =
     391             :             agent->config_manager()->
     392           4 :             FindAdjacentIFMapNode(*phy_interface, "physical-router");
     393             :     }
     394           4 :     if (!(*phy_device)) {
     395           0 :         *rx_vlan_id = VmInterface::kInvalidVlanId;
     396           0 :         *tx_vlan_id = VmInterface::kInvalidVlanId;
     397           0 :         return;
     398             :     }
     399             : 
     400             :     autogen::LogicalInterface *port =
     401           4 :         static_cast <autogen::LogicalInterface *>(node->GetObject());
     402           4 :     if (port->IsPropertySet(autogen::LogicalInterface::VLAN_TAG)) {
     403           4 :         *rx_vlan_id = port->vlan_tag();
     404           4 :         *tx_vlan_id = port->vlan_tag();
     405             :     }
     406             : }
     407             : 
     408           0 : static void BuildInterfaceConfigurationDataFromVpg(Agent *agent,
     409             :                                             IFMapNode *node,
     410             :                                             IFMapNode **vpg_node,
     411             :                                             IFMapNode **phy_interface,
     412             :                                             IFMapNode **phy_device) {
     413           0 :     if (*vpg_node == NULL) {
     414           0 :         *vpg_node = node;
     415             :     }
     416             : 
     417             :     IFMapNode *vpg_pi_node = agent->config_manager()->
     418           0 :         FindAdjacentIFMapNode(node, "virtual-port-group-physical-interface");
     419           0 :     if (vpg_pi_node == NULL) {
     420           0 :         return;
     421             :     }
     422             : 
     423           0 :     if (*phy_interface == NULL) {
     424           0 :         *phy_interface = agent->config_manager()->
     425           0 :             FindAdjacentIFMapNode(vpg_pi_node, "physical-interface");
     426             :         // Update vpg_node if phy_interface is present
     427           0 :         if (*phy_interface) {
     428           0 :             *vpg_node = node;
     429             :         }
     430             :     }
     431           0 :     if (*phy_interface == NULL) {
     432           0 :             return;
     433             :     }
     434             : 
     435           0 :     if (*phy_device == NULL) {
     436           0 :         *phy_device =
     437             :             agent->config_manager()->
     438           0 :             FindAdjacentIFMapNode(*phy_interface, "physical-router");
     439             :     }
     440           0 :     if (*phy_device == NULL) {
     441           0 :             return;
     442             :     }
     443             : }
     444             : 
     445          70 : static void BuildAllowedAddressPairRouteList(VirtualMachineInterface *cfg,
     446             :                                              VmInterfaceConfigData *data) {
     447          70 :     for (std::vector<AllowedAddressPair>::const_iterator it =
     448          70 :          cfg->allowed_address_pairs().begin();
     449          70 :          it != cfg->allowed_address_pairs().end(); ++it) {
     450           0 :         boost::system::error_code ec;
     451           0 :         int plen = it->ip.ip_prefix_len;
     452           0 :         IpAddress ip = Ip4Address::from_string(it->ip.ip_prefix, ec);
     453           0 :         if (ec.value() != 0) {
     454           0 :             ip = Ip6Address::from_string(it->ip.ip_prefix, ec);
     455             :         }
     456           0 :         if (ec.value() != 0) {
     457           0 :             continue;
     458             :         }
     459             : 
     460           0 :         MacAddress mac = MacAddress::FromString(it->mac, &ec);
     461           0 :         if (ec.value() != 0) {
     462           0 :             mac.Zero();
     463             :         }
     464             : 
     465           0 :         if (ip.is_unspecified() && mac == MacAddress::kZeroMac) {
     466           0 :             continue;
     467             :         }
     468             : 
     469           0 :         bool ecmp = false;
     470           0 :         if (it->address_mode == "active-active") {
     471           0 :             ecmp = true;
     472             :         }
     473             : 
     474           0 :         VmInterface::AllowedAddressPair entry(ip, plen, ecmp, mac);
     475           0 :         data->allowed_address_pair_list_.list_.insert(entry);
     476           0 :     }
     477          70 : }
     478             : 
     479             : // Build VM Interface VRF or one Service Vlan entry for VM Interface
     480          58 : static void BuildVrfAndServiceVlanInfo(Agent *agent,
     481             :                                        VmInterfaceConfigData *data,
     482             :                                        IFMapNode *node) {
     483             : 
     484          58 :     ConfigManager *cfg_manager= agent->config_manager();
     485             :     VirtualMachineInterfaceRoutingInstance *entry =
     486          58 :         static_cast<VirtualMachineInterfaceRoutingInstance*>(node->GetObject());
     487          58 :     assert(entry);
     488             : 
     489             :     // Ignore node if direction is not yet set. An update will come later
     490          58 :     const PolicyBasedForwardingRuleType &rule = entry->data();
     491          58 :     if (rule.direction == "" && !agent->isMockMode()) {
     492           0 :         return;
     493             :     }
     494             : 
     495             :     // Find VRF by looking for link
     496             :     // virtual-machine-interface-routing-instance <-> routing-instance
     497          58 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     498          58 :     DBGraph *graph = table->GetGraph();
     499             : 
     500             :     // Iterate thru links looking for routing-instance node
     501          58 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     502          78 :          iter != node->end(graph); ++iter) {
     503             : 
     504          74 :         IFMapNode *vrf_node = static_cast<IFMapNode *>(iter.operator->());
     505          74 :         if (cfg_manager->SkipNode(vrf_node, agent->cfg()->cfg_vrf_table())) {
     506          20 :             continue;
     507             :         }
     508             : 
     509         108 :         if (rule.vlan_tag == 0 && rule.protocol == "" &&
     510          54 :             rule.service_chain_address == "") {
     511          54 :             data->vrf_name_ = vrf_node->name();
     512             :             const autogen::RoutingInstance *ri =
     513          54 :                 static_cast<autogen::RoutingInstance *>(vrf_node->GetObject());
     514          54 :             if (ri->fabric_snat()) {
     515           0 :                 AddFabricFloatingIp(agent, data, Ip4Address(0));
     516             :             }
     517             :         } else {
     518           0 :             if (!rule.service_chain_address.size() &&
     519           0 :                 !rule.ipv6_service_chain_address.size()) {
     520           0 :                 LOG(DEBUG, "Service VLAN IP address not specified for "
     521             :                     << node->name());
     522           0 :                 break;
     523             :             }
     524           0 :             boost::system::error_code ec;
     525           0 :             Ip4Address addr;
     526           0 :             bool ip_set = true, ip6_set = true;
     527           0 :             if (rule.service_chain_address.size()) {
     528           0 :                 addr = Ip4Address::from_string(rule.service_chain_address, ec);
     529           0 :                 if (ec.value() != 0) {
     530           0 :                     ip_set = false;
     531           0 :                     LOG(DEBUG, "Error decoding Service VLAN IP address " <<
     532             :                         rule.service_chain_address);
     533             :                 }
     534             :             }
     535           0 :             Ip6Address addr6;
     536           0 :             if (rule.ipv6_service_chain_address.size()) {
     537           0 :                 addr6 = Ip6Address::from_string(rule.ipv6_service_chain_address,
     538           0 :                                                 ec);
     539           0 :                 if (ec.value() != 0) {
     540           0 :                     ip6_set = false;
     541           0 :                     LOG(DEBUG, "Error decoding Service VLAN IP address " <<
     542             :                         rule.ipv6_service_chain_address);
     543             :                 }
     544             :             }
     545           0 :             if (!ip_set && !ip6_set) {
     546           0 :                 break;
     547             :             }
     548             : 
     549           0 :             if (rule.vlan_tag > 4093) {
     550           0 :                 LOG(DEBUG, "Invalid VLAN Tag " << rule.vlan_tag);
     551           0 :                 break;
     552             :             }
     553             : 
     554           0 :             LOG(DEBUG, "Add Service VLAN entry <" << rule.vlan_tag << " : " <<
     555             :                 rule.service_chain_address << " : " << vrf_node->name());
     556             : 
     557           0 :             MacAddress smac(agent->vrrp_mac());
     558           0 :             MacAddress dmac = MacAddress::FromString(Agent::BcastMac());
     559           0 :             if (rule.src_mac != Agent::NullString()) {
     560           0 :                 smac = MacAddress::FromString(rule.src_mac);
     561             :             }
     562           0 :             if (rule.src_mac != Agent::NullString()) {
     563           0 :                 dmac = MacAddress::FromString(rule.dst_mac);
     564             :             }
     565             :             data->service_vlan_list_.list_.insert
     566           0 :                 (VmInterface::ServiceVlan(rule.vlan_tag, vrf_node->name(), addr,
     567             :                                           addr6, smac, dmac));
     568             :         }
     569          54 :         break;
     570             :     }
     571             : 
     572          58 :     return;
     573             : }
     574             : 
     575             : // Build proxy-arp flag on VMI
     576             : // In future, we expect a proxy-arp flag on VMI. In the meanwhile, we want
     577             : // to enable proxy-arp on following,
     578             : // 1. Left and right interface of transparent service-chain
     579             : // 2. Left and right interface of in-network service-chain
     580             : // 3. Left interface of in-network-nat service-chain
     581             : //
     582             : // The common attribute for all these interface are,
     583             : // - They have vrf-assign rules
     584             : // - They have service-interface-type attribute
     585             : //
     586             : // Note: Right interface of in-network-nat will not have vrf-assign
     587          70 : static void BuildProxyArpFlags(Agent *agent, VmInterfaceConfigData *data,
     588             :                                VirtualMachineInterface *cfg) {
     589          70 :     if (cfg->vrf_assign_table().size() == 0)
     590          70 :         return;
     591             : 
     592             :     // Proxy-mode valid only on left or right interface os SI
     593           0 :     if (cfg->properties().service_interface_type != "left" &&
     594           0 :         cfg->properties().service_interface_type != "right") {
     595           0 :         return;
     596             :     }
     597             : 
     598           0 :     data->proxy_arp_mode_ = VmInterface::PROXY_ARP_UNRESTRICTED;
     599             : }
     600             : 
     601           9 : static bool ValidateFatFlowCfg(const boost::uuids::uuid &u, const ProtocolType *pt)
     602             : {
     603           9 :     if (pt->source_prefix.ip_prefix.length() > 0) {
     604           0 :         if (pt->source_prefix.ip_prefix_len < 8) {
     605           0 :             LOG(ERROR, "FatFlowCfg validation failed for VMI uuid:" << u
     606             :                         << " Protocol:" << pt->protocol << " Port:" << pt->port
     607             :                         << " Plen:" << pt->source_prefix.ip_prefix_len
     608             :                         << " src mask cannot be < 8\n");
     609           0 :             return false;
     610             :         }
     611           0 :         if (pt->source_aggregate_prefix_length < pt->source_prefix.ip_prefix_len) {
     612           0 :             LOG(ERROR, "FatFlowCfg validation failed for VMI uuid:" << u
     613             :                         << " Protocol:" << pt->protocol << " Port:" << pt->port
     614             :                         << " src aggr plen is less than src mask\n");
     615           0 :             return false;
     616             :         }
     617             :     }
     618           9 :     if (pt->destination_prefix.ip_prefix.length() > 0) {
     619           0 :         if (pt->destination_prefix.ip_prefix_len < 8) {
     620           0 :             LOG(ERROR, "FatFlowCfg validation failed for VMI uuid:" << u
     621             :                        << " Protocol:" << pt->protocol << " Port:" << pt->port
     622             :                        << " Plen:" << pt->destination_prefix.ip_prefix_len
     623             :                        << " dst mask cannot be < 8\n");
     624           0 :             return false;
     625             :         }
     626           0 :         if (pt->destination_aggregate_prefix_length <
     627           0 :                 pt->destination_prefix.ip_prefix_len) {
     628           0 :             LOG(ERROR, "FatFlowCfg validation failed for VMI uuid:" << u
     629             :                        << " Protocol:" << pt->protocol << " Port:" << pt->port
     630             :                        << " dst aggr plen is less than dst mask\n");
     631           0 :             return false;
     632             :         }
     633             :     }
     634           9 :     if ((pt->source_prefix.ip_prefix.length() > 0) &&
     635           0 :         (pt->destination_prefix.ip_prefix.length() > 0)) {
     636           0 :         IpAddress ip_src = IpAddress::from_string(pt->source_prefix.ip_prefix);
     637           0 :         IpAddress ip_dst = IpAddress::from_string(pt->destination_prefix.ip_prefix);
     638           0 :         if ((ip_src.is_v4() && ip_dst.is_v6()) ||
     639           0 :             (ip_src.is_v6() && ip_dst.is_v4())) {
     640           0 :             LOG(ERROR, "FatFlowCfg validation failed for VMI uuid:" << u << " Protocol:" << pt->protocol
     641             :                         << " Port:" << pt->port << " src and dst addr family mismatch\n");
     642           0 :             return false;
     643             :         }
     644             :     }
     645           9 :     return true;
     646             : }
     647             : 
     648          70 : static void BuildFatFlowTable(Agent *agent, const boost::uuids::uuid &u,
     649             :                               VmInterfaceConfigData *data, IFMapNode *node) {
     650             :     VirtualMachineInterface *cfg = static_cast <VirtualMachineInterface *>
     651          70 :                                        (node->GetObject());
     652             : 
     653          70 :     for (FatFlowProtocols::const_iterator it = cfg->fat_flow_protocols().begin();
     654          79 :             it != cfg->fat_flow_protocols().end(); it++) {
     655           9 :         if (!ValidateFatFlowCfg(u, &(*it))) {
     656           0 :             continue;
     657             :         }
     658             :         VmInterface::FatFlowEntry e = VmInterface::FatFlowEntry::MakeFatFlowEntry(
     659           9 :                                                   it->protocol, it->port,
     660           9 :                                                   it->ignore_address,
     661           9 :                                                   it->source_prefix.ip_prefix,
     662           9 :                                                   it->source_prefix.ip_prefix_len,
     663           9 :                                                   it->source_aggregate_prefix_length,
     664           9 :                                                   it->destination_prefix.ip_prefix,
     665           9 :                                                   it->destination_prefix.ip_prefix_len,
     666          18 :                                                   it->destination_aggregate_prefix_length);
     667           9 :         data->fat_flow_list_.Insert(&e);
     668           9 :     }
     669          70 : }
     670             : 
     671          10 : static void BuildInstanceIp(Agent *agent, VmInterfaceConfigData *data,
     672             :                             IFMapNode *node) {
     673          10 :     InstanceIp *ip = static_cast<InstanceIp *>(node->GetObject());
     674          10 :     boost::system::error_code err;
     675          10 :     IpAddress addr = IpAddress::from_string(ip->address(), err);
     676          10 :     bool is_primary = false;
     677             : 
     678          10 :     if (err.value() != 0) {
     679           0 :         return;
     680             :     }
     681             : 
     682          20 :     if (ip->secondary() != true && ip->service_instance_ip() != true &&
     683          10 :         ip->service_health_check_ip() != true) {
     684          10 :         is_primary = true;
     685          10 :         if (addr.is_v4()) {
     686          10 :             if (addr == Ip4Address(0)) {
     687           0 :                 return;
     688             :             }
     689             : 
     690          10 :             if (data->addr_ == Ip4Address(0) ||
     691          10 :                 data->addr_ > addr.to_v4()) {
     692          10 :                 data->addr_ = addr.to_v4();
     693          10 :                 if (ip->mode() == "active-active") {
     694           4 :                     data->ecmp_ = true;
     695             :                 } else {
     696           6 :                     data->ecmp_ = false;
     697             :                 }
     698             :             }
     699           0 :         } else if (addr.is_v6()) {
     700           0 :             if (addr == Ip6Address()) {
     701           0 :                 return;
     702             :             }
     703           0 :             if (data->ip6_addr_ == Ip6Address() ||
     704           0 :                 data->ip6_addr_ > addr.to_v6()) {
     705           0 :                 data->ip6_addr_ = addr.to_v6();
     706             :             }
     707           0 :             if (ip->mode() == "active-active") {
     708           0 :                 data->ecmp6_ = true;
     709             :             } else {
     710           0 :                 data->ecmp6_ = false;
     711             :             }
     712             :         }
     713             :     }
     714             : 
     715          10 :     if (ip->service_instance_ip()) {
     716           0 :         if (addr.is_v4()) {
     717           0 :             data->service_ip_ = addr.to_v4();
     718           0 :             data->service_ip_ecmp_ = false;
     719           0 :             if (ip->mode() == "active-active") {
     720           0 :                 data->service_ip_ecmp_ = true;
     721             :             }
     722           0 :         } else if (addr.is_v6()) {
     723           0 :             data->service_ip6_ = addr.to_v6();
     724           0 :             data->service_ip_ecmp6_ = false;
     725           0 :             if (ip->mode() == "active-active") {
     726           0 :                 data->service_ip_ecmp6_ = true;
     727             :             }
     728             :         }
     729             :     }
     730             : 
     731          10 :     bool ecmp = false;
     732          10 :     if (ip->mode() == "active-active") {
     733           4 :         ecmp = true;
     734             :     }
     735             : 
     736          10 :     IpAddress tracking_ip = Ip4Address(0);
     737          10 :     if (ip->secondary() || ip->service_instance_ip()) {
     738           0 :         tracking_ip = IpAddress::from_string(
     739           0 :                 ip->secondary_ip_tracking_ip().ip_prefix, err);
     740           0 :         if (err.value() != 0) {
     741           0 :             tracking_ip = Ip4Address(0);
     742             :         }
     743             : 
     744           0 :         if (tracking_ip == addr) {
     745           0 :             tracking_ip = Ip4Address(0);
     746             :         }
     747             :     }
     748             : 
     749          10 :     if (ip->service_health_check_ip()) {
     750             :         // if instance ip is service health check ip along with adding
     751             :         // it to instance ip list to allow route export and save it
     752             :         // under service_health_check_ip_ to allow usage for health
     753             :         // check service
     754           0 :         if (addr.is_v4()) {
     755             :             // TODO: currently only v4 health check is supported
     756           0 :             data->service_health_check_ip_ = addr;
     757             :         }
     758             :     }
     759             : 
     760          10 :     if (addr.is_v4()) {
     761          10 :         data->instance_ipv4_list_.list_.insert(
     762          10 :                 VmInterface::InstanceIp(addr, Address::kMaxV4PrefixLen, ecmp,
     763          10 :                                         is_primary, ip->service_instance_ip(),
     764          10 :                                         ip->service_health_check_ip(),
     765          10 :                                         ip->local_ip(), tracking_ip));
     766             :     } else {
     767           0 :         data->instance_ipv6_list_.list_.insert(
     768           0 :                 VmInterface::InstanceIp(addr, Address::kMaxV6PrefixLen, ecmp,
     769           0 :                                         is_primary, ip->service_instance_ip(),
     770           0 :                                         ip->service_health_check_ip(),
     771           0 :                                         ip->local_ip(), tracking_ip));
     772             :     }
     773             : }
     774             : 
     775           0 : static void BuildTagList(VmInterface::TagEntryList *tag_list, IFMapNode *node) {
     776             : 
     777           0 :     Tag *tag_cfg = static_cast<Tag *>(node->GetObject());
     778           0 :     assert(tag_cfg);
     779             : 
     780           0 :     uuid tag_uuid = nil_uuid();
     781           0 :     autogen::IdPermsType id_perms = tag_cfg->id_perms();
     782           0 :     CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
     783             :                tag_uuid);
     784           0 :     uint64_t tag_type = TagEntry::GetTypeVal(tag_cfg->type_name(),
     785             :                                              tag_cfg->id());
     786           0 :     tag_list->list_.insert(VmInterface::TagEntry(tag_type, tag_uuid));
     787           0 : }
     788             : 
     789           3 : static void BuildSgList(VmInterfaceConfigData *data, IFMapNode *node) {
     790             :     SecurityGroup *sg_cfg = static_cast<SecurityGroup *>
     791           3 :         (node->GetObject());
     792           3 :     assert(sg_cfg);
     793           3 :     autogen::IdPermsType id_perms = sg_cfg->id_perms();
     794           3 :     uint32_t sg_id = sg_cfg->id();
     795           3 :     if (sg_id != SgTable::kInvalidSgId) {
     796           3 :         uuid sg_uuid = nil_uuid();
     797           3 :         CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
     798             :                    sg_uuid);
     799             :         data->sg_list_.list_.insert
     800           3 :             (VmInterface::SecurityGroupEntry(sg_uuid));
     801             :     }
     802           3 : }
     803             : 
     804           0 : static bool BuildBridgeDomainVrfTable(Agent *agent, IFMapNode *vn_node) {
     805             : 
     806           0 :     ConfigManager *cfg_manager= agent->config_manager();
     807           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(vn_node->table());
     808           0 :     DBGraph *graph = table->GetGraph();
     809             : 
     810             :     // Iterate thru links for virtual-network looking for routing-instance
     811           0 :     for (DBGraphVertex::adjacency_iterator iter = vn_node->begin(graph);
     812           0 :             iter != vn_node->end(graph); ++iter) {
     813             : 
     814           0 :         IFMapNode *vrf_node = static_cast<IFMapNode *>(iter.operator->());
     815           0 :         if (cfg_manager->SkipNode(vrf_node, agent->cfg()->cfg_vrf_table())) {
     816           0 :             continue;
     817             :         }
     818             : 
     819             :         // We are interested only in default-vrf
     820             :         RoutingInstance *ri = static_cast<RoutingInstance *>
     821           0 :             (vrf_node->GetObject());
     822           0 :         if(ri->is_default()) {
     823           0 :             return true;
     824             :         }
     825             :     }
     826             : 
     827           0 :     return false;
     828             : }
     829             : 
     830           0 : static bool BuildBridgeDomainVnTable(Agent *agent,
     831             :                                      IFMapNode *bridge_domain_node) {
     832             : 
     833           0 :     ConfigManager *cfg_manager= agent->config_manager();
     834             :     IFMapAgentTable *table =
     835           0 :         static_cast<IFMapAgentTable *>(bridge_domain_node->table());
     836           0 :     DBGraph *graph = table->GetGraph();
     837             : 
     838             :     // Iterate thru links for virtual-network fron bridge domain
     839           0 :     for (DBGraphVertex::adjacency_iterator iter =
     840           0 :          bridge_domain_node->begin(graph);
     841           0 :          iter != bridge_domain_node->end(graph); ++iter) {
     842             : 
     843           0 :         IFMapNode *vn_node = static_cast<IFMapNode *>(iter.operator->());
     844           0 :         if (cfg_manager->SkipNode(vn_node, agent->cfg()->cfg_vn_table())) {
     845           0 :             continue;
     846             :         }
     847             : 
     848           0 :         if (BuildBridgeDomainVrfTable(agent, vn_node) == true) {
     849           0 :             return true;
     850             :         }
     851             :     }
     852           0 :     return false;
     853             : }
     854             : 
     855           0 : static void UpdateVmiSiMode(Agent *agent, VmInterfaceConfigData *data,
     856             :                             IFMapNode *node) {
     857             : 
     858           0 :     ServiceInstance *entry = static_cast<ServiceInstance*>(node->GetObject());
     859           0 :     assert(entry);
     860             : 
     861           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     862           0 :     DBGraph *graph = table->GetGraph();
     863             : 
     864           0 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     865           0 :          iter != node->end(graph); ++iter) {
     866             : 
     867           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
     868           0 :         if (agent->config_manager()->SkipNode(adj_node)) {
     869           0 :             continue;
     870             :         }
     871           0 :         if (adj_node->table() != agent->cfg()->cfg_service_template_table()) {
     872           0 :             continue;
     873             :         }
     874           0 :         ServiceTemplate *entry =  static_cast<ServiceTemplate*>(adj_node->GetObject());
     875           0 :         if (entry == NULL)
     876           0 :             return;
     877             : 
     878           0 :         ServiceTemplateType svc_template_props = entry->properties();
     879           0 :         string service_mode = svc_template_props.service_mode;
     880             : 
     881           0 :         if (service_mode == "in-network") {
     882           0 :             data->service_mode_ = VmInterface::ROUTED_MODE;
     883           0 :         } else if (service_mode == "transparent") {
     884           0 :             data->service_mode_ = VmInterface::BRIDGE_MODE;
     885           0 :         } else if (service_mode == "in-network-nat") {
     886           0 :             data->service_mode_ = VmInterface::ROUTED_NAT_MODE;
     887             :         } else {
     888           0 :             data->service_mode_ = VmInterface::SERVICE_MODE_ERROR;
     889             :         }
     890           0 :     }
     891             : }
     892             : 
     893           0 : static void BuildVmiSiMode(Agent *agent, VmInterfaceConfigData *data,
     894             :                             IFMapNode *node) {
     895             : 
     896           0 :     PortTuple *entry = static_cast<PortTuple*>(node->GetObject());
     897           0 :     assert(entry);
     898             : 
     899           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     900           0 :     DBGraph *graph = table->GetGraph();
     901             : 
     902           0 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     903           0 :          iter != node->end(graph); ++iter) {
     904           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
     905           0 :         if (adj_node->table() != agent->cfg()->cfg_service_instance_table()) {
     906           0 :             continue;
     907             :         }
     908           0 :         UpdateVmiSiMode(agent, data, adj_node);
     909             :     }
     910           0 : }
     911             : 
     912           0 : static bool BuildLogicalRouterData(Agent *agent,
     913             :                                    VmInterfaceConfigData *data,
     914             :                                    IFMapNode *node) {
     915             :     VirtualMachineInterface *vmi =
     916             :         static_cast<autogen::VirtualMachineInterface *>
     917           0 :         (node->GetObject());
     918           0 :     if (!vmi->IsPropertySet(VirtualMachineInterface::DEVICE_OWNER)) {
     919           0 :         return false;
     920             :     }
     921           0 :     if (vmi->device_owner() != VMI_NETWORK_ROUTER_INTERFACE) {
     922           0 :         return false;
     923             :     }
     924           0 :     return true;
     925             : }
     926             : 
     927           0 : static void BuildSiOtherVmi(Agent *agent, VmInterfaceConfigData *data,
     928             :                             IFMapNode *node, const string &s_intf_type) {
     929           0 :     PortTuple *entry = static_cast<PortTuple*>(node->GetObject());
     930           0 :     assert(entry);
     931             : 
     932           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     933           0 :     DBGraph *graph = table->GetGraph();
     934             : 
     935           0 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     936           0 :          iter != node->end(graph); ++iter) {
     937             : 
     938           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
     939           0 :         if (agent->config_manager()->SkipNode(adj_node)) {
     940           0 :             continue;
     941             :         }
     942           0 :         if (adj_node->table() != agent->cfg()->cfg_vm_interface_table()) {
     943           0 :             continue;
     944             :         }
     945             :         VirtualMachineInterface *cfg = static_cast <VirtualMachineInterface *>
     946           0 :             (adj_node->GetObject());
     947           0 :         if (!cfg->IsPropertySet(VirtualMachineInterface::PROPERTIES)) {
     948           0 :             continue;
     949             :         }
     950             : 
     951           0 :         string interface_to_find = "right";
     952           0 :         if (s_intf_type == "right") {
     953           0 :             interface_to_find = "left";
     954             :         }
     955           0 :         const string &cfg_intf_type = cfg->properties().service_interface_type;
     956           0 :         if (cfg_intf_type != interface_to_find) {
     957           0 :             continue;
     958             :         }
     959             : 
     960           0 :         data->is_left_si_ = (interface_to_find == "right") ? true : false;
     961           0 :         data->si_other_end_vmi_ = nil_uuid();
     962           0 :         autogen::IdPermsType id_perms = cfg->id_perms();
     963           0 :         CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
     964           0 :                    data->si_other_end_vmi_);
     965             :         /* No further iterations required for setting data->si_other_end_vmi */
     966           0 :         break;
     967           0 :     }
     968           0 : }
     969             : 
     970             : // Build VM Interface bridge domain link
     971           0 : static void BuildBridgeDomainTable(Agent *agent,
     972             :                                    VmInterfaceConfigData *data,
     973             :                                    IFMapNode *node) {
     974             : 
     975           0 :     ConfigManager *cfg_manager= agent->config_manager();
     976             :     VirtualMachineInterfaceBridgeDomain *entry =
     977           0 :         static_cast<VirtualMachineInterfaceBridgeDomain*>(node->GetObject());
     978           0 :     assert(entry);
     979             : 
     980           0 :     const BridgeDomainMembershipType &vlan = entry->data();
     981           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
     982           0 :     DBGraph *graph = table->GetGraph();
     983             : 
     984           0 :     for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
     985           0 :          iter != node->end(graph); ++iter) {
     986             : 
     987             :         IFMapNode *bridge_domain_node =
     988           0 :             static_cast<IFMapNode *>(iter.operator->());
     989           0 :         if (cfg_manager->SkipNode
     990           0 :             (bridge_domain_node, agent->cfg()->cfg_bridge_domain_table())) {
     991           0 :             continue;
     992             :         }
     993             : 
     994             :         //Verify that bridge domain has link to VN and VRF
     995             :         //then insert in config node list
     996           0 :         if (BuildBridgeDomainVnTable(agent, bridge_domain_node) == false) {
     997           0 :             continue;
     998             :         }
     999             :         autogen::BridgeDomain *bd_cfg = static_cast<autogen::BridgeDomain *>
    1000           0 :             (bridge_domain_node->GetObject());
    1001           0 :         if (bd_cfg->isid() == 0) {
    1002           0 :             continue;
    1003             :         }
    1004           0 :         autogen::IdPermsType id_perms = bd_cfg->id_perms();
    1005           0 :         uuid bd_uuid = nil_uuid();
    1006           0 :         CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
    1007             :                    bd_uuid);
    1008           0 :         data->bridge_domain_list_.list_.insert(
    1009           0 :                 VmInterface::BridgeDomain(bd_uuid, vlan.vlan_tag));
    1010             : 
    1011           0 :         if (bd_cfg->mac_learning_enabled()) {
    1012           0 :             data->learning_enabled_ = true;
    1013             :         }
    1014           0 :         break;
    1015           0 :     }
    1016           0 :     return;
    1017             : }
    1018             : 
    1019          70 : static void CompareVnVm(const uuid &vmi_uuid, VmInterfaceConfigData *data,
    1020             :                         const PortSubscribeEntry *entry) {
    1021             :     /* VN uuid is mandatory for port adds from REST API only for port type of
    1022             :      * PortSubscribeEntry::VMPORT. Hence VN match check should be done only for
    1023             :      * port type of PortSubscribeEntry::VMPORT
    1024             :      */
    1025         108 :     if (entry && entry->type() == PortSubscribeEntry::VMPORT &&
    1026          38 :         (entry->MatchVn(data->vn_uuid_) == false)) {
    1027          19 :         IFMAP_ERROR(InterfaceConfiguration,
    1028             :                     "Virtual-network UUID mismatch for interface:",
    1029             :                     UuidToString(vmi_uuid),
    1030             :                     "configuration VN uuid",
    1031             :                     UuidToString(data->vn_uuid_),
    1032             :                     "compute VN uuid",
    1033             :                     UuidToString(entry->vn_uuid()));
    1034             :     }
    1035             : 
    1036          70 :     if (entry && (entry->MatchVm(data->vm_uuid_) == false)) {
    1037           0 :         IFMAP_ERROR(InterfaceConfiguration,
    1038             :                     "Virtual-machine UUID mismatch for interface:",
    1039             :                     UuidToString(vmi_uuid),
    1040             :                     "configuration VM UUID is",
    1041             :                     UuidToString(data->vm_uuid_),
    1042             :                     "compute VM uuid is",
    1043             :                     UuidToString(entry->vm_uuid()));
    1044             :     }
    1045          70 : }
    1046             : 
    1047          62 : static void BuildVn(VmInterfaceConfigData *data,
    1048             :                     IFMapNode *node,
    1049             :                     const boost::uuids::uuid &u,
    1050             :                     VmInterface::TagEntryList *tag_list) {
    1051          62 :     const Agent *agent = data->agent();
    1052             :     VirtualNetwork *vn =
    1053          62 :         static_cast<VirtualNetwork *>(node->GetObject());
    1054          62 :     assert(vn);
    1055          62 :     autogen::IdPermsType id_perms = vn->id_perms();
    1056          62 :     CfgUuidSet(id_perms.uuid.uuid_mslong,
    1057          62 :                id_perms.uuid.uuid_lslong, data->vn_uuid_);
    1058             : 
    1059          62 :     if (node->name() == agent->fabric_vn_name()) {
    1060           0 :         data->proxy_arp_mode_ = VmInterface::PROXY_ARP_UNRESTRICTED;
    1061             :     }
    1062             : 
    1063             :     /* Copy fat-flow configured at VN level */
    1064          62 :     for (FatFlowProtocols::const_iterator it = vn->fat_flow_protocols().begin();
    1065          62 :             it != vn->fat_flow_protocols().end(); it++) {
    1066           0 :         if (!ValidateFatFlowCfg(u, &(*it))) {
    1067           0 :              continue;
    1068             :         }
    1069             : 
    1070             :         VmInterface::FatFlowEntry e = VmInterface::FatFlowEntry::MakeFatFlowEntry(
    1071           0 :                                                   it->protocol, it->port,
    1072           0 :                                                   it->ignore_address,
    1073           0 :                                                   it->source_prefix.ip_prefix,
    1074           0 :                                                   it->source_prefix.ip_prefix_len,
    1075           0 :                                                   it->source_aggregate_prefix_length,
    1076           0 :                                                   it->destination_prefix.ip_prefix,
    1077           0 :                                                   it->destination_prefix.ip_prefix_len,
    1078           0 :                                                   it->destination_aggregate_prefix_length);
    1079           0 :         data->fat_flow_list_.Insert(&e);
    1080           0 :     }
    1081          62 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
    1082          62 :     for (DBGraphVertex::adjacency_iterator iter =
    1083          62 :             node->begin(table->GetGraph());
    1084         300 :             iter != node->end(table->GetGraph()); ++iter) {
    1085             : 
    1086         238 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
    1087         238 :         if (agent->config_manager()->CanUseNode(adj_node,
    1088             :                                                 agent->cfg()->cfg_vn_table())) {
    1089           0 :             if (adj_node->name() == agent->fabric_vn_name()) {
    1090           0 :                 data->proxy_arp_mode_ = VmInterface::PROXY_ARP_UNRESTRICTED;
    1091             :             }
    1092             :         }
    1093             : 
    1094         238 :         if (agent->config_manager()->SkipNode(adj_node,
    1095             :                                               agent->cfg()->cfg_tag_table())) {
    1096         238 :             continue;
    1097             :         }
    1098           0 :         BuildTagList(tag_list, adj_node);
    1099             :     }
    1100             : 
    1101          62 :     data->mac_ip_learning_enable_ = vn->mac_ip_learning_enable();
    1102          62 : }
    1103             : 
    1104          70 : static void FillHbsInfo(VmInterfaceConfigData *data,
    1105             :                          IFMapNode *vn_node) {
    1106             :     //Reset the hbs interface
    1107          70 :     data->hbs_intf_type_ =  VmInterface::HBS_INTF_INVALID;
    1108             : 
    1109          70 :     if (vn_node == NULL) {
    1110           8 :         return;
    1111             :     }
    1112             : 
    1113          62 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(vn_node->table());
    1114          62 :     DBGraph *graph = table->GetGraph();
    1115             : 
    1116             :     //Get the HBS information from project
    1117          62 :     for (DBGraphVertex::adjacency_iterator iter = vn_node->begin(graph);
    1118         300 :          iter != vn_node->end(graph); ++iter) {
    1119         238 :         if (iter->IsDeleted()) {
    1120           0 :             continue;
    1121             :         }
    1122         238 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
    1123             :         //Check if HBS service is enabled for this project
    1124         238 :         if (strcmp(adj_node->table()->Typename(),
    1125         238 :                    "host-based-service-virtual-network") == 0) {
    1126             :             autogen::HostBasedServiceVirtualNetwork *hbsvn =
    1127           0 :                 static_cast<HostBasedServiceVirtualNetwork *>(adj_node->GetObject());
    1128           0 :             ServiceVirtualNetworkType type = hbsvn->data();
    1129           0 :             if (strcmp(type.virtual_network_type.c_str(),
    1130           0 :                        "right") == 0) {
    1131           0 :                 data->hbs_intf_type_ = VmInterface::HBS_INTF_RIGHT;
    1132           0 :             } else if (strcmp(type.virtual_network_type.c_str(),
    1133           0 :                               "left") == 0) {
    1134           0 :                 data->hbs_intf_type_ = VmInterface::HBS_INTF_LEFT;
    1135           0 :             } else if (strcmp(type.virtual_network_type.c_str(),
    1136           0 :                               "management") == 0) {
    1137           0 :                 data->hbs_intf_type_ = VmInterface::HBS_INTF_MGMT;
    1138             :             }
    1139           0 :         }
    1140             :     }
    1141             : }
    1142             : 
    1143           0 : static void BuildProject(VmInterfaceConfigData *data,
    1144             :                          IFMapNode *node,
    1145             :                          const boost::uuids::uuid &u,
    1146             :                          VmInterface::TagEntryList *tag_list) {
    1147           0 :     const Agent *agent = data->agent();
    1148           0 :     Project *pr = static_cast<Project *>(node->GetObject());
    1149           0 :     assert(pr);
    1150             : 
    1151             :     //We parse thru edge table while getting tag attached to project
    1152             :     //This is done because project to tag has 2 links
    1153             :     //1> With metadata project-scoped-tag this is used to create tag
    1154             :     //   specific to project
    1155             :     //2> Another with metadata project-tag which signifies that tag
    1156             :     //   is attached to project
    1157           0 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
    1158           0 :     for (DBGraphVertex::edge_iterator iter =
    1159           0 :             node->edge_list_begin(table->GetGraph());
    1160           0 :             iter != node->edge_list_end(table->GetGraph()); ++iter) {
    1161             : 
    1162           0 :         IFMapLink *link = static_cast<IFMapLink *>(iter.operator->());
    1163           0 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.target());
    1164           0 :         if (link->metadata() != "project-tag") {
    1165           0 :             continue;
    1166             :         }
    1167             : 
    1168           0 :         if (agent->config_manager()->SkipNode(adj_node,
    1169             :                                               agent->cfg()->cfg_tag_table())) {
    1170           0 :             continue;
    1171             :         }
    1172           0 :         BuildTagList(tag_list, adj_node);
    1173             :     }
    1174           0 : }
    1175             : 
    1176           0 : static void BuildQosConfig(VmInterfaceConfigData *data, IFMapNode *node) {
    1177             :     autogen::QosConfig *qc =
    1178           0 :         static_cast<autogen::QosConfig *>(node->GetObject());
    1179           0 :     assert(qc);
    1180           0 :     autogen::IdPermsType id_perms = qc->id_perms();
    1181           0 :     CfgUuidSet(id_perms.uuid.uuid_mslong,
    1182           0 :                id_perms.uuid.uuid_lslong, data->qos_config_uuid_);
    1183           0 : }
    1184             : 
    1185          70 : static void BuildVm(VmInterfaceConfigData *data,
    1186             :                     IFMapNode *node,
    1187             :                     const boost::uuids::uuid &u,
    1188             :                     VmInterface::TagEntryList *tag_list) {
    1189          70 :     const Agent *agent = data->agent();
    1190          70 :     VirtualMachine *vm = static_cast<VirtualMachine *>(node->GetObject());
    1191          70 :     assert(vm);
    1192             : 
    1193          70 :     autogen::IdPermsType id_perms = vm->id_perms();
    1194          70 :     CfgUuidSet(id_perms.uuid.uuid_mslong,
    1195          70 :                id_perms.uuid.uuid_lslong, data->vm_uuid_);
    1196             : 
    1197             : 
    1198          70 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
    1199          70 :     for (DBGraphVertex::adjacency_iterator iter =
    1200          70 :             node->begin(table->GetGraph());
    1201         146 :             iter != node->end(table->GetGraph()); ++iter) {
    1202             : 
    1203          76 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
    1204          76 :         if (agent->config_manager()->SkipNode(adj_node,
    1205             :                                               agent->cfg()->cfg_tag_table())) {
    1206          76 :             continue;
    1207             :         }
    1208           0 :         BuildTagList(tag_list, adj_node);
    1209             :     }
    1210          70 : }
    1211             : 
    1212             : // Get DHCP configuration
    1213          70 : static void ReadDhcpOptions(VirtualMachineInterface *cfg,
    1214             :                             VmInterfaceConfigData &data) {
    1215          70 :     data.oper_dhcp_options_.set_options(cfg->dhcp_option_list());
    1216          70 :     data.oper_dhcp_options_.set_host_routes(cfg->host_routes());
    1217          70 : }
    1218             : 
    1219             : // Get interface mirror configuration.
    1220          70 : static void ReadAnalyzerNameAndCreate(Agent *agent,
    1221             :                                       VirtualMachineInterface *cfg,
    1222             :                                       VmInterfaceConfigData &data) {
    1223          70 :     if (!cfg) {
    1224          70 :         return;
    1225             :     }
    1226          70 :     MirrorActionType mirror_to = cfg->properties().interface_mirror.mirror_to;
    1227          70 :     if (mirror_to.analyzer_name.empty())
    1228          70 :         return;
    1229             :     // Check for nic assisted mirroring support.
    1230           0 :     if (!mirror_to.nic_assisted_mirroring) {
    1231           0 :         boost::system::error_code ec;
    1232             :         IpAddress dip = IpAddress::from_string(mirror_to.analyzer_ip_address,
    1233           0 :                                               ec);
    1234           0 :         if (ec.value() != 0) {
    1235           0 :             return;
    1236             :         }
    1237             :         uint16_t dport;
    1238           0 :         if (mirror_to.udp_port) {
    1239           0 :             dport = mirror_to.udp_port;
    1240             :         } else {
    1241           0 :             dport = ContrailPorts::AnalyzerUdpPort();
    1242             :         }
    1243             :          MirrorEntryData::MirrorEntryFlags mirror_flag =
    1244           0 :              MirrorTable::DecodeMirrorFlag(mirror_to.nh_mode,
    1245           0 :                                            mirror_to.juniper_header);
    1246             :         // not using the vrf coming in; by setting this to empty, -1 will be
    1247             :         // configured so that current VRF will be used (for leaked routes).
    1248           0 :         if (mirror_flag == MirrorEntryData::DynamicNH_With_JuniperHdr) {
    1249           0 :             agent->mirror_table()->AddMirrorEntry
    1250           0 :                 (mirror_to.analyzer_name, std::string(),
    1251           0 :                  agent->GetMirrorSourceIp(dip),
    1252           0 :                  agent->mirror_port(), dip, dport);
    1253           0 :         } else if (mirror_flag ==
    1254             :                    MirrorEntryData::DynamicNH_Without_JuniperHdr) {
    1255           0 :             agent->mirror_table()->AddMirrorEntry(mirror_to.analyzer_name,
    1256           0 :                     mirror_to.routing_instance, agent->GetMirrorSourceIp(dip),
    1257           0 :                     agent->mirror_port(), dip, dport, 0, mirror_flag,
    1258           0 :                     MacAddress::FromString(mirror_to.analyzer_mac_address));
    1259           0 :         } else if (mirror_flag ==
    1260             :                    MirrorEntryData::StaticNH_Without_JuniperHdr) {
    1261             :             IpAddress vtep_dip = IpAddress::from_string
    1262           0 :                 (mirror_to.static_nh_header.vtep_dst_ip_address, ec);
    1263           0 :             if (ec.value() != 0) {
    1264           0 :                 return;
    1265             :             }
    1266           0 :             agent->mirror_table()->AddMirrorEntry(mirror_to.analyzer_name,
    1267           0 :                     mirror_to.routing_instance, agent->GetMirrorSourceIp(dip),
    1268           0 :                     agent->mirror_port(), vtep_dip, dport,
    1269           0 :                     mirror_to.static_nh_header.vni, mirror_flag,
    1270             :                     MacAddress::FromString
    1271           0 :                     (mirror_to.static_nh_header.vtep_dst_mac_address));
    1272             :         }
    1273             :         else {
    1274           0 :             LOG(ERROR, "Mirror nh mode not supported");
    1275             :         }
    1276             :     } else {
    1277           0 :         agent->mirror_table()->AddMirrorEntry(
    1278             :                 mirror_to.analyzer_name,
    1279           0 :                 mirror_to.nic_assisted_mirroring_vlan);
    1280             :     }
    1281           0 :     data.analyzer_name_ =  mirror_to.analyzer_name;
    1282             :     string traffic_direction =
    1283           0 :         cfg->properties().interface_mirror.traffic_direction;
    1284           0 :     if (traffic_direction.compare("egress") == 0) {
    1285           0 :         data.mirror_direction_ = Interface::MIRROR_TX;
    1286           0 :     } else if (traffic_direction.compare("ingress") == 0) {
    1287           0 :         data.mirror_direction_ = Interface::MIRROR_RX;
    1288             :     } else {
    1289           0 :         data.mirror_direction_ = Interface::MIRROR_RX_TX;
    1290             :     }
    1291          70 : }
    1292             : 
    1293          70 : static void BuildVrfAssignRule(VirtualMachineInterface *cfg,
    1294             :                                VmInterfaceConfigData *data) {
    1295          70 :     uint32_t id = 1;
    1296          70 :     for (std::vector<VrfAssignRuleType>::const_iterator iter =
    1297         140 :          cfg->vrf_assign_table().begin(); iter != cfg->vrf_assign_table().end();
    1298           0 :          ++iter) {
    1299           0 :         VmInterface::VrfAssignRule entry(id++, iter->match_condition,
    1300           0 :                                          iter->routing_instance,
    1301           0 :                                          iter->ignore_acl);
    1302           0 :         data->vrf_assign_rule_list_.list_.insert(entry);
    1303           0 :     }
    1304          70 : }
    1305             : 
    1306          10 : static IFMapNode *FindTarget(IFMapAgentTable *table, IFMapNode *node,
    1307             :                              const std::string &node_type) {
    1308          10 :     for (DBGraphVertex::adjacency_iterator it = node->begin(table->GetGraph());
    1309          10 :          it != node->end(table->GetGraph()); ++it) {
    1310          10 :         IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
    1311          10 :         if (adj_node->table()->Typename() == node_type)
    1312          10 :             return adj_node;
    1313             :     }
    1314           0 :     return NULL;
    1315             : }
    1316             : 
    1317          10 : static void ReadDhcpEnable(Agent *agent, VmInterfaceConfigData *data,
    1318             :                            IFMapNode *node) {
    1319          10 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
    1320          10 :     for (DBGraphVertex::adjacency_iterator it = node->begin(table->GetGraph());
    1321          63 :          it != node->end(table->GetGraph()); ++it) {
    1322          53 :         IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->());
    1323          53 :         IFMapNode *ipam_node = NULL;
    1324          63 :         if (adj_node->table() == agent->cfg()->cfg_vn_network_ipam_table() &&
    1325          63 :             (ipam_node = FindTarget(table, adj_node, "network-ipam"))) {
    1326             :             VirtualNetworkNetworkIpam *ipam =
    1327          10 :                 static_cast<VirtualNetworkNetworkIpam *>(adj_node->GetObject());
    1328          10 :             assert(ipam);
    1329          10 :             const VnSubnetsType &subnets = ipam->data();
    1330          10 :             boost::system::error_code ec;
    1331          20 :             for (unsigned int i = 0; i < subnets.ipam_subnets.size(); ++i) {
    1332          10 :                 if (IsIp4SubnetMember(data->addr_,
    1333           0 :                         Ip4Address::from_string(
    1334          10 :                             subnets.ipam_subnets[i].subnet.ip_prefix, ec),
    1335          20 :                         subnets.ipam_subnets[i].subnet.ip_prefix_len) && data->addr_ != Ip4Address(0)) {
    1336          10 :                     data->dhcp_enable_ = subnets.ipam_subnets[i].enable_dhcp;
    1337             :                 }
    1338           0 :                 else if (IsIp6SubnetMember(data->ip6_addr_,
    1339           0 :                         (Ip6Address::from_string(
    1340           0 :                             subnets.ipam_subnets[i].subnet.ip_prefix, ec)),
    1341           0 :                         subnets.ipam_subnets[i].subnet.ip_prefix_len)) {
    1342           0 :                     data->dhcp_enable_v6_ = subnets.ipam_subnets[i].enable_dhcp;
    1343             :                 }
    1344             : 
    1345             :             }
    1346             :         }
    1347             :     }
    1348          10 : }
    1349             : 
    1350             : 
    1351             : 
    1352             : // Builds parent for VMI (not to be confused with parent ifmap-node)
    1353             : // Possible values are,
    1354             : // - logical-interface or virtual-port-group : Incase of baremetals
    1355             : //   logical-interface would be examined before virtual-port-group
    1356             : // - virtual-machine-interface : We support virtual-machine-interface
    1357             : //   sub-interfaces. In this case, another virtual-machine-interface itself
    1358             : //   can be a parent
    1359          70 : static PhysicalRouter *BuildParentInfo(Agent *agent,
    1360             :                                        VirtualMachineInterface *cfg,
    1361             :                                        IFMapNode *node,
    1362             :                                        IFMapNode *logical_node,
    1363             :                                        IFMapNode *vpg_node,
    1364             :                                        VmInterfaceConfigData *data,
    1365             :                                        IFMapNode *parent_vmi_node,
    1366             :                                        IFMapNode **phy_interface,
    1367             :                                        IFMapNode **phy_device) {
    1368          70 :     if (logical_node) {
    1369           4 :         if (*phy_interface) {
    1370           4 :             data->physical_interface_ = (*phy_interface)->name();
    1371             :         }
    1372             :         agent->interface_table()->
    1373           4 :            LogicalInterfaceIFNodeToUuid(logical_node, data->logical_interface_);
    1374           4 :         if ((*phy_device) == NULL) {
    1375           0 :             return NULL;
    1376             :         }
    1377           4 :         return static_cast<PhysicalRouter *>((*phy_device)->GetObject());
    1378             :     }
    1379             : 
    1380          66 :     if (vpg_node) {
    1381           0 :         if (*phy_interface) {
    1382           0 :             data->physical_interface_ = (*phy_interface)->name();
    1383             :         }
    1384           0 :         if (IsVlanSubInterface(cfg) == true) {
    1385           0 :             data->rx_vlan_id_ = cfg->properties().sub_interface_vlan_tag;
    1386           0 :             data->tx_vlan_id_ = cfg->properties().sub_interface_vlan_tag;
    1387             :         }
    1388           0 :         if ((*phy_device) == NULL) {
    1389           0 :             return NULL;
    1390             :         }
    1391           0 :         return static_cast<PhysicalRouter *>((*phy_device)->GetObject());
    1392             :     }
    1393             : 
    1394             :     // Check if this is VLAN sub-interface VMI
    1395          66 :     if (IsVlanSubInterface(cfg) == false) {
    1396          66 :         return NULL;
    1397             :     }
    1398             : 
    1399           0 :     if (!parent_vmi_node)
    1400           0 :         return NULL;
    1401             : 
    1402             :     // process Parent VMI for sub-interface
    1403             :     VirtualMachineInterface *parent_cfg =
    1404           0 :         static_cast <VirtualMachineInterface *> (parent_vmi_node->GetObject());
    1405           0 :     assert(parent_cfg);
    1406           0 :     if (IsVlanSubInterface(parent_cfg)) {
    1407           0 :         return NULL;
    1408             :     }
    1409           0 :     autogen::IdPermsType id_perms = parent_cfg->id_perms();
    1410           0 :     CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
    1411           0 :                data->parent_vmi_);
    1412           0 :     data->rx_vlan_id_ = cfg->properties().sub_interface_vlan_tag;
    1413           0 :     data->tx_vlan_id_ = cfg->properties().sub_interface_vlan_tag;
    1414           0 :     return NULL;
    1415           0 : }
    1416             : 
    1417          70 : static void BuildEcmpHashingIncludeFields(VirtualMachineInterface *cfg,
    1418             :                                           IFMapNode *vn_node,
    1419             :                                           VmInterfaceConfigData *data) {
    1420          70 :     data->ecmp_load_balance_.set_use_global_vrouter(false);
    1421          70 :     if (cfg->IsPropertySet
    1422          70 :         (VirtualMachineInterface::ECMP_HASHING_INCLUDE_FIELDS) &&
    1423           0 :         (cfg->ecmp_hashing_include_fields().hashing_configured)) {
    1424           0 :         data->ecmp_load_balance_.UpdateFields(cfg->
    1425           0 :                                               ecmp_hashing_include_fields());
    1426             :     } else {
    1427             :         //Extract from VN
    1428          70 :         if (!vn_node) {
    1429           8 :             data->ecmp_load_balance_.reset();
    1430           8 :             data->ecmp_load_balance_.set_use_global_vrouter(true);
    1431           8 :             return;
    1432             :         }
    1433             :         VirtualNetwork *vn_cfg =
    1434          62 :             static_cast <VirtualNetwork *> (vn_node->GetObject());
    1435          62 :         if ((vn_cfg->IsPropertySet
    1436          62 :             (VirtualNetwork::ECMP_HASHING_INCLUDE_FIELDS) == false) ||
    1437           0 :             (vn_cfg->ecmp_hashing_include_fields().hashing_configured == false)) {
    1438          62 :             data->ecmp_load_balance_.set_use_global_vrouter(true);
    1439          62 :             data->ecmp_load_balance_.reset();
    1440          62 :             return;
    1441             :         }
    1442           0 :         data->ecmp_load_balance_.UpdateFields(vn_cfg->
    1443           0 :                                               ecmp_hashing_include_fields());
    1444             :     }
    1445             : 
    1446             : }
    1447             : 
    1448             : // Get IGMP configuration
    1449          70 : static void ReadIgmpConfig(Agent *agent, const IFMapNode *vn_node,
    1450             :                             const VirtualMachineInterface *cfg,
    1451             :                             VmInterfaceConfigData *data) {
    1452             : 
    1453          70 :     const VirtualNetwork *vn = NULL;
    1454          70 :     bool igmp_enabled = false;
    1455             : 
    1456          70 :     if (vn_node) {
    1457          62 :         vn = static_cast<const VirtualNetwork *>(vn_node->GetObject());
    1458             :     }
    1459             : 
    1460          70 :     if (cfg) igmp_enabled = cfg->igmp_enable();
    1461             : 
    1462          70 :     if (vn && !igmp_enabled) igmp_enabled = vn->igmp_enable();
    1463             : 
    1464          70 :     if (!igmp_enabled) {
    1465             :         igmp_enabled =
    1466          70 :                     agent->oper_db()->global_system_config()->cfg_igmp_enable();
    1467             :     }
    1468             : 
    1469          70 :     data->cfg_igmp_enable_ = cfg->igmp_enable();
    1470          70 :     data->igmp_enabled_ = igmp_enabled;
    1471             : 
    1472          70 :     return;
    1473             : }
    1474             : 
    1475             : // max_flows is read from vmi properties preferentially , else vn properties
    1476          70 : static void ReadMaxFlowsConfig(const IFMapNode *vn_node,
    1477             :                             const VirtualMachineInterface *cfg,
    1478             :                             VmInterfaceConfigData *data) {
    1479             : 
    1480          70 :     const VirtualNetwork *vn = NULL;
    1481          70 :     if (vn_node) {
    1482          62 :         vn = static_cast<const VirtualNetwork *>(vn_node->GetObject());
    1483             :     }
    1484             : 
    1485          70 :     if (cfg->IsPropertySet(VirtualMachineInterface::PROPERTIES)) {
    1486           0 :         data->max_flows_ = cfg->properties().max_flows;
    1487             :     }
    1488          70 :     if (vn && (data->max_flows_ == 0)) {
    1489          62 :         autogen::VirtualNetworkType properties = vn->properties();
    1490          62 :         data->max_flows_ = properties.max_flows;
    1491             : 
    1492          62 :     }
    1493          70 : }
    1494             : 
    1495          70 : static void BuildAttributes(Agent *agent, IFMapNode *node,
    1496             :                             VirtualMachineInterface *cfg,
    1497             :                             VmInterfaceConfigData *data) {
    1498             :     //Extract the local preference
    1499          70 :     if (cfg->IsPropertySet(VirtualMachineInterface::PROPERTIES)) {
    1500           0 :         data->local_preference_ = cfg->properties().local_preference;
    1501             :     }
    1502             : 
    1503          70 :     ReadAnalyzerNameAndCreate(agent, cfg, *data);
    1504             : 
    1505             :     // Fill DHCP option data
    1506          70 :     ReadDhcpOptions(cfg, *data);
    1507             : 
    1508             :     //Fill config data items
    1509          70 :     data->cfg_name_ = node->name();
    1510          70 :     data->admin_state_ = cfg->id_perms().enable;
    1511             : 
    1512          70 :     BuildVrfAssignRule(cfg, data);
    1513          70 :     BuildAllowedAddressPairRouteList(cfg, data);
    1514             : 
    1515          70 :     if (cfg->mac_addresses().size()) {
    1516           0 :         data->vm_mac_ = cfg->mac_addresses().at(0);
    1517             :     }
    1518          70 :     data->disable_policy_ = cfg->disable_policy();
    1519          70 :     BuildProxyArpFlags(agent, data, cfg);
    1520          70 : }
    1521             : 
    1522          70 : static void UpdateAttributes(Agent *agent, VmInterfaceConfigData *data) {
    1523             :     // Compute fabric_port_ and need_linklocal_ip_ flags
    1524          70 :     data->fabric_port_ = false;
    1525          70 :     data->need_linklocal_ip_ = true;
    1526         140 :     if (data->vrf_name_ == agent->fabric_vrf_name() ||
    1527          70 :         data->vrf_name_ == agent->linklocal_vrf_name()) {
    1528           0 :         data->fabric_port_ = true;
    1529           0 :         data->need_linklocal_ip_ = false;
    1530             :     }
    1531             : 
    1532          70 :     if (agent->isXenMode()) {
    1533           0 :         data->need_linklocal_ip_ = false;
    1534             :     }
    1535          70 : }
    1536             : 
    1537          70 : static void ComputeTypeInfo(Agent *agent, VmInterfaceConfigData *data,
    1538             :                             const PortSubscribeEntry *entry,
    1539             :                             PhysicalRouter *prouter,
    1540             :                             IFMapNode *node, IFMapNode *logical_node,
    1541             :                             IFMapNode *logical_router) {
    1542          70 :     if (entry != NULL) {
    1543             :         // Have got InstancePortAdd message. Treat it as VM_ON_TAP by default
    1544             :         // TODO: Need to identify more cases here
    1545          38 :         data->device_type_ = VmInterface::VM_ON_TAP;
    1546          38 :         data->vmi_type_ = VmInterface::INSTANCE;
    1547          38 :         return;
    1548             :     }
    1549             : 
    1550             :     VirtualMachineInterface *cfg = static_cast <VirtualMachineInterface *>
    1551          32 :                    (node->GetObject());
    1552          32 :     const std::vector<KeyValuePair> &bindings  = cfg->bindings();
    1553          32 :     bool vnic_type_direct = false;
    1554          32 :     bool vif_type_hw_veb = false;
    1555          32 :     for (std::vector<KeyValuePair>::const_iterator it = bindings.begin();
    1556          32 :          it != bindings.end(); ++it) {
    1557           0 :         KeyValuePair kvp = *it;
    1558           0 :         if ((kvp.key == "vnic_type") && (kvp.value == "direct")) {
    1559           0 :             vnic_type_direct = true;
    1560           0 :         } else if ((kvp.key == "vif_type") && (kvp.value == "hw_veb")) {
    1561           0 :             vif_type_hw_veb = true;
    1562             :         }
    1563           0 :     }
    1564             : 
    1565          32 :     if (vnic_type_direct && vif_type_hw_veb) {
    1566           0 :         data->device_type_ = VmInterface::VM_SRIOV;
    1567           0 :         data->vmi_type_ = VmInterface::SRIOV;
    1568           0 :         return;
    1569             :     }
    1570             : 
    1571          32 :     data->device_type_ = VmInterface::DEVICE_TYPE_INVALID;
    1572          32 :     data->vmi_type_ = VmInterface::VMI_TYPE_INVALID;
    1573             :     // Does it have physical-interface
    1574          32 :     if (data->physical_interface_.empty() == false) {
    1575             :         // no physical-router connected. Should be transient case
    1576           4 :         if (prouter == NULL) {
    1577             :             // HACK : TSN/ToR agent only supports barements. So, set as
    1578             :             // baremetal anyway
    1579           0 :             if (agent->tsn_enabled() || agent->tor_agent_enabled()) {
    1580           0 :                 data->device_type_ = VmInterface::TOR;
    1581           0 :                 data->vmi_type_ = VmInterface::BAREMETAL;
    1582             :             }
    1583           0 :             return;
    1584             :         }
    1585             : 
    1586             :         // VMI is either Baremetal or Gateway interface
    1587           4 :         if (prouter->display_name() == agent->agent_name()) {
    1588             :             // VMI connected to local vrouter. Treat it as GATEWAY / Remote VM.
    1589           0 :             if (agent->server_gateway_mode() ||
    1590           0 :                 agent->pbb_gateway_mode()) {
    1591           0 :                 data->device_type_ = VmInterface::REMOTE_VM_VLAN_ON_VMI;
    1592           0 :                 data->vmi_type_ = VmInterface::REMOTE_VM;
    1593             :             } else {
    1594           0 :                 data->device_type_ = VmInterface::LOCAL_DEVICE;
    1595           0 :                 data->vmi_type_ = VmInterface::GATEWAY;
    1596             :             }
    1597           0 :             if (logical_node) {
    1598             :                 autogen::LogicalInterface *port =
    1599             :                     static_cast <autogen::LogicalInterface *>
    1600           0 :                     (logical_node->GetObject());
    1601           0 :                 data->rx_vlan_id_ = port->vlan_tag();
    1602           0 :                 data->tx_vlan_id_ = port->vlan_tag();
    1603             :             }
    1604           0 :             return;
    1605             :         } else {
    1606             :             // prouter does not match. Treat as baremetal
    1607           4 :             data->device_type_ = VmInterface::TOR;
    1608           4 :             data->vmi_type_ = VmInterface::BAREMETAL;
    1609           4 :             return;
    1610             :         }
    1611             :         return;
    1612             :     }
    1613             : 
    1614             :     // Physical router not specified. Check if this is VMI sub-interface
    1615          28 :     if (data->parent_vmi_.is_nil() == false) {
    1616           0 :         data->device_type_ = VmInterface::VM_VLAN_ON_VMI;
    1617           0 :         data->vmi_type_ = VmInterface::INSTANCE;
    1618           0 :         return;
    1619             :     }
    1620             : 
    1621             :     // Logical Router attached node
    1622          28 :     if (logical_router) {
    1623             :         /*
    1624             :          * since logical-router type "snat-routing" is handled
    1625             :          * via service-instances, vmi update should happen only
    1626             :          * for logical-router type "vxlan-routing".
    1627             :          */
    1628             :         autogen::LogicalRouter *lr_obj =
    1629             :             static_cast <autogen::LogicalRouter *>
    1630           0 :             (logical_router->GetObject());
    1631           0 :         if (lr_obj->type() == "vxlan-routing") {
    1632           0 :             data->device_type_ = VmInterface::VMI_ON_LR;
    1633           0 :             data->vmi_type_ = VmInterface::ROUTER;
    1634             :         }
    1635           0 :         return;
    1636             :     }
    1637             : 
    1638          28 :     return;
    1639             : }
    1640             : 
    1641         280 : void CopyTagList(VmInterfaceConfigData *data,
    1642             :                  VmInterface::TagEntryList &tag_list, bool *label_added) {
    1643         280 :     bool dont_copy_label = *label_added;
    1644             : 
    1645         280 :     VmInterface::TagEntrySet::iterator tag_it;
    1646         280 :     for (tag_it = tag_list.list_.begin(); tag_it != tag_list.list_.end();
    1647           0 :          tag_it++) {
    1648           0 :         if (tag_it->type_ == TagTable::LABEL) {
    1649           0 :             *label_added = true;
    1650           0 :             if (dont_copy_label) {
    1651           0 :                 continue;
    1652             :             }
    1653             :         }
    1654           0 :         data->tag_list_.list_.insert(*tag_it);
    1655             :     }
    1656         280 : }
    1657             : 
    1658          70 : void CopyTag(VmInterfaceConfigData *data ,
    1659             :              VmInterface::TagEntryList &vmi_list,
    1660             :              VmInterface::TagEntryList &vm_list,
    1661             :              VmInterface::TagEntryList &vn_list,
    1662             :              VmInterface::TagEntryList &project_list) {
    1663          70 :     bool label_added = false;
    1664             :     //Order of below should be maintained
    1665             :     //This is becasue any tag present at VMI takes
    1666             :     //precedence over VM, VN and project and since
    1667             :     //tag type is key (except for label) duplicate
    1668             :     //insertion doesnt happen
    1669          70 :     CopyTagList(data, vmi_list, &label_added);
    1670          70 :     CopyTagList(data, vm_list, &label_added);
    1671          70 :     CopyTagList(data, vn_list, &label_added);
    1672          70 :     CopyTagList(data, project_list, &label_added);
    1673          70 : }
    1674             : 
    1675          70 : bool InterfaceTable::VmiProcessConfig(IFMapNode *node, DBRequest &req,
    1676             :                                       const boost::uuids::uuid &u) {
    1677             :     // Get interface UUID
    1678             :     VirtualMachineInterface *cfg = static_cast <VirtualMachineInterface *>
    1679          70 :         (node->GetObject());
    1680             : 
    1681          70 :     boost::uuids::uuid vmi_uuid = u;
    1682          70 :     assert(cfg);
    1683             :     // Handle object delete
    1684          70 :     if (node->IsDeleted()) {
    1685           0 :         return false;
    1686             :     }
    1687             : 
    1688          70 :     assert(!u.is_nil());
    1689             :     // Update interface configuration
    1690          70 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    1691          70 :     VmInterfaceConfigData *data = new VmInterfaceConfigData(agent(), NULL);
    1692          70 :     data->SetIFMapNode(node);
    1693             : 
    1694          70 :     BuildAttributes(agent_, node, cfg, data);
    1695             : 
    1696             :     // Graph walk to get interface configuration
    1697          70 :     IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table());
    1698          70 :     IFMapNode *vn_node = NULL;
    1699          70 :     IFMapNode *li_node = NULL;
    1700          70 :     IFMapNode *vpg_node = NULL;
    1701          70 :     IFMapNode *lr_node = NULL;
    1702          70 :     IFMapNode *phy_interface = NULL;
    1703          70 :     IFMapNode *phy_device = NULL;
    1704          70 :     IFMapNode *parent_vmi_node = NULL;
    1705          70 :     uint16_t rx_vlan_id = VmInterface::kInvalidVlanId;
    1706          70 :     uint16_t tx_vlan_id = VmInterface::kInvalidVlanId;
    1707          70 :     VmInterface::TagEntryList vmi_list;
    1708          70 :     VmInterface::TagEntryList vm_list;
    1709          70 :     VmInterface::TagEntryList vn_list;
    1710          70 :     VmInterface::TagEntryList project_list;
    1711          70 :     string service_intf_type = "";
    1712             : 
    1713          70 :     if (cfg->IsPropertySet(VirtualMachineInterface::PROPERTIES)) {
    1714           0 :         service_intf_type = cfg->properties().service_interface_type;
    1715           0 :         data->service_intf_type_ = cfg->properties().service_interface_type;
    1716             :         /* Overwrite service_intf_type if it is not left or right interface */
    1717           0 :         if (service_intf_type != "left" && service_intf_type != "right") {
    1718           0 :             service_intf_type = "";
    1719             :         }
    1720             :     }
    1721             : 
    1722          70 :     data->vmi_cfg_uuid_ = vmi_uuid;
    1723          70 :     std::list<IFMapNode *> bgp_as_a_service_node_list;
    1724          70 :     std::list<IFMapNode *> bgp_router_node_list;
    1725          70 :     for (DBGraphVertex::adjacency_iterator iter =
    1726          70 :          node->begin(table->GetGraph());
    1727         277 :          iter != node->end(table->GetGraph()); ++iter) {
    1728             : 
    1729         207 :         IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->());
    1730             :         /* SkipNode() will be true, if node is registed with dependency_manager.
    1731             :          * Eventhough bgp-router is registered with dependency_manager,
    1732             :          * bgp_routers associated to a vmi is passed to bgp-as-a-sercice
    1733             :          * process_config() for validation. */
    1734         207 :         if (agent_->config_manager()->SkipNode(adj_node)) {
    1735           0 :             if (strcmp(adj_node->table()->Typename(),
    1736           0 :                         BGP_ROUTER_CONFIG_NAME) != 0) {
    1737           0 :                 continue;
    1738             :             }
    1739             :         }
    1740             : 
    1741         207 :         if (adj_node->table() == agent_->cfg()->cfg_sg_table()) {
    1742           3 :             BuildSgList(data, adj_node);
    1743             :         }
    1744             : 
    1745         207 :         if (adj_node->table() == agent_->cfg()->cfg_tag_table()) {
    1746           0 :             BuildTagList(&vmi_list, adj_node);
    1747             :         }
    1748             : 
    1749         207 :         if (adj_node->table() == agent()->cfg()->cfg_slo_table()) {
    1750           0 :             uuid slo_uuid = nil_uuid();
    1751             :             autogen::SecurityLoggingObject *slo =
    1752             :                 static_cast<autogen::SecurityLoggingObject *>(adj_node->
    1753           0 :                                                               GetObject());
    1754           0 :             autogen::IdPermsType id_perms = slo->id_perms();
    1755           0 :             CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
    1756             :                        slo_uuid);
    1757           0 :             data->slo_list_.push_back(slo_uuid);
    1758           0 :         }
    1759             : 
    1760         207 :         if (adj_node->table() == agent_->cfg()->cfg_vn_table()) {
    1761          62 :             vn_node = adj_node;
    1762          62 :             BuildVn(data, adj_node, u, &vn_list);
    1763             :         }
    1764             : 
    1765         207 :         if (adj_node->table() == agent_->cfg()->cfg_qos_table()) {
    1766           0 :             BuildQosConfig(data, adj_node);
    1767             :         }
    1768             : 
    1769         207 :         if (adj_node->table() == agent_->cfg()->cfg_vm_table()) {
    1770          70 :             BuildVm(data, adj_node, u, &vm_list);
    1771             :         }
    1772             : 
    1773         207 :         if (adj_node->table() == agent_->cfg()->cfg_project_table()) {
    1774           0 :             BuildProject(data, adj_node, u, &project_list);
    1775             :         }
    1776             : 
    1777         207 :         if (adj_node->table() == agent_->cfg()->cfg_instanceip_table()) {
    1778          10 :             BuildInstanceIp(agent_, data, adj_node);
    1779             :         }
    1780             : 
    1781         207 :         if (adj_node->table() == agent_->cfg()->cfg_floatingip_table()) {
    1782           0 :             BuildFloatingIpList(agent_, data, adj_node);
    1783             :         }
    1784             : 
    1785         207 :         if (adj_node->table() == agent_->cfg()->cfg_aliasip_table()) {
    1786           0 :             BuildAliasIpList(this, data, adj_node);
    1787             :         }
    1788             : 
    1789         207 :         if (adj_node->table() == agent_->cfg()->cfg_vm_port_vrf_table()) {
    1790          58 :             BuildVrfAndServiceVlanInfo(agent_, data, adj_node);
    1791             :         }
    1792             : 
    1793         207 :         if (adj_node->table() == agent_->cfg()->cfg_route_table()) {
    1794           0 :             BuildStaticRouteList(data, adj_node);
    1795             :         }
    1796             : 
    1797         207 :         if (adj_node->table() == agent_->cfg()->cfg_subnet_table()) {
    1798           0 :             BuildResolveRoute(data, adj_node);
    1799             :         }
    1800             : 
    1801         207 :         if (adj_node->table() == agent_->cfg()->cfg_logical_port_table()) {
    1802           4 :             BuildInterfaceConfigurationData(agent(), adj_node,
    1803             :                                             &rx_vlan_id, &tx_vlan_id,
    1804             :                                             &li_node, &phy_interface,
    1805             :                                             &phy_device);
    1806             :         }
    1807             : 
    1808         207 :         if (adj_node->table() == agent_->cfg()->cfg_vm_interface_table()) {
    1809           0 :             parent_vmi_node = adj_node;
    1810             :         }
    1811             : 
    1812         207 :         if (strcmp(adj_node->table()->Typename(), BGP_AS_SERVICE_CONFIG_NAME) == 0) {
    1813           0 :             bgp_as_a_service_node_list.push_back(adj_node);
    1814             :         }
    1815             : 
    1816         207 :         if (strcmp(adj_node->table()->Typename(), BGP_ROUTER_CONFIG_NAME) == 0) {
    1817           0 :             bgp_router_node_list.push_back(adj_node);
    1818             :         }
    1819             : 
    1820         207 :         if (adj_node->table() == agent_->cfg()->cfg_vm_port_bridge_domain_table()) {
    1821           0 :             BuildBridgeDomainTable(agent_, data, adj_node);
    1822             :         }
    1823             : 
    1824         207 :         if (adj_node->table() == agent_->cfg()->cfg_port_tuple_table()) {
    1825           0 :             if (!service_intf_type.empty()) {
    1826           0 :                 BuildSiOtherVmi(agent_, data, adj_node, service_intf_type);
    1827             :             }
    1828           0 :             BuildVmiSiMode(agent_, data, adj_node);
    1829             :         }
    1830             : 
    1831         207 :         if (strcmp(adj_node->table()->Typename(), LOGICAL_ROUTER_NAME) == 0) {
    1832           0 :             if (BuildLogicalRouterData(agent_, data, node)) {
    1833           0 :                 lr_node = adj_node;
    1834             :             }
    1835             :         }
    1836             : 
    1837         207 :         if (strcmp(adj_node->table()->Typename(),
    1838         207 :                 VIRTUAL_PORT_GROUP_CONFIG_NAME) == 0) {
    1839           0 :             BuildInterfaceConfigurationDataFromVpg(agent(), adj_node,
    1840             :                                                    &vpg_node,
    1841             :                                                    &phy_interface,
    1842             :                                                    &phy_device);
    1843             :         }
    1844             :     }
    1845             : 
    1846             :     //Fill HBS data
    1847          70 :     FillHbsInfo(data, vn_node);
    1848             : 
    1849             :     // Fill IGMP data
    1850          70 :     ReadIgmpConfig(agent(), vn_node, cfg, data);
    1851             : 
    1852             :     // Read flow control parameter on vmi
    1853          70 :     ReadMaxFlowsConfig(vn_node, cfg, data);
    1854             : 
    1855          70 :     if (parent_vmi_node && data->vm_uuid_ == nil_uuid()) {
    1856             :         IFMapAgentTable *vmi_table = static_cast<IFMapAgentTable *>
    1857           0 :                                     (parent_vmi_node->table());
    1858           0 :         DBGraph *vmi_graph = vmi_table->GetGraph();
    1859             :         //iterate through links for paremt VMI for VM
    1860           0 :         for (DBGraphVertex::adjacency_iterator vmi_iter = parent_vmi_node->begin(vmi_graph);
    1861           0 :              vmi_iter != parent_vmi_node->end(vmi_graph); ++vmi_iter) {
    1862             : 
    1863           0 :             IFMapNode *vm_node = static_cast<IFMapNode *>(vmi_iter.operator->());
    1864           0 :             if (agent_->config_manager()->SkipNode(vm_node, agent_->cfg()->cfg_vm_table())) {
    1865           0 :                 continue;
    1866             :             }
    1867           0 :             BuildVm(data, vm_node, u, &vm_list);
    1868           0 :             break;
    1869             :         }
    1870             :     }
    1871             : 
    1872             : 
    1873          70 :     agent_->oper_db()->bgp_as_a_service()->ProcessConfig
    1874          70 :         (data->vrf_name_, bgp_router_node_list, bgp_as_a_service_node_list, u);
    1875          70 :     UpdateAttributes(agent_, data);
    1876          70 :     BuildFatFlowTable(agent_, u, data, node);
    1877             : 
    1878             :     // Get DHCP enable flag from subnet
    1879          70 :     if ((vn_node && data->addr_.to_ulong()) || (vn_node && !(data->ip6_addr_.is_unspecified()))) {
    1880          10 :         ReadDhcpEnable(agent_, data, vn_node);
    1881             :     }
    1882             : 
    1883             : 
    1884          70 :     PhysicalRouter *prouter = NULL;
    1885             :     // Build parent for the virtual-machine-interface
    1886          70 :     prouter = BuildParentInfo(agent_, cfg, node, li_node, vpg_node,
    1887             :                               data, parent_vmi_node, &phy_interface,
    1888             :                               &phy_device);
    1889          70 :     BuildEcmpHashingIncludeFields(cfg, vn_node, data);
    1890             : 
    1891             :     // Compare and log any mismatch in vm/vn between config and port-subscribe
    1892          70 :     PortSubscribeEntryPtr subscribe_entry;
    1893          70 :     PortIpcHandler *pih =  agent_->port_ipc_handler();
    1894          70 :     if (pih) {
    1895             :         subscribe_entry =
    1896          70 :             pih->port_subscribe_table()->Get(u, data->vm_uuid_, data->vn_uuid_);
    1897          70 :         CompareVnVm(u, data, subscribe_entry.get());
    1898          70 :         pih->port_subscribe_table()->HandleVmiIfnodeAdd(u, data);
    1899             :     }
    1900             : 
    1901             :     // Compute device-type and vmi-type for the interface
    1902          70 :     ComputeTypeInfo(agent_, data, subscribe_entry.get(), prouter, node,
    1903             :                     li_node, lr_node);
    1904             : 
    1905          70 :     if (cfg->display_name() == agent_->vhost_interface_name()) {
    1906           0 :         data->CopyVhostData(agent());
    1907           0 :         agent_->set_vhost_disable_policy(cfg->disable_policy());
    1908           0 :         vmi_uuid = nil_uuid();
    1909             :     }
    1910             : 
    1911          70 :     InterfaceKey *key = NULL;
    1912          70 :     if (cfg->display_name() == agent_->vhost_interface_name()) {
    1913           0 :         key = new VmInterfaceKey(AgentKey::RESYNC, vmi_uuid, cfg->display_name());
    1914          70 :     } else if (data->device_type_ == VmInterface::VM_ON_TAP ||
    1915          32 :                     data->device_type_ == VmInterface::DEVICE_TYPE_INVALID) {
    1916          66 :         key = new VmInterfaceKey(AgentKey::RESYNC, u, "");
    1917             :     } else {
    1918           4 :         key = new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, vmi_uuid,
    1919           4 :                 cfg->display_name());
    1920             :     }
    1921             : 
    1922          70 :     if (data->device_type_ != VmInterface::DEVICE_TYPE_INVALID) {
    1923          42 :         AddVmiToVmiType(u, data->device_type_);
    1924             :     }
    1925             : 
    1926          70 :     CopyTag(data, vmi_list, vm_list, vn_list, project_list);
    1927             : 
    1928          70 :     if (data->device_type_ == VmInterface::REMOTE_VM_VLAN_ON_VMI &&
    1929           0 :         (rx_vlan_id == VmInterface::kInvalidVlanId ||
    1930           0 :          tx_vlan_id == VmInterface::kInvalidVlanId)) {
    1931           0 :          req.key.reset(key);
    1932           0 :          req.data.reset(data);
    1933           0 :         return false;
    1934             :     }
    1935             : 
    1936          70 :     if (data->vm_mac_ == MacAddress::ZeroMac().ToString()) {
    1937           0 :         req.key.reset(key);
    1938           0 :         req.data.reset(data);
    1939           0 :         return false;
    1940             :     }
    1941             : 
    1942          70 :     req.key.reset(key);
    1943          70 :     req.data.reset(data);
    1944             : 
    1945          70 :     boost::uuids::uuid dev = nil_uuid();
    1946          70 :     if (prouter) {
    1947           4 :         autogen::IdPermsType id_perms = prouter->id_perms();
    1948           4 :         CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, dev);
    1949           4 :     }
    1950          70 :     UpdatePhysicalDeviceVnEntry(u, dev, data->vn_uuid_, vn_node);
    1951          70 :     vmi_ifnode_to_req_++;
    1952             : 
    1953          70 :     return true;
    1954          70 : }
    1955             : 
    1956          12 : static bool DeleteVmi(InterfaceTable *table, const uuid &u, DBRequest *req) {
    1957          12 :     int type = table->GetVmiToVmiType(u);
    1958          12 :     if (type <= (int)VmInterface::VMI_TYPE_INVALID)
    1959          10 :         return false;
    1960             : 
    1961           2 :     table->DelVmiToVmiType(u);
    1962             :     // Process delete based on VmiType
    1963           2 :     if (type == VmInterface::INSTANCE) {
    1964             :         // INSTANCE type are not added by config. We only do RESYNC
    1965           0 :         req->oper = DBRequest::DB_ENTRY_ADD_CHANGE;
    1966           0 :         req->key.reset(new VmInterfaceKey(AgentKey::RESYNC, u, ""));
    1967           0 :         req->data.reset(new VmInterfaceConfigData(NULL, NULL));
    1968           0 :         table->Enqueue(req);
    1969           0 :         return false;
    1970             :     } else {
    1971           2 :         VmInterface::Delete(table, u, VmInterface::CONFIG);
    1972           2 :         return false;
    1973             :     }
    1974             : }
    1975             : 
    1976         186 : bool InterfaceTable::VmiIFNodeToReq(IFMapNode *node, DBRequest &req,
    1977             :                                     const boost::uuids::uuid &u) {
    1978             :     // Handle object delete
    1979         186 :     if ((req.oper == DBRequest::DB_ENTRY_DELETE) || node->IsDeleted()) {
    1980          12 :         agent_->oper_db()->bgp_as_a_service()->DeleteVmInterface(u);
    1981          12 :         DelPhysicalDeviceVnEntry(u);
    1982          12 :         PortIpcHandler *pih =  agent_->port_ipc_handler();
    1983          12 :         if (pih) {
    1984          12 :             pih->port_subscribe_table()->HandleVmiIfnodeDelete(u);
    1985             :         }
    1986          12 :         return DeleteVmi(this, u, &req);
    1987             :     }
    1988             : 
    1989         174 :     IFMapDependencyManager *dep = agent()->oper_db()->dependency_manager();
    1990         174 :     IFMapNodeState *state = dep->IFMapNodeGet(node);
    1991         174 :     IFMapDependencyManager::IFMapNodePtr vm_node_ref;
    1992         174 :     if (!state) {
    1993           0 :         vm_node_ref = dep->SetState(node);
    1994           0 :         state = dep->IFMapNodeGet(node);
    1995             :     }
    1996             : 
    1997         174 :     if (state->uuid().is_nil())
    1998           0 :         state->set_uuid(u);
    1999             : 
    2000         174 :     agent()->config_manager()->AddVmiNode(node);
    2001         174 :     return false;
    2002         174 : }
    2003             : 
    2004         186 : bool InterfaceTable::VmiIFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u) {
    2005             : 
    2006             :     VirtualMachineInterface *cfg = static_cast <VirtualMachineInterface *>
    2007         186 :         (node->GetObject());
    2008         186 :     autogen::IdPermsType id_perms = cfg->id_perms();
    2009         186 :     CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u);
    2010         186 :     return true;
    2011         186 : }

Generated by: LCOV version 1.14