Line data Source code
1 : /* 2 : * Copyright (c) 2018 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include <cmn/agent.h> 6 : #include <vnc_cfg_types.h> 7 : #include <bgp_schema_types.h> 8 : #include <oper_db.h> 9 : #include <bgp_router.h> 10 : #include <config_manager.h> 11 : 12 : #define INET_LABELED "inet-labeled" 13 : 14 : //////////////////////////////////////////////////////////////////////////////// 15 : // ControlNodeZone routines 16 : //////////////////////////////////////////////////////////////////////////////// 17 0 : ControlNodeZone::ControlNodeZone(const std::string &name, 18 : const std::string &display_name, 19 0 : const boost::uuids::uuid &uuid) : 20 0 : name_(name), display_name_(display_name), uuid_(uuid) { 21 0 : } 22 : 23 0 : ControlNodeZone::~ControlNodeZone() { 24 0 : } 25 : 26 : //////////////////////////////////////////////////////////////////////////////// 27 : // BgpRouter routines 28 : //////////////////////////////////////////////////////////////////////////////// 29 0 : BgpRouter::BgpRouter(const std::string &name, 30 : const std::string &ipv4_address, 31 0 : const uint32_t &port, autogen::BgpRouterParams ¶ms) : 32 0 : name_(name), port_(port) ,params_(params) { 33 0 : boost::system::error_code ec; 34 0 : ipv4_address_ = Ip4Address::from_string(ipv4_address, ec); 35 0 : if (ec.value() != 0) { 36 0 : ipv4_address_ = Ip4Address(); 37 : } 38 0 : if ( std::find(params.address_families.begin(), 39 0 : params.address_families.end(), INET_LABELED) != 40 0 : params.address_families.end() ) { 41 0 : inet_labeled_af_enable_ = true; 42 : } else { 43 0 : inet_labeled_af_enable_ = false; 44 : } 45 0 : } 46 : 47 0 : void BgpRouter::set_ip_address_port(const std::string &ip_address, 48 : const uint32_t &port) { 49 0 : boost::system::error_code ec; 50 0 : ipv4_address_ = Ip4Address::from_string(ip_address, ec); 51 0 : if (ec.value() != 0) { 52 0 : ipv4_address_ = Ip4Address(); 53 : } 54 0 : port_ = port; 55 0 : } 56 : 57 0 : void BgpRouter::set_control_node_zone_name( 58 : const std::string &control_node_zone_name) { 59 0 : control_node_zone_name_ = control_node_zone_name; 60 0 : } 61 : 62 0 : void BgpRouter::set_inet_labeled_af(const autogen::BgpRouterParams params) { 63 0 : if ( std::find(params.address_families.begin(), 64 0 : params.address_families.end(), INET_LABELED) != 65 0 : params.address_families.end() ) { 66 0 : inet_labeled_af_enable_ = true; 67 : } else { 68 0 : inet_labeled_af_enable_ = false; 69 : } 70 0 : } 71 : 72 : 73 0 : BgpRouter::~BgpRouter() { 74 0 : } 75 : 76 : //////////////////////////////////////////////////////////////////////////////// 77 : // BgpRouterConfig routines 78 : //////////////////////////////////////////////////////////////////////////////// 79 1 : BgpRouterConfig::BgpRouterConfig(Agent *agent) : 80 1 : OperIFMapTable(agent), inet_labeled_af_enabled_(false) { 81 1 : } 82 : 83 0 : BgpRouterPtr BgpRouterConfig::GetBgpRouterFromXmppServer( 84 : const std::string &xmpp_server) { 85 0 : boost::system::error_code ec; 86 0 : bool xmpp_server_ip_presence = true; 87 0 : Ip4Address ipv4_address = Ip4Address::from_string(xmpp_server, ec); 88 0 : if (ec.value() != 0) { 89 0 : xmpp_server_ip_presence = false; 90 : } 91 0 : BgpRouterPtr entry; 92 0 : std::scoped_lock lock(mutex_); 93 0 : BgpRouterTree::const_iterator it = bgp_router_tree_.begin(); 94 0 : for ( ;it != bgp_router_tree_.end(); it++) { 95 0 : entry = it->second; 96 0 : if (xmpp_server_ip_presence) { 97 0 : if (entry->ipv4_address() == ipv4_address) 98 0 : return entry; 99 : } else { 100 0 : std::string fqdn_name = entry->name(); 101 0 : size_t pos = fqdn_name.rfind(":"); 102 0 : if (pos != std::string::npos) 103 0 : pos = pos + 1; 104 : else 105 0 : pos = 0; 106 : std::string bgp_router_name = 107 0 : fqdn_name.substr(pos, fqdn_name.length()); 108 0 : if (bgp_router_name == xmpp_server) 109 0 : return entry; 110 0 : } 111 : } 112 0 : return BgpRouterPtr(); 113 0 : } 114 : 115 0 : BgpRouterPtr BgpRouterConfig::GetBgpRouterFromControlNodeZone( 116 : const std::string &cnz_name) { 117 0 : std::scoped_lock lock(mutex_); 118 : ControlNodeZoneTree::const_iterator cnz_it = 119 0 : control_node_zone_tree_.find(cnz_name); 120 0 : if (cnz_it != control_node_zone_tree_.end()) { 121 0 : ControlNodeZonePtr entry = cnz_it->second; 122 0 : int count = 0; 123 0 : int index = rand() % entry->bgp_router_tree_.size(); 124 0 : BgpRouterTree::const_iterator it = entry->bgp_router_tree_.begin(); 125 0 : for ( ;it != entry->bgp_router_tree_.end(); it++) { 126 0 : if (count == index) 127 0 : return it->second; 128 0 : count++; 129 : } 130 0 : } 131 0 : return BgpRouterPtr(); 132 0 : } 133 : 134 0 : uint32_t BgpRouterConfig::GetBgpRouterCount(const std::string &cnz_name) { 135 0 : std::scoped_lock lock(mutex_); 136 : ControlNodeZoneTree::const_iterator cnz_it = 137 0 : control_node_zone_tree_.find(cnz_name); 138 0 : if (cnz_it != control_node_zone_tree_.end()) { 139 0 : ControlNodeZonePtr entry = cnz_it->second; 140 0 : return entry->bgp_router_tree_.size(); 141 0 : } 142 0 : return 0; 143 0 : } 144 : 145 0 : void BgpRouterConfig::DeleteControlNodeZoneConfig(IFMapNode *bgp_router_node, 146 : BgpRouterPtr bgp_router) { 147 0 : std::string cnz_name = bgp_router->control_node_zone_name(); 148 0 : if (cnz_name.empty()) 149 0 : return; 150 : ControlNodeZoneTree::const_iterator it = 151 0 : control_node_zone_tree_.find(cnz_name); 152 0 : if (it != control_node_zone_tree_.end()) { 153 0 : ControlNodeZonePtr entry = it->second; 154 0 : entry->bgp_router_tree_.erase(bgp_router->name()); 155 0 : if (entry->bgp_router_tree_.size() == 0) { 156 0 : control_node_zone_tree_.erase(cnz_name); 157 0 : entry.reset(); 158 : } 159 0 : } 160 0 : } 161 : 162 0 : void BgpRouterConfig::UpdateControlNodeZoneConfig(IFMapNode *bgp_router_node, 163 : BgpRouterPtr bgp_router) { 164 0 : std::string cnz_node_name; 165 0 : IFMapNode *cnz_node = NULL; 166 : IFMapAgentTable *bgp_router_table = 167 0 : static_cast<IFMapAgentTable *>(bgp_router_node->table()); 168 0 : DBGraph *graph = bgp_router_table->GetGraph(); 169 0 : DBGraphVertex::adjacency_iterator iter = bgp_router_node->begin(graph); 170 0 : while (iter != bgp_router_node->end(graph)) { 171 0 : IFMapNode *node = static_cast<IFMapNode *>(iter.operator->()); 172 0 : if (strcmp(node->table()->Typename(), 173 0 : CONTROL_NODE_ZONE_CONFIG_NAME) == 0) { 174 0 : cnz_node = node; 175 0 : cnz_node_name = cnz_node->name(); 176 0 : break; 177 : } 178 0 : iter++; 179 : } 180 : 181 0 : std::string cnz_name = bgp_router->control_node_zone_name(); 182 0 : if (strcmp(cnz_name.c_str(), cnz_node_name.c_str()) == 0) { 183 0 : return; 184 : } 185 : 186 0 : DeleteControlNodeZoneConfig(bgp_router_node, bgp_router); 187 0 : bgp_router->set_control_node_zone_name(cnz_node_name); 188 0 : if (cnz_node == NULL) 189 0 : return; 190 : 191 0 : ControlNodeZonePtr entry; 192 : ControlNodeZoneTree::const_iterator it = 193 0 : control_node_zone_tree_.find(cnz_node->name()); 194 0 : if (it != control_node_zone_tree_.end()) { 195 0 : entry = it->second; 196 0 : entry->bgp_router_tree_.insert( 197 0 : std::make_pair(bgp_router->name(), bgp_router)); 198 : } else { 199 : autogen::ControlNodeZone *cfg = 200 0 : static_cast<autogen::ControlNodeZone *>(cnz_node->GetObject()); 201 0 : autogen::IdPermsType id_perms = cfg->id_perms(); 202 : boost::uuids::uuid uuid; 203 0 : CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong, uuid); 204 : ControlNodeZonePtr cnz( 205 0 : new ControlNodeZone(cnz_node_name, cfg->display_name(), uuid)); 206 0 : entry = cnz; 207 0 : entry->bgp_router_tree_.insert( 208 0 : std::make_pair(bgp_router->name(), bgp_router)); 209 0 : control_node_zone_tree_.insert(std::make_pair(cnz_node_name, entry)); 210 0 : } 211 0 : } 212 : 213 0 : void BgpRouterConfig::UpdateBgpRouterConfigAf(void) { 214 0 : bool inet_labeled_flag = false; 215 0 : BgpRouterPtr entry; 216 0 : BgpRouterTree::const_iterator it = bgp_router_tree_.begin(); 217 0 : while (it != bgp_router_tree_.end()) { 218 0 : entry = it->second; 219 0 : if (entry->get_inet_labeled_af()) { 220 0 : inet_labeled_flag = true; 221 0 : break; 222 : } 223 0 : it++; 224 : } 225 : 226 0 : if (inet_labeled_af_enabled_ != inet_labeled_flag) { 227 0 : inet_labeled_af_enabled_ = inet_labeled_flag; 228 0 : agent()->set_inet_labeled_flag(inet_labeled_af_enabled_); 229 : 230 : } 231 0 : } 232 : 233 : 234 : 235 0 : void BgpRouterConfig::ConfigAddChange(IFMapNode *node) { 236 0 : if (node->IsDeleted()) 237 0 : return; 238 : autogen::BgpRouter *bgp_router_cfg = 239 0 : static_cast<autogen::BgpRouter *>(node->GetObject()); 240 0 : if (bgp_router_cfg == NULL) 241 0 : return; 242 0 : autogen::BgpRouterParams params = bgp_router_cfg->parameters(); 243 0 : if ((strcmp(params.router_type.c_str(), BGP_ROUTER_TYPE) != 0) && 244 0 : (strcmp(params.router_type.c_str(), BGP_ROUTER_EXT_TYPE) != 0)) 245 0 : return; 246 : 247 0 : std::string name = node->name(); 248 0 : BgpRouterPtr entry; 249 0 : std::scoped_lock lock(mutex_); 250 0 : BgpRouterTree::const_iterator it = bgp_router_tree_.find(name); 251 0 : if (it != bgp_router_tree_.end()) { 252 0 : entry = it->second; 253 0 : entry->set_ip_address_port(params.address, params.port); 254 0 : entry->set_inet_labeled_af(params); 255 : } else { 256 : BgpRouterPtr bgp_router( 257 0 : new BgpRouter(name, params.address, params.port, params)); 258 0 : entry = bgp_router; 259 0 : bgp_router_tree_.insert(std::make_pair(name, entry)); 260 0 : } 261 : //TODO: optimize calling this function 262 0 : UpdateBgpRouterConfigAf(); 263 0 : UpdateControlNodeZoneConfig(node, entry); 264 : 265 0 : return; 266 0 : } 267 : 268 0 : void BgpRouterConfig::ConfigDelete(IFMapNode *node) { 269 : autogen::BgpRouter *bgp_router_cfg = 270 0 : static_cast<autogen::BgpRouter *>(node->GetObject()); 271 0 : if (bgp_router_cfg == NULL) 272 0 : return; 273 0 : autogen::BgpRouterParams params = bgp_router_cfg->parameters(); 274 0 : if ((strcmp(params.router_type.c_str(), BGP_ROUTER_TYPE) != 0) && 275 0 : (strcmp(params.router_type.c_str(), BGP_ROUTER_EXT_TYPE) != 0)) 276 0 : return; 277 : 278 0 : std::string name = node->name(); 279 0 : std::scoped_lock lock(mutex_); 280 0 : BgpRouterTree::const_iterator it = bgp_router_tree_.find(name); 281 0 : if (it != bgp_router_tree_.end()) { 282 0 : BgpRouterPtr entry = it->second; 283 0 : DeleteControlNodeZoneConfig(node, entry); 284 0 : entry.reset(); 285 0 : bgp_router_tree_.erase(it->first); 286 0 : } 287 0 : } 288 : 289 0 : void BgpRouterConfig::ConfigManagerEnqueue(IFMapNode *node) { 290 0 : agent()->config_manager()->AddBgpRouterConfigNode(node); 291 0 : } 292 : 293 2 : BgpRouterConfig::~BgpRouterConfig() { 294 2 : } 295 : 296 0 : void BgpRouterSandeshReq::HandleRequest() const { 297 0 : BgpRouterSandeshResp *resp = new BgpRouterSandeshResp(); 298 0 : resp->set_context(context()); 299 0 : std::string filter = get_name(); 300 0 : std::vector<BgpRouterSandeshList> bgp_router_sandesh_list; 301 0 : Agent *agent = Agent::GetInstance(); 302 0 : BgpRouterConfig *bgp_router_cfg = agent->oper_db()->bgp_router_config(); 303 0 : BgpRouterTree bgp_router_tree = bgp_router_cfg->bgp_router_tree(); 304 0 : BgpRouterTree::const_iterator it = bgp_router_tree.begin(); 305 0 : for ( ;it != bgp_router_tree.end(); it++) { 306 0 : BgpRouterPtr bgp_router_entry = it->second; 307 0 : BgpRouterSandeshList bgp_router_sandesh_entry; 308 0 : std::string bgp_router_name = bgp_router_entry->name(); 309 0 : if (filter.size()) { 310 0 : if (bgp_router_name.find(filter) == std::string::npos) { 311 0 : continue; 312 : } 313 : } 314 0 : bgp_router_sandesh_entry.set_name(bgp_router_entry->name()); 315 0 : std::stringstream ss; 316 0 : ss << bgp_router_entry->ipv4_address() 317 0 : << ":"<< bgp_router_entry->port(); 318 0 : bgp_router_sandesh_entry.set_ipv4_address_port(ss.str()); 319 0 : bgp_router_sandesh_entry.set_control_node_zone( 320 : bgp_router_entry->control_node_zone_name()); 321 0 : bgp_router_sandesh_list.push_back(bgp_router_sandesh_entry); 322 0 : } 323 0 : resp->set_bgp_router_list(bgp_router_sandesh_list); 324 0 : resp->Response(); 325 0 : } 326 : 327 0 : void ControlNodeZoneSandeshReq::HandleRequest() const { 328 0 : ControlNodeZoneSandeshResp *resp = new ControlNodeZoneSandeshResp(); 329 0 : resp->set_context(context()); 330 0 : std::string filter = get_name(); 331 0 : std::vector<ControlNodeZoneSandeshList> cnz_sandesh_list; 332 0 : Agent *agent = Agent::GetInstance(); 333 0 : BgpRouterConfig *bgp_router_cfg = agent->oper_db()->bgp_router_config(); 334 0 : ControlNodeZoneTree cnz_tree = bgp_router_cfg->control_node_zone_tree(); 335 0 : ControlNodeZoneTree::const_iterator it = cnz_tree.begin(); 336 0 : for ( ;it != cnz_tree.end(); it++) { 337 0 : ControlNodeZonePtr cnz_entry = it->second; 338 0 : ControlNodeZoneSandeshList cnz_sandesh_entry; 339 0 : std::string cnz_name = cnz_entry->name(); 340 0 : if (filter.size()) { 341 0 : if (cnz_name.find(filter) == std::string::npos) { 342 0 : continue; 343 : } 344 : } 345 0 : cnz_sandesh_entry.set_name(cnz_entry->name()); 346 0 : BgpRouterTree bgp_router_tree = cnz_entry->bgp_router_tree(); 347 0 : BgpRouterTree::const_iterator it = bgp_router_tree.begin(); 348 0 : std::vector<BgpRouterSandeshList> bgp_router_list; 349 0 : for ( ;it != bgp_router_tree.end(); it++) { 350 0 : BgpRouterPtr bgp_router_entry = it->second; 351 0 : BgpRouterSandeshList bgp_router_sandesh_entry; 352 0 : bgp_router_sandesh_entry.set_name(bgp_router_entry->name()); 353 0 : std::stringstream ss; 354 0 : ss << bgp_router_entry->ipv4_address() 355 0 : << ":" << bgp_router_entry->port(); 356 0 : bgp_router_sandesh_entry.set_ipv4_address_port(ss.str()); 357 0 : bgp_router_sandesh_entry.set_control_node_zone( 358 : bgp_router_entry->control_node_zone_name()); 359 0 : bgp_router_list.push_back(bgp_router_sandesh_entry); 360 0 : } 361 0 : cnz_sandesh_entry.set_bgp_router_list(bgp_router_list); 362 0 : cnz_sandesh_list.push_back(cnz_sandesh_entry); 363 0 : } 364 0 : resp->set_control_node_zone_list(cnz_sandesh_list); 365 0 : resp->Response(); 366 0 : }