Line data Source code
1 : /*
2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include <boost/uuid/uuid_io.hpp>
6 : #include <vnc_cfg_types.h>
7 : #include <cmn/agent_cmn.h>
8 :
9 : #include <ifmap/ifmap_node.h>
10 : #include <cfg/cfg_init.h>
11 : #include <oper/agent_sandesh.h>
12 : #include <oper/vn.h>
13 : #include <oper/ifmap_dependency_manager.h>
14 : #include <oper/physical_device.h>
15 : #include <oper/physical_device_vn.h>
16 : #include <oper/config_manager.h>
17 :
18 : using std::string;
19 : using boost::assign::map_list_of;
20 : using boost::assign::list_of;
21 :
22 : //////////////////////////////////////////////////////////////////////////////
23 : // PhysicalDeviceVn routines
24 : //////////////////////////////////////////////////////////////////////////////
25 12 : bool PhysicalDeviceVn::IsLess(const DBEntry &rhs) const {
26 12 : const PhysicalDeviceVn &a =
27 : static_cast<const PhysicalDeviceVn &>(rhs);
28 12 : if (device_uuid_ != a.device_uuid_) {
29 0 : return (device_uuid_ < a.device_uuid_);
30 : }
31 12 : return (vn_uuid_ < a.vn_uuid_);
32 : }
33 :
34 0 : string PhysicalDeviceVn::ToString() const {
35 0 : return UuidToString(device_uuid_) + ":" + UuidToString(vn_uuid_);
36 : }
37 :
38 0 : DBEntryBase::KeyPtr PhysicalDeviceVn::GetDBRequestKey() const {
39 0 : PhysicalDeviceVnKey *key = new PhysicalDeviceVnKey(device_uuid_, vn_uuid_);
40 0 : return DBEntryBase::KeyPtr(key);
41 : }
42 :
43 0 : void PhysicalDeviceVn::SetKey(const DBRequestKey *k) {
44 0 : const PhysicalDeviceVnKey *key =
45 : static_cast<const PhysicalDeviceVnKey *>(k);
46 :
47 0 : device_uuid_ = key->device_uuid_;
48 0 : vn_uuid_ = key->vn_uuid_;
49 0 : }
50 :
51 4 : bool PhysicalDeviceVn::Copy(PhysicalDeviceVnTable *table,
52 : const PhysicalDeviceVnData *data) {
53 4 : bool ret = false;
54 :
55 : PhysicalDevice *dev =
56 4 : table->agent()->physical_device_table()->Find(device_uuid_);
57 4 : if (dev != device_.get()) {
58 1 : device_.reset(dev);
59 1 : ret = true;
60 : }
61 :
62 4 : if (dev && (dev->ip() != tor_ip_)) {
63 1 : tor_ip_ = dev->ip();
64 1 : ret = true;
65 : }
66 :
67 4 : if (dev && (dev->name() != device_display_name_)) {
68 1 : device_display_name_ = dev->name();
69 1 : ret = true;
70 : }
71 :
72 4 : VnEntry *vn = table->agent()->vn_table()->Find(vn_uuid_);
73 4 : if (vn != vn_.get()) {
74 1 : vn_.reset(vn);
75 1 : ret = true;
76 : }
77 :
78 4 : int vxlan_id = vn ? vn->GetVxLanId() : 0;
79 4 : if (vxlan_id != vxlan_id_) {
80 1 : vxlan_id_ = vxlan_id;
81 1 : ret = true;
82 : }
83 :
84 4 : return ret;
85 : }
86 :
87 : //////////////////////////////////////////////////////////////////////////////
88 : // PhysicalDeviceVnTable routines
89 : //////////////////////////////////////////////////////////////////////////////
90 3 : PhysicalDeviceVnTable::PhysicalDeviceVnTable(DB *db, const std::string &name) :
91 3 : AgentDBTable(db, name) {
92 : vxlan_id_walk_ref_ =
93 6 : AllocWalker(boost::bind(&PhysicalDeviceVnTable::DeviceVnWalk,
94 : this, _1, _2),
95 : boost::bind(&PhysicalDeviceVnTable::DeviceVnWalkDone,
96 3 : this, _1, _2));
97 3 : }
98 :
99 6 : std::unique_ptr<DBEntry> PhysicalDeviceVnTable::AllocEntry(const DBRequestKey *k)
100 : const {
101 6 : const PhysicalDeviceVnKey *key =
102 : static_cast<const PhysicalDeviceVnKey *>(k);
103 :
104 6 : PhysicalDeviceVn *entry = new PhysicalDeviceVn(key->device_uuid_,
105 6 : key->vn_uuid_);
106 6 : return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(entry));
107 : }
108 :
109 1 : DBEntry *PhysicalDeviceVnTable::Add(const DBRequest *req) {
110 : PhysicalDeviceVnKey *key =
111 1 : static_cast<PhysicalDeviceVnKey *>(req->key.get());
112 : PhysicalDeviceVnData *data =
113 1 : static_cast<PhysicalDeviceVnData *>(req->data.get());
114 :
115 1 : PhysicalDeviceVn *entry = new PhysicalDeviceVn(key->device_uuid_,
116 1 : key->vn_uuid_);
117 1 : entry->Copy(this, data);
118 1 : entry->SendObjectLog(AgentLogEvent::ADD);
119 1 : return entry;
120 : }
121 :
122 3 : bool PhysicalDeviceVnTable::OnChange(DBEntry *e, const DBRequest *req) {
123 3 : PhysicalDeviceVn *entry = static_cast<PhysicalDeviceVn *>(e);
124 : PhysicalDeviceVnData *data =
125 3 : static_cast<PhysicalDeviceVnData *>(req->data.get());
126 3 : bool ret = entry->Copy(this, data);
127 3 : return ret;
128 : }
129 :
130 0 : bool PhysicalDeviceVnTable::Resync(DBEntry *e, const DBRequest *req) {
131 0 : PhysicalDeviceVn *entry = static_cast<PhysicalDeviceVn *>(e);
132 : PhysicalDeviceVnData *data =
133 0 : static_cast<PhysicalDeviceVnData *>(req->data.get());
134 0 : bool ret = entry->Copy(this, data);
135 0 : return ret;
136 : }
137 :
138 0 : void PhysicalDeviceVnTable::Clear() {
139 0 : AgentDBTable::Clear();
140 0 : ReleaseWalker(vxlan_id_walk_ref_);
141 0 : }
142 :
143 1 : bool PhysicalDeviceVnTable::Delete(DBEntry *e, const DBRequest *req) {
144 1 : PhysicalDeviceVn *entry = static_cast<PhysicalDeviceVn *>(e);
145 1 : entry->SendObjectLog(AgentLogEvent::DEL);
146 1 : return true;
147 : }
148 :
149 3 : DBTableBase *PhysicalDeviceVnTable::CreateTable(DB *db,
150 : const std::string &name) {
151 3 : PhysicalDeviceVnTable *table = new PhysicalDeviceVnTable(db, name);
152 3 : table->Init();
153 3 : return table;
154 : }
155 :
156 0 : bool PhysicalDeviceVnTable::DeviceVnWalk(DBTablePartBase *partition,
157 : DBEntryBase *entry) {
158 0 : PhysicalDeviceVn *dev_vn = static_cast<PhysicalDeviceVn *>(entry);
159 0 : DBEntryBase::KeyPtr db_key = dev_vn->GetDBRequestKey();
160 : PhysicalDeviceVnKey *key =
161 0 : static_cast<PhysicalDeviceVnKey *>(db_key.release());
162 0 : key->sub_op_ = AgentKey::RESYNC;
163 0 : DBRequest req;
164 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
165 0 : req.key.reset(key);
166 0 : req.data.reset(NULL);
167 0 : Process(req);
168 0 : return true;
169 0 : }
170 :
171 6 : void PhysicalDeviceVnTable::DeviceVnWalkDone(DBTable::DBTableWalkRef walk_ref,
172 : DBTableBase *part) {
173 6 : }
174 :
175 6 : void PhysicalDeviceVnTable::UpdateVxLanNetworkIdentifierMode() {
176 6 : WalkAgain(vxlan_id_walk_ref_);
177 6 : }
178 :
179 : //////////////////////////////////////////////////////////////////////////////
180 : // Vmi Config handling routines
181 : //////////////////////////////////////////////////////////////////////////////
182 4 : void PhysicalDeviceVnTable::ProcessConfig(const boost::uuids::uuid &dev,
183 : const boost::uuids::uuid &vn) {
184 4 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
185 4 : req.key.reset(new PhysicalDeviceVnKey(dev, vn));
186 4 : req.data.reset(new PhysicalDeviceVnData());
187 4 : Enqueue(&req);
188 8 : return;
189 4 : }
190 :
191 70 : bool PhysicalDeviceVnTable::AddConfigEntry(const boost::uuids::uuid &vmi,
192 : const boost::uuids::uuid &dev,
193 : const boost::uuids::uuid &vn) {
194 : using boost::uuids::nil_uuid;
195 :
196 : // Sanity checks. Needed since VMInterface is not checking for nil_uuid
197 70 : if (vmi == nil_uuid() || dev == nil_uuid() || vn == nil_uuid())
198 66 : return false;
199 :
200 4 : config_tree_.insert(PhysicalDeviceVnToVmi(dev, vn, vmi));
201 4 : agent()->config_manager()->AddPhysicalDeviceVn(dev, vn);
202 4 : return true;
203 : }
204 :
205 38 : bool PhysicalDeviceVnTable::DeleteConfigEntry(const boost::uuids::uuid &vmi,
206 : const boost::uuids::uuid &dev,
207 : const boost::uuids::uuid &vn) {
208 : using boost::uuids::nil_uuid;
209 :
210 : // Sanity checks. Needed since VMInterface is not checking for nil_uuid
211 38 : if (vmi == nil_uuid() || dev == nil_uuid() || vn == nil_uuid())
212 36 : return false;
213 :
214 2 : config_tree_.erase(PhysicalDeviceVnToVmi(dev, vn, vmi));
215 : // Dont delete physical-device-vn entry if there are more entries in
216 : // config-tree with given dev and vn
217 : ConfigTree::iterator it =
218 2 : config_tree_.upper_bound(PhysicalDeviceVnToVmi(dev, vn, nil_uuid()));
219 2 : bool del_entry = false;
220 2 : if (it == config_tree_.end())
221 1 : del_entry = true;
222 1 : else if (it->dev_ != dev)
223 0 : del_entry = true;
224 1 : else if (it->vn_ != vn)
225 0 : del_entry = true;
226 :
227 2 : if (del_entry) {
228 1 : agent()->config_manager()->DelPhysicalDeviceVn(dev, vn);
229 1 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
230 1 : req.key.reset(new PhysicalDeviceVnKey(dev, vn));
231 1 : Enqueue(&req);
232 1 : }
233 :
234 2 : return del_entry;
235 : }
236 :
237 0 : bool PhysicalDeviceVnTable::IFNodeToReq(IFMapNode *node, DBRequest &req,
238 : const boost::uuids::uuid &u) {
239 0 : return false;
240 : }
241 :
242 : /////////////////////////////////////////////////////////////////////////////
243 : // Sandesh routines
244 : /////////////////////////////////////////////////////////////////////////////
245 : class AgentPhysicalDeviceVnSandesh : public AgentSandesh {
246 : public:
247 0 : AgentPhysicalDeviceVnSandesh(const std::string &context,
248 : const std::string &dev,
249 : const std::string &vn)
250 0 : : AgentSandesh(context, ""), dev_str_(dev), vn_str_(vn) {
251 0 : dev_uuid_ = StringToUuid(dev);
252 0 : vn_uuid_ = StringToUuid(vn);
253 0 : }
254 :
255 0 : virtual bool Filter(const DBEntryBase *entry) {
256 0 : const PhysicalDeviceVn *dev_vn =
257 0 : static_cast<const PhysicalDeviceVn *>(entry);
258 0 : if (dev_str_.empty() == false) {
259 0 : if (dev_vn->device_uuid() != dev_uuid_)
260 0 : return false;
261 : }
262 :
263 0 : if (vn_str_.empty() == false) {
264 0 : if (dev_vn->vn_uuid() != vn_uuid_)
265 0 : return false;
266 : }
267 :
268 0 : return true;
269 : }
270 :
271 0 : virtual bool FilterToArgs(AgentSandeshArguments *args) {
272 0 : args->Add("device", dev_str_);
273 0 : args->Add("vn", vn_str_);
274 0 : return true;
275 : }
276 :
277 : private:
278 0 : DBTable *AgentGetTable() {
279 0 : Agent *agent = Agent::GetInstance();
280 : return static_cast<DBTable *>
281 0 : (agent->physical_device_vn_table());
282 : }
283 0 : void Alloc() {
284 0 : resp_ = new SandeshPhysicalDeviceVnListResp();
285 0 : }
286 :
287 : std::string dev_str_;
288 : boost::uuids::uuid dev_uuid_;
289 : std::string vn_str_;
290 : boost::uuids::uuid vn_uuid_;
291 : };
292 :
293 0 : static void SetPhysicalDeviceVnSandeshData(const PhysicalDeviceVn *entry,
294 : SandeshPhysicalDeviceVn *data) {
295 0 : data->set_device_uuid(UuidToString(entry->device_uuid()));
296 0 : if (entry->device()) {
297 0 : data->set_device(entry->device()->name());
298 : } else {
299 0 : data->set_device("INVALID");
300 : }
301 0 : data->set_vn_uuid(UuidToString(entry->vn_uuid()));
302 0 : if (entry->vn()) {
303 0 : data->set_vn(entry->vn()->GetName());
304 : } else {
305 0 : data->set_vn("INVALID");
306 : }
307 0 : data->set_vxlan_id(entry->vxlan_id());
308 0 : }
309 :
310 0 : bool PhysicalDeviceVn::DBEntrySandesh(Sandesh *resp, std::string &name)
311 : const {
312 0 : SandeshPhysicalDeviceVnListResp *port_resp =
313 : static_cast<SandeshPhysicalDeviceVnListResp *>(resp);
314 :
315 0 : SandeshPhysicalDeviceVn data;
316 0 : SetPhysicalDeviceVnSandeshData(this, &data);
317 : std::vector<SandeshPhysicalDeviceVn> &list =
318 : const_cast<std::vector<SandeshPhysicalDeviceVn>&>
319 0 : (port_resp->get_port_list());
320 0 : list.push_back(data);
321 0 : return true;
322 0 : }
323 :
324 0 : void SandeshPhysicalDeviceVnReq::HandleRequest() const {
325 0 : AgentSandeshPtr sand(new AgentPhysicalDeviceVnSandesh(context(),
326 0 : get_device(),
327 0 : get_vn()));
328 0 : sand->DoSandesh(sand);
329 0 : }
330 :
331 0 : AgentSandeshPtr PhysicalDeviceVnTable::GetAgentSandesh
332 : (const AgentSandeshArguments *args, const std::string &context){
333 : return AgentSandeshPtr
334 0 : (new AgentPhysicalDeviceVnSandesh(context, args->GetString("device"),
335 0 : args->GetString("vn")));
336 : }
337 :
338 2 : void PhysicalDeviceVn::SendObjectLog(AgentLogEvent::type event) const {
339 2 : PhysicalDeviceVnObjectLogInfo info;
340 :
341 2 : string str;
342 2 : switch (event) {
343 1 : case AgentLogEvent::ADD:
344 1 : str.assign("Addition ");
345 1 : break;
346 1 : case AgentLogEvent::DEL:
347 1 : str.assign("Deletion ");
348 1 : break;
349 0 : case AgentLogEvent::CHANGE:
350 0 : str.assign("Modification ");
351 0 : break;
352 0 : default:
353 0 : str.assign("INVALID");
354 0 : break;
355 : }
356 2 : info.set_event(str);
357 :
358 2 : info.set_device_uuid(UuidToString(device_uuid_));
359 2 : if (device_.get()) {
360 2 : info.set_device(device_->name());
361 : } else {
362 0 : info.set_device("INVALID");
363 : }
364 2 : info.set_vn_uuid(UuidToString(vn_uuid_));
365 2 : if (vn_) {
366 2 : info.set_vn(vn_->GetName());
367 : } else {
368 0 : info.set_vn("INVALID");
369 : }
370 2 : info.set_ref_count(GetRefCount());
371 2 : PHYSICAL_DEVICE_VN_OBJECT_LOG_LOG("PhysicalDeviceVn",
372 : SandeshLevel::SYS_INFO, info);
373 2 : }
374 :
375 : /////////////////////////////////////////////////////////////////////////////
376 : // Sandesh routines to dump config tree
377 : /////////////////////////////////////////////////////////////////////////////
378 : class ConfigPhysicalDeviceVnSandesh : public Task {
379 : public:
380 0 : ConfigPhysicalDeviceVnSandesh(Agent *agent, PhysicalDeviceVnTable *table,
381 0 : const string &key, const string &context) :
382 : Task(agent->task_scheduler()->GetTaskId(AGENT_SANDESH_TASKNAME), 0),
383 0 : table_(table), key_(key), context_(context) { }
384 0 : ~ConfigPhysicalDeviceVnSandesh() { }
385 : virtual bool Run();
386 0 : std::string Description() const { return "ConfigPhysicalDeviceVnSandesh"; }
387 :
388 : private:
389 : PhysicalDeviceVnTable *table_;
390 : string key_;
391 : string context_;
392 : DISALLOW_COPY_AND_ASSIGN(ConfigPhysicalDeviceVnSandesh);
393 : };
394 :
395 0 : bool ConfigPhysicalDeviceVnSandesh::Run() {
396 : SandeshConfigPhysicalDeviceVnListResp *resp =
397 0 : new SandeshConfigPhysicalDeviceVnListResp();
398 : std::vector<SandeshConfigPhysicalDeviceVn> &list =
399 : const_cast<std::vector<SandeshConfigPhysicalDeviceVn>&>
400 0 : (resp->get_device_vn_list());
401 :
402 : PhysicalDeviceVnTable::ConfigTree::const_iterator it =
403 0 : table_->config_tree().begin();
404 0 : while (it != table_->config_tree().end()){
405 0 : SandeshConfigPhysicalDeviceVn entry;
406 0 : entry.set_device_uuid(UuidToString(it->dev_));
407 0 : entry.set_vn_uuid(UuidToString(it->vn_));
408 0 : entry.set_vmi_uuid(UuidToString(it->vmi_));
409 0 : list.push_back(entry);
410 0 : it++;
411 0 : }
412 0 : resp->set_context(context_);
413 0 : resp->set_more(false);
414 0 : resp->Response();
415 0 : return true;
416 : }
417 :
418 0 : void SandeshConfigPhysicalDeviceVnReq::HandleRequest() const {
419 0 : Agent *agent = Agent::GetInstance();
420 : ConfigPhysicalDeviceVnSandesh *task =
421 : new ConfigPhysicalDeviceVnSandesh
422 0 : (agent, agent->physical_device_vn_table(),
423 0 : get_device(), context());
424 0 : agent->task_scheduler()->Enqueue(task);
425 0 : }
|