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