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 "bgp/bgp_config_ifmap.h"
7 :
8 : #include <boost/foreach.hpp>
9 :
10 : #include <algorithm>
11 :
12 : #include "base/string_util.h"
13 : #include "base/task_annotations.h"
14 : #include "bgp/bgp_common.h"
15 : #include "bgp/bgp_config_listener.h"
16 : #include "bgp/bgp_log.h"
17 : #include "bgp/routing-instance/iservice_chain_mgr.h"
18 : #include "ifmap/ifmap_node.h"
19 : #include "ifmap/ifmap_table.h"
20 :
21 : #include "schema/bgp_schema_types.h"
22 : #include "schema/vnc_cfg_types.h"
23 :
24 : using std::unique_ptr;
25 : using std::find;
26 : using std::make_pair;
27 : using std::pair;
28 : using std::set;
29 : using std::sort;
30 : using std::string;
31 : using std::vector;
32 : using boost::iequals;
33 :
34 : const int BgpIfmapConfigManager::kConfigTaskInstanceId = 0;
35 :
36 : static BgpNeighborConfig::AddressFamilyList default_addr_family_list;
37 :
38 125 : void DefaultAddressFamilyInit() {
39 125 : default_addr_family_list.push_back("inet");
40 125 : default_addr_family_list.push_back("inet-vpn");
41 125 : }
42 :
43 : MODULE_INITIALIZER(DefaultAddressFamilyInit);
44 :
45 69500 : static string IdentifierParent(const string &identifier) {
46 69500 : string parent;
47 : size_t last;
48 69500 : last = identifier.rfind(':');
49 69500 : if (last == 0 || last == string::npos) {
50 0 : return parent;
51 : }
52 69500 : parent = identifier.substr(0, last);
53 69500 : return parent;
54 0 : }
55 :
56 69815 : static uint32_t IpAddressToBgpIdentifier(const IpAddress &address) {
57 69815 : return htonl(address.to_v4().to_ulong());
58 : }
59 :
60 13392 : static string BgpIdentifierToString(uint32_t identifier) {
61 13392 : Ip4Address addr(ntohl(identifier));
62 26784 : return addr.to_string();
63 : }
64 :
65 4312 : BgpIfmapPeeringConfig::BgpIfmapPeeringConfig(BgpIfmapInstanceConfig *instance)
66 4312 : : instance_(instance) {
67 4312 : }
68 :
69 4312 : BgpIfmapPeeringConfig::~BgpIfmapPeeringConfig() {
70 4312 : STLDeleteElements(&neighbors_);
71 4312 : }
72 :
73 4312 : void BgpIfmapPeeringConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
74 4312 : if (proxy != NULL) {
75 4312 : node_proxy_.Swap(proxy);
76 4312 : name_ = node_proxy_.node()->name();
77 : }
78 4312 : }
79 :
80 165 : BgpIfmapRoutingPolicyLinkConfig::BgpIfmapRoutingPolicyLinkConfig(
81 165 : BgpIfmapInstanceConfig *rti, BgpIfmapRoutingPolicyConfig *rtp) :
82 165 : instance_(rti), policy_(rtp) {
83 165 : }
84 :
85 165 : BgpIfmapRoutingPolicyLinkConfig::~BgpIfmapRoutingPolicyLinkConfig() {
86 165 : }
87 :
88 165 : void BgpIfmapRoutingPolicyLinkConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
89 165 : if (proxy != NULL) {
90 165 : node_proxy_.Swap(proxy);
91 165 : name_ = node_proxy_.node()->name();
92 : }
93 165 : }
94 :
95 165 : bool BgpIfmapRoutingPolicyLinkConfig::GetInstancePolicyPair(
96 : DBGraph *graph, IFMapNode *node, pair<IFMapNode *, IFMapNode *> *pair) {
97 165 : IFMapNode *routing_instance = NULL;
98 165 : IFMapNode *routing_policy = NULL;
99 :
100 165 : for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
101 495 : iter != node->end(graph); ++iter) {
102 330 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
103 330 : if (strcmp(adj->table()->Typename(), "routing-instance") == 0)
104 165 : routing_instance = adj;
105 330 : if (strcmp(adj->table()->Typename(), "routing-policy") == 0)
106 165 : routing_policy = adj;
107 : }
108 165 : if (routing_policy == NULL || routing_instance == NULL) {
109 0 : return false;
110 : }
111 :
112 165 : pair->first = routing_instance;
113 165 : pair->second = routing_policy;
114 165 : return true;
115 : }
116 :
117 190 : void BgpIfmapRoutingPolicyLinkConfig::Update(BgpIfmapConfigManager *manager,
118 : const autogen::RoutingPolicyRoutingInstance *ri_rp) {
119 190 : ri_rp_link_.reset(ri_rp);
120 190 : }
121 :
122 0 : void BgpIfmapRoutingPolicyLinkConfig::Delete(BgpIfmapConfigManager *manager) {
123 0 : ri_rp_link_.reset();
124 0 : }
125 :
126 59312 : static AuthenticationData::KeyType KeyChainType(const string &value) {
127 : // Case-insensitive comparison
128 59312 : if (boost::iequals(value, "md5")) {
129 761 : return AuthenticationData::MD5;
130 : }
131 58551 : return AuthenticationData::NIL;
132 : }
133 :
134 59312 : static void BuildKeyChain(BgpNeighborConfig *neighbor,
135 : const autogen::AuthenticationData &values) {
136 59312 : AuthenticationData keydata;
137 59312 : keydata.set_key_type(KeyChainType(values.key_type));
138 :
139 59312 : AuthenticationKey key;
140 59312 : for (vector<autogen::AuthenticationKeyItem>::const_iterator iter =
141 119281 : values.key_items.begin(); iter != values.key_items.end(); ++iter) {
142 657 : key.id = iter->key_id;
143 657 : key.value = iter->key;
144 657 : key.start_time = 0;
145 657 : keydata.AddKeyToKeyChain(key);
146 : }
147 59312 : neighbor->set_keydata(keydata);
148 59312 : }
149 :
150 : //
151 : // Check if the family is allowed to be configured for BgpNeighborConfig.
152 : // Only families inet and inet6 are allowed on non-master instances.
153 : //
154 9461 : static bool AddressFamilyIsValid(BgpNeighborConfig *neighbor,
155 : const string &family) {
156 9461 : if (neighbor->instance_name() == BgpConfigManager::kMasterInstance)
157 8263 : return true;
158 1198 : return (family == "inet" || family == "inet6");
159 : }
160 :
161 : //
162 : // Build list of BgpFamilyAttributesConfig elements from the list of address
163 : // families. This is provided for backward compatibility with configurations
164 : // that represent each family with a simple string.
165 : //
166 3583 : static void BuildFamilyAttributesList(BgpNeighborConfig *neighbor,
167 : const BgpNeighborConfig::AddressFamilyList &family_list,
168 : const vector<string> &remote_family_list) {
169 3583 : BgpNeighborConfig::FamilyAttributesList family_attributes_list;
170 17561 : BOOST_FOREACH(const string &family, family_list) {
171 : // Skip families that are not valid/supported for the neighbor.
172 6989 : if (!AddressFamilyIsValid(neighbor, family))
173 26 : continue;
174 :
175 : // Skip families that are not configured on remote bgp-router.
176 6971 : if (!remote_family_list.empty()) {
177 4971 : vector<string>::const_iterator it = find(
178 : remote_family_list.begin(), remote_family_list.end(), family);
179 4971 : if (it == remote_family_list.end())
180 8 : continue;
181 : }
182 :
183 6963 : BgpFamilyAttributesConfig family_attributes(family);
184 6963 : family_attributes_list.push_back(family_attributes);
185 6963 : }
186 :
187 3583 : neighbor->set_family_attributes_list(family_attributes_list);
188 3583 : }
189 :
190 : //
191 : // Build list of BgpFamilyAttributesConfig elements from BgpFamilyAttributes
192 : // list in BgpSessionAttributes.
193 : //
194 : // Implement backward compatibility by also adding BgpFamilyAttributesConfig
195 : // elements for families that are not in BgpFamilyAttributes list but are in
196 : // the address_families list.
197 : //
198 29182 : static void BuildFamilyAttributesList(BgpNeighborConfig *neighbor,
199 : const autogen::BgpSessionAttributes *attributes) {
200 29182 : set<string> family_set;
201 29182 : BgpNeighborConfig::FamilyAttributesList family_attributes_list;
202 34126 : BOOST_FOREACH(const autogen::BgpFamilyAttributes &family_config,
203 : attributes->family_attributes) {
204 2472 : if (!AddressFamilyIsValid(neighbor, family_config.address_family))
205 166 : continue;
206 : BgpFamilyAttributesConfig family_attributes(
207 2306 : family_config.address_family);
208 2306 : family_attributes.loop_count = family_config.loop_count;
209 2306 : family_attributes.prefix_limit = family_config.prefix_limit.maximum;
210 2306 : family_attributes.idle_timeout =
211 2306 : family_config.prefix_limit.idle_timeout;
212 : family_attributes.default_tunnel_encap_list =
213 2306 : family_config.default_tunnel_encap;
214 2306 : family_attributes_list.push_back(family_attributes);
215 2306 : family_set.insert(family_config.address_family);
216 2306 : }
217 :
218 100576 : BOOST_FOREACH(const string &family, attributes->address_families.family) {
219 35697 : if (family_set.find(family) != family_set.end())
220 0 : continue;
221 35697 : BgpFamilyAttributesConfig family_attributes(family);
222 35697 : family_attributes_list.push_back(family_attributes);
223 35697 : }
224 :
225 29182 : neighbor->set_family_attributes_list(family_attributes_list);
226 29182 : }
227 :
228 : //
229 : // Set the autogen::BgpSessionAttributes for this BgpNeighborConfig.
230 : //
231 : // The autogen::BgpSession will have up to 3 session attributes - one that
232 : // applies to the local router, one that applies the remote router and one
233 : // that applies to both.
234 : //
235 30698 : static void NeighborSetSessionAttributes(
236 : BgpNeighborConfig *neighbor, const string &localname,
237 : const autogen::BgpSession *session) {
238 : typedef vector<autogen::BgpSessionAttributes> AttributeVec;
239 30698 : const autogen::BgpSessionAttributes *common = NULL;
240 30698 : const autogen::BgpSessionAttributes *local = NULL;
241 30698 : for (AttributeVec::const_iterator iter = session->attributes.begin();
242 88573 : iter != session->attributes.end(); ++iter) {
243 57875 : const autogen::BgpSessionAttributes *attr = iter.operator->();
244 57875 : if (attr->bgp_router.empty()) {
245 197 : common = attr;
246 114360 : } else if (neighbor->router_type() != "bgpaas-client" &&
247 56682 : attr->bgp_router == localname) {
248 28487 : local = attr;
249 30187 : } else if (neighbor->router_type() == "bgpaas-client" &&
250 996 : attr->bgp_router == "bgpaas-server") {
251 498 : local = attr;
252 : }
253 : }
254 :
255 : // TODO(nsheth): local should override rather than replace common.
256 30698 : const autogen::BgpSessionAttributes *attributes = NULL;
257 30698 : if (common != NULL) {
258 197 : attributes = common;
259 30501 : } else if (local != NULL) {
260 28985 : attributes = local;
261 : }
262 30698 : if (attributes != NULL) {
263 29182 : neighbor->set_passive(attributes->passive);
264 29182 : neighbor->set_as_override(attributes->as_override);
265 29182 : neighbor->set_private_as_action(attributes->private_as_action);
266 29182 : neighbor->set_loop_count(attributes->loop_count);
267 29182 : if (attributes->admin_down) {
268 108 : neighbor->set_admin_down(true);
269 : }
270 29182 : if (attributes->local_autonomous_system) {
271 184 : neighbor->set_local_as(attributes->local_autonomous_system);
272 : }
273 29182 : if (attributes->hold_time) {
274 312 : neighbor->set_hold_time(attributes->hold_time);
275 : }
276 29182 : BuildFamilyAttributesList(neighbor, attributes);
277 29182 : BuildKeyChain(neighbor, attributes->auth_data);
278 29182 : const autogen::RouteOriginOverride &origin_override =
279 : attributes->route_origin_override;
280 29182 : neighbor->SetOriginOverride(origin_override.origin_override,
281 29182 : origin_override.origin);
282 : }
283 30698 : }
284 :
285 31079 : static BgpNeighborConfig *MakeBgpNeighborConfig(
286 : const BgpIfmapInstanceConfig *instance,
287 : const BgpIfmapInstanceConfig *master_instance,
288 : const string &local_name,
289 : const string &remote_name,
290 : const autogen::BgpRouter *local_router,
291 : const autogen::BgpRouter *remote_router,
292 : const autogen::BgpSession *session) {
293 31079 : BgpNeighborConfig *neighbor = new BgpNeighborConfig();
294 :
295 31079 : neighbor->set_instance_name(instance->name());
296 :
297 : // If the autogen::BgpSession has a uuid, we append it to the remote
298 : // bgp-router's name to make the BgpNeighborConfig's name unique.
299 31079 : if (session && !session->uuid.empty()) {
300 30694 : neighbor->set_uuid(session->uuid);
301 30694 : neighbor->set_name(remote_name + ":" + session->uuid);
302 : } else {
303 385 : neighbor->set_name(remote_name);
304 : }
305 :
306 : // Store a copy of the remote bgp-router's autogen::BgpRouterParams and
307 : // derive the autogen::BgpSessionAttributes for the session.
308 31079 : const autogen::BgpRouterParams ¶ms = remote_router->parameters();
309 31079 : neighbor->set_router_type(params.router_type);
310 31079 : if (params.admin_down) {
311 78 : neighbor->set_admin_down(true);
312 : }
313 31079 : if (params.local_autonomous_system) {
314 4259 : neighbor->set_peer_as(params.local_autonomous_system);
315 : } else {
316 26820 : neighbor->set_peer_as(params.autonomous_system);
317 : }
318 31079 : boost::system::error_code err;
319 31079 : neighbor->set_peer_address(
320 31079 : IpAddress::from_string(params.address, err));
321 31079 : if (err) {
322 12 : BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
323 : "Invalid peer address " << params.address <<
324 : " for neighbor " << neighbor->name());
325 : }
326 :
327 31079 : Ip4Address identifier = Ip4Address::from_string(params.identifier, err);
328 31079 : if (err) {
329 0 : BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
330 : "Invalid peer identifier " << params.identifier <<
331 : " for neighbor " << neighbor->name());
332 : }
333 31079 : neighbor->set_peer_identifier(IpAddressToBgpIdentifier(identifier));
334 :
335 31079 : if (params.router_type == "bgpaas-client") {
336 : IpAddress inet_gw_address =
337 510 : Ip4Address::from_string(params.gateway_address, err);
338 510 : if (!params.gateway_address.empty() && err) {
339 0 : BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
340 : "Invalid gateway address " <<
341 : params.gateway_address <<
342 : " for neighbor " << neighbor->name());
343 : } else {
344 510 : neighbor->set_gateway_address(Address::INET, inet_gw_address);
345 : }
346 :
347 : IpAddress inet6_gw_address =
348 510 : Ip6Address::from_string(params.ipv6_gateway_address, err);
349 510 : if (!params.ipv6_gateway_address.empty() && err) {
350 0 : BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
351 : "Invalid ipv6 gateway address " <<
352 : params.ipv6_gateway_address <<
353 : " for neighbor " << neighbor->name());
354 : } else {
355 510 : neighbor->set_gateway_address(Address::INET6, inet6_gw_address);
356 : }
357 : }
358 :
359 31079 : neighbor->set_port(params.port);
360 31079 : neighbor->set_source_port(params.source_port);
361 31079 : neighbor->set_hold_time(params.hold_time);
362 :
363 31079 : if (session != NULL) {
364 30698 : NeighborSetSessionAttributes(neighbor, local_name, session);
365 : }
366 :
367 : // Get the local identifier and local as from the master protocol config.
368 : const BgpIfmapProtocolConfig *master_protocol =
369 31079 : master_instance->protocol_config();
370 31079 : if (master_protocol && master_protocol->bgp_router()) {
371 : const autogen::BgpRouterParams &master_params =
372 31079 : master_protocol->router_params();
373 31079 : if (master_params.admin_down) {
374 78 : neighbor->set_admin_down(true);
375 : }
376 : Ip4Address localid =
377 31079 : Ip4Address::from_string(master_params.identifier, err);
378 31079 : if (!err) {
379 31066 : neighbor->set_local_identifier(IpAddressToBgpIdentifier(localid));
380 : }
381 31079 : if (!neighbor->local_as()) {
382 30895 : if (master_params.local_autonomous_system) {
383 4267 : neighbor->set_local_as(master_params.local_autonomous_system);
384 : } else {
385 26628 : neighbor->set_local_as(master_params.autonomous_system);
386 : }
387 : }
388 31079 : if (instance != master_instance) {
389 516 : neighbor->set_passive(true);
390 : }
391 : }
392 :
393 : // Get other parameters from the instance protocol config.
394 : // Note that there's no instance protocol config for non-master instances.
395 31079 : const BgpIfmapProtocolConfig *protocol = instance->protocol_config();
396 31079 : if (protocol && protocol->bgp_router()) {
397 : const autogen::BgpRouterParams &protocol_params =
398 30563 : protocol->router_params();
399 30563 : if (neighbor->family_attributes_list().empty()) {
400 2574 : BuildFamilyAttributesList(neighbor,
401 2574 : protocol_params.address_families.family,
402 2574 : params.address_families.family);
403 : }
404 30563 : if (neighbor->auth_data().Empty()) {
405 : const autogen::BgpRouterParams &local_params =
406 30130 : local_router->parameters();
407 30130 : BuildKeyChain(neighbor, local_params.auth_data);
408 : }
409 : }
410 :
411 31079 : if (neighbor->family_attributes_list().empty()) {
412 1009 : BuildFamilyAttributesList(neighbor, default_addr_family_list,
413 1009 : params.address_families.family);
414 : }
415 :
416 31079 : return neighbor;
417 : }
418 :
419 : //
420 : // Build map of BgpNeighborConfigs based on the data in autogen::BgpPeering.
421 : //
422 13693 : void BgpIfmapPeeringConfig::BuildNeighbors(BgpIfmapConfigManager *manager,
423 : const autogen::BgpRouter *local_rt_config,
424 : const string &peername, const autogen::BgpRouter *remote_rt_config,
425 : const autogen::BgpPeering *peering, NeighborMap *map) {
426 : const BgpIfmapInstanceConfig *master_instance =
427 13693 : manager->config()->FindInstance(BgpConfigManager::kMasterInstance);
428 :
429 : // If there are one or more autogen::BgpSessions for the peering, use
430 : // those to create the BgpNeighborConfigs.
431 13693 : const autogen::BgpPeeringAttributes &attr = peering->data();
432 13693 : for (autogen::BgpPeeringAttributes::const_iterator iter = attr.begin();
433 44391 : iter != attr.end(); ++iter) {
434 30698 : BgpNeighborConfig *neighbor = MakeBgpNeighborConfig(
435 30698 : instance_, master_instance, manager->localname(), peername,
436 30698 : local_rt_config, remote_rt_config, iter.operator->());
437 30698 : map->insert(make_pair(neighbor->name(), neighbor));
438 : }
439 :
440 : // When no sessions are present, create a single BgpNeighborConfig with
441 : // no per-session configuration.
442 13693 : if (map->empty()) {
443 1143 : BgpNeighborConfig *neighbor = MakeBgpNeighborConfig(
444 381 : instance_, master_instance, manager->localname(), peername,
445 381 : local_rt_config, remote_rt_config, NULL);
446 381 : map->insert(make_pair(neighbor->name(), neighbor));
447 : }
448 13693 : }
449 :
450 : //
451 : // Update BgpIfmapPeeringConfig based on updated autogen::BgpPeering.
452 : //
453 : // This mainly involves building future BgpNeighborConfigs and doing a diff of
454 : // the current and future BgpNeighborConfigs. Note that BgpIfmapInstanceConfig
455 : // also has references to BgpNeighborConfigs, so it also needs to be updated as
456 : // part of the process.
457 : //
458 15733 : void BgpIfmapPeeringConfig::Update(BgpIfmapConfigManager *manager,
459 : const autogen::BgpPeering *peering) {
460 15733 : IFMapNode *node = node_proxy_.node();
461 15733 : assert(node != NULL);
462 15733 : bgp_peering_.reset(peering);
463 :
464 : // Build the future NeighborMap. The future map should be empty if the
465 : // bgp-peering is deleted or if the parameters for the remote bgp-router
466 : // are not available.
467 15733 : NeighborMap future;
468 15733 : pair<IFMapNode *, IFMapNode *> routers;
469 29434 : if (!node->IsDeleted() &&
470 13701 : GetRouterPair(manager->graph(), manager->localname(), node, &routers)) {
471 : const autogen::BgpRouter *local_rt_config =
472 : static_cast<const autogen::BgpRouter *>(
473 13693 : routers.first->GetObject());
474 : const autogen::BgpRouter *remote_rt_config =
475 : static_cast<const autogen::BgpRouter *>(
476 13693 : routers.second->GetObject());
477 27386 : if (local_rt_config &&
478 13693 : local_rt_config->IsPropertySet(autogen::BgpRouter::PARAMETERS) &&
479 27386 : remote_rt_config &&
480 13693 : remote_rt_config->IsPropertySet(autogen::BgpRouter::PARAMETERS)) {
481 13693 : BuildNeighbors(manager, local_rt_config, routers.second->name(),
482 : remote_rt_config, peering, &future);
483 : }
484 : }
485 :
486 : // Swap out the NeighborMap in preparation for doing a diff.
487 15733 : NeighborMap current;
488 15733 : current.swap(neighbors_);
489 :
490 : // Do a diff on the current and future BgpNeighborConfigs, making sure
491 : // that the BgpIfmapInstanceConfig is updated accordingly. We add any new
492 : // BgpNeighborConfigs to our NeighborMap.
493 15733 : NeighborMap::iterator it1 = current.begin();
494 15733 : NeighborMap::iterator it2 = future.begin();
495 42017 : while (it1 != current.end() && it2 != future.end()) {
496 26284 : if (it1->first < it2->first) {
497 2311 : BgpNeighborConfig *prev = it1->second;
498 2311 : instance_->DeleteNeighbor(manager, prev);
499 2311 : ++it1;
500 23973 : } else if (it1->first > it2->first) {
501 2311 : BgpNeighborConfig *neighbor = it2->second;
502 2311 : instance_->AddNeighbor(manager, neighbor);
503 2311 : neighbors_.insert(*it2);
504 2311 : it2->second = NULL;
505 2311 : ++it2;
506 : } else {
507 21662 : BgpNeighborConfig *neighbor = it1->second;
508 21662 : BgpNeighborConfig *update = it2->second;
509 21662 : if (*neighbor != *update) {
510 764 : instance_->ChangeNeighbor(manager, update);
511 764 : neighbors_.insert(*it2);
512 764 : it2->second = NULL;
513 : } else {
514 20898 : neighbors_.insert(*it1);
515 20898 : it1->second = NULL;
516 : }
517 21662 : ++it1;
518 21662 : ++it2;
519 : }
520 : }
521 20052 : for (; it1 != current.end(); ++it1) {
522 4319 : BgpNeighborConfig *prev = it1->second;
523 4319 : instance_->DeleteNeighbor(manager, prev);
524 : }
525 22839 : for (; it2 != future.end(); ++it2) {
526 7106 : BgpNeighborConfig *neighbor = it2->second;
527 7106 : instance_->AddNeighbor(manager, neighbor);
528 7106 : neighbors_.insert(*it2);
529 7106 : it2->second = NULL;
530 : }
531 :
532 : // Get rid of the current and future NeighborMaps and destroy any mapped
533 : // BgpNeighborConfigs. Note that we have carefully reset mapped values to
534 : // NULL above when we don't want a BgpNeighborConfig to get destroyed.
535 15733 : STLDeleteElements(¤t);
536 15733 : STLDeleteElements(&future);
537 15733 : }
538 :
539 : //
540 : // Delete all state for the given BgpPeeringConfig.
541 : //
542 : // This mainly involves getting rid of BgpNeighborConfigs in the NeighborMap.
543 : //
544 2121 : void BgpIfmapPeeringConfig::Delete(BgpIfmapConfigManager *manager) {
545 2121 : NeighborMap current;
546 2121 : current.swap(neighbors_);
547 2121 : for (NeighborMap::iterator iter = current.begin();
548 2210 : iter != current.end(); ++iter) {
549 89 : instance_->DeleteNeighbor(manager, iter->second);
550 : }
551 2121 : STLDeleteElements(¤t);
552 2121 : bgp_peering_.reset();
553 2121 : }
554 :
555 : //
556 : // Find the IFMapNodes for a bgp-peering.
557 : //
558 : // The "node" is the IFMapNode for the bgp-peering link. The bgp-peering is
559 : // interesting only if one of the bgp-routers is the local node.
560 : //
561 : // Return true if both bgp-routers for the bgp-peering exist and one of them
562 : // is the local one. Also fill in the local and remote IFMapNode pointers if
563 : // we return true.
564 : //
565 19879 : bool BgpIfmapPeeringConfig::GetRouterPair(DBGraph *db_graph,
566 : const string &localname, IFMapNode *node,
567 : pair<IFMapNode *, IFMapNode *> *pair) {
568 19879 : IFMapNode *local = NULL;
569 19879 : IFMapNode *remote = NULL;
570 19879 : string local_router_type;
571 19879 : string remote_router_type;
572 19879 : string local_instance;
573 19879 : string remote_instance;
574 :
575 19879 : for (DBGraphVertex::adjacency_iterator iter = node->begin(db_graph);
576 59637 : iter != node->end(db_graph); ++iter) {
577 39758 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
578 39758 : if (strcmp(adj->table()->Typename(), "bgp-router") != 0)
579 23 : continue;
580 : autogen::BgpRouter *router =
581 39758 : static_cast<autogen::BgpRouter *>(adj->GetObject());
582 39758 : if (!router)
583 23 : continue;
584 39735 : const autogen::BgpRouterParams ¶ms = router->parameters();
585 39735 : string instance_name(IdentifierParent(adj->name()));
586 39735 : string name = adj->name().substr(instance_name.size() + 1);
587 39735 : if (name == localname && params.router_type != "bgpaas-client") {
588 17389 : local = adj;
589 17389 : local_router_type = params.router_type;
590 17389 : local_instance = instance_name;
591 23618 : } else if (instance_name != BgpConfigManager::kMasterInstance &&
592 1272 : params.router_type == "bgpaas-server") {
593 632 : local = adj;
594 632 : local_router_type = params.router_type;
595 632 : local_instance = instance_name;
596 : } else {
597 21714 : remote = adj;
598 21714 : remote_router_type = params.router_type;
599 21714 : remote_instance = instance_name;
600 : }
601 39735 : }
602 :
603 18021 : if ((local == NULL || remote == NULL) || (local_router_type ==
604 18639 : "bgpaas-server" && remote_router_type != "bgpaas-client") ||
605 35383 : (local_router_type != "bgpaas-server" && remote_router_type ==
606 37900 : "bgpaas-client") || (local_instance != remote_instance)) {
607 1874 : BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
608 : "localname: " << localname <<
609 : ((local == NULL) ? " Local node not present" :
610 : " Local node present") <<
611 : ((remote == NULL) ? " Remote node not present" :
612 : " Remote node present") <<
613 : " local_router_type: " << local_router_type <<
614 : " remote_router_type: " << remote_router_type <<
615 : " local instance: " << local_instance <<
616 : " remote instance: " << remote_instance);
617 1874 : return false;
618 : }
619 :
620 18005 : pair->first = local;
621 18005 : pair->second = remote;
622 18005 : return true;
623 19879 : }
624 :
625 : //
626 : // Constructor for BgpIfmapProtocolConfig.
627 : //
628 8596 : BgpIfmapProtocolConfig::BgpIfmapProtocolConfig(BgpIfmapInstanceConfig *instance)
629 8596 : : instance_(instance),
630 8596 : data_(instance->name()) {
631 8596 : }
632 :
633 : //
634 : // Destructor for BgpIfmapProtocolConfig.
635 : //
636 8596 : BgpIfmapProtocolConfig::~BgpIfmapProtocolConfig() {
637 8596 : }
638 :
639 161414 : const autogen::BgpRouterParams &BgpIfmapProtocolConfig::router_params() const {
640 161414 : return bgp_router_->parameters();
641 : }
642 :
643 : //
644 : // Set the IFMapNodeProxy for the BgpIfmapProtocolConfig.
645 : //
646 5900 : void BgpIfmapProtocolConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
647 5900 : if (proxy != NULL) {
648 5900 : node_proxy_.Swap(proxy);
649 : }
650 5900 : }
651 :
652 : //
653 : // Update autogen::BgpRouter object for this BgpIfmapProtocolConfig.
654 : //
655 15702 : void BgpIfmapProtocolConfig::Update(BgpIfmapConfigManager *manager,
656 : const autogen::BgpRouter *router) {
657 15702 : bgp_router_.reset(router);
658 15702 : const autogen::BgpRouterParams ¶ms = router->parameters();
659 15702 : data_.set_admin_down(params.admin_down);
660 15702 : data_.set_cluster_id(params.cluster_id);
661 15702 : data_.set_autonomous_system(params.autonomous_system);
662 15702 : data_.set_local_autonomous_system(params.local_autonomous_system);
663 15702 : data_.set_port(params.port ?: BgpConfigManager::kDefaultPort);
664 15702 : boost::system::error_code err;
665 15702 : IpAddress identifier = IpAddress::from_string(params.identifier, err);
666 15702 : if (!err) {
667 7670 : data_.set_identifier(IpAddressToBgpIdentifier(identifier));
668 : }
669 15702 : data_.set_hold_time(params.hold_time);
670 :
671 : // reset subcluster name and id,
672 : // will be set again if mapping is found in schema
673 15702 : data_.reset_subcluster_name();
674 15702 : data_.reset_subcluster_id();
675 : // get subcluster name this router is associated with
676 15702 : IFMapNode *node = node_proxy_.node();
677 15702 : if (!node)
678 8031 : return;
679 7671 : DBGraph *graph = manager->graph();
680 7671 : for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
681 20889 : iter != node->end(graph); ++iter) {
682 13234 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
683 13234 : if (strcmp(adj->table()->Typename(), "sub-cluster") == 0) {
684 16 : data_.set_subcluster_name(adj->name());
685 : const autogen::SubCluster *sc =
686 16 : static_cast<autogen::SubCluster *>(adj->GetObject());
687 16 : if (sc) {
688 16 : data_.set_subcluster_id(sc->id());
689 : }
690 16 : break;
691 : }
692 : }
693 : }
694 :
695 : //
696 : // Delete autogen::BgpRouter object for this BgpIfmapProtocolConfig.
697 : //
698 1379 : void BgpIfmapProtocolConfig::Delete(BgpIfmapConfigManager *manager) {
699 1379 : manager->Notify(&data_, BgpConfigManager::CFG_DELETE);
700 1379 : bgp_router_.reset();
701 1379 : }
702 :
703 0 : const string &BgpIfmapProtocolConfig::InstanceName() const {
704 0 : return instance_->name();
705 : }
706 :
707 : //
708 : // Constructor for BgpIfmapInstanceConfig.
709 : //
710 50601 : BgpIfmapInstanceConfig::BgpIfmapInstanceConfig(const string &name)
711 50601 : : name_(name),
712 50601 : data_(name),
713 50601 : index_(-1),
714 101202 : protocol_(NULL) {
715 50601 : }
716 :
717 : //
718 : // Destructor for BgpIfmapInstanceConfig.
719 : //
720 50601 : BgpIfmapInstanceConfig::~BgpIfmapInstanceConfig() {
721 50601 : }
722 :
723 : //
724 : // Set the IFMapNodeProxy for the BgpIfmapInstanceConfig.
725 : //
726 48411 : void BgpIfmapInstanceConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
727 48411 : if (proxy != NULL) {
728 48411 : node_proxy_.Swap(proxy);
729 : }
730 48411 : }
731 :
732 : //
733 : // Get the BgpIfmapProtocolConfig for this BgpIfmapInstanceConfig, create
734 : // it if needed.
735 : //
736 8596 : BgpIfmapProtocolConfig *BgpIfmapInstanceConfig::LocateProtocol() {
737 8596 : if (protocol_.get() == NULL) {
738 8596 : protocol_.reset(new BgpIfmapProtocolConfig(this));
739 : }
740 8596 : return protocol_.get();
741 : }
742 :
743 : //
744 : // Delete the BgpIfmapProtocolConfig for this BgpIfmapInstanceConfig.
745 : //
746 1379 : void BgpIfmapInstanceConfig::ResetProtocol() {
747 1379 : protocol_.reset();
748 1379 : }
749 :
750 : //
751 : // Get the route-target for an instance-target. The input IFMapNode is the
752 : // midnode that represents the instance-target link. We traverse the graph
753 : // the graph edges till we find the adjacency to the route-target.
754 : //
755 : // Return true and fill in the target string if we find the route-target.
756 : //
757 551076 : static bool GetInstanceTargetRouteTarget(DBGraph *graph, IFMapNode *node,
758 : string *target) {
759 551076 : for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
760 1102152 : iter != node->end(graph); ++iter) {
761 1102152 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
762 1102152 : if (strcmp(adj->table()->Typename(), "route-target") == 0) {
763 551076 : *target = adj->name();
764 551076 : return true;
765 : }
766 : }
767 0 : return false;
768 : }
769 :
770 : //
771 : // Fill in all the export route targets for a routing-instance. The input
772 : // IFMapNode represents the routing-instance. We traverse the graph edges
773 : // and look for instance-target adjacencies. If the instance-target is an
774 : // export and import target, add it to the vector.
775 : //
776 : // Note that we purposely skip adding export only targets to the vector.
777 : // Reasoning is that export only targets are manually configured by users
778 : // and hence should not be imported based on policy.
779 : //
780 28123 : static void GetRoutingInstanceExportTargets(DBGraph *graph, IFMapNode *node,
781 : vector<string> *target_list) {
782 28123 : for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
783 115069 : iter != node->end(graph); ++iter) {
784 86946 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
785 86946 : string target;
786 115024 : if ((strcmp(adj->table()->Typename(), "instance-target") == 0) &&
787 28078 : (GetInstanceTargetRouteTarget(graph, adj, &target))) {
788 : const autogen::InstanceTarget *itarget =
789 28078 : dynamic_cast<autogen::InstanceTarget *>(adj->GetObject());
790 28078 : if (!itarget)
791 0 : continue;
792 28078 : const autogen::InstanceTargetType &itt = itarget->data();
793 28078 : if (itt.import_export.empty())
794 28074 : target_list->push_back(target);
795 : }
796 86946 : }
797 28123 : }
798 :
799 : //
800 : // Fill in all the export route targets of the routing-instance at the other
801 : // end of a connection. The src_node is the routing-instance from which we
802 : // reached the connection node. The name of the source routing-instance is
803 : // src_instance.
804 : //
805 : // If the connection is unidirectional and the destination-instance for the
806 : // connection is not the routing-instance from which we started, we should
807 : // not get any targets from this connection. This is what a unidirectional
808 : // connection means.
809 : //
810 28127 : static void GetConnectionExportTargets(DBGraph *graph, IFMapNode *src_node,
811 : const string &src_instance, IFMapNode *node,
812 : vector<string> *target_list) {
813 : const autogen::Connection *conn =
814 28127 : dynamic_cast<autogen::Connection *>(node->GetObject());
815 28127 : if (!conn)
816 0 : return;
817 28127 : const autogen::ConnectionType &conn_type = conn->data();
818 28135 : if (!conn_type.destination_instance.empty() &&
819 8 : conn_type.destination_instance != src_instance)
820 4 : return;
821 28123 : for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
822 84369 : iter != node->end(graph); ++iter) {
823 56246 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
824 56246 : if (adj == src_node)
825 28123 : continue;
826 28123 : if (strcmp(adj->table()->Typename(), "routing-instance") != 0)
827 0 : continue;
828 28123 : GetRoutingInstanceExportTargets(graph, adj, target_list);
829 : }
830 : }
831 :
832 : //
833 : // Fill in all the routing-policies for a routing-instance. The input
834 : // IFMapNode represents the routing-policy-routing-instance. We traverse to
835 : // graph edges and look for routing-policy adjacency
836 : //
837 530 : static bool GetRoutingInstanceRoutingPolicy(DBGraph *graph, IFMapNode *node,
838 : RoutingPolicyAttachInfo *ri_rp_link) {
839 530 : string sequence;
840 : const autogen::RoutingPolicyRoutingInstance *policy =
841 530 : static_cast<autogen::RoutingPolicyRoutingInstance *>(node->GetObject());
842 530 : const autogen::RoutingPolicyType &attach_info = policy->data();
843 :
844 530 : ri_rp_link->sequence_ = attach_info.sequence;
845 :
846 530 : for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
847 1060 : iter != node->end(graph); ++iter) {
848 1060 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
849 1060 : if (strcmp(adj->table()->Typename(), "routing-policy") == 0) {
850 530 : ri_rp_link->routing_policy_ = adj->name();
851 530 : return true;
852 : }
853 : }
854 0 : return false;
855 530 : }
856 :
857 : //
858 : // Fill in all the route-aggregation for a routing-instance.
859 : //
860 726 : static bool GetRouteAggregateConfig(DBGraph *graph, IFMapNode *node,
861 : BgpInstanceConfig::AggregateRouteList *inet_list,
862 : BgpInstanceConfig::AggregateRouteList *inet6_list) {
863 : const autogen::RouteAggregate *ra =
864 726 : static_cast<autogen::RouteAggregate *>(node->GetObject());
865 726 : if (ra == NULL) return false;
866 :
867 726 : boost::system::error_code ec;
868 : IpAddress nexthop =
869 726 : IpAddress::from_string(ra->aggregate_route_nexthop(), ec);
870 726 : if (ec.failed()) return false;
871 :
872 2464 : BOOST_FOREACH(const string &route, ra->aggregate_route_entries()) {
873 869 : AggregateRouteConfig aggregate;
874 869 : aggregate.nexthop = nexthop;
875 :
876 869 : Ip4Address address;
877 869 : ec = Ip4SubnetParse(route, &address, &aggregate.prefix_length);
878 869 : if (!ec) {
879 842 : if (!nexthop.is_v4()) continue;
880 836 : aggregate.aggregate = address;
881 836 : inet_list->push_back(aggregate);
882 : } else {
883 30 : if (!nexthop.is_v6()) continue;
884 27 : Ip6Address address;
885 27 : ec = Inet6SubnetParse(route, &address, &aggregate.prefix_length);
886 27 : if (ec.failed()) continue;
887 27 : aggregate.aggregate = address;
888 27 : inet6_list->push_back(aggregate);
889 : }
890 : }
891 :
892 726 : return true;
893 : }
894 :
895 : //
896 : // Get the network id for a virtual-network. The input IFMapNode represents
897 : // the virtual-network.
898 : //
899 74292 : static int GetVirtualNetworkIndex(DBGraph *graph, IFMapNode *node) {
900 : const autogen::VirtualNetwork *vn =
901 74292 : static_cast<autogen::VirtualNetwork *>(node->GetObject());
902 74292 : if (vn && vn->IsPropertySet(autogen::VirtualNetwork::NETWORK_ID))
903 118 : return vn->network_id();
904 74174 : if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PROPERTIES))
905 74107 : return vn->properties().network_id;
906 67 : return 0;
907 : }
908 :
909 : //
910 : // Check if a virtual-network allows transit. The input IFMapNode represents
911 : // the virtual-network.
912 : //
913 74292 : static bool GetVirtualNetworkAllowTransit(DBGraph *graph, IFMapNode *node) {
914 : const autogen::VirtualNetwork *vn =
915 74292 : static_cast<autogen::VirtualNetwork *>(node->GetObject());
916 74292 : if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PROPERTIES))
917 74139 : return vn->properties().allow_transit;
918 153 : return false;
919 : }
920 :
921 :
922 : //
923 : // Check if a virtual-network has pbb-evpn enabled.
924 : // The input IFMapNode represents the virtual-network.
925 : //
926 74292 : static bool GetVirtualNetworkPbbEvpnEnable(DBGraph *graph, IFMapNode *node) {
927 : const autogen::VirtualNetwork *vn =
928 74292 : static_cast<autogen::VirtualNetwork *>(node->GetObject());
929 74292 : if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PBB_EVPN_ENABLE))
930 15238 : return vn->pbb_evpn_enable();
931 59054 : return false;
932 : }
933 :
934 :
935 : //
936 : // Get the vxlan id for a virtual-network. The input IFMapNode represents
937 : // the virtual-network.
938 : //
939 : // The vxlan_network_identifier is 0 when automatic mode is in use. In that
940 : // case, the network_id is used as vxlan id.
941 : //
942 74292 : static int GetVirtualNetworkVxlanId(DBGraph *graph, IFMapNode *node) {
943 : const autogen::VirtualNetwork *vn =
944 74292 : static_cast<autogen::VirtualNetwork *>(node->GetObject());
945 74292 : if (vn && vn->IsPropertySet(autogen::VirtualNetwork::PROPERTIES)) {
946 74139 : if (vn->properties().vxlan_network_identifier) {
947 0 : return vn->properties().vxlan_network_identifier;
948 : } else {
949 74139 : return vn->properties().network_id;
950 : }
951 : }
952 153 : return 0;
953 : }
954 :
955 4221 : static void SetStaticRouteConfig(BgpInstanceConfig *rti,
956 : const autogen::RoutingInstance *config) {
957 4221 : BgpInstanceConfig::StaticRouteList inet_list;
958 4221 : BgpInstanceConfig::StaticRouteList inet6_list;
959 4973 : BOOST_FOREACH(const autogen::StaticRouteType &route,
960 : config->static_route_entries()) {
961 376 : boost::system::error_code ec;
962 376 : StaticRouteConfig item;
963 376 : item.nexthop = IpAddress::from_string(route.next_hop, ec);
964 376 : if (ec.failed())
965 4 : continue;
966 :
967 372 : item.route_targets = route.route_target;
968 372 : item.communities = route.community;
969 372 : if (item.nexthop.is_v4()) {
970 291 : Ip4Address address;
971 291 : ec = Ip4SubnetParse(route.prefix, &address, &item.prefix_length);
972 291 : if (ec.failed())
973 3 : continue;
974 288 : item.address = address;
975 : std::pair<BgpInstanceConfig::StaticRouteList::iterator, bool> ret =
976 288 : inet_list.insert(item);
977 288 : if (!ret.second) {
978 0 : BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
979 : "Duplicate static route prefix " << route.prefix <<
980 : " with nexthop " << route.next_hop <<
981 : " for routing instance " << rti->name());
982 : }
983 : } else {
984 81 : Ip6Address address;
985 81 : ec = Inet6SubnetParse(route.prefix, &address, &item.prefix_length);
986 81 : if (ec.failed())
987 3 : continue;
988 78 : item.address = address;
989 : std::pair<BgpInstanceConfig::StaticRouteList::iterator, bool> ret =
990 78 : inet6_list.insert(item);
991 78 : if (!ret.second) {
992 0 : BGP_LOG_WARNING_STR(BgpConfig, BGP_LOG_FLAG_ALL,
993 : "Duplicate static route prefix " << route.prefix <<
994 : " with nexthop " << route.next_hop <<
995 : " for routing instance " << rti->name());
996 : }
997 : }
998 376 : }
999 4221 : rti->swap_static_routes(Address::INET, &inet_list);
1000 4221 : rti->swap_static_routes(Address::INET6, &inet6_list);
1001 4221 : }
1002 :
1003 4221 : static void SetServiceChainConfig(BgpInstanceConfig *rti,
1004 : const autogen::RoutingInstance *config) {
1005 4221 : BgpInstanceConfig::ServiceChainList list;
1006 : const autogen::ServiceChainInfo &inet_chain =
1007 4221 : config->service_chain_information();
1008 4221 : if (config->IsPropertySet(
1009 : autogen::RoutingInstance::SERVICE_CHAIN_INFORMATION)) {
1010 1178 : ServiceChainConfig item = {
1011 : SCAddress::INET,
1012 1178 : inet_chain.routing_instance,
1013 1178 : inet_chain.prefix,
1014 1178 : inet_chain.service_chain_address,
1015 1178 : inet_chain.service_instance,
1016 1178 : inet_chain.source_routing_instance,
1017 1178 : inet_chain.service_chain_id,
1018 1178 : inet_chain.sc_head,
1019 1178 : inet_chain.retain_as_path,
1020 1178 : };
1021 1178 : list.push_back(item);
1022 1178 : }
1023 :
1024 : const autogen::ServiceChainInfo &inet6_chain =
1025 4221 : config->ipv6_service_chain_information();
1026 4221 : if (config->IsPropertySet(
1027 : autogen::RoutingInstance::IPV6_SERVICE_CHAIN_INFORMATION)) {
1028 1048 : ServiceChainConfig item = {
1029 : SCAddress::INET6,
1030 1048 : inet6_chain.routing_instance,
1031 1048 : inet6_chain.prefix,
1032 1048 : inet6_chain.service_chain_address,
1033 1048 : inet6_chain.service_instance,
1034 1048 : inet6_chain.source_routing_instance,
1035 1048 : inet6_chain.service_chain_id,
1036 1048 : inet6_chain.sc_head,
1037 1048 : inet6_chain.retain_as_path,
1038 1048 : };
1039 1048 : list.push_back(item);
1040 1048 : }
1041 :
1042 : const autogen::ServiceChainInfo &evpn_chain =
1043 4221 : config->evpn_service_chain_information();
1044 4221 : if (config->IsPropertySet(
1045 : autogen::RoutingInstance::EVPN_SERVICE_CHAIN_INFORMATION)) {
1046 718 : ServiceChainConfig item = {
1047 : SCAddress::EVPN,
1048 718 : evpn_chain.routing_instance,
1049 718 : evpn_chain.prefix,
1050 718 : evpn_chain.service_chain_address,
1051 718 : evpn_chain.service_instance,
1052 718 : evpn_chain.source_routing_instance,
1053 718 : evpn_chain.service_chain_id,
1054 718 : evpn_chain.sc_head,
1055 718 : evpn_chain.retain_as_path,
1056 718 : };
1057 718 : list.push_back(item);
1058 718 : }
1059 :
1060 : const autogen::ServiceChainInfo &evpnv6_chain =
1061 4221 : config->evpn_ipv6_service_chain_information();
1062 4221 : if (config->IsPropertySet(
1063 : autogen::RoutingInstance::EVPN_IPV6_SERVICE_CHAIN_INFORMATION)) {
1064 720 : ServiceChainConfig item = {
1065 : SCAddress::EVPN6,
1066 720 : evpnv6_chain.routing_instance,
1067 720 : evpnv6_chain.prefix,
1068 720 : evpnv6_chain.service_chain_address,
1069 720 : evpnv6_chain.service_instance,
1070 720 : evpnv6_chain.source_routing_instance,
1071 720 : evpnv6_chain.service_chain_id,
1072 720 : evpnv6_chain.sc_head,
1073 720 : evpnv6_chain.retain_as_path,
1074 720 : };
1075 720 : list.push_back(item);
1076 720 : }
1077 :
1078 4221 : rti->swap_service_chain_list(&list);
1079 4221 : }
1080 :
1081 : // Get name of vxlan RI for bridge RI
1082 :
1083 17 : static string GetConnectedVxlanRiVn(DBGraph *graph, IFMapNode *node) {
1084 : const autogen::VirtualNetwork *vn_vxlan =
1085 17 : static_cast<autogen::VirtualNetwork *>(node->GetObject());
1086 17 : if (!vn_vxlan)
1087 0 : return "";
1088 17 : for (DBGraphVertex::adjacency_iterator iter_ri = node->begin(graph);
1089 136 : iter_ri != node->end(graph); ++iter_ri) {
1090 136 : IFMapNode *adj_ri = static_cast<IFMapNode *>(iter_ri.operator->());
1091 136 : if (strcmp(adj_ri->table()->Typename(), "routing-instance") == 0) {
1092 : const autogen::RoutingInstance *iri =
1093 17 : dynamic_cast<autogen::RoutingInstance *>(adj_ri->GetObject());
1094 17 : if (!iri)
1095 0 : continue;
1096 34 : return adj_ri->name();
1097 : }
1098 : }
1099 0 : return "";
1100 : }
1101 :
1102 17 : static string GetConnectedVxlanRiLr(DBGraph *graph, IFMapNode *node) {
1103 17 : std::string ri_name = "";
1104 17 : for (DBGraphVertex::adjacency_iterator iter_lr = node->begin(graph);
1105 102 : iter_lr != node->end(graph); ++iter_lr) {
1106 102 : IFMapNode *adj_lr = static_cast<IFMapNode *>(iter_lr.operator->());
1107 102 : if (strcmp(adj_lr->table()->Typename(),
1108 102 : "logical-router-virtual-network") == 0) {
1109 17 : for (DBGraphVertex::adjacency_iterator iter_vn = adj_lr->begin(graph);
1110 34 : iter_vn != adj_lr->end(graph); ++iter_vn) {
1111 34 : IFMapNode *adj_vn = static_cast<IFMapNode *>(iter_vn.operator->());
1112 34 : if (strcmp(adj_vn->table()->Typename(), "virtual-network") == 0) {
1113 17 : ri_name = GetConnectedVxlanRiVn(graph, adj_vn);
1114 17 : if (ri_name != "") {
1115 17 : return ri_name;
1116 : }
1117 : }
1118 : }
1119 : }
1120 : }
1121 0 : return "";
1122 17 : }
1123 :
1124 :
1125 74292 : static string GetConnectedVxlanRi(DBGraph *graph, IFMapNode *node) {
1126 74292 : std::string ri_name = "";
1127 : const autogen::VirtualNetwork *vn =
1128 74292 : static_cast<autogen::VirtualNetwork *>(node->GetObject());
1129 74292 : if (!vn) {
1130 66 : return "";
1131 : }
1132 74226 : for (DBGraphVertex::adjacency_iterator iter_vmi = node->begin(graph);
1133 162557 : iter_vmi != node->end(graph); ++iter_vmi) {
1134 88348 : IFMapNode *adj_vmi = static_cast<IFMapNode *>(iter_vmi.operator->());
1135 88348 : if (strcmp(adj_vmi->table()->Typename(),
1136 88348 : "virtual-machine-interface") == 0) {
1137 143 : for (DBGraphVertex::adjacency_iterator iter_lr = adj_vmi->begin(graph);
1138 958 : iter_lr != adj_vmi->end(graph); ++iter_lr) {
1139 832 : IFMapNode *adj_lr = static_cast<IFMapNode *>(iter_lr.operator->());
1140 832 : if (strcmp(adj_lr->table()->Typename(), "logical-router") == 0) {
1141 17 : ri_name = GetConnectedVxlanRiLr(graph, adj_lr);
1142 17 : if (ri_name != "") {
1143 17 : return ri_name;
1144 : }
1145 : }
1146 : }
1147 : }
1148 : }
1149 74209 : return "";
1150 74292 : }
1151 :
1152 :
1153 236 : void BgpIfmapConfigManager::ProcessRoutingPolicyLink(
1154 : const BgpConfigDelta &delta) {
1155 236 : CHECK_CONCURRENCY("bgp::Config");
1156 :
1157 : BgpIfmapRoutingPolicyLinkConfig *ri_rp_link
1158 236 : = config_->FindRoutingPolicyLink(delta.id_name);
1159 236 : if (ri_rp_link == NULL) {
1160 165 : IFMapNodeProxy *proxy = delta.node.get();
1161 165 : if (proxy == NULL) {
1162 0 : return;
1163 : }
1164 165 : IFMapNode *node = proxy->node();
1165 165 : if (node == NULL || delta.obj.get() == NULL) {
1166 0 : return;
1167 : }
1168 :
1169 165 : pair<IFMapNode *, IFMapNode *> ri_rp_pair;
1170 165 : if (!BgpIfmapRoutingPolicyLinkConfig::GetInstancePolicyPair(db_graph_,
1171 : node, &ri_rp_pair)) {
1172 0 : return;
1173 : }
1174 :
1175 165 : string instance_name = ri_rp_pair.first->name();
1176 165 : string policy_name = ri_rp_pair.second->name();
1177 :
1178 : BgpIfmapInstanceConfig *rti =
1179 165 : config_->FindInstance(instance_name);
1180 : BgpIfmapRoutingPolicyConfig *rtp =
1181 165 : config_->FindRoutingPolicy(policy_name);
1182 165 : if (!rti || !rtp) {
1183 0 : return;
1184 : }
1185 :
1186 165 : ri_rp_link = config_->CreateRoutingPolicyLink(rti, rtp, proxy);
1187 165 : } else {
1188 71 : const IFMapNode *node = ri_rp_link->node();
1189 71 : assert(node != NULL);
1190 71 : if (delta.obj.get() == NULL) {
1191 46 : BgpIfmapRoutingPolicyConfig *rtp = ri_rp_link->policy();
1192 46 : BgpIfmapInstanceConfig *rti = ri_rp_link->instance();
1193 46 : config_->DeleteRoutingPolicyLink(ri_rp_link);
1194 46 : if (rtp->DeleteIfEmpty(this)) {
1195 38 : config_->DeleteRoutingPolicy(rtp);
1196 : }
1197 46 : if (rti->DeleteIfEmpty(this)) {
1198 1 : BGP_CONFIG_LOG_INSTANCE(Delete, server(), rti,
1199 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
1200 1 : config_->DeleteInstance(rti);
1201 : }
1202 46 : return;
1203 : }
1204 : }
1205 :
1206 : autogen::RoutingPolicyRoutingInstance *ri_rp_link_cfg =
1207 190 : static_cast<autogen::RoutingPolicyRoutingInstance *>(delta.obj.get());
1208 :
1209 190 : ri_rp_link->Update(this, ri_rp_link_cfg);
1210 : }
1211 :
1212 151 : static bool CompareRoutingPolicyOrder(const RoutingPolicyAttachInfo &lhs,
1213 : const RoutingPolicyAttachInfo &rhs) {
1214 151 : return (lhs.sequence_ < rhs.sequence_);
1215 : }
1216 :
1217 18180 : void BgpIfmapInstanceConfig::ProcessIdentifierUpdate(uint32_t new_id,
1218 : uint32_t old_id) {
1219 18180 : BgpInstanceConfig::RouteTargetList import_list = data_.import_list();
1220 18180 : if (old_id > 0) {
1221 183 : string old_vit = "target:" + GetVitFromId(ntohl(old_id));
1222 183 : import_list.erase(old_vit);
1223 183 : }
1224 18180 : if (new_id > 0) {
1225 18180 : string new_vit = "target:" + GetVitFromId(ntohl(new_id));
1226 18180 : import_list.insert(new_vit);
1227 18180 : }
1228 18180 : data_.set_import_list(import_list);
1229 18180 : }
1230 :
1231 12268 : void BgpIfmapInstanceConfig::ProcessASUpdate(uint32_t new_as, uint32_t old_as) {
1232 12268 : BgpInstanceConfig::RouteTargetList import_list = data_.import_list();
1233 12268 : if (old_as > 0) {
1234 11519 : string old_es_rtarget = "target:" + GetESRouteTarget(old_as);
1235 11519 : import_list.erase(old_es_rtarget);
1236 11519 : }
1237 12268 : if (new_as > 0) {
1238 12267 : string new_es_rtarget = "target:" + GetESRouteTarget(new_as);
1239 12267 : import_list.insert(new_es_rtarget);
1240 12267 : }
1241 12268 : data_.set_import_list(import_list);
1242 12268 : }
1243 :
1244 97058 : string BgpIfmapInstanceConfig::GetVitFromId(uint32_t identifier) const {
1245 97058 : if (identifier == 0)
1246 0 : return "";
1247 194116 : return Ip4Address(identifier).to_string() + ":" + integerToString(index());
1248 : }
1249 :
1250 147667 : string BgpIfmapInstanceConfig::GetESRouteTarget(uint32_t as) const {
1251 147667 : if (as == 0)
1252 0 : return "";
1253 147667 : if (as > 0xffFF)
1254 80 : return integerToString(as) + ":" +
1255 120 : integerToString(EVPN_ES_IMPORT_ROUTE_TARGET_AS4);
1256 295254 : return integerToString(as) + ":" +
1257 442881 : integerToString(EVPN_ES_IMPORT_ROUTE_TARGET_AS2);
1258 : }
1259 :
1260 : // Populate vrf import route-target (used for MVPN) and ES route target in
1261 : // import list.
1262 124446 : void BgpIfmapInstanceConfig::InsertVitAndESRTargetInImportList(
1263 : BgpIfmapConfigManager *mgr,
1264 : BgpInstanceConfig::RouteTargetList& import_list) {
1265 : const BgpIfmapInstanceConfig *master_instance =
1266 124446 : mgr->config()->FindInstance(BgpConfigManager::kMasterInstance);
1267 124446 : uint32_t bgp_identifier = 0;
1268 124446 : uint32_t as = 0;
1269 124446 : if (master_instance) {
1270 : const BgpIfmapProtocolConfig *master_protocol =
1271 124446 : master_instance->protocol_config();
1272 124446 : if (master_protocol) {
1273 123881 : if (master_protocol->protocol_config()) {
1274 : bgp_identifier =
1275 123881 : master_protocol->protocol_config()->identifier();
1276 123881 : as = master_protocol->protocol_config()->autonomous_system();
1277 : }
1278 : }
1279 : }
1280 124446 : if (bgp_identifier > 0)
1281 78695 : import_list.insert("target:" + GetVitFromId(ntohl(bgp_identifier)));
1282 124446 : if (as > 0)
1283 123881 : import_list.insert("target:" + GetESRouteTarget(as));
1284 124446 : }
1285 :
1286 : //
1287 : // Update BgpIfmapInstanceConfig based on a new autogen::RoutingInstance object.
1288 : //
1289 : // Rebuild the import and export route target lists and update the virtual
1290 : // network information.
1291 : //
1292 : // Targets that are configured on this routing-instance (which corresponds
1293 : // to all adjacencies to instance-target) are added to the import list or
1294 : // export list or both depending on the import_export attribute.
1295 : //
1296 : // Export targets for all other routing-instances that we are connected to
1297 : // are added to our import list.
1298 : //
1299 124446 : void BgpIfmapInstanceConfig::Update(BgpIfmapConfigManager *manager,
1300 : const autogen::RoutingInstance *config) {
1301 124446 : BgpInstanceConfig::RouteTargetList import_list, export_list;
1302 124446 : BgpInstanceConfig::AggregateRouteList inet6_aggregate_list;
1303 124446 : BgpInstanceConfig::AggregateRouteList inet_aggregate_list;
1304 124446 : RoutingPolicyConfigList policy_list;
1305 124446 : data_.Clear();
1306 :
1307 124446 : DBGraph *graph = manager->graph();
1308 124446 : IFMapNode *node = node_proxy_.node();
1309 124446 : for (DBGraphVertex::adjacency_iterator iter = node->begin(graph);
1310 762560 : iter != node->end(graph); ++iter) {
1311 638114 : IFMapNode *adj = static_cast<IFMapNode *>(iter.operator->());
1312 638114 : if (strcmp(adj->table()->Typename(), "instance-target") == 0) {
1313 522998 : string target;
1314 522998 : if (GetInstanceTargetRouteTarget(graph, adj, &target)) {
1315 : const autogen::InstanceTarget *itarget =
1316 522998 : dynamic_cast<autogen::InstanceTarget *>(adj->GetObject());
1317 522998 : if (!itarget)
1318 0 : continue;
1319 522998 : const autogen::InstanceTargetType &itt = itarget->data();
1320 522998 : if (itt.import_export == "import") {
1321 10857 : import_list.insert(target);
1322 512141 : } else if (itt.import_export == "export") {
1323 889 : export_list.insert(target);
1324 : } else {
1325 511252 : import_list.insert(target);
1326 511252 : export_list.insert(target);
1327 : }
1328 : }
1329 638114 : } else if (strcmp(adj->table()->Typename(),
1330 115116 : "routing-policy-routing-instance") == 0) {
1331 530 : RoutingPolicyAttachInfo policy_info;
1332 530 : if (GetRoutingInstanceRoutingPolicy(graph, adj, &policy_info)) {
1333 530 : policy_list.push_back(policy_info);
1334 : }
1335 115116 : } else if (strcmp(adj->table()->Typename(), "route-aggregate") == 0) {
1336 726 : GetRouteAggregateConfig(graph, adj, &inet_aggregate_list,
1337 : &inet6_aggregate_list);
1338 113860 : } else if (strcmp(adj->table()->Typename(), "connection") == 0) {
1339 28127 : vector<string> target_list;
1340 28127 : GetConnectionExportTargets(graph, node, name_, adj, &target_list);
1341 84275 : BOOST_FOREACH(string target, target_list) {
1342 28074 : import_list.insert(target);
1343 28074 : }
1344 113860 : } else if (strcmp(adj->table()->Typename(), "virtual-network") == 0) {
1345 74292 : data_.set_virtual_network(adj->name());
1346 74292 : data_.set_virtual_network_index(GetVirtualNetworkIndex(graph, adj));
1347 148584 : data_.set_virtual_network_allow_transit(
1348 74292 : GetVirtualNetworkAllowTransit(graph, adj));
1349 74292 : data_.set_vxlan_id(GetVirtualNetworkVxlanId(graph, adj));
1350 148584 : data_.set_virtual_network_pbb_evpn_enable(
1351 74292 : GetVirtualNetworkPbbEvpnEnable(graph, adj));
1352 74292 : data_.set_routing_instance_vxlan(GetConnectedVxlanRi(graph, adj));
1353 : }
1354 : }
1355 :
1356 124446 : InsertVitAndESRTargetInImportList(manager, import_list);
1357 124446 : data_.set_import_list(import_list);
1358 124446 : data_.set_export_list(export_list);
1359 :
1360 124446 : sort(policy_list.begin(), policy_list.end(), CompareRoutingPolicyOrder);
1361 124446 : data_.swap_routing_policy_list(&policy_list);
1362 124446 : data_.swap_aggregate_routes(Address::INET, &inet_aggregate_list);
1363 124446 : data_.swap_aggregate_routes(Address::INET6, &inet6_aggregate_list);
1364 :
1365 124446 : if (config) {
1366 4221 : data_.set_has_pnf(config->has_pnf());
1367 4221 : SetStaticRouteConfig(&data_, config);
1368 4221 : SetServiceChainConfig(&data_, config);
1369 : }
1370 124446 : }
1371 :
1372 : //
1373 : // Reset IFMap related state in the BgpIfmapInstanceConfig.
1374 : //
1375 11643 : void BgpIfmapInstanceConfig::ResetConfig() {
1376 11643 : node_proxy_.Clear();
1377 11643 : }
1378 :
1379 : //
1380 : // Return true if the BgpIfmapInstanceConfig is ready to be deleted. The
1381 : // caller is responsible for actually deleting it.
1382 : //
1383 15189 : bool BgpIfmapInstanceConfig::DeleteIfEmpty(BgpConfigManager *manager) {
1384 15189 : if (name_ == BgpConfigManager::kMasterInstance) {
1385 4770 : return false;
1386 : }
1387 10419 : if (node() != NULL || protocol_.get() != NULL) {
1388 52 : return false;
1389 : }
1390 20691 : if (!neighbors_.empty() || !peerings_.empty() ||
1391 10324 : !routing_policies_.empty()) {
1392 44 : return false;
1393 : }
1394 :
1395 10323 : manager->Notify(&data_, BgpConfigManager::CFG_DELETE);
1396 10323 : return true;
1397 : }
1398 :
1399 : //
1400 : // Add a BgpNeighborConfig to this BgpIfmapInstanceConfig.
1401 : //
1402 : // The BgpNeighborConfig is added to the NeighborMap and the BgpConfigManager
1403 : // is notified.
1404 : //
1405 9417 : void BgpIfmapInstanceConfig::AddNeighbor(BgpConfigManager *manager,
1406 : BgpNeighborConfig *neighbor) {
1407 9417 : BGP_CONFIG_LOG_NEIGHBOR(
1408 : Create, manager->server(), neighbor, SandeshLevel::SYS_DEBUG,
1409 : BGP_LOG_FLAG_ALL,
1410 : neighbor->admin_down(),
1411 : neighbor->passive(),
1412 : BgpIdentifierToString(neighbor->local_identifier()),
1413 : neighbor->local_as(),
1414 : neighbor->peer_address().to_string(), neighbor->peer_as(),
1415 : neighbor->GetAddressFamilies(), neighbor->AuthKeyTypeToString(),
1416 : neighbor->AuthKeysToString());
1417 9417 : neighbors_.insert(make_pair(neighbor->name(), neighbor));
1418 9417 : data_.add_neighbor(neighbor->name());
1419 9417 : manager->Notify(neighbor, BgpConfigManager::CFG_ADD);
1420 9417 : }
1421 :
1422 : //
1423 : // Change a BgpNeighborConfig that's already in this BgpIfmapInstanceConfig.
1424 : //
1425 764 : void BgpIfmapInstanceConfig::ChangeNeighbor(BgpConfigManager *manager,
1426 : BgpNeighborConfig *neighbor) {
1427 764 : NeighborMap::iterator loc = neighbors_.find(neighbor->name());
1428 764 : assert(loc != neighbors_.end());
1429 764 : loc->second = neighbor;
1430 :
1431 764 : BGP_CONFIG_LOG_NEIGHBOR(
1432 : Update, manager->server(), neighbor,
1433 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
1434 : neighbor->admin_down(),
1435 : neighbor->passive(),
1436 : BgpIdentifierToString(neighbor->local_identifier()),
1437 : neighbor->local_as(),
1438 : neighbor->peer_address().to_string(), neighbor->peer_as(),
1439 : neighbor->GetAddressFamilies(), neighbor->AuthKeyTypeToString(),
1440 : neighbor->AuthKeysToString());
1441 764 : manager->Notify(neighbor, BgpConfigManager::CFG_CHANGE);
1442 764 : }
1443 :
1444 : //
1445 : // Delete a BgpNeighborConfig from this BgpIfmapInstanceConfig.
1446 : //
1447 : // The BgpConfigManager is notified and BgpNeighborConfig is removed from the
1448 : // NeighborMap. Note that the caller is responsible for actually deleting the
1449 : // BgpNeighborConfig object.
1450 : //
1451 6719 : void BgpIfmapInstanceConfig::DeleteNeighbor(BgpConfigManager *manager,
1452 : BgpNeighborConfig *neighbor) {
1453 6719 : BGP_CONFIG_LOG_NEIGHBOR(Delete, manager->server(), neighbor,
1454 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
1455 6719 : manager->Notify(neighbor, BgpConfigManager::CFG_DELETE);
1456 6719 : neighbors_.erase(neighbor->name());
1457 6719 : data_.delete_neighbor(neighbor->name());
1458 6719 : }
1459 :
1460 : //
1461 : // Find the BgpNeighborConfig by name in this BgpIfmapInstanceConfig.
1462 : //
1463 6802 : const BgpNeighborConfig *BgpIfmapInstanceConfig::FindNeighbor(
1464 : const string &name) const {
1465 6802 : NeighborMap::const_iterator loc;
1466 :
1467 6802 : if (name.find(name_) == string::npos) {
1468 7 : string fqn(name_);
1469 7 : fqn += ":";
1470 7 : fqn += name;
1471 7 : loc = neighbors_.find(fqn);
1472 7 : } else {
1473 6795 : loc = neighbors_.find(name);
1474 : }
1475 :
1476 6802 : return loc != neighbors_.end() ? loc->second : NULL;
1477 : }
1478 :
1479 : //
1480 : // Add a BgpPeeringConfig to this BgpIfmapInstanceConfig.
1481 : //
1482 4312 : void BgpIfmapInstanceConfig::AddPeering(BgpIfmapPeeringConfig *peering) {
1483 4312 : peerings_.insert(make_pair(peering->name(), peering));
1484 4312 : }
1485 :
1486 : //
1487 : // Delete a BgpPeeringConfig from this BgpIfmapInstanceConfig.
1488 : //
1489 2121 : void BgpIfmapInstanceConfig::DeletePeering(BgpIfmapPeeringConfig *peering) {
1490 2121 : peerings_.erase(peering->name());
1491 2121 : }
1492 :
1493 : //
1494 : // Add a BgpIfmapRoutingPolicyConfig to this BgpIfmapInstanceConfig.
1495 : //
1496 165 : void BgpIfmapInstanceConfig::AddRoutingPolicy(
1497 : BgpIfmapRoutingPolicyConfig *rtp) {
1498 165 : routing_policies_.insert(make_pair(rtp->name(), rtp));
1499 165 : }
1500 :
1501 : //
1502 : // Delete a BgpIfmapRoutingPolicyConfig from this BgpIfmapInstanceConfig.
1503 : //
1504 46 : void BgpIfmapInstanceConfig::DeleteRoutingPolicy(
1505 : BgpIfmapRoutingPolicyConfig *rtp) {
1506 46 : routing_policies_.erase(rtp->name());
1507 46 : }
1508 :
1509 6023 : void BgpIfmapConfigData::ProcessIdentifierAndASUpdate(
1510 : BgpIfmapConfigManager* manager,
1511 : uint32_t new_id, uint32_t old_id,
1512 : uint32_t new_as, uint32_t old_as) {
1513 6023 : assert(new_id != old_id || new_as != old_as);
1514 24306 : for (unsigned int i = 0; i < instances_.size(); i++) {
1515 18283 : BgpIfmapInstanceConfig * ifmap_config = instances_.At(i);
1516 18283 : if (!ifmap_config)
1517 0 : continue;
1518 18283 : if (new_id != old_id)
1519 18180 : ifmap_config->ProcessIdentifierUpdate(new_id, old_id);
1520 18283 : if (new_as != old_as)
1521 12268 : ifmap_config->ProcessASUpdate(new_as, old_as);
1522 18283 : manager->UpdateInstanceConfig(ifmap_config,
1523 : BgpConfigManager::CFG_CHANGE);
1524 : }
1525 6023 : }
1526 :
1527 : //
1528 : // Constructor for BgpIfmapConfigData.
1529 : //
1530 8049 : BgpIfmapConfigData::BgpIfmapConfigData() {
1531 : // Reserve bit 0 for master instance
1532 8049 : instances_.ReserveBit(0);
1533 8049 : }
1534 :
1535 : //
1536 : // Destructor for BgpConfigData.
1537 : //
1538 8049 : BgpIfmapConfigData::~BgpIfmapConfigData() {
1539 8049 : instances_.clear();
1540 8049 : STLDeleteElements(&peerings_);
1541 8049 : STLDeleteElements(&routing_policies_);
1542 8049 : STLDeleteElements(&ri_rp_links_);
1543 8049 : }
1544 :
1545 : //
1546 : // Locate the BgpIfmapInstanceConfig by name, create it if not found. The newly
1547 : // created BgpIfmapInstanceConfig gets added to the IfmapInstanceMap.
1548 : //
1549 : // Note that we do not have the IFMapNode representing the routing-instance
1550 : // at this point.
1551 : //
1552 50601 : BgpIfmapInstanceConfig *BgpIfmapConfigData::LocateInstance(const string &name) {
1553 50601 : BgpIfmapInstanceConfig *rti = FindInstance(name);
1554 50601 : if (rti != NULL) {
1555 0 : return rti;
1556 : }
1557 50601 : rti = new BgpIfmapInstanceConfig(name);
1558 50601 : int index = -1;
1559 50601 : if (name == BgpConfigManager::kMasterInstance) {
1560 8031 : index = 0;
1561 : }
1562 50601 : index = instances_.Insert(name, rti, index);
1563 50601 : rti->set_index(index);
1564 : pair<BgpInstanceMap::iterator, bool> result2 =
1565 50601 : instance_config_map_.insert(
1566 101202 : make_pair(name, rti->instance_config()));
1567 50601 : assert(result2.second);
1568 50601 : return rti;
1569 : }
1570 :
1571 : //
1572 : // Remove the given BgpIfmapInstanceConfig from the IfmapInstanceMap
1573 : // and delete it.
1574 : //
1575 10323 : void BgpIfmapConfigData::DeleteInstance(BgpIfmapInstanceConfig *rti) {
1576 10323 : BgpInstanceMap::iterator loc2 = instance_config_map_.find(rti->name());
1577 10323 : assert(loc2 != instance_config_map_.end());
1578 10323 : instance_config_map_.erase(loc2);
1579 10323 : instances_.Remove(rti->name(), rti->index(), false);
1580 10323 : }
1581 :
1582 : //
1583 : // Find the BgpIfmapInstanceConfig by name.
1584 : //
1585 487051 : BgpIfmapInstanceConfig *BgpIfmapConfigData::FindInstance(const string &name) {
1586 487051 : return instances_.Find(name);
1587 : }
1588 :
1589 : //
1590 : // Find the BgpIfmapInstanceConfig by name.
1591 : // Const version.
1592 : //
1593 7 : const BgpIfmapInstanceConfig *BgpIfmapConfigData::FindInstance(
1594 : const string &name) const {
1595 7 : return instances_.Find(name);
1596 : }
1597 :
1598 : BgpConfigManager::NeighborMapRange
1599 190 : BgpIfmapInstanceConfig::NeighborMapItems() const {
1600 190 : return make_pair(neighbors_.begin(), neighbors_.end());
1601 : }
1602 :
1603 : //
1604 : // Create a new BgpIfmapRoutingPolicyLinkConfig.
1605 : //
1606 : // The IFMapNodeProxy is a proxy for the IFMapNode which is the midnode that
1607 : // represents the routing-policy-routing-instance. The newly created
1608 : // BgpIfmapRoutingPolicyLinkConfig gets added to the IfmapRoutingPolicyLinkMap.
1609 : //
1610 165 : BgpIfmapRoutingPolicyLinkConfig *BgpIfmapConfigData::CreateRoutingPolicyLink(
1611 : BgpIfmapInstanceConfig *rti, BgpIfmapRoutingPolicyConfig *rtp,
1612 : IFMapNodeProxy *proxy) {
1613 : BgpIfmapRoutingPolicyLinkConfig *ri_rp_link =
1614 165 : new BgpIfmapRoutingPolicyLinkConfig(rti, rtp);
1615 165 : ri_rp_link->SetNodeProxy(proxy);
1616 : pair<IfmapRoutingPolicyLinkMap::iterator, bool> result =
1617 165 : ri_rp_links_.insert(make_pair(ri_rp_link->node()->name(), ri_rp_link));
1618 165 : assert(result.second);
1619 165 : ri_rp_link->instance()->AddRoutingPolicy(rtp);
1620 165 : ri_rp_link->policy()->AddInstance(rti);
1621 165 : return ri_rp_link;
1622 : }
1623 :
1624 : //
1625 : // Delete a BgpIfmapRoutingPolicyLinkConfig.
1626 : //
1627 : // The BgpIfmapRoutingPolicyLinkConfig is erased from IfmapRoutingPolicyLinkMap
1628 : // and then deleted.
1629 : // Note that the reference to the IFMapNode for routing-policy-routing-instance
1630 : // gets released via the destructor when the IFMapNodeProxy is destroyed.
1631 : //
1632 46 : void BgpIfmapConfigData::DeleteRoutingPolicyLink(
1633 : BgpIfmapRoutingPolicyLinkConfig *ri_rp_link) {
1634 46 : ri_rp_links_.erase(ri_rp_link->node()->name());
1635 46 : ri_rp_link->instance()->DeleteRoutingPolicy(ri_rp_link->policy());
1636 46 : ri_rp_link->policy()->RemoveInstance(ri_rp_link->instance());
1637 46 : delete ri_rp_link;
1638 46 : }
1639 :
1640 : //
1641 : // Find the BgpIfmapRoutingPolicyLinkConfig by name.
1642 : //
1643 236 : BgpIfmapRoutingPolicyLinkConfig *BgpIfmapConfigData::FindRoutingPolicyLink(
1644 : const string &name) {
1645 236 : IfmapRoutingPolicyLinkMap::iterator loc = ri_rp_links_.find(name);
1646 236 : if (loc != ri_rp_links_.end()) {
1647 71 : return loc->second;
1648 : }
1649 165 : return NULL;
1650 : }
1651 :
1652 : //
1653 : // Find the BgpIfmapRoutingPolicyLinkConfig by name.
1654 : // Const version.
1655 : //
1656 : const BgpIfmapRoutingPolicyLinkConfig *
1657 0 : BgpIfmapConfigData::FindRoutingPolicyLink(const string &name) const {
1658 0 : IfmapRoutingPolicyLinkMap::const_iterator loc = ri_rp_links_.find(name);
1659 0 : if (loc != ri_rp_links_.end()) {
1660 0 : return loc->second;
1661 : }
1662 0 : return NULL;
1663 : }
1664 :
1665 : //
1666 : // Create a new BgpIfmapPeeringConfig.
1667 : //
1668 : // The IFMapNodeProxy is a proxy for the IFMapNode which is the
1669 : // midnode that represents the bgp-peering. The newly created
1670 : // BgpIfmapPeeringConfig gets added to the IfmapPeeringMap.
1671 : //
1672 4312 : BgpIfmapPeeringConfig *BgpIfmapConfigData::CreatePeering(
1673 : BgpIfmapInstanceConfig *rti, IFMapNodeProxy *proxy) {
1674 4312 : BgpIfmapPeeringConfig *peering = new BgpIfmapPeeringConfig(rti);
1675 4312 : peering->SetNodeProxy(proxy);
1676 : pair<IfmapPeeringMap::iterator, bool> result =
1677 4312 : peerings_.insert(make_pair(peering->node()->name(), peering));
1678 4312 : assert(result.second);
1679 4312 : peering->instance()->AddPeering(peering);
1680 4312 : BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
1681 : "Creating BgpIfmapPeering " << peering->node()->name());
1682 4312 : return peering;
1683 : }
1684 :
1685 : //
1686 : // Delete a BgpPeeringConfig.
1687 : //
1688 : // The BgpPeeringConfig is removed from the IfmapPeeringMap and then deleted.
1689 : // Note that the reference to the IFMapNode for the bgp-peering gets released
1690 : // via the destructor when the IFMapNodeProxy is destroyed.
1691 : //
1692 2121 : void BgpIfmapConfigData::DeletePeering(BgpIfmapPeeringConfig *peering) {
1693 2121 : BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
1694 : "Deleting BgpIfmapPeering " << peering->node()->name());
1695 2121 : peering->instance()->DeletePeering(peering);
1696 2121 : peerings_.erase(peering->node()->name());
1697 2121 : delete peering;
1698 2121 : }
1699 :
1700 : //
1701 : // Find the BgpPeeringConfig by name.
1702 : //
1703 20900 : BgpIfmapPeeringConfig *BgpIfmapConfigData::FindPeering(const string &name) {
1704 20900 : IfmapPeeringMap::iterator loc = peerings_.find(name);
1705 20900 : if (loc != peerings_.end()) {
1706 12879 : return loc->second;
1707 : }
1708 8021 : return NULL;
1709 : }
1710 :
1711 : //
1712 : // Find the BgpPeeringConfig by name.
1713 : // Const version.
1714 : //
1715 0 : const BgpIfmapPeeringConfig *BgpIfmapConfigData::FindPeering(
1716 : const string &name) const {
1717 0 : IfmapPeeringMap::const_iterator loc = peerings_.find(name);
1718 0 : if (loc != peerings_.end()) {
1719 0 : return loc->second;
1720 : }
1721 0 : return NULL;
1722 : }
1723 :
1724 : BgpConfigManager::InstanceMapRange
1725 59 : BgpIfmapConfigData::InstanceMapItems(const string &start_name) const {
1726 59 : return make_pair(instance_config_map_.lower_bound(start_name),
1727 118 : instance_config_map_.end());
1728 : }
1729 :
1730 : BgpConfigManager::RoutingPolicyMapRange
1731 2 : BgpIfmapConfigData::RoutingPolicyMapItems(const string &start_name) const {
1732 2 : return make_pair(routing_policy_config_map_.lower_bound(start_name),
1733 4 : routing_policy_config_map_.end());
1734 : }
1735 :
1736 : //
1737 : // Locate the BgpIfmapRoutingPolicyConfig by name, create it if not found.
1738 : // The newly created BgpIfmapRoutingPolicyConfig gets added to the
1739 : // IfmapRoutingPolicyMap.
1740 : //
1741 161 : BgpIfmapRoutingPolicyConfig *BgpIfmapConfigData::LocateRoutingPolicy(
1742 : const string &name) {
1743 161 : BgpIfmapRoutingPolicyConfig *rtp = FindRoutingPolicy(name);
1744 161 : if (rtp != NULL) {
1745 0 : return rtp;
1746 : }
1747 161 : rtp = new BgpIfmapRoutingPolicyConfig(name);
1748 : pair<IfmapRoutingPolicyMap::iterator, bool> result =
1749 161 : routing_policies_.insert(make_pair(name, rtp));
1750 161 : assert(result.second);
1751 : pair<BgpRoutingPolicyMap::iterator, bool> result2 =
1752 161 : routing_policy_config_map_.insert(
1753 322 : make_pair(name, rtp->routing_policy_config()));
1754 161 : assert(result2.second);
1755 161 : return rtp;
1756 : }
1757 :
1758 : //
1759 : // Remove the given BgpIfmapRoutingPolicyConfig from the IfmapRoutingPolicyMap
1760 : // and delete it.
1761 : //
1762 43 : void BgpIfmapConfigData::DeleteRoutingPolicy(BgpIfmapRoutingPolicyConfig *rtp) {
1763 43 : IfmapRoutingPolicyMap::iterator loc = routing_policies_.find(rtp->name());
1764 43 : assert(loc != routing_policies_.end());
1765 43 : routing_policies_.erase(loc);
1766 : BgpRoutingPolicyMap::iterator loc2 =
1767 43 : routing_policy_config_map_.find(rtp->name());
1768 43 : assert(loc2 != routing_policy_config_map_.end());
1769 43 : routing_policy_config_map_.erase(loc2);
1770 43 : delete rtp;
1771 43 : }
1772 :
1773 830 : BgpIfmapRoutingPolicyConfig *BgpIfmapConfigData::FindRoutingPolicy(
1774 : const string &name) {
1775 830 : IfmapRoutingPolicyMap::iterator loc = routing_policies_.find(name);
1776 830 : if (loc != routing_policies_.end()) {
1777 457 : return loc->second;
1778 : }
1779 373 : return NULL;
1780 : }
1781 :
1782 0 : const BgpIfmapRoutingPolicyConfig *BgpIfmapConfigData::FindRoutingPolicy(
1783 : const string &name) const {
1784 0 : IfmapRoutingPolicyMap::const_iterator loc = routing_policies_.find(name);
1785 0 : if (loc != routing_policies_.end()) {
1786 0 : return loc->second;
1787 : }
1788 0 : return NULL;
1789 : }
1790 :
1791 : //
1792 : // Constructor for BgpIfmapConfigManager.
1793 : //
1794 8049 : BgpIfmapConfigManager::BgpIfmapConfigManager(BgpServer *server)
1795 : : BgpConfigManager(server),
1796 8049 : db_(NULL),
1797 8049 : db_graph_(NULL),
1798 8049 : trigger_(boost::bind(&BgpIfmapConfigManager::ConfigHandler, this),
1799 : TaskScheduler::GetInstance()->GetTaskId("bgp::Config"),
1800 : kConfigTaskInstanceId),
1801 8049 : listener_(new BgpConfigListener(this)),
1802 16098 : config_(new BgpIfmapConfigData()) {
1803 8049 : IdentifierMapInit();
1804 8049 : }
1805 :
1806 : //
1807 : // Destructor for BgpIfmapConfigManager.
1808 : //
1809 16098 : BgpIfmapConfigManager::~BgpIfmapConfigManager() {
1810 16098 : }
1811 :
1812 : //
1813 : // Initialize the BgpConfigManager.
1814 : //
1815 8031 : void BgpIfmapConfigManager::Initialize(DB *db, DBGraph *db_graph,
1816 : const string &localname) {
1817 8031 : db_ = db;
1818 8031 : db_graph_ = db_graph;
1819 8031 : localname_ = localname;
1820 8031 : listener_->Initialize();
1821 8031 : DefaultConfig();
1822 8031 : }
1823 :
1824 : //
1825 : // Used to trigger a build and subsequent evaluation of the ChangeList.
1826 : //
1827 219023 : void BgpIfmapConfigManager::OnChange() {
1828 219023 : CHECK_CONCURRENCY("db::IFMapTable");
1829 219023 : trigger_.Set();
1830 219023 : }
1831 :
1832 : BgpConfigManager::InstanceMapRange
1833 59 : BgpIfmapConfigManager::InstanceMapItems(const string &start_name) const {
1834 59 : return config_->InstanceMapItems(start_name);
1835 : }
1836 :
1837 : BgpConfigManager::RoutingPolicyMapRange
1838 2 : BgpIfmapConfigManager::RoutingPolicyMapItems(const string &start_name) const {
1839 2 : return config_->RoutingPolicyMapItems(start_name);
1840 : }
1841 :
1842 : BgpConfigManager::NeighborMapRange
1843 190 : BgpIfmapConfigManager::NeighborMapItems(
1844 : const string &instance_name) const {
1845 190 : static BgpConfigManager::NeighborMap nilMap;
1846 190 : BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
1847 190 : if (rti == NULL) {
1848 0 : return make_pair(nilMap.begin(), nilMap.end());
1849 : }
1850 190 : return rti->NeighborMapItems();
1851 : }
1852 :
1853 50478 : void BgpIfmapConfigManager::ResetRoutingInstanceIndexBit(int index) {
1854 50478 : config()->instances().ResetBit(index);
1855 50478 : }
1856 :
1857 14 : int BgpIfmapConfigManager::NeighborCount(
1858 : const string &instance_name) const {
1859 14 : BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
1860 14 : if (rti == NULL) {
1861 2 : return 0;
1862 : }
1863 12 : return rti->neighbors().size();
1864 : }
1865 :
1866 : //
1867 : // Constructor for BgpIfmapRoutingPolicyConfig.
1868 : //
1869 161 : BgpIfmapRoutingPolicyConfig::BgpIfmapRoutingPolicyConfig(
1870 161 : const string &name)
1871 161 : : name_(name),
1872 161 : data_(name) {
1873 161 : }
1874 :
1875 : //
1876 : // Destructor for BgpIfmapRoutingPolicyConfig.
1877 : //
1878 161 : BgpIfmapRoutingPolicyConfig::~BgpIfmapRoutingPolicyConfig() {
1879 161 : }
1880 :
1881 : //
1882 : // Set the IFMapNodeProxy for the BgpIfmapRoutingPolicyConfig.
1883 : //
1884 161 : void BgpIfmapRoutingPolicyConfig::SetNodeProxy(IFMapNodeProxy *proxy) {
1885 161 : if (proxy != NULL) {
1886 161 : node_proxy_.Swap(proxy);
1887 : }
1888 161 : }
1889 :
1890 43 : void BgpIfmapRoutingPolicyConfig::Delete(BgpConfigManager *manager) {
1891 43 : manager->Notify(&data_, BgpConfigManager::CFG_DELETE);
1892 43 : routing_policy_.reset();
1893 43 : }
1894 :
1895 : //
1896 : // Return true if the BgpIfmapRoutingPolicyConfig is ready to be deleted.
1897 : // The caller is responsible for actually deleting it.
1898 : //
1899 89 : bool BgpIfmapRoutingPolicyConfig::DeleteIfEmpty(BgpConfigManager *manager) {
1900 89 : if (node() != NULL) {
1901 5 : return false;
1902 : }
1903 84 : if (!instances_.empty()) {
1904 41 : return false;
1905 : }
1906 :
1907 43 : Delete(manager);
1908 43 : return true;
1909 : }
1910 :
1911 : //
1912 : // Add a BgpIfmapInstanceConfig to BgpIfmapRoutingPolicyConfig.
1913 : //
1914 165 : void BgpIfmapRoutingPolicyConfig::AddInstance(BgpIfmapInstanceConfig *rti) {
1915 165 : instances_.insert(make_pair(rti->name(), rti));
1916 165 : }
1917 :
1918 : //
1919 : // Remove a BgpIfmapInstanceConfig to BgpIfmapRoutingPolicyConfig.
1920 : //
1921 46 : void BgpIfmapRoutingPolicyConfig::RemoveInstance(BgpIfmapInstanceConfig *rti) {
1922 46 : instances_.erase(rti->name());
1923 46 : }
1924 :
1925 :
1926 477 : static void BuildPolicyTermConfig(autogen::PolicyTermType cfg_term,
1927 : RoutingPolicyTermConfig *term) {
1928 477 : term->match.protocols_match = cfg_term.term_match_condition.protocol;
1929 933 : BOOST_FOREACH(const autogen::PrefixMatchType &prefix_match,
1930 : cfg_term.term_match_condition.prefix) {
1931 228 : string prefix_type(prefix_match.prefix_type);
1932 228 : PrefixMatchConfig match(prefix_match.prefix,
1933 456 : prefix_type.empty() ? "exact" : prefix_type);
1934 228 : term->match.prefixes_to_match.push_back(match);
1935 228 : }
1936 477 : term->match.community_match_all =
1937 477 : cfg_term.term_match_condition.community_match_all;
1938 477 : if (!cfg_term.term_match_condition.community_list.empty()) {
1939 : term->match.community_match =
1940 24 : cfg_term.term_match_condition.community_list;
1941 : }
1942 477 : if (!cfg_term.term_match_condition.community.empty()) {
1943 272 : term->match.community_match.push_back(
1944 272 : cfg_term.term_match_condition.community);
1945 : }
1946 477 : term->match.ext_community_match_all =
1947 477 : cfg_term.term_match_condition.extcommunity_match_all;
1948 477 : if (!cfg_term.term_match_condition.extcommunity_list.empty()) {
1949 : term->match.ext_community_match =
1950 12 : cfg_term.term_match_condition.extcommunity_list;
1951 : }
1952 :
1953 493 : BOOST_FOREACH(uint32_t asn,
1954 : cfg_term.term_action_list.update.as_path.expand.asn_list) {
1955 8 : term->action.update.aspath_expand.push_back(asn);
1956 : }
1957 645 : BOOST_FOREACH(const string community,
1958 : cfg_term.term_action_list.update.community.add.community) {
1959 84 : term->action.update.community_add.push_back(community);
1960 84 : }
1961 549 : BOOST_FOREACH(const string community,
1962 : cfg_term.term_action_list.update.community.remove.community) {
1963 36 : term->action.update.community_remove.push_back(community);
1964 36 : }
1965 589 : BOOST_FOREACH(const string community,
1966 : cfg_term.term_action_list.update.community.set.community) {
1967 56 : term->action.update.community_set.push_back(community);
1968 56 : }
1969 509 : BOOST_FOREACH(const string community,
1970 : cfg_term.term_action_list.update.extcommunity.add.community) {
1971 16 : term->action.update.ext_community_add.push_back(community);
1972 16 : }
1973 521 : BOOST_FOREACH(const string community,
1974 : cfg_term.term_action_list.update.extcommunity.remove.community) {
1975 22 : term->action.update.ext_community_remove.push_back(community);
1976 22 : }
1977 493 : BOOST_FOREACH(const string community,
1978 : cfg_term.term_action_list.update.extcommunity.set.community) {
1979 8 : term->action.update.ext_community_set.push_back(community);
1980 8 : }
1981 477 : term->action.update.local_pref =
1982 477 : cfg_term.term_action_list.update.local_pref;
1983 477 : term->action.update.med = cfg_term.term_action_list.update.med;
1984 :
1985 477 : term->action.action = RoutingPolicyActionConfig::NEXT_TERM;
1986 477 : if (strcmp(cfg_term.term_action_list.action.c_str(), "reject") == 0) {
1987 134 : term->action.action = RoutingPolicyActionConfig::REJECT;
1988 343 : } else if (
1989 343 : strcmp(cfg_term.term_action_list.action.c_str(), "accept") == 0) {
1990 241 : term->action.action = RoutingPolicyActionConfig::ACCEPT;
1991 : }
1992 477 : }
1993 :
1994 396 : static void BuildPolicyTermsConfig(BgpRoutingPolicyConfig *policy_cfg,
1995 : const autogen::RoutingPolicy *policy) {
1996 396 : vector<autogen::PolicyTermType> terms = policy->entries();
1997 1350 : BOOST_FOREACH(autogen::PolicyTermType cfg_term, terms) {
1998 477 : RoutingPolicyTermConfig policy_term_cfg;
1999 477 : BuildPolicyTermConfig(cfg_term, &policy_term_cfg);
2000 477 : policy_cfg->add_term(policy_term_cfg);
2001 954 : }
2002 396 : }
2003 :
2004 396 : void BgpIfmapRoutingPolicyConfig::Update(BgpIfmapConfigManager *manager,
2005 : const autogen::RoutingPolicy *policy) {
2006 396 : routing_policy_.reset(policy);
2007 396 : data_.Clear();
2008 396 : if (policy) {
2009 396 : BuildPolicyTermsConfig(&data_, policy);
2010 : }
2011 396 : }
2012 :
2013 : //
2014 : // Reset IFMap related state in the BgpIfmapRoutingPolicyConfig.
2015 : //
2016 43 : void BgpIfmapRoutingPolicyConfig::ResetConfig() {
2017 43 : node_proxy_.Clear();
2018 43 : }
2019 :
2020 65 : const BgpRoutingPolicyConfig *BgpIfmapConfigManager::FindRoutingPolicy(
2021 : const string &name) const {
2022 65 : BgpIfmapRoutingPolicyConfig *rtp = config_->FindRoutingPolicy(name);
2023 65 : if (rtp == NULL) {
2024 51 : return NULL;
2025 : }
2026 14 : return rtp->routing_policy_config();
2027 : }
2028 :
2029 79113 : const BgpInstanceConfig *BgpIfmapConfigManager::FindInstance(
2030 : const string &name) const {
2031 79113 : BgpIfmapInstanceConfig *rti = config_->FindInstance(name);
2032 78967 : if (rti == NULL) {
2033 10205 : return NULL;
2034 : }
2035 68762 : return rti->instance_config();
2036 : }
2037 :
2038 62434 : const BgpProtocolConfig *BgpIfmapConfigManager::GetProtocolConfig(
2039 : const string &instance_name) const {
2040 62434 : BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
2041 62401 : if (rti == NULL) {
2042 1016 : return NULL;
2043 : }
2044 61385 : const BgpIfmapProtocolConfig *proto = rti->protocol_config();
2045 61390 : if (proto == NULL) {
2046 55 : return NULL;
2047 : }
2048 61335 : return proto->protocol_config();
2049 : }
2050 :
2051 6802 : const BgpNeighborConfig *BgpIfmapConfigManager::FindNeighbor(
2052 : const string &instance_name, const string &name) const {
2053 6802 : BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
2054 6802 : if (rti == NULL) {
2055 0 : return NULL;
2056 : }
2057 6802 : return rti->FindNeighbor(name);
2058 : }
2059 :
2060 : //
2061 : // Initialize autogen::BgpRouterParams with default values.
2062 : //
2063 8031 : void BgpIfmapConfigManager::DefaultBgpRouterParams(
2064 : autogen::BgpRouterParams *param) {
2065 8031 : param->Clear();
2066 8031 : param->autonomous_system = BgpConfigManager::kDefaultAutonomousSystem;
2067 8031 : param->port = BgpConfigManager::kDefaultPort;
2068 8031 : }
2069 :
2070 : //
2071 : // Create BgpInsatnceConfig for master routing-instance. This
2072 : // includes the BgpIfmapProtocolConfig for the local bgp-router in the
2073 : // master routing-instance.
2074 : //
2075 8031 : void BgpIfmapConfigManager::DefaultConfig() {
2076 8031 : BgpIfmapInstanceConfig *rti = config_->LocateInstance(kMasterInstance);
2077 8031 : unique_ptr<autogen::BgpRouter> router(new autogen::BgpRouter());
2078 8031 : autogen::BgpRouterParams param;
2079 8031 : DefaultBgpRouterParams(¶m);
2080 8031 : router->SetProperty("bgp-router-parameters", ¶m);
2081 8031 : BgpIfmapProtocolConfig *protocol = rti->LocateProtocol();
2082 8031 : protocol->Update(this, router.release());
2083 8031 : Notify(rti->instance_config(), BgpConfigManager::CFG_ADD);
2084 :
2085 8031 : vector<string> import_list;
2086 8031 : vector<string> export_list;
2087 8031 : BGP_CONFIG_LOG_INSTANCE(
2088 : Create, server(), rti, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
2089 : import_list, export_list,
2090 : rti->virtual_network(), rti->virtual_network_index());
2091 :
2092 8031 : BGP_CONFIG_LOG_PROTOCOL(
2093 : Create, server(), protocol,
2094 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
2095 : protocol->router_params().admin_down,
2096 : protocol->router_params().autonomous_system,
2097 : protocol->router_params().identifier,
2098 : protocol->router_params().address,
2099 : protocol->router_params().hold_time,
2100 : vector<string>());
2101 8031 : }
2102 :
2103 1136 : bool BgpIfmapGlobalSystemConfig::Update(BgpIfmapConfigManager *manager,
2104 : const autogen::GlobalSystemConfig *system) {
2105 1136 : bool changed = false;
2106 :
2107 1136 : if (data_.gr_enable() != system->graceful_restart_parameters().enable) {
2108 564 : data_.set_gr_enable(system->graceful_restart_parameters().enable);
2109 564 : changed |= true;
2110 : }
2111 :
2112 1136 : if (data_.gr_time() != system->graceful_restart_parameters().restart_time) {
2113 784 : data_.set_gr_time(system->graceful_restart_parameters().restart_time);
2114 784 : changed |= true;
2115 : }
2116 :
2117 1136 : if (data_.llgr_time() != static_cast<uint32_t>(
2118 1136 : system->graceful_restart_parameters().long_lived_restart_time)) {
2119 1568 : data_.set_llgr_time(
2120 784 : system->graceful_restart_parameters().long_lived_restart_time);
2121 784 : changed |= true;
2122 : }
2123 :
2124 1136 : if (data_.end_of_rib_timeout() !=
2125 1136 : system->graceful_restart_parameters().end_of_rib_timeout) {
2126 1126 : data_.set_end_of_rib_timeout(
2127 563 : system->graceful_restart_parameters().end_of_rib_timeout);
2128 563 : changed |= true;
2129 : }
2130 :
2131 1136 : if (data_.gr_bgp_helper() !=
2132 1136 : system->graceful_restart_parameters().bgp_helper_enable) {
2133 1122 : data_.set_gr_bgp_helper(
2134 561 : system->graceful_restart_parameters().bgp_helper_enable);
2135 561 : changed |= true;
2136 : }
2137 :
2138 1136 : if (data_.gr_xmpp_helper() !=
2139 1136 : system->graceful_restart_parameters().xmpp_helper_enable) {
2140 1122 : data_.set_gr_xmpp_helper(
2141 561 : system->graceful_restart_parameters().xmpp_helper_enable);
2142 561 : changed |= true;
2143 : }
2144 :
2145 1136 : if (data_.enable_4byte_as() != system->enable_4byte_as()) {
2146 16 : data_.set_enable_4byte_as(system->enable_4byte_as());
2147 16 : changed |= true;
2148 : }
2149 :
2150 1136 : if (data_.always_compare_med() != system->bgp_always_compare_med()) {
2151 5 : data_.set_always_compare_med(system->bgp_always_compare_med());
2152 5 : changed |= true;
2153 : }
2154 :
2155 1136 : if (data_.rd_cluster_seed() != system->rd_cluster_seed()) {
2156 25 : data_.set_rd_cluster_seed(system->rd_cluster_seed());
2157 25 : changed |= true;
2158 : }
2159 :
2160 1136 : if (data_.xmpp_hold_time() !=
2161 1136 : system->fast_convergence_parameters().xmpp_hold_time) {
2162 22 : data_.set_xmpp_hold_time(
2163 11 : system->fast_convergence_parameters().xmpp_hold_time);
2164 11 : changed |= true;
2165 : }
2166 :
2167 1136 : if (data_.bgpaas_port_start() != system->bgpaas_parameters().port_start) {
2168 676 : data_.set_bgpaas_port_start(system->bgpaas_parameters().port_start);
2169 676 : changed |= true;
2170 : }
2171 :
2172 1136 : if (data_.bgpaas_port_end() != system->bgpaas_parameters().port_end) {
2173 676 : data_.set_bgpaas_port_end(system->bgpaas_parameters().port_end);
2174 676 : changed |= true;
2175 : }
2176 :
2177 1136 : if (data_.fc_enabled() != system->fast_convergence_parameters().enable) {
2178 9 : data_.set_fc_enabled(system->fast_convergence_parameters().enable);
2179 9 : changed |= true;
2180 : }
2181 :
2182 1136 : if (data_.nh_check_enabled() !=
2183 1136 : system->fast_convergence_parameters().nh_reachability_check) {
2184 4 : data_.set_nh_check_enabled(
2185 2 : system->fast_convergence_parameters().nh_reachability_check);
2186 2 : changed |= true;
2187 : }
2188 :
2189 1136 : if (data_.all_tags_are_global() != system->bgp_all_tags_are_global()) {
2190 4 : data_.set_all_tags_are_global(system->bgp_all_tags_are_global());
2191 4 : changed |= true;
2192 : }
2193 :
2194 1136 : return changed;
2195 : }
2196 :
2197 11 : bool BgpIfmapGlobalQosConfig::Update(BgpIfmapConfigManager *manager,
2198 : const autogen::GlobalQosConfig *qos) {
2199 11 : bool changed = false;
2200 11 : const autogen::ControlTrafficDscpType &dscp = qos->control_traffic_dscp();
2201 :
2202 11 : if (data_.control_dscp() != dscp.control) {
2203 9 : data_.set_control_dscp(dscp.control);
2204 9 : Sandesh::SetDscpValue(dscp.control);
2205 9 : changed = true;
2206 : }
2207 11 : if (data_.analytics_dscp() != dscp.analytics) {
2208 3 : data_.set_analytics_dscp(dscp.analytics);
2209 3 : changed = true;
2210 : }
2211 11 : return changed;
2212 : }
2213 :
2214 : //
2215 : // Initialize IdentifierMap with handlers for interesting identifier types.
2216 : //
2217 : // The IdentifierMap is used when processing BgpConfigDeltas generated by
2218 : // the BgpConfigListener.
2219 : //
2220 8049 : void BgpIfmapConfigManager::IdentifierMapInit() {
2221 8049 : id_map_.insert(make_pair("routing-instance",
2222 8049 : boost::bind(&BgpIfmapConfigManager::ProcessRoutingInstance,
2223 : this, _1)));
2224 8049 : id_map_.insert(make_pair("routing-policy",
2225 8049 : boost::bind(&BgpIfmapConfigManager::ProcessRoutingPolicy, this, _1)));
2226 8049 : id_map_.insert(make_pair("routing-policy-routing-instance",
2227 8049 : boost::bind(&BgpIfmapConfigManager::ProcessRoutingPolicyLink, this,
2228 : _1)));
2229 8049 : id_map_.insert(make_pair("bgp-router",
2230 8049 : boost::bind(&BgpIfmapConfigManager::ProcessBgpRouter, this, _1)));
2231 8049 : id_map_.insert(make_pair("bgp-peering",
2232 8049 : boost::bind(&BgpIfmapConfigManager::ProcessBgpPeering, this, _1)));
2233 8049 : id_map_.insert(make_pair("global-system-config",
2234 8049 : boost::bind(&BgpIfmapConfigManager::ProcessGlobalSystemConfig, this,
2235 : _1)));
2236 8049 : id_map_.insert(make_pair("global-qos-config",
2237 8049 : boost::bind(&BgpIfmapConfigManager::ProcessGlobalQosConfig, this,
2238 : _1)));
2239 8049 : }
2240 :
2241 142731 : void BgpIfmapConfigManager::UpdateInstanceConfig(BgpIfmapInstanceConfig *rti,
2242 : BgpConfigManager::EventType event) {
2243 142731 : if (!rti) {
2244 0 : return;
2245 : }
2246 :
2247 : // in case of id change, update import list and call subsequent code
2248 142731 : Notify(rti->instance_config(), event);
2249 :
2250 142731 : vector<string> import_rt(rti->import_list().begin(),
2251 285462 : rti->import_list().end());
2252 142731 : vector<string> export_rt(rti->export_list().begin(),
2253 285462 : rti->export_list().end());
2254 142731 : if (event == BgpConfigManager::CFG_ADD) {
2255 42570 : BGP_CONFIG_LOG_INSTANCE(Create, server(), rti,
2256 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
2257 : import_rt, export_rt,
2258 : rti->virtual_network(), rti->virtual_network_index());
2259 : } else {
2260 100161 : BGP_CONFIG_LOG_INSTANCE(Update, server(), rti,
2261 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
2262 : import_rt, export_rt,
2263 : rti->virtual_network(), rti->virtual_network_index());
2264 : }
2265 142731 : }
2266 :
2267 : //
2268 : // Handler for routing-instance objects.
2269 : //
2270 : // Note that BgpIfmapInstanceConfig object for the master instance is created
2271 : // before we have received any configuration for it i.e. there's no IFMapNode
2272 : // or autogen::RoutingInstance for it. However, we will eventually receive a
2273 : // delta for the master. The IFMapNodeProxy and autogen::RoutingInstance are
2274 : // set at that time.
2275 : //
2276 : // For other routing-instances BgpIfmapConfigInstance can get created before we
2277 : // see the IFMapNode for the routing-instance if we see the IFMapNode for the
2278 : // local bgp-router in the routing-instance. In this case, the IFMapNodeProxy
2279 : // and autogen::RoutingInstance are set when we later see the IFMapNode for the
2280 : // routing-instance.
2281 : //
2282 : // In all other cases, BgpIfmapConfigInstance is created when we see IFMapNode
2283 : // for the routing-instance. The IFMapNodeProxy and autogen::RoutingInstance
2284 : // are set right away.
2285 : //
2286 : // References to the IFMapNode and the autogen::RoutingInstance are
2287 : // released when the IFMapNode is marked deleted. However the
2288 : // BgpIfmapInstanceConfig does not get deleted till the NeighborMap is
2289 : // empty and the BgpIfmapProtocolConfig is gone.
2290 : //
2291 136089 : void BgpIfmapConfigManager::ProcessRoutingInstance(
2292 : const BgpConfigDelta &delta) {
2293 136089 : CHECK_CONCURRENCY("bgp::Config");
2294 :
2295 136089 : BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
2296 136089 : string instance_name = delta.id_name;
2297 136089 : BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
2298 136089 : if (rti == NULL) {
2299 42568 : IFMapNodeProxy *proxy = delta.node.get();
2300 42568 : if (proxy == NULL) {
2301 0 : return;
2302 : }
2303 42568 : IFMapNode *node = proxy->node();
2304 42568 : if (node == NULL || node->IsDeleted()) {
2305 0 : return;
2306 : }
2307 42568 : event = BgpConfigManager::CFG_ADD;
2308 42568 : rti = config_->LocateInstance(instance_name);
2309 42568 : rti->SetNodeProxy(proxy);
2310 : } else {
2311 93521 : IFMapNode *node = rti->node();
2312 93521 : if (node == NULL) {
2313 5843 : IFMapNodeProxy *proxy = delta.node.get();
2314 5843 : if (proxy == NULL) {
2315 0 : return;
2316 : }
2317 5843 : rti->SetNodeProxy(proxy);
2318 87678 : } else if (node->IsDeleted()) {
2319 11643 : rti->ResetConfig();
2320 11643 : if (rti->DeleteIfEmpty(this)) {
2321 10300 : BGP_CONFIG_LOG_INSTANCE(
2322 : Delete, server(), rti,
2323 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
2324 10300 : config_->DeleteInstance(rti);
2325 : }
2326 11643 : return;
2327 : }
2328 : }
2329 :
2330 : autogen::RoutingInstance *rti_config =
2331 124446 : static_cast<autogen::RoutingInstance *>(delta.obj.get());
2332 124446 : if (rti->index() != -1)
2333 124446 : rti->instance_config()->set_index(rti->index());
2334 124446 : rti->Update(this, rti_config);
2335 124446 : UpdateInstanceConfig(rti, event);
2336 136089 : }
2337 :
2338 : //
2339 : // Handler for bgp protocol config.
2340 : //
2341 : // Note that there's no underlying IFMap object for the bgp protocol config.
2342 : // This is called by the handler for bgp-router objects. The BgpConfigDelta
2343 : // is a delta for the bgp-router object.
2344 : //
2345 9181 : void BgpIfmapConfigManager::ProcessBgpProtocol(const BgpConfigDelta &delta) {
2346 9181 : CHECK_CONCURRENCY("bgp::Config");
2347 :
2348 9181 : BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
2349 9181 : string instance_name(IdentifierParent(delta.id_name));
2350 9181 : BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
2351 9181 : BgpIfmapProtocolConfig *protocol = NULL;
2352 9181 : if (rti != NULL) {
2353 9181 : protocol = rti->protocol_config_mutable();
2354 : }
2355 :
2356 9181 : if (protocol == NULL) {
2357 565 : IFMapNodeProxy *proxy = delta.node.get();
2358 565 : if (proxy == NULL) {
2359 0 : return;
2360 : }
2361 : // ignore identifier with no properties
2362 565 : if (delta.obj.get() == NULL) {
2363 0 : return;
2364 : }
2365 565 : IFMapNode *node = proxy->node();
2366 565 : if (node == NULL || node->IsDeleted()) {
2367 0 : return;
2368 : }
2369 565 : event = BgpConfigManager::CFG_ADD;
2370 565 : if (rti == NULL) {
2371 0 : rti = config_->LocateInstance(instance_name);
2372 0 : UpdateInstanceConfig(rti, event);
2373 : }
2374 565 : protocol = rti->LocateProtocol();
2375 565 : protocol->SetNodeProxy(proxy);
2376 : } else {
2377 8616 : IFMapNode *node = protocol->node();
2378 8616 : if (node == NULL) {
2379 : // The master instance creates a BgpRouter node internally. Ignore
2380 : // an update that doesn't specify any content.
2381 5466 : if (delta.obj.get() == NULL) {
2382 131 : return;
2383 : }
2384 5335 : protocol->SetNodeProxy(delta.node.get());
2385 3150 : } else if (delta.obj.get() == NULL) {
2386 1379 : BGP_CONFIG_LOG_PROTOCOL(Delete, server(), protocol,
2387 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
2388 1379 : protocol->Delete(this);
2389 1379 : rti->ResetProtocol();
2390 1379 : if (rti->DeleteIfEmpty(this)) {
2391 0 : BGP_CONFIG_LOG_INSTANCE(Delete, server(), rti,
2392 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
2393 0 : config_->DeleteInstance(rti);
2394 : }
2395 1379 : return;
2396 : }
2397 : }
2398 :
2399 : autogen::BgpRouter *rt_config =
2400 7671 : static_cast<autogen::BgpRouter *>(delta.obj.get());
2401 7671 : uint32_t old_id = protocol->protocol_config()->identifier();
2402 7671 : uint32_t old_as = protocol->protocol_config()->autonomous_system();
2403 7671 : protocol->Update(this, rt_config);
2404 7671 : uint32_t new_id = protocol->protocol_config()->identifier();
2405 7671 : uint32_t new_as = protocol->protocol_config()->autonomous_system();
2406 7671 : if (new_id != old_id || new_as != old_as) {
2407 6023 : config_->ProcessIdentifierAndASUpdate(this, new_id, old_id, new_as,
2408 : old_as);
2409 : }
2410 7671 : Notify(protocol->protocol_config(), event);
2411 :
2412 7671 : if (!rt_config) {
2413 0 : return;
2414 : }
2415 :
2416 : vector<string> families(
2417 7671 : protocol->router_params().address_families.begin(),
2418 15342 : protocol->router_params().address_families.end());
2419 7671 : if (event == BgpConfigManager::CFG_ADD) {
2420 565 : BGP_CONFIG_LOG_PROTOCOL(Create, server(), protocol,
2421 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
2422 : protocol->router_params().admin_down,
2423 : protocol->router_params().autonomous_system,
2424 : protocol->router_params().identifier,
2425 : protocol->router_params().address,
2426 : protocol->router_params().hold_time,
2427 : families);
2428 : } else {
2429 7106 : BGP_CONFIG_LOG_PROTOCOL(Update, server(), protocol,
2430 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL,
2431 : protocol->router_params().admin_down,
2432 : protocol->router_params().autonomous_system,
2433 : protocol->router_params().identifier,
2434 : protocol->router_params().address,
2435 : protocol->router_params().hold_time,
2436 : families);
2437 : }
2438 9181 : }
2439 :
2440 : //
2441 : // Handler for routing policy objects.
2442 : //
2443 : // BgpConfigListener::DependencyTracker ensures associated routing instances
2444 : // are present in the change list.
2445 : //
2446 439 : void BgpIfmapConfigManager::ProcessRoutingPolicy(const BgpConfigDelta &delta) {
2447 439 : CHECK_CONCURRENCY("bgp::Config");
2448 :
2449 439 : BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
2450 439 : string policy_name = delta.id_name;
2451 439 : BgpIfmapRoutingPolicyConfig *rtp = config_->FindRoutingPolicy(policy_name);
2452 439 : if (rtp == NULL) {
2453 161 : IFMapNodeProxy *proxy = delta.node.get();
2454 161 : if (proxy == NULL) {
2455 0 : return;
2456 : }
2457 161 : IFMapNode *node = proxy->node();
2458 161 : if (node == NULL || node->IsDeleted()) {
2459 0 : return;
2460 : }
2461 161 : event = BgpConfigManager::CFG_ADD;
2462 161 : rtp = config_->LocateRoutingPolicy(policy_name);
2463 161 : rtp->SetNodeProxy(proxy);
2464 : } else {
2465 278 : IFMapNode *node = rtp->node();
2466 278 : if (node == NULL) {
2467 0 : IFMapNodeProxy *proxy = delta.node.get();
2468 0 : if (proxy == NULL) {
2469 0 : return;
2470 : }
2471 0 : rtp->SetNodeProxy(proxy);
2472 278 : } else if (node->IsDeleted()) {
2473 43 : rtp->ResetConfig();
2474 43 : if (rtp->DeleteIfEmpty(this)) {
2475 5 : config_->DeleteRoutingPolicy(rtp);
2476 : }
2477 43 : return;
2478 : }
2479 : }
2480 :
2481 : autogen::RoutingPolicy *rtp_config =
2482 396 : static_cast<autogen::RoutingPolicy *>(delta.obj.get());
2483 396 : rtp->Update(this, rtp_config);
2484 396 : Notify(rtp->routing_policy_config(), event);
2485 439 : }
2486 :
2487 :
2488 : //
2489 : // Handler for bgp-router objects.
2490 : //
2491 16272 : void BgpIfmapConfigManager::ProcessBgpRouter(const BgpConfigDelta &delta) {
2492 16272 : CHECK_CONCURRENCY("bgp::Config");
2493 :
2494 16272 : string instance_name(IdentifierParent(delta.id_name));
2495 32544 : if (instance_name.empty() ||
2496 16272 : instance_name != BgpConfigManager::kMasterInstance) {
2497 449 : return;
2498 : }
2499 :
2500 : // Ignore if this change is not for the local router.
2501 15823 : string name = delta.id_name.substr(instance_name.size() + 1);
2502 15823 : if (name != localname_) {
2503 6642 : return;
2504 : }
2505 :
2506 9181 : ProcessBgpProtocol(delta);
2507 :
2508 : // Update all peerings since we use local asn and identifier from master
2509 : // instance for all neighbors, including those in non-master instances.
2510 16677 : BOOST_FOREACH(const BgpIfmapConfigData::IfmapPeeringMap::value_type &value,
2511 : config_->peerings()) {
2512 3748 : BgpIfmapPeeringConfig *peering = value.second;
2513 3748 : peering->Update(this, peering->bgp_peering());
2514 : }
2515 22914 : }
2516 :
2517 : //
2518 : // Handler for bgp-peering objects.
2519 : //
2520 : // We are only interested in this bgp-peering if it is adjacent to the local
2521 : // router node.
2522 : //
2523 : // The BgpPeeringConfig is created the first time we see the bgp-peering. It
2524 : // is updated on subsequent changes and is deleted when the IFMapNode midnode
2525 : // for the bgp-peering is deleted.
2526 : //
2527 : // Note that we are guaranteed that the IFMapNodes for the 2
2528 : // bgp-routers for the bgp-peering already exist when we see the
2529 : // bgp-peering. IFMap creates the nodes for the bgp-routers before
2530 : // creating the midnode. This in turn guarantees that the
2531 : // BgpIfmapInstanceConfig for the routing-instance also exists since we
2532 : // create the BgpIfmapInstanceConfig before creating the
2533 : // BgpIfmapProtocolConfig for a local bgp-router.
2534 : //
2535 17815 : void BgpIfmapConfigManager::ProcessBgpPeering(const BgpConfigDelta &delta) {
2536 17815 : CHECK_CONCURRENCY("bgp::Config");
2537 :
2538 17815 : BgpConfigManager::EventType event = BgpConfigManager::CFG_CHANGE;
2539 17815 : BgpIfmapPeeringConfig *peering = config_->FindPeering(delta.id_name);
2540 17815 : if (peering == NULL) {
2541 8021 : IFMapNodeProxy *proxy = delta.node.get();
2542 8021 : if (proxy == NULL) {
2543 1843 : BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
2544 : "ProcessBgpPeering failed. Cannot find proxy " <<
2545 : delta.id_name);
2546 3709 : return;
2547 : }
2548 6178 : IFMapNode *node = proxy->node();
2549 6178 : if (node == NULL || delta.obj.get() == NULL) {
2550 0 : BGP_LOG_STR(BgpConfig, SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_SYSLOG,
2551 : "ProcessBgpPeering failed. Cannot find node/obj " <<
2552 : delta.id_name);
2553 0 : return;
2554 : }
2555 :
2556 6178 : pair<IFMapNode *, IFMapNode *> routers;
2557 6178 : if (!BgpIfmapPeeringConfig::GetRouterPair(db_graph_, localname_, node,
2558 : &routers)) {
2559 1866 : return;
2560 : }
2561 :
2562 4312 : string instance_name(IdentifierParent(routers.first->name()));
2563 4312 : BgpIfmapInstanceConfig *rti = config_->FindInstance(instance_name);
2564 4312 : event = BgpConfigManager::CFG_ADD;
2565 : // Create rti if not present.
2566 4312 : if (rti == NULL) {
2567 2 : rti = config_->LocateInstance(instance_name);
2568 2 : UpdateInstanceConfig(rti, event);
2569 : }
2570 4312 : peering = config_->CreatePeering(rti, proxy);
2571 4312 : } else {
2572 9794 : const IFMapNode *node = peering->node();
2573 9794 : assert(node != NULL);
2574 9794 : if (delta.obj.get() == NULL) {
2575 2121 : BGP_CONFIG_LOG_PEERING(Delete, server(), peering,
2576 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
2577 2121 : BgpIfmapInstanceConfig *rti = peering->instance();
2578 2121 : peering->Delete(this);
2579 2121 : config_->DeletePeering(peering);
2580 2121 : if (rti->DeleteIfEmpty(this)) {
2581 22 : BGP_CONFIG_LOG_INSTANCE(Delete, server(), rti,
2582 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
2583 22 : config_->DeleteInstance(rti);
2584 : }
2585 2121 : return;
2586 : }
2587 : }
2588 :
2589 11985 : if (event == BgpConfigManager::CFG_ADD) {
2590 4312 : BGP_CONFIG_LOG_PEERING(Create, server(), peering,
2591 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
2592 : } else {
2593 7673 : BGP_CONFIG_LOG_PEERING(Update, server(), peering,
2594 : SandeshLevel::SYS_DEBUG, BGP_LOG_FLAG_ALL);
2595 : }
2596 : autogen::BgpPeering *peering_config =
2597 11985 : static_cast<autogen::BgpPeering *>(delta.obj.get());
2598 11985 : peering->Update(this, peering_config);
2599 : }
2600 :
2601 1136 : void BgpIfmapConfigManager::ProcessGlobalSystemConfig(
2602 : const BgpConfigDelta &delta) {
2603 1136 : IFMapNodeProxy *proxy = delta.node.get();
2604 1136 : if (proxy == NULL)
2605 0 : return;
2606 :
2607 1136 : IFMapNode *node = proxy->node();
2608 1136 : autogen::GlobalSystemConfig *config, default_config;
2609 1136 : if (node == NULL || node->IsDeleted() || delta.obj.get() == NULL) {
2610 0 : config = &default_config;
2611 : } else {
2612 1136 : config = static_cast<autogen::GlobalSystemConfig *>(delta.obj.get());
2613 : }
2614 :
2615 1136 : if (config_->global_config()->Update(this, config))
2616 840 : Notify(config_->global_config()->config(), BgpConfigManager::CFG_ADD);
2617 1136 : }
2618 :
2619 11 : void BgpIfmapConfigManager::ProcessGlobalQosConfig(
2620 : const BgpConfigDelta &delta) {
2621 11 : IFMapNodeProxy *proxy = delta.node.get();
2622 11 : if (proxy == NULL)
2623 0 : return;
2624 :
2625 11 : IFMapNode *node = proxy->node();
2626 11 : autogen::GlobalQosConfig *config, default_config;
2627 11 : if (node == NULL || node->IsDeleted() || delta.obj.get() == NULL) {
2628 0 : config = &default_config;
2629 : } else {
2630 11 : config = static_cast<autogen::GlobalQosConfig *>(delta.obj.get());
2631 : }
2632 :
2633 11 : if (config_->global_qos()->Update(this, config))
2634 9 : Notify(config_->global_qos()->config(), BgpConfigManager::CFG_ADD);
2635 11 : }
2636 :
2637 : //
2638 : // Process the BgpConfigDeltas on the change list. We simply call the handler
2639 : // for each delta based on the object's identifier type.
2640 : //
2641 24100 : void BgpIfmapConfigManager::ProcessChanges(const ChangeList &change_list) {
2642 24100 : CHECK_CONCURRENCY("bgp::Config");
2643 :
2644 24100 : for (ChangeList::const_iterator iter = change_list.begin();
2645 219847 : iter != change_list.end(); ++iter) {
2646 195747 : IdentifierMap::iterator loc = id_map_.find(iter->id_type);
2647 195747 : if (loc != id_map_.end()) {
2648 171998 : (loc->second)(*iter);
2649 : }
2650 : }
2651 24100 : }
2652 :
2653 : //
2654 : // Build and process the change list of BgpConfigDeltas. The logic to build
2655 : // the list is in BgpConfigListener and BgpConfigListener::DependencyTracker.
2656 : //
2657 24100 : bool BgpIfmapConfigManager::ConfigHandler() {
2658 24100 : CHECK_CONCURRENCY("bgp::Config");
2659 :
2660 24100 : BgpConfigListener::ChangeList change_list;
2661 24100 : listener_->GetChangeList(&change_list);
2662 24100 : ProcessChanges(change_list);
2663 24100 : return true;
2664 24100 : }
2665 :
2666 : //
2667 : // Terminate the BgpConfigManager.
2668 : //
2669 8049 : void BgpIfmapConfigManager::Terminate() {
2670 8049 : listener_->Terminate();
2671 8049 : config_.reset();
2672 8049 : }
|