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 696 : string OriginVnPathSpec::ToString() const { 18 : char repr[80]; 19 696 : snprintf(repr, sizeof(repr), "OriginVnPath <code: %d, flags: %02x> : %zu", 20 696 : code, flags, origin_vns.size()); 21 696 : 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 702 : void OriginVnPathSpec::ToCanonical(BgpAttr *attr) { 34 702 : attr->set_origin_vn_path(this); 35 702 : } 36 : 37 12584 : size_t OriginVnPathSpec::EncodeLength() const { 38 12584 : return origin_vns.size() * sizeof(uint64_t); 39 : } 40 : 41 1725 : OriginVnPath::OriginVnPath(OriginVnPathDB *ovnpath_db, 42 1725 : const OriginVnPathSpec spec) 43 1725 : : ovnpath_db_(ovnpath_db) { 44 1725 : refcount_ = 0; 45 1737 : for (vector<uint64_t>::const_iterator it = spec.origin_vns.begin(); 46 2490 : it < spec.origin_vns.end(); ++it) { 47 : OriginVnValue value; 48 758 : put_value(value.data(), value.size(), *it); 49 758 : origin_vns_.push_back(value); 50 : } 51 1729 : } 52 : 53 1844 : void OriginVnPath::Remove() { 54 1844 : ovnpath_db_->Delete(this); 55 1844 : } 56 : 57 17535 : void OriginVnPath::Prepend(const OriginVnValue &value) { 58 17535 : OriginVnList::iterator it = origin_vns_.begin(); 59 17535 : origin_vns_.insert(it, value); 60 17535 : } 61 : 62 1712 : bool OriginVnPath::Contains(as_t asn, uint32_t vn_index) const { 63 1712 : if (asn <= 0xffff) { 64 1712 : OriginVn origin_vn(asn, vn_index); 65 1711 : 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 1740 : bool OriginVnPath::Contains(const OriginVnValue &val) const { 74 1740 : OriginVn in_origin_vn(val); 75 1741 : int in_vn_index = in_origin_vn.IsGlobal() ? in_origin_vn.vn_index() : 0; 76 1741 : for (OriginVnList::const_iterator it = origin_vns_.begin(); 77 2513 : it != origin_vns_.end(); ++it) { 78 1857 : if (*it == val) 79 1085 : return true; 80 777 : if (in_vn_index == 0) 81 716 : continue; 82 61 : OriginVn origin_vn(*it); 83 61 : if (origin_vn.vn_index() == in_vn_index) 84 5 : return true; 85 : } 86 656 : return false; 87 : } 88 : 89 379469 : int OriginVnPath::CompareTo(const OriginVnPath &rhs) const { 90 379469 : KEY_COMPARE(origin_vns_.size(), rhs.origin_vns_.size()); 91 : 92 377845 : OriginVnList::const_iterator it1, it2; 93 377845 : for (it1 = origin_vns_.begin(), it2 = rhs.origin_vns_.begin(); 94 416305 : it1 < origin_vns_.end(); ++it1, ++it2) { 95 40231 : if (*it1 < *it2) { 96 1117 : return -1; 97 : } 98 39114 : if (*it1 > *it2) { 99 654 : return 1; 100 : } 101 : } 102 376074 : return 0; 103 : } 104 : 105 9742 : OriginVnPathDB::OriginVnPathDB(BgpServer *server) { 106 9742 : } 107 : 108 17527 : OriginVnPathPtr OriginVnPathDB::PrependAndLocate(const OriginVnPath *ovnpath, 109 : const OriginVnPath::OriginVnValue &value) { 110 : OriginVnPath *clone; 111 17527 : if (ovnpath) { 112 899 : clone = new OriginVnPath(*ovnpath); 113 : } else { 114 16628 : clone = new OriginVnPath(this); 115 : } 116 17527 : clone->Prepend(value); 117 17527 : return Locate(clone); 118 : }