<commit_before>/*
 * Copyright (c) 2013 <NAME>, Inc. All rights reserved.
 */

#include "bgp/bgp_server.h"

#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>

#include "base/connection_info.h"
#include "base/misc_utils.h"
#include "base/task_annotations.h"
#include "bgp/bgp_condition_listener.h"
#include "bgp/bgp_factory.h"
#include "bgp/bgp_lifetime.h"
#include "bgp/bgp_log.h"
#include "bgp/bgp_membership.h"
#include "bgp/bgp_peer.h"
#include "bgp/bgp_ribout_updates.h"
#include "bgp/rtarget/rtarget_table.h"
#include "bgp/bgp_session_manager.h"
#include "bgp/bgp_update_sender.h"
#include "bgp/peer_stats.h"
#include "bgp/routing-instance/iservice_chain_mgr.h"
#include "bgp/routing-instance/istatic_route_mgr.h"
#include "bgp/routing-instance/peer_manager.h"
#include "bgp/routing-instance/routepath_replicator.h"
#include "bgp/routing-instance/routing_instance.h"
#include "bgp/routing-instance/rtarget_group_mgr.h"
#include "bgp/routing-policy/routing_policy.h"

#include "control-node/sandesh/control_node_types.h"

using boost::system::error_code;
using boost::tie;
using process::ConnectionState;
using std::boolalpha;
using std::make_pair;
using std::map;
using std::noboolalpha;
using std::sort;
using std::string;

// The ConfigUpdater serves as glue between the BgpConfigManager and the
// BgpServer.
class BgpServer::ConfigUpdater {
public:
    explicit ConfigUpdater(BgpServer *server) : server_(server) {
        BgpConfigManager::Observers obs;
        obs.instance = boost::bind(&ConfigUpdater::ProcessInstanceConfig,
            this, _1, _2);
        obs.protocol = boost::bind(&ConfigUpdater::ProcessProtocolConfig,
            this, _1, _2);
        obs.neighbor = boost::bind(&ConfigUpdater::ProcessNeighborConfig,
            this, _1, _2);
        obs.policy = boost::bind(&ConfigUpdater::ProcessRoutingPolicyConfig,
            this, _1, _2);
        obs.system= boost::bind(&ConfigUpdater::ProcessGlobalSystemConfig,
            this, _1, _2);
        obs.qos = boost::bind(&ConfigUpdater::ProcessGlobalQosConfig,
            this, _1, _2);
        server->config_manager()->RegisterObservers(obs);
    }

    void ProcessGlobalQosConfig(const BgpGlobalQosConfig *qos,
        BgpConfigManager::EventType event) {
        if (qos->control_dscp() != server_->global_qos()->control_dscp()) {
            server_->global_qos()->set_control_dscp(qos->control_dscp());
            server_->NotifyDSCPUpdate(qos->control_dscp());
        }
        server_->global_qos()->set_analytics_dscp(qos->analytics_dscp());
    }

    void ProcessGlobalSystemConfig(const BgpGlobalSystemConfig *new_config,
            BgpConfigManager::EventType event) {
        bool clear_peers = false;

        if (server_->global_config()->gr_enable() != new_config->gr_enable()) {
            server_->global_config()->set_gr_enable(new_config->gr_enable());
            clear_peers = true;
        }
        if (server_->global_config()->gr_time() != new_config->gr_time()) {
            server_->global_config()->set_gr_time(new_config->gr_time());
            clear_peers = true;
        }
        if (server_->global_config()->llgr_time() != new_config->llgr_time()) {
            server_->global_config()->set_llgr_time(new_config->llgr_time());
            clear_peers = true;
        }
        if (server_->global_config()->end_of_rib_timeout() !=
                new_config->end_of_rib_timeout()) {
            server_->global_config()->set_end_of_rib_timeout(
                new_config->end_of_rib_timeout());
            clear_peers = true;
        }
        if (server_->global_config()->gr_bgp_helper() !=
                new_config->gr_bgp_helper()) {
            server_->global_config()->set_gr_bgp_helper(
                new_config->gr_bgp_helper());
            clear_peers = true;
        }

        // Clear peers if there's a change in always-compare-med knob.
        if (server_->global_config()->always_compare_med() !=
            new_config->always_compare_med()) {
            server_->global_config()->set_always_compare_med(
                new_config->always_compare_med());
            clear_peers = true;
        }

        bool clear_bgpaas_peers = false;

        // Clear bgpaas peers if there's a change in bgpaas-port-start.
        if (server_->global_config()->bgpaas_port_start() !=
                new_config->bgpaas_port_start()) {
            server_->global_config()->set_bgpaas_port_start(
                new_config->bgpaas_port_start());
            clear_bgpaas_peers = true;
        }

        // Clear bgpaas peers if there's a change in bgpaas-port-end.
        if (server_->global_config()->bgpaas_port_end() !=
                new_config->bgpaas_port_end()) {
            server_->global_config()->set_bgpaas_port_end(
                new_config->bgpaas_port_end());
            clear_bgpaas_peers = true;
        }

        if (clear_peers) {
            RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
            RoutingInstance *rti = ri_mgr->GetDefaultRoutingInstance();
            assert(rti);
            PeerManager *peer_manager = rti->LocatePeerManager();
            peer_manager->ClearAllPeers();
        }

        if (clear_bgpaas_peers)
            server_->ClearBgpaaSPeers();
    }

    void ProcessProtocolConfig(const BgpProtocolConfig *protocol_config,
                               BgpConfigManager::EventType event) {
        const string &instance_name = protocol_config->instance_name();

        // We only support BGP sessions in master instance for now.
        if (instance_name != BgpConfigManager::kMasterInstance) {
            return;
        }

        if (event == BgpConfigManager::CFG_ADD ||
            event == BgpConfigManager::CFG_CHANGE) {
            BgpServerConfigUpdate(instance_name, protocol_config);
        } else if (event == BgpConfigManager::CFG_DELETE) {
            BgpServerConfigUpdate(instance_name, NULL);
        } else {
            assert(false);
        }
    }

    void BgpServerConfigUpdate(string instance_name,
                               const BgpProtocolConfig *config) {
        boost::system::error_code ec;
        uint32_t config_identifier = 0;
        uint32_t config_autonomous_system = 0;<commit_msg>Clear bgpaas peers aslo if gr or always-compare-med config changes<commit_after>/*
 * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
 */

#include "bgp/bgp_server.h"

#include <boost/foreach.hpp>
#include <boost/tuple/tuple.hpp>

#include "base/connection_info.h"
#include "base/misc_utils.h"
#include "base/task_annotations.h"
#include "bgp/bgp_condition_listener.h"
#include "bgp/bgp_factory.h"
#include "bgp/bgp_lifetime.h"
#include "bgp/bgp_log.h"
#include "bgp/bgp_membership.h"
#include "bgp/bgp_peer.h"
#include "bgp/bgp_ribout_updates.h"
#include "bgp/rtarget/rtarget_table.h"
#include "bgp/bgp_session_manager.h"
#include "bgp/bgp_update_sender.h"
#include "bgp/peer_stats.h"
#include "bgp/routing-instance/iservice_chain_mgr.h"
#include "bgp/routing-instance/istatic_route_mgr.h"
#include "bgp/routing-instance/peer_manager.h"
#include "bgp/routing-instance/routepath_replicator.h"
#include "bgp/routing-instance/routing_instance.h"
#include "bgp/routing-instance/rtarget_group_mgr.h"
#include "bgp/routing-policy/routing_policy.h"

#include "control-node/sandesh/control_node_types.h"

using boost::system::error_code;
using boost::tie;
using process::ConnectionState;
using std::boolalpha;
using std::make_pair;
using std::map;
using std::noboolalpha;
using std::sort;
using std::string;

// The ConfigUpdater serves as glue between the BgpConfigManager and the
// BgpServer.
class BgpServer::ConfigUpdater {
public:
    explicit ConfigUpdater(BgpServer *server) : server_(server) {
        BgpConfigManager::Observers obs;
        obs.instance = boost::bind(&ConfigUpdater::ProcessInstanceConfig,
            this, _1, _2);
        obs.protocol = boost::bind(&ConfigUpdater::ProcessProtocolConfig,
            this, _1, _2);
        obs.neighbor = boost::bind(&ConfigUpdater::ProcessNeighborConfig,
            this, _1, _2);
        obs.policy = boost::bind(&ConfigUpdater::ProcessRoutingPolicyConfig,
            this, _1, _2);
        obs.system= boost::bind(&ConfigUpdater::ProcessGlobalSystemConfig,
            this, _1, _2);
        obs.qos = boost::bind(&ConfigUpdater::ProcessGlobalQosConfig,
            this, _1, _2);
        server->config_manager()->RegisterObservers(obs);
    }

    void ProcessGlobalQosConfig(const BgpGlobalQosConfig *qos,
        BgpConfigManager::EventType event) {
        if (qos->control_dscp() != server_->global_qos()->control_dscp()) {
            server_->global_qos()->set_control_dscp(qos->control_dscp());
            server_->NotifyDSCPUpdate(qos->control_dscp());
        }
        server_->global_qos()->set_analytics_dscp(qos->analytics_dscp());
    }

    void ProcessGlobalSystemConfig(const BgpGlobalSystemConfig *new_config,
            BgpConfigManager::EventType event) {
        bool clear_peers = false;

        if (server_->global_config()->gr_enable() != new_config->gr_enable()) {
            server_->global_config()->set_gr_enable(new_config->gr_enable());
            clear_peers = true;
        }
        if (server_->global_config()->gr_time() != new_config->gr_time()) {
            server_->global_config()->set_gr_time(new_config->gr_time());
            clear_peers = true;
        }
        if (server_->global_config()->llgr_time() != new_config->llgr_time()) {
            server_->global_config()->set_llgr_time(new_config->llgr_time());
            clear_peers = true;
        }
        if (server_->global_config()->end_of_rib_timeout() !=
                new_config->end_of_rib_timeout()) {
            server_->global_config()->set_end_of_rib_timeout(
                new_config->end_of_rib_timeout());
            clear_peers = true;
        }
        if (server_->global_config()->gr_bgp_helper() !=
                new_config->gr_bgp_helper()) {
            server_->global_config()->set_gr_bgp_helper(
                new_config->gr_bgp_helper());
            clear_peers = true;
        }

        // Clear peers if there's a change in always-compare-med knob.
        if (server_->global_config()->always_compare_med() !=
            new_config->always_compare_med()) {
            server_->global_config()->set_always_compare_med(
                new_config->always_compare_med());
            clear_peers = true;
        }

        bool clear_bgpaas_peers = false;

        // Clear bgpaas peers if there's a change in bgpaas-port-start.
        if (server_->global_config()->bgpaas_port_start() !=
                new_config->bgpaas_port_start()) {
            server_->global_config()->set_bgpaas_port_start(
                new_config->bgpaas_port_start());
            clear_bgpaas_peers = true;
        }

        // Clear bgpaas peers if there's a change in bgpaas-port-end.
        if (server_->global_config()->bgpaas_port_end() !=
                new_config->bgpaas_port_end()) {
            server_->global_config()->set_bgpaas_port_end(
                new_config->bgpaas_port_end());
            clear_bgpaas_peers = true;
        }

        if (clear_peers) {
            RoutingInstanceMgr *ri_mgr = server_->routing_instance_mgr();
            RoutingInstance *rti = ri_mgr->GetDefaultRoutingInstance();
            assert(rti);
            PeerManager *peer_manager = rti->LocatePeerManager();
            peer_manager->ClearAllPeers();
        }

        if (clear_peers || clear_bgpaas_peers)
            server_->ClearBgpaaSPeers();
    }

    void ProcessProtocolConfig(const BgpProtocolConfig *protocol_config,
                               BgpConfigManager::EventType event) {
        const string &instance_name = protocol_config->instance_name();

        // We only support BGP sessions in master instance for now.
        if (instance_name != BgpConfigManager::kMasterInstance) {
            return;
        }

        if (event == BgpConfigManager::CFG_ADD ||
            event == BgpConfigManager::CFG_CHANGE) {
            BgpServerConfigUpdate(instance_name, protocol_config);
        } else if (event == BgpConfigManager::CFG_DELETE) {
            BgpServerConfigUpdate(instance_name, NULL);
        } else {
            assert(false);
        }
    }

    void BgpServerConfigUpdate(string instance_name,
                               const BgpProtocolConfig *config) {
        boost::system::error_code ec;
        uint32_t config_identifier = 0;
        uint32_t config_autonomous_system = 0;
{'fraction_non_alphanumeric': 0.12149088025376685, 'fraction_numerical': 0.0034892942109436957, 'mean_word_length': 2.8436452301127706, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 142, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5592280', 'n_tokens_mistral': 3956, 'n_tokens_neox': 3931, 'n_words': 612}