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 : }
|