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 4269 : void CommunitySpec::ToCanonical(BgpAttr *attr) {
43 4269 : attr->set_community(this);
44 4269 : }
45 :
46 3993 : string CommunitySpec::ToString() const {
47 3993 : string repr;
48 : char start[32];
49 3993 : snprintf(start, sizeof(start), "Communities: %zu [", communities.size());
50 3993 : repr += start;
51 :
52 7996 : for (size_t i = 0; i < communities.size(); ++i) {
53 : char community[12];
54 4003 : snprintf(community, sizeof(community), " %X", communities[i]);
55 4003 : repr += community;
56 : }
57 3993 : repr += " ]";
58 :
59 7986 : return repr;
60 0 : }
61 :
62 5625 : Community::Community(CommunityDB *comm_db, const CommunitySpec spec)
63 5625 : : comm_db_(comm_db), communities_(spec.communities) {
64 5623 : refcount_ = 0;
65 5642 : sort(communities_.begin(), communities_.end());
66 : vector<uint32_t>::iterator it =
67 5638 : unique(communities_.begin(), communities_.end());
68 5633 : communities_.erase(it, communities_.end());
69 5627 : }
70 :
71 416645 : int Community::CompareTo(const Community &rhs) const {
72 416645 : KEY_COMPARE(communities_, rhs.communities_);
73 415443 : return 0;
74 : }
75 :
76 22845 : size_t CommunitySpec::EncodeLength() const {
77 22845 : return communities.size() * sizeof(uint32_t);
78 : }
79 :
80 23441 : void Community::Append(uint32_t value) {
81 23441 : if (ContainsValue(value))
82 897 : return;
83 22544 : communities_.push_back(value);
84 22544 : 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 2364 : void Community::Remove() {
112 2364 : comm_db_->Delete(this);
113 2364 : }
114 :
115 117537 : bool Community::ContainsValue(uint32_t value) const {
116 197852 : for (auto community : communities_) {
117 95841 : if (community == value)
118 15526 : return true;
119 : }
120 102010 : 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 23441 : CommunityPtr CommunityDB::AppendAndLocate(const Community *src,
134 : uint32_t value) {
135 : Community *clone;
136 23441 : if (src) {
137 937 : clone = new Community(*src);
138 : } else {
139 22504 : clone = new Community(this);
140 : }
141 :
142 23441 : clone->Append(value);
143 23440 : 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 89638 : string ExtCommunitySpec::ToString() const {
193 : char repr[80];
194 89638 : snprintf(repr, sizeof(repr), "ExtCommunity <code: %d, flags: %02x>:%d",
195 89638 : code, flags, (uint32_t)communities.size());
196 89638 : return string(repr);
197 : }
198 :
199 183205 : LargeCommunitySpec LargeCommunitySpec::FromTag(
200 : const ExtCommunitySpec &ex_spec) {
201 183205 : LargeCommunitySpec large_spec;
202 : using extcomm_iterator = decltype(large_spec.communities)::iterator;
203 183206 : std::map<uint16_t, extcomm_iterator> tno_vs_tspec;
204 183204 : std::vector<std::pair<uint32_t,uint16_t> > asn4_vs_tno;
205 183204 : const uint64_t ExtCommTag = uint64_t(
206 : (BgpExtendedCommunityType::Experimental << 8) |
207 : (BgpExtendedCommunityExperimentalSubType::Tag)) << 48;
208 183204 : 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 1363966 : for (const auto &val64 : ex_spec.communities) {
215 1180762 : 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 1180754 : 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 183201 : 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 366404 : return large_spec;
246 183202 : }
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 390618 : size_t ExtCommunitySpec::EncodeLength() const {
267 390618 : 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 183165 : void ExtCommunitySpec::ToCanonical(BgpAttr *attr) {
279 183165 : attr->set_ext_community(this);
280 183167 : }
281 :
282 2117 : void ExtCommunitySpec::AddTunnelEncaps(vector<string> encaps) {
283 2354 : for (vector<string>::size_type i = 0; i < encaps.size(); i++) {
284 237 : string encap_str = encaps[i];
285 237 : TunnelEncap tun_encap(encap_str);
286 237 : communities.push_back(tun_encap.GetExtCommunityValue());
287 237 : }
288 2117 : }
289 :
290 5013099 : int ExtCommunity::CompareTo(const ExtCommunity &rhs) const {
291 5013099 : KEY_COMPARE(communities_.size(), rhs.communities_.size());
292 :
293 3578571 : ExtCommunityList::const_iterator i, j;
294 3578571 : for (i = communities_.begin(), j = rhs.communities_.begin();
295 11891458 : i < communities_.end(); ++i, ++j) {
296 9421552 : if (*i < *j) {
297 675270 : return -1;
298 : }
299 8746670 : if (*i > *j) {
300 433634 : return 1;
301 : }
302 : }
303 2469711 : 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 184685 : void ExtCommunity::Remove() {
314 184685 : extcomm_db_->Delete(this);
315 184685 : }
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 426321 : void ExtCommunity::Append(const ExtCommunityList &list) {
326 426321 : communities_.insert(communities_.end(), list.begin(), list.end());
327 426282 : sort(communities_.begin(), communities_.end());
328 : ExtCommunityList::iterator it =
329 426285 : unique(communities_.begin(), communities_.end());
330 426287 : communities_.erase(it, communities_.end());
331 426277 : }
332 :
333 73335 : void ExtCommunity::Append(const ExtCommunityValue &value) {
334 73335 : communities_.push_back(value);
335 73330 : sort(communities_.begin(), communities_.end());
336 : ExtCommunityList::iterator it =
337 73330 : unique(communities_.begin(), communities_.end());
338 73329 : communities_.erase(it, communities_.end());
339 73326 : }
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 97177 : bool ExtCommunity::ContainsOriginVn(const ExtCommunityValue &val) const {
496 97177 : for (ExtCommunityList::const_iterator it = communities_.begin();
497 827197 : it != communities_.end(); ++it) {
498 737040 : if (ExtCommunity::is_origin_vn(*it) && *it == val)
499 7020 : return true;
500 : }
501 90157 : return false;
502 : }
503 :
504 97177 : bool ExtCommunity::ContainsOriginVn(as_t asn, uint32_t vn_index) const {
505 : if (asn <= 0xffffffff) {
506 97177 : OriginVn origin_vn(asn, vn_index);
507 97177 : 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 386742 : uint32_t ExtCommunity::GetSubClusterId() const {
525 386742 : for (ExtCommunityList::const_iterator it = communities_.begin();
526 2863643 : it != communities_.end(); ++it) {
527 2476928 : if (ExtCommunity::is_sub_cluster(*it)) {
528 2 : SubCluster sc(*it);
529 2 : return sc.GetId();
530 : }
531 : }
532 386678 : 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 20173 : void ExtCommunity::RemoveMFlags() {
545 20173 : for (ExtCommunityList::iterator it = communities_.begin();
546 47201 : it != communities_.end(); ) {
547 27028 : if (ExtCommunity::is_multicast_flags(*it)) {
548 0 : it = communities_.erase(it);
549 : } else {
550 27028 : ++it;
551 : }
552 : }
553 20173 : }
554 :
555 32520 : void ExtCommunity::RemoveRTarget() {
556 32520 : for (ExtCommunityList::iterator it = communities_.begin();
557 81761 : it != communities_.end(); ) {
558 49241 : if (ExtCommunity::is_route_target(*it)) {
559 25375 : it = communities_.erase(it);
560 : } else {
561 23866 : ++it;
562 : }
563 : }
564 32520 : }
565 :
566 24155 : void ExtCommunity::RemoveSGID() {
567 24155 : for (ExtCommunityList::iterator it = communities_.begin();
568 43946 : it != communities_.end(); ) {
569 35879 : if (ExtCommunity::is_security_group(*it) ||
570 16088 : ExtCommunity::is_security_group4(*it)) {
571 3703 : it = communities_.erase(it);
572 : } else {
573 16088 : ++it;
574 : }
575 : }
576 24155 : }
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 18872 : void ExtCommunity::RemoveSiteOfOrigin() {
590 18872 : for (ExtCommunityList::iterator it = communities_.begin();
591 37686 : it != communities_.end(); ) {
592 18814 : if (ExtCommunity::is_site_of_origin(*it)) {
593 0 : it = communities_.erase(it);
594 : } else {
595 18814 : ++it;
596 : }
597 : }
598 18872 : }
599 :
600 380 : void ExtCommunity::RemoveSourceAS() {
601 380 : for (ExtCommunityList::iterator it = communities_.begin();
602 1888 : it != communities_.end(); ) {
603 1508 : if (ExtCommunity::is_source_as(*it)) {
604 156 : it = communities_.erase(it);
605 : } else {
606 1352 : ++it;
607 : }
608 : }
609 380 : }
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 241685 : void ExtCommunity::RemoveOriginVn() {
622 241685 : for (ExtCommunityList::iterator it = communities_.begin();
623 1790450 : it != communities_.end(); ) {
624 1548812 : if (ExtCommunity::is_origin_vn(*it))
625 15291 : it = communities_.erase(it);
626 : else
627 1533498 : ++it;
628 : }
629 241553 : }
630 :
631 17795 : void ExtCommunity::RemoveTunnelEncapsulation() {
632 17795 : for (ExtCommunityList::iterator it = communities_.begin();
633 36967 : it != communities_.end(); ) {
634 19171 : if (ExtCommunity::is_tunnel_encap(*it)) {
635 165 : it = communities_.erase(it);
636 : } else {
637 19006 : ++it;
638 : }
639 : }
640 17796 : }
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 477958 : vector<string> ExtCommunity::GetTunnelEncap() const {
665 477958 : vector<string> encap_list;
666 477998 : for (ExtCommunityList::const_iterator iter = communities_.begin();
667 3304435 : iter != communities_.end(); ++iter) {
668 2826225 : if (!ExtCommunity::is_tunnel_encap(*iter))
669 2346972 : continue;
670 479391 : TunnelEncap encap(*iter);
671 479418 : if (encap.tunnel_encap() == TunnelEncapType::UNSPEC)
672 0 : continue;
673 479356 : encap_list.push_back(encap.ToXmppString());
674 : }
675 :
676 478048 : sort(encap_list.begin(), encap_list.end());
677 : vector<string>::iterator encap_iter =
678 478029 : unique(encap_list.begin(), encap_list.end());
679 477991 : encap_list.erase(encap_iter, encap_list.end());
680 955882 : 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 138980 : bool ExtCommunity::ContainsTunnelEncapVxlan() const {
725 138980 : for (ExtCommunityList::const_iterator iter = communities_.begin();
726 1966238 : iter != communities_.end(); ++iter) {
727 1827697 : if (!ExtCommunity::is_tunnel_encap(*iter))
728 1657186 : continue;
729 170524 : TunnelEncap encap(*iter);
730 170523 : if (encap.tunnel_encap() == TunnelEncapType::VXLAN)
731 449 : return true;
732 : }
733 138524 : return false;
734 : }
735 :
736 451282 : int ExtCommunity::GetOriginVnIndex() const {
737 451282 : for (ExtCommunityList::const_iterator iter = communities_.begin();
738 3159944 : iter != communities_.end(); ++iter) {
739 2742370 : if (ExtCommunity::is_origin_vn(*iter)) {
740 33720 : OriginVn origin_vn(*iter);
741 33724 : return origin_vn.vn_index();
742 : }
743 : }
744 417596 : return -1;
745 : }
746 :
747 189837 : ExtCommunity::ExtCommunity(ExtCommunityDB *extcomm_db,
748 189837 : const ExtCommunitySpec spec) : extcomm_db_(extcomm_db) {
749 189836 : refcount_ = 0;
750 189846 : for (vector<uint64_t>::const_iterator it = spec.communities.begin();
751 1376062 : it < spec.communities.end(); ++it) {
752 : ExtCommunityValue comm;
753 1186211 : put_value(comm.data(), comm.size(), *it);
754 1186212 : communities_.push_back(comm);
755 : }
756 189844 : sort(communities_.begin(), communities_.end());
757 : ExtCommunityList::iterator it =
758 189844 : unique(communities_.begin(), communities_.end());
759 189845 : communities_.erase(it, communities_.end());
760 189842 : }
761 :
762 9742 : ExtCommunityDB::ExtCommunityDB(BgpServer *server) {
763 9742 : }
764 :
765 331618 : ExtCommunityPtr ExtCommunityDB::AppendAndLocate(const ExtCommunity *src,
766 : const ExtCommunity::ExtCommunityList &list) {
767 : ExtCommunity *clone;
768 331618 : if (src) {
769 190179 : clone = new ExtCommunity(*src);
770 : } else {
771 141439 : clone = new ExtCommunity(this);
772 : }
773 :
774 331680 : clone->Append(list);
775 331638 : 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 20173 : ExtCommunityPtr ExtCommunityDB::ReplaceMFlagsAndLocate(const ExtCommunity *src,
799 : const ExtCommunity::ExtCommunityList &export_list) {
800 : ExtCommunity *clone;
801 20173 : if (src) {
802 20173 : clone = new ExtCommunity(*src);
803 : } else {
804 0 : clone = new ExtCommunity(this);
805 : }
806 :
807 20173 : clone->RemoveMFlags();
808 20173 : clone->Append(export_list);
809 20173 : return Locate(clone);
810 : }
811 :
812 32520 : ExtCommunityPtr ExtCommunityDB::ReplaceRTargetAndLocate(const ExtCommunity *src,
813 : const ExtCommunity::ExtCommunityList &export_list) {
814 : ExtCommunity *clone;
815 32520 : if (src) {
816 27208 : clone = new ExtCommunity(*src);
817 : } else {
818 5312 : clone = new ExtCommunity(this);
819 : }
820 :
821 32520 : clone->RemoveRTarget();
822 32520 : clone->Append(export_list);
823 32520 : return Locate(clone);
824 : }
825 :
826 24155 : ExtCommunityPtr ExtCommunityDB::ReplaceSGIDListAndLocate(
827 : const ExtCommunity *src,
828 : const ExtCommunity::ExtCommunityList &sgid_list) {
829 : ExtCommunity *clone;
830 24155 : if (src) {
831 24155 : clone = new ExtCommunity(*src);
832 : } else {
833 0 : clone = new ExtCommunity(this);
834 : }
835 :
836 24155 : clone->RemoveSGID();
837 24155 : clone->Append(sgid_list);
838 24152 : 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 18655 : ExtCommunityPtr ExtCommunityDB::RemoveSiteOfOriginAndLocate(
857 : const ExtCommunity *src) {
858 : ExtCommunity *clone;
859 18655 : if (src) {
860 18655 : clone = new ExtCommunity(*src);
861 : } else {
862 0 : clone = new ExtCommunity(this);
863 : }
864 :
865 18655 : clone->RemoveSiteOfOrigin();
866 18655 : return Locate(clone);
867 : }
868 :
869 217 : ExtCommunityPtr ExtCommunityDB::ReplaceSiteOfOriginAndLocate(
870 : const ExtCommunity *src,
871 : const ExtCommunity::ExtCommunityValue &soo) {
872 : ExtCommunity *clone;
873 217 : if (src) {
874 217 : clone = new ExtCommunity(*src);
875 : } else {
876 0 : clone = new ExtCommunity(this);
877 : }
878 :
879 217 : clone->RemoveSiteOfOrigin();
880 217 : clone->Append(soo);
881 217 : 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 224 : ExtCommunityPtr ExtCommunityDB::ReplaceSourceASAndLocate(
898 : const ExtCommunity *src,
899 : const ExtCommunity::ExtCommunityValue &sas) {
900 : ExtCommunity *clone;
901 224 : if (src) {
902 224 : clone = new ExtCommunity(*src);
903 : } else {
904 0 : clone = new ExtCommunity(this);
905 : }
906 :
907 224 : clone->RemoveSourceAS();
908 224 : clone->Append(sas);
909 224 : 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 168880 : ExtCommunityPtr ExtCommunityDB::RemoveOriginVnAndLocate(
941 : const ExtCommunity *src) {
942 : ExtCommunity *clone;
943 168880 : if (src) {
944 168882 : clone = new ExtCommunity(*src);
945 : } else {
946 0 : clone = new ExtCommunity(this);
947 : }
948 :
949 168921 : clone->RemoveOriginVn();
950 168783 : return Locate(clone);
951 : }
952 :
953 72770 : ExtCommunityPtr ExtCommunityDB::ReplaceOriginVnAndLocate(
954 : const ExtCommunity *src,
955 : const ExtCommunity::ExtCommunityValue &origin_vn) {
956 : ExtCommunity *clone;
957 72770 : if (src) {
958 72764 : clone = new ExtCommunity(*src);
959 : } else {
960 6 : clone = new ExtCommunity(this);
961 : }
962 :
963 72779 : clone->RemoveOriginVn();
964 72770 : clone->Append(origin_vn);
965 72762 : return Locate(clone);
966 : }
967 :
968 17796 : ExtCommunityPtr ExtCommunityDB::ReplaceTunnelEncapsulationAndLocate(
969 : const ExtCommunity *src,
970 : const ExtCommunity::ExtCommunityList &tunnel_encaps) {
971 : ExtCommunity *clone;
972 17796 : if (src) {
973 17796 : clone = new ExtCommunity(*src);
974 : } else {
975 0 : clone = new ExtCommunity(this);
976 : }
977 :
978 17796 : clone->RemoveTunnelEncapsulation();
979 17796 : clone->Append(tunnel_encaps);
980 17796 : 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 404814 : int LargeCommunity::CompareTo(const LargeCommunity &rhs) const {
1051 404814 : KEY_COMPARE(communities_.size(), rhs.communities_.size());
1052 :
1053 404604 : LargeCommunityList::const_iterator i, j;
1054 404604 : for (i = communities_.begin(), j = rhs.communities_.begin();
1055 404938 : 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 404530 : 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 6005 : void LargeCommunity::Remove() {
1074 6005 : largecomm_db_->Delete(this);
1075 6005 : }
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 18872 : void LargeCommunity::Append(const LargeCommunityList &list) {
1086 18872 : communities_.insert(communities_.end(), list.begin(), list.end());
1087 18872 : sort(communities_.begin(), communities_.end());
1088 : LargeCommunityList::iterator it =
1089 18872 : unique(communities_.begin(), communities_.end());
1090 18872 : communities_.erase(it, communities_.end());
1091 18872 : }
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 18872 : void LargeCommunity::RemoveTag() {
1167 18872 : for (LargeCommunityList::iterator it = communities_.begin();
1168 18872 : it != communities_.end(); ) {
1169 0 : if (LargeCommunity::is_tag(*it)) {
1170 0 : it = communities_.erase(it);
1171 : } else {
1172 0 : ++it;
1173 : }
1174 : }
1175 18872 : }
1176 :
1177 447608 : vector<uint64_t> LargeCommunity::GetTagList(as_t asn) const {
1178 447608 : vector<uint64_t> tag_list;
1179 447662 : 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 447589 : sort(tag_list.begin(), tag_list.end());
1189 447594 : vector<uint64_t>::iterator tag_iter = unique(tag_list.begin(),
1190 : tag_list.end());
1191 447570 : tag_list.erase(tag_iter, tag_list.end());
1192 895126 : return tag_list;
1193 0 : }
1194 :
1195 :
1196 183246 : LargeCommunity::LargeCommunity(LargeCommunityDB *largecomm_db,
1197 183246 : const LargeCommunitySpec spec) : largecomm_db_(largecomm_db) {
1198 183245 : refcount_ = 0;
1199 183253 : std::vector<uint32_t>::const_iterator lcit = spec.communities.begin();
1200 183357 : 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 183251 : sort(communities_.begin(), communities_.end());
1211 : LargeCommunityList::iterator it =
1212 183244 : unique(communities_.begin(), communities_.end());
1213 183244 : communities_.erase(it, communities_.end());
1214 183242 : }
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 18872 : LargeCommunityPtr LargeCommunityDB::ReplaceTagListAndLocate(
1240 : const LargeCommunity *src,
1241 : const LargeCommunity::LargeCommunityList &tag_list) {
1242 : LargeCommunity *clone;
1243 18872 : if (src) {
1244 0 : clone = new LargeCommunity(*src);
1245 : } else {
1246 18872 : clone = new LargeCommunity(this);
1247 : }
1248 :
1249 18872 : clone->RemoveTag();
1250 18872 : clone->Append(tag_list);
1251 18872 : 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 :
|