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 : #ifndef SRC_BGP_BGP_ORIGIN_VN_PATH_H_ 7 : #define SRC_BGP_BGP_ORIGIN_VN_PATH_H_ 8 : 9 : #include <boost/array.hpp> 10 : #include <boost/intrusive_ptr.hpp> 11 : 12 : #include <set> 13 : #include <string> 14 : #include <vector> 15 : #include <atomic> 16 : 17 : #include "base/parse_object.h" 18 : #include "base/util.h" 19 : #include "bgp/bgp_attr_base.h" 20 : #include "bgp/bgp_common.h" 21 : 22 : class BgpAttr; 23 : class OriginVnPathDB; 24 : class BgpServer; 25 : 26 : struct OriginVnPathSpec : public BgpAttribute { 27 : static const int kSize = -1; 28 : static const uint8_t kFlags = Optional | Transitive; 29 5732 : OriginVnPathSpec() : BgpAttribute(OriginVnPath, kFlags) { } 30 3252 : explicit OriginVnPathSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) { } 31 : std::vector<uint64_t> origin_vns; 32 : virtual int CompareTo(const BgpAttribute &rhs_attr) const; 33 : virtual void ToCanonical(BgpAttr *attr); 34 : virtual std::string ToString() const; 35 : virtual size_t EncodeLength() const; 36 : }; 37 : 38 : class OriginVnPath { 39 : public: 40 : typedef boost::array<uint8_t, 8> OriginVnValue; 41 : typedef std::vector<OriginVnValue> OriginVnList; 42 : 43 16714 : explicit OriginVnPath(OriginVnPathDB *ovnpath_db) 44 16714 : : ovnpath_db_(ovnpath_db) { 45 16714 : refcount_ = 0; 46 16714 : } 47 899 : explicit OriginVnPath(const OriginVnPath &rhs) 48 899 : : ovnpath_db_(rhs.ovnpath_db_), 49 899 : origin_vns_(rhs.origin_vns_) { 50 899 : refcount_ = 0; 51 899 : } 52 : explicit OriginVnPath(OriginVnPathDB *ovnpath_db, 53 : const OriginVnPathSpec spec); 54 37705 : virtual ~OriginVnPath() { } 55 : virtual void Remove(); 56 : 57 : bool Contains(const OriginVnValue &value) const; 58 : bool Contains(as_t asn, uint32_t vn_index) const; 59 : int CompareTo(const OriginVnPath &rhs) const; 60 : 61 3392 : const OriginVnList &origin_vns() const { return origin_vns_; } 62 : 63 0 : friend std::size_t hash_value(const OriginVnPath &ovnpath) { 64 0 : size_t hash = 0; 65 0 : for (OriginVnList::const_iterator it = ovnpath.origin_vns_.begin(); 66 0 : it != ovnpath.origin_vns_.end(); ++it) { 67 0 : boost::hash_range(hash, it->begin(), it->end()); 68 : } 69 0 : return hash; 70 : } 71 : 72 : private: 73 : friend int intrusive_ptr_add_ref(const OriginVnPath *covnpath); 74 : friend int intrusive_ptr_del_ref(const OriginVnPath *covnpath); 75 : friend void intrusive_ptr_release(const OriginVnPath *covnpath); 76 : friend class OriginVnPathDB; 77 : friend class BgpAttrTest; 78 : 79 : void Prepend(const OriginVnValue &value); 80 : 81 : mutable std::atomic<int> refcount_; 82 : OriginVnPathDB *ovnpath_db_; 83 : OriginVnList origin_vns_; 84 : }; 85 : 86 514541 : inline int intrusive_ptr_add_ref(const OriginVnPath *covnpath) { 87 1029082 : return covnpath->refcount_.fetch_add(1); 88 : } 89 : 90 341101 : inline int intrusive_ptr_del_ref(const OriginVnPath *covnpath) { 91 682202 : return covnpath->refcount_.fetch_sub(1); 92 : } 93 : 94 173459 : inline void intrusive_ptr_release(const OriginVnPath *covnpath) { 95 173459 : int prev = covnpath->refcount_.fetch_sub(1); 96 173459 : if (prev == 1) { 97 1837 : OriginVnPath *ovnpath = const_cast<OriginVnPath *>(covnpath); 98 1837 : ovnpath->Remove(); 99 1837 : assert(ovnpath->refcount_ == 0); 100 1837 : delete ovnpath; 101 : } 102 173459 : } 103 : 104 : typedef boost::intrusive_ptr<const OriginVnPath> OriginVnPathPtr; 105 : 106 : struct OriginVnPathCompare { 107 685708 : bool operator()(const OriginVnPath *lhs, const OriginVnPath *rhs) const { 108 685708 : return lhs->CompareTo(*rhs) < 0; 109 : } 110 : }; 111 : 112 : class OriginVnPathDB : public BgpPathAttributeDB<OriginVnPath, OriginVnPathPtr, 113 : OriginVnPathSpec, 114 : OriginVnPathCompare, 115 : OriginVnPathDB> { 116 : public: 117 : explicit OriginVnPathDB(BgpServer *server); 118 : OriginVnPathPtr PrependAndLocate(const OriginVnPath *ovnpath, 119 : const OriginVnPath::OriginVnValue &value); 120 : 121 : private: 122 : DISALLOW_COPY_AND_ASSIGN(OriginVnPathDB); 123 : }; 124 : 125 : #endif // SRC_BGP_BGP_ORIGIN_VN_PATH_H_