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 0 : bool SgEntry::IsLess(const DBEntry &rhs) const { 28 0 : const SgEntry &a = static_cast<const SgEntry &>(rhs); 29 0 : 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 0 : std::unique_ptr<DBEntry> SgTable::AllocEntry(const DBRequestKey *k) const { 49 0 : const SgKey *key = static_cast<const SgKey *>(k); 50 0 : SgEntry *sg = new SgEntry(key->sg_uuid_); 51 0 : return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(sg)); 52 : } 53 : 54 0 : DBEntry *SgTable::OperDBAdd(const DBRequest *req) { 55 0 : SgKey *key = static_cast<SgKey *>(req->key.get()); 56 0 : SgEntry *sg = new SgEntry(key->sg_uuid_); 57 0 : ChangeHandler(sg, req); 58 0 : sg->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::ADD); 59 0 : return sg; 60 : } 61 : 62 0 : bool SgTable::OperDBOnChange(DBEntry *entry, const DBRequest *req) { 63 0 : bool ret = ChangeHandler(entry, req); 64 0 : SgEntry *sg = static_cast<SgEntry *>(entry); 65 0 : sg->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::CHANGE); 66 0 : return ret; 67 : } 68 : 69 0 : bool SgTable::ChangeHandler(DBEntry *entry, const DBRequest *req) { 70 0 : bool ret = false; 71 0 : SgEntry *sg = static_cast<SgEntry *>(entry); 72 0 : SgData *data = static_cast<SgData *>(req->data.get()); 73 : 74 0 : if (sg->sg_id_ != data->sg_id_) { 75 0 : sg->sg_id_ = data->sg_id_; 76 0 : ret = true; 77 : } 78 : 79 0 : AclKey key(data->egress_acl_id_); 80 0 : AclDBEntry *acl = static_cast<AclDBEntry *>(agent()->acl_table()->FindActiveEntry(&key)); 81 0 : if (sg->egress_acl_ != acl) { 82 0 : sg->egress_acl_ = acl; 83 0 : ret = true; 84 : } 85 0 : key = AclKey(data->ingress_acl_id_); 86 0 : acl = static_cast<AclDBEntry *>(agent()->acl_table()->FindActiveEntry(&key)); 87 0 : if (sg->ingress_acl_ != acl) { 88 0 : sg->ingress_acl_ = acl; 89 0 : ret = true; 90 : } 91 0 : return ret; 92 0 : } 93 : 94 0 : bool SgTable::OperDBDelete(DBEntry *entry, const DBRequest *req) { 95 0 : SgEntry *sg = static_cast<SgEntry *>(entry); 96 0 : sg->SendObjectLog(GetOperDBTraceBuf(), AgentLogEvent::DEL); 97 0 : 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 0 : bool SgTable::IFNodeToUuid(IFMapNode *node, boost::uuids::uuid &u) { 107 0 : SecurityGroup *cfg = static_cast<SecurityGroup *>(node->GetObject()); 108 0 : assert(cfg); 109 0 : autogen::IdPermsType id_perms = cfg->id_perms(); 110 0 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u); 111 0 : return true; 112 0 : } 113 : 114 0 : bool SgTable::IFNodeToReq(IFMapNode *node, DBRequest &req, 115 : const boost::uuids::uuid &u) { 116 0 : SecurityGroup *cfg = static_cast<SecurityGroup *>(node->GetObject()); 117 0 : assert(cfg); 118 : 119 0 : assert(!u.is_nil()); 120 : 121 0 : if ((req.oper == DBRequest::DB_ENTRY_DELETE) || node->IsDeleted()) { 122 0 : req.oper = DBRequest::DB_ENTRY_DELETE; 123 0 : req.key.reset(new SgKey(u)); 124 0 : agent()->sg_table()->Enqueue(&req); 125 0 : return false; 126 : } 127 : 128 0 : agent()->config_manager()->AddSgNode(node); 129 0 : return false; 130 : } 131 : 132 0 : bool SgTable::ProcessConfig(IFMapNode *node, DBRequest &req, 133 : const boost::uuids::uuid &u) { 134 : 135 0 : if (node->IsDeleted()) 136 0 : return false; 137 : 138 0 : SecurityGroup *cfg = static_cast<SecurityGroup *>(node->GetObject()); 139 0 : assert(cfg); 140 : 141 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; 142 0 : uint32_t sg_id = cfg->id(); 143 0 : if (sg_id == SgTable::kInvalidSgId) { 144 0 : OPER_TRACE(Sg, "Ignore SG id 0", UuidToString(u)); 145 0 : return false; 146 : } 147 : 148 0 : SgKey *key = new SgKey(u); 149 0 : SgData *data = NULL; 150 : 151 0 : boost::uuids::uuid egress_acl_uuid = boost::uuids::nil_uuid(); 152 0 : boost::uuids::uuid ingress_acl_uuid = boost::uuids::nil_uuid(); 153 0 : IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table()); 154 0 : for (DBGraphVertex::adjacency_iterator iter = 155 0 : node->begin(table->GetGraph()); 156 0 : iter != node->end(table->GetGraph()); ++iter) { 157 0 : IFMapNode *adj_node = static_cast<IFMapNode *>(iter.operator->()); 158 0 : if (agent()->config_manager()->SkipNode(adj_node)) { 159 0 : continue; 160 : } 161 : 162 0 : if (adj_node->table() == agent()->cfg()->cfg_acl_table()) { 163 : AccessControlList *acl_cfg = static_cast<AccessControlList *> 164 0 : (adj_node->GetObject()); 165 0 : assert(acl_cfg); 166 0 : autogen::IdPermsType id_perms = acl_cfg->id_perms(); 167 0 : if (adj_node->name().find("egress-access-control-list") != std::string::npos) { 168 0 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, 169 : egress_acl_uuid); 170 : } 171 0 : if (adj_node->name().find("ingress-access-control-list") != std::string::npos) { 172 0 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, 173 : ingress_acl_uuid); 174 : } 175 0 : } 176 : } 177 0 : data = new SgData(agent(), node, sg_id, egress_acl_uuid, ingress_acl_uuid); 178 0 : req.key.reset(key); 179 0 : req.data.reset(data); 180 0 : agent()->sg_table()->Enqueue(&req); 181 0 : 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 0 : void SgEntry::SendObjectLog(SandeshTraceBufferPtr buf, 209 : AgentLogEvent::type event) const { 210 0 : SgObjectLogInfo info; 211 : 212 0 : string str; 213 0 : switch(event) { 214 0 : case AgentLogEvent::ADD: 215 0 : str.assign("Addition"); 216 0 : break; 217 0 : case AgentLogEvent::DEL: 218 0 : str.assign("Deletion"); 219 0 : break; 220 0 : case AgentLogEvent::CHANGE: 221 0 : str.assign("Modification"); 222 0 : break; 223 0 : default: 224 0 : str.assign(""); 225 0 : break; 226 : } 227 0 : info.set_event(str); 228 : 229 0 : string sg_uuid = UuidToString(GetSgUuid()); 230 0 : info.set_uuid(sg_uuid); 231 0 : info.set_id(GetSgId()); 232 0 : if (GetEgressAcl()) { 233 0 : info.set_egress_acl_uuid(UuidToString(GetEgressAcl()->GetUuid())); 234 : } 235 0 : if (GetIngressAcl()) { 236 0 : info.set_ingress_acl_uuid(UuidToString(GetIngressAcl()->GetUuid())); 237 : } 238 0 : info.set_ref_count(GetRefCount()); 239 0 : SG_OBJECT_LOG_LOG("AgentSg", SandeshLevel::SYS_INFO, info); 240 0 : SG_OBJECT_TRACE_TRACE(buf, info); 241 0 : } 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 : }