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

Generated by: LCOV version 1.14