OpenSDN source code
community.cc
Go to the documentation of this file.
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 
12 #include "base/string_util.h"
13 #include "bgp/bgp_proto.h"
34 #include "net/community_type.h"
35 
36 using std::sort;
37 using std::string;
38 using std::unique;
39 using std::vector;
40 
42  attr->set_community(this);
43 }
44 
45 string CommunitySpec::ToString() const {
46  string repr;
47  char start[32];
48  snprintf(start, sizeof(start), "Communities: %zu [", communities.size());
49  repr += start;
50 
51  for (size_t i = 0; i < communities.size(); ++i) {
52  char community[12];
53  snprintf(community, sizeof(community), " %X", communities[i]);
54  repr += community;
55  }
56  repr += " ]";
57 
58  return repr;
59 }
60 
62  : comm_db_(comm_db), communities_(spec.communities) {
63  refcount_ = 0;
64  sort(communities_.begin(), communities_.end());
65  vector<uint32_t>::iterator it =
66  unique(communities_.begin(), communities_.end());
67  communities_.erase(it, communities_.end());
68 }
69 
70 int Community::CompareTo(const Community &rhs) const {
72  return 0;
73 }
74 
76  return communities.size() * sizeof(uint32_t);
77 }
78 
79 void Community::Append(uint32_t value) {
80  if (ContainsValue(value))
81  return;
82  communities_.push_back(value);
83  sort(communities_.begin(), communities_.end());
84 }
85 
86 void Community::Append(const std::vector<uint32_t> &communities) {
87  for (auto community : communities) {
88  communities_.push_back(community);
89  }
90  sort(communities_.begin(), communities_.end());
91  vector<uint32_t>::iterator it =
92  unique(communities_.begin(), communities_.end());
93  communities_.erase(it, communities_.end());
94 }
95 
96 void Community::Set(const std::vector<uint32_t> &communities) {
97  communities_.clear();
98  for (auto community : communities) {
99  communities_.push_back(community);
100  }
101 }
102 
103 void Community::Remove(const std::vector<uint32_t> &communities) {
104  for (auto community : communities) {
105  communities_.erase(
106  std::remove(communities_.begin(), communities_.end(), community),
107  communities_.end());
108  }
109 }
111  comm_db_->Delete(this);
112 }
113 
114 bool Community::ContainsValue(uint32_t value) const {
115  for (auto community : communities_) {
116  if (community == value)
117  return true;
118  }
119  return false;
120 }
121 
122 void Community::BuildStringList(vector<string> *list) const {
123  for (auto community : communities_) {
124  string name = CommunityType::CommunityToString(community);
125  list->push_back(name);
126  }
127 }
128 
130 }
131 
133  uint32_t value) {
134  Community *clone;
135  if (src) {
136  clone = new Community(*src);
137  } else {
138  clone = new Community(this);
139  }
140 
141  clone->Append(value);
142  return Locate(clone);
143 }
144 
146  const std::vector<uint32_t> &value) {
147  Community *clone;
148  if (src) {
149  clone = new Community(*src);
150  } else {
151  clone = new Community(this);
152  }
153 
154  clone->Append(value);
155  return Locate(clone);
156 }
157 
159  const std::vector<uint32_t> &value) {
160  Community *clone;
161  if (src) {
162  clone = new Community(*src);
163  } else {
164  clone = new Community(this);
165  }
166 
167  clone->Set(value);
168  return Locate(clone);
169 }
170 
172  const std::vector<uint32_t> &value) {
173  Community *clone;
174  if (src) {
175  clone = new Community(*src);
176  } else {
177  clone = new Community(this);
178  }
179 
180  clone->Remove(value);
181  return Locate(clone);
182 }
183 
185  uint32_t value) {
186  Community::CommunityList communities;
187  communities.push_back(value);
188  return RemoveAndLocate(src, communities);
189 }
190 
192  char repr[80];
193  snprintf(repr, sizeof(repr), "ExtCommunity <code: %d, flags: %02x>:%d",
194  code, flags, (uint32_t)communities.size());
195  return string(repr);
196 }
197 
199  return communities.size() * sizeof(uint64_t);
200 }
201 
202 int ExtCommunitySpec::CompareTo(const BgpAttribute &rhs_attr) const {
203  int ret = BgpAttribute::CompareTo(rhs_attr);
204  if (ret != 0) return ret;
206  static_cast<const ExtCommunitySpec &>(rhs_attr).communities);
207  return 0;
208 }
209 
211  attr->set_ext_community(this);
212 }
213 
214 void ExtCommunitySpec::AddTunnelEncaps(vector<string> encaps) {
215  for (vector<string>::size_type i = 0; i < encaps.size(); i++) {
216  string encap_str = encaps[i];
217  TunnelEncap tun_encap(encap_str);
218  communities.push_back(tun_encap.GetExtCommunityValue());
219  }
220 }
221 
222 int ExtCommunity::CompareTo(const ExtCommunity &rhs) const {
223  KEY_COMPARE(communities_.size(), rhs.communities_.size());
224 
225  ExtCommunityList::const_iterator i, j;
226  for (i = communities_.begin(), j = rhs.communities_.begin();
227  i < communities_.end(); ++i, ++j) {
228  if (*i < *j) {
229  return -1;
230  }
231  if (*i > *j) {
232  return 1;
233  }
234  }
235  return 0;
236 }
237 
239  for (ExtCommunityList::const_iterator it = list.begin();
240  it != list.end(); ++it) {
241  communities_.erase(std::remove(communities_.begin(),
242  communities_.end(), *it), communities_.end());
243  }
244 }
246  extcomm_db_->Delete(this);
247 }
248 
250  communities_.clear();
251  for (ExtCommunityList::const_iterator it = list.begin();
252  it != list.end(); ++it) {
253  communities_.push_back(*it);
254  }
255 }
256 
258  communities_.insert(communities_.end(), list.begin(), list.end());
259  sort(communities_.begin(), communities_.end());
260  ExtCommunityList::iterator it =
261  unique(communities_.begin(), communities_.end());
262  communities_.erase(it, communities_.end());
263 }
264 
266  communities_.push_back(value);
267  sort(communities_.begin(), communities_.end());
268  ExtCommunityList::iterator it =
269  unique(communities_.begin(), communities_.end());
270  communities_.erase(it, communities_.end());
271 }
272 
274  const string &comm, boost::system::error_code *errorp) {
275  ExtCommunityValue data;
276  put_value(&data[0], 8, 0);
277  char *end;
278  uint64_t value = strtoull(comm.c_str(), &end, 16);
279  if (value == 0 || *end) {
280  // e.g. 0 or 12x34ff (invalid hex)
281  if (errorp != NULL) {
282  *errorp = make_error_code(
283  boost::system::errc::invalid_argument);
284  return data;
285  }
286  }
287  if (comm[0] == '0' && (comm[1] == 'x' || comm[1] == 'X')) {
288  if (comm.length() > 18 && errorp != NULL) {
289  // e.g. 0xabcdef0123456789f is an invalid 8byte hex value
290  *errorp = make_error_code(
291  boost::system::errc::invalid_argument);
292  return data;
293  }
294  } else {
295  if (comm.length() > 16 && errorp != NULL) {
296  // e.g. abcdef0123456789f is an invalid 8byte hex value
297  *errorp = make_error_code(
298  boost::system::errc::invalid_argument);
299  return data;
300  }
301  }
302  put_value(&data[0], 8, value);
303  return data;
304 }
305 
307  const string &comm) {
308  ExtCommunityList commList;
309  ExtCommunityValue value;
310  size_t pos = comm.find(':');
311  string first(comm.substr(0, pos));
312  boost::system::error_code error;
313  if (first == "soo") {
314  SiteOfOrigin soo = SiteOfOrigin::FromString(comm, &error);
315  if (error) {
316  return commList;
317  }
318  commList.push_back(soo.GetExtCommunity());
319  } else if (first == "target") {
320  RouteTarget rt = RouteTarget::FromString(comm, &error);
321  if (error) {
322  return commList;
323  }
324  commList.push_back(rt.GetExtCommunity());
325  } else if (first == "source-as") {
326  SourceAs sas = SourceAs::FromString(comm, &error);
327  if (error) {
328  return commList;
329  }
330  commList.push_back(sas.GetExtCommunity());
331  } else if (first == "rt-import") {
332  VrfRouteImport vit = VrfRouteImport::FromString(comm, &error);
333  if (error) {
334  return commList;
335  }
336  commList.push_back(vit.GetExtCommunity());
337  } else if (first == "subcluster") {
338  SubCluster sc = SubCluster::FromString(comm, &error);
339  if (error) {
340  return commList;
341  }
342  commList.push_back(sc.GetExtCommunity());
343  } else {
344  value = FromHexString(comm, &error);
345  if (error) {
346  return commList;
347  }
348  commList.push_back(value);
349  }
350  return commList;
351 }
352 
354  char temp[50];
355  int len = 0;
356  for (size_t i = 0; i < comm.size(); i++) {
357  len += snprintf(temp+len, sizeof(temp) - len, "%02x", (comm)[i]);
358  }
359  return(string(temp));
360 }
361 
363  if (is_route_target(comm)) {
364  RouteTarget rt(comm);
365  return(rt.ToString());
366  } else if (is_default_gateway(comm)) {
367  DefaultGateway dgw(comm);
368  return(dgw.ToString());
369  } else if (is_es_import(comm)) {
370  EsImport es_import(comm);
371  return(es_import.ToString());
372  } else if (is_esi_label(comm)) {
373  EsiLabel esi_label(comm);
374  return(esi_label.ToString());
375  } else if (is_mac_mobility(comm)) {
376  MacMobility mm(comm);
377  return(mm.ToString());
378  } else if (is_local_sequence_number(comm)) {
379  LocalSequenceNumber lsn(comm);
380  return lsn.ToString();
381  } else if (is_etree(comm)) {
382  ETree etree(comm);
383  return(etree.ToString());
384  } else if (is_router_mac(comm)) {
385  RouterMac router_mac(comm);
386  return(router_mac.ToString());
387  } else if (is_origin_vn(comm)) {
388  OriginVn origin_vn(comm);
389  return(origin_vn.ToString());
390  } else if (is_security_group(comm)) {
391  SecurityGroup sg(comm);
392  return(sg.ToString());
393  } else if (is_site_of_origin(comm)) {
394  SiteOfOrigin soo(comm);
395  return(soo.ToString());
396  } else if (is_tunnel_encap(comm)) {
397  TunnelEncap encap(comm);
398  return(encap.ToString());
399  } else if (is_load_balance(comm)) {
400  LoadBalance load_balance(comm);
401  return(load_balance.ToString());
402  } else if (is_tag(comm)) {
403  Tag tag(comm);
404  return(tag.ToString());
405  } else if (is_source_as(comm)) {
406  SourceAs sas(comm);
407  return(sas.ToString());
408  } else if (is_vrf_route_import(comm)) {
409  VrfRouteImport rt_import(comm);
410  return(rt_import.ToString());
411  } else if (is_sub_cluster(comm)) {
412  SubCluster sc(comm);
413  return(sc.ToString());
414  }
415  return ToHexString(comm);
416 }
417 
419  for (ExtCommunityList::const_iterator it = communities_.begin();
420  it != communities_.end(); ++it) {
421  if (ExtCommunity::is_route_target(*it) && *it == val)
422  return true;
423  }
424  return false;
425 }
426 
428  for (ExtCommunityList::const_iterator it = communities_.begin();
429  it != communities_.end(); ++it) {
430  if (ExtCommunity::is_origin_vn(*it) && *it == val)
431  return true;
432  }
433  return false;
434 }
435 
436 bool ExtCommunity::ContainsOriginVn(as_t asn, uint32_t vn_index) const {
437  if (asn <= 0xffffffff) {
438  OriginVn origin_vn(asn, vn_index);
439  return ContainsOriginVn(origin_vn.GetExtCommunity());
440  }
441  OriginVn origin_vn4(asn, AS_TRANS);
442  OriginVn origin_vn(AS_TRANS, vn_index);
443  return (ContainsOriginVn(origin_vn.GetExtCommunity()) &&
444  ContainsOriginVn(origin_vn4.GetExtCommunity()));
445 }
446 
448  for (ExtCommunityList::const_iterator it = communities_.begin();
449  it != communities_.end(); ++it) {
450  if (ExtCommunity::is_source_as(*it) && *it == val)
451  return true;
452  }
453  return false;
454 }
455 
457  for (ExtCommunityList::const_iterator it = communities_.begin();
458  it != communities_.end(); ++it) {
459  if (ExtCommunity::is_sub_cluster(*it)) {
460  SubCluster sc(*it);
461  return sc.GetId();
462  }
463  }
464  return 0;
465 }
466 
468  for (ExtCommunityList::const_iterator it = communities_.begin();
469  it != communities_.end(); ++it) {
470  if (ExtCommunity::is_vrf_route_import(*it) && *it == val)
471  return true;
472  }
473  return false;
474 }
475 
477  for (ExtCommunityList::iterator it = communities_.begin();
478  it != communities_.end(); ) {
480  it = communities_.erase(it);
481  } else {
482  ++it;
483  }
484  }
485 }
486 
488  for (ExtCommunityList::iterator it = communities_.begin();
489  it != communities_.end(); ) {
491  it = communities_.erase(it);
492  } else {
493  ++it;
494  }
495  }
496 }
497 
499  for (ExtCommunityList::iterator it = communities_.begin();
500  it != communities_.end(); ) {
503  it = communities_.erase(it);
504  } else {
505  ++it;
506  }
507  }
508 }
509 
511  for (ExtCommunityList::iterator it = communities_.begin();
512  it != communities_.end(); ) {
513  if (ExtCommunity::is_tag(*it) || ExtCommunity::is_tag4(*it)) {
514  it = communities_.erase(it);
515  } else {
516  ++it;
517  }
518  }
519 }
520 
522  for (ExtCommunityList::iterator it = communities_.begin();
523  it != communities_.end(); ) {
525  it = communities_.erase(it);
526  } else {
527  ++it;
528  }
529  }
530 }
531 
533  for (ExtCommunityList::iterator it = communities_.begin();
534  it != communities_.end(); ) {
535  if (ExtCommunity::is_source_as(*it)) {
536  it = communities_.erase(it);
537  } else {
538  ++it;
539  }
540  }
541 }
543  for (ExtCommunityList::iterator it = communities_.begin();
544  it != communities_.end(); ) {
546  it = communities_.erase(it);
547  } else {
548  ++it;
549  }
550  }
551 }
552 
554  for (ExtCommunityList::iterator it = communities_.begin();
555  it != communities_.end(); ) {
557  it = communities_.erase(it);
558  else
559  ++it;
560  }
561 }
562 
564  for (ExtCommunityList::iterator it = communities_.begin();
565  it != communities_.end(); ) {
567  it = communities_.erase(it);
568  } else {
569  ++it;
570  }
571  }
572 }
573 
575  for (ExtCommunityList::iterator it = communities_.begin();
576  it != communities_.end(); ) {
578  it = communities_.erase(it);
579  } else {
580  ++it;
581  }
582  }
583 }
584 
586  for (ExtCommunityList::iterator it = communities_.begin();
587  it != communities_.end(); ) {
588  if (ExtCommunity::is_sub_cluster(*it)) {
589  it = communities_.erase(it);
590  } else {
591  ++it;
592  }
593  }
594 }
595 
596 vector<string> ExtCommunity::GetTunnelEncap() const {
597  vector<string> encap_list;
598  for (ExtCommunityList::const_iterator iter = communities_.begin();
599  iter != communities_.end(); ++iter) {
600  if (!ExtCommunity::is_tunnel_encap(*iter))
601  continue;
602  TunnelEncap encap(*iter);
603  if (encap.tunnel_encap() == TunnelEncapType::UNSPEC)
604  continue;
605  encap_list.push_back(encap.ToXmppString());
606  }
607 
608  sort(encap_list.begin(), encap_list.end());
609  vector<string>::iterator encap_iter =
610  unique(encap_list.begin(), encap_list.end());
611  encap_list.erase(encap_iter, encap_list.end());
612  return encap_list;
613 }
614 
615 vector<int> ExtCommunity::GetTagList(as2_t asn) const {
616  vector<int> tag_list;
617  for (ExtCommunityList::const_iterator iter = communities_.begin();
618  iter != communities_.end(); ++iter) {
619  if (!ExtCommunity::is_tag(*iter))
620  continue;
621  Tag tag_comm(*iter);
622  if (asn && tag_comm.as_number() != asn && !tag_comm.IsGlobal())
623  continue;
624  tag_list.push_back(tag_comm.tag());
625  }
626 
627  sort(tag_list.begin(), tag_list.end());
628  vector<int>::iterator tag_iter = unique(tag_list.begin(), tag_list.end());
629  tag_list.erase(tag_iter, tag_list.end());
630  return tag_list;
631 }
632 
633 vector<int> ExtCommunity::GetTag4List(as_t asn) const {
634  vector<int> tag_list;
635  for (ExtCommunityList::const_iterator iter = communities_.begin();
636  iter != communities_.end(); ++iter) {
637  if (!ExtCommunity::is_tag4(*iter))
638  continue;
639  Tag4ByteAs tag_comm(*iter);
640  if (asn && tag_comm.as_number() != asn && !tag_comm.IsGlobal())
641  continue;
642  vector<int> matching_tag_list = GetTagList(tag_comm.tag());
643  tag_list.insert(tag_list.end(), matching_tag_list.begin(),
644  matching_tag_list.end());
645  tag_list.push_back(tag_comm.tag());
646  }
647  if ((asn <= 0xffff) && tag_list.size() == 0)
648  tag_list = GetTagList(asn);
649 
650  sort(tag_list.begin(), tag_list.end());
651  vector<int>::iterator tag_iter = unique(tag_list.begin(), tag_list.end());
652  tag_list.erase(tag_iter, tag_list.end());
653  return tag_list;
654 }
655 
657  for (ExtCommunityList::const_iterator iter = communities_.begin();
658  iter != communities_.end(); ++iter) {
659  if (!ExtCommunity::is_tunnel_encap(*iter))
660  continue;
661  TunnelEncap encap(*iter);
662  if (encap.tunnel_encap() == TunnelEncapType::VXLAN)
663  return true;
664  }
665  return false;
666 }
667 
669  for (ExtCommunityList::const_iterator iter = communities_.begin();
670  iter != communities_.end(); ++iter) {
671  if (ExtCommunity::is_origin_vn(*iter)) {
672  OriginVn origin_vn(*iter);
673  return origin_vn.vn_index();
674  }
675  }
676  return -1;
677 }
678 
680  const ExtCommunitySpec spec) : extcomm_db_(extcomm_db) {
681  refcount_ = 0;
682  for (vector<uint64_t>::const_iterator it = spec.communities.begin();
683  it < spec.communities.end(); ++it) {
684  ExtCommunityValue comm;
685  put_value(comm.data(), comm.size(), *it);
686  communities_.push_back(comm);
687  }
688  sort(communities_.begin(), communities_.end());
689  ExtCommunityList::iterator it =
690  unique(communities_.begin(), communities_.end());
691  communities_.erase(it, communities_.end());
692 }
693 
695 }
696 
698  const ExtCommunity::ExtCommunityList &list) {
699  ExtCommunity *clone;
700  if (src) {
701  clone = new ExtCommunity(*src);
702  } else {
703  clone = new ExtCommunity(this);
704  }
705 
706  clone->Append(list);
707  return Locate(clone);
708 }
709 
711  const ExtCommunity::ExtCommunityValue &value) {
713  list.push_back(value);
714  return AppendAndLocate(src, list);
715 }
716 
718  const ExtCommunity::ExtCommunityList &list) {
719  ExtCommunity *clone;
720  if (src) {
721  clone = new ExtCommunity(*src);
722  } else {
723  clone = new ExtCommunity(this);
724  }
725 
726  clone->Remove(list);
727  return Locate(clone);
728 }
729 
731  const ExtCommunity::ExtCommunityList &export_list) {
732  ExtCommunity *clone;
733  if (src) {
734  clone = new ExtCommunity(*src);
735  } else {
736  clone = new ExtCommunity(this);
737  }
738 
739  clone->RemoveMFlags();
740  clone->Append(export_list);
741  return Locate(clone);
742 }
743 
745  const ExtCommunity::ExtCommunityList &export_list) {
746  ExtCommunity *clone;
747  if (src) {
748  clone = new ExtCommunity(*src);
749  } else {
750  clone = new ExtCommunity(this);
751  }
752 
753  clone->RemoveRTarget();
754  clone->Append(export_list);
755  return Locate(clone);
756 }
757 
759  const ExtCommunity *src,
760  const ExtCommunity::ExtCommunityList &sgid_list) {
761  ExtCommunity *clone;
762  if (src) {
763  clone = new ExtCommunity(*src);
764  } else {
765  clone = new ExtCommunity(this);
766  }
767 
768  clone->RemoveSGID();
769  clone->Append(sgid_list);
770  return Locate(clone);
771 }
772 
774  const ExtCommunity *src,
775  const ExtCommunity::ExtCommunityList &tag_list) {
776  ExtCommunity *clone;
777  if (src) {
778  clone = new ExtCommunity(*src);
779  } else {
780  clone = new ExtCommunity(this);
781  }
782 
783  clone->RemoveTag();
784  clone->Append(tag_list);
785  return Locate(clone);
786 }
787 
789  const ExtCommunity *src) {
790  ExtCommunity *clone;
791  if (src) {
792  clone = new ExtCommunity(*src);
793  } else {
794  clone = new ExtCommunity(this);
795  }
796 
797  clone->RemoveSiteOfOrigin();
798  return Locate(clone);
799 }
800 
802  const ExtCommunity *src,
803  const ExtCommunity::ExtCommunityValue &soo) {
804  ExtCommunity *clone;
805  if (src) {
806  clone = new ExtCommunity(*src);
807  } else {
808  clone = new ExtCommunity(this);
809  }
810 
811  clone->RemoveSiteOfOrigin();
812  clone->Append(soo);
813  return Locate(clone);
814 }
815 
817  const ExtCommunity *src) {
818  ExtCommunity *clone;
819  if (src) {
820  clone = new ExtCommunity(*src);
821  } else {
822  clone = new ExtCommunity(this);
823  }
824 
825  clone->RemoveSourceAS();
826  return Locate(clone);
827 }
828 
830  const ExtCommunity *src,
831  const ExtCommunity::ExtCommunityValue &sas) {
832  ExtCommunity *clone;
833  if (src) {
834  clone = new ExtCommunity(*src);
835  } else {
836  clone = new ExtCommunity(this);
837  }
838 
839  clone->RemoveSourceAS();
840  clone->Append(sas);
841  return Locate(clone);
842 }
843 
845  const ExtCommunity *src) {
846  ExtCommunity *clone;
847  if (src) {
848  clone = new ExtCommunity(*src);
849  } else {
850  clone = new ExtCommunity(this);
851  }
852 
853  clone->RemoveVrfRouteImport();
854  return Locate(clone);
855 }
856 
858  const ExtCommunity *src,
859  const ExtCommunity::ExtCommunityValue &vit) {
860  ExtCommunity *clone;
861  if (src) {
862  clone = new ExtCommunity(*src);
863  } else {
864  clone = new ExtCommunity(this);
865  }
866 
867  clone->RemoveVrfRouteImport();
868  clone->Append(vit);
869  return Locate(clone);
870 }
871 
873  const ExtCommunity *src) {
874  ExtCommunity *clone;
875  if (src) {
876  clone = new ExtCommunity(*src);
877  } else {
878  clone = new ExtCommunity(this);
879  }
880 
881  clone->RemoveOriginVn();
882  return Locate(clone);
883 }
884 
886  const ExtCommunity *src,
887  const ExtCommunity::ExtCommunityValue &origin_vn) {
888  ExtCommunity *clone;
889  if (src) {
890  clone = new ExtCommunity(*src);
891  } else {
892  clone = new ExtCommunity(this);
893  }
894 
895  clone->RemoveOriginVn();
896  clone->Append(origin_vn);
897  return Locate(clone);
898 }
899 
901  const ExtCommunity *src,
902  const ExtCommunity::ExtCommunityList &tunnel_encaps) {
903  ExtCommunity *clone;
904  if (src) {
905  clone = new ExtCommunity(*src);
906  } else {
907  clone = new ExtCommunity(this);
908  }
909 
910  clone->RemoveTunnelEncapsulation();
911  clone->Append(tunnel_encaps);
912  return Locate(clone);
913 }
914 
916  const ExtCommunity *src,
918  ExtCommunity *clone;
919  if (src) {
920  clone = new ExtCommunity(*src);
921  } else {
922  clone = new ExtCommunity(this);
923  }
924 
925  clone->RemoveLoadBalance();
926  clone->Append(lb);
927  return Locate(clone);
928 }
929 
931  const ExtCommunity *src,
933  ExtCommunity *clone;
934  if (src) {
935  clone = new ExtCommunity(*src);
936  } else {
937  clone = new ExtCommunity(this);
938  }
939 
940  clone->RemoveSubCluster();
941  clone->Append(sc);
942  return Locate(clone);
943 }
944 
946  const ExtCommunity::ExtCommunityList &value) {
947  ExtCommunity *clone;
948  if (src) {
949  clone = new ExtCommunity(*src);
950  } else {
951  clone = new ExtCommunity(this);
952  }
953 
954  clone->Set(value);
955  return Locate(clone);
956 }
957 
959  char repr[80];
960  snprintf(repr, sizeof(repr), "LargeCommunity <code: %d, flags: %02x>:%d",
961  code, flags, (uint32_t)communities.size() / 3);
962  return string(repr);
963 }
964 
966  return communities.size() * sizeof(uint32_t);
967 }
968 
969 int LargeCommunitySpec::CompareTo(const BgpAttribute &rhs_attr) const {
970  int ret = BgpAttribute::CompareTo(rhs_attr);
971  if (ret != 0) return ret;
973  static_cast<const LargeCommunitySpec &>(rhs_attr).communities);
974  return 0;
975 }
976 
978  // add LarceComm to attr
979  attr->set_large_community(this);
980 }
981 
983  KEY_COMPARE(communities_.size(), rhs.communities_.size());
984 
985  LargeCommunityList::const_iterator i, j;
986  for (i = communities_.begin(), j = rhs.communities_.begin();
987  i < communities_.end(); ++i, ++j) {
988  if (*i < *j) {
989  return -1;
990  }
991  if (*i > *j) {
992  return 1;
993  }
994  }
995  return 0;
996 }
997 
999  for (LargeCommunityList::const_iterator it = list.begin();
1000  it != list.end(); ++it) {
1001  communities_.erase(std::remove(communities_.begin(),
1002  communities_.end(), *it), communities_.end());
1003  }
1004 }
1006  largecomm_db_->Delete(this);
1007 }
1008 
1010  communities_.clear();
1011  for (LargeCommunityList::const_iterator it = list.begin();
1012  it != list.end(); ++it) {
1013  communities_.push_back(*it);
1014  }
1015 }
1016 
1018  communities_.insert(communities_.end(), list.begin(), list.end());
1019  sort(communities_.begin(), communities_.end());
1020  LargeCommunityList::iterator it =
1021  unique(communities_.begin(), communities_.end());
1022  communities_.erase(it, communities_.end());
1023 }
1024 
1026  communities_.push_back(value);
1027  sort(communities_.begin(), communities_.end());
1028  LargeCommunityList::iterator it =
1029  unique(communities_.begin(), communities_.end());
1030  communities_.erase(it, communities_.end());
1031 }
1032 
1034  const string &comm, boost::system::error_code *errorp) {
1035  LargeCommunityValue data;
1036  put_value(&data[0], 12, 0);
1037  char *end;
1038  uint64_t value = strtoull(comm.c_str(), &end, 24);
1039  if (value == 0 || *end) {
1040  // e.g. 0 or 12x34ff (invalid hex)
1041  if (errorp != NULL) {
1042  *errorp = make_error_code(
1043  boost::system::errc::invalid_argument);
1044  return data;
1045  }
1046  }
1047  if (comm[0] == '0' && (comm[1] == 'x' || comm[1] == 'X')) {
1048  if (comm.length() > 26 && errorp != NULL) {
1049  // e.g. 0xabcdef0123456789abcdef012 is an invalid 8byte hex value
1050  *errorp = make_error_code(
1051  boost::system::errc::invalid_argument);
1052  return data;
1053  }
1054  } else {
1055  if (comm.length() > 24 && errorp != NULL) {
1056  // e.g. abcdef0123456789abcdef012 is an invalid 8byte hex value
1057  *errorp = make_error_code(
1058  boost::system::errc::invalid_argument);
1059  return data;
1060  }
1061  }
1062  put_value(&data[0], 12, value);
1063  return data;
1064 }
1065 
1067  const string &comm) {
1068  LargeCommunityList commList;
1069  LargeCommunityValue value;
1070  size_t pos = comm.find(':');
1071  string first(comm.substr(0, pos));
1072  boost::system::error_code error;
1073  value = FromHexString(comm, &error);
1074  if (error) {
1075  return commList;
1076  }
1077  commList.push_back(value);
1078  return commList;
1079 }
1080 
1082  char temp[50];
1083  int len = 0;
1084  for (size_t i = 0; i < comm.size(); i++) {
1085  len += snprintf(temp+len, sizeof(temp) - len, "%02x", (comm)[i]);
1086  }
1087  return(string(temp));
1088 }
1089 
1091  if (is_tag(comm)) {
1092  TagLC tag(comm);
1093  return(tag.ToString());
1094  }
1095  return ToHexString(comm);
1096 }
1097 
1099  for (LargeCommunityList::iterator it = communities_.begin();
1100  it != communities_.end(); ) {
1101  if (LargeCommunity::is_tag(*it)) {
1102  it = communities_.erase(it);
1103  } else {
1104  ++it;
1105  }
1106  }
1107 }
1108 
1109 vector<uint64_t> LargeCommunity::GetTagList(as_t asn) const {
1110  vector<uint64_t> tag_list;
1111  for (const auto &lc : communities_) {
1112  if (!LargeCommunity::is_tag(lc))
1113  continue;
1114  TagLC tag_comm(lc);
1115  if (asn && tag_comm.as_number() != asn && !tag_comm.IsGlobal())
1116  continue;
1117  tag_list.push_back(tag_comm.tag());
1118  }
1119 
1120  sort(tag_list.begin(), tag_list.end());
1121  vector<uint64_t>::iterator tag_iter = unique(tag_list.begin(),
1122  tag_list.end());
1123  tag_list.erase(tag_iter, tag_list.end());
1124  return tag_list;
1125 }
1126 
1127 
1129  const LargeCommunitySpec spec) : largecomm_db_(largecomm_db) {
1130  refcount_ = 0;
1131  std::vector<uint32_t>::const_iterator lcit = spec.communities.begin();
1132  while (lcit < spec.communities.end()) {
1133  LargeCommunityValue comm;
1134  put_value(comm.data(), 4, *lcit);
1135  lcit++;
1136  put_value(comm.data()+4, 4, *lcit);
1137  lcit++;
1138  put_value(comm.data()+8, 4, *lcit);
1139  lcit++;
1140  communities_.push_back(comm);
1141  }
1142  sort(communities_.begin(), communities_.end());
1143  LargeCommunityList::iterator it =
1144  unique(communities_.begin(), communities_.end());
1145  communities_.erase(it, communities_.end());
1146 }
1147 
1149 }
1150 
1152  const LargeCommunity::LargeCommunityList &list) {
1153  LargeCommunity *clone;
1154  if (src) {
1155  clone = new LargeCommunity(*src);
1156  } else {
1157  clone = new LargeCommunity(this);
1158  }
1159 
1160  clone->Append(list);
1161  return Locate(clone);
1162 }
1163 
1165  const LargeCommunity::LargeCommunityValue &value) {
1167  list.push_back(value);
1168  return AppendAndLocate(src, list);
1169 }
1170 
1172  const LargeCommunity *src,
1173  const LargeCommunity::LargeCommunityList &tag_list) {
1174  LargeCommunity *clone;
1175  if (src) {
1176  clone = new LargeCommunity(*src);
1177  } else {
1178  clone = new LargeCommunity(this);
1179  }
1180 
1181  clone->RemoveTag();
1182  clone->Append(tag_list);
1183  return Locate(clone);
1184 }
1185 
1187  const LargeCommunity::LargeCommunityList &list) {
1188  LargeCommunity *clone;
1189  if (src) {
1190  clone = new LargeCommunity(*src);
1191  } else {
1192  clone = new LargeCommunity(this);
1193  }
1194 
1195  clone->Remove(list);
1196  return Locate(clone);
1197 }
1198 
1199 
1201  const LargeCommunity::LargeCommunityList &list) {
1202  LargeCommunity *clone;
1203  if (src) {
1204  clone = new LargeCommunity(*src);
1205  } else {
1206  clone = new LargeCommunity(this);
1207  }
1208 
1209  clone->Set(list);
1210  return Locate(clone);
1211 }
1212 
#define AS_TRANS
Definition: bgp_common.h:23
uint16_t as2_t
Definition: bgp_common.h:22
uint32_t as_t
Definition: bgp_common.h:21
void set_community(CommunityPtr comm)
Definition: bgp_attr.cc:1000
void set_large_community(LargeCommunityPtr largecomm)
Definition: bgp_attr.cc:1024
void set_ext_community(ExtCommunityPtr extcomm)
Definition: bgp_attr.cc:1012
uint8_t flags
Definition: bgp_attr_base.h:71
virtual int CompareTo(const BgpAttribute &rhs) const
uint8_t code
Definition: bgp_attr_base.h:69
void Delete(Type *attr)
CommunityPtr RemoveAndLocate(const Community *src, const std::vector< uint32_t > &value)
Definition: community.cc:171
CommunityPtr AppendAndLocate(const Community *src, uint32_t value)
Definition: community.cc:132
CommunityDB(BgpServer *server)
Definition: community.cc:129
CommunityPtr SetAndLocate(const Community *src, const std::vector< uint32_t > &value)
Definition: community.cc:158
static const std::string CommunityToString(uint32_t comm)
const std::vector< uint32_t > & communities() const
Definition: community.h:67
std::vector< uint32_t > communities_
Definition: community.h:90
Community(CommunityDB *comm_db)
Definition: community.h:51
tbb::atomic< int > refcount_
Definition: community.h:88
int CompareTo(const Community &rhs) const
Definition: community.cc:70
void Set(const std::vector< uint32_t > &communities)
Definition: community.cc:96
CommunityDB * comm_db_
Definition: community.h:89
virtual void Remove()
Definition: community.cc:110
bool ContainsValue(uint32_t value) const
Definition: community.cc:114
void BuildStringList(std::vector< std::string > *list) const
Definition: community.cc:122
std::vector< uint32_t > CommunityList
Definition: community.h:50
void Append(uint32_t value)
Definition: community.cc:79
std::string ToString() const
Definition: etree.h:16
std::string ToString()
Definition: etree.cc:44
std::string ToString() const
Definition: es_import.cc:28
std::string ToString() const
Definition: esi_label.cc:44
ExtCommunityPtr AppendAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &list)
Definition: community.cc:697
ExtCommunityPtr RemoveVrfRouteImportAndLocate(const ExtCommunity *src)
Definition: community.cc:844
ExtCommunityPtr ReplaceVrfRouteImportAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityValue &vit)
Definition: community.cc:857
ExtCommunityPtr ReplaceMFlagsAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &export_list)
Definition: community.cc:730
ExtCommunityDB(BgpServer *server)
Definition: community.cc:694
ExtCommunityPtr RemoveSourceASAndLocate(const ExtCommunity *src)
Definition: community.cc:816
ExtCommunityPtr RemoveSiteOfOriginAndLocate(const ExtCommunity *src)
Definition: community.cc:788
ExtCommunityPtr ReplaceSGIDListAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &sgid_list)
Definition: community.cc:758
ExtCommunityPtr ReplaceSourceASAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityValue &sas)
Definition: community.cc:829
ExtCommunityPtr ReplaceSiteOfOriginAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityValue &soo)
Definition: community.cc:801
ExtCommunityPtr RemoveAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &list)
Definition: community.cc:717
ExtCommunityPtr ReplaceSubClusterAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityValue &sc)
Definition: community.cc:930
ExtCommunityPtr ReplaceTagListAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &tag_list)
Definition: community.cc:773
ExtCommunityPtr ReplaceLoadBalanceAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityValue &lb)
Definition: community.cc:915
ExtCommunityPtr ReplaceTunnelEncapsulationAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &tunnel_encaps)
Definition: community.cc:900
ExtCommunityPtr SetAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &list)
Definition: community.cc:945
ExtCommunityPtr ReplaceOriginVnAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityValue &origin_vn)
Definition: community.cc:885
ExtCommunityPtr RemoveOriginVnAndLocate(const ExtCommunity *src)
Definition: community.cc:872
ExtCommunityPtr ReplaceRTargetAndLocate(const ExtCommunity *src, const ExtCommunity::ExtCommunityList &export_list)
Definition: community.cc:744
void AddTunnelEncaps(std::vector< std::string > encaps)
Definition: community.cc:214
std::vector< uint64_t > communities
Definition: community.h:145
virtual int CompareTo(const BgpAttribute &rhs_attr) const
Definition: community.cc:202
virtual size_t EncodeLength() const
Definition: community.cc:198
virtual std::string ToString() const
Definition: community.cc:191
virtual void ToCanonical(BgpAttr *attr)
Definition: community.cc:210
static bool is_tunnel_encap(const ExtCommunityValue &val)
Definition: community.h:368
static bool is_router_mac(const ExtCommunityValue &val)
Definition: community.h:259
ExtCommunityList communities_
Definition: community.h:429
static bool is_route_target(const ExtCommunityValue &val)
Definition: community.h:267
static bool is_source_as(const ExtCommunityValue &val)
Definition: community.h:337
static ExtCommunityValue FromHexString(const std::string &comm, boost::system::error_code *errorp)
Definition: community.cc:273
static ExtCommunityList ExtCommunityFromString(const std::string &comm)
Definition: community.cc:306
bool ContainsOriginVn(as_t asn, uint32_t vn_index) const
Definition: community.cc:436
void RemoveVrfRouteImport()
Definition: community.cc:542
bool ContainsSourceAs(const ExtCommunityValue &val) const
Definition: community.cc:447
static bool is_esi_label(const ExtCommunityValue &val)
Definition: community.h:221
ExtCommunity(ExtCommunityDB *extcomm_db)
Definition: community.h:157
std::vector< int > GetTag4List(as_t asn=0) const
Definition: community.cc:633
void Set(const ExtCommunityList &list)
Definition: community.cc:249
int GetOriginVnIndex() const
Definition: community.cc:668
std::vector< ExtCommunityValue > ExtCommunityList
Definition: community.h:155
static bool is_security_group4(const ExtCommunityValue &val)
Definition: community.h:315
boost::array< uint8_t, 8 > ExtCommunityValue
Definition: community.h:154
static std::string ToHexString(const ExtCommunityValue &val)
Definition: community.cc:353
uint32_t GetSubClusterId() const
Definition: community.cc:456
static bool is_local_sequence_number(const ExtCommunityValue &val)
Definition: community.h:237
void RemoveMFlags()
Definition: community.cc:476
int CompareTo(const ExtCommunity &rhs) const
Definition: community.cc:222
std::vector< int > GetTagList(as2_t asn=0) const
Definition: community.cc:615
static std::string ToString(const ExtCommunityValue &val)
Definition: community.cc:362
static bool is_sub_cluster(const ExtCommunityValue &val)
Definition: community.h:348
void RemoveOriginVn()
Definition: community.cc:553
void Append(const ExtCommunityValue &value)
Definition: community.cc:265
static bool is_tag(const ExtCommunityValue &val)
Definition: community.h:380
void RemoveLoadBalance()
Definition: community.cc:574
bool ContainsRTarget(const ExtCommunityValue &val) const
Definition: community.cc:418
void RemoveTag()
Definition: community.cc:510
void RemoveSGID()
Definition: community.cc:498
static bool is_tag4(const ExtCommunityValue &val)
Definition: community.h:386
bool ContainsVrfRouteImport(const ExtCommunityValue &val) const
Definition: community.cc:467
static bool is_default_gateway(const ExtCommunityValue &val)
Definition: community.h:205
void RemoveSourceAS()
Definition: community.cc:532
void RemoveSubCluster()
Definition: community.cc:585
ExtCommunityDB * extcomm_db_
Definition: community.h:428
static bool is_load_balance(const ExtCommunityValue &val)
Definition: community.h:374
static bool is_security_group(const ExtCommunityValue &val)
Definition: community.h:306
static bool is_origin_vn(const ExtCommunityValue &val)
Definition: community.h:195
void RemoveRTarget()
Definition: community.cc:487
static bool is_mac_mobility(const ExtCommunityValue &val)
Definition: community.h:229
static bool is_etree(const ExtCommunityValue &val)
Definition: community.h:242
static bool is_site_of_origin(const ExtCommunityValue &val)
Definition: community.h:324
void RemoveTunnelEncapsulation()
Definition: community.cc:563
static bool is_es_import(const ExtCommunityValue &val)
Definition: community.h:213
static bool is_multicast_flags(const ExtCommunityValue &val)
Definition: community.h:250
static bool is_vrf_route_import(const ExtCommunityValue &val)
Definition: community.h:359
tbb::atomic< int > refcount_
Definition: community.h:427
std::vector< std::string > GetTunnelEncap() const
Definition: community.cc:596
bool ContainsTunnelEncapVxlan() const
Definition: community.cc:656
void RemoveSiteOfOrigin()
Definition: community.cc:521
virtual void Remove()
Definition: community.cc:245
This class represents a database for managing LargeCommunity objects. It is used to store,...
Definition: community.h:694
LargeCommunityPtr AppendAndLocate(const LargeCommunity *src, const LargeCommunity::LargeCommunityList &list)
Append a list of LargeCommunity values to an existing attribute.
Definition: community.cc:1151
LargeCommunityPtr ReplaceTagListAndLocate(const LargeCommunity *src, const LargeCommunity::LargeCommunityList &tag_list)
Replace all tags in a LargeCommunity with a new tag list.
Definition: community.cc:1171
LargeCommunityPtr SetAndLocate(const LargeCommunity *src, const LargeCommunity::LargeCommunityList &list)
Replace all values in a LargeCommunity with a new list.
Definition: community.cc:1200
LargeCommunityPtr RemoveAndLocate(const LargeCommunity *src, const LargeCommunity::LargeCommunityList &list)
Remove a list of LargeCommunity values from an existing attribute.
Definition: community.cc:1186
LargeCommunityDB(BgpServer *server)
Constructs an instance of the class and links to the given BgpServer instance.
Definition: community.cc:1148
This class encapsulates the wire-format representation of a BGP Large Community attribute and provide...
Definition: community.h:508
virtual void ToCanonical(BgpAttr *attr)
Convert the attribute to its canonical form.
Definition: community.cc:977
virtual size_t EncodeLength() const
Compute the encoded length of the attribute.
Definition: community.cc:965
virtual std::string ToString() const
Generate a human-readable string representation.
Definition: community.cc:958
virtual int CompareTo(const BgpAttribute &rhs_attr) const
Compare the attribute with another BgpAttribute.
Definition: community.cc:969
std::vector< uint32_t > communities
Vector of community values. Each Large Community value consists of three 4-byte fields (12 bytes tota...
Definition: community.h:532
This class represents an array of BGP Large Community values. A LargeCommunity consists of one or mor...
Definition: community.h:548
static std::string ToHexString(const LargeCommunityValue &val)
Convert a LargeCommunityValue to a hexadecimal string.
Definition: community.cc:1081
std::vector< LargeCommunityValue > LargeCommunityList
A list (vector) of LargeCommunityValue items.
Definition: community.h:554
tbb::atomic< int > refcount_
A reference counter, needed for memory management.
Definition: community.h:648
LargeCommunity(LargeCommunityDB *largecomm_db)
Constructs an instance of the class and links to the given LargeCommunityDB instance.
Definition: community.h:558
std::vector< uint64_t > GetTagList(as_t asn=0) const
Get the list of tags with the specified ASN.
Definition: community.cc:1109
void Set(const LargeCommunityList &list)
Replace all existing values with the provided list.
Definition: community.cc:1009
LargeCommunityDB * largecomm_db_
A pointer to the managing LargeCommunityDB.
Definition: community.h:650
virtual void Remove()
Remove this community.
Definition: community.cc:1005
int CompareTo(const LargeCommunity &rhs) const
Compare this LargeCommunity to another.
Definition: community.cc:982
static LargeCommunityList LargeCommunityFromString(const std::string &comm)
Parse a string into a list of LargeCommunity values.
Definition: community.cc:1066
static std::string ToString(const LargeCommunityValue &val)
Convert a LargeCommunityValue to a human-readable string.
Definition: community.cc:1090
void RemoveTag()
Remove all the tags.
Definition: community.cc:1098
LargeCommunityList communities_
A list of LargeCommunity storing BGP Large Community values.
Definition: community.h:652
boost::array< uint8_t, 12 > LargeCommunityValue
A single Large Community value.
Definition: community.h:551
static bool is_tag(const LargeCommunityValue &val)
Check if the LargeCommunity value is tag.
Definition: community.h:613
void Append(const LargeCommunityValue &value)
Append a single LargeCommunity value.
Definition: community.cc:1025
static LargeCommunityValue FromHexString(const std::string &comm, boost::system::error_code *errorp)
Convert a hexadecimal string to a LargeCommunityValue.
Definition: community.cc:1033
std::string ToString() const
std::string ToString()
Definition: mac_mobility.cc:43
int vn_index() const
Definition: origin_vn.cc:122
std::string ToString()
Definition: origin_vn.cc:138
const bytes_type & GetExtCommunity() const
Definition: origin_vn.h:33
std::string ToString() const
static RouteTarget FromString(const std::string &str, boost::system::error_code *error=NULL)
const bytes_type & GetExtCommunity() const
std::string ToString()
Definition: router_mac.cc:33
std::string ToString()
static SiteOfOrigin FromString(const std::string &str, boost::system::error_code *error=NULL)
const bytes_type & GetExtCommunity() const
std::string ToString() const
std::string ToString() const
Definition: source_as.cc:50
static SourceAs FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: source_as.cc:68
const bytes_type & GetExtCommunity() const
Definition: source_as.h:44
uint32_t GetId() const
Definition: sub_cluster.cc:37
const bytes_type & GetExtCommunity() const
Definition: sub_cluster.h:44
std::string ToString() const
Definition: sub_cluster.cc:59
static SubCluster FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: sub_cluster.cc:80
Represents a single BGP Large Community tag.
std::string ToString() const
Returns a string representation.
as_t as_number() const
Returns the AS number.
uint64_t tag() const
Returns the tag id.
bool IsGlobal() const
Returns true if this tag belongs to a global community.
as2_t as_number() const
std::string ToString() const
int tag() const
bool IsGlobal() const
const uint64_t GetExtCommunityValue() const
Definition: tunnel_encap.h:32
std::string ToString()
Definition: tunnel_encap.cc:51
std::string ToXmppString()
Definition: tunnel_encap.cc:57
TunnelEncapType::Encap tunnel_encap() const
Definition: tunnel_encap.cc:40
const bytes_type & GetExtCommunity() const
static VrfRouteImport FromString(const std::string &str, boost::system::error_code *error=NULL)
std::string ToString() const
boost::intrusive_ptr< const LargeCommunity > LargeCommunityPtr
Defines a type for automatic storage of a LargeCommunity instance.
Definition: community.h:678
boost::intrusive_ptr< const Community > CommunityPtr
Definition: community.h:111
boost::intrusive_ptr< const ExtCommunity > ExtCommunityPtr
Definition: community.h:450
static void put_value(uint8_t *data, int size, uint64_t value)
Definition: parse_object.h:55
virtual size_t EncodeLength() const
Definition: community.cc:75
virtual std::string ToString() const
Definition: community.cc:45
std::vector< uint32_t > communities
Definition: community.h:35
virtual void ToCanonical(BgpAttr *attr)
Definition: community.cc:41
#define KEY_COMPARE(x, y)
Definition: util.h:70