Line data Source code
1 : /* 2 : * Copyright (c) 2018 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/config_manager.h> 16 : #include <oper/multicast_policy.h> 17 : 18 : #include <oper/agent_sandesh.h> 19 : 20 : using namespace autogen; 21 : using namespace std; 22 : 23 : SandeshTraceBufferPtr 24 : MulticastPolicyTraceBuf(SandeshTraceBufferCreate("MulticastPolicy", 5000)); 25 : 26 : MulticastPolicyTable *MulticastPolicyTable::mp_table_; 27 : 28 0 : bool MulticastPolicyEntry::IsLess(const DBEntry &rhs) const { 29 0 : const MulticastPolicyEntry &a = 30 : static_cast<const MulticastPolicyEntry &>(rhs); 31 0 : return (mp_uuid_ < a.mp_uuid_); 32 : } 33 : 34 0 : string MulticastPolicyEntry::ToString() const { 35 0 : std::stringstream uuidstring; 36 0 : uuidstring << mp_uuid_; 37 0 : return uuidstring.str(); 38 0 : } 39 : 40 0 : DBEntryBase::KeyPtr MulticastPolicyEntry::GetDBRequestKey() const { 41 0 : MulticastPolicyKey *key = new MulticastPolicyKey(mp_uuid_); 42 0 : return DBEntryBase::KeyPtr(key); 43 : } 44 : 45 0 : void MulticastPolicyEntry::SetKey(const DBRequestKey *key) { 46 0 : const MulticastPolicyKey *k = static_cast<const MulticastPolicyKey *>(key); 47 0 : mp_uuid_ = k->mp_uuid_; 48 0 : } 49 : 50 0 : SourceGroupInfo::Action MulticastPolicyEntry::GetAction(IpAddress source, 51 : IpAddress group) const { 52 : 53 0 : std::vector<SourceGroupInfo>::const_iterator it = mcast_sg_.begin(); 54 0 : while (it != mcast_sg_.end()) { 55 0 : if ((it->source == source) && (it->group == group)) { 56 0 : return it->action; 57 : } 58 0 : it++; 59 : } 60 : 61 0 : return SourceGroupInfo::ACTION_DENY; 62 : } 63 : 64 0 : std::unique_ptr<DBEntry> MulticastPolicyTable::AllocEntry(const DBRequestKey *k) 65 : const { 66 : 67 0 : const MulticastPolicyKey *key = static_cast<const MulticastPolicyKey *>(k); 68 0 : MulticastPolicyEntry *mp = new MulticastPolicyEntry(key->mp_uuid_); 69 0 : return std::unique_ptr<DBEntry>(static_cast<DBEntry *>(mp)); 70 : } 71 : 72 0 : DBEntry *MulticastPolicyTable::OperDBAdd(const DBRequest *req) { 73 0 : MulticastPolicyKey *key = static_cast<MulticastPolicyKey *>(req->key.get()); 74 0 : MulticastPolicyEntry *mp = new MulticastPolicyEntry(key->mp_uuid_); 75 0 : ChangeHandler(mp, req); 76 0 : return mp; 77 : } 78 : 79 0 : bool MulticastPolicyTable::OperDBOnChange(DBEntry *entry, 80 : const DBRequest *req) { 81 : 82 0 : MulticastPolicyEntry *mp = static_cast<MulticastPolicyEntry *>(entry); 83 0 : bool ret = ChangeHandler(mp, req); 84 0 : return ret; 85 : } 86 : 87 0 : bool MulticastPolicyTable::OperDBDelete(DBEntry *entry, const DBRequest *req) { 88 0 : std::vector<SourceGroupInfo> mcast_sg; 89 0 : MulticastPolicyEntry *mp = static_cast<MulticastPolicyEntry *>(entry); 90 0 : mp->set_mcast_sg(mcast_sg); 91 0 : return true; 92 0 : } 93 : 94 0 : bool MulticastPolicyTable::IsEqual( 95 : const std::vector<SourceGroupInfo> &lhs, 96 : const std::vector<SourceGroupInfo> &rhs) const { 97 : 98 0 : if (lhs.size() != rhs.size()) { 99 0 : return false; 100 : } 101 : 102 0 : vector<SourceGroupInfo>::const_iterator lit = lhs.begin(); 103 0 : vector<SourceGroupInfo>::const_iterator rit = rhs.begin(); 104 0 : while (lit != lhs.end() && rit != rhs.end()) { 105 0 : if ((lit->source != rit->source) || 106 0 : (lit->group != rit->group) || 107 0 : (lit->action != rit->action)) { 108 0 : return false; 109 : } 110 0 : ++lit; 111 0 : ++rit; 112 : } 113 0 : return true; 114 : } 115 : 116 0 : bool MulticastPolicyTable::ChangeHandler(DBEntry *entry, const DBRequest *req) { 117 0 : bool ret = false; 118 0 : MulticastPolicyEntry *mp = static_cast<MulticastPolicyEntry *>(entry); 119 0 : MulticastPolicyData *data = static_cast<MulticastPolicyData *>(req->data.get()); 120 : 121 0 : if (!IsEqual(mp->mcast_sg(), data->mcast_sg_)) { 122 0 : mp->set_mcast_sg(data->mcast_sg_); 123 0 : ret = true; 124 : } 125 : 126 0 : if (mp->name() != data->name_) { 127 0 : mp->set_name(data->name_); 128 0 : ret = true; 129 : } 130 : 131 0 : return ret; 132 : } 133 : 134 2 : DBTableBase *MulticastPolicyTable::CreateTable(DB *db, 135 : const std::string &name) { 136 2 : mp_table_ = new MulticastPolicyTable(db, name); 137 2 : mp_table_->Init(); 138 2 : return mp_table_; 139 : }; 140 : 141 0 : bool MulticastPolicyTable::IFNodeToUuid(IFMapNode *node, 142 : boost::uuids::uuid &u) { 143 0 : MulticastPolicy *cfg = static_cast<MulticastPolicy *>(node->GetObject()); 144 0 : assert(cfg); 145 0 : autogen::IdPermsType id_perms = cfg->id_perms(); 146 0 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, u); 147 0 : return true; 148 0 : } 149 : 150 0 : bool MulticastPolicyTable::IFNodeToReq(IFMapNode *node, DBRequest &req, 151 : const boost::uuids::uuid &u) { 152 0 : MulticastPolicy *cfg = static_cast<MulticastPolicy *>(node->GetObject()); 153 0 : assert(cfg); 154 : 155 0 : assert(!u.is_nil()); 156 : 157 0 : if ((req.oper == DBRequest::DB_ENTRY_DELETE) || node->IsDeleted()) { 158 0 : req.oper = DBRequest::DB_ENTRY_DELETE; 159 0 : req.key.reset(new MulticastPolicyKey(u)); 160 0 : agent()->mp_table()->Enqueue(&req); 161 0 : return false; 162 : } 163 : 164 0 : agent()->config_manager()->AddMulticastPolicyNode(node); 165 0 : return false; 166 : } 167 : 168 0 : bool MulticastPolicyTable::ProcessConfig(IFMapNode *node, DBRequest &req, 169 : const boost::uuids::uuid &u) { 170 : 171 0 : if (node->IsDeleted()) 172 0 : return false; 173 : 174 0 : MulticastPolicy *cfg = static_cast<MulticastPolicy *>(node->GetObject()); 175 0 : assert(cfg); 176 : 177 0 : req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; 178 : 179 : autogen::MulticastPolicy *data = 180 0 : static_cast<autogen::MulticastPolicy *>(node->GetObject()); 181 : 182 0 : autogen::IdPermsType id_perms = data->id_perms(); 183 : 184 : std::vector<autogen::MulticastSourceGroup> cfg_sg_list = 185 0 : data->multicast_source_groups(); 186 : std::vector<autogen::MulticastSourceGroup>::const_iterator it = 187 0 : cfg_sg_list.begin(); 188 : 189 0 : std::vector<SourceGroupInfo> sg_list; 190 0 : SourceGroupInfo sg; 191 0 : boost::system::error_code ec; 192 0 : while (it != cfg_sg_list.end()) { 193 0 : sg.source = IpAddress::from_string(it->source_address, ec); 194 0 : sg.group = IpAddress::from_string(it->group_address, ec); 195 0 : sg.action = (it->action == "pass") ? 196 : SourceGroupInfo::ACTION_PASS : 197 : SourceGroupInfo::ACTION_DENY; 198 0 : sg_list.push_back(sg); 199 0 : it++; 200 : } 201 : 202 0 : MulticastPolicyKey *mp_key = new MulticastPolicyKey(u); 203 : MulticastPolicyData *mp_data = 204 0 : new MulticastPolicyData(agent(), node, node->name(), sg_list); 205 : 206 0 : req.key.reset(mp_key); 207 0 : req.data.reset(mp_data); 208 0 : agent()->mp_table()->Enqueue(&req); 209 0 : return false; 210 0 : } 211 : 212 0 : bool MulticastPolicyEntry::DBEntrySandesh(Sandesh *sresp, 213 : std::string &name) const { 214 : 215 0 : MulticastPolicyResp *resp = static_cast<MulticastPolicyResp *>(sresp); 216 0 : std::string str_uuid = UuidToString(GetMpUuid()); 217 : 218 0 : MulticastPolicySandeshData data; 219 0 : std::vector<MulticastPolicyEntrySandeshData> entries; 220 : std::vector<SourceGroupInfo>::const_iterator it = 221 0 : mcast_sg_.begin(); 222 0 : uint32_t id = 0; 223 0 : while (it != mcast_sg_.end()) { 224 0 : MulticastPolicyEntrySandeshData entry; 225 0 : entry.set_entry_id(id); 226 0 : entry.set_source_address(it->source.to_string()); 227 0 : entry.set_group_address(it->group.to_string()); 228 0 : entry.set_action((it->action == SourceGroupInfo::ACTION_PASS) ? 229 : "pass" : "deny"); 230 0 : entries.push_back(entry); 231 0 : it++; 232 0 : } 233 0 : data.set_entries(entries); 234 : 235 : std::vector<MulticastPolicySandeshData> &list = 236 : const_cast<std::vector<MulticastPolicySandeshData>&> 237 0 : (resp->get_mp_list()); 238 0 : list.push_back(data); 239 : 240 0 : return true; 241 0 : } 242 : 243 0 : void MulticastPolicyReq::HandleRequest() const { 244 0 : AgentSandeshPtr sand(new AgentMulticastPolicySandesh(context(), 245 0 : get_uuid())); 246 0 : sand->DoSandesh(sand); 247 0 : } 248 : 249 0 : AgentSandeshPtr MulticastPolicyTable::GetAgentSandesh( 250 : const AgentSandeshArguments *args, 251 : const std::string &context) { 252 : 253 : return AgentSandeshPtr(new AgentMulticastPolicySandesh(context, 254 0 : args->GetString("uuid"))); 255 : }