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