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 722 : string OriginVnPathSpec::ToString() const { 18 : char repr[80]; 19 722 : snprintf(repr, sizeof(repr), "OriginVnPath <code: %d, flags: %02x> : %zu", 20 722 : code, flags, origin_vns.size()); 21 722 : 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 729 : void OriginVnPathSpec::ToCanonical(BgpAttr *attr) { 34 729 : attr->set_origin_vn_path(this); 35 729 : } 36 : 37 12634 : size_t OriginVnPathSpec::EncodeLength() const { 38 12634 : return origin_vns.size() * sizeof(uint64_t); 39 : } 40 : 41 1764 : OriginVnPath::OriginVnPath(OriginVnPathDB *ovnpath_db, 42 1764 : const OriginVnPathSpec spec) 43 1764 : : ovnpath_db_(ovnpath_db) { 44 1764 : refcount_ = 0; 45 1764 : for (vector<uint64_t>::const_iterator it = spec.origin_vns.begin(); 46 2549 : it < spec.origin_vns.end(); ++it) { 47 : OriginVnValue value; 48 785 : put_value(value.data(), value.size(), *it); 49 785 : origin_vns_.push_back(value); 50 : } 51 1764 : } 52 : 53 1832 : void OriginVnPath::Remove() { 54 1832 : ovnpath_db_->Delete(this); 55 1832 : } 56 : 57 17572 : void OriginVnPath::Prepend(const OriginVnValue &value) { 58 17572 : OriginVnList::iterator it = origin_vns_.begin(); 59 17572 : origin_vns_.insert(it, value); 60 17572 : } 61 : 62 1727 : bool OriginVnPath::Contains(as_t asn, uint32_t vn_index) const { 63 1727 : if (asn <= 0xffff) { 64 1727 : OriginVn origin_vn(asn, vn_index); 65 1727 : 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 1756 : bool OriginVnPath::Contains(const OriginVnValue &val) const { 74 1756 : OriginVn in_origin_vn(val); 75 1756 : int in_vn_index = in_origin_vn.IsGlobal() ? in_origin_vn.vn_index() : 0; 76 1756 : for (OriginVnList::const_iterator it = origin_vns_.begin(); 77 2495 : it != origin_vns_.end(); ++it) { 78 1872 : if (*it == val) 79 1133 : return true; 80 744 : if (in_vn_index == 0) 81 683 : continue; 82 61 : OriginVn origin_vn(*it); 83 61 : if (origin_vn.vn_index() == in_vn_index) 84 5 : return true; 85 : } 86 623 : return false; 87 : } 88 : 89 1338947 : int OriginVnPath::CompareTo(const OriginVnPath &rhs) const { 90 1338947 : KEY_COMPARE(origin_vns_.size(), rhs.origin_vns_.size()); 91 : 92 1337319 : OriginVnList::const_iterator it1, it2; 93 1337319 : for (it1 = origin_vns_.begin(), it2 = rhs.origin_vns_.begin(); 94 1375915 : it1 < origin_vns_.end(); ++it1, ++it2) { 95 40331 : if (*it1 < *it2) { 96 1142 : return -1; 97 : } 98 39189 : if (*it1 > *it2) { 99 593 : return 1; 100 : } 101 : } 102 1335584 : return 0; 103 : } 104 : 105 10141 : OriginVnPathDB::OriginVnPathDB(BgpServer *server) { 106 10141 : } 107 : 108 17564 : OriginVnPathPtr OriginVnPathDB::PrependAndLocate(const OriginVnPath *ovnpath, 109 : const OriginVnPath::OriginVnValue &value) { 110 : OriginVnPath *clone; 111 17564 : if (ovnpath) { 112 903 : clone = new OriginVnPath(*ovnpath); 113 : } else { 114 16661 : clone = new OriginVnPath(this); 115 : } 116 17564 : clone->Prepend(value); 117 17564 : return Locate(clone); 118 : }