OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
dns_proto.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <sys/types.h>
6 #include "base/address_util.h"
7 #include "init/agent_init.h"
9 #include "services/dns_proto.h"
10 #include "bind/bind_resolver.h"
11 #include "cmn/agent_cmn.h"
12 #include "init/agent_param.h"
13 #include "ifmap/ifmap_link.h"
14 #include "ifmap/ifmap_table.h"
15 #include "pkt/pkt_init.h"
17 #include "oper/global_qos_config.h"
18 #include "oper/vn.h"
19 #include "oper/route_common.h"
20 #include <fstream>
21 
23 const Ip6Address DnsProto::ip6_unspec_ = Ip6Address::from_string("::");
24 
27 
28  for (DnsBindQueryMap::iterator it = dns_query_map_.begin();
29  it != dns_query_map_.end(); ) {
30  DnsBindQueryMap::iterator next = it++;
31  delete it->second;
32  it = next;
33  }
34 
35  curr_vm_requests_.clear();
36  // Following tables should be deleted when all VMs are gone
37  assert(update_set_.empty());
38  assert(all_vms_.empty());
39 }
40 
45  this));
46  std::vector<BindResolver::DnsServer> dns_servers;
47  for (int i = 0; i < MAX_XMPP_SERVERS; i++) {
48  std::string server = agent()->dns_server(i);
49  if (server != "")
50  dns_servers.push_back(BindResolver::DnsServer(
51  server, agent()->dns_server_port(i)));
52  }
53  GlobalQosConfig* qos = NULL;
54  uint8_t dscp = 0;
55  if (agent_->oper_db()) {
56  qos = agent_->oper_db()->global_qos_config();
57  }
58  if (qos && qos->control_dscp() != GlobalQosConfig::kInvalidDscp) {
59  dscp = qos->dns_dscp();
60  }
61  BindResolver::Init(*agent()->event_manager()->io_service(), dns_servers,
62  agent()->params()->dns_client_port(),
63  boost::bind(&DnsProto::SendDnsIpc, this, _1, _2), dscp);
64 }
65 
66 DnsProto::DnsProto(Agent *agent, boost::asio::io_context &io) :
67  Proto(agent, "Agent::Services", PktHandler::DNS, io),
68  xid_(0), timeout_(agent->params()->dns_timeout()),
69  max_retries_(agent->params()->dns_max_retries()) {
70  // limit the number of entries in the workqueue
72  work_queue_.SetBounded(true);
73  def_server_list_.clear();
74  default_slist_timer_ = TimerManager::CreateTimer(io, "DnsDefSlistTimer",
76  GetTaskId("Agent::Services"), PktHandler::DNS);
77 
78  lid_ = agent->interface_table()->Register(
79  boost::bind(&DnsProto::InterfaceNotify, this, _2));
80  Vnlid_ = agent->vn_table()->Register(
81  boost::bind(&DnsProto::VnNotify, this, _2));
82  if (agent->tsn_enabled()) {
84  agent->vrf_table()->Register(boost::bind(&DnsProto::VrfNotify,
85  this, _2));
86  }
88  boost::bind(&DnsProto::IpamNotify, this, _1));
90  boost::bind(&DnsProto::VdnsNotify, this, _1));
92  (boost::bind(&DnsProto::UpdateFloatingIp, this, _1, _2, _3, _4));
93 
95  (boost::bind(&DnsProto::SendDnsUpdateIpc, this, _1, _2, _3, _4));
97  (boost::bind(&DnsProto::SendDnsUpdateIpc, this, _1));
98 }
99 
101 }
102 
106  if (agent_->tsn_enabled()) {
108  }
111 }
112 
114  def_server_list_ = BuildDefaultServerListImpl(); // assign new contents
115  return true;
116 }
117 
118 std::vector<IpAddress> DnsProto::GetDefaultServerList() {
119  return def_server_list_;
120 }
121 
122 ProtoHandler *DnsProto::AllocProtoHandler(boost::shared_ptr<PktInfo> info,
123  boost::asio::io_context &io) {
124  return new DnsHandler(agent(), info, io);
125 }
126 
128  Interface *itf = static_cast<Interface *>(entry);
129  if (itf->type() != Interface::VM_INTERFACE)
130  return;
131 
132  const VmInterface *vmitf = static_cast<VmInterface *>(entry);
133  if (entry->IsDeleted()) {
134  SendDnsUpdateIpc(NULL, DnsAgentXmpp::Update, vmitf, false);
135  SendDnsUpdateIpc(NULL, DnsAgentXmpp::Update, vmitf, true);
136  all_vms_.erase(vmitf);
137  DNS_BIND_TRACE(DnsBindTrace, "Vm Interface deleted : " <<
138  vmitf->vm_name());
139  // remove floating ip entries from fip list
140  const VmInterface::FloatingIpList &fip = vmitf->floating_ip_list();
141  for (VmInterface::FloatingIpSet::iterator it = fip.list_.begin(),
142  next = fip.list_.begin(); it != fip.list_.end(); it = next) {
143  ++next;
144  UpdateFloatingIp(vmitf, it->vn_.get(), it->floating_ip_,true);
145  }
146  } else {
147  autogen::VirtualDnsType vdns_type;
148  std::string vdns_name;
149  GetVdnsData(vmitf->vn(), vmitf->primary_ip_addr(),
150  vmitf->primary_ip6_addr(),
151  vdns_name, vdns_type);
152  VmDataMap::iterator it = all_vms_.find(vmitf);
153  if (it == all_vms_.end()) {
154  if (!UpdateDnsEntry(vmitf, vmitf->vn(), vmitf->vm_name(), vdns_name,
155  vmitf->primary_ip_addr(), vmitf->primary_ip6_addr(),
156  false, false))
157  vdns_name = "";
158  IpVdnsMap vmdata;
159  vmdata.insert(IpVdnsPair(vmitf->primary_ip_addr().to_ulong(), vdns_name));
160  all_vms_.insert(VmDataPair(vmitf, vmdata));
161  DNS_BIND_TRACE(DnsBindTrace, "Vm Interface added : " <<
162  vmitf->vm_name());
163  } else {
164  CheckForUpdate(it->second, vmitf, vmitf->vn(),
165  vmitf->primary_ip_addr(), vmitf->primary_ip6_addr(),
166  vdns_name, vdns_type);
167  }
168 
169  // floating ip activate & de-activate are updated via the callback to
170  // UpdateFloatingIp; If tenant name is also required in the fip name,
171  // it may not be available during activate if the vm interface doesnt
172  // have vn at that time. Invoke Update here to handle that case.
173  if (vmitf->vn()) {
174  const VmInterface::FloatingIpList &fip = vmitf->floating_ip_list();
175  for (VmInterface::FloatingIpSet::iterator it = fip.list_.begin();
176  it != fip.list_.end(); ++it) {
177  if (it->Installed()) {
178  UpdateFloatingIp(vmitf, it->vn_.get(),
179  it->floating_ip_, false);
180  }
181  }
182  }
183  }
184 }
185 
187  const VnEntry *vn = static_cast<const VnEntry *>(entry);
188  if (vn->IsDeleted()) {
189  // remove floating ip entries from this vn in floating ip list
190  // Ip4Address is the smallest address
191  IpAddress ip_key = Ip4Address(0);
192  DnsFipEntryPtr key(new DnsFipEntry(vn, ip_key, NULL));
193  DnsFipSet::iterator it = fip_list_.upper_bound(key);
194  while (it != fip_list_.end()) {
195  DnsFipEntry *entry = (*it).get();
196  if (entry->vn_ != vn) {
197  break;
198  }
199  ++it;
200  UpdateFloatingIp(entry->interface_, entry->vn_,
201  entry->floating_ip_, true);
202  }
203  return;
204  }
205  if (vn->GetVnIpam().size() == 0)
206  return;
207  DNS_BIND_TRACE(DnsBindTrace, "Vn Notify : " << vn->GetName());
208  for (VmDataMap::iterator it = all_vms_.begin(); it != all_vms_.end(); ++it) {
209  if (it->first->vn() == vn) {
210  std::string vdns_name;
211  autogen::VirtualDnsType vdns_type;
212  GetVdnsData(vn, it->first->primary_ip_addr(),
213  it->first->primary_ip6_addr(),
214  vdns_name, vdns_type);
215  CheckForUpdate(it->second, it->first, it->first->vn(),
216  it->first->primary_ip_addr(),
217  it->first->primary_ip6_addr(),
218  vdns_name, vdns_type);
219  }
220  }
221  IpAddress ip_key = Ip4Address(0);
222  DnsFipEntryPtr key(new DnsFipEntry(vn, ip_key, NULL));
223  DnsFipSet::iterator it = fip_list_.upper_bound(key);
224  while (it != fip_list_.end()) {
225  std::string fip_vdns_name;
226  DnsFipEntry *entry = (*it).get();
227  if (entry->vn_ != vn) {
228  break;
229  }
230  autogen::VirtualDnsType fip_vdns_type;
231  Ip4Address ip4 = ip4_unspec_;
232  Ip6Address ip6 = ip6_unspec_;
233  if (entry->floating_ip_.is_v4()) {
234  ip4 = entry->floating_ip_.to_v4();
235  }
236  if (entry->floating_ip_.is_v6()) {
237  ip6 = entry->floating_ip_.to_v6();
238  }
239  GetVdnsData(entry->vn_, ip4, ip6,
240  fip_vdns_name, fip_vdns_type);
241  CheckForFipUpdate(entry, fip_vdns_name, fip_vdns_type);
242  ++it;
243  }
244 }
245 
247  VrfEntry *vrf = static_cast<VrfEntry *>(entry);
248  if (vrf->GetName() == agent_->fabric_vrf_name())
249  return;
250  MacAddress address(agent_->vhost_interface()->mac());
251 
252  if (entry->IsDeleted()) {
254  address, -1);
255  return;
256  }
257 
258  if (vrf->vn()) {
260  vrf->GetName(),
261  address,
262  vrf->vn()->GetName(),
263  "pkt0", true);
264  }
265 }
266 
268  if (node->IsDeleted())
269  return;
270  DNS_BIND_TRACE(DnsBindTrace, "Ipam Notify : " << node->name());
271  ProcessNotify(node->name(), node->IsDeleted(), true);
272 }
273 
275  DNS_BIND_TRACE(DnsBindTrace, "Vdns Notify : " << node->name());
276  // Update any existing records prior to checking for new ones
277  if (!node->IsDeleted()) {
278  autogen::VirtualDns *virtual_dns =
279  static_cast <autogen::VirtualDns *> (node->GetObject());
280  autogen::VirtualDnsType vdns_type = virtual_dns->data();
281  std::string name = node->name();
282  MoveVDnsEntry(NULL, name, name, vdns_type, false);
283  }
284  ProcessNotify(node->name(), node->IsDeleted(), false);
285 }
286 
287 void DnsProto::ProcessNotify(std::string name, bool is_deleted, bool is_ipam) {
288  for (VmDataMap::iterator it = all_vms_.begin(); it != all_vms_.end(); ++it) {
289  std::string vdns_name;
290  autogen::VirtualDnsType vdns_type;
291  GetVdnsData(it->first->vn(), it->first->primary_ip_addr(),
292  it->first->primary_ip6_addr(), vdns_name, vdns_type);
293  // in case of VDNS delete, clear the name
294  if (!is_ipam && is_deleted && vdns_name == name)
295  vdns_name.clear();
296  CheckForUpdate(it->second, it->first, it->first->vn(),
297  it->first->primary_ip_addr(),
298  it->first->primary_ip6_addr(),
299  vdns_name, vdns_type);
300  }
301  DnsFipSet::iterator it = fip_list_.begin();
302  while (it != fip_list_.end()) {
303  std::string fip_vdns_name;
304  DnsFipEntry *entry = (*it).get();
305  autogen::VirtualDnsType fip_vdns_type;
306  Ip4Address ip4 = ip4_unspec_;
307  Ip6Address ip6 = ip6_unspec_;
308  if (entry->floating_ip_.is_v4()) {
309  ip4 = entry->floating_ip_.to_v4();
310  }
311  if (entry->floating_ip_.is_v6()) {
312  ip6 = entry->floating_ip_.to_v6();
313  }
314  GetVdnsData(entry->vn_, ip4, ip6,
315  fip_vdns_name, fip_vdns_type);
316  CheckForFipUpdate(entry, fip_vdns_name, fip_vdns_type);
317  ++it;
318  }
319 }
320 
321 void DnsProto::CheckForUpdate(IpVdnsMap &ipvdns, const VmInterface *vmitf,
322  const VnEntry *vn, const Ip4Address &ip,
323  const Ip6Address &ip6, std::string &vdns_name,
324  const autogen::VirtualDnsType &vdns_type) {
325  IpVdnsMap::iterator vmdata_it = ipvdns.find(ip.to_ulong());
326  if (vmdata_it == ipvdns.end()) {
327  if (UpdateDnsEntry(vmitf, vn, vmitf->vm_name(),
328  vdns_name, ip, ip6, false, false))
329  ipvdns.insert(IpVdnsPair(ip.to_ulong(), vdns_name));
330  else
331  ipvdns.insert(IpVdnsPair(ip.to_ulong(), ""));
332  return;
333  }
334  if (vmdata_it->second.empty() && vmdata_it->second != vdns_name) {
335  if (UpdateDnsEntry(vmitf, vn, vmitf->vm_name(),
336  vdns_name, ip, ip6, false, false))
337  vmdata_it->second = vdns_name;
338  } else if (vmdata_it->second != vdns_name) {
339  if (MoveVDnsEntry(vmitf, vdns_name, vmdata_it->second,
340  vdns_type, false))
341  vmdata_it->second = vdns_name;
342  }
343 }
344 
345 void DnsProto::CheckForFipUpdate(DnsFipEntry *entry, std::string &vdns_name,
346  const autogen::VirtualDnsType &vdns_type) {
347  if (entry->vdns_name_.empty() && entry->vdns_name_ != vdns_name) {
348  std::string fip_name;
349  if (!GetFipName(entry->interface_, vdns_type,
350  entry->floating_ip_, fip_name))
351  vdns_name = "";
352 
353  Ip4Address ip4 = ip4_unspec_;
354  Ip6Address ip6 = ip6_unspec_;
355  if (entry->floating_ip_.is_v4()) {
356  ip4 = entry->floating_ip_.to_v4();
357  }
358  if (entry->floating_ip_.is_v6()) {
359  ip6 = entry->floating_ip_.to_v6();
360  }
361  if (UpdateDnsEntry(entry->interface_, entry->vn_, fip_name,
362  vdns_name, ip4, ip6, true, false)) {
363  entry->vdns_name_.assign(vdns_name);
364  entry->fip_name_ = fip_name;
365  }
366  } else if (entry->vdns_name_ != vdns_name) {
367  if (MoveVDnsEntry(entry->interface_, vdns_name, entry->vdns_name_,
368  vdns_type, true)) {
369  entry->vdns_name_.assign(vdns_name);
370  }
371  }
372 }
373 
374 // Send A & PTR record entries
376  const std::string &name,
377  const Ip4Address &ip, uint32_t plen,
378  const Ip6Address &ip6, uint32_t plen6,
379  const std::string &vdns_name,
380  const autogen::VirtualDnsType &vdns_type,
381  bool is_floating, bool is_delete) {
382  if (!name.size() || !vdns_type.dynamic_records_from_client) {
383  DNS_BIND_TRACE(DnsBindTrace, "Not adding DNS entry; Name = " <<
384  name << "Dynamic records allowed = " <<
385  (vdns_type.dynamic_records_from_client ? "yes" : "no"));
386  return false;
387  }
388 
389  DnsUpdateData *data = new DnsUpdateData();
390  data->virtual_dns = vdns_name;
391  data->zone = vdns_type.domain_name;
392 
393  // Add a DNS record
394  DnsItem item;
395  if (!ip.is_unspecified()) {
396  item.eclass = is_delete ? DNS_CLASS_NONE : DNS_CLASS_IN;
397  item.type = DNS_A_RECORD;
398  item.ttl = is_delete ? 0 : vdns_type.default_ttl_seconds;
399  item.name = name;
400  boost::system::error_code ec;
401  item.data = ip.to_string(ec);
402  data->items.push_back(item);
403  }
404 
405  DnsItem ip6_item;
406  if (!ip6.is_unspecified()) {
407  ip6_item.eclass = is_delete ? DNS_CLASS_NONE : DNS_CLASS_IN;
408  ip6_item.type = DNS_AAAA_RECORD;
409  ip6_item.ttl = is_delete ? 0 : vdns_type.default_ttl_seconds;
410  ip6_item.name = name;
411  boost::system::error_code ec;
412  ip6_item.data = ip6.to_string(ec);
413  data->items.push_back(ip6_item);
414  }
415 
416  if (data->items.size()) {
417  DNS_BIND_TRACE(DnsBindTrace,
418  "DNS update sent for : " << item.ToString() <<
419  " IPv6 : " << ip6_item.ToString() <<
420  " VDNS : " << data->virtual_dns <<
421  " Zone : " << data->zone);
422  SendDnsUpdateIpc(data, DnsAgentXmpp::Update, vmitf, is_floating);
423  } else {
424  DNS_BIND_TRACE(DnsBindTrace, "Not adding DNS entry; Name = " <<
425  name << "Address unspecified");
426  return false;
427  }
428 
429  // Add a PTR record as well
430  DnsUpdateData *ptr_data = new DnsUpdateData();
431  ptr_data->virtual_dns = vdns_name;
432  BindUtil::GetReverseZone(ip, plen, ptr_data->zone);
433 
434  item.type = DNS_PTR_RECORD;
435  item.data.swap(item.name);
437  ptr_data->items.push_back(item);
438 
439  DNS_BIND_TRACE(DnsBindTrace, "DNS update sent for : " << item.ToString() <<
440  " VDNS : " << ptr_data->virtual_dns <<
441  " Zone : " << ptr_data->zone);
442  SendDnsUpdateIpc(ptr_data, DnsAgentXmpp::Update, vmitf, is_floating);
443 
444  // Add a PTR record for IPv6, if present
445  if (!ip6.is_unspecified()) {
446  DnsUpdateData *ptr6_data = new DnsUpdateData();
447  ptr6_data->virtual_dns = vdns_name;
448  BindUtil::GetReverseZone(ip6, plen6, ptr6_data->zone);
449 
450  ip6_item.type = DNS_PTR_RECORD;
451  ip6_item.data.swap(ip6_item.name);
452 
453  ip6_item.name = BindUtil::GetPtrNameFromAddr(ip6);
454  ptr6_data->items.push_back(ip6_item);
455 
456  DNS_BIND_TRACE(DnsBindTrace, "DNS update sent for : " << ip6_item.ToString() <<
457  " VDNS : " << ptr6_data->virtual_dns <<
458  " Zone : " << ptr6_data->zone);
459  SendDnsUpdateIpc(ptr6_data, DnsAgentXmpp::Update, vmitf, is_floating);
460  }
461 
462  return true;
463 }
464 
465 // Update the floating ip entries
466 bool DnsProto::UpdateFloatingIp(const VmInterface *vmitf, const VnEntry *vn,
467  const IpAddress &ip, bool is_deleted) {
468  Ip4Address ip4 = ip4_unspec_;
469  Ip6Address ip6 = ip6_unspec_;
470  if (ip.is_v6()) {
471  ip6 = ip.to_v6();
472  }
473  if (ip.is_v4()) {
474  ip4 = ip.to_v4();
475  }
476  bool is_floating = true;
477  std::string vdns_name;
478  autogen::VirtualDnsType vdns_type;
479  GetVdnsData(vn, ip4, ip6, vdns_name, vdns_type);
480  DnsFipEntryPtr key(new DnsFipEntry(vn, ip, vmitf));
481  DnsFipSet::iterator it = fip_list_.find(key);
482  if (it == fip_list_.end()) {
483  if (is_deleted)
484  return true;
485  std::string fip_name;
486  if (!GetFipName(vmitf, vdns_type, ip, fip_name))
487  vdns_name = "";
488  if (!UpdateDnsEntry(vmitf, vn, fip_name,
489  vdns_name, ip4, ip6, is_floating, false))
490  vdns_name = "";
491  key.get()->vdns_name_ = vdns_name;
492  key.get()->fip_name_ = fip_name;
493  fip_list_.insert(key);
494  } else {
495  if (is_deleted) {
496  std::string fip_name;
497  UpdateDnsEntry(vmitf, vn, (*it)->fip_name_,
498  (*it)->vdns_name_, ip4, ip6, is_floating, true);
499  fip_list_.erase(key);
500  } else {
501  DnsFipEntry *entry = (*it).get();
502  CheckForFipUpdate(entry, vdns_name, vdns_type);
503  }
504  }
505  return true;
506 }
507 
508 bool DnsProto::UpdateDnsEntry(const VmInterface *vmitf, const VnEntry *vn,
509  const std::string &vm_name,
510  const std::string &vdns_name,
511  const Ip4Address &ip,
512  const Ip6Address &ip6,
513  bool is_floating, bool is_deleted) {
514  if (!vdns_name.empty()) {
515  uint32_t plen = 0;
516  const std::vector<VnIpam> &ipam = vn->GetVnIpam();
517  unsigned int i;
518  if (!ip.is_unspecified()) {
519  for (i = 0; i < ipam.size(); ++i) {
520  if (ipam[i].IsV4() &&
521  IsIp4SubnetMember(ip, ipam[i].ip_prefix.to_v4(), ipam[i].plen)) {
522  plen = ipam[i].plen;
523  break;
524  }
525  }
526  if (i == ipam.size()) {
527  DNS_BIND_TRACE(DnsBindTrace, "UpdateDnsEntry for VM <" <<
528  vm_name << "> not done for vn <" <<
529  vn->GetName() << "> IPAM doesnt have Ipv4 subnet; " <<
530  ((is_deleted)? "delete" : "update"));
531  return false;
532  }
533  }
534 
535  uint32_t plen6 = 0;
536  if (!ip6.is_unspecified()) {
537  for (i = 0; i < ipam.size(); ++i) {
538  if (ipam[i].IsV6() &&
539  IsIp6SubnetMember(ip6, ipam[i].ip_prefix.to_v6(), ipam[i].plen)) {
540  plen6 = ipam[i].plen;
541  break;
542  }
543  }
544  if (i == ipam.size()) {
545  DNS_BIND_TRACE(DnsBindTrace, "UpdateDnsEntry for VM <" <<
546  vm_name << "> not done for vn <" <<
547  vn->GetName() << "> IPAM doesnt have Ipv6 subnet; " <<
548  ((is_deleted)? "delete" : "update"));
549  return false;
550  }
551  }
552 
553  autogen::VirtualDnsType vdns_type;
554  if (agent_->domain_config_table()->GetVDns(vdns_name, &vdns_type)) {
555  return SendUpdateDnsEntry(vmitf, vm_name, ip, plen, ip6, plen6,
556  vdns_name, vdns_type, is_floating,
557  is_deleted);
558  } else {
559  DNS_BIND_TRACE(DnsBindTrace, "UpdateDnsEntry for VM <" <<
560  vm_name << "> entry not " <<
561  ((is_deleted)? "deleted; " : "updated; ") <<
562  "VDNS info for " << vdns_name << " not present");
563  return false;
564  }
565  }
566 
567  return true;
568 }
569 
570 // Move DNS entries for a VM from one VDNS to another
572  std::string &new_vdns_name,
573  std::string &old_vdns_name,
574  const autogen::VirtualDnsType &vdns_type,
575  bool is_floating) {
576  std::string name = (vmitf ? vmitf->vm_name() : "All Vms");
577  DNS_BIND_TRACE(DnsBindTrace, "VDNS modify for VM <" << name <<
578  " old VDNS : " << old_vdns_name <<
579  " new VDNS : " << new_vdns_name <<
580  " ttl : " << vdns_type.default_ttl_seconds <<
581  " floating : " << (is_floating ? "yes" : "no"));
582  SendDnsUpdateIpc(vmitf, new_vdns_name,
583  old_vdns_name, vdns_type.domain_name,
584  (uint32_t)vdns_type.default_ttl_seconds, is_floating);
585  return true;
586 }
587 
588 bool DnsProto::GetVdnsData(const VnEntry *vn, const Ip4Address &v4_addr,
589  const Ip6Address &v6_addr, std::string &vdns_name,
590  autogen::VirtualDnsType &vdns_type) {
591  if (!vn)
592  return false;
593 
594  autogen::IpamType ipam_type;
595  if ((!v4_addr.to_ulong() ||
596  !vn->GetIpamVdnsData(v4_addr, &ipam_type, &vdns_type)) &&
597  (v6_addr.is_unspecified() ||
598  !vn->GetIpamVdnsData(v6_addr, &ipam_type, &vdns_type))) {
599  DNS_BIND_TRACE(DnsBindTrace, "Unable to retrieve VDNS data; VN : " <<
600  vn->GetName() << " IPv4 : " << v4_addr.to_string() <<
601  " IPv6 : " << v6_addr.to_string());
602  return false;
603  }
604 
605  vdns_name = ipam_type.ipam_dns_server.virtual_dns_server_name;
606  return true;
607 }
608 
610  const autogen::VirtualDnsType &vdns_type,
611  const IpAddress &ip, std::string &fip_name) const {
612  std::string fip_name_notation =
613  boost::to_lower_copy(vdns_type.floating_ip_record);
614 
615  std::string name;
616  if (fip_name_notation == "" ||
617  fip_name_notation == "dashed-ip" ||
618  fip_name_notation == "dashed-ip-tenant-name") {
619  name = ip.to_string();
620  boost::replace_all(name, ".", "-");
621  } else {
622  name = vmitf->vm_name();
623  }
624 
625  if (fip_name_notation == "" ||
626  fip_name_notation == "dashed-ip-tenant-name" ||
627  fip_name_notation == "vm-name-tenant-name") {
628  if (!vmitf->vn())
629  return false;
630  name += "." + vmitf->vn()->GetProject();
631  }
632 
633  fip_name = name;
634  return true;
635 }
636 
638  return (++xid_ == 0 ? ++xid_ : xid_);
639 }
640 
641 void DnsProto::SendDnsIpc(uint8_t *pkt, std::size_t length) {
642  DnsIpc *ipc = new DnsIpc(pkt, length, 0, NULL, DnsProto::DNS_BIND_RESPONSE);
644 }
645 
646 void DnsProto::SendDnsIpc(InterTaskMessage cmd, uint16_t xid, uint8_t *msg,
647  DnsHandler *handler) {
648  DnsIpc *ipc = new DnsIpc(msg, 0, xid, handler, cmd);
650 }
651 
654  const VmInterface *vm, bool floating) {
655  DnsUpdateIpc *ipc = new DnsUpdateIpc(type, data, vm, floating);
657 }
658 
660  const std::string &new_vdns,
661  const std::string &old_vdns,
662  const std::string &new_dom,
663  uint32_t ttl, bool is_floating) {
664  DnsUpdateIpc *ipc = new DnsUpdateIpc(vm, new_vdns, old_vdns, new_dom,
665  ttl, is_floating);
667 }
668 
670  DnsUpdateAllIpc *ipc = new DnsUpdateAllIpc(channel);
672 }
673 
674 void DnsProto::AddDnsQuery(uint16_t xid, DnsHandler *handler) {
675  dns_query_map_.insert(DnsBindQueryPair(xid, handler));
676 }
677 
678 void DnsProto::DelDnsQuery(uint16_t xid) {
679  dns_query_map_.erase(xid);
680 }
681 
682 bool DnsProto::IsDnsQueryInProgress(uint16_t xid) {
683  return dns_query_map_.find(xid) != dns_query_map_.end();
684 }
685 
687  for (DnsBindQueryMap::iterator it = dns_query_map_.begin();
688  it != dns_query_map_.end(); it++) {
689  if (it->second == handler) {
690  return true;
691  }
692  }
693  return false;
694 }
695 
697  for (DnsBindQueryMap::iterator it = dns_query_map_.begin();
698  it != dns_query_map_.end();) {
699  if (it->second == handler) {
700  dns_query_map_.erase(it++);
701  continue;
702  }
703  ++it;
704  }
705 }
706 
708  DnsBindQueryMap::iterator it = dns_query_map_.find(xid);
709  if (it != dns_query_map_.end())
710  return it->second;
711  return NULL;
712 }
713 
714 void DnsProto::AddDnsQueryIndex(uint16_t xid, int16_t srv_idx) {
715  dns_query_index_map_.insert(DnsBindQueryIndexPair(xid, srv_idx));
716 }
717 
718 void DnsProto::DelDnsQueryIndex(uint16_t xid) {
719  dns_query_index_map_.erase(xid);
720 }
721 
722 int16_t DnsProto::GetDnsQueryServerIndex(uint16_t xid) {
723  DnsBindQueryIndexMap::iterator it = dns_query_index_map_.find(xid);
724  if (it != dns_query_index_map_.end())
725  return it->second;
726  return -1;
727 }
728 
729 
731  curr_vm_requests_.insert(*key);
732 }
733 
735  curr_vm_requests_.erase(*key);
736 }
737 
739  return curr_vm_requests_.find(*key) != curr_vm_requests_.end();
740 }
741 
743  const VmInterface *itf)
744  : vn_(vn), floating_ip_(fip), interface_(itf) {
745 }
746 
748 }
749 
751  const DnsFipEntryPtr &rhs) const {
752  return lhs->IsLess(rhs.get());
753 }
754 
756  if (vn_ != rhs->vn_) {
757  return vn_ < rhs->vn_;
758  }
759  if (floating_ip_ != rhs->floating_ip_) {
760  return floating_ip_ < rhs->floating_ip_;
761  }
762  return interface_ < rhs->interface_;
763 }
void SetBounded(bool bounded)
Definition: queue_task.h:200
VmDataMap all_vms_
Definition: dns_proto.h:266
bool IsLess(const DnsFipEntry *rhs) const
Definition: dns_proto.cc:755
bool UpdateDnsEntry(const VmInterface *vmitf, const VnEntry *vn, const std::string &vm_name, const std::string &vdns_name, const Ip4Address &ip, const Ip6Address &ip6, bool is_floating, bool is_deleted)
Definition: dns_proto.cc:508
Type type() const
Definition: interface.h:112
void DelVmRequest(DnsHandler::QueryKey *key)
Definition: dns_proto.cc:734
bool tsn_enabled() const
Definition: agent.h:1162
#define DNS_BIND_TRACE(obj, arg)
Definition: bind_util.h:21
void Shutdown()
Definition: dns_proto.cc:103
void SendMessage(PktModuleName mod, InterTaskMsg *msg)
std::string zone
Definition: bind_util.h:207
void set_update_floatingip_cb(UpdateFloatingIpFn fn)
Definition: interface.cc:630
Definition: vrf.h:86
static const uint8_t kInvalidDscp
static void Delete(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, uint32_t ethernet_tag)
void ConfigInit()
Definition: dns_proto.cc:41
#define DNS_A_RECORD
Definition: bind_util.h:36
DomainConfig * domain_config_table() const
Definition: agent.cc:1029
bool GetVdnsData(const VnEntry *vn, const Ip4Address &v4_addr, const Ip6Address &v6_addr, std::string &vdns_name, autogen::VirtualDnsType &vdns_type)
Definition: dns_proto.cc:588
int16_t GetDnsQueryServerIndex(uint16_t xid)
Definition: dns_proto.cc:722
bool SendUpdateDnsEntry(const VmInterface *vmitf, const std::string &name, const Ip4Address &ip, uint32_t plen, const Ip6Address &ip6, uint32_t plen6, const std::string &vdns_name, const autogen::VirtualDnsType &vdns_type, bool is_floating, bool is_delete)
Definition: dns_proto.cc:375
bool IsIp4SubnetMember(const Ip4Address &ip, const Ip4Address &prefix_ip, uint16_t plen)
Definition: address_util.cc:19
#define DNS_PTR_RECORD
Definition: bind_util.h:40
void DelDnsQuery(uint16_t xid)
Definition: dns_proto.cc:678
const Interface * vhost_interface() const
Definition: agent.h:935
DnsProto(Agent *agent, boost::asio::io_context &io)
Definition: dns_proto.cc:66
bool IsDeleted() const
Definition: db_entry.h:49
const std::string & dns_server(uint8_t idx) const
Definition: agent.h:857
boost::asio::ip::address IpAddress
Definition: address.h:13
GlobalQosConfig * global_qos_config() const
Definition: operdb_init.h:81
virtual ~DnsProto()
Definition: dns_proto.cc:100
void VnNotify(DBEntryBase *entry)
Definition: dns_proto.cc:186
uint8_t control_dscp() const
void InterfaceNotify(DBEntryBase *entry)
Definition: dns_proto.cc:127
void DelDnsQueryIndex(uint16_t xid)
Definition: dns_proto.cc:718
InterfaceTable * interface_table() const
Definition: agent.h:465
DnsUpdateSet update_set_
Definition: dns_proto.h:256
VnTable * vn_table() const
Definition: agent.h:495
void IpamNotify(IFMapNode *node)
Definition: dns_proto.cc:267
void DelDnsQueryHandler(DnsHandler *handler)
Definition: dns_proto.cc:696
const string & GetName() const
Definition: vrf.h:100
std::string fip_name_
Definition: dns_proto.h:129
const MacAddress & mac() const
Definition: interface.h:131
DBTableBase::ListenerId lid_
Definition: dns_proto.h:268
std::string name
Definition: bind_util.h:158
std::pair< uint32_t, std::string > IpVdnsPair
Definition: dns_proto.h:144
#define DNS_CLASS_IN
Definition: bind_util.h:31
DnsFipEntry(const VnEntry *vn, const IpAddress &fip, const VmInterface *itf)
Definition: dns_proto.cc:742
void AddDnsQueryIndex(uint16_t xid, int16_t srv_idx)
Definition: dns_proto.cc:714
DnsVmRequestSet curr_vm_requests_
Definition: dns_proto.h:258
void VrfNotify(DBEntryBase *entry)
Definition: dns_proto.cc:246
bool MoveVDnsEntry(const VmInterface *vmitf, std::string &new_vdns_name, std::string &old_vdns_name, const autogen::VirtualDnsType &vdns_type, bool is_floating)
Definition: dns_proto.cc:571
uint16_t xid_
Definition: dns_proto.h:255
bool GetIpamVdnsData(const IpAddress &vm_addr, autogen::IpamType *ipam_type, autogen::VirtualDnsType *vdns_type) const
Definition: vn.cc:684
IpAddress floating_ip_
Definition: dns_proto.h:126
void Unregister(ListenerId listener)
Definition: db_table.cc:186
OperDB * oper_db() const
Definition: agent.cc:1013
const VmInterface * interface_
Definition: dns_proto.h:127
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
std::string GetProject() const
Definition: vn.cc:716
const std::string & fabric_vrf_name() const
Definition: agent.h:903
bool IsDnsQueryInProgress(uint16_t xid)
Definition: dns_proto.cc:682
uint16_t GetTransId()
Definition: dns_proto.cc:637
static void set_dns_xmpp_event_handler_cb(DnsXmppEventHandler cb)
virtual ~DnsFipEntry()
Definition: dns_proto.cc:747
std::string virtual_dns
Definition: bind_util.h:206
bool IsDnsHandlerInUse(DnsHandler *handler)
Definition: dns_proto.cc:686
ProtoHandler * AllocProtoHandler(boost::shared_ptr< PktInfo > info, boost::asio::io_context &io)
Definition: dns_proto.cc:122
void SendDnsIpc(uint8_t *pkt, std::size_t length)
Definition: dns_proto.cc:641
uint8_t type
Definition: load_balance.h:109
bool BuildDefaultServerList()
Definition: dns_proto.cc:113
void SetSize(size_t size)
Definition: queue_task.h:196
Definition: agent.h:358
void ProcessNotify(std::string name, bool is_deleted, bool is_ipam)
Definition: dns_proto.cc:287
DefaultServerList def_server_list_
Definition: dns_proto.h:260
static TaskScheduler * GetInstance()
Definition: task.cc:547
static void set_dns_message_handler_cb(DnsMessageHandler cb)
VnEntryRef vn_
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
DBTableBase::ListenerId vrf_table_listener_id_
Definition: dns_proto.h:270
std::pair< uint32_t, int16_t > DnsBindQueryIndexPair
Definition: dns_proto.h:149
std::string ToString() const
Definition: bind_util.cc:63
uint16_t eclass
Definition: bind_util.h:149
void AddDnsQuery(uint16_t xid, DnsHandler *handler)
Definition: dns_proto.cc:674
static std::string GetPtrNameFromAddr(const Ip4Address &ip)
Definition: bind_util.cc:959
DnsHandler * GetDnsQueryHandler(uint16_t xid)
Definition: dns_proto.cc:707
std::string data
Definition: bind_util.h:160
const Peer * local_peer() const
Definition: agent.h:1022
PktHandler * pkt_handler() const
Definition: pkt_init.h:31
std::pair< uint32_t, DnsHandler * > DnsBindQueryPair
Definition: dns_proto.h:140
std::pair< const VmInterface *, IpVdnsMap > VmDataPair
Definition: dns_proto.h:146
const std::vector< VnIpam > & GetVnIpam() const
Definition: vn.h:171
void IoShutdown()
Definition: dns_proto.cc:25
const VnEntry * vn() const
AgentParam * params() const
Definition: agent.h:1218
#define DNS_CLASS_NONE
Definition: bind_util.h:33
const VnEntry * vn_
Definition: dns_proto.h:125
static Timer * CreateTimer(boost::asio::io_context &service, const std::string &name, int task_id=Timer::GetTimerTaskId(), int task_instance=Timer::GetTimerInstanceId(), bool delete_on_completion=false)
Definition: timer.cc:201
const std::string & name() const
Definition: ifmap_node.h:48
bool operator()(const DnsFipEntryPtr &lhs, const DnsFipEntryPtr &rhs) const
Definition: dns_proto.cc:750
DnsFipSet fip_list_
Definition: dns_proto.h:267
static void Shutdown()
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
void AddVmRequest(DnsHandler::QueryKey *key)
Definition: dns_proto.cc:730
void SendDnsUpdateIpc(DnsUpdateData *data, DnsAgentXmpp::XmppType type, const VmInterface *vm, bool floating)
Definition: dns_proto.cc:652
bool Cancel()
Definition: timer.cc:150
Definition: vn.h:151
DefaultServerList GetDefaultServerList()
Definition: dns_proto.cc:118
#define MAX_XMPP_SERVERS
Definition: agent.h:291
VrfTable * vrf_table() const
Definition: agent.h:485
const Ip4Address & primary_ip_addr() const
DefaultServerList BuildDefaultServerListImpl()
IFMapObject * GetObject()
Definition: ifmap_node.cc:63
#define DNS_AAAA_RECORD
Definition: bind_util.h:43
const FloatingIpList & floating_ip_list() const
uint32_t services_queue_limit()
Definition: agent_param.h:417
const std::string & vm_name() const
bool UpdateFloatingIp(const VmInterface *vmitf, const VnEntry *vn, const IpAddress &ip, bool is_deleted)
Definition: dns_proto.cc:466
const Ip6Address & primary_ip6_addr() const
bool Start(int time, Handler handler, ErrorHandler error_handler=NULL)
Definition: timer.cc:108
VnEntry * vn() const
Definition: vrf.h:101
static const Ip6Address ip6_unspec_
Definition: dns_proto.h:18
static void AddBridgeReceiveRoute(const Peer *peer, const std::string &vrf_name, const MacAddress &mac, const std::string &vn_name, const std::string &interface, bool policy)
static const Ip4Address ip4_unspec_
Definition: dns_proto.h:17
boost::shared_ptr< DnsFipEntry > DnsFipEntryPtr
Definition: dns_proto.h:132
bool GetFipName(const VmInterface *vmitf, const autogen::VirtualDnsType &vdns_type, const IpAddress &ip, std::string &fip_name) const
Definition: dns_proto.cc:609
void RegisterIpamCb(Callback cb)
Definition: vn.cc:1424
uint32_t ttl
Definition: bind_util.h:151
static const uint32_t kDnsDefaultSlistInterval
Definition: dns_proto.h:22
uint8_t dns_dscp() const
Timer * default_slist_timer_
Definition: dns_proto.h:264
const string & GetName() const
Definition: vn.h:162
bool GetVDns(const std::string &vdns, autogen::VirtualDnsType *vdns_type)
Definition: vn.cc:1550
PktModule * pkt() const
Definition: agent.cc:965
DnsBindQueryMap dns_query_map_
Definition: dns_proto.h:257
void CheckForFipUpdate(DnsFipEntry *entry, std::string &vdns_name, const autogen::VirtualDnsType &vdns_type)
Definition: dns_proto.cc:345
static void GetReverseZone(const Ip4Address &addr, uint32_t plen, std::string &zone)
Definition: bind_util.cc:812
DnsItems items
Definition: bind_util.h:208
std::map< uint32_t, std::string > IpVdnsMap
Definition: dns_proto.h:143
DBTableBase::ListenerId Vnlid_
Definition: dns_proto.h:269
static void Init(boost::asio::io_context &io, const std::vector< DnsServer > &dns_servers, uint16_t client_port, Callback cb, uint8_t dscp)
bool IsIp6SubnetMember(const Ip6Address &ip, const Ip6Address &subnet, uint8_t plen)
Definition: address_util.cc:29
InterTaskMessage
Definition: dns_proto.h:25
std::string vdns_name_
Definition: dns_proto.h:128
DnsBindQueryIndexMap dns_query_index_map_
Definition: dns_proto.h:259
static bool DeleteTimer(Timer *Timer)
Definition: timer.cc:222
void RegisterVdnsCb(Callback cb)
Definition: vn.cc:1428
bool IsVmRequestDuplicate(DnsHandler::QueryKey *key)
Definition: dns_proto.cc:738
uint16_t type
Definition: bind_util.h:150
void CheckForUpdate(IpVdnsMap &ipvdns, const VmInterface *vmitf, const VnEntry *vn, const Ip4Address &ip, const Ip6Address &ip6, std::string &vdns_name, const autogen::VirtualDnsType &vdns_type)
Definition: dns_proto.cc:321
void VdnsNotify(IFMapNode *node)
Definition: dns_proto.cc:274