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