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