LCOV - code coverage report
Current view: top level - vnsw/agent/cfg - cfg_mirror.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 13 437 3.0 %
Date: 2026-11-09 02:10:49 Functions: 5 20 25.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : 
       6             : #include <base/address.h>
       7             : 
       8             : #if defined(__GNUC__)
       9             : #include "base/compiler.h"
      10             : #if __GNUC_PREREQ(4, 5)
      11             : #pragma GCC diagnostic push
      12             : #pragma GCC diagnostic ignored "-Wunused-result"
      13             : #endif
      14             : #endif
      15             : 
      16             : #include <boost/uuid/random_generator.hpp>
      17             : 
      18             : #if defined(__GNUC__)
      19             : #if __GNUC_PREREQ(4, 6)
      20             : #pragma GCC diagnostic pop
      21             : #endif
      22             : #endif
      23             : 
      24             : #include <ifmap/ifmap_table.h>
      25             : #include <ifmap/ifmap_link.h>
      26             : #include <base/logging.h>
      27             : 
      28             : #include <cmn/agent_cmn.h>
      29             : #include <agent_types.h>
      30             : 
      31             : #include <cfg/cfg_init.h>
      32             : #include <cfg/cfg_mirror.h>
      33             : #include <oper/config_manager.h>
      34             : 
      35             : #include <oper/vn.h>
      36             : #include <oper/mirror_table.h>
      37             : #include <oper/interface_common.h>
      38             : 
      39             : #include <filter/traffic_action.h>
      40             : #include <filter/acl_entry_match.h>
      41             : #include <filter/acl_entry_spec.h>
      42             : #include <filter/acl.h>
      43             : 
      44           2 : void MirrorCfgTable::Shutdown() {
      45           2 : }
      46             : 
      47           2 : void MirrorCfgTable::Init() {
      48           2 :      return;
      49             : }
      50             : 
      51           0 : const char *MirrorCfgTable::Add(const MirrorCreateReq &cfg) {
      52           0 :     MirrorCfgKey key;
      53           0 :     boost::system::error_code ec;
      54           0 :     IpAddress sip;
      55           0 :     IpAddress dest_ip;
      56             :     MirrorEntryData::MirrorEntryFlags mirror_flag;
      57           0 :     key.handle = cfg.get_handle();
      58           0 :     if (key.handle.empty()) {
      59           0 :         return "Invalid Handle";
      60             :     }
      61             : 
      62           0 :     MirrorCfgTree::iterator it;
      63           0 :     it = mc_tree_.find(key);
      64           0 :     if (it != mc_tree_.end()) {
      65           0 :         return "Update not supported";
      66             :     }
      67             : 
      68           0 :     MirrorCfgEntry *entry = new MirrorCfgEntry;
      69           0 :     entry->key = key;
      70           0 :     if (cfg.get_nic_assisted_mirroring()) {
      71           0 :         if (cfg.get_nic_assisted_mirroring_vlan() == 0 ||
      72           0 :             cfg.get_nic_assisted_mirroring_vlan() >= 4095) {
      73           0 :             delete entry;
      74           0 :             return "Invalid Vlan";
      75             :         }
      76           0 :         MirrorTable::AddMirrorEntry(entry->key.handle,
      77           0 :                 cfg.get_nic_assisted_mirroring_vlan());
      78           0 :         goto update_acl;
      79             :     }
      80             : 
      81           0 :     entry->data.apply_vn = cfg.get_apply_vn();
      82           0 :     entry->data.src_vn = cfg.get_src_vn();
      83           0 :     entry->data.src_ip_prefix = cfg.get_src_ip_prefix();
      84           0 :     entry->data.src_ip_prefix_len = cfg.get_src_ip_prefix_len();
      85             : 
      86           0 :     entry->data.dst_vn = cfg.get_dst_vn();
      87           0 :     entry->data.dst_ip_prefix = cfg.get_dst_ip_prefix();
      88           0 :     entry->data.dst_ip_prefix_len = cfg.get_dst_ip_prefix_len();
      89             : 
      90           0 :     entry->data.start_src_port = cfg.get_start_src_port();
      91           0 :     entry->data.end_src_port = cfg.get_end_src_port();
      92             : 
      93           0 :     entry->data.start_dst_port = cfg.get_start_dst_port();
      94           0 :     entry->data.end_dst_port = cfg.get_end_dst_port();
      95             : 
      96           0 :     entry->data.protocol = cfg.get_protocol();
      97             : 
      98           0 :     entry->data.ip = cfg.get_ip();
      99           0 :     entry->data.udp_port = cfg.get_udp_port();
     100             : 
     101           0 :     entry->data.time_period = cfg.get_time_period();
     102           0 :     if (cfg.get_mirror_vrf().empty()) {
     103           0 :         entry->data.mirror_vrf = agent_cfg_->agent()->fabric_vrf_name();
     104             :     } else {
     105           0 :         entry->data.mirror_vrf = cfg.get_mirror_vrf();
     106             :     }
     107             : 
     108             :     // Send create request to Mirror Index table
     109           0 :     dest_ip = IpAddress::from_string(entry->data.ip, ec);
     110           0 :     if (ec.value() != 0) {
     111           0 :         delete entry;
     112           0 :         return "Invalid mirror destination address ";
     113             :     }
     114             : 
     115           0 :     if (entry->data.udp_port == 0) {
     116           0 :         delete entry;
     117           0 :         return "Invalid mirror destination port ";
     118             :     }
     119             : 
     120           0 :    sip = agent_cfg_->agent()->GetMirrorSourceIp(dest_ip);
     121           0 :    mirror_flag = MirrorTable::DecodeMirrorFlag(cfg.get_nhmode(),
     122           0 :                                                cfg.get_juniperheader());
     123           0 :     if (mirror_flag == MirrorEntryData::DynamicNH_With_JuniperHdr) {
     124           0 :         MirrorTable::AddMirrorEntry(entry->key.handle,
     125           0 :                                     entry->data.mirror_vrf, sip,
     126           0 :                                     agent_cfg_->agent()->mirror_port(),
     127           0 :                                     dest_ip, entry->data.udp_port);
     128           0 :     } else if (mirror_flag == MirrorEntryData::DynamicNH_Without_JuniperHdr) {
     129           0 :        MacAddress mac = MacAddress::FromString(cfg.get_analyzer_vm_mac());
     130           0 :         MirrorTable::AddMirrorEntry(entry->key.handle,entry->data.mirror_vrf,
     131           0 :                                     sip, agent_cfg_->agent()->mirror_port(),
     132           0 :                                     dest_ip, entry->data.udp_port, 0,
     133             :                                     mirror_flag, mac);
     134           0 :     } else if (mirror_flag == MirrorEntryData::StaticNH_Without_JuniperHdr) {
     135             : 
     136           0 :         dest_ip = IpAddress::from_string(cfg.get_vtep_dst_ip(), ec);
     137           0 :         if (ec.value() != 0) {
     138           0 :             delete entry;
     139           0 :             return "Invalid mirror destination address ";
     140             :         }
     141           0 :         sip = agent_cfg_->agent()->GetMirrorSourceIp(dest_ip);
     142           0 :         MirrorTable::AddMirrorEntry(entry->key.handle, entry->data.mirror_vrf,
     143           0 :                                     sip, agent_cfg_->agent()->mirror_port(),
     144           0 :                                     dest_ip, entry->data.udp_port,
     145           0 :                                     cfg.get_vni(), mirror_flag,
     146             :                                     MacAddress::ZeroMac());
     147             :     } else {
     148           0 :         delete entry;
     149           0 :         return "Mode not supported";
     150             :     }
     151             : 
     152           0 : update_acl:
     153             :     // Update ACL
     154           0 :     VnAclMap::iterator va_it;
     155           0 :     va_it = vn_acl_map_.find(entry->data.apply_vn);
     156             :     AclUuid dyn_acl_uuid;
     157           0 :     const char *str = NULL;
     158           0 :     int ace_id = 0;
     159           0 :     if (va_it == vn_acl_map_.end()) {
     160           0 :         dyn_acl_uuid = boost::uuids::random_generator() ();
     161           0 :         AclIdInfo acl_info;
     162           0 :         acl_info.id = dyn_acl_uuid;
     163           0 :         acl_info.num_of_entries++;
     164           0 :         ace_id = ++acl_info.ace_id_latest;
     165           0 :         vn_acl_map_.insert(std::pair<VnIdStr, AclIdInfo>(entry->data.apply_vn, acl_info));
     166             :         // Create ACL with given dyn_acl_uuid
     167           0 :         str = UpdateAclEntry(dyn_acl_uuid, true, entry, ace_id);
     168             :     } else {
     169           0 :         dyn_acl_uuid = va_it->second.id;
     170           0 :         va_it->second.num_of_entries++;
     171           0 :         ace_id = ++va_it->second.ace_id_latest;
     172           0 :         str = UpdateAclEntry(dyn_acl_uuid, false, entry, ace_id);
     173             :     }
     174             : 
     175           0 :     if (str != NULL) {
     176           0 :         delete entry;
     177           0 :         return str;
     178             :     } else {
     179           0 :         entry->ace_info.acl_id = dyn_acl_uuid;
     180           0 :         entry->ace_info.id = ace_id;
     181             :     }
     182             : 
     183           0 :     mc_tree_.insert(std::pair<MirrorCfgKey, MirrorCfgEntry *>(key, entry));
     184             : 
     185             : 
     186           0 :     IFMapNode *vn_node = agent_cfg_->cfg_vn_table()->FindNode(entry->data.apply_vn);
     187           0 :     if (vn_node && agent_cfg_->agent()->config_manager()->CanUseNode(vn_node)) {
     188           0 :         DBRequest req;
     189             :         boost::uuids::uuid id;
     190           0 :         agent_cfg_->agent()->vn_table()->IFNodeToUuid(vn_node, id);
     191           0 :         assert(agent_cfg_->agent()->vn_table()->IFNodeToReq(vn_node,
     192             :                     req, id) == false);
     193           0 :     }
     194           0 :     return NULL;
     195           0 : }
     196             : 
     197           0 : const char *MirrorCfgTable::UpdateAclEntry (AclUuid &uuid, bool create,
     198             :                                             MirrorCfgEntry *entry,
     199             :                                             int ace_id) {
     200           0 :     AclSpec acl_spec;
     201           0 :     AclEntrySpec ace_spec;
     202             : 
     203           0 :     acl_spec.acl_id = uuid;
     204           0 :     ace_spec.terminal = false;
     205           0 :     ace_spec.id = ace_id;
     206             : 
     207           0 :     if (!(entry->data.src_ip_prefix.empty())) {
     208           0 :         ace_spec.src_addr_type = AddressMatch::IP_ADDR;
     209           0 :         ace_spec.BuildAddressInfo(entry->data.src_ip_prefix,
     210             :                                   entry->data.src_ip_prefix_len,
     211             :                                   &ace_spec.src_ip_list);
     212             :     } else {
     213           0 :         ace_spec.src_addr_type = AddressMatch::NETWORK_ID;
     214           0 :         ace_spec.src_policy_id_str = entry->data.src_vn;
     215             :     }
     216             : 
     217           0 :     if (!(entry->data.dst_ip_prefix.empty())) {
     218           0 :         ace_spec.dst_addr_type = AddressMatch::IP_ADDR;
     219           0 :         ace_spec.BuildAddressInfo(entry->data.dst_ip_prefix,
     220             :                                   entry->data.dst_ip_prefix_len,
     221             :                                   &ace_spec.dst_ip_list);
     222             :     } else {
     223           0 :         ace_spec.dst_addr_type = AddressMatch::NETWORK_ID;
     224           0 :         ace_spec.dst_policy_id_str = entry->data.dst_vn;
     225             :     }
     226             : 
     227             :     RangeSpec rs;
     228           0 :     rs.min = entry->data.start_src_port;
     229           0 :     rs.max = entry->data.end_src_port;
     230           0 :     if ((rs.min == (uint16_t)-1) && (rs.max == (uint16_t)-1)) {
     231           0 :         rs.min = 0;
     232             :     }
     233           0 :     ace_spec.src_port.push_back(rs);
     234             : 
     235           0 :     rs.min = entry->data.start_dst_port;
     236           0 :     rs.max = entry->data.end_dst_port;
     237           0 :     if ((rs.min == (uint16_t)-1) && (rs.max == (uint16_t)-1)) {
     238           0 :         rs.min = 0;
     239             :     }
     240           0 :     ace_spec.dst_port.push_back(rs);
     241             : 
     242           0 :     if (entry->data.protocol == -1) {
     243           0 :         rs.min = 0x0;
     244           0 :         rs.max = 0xff;
     245             :     } else {
     246           0 :         rs.min = rs.max = entry->data.protocol;
     247             :     }
     248           0 :     ace_spec.protocol.push_back(rs);
     249             : 
     250             :     // Fill action part later
     251           0 :     ActionSpec action_spec;
     252           0 :     action_spec.ta_type = TrafficAction::MIRROR_ACTION;
     253           0 :     boost::system::error_code ec;
     254           0 :     action_spec.ma.ip = Ip4Address::from_string(entry->data.ip, ec);
     255           0 :     if (ec.value() != 0) {
     256           0 :         return "Invalid mirror destination address ";
     257             :     }
     258           0 :     action_spec.ma.port = entry->data.udp_port;
     259           0 :     action_spec.ma.vrf_name = entry->data.mirror_vrf;
     260           0 :     action_spec.ma.analyzer_name = entry->key.handle;
     261           0 :     ace_spec.action_l.push_back(action_spec);
     262             :     // Add the ace to the acl
     263           0 :     acl_spec.acl_entry_specs_.push_back(ace_spec);
     264             : 
     265             :     // Enqueue ACL request
     266           0 :     DBRequest req;
     267           0 :     AclKey *key = new AclKey(uuid);
     268           0 :     AclData *data = new AclData(agent_cfg_->agent(), NULL, acl_spec);
     269           0 :     data->ace_add = true;
     270           0 :     LOG(DEBUG, "Ace add: " << data->ace_add << ", Ace spec id:"
     271             :         << ace_spec.id.id_);
     272           0 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     273           0 :     req.key.reset(key);
     274           0 :     req.data.reset(data);
     275           0 :     agent_cfg_->agent()->acl_table()->Enqueue(&req);
     276             : 
     277           0 :     return NULL;
     278           0 : }
     279             : 
     280           0 : void MirrorCfgTable::Delete(MirrorCfgKey &key) {
     281           0 :     MirrorCfgTree::iterator it;
     282           0 :     it = mc_tree_.find(key);
     283           0 :     if (it == mc_tree_.end()) {
     284           0 :         return;
     285             :     }
     286             : 
     287           0 :     MirrorCfgEntry *entry = it->second;
     288           0 :     MirrorTable::DelMirrorEntry(entry->key.handle);
     289             : 
     290             :     // Update ACL
     291           0 :     VnAclMap::iterator va_it;
     292           0 :     va_it = vn_acl_map_.find(entry->data.apply_vn);
     293           0 :     va_it->second.num_of_entries--;
     294           0 :     if (va_it->second.num_of_entries) {
     295           0 :         DBRequest areq;
     296           0 :         areq.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     297           0 :         AclKey *akey = new AclKey(va_it->second.id);
     298           0 :         AclData *adata = new AclData(agent_cfg_->agent(),
     299           0 :                                      NULL, entry->ace_info.id);
     300           0 :         areq.key.reset(akey);
     301           0 :         areq.data.reset(adata);
     302           0 :         agent_cfg_->agent()->acl_table()->Enqueue(&areq);
     303             : 
     304             :         // delete entry from mv map
     305           0 :         delete entry;
     306           0 :         mc_tree_.erase(it);
     307           0 :         return;
     308           0 :     }
     309             : 
     310           0 :     DBRequest areq;
     311           0 :     areq.oper = DBRequest::DB_ENTRY_DELETE;
     312           0 :     AclKey *akey = new AclKey(va_it->second.id);
     313           0 :     areq.key.reset(akey);
     314           0 :     areq.data.reset(NULL);
     315           0 :     agent_cfg_->agent()->acl_table()->Enqueue(&areq);
     316             : 
     317           0 :     mc_tree_.erase(it);
     318             : 
     319             :     // delete from vn_acl map
     320           0 :     vn_acl_map_.erase(va_it);
     321             : 
     322           0 :     IFMapNode *vn_node = agent_cfg_->cfg_vn_table()->FindNode(entry->data.apply_vn);
     323           0 :     if (vn_node && agent_cfg_->agent()->config_manager()->CanUseNode(vn_node)) {
     324           0 :         DBRequest req;
     325             :         boost::uuids::uuid id;
     326           0 :         agent_cfg_->agent()->vn_table()->IFNodeToUuid(vn_node, id);
     327           0 :         assert(agent_cfg_->agent()->vn_table()->IFNodeToReq(vn_node,
     328             :                     req, id) == false);
     329           0 :     }
     330             : 
     331             :     // delete entry from mv map
     332           0 :     delete entry;
     333           0 :     return;
     334           0 : }
     335             : 
     336         651 : const boost::uuids::uuid MirrorCfgTable::GetMirrorUuid(const string &vn_name) const {
     337         651 :      VnAclMap::const_iterator va_it;
     338         651 :      va_it = vn_acl_map_.find(vn_name);
     339         651 :      if (va_it == vn_acl_map_.end()) {
     340         651 :          return boost::uuids::nil_uuid();
     341             :      }
     342             : 
     343           0 :      return va_it->second.id;
     344             : }
     345             : 
     346           0 : void MirrorCfgTable::SetMirrorCfgSandeshData(std::string &handle,
     347             :                          MirrorCfgDisplayResp &resp) {
     348           0 :     MirrorCfgTree::iterator it;
     349             : 
     350           0 :     std::vector<MirrorCfgSandesh> mc_l;
     351           0 :     for (it = mc_tree_.begin(); it != mc_tree_.end(); ++it) {
     352           0 :         MirrorCfgEntry *mc_entry = it->second;
     353           0 :         if (!handle.empty() && (handle != mc_entry->key.handle)) {
     354           0 :             continue;
     355             :         }
     356           0 :         MirrorCfgSandesh mc_s;
     357           0 :         mc_s.set_handle(mc_entry->key.handle);
     358           0 :         mc_s.set_apply_vn(mc_entry->data.apply_vn);
     359           0 :         mc_s.set_src_vn(mc_entry->data.src_vn);
     360           0 :         mc_s.set_src_ip_prefix(mc_entry->data.src_ip_prefix);
     361           0 :         mc_s.set_src_ip_prefix_len(mc_entry->data.src_ip_prefix_len);
     362           0 :         mc_s.set_dst_vn(mc_entry->data.dst_vn);
     363           0 :         mc_s.set_dst_ip_prefix(mc_entry->data.dst_ip_prefix);
     364           0 :         mc_s.set_dst_ip_prefix_len(mc_entry->data.dst_ip_prefix_len);
     365           0 :         mc_s.set_start_src_port(mc_entry->data.start_src_port);
     366           0 :         mc_s.set_end_src_port(mc_entry->data.end_src_port);
     367           0 :         mc_s.set_start_dst_port(mc_entry->data.start_dst_port);
     368           0 :         mc_s.set_end_dst_port(mc_entry->data.end_dst_port);
     369           0 :         mc_s.set_protocol(mc_entry->data.protocol);
     370           0 :         mc_s.set_ip(mc_entry->data.ip);
     371           0 :         mc_s.set_udp_port(mc_entry->data.udp_port);
     372           0 :         mc_s.set_time_period(mc_entry->data.time_period);
     373           0 :         mc_s.set_mirror_vrf(mc_entry->data.mirror_vrf);
     374           0 :         mc_l.push_back(mc_s);
     375           0 :     }
     376           0 :     resp.set_mcfg_l(mc_l);
     377           0 : }
     378             : 
     379           0 : void MirrorCfgTable::SetMirrorCfgVnSandeshData(std::string &vn_name,
     380             :                            MirrorCfgVnInfoResp &resp) {
     381           0 :     VnAclMap::iterator it;
     382           0 :     std::vector<VnAclInfo> vn_l;
     383           0 :     for (it = vn_acl_map_.begin(); it != vn_acl_map_.end(); ++it) {
     384           0 :         if (!vn_name.empty() && (vn_name != it->first)) {
     385           0 :             continue;
     386             :         }
     387           0 :         VnAclInfo vn_acl_info;
     388           0 :         vn_acl_info.set_vn_name(it->first);
     389           0 :         vn_acl_info.set_dyn_acl_uuid(UuidToString(it->second.id));
     390           0 :         vn_acl_info.set_num_of_entries(it->second.num_of_entries);
     391           0 :         vn_l.push_back(vn_acl_info);
     392           0 :     }
     393           0 :     resp.set_vn_acl_info_l(vn_l);
     394           0 : }
     395             : 
     396           0 : void MirrorCreateReq::HandleRequest() const {
     397           0 :     const char *str = Agent::GetInstance()->mirror_cfg_table()->Add(*this);
     398           0 :     MirrorCfgResp *resp = new MirrorCfgResp();
     399           0 :     resp->set_context(context());
     400           0 :     if (str == NULL) {
     401           0 :         str = "Success";
     402             :     }
     403           0 :     resp->set_resp(str);
     404           0 :     resp->Response();
     405           0 :     return;
     406             : }
     407             : 
     408           0 : void MirrorDeleteReq::HandleRequest() const {
     409           0 :     MirrorCfgKey key;
     410           0 :     key.handle = get_handle();
     411           0 :     Agent::GetInstance()->mirror_cfg_table()->Delete(key);
     412           0 :     MirrorCfgResp *resp = new MirrorCfgResp();
     413           0 :     resp->set_context(context());
     414           0 :     resp->Response();
     415           0 :     return;
     416           0 : }
     417             : 
     418           0 : void MirrorCfgDisplayReq::HandleRequest() const {
     419           0 :     std::string handle = get_handle();
     420           0 :     MirrorCfgDisplayResp *resp = new MirrorCfgDisplayResp();
     421           0 :     Agent::GetInstance()->mirror_cfg_table()->SetMirrorCfgSandeshData(handle, *resp);
     422           0 :     resp->set_context(context());
     423           0 :     resp->Response();
     424           0 :     return;
     425           0 : }
     426             : 
     427           0 : void MirrorCfgVnInfoReq::HandleRequest() const {
     428           0 :     std::string vn_name = get_vn_name();
     429           0 :     MirrorCfgVnInfoResp *resp = new MirrorCfgVnInfoResp();
     430           0 :     Agent::GetInstance()->mirror_cfg_table()->SetMirrorCfgVnSandeshData(vn_name, *resp);
     431           0 :     resp->set_context(context());
     432           0 :     resp->Response();
     433           0 :     return;
     434           0 : }
     435             : 
     436           2 : void IntfMirrorCfgTable::Shutdown() {
     437           2 : }
     438             : 
     439           2 : void IntfMirrorCfgTable::Init() {
     440           2 :      return;
     441             : }
     442             : 
     443           0 : const char *IntfMirrorCfgTable::Add(const IntfMirrorCreateReq &intf_mirror) {
     444           0 :     MirrorCfgKey key;
     445           0 :     boost::system::error_code ec;
     446             :     MirrorEntryData::MirrorEntryFlags mirror_flag;
     447             :     //const IntfMirrorCfgSandesh &intf_mirror = cfg.get_intf_mirr();
     448           0 :     key.handle = intf_mirror.get_handle();
     449           0 :     if (key.handle.empty()) {
     450           0 :         return "Invalid Handle";
     451             :     }
     452             : 
     453           0 :     IntfMirrorCfgTree::iterator it;
     454           0 :     it = intf_mc_tree_.find(key);
     455           0 :     if (it != intf_mc_tree_.end()) {
     456           0 :         return "Update not supported";
     457             :     }
     458             : 
     459           0 :     IntfMirrorCfgEntry *entry = new IntfMirrorCfgEntry;
     460           0 :     entry->key = key;
     461           0 :     if (intf_mirror.get_nic_assisted_mirroring()) {
     462           0 :         if (intf_mirror.get_nic_assisted_mirroring_vlan() == 0 ||
     463           0 :             intf_mirror.get_nic_assisted_mirroring_vlan() >= 4095) {
     464           0 :             delete entry;
     465           0 :             return "Invalid Vlan";
     466             :         }
     467           0 :         MirrorTable::AddMirrorEntry(entry->key.handle,
     468           0 :                 intf_mirror.get_nic_assisted_mirroring_vlan());
     469           0 :         goto intf_update;
     470             :     }
     471           0 :     entry->data.intf_id = StringToUuid(intf_mirror.get_intf_uuid());
     472           0 :     entry->data.intf_name = intf_mirror.get_intf_name();
     473           0 :     entry->data.mirror_dest.handle = intf_mirror.get_handle();
     474           0 :     entry->data.mirror_dest.dip = IpAddress::from_string(intf_mirror.get_ip(),
     475           0 :                                                          ec);
     476           0 :     if (ec.value() != 0) {
     477           0 :         delete entry;
     478           0 :         return "Invalid mirror destination address ";
     479             :     }
     480           0 :     if (intf_mirror.get_udp_port() == 0) {
     481           0 :         delete entry;
     482           0 :         return "Invald mirror destination port ";
     483             :     }
     484           0 :     entry->data.mirror_dest.dport = intf_mirror.get_udp_port();
     485           0 :     entry->data.mirror_dest.sip = agent_cfg_->agent()->
     486           0 :         GetMirrorSourceIp(entry->data.mirror_dest.dip);
     487           0 :     entry->data.mirror_dest.sport = agent_cfg_->agent()->mirror_port();
     488           0 :     entry->data.mirror_dest.time_period = intf_mirror.get_time_period();
     489           0 :     entry->data.mirror_dest.mirror_vrf = intf_mirror.get_mirror_vrf();
     490             : 
     491           0 :     mirror_flag = MirrorTable::DecodeMirrorFlag (intf_mirror.get_nhmode(),
     492           0 :             intf_mirror.get_juniperheader());
     493           0 :     if (mirror_flag == MirrorEntryData::DynamicNH_With_JuniperHdr) {
     494           0 :          MirrorTable::AddMirrorEntry(entry->key.handle,
     495           0 :                                      entry->data.mirror_dest.mirror_vrf,
     496           0 :                                      entry->data.mirror_dest.sip,
     497           0 :                                      entry->data.mirror_dest.sport,
     498           0 :                                      entry->data.mirror_dest.dip,
     499           0 :                                      entry->data.mirror_dest.dport);
     500           0 :      } else if (mirror_flag == MirrorEntryData::DynamicNH_Without_JuniperHdr) {
     501           0 :         MacAddress mac = MacAddress::FromString(intf_mirror.get_analyzer_vm_mac());
     502           0 :         MirrorTable::AddMirrorEntry(entry->key.handle,
     503           0 :                                     entry->data.mirror_dest.mirror_vrf,
     504           0 :                                     entry->data.mirror_dest.sip,
     505           0 :                                     entry->data.mirror_dest.sport,
     506           0 :                                     entry->data.mirror_dest.dip,
     507           0 :                                     entry->data.mirror_dest.dport, 0,
     508             :                                     mirror_flag, mac);
     509           0 :      } else if (mirror_flag == MirrorEntryData::StaticNH_Without_JuniperHdr) {
     510           0 :          IpAddress dst_ip = IpAddress::from_string(intf_mirror.get_vtep_dst_ip(), ec);
     511           0 :          if (ec.value() != 0) {
     512           0 :              delete entry;
     513           0 :              return "Invalid mirror destination address ";
     514             :          }
     515           0 :          MirrorTable::AddMirrorEntry(entry->key.handle,
     516           0 :                                      entry->data.mirror_dest.mirror_vrf,
     517           0 :                                      entry->data.mirror_dest.sip,
     518           0 :                                      entry->data.mirror_dest.sport,
     519           0 :                                      dst_ip, entry->data.mirror_dest.dport,
     520           0 :                                      intf_mirror.get_vni(), mirror_flag,
     521             :                                      MacAddress::ZeroMac());
     522             :      } else {
     523           0 :         delete entry;
     524           0 :         return "not supported";
     525             :      }
     526           0 : intf_update:
     527           0 :     intf_mc_tree_.insert(std::pair<MirrorCfgKey, IntfMirrorCfgEntry *>(key, entry));
     528             : 
     529             :     VmInterfaceKey *intf_key = new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE,
     530           0 :                                                   entry->data.intf_id,
     531           0 :                                                   entry->data.intf_name);
     532             :     Interface *intf;
     533           0 :     intf = static_cast<Interface *>(agent_cfg_->agent()->interface_table()->FindActiveEntry(intf_key));
     534           0 :     if (intf) {
     535           0 :         DBRequest req;
     536           0 :         req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     537           0 :         req.key.reset(intf_key);
     538             :         VmInterfaceMirrorData *intf_data =
     539           0 :             new VmInterfaceMirrorData(true, entry->key.handle);
     540           0 :         req.data.reset(intf_data);
     541           0 :         agent_cfg_->agent()->interface_table()->Enqueue(&req);
     542           0 :     } else {
     543           0 :         delete intf_key;
     544             :     }
     545             : 
     546           0 :     return NULL;
     547           0 : }
     548             : 
     549           0 : void IntfMirrorCfgTable::Delete(MirrorCfgKey &key) {
     550           0 :     IntfMirrorCfgTree::iterator it;
     551           0 :     it = intf_mc_tree_.find(key);
     552           0 :     if (it == intf_mc_tree_.end()) {
     553           0 :         return;
     554             :     }
     555           0 :     IntfMirrorCfgEntry *entry = it->second;
     556           0 :     MirrorTable::DelMirrorEntry(entry->key.handle);
     557             : 
     558             :     VmInterfaceKey *intf_key = new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE,
     559           0 :                                                   entry->data.intf_id,
     560           0 :                                                   entry->data.intf_name);
     561             :     Interface *intf;
     562           0 :     intf = static_cast<Interface *>(agent_cfg_->agent()->interface_table()->FindActiveEntry(intf_key));
     563           0 :     if (intf) {
     564           0 :         DBRequest req;
     565           0 :         req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     566           0 :         req.key.reset(intf_key);
     567             :         VmInterfaceMirrorData *intf_data =
     568           0 :             new VmInterfaceMirrorData(false, std::string());
     569           0 :         req.data.reset(intf_data);
     570           0 :         agent_cfg_->agent()->interface_table()->Enqueue(&req);
     571           0 :     } else {
     572           0 :         delete intf_key;
     573             :     }
     574             : 
     575           0 :     delete entry;
     576           0 :     intf_mc_tree_.erase(it);
     577             : }
     578             : 
     579           0 : void IntfMirrorCreateReq::HandleRequest() const {
     580           0 :     const char *str = Agent::GetInstance()->interface_mirror_cfg_table()->Add(*this);
     581           0 :     MirrorCfgResp *resp = new MirrorCfgResp();
     582           0 :     resp->set_context(context());
     583           0 :     if (str == NULL) {
     584           0 :         str = "Success";
     585             :     }
     586           0 :     resp->set_resp(str);
     587           0 :     resp->Response();
     588           0 :     return;
     589             : }
     590             : 
     591           0 : void IntfMirrorDeleteReq::HandleRequest() const {
     592           0 :     MirrorCfgKey key;
     593           0 :     key.handle = get_handle();
     594           0 :     Agent::GetInstance()->interface_mirror_cfg_table()->Delete(key);
     595           0 :     MirrorCfgResp *resp = new MirrorCfgResp();
     596           0 :     resp->set_context(context());
     597           0 :     resp->set_resp("Success");
     598           0 :     resp->Response();
     599           0 :     return;
     600           0 : }
     601             : 
     602           0 : void IntfMirrorCfgTable::SetIntfMirrorCfgSandeshData(std::string &handle,
     603             :                                             IntfMirrorCfgDisplayResp &resp) {
     604           0 :     IntfMirrorCfgTree::iterator it;
     605           0 :     std::vector<IntfMirrorCfgSandesh> mc_l;
     606           0 :     for (it = intf_mc_tree_.begin(); it != intf_mc_tree_.end(); ++it) {
     607           0 :         IntfMirrorCfgEntry *mc_entry = it->second;
     608           0 :         if (!handle.empty() && (handle != mc_entry->key.handle)) {
     609           0 :             continue;
     610             :         }
     611           0 :         IntfMirrorCfgSandesh mc_s;
     612           0 :         mc_s.set_handle(mc_entry->key.handle);
     613           0 :         mc_s.set_intf_uuid(UuidToString(mc_entry->data.intf_id));
     614           0 :         mc_s.set_intf_name(mc_entry->data.intf_name);
     615           0 :         mc_s.set_ip(mc_entry->data.mirror_dest.dip.to_string());
     616           0 :         mc_s.set_udp_port(mc_entry->data.mirror_dest.dport);
     617           0 :         mc_s.set_time_period(mc_entry->data.mirror_dest.time_period);
     618           0 :         mc_s.set_mirror_vrf(mc_entry->data.mirror_dest.mirror_vrf);
     619           0 :         mc_l.push_back(mc_s);
     620           0 :     }
     621           0 :     resp.set_imcfg_l(mc_l);
     622           0 : }
     623             : 
     624           0 : void IntfMirrorCfgDisplayReq::HandleRequest() const {
     625           0 :     std::string handle = get_handle();
     626           0 :     IntfMirrorCfgDisplayResp *resp = new IntfMirrorCfgDisplayResp();
     627           0 :     Agent::GetInstance()->interface_mirror_cfg_table()->SetIntfMirrorCfgSandeshData(handle, *resp);
     628           0 :     resp->set_context(context());
     629           0 :     resp->Response();
     630           0 :     return;
     631           0 : }

Generated by: LCOV version 1.14