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 716 : string OriginVnPathSpec::ToString() const { 18 : char repr[80]; 19 716 : snprintf(repr, sizeof(repr), "OriginVnPath <code: %d, flags: %02x> : %zu", 20 716 : code, flags, origin_vns.size()); 21 716 : 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 723 : void OriginVnPathSpec::ToCanonical(BgpAttr *attr) { 34 723 : attr->set_origin_vn_path(this); 35 723 : } 36 : 37 12626 : size_t OriginVnPathSpec::EncodeLength() const { 38 12626 : return origin_vns.size() * sizeof(uint64_t); 39 : } 40 : 41 1753 : OriginVnPath::OriginVnPath(OriginVnPathDB *ovnpath_db, 42 1753 : const OriginVnPathSpec spec) 43 1753 : : ovnpath_db_(ovnpath_db) { 44 1753 : refcount_ = 0; 45 1757 : for (vector<uint64_t>::const_iterator it = spec.origin_vns.begin(); 46 2532 : it < spec.origin_vns.end(); ++it) { 47 : OriginVnValue value; 48 778 : put_value(value.data(), value.size(), *it); 49 778 : origin_vns_.push_back(value); 50 : } 51 1752 : } 52 : 53 1838 : void OriginVnPath::Remove() { 54 1838 : ovnpath_db_->Delete(this); 55 1838 : } 56 : 57 17610 : void OriginVnPath::Prepend(const OriginVnValue &value) { 58 17610 : OriginVnList::iterator it = origin_vns_.begin(); 59 17610 : origin_vns_.insert(it, value); 60 17610 : } 61 : 62 1720 : bool OriginVnPath::Contains(as_t asn, uint32_t vn_index) const { 63 1720 : if (asn <= 0xffff) { 64 1720 : OriginVn origin_vn(asn, vn_index); 65 1721 : 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 1750 : bool OriginVnPath::Contains(const OriginVnValue &val) const { 74 1750 : OriginVn in_origin_vn(val); 75 1750 : int in_vn_index = in_origin_vn.IsGlobal() ? in_origin_vn.vn_index() : 0; 76 1749 : for (OriginVnList::const_iterator it = origin_vns_.begin(); 77 2503 : it != origin_vns_.end(); ++it) { 78 1865 : if (*it == val) 79 1111 : return true; 80 759 : if (in_vn_index == 0) 81 698 : continue; 82 61 : OriginVn origin_vn(*it); 83 61 : if (origin_vn.vn_index() == in_vn_index) 84 5 : return true; 85 : } 86 638 : return false; 87 : } 88 : 89 588121 : int OriginVnPath::CompareTo(const OriginVnPath &rhs) const { 90 588121 : KEY_COMPARE(origin_vns_.size(), rhs.origin_vns_.size()); 91 : 92 586455 : OriginVnList::const_iterator it1, it2; 93 586455 : for (it1 = origin_vns_.begin(), it2 = rhs.origin_vns_.begin(); 94 625151 : it1 < origin_vns_.end(); ++it1, ++it2) { 95 40611 : if (*it1 < *it2) { 96 1154 : return -1; 97 : } 98 39457 : if (*it1 > *it2) { 99 761 : return 1; 100 : } 101 : } 102 584540 : return 0; 103 : } 104 : 105 9742 : OriginVnPathDB::OriginVnPathDB(BgpServer *server) { 106 9742 : } 107 : 108 17602 : OriginVnPathPtr OriginVnPathDB::PrependAndLocate(const OriginVnPath *ovnpath, 109 : const OriginVnPath::OriginVnValue &value) { 110 : OriginVnPath *clone; 111 17602 : if (ovnpath) { 112 922 : clone = new OriginVnPath(*ovnpath); 113 : } else { 114 16680 : clone = new OriginVnPath(this); 115 : } 116 17602 : clone->Prepend(value); 117 17602 : return Locate(clone); 118 : }