Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <cmn/dns.h>
6 : #include <bind/bind_util.h>
7 : #include <bind/bind_resolver.h>
8 : #include <mgr/dns_mgr.h>
9 : #include <mgr/dns_oper.h>
10 : #include <bind/named_config.h>
11 : #include <agent/agent_xmpp_channel.h>
12 : #include <sandesh/sandesh_types.h>
13 : #include <sandesh/common/vns_types.h>
14 : #include <vnc_cfg_types.h>
15 :
16 : #include <boost/bind/bind.hpp>
17 : #include "base/logging.h"
18 : #include "base/task.h"
19 : #include "base/util.h"
20 : #include "bind/bind_util.h"
21 : #include "cfg/dns_config.h"
22 : #include "cfg/config_listener.h"
23 : #include "ifmap/ifmap_link.h"
24 : #include "ifmap/ifmap_table.h"
25 : #include "cmn/dns.h"
26 : #include "xmpp/xmpp_server.h"
27 :
28 : using namespace std;
29 : using namespace boost::placeholders;
30 :
31 : ////////////////////////////////////////////////////////////////////////////////
32 :
33 : const std::string DnsConfig::EventString[] = {
34 : "Add",
35 : "Change",
36 : "Delete"
37 : };
38 : DnsConfig::Callback DnsConfig::VdnsCallback;
39 : DnsConfig::Callback DnsConfig::VdnsRecordCallback;
40 : DnsConfig::ZoneCallback DnsConfig::VdnsZoneCallback;
41 : VnniConfig::DataMap VnniConfig::vnni_config_;
42 : IpamConfig::DataMap IpamConfig::ipam_config_;
43 : VirtualDnsConfig::DataMap VirtualDnsConfig::virt_dns_config_;
44 : VirtualDnsRecordConfig::DataMap VirtualDnsRecordConfig::virt_dns_rec_config_;
45 : GlobalQosConfig *GlobalQosConfig::singleton_;
46 :
47 : ////////////////////////////////////////////////////////////////////////////////
48 :
49 16 : VnniConfig::VnniConfig(IFMapNode *node)
50 16 : : DnsConfig(node->name()), ipam_(NULL) {
51 16 : vnni_config_.insert(DataPair(GetName(), this));
52 16 : UpdateIpam(node);
53 16 : }
54 :
55 16 : VnniConfig::~VnniConfig() {
56 16 : vnni_config_.erase(name_);
57 16 : }
58 :
59 16 : void VnniConfig::OnAdd(IFMapNode *node) {
60 16 : MarkValid();
61 16 : FindSubnets(node, subnets_);
62 16 : if (!ipam_) {
63 0 : UpdateIpam(node);
64 : }
65 16 : if (ipam_ && ipam_->IsValid() && ipam_->GetVirtualDns()) {
66 5 : Subnets subnets;
67 5 : NotifySubnets(subnets, subnets_, ipam_->GetVirtualDns());
68 5 : ipam_->GetVirtualDns()->NotifyPendingDnsRecords();
69 5 : }
70 16 : }
71 :
72 16 : void VnniConfig::OnDelete() {
73 16 : MarkDelete();
74 16 : if (ipam_) {
75 7 : if (ipam_->IsValid() && ipam_->GetVirtualDns()) {
76 18 : for (unsigned int i = 0; i < subnets_.size(); i++) {
77 11 : VdnsZoneCallback(subnets_[i], ipam_->GetVirtualDns(),
78 : DnsConfig::CFG_DELETE);
79 : }
80 7 : ipam_->GetVirtualDns()->NotifyPendingDnsRecords();
81 : }
82 7 : ipam_->DelVnni(this);
83 : }
84 16 : }
85 :
86 14 : void VnniConfig::OnChange(IFMapNode *node) {
87 14 : Subnets old_subnets;
88 14 : subnets_.swap(old_subnets);
89 14 : FindSubnets(node, subnets_);
90 14 : if (!ipam_) {
91 0 : UpdateIpam(node);
92 : }
93 28 : if (ipam_ && ipam_->IsValid() && ipam_->GetVirtualDns() &&
94 14 : NotifySubnets(old_subnets, subnets_, ipam_->GetVirtualDns())) {
95 6 : ipam_->GetVirtualDns()->NotifyPendingDnsRecords();
96 : }
97 14 : }
98 :
99 16 : void VnniConfig::UpdateIpam(IFMapNode *node) {
100 16 : if (node) {
101 16 : IFMapNode *ipam_node = Dns::GetDnsConfigManager()->FindTarget(node,
102 : "virtual-network-network-ipam", "network-ipam");
103 16 : if (ipam_node == NULL) {
104 0 : DNS_TRACE(DnsError, "VirtualNetworkNetworkIpam <" + GetName() +
105 : "> does not have Ipam link");
106 0 : return;
107 : }
108 16 : ipam_ = IpamConfig::Find(ipam_node->name());
109 16 : if (!ipam_) {
110 0 : ipam_ = new IpamConfig(ipam_node);
111 : }
112 16 : ipam_->AddVnni(this);
113 : }
114 : }
115 :
116 30 : void VnniConfig::FindSubnets(IFMapNode *node, Subnets &subnets) {
117 30 : if (!node || node->IsDeleted())
118 0 : return;
119 :
120 : autogen::VirtualNetworkNetworkIpam *vnni =
121 30 : static_cast<autogen::VirtualNetworkNetworkIpam *> (node->GetObject());
122 30 : if (!vnni)
123 0 : return;
124 :
125 30 : const autogen::VnSubnetsType &subnets_type = vnni->data();
126 73 : for (unsigned int i = 0; i < subnets_type.ipam_subnets.size(); ++i) {
127 86 : Subnet subnet(subnets_type.ipam_subnets[i].subnet.ip_prefix,
128 43 : subnets_type.ipam_subnets[i].subnet.ip_prefix_len);
129 43 : subnets.push_back(subnet);
130 : }
131 30 : std::sort(subnets.begin(), subnets.end());
132 : }
133 :
134 19 : bool VnniConfig::NotifySubnets(Subnets &old_nets, Subnets &new_nets,
135 : VirtualDnsConfig *vdns) {
136 19 : bool change = false;
137 19 : Subnets::iterator it_old = old_nets.begin();
138 19 : Subnets::iterator it_new = new_nets.begin();
139 39 : while (it_old != old_nets.end() && it_new != new_nets.end()) {
140 20 : if (*it_old < *it_new) {
141 : // old entry is deleted
142 2 : it_old->MarkDelete();
143 2 : VdnsZoneCallback(*it_old, vdns, DnsConfig::CFG_DELETE);
144 2 : change = true;
145 2 : it_old++;
146 18 : } else if (*it_new < *it_old) {
147 : // new entry
148 0 : VdnsZoneCallback(*it_new, vdns, DnsConfig::CFG_ADD);
149 0 : change = true;
150 0 : it_new++;
151 : } else {
152 : // no change in entry
153 18 : it_old++;
154 18 : it_new++;
155 : }
156 : }
157 :
158 : // delete remaining old entries
159 21 : for (; it_old != old_nets.end(); ++it_old) {
160 2 : it_old->MarkDelete();
161 2 : VdnsZoneCallback(*it_old, vdns, DnsConfig::CFG_DELETE);
162 2 : change = true;
163 : }
164 :
165 : // add remaining new entries
166 28 : for (; it_new != new_nets.end(); ++it_new) {
167 9 : VdnsZoneCallback(*it_new, vdns, DnsConfig::CFG_ADD);
168 9 : change = true;
169 : }
170 :
171 19 : return change;
172 : }
173 :
174 46 : VnniConfig *VnniConfig::Find(std::string name) {
175 46 : if (name.empty())
176 0 : return NULL;
177 46 : DataMap::iterator iter = vnni_config_.find(name);
178 46 : if (iter != vnni_config_.end())
179 30 : return iter->second;
180 16 : return NULL;
181 : }
182 :
183 : ////////////////////////////////////////////////////////////////////////////////
184 :
185 9 : IpamConfig::IpamConfig(IFMapNode *node)
186 9 : : DnsConfig(node->name()), virtual_dns_(NULL) {
187 9 : GetObject(node, rec_);
188 9 : ipam_config_.insert(DataPair(GetName(), this));
189 9 : }
190 :
191 9 : IpamConfig::~IpamConfig() {
192 9 : for (VnniList::iterator it = vnni_list_.begin();
193 18 : it != vnni_list_.end(); ++it) {
194 9 : (*it)->ipam_ = NULL;
195 : }
196 9 : ipam_config_.erase(name_);
197 9 : }
198 :
199 9 : void IpamConfig::OnAdd(IFMapNode *node) {
200 9 : MarkValid();
201 9 : GetObject(node, rec_);
202 9 : Add(VirtualDnsConfig::Find(GetVirtualDnsName()));
203 9 : if (GetVirtualDns())
204 0 : GetVirtualDns()->NotifyPendingDnsRecords();
205 9 : }
206 :
207 9 : void IpamConfig::OnDelete() {
208 9 : Delete();
209 9 : if (GetVirtualDns())
210 3 : GetVirtualDns()->NotifyPendingDnsRecords();
211 9 : }
212 :
213 22 : void IpamConfig::OnChange(IFMapNode *node) {
214 22 : autogen::IpamType new_rec;
215 22 : GetObject(node, new_rec);
216 22 : if (new_rec.ipam_dns_server.virtual_dns_server_name != GetVirtualDnsName()) {
217 8 : Delete();
218 8 : if (GetVirtualDns())
219 8 : GetVirtualDns()->NotifyPendingDnsRecords();
220 8 : ClearDelete();
221 8 : rec_ = new_rec;
222 8 : Add(VirtualDnsConfig::Find(GetVirtualDnsName()));
223 8 : if (GetVirtualDns())
224 2 : GetVirtualDns()->NotifyPendingDnsRecords();
225 : } else
226 14 : rec_ = new_rec;
227 22 : }
228 :
229 17 : void IpamConfig::Add(VirtualDnsConfig *vdns) {
230 17 : virtual_dns_ = vdns;
231 17 : if (virtual_dns_) {
232 2 : virtual_dns_->AddIpam(this);
233 2 : Notify(DnsConfig::CFG_ADD);
234 : }
235 17 : }
236 :
237 17 : void IpamConfig::Delete() {
238 17 : MarkDelete();
239 17 : if (virtual_dns_) {
240 11 : Notify(DnsConfig::CFG_DELETE);
241 11 : virtual_dns_->DelIpam(this);
242 : }
243 17 : }
244 :
245 13 : void IpamConfig::Notify(DnsConfigEvent ev) {
246 13 : for (IpamConfig::VnniList::iterator it = vnni_list_.begin();
247 30 : it != vnni_list_.end(); ++it) {
248 17 : Subnets &subnets = (*it)->GetSubnets();
249 35 : for (unsigned int i = 0; i < subnets.size(); i++) {
250 18 : VdnsZoneCallback(subnets[i], virtual_dns_, ev);
251 : }
252 : }
253 13 : }
254 :
255 40 : bool IpamConfig::GetObject(IFMapNode *node, autogen::IpamType &data) {
256 40 : if (!node)
257 0 : return false;
258 :
259 : autogen::NetworkIpam *ipam =
260 40 : static_cast<autogen::NetworkIpam *>(node->GetObject());
261 40 : if (!ipam)
262 6 : return false;
263 :
264 34 : data = ipam->mgmt();
265 34 : return true;
266 : }
267 :
268 0 : void IpamConfig::Trace(const std::string &ev) {
269 0 : DNS_TRACE(IpamTrace, name_, GetVirtualDnsName(), ev);
270 0 : }
271 :
272 56 : IpamConfig *IpamConfig::Find(std::string name) {
273 56 : if (name.empty())
274 0 : return NULL;
275 56 : DataMap::iterator iter = ipam_config_.find(name);
276 56 : if (iter != ipam_config_.end())
277 47 : return iter->second;
278 9 : return NULL;
279 : }
280 :
281 11 : void IpamConfig::AssociateIpamVdns(VirtualDnsConfig *vdns) {
282 11 : for (DataMap::iterator iter = ipam_config_.begin();
283 38 : iter != ipam_config_.end(); ++iter) {
284 27 : IpamConfig *ipam = iter->second;
285 42 : if (!ipam->GetVirtualDns() &&
286 15 : ipam->GetVirtualDnsName() == vdns->GetName()) {
287 9 : ipam->virtual_dns_ = vdns;
288 9 : vdns->AddIpam(ipam);
289 : }
290 : }
291 11 : }
292 :
293 : ////////////////////////////////////////////////////////////////////////////////
294 :
295 11 : VirtualDnsConfig::VirtualDnsConfig(IFMapNode *node) : DnsConfig(node->name()) {
296 11 : GetObject(node, rec_);
297 11 : old_rec_ = rec_;
298 11 : virt_dns_config_.insert(DataPair(GetName(), this));
299 11 : }
300 :
301 0 : VirtualDnsConfig::VirtualDnsConfig(const std::string &name) : DnsConfig(name) {
302 0 : rec_.external_visible = false;
303 0 : rec_.reverse_resolution = false;
304 0 : old_rec_ = rec_;
305 0 : virt_dns_config_.insert(DataPair(GetName(), this));
306 0 : }
307 :
308 11 : VirtualDnsConfig::~VirtualDnsConfig() {
309 11 : virt_dns_config_.erase(name_);
310 11 : }
311 :
312 11 : void VirtualDnsConfig::OnAdd(IFMapNode *node) {
313 11 : if (!GetObject(node, rec_) || GetDomainName().empty())
314 0 : return;
315 11 : MarkValid();
316 : // Update any ipam configs dependent on this virtual dns
317 11 : IpamConfig::AssociateIpamVdns(this);
318 : // Update any records dependent on this virtual dns
319 11 : VirtualDnsRecordConfig::UpdateVirtualDns(this);
320 11 : VdnsCallback(this, DnsConfig::CFG_ADD);
321 11 : old_rec_ = rec_;
322 : // No notification for subnets is required here as the config was
323 : // available in the above notify
324 11 : NotifyPendingDnsRecords();
325 11 : Trace("Add");
326 : }
327 :
328 11 : void VirtualDnsConfig::OnDelete() {
329 11 : Trace("Delete");
330 11 : MarkDelete();
331 11 : VdnsCallback(this, DnsConfig::CFG_DELETE);
332 11 : for (VirtualDnsConfig::IpamList::iterator iter = ipams_.begin();
333 11 : iter != ipams_.end(); ++iter) {
334 0 : (*iter)->virtual_dns_ = NULL;
335 : }
336 11 : for (VirtualDnsConfig::VDnsRec::iterator it =
337 11 : virtual_dns_records_.begin();
338 15 : it != virtual_dns_records_.end(); ++it) {
339 4 : (*it)->virt_dns_ = NULL;
340 4 : (*it)->ClearNotified();
341 : }
342 11 : NotifyPendingDnsRecords();
343 11 : }
344 :
345 8 : void VirtualDnsConfig::OnChange(IFMapNode *node) {
346 8 : Trace("Change");
347 8 : if (!GetObject(node, rec_) || !HasChanged())
348 0 : return;
349 :
350 8 : bool notify = false;
351 8 : if (!IsValid()) {
352 0 : MarkValid();
353 : // Update any ipam configs dependent on this virtual dns
354 0 : IpamConfig::AssociateIpamVdns(this);
355 : // Update any records dependent on this virtual dns
356 0 : VirtualDnsRecordConfig::UpdateVirtualDns(this);
357 0 : notify = true;
358 : }
359 :
360 8 : VdnsCallback(this, DnsConfig::CFG_CHANGE);
361 8 : old_rec_ = rec_;
362 8 : if (notify) NotifyPendingDnsRecords();
363 : }
364 :
365 45 : void VirtualDnsConfig::AddRecord(VirtualDnsRecordConfig *record) {
366 45 : virtual_dns_records_.insert(record);
367 45 : }
368 :
369 18 : void VirtualDnsConfig::DelRecord(VirtualDnsRecordConfig *record) {
370 18 : virtual_dns_records_.erase(record);
371 18 : }
372 :
373 30 : bool VirtualDnsConfig::GetObject(IFMapNode *node,
374 : autogen::VirtualDnsType &data) {
375 30 : if (!node)
376 0 : return false;
377 :
378 : autogen::VirtualDns *dns =
379 30 : static_cast<autogen::VirtualDns *>(node->GetObject());
380 : // if (!dns || !dns->IsPropertySet(autogen::VirtualDns::ID_PERMS))
381 30 : if (!dns)
382 0 : return false;
383 :
384 30 : data = dns->data();
385 30 : return true;
386 : }
387 :
388 10 : bool VirtualDnsConfig::GetSubnet(const IpAddress &addr, Subnet &subnet) const {
389 10 : for (IpamList::iterator ipam_iter = ipams_.begin();
390 10 : ipam_iter != ipams_.end(); ++ipam_iter) {
391 8 : IpamConfig *ipam = *ipam_iter;
392 8 : const IpamConfig::VnniList &vnni = ipam->GetVnniList();
393 8 : for (IpamConfig::VnniList::iterator vnni_it = vnni.begin();
394 8 : vnni_it != vnni.end(); ++vnni_it) {
395 8 : Subnets &subnets = (*vnni_it)->GetSubnets();
396 12 : for (unsigned int i = 0; i < subnets.size(); i++) {
397 12 : if (subnets[i].Contains(addr)) {
398 8 : subnet = subnets[i];
399 8 : return true;
400 : }
401 : }
402 : }
403 : }
404 2 : return false;
405 : }
406 :
407 53 : void VirtualDnsConfig::NotifyPendingDnsRecords() {
408 53 : for (VirtualDnsConfig::VDnsRec::iterator it = virtual_dns_records_.begin();
409 131 : it != virtual_dns_records_.end(); ++it) {
410 78 : VirtualDnsRecordConfig *rec = *it;
411 78 : if (rec->CanNotify()) {
412 72 : if (!rec->IsNotified()) {
413 18 : VdnsRecordCallback(rec, DnsConfig::CFG_ADD);
414 : }
415 : } else {
416 6 : rec->ClearNotified();
417 : }
418 : }
419 53 : }
420 :
421 8 : bool VirtualDnsConfig::HasChanged() {
422 8 : if (rec_.domain_name == old_rec_.domain_name &&
423 16 : rec_.dynamic_records_from_client == old_rec_.dynamic_records_from_client &&
424 8 : rec_.record_order == old_rec_.record_order &&
425 16 : rec_.default_ttl_seconds == old_rec_.default_ttl_seconds &&
426 8 : rec_.next_virtual_DNS == old_rec_.next_virtual_DNS &&
427 8 : rec_.external_visible == old_rec_.external_visible &&
428 16 : rec_.reverse_resolution == old_rec_.reverse_resolution &&
429 0 : rec_.soa_record.negative_cache_ttl_seconds == old_rec_.soa_record.negative_cache_ttl_seconds)
430 0 : return false;
431 8 : return true;
432 : }
433 :
434 30 : void VirtualDnsConfig::VirtualDnsTrace(VirtualDnsTraceData &rec) {
435 30 : rec.name = name_;
436 30 : rec.dns_name = rec_.domain_name;
437 30 : rec.dns_dyn_rec = rec_.dynamic_records_from_client;
438 30 : rec.dns_order = rec_.record_order;
439 30 : rec.dns_ttl = rec_.default_ttl_seconds;
440 30 : rec.dns_next = rec_.next_virtual_DNS;
441 30 : rec.installed = (IsNotified() ? "true" : "false");
442 30 : rec.floating_ip_record = rec_.floating_ip_record;
443 30 : rec.external_visible = (rec_.external_visible ? "yes" : "no");
444 30 : rec.reverse_resolution = (rec_.reverse_resolution ? "yes" : "no");
445 30 : rec.flags = flags_;
446 30 : rec.negative_cache_ttl_seconds = rec_.soa_record.negative_cache_ttl_seconds;
447 30 : }
448 :
449 30 : void VirtualDnsConfig::Trace(const std::string &ev) {
450 30 : VirtualDnsTraceData rec;
451 30 : VirtualDnsTrace(rec);
452 30 : DNS_TRACE(VirtualDnsTrace, ev, rec);
453 30 : }
454 :
455 713 : std::string VirtualDnsConfig::GetViewName() const {
456 713 : std::string name(GetName());
457 713 : BindUtil::RemoveSpecialChars(name);
458 713 : return name;
459 0 : }
460 :
461 217 : std::string VirtualDnsConfig::GetNextDns() const {
462 217 : std::string name(rec_.next_virtual_DNS);
463 217 : BindUtil::RemoveSpecialChars(name);
464 217 : return name;
465 0 : }
466 :
467 0 : bool VirtualDnsConfig::DynamicUpdatesEnabled() const {
468 0 : return rec_.dynamic_records_from_client;
469 : }
470 :
471 69 : VirtualDnsConfig *VirtualDnsConfig::Find(std::string name) {
472 69 : if (name.empty())
473 6 : return NULL;
474 63 : DataMap::iterator iter = virt_dns_config_.find(name);
475 63 : if (iter != virt_dns_config_.end())
476 43 : return iter->second;
477 20 : return NULL;
478 : }
479 :
480 : ////////////////////////////////////////////////////////////////////////////////
481 :
482 22 : VirtualDnsRecordConfig::VirtualDnsRecordConfig(IFMapNode *node)
483 22 : : DnsConfig(node->name()), virt_dns_(NULL), src_(VirtualDnsRecordConfig::Config) {
484 22 : GetObject(node, rec_);
485 22 : virt_dns_rec_config_.insert(DataPair(GetName(), this));
486 22 : UpdateVdns(node);
487 22 : }
488 :
489 0 : VirtualDnsRecordConfig::VirtualDnsRecordConfig(const std::string &name,
490 : const std::string &vdns_name,
491 0 : const DnsItem &item)
492 0 : : DnsConfig(name), rec_(item), virt_dns_(NULL),
493 0 : src_(VirtualDnsRecordConfig::Agent) {
494 0 : virt_dns_rec_config_.insert(DataPair(GetName(), this));
495 0 : virt_dns_ = VirtualDnsConfig::Find(vdns_name);
496 0 : if (!virt_dns_) {
497 0 : virt_dns_ = new VirtualDnsConfig(vdns_name);
498 0 : virt_dns_->AddRecord(this);
499 : }
500 0 : virtual_dns_name_ = virt_dns_->GetName();
501 0 : }
502 :
503 22 : VirtualDnsRecordConfig::~VirtualDnsRecordConfig() {
504 22 : virt_dns_rec_config_.erase(name_);
505 22 : }
506 :
507 23 : void VirtualDnsRecordConfig::OnAdd(IFMapNode *node) {
508 23 : MarkValid();
509 23 : if (!virt_dns_) {
510 0 : if (!UpdateVdns(node)) {
511 0 : ClearValid();
512 : }
513 23 : } else if (!virt_dns_->IsValid()) {
514 18 : virt_dns_->AddRecord(this);
515 : } else {
516 5 : virt_dns_->AddRecord(this);
517 5 : if (CanNotify()) {
518 5 : VdnsRecordCallback(this, DnsConfig::CFG_ADD);
519 : }
520 : }
521 23 : Trace("Add");
522 23 : }
523 :
524 22 : void VirtualDnsRecordConfig::OnDelete() {
525 22 : Trace("Delete");
526 22 : MarkDelete();
527 22 : if (virt_dns_) {
528 18 : if (IsNotified()) {
529 18 : VdnsRecordCallback(this, DnsConfig::CFG_DELETE);
530 : }
531 18 : virt_dns_->DelRecord(this);
532 : }
533 22 : }
534 :
535 18 : void VirtualDnsRecordConfig::OnChange(IFMapNode *node) {
536 18 : DnsItem new_rec;
537 54 : if (!GetObject(node, new_rec) ||
538 36 : (IsValid() && !HasChanged(new_rec))) {
539 18 : return;
540 : }
541 0 : if (!virt_dns_) {
542 0 : MarkValid();
543 0 : if (!UpdateVdns(node)) {
544 0 : ClearValid();
545 : }
546 : }
547 : // For records, notify a change with a delete of the old record
548 : // followed by addition of new record; If only TTL has changed,
549 : // do not delete, as the order of delete and add processing is
550 : // not controlled and we might end up with deleted record
551 0 : if (IsNotified() && !OnlyTtlChange(new_rec)) {
552 0 : VdnsRecordCallback(this, DnsConfig::CFG_DELETE);
553 : }
554 0 : OnChange(new_rec);
555 18 : }
556 :
557 0 : void VirtualDnsRecordConfig::OnChange(const DnsItem &new_rec) {
558 0 : rec_ = new_rec;
559 0 : if (CanNotify()) {
560 0 : VdnsRecordCallback(this, DnsConfig::CFG_ADD);
561 : }
562 0 : Trace("Change");
563 0 : }
564 :
565 22 : bool VirtualDnsRecordConfig::UpdateVdns(IFMapNode *node) {
566 22 : if (!node) {
567 0 : return false;
568 : }
569 :
570 22 : IFMapNode *vdns_node = Dns::GetDnsConfigManager()->FindTarget(node,
571 : "virtual-DNS-virtual-DNS-record");
572 22 : if (vdns_node == NULL) {
573 0 : DNS_TRACE(DnsError, "Virtual DNS Record <" + GetName() +
574 : "> does not have virtual DNS link");
575 0 : return false;
576 : }
577 22 : virt_dns_ = VirtualDnsConfig::Find(vdns_node->name());
578 22 : if (!virt_dns_) {
579 8 : virt_dns_ = new VirtualDnsConfig(vdns_node);
580 : }
581 22 : virt_dns_->AddRecord(this);
582 22 : virtual_dns_name_ = virt_dns_->GetName();
583 22 : return true;
584 : }
585 :
586 83 : bool VirtualDnsRecordConfig::CanNotify() {
587 83 : if (!IsValid() || !virt_dns_ || !virt_dns_->IsValid())
588 4 : return false;
589 :
590 79 : if (rec_.eclass == DNS_CLASS_IN && rec_.type == DNS_PTR_RECORD) {
591 8 : if (!virt_dns_->IsReverseResolutionEnabled()) {
592 0 : return false;
593 : }
594 8 : IpAddress addr;
595 16 : if (BindUtil::IsIP(rec_.name, addr) ||
596 8 : BindUtil::GetAddrFromPtrName(rec_.name, addr)) {
597 8 : Subnet net;
598 8 : return virt_dns_->GetSubnet(addr, net);
599 : }
600 0 : if (!IsErrorLogged()) {
601 0 : DNS_CONFIGURATION_LOG(
602 : g_vns_constants.CategoryNames.find(Category::DNSAGENT)->second,
603 : SandeshLevel::SYS_ERR, "Invalid PTR Name",
604 : GetName(), rec_.name);
605 0 : MarkErrorLogged();
606 : }
607 0 : return false;
608 : }
609 :
610 71 : return true;
611 : }
612 :
613 18 : bool VirtualDnsRecordConfig::HasChanged(DnsItem &rhs) {
614 36 : if (rec_.name == rhs.name && rec_.type == rhs.type &&
615 18 : rec_.eclass == rhs.eclass && rec_.data == rhs.data &&
616 36 : rec_.ttl == rhs.ttl && rec_.priority == rhs.priority)
617 18 : return false;
618 0 : return true;
619 : }
620 :
621 0 : bool VirtualDnsRecordConfig::OnlyTtlChange(DnsItem &rhs) {
622 0 : if (rec_.name == rhs.name && rec_.type == rhs.type &&
623 0 : rec_.eclass == rhs.eclass && rec_.data == rhs.data &&
624 0 : rec_.ttl != rhs.ttl && rec_.priority == rhs.priority)
625 0 : return true;
626 0 : return false;
627 : }
628 :
629 80 : autogen::VirtualDnsType VirtualDnsRecordConfig::GetVDns() const {
630 80 : autogen::VirtualDnsType data;
631 80 : data.dynamic_records_from_client = false;
632 80 : data.default_ttl_seconds = 0;
633 80 : data.soa_record.negative_cache_ttl_seconds = 0;
634 80 : if (virt_dns_)
635 80 : data = virt_dns_->GetVDns();
636 80 : return data;
637 0 : }
638 :
639 82 : std::string VirtualDnsRecordConfig::GetViewName() const {
640 82 : if (virt_dns_) {
641 82 : return virt_dns_->GetViewName();
642 : } else
643 0 : return "";
644 : }
645 :
646 40 : bool VirtualDnsRecordConfig::GetObject(IFMapNode *node, DnsItem &item) {
647 40 : if (!node)
648 0 : return false;
649 :
650 : autogen::VirtualDnsRecord *rec =
651 40 : static_cast<autogen::VirtualDnsRecord *>(node->GetObject());
652 40 : if (!rec)
653 0 : return false;
654 :
655 40 : autogen::VirtualDnsRecordType rec_data = rec->data();
656 40 : item.eclass = BindUtil::DnsClass(rec_data.record_class);
657 40 : item.type = BindUtil::DnsType(rec_data.record_type);
658 40 : item.name = rec_data.record_name;
659 40 : item.data = rec_data.record_data;
660 40 : item.ttl = rec_data.record_ttl_seconds;
661 40 : item.priority = rec_data.record_mx_preference;
662 40 : item.source_name = rec_data.record_source_name;
663 40 : return true;
664 40 : }
665 :
666 48 : void VirtualDnsRecordConfig::VirtualDnsRecordTrace(VirtualDnsRecordTraceData &rec) {
667 48 : rec.name = name_;
668 48 : rec.rec_name = rec_.name;
669 48 : rec.rec_type = BindUtil::DnsType(rec_.type);
670 48 : if (rec_.eclass == DNS_CLASS_IN)
671 48 : rec.rec_class = "IN";
672 48 : rec.rec_data = rec_.data;
673 48 : rec.rec_ttl = rec_.ttl;
674 48 : if (src_ == VirtualDnsRecordConfig::Config)
675 48 : rec.source = "Config";
676 : else
677 0 : rec.source = "Agent";
678 48 : if (IsNotified())
679 26 : rec.installed = "true";
680 : else
681 22 : rec.installed = "false";
682 48 : rec.flags = flags_;
683 48 : rec.rec_source_name = rec_.source_name;
684 48 : }
685 :
686 45 : void VirtualDnsRecordConfig::Trace(const std::string &ev) {
687 45 : VirtualDnsRecordTraceData rec;
688 45 : VirtualDnsRecordTrace(rec);
689 45 : std::string dns_name;
690 45 : if (virt_dns_)
691 41 : dns_name = virt_dns_->name_;
692 45 : DNS_TRACE(VirtualDnsRecordTrace, ev, dns_name, rec);
693 45 : }
694 :
695 64 : VirtualDnsRecordConfig *VirtualDnsRecordConfig::Find(std::string name) {
696 64 : if (name.empty())
697 0 : return NULL;
698 64 : DataMap::iterator iter = virt_dns_rec_config_.find(name);
699 64 : if (iter != virt_dns_rec_config_.end())
700 42 : return iter->second;
701 22 : return NULL;
702 : }
703 :
704 : // Check virtual dns records having empty VDNS to see if they belong to
705 : // the vdns being added now; update the reference accordingly
706 11 : void VirtualDnsRecordConfig::UpdateVirtualDns(VirtualDnsConfig *vdns) {
707 11 : for (DataMap::iterator it = virt_dns_rec_config_.begin();
708 77 : it != virt_dns_rec_config_.end(); ++it) {
709 66 : if (!it->second || it->second->GetVirtualDns()) continue;
710 0 : if (it->second->virtual_dns_name_ == vdns->GetName()) {
711 0 : it->second->virt_dns_ = vdns;
712 0 : vdns->AddRecord(it->second);
713 : }
714 : }
715 11 : }
716 :
717 0 : GlobalQosConfig::GlobalQosConfig(IFMapNode *node)
718 0 : : DnsConfig(node->name()) {
719 0 : assert(singleton_ == NULL);
720 0 : singleton_ = this;
721 0 : }
722 :
723 0 : GlobalQosConfig::~GlobalQosConfig() {
724 0 : singleton_ = NULL;
725 0 : }
726 :
727 0 : GlobalQosConfig* GlobalQosConfig::Find(const string &name) {
728 0 : return singleton_;
729 : }
730 :
731 0 : void GlobalQosConfig::SetDscp() {
732 0 : XmppServer *server = Dns::GetXmppServer();
733 0 : if (server) {
734 0 : server->SetDscpValue(control_dscp_);
735 : }
736 0 : }
737 :
738 0 : void GlobalQosConfig::OnAdd(IFMapNode *node) {
739 0 : MarkValid();
740 : autogen::GlobalQosConfig *qos =
741 0 : static_cast<autogen::GlobalQosConfig *>(node->GetObject());
742 0 : if (!qos)
743 0 : return;
744 0 : const autogen::ControlTrafficDscpType &dscp = qos->control_traffic_dscp();
745 0 : if (control_dscp_ != dscp.control) {
746 0 : control_dscp_ = dscp.control;
747 0 : Sandesh::SetDscpValue(dscp.control);
748 0 : SetDscp();
749 : }
750 0 : if (analytics_dscp_ != dscp.analytics) {
751 0 : analytics_dscp_ = dscp.analytics;
752 : }
753 : }
754 :
755 0 : void GlobalQosConfig::OnDelete() {
756 0 : if (control_dscp_ != 0) {
757 0 : control_dscp_ = 0;
758 0 : SetDscp();
759 : }
760 0 : analytics_dscp_ = 0;
761 0 : }
762 :
763 0 : void GlobalQosConfig::OnChange(IFMapNode *node) {
764 0 : OnAdd(node);
765 0 : }
766 :
767 : ////////////////////////////////////////////////////////////////////////////////
|