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