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