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/ifmap_dependency_manager.h>
14 : #include <oper/interface_common.h>
15 : #include <oper/physical_device.h>
16 : #include <oper/logical_interface.h>
17 : #include <oper/vm_interface.h>
18 : #include <oper/config_manager.h>
19 : #include <oper/vn.h>
20 :
21 : #include <vector>
22 : #include <string>
23 :
24 : using std::string;
25 : using std::unique_ptr;
26 : using boost::uuids::uuid;
27 :
28 : /////////////////////////////////////////////////////////////////////////////
29 : // LogicalInterface routines
30 : /////////////////////////////////////////////////////////////////////////////
31 10 : LogicalInterface::LogicalInterface(const boost::uuids::uuid &uuid,
32 : const std::string &name,
33 10 : const boost::uuids::uuid &logical_router_uuid) :
34 : Interface(Interface::LOGICAL, uuid, name, NULL, true, logical_router_uuid),
35 10 : display_name_(),
36 10 : physical_interface_(),
37 10 : vm_interface_(),
38 10 : physical_device_(NULL),
39 10 : phy_dev_display_name_(),
40 10 : phy_intf_display_name_(),
41 10 : vn_uuid_() {
42 10 : }
43 :
44 10 : LogicalInterface::~LogicalInterface() {
45 10 : }
46 :
47 8 : PhysicalDevice *LogicalInterface::physical_device() const {
48 8 : return physical_device_.get();
49 : }
50 :
51 0 : string LogicalInterface::ToString() const {
52 0 : return UuidToString(uuid_);
53 : }
54 :
55 18 : bool LogicalInterface::CmpInterface(const DBEntry &rhs) const {
56 18 : const LogicalInterface &a = static_cast<const LogicalInterface &>(rhs);
57 18 : return (uuid_ < a.uuid_);
58 : }
59 :
60 8 : bool LogicalInterface::OnChange(const InterfaceTable *table,
61 : const LogicalInterfaceData *data) {
62 8 : bool ret = false;
63 :
64 8 : if (display_name_ != data->display_name_) {
65 1 : display_name_ = data->display_name_;
66 1 : ret = true;
67 : }
68 :
69 8 : PhysicalInterfaceKey phy_key(data->physical_interface_);
70 8 : Interface *intf = static_cast<PhysicalInterface *>
71 8 : (table->agent()->interface_table()->FindActiveEntry(&phy_key));
72 8 : if (intf == NULL) {
73 1 : RemotePhysicalInterfaceKey rem_key(data->physical_interface_);
74 1 : intf = static_cast<RemotePhysicalInterface *>
75 1 : (table->agent()->interface_table()->FindActiveEntry(&rem_key));
76 1 : }
77 :
78 8 : if (intf != physical_interface_.get()) {
79 2 : physical_interface_.reset(intf);
80 2 : ret = true;
81 : }
82 :
83 8 : if (phy_intf_display_name_ != data->phy_intf_display_name_) {
84 2 : OPER_TRACE_ENTRY(Trace, table,
85 : "Changing Physical Interface display name from " \
86 : + phy_intf_display_name_ + " to " +
87 : data->phy_intf_display_name_);
88 2 : phy_intf_display_name_ = data->phy_intf_display_name_;
89 2 : ret = true;
90 : }
91 :
92 16 : VmInterfaceKey vmi_key(AgentKey::ADD_DEL_CHANGE, data->vm_interface_, "");
93 8 : Interface *intrface = static_cast<Interface *>
94 8 : (table->agent()->interface_table()->FindActiveEntry(&vmi_key));
95 8 : if (intrface != vm_interface_.get()) {
96 3 : vm_interface_.reset(intrface);
97 3 : ret = true;
98 : }
99 :
100 8 : boost::uuids::uuid old_vn_uuid = vn_uuid_;
101 8 : VmInterface *vmi = static_cast<VmInterface *>(vm_interface_.get());
102 8 : if (vm_interface_.get() && vmi->vn()) {
103 3 : vn_uuid_ = vmi->vn()->GetUuid();
104 : } else {
105 5 : vn_uuid_ = boost::uuids::nil_uuid();
106 : }
107 8 : if (old_vn_uuid != vn_uuid_)
108 2 : ret = true;
109 :
110 8 : vm_uuid_ = data->vm_interface_;
111 :
112 : PhysicalDevice *dev = table->agent()->physical_device_table()->
113 8 : Find(data->device_uuid_);
114 8 : if (dev != physical_device_.get()) {
115 2 : physical_device_.reset(dev);
116 2 : ret = true;
117 : }
118 :
119 8 : if (phy_dev_display_name_ != data->phy_dev_display_name_) {
120 2 : OPER_TRACE_ENTRY(Trace, table,
121 : "Changing Physical Device display name from " \
122 : + phy_dev_display_name_ + " to " +
123 : data->phy_dev_display_name_);
124 2 : phy_dev_display_name_ = data->phy_dev_display_name_;
125 2 : ret = true;
126 : }
127 :
128 8 : return ret;
129 8 : }
130 :
131 1 : bool LogicalInterface::Delete(const DBRequest *req) {
132 1 : return true;
133 : }
134 :
135 1 : void LogicalInterface::GetOsParams(Agent *agent) {
136 1 : os_params_.os_index_ = Interface::kInvalidIndex;
137 1 : os_params_.mac_.Zero();
138 1 : os_params_.os_oper_state_ = true;
139 1 : }
140 :
141 0 : VmInterface *LogicalInterface::vm_interface() const {
142 0 : return static_cast<VmInterface *>(vm_interface_.get());
143 : }
144 :
145 8 : Interface *LogicalInterface::physical_interface() const {
146 8 : return static_cast<Interface *>(physical_interface_.get());
147 : }
148 :
149 : //////////////////////////////////////////////////////////////////////////////
150 : // LogicalInterfaceKey routines
151 : //////////////////////////////////////////////////////////////////////////////
152 :
153 27 : LogicalInterfaceKey::LogicalInterfaceKey(const boost::uuids::uuid &uuid,
154 27 : const std::string &name) :
155 : InterfaceKey(AgentKey::ADD_DEL_CHANGE, Interface::LOGICAL, uuid, name,
156 27 : false) {
157 27 : }
158 :
159 27 : LogicalInterfaceKey::~LogicalInterfaceKey() {
160 27 : }
161 :
162 : //////////////////////////////////////////////////////////////////////////////
163 : // LogicalInterfaceData routines
164 : //////////////////////////////////////////////////////////////////////////////
165 8 : LogicalInterfaceData::LogicalInterfaceData(Agent *agent, IFMapNode *node,
166 : const std::string &display_name,
167 : const std::string &port,
168 : const boost::uuids::uuid &vif,
169 : const uuid &device_uuid,
170 : const std::string &phy_dev_display_name,
171 8 : const std::string &phy_intf_display_name) :
172 : InterfaceData(agent, node, Interface::TRANSPORT_INVALID),
173 8 : display_name_(display_name),
174 8 : physical_interface_(port), vm_interface_(vif), device_uuid_(device_uuid),
175 8 : phy_dev_display_name_(phy_dev_display_name),
176 16 : phy_intf_display_name_(phy_intf_display_name) {
177 8 : }
178 :
179 8 : LogicalInterfaceData::~LogicalInterfaceData() {
180 8 : }
181 :
182 : //////////////////////////////////////////////////////////////////////////////
183 : // VlanLogicalInterface routines
184 : //////////////////////////////////////////////////////////////////////////////
185 10 : VlanLogicalInterface::VlanLogicalInterface(const boost::uuids::uuid &uuid,
186 : const std::string &name,
187 : uint16_t vlan,
188 10 : const boost::uuids::uuid &logical_router_uuid) :
189 10 : LogicalInterface(uuid, name, logical_router_uuid), vlan_(vlan) {
190 10 : }
191 :
192 20 : VlanLogicalInterface::~VlanLogicalInterface() {
193 20 : }
194 :
195 0 : DBEntryBase::KeyPtr VlanLogicalInterface::GetDBRequestKey() const {
196 0 : InterfaceKey *key = new VlanLogicalInterfaceKey(uuid_, name());
197 0 : return DBEntryBase::KeyPtr(key);
198 : }
199 :
200 : //////////////////////////////////////////////////////////////////////////////
201 : // VlanLogicalInterfaceKey routines
202 : //////////////////////////////////////////////////////////////////////////////
203 27 : VlanLogicalInterfaceKey::VlanLogicalInterfaceKey(const boost::uuids::uuid &uuid,
204 27 : const std::string &name) :
205 27 : LogicalInterfaceKey(uuid, name) {
206 27 : }
207 :
208 54 : VlanLogicalInterfaceKey::~VlanLogicalInterfaceKey() {
209 54 : }
210 :
211 : LogicalInterface *
212 9 : VlanLogicalInterfaceKey::AllocEntry(const InterfaceTable *table)
213 : const {
214 9 : return new VlanLogicalInterface(uuid_, name_, 0, boost::uuids::nil_uuid());
215 : }
216 :
217 : LogicalInterface *
218 1 : VlanLogicalInterfaceKey::AllocEntry(const InterfaceTable *table,
219 : const InterfaceData *d) const {
220 1 : const VlanLogicalInterfaceData *data =
221 : static_cast<const VlanLogicalInterfaceData *>(d);
222 1 : VlanLogicalInterface *intf = new VlanLogicalInterface(uuid_, name_,
223 1 : data->vlan_,
224 1 : data->logical_router_uuid_);
225 :
226 1 : intf->OnChange(table, data);
227 1 : return intf;
228 : }
229 :
230 0 : InterfaceKey *VlanLogicalInterfaceKey::Clone() const {
231 0 : return new VlanLogicalInterfaceKey(uuid_, name_);
232 : }
233 :
234 8 : VlanLogicalInterfaceData::VlanLogicalInterfaceData
235 : (Agent *agent, IFMapNode *node, const std::string &display_name,
236 : const std::string &physical_interface,
237 : const boost::uuids::uuid &vif, const boost::uuids::uuid &u,
238 : const std::string &phy_dev_display_name,
239 8 : const std::string &phy_intf_display_name, uint16_t vlan) :
240 : LogicalInterfaceData(agent, node, display_name, physical_interface, vif, u,
241 : phy_dev_display_name, phy_intf_display_name),
242 8 : vlan_(vlan) {
243 8 : }
244 :
245 16 : VlanLogicalInterfaceData::~VlanLogicalInterfaceData() {
246 16 : }
247 :
248 : #if 0
249 : void VlanLogicalInterface::SetSandeshData(SandeshLogicalInterface *data) const {
250 : data->set_vlan_tag(vlan_);
251 : }
252 : #endif
253 : /////////////////////////////////////////////////////////////////////////////
254 : // Config handling routines
255 : /////////////////////////////////////////////////////////////////////////////
256 27 : static LogicalInterfaceKey *BuildKey(IFMapNode *node,
257 : const boost::uuids::uuid &u) {
258 27 : return new VlanLogicalInterfaceKey(u, node->name());
259 : }
260 :
261 8 : static LogicalInterfaceData *BuildData(Agent *agent, IFMapNode *node,
262 : const uuid &u,
263 : const autogen::LogicalInterface *port) {
264 : // Find link with physical-interface adjacency
265 8 : string physical_interface;
266 8 : string phy_dev_display_name;
267 8 : string phy_intf_display_name;
268 8 : IFMapNode *adj_node = NULL;
269 8 : boost::uuids::uuid dev_uuid = boost::uuids::nil_uuid();
270 8 : adj_node = agent->config_manager()->FindAdjacentIFMapNode(node,
271 : "physical-interface");
272 8 : IFMapNode *prouter_node = NULL;
273 :
274 8 : if (adj_node) {
275 7 : physical_interface = adj_node->name();
276 : autogen::PhysicalInterface *port =
277 7 : static_cast <autogen::PhysicalInterface *>(adj_node->GetObject());
278 7 : assert(port);
279 7 : phy_intf_display_name = port->display_name();
280 : prouter_node = agent->config_manager()->
281 7 : FindAdjacentIFMapNode(adj_node, "physical-router");
282 7 : if (prouter_node) {
283 : autogen::PhysicalRouter *router =
284 6 : static_cast<autogen::PhysicalRouter *>(prouter_node->GetObject());
285 6 : phy_dev_display_name = router->display_name();
286 6 : autogen::IdPermsType id_perms = router->id_perms();
287 6 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
288 : dev_uuid);
289 6 : }
290 : }
291 :
292 : // Find link with virtual-machine-interface adjacency
293 8 : boost::uuids::uuid vmi_uuid = boost::uuids::nil_uuid();
294 : adj_node = agent->config_manager()->FindAdjacentIFMapNode
295 8 : (node, "virtual-machine-interface");
296 8 : if (adj_node) {
297 : autogen::VirtualMachineInterface *vmi =
298 : static_cast<autogen::VirtualMachineInterface *>
299 5 : (adj_node->GetObject());
300 5 : autogen::IdPermsType id_perms = vmi->id_perms();
301 5 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
302 : vmi_uuid);
303 5 : }
304 :
305 8 : string dev_name;
306 : adj_node = agent->config_manager()->FindAdjacentIFMapNode
307 8 : (node, "physical-router");
308 8 : if (adj_node) {
309 0 : dev_name = adj_node->name();
310 0 : if (dev_uuid != boost::uuids::nil_uuid()) {
311 0 : IFMAP_ERROR(LogicalInterfaceConfiguration,
312 : "Both physical-router and physical-interface links for "
313 : "interface:", node->name(),
314 : "physical interface", physical_interface,
315 : "prouter name", dev_name);
316 : }
317 : autogen::PhysicalRouter *router =
318 0 : static_cast<autogen::PhysicalRouter *>(adj_node->GetObject());
319 0 : autogen::IdPermsType id_perms = router->id_perms();
320 0 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
321 : dev_uuid);
322 0 : }
323 :
324 : // Logical-Interface must have VLAN-Tag field. Ignore the interface if
325 : // VLAN-Tag is not yet present
326 8 : if (port->IsPropertySet(autogen::LogicalInterface::VLAN_TAG) == false) {
327 0 : OperConfigInfo t;
328 0 : t.set_name(node->name());
329 0 : t.set_uuid(UuidToString(u));
330 0 : t.set_message("VLAN-Tag property not set. Ignoring node");
331 :
332 0 : OPER_IFMAP_TRACE(Config, t);
333 0 : return NULL;
334 0 : }
335 :
336 8 : return new VlanLogicalInterfaceData(agent, node, port->display_name(),
337 : physical_interface, vmi_uuid, dev_uuid,
338 : phy_dev_display_name,
339 : phy_intf_display_name,
340 8 : port->vlan_tag());
341 8 : }
342 :
343 23 : bool InterfaceTable::LogicalInterfaceIFNodeToUuid(IFMapNode *node,
344 : boost::uuids::uuid &u) {
345 :
346 : autogen::LogicalInterface *port =
347 23 : static_cast <autogen::LogicalInterface *>(node->GetObject());
348 23 : assert(port);
349 :
350 23 : autogen::IdPermsType id_perms = port->id_perms();
351 23 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u);
352 23 : return true;
353 23 : }
354 :
355 8 : bool InterfaceTable::LogicalInterfaceProcessConfig(IFMapNode *node,
356 : DBRequest &req,
357 : const boost::uuids::uuid &u) {
358 : autogen::LogicalInterface *port =
359 8 : static_cast <autogen::LogicalInterface *>(node->GetObject());
360 8 : assert(port);
361 :
362 8 : req.key.reset(BuildKey(node, u));
363 8 : if (node->IsDeleted()) {
364 0 : req.oper = DBRequest::DB_ENTRY_DELETE;
365 0 : return true;
366 : }
367 :
368 8 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
369 8 : req.data.reset(BuildData(agent(), node, u, port));
370 :
371 8 : if (req.data.get() != NULL) {
372 8 : li_ifnode_to_req_++;
373 8 : Enqueue(&req);
374 : }
375 8 : return false;
376 : }
377 :
378 19 : bool InterfaceTable::LogicalInterfaceIFNodeToReq(IFMapNode *node,
379 : DBRequest &req,
380 : const boost::uuids::uuid &u) {
381 : autogen::LogicalInterface *port =
382 19 : static_cast <autogen::LogicalInterface *>(node->GetObject());
383 19 : assert(port);
384 :
385 19 : req.key.reset(BuildKey(node, u));
386 19 : if (req.oper == DBRequest::DB_ENTRY_DELETE || node->IsDeleted()) {
387 1 : req.oper = DBRequest::DB_ENTRY_DELETE;
388 1 : return true;
389 : }
390 :
391 18 : agent()->config_manager()->AddLogicalInterfaceNode(node);
392 18 : return false;
393 : }
|