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