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