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 697 : string OriginVnPathSpec::ToString() const { 18 : char repr[80]; 19 697 : snprintf(repr, sizeof(repr), "OriginVnPath <code: %d, flags: %02x> : %zu", 20 697 : code, flags, origin_vns.size()); 21 697 : 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 703 : void OriginVnPathSpec::ToCanonical(BgpAttr *attr) { 34 703 : attr->set_origin_vn_path(this); 35 703 : } 36 : 37 12589 : size_t OriginVnPathSpec::EncodeLength() const { 38 12589 : return origin_vns.size() * sizeof(uint64_t); 39 : } 40 : 41 1733 : OriginVnPath::OriginVnPath(OriginVnPathDB *ovnpath_db, 42 1733 : const OriginVnPathSpec spec) 43 1733 : : ovnpath_db_(ovnpath_db) { 44 1736 : refcount_ = 0; 45 1738 : for (vector<uint64_t>::const_iterator it = spec.origin_vns.begin(); 46 2495 : 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 1736 : } 52 : 53 1851 : void OriginVnPath::Remove() { 54 1851 : ovnpath_db_->Delete(this); 55 1851 : } 56 : 57 17580 : void OriginVnPath::Prepend(const OriginVnValue &value) { 58 17580 : OriginVnList::iterator it = origin_vns_.begin(); 59 17580 : origin_vns_.insert(it, value); 60 17580 : } 61 : 62 1699 : bool OriginVnPath::Contains(as_t asn, uint32_t vn_index) const { 63 1699 : if (asn <= 0xffff) { 64 1699 : OriginVn origin_vn(asn, vn_index); 65 1699 : 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 1728 : bool OriginVnPath::Contains(const OriginVnValue &val) const { 74 1728 : OriginVn in_origin_vn(val); 75 1728 : int in_vn_index = in_origin_vn.IsGlobal() ? in_origin_vn.vn_index() : 0; 76 1728 : for (OriginVnList::const_iterator it = origin_vns_.begin(); 77 2485 : it != origin_vns_.end(); ++it) { 78 1844 : if (*it == val) 79 1087 : return true; 80 762 : if (in_vn_index == 0) 81 701 : continue; 82 61 : OriginVn origin_vn(*it); 83 61 : if (origin_vn.vn_index() == in_vn_index) 84 5 : return true; 85 : } 86 640 : return false; 87 : } 88 : 89 803630 : int OriginVnPath::CompareTo(const OriginVnPath &rhs) const { 90 803630 : KEY_COMPARE(origin_vns_.size(), rhs.origin_vns_.size()); 91 : 92 802013 : OriginVnList::const_iterator it1, it2; 93 802013 : for (it1 = origin_vns_.begin(), it2 = rhs.origin_vns_.begin(); 94 840563 : it1 < origin_vns_.end(); ++it1, ++it2) { 95 40429 : if (*it1 < *it2) { 96 1225 : return -1; 97 : } 98 39204 : if (*it1 > *it2) { 99 654 : return 1; 100 : } 101 : } 102 800134 : return 0; 103 : } 104 : 105 9742 : OriginVnPathDB::OriginVnPathDB(BgpServer *server) { 106 9742 : } 107 : 108 17572 : OriginVnPathPtr OriginVnPathDB::PrependAndLocate(const OriginVnPath *ovnpath, 109 : const OriginVnPath::OriginVnValue &value) { 110 : OriginVnPath *clone; 111 17572 : if (ovnpath) { 112 899 : clone = new OriginVnPath(*ovnpath); 113 : } else { 114 16673 : clone = new OriginVnPath(this); 115 : } 116 17572 : clone->Prepend(value); 117 17572 : return Locate(clone); 118 : }