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