Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <boost/bind/bind.hpp>
6 : #include "base/logging.h"
7 : #include "base/task.h"
8 : #include "base/util.h"
9 : #include "bind/bind_util.h"
10 : #include "cfg/dns_config.h"
11 : #include "cfg/config_listener.h"
12 : #include "ifmap/ifmap_link.h"
13 : #include "ifmap/ifmap_table.h"
14 : #include "cmn/dns.h"
15 :
16 : using namespace std;
17 : using namespace boost::placeholders;
18 :
19 : const char *DnsConfigManager::config_types[] = {
20 : "virtual-DNS",
21 : "virtual-DNS-record",
22 : "network-ipam",
23 : "virtual-network-network-ipam",
24 : "global-qos-config",
25 : };
26 : uint32_t DnsConfigManager::config_types_size = sizeof(DnsConfigManager::config_types);
27 :
28 : const std::string DnsConfigManager::EventString[] = {
29 : "None",
30 : "Add",
31 : "Change",
32 : "Delete"
33 : };
34 :
35 : SandeshTraceBufferPtr DnsConfigTraceBuf(SandeshTraceBufferCreate("Config", 2000));
36 : int DnsConfigManager::config_task_id_ = -1;
37 : const int DnsConfigManager::kConfigTaskInstanceId;
38 :
39 170 : ConfigDelta::ConfigDelta() {
40 170 : }
41 :
42 407 : ConfigDelta::ConfigDelta(const ConfigDelta &rhs)
43 407 : : id_type(rhs.id_type), id_name(rhs.id_name),
44 407 : node(rhs.node), obj(rhs.obj) {
45 407 : }
46 :
47 577 : ConfigDelta::~ConfigDelta() {
48 577 : }
49 :
50 15 : DnsConfigManager::DnsConfigManager()
51 15 : : db_(NULL), db_graph_(NULL),
52 15 : trigger_(boost::bind(&DnsConfigManager::ConfigHandler, this),
53 : TaskScheduler::GetInstance()->GetTaskId("dns::Config"), 0),
54 30 : listener_(new ConfigListener(this)) {
55 15 : IdentifierMapInit();
56 :
57 15 : if (config_task_id_ == -1) {
58 1 : TaskScheduler *scheduler = TaskScheduler::GetInstance();
59 1 : config_task_id_ = scheduler->GetTaskId("dns::Config");
60 : }
61 15 : }
62 :
63 15 : DnsConfigManager::~DnsConfigManager() {
64 15 : }
65 :
66 15 : void DnsConfigManager::Initialize(DB *db, DBGraph *db_graph) {
67 15 : db_ = db;
68 15 : db_graph_ = db_graph;
69 15 : int ntypes = config_types_size / sizeof(const char *);
70 15 : listener_->Initialize(db, ntypes, config_types);
71 15 : }
72 :
73 207 : void DnsConfigManager::OnChange() {
74 207 : trigger_.Set();
75 207 : }
76 :
77 15 : void DnsConfigManager::IdentifierMapInit() {
78 15 : id_map_.insert(make_pair("network-ipam",
79 15 : boost::bind(&DnsConfigManager::ProcessNetworkIpam, this, _1)));
80 15 : id_map_.insert(make_pair("virtual-network-network-ipam",
81 15 : boost::bind(&DnsConfigManager::ProcessVNNI, this, _1)));
82 15 : id_map_.insert(make_pair("virtual-DNS",
83 15 : boost::bind(&DnsConfigManager::ProcessVirtualDNS, this, _1)));
84 15 : id_map_.insert(make_pair("virtual-DNS-record",
85 15 : boost::bind(&DnsConfigManager::ProcessVirtualDNSRecord, this, _1)));
86 15 : id_map_.insert(make_pair("global-qos-config",
87 15 : boost::bind(&DnsConfigManager::ProcessGlobalQosConfig, this, _1)));
88 15 : }
89 :
90 170 : void DnsConfigManager::ProcessNode(const ConfigDelta &delta,
91 : DnsConfigData &config_data,
92 : Observer observer) {
93 170 : IFMapNodeProxy *proxy = config_data.Find(delta.id_name);
94 170 : if (!proxy) {
95 58 : proxy = delta.node.get();
96 58 : if (proxy == NULL)
97 0 : return;
98 58 : IFMapNode *node = proxy->node();
99 58 : if (node == NULL || node->IsDeleted())
100 0 : return;
101 58 : config_data.Add(delta.id_name, delta.node);
102 58 : if (observer) {
103 58 : (observer)(proxy, delta.id_name, DnsConfigManager::CFG_ADD);
104 : }
105 58 : DNS_TRACE(DnsConfigTrace, "Add : Type = " + delta.id_type +
106 : " Name = " + delta.id_name);
107 : } else {
108 112 : IFMapNode *node = proxy->node();
109 112 : if (node->IsDeleted() || !node->HasAdjacencies(db_graph_)) {
110 58 : if (observer) {
111 58 : (observer)(proxy, delta.id_name,
112 : DnsConfigManager::CFG_DELETE);
113 : }
114 58 : config_data.Del(delta.id_name);
115 58 : DNS_TRACE(DnsConfigTrace, "Delete : Type = " + delta.id_type +
116 : " Name = " + delta.id_name);
117 : } else {
118 54 : if (observer) {
119 54 : (observer)(proxy, delta.id_name,
120 : DnsConfigManager::CFG_CHANGE);
121 : }
122 54 : DNS_TRACE(DnsConfigTrace, "Change : Type = " + delta.id_type +
123 : " Name = " + delta.id_name);
124 : }
125 : }
126 : }
127 :
128 30 : void DnsConfigManager::ProcessVirtualDNS(const ConfigDelta &delta) {
129 30 : if (!delta.id_name.size()) {
130 0 : DNS_TRACE(DnsConfigTrace, "Error - Received Virtual DNS without a name");
131 0 : return;
132 : }
133 30 : ProcessNode(delta, virt_dns_config_, obs_.virtual_dns);
134 : }
135 :
136 60 : void DnsConfigManager::ProcessVirtualDNSRecord(const ConfigDelta &delta) {
137 60 : if (!delta.id_name.size()) {
138 0 : DNS_TRACE(DnsConfigTrace, "Error - Received Virtual DNS Record without a name");
139 0 : return;
140 : }
141 60 : ProcessNode(delta, virt_dns_rec_config_, obs_.virtual_dns_record);
142 : }
143 :
144 46 : void DnsConfigManager::ProcessVNNI(const ConfigDelta &delta) {
145 46 : if (!delta.id_name.size()) {
146 0 : DNS_TRACE(DnsConfigTrace, "Error - Received VNNI without a name");
147 0 : return;
148 : }
149 46 : ProcessNode(delta, vnni_config_, obs_.vnni);
150 : }
151 :
152 34 : void DnsConfigManager::ProcessNetworkIpam(const ConfigDelta &delta) {
153 34 : if (!delta.id_name.size()) {
154 0 : DNS_TRACE(DnsConfigTrace, "Error - Received Ipam without a name");
155 0 : return;
156 : }
157 34 : ProcessNode(delta, ipam_config_, obs_.ipam);
158 : }
159 :
160 0 : void DnsConfigManager::ProcessGlobalQosConfig(const ConfigDelta &delta) {
161 0 : if (!delta.id_name.size()) {
162 0 : DNS_TRACE(DnsConfigTrace, "Error - Received GlobalQosConfig without a"
163 : " name");
164 0 : return;
165 : }
166 0 : ProcessNode(delta, global_qos_config_, obs_.global_qos);
167 : }
168 :
169 22 : IFMapNode *DnsConfigManager::FindTarget(IFMapNode *node,
170 : std::string link_name) {
171 22 : for (DBGraphVertex::edge_iterator iter = node->edge_list_begin(graph());
172 22 : iter != node->edge_list_end(graph()); ++iter) {
173 22 : IFMapLink *link = static_cast<IFMapLink *>(iter.operator->());
174 22 : if (link->metadata() == link_name)
175 22 : return static_cast<IFMapNode *>(iter.target());
176 : }
177 0 : return NULL;
178 : }
179 :
180 16 : IFMapNode *DnsConfigManager::FindTarget(IFMapNode *node,
181 : std::string link_name,
182 : std::string node_type) {
183 16 : for (DBGraphVertex::edge_iterator iter = node->edge_list_begin(graph());
184 32 : iter != node->edge_list_end(graph()); ++iter) {
185 32 : IFMapLink *link = static_cast<IFMapLink *>(iter.operator->());
186 32 : if (link->metadata() == link_name) {
187 32 : IFMapNode *targ_node = static_cast<IFMapNode *>(iter.target());
188 32 : if (targ_node->table()->Typename() == node_type)
189 16 : return targ_node;
190 : }
191 : }
192 0 : return NULL;
193 : }
194 :
195 28 : void DnsConfigManager::ProcessChanges(const ChangeList &change_list) {
196 28 : for (ChangeList::const_iterator iter = change_list.begin();
197 198 : iter != change_list.end(); ++iter) {
198 170 : IdentifierMap::iterator loc = id_map_.find(iter->id_type);
199 170 : if (loc != id_map_.end()) {
200 170 : (loc->second)(*iter);
201 : }
202 : }
203 28 : }
204 :
205 28 : bool DnsConfigManager::ConfigHandler() {
206 28 : ConfigListener::ChangeList change_list;
207 28 : listener_->GetChangeList(&change_list);
208 28 : ProcessChanges(change_list);
209 28 : return true;
210 28 : }
211 :
212 15 : void DnsConfigManager::Terminate() {
213 15 : listener_->Terminate(db_);
214 15 : }
215 :
|