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