6 #include <boost/assign/list_of.hpp>
7 #include <boost/bind/bind.hpp>
8 #include <yaml-cpp/yaml.h>
13 using boost::assign::map_list_of;
14 using namespace boost::placeholders;
29 pair<NeighborMap::iterator, bool> result =
30 neighbors_.insert(make_pair(neighbor->
name(), neighbor));
31 bool success = result.second;
102 return routing_policies_;
105 return &routing_policies_;
110 InstanceMap::iterator loc = instances_.find(name);
111 if (loc != instances_.end()) {
114 pair<InstanceMap::iterator, bool> result =
117 return result.first->second;
121 RoutingPolicyMap::iterator loc = routing_policies_.find(name);
122 if (loc != routing_policies_.end()) {
125 pair<RoutingPolicyMap::iterator, bool> result =
126 routing_policies_.insert(
128 return result.first->second;
132 InstanceDataMap::iterator loc = config_map_.find(name);
133 if (loc != config_map_.end()) {
136 pair<InstanceDataMap::iterator, bool> result =
139 return result.first->second;
161 PeerTypeMap::const_iterator loc =
peertype_map.find(value);
187 return make_pair(map.lower_bound(start_name), map.end());
192 const std::string &policy_name)
const {
194 return make_pair(map.begin(), map.end());
198 const std::string &instance_name)
const {
200 return make_pair(map.begin(), map.end());
204 const std::string &instance_name)
const {
210 const std::string &name)
const {
215 const std::string &instance_name)
const {
216 return data_->GetProtocolConfig(instance_name);
220 const std::string &instance_name,
const std::string &name)
const {
224 static bool ParseTimers(
const YAML::Node &timers, uint32_t *hold_time,
226 if (timers[
"hold-time"]) {
229 value = timers[
"hold-time"].as<uint32_t>();
231 *error_msg =
"Invalid hold-time value: not an integer";
236 msg <<
"Invalid hold-time value (out of range): " << value;
237 *error_msg = msg.str();
254 value = node.as<
string>();
256 *error_msg =
"Invalid identifier value: not a string";
259 boost::system::error_code ec;
260 Ip4Address address = Ip4Address::from_string(value, ec);
263 long int id = strtol(value.c_str(), &endp, 10);
264 size_t strlen = endp - value.c_str();
265 if (
id == 0 || strlen != value.length()) {
266 *error_msg =
"Invalid identifier value: "
267 "not an IP address or integer";
272 *valuep = htonl(address.to_ulong());
279 if (node[
"peer-as"]) {
282 value = node[
"peer-as"].as<
int>();
284 *error_msg =
"Invalid peer-as value: not an integer";
287 if (value < 0 || value > USHRT_MAX) {
289 msg <<
"Invalid peer-as value (out of range): " << value;
290 *error_msg = msg.str();
299 value = node[
"port"].as<
int>();
301 *error_msg =
"Invalid port value: not an integer";
304 if (value < 0 || value > USHRT_MAX) {
306 msg <<
"Invalid port value (out of range): " << value;
307 *error_msg = msg.str();
313 if (node[
"peer-type"]) {
316 value = node[
"peer-type"].as<
string>();
318 *error_msg =
"Invalid peer-type value: not a string";
324 msg <<
"Invalid peer-type value: " << value;
325 *error_msg = msg.str();
331 if (node[
"identifier"]) {
339 if (node[
"local-identifier"]) {
347 if (node[
"local-address"]) {
350 value = node[
"local-address"].as<
string>();
352 *error_msg =
"Invalid local-address value: not a string";
355 boost::system::error_code ec;
356 IpAddress address = IpAddress::from_string(value, ec);
359 ss <<
"Invalid local-address value: " << value;
360 *error_msg = ss.str();
363 LOG(DEBUG,
"local-address " << address.to_string() <<
" not used");
367 if (node[
"timers"]) {
369 if (!
ParseTimers(node[
"timers"], &hold_time, error_msg)) {
377 if (node[
"address-families"]) {
378 YAML::Node families = node[
"address-families"];
380 for (YAML::const_iterator iter = families.begin();
381 iter != families.end(); ++iter) {
384 family = iter->as<
string>();
386 *error_msg =
"Invalid address family value: not a string";
390 *error_msg =
"Invalid address family value: " + family;
394 list.push_back(family_config);
408 const YAML::Node &node,
string *error_msg) {
410 *error_msg =
"Expected mapping under bgp:neighbors";
413 for (YAML::const_iterator iter = node.begin();
414 iter != node.end(); ++iter) {
417 address = iter->first.as<
string>();
419 *error_msg =
"Invalid neighbor key: not a string";
422 boost::system::error_code ec;
423 IpAddress ipaddress = IpAddress::from_string(address, ec);
425 *error_msg =
"Invalid address: " + address;
428 LOG(DEBUG,
"neighbor: " << address);
430 neighbor->CopyValues(*tmpl);
431 neighbor->set_name(address);
432 neighbor->set_peer_address(ipaddress);
437 neighbor.release())) {
438 *error_msg =
"Duplicate neighbor " + address;
448 const string &group_name,
449 const YAML::Node &node,
string *error_msg) {
458 YAML::Node neighbors = node[
"neighbors"];
467 const YAML::Node &node,
string *error_msg) {
469 *error_msg =
"Expected mapping under bgp:peer-groups";
473 for (YAML::const_iterator iter = node.begin();
474 iter != node.end(); ++iter) {
477 group_name = iter->first.as<
string>();
479 *error_msg =
"Invalid group key: not a string";
491 const YAML::Node &node,
string *error_msg) {
495 if (node[
"autonomous-system"]) {
498 value = node[
"autonomous-system"].as<
int>();
500 *error_msg =
"Invalid autonomous-system number: not an integer";
509 value = node[
"port"].as<
int>();
511 *error_msg =
"Invalid port number: not an integer";
514 if (value < 0 || value > USHRT_MAX) {
516 msg <<
"Invalid port value (out of range): " << value;
517 *error_msg = msg.str();
523 if (node[
"identifier"]) {
531 YAML::Node timers = node[
"timers"];
534 if (!
ParseTimers(node[
"timers"], &hold_time, error_msg)) {
542 YAML::Node groups = node[
"peer-groups"];
543 if (groups && !
ParseBgpGroups(data, &global, groups, error_msg)) {
547 YAML::Node neighbors = node[
"neighbors"];
559 for (NeighborMap::const_iterator iter = neighbors.begin();
560 iter != neighbors.end(); ++iter) {
562 if (neighbor->
peer_as() == 0) {
567 msg <<
"Neighbor " << neighbor->
name()
568 <<
" autonomous-system must be set";
569 *error_msg = msg.str();
576 msg <<
"Neighbor " << neighbor->
name()
577 <<
": autonomous-system mismatch ("
579 <<
") for IBGP peer";
580 *error_msg = msg.str();
586 msg <<
"Neighbor " << neighbor->
name()
587 <<
": EBGP peer configured with local "
588 <<
"autonomous-system";
589 *error_msg = msg.str();
608 if (curr_proto->
CompareTo(*next_proto) == 0) {
621 InstanceMap::iterator iter2) {
624 swap(iter1->second, iter2->second);
647 NeighborMap::iterator iter2) {
648 if (*iter1->second != *iter2->second) {
651 swap(iter1->second, iter2->second);
676 config = YAML::Load(*stream);
677 }
catch (YAML::Exception &ex) {
682 YAML::Node bgp = config[
"bgp"];
684 if (bgp && !
ParseBgp(candidate.get(), bgp, error_msg)) {
688 if (!
Resolve(candidate.get(), error_msg)) {
boost::asio::ip::address IpAddress
boost::asio::ip::address_v4 Ip4Address
static PeerTypeMap peertype_map
static bool ParseBgpNeighbors(BgpYamlConfigManager::Configuration *data, const BgpNeighborConfig *tmpl, const YAML::Node &node, string *error_msg)
static bool ParseBgpNeighbor(BgpNeighborConfig *neighbor, const YAML::Node &node, string *error_msg)
map< string, BgpNeighborConfig::Type > PeerTypeMap
static bool ParseBgpGroups(BgpYamlConfigManager::Configuration *data, const BgpNeighborConfig *global, const YAML::Node &node, string *error_msg)
static BgpNeighborConfig::Type PeerTypeGetValue(const string &value)
static bool ParseIdentifier(const YAML::Node &node, uint32_t *valuep, string *error_msg)
static bool ParseBgp(BgpYamlConfigManager::Configuration *data, const YAML::Node &node, string *error_msg)
static bool ParseTimers(const YAML::Node &timers, uint32_t *hold_time, string *error_msg)
static bool ParseBgpGroupNeighborCommon(BgpNeighborConfig *neighbor, const YAML::Node &node, string *error_msg)
static bool ParseBgpGroup(BgpYamlConfigManager::Configuration *data, const BgpNeighborConfig *global, const string &group_name, const YAML::Node &node, string *error_msg)
static Family FamilyFromString(const std::string &family)
static const int kDefaultPort
std::map< std::string, BgpNeighborConfig * > NeighborMap
void Notify(const BgpConfigObject *, EventType)
std::pair< NeighborMap::const_iterator, NeighborMap::const_iterator > NeighborMapRange
std::map< std::string, BgpInstanceConfig * > InstanceMap
std::map< std::string, BgpRoutingPolicyConfig * > RoutingPolicyMap
static const uint32_t kDefaultAutonomousSystem
virtual RoutingPolicyMapRange RoutingPolicyMapItems(const std::string &start_policy=std::string()) const =0
static const char * kMasterInstance
std::pair< InstanceMap::const_iterator, InstanceMap::const_iterator > InstanceMapRange
std::pair< RoutingPolicyMap::const_iterator, RoutingPolicyMap::const_iterator > RoutingPolicyMapRange
void set_peer_as(uint32_t peer_as)
void set_hold_time(int hold_time)
void set_port(uint16_t port)
void set_group_name(const std::string &group_name)
const std::string & name() const
std::vector< BgpFamilyAttributesConfig > FamilyAttributesList
void set_family_attributes_list(const FamilyAttributesList &family_attributes_list)
void set_peer_type(Type type)
void CopyValues(const BgpNeighborConfig &rhs)
void set_peer_identifier(uint32_t identifier)
void set_local_identifier(uint32_t identifier)
void set_hold_time(uint32_t hold_time)
uint32_t autonomous_system() const
void set_autonomous_system(uint32_t autonomous_system)
void set_identifier(uint32_t identifier)
int CompareTo(const BgpProtocolConfig &rhs) const
YamlInstanceData * LocateInstanceData(const std::string &name)
NeighborMap * NeighborMapMutable()
const InstanceMap & GetInstanceMap() const
BgpInstanceConfig * LocateInstance(const std::string &name)
map< string, YamlInstanceData * > InstanceDataMap
bool AddNeighbor(const string &instance, BgpNeighborConfig *neighbor)
BgpConfigManager::InstanceMap instances_
InstanceDataMap config_map_
const NeighborMap & GetNeighborMap()
RoutingPolicyMap * RoutingPolicyMapMutable()
InstanceMap * InstanceMapMutable()
BgpProtocolConfig * GetProtocolConfig(const std::string &instance_name)
BgpConfigManager::RoutingPolicyMap routing_policies_
const RoutingPolicyMap & GetRoutingPolicyMap() const
BgpRoutingPolicyConfig * LocateRoutingPolicy(const std::string &name)
BgpProtocolConfig * GetProtocolConfig()
virtual const std::string & localname() const
void UpdateNeighbor(NeighborMap::iterator iter1, NeighborMap::iterator iter2)
void UpdateProtocol(Configuration *current, Configuration *next)
virtual const BgpInstanceConfig * FindInstance(const std::string &name) const
BgpYamlConfigManager(BgpServer *server)
void AddNeighbor(NeighborMap::iterator iter)
bool Parse(std::istream *istream, std::string *error_msg)
virtual const BgpProtocolConfig * GetProtocolConfig(const std::string &instance_name) const
virtual NeighborMapRange NeighborMapItems(const std::string &instance_name) const
virtual int NeighborCount(const std::string &instance_name) const
std::unique_ptr< Configuration > data_
void UpdateInstance(InstanceMap::iterator iter1, InstanceMap::iterator iter2)
static const int kMaxHoldTime
virtual const BgpNeighborConfig * FindNeighbor(const std::string &instance_name, const std::string &name) const
void UpdateNeighbors(Configuration *current, Configuration *next)
void DeleteInstance(InstanceMap::iterator iter)
void DeleteNeighbor(NeighborMap::iterator iter)
void Update(Configuration *current, Configuration *next)
bool Resolve(Configuration *candidate, std::string *error_msg)
void AddInstance(InstanceMap::iterator iter)
virtual ~BgpYamlConfigManager()
virtual InstanceMapRange InstanceMapItems(const std::string &start_name=std::string()) const
void UpdateInstances(Configuration *current, Configuration *next)
NeighborMap * neighbors()
bool AddNeighbor(BgpNeighborConfig *neighbor)
const NeighborMap & neighbors() const
BgpProtocolConfig protocol_
BgpConfigManager::NeighborMap NeighborMap
YamlInstanceData(const std::string &name)
BgpProtocolConfig * GetProtocol()
#define LOG(_Level, _Msg)
void map_difference(ForwardIterator __first1, ForwardIterator __last1, ForwardIterator __first2, ForwardIterator __last2, AddFunctor __add_fn, DelFunctor __del_fn, EqFunctor __eq_fn)
void STLDeleteElements(Container *container)