-
Notifications
You must be signed in to change notification settings - Fork 390
/
bgp_origin_vn_path.h
122 lines (100 loc) · 3.7 KB
/
bgp_origin_vn_path.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
*/
#ifndef SRC_BGP_BGP_ORIGIN_VN_PATH_H_
#define SRC_BGP_BGP_ORIGIN_VN_PATH_H_
#include <boost/array.hpp>
#include <boost/intrusive_ptr.hpp>
#include <tbb/atomic.h>
#include <set>
#include <string>
#include <vector>
#include "base/parse_object.h"
#include "base/util.h"
#include "bgp/bgp_attr_base.h"
class BgpAttr;
class OriginVnPathDB;
class BgpServer;
struct OriginVnPathSpec : public BgpAttribute {
static const int kSize = -1;
static const uint8_t kFlags = Optional | Transitive;
OriginVnPathSpec() : BgpAttribute(OriginVnPath, kFlags) { }
explicit OriginVnPathSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) { }
std::vector<uint64_t> origin_vns;
virtual int CompareTo(const BgpAttribute &rhs_attr) const;
virtual void ToCanonical(BgpAttr *attr);
virtual std::string ToString() const;
virtual size_t EncodeLength() const;
};
class OriginVnPath {
public:
typedef boost::array<uint8_t, 8> OriginVnValue;
typedef std::vector<OriginVnValue> OriginVnList;
explicit OriginVnPath(OriginVnPathDB *ovnpath_db)
: ovnpath_db_(ovnpath_db) {
refcount_ = 0;
}
explicit OriginVnPath(const OriginVnPath &rhs)
: ovnpath_db_(rhs.ovnpath_db_),
origin_vns_(rhs.origin_vns_) {
refcount_ = 0;
}
explicit OriginVnPath(OriginVnPathDB *ovnpath_db,
const OriginVnPathSpec spec);
virtual ~OriginVnPath() { }
virtual void Remove();
bool Contains(const OriginVnValue &value) const;
int CompareTo(const OriginVnPath &rhs) const;
const OriginVnList &origin_vns() const { return origin_vns_; }
friend std::size_t hash_value(const OriginVnPath &ovnpath) {
size_t hash = 0;
for (OriginVnList::const_iterator it = ovnpath.origin_vns_.begin();
it != ovnpath.origin_vns_.end(); ++it) {
boost::hash_range(hash, it->begin(), it->end());
}
return hash;
}
private:
friend int intrusive_ptr_add_ref(const OriginVnPath *covnpath);
friend int intrusive_ptr_del_ref(const OriginVnPath *covnpath);
friend void intrusive_ptr_release(const OriginVnPath *covnpath);
friend class OriginVnPathDB;
friend class BgpAttrTest;
void Prepend(const OriginVnValue &value);
mutable tbb::atomic<int> refcount_;
OriginVnPathDB *ovnpath_db_;
OriginVnList origin_vns_;
};
inline int intrusive_ptr_add_ref(const OriginVnPath *covnpath) {
return covnpath->refcount_.fetch_and_increment();
}
inline int intrusive_ptr_del_ref(const OriginVnPath *covnpath) {
return covnpath->refcount_.fetch_and_decrement();
}
inline void intrusive_ptr_release(const OriginVnPath *covnpath) {
int prev = covnpath->refcount_.fetch_and_decrement();
if (prev == 1) {
OriginVnPath *ovnpath = const_cast<OriginVnPath *>(covnpath);
ovnpath->Remove();
assert(ovnpath->refcount_ == 0);
delete ovnpath;
}
}
typedef boost::intrusive_ptr<const OriginVnPath> OriginVnPathPtr;
struct OriginVnPathCompare {
bool operator()(const OriginVnPath *lhs, const OriginVnPath *rhs) {
return lhs->CompareTo(*rhs) < 0;
}
};
class OriginVnPathDB : public BgpPathAttributeDB<OriginVnPath, OriginVnPathPtr,
OriginVnPathSpec,
OriginVnPathCompare,
OriginVnPathDB> {
public:
explicit OriginVnPathDB(BgpServer *server);
OriginVnPathPtr PrependAndLocate(const OriginVnPath *ovnpath,
const OriginVnPath::OriginVnValue &value);
private:
DISALLOW_COPY_AND_ASSIGN(OriginVnPathDB);
};
#endif // SRC_BGP_BGP_ORIGIN_VN_PATH_H_