Line data Source code
1 : /*
2 : * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3 : * Copyright Contributors to the OpenSDN project
4 : */
5 : #include "bgp/bgp_config.h"
6 :
7 : #include <boost/foreach.hpp>
8 :
9 : #include <sstream>
10 :
11 : #include "base/string_util.h"
12 : #include "base/time_util.h"
13 :
14 : using std::copy;
15 : using std::endl;
16 : using std::ostringstream;
17 : using std::ostream_iterator;
18 : using std::sort;
19 : using std::string;
20 : using std::swap;
21 : using std::vector;
22 :
23 : const char *BgpConfigManager::kMasterNetwork =
24 : "default-domain:default-project:ip-fabric";
25 : const char *BgpConfigManager::kMasterInstance =
26 : "default-domain:default-project:ip-fabric:__default__";
27 : const char *BgpConfigManager::kFabricInstance =
28 : "default-domain:default-project:ip-fabric:ip-fabric";
29 : const int BgpConfigManager::kDefaultPort = 179;
30 : const uint32_t BgpConfigManager::kDefaultAutonomousSystem = 64512;
31 :
32 3410 : static int CompareTo(const AuthenticationKey &lhs,
33 : const AuthenticationKey &rhs) {
34 3410 : KEY_COMPARE(lhs.id, rhs.id);
35 3410 : KEY_COMPARE(lhs.value, rhs.value);
36 3303 : KEY_COMPARE(lhs.start_time, rhs.start_time);
37 3303 : return 0;
38 : }
39 :
40 3195 : bool AuthenticationKey::operator<(const AuthenticationKey &rhs) const {
41 3195 : int cmp = CompareTo(*this, rhs);
42 3195 : return cmp < 0;
43 : }
44 :
45 215 : bool AuthenticationKey::operator==(const AuthenticationKey &rhs) const {
46 215 : int cmp = CompareTo(*this, rhs);
47 215 : return cmp == 0;
48 : }
49 :
50 101702 : AuthenticationData::AuthenticationData() : key_type_(NIL) {
51 101702 : }
52 :
53 0 : AuthenticationData::AuthenticationData(KeyType type,
54 0 : const AuthenticationKeyChain &chain) :
55 0 : key_type_(type), key_chain_(chain) {
56 0 : }
57 :
58 42040 : bool AuthenticationData::operator<(const AuthenticationData &rhs) const {
59 42040 : BOOL_KEY_COMPARE(key_type_, rhs.key_type());
60 42021 : BOOL_KEY_COMPARE(key_chain_, rhs.key_chain());
61 41964 : return false;
62 : }
63 :
64 20418 : bool AuthenticationData::operator==(const AuthenticationData &rhs) const {
65 40668 : if ((key_chain_.size() != rhs.key_chain().size()) ||
66 20250 : (key_type_ != rhs.key_type())) {
67 168 : return false;
68 : }
69 :
70 20425 : for (size_t ocnt = 0; ocnt < rhs.key_chain().size(); ++ocnt) {
71 215 : bool found = false;
72 255 : for (size_t icnt = 0; icnt < key_chain_.size(); ++icnt) {
73 215 : if (key_chain_[icnt] == rhs.key_chain()[ocnt]) {
74 175 : found = true;
75 175 : break;
76 : }
77 : }
78 215 : if (!found) {
79 40 : return false;
80 : }
81 : }
82 20210 : return true;
83 : }
84 :
85 59521 : AuthenticationData &AuthenticationData::operator=(
86 : const AuthenticationData &rhs) {
87 59521 : set_key_type(rhs.key_type());
88 59521 : set_key_chain(rhs.key_chain());
89 59521 : return *this;
90 : }
91 :
92 657 : void AuthenticationData::AddKeyToKeyChain(const AuthenticationKey &key) {
93 657 : key_chain_.push_back(key);
94 657 : }
95 :
96 0 : const AuthenticationKey *AuthenticationData::Find(int key_id) const {
97 : const AuthenticationKey *item;
98 0 : for (size_t i = 0; i < key_chain_.size(); ++i) {
99 0 : item = &key_chain_[i];
100 0 : if (item->id == key_id) {
101 0 : return item;
102 : }
103 : }
104 0 : return NULL;
105 : }
106 :
107 30771 : bool AuthenticationData::Empty() const {
108 30771 : return key_chain_.empty();
109 : }
110 :
111 0 : void AuthenticationData::Clear() {
112 0 : key_chain_.clear();
113 0 : }
114 :
115 13397 : string AuthenticationData::KeyTypeToString() const {
116 13397 : switch (key_type_) {
117 344 : case MD5:
118 344 : return "MD5";
119 13053 : default:
120 13053 : return "NIL";
121 : }
122 : }
123 :
124 1725 : string AuthenticationData::KeyTypeToString(KeyType key_type) {
125 1725 : switch (key_type) {
126 1613 : case MD5:
127 1613 : return "MD5";
128 112 : default:
129 112 : return "NIL";
130 : }
131 : }
132 :
133 13392 : vector<string> AuthenticationData::KeysToString() const {
134 13392 : AuthenticationKeyChain::const_iterator iter;
135 13392 : vector<string> auth_keys;
136 13736 : for (iter = key_chain_.begin(); iter != key_chain_.end(); ++iter) {
137 344 : AuthenticationKey key = *iter;
138 344 : auth_keys.push_back(integerToString(key.id));
139 344 : }
140 26784 : return auth_keys;
141 0 : }
142 :
143 : // NOTE: This prints the actual key too. Use with care.
144 0 : vector<string> AuthenticationData::KeysToStringDetail() const {
145 0 : AuthenticationKeyChain::const_iterator iter;
146 0 : vector<string> auth_keys;
147 0 : for (iter = key_chain_.begin(); iter != key_chain_.end(); ++iter) {
148 0 : AuthenticationKey key = *iter;
149 0 : auth_keys.push_back(integerToString(key.id) + ":" + key.value);
150 0 : }
151 0 : return auth_keys;
152 0 : }
153 :
154 32032 : BgpNeighborConfig::OriginOverrideConfig::OriginOverrideConfig()
155 32032 : : origin_override(false), origin("IGP") {
156 32032 : }
157 :
158 43032 : bool BgpNeighborConfig::OriginOverrideConfig::operator<(
159 : const OriginOverrideConfig &rhs) const {
160 43032 : if (origin_override == rhs.origin_override) {
161 43032 : if (origin_override) {
162 : // chek origin value only if override is set
163 6 : return origin < rhs.origin;
164 : }
165 43026 : return false;
166 : }
167 :
168 0 : return origin_override < rhs.origin_override;
169 : }
170 :
171 1 : bool BgpFamilyAttributesConfig::operator==(
172 : const BgpFamilyAttributesConfig &rhs) const {
173 1 : if (family != rhs.family)
174 0 : return false;
175 1 : if (loop_count != rhs.loop_count)
176 0 : return false;
177 1 : if (prefix_limit != rhs.prefix_limit)
178 0 : return false;
179 1 : if (idle_timeout != rhs.idle_timeout)
180 0 : return false;
181 1 : if (default_tunnel_encap_list != rhs.default_tunnel_encap_list)
182 0 : return false;
183 1 : return true;
184 : }
185 :
186 32032 : BgpNeighborConfig::BgpNeighborConfig()
187 32032 : : type_(UNSPECIFIED),
188 32032 : admin_down_(false),
189 32032 : passive_(false),
190 32032 : as_override_(false),
191 32032 : cluster_id_(0),
192 32032 : peer_as_(0),
193 32032 : identifier_(0),
194 32032 : port_(BgpConfigManager::kDefaultPort),
195 32032 : source_port_(0),
196 32032 : hold_time_(0),
197 32032 : loop_count_(0),
198 32032 : local_as_(0),
199 32032 : local_identifier_(0),
200 32032 : last_change_at_(UTCTimestampUsec()) {
201 32032 : }
202 :
203 1 : void BgpNeighborConfig::CopyValues(const BgpNeighborConfig &rhs) {
204 1 : instance_name_ = rhs.instance_name_;
205 1 : group_name_ = rhs.group_name_;
206 1 : type_ = rhs.type_;
207 1 : admin_down_ = rhs.admin_down_;
208 1 : passive_ = rhs.passive_;
209 1 : as_override_ = rhs.as_override_;
210 1 : private_as_action_ = rhs.private_as_action_;
211 1 : cluster_id_ = rhs.cluster_id_;
212 1 : peer_as_ = rhs.peer_as_;
213 1 : identifier_ = rhs.identifier_;
214 1 : address_ = rhs.address_;
215 1 : inet_gateway_address_ = rhs.inet_gateway_address_;
216 1 : inet6_gateway_address_ = rhs.inet6_gateway_address_;
217 1 : port_ = rhs.port_;
218 1 : source_port_ = rhs.source_port_;
219 1 : hold_time_ = rhs.hold_time_;
220 1 : loop_count_ = rhs.loop_count_;
221 1 : local_as_ = rhs.local_as_;
222 1 : local_identifier_ = rhs.local_identifier_;
223 1 : auth_data_ = rhs.auth_data_;
224 1 : family_attributes_list_ = rhs.family_attributes_list_;
225 1 : origin_override_ = rhs.origin_override_;
226 1 : }
227 :
228 21662 : int BgpNeighborConfig::CompareTo(const BgpNeighborConfig &rhs) const {
229 21662 : KEY_COMPARE(name_, rhs.name_);
230 21662 : KEY_COMPARE(uuid_, rhs.uuid_);
231 21662 : KEY_COMPARE(instance_name_, rhs.instance_name_);
232 21662 : KEY_COMPARE(type_, rhs.type_);
233 21662 : KEY_COMPARE(admin_down_, rhs.admin_down_);
234 21542 : KEY_COMPARE(passive_, rhs.passive_);
235 21518 : KEY_COMPARE(as_override_, rhs.as_override_);
236 21516 : KEY_COMPARE(origin_override_, rhs.origin_override_);
237 21516 : KEY_COMPARE(private_as_action_, rhs.private_as_action_);
238 21513 : KEY_COMPARE(cluster_id_, rhs.cluster_id_);
239 21513 : KEY_COMPARE(peer_as_, rhs.peer_as_);
240 21318 : KEY_COMPARE(identifier_, rhs.identifier_);
241 21261 : KEY_COMPARE(address_, rhs.address_);
242 21261 : KEY_COMPARE(inet_gateway_address_, rhs.inet_gateway_address_);
243 21259 : KEY_COMPARE(inet6_gateway_address_, rhs.inet6_gateway_address_);
244 21259 : KEY_COMPARE(port_, rhs.port_);
245 21258 : KEY_COMPARE(source_port_, rhs.source_port_);
246 21250 : KEY_COMPARE(hold_time_, rhs.hold_time_);
247 21142 : KEY_COMPARE(loop_count_, rhs.loop_count_);
248 21142 : KEY_COMPARE(local_as_, rhs.local_as_);
249 21053 : KEY_COMPARE(local_identifier_, rhs.local_identifier_);
250 21043 : KEY_COMPARE(auth_data_, rhs.auth_data_);
251 20982 : return STLSortedCompare(
252 : family_attributes_list_.begin(), family_attributes_list_.end(),
253 : rhs.family_attributes_list_.begin(), rhs.family_attributes_list_.end(),
254 20982 : BgpFamilyAttributesConfigCompare());
255 : }
256 :
257 29194 : void BgpNeighborConfig::SetOriginOverride(bool origin_override,
258 : std::string origin) {
259 29194 : origin_override_.origin_override = origin_override;
260 29194 : origin_override_.origin = origin;
261 29194 : }
262 :
263 407 : const IpAddress &BgpNeighborConfig::gateway_address(
264 : Address::Family family) const {
265 407 : assert(family == Address::INET || family == Address::INET6);
266 407 : if (family == Address::INET) {
267 207 : return inet_gateway_address_;
268 : } else {
269 200 : return inet6_gateway_address_;
270 : }
271 : }
272 :
273 1022 : void BgpNeighborConfig::set_gateway_address(Address::Family family,
274 : const IpAddress &address) {
275 1022 : assert(family == Address::INET || family == Address::INET6);
276 1022 : if (family == Address::INET) {
277 511 : inet_gateway_address_ = address;
278 : } else {
279 511 : inet6_gateway_address_ = address;
280 : }
281 1022 : }
282 :
283 : BgpNeighborConfig::AddressFamilyList
284 33815 : BgpNeighborConfig::GetAddressFamilies() const {
285 33815 : BgpNeighborConfig::AddressFamilyList family_list;
286 85826 : for (const auto& family_config : family_attributes_list_) {
287 52011 : family_list.push_back(family_config.family);
288 : }
289 33815 : sort(family_list.begin(), family_list.end());
290 33815 : return family_list;
291 0 : }
292 :
293 13392 : string BgpNeighborConfig::AuthKeyTypeToString() const {
294 13392 : return auth_data_.KeyTypeToString();
295 : }
296 :
297 : // Return the key's id concatenated with its type.
298 13392 : vector<string> BgpNeighborConfig::AuthKeysToString() const {
299 13392 : return auth_data_.KeysToString();
300 : }
301 :
302 :
303 415 : bool StaticRouteConfig::operator<(const StaticRouteConfig &rhs) const {
304 415 : BOOL_KEY_COMPARE(address, rhs.address);
305 14 : BOOL_KEY_COMPARE(prefix_length, rhs.prefix_length);
306 14 : BOOL_KEY_COMPARE(nexthop, rhs.nexthop);
307 0 : return false;
308 : }
309 :
310 8596 : BgpProtocolConfig::BgpProtocolConfig(const string &instance_name)
311 8596 : : instance_name_(instance_name),
312 8596 : admin_down_(false),
313 8596 : cluster_id_(0),
314 8596 : autonomous_system_(0),
315 8596 : local_autonomous_system_(0),
316 8596 : identifier_(0),
317 8596 : port_(0),
318 8596 : hold_time_(0),
319 8596 : last_change_at_(UTCTimestampUsec()) {
320 8596 : }
321 :
322 0 : int BgpProtocolConfig::CompareTo(const BgpProtocolConfig &rhs) const {
323 0 : KEY_COMPARE(instance_name_, rhs.instance_name_);
324 0 : KEY_COMPARE(admin_down_, rhs.admin_down_);
325 0 : KEY_COMPARE(autonomous_system_, rhs.autonomous_system_);
326 0 : KEY_COMPARE(identifier_, rhs.identifier_);
327 0 : KEY_COMPARE(port_, rhs.port_);
328 0 : KEY_COMPARE(hold_time_, rhs.hold_time_);
329 0 : return 0;
330 : }
331 :
332 51340 : BgpInstanceConfig::BgpInstanceConfig(const string &name)
333 51340 : : name_(name),
334 51340 : has_pnf_(false),
335 51340 : virtual_network_index_(0),
336 51340 : virtual_network_allow_transit_(false),
337 51340 : virtual_network_pbb_evpn_enable_(false),
338 51340 : index_(-1),
339 51340 : vxlan_id_(0),
340 51340 : last_change_at_(UTCTimestampUsec()) {
341 51340 : }
342 :
343 51353 : BgpInstanceConfig::~BgpInstanceConfig() {
344 51353 : }
345 :
346 124446 : void BgpInstanceConfig::Clear() {
347 124446 : import_list_.clear();
348 124446 : export_list_.clear();
349 124446 : has_pnf_ = false;
350 124446 : virtual_network_.clear();
351 124446 : virtual_network_index_ = 0;
352 124446 : virtual_network_allow_transit_ = false;
353 124446 : virtual_network_pbb_evpn_enable_ = false;
354 124446 : vxlan_id_ = 0;
355 124446 : inet_static_routes_.clear();
356 124446 : inet6_static_routes_.clear();
357 124446 : service_chain_list_.clear();
358 124446 : }
359 :
360 99535 : const BgpInstanceConfig::StaticRouteList &BgpInstanceConfig::static_routes(
361 : Address::Family family) const {
362 99535 : assert(family == Address::INET || family == Address::INET6);
363 99535 : if (family == Address::INET) {
364 49786 : return inet_static_routes_;
365 : } else {
366 49749 : return inet6_static_routes_;
367 : }
368 : }
369 :
370 8442 : void BgpInstanceConfig::swap_static_routes(Address::Family family,
371 : StaticRouteList *list) {
372 8442 : assert(family == Address::INET || family == Address::INET6);
373 8442 : if (family == Address::INET) {
374 4221 : swap(inet_static_routes_, *list);
375 : } else {
376 4221 : swap(inet6_static_routes_, *list);
377 : }
378 8442 : }
379 :
380 591492 : const ServiceChainConfig *BgpInstanceConfig::service_chain_info(
381 : SCAddress::Family family) const {
382 591492 : for (ServiceChainList::const_iterator it = service_chain_list_.begin();
383 601024 : it != service_chain_list_.end(); ++it) {
384 16887 : if (it->family == family)
385 7355 : return it.operator->();
386 : }
387 584120 : return NULL;
388 : }
389 :
390 : const BgpInstanceConfig::AggregateRouteList &
391 99587 : BgpInstanceConfig::aggregate_routes(Address::Family family) const {
392 99587 : assert(family == Address::INET || family == Address::INET6);
393 99587 : if (family == Address::INET) {
394 49884 : return inet_aggregate_routes_;
395 : } else {
396 49703 : return inet6_aggregate_routes_;
397 : }
398 : }
399 :
400 248892 : void BgpInstanceConfig::swap_aggregate_routes(Address::Family family,
401 : AggregateRouteList *list) {
402 248892 : assert(family == Address::INET || family == Address::INET6);
403 248892 : if (family == Address::INET) {
404 124446 : swap(inet_aggregate_routes_, *list);
405 : } else {
406 124446 : swap(inet6_aggregate_routes_, *list);
407 : }
408 248892 : }
409 :
410 161 : BgpRoutingPolicyConfig::BgpRoutingPolicyConfig(const string &name)
411 161 : : name_(name),
412 161 : last_change_at_(UTCTimestampUsec()) {
413 161 : }
414 :
415 161 : BgpRoutingPolicyConfig::~BgpRoutingPolicyConfig() {
416 161 : }
417 :
418 396 : void BgpRoutingPolicyConfig::Clear() {
419 396 : terms_.clear();
420 396 : }
421 :
422 10 : string RoutingPolicyMatchConfig::ToString() const {
423 10 : ostringstream oss;
424 10 : oss << "from {" << endl;
425 10 : if (!protocols_match.empty()) {
426 0 : oss << " protocol [ ";
427 0 : for (const auto &protocol : protocols_match) {
428 0 : oss << protocol << ",";
429 : }
430 0 : oss.seekp(-1, oss.cur);
431 0 : oss << " ]";
432 : }
433 10 : if (!community_match.empty()) {
434 4 : if (community_match_all) {
435 0 : oss << " community (all) [ ";
436 : } else {
437 4 : oss << " community (any) [ ";
438 : }
439 8 : for (const auto &community : community_match) {
440 4 : oss << community << ",";
441 : }
442 4 : oss.seekp(-1, oss.cur);
443 4 : oss << " ]";
444 : }
445 10 : if (!prefixes_to_match.empty()) {
446 16 : for (const auto &match : prefixes_to_match) {
447 10 : oss << " prefix " << match.prefix_to_match << " "
448 10 : << match.prefix_match_type << endl;
449 : }
450 : }
451 10 : oss << "}" << endl;
452 20 : return oss.str();
453 10 : }
454 :
455 0 : static void PutAsnList(ostringstream *oss, const AsnList &list) {
456 0 : copy(list.begin(), list.end(), ostream_iterator<uint16_t>(*oss, ","));
457 0 : oss->seekp(-1, oss->cur);
458 0 : }
459 :
460 6 : static void PutCommunityList(ostringstream *oss, const CommunityList &list) {
461 6 : copy(list.begin(), list.end(), ostream_iterator<string>(*oss, ","));
462 6 : oss->seekp(-1, oss->cur);
463 6 : }
464 :
465 10 : string RoutingPolicyActionConfig::ToString() const {
466 10 : ostringstream oss;
467 10 : oss << "then {" << endl;
468 10 : if (!update.aspath_expand.empty()) {
469 0 : oss << " as-path expand [ ";
470 0 : PutAsnList(&oss, update.aspath_expand);
471 0 : oss << " ]" << endl;
472 : }
473 10 : if (!update.community_set.empty()) {
474 2 : oss << " community set [ ";
475 2 : PutCommunityList(&oss, update.community_set);
476 2 : oss << " ]" << endl;
477 : }
478 10 : if (!update.community_add.empty()) {
479 0 : oss << " community add [ ";
480 0 : PutCommunityList(&oss, update.community_add);
481 0 : oss << " ]" << endl;
482 : }
483 10 : if (!update.community_remove.empty()) {
484 4 : oss << " community remove [ ";
485 4 : PutCommunityList(&oss, update.community_remove);
486 4 : oss << " ]" << endl;
487 : }
488 10 : if (update.local_pref) {
489 6 : oss << " local-preference " << update.local_pref << endl;
490 : }
491 10 : if (update.med) {
492 0 : oss << " med " << update.med << endl;
493 : }
494 :
495 10 : if (action == ACCEPT) {
496 2 : oss << " accept" << endl;
497 8 : } else if (action == REJECT) {
498 4 : oss << " reject" << endl;
499 4 : } else if (action == NEXT_TERM) {
500 4 : oss << " next-term" << endl;
501 : }
502 10 : oss << "}" << endl;
503 20 : return oss.str();
504 10 : }
505 :
506 9743 : BgpConfigManager::BgpConfigManager(BgpServer *server)
507 9743 : : server_(server) {
508 9743 : }
509 :
510 9743 : BgpConfigManager::~BgpConfigManager() {
511 9743 : }
512 :
513 : template<>
514 161085 : void BgpConfigManager::Notify<BgpInstanceConfig>(
515 : const BgpInstanceConfig *config, EventType event) {
516 161085 : config->set_last_change_at(UTCTimestampUsec());
517 358065 : for (auto obs : obs_) {
518 196980 : if (obs.instance) {
519 161085 : (obs.instance)(config, event);
520 : }
521 196980 : }
522 161085 : }
523 :
524 : template<>
525 439 : void BgpConfigManager::Notify<BgpRoutingPolicyConfig>(
526 : const BgpRoutingPolicyConfig *config, EventType event) {
527 439 : config->set_last_change_at(UTCTimestampUsec());
528 888 : for (auto obs : obs_) {
529 449 : if (obs.policy) {
530 439 : (obs.policy)(config, event);
531 : }
532 449 : }
533 439 : }
534 :
535 : template<>
536 9050 : void BgpConfigManager::Notify<BgpProtocolConfig>(
537 : const BgpProtocolConfig *config, EventType event) {
538 9050 : config->set_last_change_at(UTCTimestampUsec());
539 20786 : for (auto obs : obs_) {
540 11736 : if (obs.protocol) {
541 11736 : (obs.protocol)(config, event);
542 : }
543 11736 : }
544 9050 : }
545 :
546 : template<>
547 16900 : void BgpConfigManager::Notify<BgpNeighborConfig>(
548 : const BgpNeighborConfig *config, EventType event) {
549 16900 : config->set_last_change_at(UTCTimestampUsec());
550 37162 : for (auto obs : obs_) {
551 20262 : if (obs.neighbor) {
552 16900 : (obs.neighbor)(config, event);
553 : }
554 20262 : }
555 16900 : }
556 :
557 : template<>
558 840 : void BgpConfigManager::Notify<BgpGlobalSystemConfig>(
559 : const BgpGlobalSystemConfig *config, EventType event) {
560 840 : config->set_last_change_at(UTCTimestampUsec());
561 2147 : for (auto obs : obs_) {
562 1307 : if (obs.system) {
563 1307 : (obs.system)(config, event);
564 : }
565 1307 : }
566 840 : }
567 :
568 : template<>
569 9 : void BgpConfigManager::Notify<BgpGlobalQosConfig>(
570 : const BgpGlobalQosConfig *config, EventType event) {
571 9 : config->set_last_change_at(UTCTimestampUsec());
572 25 : for (auto obs : obs_) {
573 16 : if (obs.qos) {
574 9 : (obs.qos)(config, event);
575 : }
576 16 : }
577 9 : }
|