Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #include "bgp/community.h"
6 :
7 : #include <boost/foreach.hpp>
8 :
9 : #include <algorithm>
10 : #include <string>
11 : #include <map>
12 :
13 : #include "base/string_util.h"
14 : #include "bgp/bgp_proto.h"
15 : #include "bgp/extended-community/tag.h"
16 : #include "bgp/extended-community/default_gateway.h"
17 : #include "bgp/extended-community/es_import.h"
18 : #include "bgp/extended-community/esi_label.h"
19 : #include "bgp/extended-community/etree.h"
20 : #include "bgp/extended-community/load_balance.h"
21 : #include "bgp/extended-community/mac_mobility.h"
22 : #include "bgp/extended-community/local_sequence_number.h"
23 : #include "bgp/extended-community/router_mac.h"
24 : #include "bgp/extended-community/site_of_origin.h"
25 : #include "bgp/extended-community/source_as.h"
26 : #include "bgp/extended-community/sub_cluster.h"
27 : #include "bgp/extended-community/tag.h"
28 : #include "bgp/extended-community/vrf_route_import.h"
29 : #include "bgp/large-community/tag.h"
30 : #include "bgp/tunnel_encap/tunnel_encap.h"
31 : #include "bgp/origin-vn/origin_vn.h"
32 : #include "bgp/rtarget/rtarget_address.h"
33 : #include "bgp/security_group/security_group.h"
34 : #include "bgp/tunnel_encap/tunnel_encap.h"
35 : #include "net/community_type.h"
36 :
37 : using std::sort;
38 : using std::string;
39 : using std::unique;
40 : using std::vector;
41 :
42 4246 : void CommunitySpec::ToCanonical(BgpAttr *attr) {
43 4246 : attr->set_community(this);
44 4246 : }
45 :
46 3971 : string CommunitySpec::ToString() const {
47 3971 : string repr;
48 : char start[32];
49 3971 : snprintf(start, sizeof(start), "Communities: %zu [", communities.size());
50 3971 : repr += start;
51 :
52 7952 : for (size_t i = 0; i < communities.size(); ++i) {
53 : char community[12];
54 3981 : snprintf(community, sizeof(community), " %X", communities[i]);
55 3981 : repr += community;
56 : }
57 3971 : repr += " ]";
58 :
59 7942 : return repr;
60 0 : }
61 :
62 5618 : Community::Community(CommunityDB *comm_db, const CommunitySpec spec)
63 5618 : : comm_db_(comm_db), communities_(spec.communities) {
64 5616 : refcount_ = 0;
65 5620 : sort(communities_.begin(), communities_.end());
66 : vector<uint32_t>::iterator it =
67 5618 : unique(communities_.begin(), communities_.end());
68 5616 : communities_.erase(it, communities_.end());
69 5614 : }
70 :
71 498496 : int Community::CompareTo(const Community &rhs) const {
72 498496 : KEY_COMPARE(communities_, rhs.communities_);
73 497294 : return 0;
74 : }
75 :
76 22808 : size_t CommunitySpec::EncodeLength() const {
77 22808 : return communities.size() * sizeof(uint32_t);
78 : }
79 :
80 23442 : void Community::Append(uint32_t value) {
81 23442 : if (ContainsValue(value))
82 897 : return;
83 22545 : communities_.push_back(value);
84 22545 : sort(communities_.begin(), communities_.end());
85 : }
86 :
87 31 : void Community::Append(const std::vector<uint32_t> &communities) {
88 66 : for (auto community : communities) {
89 35 : communities_.push_back(community);
90 : }
91 31 : sort(communities_.begin(), communities_.end());
92 : vector<uint32_t>::iterator it =
93 31 : unique(communities_.begin(), communities_.end());
94 31 : communities_.erase(it, communities_.end());
95 31 : }
96 :
97 7 : void Community::Set(const std::vector<uint32_t> &communities) {
98 7 : communities_.clear();
99 26 : for (auto community : communities) {
100 19 : communities_.push_back(community);
101 : }
102 7 : }
103 :
104 13 : void Community::Remove(const std::vector<uint32_t> &communities) {
105 30 : for (auto community : communities) {
106 34 : communities_.erase(
107 17 : std::remove(communities_.begin(), communities_.end(), community),
108 34 : communities_.end());
109 : }
110 13 : }
111 2359 : void Community::Remove() {
112 2359 : comm_db_->Delete(this);
113 2359 : }
114 :
115 114848 : bool Community::ContainsValue(uint32_t value) const {
116 192936 : for (auto community : communities_) {
117 93168 : if (community == value)
118 15080 : return true;
119 : }
120 99784 : return false;
121 : }
122 :
123 194 : void Community::BuildStringList(vector<string> *list) const {
124 402 : for (auto community : communities_) {
125 208 : string name = CommunityType::CommunityToString(community);
126 208 : list->push_back(name);
127 208 : }
128 194 : }
129 :
130 9742 : CommunityDB::CommunityDB(BgpServer *server) {
131 9742 : }
132 :
133 23442 : CommunityPtr CommunityDB::AppendAndLocate(const Community *src,
134 : uint32_t value) {
135 : Community *clone;
136 23442 : if (src) {
137 937 : clone = new Community(*src);
138 : } else {
139 22505 : clone = new Community(this);
140 : }
141 :
142 23442 : clone->Append(value);
143 23442 : return Locate(clone);
144 : }
145 :
146 31 : CommunityPtr CommunityDB::AppendAndLocate(const Community *src,
147 : const std::vector<uint32_t> &value) {
148 : Community *clone;
149 31 : if (src) {
150 30 : clone = new Community(*src);
151 : } else {
152 1 : clone = new Community(this);
153 : }
154 :
155 31 : clone->Append(value);
156 31 : return Locate(clone);
157 : }
158 :
159 7 : CommunityPtr CommunityDB::SetAndLocate(const Community *src,
160 : const std::vector<uint32_t> &value) {
161 : Community *clone;
162 7 : if (src) {
163 6 : clone = new Community(*src);
164 : } else {
165 1 : clone = new Community(this);
166 : }
167 :
168 7 : clone->Set(value);
169 7 : return Locate(clone);
170 : }
171 :
172 13 : CommunityPtr CommunityDB::RemoveAndLocate(const Community *src,
173 : const std::vector<uint32_t> &value) {
174 : Community *clone;
175 13 : if (src) {
176 13 : clone = new Community(*src);
177 : } else {
178 0 : clone = new Community(this);
179 : }
180 :
181 13 : clone->Remove(value);
182 13 : return Locate(clone);
183 : }
184 :
185 8 : CommunityPtr CommunityDB::RemoveAndLocate(const Community *src,
186 : uint32_t value) {
187 8 : Community::CommunityList communities;
188 8 : communities.push_back(value);
189 16 : return RemoveAndLocate(src, communities);
190 8 : }
191 :
192 90847 : string ExtCommunitySpec::ToString() const {
193 : char repr[80];
194 90847 : snprintf(repr, sizeof(repr), "ExtCommunity <code: %d, flags: %02x>:%d",
195 90847 : code, flags, (uint32_t)communities.size());
196 90847 : return string(repr);
197 : }
198 :
199 184389 : LargeCommunitySpec LargeCommunitySpec::FromTag(
200 : const ExtCommunitySpec &ex_spec) {
201 184389 : LargeCommunitySpec large_spec;
202 : using extcomm_iterator = decltype(large_spec.communities)::iterator;
203 184389 : std::map<uint16_t, extcomm_iterator> tno_vs_tspec;
204 184389 : std::vector<std::pair<uint32_t,uint16_t> > asn4_vs_tno;
205 184389 : const uint64_t ExtCommTag = uint64_t(
206 : (BgpExtendedCommunityType::Experimental << 8) |
207 : (BgpExtendedCommunityExperimentalSubType::Tag)) << 48;
208 184389 : const uint64_t ExtCommTag4 = uint64_t(
209 : (BgpExtendedCommunityType::Experimental4ByteAs << 8) |
210 : (BgpExtendedCommunityExperimentalSubType::Tag)) << 48;
211 : uint16_t asn_or_tno;
212 : uint32_t asn4;
213 : uint16_t tno;
214 1370635 : for (const auto &val64 : ex_spec.communities) {
215 1186246 : if ((0xFFFF000000000000 & val64) == ExtCommTag) {
216 8 : asn_or_tno = (0x0000FFFF00000000 & val64) >> 32;
217 : std::vector<uint32_t> large_comm = {
218 8 : asn_or_tno,
219 8 : 0x01000000 | uint32_t((val64 & 0x00000000FFFF0000) >> 16),
220 8 : uint32_t(val64 & 0x000000000000FFFF)
221 8 : };
222 16 : extcomm_iterator it_tspec = large_spec.communities.insert(
223 8 : large_spec.communities.end(),
224 : large_comm.begin(),
225 : large_comm.end());
226 8 : tno_vs_tspec.insert({asn_or_tno,
227 : it_tspec});
228 8 : continue;
229 8 : }
230 :
231 1186238 : if ((0xFFFF000000000000 & val64) == ExtCommTag4) {
232 0 : asn4 = (0x0000FFFFFFFF0000 & val64) >> 16;
233 0 : tno = (0x000000000000FFFF & val64);
234 0 : asn4_vs_tno.push_back({asn4, tno});
235 : }
236 : }
237 : // loop over all 4-byte ASNs and modify their value in large_spec
238 184383 : for(const auto &[asn4, tno] : asn4_vs_tno) {
239 0 : auto &large_comm_asn = tno_vs_tspec[tno];
240 0 : if (large_comm_asn == large_spec.communities.end()) {
241 0 : continue;
242 : }
243 0 : *large_comm_asn = asn4;
244 : }
245 368772 : return large_spec;
246 184387 : }
247 :
248 4 : ExtCommunitySpec LargeCommunitySpec::RemoveTags(
249 : const ExtCommunitySpec& ex_spec) {
250 4 : const uint64_t ExtCommTag = uint64_t(
251 : (BgpExtendedCommunityType::Experimental << 8) |
252 : (BgpExtendedCommunityExperimentalSubType::Tag)) << 48;
253 4 : const uint64_t ExtCommTag4 = uint64_t(
254 : (BgpExtendedCommunityType::Experimental4ByteAs << 8) |
255 : (BgpExtendedCommunityExperimentalSubType::Tag)) << 48;
256 4 : ExtCommunitySpec new_ex_spec;
257 32 : for (const auto &val64 : ex_spec.communities) {
258 28 : if ((0xFFFF000000000000 & val64) != ExtCommTag &&
259 20 : (0xFFFF000000000000 & val64) != ExtCommTag4) {
260 20 : new_ex_spec.communities.push_back(val64);
261 : }
262 : }
263 4 : return new_ex_spec;
264 0 : }
265 :
266 395354 : size_t ExtCommunitySpec::EncodeLength() const {
267 395354 : return communities.size() * sizeof(uint64_t);
268 : }
269 :
270 1941 : int ExtCommunitySpec::CompareTo(const BgpAttribute &rhs_attr) const {
271 1941 : int ret = BgpAttribute::CompareTo(rhs_attr);
272 1941 : if (ret != 0) return ret;
273 1941 : KEY_COMPARE(communities,
274 : static_cast<const ExtCommunitySpec &>(rhs_attr).communities);
275 1941 : return 0;
276 : }
277 :
278 184348 : void ExtCommunitySpec::ToCanonical(BgpAttr *attr) {
279 184348 : attr->set_ext_community(this);
280 184350 : }
281 :
282 2175 : void ExtCommunitySpec::AddTunnelEncaps(vector<string> encaps) {
283 2365 : for (vector<string>::size_type i = 0; i < encaps.size(); i++) {
284 190 : string encap_str = encaps[i];
285 190 : TunnelEncap tun_encap(encap_str);
286 190 : communities.push_back(tun_encap.GetExtCommunityValue());
287 190 : }
288 2175 : }
289 :
290 5385730 : int ExtCommunity::CompareTo(const ExtCommunity &rhs) const {
291 5385730 : KEY_COMPARE(communities_.size(), rhs.communities_.size());
292 :
293 3873544 : ExtCommunityList::const_iterator i, j;
294 3873544 : for (i = communities_.begin(), j = rhs.communities_.begin();
295 12183911 : i < communities_.end(); ++i, ++j) {
296 9401146 : if (*i < *j) {
297 659019 : return -1;
298 : }
299 8742221 : if (*i > *j) {
300 431825 : return 1;
301 : }
302 : }
303 2782739 : return 0;
304 : }
305 :
306 6 : void ExtCommunity::Remove(const ExtCommunityList &list) {
307 6 : for (ExtCommunityList::const_iterator it = list.begin();
308 18 : it != list.end(); ++it) {
309 24 : communities_.erase(std::remove(communities_.begin(),
310 36 : communities_.end(), *it), communities_.end());
311 : }
312 6 : }
313 184217 : void ExtCommunity::Remove() {
314 184217 : extcomm_db_->Delete(this);
315 184217 : }
316 :
317 41 : void ExtCommunity::Set(const ExtCommunityList &list) {
318 41 : communities_.clear();
319 41 : for (ExtCommunityList::const_iterator it = list.begin();
320 155 : it != list.end(); ++it) {
321 114 : communities_.push_back(*it);
322 : }
323 41 : }
324 :
325 424750 : void ExtCommunity::Append(const ExtCommunityList &list) {
326 424750 : communities_.insert(communities_.end(), list.begin(), list.end());
327 424689 : sort(communities_.begin(), communities_.end());
328 : ExtCommunityList::iterator it =
329 424701 : unique(communities_.begin(), communities_.end());
330 424710 : communities_.erase(it, communities_.end());
331 424695 : }
332 :
333 73122 : void ExtCommunity::Append(const ExtCommunityValue &value) {
334 73122 : communities_.push_back(value);
335 73122 : sort(communities_.begin(), communities_.end());
336 : ExtCommunityList::iterator it =
337 73119 : unique(communities_.begin(), communities_.end());
338 73120 : communities_.erase(it, communities_.end());
339 73119 : }
340 :
341 13 : ExtCommunity::ExtCommunityValue ExtCommunity::FromHexString(
342 : const string &comm, boost::system::error_code *errorp) {
343 : ExtCommunityValue data;
344 13 : put_value(&data[0], 8, 0);
345 : char *end;
346 13 : uint64_t value = strtoull(comm.c_str(), &end, 16);
347 13 : if (value == 0 || *end) {
348 : // e.g. 0 or 12x34ff (invalid hex)
349 4 : if (errorp != NULL) {
350 4 : *errorp = make_error_code(
351 : boost::system::errc::invalid_argument);
352 4 : return data;
353 : }
354 : }
355 9 : if (comm[0] == '0' && (comm[1] == 'x' || comm[1] == 'X')) {
356 5 : if (comm.length() > 18 && errorp != NULL) {
357 : // e.g. 0xabcdef0123456789f is an invalid 8byte hex value
358 1 : *errorp = make_error_code(
359 : boost::system::errc::invalid_argument);
360 1 : return data;
361 : }
362 : } else {
363 4 : if (comm.length() > 16 && errorp != NULL) {
364 : // e.g. abcdef0123456789f is an invalid 8byte hex value
365 1 : *errorp = make_error_code(
366 : boost::system::errc::invalid_argument);
367 1 : return data;
368 : }
369 : }
370 7 : put_value(&data[0], 8, value);
371 7 : return data;
372 : }
373 :
374 371 : ExtCommunity::ExtCommunityList ExtCommunity::ExtCommunityFromString(
375 : const string &comm) {
376 371 : ExtCommunityList commList;
377 : ExtCommunityValue value;
378 371 : size_t pos = comm.find(':');
379 371 : string first(comm.substr(0, pos));
380 371 : boost::system::error_code error;
381 371 : if (first == "soo") {
382 0 : SiteOfOrigin soo = SiteOfOrigin::FromString(comm, &error);
383 0 : if (error) {
384 0 : return commList;
385 : }
386 0 : commList.push_back(soo.GetExtCommunity());
387 371 : } else if (first == "target") {
388 357 : RouteTarget rt = RouteTarget::FromString(comm, &error);
389 357 : if (error) {
390 98 : return commList;
391 : }
392 259 : commList.push_back(rt.GetExtCommunity());
393 14 : } else if (first == "source-as") {
394 0 : SourceAs sas = SourceAs::FromString(comm, &error);
395 0 : if (error) {
396 0 : return commList;
397 : }
398 0 : commList.push_back(sas.GetExtCommunity());
399 14 : } else if (first == "rt-import") {
400 0 : VrfRouteImport vit = VrfRouteImport::FromString(comm, &error);
401 0 : if (error) {
402 0 : return commList;
403 : }
404 0 : commList.push_back(vit.GetExtCommunity());
405 14 : } else if (first == "subcluster") {
406 1 : SubCluster sc = SubCluster::FromString(comm, &error);
407 1 : if (error) {
408 0 : return commList;
409 : }
410 1 : commList.push_back(sc.GetExtCommunity());
411 : } else {
412 13 : value = FromHexString(comm, &error);
413 13 : if (error) {
414 6 : return commList;
415 : }
416 7 : commList.push_back(value);
417 : }
418 267 : return commList;
419 371 : }
420 :
421 106 : string ExtCommunity::ToHexString(const ExtCommunityValue &comm) {
422 : char temp[50];
423 106 : int len = 0;
424 954 : for (size_t i = 0; i < comm.size(); i++) {
425 848 : len += snprintf(temp+len, sizeof(temp) - len, "%02x", (comm)[i]);
426 : }
427 106 : return(string(temp));
428 : }
429 :
430 223 : string ExtCommunity::ToString(const ExtCommunityValue &comm) {
431 223 : if (is_route_target(comm)) {
432 217 : RouteTarget rt(comm);
433 217 : return(rt.ToString());
434 6 : } else if (is_default_gateway(comm)) {
435 0 : DefaultGateway dgw(comm);
436 0 : return(dgw.ToString());
437 6 : } else if (is_es_import(comm)) {
438 0 : EsImport es_import(comm);
439 0 : return(es_import.ToString());
440 6 : } else if (is_esi_label(comm)) {
441 0 : EsiLabel esi_label(comm);
442 0 : return(esi_label.ToString());
443 6 : } else if (is_mac_mobility(comm)) {
444 0 : MacMobility mm(comm);
445 0 : return(mm.ToString());
446 6 : } else if (is_local_sequence_number(comm)) {
447 0 : LocalSequenceNumber lsn(comm);
448 0 : return lsn.ToString();
449 6 : } else if (is_etree(comm)) {
450 0 : ETree etree(comm);
451 0 : return(etree.ToString());
452 6 : } else if (is_router_mac(comm)) {
453 0 : RouterMac router_mac(comm);
454 0 : return(router_mac.ToString());
455 6 : } else if (is_origin_vn(comm)) {
456 0 : OriginVn origin_vn(comm);
457 0 : return(origin_vn.ToString());
458 6 : } else if (is_security_group(comm)) {
459 0 : SecurityGroup sg(comm);
460 0 : return(sg.ToString());
461 6 : } else if (is_site_of_origin(comm)) {
462 0 : SiteOfOrigin soo(comm);
463 0 : return(soo.ToString());
464 6 : } else if (is_tunnel_encap(comm)) {
465 0 : TunnelEncap encap(comm);
466 0 : return(encap.ToString());
467 6 : } else if (is_load_balance(comm)) {
468 0 : LoadBalance load_balance(comm);
469 0 : return(load_balance.ToString());
470 6 : } else if (is_tag(comm)) {
471 0 : Tag tag(comm);
472 0 : return(tag.ToString());
473 6 : } else if (is_source_as(comm)) {
474 0 : SourceAs sas(comm);
475 0 : return(sas.ToString());
476 6 : } else if (is_vrf_route_import(comm)) {
477 0 : VrfRouteImport rt_import(comm);
478 0 : return(rt_import.ToString());
479 6 : } else if (is_sub_cluster(comm)) {
480 3 : SubCluster sc(comm);
481 3 : return(sc.ToString());
482 : }
483 3 : return ToHexString(comm);
484 : }
485 :
486 4 : bool ExtCommunity::ContainsRTarget(const ExtCommunityValue &val) const {
487 4 : for (ExtCommunityList::const_iterator it = communities_.begin();
488 4 : it != communities_.end(); ++it) {
489 4 : if (ExtCommunity::is_route_target(*it) && *it == val)
490 4 : return true;
491 : }
492 0 : return false;
493 : }
494 :
495 96793 : bool ExtCommunity::ContainsOriginVn(const ExtCommunityValue &val) const {
496 96793 : for (ExtCommunityList::const_iterator it = communities_.begin();
497 823104 : it != communities_.end(); ++it) {
498 733413 : if (ExtCommunity::is_origin_vn(*it) && *it == val)
499 7101 : return true;
500 : }
501 89692 : return false;
502 : }
503 :
504 96793 : bool ExtCommunity::ContainsOriginVn(as_t asn, uint32_t vn_index) const {
505 : if (asn <= 0xffffffff) {
506 96793 : OriginVn origin_vn(asn, vn_index);
507 96793 : return ContainsOriginVn(origin_vn.GetExtCommunity());
508 : }
509 : OriginVn origin_vn4(asn, AS_TRANS);
510 : OriginVn origin_vn(AS_TRANS, vn_index);
511 : return (ContainsOriginVn(origin_vn.GetExtCommunity()) &&
512 : ContainsOriginVn(origin_vn4.GetExtCommunity()));
513 : }
514 :
515 80 : bool ExtCommunity::ContainsSourceAs(const ExtCommunityValue &val) const {
516 80 : for (ExtCommunityList::const_iterator it = communities_.begin();
517 168 : it != communities_.end(); ++it) {
518 168 : if (ExtCommunity::is_source_as(*it) && *it == val)
519 80 : return true;
520 : }
521 0 : return false;
522 : }
523 :
524 387025 : uint32_t ExtCommunity::GetSubClusterId() const {
525 387025 : for (ExtCommunityList::const_iterator it = communities_.begin();
526 2880639 : it != communities_.end(); ++it) {
527 2493625 : if (ExtCommunity::is_sub_cluster(*it)) {
528 2 : SubCluster sc(*it);
529 2 : return sc.GetId();
530 : }
531 : }
532 386996 : return 0;
533 : }
534 :
535 80 : bool ExtCommunity::ContainsVrfRouteImport(const ExtCommunityValue &val) const {
536 80 : for (ExtCommunityList::const_iterator it = communities_.begin();
537 248 : it != communities_.end(); ++it) {
538 248 : if (ExtCommunity::is_vrf_route_import(*it) && *it == val)
539 80 : return true;
540 : }
541 0 : return false;
542 : }
543 :
544 19807 : void ExtCommunity::RemoveMFlags() {
545 19807 : for (ExtCommunityList::iterator it = communities_.begin();
546 45881 : it != communities_.end(); ) {
547 26074 : if (ExtCommunity::is_multicast_flags(*it)) {
548 0 : it = communities_.erase(it);
549 : } else {
550 26074 : ++it;
551 : }
552 : }
553 19807 : }
554 :
555 32503 : void ExtCommunity::RemoveRTarget() {
556 32503 : for (ExtCommunityList::iterator it = communities_.begin();
557 81677 : it != communities_.end(); ) {
558 49174 : if (ExtCommunity::is_route_target(*it)) {
559 25351 : it = communities_.erase(it);
560 : } else {
561 23823 : ++it;
562 : }
563 : }
564 32503 : }
565 :
566 24140 : void ExtCommunity::RemoveSGID() {
567 24140 : for (ExtCommunityList::iterator it = communities_.begin();
568 43895 : it != communities_.end(); ) {
569 35824 : if (ExtCommunity::is_security_group(*it) ||
570 16069 : ExtCommunity::is_security_group4(*it)) {
571 3686 : it = communities_.erase(it);
572 : } else {
573 16069 : ++it;
574 : }
575 : }
576 24140 : }
577 :
578 0 : void ExtCommunity::RemoveTag() {
579 0 : for (ExtCommunityList::iterator it = communities_.begin();
580 0 : it != communities_.end(); ) {
581 0 : if (ExtCommunity::is_tag(*it) || ExtCommunity::is_tag4(*it)) {
582 0 : it = communities_.erase(it);
583 : } else {
584 0 : ++it;
585 : }
586 : }
587 0 : }
588 :
589 18862 : void ExtCommunity::RemoveSiteOfOrigin() {
590 18862 : for (ExtCommunityList::iterator it = communities_.begin();
591 37671 : it != communities_.end(); ) {
592 18809 : if (ExtCommunity::is_site_of_origin(*it)) {
593 0 : it = communities_.erase(it);
594 : } else {
595 18809 : ++it;
596 : }
597 : }
598 18862 : }
599 :
600 385 : void ExtCommunity::RemoveSourceAS() {
601 385 : for (ExtCommunityList::iterator it = communities_.begin();
602 1908 : it != communities_.end(); ) {
603 1523 : if (ExtCommunity::is_source_as(*it)) {
604 156 : it = communities_.erase(it);
605 : } else {
606 1367 : ++it;
607 : }
608 : }
609 385 : }
610 114 : void ExtCommunity::RemoveVrfRouteImport() {
611 114 : for (ExtCommunityList::iterator it = communities_.begin();
612 242 : it != communities_.end(); ) {
613 128 : if (ExtCommunity::is_vrf_route_import(*it)) {
614 0 : it = communities_.erase(it);
615 : } else {
616 128 : ++it;
617 : }
618 : }
619 114 : }
620 :
621 243249 : void ExtCommunity::RemoveOriginVn() {
622 243249 : for (ExtCommunityList::iterator it = communities_.begin();
623 1796614 : it != communities_.end(); ) {
624 1553406 : if (ExtCommunity::is_origin_vn(*it))
625 15297 : it = communities_.erase(it);
626 : else
627 1538085 : ++it;
628 : }
629 243166 : }
630 :
631 17794 : void ExtCommunity::RemoveTunnelEncapsulation() {
632 17794 : for (ExtCommunityList::iterator it = communities_.begin();
633 36974 : it != communities_.end(); ) {
634 19180 : if (ExtCommunity::is_tunnel_encap(*it)) {
635 171 : it = communities_.erase(it);
636 : } else {
637 19009 : ++it;
638 : }
639 : }
640 17794 : }
641 :
642 8 : void ExtCommunity::RemoveLoadBalance() {
643 8 : for (ExtCommunityList::iterator it = communities_.begin();
644 8 : it != communities_.end(); ) {
645 0 : if (ExtCommunity::is_load_balance(*it)) {
646 0 : it = communities_.erase(it);
647 : } else {
648 0 : ++it;
649 : }
650 : }
651 8 : }
652 :
653 1 : void ExtCommunity::RemoveSubCluster() {
654 1 : for (ExtCommunityList::iterator it = communities_.begin();
655 2 : it != communities_.end(); ) {
656 1 : if (ExtCommunity::is_sub_cluster(*it)) {
657 1 : it = communities_.erase(it);
658 : } else {
659 0 : ++it;
660 : }
661 : }
662 1 : }
663 :
664 474591 : vector<string> ExtCommunity::GetTunnelEncap() const {
665 474591 : vector<string> encap_list;
666 474614 : for (ExtCommunityList::const_iterator iter = communities_.begin();
667 3303611 : iter != communities_.end(); ++iter) {
668 2828983 : if (!ExtCommunity::is_tunnel_encap(*iter))
669 2353900 : continue;
670 475051 : TunnelEncap encap(*iter);
671 475060 : if (encap.tunnel_encap() == TunnelEncapType::UNSPEC)
672 0 : continue;
673 475038 : encap_list.push_back(encap.ToXmppString());
674 : }
675 :
676 474684 : sort(encap_list.begin(), encap_list.end());
677 : vector<string>::iterator encap_iter =
678 474671 : unique(encap_list.begin(), encap_list.end());
679 474646 : encap_list.erase(encap_iter, encap_list.end());
680 949232 : return encap_list;
681 0 : }
682 :
683 0 : vector<int> ExtCommunity::GetTagList(as2_t asn) const {
684 0 : vector<int> tag_list;
685 0 : for (ExtCommunityList::const_iterator iter = communities_.begin();
686 0 : iter != communities_.end(); ++iter) {
687 0 : if (!ExtCommunity::is_tag(*iter))
688 0 : continue;
689 0 : Tag tag_comm(*iter);
690 0 : if (asn && tag_comm.as_number() != asn && !tag_comm.IsGlobal())
691 0 : continue;
692 0 : tag_list.push_back(tag_comm.tag());
693 : }
694 :
695 0 : sort(tag_list.begin(), tag_list.end());
696 0 : vector<int>::iterator tag_iter = unique(tag_list.begin(), tag_list.end());
697 0 : tag_list.erase(tag_iter, tag_list.end());
698 0 : return tag_list;
699 0 : }
700 :
701 0 : vector<int> ExtCommunity::GetTag4List(as_t asn) const {
702 0 : vector<int> tag_list;
703 0 : for (ExtCommunityList::const_iterator iter = communities_.begin();
704 0 : iter != communities_.end(); ++iter) {
705 0 : if (!ExtCommunity::is_tag4(*iter))
706 0 : continue;
707 0 : Tag4ByteAs tag_comm(*iter);
708 0 : if (asn && tag_comm.as_number() != asn && !tag_comm.IsGlobal())
709 0 : continue;
710 0 : vector<int> matching_tag_list = GetTagList(tag_comm.tag());
711 0 : tag_list.insert(tag_list.end(), matching_tag_list.begin(),
712 : matching_tag_list.end());
713 0 : tag_list.push_back(tag_comm.tag());
714 0 : }
715 0 : if ((asn <= 0xffff) && tag_list.size() == 0)
716 0 : tag_list = GetTagList(asn);
717 :
718 0 : sort(tag_list.begin(), tag_list.end());
719 0 : vector<int>::iterator tag_iter = unique(tag_list.begin(), tag_list.end());
720 0 : tag_list.erase(tag_iter, tag_list.end());
721 0 : return tag_list;
722 0 : }
723 :
724 139788 : bool ExtCommunity::ContainsTunnelEncapVxlan() const {
725 139788 : for (ExtCommunityList::const_iterator iter = communities_.begin();
726 1970807 : iter != communities_.end(); ++iter) {
727 1831461 : if (!ExtCommunity::is_tunnel_encap(*iter))
728 1659139 : continue;
729 172337 : TunnelEncap encap(*iter);
730 172336 : if (encap.tunnel_encap() == TunnelEncapType::VXLAN)
731 448 : return true;
732 : }
733 139326 : return false;
734 : }
735 :
736 448899 : int ExtCommunity::GetOriginVnIndex() const {
737 448899 : for (ExtCommunityList::const_iterator iter = communities_.begin();
738 3168113 : iter != communities_.end(); ++iter) {
739 2749962 : if (ExtCommunity::is_origin_vn(*iter)) {
740 30770 : OriginVn origin_vn(*iter);
741 30769 : return origin_vn.vn_index();
742 : }
743 : }
744 418184 : return -1;
745 : }
746 :
747 191012 : ExtCommunity::ExtCommunity(ExtCommunityDB *extcomm_db,
748 191012 : const ExtCommunitySpec spec) : extcomm_db_(extcomm_db) {
749 191013 : refcount_ = 0;
750 191028 : for (vector<uint64_t>::const_iterator it = spec.communities.begin();
751 1382724 : it < spec.communities.end(); ++it) {
752 : ExtCommunityValue comm;
753 1191701 : put_value(comm.data(), comm.size(), *it);
754 1191707 : communities_.push_back(comm);
755 : }
756 191022 : sort(communities_.begin(), communities_.end());
757 : ExtCommunityList::iterator it =
758 191021 : unique(communities_.begin(), communities_.end());
759 191020 : communities_.erase(it, communities_.end());
760 191016 : }
761 :
762 9742 : ExtCommunityDB::ExtCommunityDB(BgpServer *server) {
763 9742 : }
764 :
765 330454 : ExtCommunityPtr ExtCommunityDB::AppendAndLocate(const ExtCommunity *src,
766 : const ExtCommunity::ExtCommunityList &list) {
767 : ExtCommunity *clone;
768 330454 : if (src) {
769 188721 : clone = new ExtCommunity(*src);
770 : } else {
771 141733 : clone = new ExtCommunity(this);
772 : }
773 :
774 330508 : clone->Append(list);
775 330457 : return Locate(clone);
776 : }
777 :
778 64 : ExtCommunityPtr ExtCommunityDB::AppendAndLocate(const ExtCommunity *src,
779 : const ExtCommunity::ExtCommunityValue &value) {
780 64 : ExtCommunity::ExtCommunityList list;
781 64 : list.push_back(value);
782 128 : return AppendAndLocate(src, list);
783 64 : }
784 :
785 6 : ExtCommunityPtr ExtCommunityDB::RemoveAndLocate(const ExtCommunity *src,
786 : const ExtCommunity::ExtCommunityList &list) {
787 : ExtCommunity *clone;
788 6 : if (src) {
789 5 : clone = new ExtCommunity(*src);
790 : } else {
791 1 : clone = new ExtCommunity(this);
792 : }
793 :
794 6 : clone->Remove(list);
795 6 : return Locate(clone);
796 : }
797 :
798 19807 : ExtCommunityPtr ExtCommunityDB::ReplaceMFlagsAndLocate(const ExtCommunity *src,
799 : const ExtCommunity::ExtCommunityList &export_list) {
800 : ExtCommunity *clone;
801 19807 : if (src) {
802 19807 : clone = new ExtCommunity(*src);
803 : } else {
804 0 : clone = new ExtCommunity(this);
805 : }
806 :
807 19807 : clone->RemoveMFlags();
808 19807 : clone->Append(export_list);
809 19807 : return Locate(clone);
810 : }
811 :
812 32503 : ExtCommunityPtr ExtCommunityDB::ReplaceRTargetAndLocate(const ExtCommunity *src,
813 : const ExtCommunity::ExtCommunityList &export_list) {
814 : ExtCommunity *clone;
815 32503 : if (src) {
816 27196 : clone = new ExtCommunity(*src);
817 : } else {
818 5307 : clone = new ExtCommunity(this);
819 : }
820 :
821 32503 : clone->RemoveRTarget();
822 32503 : clone->Append(export_list);
823 32503 : return Locate(clone);
824 : }
825 :
826 24140 : ExtCommunityPtr ExtCommunityDB::ReplaceSGIDListAndLocate(
827 : const ExtCommunity *src,
828 : const ExtCommunity::ExtCommunityList &sgid_list) {
829 : ExtCommunity *clone;
830 24140 : if (src) {
831 24140 : clone = new ExtCommunity(*src);
832 : } else {
833 0 : clone = new ExtCommunity(this);
834 : }
835 :
836 24140 : clone->RemoveSGID();
837 24140 : clone->Append(sgid_list);
838 24137 : return Locate(clone);
839 : }
840 :
841 0 : ExtCommunityPtr ExtCommunityDB::ReplaceTagListAndLocate(
842 : const ExtCommunity *src,
843 : const ExtCommunity::ExtCommunityList &tag_list) {
844 : ExtCommunity *clone;
845 0 : if (src) {
846 0 : clone = new ExtCommunity(*src);
847 : } else {
848 0 : clone = new ExtCommunity(this);
849 : }
850 :
851 0 : clone->RemoveTag();
852 0 : clone->Append(tag_list);
853 0 : return Locate(clone);
854 : }
855 :
856 18658 : ExtCommunityPtr ExtCommunityDB::RemoveSiteOfOriginAndLocate(
857 : const ExtCommunity *src) {
858 : ExtCommunity *clone;
859 18658 : if (src) {
860 18658 : clone = new ExtCommunity(*src);
861 : } else {
862 0 : clone = new ExtCommunity(this);
863 : }
864 :
865 18658 : clone->RemoveSiteOfOrigin();
866 18658 : return Locate(clone);
867 : }
868 :
869 204 : ExtCommunityPtr ExtCommunityDB::ReplaceSiteOfOriginAndLocate(
870 : const ExtCommunity *src,
871 : const ExtCommunity::ExtCommunityValue &soo) {
872 : ExtCommunity *clone;
873 204 : if (src) {
874 204 : clone = new ExtCommunity(*src);
875 : } else {
876 0 : clone = new ExtCommunity(this);
877 : }
878 :
879 204 : clone->RemoveSiteOfOrigin();
880 204 : clone->Append(soo);
881 204 : return Locate(clone);
882 : }
883 :
884 156 : ExtCommunityPtr ExtCommunityDB::RemoveSourceASAndLocate(
885 : const ExtCommunity *src) {
886 : ExtCommunity *clone;
887 156 : if (src) {
888 156 : clone = new ExtCommunity(*src);
889 : } else {
890 0 : clone = new ExtCommunity(this);
891 : }
892 :
893 156 : clone->RemoveSourceAS();
894 156 : return Locate(clone);
895 : }
896 :
897 229 : ExtCommunityPtr ExtCommunityDB::ReplaceSourceASAndLocate(
898 : const ExtCommunity *src,
899 : const ExtCommunity::ExtCommunityValue &sas) {
900 : ExtCommunity *clone;
901 229 : if (src) {
902 229 : clone = new ExtCommunity(*src);
903 : } else {
904 0 : clone = new ExtCommunity(this);
905 : }
906 :
907 229 : clone->RemoveSourceAS();
908 229 : clone->Append(sas);
909 229 : return Locate(clone);
910 : }
911 :
912 0 : ExtCommunityPtr ExtCommunityDB::RemoveVrfRouteImportAndLocate(
913 : const ExtCommunity *src) {
914 : ExtCommunity *clone;
915 0 : if (src) {
916 0 : clone = new ExtCommunity(*src);
917 : } else {
918 0 : clone = new ExtCommunity(this);
919 : }
920 :
921 0 : clone->RemoveVrfRouteImport();
922 0 : return Locate(clone);
923 : }
924 :
925 114 : ExtCommunityPtr ExtCommunityDB::ReplaceVrfRouteImportAndLocate(
926 : const ExtCommunity *src,
927 : const ExtCommunity::ExtCommunityValue &vit) {
928 : ExtCommunity *clone;
929 114 : if (src) {
930 66 : clone = new ExtCommunity(*src);
931 : } else {
932 48 : clone = new ExtCommunity(this);
933 : }
934 :
935 114 : clone->RemoveVrfRouteImport();
936 114 : clone->Append(vit);
937 114 : return Locate(clone);
938 : }
939 :
940 170650 : ExtCommunityPtr ExtCommunityDB::RemoveOriginVnAndLocate(
941 : const ExtCommunity *src) {
942 : ExtCommunity *clone;
943 170650 : if (src) {
944 170652 : clone = new ExtCommunity(*src);
945 : } else {
946 0 : clone = new ExtCommunity(this);
947 : }
948 :
949 170682 : clone->RemoveOriginVn();
950 170599 : return Locate(clone);
951 : }
952 :
953 72567 : ExtCommunityPtr ExtCommunityDB::ReplaceOriginVnAndLocate(
954 : const ExtCommunity *src,
955 : const ExtCommunity::ExtCommunityValue &origin_vn) {
956 : ExtCommunity *clone;
957 72567 : if (src) {
958 72561 : clone = new ExtCommunity(*src);
959 : } else {
960 6 : clone = new ExtCommunity(this);
961 : }
962 :
963 72575 : clone->RemoveOriginVn();
964 72566 : clone->Append(origin_vn);
965 72563 : return Locate(clone);
966 : }
967 :
968 17794 : ExtCommunityPtr ExtCommunityDB::ReplaceTunnelEncapsulationAndLocate(
969 : const ExtCommunity *src,
970 : const ExtCommunity::ExtCommunityList &tunnel_encaps) {
971 : ExtCommunity *clone;
972 17794 : if (src) {
973 17794 : clone = new ExtCommunity(*src);
974 : } else {
975 0 : clone = new ExtCommunity(this);
976 : }
977 :
978 17794 : clone->RemoveTunnelEncapsulation();
979 17794 : clone->Append(tunnel_encaps);
980 17794 : return Locate(clone);
981 : }
982 :
983 8 : ExtCommunityPtr ExtCommunityDB::ReplaceLoadBalanceAndLocate(
984 : const ExtCommunity *src,
985 : const ExtCommunity::ExtCommunityValue &lb) {
986 : ExtCommunity *clone;
987 8 : if (src) {
988 8 : clone = new ExtCommunity(*src);
989 : } else {
990 0 : clone = new ExtCommunity(this);
991 : }
992 :
993 8 : clone->RemoveLoadBalance();
994 8 : clone->Append(lb);
995 8 : return Locate(clone);
996 : }
997 :
998 1 : ExtCommunityPtr ExtCommunityDB::ReplaceSubClusterAndLocate(
999 : const ExtCommunity *src,
1000 : const ExtCommunity::ExtCommunityValue &sc) {
1001 : ExtCommunity *clone;
1002 1 : if (src) {
1003 1 : clone = new ExtCommunity(*src);
1004 : } else {
1005 0 : clone = new ExtCommunity(this);
1006 : }
1007 :
1008 1 : clone->RemoveSubCluster();
1009 1 : clone->Append(sc);
1010 1 : return Locate(clone);
1011 : }
1012 :
1013 41 : ExtCommunityPtr ExtCommunityDB::SetAndLocate(const ExtCommunity *src,
1014 : const ExtCommunity::ExtCommunityList &value) {
1015 : ExtCommunity *clone;
1016 41 : if (src) {
1017 2 : clone = new ExtCommunity(*src);
1018 : } else {
1019 39 : clone = new ExtCommunity(this);
1020 : }
1021 :
1022 41 : clone->Set(value);
1023 41 : return Locate(clone);
1024 : }
1025 :
1026 6 : string LargeCommunitySpec::ToString() const {
1027 : char repr[80];
1028 6 : snprintf(repr, sizeof(repr), "LargeCommunity <code: %d, flags: %02x>:%d",
1029 6 : code, flags, (uint32_t)communities.size() / 3);
1030 6 : return string(repr);
1031 : }
1032 :
1033 18 : size_t LargeCommunitySpec::EncodeLength() const {
1034 18 : return communities.size() * sizeof(uint32_t);
1035 : }
1036 :
1037 0 : int LargeCommunitySpec::CompareTo(const BgpAttribute &rhs_attr) const {
1038 0 : int ret = BgpAttribute::CompareTo(rhs_attr);
1039 0 : if (ret != 0) return ret;
1040 0 : KEY_COMPARE(communities,
1041 : static_cast<const LargeCommunitySpec &>(rhs_attr).communities);
1042 0 : return 0;
1043 : }
1044 :
1045 44 : void LargeCommunitySpec::ToCanonical(BgpAttr *attr) {
1046 : // add LarceComm to attr
1047 44 : attr->set_large_community(this);
1048 44 : }
1049 :
1050 407600 : int LargeCommunity::CompareTo(const LargeCommunity &rhs) const {
1051 407600 : KEY_COMPARE(communities_.size(), rhs.communities_.size());
1052 :
1053 407391 : LargeCommunityList::const_iterator i, j;
1054 407391 : for (i = communities_.begin(), j = rhs.communities_.begin();
1055 407726 : i < communities_.end(); ++i, ++j) {
1056 409 : if (*i < *j) {
1057 38 : return -1;
1058 : }
1059 371 : if (*i > *j) {
1060 35 : return 1;
1061 : }
1062 : }
1063 407320 : return 0;
1064 : }
1065 :
1066 0 : void LargeCommunity::Remove(const LargeCommunityList &list) {
1067 0 : for (LargeCommunityList::const_iterator it = list.begin();
1068 0 : it != list.end(); ++it) {
1069 0 : communities_.erase(std::remove(communities_.begin(),
1070 0 : communities_.end(), *it), communities_.end());
1071 : }
1072 0 : }
1073 6348 : void LargeCommunity::Remove() {
1074 6348 : largecomm_db_->Delete(this);
1075 6348 : }
1076 :
1077 0 : void LargeCommunity::Set(const LargeCommunityList &list) {
1078 0 : communities_.clear();
1079 0 : for (LargeCommunityList::const_iterator it = list.begin();
1080 0 : it != list.end(); ++it) {
1081 0 : communities_.push_back(*it);
1082 : }
1083 0 : }
1084 :
1085 18862 : void LargeCommunity::Append(const LargeCommunityList &list) {
1086 18862 : communities_.insert(communities_.end(), list.begin(), list.end());
1087 18862 : sort(communities_.begin(), communities_.end());
1088 : LargeCommunityList::iterator it =
1089 18862 : unique(communities_.begin(), communities_.end());
1090 18862 : communities_.erase(it, communities_.end());
1091 18862 : }
1092 :
1093 0 : void LargeCommunity::Append(const LargeCommunityValue &value) {
1094 0 : communities_.push_back(value);
1095 0 : sort(communities_.begin(), communities_.end());
1096 : LargeCommunityList::iterator it =
1097 0 : unique(communities_.begin(), communities_.end());
1098 0 : communities_.erase(it, communities_.end());
1099 0 : }
1100 :
1101 0 : LargeCommunity::LargeCommunityValue LargeCommunity::FromHexString(
1102 : const string &comm, boost::system::error_code *errorp) {
1103 : LargeCommunityValue data;
1104 0 : put_value(&data[0], 12, 0);
1105 : char *end;
1106 0 : uint64_t value = strtoull(comm.c_str(), &end, 24);
1107 0 : if (value == 0 || *end) {
1108 : // e.g. 0 or 12x34ff (invalid hex)
1109 0 : if (errorp != NULL) {
1110 0 : *errorp = make_error_code(
1111 : boost::system::errc::invalid_argument);
1112 0 : return data;
1113 : }
1114 : }
1115 0 : if (comm[0] == '0' && (comm[1] == 'x' || comm[1] == 'X')) {
1116 0 : if (comm.length() > 26 && errorp != NULL) {
1117 : // e.g. 0xabcdef0123456789abcdef012 is an invalid 8byte hex value
1118 0 : *errorp = make_error_code(
1119 : boost::system::errc::invalid_argument);
1120 0 : return data;
1121 : }
1122 : } else {
1123 0 : if (comm.length() > 24 && errorp != NULL) {
1124 : // e.g. abcdef0123456789abcdef012 is an invalid 8byte hex value
1125 0 : *errorp = make_error_code(
1126 : boost::system::errc::invalid_argument);
1127 0 : return data;
1128 : }
1129 : }
1130 0 : put_value(&data[0], 12, value);
1131 0 : return data;
1132 : }
1133 :
1134 0 : LargeCommunity::LargeCommunityList LargeCommunity::LargeCommunityFromString(
1135 : const string &comm) {
1136 0 : LargeCommunityList commList;
1137 : LargeCommunityValue value;
1138 0 : size_t pos = comm.find(':');
1139 0 : string first(comm.substr(0, pos));
1140 0 : boost::system::error_code error;
1141 0 : value = FromHexString(comm, &error);
1142 0 : if (error) {
1143 0 : return commList;
1144 : }
1145 0 : commList.push_back(value);
1146 0 : return commList;
1147 0 : }
1148 :
1149 0 : string LargeCommunity::ToHexString(const LargeCommunityValue &comm) {
1150 : char temp[50];
1151 0 : int len = 0;
1152 0 : for (size_t i = 0; i < comm.size(); i++) {
1153 0 : len += snprintf(temp+len, sizeof(temp) - len, "%02x", (comm)[i]);
1154 : }
1155 0 : return(string(temp));
1156 : }
1157 :
1158 0 : string LargeCommunity::ToString(const LargeCommunityValue &comm) {
1159 0 : if (is_tag(comm)) {
1160 0 : TagLC tag(comm);
1161 0 : return(tag.ToString());
1162 : }
1163 0 : return ToHexString(comm);
1164 : }
1165 :
1166 18862 : void LargeCommunity::RemoveTag() {
1167 18862 : for (LargeCommunityList::iterator it = communities_.begin();
1168 18862 : it != communities_.end(); ) {
1169 0 : if (LargeCommunity::is_tag(*it)) {
1170 0 : it = communities_.erase(it);
1171 : } else {
1172 0 : ++it;
1173 : }
1174 : }
1175 18862 : }
1176 :
1177 445164 : vector<uint64_t> LargeCommunity::GetTagList(as_t asn) const {
1178 445164 : vector<uint64_t> tag_list;
1179 445234 : for (const auto &lc : communities_) {
1180 32 : if (!LargeCommunity::is_tag(lc))
1181 2 : continue;
1182 32 : TagLC tag_comm(lc);
1183 32 : if (asn && tag_comm.as_number() != asn && !tag_comm.IsGlobal())
1184 2 : continue;
1185 30 : tag_list.push_back(tag_comm.tag());
1186 : }
1187 :
1188 445183 : sort(tag_list.begin(), tag_list.end());
1189 445185 : vector<uint64_t>::iterator tag_iter = unique(tag_list.begin(),
1190 : tag_list.end());
1191 445169 : tag_list.erase(tag_iter, tag_list.end());
1192 890368 : return tag_list;
1193 0 : }
1194 :
1195 :
1196 184426 : LargeCommunity::LargeCommunity(LargeCommunityDB *largecomm_db,
1197 184426 : const LargeCommunitySpec spec) : largecomm_db_(largecomm_db) {
1198 184425 : refcount_ = 0;
1199 184435 : std::vector<uint32_t>::const_iterator lcit = spec.communities.begin();
1200 184537 : while (lcit < spec.communities.end()) {
1201 : LargeCommunityValue comm;
1202 104 : put_value(comm.data(), 4, *lcit);
1203 104 : lcit++;
1204 104 : put_value(comm.data()+4, 4, *lcit);
1205 104 : lcit++;
1206 104 : put_value(comm.data()+8, 4, *lcit);
1207 104 : lcit++;
1208 104 : communities_.push_back(comm);
1209 : }
1210 184433 : sort(communities_.begin(), communities_.end());
1211 : LargeCommunityList::iterator it =
1212 184429 : unique(communities_.begin(), communities_.end());
1213 184426 : communities_.erase(it, communities_.end());
1214 184426 : }
1215 :
1216 9742 : LargeCommunityDB::LargeCommunityDB(BgpServer *server) {
1217 9742 : }
1218 :
1219 0 : LargeCommunityPtr LargeCommunityDB::AppendAndLocate(const LargeCommunity *src,
1220 : const LargeCommunity::LargeCommunityList &list) {
1221 : LargeCommunity *clone;
1222 0 : if (src) {
1223 0 : clone = new LargeCommunity(*src);
1224 : } else {
1225 0 : clone = new LargeCommunity(this);
1226 : }
1227 :
1228 0 : clone->Append(list);
1229 0 : return Locate(clone);
1230 : }
1231 :
1232 0 : LargeCommunityPtr LargeCommunityDB::AppendAndLocate(const LargeCommunity *src,
1233 : const LargeCommunity::LargeCommunityValue &value) {
1234 0 : LargeCommunity::LargeCommunityList list;
1235 0 : list.push_back(value);
1236 0 : return AppendAndLocate(src, list);
1237 0 : }
1238 :
1239 18862 : LargeCommunityPtr LargeCommunityDB::ReplaceTagListAndLocate(
1240 : const LargeCommunity *src,
1241 : const LargeCommunity::LargeCommunityList &tag_list) {
1242 : LargeCommunity *clone;
1243 18862 : if (src) {
1244 0 : clone = new LargeCommunity(*src);
1245 : } else {
1246 18862 : clone = new LargeCommunity(this);
1247 : }
1248 :
1249 18862 : clone->RemoveTag();
1250 18862 : clone->Append(tag_list);
1251 18862 : return Locate(clone);
1252 : }
1253 :
1254 0 : LargeCommunityPtr LargeCommunityDB::RemoveAndLocate(const LargeCommunity *src,
1255 : const LargeCommunity::LargeCommunityList &list) {
1256 : LargeCommunity *clone;
1257 0 : if (src) {
1258 0 : clone = new LargeCommunity(*src);
1259 : } else {
1260 0 : clone = new LargeCommunity(this);
1261 : }
1262 :
1263 0 : clone->Remove(list);
1264 0 : return Locate(clone);
1265 : }
1266 :
1267 :
1268 0 : LargeCommunityPtr LargeCommunityDB::SetAndLocate(const LargeCommunity *src,
1269 : const LargeCommunity::LargeCommunityList &list) {
1270 : LargeCommunity *clone;
1271 0 : if (src) {
1272 0 : clone = new LargeCommunity(*src);
1273 : } else {
1274 0 : clone = new LargeCommunity(this);
1275 : }
1276 :
1277 0 : clone->Set(list);
1278 0 : return Locate(clone);
1279 : }
1280 :
|