Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge "Prevent loops when re-originating service chain routes"
- Loading branch information
Showing
20 changed files
with
898 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. | ||
*/ | ||
|
||
#include "bgp/bgp_origin_vn_path.h" | ||
|
||
#include <boost/foreach.hpp> | ||
|
||
#include <algorithm> | ||
#include <string> | ||
|
||
#include "bgp/bgp_proto.h" | ||
|
||
using std::string; | ||
using std::vector; | ||
|
||
string OriginVnPathSpec::ToString() const { | ||
char repr[80]; | ||
snprintf(repr, sizeof(repr), "OriginVnPath <code: %d, flags: %02x> : %lu", | ||
code, flags, origin_vns.size()); | ||
return string(repr); | ||
} | ||
|
||
int OriginVnPathSpec::CompareTo(const BgpAttribute &rhs) const { | ||
int ret = BgpAttribute::CompareTo(rhs); | ||
if (ret != 0) | ||
return ret; | ||
KEY_COMPARE(origin_vns, | ||
static_cast<const OriginVnPathSpec &>(rhs).origin_vns); | ||
return 0; | ||
} | ||
|
||
void OriginVnPathSpec::ToCanonical(BgpAttr *attr) { | ||
attr->set_origin_vn_path(this); | ||
} | ||
|
||
OriginVnPath::OriginVnPath(OriginVnPathDB *ovnpath_db, | ||
const OriginVnPathSpec spec) | ||
: ovnpath_db_(ovnpath_db) { | ||
refcount_ = 0; | ||
for (vector<uint64_t>::const_iterator it = spec.origin_vns.begin(); | ||
it < spec.origin_vns.end(); ++it) { | ||
OriginVnValue value; | ||
put_value(value.data(), value.size(), *it); | ||
origin_vns_.push_back(value); | ||
} | ||
} | ||
|
||
void OriginVnPath::Remove() { | ||
ovnpath_db_->Delete(this); | ||
} | ||
|
||
void OriginVnPath::Prepend(const OriginVnValue &value) { | ||
OriginVnList::iterator it = origin_vns_.begin(); | ||
origin_vns_.insert(it, value); | ||
} | ||
|
||
bool OriginVnPath::Contains(const OriginVnValue &val) const { | ||
for (OriginVnList::const_iterator it = origin_vns_.begin(); | ||
it != origin_vns_.end(); ++it) { | ||
if (*it == val) | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
int OriginVnPath::CompareTo(const OriginVnPath &rhs) const { | ||
KEY_COMPARE(origin_vns_.size(), rhs.origin_vns_.size()); | ||
|
||
OriginVnList::const_iterator it1, it2; | ||
for (it1 = origin_vns_.begin(), it2 = rhs.origin_vns_.begin(); | ||
it1 < origin_vns_.end(); ++it1, ++it2) { | ||
if (*it1 < *it2) { | ||
return -1; | ||
} | ||
if (*it1 > *it2) { | ||
return 1; | ||
} | ||
} | ||
return 0; | ||
} | ||
|
||
OriginVnPathDB::OriginVnPathDB(BgpServer *server) { | ||
} | ||
|
||
OriginVnPathPtr OriginVnPathDB::PrependAndLocate(const OriginVnPath *ovnpath, | ||
const OriginVnPath::OriginVnValue &value) { | ||
OriginVnPath *clone; | ||
if (ovnpath) { | ||
clone = new OriginVnPath(*ovnpath); | ||
} else { | ||
clone = new OriginVnPath(this); | ||
} | ||
clone->Prepend(value); | ||
return Locate(clone); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/* | ||
* 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 "bgp/bgp_attr_base.h" | ||
#include "base/parse_object.h" | ||
#include "base/util.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; | ||
}; | ||
|
||
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(); | ||
void Prepend(const OriginVnValue &value); | ||
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); | ||
|
||
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_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.