Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : sact*/
5 :
6 : #include "base/os.h"
7 : #include <sys/types.h>
8 : #include <net/ethernet.h>
9 : #include <netinet/ether.h>
10 : #include <boost/uuid/uuid_io.hpp>
11 :
12 : #include "base/logging.h"
13 : #include "base/address.h"
14 : #include "db/db.h"
15 : #include "db/db_entry.h"
16 : #include "db/db_table.h"
17 : #include "ifmap/ifmap_node.h"
18 :
19 : #include <init/agent_param.h>
20 : #include <cfg/cfg_init.h>
21 : #include <oper/operdb_init.h>
22 : #include <oper/route_common.h>
23 : #include <oper/vm.h>
24 : #include <oper/vn.h>
25 : #include <oper/vrf.h>
26 : #include <oper/nexthop.h>
27 : #include <oper/mpls.h>
28 : #include <oper/mirror_table.h>
29 : #include <oper/interface_common.h>
30 : #include <oper/vrf_assign.h>
31 : #include <oper/vxlan.h>
32 : #include <oper/qos_config.h>
33 : #include <oper/ifmap_dependency_manager.h>
34 : #include <oper/tag.h>
35 : #include <oper/config_manager.h>
36 :
37 : #include <vnc_cfg_types.h>
38 : #include <oper/agent_sandesh.h>
39 : #include <oper/sg.h>
40 : #include <oper/metadata_ip.h>
41 : #include <sandesh/sandesh_trace.h>
42 : #include <sandesh/common/vns_types.h>
43 : #include <sandesh/common/vns_constants.h>
44 : #include <filter/acl.h>
45 : #include <filter/policy_set.h>
46 : #include <resource_manager/resource_manager.h>
47 : #include <resource_manager/resource_table.h>
48 : #include <resource_manager/vm_interface_index.h>
49 : using namespace std;
50 : using namespace boost::uuids;
51 : using boost::assign::map_list_of;
52 : using boost::assign::list_of;
53 :
54 : InterfaceTable *InterfaceTable::interface_table_;
55 :
56 : /////////////////////////////////////////////////////////////////////////////
57 : // Interface Table routines
58 : /////////////////////////////////////////////////////////////////////////////
59 2 : InterfaceTable::InterfaceTable(DB *db, const std::string &name) :
60 2 : AgentOperDBTable(db, name), operdb_(NULL), agent_(NULL),
61 2 : index_table_(), vmi_count_(0), li_count_(0), active_vmi_count_(0),
62 4 : vmi_ifnode_to_req_(0), li_ifnode_to_req_(0), pi_ifnode_to_req_(0) {
63 : global_config_change_walk_ref_ =
64 4 : AllocWalker(boost::bind(&InterfaceTable::L2VmInterfaceWalk,
65 : this, _1, _2),
66 : boost::bind(&InterfaceTable::VmInterfaceWalkDone,
67 2 : this, _1, _2));
68 2 : }
69 :
70 2 : void InterfaceTable::Init(OperDB *oper) {
71 2 : operdb_ = oper;
72 2 : agent_ = oper->agent();
73 2 : }
74 :
75 2 : void InterfaceTable::RegisterDBClients(IFMapDependencyManager *dep) {
76 2 : }
77 :
78 3001 : bool InterfaceTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u) {
79 3001 : if (strcmp(node->table()->Typename(), "virtual-machine-interface") == 0) {
80 2973 : return VmiIFNodeToUuid(node, u);
81 : }
82 :
83 28 : if (strcmp(node->table()->Typename(), "logical-interface") == 0) {
84 19 : return LogicalInterfaceIFNodeToUuid(node, u);
85 : }
86 :
87 9 : return false;
88 : }
89 :
90 3001 : bool InterfaceTable::IFNodeToReq(IFMapNode *node, DBRequest &req,
91 : const boost::uuids::uuid &u) {
92 3001 : if (strcmp(node->table()->Typename(), "physical-interface") == 0) {
93 9 : return PhysicalInterfaceIFNodeToReq(node, req, u);
94 : }
95 :
96 2992 : if (strcmp(node->table()->Typename(), "logical-interface") == 0) {
97 19 : return LogicalInterfaceIFNodeToReq(node, req, u);
98 : }
99 :
100 2973 : if (strcmp(node->table()->Typename(), "virtual-machine-interface") == 0) {
101 2973 : return VmiIFNodeToReq(node, req, u);
102 : }
103 :
104 0 : return false;
105 : }
106 :
107 1202 : bool InterfaceTable::InterfaceCommonProcessConfig(IFMapNode *node,
108 : DBRequest &req,
109 : const boost::uuids::uuid &u) {
110 1202 : if (req.oper == DBRequest::DB_ENTRY_DELETE || node->IsDeleted()) {
111 0 : return true;
112 : }
113 :
114 1202 : InterfaceData *data = static_cast<InterfaceData *>(req.data.get());
115 : IFMapNode *adj_node = agent()->config_manager()->
116 1202 : FindAdjacentIFMapNode(node, "logical-router");
117 1202 : if (adj_node) {
118 : autogen::LogicalRouter *lr =
119 0 : static_cast<autogen::LogicalRouter *>(adj_node->GetObject());
120 0 : autogen::IdPermsType id_perms = lr->id_perms();
121 0 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
122 0 : data->logical_router_uuid_);
123 0 : }
124 :
125 1202 : return true;
126 : }
127 :
128 1227 : bool InterfaceTable::ProcessConfig(IFMapNode *node, DBRequest &req,
129 : const boost::uuids::uuid &u) {
130 1227 : bool config_processed = false;
131 1227 : if (strcmp(node->table()->Typename(), "physical-interface") == 0) {
132 4 : if (PhysicalInterfaceProcessConfig(node, req, u)) {
133 0 : config_processed = true;
134 : }
135 : }
136 :
137 1227 : if (strcmp(node->table()->Typename(), "logical-interface") == 0) {
138 8 : if (LogicalInterfaceProcessConfig(node, req, u)) {
139 0 : config_processed = true;
140 : }
141 : }
142 :
143 1227 : if (strcmp(node->table()->Typename(), "virtual-machine-interface") == 0) {
144 1215 : if (VmiProcessConfig(node, req, u)) {
145 1202 : config_processed = true;
146 : }
147 : }
148 :
149 : //Interface type was identified, if not no need to fill common interface
150 : //data.
151 1227 : if (config_processed) {
152 1202 : InterfaceCommonProcessConfig(node, req, u);
153 : }
154 1227 : return config_processed;
155 : }
156 :
157 26956 : std::unique_ptr<DBEntry> InterfaceTable::AllocEntry(const DBRequestKey *k) const{
158 26956 : const InterfaceKey *key = static_cast<const InterfaceKey *>(k);
159 :
160 : return std::unique_ptr<DBEntry>(static_cast<DBEntry *>
161 26956 : (key->AllocEntry(this)));
162 : }
163 :
164 176 : void InterfaceTable::FreeInterfaceId(size_t index) {
165 176 : agent()->resource_manager()->Release(Resource::INTERFACE_INDEX, index);
166 176 : index_table_.Remove(index);
167 176 : }
168 :
169 176 : DBEntry *InterfaceTable::OperDBAdd(const DBRequest *req) {
170 176 : InterfaceKey *key = static_cast<InterfaceKey *>(req->key.get());
171 176 : InterfaceData *data = static_cast<InterfaceData *>(req->data.get());
172 :
173 176 : Interface *intf = key->AllocEntry(this, data);
174 176 : if (intf == NULL)
175 0 : return NULL;
176 176 : if (intf->type_ == Interface::VM_INTERFACE) {
177 169 : vmi_count_++;
178 7 : } else if (intf->type_ == Interface::LOGICAL) {
179 1 : li_count_++;
180 : }
181 : ResourceManager::KeyPtr rkey(new VmInterfaceIndexResourceKey
182 176 : (agent()->resource_manager(), key->uuid_,
183 176 : key->name_));
184 176 : intf->id_ = static_cast<IndexResourceData *>(agent()->resource_manager()->
185 176 : Allocate(rkey).get())->index();
186 176 : index_table_.InsertAtIndex(intf->id_, intf);
187 :
188 176 : intf->transport_ = data->transport_;
189 : // Get the os-ifindex and mac of interface
190 176 : intf->GetOsParams(agent());
191 :
192 176 : intf->Add();
193 :
194 176 : intf->SendTrace(this, Interface::ADD);
195 176 : return intf;
196 176 : }
197 :
198 14 : bool InterfaceTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) {
199 14 : bool ret = false;
200 14 : InterfaceKey *key = static_cast<InterfaceKey *>(req->key.get());
201 :
202 14 : switch (key->type_) {
203 4 : case Interface::VM_INTERFACE: {
204 4 : VmInterface *intf = static_cast<VmInterface *>(entry);
205 4 : ret = intf->OnChange(static_cast<VmInterfaceData *>(req->data.get()));
206 4 : break;
207 : }
208 0 : case Interface::INET: {
209 0 : InetInterface *intf = static_cast<InetInterface *>(entry);
210 0 : if (intf) {
211 : // Get the os-ifindex and mac of interface
212 0 : intf->GetOsParams(agent());
213 0 : intf->OnChange(static_cast<InetInterfaceData *>(req->data.get()));
214 0 : ret = true;
215 : }
216 0 : break;
217 : }
218 :
219 3 : case Interface::PHYSICAL: {
220 3 : PhysicalInterface *intf = static_cast<PhysicalInterface *>(entry);
221 3 : ret = intf->OnChange(this, static_cast<PhysicalInterfaceData *>
222 3 : (req->data.get()));
223 3 : break;
224 : }
225 :
226 0 : case Interface::REMOTE_PHYSICAL: {
227 0 : RemotePhysicalInterface *intf =
228 0 : static_cast<RemotePhysicalInterface *>(entry);
229 0 : ret = intf->OnChange(this, static_cast<RemotePhysicalInterfaceData *>
230 0 : (req->data.get()));
231 0 : break;
232 : }
233 :
234 7 : case Interface::LOGICAL: {
235 7 : LogicalInterface *intf = static_cast<LogicalInterface *>(entry);
236 7 : ret = intf->OnChange(this, static_cast<LogicalInterfaceData *>
237 7 : (req->data.get()));
238 7 : break;
239 : }
240 :
241 0 : case Interface::PACKET: {
242 0 : PacketInterface *intf = static_cast<PacketInterface *>(entry);
243 0 : PacketInterfaceData *data = static_cast<PacketInterfaceData *>(req->data.get());
244 0 : ret = intf->OnChange(data);
245 0 : break;
246 : }
247 :
248 0 : default:
249 0 : break;
250 : }
251 :
252 14 : return ret;
253 : }
254 :
255 : // RESYNC supported only for VM_INTERFACE
256 1160 : bool InterfaceTable::OperDBResync(DBEntry *entry, const DBRequest *req) {
257 1160 : InterfaceKey *key = static_cast<InterfaceKey *>(req->key.get());
258 :
259 : //RESYNC for QOS config handling for vhost and fabric interface
260 : InterfaceQosConfigData *qos_config_data =
261 1160 : dynamic_cast<InterfaceQosConfigData *>(req->data.get());
262 1160 : if (qos_config_data) {
263 0 : Interface *intf = static_cast<Interface *>(entry);
264 0 : AgentQosConfigKey key(qos_config_data->qos_config_uuid_);
265 :
266 0 : AgentQosConfig *qos_config = static_cast<AgentQosConfig *>
267 0 : (agent()->qos_config_table()->FindActiveEntry(&key));
268 :
269 0 : if (intf->qos_config_ != qos_config) {
270 0 : intf->qos_config_ = qos_config;
271 0 : return true;
272 : }
273 0 : return false;
274 0 : }
275 :
276 1160 : if (key->type_ != Interface::VM_INTERFACE)
277 0 : return false;
278 :
279 1160 : VmInterfaceData *vm_data = static_cast<VmInterfaceData *>(req->data.get());
280 1160 : VmInterface *intf = static_cast<VmInterface *>(entry);
281 1160 : return intf->Resync(this, vm_data);
282 : }
283 :
284 177 : bool InterfaceTable::OperDBDelete(DBEntry *entry, const DBRequest *req) {
285 177 : Interface *intf = static_cast<Interface *>(entry);
286 177 : bool ret = false;
287 :
288 177 : if (intf->Delete(req)) {
289 177 : intf->SendTrace(this, Interface::DEL);
290 177 : ret = true;
291 : }
292 177 : return ret;
293 : }
294 :
295 2192 : VrfEntry *InterfaceTable::FindVrfRef(const string &name) const {
296 2192 : VrfKey key(name);
297 2192 : return static_cast<VrfEntry *>
298 4384 : (agent_->vrf_table()->FindActiveEntry(&key));
299 2192 : }
300 :
301 1327 : VmEntry *InterfaceTable::FindVmRef(const uuid &uuid) const {
302 1327 : VmKey key(uuid);
303 2654 : return static_cast<VmEntry *>(agent_->vm_table()->FindActiveEntry(&key));
304 1327 : }
305 :
306 1553 : VnEntry *InterfaceTable::FindVnRef(const uuid &uuid) const {
307 1553 : VnKey key(uuid);
308 3106 : return static_cast<VnEntry *>(agent_->vn_table()->FindActiveEntry(&key));
309 1553 : }
310 :
311 1327 : MirrorEntry *InterfaceTable::FindMirrorRef(const string &name) const {
312 1327 : MirrorEntryKey key(name);
313 1327 : return static_cast<MirrorEntry *>
314 2654 : (agent_->mirror_table()->FindActiveEntry(&key));
315 1327 : }
316 :
317 2 : DBTableBase *InterfaceTable::CreateTable(DB *db, const std::string &name) {
318 2 : interface_table_ = new InterfaceTable(db, name);
319 2 : (static_cast<DBTable *>(interface_table_))->Init();
320 2 : return interface_table_;
321 : };
322 :
323 0 : const Interface *InterfaceTable::FindInterface(size_t index) const {
324 0 : Interface *intf = index_table_.At(index);
325 0 : if (intf && intf->IsDeleted() != true) {
326 0 : return intf;
327 : }
328 0 : return NULL;
329 : }
330 :
331 5717 : Interface *InterfaceTable::FindInterface(size_t index) {
332 5717 : Interface *intf = index_table_.At(index);
333 5717 : if (intf && intf->IsDeleted() != true) {
334 5691 : return intf;
335 : }
336 26 : return NULL;
337 : }
338 :
339 0 : bool InterfaceTable::FindVmUuidFromMetadataIp(const IpAddress &ip,
340 : std::string *vm_ip,
341 : std::string *vm_uuid,
342 : std::string *vm_project_uuid) {
343 0 : const Interface *intf = NULL;
344 0 : if (ip.is_v4()) {
345 0 : intf = FindInterfaceFromMetadataIp(ip.to_v4());
346 : } else {
347 0 : intf = FindInterfaceFromMetadataIp(ip.to_v6());
348 : }
349 0 : if (!intf) {
350 0 : LOG(ERROR, "Interface in table was not found, ip = " <<
351 : ip.to_string() << ", in: " <<
352 : "InterfaceTable::FindVmUuidFromMetadataIp" <<
353 : std::endl);
354 0 : return false;
355 : }
356 0 : if (intf && intf->type() == Interface::VM_INTERFACE) {
357 0 : const VmInterface *vintf = static_cast<const VmInterface *>(intf);
358 0 : if (ip.is_v4())
359 0 : *vm_ip = vintf->primary_ip_addr().to_string();
360 : else
361 0 : *vm_ip = vintf->primary_ip6_addr().to_string();
362 0 : if (vintf->vm()) {
363 0 : *vm_uuid = UuidToString(vintf->vm()->GetUuid());
364 0 : *vm_project_uuid = UuidToString(vintf->vm_project_uuid());
365 0 : return true;
366 : }
367 : }
368 0 : return false;
369 : }
370 :
371 0 : const Interface *InterfaceTable::FindInterfaceFromMetadataIp(const Ip4Address &ip) const {
372 0 : uint32_t idx = MetaDataIp::IpAddressToIndex(ip);
373 0 : const MetaDataIp *mip = agent_->metadata_ip_allocator()->FindIndex(idx);
374 0 : return mip != NULL ? mip->GetInterface() : NULL;
375 : }
376 :
377 0 : const Interface *InterfaceTable::FindInterfaceFromMetadataIp(const Ip6Address &ip) const {
378 0 : uint32_t idx = MetaDataIp::IpAddressToIndex(ip);
379 0 : const MetaDataIp *mip = agent_->metadata_ip6_allocator()->FindIndex(idx);
380 0 : return mip != NULL ? mip->GetInterface() : NULL;
381 : }
382 :
383 6 : bool InterfaceTable::L2VmInterfaceWalk(DBTablePartBase *partition,
384 : DBEntryBase *entry) {
385 6 : Interface *intf = static_cast<Interface *>(entry);
386 6 : if ((intf->type() != Interface::VM_INTERFACE) || intf->IsDeleted())
387 4 : return true;
388 :
389 2 : VmInterface *vm_intf = static_cast<VmInterface *>(entry);
390 2 : const VnEntry *vn = vm_intf->vn();
391 2 : if (!vm_intf->IsActive())
392 0 : return true;
393 :
394 2 : if (!vn) {
395 2 : return true;
396 : }
397 :
398 0 : VmInterfaceGlobalVrouterData data(vn->bridging(),
399 0 : vn->layer3_forwarding(),
400 0 : vn->GetVxLanId());
401 0 : vm_intf->Resync(this, &data);
402 0 : return true;
403 0 : }
404 :
405 2 : void InterfaceTable::VmInterfaceWalkDone(DBTable::DBTableWalkRef walk_ref,
406 : DBTableBase *partition) {
407 2 : }
408 :
409 2 : void InterfaceTable::GlobalVrouterConfigChanged() {
410 2 : WalkAgain(global_config_change_walk_ref_);
411 2 : }
412 :
413 0 : void InterfaceTable::Clear() {
414 0 : AgentDBTable::Clear();
415 0 : ReleaseWalker(global_config_change_walk_ref_);
416 0 : global_config_change_walk_ref_ = NULL;
417 0 : }
418 :
419 0 : InterfaceConstRef InterfaceTable::FindVmi(const boost::uuids::uuid &vmi_uuid) {
420 0 : VmInterfaceKey key(AgentKey::ADD_DEL_CHANGE, vmi_uuid, "");
421 0 : Interface *intf = static_cast<Interface *>(Find(&key, false));
422 0 : InterfaceConstRef ref(intf);
423 0 : return ref;
424 0 : }
425 :
426 4 : void InterfaceTable::CreateVhost() {
427 4 : if (agent()->tsn_enabled()) {
428 : Interface::Transport transport = static_cast<Interface::Transport>
429 0 : (agent()->GetInterfaceTransport());
430 0 : AgentParam *params = agent()->params();
431 0 : InetInterface::Create(this, agent()->vhost_interface_name(),
432 : InetInterface::VHOST,
433 : agent()->fabric_vrf_name(),
434 : params->vhost_addr(),
435 : params->vhost_plen(),
436 0 : params->gateway_list()[0],
437 0 : params->eth_port_list()[0],
438 : agent()->fabric_vn_name(), transport);
439 : } else {
440 4 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
441 4 : req.key.reset(new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE,
442 4 : nil_uuid(),
443 4 : agent()->vhost_interface_name()));
444 :
445 4 : VmInterfaceConfigData *data = new VmInterfaceConfigData(agent(), NULL);
446 4 : data->CopyVhostData(agent());
447 4 : data->disable_policy_ = true;
448 4 : req.data.reset(data);
449 4 : Process(req);
450 4 : }
451 4 : }
452 :
453 0 : void InterfaceTable::CreateVhostReq() {
454 0 : if (agent()->tsn_enabled()) {
455 : Interface::Transport transport = static_cast<Interface::Transport>
456 0 : (agent()->GetInterfaceTransport());
457 0 : InetInterface::CreateReq(this, agent()->vhost_interface_name(),
458 : InetInterface::VHOST,
459 : agent()->fabric_vrf_name(),
460 0 : agent()->router_id(),
461 0 : agent()->vhost_prefix_len(),
462 0 : agent()->vhost_default_gateway()[0],
463 0 : Agent::NullString(), agent_->fabric_vrf_name(),
464 : transport);
465 : } else {
466 0 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
467 0 : req.key.reset(new VmInterfaceKey(AgentKey::ADD_DEL_CHANGE, nil_uuid(),
468 0 : agent()->vhost_interface_name()));
469 :
470 0 : VmInterfaceConfigData *data = new VmInterfaceConfigData(agent(), NULL);
471 0 : data->CopyVhostData(agent());
472 :
473 0 : req.data.reset(data);
474 0 : Enqueue(&req);
475 0 : }
476 0 : }
477 : /////////////////////////////////////////////////////////////////////////////
478 : // Interface Base Entry routines
479 : /////////////////////////////////////////////////////////////////////////////
480 27132 : Interface::Interface(Type type, const uuid &uuid, const string &name,
481 : VrfEntry *vrf, bool state,
482 27132 : const boost::uuids::uuid &logical_router_uuid) :
483 27132 : type_(type), uuid_(uuid),
484 54264 : vrf_(vrf, this), label_(MplsTable::kInvalidLabel),
485 27132 : l2_label_(MplsTable::kInvalidLabel), ipv4_active_(true),
486 27132 : ipv6_active_(false), is_hc_active_(true),
487 27132 : metadata_ip_active_(true), metadata_l2_active_(true),
488 27132 : l2_active_(true), id_(kInvalidIndex), dhcp_enabled_(true), dhcp_enabled_v6_(true),
489 27132 : dns_enabled_(true),
490 54264 : admin_state_(true), test_oper_state_(true), transport_(TRANSPORT_INVALID),
491 27132 : os_params_(name, kInvalidIndex, state),
492 27132 : logical_router_uuid_(logical_router_uuid) {
493 27132 : }
494 :
495 27132 : Interface::~Interface() {
496 27132 : InterfaceTable *table = static_cast<InterfaceTable *>(get_table());
497 27132 : if (id_ != kInvalidIndex) {
498 176 : table->FreeInterfaceId(id_);
499 176 : id_ = kInvalidIndex;
500 176 : if (type_ == VM_INTERFACE) {
501 169 : table->decr_vmi_count();
502 7 : } else if (type_ == LOGICAL) {
503 1 : table->decr_li_count();
504 : }
505 : }
506 27132 : }
507 :
508 0 : void Interface::SetPciIndex(Agent *agent, size_t index) {
509 0 : std::istringstream pci(agent->params()->physical_interface_pci_addr_list()[index]);
510 :
511 : uint32_t domain, bus, device, function;
512 : char c;
513 0 : if (pci >> std::hex >> domain) {
514 0 : pci >> c;
515 : } else {
516 0 : assert(0);
517 : }
518 :
519 0 : if (pci >> std::hex >> bus) {
520 0 : pci >> c;
521 : } else {
522 0 : assert(0);
523 : }
524 :
525 0 : if (pci >> std::hex >> device) {
526 0 : pci >> c;
527 : } else {
528 0 : assert(0);
529 : }
530 :
531 0 : pci >> std::hex >> function;
532 0 : os_params_.os_index_ = domain << 16 | bus << 8 | device << 3 | function;
533 0 : os_params_.os_oper_state_ = true;
534 0 : }
535 :
536 173 : void Interface::GetOsParams(Agent *agent) {
537 173 : if (agent->test_mode()) {
538 : static int dummy_ifindex = 0;
539 173 : if (os_params_.os_index_ == kInvalidIndex) {
540 173 : os_params_.os_index_ = ++dummy_ifindex;
541 173 : os_params_.mac_.Zero();
542 173 : os_params_.mac_.last_octet() = os_params_.os_index_;
543 : }
544 173 : os_params_.os_oper_state_ = test_oper_state_;
545 173 : return;
546 : }
547 :
548 0 : std::string lookup_name = name();
549 0 : const PhysicalInterface *phy_intf = dynamic_cast<const PhysicalInterface *>(this);
550 0 : if (phy_intf) {
551 0 : lookup_name = phy_intf->display_name();
552 : }
553 :
554 0 : size_t index = 0;
555 0 : if (transport_ == TRANSPORT_PMD && type_ == PHYSICAL) {
556 : //PCI address is the name of the interface
557 : // os index from that
558 0 : std::vector<std::string>::const_iterator ptr;
559 0 : for (ptr = agent->fabric_interface_name_list().begin();
560 0 : ptr != agent->fabric_interface_name_list().end(); ++ptr) {
561 0 : if (*ptr == lookup_name) {
562 0 : break;
563 : }
564 0 : index++;
565 : }
566 0 : SetPciIndex(agent, index);
567 : }
568 :
569 : //In case of DPDK, set mac-address to the physical
570 : //mac address set in configuration file, since
571 : //agent cane query for mac address as physical interface
572 : //will not be present
573 0 : const VmInterface *vm_intf = dynamic_cast<const VmInterface *>(this);
574 0 : if (transport_ == TRANSPORT_PMD) {
575 0 : struct ether_addr *addr = NULL;
576 0 : if (agent->is_l3mh()) {
577 0 : if (phy_intf) {
578 0 : addr = ether_aton(agent->params()->
579 0 : physical_interface_mac_addr_list()[index].c_str());
580 0 : if(addr==NULL){
581 0 : LOG(ERROR, "Physical interface MAC not set in DPDK vrouter agent");
582 : }
583 :
584 0 : } else if (vm_intf && vm_intf->vmi_type() == VmInterface::VHOST) {
585 0 : addr = ether_aton(agent->vrrp_mac().ToString().c_str());
586 0 : if(addr==NULL){
587 0 : LOG(ERROR, "Physical interface MAC not set in DPDK vrouter agent");
588 : }
589 : }
590 : } else {
591 0 : if (phy_intf || (vm_intf && vm_intf->vmi_type() == VmInterface::VHOST)) {
592 0 : addr = ether_aton(agent->params()->
593 0 : physical_interface_mac_addr_list()[0].c_str());
594 0 : if(addr==NULL){
595 0 : LOG(ERROR, "Physical interface MAC not set in DPDK vrouter agent");
596 : }
597 : }
598 : }
599 0 : if (addr) {
600 0 : os_params_.mac_ = *addr;
601 : }
602 0 : return;
603 : }
604 0 : if (transport_ != TRANSPORT_ETHERNET) {
605 0 : if (!agent->isVmwareMode()) {
606 0 : os_params_.os_oper_state_ = true;
607 : }
608 0 : return;
609 : }
610 :
611 0 : ObtainOsSpecificParams(lookup_name, agent);
612 0 : }
613 :
614 0 : void Interface::SetKey(const DBRequestKey *key) {
615 0 : const InterfaceKey *k = static_cast<const InterfaceKey *>(key);
616 0 : type_ = k->type_;
617 0 : uuid_ = k->uuid_;
618 0 : os_params_.name_ = k->name_;
619 0 : }
620 :
621 15355 : uint32_t Interface::vrf_id() const {
622 15355 : VrfEntryRef p = vrf_;
623 15355 : if (p == NULL) {
624 956 : return VrfEntry::kInvalidIndex;
625 : }
626 :
627 14399 : return p->vrf_id();
628 15355 : }
629 :
630 2 : void InterfaceTable::set_update_floatingip_cb(UpdateFloatingIpFn fn) {
631 2 : update_floatingip_cb_ = fn;
632 2 : }
633 :
634 618 : const InterfaceTable::UpdateFloatingIpFn &InterfaceTable::update_floatingip_cb()
635 : const {
636 618 : return update_floatingip_cb_;
637 : }
638 :
639 : /////////////////////////////////////////////////////////////////////////////
640 : // Pkt Interface routines
641 : /////////////////////////////////////////////////////////////////////////////
642 524 : PacketInterface::PacketInterface(const std::string &name) :
643 524 : Interface(Interface::PACKET, nil_uuid(), name, NULL, true, nil_uuid()) {
644 524 : }
645 :
646 1048 : PacketInterface::~PacketInterface() {
647 1048 : }
648 :
649 18 : DBEntryBase::KeyPtr PacketInterface::GetDBRequestKey() const {
650 18 : InterfaceKey *key = new PacketInterfaceKey(uuid_, name());
651 18 : return DBEntryBase::KeyPtr(key);
652 : }
653 :
654 2 : void PacketInterface::PostAdd() {
655 2 : InterfaceTable *table = static_cast<InterfaceTable *>(get_table());
656 2 : InterfaceNH::CreatePacketInterfaceNh(table->agent(), name());
657 2 : }
658 :
659 2 : bool PacketInterface::Delete(const DBRequest *req) {
660 2 : flow_key_nh_= NULL;
661 2 : return true;
662 : }
663 :
664 : // Enqueue DBRequest to create a Pkt Interface
665 0 : void PacketInterface::CreateReq(InterfaceTable *table,
666 : const std::string &ifname,
667 : Interface::Transport transport) {
668 0 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
669 0 : req.key.reset(new PacketInterfaceKey(nil_uuid(), ifname));
670 0 : req.data.reset(new PacketInterfaceData(transport));
671 0 : table->Enqueue(&req);
672 0 : }
673 :
674 2 : void PacketInterface::Create(InterfaceTable *table, const std::string &ifname,
675 : Interface::Transport transport) {
676 2 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
677 2 : req.key.reset(new PacketInterfaceKey(nil_uuid(), ifname));
678 2 : req.data.reset(new PacketInterfaceData(transport));
679 2 : table->Process(req);
680 2 : }
681 :
682 : // Enqueue DBRequest to delete a Pkt Interface
683 0 : void PacketInterface::DeleteReq(InterfaceTable *table,
684 : const std::string &ifname) {
685 0 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
686 0 : req.key.reset(new PacketInterfaceKey(nil_uuid(), ifname));
687 0 : req.data.reset(NULL);
688 0 : table->Enqueue(&req);
689 0 : }
690 :
691 0 : void PacketInterface::Delete(InterfaceTable *table, const std::string &ifname) {
692 0 : DBRequest req(DBRequest::DB_ENTRY_DELETE);
693 0 : req.key.reset(new PacketInterfaceKey(nil_uuid(), ifname));
694 0 : req.data.reset(NULL);
695 0 : table->Process(req);
696 0 : }
697 :
698 0 : bool PacketInterface::OnChange(PacketInterfaceData *data) {
699 0 : return false;
700 : }
701 : /////////////////////////////////////////////////////////////////////////////
702 : // DHCP Snoop routines
703 : // DHCP Snoop entry can be added from 3 different places,
704 : // - Interface added from config
705 : // - Address learnt from DHCP Snoop on fabric interface
706 : // - Address learnt from vrouter when agent restarts
707 : //
708 : // DHCP Snoop entry is deleted from 2 places
709 : // - Interface deleted from config
710 : // - Audit of entries read from vrouter on restart and config table
711 : /////////////////////////////////////////////////////////////////////////////
712 :
713 : // Get DHCP IP address. First try to find entry in DHCP Snoop table.
714 : // If no entry in DHCP Snoop table, query the InterfaceKScan table.
715 : //
716 : // InterfaceKScan table is populated on agent restart
717 0 : const Ip4Address InterfaceTable::GetDhcpSnoopEntry(const std::string &ifname) {
718 0 : std::scoped_lock lock(dhcp_snoop_mutex_);
719 0 : const DhcpSnoopIterator it = dhcp_snoop_map_.find(ifname);
720 0 : if (it != dhcp_snoop_map_.end()) {
721 0 : return it->second.addr_;
722 : }
723 :
724 0 : return Ip4Address(0);
725 0 : }
726 :
727 169 : void InterfaceTable::DeleteDhcpSnoopEntry(const std::string &ifname) {
728 169 : std::scoped_lock lock(dhcp_snoop_mutex_);
729 169 : const DhcpSnoopIterator it = dhcp_snoop_map_.find(ifname);
730 169 : if (it == dhcp_snoop_map_.end()) {
731 169 : return;
732 : }
733 :
734 0 : dhcp_snoop_map_.erase(it);
735 169 : }
736 :
737 : // Set config_seen_ flag in DHCP Snoop entry.
738 : // Create the DHCP Snoop entry, if not already present
739 0 : void InterfaceTable::DhcpSnoopSetConfigSeen(const std::string &ifname) {
740 0 : std::scoped_lock lock(dhcp_snoop_mutex_);
741 0 : const DhcpSnoopIterator it = dhcp_snoop_map_.find(ifname);
742 0 : Ip4Address addr(0);
743 :
744 0 : if (it != dhcp_snoop_map_.end()) {
745 0 : addr = it->second.addr_;
746 : }
747 0 : dhcp_snoop_map_[ifname] = DhcpSnoopEntry(addr, true);
748 0 : }
749 :
750 0 : void InterfaceTable::AddDhcpSnoopEntry(const std::string &ifname,
751 : const Ip4Address &addr) {
752 0 : std::scoped_lock lock(dhcp_snoop_mutex_);
753 0 : DhcpSnoopEntry entry(addr, false);
754 0 : const DhcpSnoopIterator it = dhcp_snoop_map_.find(ifname);
755 :
756 0 : if (it != dhcp_snoop_map_.end()) {
757 : // Retain config_entry_ flag from old entry
758 0 : if (it->second.config_entry_) {
759 0 : entry.config_entry_ = true;
760 : }
761 :
762 : // If IP address is not specified, retain old IP address
763 0 : if (addr.to_ulong() == 0) {
764 0 : entry.addr_ = it->second.addr_;
765 : }
766 : }
767 :
768 0 : dhcp_snoop_map_[ifname] = entry;
769 0 : }
770 :
771 : // Audit DHCP Snoop table. Delete the entries which are not seen from config
772 0 : void InterfaceTable::AuditDhcpSnoopTable() {
773 0 : std::scoped_lock lock(dhcp_snoop_mutex_);
774 0 : DhcpSnoopIterator it = dhcp_snoop_map_.begin();
775 0 : while (it != dhcp_snoop_map_.end()){
776 0 : DhcpSnoopIterator del_it = it++;
777 0 : if (del_it->second.config_entry_ == false) {
778 0 : dhcp_snoop_map_.erase(del_it);
779 : }
780 : }
781 0 : }
782 :
783 : /////////////////////////////////////////////////////////////////////////////
784 : // Sandesh routines
785 : /////////////////////////////////////////////////////////////////////////////
786 0 : static string DeviceTypeToString(VmInterface::DeviceType type) {
787 0 : if (type == VmInterface::LOCAL_DEVICE) {
788 0 : return "Gateway";
789 0 : } else if (type == VmInterface::TOR) {
790 0 : return "TOR";
791 0 : } else if (type == VmInterface::VM_ON_TAP) {
792 0 : return "Tap";
793 0 : } else if (type == VmInterface::VM_VLAN_ON_VMI) {
794 0 : return "VMI vlan-sub-if";
795 0 : } else if (type == VmInterface::REMOTE_VM_VLAN_ON_VMI) {
796 0 : return "Remote VM";
797 : }
798 0 : return "Invalid";
799 : }
800 :
801 0 : static string VmiTypeToString(VmInterface::VmiType type) {
802 0 : if (type == VmInterface::INSTANCE) {
803 0 : return "Virtual Machine";
804 0 : } else if (type == VmInterface::SERVICE_CHAIN) {
805 0 : return "Service Chain";
806 0 : } else if (type == VmInterface::SERVICE_INSTANCE) {
807 0 : return "Service Instance";
808 0 : } else if (type == VmInterface::BAREMETAL) {
809 0 : return "Baremetal";
810 0 : } else if (type == VmInterface::GATEWAY) {
811 0 : return "Gateway";
812 0 : } else if (type == VmInterface::REMOTE_VM) {
813 0 : return "Remote VM";
814 0 : } else if (type == VmInterface::SRIOV) {
815 0 : return "Sriov";
816 0 : } else if (type == VmInterface::VHOST) {
817 0 : return "VHOST";
818 : }
819 0 : return "Invalid";
820 : }
821 :
822 0 : void Interface::SetItfSandeshData(ItfSandeshData &data) const {
823 0 : data.set_index(id_);
824 0 : data.set_name(name());
825 0 : data.set_uuid(UuidToString(uuid_));
826 :
827 0 : if (vrf_)
828 0 : data.set_vrf_name(vrf_->GetName());
829 : else
830 0 : data.set_vrf_name("--ERROR--");
831 :
832 0 : if (IsUveActive()) {
833 0 : data.set_active("Active");
834 : } else {
835 0 : data.set_active("Inactive");
836 : }
837 :
838 0 : if (ipv4_active_) {
839 0 : data.set_ipv4_active("Active");
840 : } else {
841 0 : data.set_ipv4_active("Inactive");
842 : }
843 :
844 0 : if (is_hc_active_) {
845 0 : data.set_health_check_active("Active");
846 : } else {
847 0 : data.set_health_check_active("Inactive");
848 : }
849 :
850 0 : if (metadata_ip_active_) {
851 0 : data.set_metadata_ip_active("Active");
852 : } else {
853 0 : data.set_metadata_ip_active("Inactive");
854 : }
855 :
856 0 : if (ipv6_active_) {
857 0 : data.set_ip6_active("Active");
858 : } else {
859 0 : data.set_ip6_active("Inactive");
860 : }
861 :
862 0 : if (l2_active_) {
863 0 : data.set_l2_active("L2 Active");
864 : } else {
865 0 : data.set_l2_active("L2 Inactive");
866 : }
867 :
868 0 : if (dhcp_enabled_) {
869 0 : data.set_dhcp_service("Enable");
870 : } else {
871 0 : data.set_dhcp_service("Disable");
872 : }
873 :
874 0 : if (dhcp_enabled_v6_) {
875 0 : data.set_dhcp_service_v6("Enable");
876 : } else {
877 0 : data.set_dhcp_service_v6("Disable");
878 : }
879 :
880 :
881 0 : if (dns_enabled_) {
882 0 : data.set_dns_service("Enable");
883 : } else {
884 0 : data.set_dns_service("Disable");
885 : }
886 0 : data.set_label(label_);
887 0 : data.set_l2_label(l2_label_);
888 0 : if (flow_key_nh()) {
889 0 : data.set_flow_key_idx(flow_key_nh()->id());
890 : }
891 : /* For optional fields set the default values here. This will overwritten
892 : * (if required) based on interface type */
893 0 : data.set_ip6_addr("--NA--");
894 0 : std::vector<StaticRouteSandesh> aap_list;
895 0 : data.set_allowed_address_pair_list(aap_list);
896 0 : data.set_subnet("--NA--");
897 0 : data.set_sub_type("--NA--");
898 0 : data.set_vrf_assign_acl_uuid("--NA--");
899 0 : data.set_vmi_type("--NA--");
900 0 : data.set_flood_unknown_unicast(false);
901 :
902 0 : if (qos_config_.get()) {
903 0 : data.set_qos_config(UuidToString(qos_config_->uuid()));
904 : }
905 :
906 0 : switch (type_) {
907 0 : case Interface::PHYSICAL:
908 : {
909 0 : const PhysicalInterface *pintf =
910 : static_cast<const PhysicalInterface *>(this);
911 : PhysicalInterface::BondChildIntfMapIterator it =
912 0 : pintf->getBondChildIntfMap().begin();
913 0 : vector<BondInterface> bond_interface_list;
914 0 : for(; it != pintf->getBondChildIntfMap().end(); it++)
915 : {
916 0 : PhysicalInterface::Bond_ChildIntf bond_intf;
917 0 : bond_intf = it->second;
918 0 : BondInterface entry;
919 0 : entry.set_intf_name(bond_intf.intf_name);
920 0 : entry.set_intf_drv_name(bond_intf.intf_drv_name);
921 0 : entry.set_intf_status(bond_intf.intf_status ? "UP" : "DOWN");
922 0 : bond_interface_list.push_back(entry);
923 0 : }
924 0 : data.set_bond_interface_list(bond_interface_list);
925 :
926 0 : if(pintf->os_params_.os_oper_state_)
927 0 : data.set_active("Active");
928 : else
929 0 : data.set_active("Inactive <Oper-state-down>");
930 0 : data.set_type("eth");
931 :
932 0 : }
933 0 : break;
934 :
935 0 : case Interface::REMOTE_PHYSICAL:
936 0 : data.set_type("remote-physical-port");
937 0 : data.set_vrf_name("--NA--");
938 0 : break;
939 :
940 0 : case Interface::LOGICAL:
941 : {
942 0 : const LogicalInterface *lintf =
943 : static_cast<const LogicalInterface*>(this);
944 0 : data.set_type("logical-port");
945 0 : data.set_vrf_name("--NA--");
946 0 : data.set_physical_device(lintf->phy_dev_display_name());
947 0 : data.set_physical_interface(lintf->phy_intf_display_name());
948 : }
949 0 : break;
950 :
951 0 : case Interface::VM_INTERFACE: {
952 0 : data.set_type("vport");
953 0 : const VmInterface *vintf = static_cast<const VmInterface *>(this);
954 0 : if (vintf->vn())
955 0 : data.set_vn_name(vintf->vn()->GetName());
956 0 : if (vintf->vm())
957 0 : data.set_vm_uuid(UuidToString(vintf->vm()->GetUuid()));
958 0 : data.set_ip_addr(vintf->primary_ip_addr().to_string());
959 0 : data.set_ip6_addr(vintf->primary_ip6_addr().to_string());
960 0 : data.set_mac_addr(vintf->vm_mac().ToString());
961 0 : data.set_mdata_ip_addr(vintf->mdata_ip_addr().to_string());
962 0 : data.set_vxlan_id(vintf->vxlan_id());
963 0 : if (vintf->policy_enabled()) {
964 0 : data.set_policy("Enable");
965 : } else {
966 0 : data.set_policy("Disable");
967 : }
968 0 : data.set_flood_unknown_unicast(vintf->flood_unknown_unicast());
969 :
970 0 : string common_reason = "";
971 0 : if (IsUveActive() == false) {
972 :
973 0 : if (!vintf->admin_state()) {
974 0 : common_reason += "admin-down ";
975 : }
976 :
977 0 : if (vintf->vn() == NULL) {
978 0 : common_reason += "vn-null ";
979 0 : } else if (!vintf->vn()->admin_state()) {
980 0 : common_reason += "vn-admin-down ";
981 : }
982 :
983 0 : if (vintf->vrf() == NULL) {
984 0 : common_reason += "vrf-null ";
985 : }
986 :
987 0 : if (vintf->NeedDevice()) {
988 0 : if (vintf->os_index() == Interface::kInvalidIndex) {
989 0 : common_reason += "no-dev ";
990 : }
991 :
992 0 : if (vintf->os_oper_state() == false) {
993 0 : common_reason += "os-state-down ";
994 : }
995 0 : } else if (vintf->NeedOsStateWithoutDevice()) {
996 0 : if (vintf->os_oper_state() == false) {
997 0 : common_reason += "os-state-down ";
998 : }
999 : }
1000 :
1001 0 : if (vintf->parent() && vintf->parent()->IsActive() == false) {
1002 0 : common_reason += "parent-inactive ";
1003 : }
1004 :
1005 0 : string total_reason = common_reason;
1006 0 : if (!ipv4_active_) {
1007 0 : total_reason += "ipv4_inactive ";
1008 : }
1009 0 : if (!ipv6_active_) {
1010 0 : total_reason += "ipv6_inactive ";
1011 : }
1012 0 : if (!l2_active_) {
1013 0 : total_reason += "l2_inactive ";
1014 : }
1015 0 : string reason = "Inactive < " + total_reason + " >";
1016 0 : data.set_active(reason);
1017 0 : }
1018 0 : if (!ipv4_active_ || !ipv6_active_) {
1019 0 : string v4_v6_common_reason = common_reason;
1020 0 : if (vintf->layer3_forwarding() == false) {
1021 0 : v4_v6_common_reason += "l3-disabled ";
1022 : }
1023 :
1024 0 : if (!ipv4_active_) {
1025 0 : string reason = "Ipv4 Inactive < " + v4_v6_common_reason;
1026 0 : if (vintf->primary_ip_addr().to_ulong() == 0) {
1027 0 : reason += "no-ipv4-addr ";
1028 : }
1029 0 : reason += " >";
1030 0 : data.set_ipv4_active(reason);
1031 0 : }
1032 0 : if (!ipv6_active_) {
1033 0 : string reason = "Ipv6 Inactive < " + v4_v6_common_reason;
1034 0 : if (vintf->primary_ip6_addr().is_unspecified()) {
1035 0 : reason += "no-ipv6-addr ";
1036 : }
1037 0 : reason += " >";
1038 0 : data.set_ip6_active(reason);
1039 0 : }
1040 0 : }
1041 :
1042 0 : if (!l2_active_) {
1043 0 : string l2_reason = common_reason;
1044 0 : if (vintf->bridging() == false) {
1045 0 : l2_reason += "l2-disabled ";
1046 : }
1047 0 : string reason = "L2 Inactive < " + l2_reason;
1048 0 : reason += " >";
1049 0 : data.set_l2_active(reason);
1050 0 : }
1051 :
1052 0 : std::vector<FloatingIpSandeshList> fip_list;
1053 : VmInterface::FloatingIpSet::const_iterator it =
1054 0 : vintf->floating_ip_list().list_.begin();
1055 0 : while (it != vintf->floating_ip_list().list_.end()) {
1056 0 : const VmInterface::FloatingIp &ip = *it;
1057 0 : FloatingIpSandeshList entry;
1058 :
1059 0 : entry.set_ip_addr(ip.floating_ip_.to_string());
1060 0 : if (ip.vrf_.get()) {
1061 0 : entry.set_vrf_name(ip.vrf_.get()->GetName());
1062 : } else {
1063 0 : entry.set_vrf_name("--ERROR--");
1064 : }
1065 :
1066 0 : if (ip.Installed()) {
1067 0 : entry.set_installed("Y");
1068 : } else {
1069 0 : entry.set_installed("N");
1070 : }
1071 0 : entry.set_fixed_ip(ip.fixed_ip_.to_string());
1072 :
1073 0 : string dir = "";
1074 0 : switch (it->direction()) {
1075 0 : case VmInterface::FloatingIp::DIRECTION_BOTH:
1076 0 : dir = "both";
1077 0 : break;
1078 :
1079 0 : case VmInterface::FloatingIp::DIRECTION_INGRESS:
1080 0 : dir = "ingress";
1081 0 : break;
1082 :
1083 0 : case VmInterface::FloatingIp::DIRECTION_EGRESS:
1084 0 : dir = "egress";
1085 0 : break;
1086 :
1087 0 : default:
1088 0 : dir = "INVALID";
1089 0 : break;
1090 : }
1091 0 : entry.set_direction(dir);
1092 :
1093 0 : entry.set_port_map_enabled(it->port_map_enabled());
1094 0 : std::vector<SandeshPortMapping> pmap_list;
1095 : VmInterface::FloatingIp::PortMapIterator pmap_it =
1096 0 : it->src_port_map_.begin();
1097 0 : while (pmap_it != it->src_port_map_.end()) {
1098 0 : SandeshPortMapping pmap;
1099 0 : pmap.set_protocol(pmap_it->first.protocol_);
1100 0 : pmap.set_port(pmap_it->first.port_);
1101 0 : pmap.set_nat_port(pmap_it->second);
1102 0 : pmap_list.push_back(pmap);
1103 0 : pmap_it++;
1104 0 : }
1105 0 : entry.set_port_map(pmap_list);
1106 :
1107 0 : fip_list.push_back(entry);
1108 0 : it++;
1109 0 : }
1110 0 : data.set_fip_list(fip_list);
1111 :
1112 0 : std::vector<AliasIpSandeshList> aip_list;
1113 : VmInterface::AliasIpSet::const_iterator a_it =
1114 0 : vintf->alias_ip_list().list_.begin();
1115 0 : while (a_it != vintf->alias_ip_list().list_.end()) {
1116 0 : const VmInterface::AliasIp &ip = *a_it;
1117 0 : AliasIpSandeshList entry;
1118 0 : entry.set_ip_addr(ip.alias_ip_.to_string());
1119 0 : if (ip.vrf_.get()) {
1120 0 : entry.set_vrf_name(ip.vrf_.get()->GetName());
1121 : } else {
1122 0 : entry.set_vrf_name("--ERROR--");
1123 : }
1124 :
1125 0 : if (ip.Installed()) {
1126 0 : entry.set_installed("Y");
1127 : } else {
1128 0 : entry.set_installed("N");
1129 : }
1130 0 : aip_list.push_back(entry);
1131 0 : a_it++;
1132 0 : }
1133 0 : data.set_alias_ip_list(aip_list);
1134 :
1135 0 : data.set_logical_interface_uuid(to_string(vintf->logical_interface()));
1136 :
1137 : // Add Service VLAN list
1138 0 : std::vector<ServiceVlanSandeshList> vlan_list;
1139 : VmInterface::ServiceVlanSet::const_iterator vlan_it =
1140 0 : vintf->service_vlan_list().list_.begin();
1141 0 : while (vlan_it != vintf->service_vlan_list().list_.end()) {
1142 0 : const VmInterface::ServiceVlan *vlan = vlan_it.operator->();
1143 0 : ServiceVlanSandeshList entry;
1144 :
1145 0 : entry.set_tag(vlan->tag_);
1146 0 : if (vlan->vrf_.get()) {
1147 0 : entry.set_vrf_name(vlan->vrf_.get()->GetName());
1148 : } else {
1149 0 : entry.set_vrf_name("--ERROR--");
1150 : }
1151 0 : entry.set_ip_addr(vlan->addr_.to_string());
1152 0 : entry.set_ip6_addr(vlan->addr6_.to_string());
1153 0 : entry.set_label(vlan->label_);
1154 :
1155 0 : if (vlan->v4_rt_installed_ || vlan->v6_rt_installed_) {
1156 0 : entry.set_installed("Y");
1157 : } else {
1158 0 : entry.set_installed("N");
1159 : }
1160 0 : if (vlan->v4_rt_installed_) {
1161 0 : entry.set_v4_route_installed("Y");
1162 : } else {
1163 0 : entry.set_v4_route_installed("N");
1164 : }
1165 0 : if (vlan->v6_rt_installed_) {
1166 0 : entry.set_v6_route_installed("Y");
1167 : } else {
1168 0 : entry.set_v6_route_installed("N");
1169 : }
1170 0 : vlan_list.push_back(entry);
1171 0 : vlan_it++;
1172 0 : }
1173 :
1174 0 : std::vector<StaticRouteSandesh> static_route_list;
1175 : VmInterface::StaticRouteSet::iterator static_rt_it =
1176 0 : vintf->static_route_list().list_.begin();
1177 0 : while (static_rt_it != vintf->static_route_list().list_.end()) {
1178 0 : const VmInterface::StaticRoute &rt = *static_rt_it;
1179 0 : StaticRouteSandesh entry;
1180 0 : entry.set_vrf_name("");
1181 0 : entry.set_ip_addr(rt.addr_.to_string());
1182 0 : entry.set_prefix(rt.plen_);
1183 0 : entry.set_communities(rt.communities_);
1184 0 : static_rt_it++;
1185 0 : static_route_list.push_back(entry);
1186 0 : }
1187 0 : data.set_static_route_list(static_route_list);
1188 :
1189 0 : std::vector<StaticRouteSandesh> aap_list;
1190 : VmInterface::AllowedAddressPairSet::iterator aap_it =
1191 0 : vintf->allowed_address_pair_list().list_.begin();
1192 0 : while (aap_it != vintf->allowed_address_pair_list().list_.end()) {
1193 0 : const VmInterface::AllowedAddressPair &rt = *aap_it;
1194 0 : StaticRouteSandesh entry;
1195 0 : entry.set_vrf_name("");
1196 0 : entry.set_ip_addr(rt.addr_.to_string());
1197 0 : entry.set_prefix(rt.plen_);
1198 0 : if (rt.mac_ != MacAddress::ZeroMac()) {
1199 0 : entry.set_mac_addr(rt.mac_.ToString());
1200 0 : entry.set_label(rt.label_);
1201 : }
1202 0 : aap_it++;
1203 0 : aap_list.push_back(entry);
1204 0 : }
1205 0 : data.set_allowed_address_pair_list(aap_list);
1206 :
1207 0 : std::vector<std::string> fixed_ip4_list;
1208 0 : vintf->BuildIpStringList(Address::INET, &fixed_ip4_list);
1209 0 : data.set_fixed_ip4_list(fixed_ip4_list);
1210 :
1211 0 : std::vector<std::string> fixed_ip6_list;
1212 0 : vintf->BuildIpStringList(Address::INET6, &fixed_ip6_list);
1213 0 : data.set_fixed_ip6_list(fixed_ip6_list);
1214 :
1215 0 : std::vector<std::string> fat_flow_list;
1216 : VmInterface::FatFlowEntrySet::iterator fat_flow_it =
1217 0 : vintf->fat_flow_list().list_.begin();
1218 0 : while (fat_flow_it != vintf->fat_flow_list().list_.end()) {
1219 0 : ostringstream str;
1220 0 : str << (int)fat_flow_it->protocol << ":" << (int)fat_flow_it->port
1221 0 : << ":" << fat_flow_it->ignore_address;
1222 0 : fat_flow_list.push_back(str.str());
1223 0 : fat_flow_it++;
1224 0 : }
1225 0 : data.set_fat_flow_list(fat_flow_list);
1226 :
1227 0 : if (vintf->fabric_port()) {
1228 0 : data.set_fabric_port("FabricPort");
1229 : } else {
1230 0 : data.set_fabric_port("NotFabricPort");
1231 : }
1232 0 : if (vintf->need_linklocal_ip()) {
1233 0 : data.set_alloc_linklocal_ip("LL-Enable");
1234 : } else {
1235 0 : data.set_alloc_linklocal_ip("LL-Disable");
1236 : }
1237 0 : data.set_service_vlan_list(vlan_list);
1238 0 : data.set_analyzer_name(vintf->GetAnalyzer());
1239 0 : data.set_config_name(vintf->cfg_name());
1240 :
1241 0 : VmInterface::TagEntrySet::const_iterator tag_it;
1242 0 : std::vector<VmiTagData> vmi_tag_l;
1243 0 : const VmInterface::TagEntryList &tag_l = vintf->tag_list();
1244 0 : for (tag_it = tag_l.list_.begin(); tag_it != tag_l.list_.end();
1245 0 : ++tag_it) {
1246 0 : VmiTagData vmi_tag_data;
1247 0 : if (tag_it->tag_.get()) {
1248 0 : vmi_tag_data.set_name(tag_it->tag_->name());
1249 0 : vmi_tag_data.set_id(tag_it->tag_->tag_id());
1250 : TagEntry::PolicySetList::const_iterator aps_it =
1251 0 : tag_it->tag_->policy_set_list().begin();
1252 0 : std::vector<ApplicationPolicySetLink> aps_uuid_list;
1253 0 : for(; aps_it != tag_it->tag_->policy_set_list().end();
1254 0 : aps_it++) {
1255 : std::string aps_id =
1256 0 : UuidToString(aps_it->get()->uuid());
1257 0 : ApplicationPolicySetLink apl;
1258 0 : apl.set_application_policy_set(aps_id);
1259 0 : aps_uuid_list.push_back(apl);
1260 0 : }
1261 :
1262 0 : vmi_tag_data.set_application_policy_set_list(aps_uuid_list);
1263 0 : vmi_tag_l.push_back(vmi_tag_data);
1264 0 : }
1265 0 : }
1266 0 : data.set_vmi_tag_list(vmi_tag_l);
1267 :
1268 0 : VmInterface::SecurityGroupEntrySet::const_iterator sgit;
1269 0 : std::vector<VmIntfSgUuid> intf_sg_uuid_l;
1270 0 : const VmInterface::SecurityGroupEntryList &sg_uuid_l = vintf->sg_list();
1271 0 : for (sgit = sg_uuid_l.list_.begin(); sgit != sg_uuid_l.list_.end();
1272 0 : ++sgit) {
1273 0 : VmIntfSgUuid sg_id;
1274 0 : sg_id.set_sg_uuid(UuidToString(sgit->uuid_));
1275 0 : intf_sg_uuid_l.push_back(sg_id);
1276 0 : }
1277 0 : data.set_sg_uuid_list(intf_sg_uuid_l);
1278 :
1279 0 : data.set_vm_name(vintf->vm_name());
1280 0 : data.set_vm_project_uuid(UuidToString(vintf->vm_project_uuid()));
1281 0 : data.set_local_preference(vintf->local_preference());
1282 :
1283 0 : data.set_tx_vlan_id(vintf->tx_vlan_id());
1284 0 : data.set_rx_vlan_id(vintf->rx_vlan_id());
1285 0 : if (vintf->parent()) {
1286 0 : data.set_parent_interface(vintf->parent()->name());
1287 : }
1288 0 : if (vintf->subnet().to_ulong() != 0) {
1289 0 : std::ostringstream str;
1290 0 : str << vintf->subnet().to_string() << "/"
1291 0 : << (int)vintf->subnet_plen();
1292 0 : data.set_subnet(str.str());
1293 0 : }
1294 :
1295 0 : data.set_sub_type(DeviceTypeToString(vintf->device_type()));
1296 0 : data.set_vmi_type(VmiTypeToString(vintf->vmi_type()));
1297 0 : data.set_vhostuser_mode(vintf->vhostuser_mode());
1298 :
1299 0 : if (vintf->vrf_assign_acl()) {
1300 0 : std::string vrf_assign_acl;
1301 0 : vrf_assign_acl.assign(UuidToString(vintf->vrf_assign_acl()->GetUuid()));
1302 0 : data.set_vrf_assign_acl_uuid(vrf_assign_acl);
1303 0 : }
1304 :
1305 0 : data.set_service_health_check_ip(
1306 0 : vintf->service_health_check_ip().to_string());
1307 0 : data.set_drop_new_flows(vintf->drop_new_flows());
1308 :
1309 0 : VmInterface::BridgeDomainEntrySet::const_iterator bd_it;
1310 0 : std::vector<VmIntfBridgeDomainUuid> intf_bd_uuid_l;
1311 : const VmInterface::BridgeDomainList &bd_list =
1312 0 : vintf->bridge_domain_list();
1313 0 : for (bd_it = bd_list.list_.begin(); bd_it != bd_list.list_.end(); ++bd_it) {
1314 0 : VmIntfBridgeDomainUuid bd_id;
1315 0 : bd_id.set_bridge_domain_uuid(UuidToString(bd_it->uuid_));
1316 0 : intf_bd_uuid_l.push_back(bd_id);
1317 0 : }
1318 0 : data.set_bridge_domain_list(intf_bd_uuid_l);
1319 :
1320 0 : std::vector<std::string> policy_set_acl_list;
1321 0 : FirewallPolicyList::const_iterator fw_it = vintf->fw_policy_list().begin();
1322 0 : for(; fw_it != vintf->fw_policy_list().end(); fw_it++) {
1323 0 : policy_set_acl_list.push_back(UuidToString(fw_it->get()->GetUuid()));
1324 : }
1325 0 : data.set_policy_set_acl_list(policy_set_acl_list);
1326 :
1327 0 : std::vector<std::string> policy_set_fwaas_list;
1328 0 : fw_it = vintf->fwaas_fw_policy_list().begin();
1329 0 : for(; fw_it != vintf->fwaas_fw_policy_list().end(); fw_it++) {
1330 0 : policy_set_fwaas_list.push_back(UuidToString(fw_it->get()->GetUuid()));
1331 : }
1332 0 : data.set_policy_set_fwaas_list(policy_set_fwaas_list);
1333 :
1334 0 : std::vector<SecurityLoggingObjectLink> slo_list;
1335 0 : UuidList::const_iterator sit = vintf->slo_list().begin();
1336 0 : while (sit != vintf->slo_list().end()) {
1337 0 : SecurityLoggingObjectLink slo_entry;
1338 0 : slo_entry.set_slo_uuid(to_string(*sit));
1339 0 : slo_list.push_back(slo_entry);
1340 0 : ++sit;
1341 0 : }
1342 0 : data.set_slo_list(slo_list);
1343 0 : data.set_si_other_end_vmi(UuidToString(vintf->si_other_end_vmi()));
1344 0 : data.set_cfg_igmp_enable(vintf->cfg_igmp_enable());
1345 0 : data.set_igmp_enabled(vintf->igmp_enabled());
1346 0 : data.set_max_flows(vintf->max_flows());
1347 0 : data.set_mac_ip_learning_enable(vintf->mac_ip_learning_enable());
1348 0 : if (vintf->mac_ip_learning_enable()) {
1349 0 : std::vector<LearntMacIpSandeshList> mac_ip_list;
1350 : VmInterface::LearntMacIpSet::const_iterator it =
1351 0 : vintf->learnt_mac_ip_list().list_.begin();
1352 0 : while (it != vintf->learnt_mac_ip_list().list_.end()) {
1353 0 : const VmInterface::LearntMacIp &mac_ip = *it;
1354 0 : LearntMacIpSandeshList entry;
1355 0 : entry.set_ip_addr(mac_ip.ip_.to_string());
1356 0 : entry.set_mac_addr(mac_ip.mac_.ToString());
1357 0 : if (mac_ip.l2_installed_) {
1358 0 : entry.set_l2_installed("Y");
1359 : } else {
1360 0 : entry.set_l2_installed("N");
1361 : }
1362 0 : if (mac_ip.l3_installed_) {
1363 0 : entry.set_l3_installed("Y");
1364 : } else {
1365 0 : entry.set_l3_installed("N");
1366 : }
1367 0 : mac_ip_list.push_back(entry);
1368 0 : it++;
1369 0 : }
1370 0 : data.set_mac_ip_list(mac_ip_list);
1371 0 : }
1372 :
1373 0 : break;
1374 0 : }
1375 0 : case Interface::INET: {
1376 0 : data.set_type("vhost");
1377 0 : const InetInterface *intf = static_cast<const InetInterface*>(this);
1378 0 : if(intf->xconnect()) {
1379 0 : data.set_physical_interface(intf->xconnect()->name());
1380 : }
1381 0 : break;
1382 : }
1383 0 : case Interface::PACKET:
1384 0 : data.set_type("pkt");
1385 0 : break;
1386 0 : default:
1387 0 : data.set_type("invalid");
1388 0 : break;
1389 : }
1390 0 : data.set_os_ifindex(os_index());
1391 0 : if (admin_state_) {
1392 0 : data.set_admin_state("Enabled");
1393 : } else {
1394 0 : data.set_admin_state("Disabled");
1395 : }
1396 :
1397 0 : switch (transport_) {
1398 0 : case TRANSPORT_ETHERNET:{
1399 0 : data.set_transport("Ethernet");
1400 0 : break;
1401 : }
1402 0 : case TRANSPORT_SOCKET: {
1403 0 : data.set_transport("Socket");
1404 0 : break;
1405 : }
1406 0 : case TRANSPORT_PMD: {
1407 0 : data.set_transport("PMD");
1408 0 : break;
1409 : }
1410 0 : default: {
1411 0 : data.set_transport("Unknown");
1412 0 : break;
1413 : }
1414 : }
1415 0 : }
1416 :
1417 0 : bool Interface::DBEntrySandesh(Sandesh *sresp, std::string &name) const {
1418 0 : ItfResp *resp = static_cast<ItfResp *>(sresp);
1419 :
1420 0 : ItfSandeshData data;
1421 0 : SetItfSandeshData(data);
1422 : std::vector<ItfSandeshData> &list =
1423 0 : const_cast<std::vector<ItfSandeshData>&>(resp->get_itf_list());
1424 0 : list.push_back(data);
1425 :
1426 0 : return true;
1427 0 : }
1428 :
1429 0 : void ItfReq::HandleRequest() const {
1430 0 : AgentSandeshPtr sand(new AgentIntfSandesh(context(), get_type(),
1431 0 : get_name(), get_uuid(),
1432 0 : get_vn(), get_mac(),
1433 0 : get_ipv4_address(),
1434 0 : get_ipv6_address(),
1435 0 : get_parent_uuid(),
1436 0 : get_ip_active(),
1437 0 : get_ip6_active(),
1438 0 : get_l2_active()));
1439 0 : sand->DoSandesh(sand);
1440 0 : }
1441 :
1442 0 : AgentSandeshPtr InterfaceTable::GetAgentSandesh(const AgentSandeshArguments *args,
1443 : const std::string &context) {
1444 : return AgentSandeshPtr
1445 0 : (new AgentIntfSandesh(context, args->GetString("type"),
1446 0 : args->GetString("name"), args->GetString("uuid"),
1447 0 : args->GetString("vn"), args->GetString("mac"),
1448 0 : args->GetString("ipv4"), args->GetString("ipv6"),
1449 0 : args->GetString("parent_uuid"),
1450 0 : args->GetString("ip_active"),
1451 0 : args->GetString("ip6_active"),
1452 0 : args->GetString("l2_active")));
1453 : }
1454 :
1455 353 : void Interface::SendTrace(const AgentDBTable *table, Trace event) const {
1456 353 : InterfaceInfo intf_info;
1457 353 : intf_info.set_name(name());
1458 353 : intf_info.set_index(id_);
1459 :
1460 353 : switch(event) {
1461 176 : case ADD:
1462 176 : intf_info.set_op("Add");
1463 176 : break;
1464 177 : case DEL:
1465 177 : intf_info.set_op("Delete");
1466 177 : break;
1467 0 : default:
1468 0 : intf_info.set_op("Unknown");
1469 0 : break;
1470 : }
1471 353 : OPER_TRACE_ENTRY(Interface,
1472 : table,
1473 : intf_info);
1474 353 : }
1475 :
1476 26 : bool Interface::ip_active(Address::Family family) const {
1477 26 : if (family == Address::INET)
1478 26 : return ipv4_active_;
1479 0 : else if (family == Address::INET6)
1480 0 : return ipv6_active_;
1481 : else
1482 0 : assert(0);
1483 : return false;
1484 : }
1485 :
1486 2629 : bool Interface::IsUveActive() const {
1487 2629 : if (ipv4_active() || ipv6_active() || l2_active()) {
1488 2121 : return true;
1489 : }
1490 508 : return false;
1491 : }
1492 :
1493 0 : void Interface::UpdateOperStateOfSubIntf(const InterfaceTable *table) {
1494 0 : std::scoped_lock lock(Interface::back_ref_mutex_);
1495 0 : std::set<IntrusiveReferrer>::const_iterator it = Interface::back_ref_set_.begin();
1496 0 : for (; it != Interface::back_ref_set_.end(); it++) {
1497 0 : VmInterface *vm_intf = static_cast<VmInterface *>((*it).first);
1498 0 : if (vm_intf && vm_intf->parent()) {
1499 0 : DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
1500 0 : req.key.reset(new VmInterfaceKey(AgentKey::RESYNC, vm_intf->GetUuid(),
1501 0 : vm_intf->name()));
1502 0 : req.data.reset(new VmInterfaceOsOperStateData(vm_intf->
1503 0 : os_oper_state()));
1504 0 : const_cast<InterfaceTable *>(table)->Enqueue(&req);
1505 0 : }
1506 : }
1507 0 : }
1508 :
1509 10866 : bool Interface::NeedDefaultOsOperStateDisabled(Agent *agent) const {
1510 10866 : if ((transport_ != TRANSPORT_ETHERNET) && agent->isVmwareMode()) {
1511 0 : return true;
1512 : }
1513 10866 : return false;
1514 : }
1515 :
1516 : /////////////////////////////////////////////////////////////////////////////
1517 : // Map of VMI-UUID to VmiType
1518 : /////////////////////////////////////////////////////////////////////////////
1519 1158 : void InterfaceTable::AddVmiToVmiType(const boost::uuids::uuid &u, int type) {
1520 1158 : vmi_to_vmitype_map_[u] = type;
1521 1158 : }
1522 :
1523 120 : int InterfaceTable::GetVmiToVmiType(const boost::uuids::uuid &u) {
1524 120 : InterfaceTable::VmiToVmiTypeMap::iterator it = vmi_to_vmitype_map_.find(u);
1525 120 : if (it == vmi_to_vmitype_map_.end())
1526 87 : return -1;
1527 33 : return it->second;
1528 : }
1529 :
1530 33 : void InterfaceTable::DelVmiToVmiType(const boost::uuids::uuid &u) {
1531 33 : InterfaceTable::VmiToVmiTypeMap::iterator it = vmi_to_vmitype_map_.find(u);
1532 33 : if (it == vmi_to_vmitype_map_.end())
1533 0 : return;
1534 33 : vmi_to_vmitype_map_.erase(it);
1535 : }
|