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