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