Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include "bgp/bgp_origin_vn_path.h" 6 : 7 : 8 : #include <algorithm> 9 : #include <string> 10 : 11 : #include "bgp/bgp_proto.h" 12 : #include "bgp/origin-vn/origin_vn.h" 13 : 14 : using std::string; 15 : using std::vector; 16 : 17 725 : string OriginVnPathSpec::ToString() const { 18 : char repr[80]; 19 725 : snprintf(repr, sizeof(repr), "OriginVnPath <code: %d, flags: %02x> : %zu", 20 725 : code, flags, origin_vns.size()); 21 725 : return string(repr); 22 : } 23 : 24 1968 : int OriginVnPathSpec::CompareTo(const BgpAttribute &rhs) const { 25 1968 : int ret = BgpAttribute::CompareTo(rhs); 26 1968 : if (ret != 0) 27 0 : return ret; 28 1968 : KEY_COMPARE(origin_vns, 29 : static_cast<const OriginVnPathSpec &>(rhs).origin_vns); 30 1968 : return 0; 31 : } 32 : 33 731 : void OriginVnPathSpec::ToCanonical(BgpAttr *attr) { 34 731 : attr->set_origin_vn_path(this); 35 731 : } 36 : 37 12695 : size_t OriginVnPathSpec::EncodeLength() const { 38 12695 : return origin_vns.size() * sizeof(uint64_t); 39 : } 40 : 41 1761 : OriginVnPath::OriginVnPath(OriginVnPathDB *ovnpath_db, 42 1761 : const OriginVnPathSpec spec) 43 1761 : : ovnpath_db_(ovnpath_db) { 44 1761 : refcount_ = 0; 45 1766 : for (vector<uint64_t>::const_iterator it = spec.origin_vns.begin(); 46 2552 : it < spec.origin_vns.end(); ++it) { 47 : OriginVnValue value; 48 786 : put_value(value.data(), value.size(), *it); 49 786 : origin_vns_.push_back(value); 50 : } 51 1766 : } 52 : 53 1848 : void OriginVnPath::Remove() { 54 1848 : ovnpath_db_->Delete(this); 55 1848 : } 56 : 57 17630 : void OriginVnPath::Prepend(const OriginVnValue &value) { 58 17630 : OriginVnList::iterator it = origin_vns_.begin(); 59 17630 : origin_vns_.insert(it, value); 60 17630 : } 61 : 62 1726 : bool OriginVnPath::Contains(as_t asn, uint32_t vn_index) const { 63 1726 : if (asn <= 0xffff) { 64 1726 : OriginVn origin_vn(asn, vn_index); 65 1726 : return Contains(origin_vn.GetExtCommunity()); 66 : } 67 0 : OriginVn origin_vn4(asn, AS_TRANS); 68 0 : OriginVn origin_vn(AS_TRANS, vn_index); 69 0 : return (Contains(origin_vn.GetExtCommunity()) && 70 0 : Contains(origin_vn4.GetExtCommunity())); 71 : } 72 : 73 1755 : bool OriginVnPath::Contains(const OriginVnValue &val) const { 74 1755 : OriginVn in_origin_vn(val); 75 1755 : int in_vn_index = in_origin_vn.IsGlobal() ? in_origin_vn.vn_index() : 0; 76 1755 : for (OriginVnList::const_iterator it = origin_vns_.begin(); 77 2508 : it != origin_vns_.end(); ++it) { 78 1871 : if (*it == val) 79 1118 : return true; 80 758 : if (in_vn_index == 0) 81 697 : continue; 82 61 : OriginVn origin_vn(*it); 83 61 : if (origin_vn.vn_index() == in_vn_index) 84 5 : return true; 85 : } 86 637 : return false; 87 : } 88 : 89 669021 : int OriginVnPath::CompareTo(const OriginVnPath &rhs) const { 90 669021 : KEY_COMPARE(origin_vns_.size(), rhs.origin_vns_.size()); 91 : 92 667366 : OriginVnList::const_iterator it1, it2; 93 667366 : for (it1 = origin_vns_.begin(), it2 = rhs.origin_vns_.begin(); 94 706114 : it1 < origin_vns_.end(); ++it1, ++it2) { 95 40646 : if (*it1 < *it2) { 96 1219 : return -1; 97 : } 98 39427 : if (*it1 > *it2) { 99 679 : return 1; 100 : } 101 : } 102 665468 : return 0; 103 : } 104 : 105 9742 : OriginVnPathDB::OriginVnPathDB(BgpServer *server) { 106 9742 : } 107 : 108 17622 : OriginVnPathPtr OriginVnPathDB::PrependAndLocate(const OriginVnPath *ovnpath, 109 : const OriginVnPath::OriginVnValue &value) { 110 : OriginVnPath *clone; 111 17622 : if (ovnpath) { 112 920 : clone = new OriginVnPath(*ovnpath); 113 : } else { 114 16702 : clone = new OriginVnPath(this); 115 : } 116 17622 : clone->Prepend(value); 117 17622 : return Locate(clone); 118 : }