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