6 #include <boost/assign/list_of.hpp>
7 #include <boost/bind.hpp>
8 #include <yaml-cpp/yaml.h>
13 using boost::assign::map_list_of;
28 pair<NeighborMap::iterator, bool> result =
29 neighbors_.insert(make_pair(neighbor->
name(), neighbor));
30 bool success = result.second;
101 return routing_policies_;
104 return &routing_policies_;
109 InstanceMap::iterator loc = instances_.find(name);
110 if (loc != instances_.end()) {
113 pair<InstanceMap::iterator, bool> result =
116 return result.first->second;
120 RoutingPolicyMap::iterator loc = routing_policies_.find(name);
121 if (loc != routing_policies_.end()) {
124 pair<RoutingPolicyMap::iterator, bool> result =
125 routing_policies_.insert(
127 return result.first->second;
131 InstanceDataMap::iterator loc = config_map_.find(name);
132 if (loc != config_map_.end()) {
135 pair<InstanceDataMap::iterator, bool> result =
138 return result.first->second;
160 PeerTypeMap::const_iterator loc =
peertype_map.find(value);
186 return make_pair(map.lower_bound(start_name), map.end());
191 const std::string &policy_name)
const {
193 return make_pair(map.begin(), map.end());
197 const std::string &instance_name)
const {
199 return make_pair(map.begin(), map.end());
203 const std::string &instance_name)
const {
209 const std::string &name)
const {
214 const std::string &instance_name)
const {
215 return data_->GetProtocolConfig(instance_name);
219 const std::string &instance_name,
const std::string &name)
const {
223 static bool ParseTimers(
const YAML::Node &timers, uint32_t *hold_time,
225 if (timers[
"hold-time"]) {
228 value = timers[
"hold-time"].as<uint32_t>();
230 *error_msg =
"Invalid hold-time value: not an integer";
235 msg <<
"Invalid hold-time value (out of range): " << value;
236 *error_msg = msg.str();
253 value = node.as<
string>();
255 *error_msg =
"Invalid identifier value: not a string";
258 boost::system::error_code ec;
259 Ip4Address address = Ip4Address::from_string(value, ec);
262 long int id = strtol(value.c_str(), &endp, 10);
263 size_t strlen = endp - value.c_str();
264 if (
id == 0 || strlen != value.length()) {
265 *error_msg =
"Invalid identifier value: "
266 "not an IP address or integer";
271 *valuep = htonl(address.to_ulong());
278 if (node[
"peer-as"]) {
281 value = node[
"peer-as"].as<
int>();
283 *error_msg =
"Invalid peer-as value: not an integer";
286 if (value < 0 || value > USHRT_MAX) {
288 msg <<
"Invalid peer-as value (out of range): " << value;
289 *error_msg = msg.str();
298 value = node[
"port"].as<
int>();
300 *error_msg =
"Invalid port value: not an integer";
303 if (value < 0 || value > USHRT_MAX) {
305 msg <<
"Invalid port value (out of range): " << value;
306 *error_msg = msg.str();
312 if (node[
"peer-type"]) {
315 value = node[
"peer-type"].as<
string>();
317 *error_msg =
"Invalid peer-type value: not a string";
323 msg <<
"Invalid peer-type value: " << value;
324 *error_msg = msg.str();
330 if (node[
"identifier"]) {
338 if (node[
"local-identifier"]) {
346 if (node[
"local-address"]) {
349 value = node[
"local-address"].as<
string>();
351 *error_msg =
"Invalid local-address value: not a string";
354 boost::system::error_code ec;
355 IpAddress address = IpAddress::from_string(value, ec);
358 ss <<
"Invalid local-address value: " << value;
359 *error_msg = ss.str();
362 LOG(DEBUG,
"local-address " << address.to_string() <<
" not used");
366 if (node[
"timers"]) {
368 if (!
ParseTimers(node[
"timers"], &hold_time, error_msg)) {
376 if (node[
"address-families"]) {
377 YAML::Node families = node[
"address-families"];
379 for (YAML::const_iterator iter = families.begin();
380 iter != families.end(); ++iter) {
383 family = iter->as<
string>();
385 *error_msg =
"Invalid address family value: not a string";
389 *error_msg =
"Invalid address family value: " + family;
393 list.push_back(family_config);
407 const YAML::Node &node,
string *error_msg) {
409 *error_msg =
"Expected mapping under bgp:neighbors";
412 for (YAML::const_iterator iter = node.begin();
413 iter != node.end(); ++iter) {
416 address = iter->first.as<
string>();
418 *error_msg =
"Invalid neighbor key: not a string";
421 boost::system::error_code ec;
422 IpAddress ipaddress = IpAddress::from_string(address, ec);
424 *error_msg =
"Invalid address: " + address;
427 LOG(DEBUG,
"neighbor: " << address);
429 neighbor->CopyValues(*tmpl);
430 neighbor->set_name(address);
431 neighbor->set_peer_address(ipaddress);
436 neighbor.release())) {
437 *error_msg =
"Duplicate neighbor " + address;
447 const string &group_name,
448 const YAML::Node &node,
string *error_msg) {
457 YAML::Node neighbors = node[
"neighbors"];
466 const YAML::Node &node,
string *error_msg) {
468 *error_msg =
"Expected mapping under bgp:peer-groups";
472 for (YAML::const_iterator iter = node.begin();
473 iter != node.end(); ++iter) {
476 group_name = iter->first.as<
string>();
478 *error_msg =
"Invalid group key: not a string";
490 const YAML::Node &node,
string *error_msg) {
494 if (node[
"autonomous-system"]) {
497 value = node[
"autonomous-system"].as<
int>();
499 *error_msg =
"Invalid autonomous-system number: not an integer";
508 value = node[
"port"].as<
int>();
510 *error_msg =
"Invalid port number: not an integer";
513 if (value < 0 || value > USHRT_MAX) {
515 msg <<
"Invalid port value (out of range): " << value;
516 *error_msg = msg.str();
522 if (node[
"identifier"]) {
530 YAML::Node timers = node[
"timers"];
533 if (!
ParseTimers(node[
"timers"], &hold_time, error_msg)) {
541 YAML::Node groups = node[
"peer-groups"];
542 if (groups && !
ParseBgpGroups(data, &global, groups, error_msg)) {
546 YAML::Node neighbors = node[
"neighbors"];
558 for (NeighborMap::const_iterator iter = neighbors.begin();
559 iter != neighbors.end(); ++iter) {
561 if (neighbor->
peer_as() == 0) {
566 msg <<
"Neighbor " << neighbor->
name()
567 <<
" autonomous-system must be set";
568 *error_msg = msg.str();
575 msg <<
"Neighbor " << neighbor->
name()
576 <<
": autonomous-system mismatch ("
578 <<
") for IBGP peer";
579 *error_msg = msg.str();
585 msg <<
"Neighbor " << neighbor->
name()
586 <<
": EBGP peer configured with local "
587 <<
"autonomous-system";
588 *error_msg = msg.str();
607 if (curr_proto->
CompareTo(*next_proto) == 0) {
620 InstanceMap::iterator iter2) {
623 swap(iter1->second, iter2->second);
646 NeighborMap::iterator iter2) {
647 if (*iter1->second != *iter2->second) {
650 swap(iter1->second, iter2->second);
675 config = YAML::Load(*stream);
676 }
catch (YAML::Exception &ex) {
681 YAML::Node bgp = config[
"bgp"];
683 if (bgp && !
ParseBgp(candidate.get(), bgp, error_msg)) {
687 if (!
Resolve(candidate.get(), error_msg)) {
map< string, YamlInstanceData * > InstanceDataMap
static bool ParseBgpNeighbor(BgpNeighborConfig *neighbor, const YAML::Node &node, 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)
std::map< std::string, BgpRoutingPolicyConfig * > RoutingPolicyMap
void Update(Configuration *current, Configuration *next)
const RoutingPolicyMap & GetRoutingPolicyMap() const
const NeighborMap & neighbors() const
static bool ParseBgpNeighbors(BgpYamlConfigManager::Configuration *data, const BgpNeighborConfig *tmpl, const YAML::Node &node, string *error_msg)
void UpdateNeighbor(NeighborMap::iterator iter1, NeighborMap::iterator iter2)
static bool ParseBgpGroups(BgpYamlConfigManager::Configuration *data, const BgpNeighborConfig *global, const YAML::Node &node, string *error_msg)
std::pair< RoutingPolicyMap::const_iterator, RoutingPolicyMap::const_iterator > RoutingPolicyMapRange
void set_group_name(const std::string &group_name)
const std::string & name() const
std::pair< InstanceMap::const_iterator, InstanceMap::const_iterator > InstanceMapRange
void set_identifier(uint32_t identifier)
NeighborMap * NeighborMapMutable()
void DeleteInstance(InstanceMap::iterator iter)
int CompareTo(const BgpProtocolConfig &rhs) const
BgpProtocolConfig * GetProtocol()
uint32_t autonomous_system() const
static const char * kMasterInstance
static Family FamilyFromString(const std::string &family)
void Notify(const BgpConfigObject *, EventType)
boost::asio::ip::address IpAddress
static PeerTypeMap peertype_map
void set_peer_type(Type type)
void AddNeighbor(NeighborMap::iterator iter)
bool AddNeighbor(const string &instance, BgpNeighborConfig *neighbor)
NeighborMap * neighbors()
void set_peer_identifier(uint32_t identifier)
RoutingPolicyMap * RoutingPolicyMapMutable()
void UpdateProtocol(Configuration *current, Configuration *next)
virtual NeighborMapRange NeighborMapItems(const std::string &instance_name) const
BgpProtocolConfig * GetProtocolConfig()
BgpProtocolConfig protocol_
static BgpNeighborConfig::Type PeerTypeGetValue(const string &value)
YamlInstanceData(const std::string &name)
void set_hold_time(int hold_time)
const NeighborMap & GetNeighborMap()
static bool ParseBgpGroup(BgpYamlConfigManager::Configuration *data, const BgpNeighborConfig *global, const string &group_name, const YAML::Node &node, string *error_msg)
BgpInstanceConfig * LocateInstance(const std::string &name)
BgpConfigManager::InstanceMap instances_
static const int kMaxHoldTime
InstanceDataMap config_map_
bool Resolve(Configuration *candidate, std::string *error_msg)
virtual const std::string & localname() const
static bool ParseBgpGroupNeighborCommon(BgpNeighborConfig *neighbor, const YAML::Node &node, string *error_msg)
virtual int NeighborCount(const std::string &instance_name) const
void set_hold_time(uint32_t hold_time)
void map_difference(ForwardIterator __first1, ForwardIterator __last1, ForwardIterator __first2, ForwardIterator __last2, AddFunctor __add_fn, DelFunctor __del_fn, EqFunctor __eq_fn)
void DeleteNeighbor(NeighborMap::iterator iter)
std::pair< NeighborMap::const_iterator, NeighborMap::const_iterator > NeighborMapRange
void STLDeleteElements(Container *container)
BgpConfigManager::NeighborMap NeighborMap
BgpYamlConfigManager(BgpServer *server)
void set_family_attributes_list(const FamilyAttributesList &family_attributes_list)
YamlInstanceData * LocateInstanceData(const std::string &name)
void set_local_identifier(uint32_t identifier)
virtual const BgpNeighborConfig * FindNeighbor(const std::string &instance_name, const std::string &name) const
static bool ParseIdentifier(const YAML::Node &node, uint32_t *valuep, string *error_msg)
virtual ~BgpYamlConfigManager()
boost::asio::ip::address_v4 Ip4Address
void UpdateNeighbors(Configuration *current, Configuration *next)
std::map< std::string, BgpInstanceConfig * > InstanceMap
std::vector< BgpFamilyAttributesConfig > FamilyAttributesList
void AddInstance(InstanceMap::iterator iter)
void UpdateInstance(InstanceMap::iterator iter1, InstanceMap::iterator iter2)
void UpdateInstances(Configuration *current, Configuration *next)
map< string, BgpNeighborConfig::Type > PeerTypeMap
bool AddNeighbor(BgpNeighborConfig *neighbor)
#define LOG(_Level, _Msg)
static const int kDefaultPort
std::map< std::string, BgpNeighborConfig * > NeighborMap
BgpConfigManager::RoutingPolicyMap routing_policies_
void set_autonomous_system(uint32_t autonomous_system)
void set_peer_as(uint32_t peer_as)
void set_port(uint16_t port)
InstanceMap * InstanceMapMutable()
virtual const BgpProtocolConfig * GetProtocolConfig(const std::string &instance_name) const
std::unique_ptr< Configuration > data_
BgpRoutingPolicyConfig * LocateRoutingPolicy(const std::string &name)
BgpProtocolConfig * GetProtocolConfig(const std::string &instance_name)
void CopyValues(const BgpNeighborConfig &rhs)
virtual RoutingPolicyMapRange RoutingPolicyMapItems(const std::string &start_policy=std::string()) const =0
virtual InstanceMapRange InstanceMapItems(const std::string &start_name=std::string()) const
virtual const BgpInstanceConfig * FindInstance(const std::string &name) const
static const uint32_t kDefaultAutonomousSystem
bool Parse(std::istream *istream, std::string *error_msg)
const InstanceMap & GetInstanceMap() const