Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include <algorithm> 6 : #include <boost/uuid/uuid_io.hpp> 7 : #include <base/parse_object.h> 8 : #include <ifmap/ifmap_link.h> 9 : #include <ifmap/ifmap_table.h> 10 : #include <vnc_cfg_types.h> 11 : 12 : #include <cmn/agent_cmn.h> 13 : #include <cfg/cfg_init.h> 14 : #include <oper/sg.h> 15 : #include <filter/acl.h> 16 : 17 : #include <oper/interface_common.h> 18 : #include <oper/mirror_table.h> 19 : #include <oper/agent_sandesh.h> 20 : #include <oper/config_manager.h> 21 : 22 : using namespace autogen; 23 : using namespace std; 24 : 25 : SgTable *SgTable::sg_table_; 26 : 27 42 : bool SgEntry::IsLess(const DBEntry &rhs) const { 28 42 : const SgEntry &a = static_cast<const SgEntry &>(rhs); 29 42 : return (sg_uuid_ < a.sg_uuid_); 30 : } 31 : 32 0 : string SgEntry::ToString() const { 33 0 : std::stringstream uuidstring; 34 0 : uuidstring << sg_uuid_; 35 0 : return uuidstring.str(); 36 0 : } 37 : 38 0 : DBEntryBase::KeyPtr SgEntry::GetDBRequestKey() const { 39 0 : SgKey *key = new SgKey(sg_uuid_); 40 0 : return DBEntryBase::KeyPtr(key); 41 : } 42 : 43 0 : void SgEntry::SetKey(const DBRequestKey *key) { 44 0 : const SgKey *k = static_cast<const SgKey *>(key); 45 0 : sg_uuid_ = k->sg_uuid_; 46 0 : } 47 : 48 21 : std::unique_ptr<DBEntry> SgTable::AllocEntry(const DBRequestKey *k) const { 49 21 : const SgKey *key = static_cast<const SgKey *>(k); 50 21 : SgEntry *sg = new SgEntry(key->sg_uuid_); 51 21 : return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(sg)); 52 : } 53 : 54 2 : DBEntry *SgTable::OperDBAdd(const DBRequest *req) { 55 2 : SgKey *key = static_cast<SgKey *>(req->key.get()); 56 2 : SgEntry *sg = new SgEntry(key->sg_uuid_); 57 2 : ChangeHandler(sg, req); 58 2 : sg->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::ADD); 59 2 : return sg; 60 : } 61 : 62 10 : bool SgTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) { 63 10 : bool ret = ChangeHandler(entry, req); 64 10 : SgEntry *sg = static_cast<SgEntry *>(entry); 65 10 : sg->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::CHANGE); 66 10 : return ret; 67 : } 68 : 69 12 : bool SgTable::ChangeHandler(DBEntry *entry, const DBRequest *req) { 70 12 : bool ret = false; 71 12 : SgEntry *sg = static_cast<SgEntry *>(entry); 72 12 : SgData *data = static_cast<SgData *>(req->data.get()); 73 : 74 12 : if (sg->sg_id_ != data->sg_id_) { 75 2 : sg->sg_id_ = data->sg_id_; 76 2 : ret = true; 77 : } 78 : 79 12 : AclKey key(data->egress_acl_id_); 80 12 : AclDBEntry *acl = static_cast<AclDBEntry *>(agent()->acl_table()->FindActiveEntry(&key)); 81 12 : if (sg->egress_acl_ != acl) { 82 2 : sg->egress_acl_ = acl; 83 2 : ret = true; 84 : } 85 12 : key = AclKey(data->ingress_acl_id_); 86 12 : acl = static_cast<AclDBEntry *>(agent()->acl_table()->FindActiveEntry(&key)); 87 12 : if (sg->ingress_acl_ != acl) { 88 2 : sg->ingress_acl_ = acl; 89 2 : ret = true; 90 : } 91 12 : return ret; 92 12 : } 93 : 94 6 : bool SgTable::OperDBDelete(DBEntry *entry, const DBRequest *req) { 95 6 : SgEntry *sg = static_cast<SgEntry *>(entry); 96 6 : sg->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::DEL); 97 6 : return true; 98 : } 99 : 100 1 : DBTableBase *SgTable::CreateTable(DB *db, const std::string &name) { 101 1 : sg_table_ = new SgTable(db, name); 102 1 : sg_table_->Init(); 103 1 : return sg_table_; 104 : }; 105 : 106 24 : bool SgTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u) { 107 24 : SecurityGroup *cfg = static_cast<SecurityGroup *>(node->GetObject()); 108 24 : assert(cfg); 109 24 : autogen::IdPermsType id_perms = cfg->id_perms(); 110 24 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u); 111 24 : return true; 112 24 : } 113 : 114 24 : bool SgTable::IFNodeToReq(IFMapNode *node, DBRequest &req, 115 : const boost::uuids::uuid &u) { 116 24 : SecurityGroup *cfg = static_cast<SecurityGroup *>(node->GetObject()); 117 24 : assert(cfg); 118 : 119 24 : assert(!u.is_nil()); 120 : 121 24 : if ((req.oper == DBRequest::DB_ENTRY_DELETE) || node->IsDeleted()) { 122 6 : req.oper = DBRequest::DB_ENTRY_DELETE; 123 6 : req.key.reset(new SgKey(u)); 124 6 : agent()->sg_table()->Enqueue(&req); 125 6 : return false; 126 : } 127 : 128 18 : agent()->config_manager()->AddSgNode(node); 129 18 : return false; 130 : } 131 : 132 12 : bool SgTable::ProcessConfig(IFMapNode *node, DBRequest &req, 133 : const boost::uuids::uuid &u) { 134 : 135 12 : if (node->IsDeleted()) 136 0 : return false; 137 : 138 12 : SecurityGroup *cfg = static_cast<SecurityGroup *>(node->GetObject()); 139 12 : assert(cfg); 140 : 141 12 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; 142 12 : uint32_t sg_id = cfg->id(); 143 12 : if (sg_id == SgTable::kInvalidSgId) { 144 0 : OPER_TRACE(Sg, "Ignore SG id 0", UuidToString(u)); 145 0 : return false; 146 : } 147 : 148 12 : SgKey *key = new SgKey(u); 149 12 : SgData *data = NULL; 150 : 151 12 : boost::uuids::uuid egress_acl_uuid = boost::uuids::nil_uuid(); 152 12 : boost::uuids::uuid ingress_acl_uuid = boost::uuids::nil_uuid(); 153 12 : IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table()); 154 12 : for (DBGraphVertex::adjacency_iterator iter = 155 12 : node->begin(table->GetGraph()); 156 43 : iter != node->end(table->GetGraph()); ++iter) { 157 31 : IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->()); 158 31 : if (agent()->config_manager()->SkipNode(adj_node)) { 159 0 : continue; 160 : } 161 : 162 31 : if (adj_node->table() == agent()->cfg()->cfg_acl_table()) { 163 : AccessControlList *acl_cfg = static_cast<AccessControlList *> 164 24 : (adj_node->GetObject()); 165 24 : assert(acl_cfg); 166 24 : autogen::IdPermsType id_perms = acl_cfg->id_perms(); 167 24 : if (adj_node->name().find("egress-access-control-list") != std::string::npos) { 168 12 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, 169 : egress_acl_uuid); 170 : } 171 24 : if (adj_node->name().find("ingress-access-control-list") != std::string::npos) { 172 12 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, 173 : ingress_acl_uuid); 174 : } 175 24 : } 176 : } 177 12 : data = new SgData(agent(), node, sg_id, egress_acl_uuid, ingress_acl_uuid); 178 12 : req.key.reset(key); 179 12 : req.data.reset(data); 180 12 : agent()->sg_table()->Enqueue(&req); 181 12 : return false; 182 : } 183 : 184 0 : bool SgEntry::DBEntrySandesh(Sandesh *sresp, std::string &name) const { 185 0 : SgListResp *resp = static_cast<SgListResp *>(sresp); 186 0 : std::string str_uuid = UuidToString(GetSgUuid()); 187 0 : if (name.empty() || 188 0 : (str_uuid == name) || 189 0 : (integerToString(GetSgId()) == name)) { 190 0 : SgSandeshData data; 191 0 : data.set_ref_count(GetRefCount()); 192 0 : data.set_sg_uuid(str_uuid); 193 0 : data.set_sg_id(GetSgId()); 194 0 : if (GetEgressAcl()) { 195 0 : data.set_egress_acl_uuid(UuidToString(GetEgressAcl()->GetUuid())); 196 : } 197 0 : if (GetIngressAcl()) { 198 0 : data.set_ingress_acl_uuid(UuidToString(GetIngressAcl()->GetUuid())); 199 : } 200 : std::vector<SgSandeshData> &list = 201 0 : const_cast<std::vector<SgSandeshData>&>(resp->get_sg_list()); 202 0 : list.push_back(data); 203 0 : return true; 204 0 : } 205 0 : return false; 206 0 : } 207 : 208 18 : void SgEntry::SendObjectLog(SandeshTraceBufferPtr buf, 209 : AgentLogEvent::type event) const { 210 18 : SgObjectLogInfo info; 211 : 212 18 : string str; 213 18 : switch(event) { 214 2 : case AgentLogEvent::ADD: 215 2 : str.assign("Addition"); 216 2 : break; 217 6 : case AgentLogEvent::DEL: 218 6 : str.assign("Deletion"); 219 6 : break; 220 10 : case AgentLogEvent::CHANGE: 221 10 : str.assign("Modification"); 222 10 : break; 223 0 : default: 224 0 : str.assign(""); 225 0 : break; 226 : } 227 18 : info.set_event(str); 228 : 229 18 : string sg_uuid = UuidToString(GetSgUuid()); 230 18 : info.set_uuid(sg_uuid); 231 18 : info.set_id(GetSgId()); 232 18 : if (GetEgressAcl()) { 233 18 : info.set_egress_acl_uuid(UuidToString(GetEgressAcl()->GetUuid())); 234 : } 235 18 : if (GetIngressAcl()) { 236 18 : info.set_ingress_acl_uuid(UuidToString(GetIngressAcl()->GetUuid())); 237 : } 238 18 : info.set_ref_count(GetRefCount()); 239 18 : SG_OBJECT_LOG_LOG("AgentSg", SandeshLevel::SYS_INFO, info); 240 18 : SG_OBJECT_TRACE_TRACE(buf, info); 241 18 : } 242 : 243 0 : void SgListReq::HandleRequest() const { 244 0 : AgentSandeshPtr sand(new AgentSgSandesh(context(), get_name())); 245 0 : sand->DoSandesh(sand); 246 0 : } 247 : 248 0 : AgentSandeshPtr SgTable::GetAgentSandesh(const AgentSandeshArguments *args, 249 : const std::string &context) { 250 : return AgentSandeshPtr(new AgentSgSandesh(context, 251 0 : args->GetString("name"))); 252 : }