LCOV - code coverage report
Current view: top level - bgp - bgp_attr.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 912 992 91.9 %
Date: 2026-06-22 02:21:21 Functions: 173 182 95.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bgp/bgp_attr.h"
       6             : 
       7             : #include <algorithm>
       8             : #include <string>
       9             : 
      10             : #include "bgp/bgp_server.h"
      11             : #include "bgp/extended-community/esi_label.h"
      12             : #include "bgp/extended-community/etree.h"
      13             : #include "bgp/extended-community/mac_mobility.h"
      14             : #include "bgp/extended-community/router_mac.h"
      15             : #include "net/bgp_af.h"
      16             : 
      17             : using std::sort;
      18             : using std::vector;
      19             : using std::string;
      20             : 
      21        9985 : int BgpAttrOrigin::CompareTo(const BgpAttribute &rhs_attr) const {
      22        9985 :     int ret = BgpAttribute::CompareTo(rhs_attr);
      23        9985 :     if (ret != 0) return ret;
      24        9985 :     KEY_COMPARE(origin, static_cast<const BgpAttrOrigin &>(rhs_attr).origin);
      25        9985 :     return 0;
      26             : }
      27             : 
      28      184742 : void BgpAttrOrigin::ToCanonical(BgpAttr *attr) {
      29      184742 :     attr->set_origin(static_cast<BgpAttrOrigin::OriginType>(origin));
      30      184742 : }
      31             : 
      32      111636 : string BgpAttrOrigin::ToString() const {
      33             :     char repr[80];
      34      111636 :     snprintf(repr, sizeof(repr), "ORIGIN <code: %d, flags: %02x> : %02x",
      35      111636 :              code, flags, origin);
      36      111636 :     return string(repr);
      37             : }
      38             : 
      39        9981 : int BgpAttrNextHop::CompareTo(const BgpAttribute &rhs_attr) const {
      40        9981 :     int ret = BgpAttribute::CompareTo(rhs_attr);
      41        9981 :     if (ret != 0) return ret;
      42        9981 :     KEY_COMPARE(nexthop,
      43             :             static_cast<const BgpAttrNextHop &>(rhs_attr).nexthop);
      44        9981 :     return 0;
      45             : }
      46             : 
      47      191484 : void BgpAttrNextHop::ToCanonical(BgpAttr *attr) {
      48      191484 :     if (v6_nexthop.is_unspecified()) {
      49      188951 :         attr->set_nexthop(Ip4Address(nexthop));
      50             :     } else {
      51        2532 :         attr->set_nexthop(v6_nexthop);
      52             :     }
      53      191483 : }
      54             : 
      55        3259 : string BgpAttrNextHop::ToString() const {
      56             :     char repr[80];
      57        3259 :     snprintf(repr, sizeof(repr), "NEXTHOP <code: %d, flags: %02x> : %04x",
      58        3259 :              code, flags, nexthop);
      59        3259 :     return string(repr);
      60             : }
      61             : 
      62        1988 : int BgpAttrMultiExitDisc::CompareTo(const BgpAttribute &rhs_attr) const {
      63        1988 :     int ret = BgpAttribute::CompareTo(rhs_attr);
      64        1988 :     if (ret != 0) return ret;
      65        1988 :     KEY_COMPARE(med, static_cast<const BgpAttrMultiExitDisc &>(rhs_attr).med);
      66        1986 :     return 0;
      67             : }
      68       76713 : void BgpAttrMultiExitDisc::ToCanonical(BgpAttr *attr) {
      69       76713 :     attr->set_med(med);
      70       76713 : }
      71             : 
      72       51879 : string BgpAttrMultiExitDisc::ToString() const {
      73             :     char repr[80];
      74       51879 :     snprintf(repr, sizeof(repr), "MED <code: %d, flags: %02x> : %d",
      75       51879 :              code, flags, med);
      76       51879 :     return string(repr);
      77             : }
      78             : 
      79        1994 : int BgpAttrLocalPref::CompareTo(const BgpAttribute &rhs_attr) const {
      80        1994 :     int ret = BgpAttribute::CompareTo(rhs_attr);
      81        1994 :     if (ret != 0) return ret;
      82        1994 :     KEY_COMPARE(local_pref,
      83             :             static_cast<const BgpAttrLocalPref &>(rhs_attr).local_pref);
      84        1994 :     return 0;
      85             : }
      86       92447 : void BgpAttrLocalPref::ToCanonical(BgpAttr *attr) {
      87       92447 :     attr->set_local_pref(local_pref);
      88       92447 : }
      89             : 
      90       24221 : string BgpAttrLocalPref::ToString() const {
      91             :     char repr[80];
      92       24221 :     snprintf(repr, sizeof(repr), "LOCAL_PREF <code: %d, flags: %02x> : %d",
      93       24221 :              code, flags, local_pref);
      94       24221 :     return string(repr);
      95             : }
      96             : 
      97           9 : void BgpAttrAtomicAggregate::ToCanonical(BgpAttr *attr) {
      98           9 :     attr->set_atomic_aggregate(true);
      99           9 : }
     100             : 
     101           1 : string BgpAttrAtomicAggregate::ToString() const {
     102             :     char repr[80];
     103           1 :     snprintf(repr, sizeof(repr), "ATOMIC_AGGR <code: %d, flags: %02x>",
     104           1 :              code, flags);
     105           1 :     return string(repr);
     106             : }
     107             : 
     108           3 : int BgpAttr4ByteAggregator::CompareTo(const BgpAttribute &rhs_attr) const {
     109           3 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     110           3 :     if (ret != 0) return ret;
     111           3 :     KEY_COMPARE(as_num,
     112             :             static_cast<const BgpAttr4ByteAggregator &>(rhs_attr).as_num);
     113           3 :     KEY_COMPARE(address,
     114             :             static_cast<const BgpAttr4ByteAggregator &>(rhs_attr).address);
     115           3 :     return 0;
     116             : }
     117           1 : void BgpAttr4ByteAggregator::ToCanonical(BgpAttr *attr) {
     118           1 :     attr->set_aggregator(as_num, Ip4Address(address));
     119           1 : }
     120             : 
     121           0 : string BgpAttr4ByteAggregator::ToString() const {
     122             :     char repr[80];
     123           0 :     snprintf(repr, sizeof(repr),
     124             :              "Aggregator <code: %d, flags: %02x> : %d:%08x",
     125           0 :              code, flags, as_num, address);
     126           0 :     return string(repr);
     127             : }
     128             : 
     129        1973 : int BgpAttrAggregator::CompareTo(const BgpAttribute &rhs_attr) const {
     130        1973 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     131        1973 :     if (ret != 0) return ret;
     132        1973 :     KEY_COMPARE(as_num,
     133             :             static_cast<const BgpAttrAggregator &>(rhs_attr).as_num);
     134        1971 :     KEY_COMPARE(address,
     135             :             static_cast<const BgpAttrAggregator &>(rhs_attr).address);
     136        1969 :     return 0;
     137             : }
     138           8 : void BgpAttrAggregator::ToCanonical(BgpAttr *attr) {
     139           8 :     attr->set_aggregator(as_num, Ip4Address(address));
     140           8 : }
     141             : 
     142           1 : string BgpAttrAggregator::ToString() const {
     143             :     char repr[80];
     144           1 :     snprintf(repr, sizeof(repr),
     145             :              "Aggregator <code: %d, flags: %02x> : %d:%08x",
     146           1 :              code, flags, as_num, address);
     147           1 :     return string(repr);
     148             : }
     149             : 
     150           0 : int BgpAttrAs4Aggregator::CompareTo(const BgpAttribute &rhs_attr) const {
     151           0 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     152           0 :     if (ret != 0) return ret;
     153           0 :     KEY_COMPARE(as_num,
     154             :             static_cast<const BgpAttrAs4Aggregator &>(rhs_attr).as_num);
     155           0 :     KEY_COMPARE(address,
     156             :             static_cast<const BgpAttrAs4Aggregator &>(rhs_attr).address);
     157           0 :     return 0;
     158             : }
     159           0 : void BgpAttrAs4Aggregator::ToCanonical(BgpAttr *attr) {
     160           0 :     attr->set_as4_aggregator(as_num, Ip4Address(address));
     161           0 : }
     162             : 
     163           0 : string BgpAttrAs4Aggregator::ToString() const {
     164             :     char repr[80];
     165           0 :     snprintf(repr, sizeof(repr),
     166             :              "Aggregator <code: %d, flags: %02x> : %d:%08x",
     167           0 :              code, flags, as_num, address);
     168           0 :     return string(repr);
     169             : }
     170             : 
     171           3 : int BgpAttrOriginatorId::CompareTo(const BgpAttribute &rhs_attr) const {
     172           3 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     173           3 :     if (ret != 0) return ret;
     174           3 :     KEY_COMPARE(originator_id,
     175             :         static_cast<const BgpAttrOriginatorId &>(rhs_attr).originator_id);
     176           1 :     return 0;
     177             : }
     178             : 
     179          18 : void BgpAttrOriginatorId::ToCanonical(BgpAttr *attr) {
     180          18 :     attr->set_originator_id(Ip4Address(originator_id));
     181          18 : }
     182             : 
     183           3 : string BgpAttrOriginatorId::ToString() const {
     184             :     char repr[80];
     185           3 :     snprintf(repr, sizeof(repr), "OriginatorId <code: %d, flags: 0x%02x> : %s",
     186           6 :              code, flags, Ip4Address(originator_id).to_string().c_str());
     187           3 :     return string(repr);
     188             : }
     189             : 
     190           9 : ClusterListSpec::ClusterListSpec(uint32_t cluster_id,
     191           9 :     const ClusterListSpec *rhs)
     192           9 :     : BgpAttribute(BgpAttribute::ClusterList, kFlags) {
     193           9 :     cluster_list.push_back(cluster_id);
     194           9 :     if (rhs) {
     195           1 :         cluster_list.insert(cluster_list.end(), rhs->cluster_list.begin(),
     196             :             rhs->cluster_list.end());
     197             :     }
     198           9 : }
     199             : 
     200          46 : int ClusterListSpec::CompareTo(const BgpAttribute &rhs_attr) const {
     201          46 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     202          46 :     if (ret != 0) return ret;
     203          46 :     KEY_COMPARE(cluster_list,
     204             :         static_cast<const ClusterListSpec &>(rhs_attr).cluster_list);
     205          38 :     return 0;
     206             : }
     207             : 
     208           8 : void ClusterListSpec::ToCanonical(BgpAttr *attr) {
     209           8 :     attr->set_cluster_list(this);
     210           8 : }
     211             : 
     212           3 : string ClusterListSpec::ToString() const {
     213           3 :     std::stringstream repr;
     214           3 :     repr << "CLUSTER_LIST <code: " << int(code);
     215           3 :     repr << ", flags: 0x" << std::hex << int(flags) << "> :";
     216           3 :     for (vector<uint32_t>::const_iterator iter = cluster_list.begin();
     217           9 :          iter != cluster_list.end(); ++iter) {
     218           6 :         repr << " " << Ip4Address(*iter).to_string();
     219             :     }
     220           6 :     return repr.str();
     221           3 : }
     222             : 
     223          14 : bool ClusterListSpec::ClusterListLoop(uint32_t cluster_id) const {
     224          14 :     for (vector<uint32_t>::const_iterator iter = cluster_list.begin();
     225          56 :          iter != cluster_list.end(); ++iter) {
     226          47 :         if (*iter == cluster_id)
     227           5 :             return true;
     228             :     }
     229           9 :     return false;
     230             : }
     231             : 
     232          22 : ClusterList::ClusterList(ClusterListDB *cluster_list_db,
     233          22 :     const ClusterListSpec &spec)
     234          22 :     : cluster_list_db_(cluster_list_db),
     235          22 :       spec_(spec) {
     236          22 :     refcount_ = 0;
     237          22 : }
     238             : 
     239          18 : void ClusterList::Remove() {
     240          18 :     cluster_list_db_->Delete(this);
     241          18 : }
     242             : 
     243        9742 : ClusterListDB::ClusterListDB(BgpServer *server) {
     244        9742 : }
     245             : 
     246        1990 : int BgpMpNlri::CompareTo(const BgpAttribute &rhs_attr) const {
     247        1990 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     248        1990 :     if (ret != 0) return ret;
     249        1990 :     const BgpMpNlri &rhs = static_cast<const BgpMpNlri &>(rhs_attr);
     250        1990 :     KEY_COMPARE(afi, rhs.afi);
     251        1990 :     KEY_COMPARE(safi, rhs.safi);
     252        1990 :     KEY_COMPARE(nexthop, rhs.nexthop);
     253        1990 :     KEY_COMPARE(nlri.size(), rhs.nlri.size());
     254             : 
     255      498340 :     for (size_t i = 0; i < nlri.size(); i++) {
     256      496350 :         KEY_COMPARE(nlri[i]->type, rhs.nlri[i]->type);
     257      496350 :         KEY_COMPARE(nlri[i]->prefixlen, rhs.nlri[i]->prefixlen);
     258      496350 :         KEY_COMPARE(nlri[i]->prefix, rhs.nlri[i]->prefix);
     259             :     }
     260        1990 :     return 0;
     261             : }
     262             : 
     263      158416 : void BgpMpNlri::ToCanonical(BgpAttr *attr) {
     264      158416 : }
     265             : 
     266      510261 : size_t BgpMpNlri::EncodeLength() const {
     267      510261 :     size_t sz = 2 /* safi */ + 1 /* afi */ +
     268             :                 1 /* NlriNextHopLength */ +
     269             :                 1 /* Reserved */;
     270      510261 :     sz += nexthop.size();
     271      510258 :     for (vector<BgpProtoPrefix*>::const_iterator iter = nlri.begin();
     272     2864211 :          iter != nlri.end(); ++iter) {
     273     2353966 :         size_t bytes = 0;
     274     2353966 :         if (afi == BgpAf::L2Vpn &&
     275       40860 :             (safi == BgpAf::EVpn || safi == BgpAf::ErmVpn)) {
     276       40860 :             bytes = (*iter)->prefixlen;
     277             :         } else {
     278     2313106 :             bytes = ((*iter)->prefixlen + 7) / 8;
     279             :         }
     280     2353966 :         sz += 1 + bytes;
     281             :     }
     282      510224 :     return sz;
     283             : }
     284             : 
     285       25400 : PmsiTunnelSpec::PmsiTunnelSpec()
     286             :     : BgpAttribute(PmsiTunnel, kFlags),
     287       25400 :       tunnel_flags(0), tunnel_type(0), label(0) {
     288       25400 : }
     289             : 
     290        3007 : PmsiTunnelSpec::PmsiTunnelSpec(const BgpAttribute &rhs)
     291        3007 :     : BgpAttribute(rhs), tunnel_flags(0), tunnel_type(0), label(0) {
     292        3007 : }
     293             : 
     294      326564 : int PmsiTunnelSpec::CompareTo(const BgpAttribute &rhs_attr) const {
     295      326564 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     296      326564 :     if (ret != 0) return ret;
     297      326564 :     const PmsiTunnelSpec &rhs = static_cast<const PmsiTunnelSpec &>(rhs_attr);
     298      326564 :     KEY_COMPARE(tunnel_flags, rhs.tunnel_flags);
     299      314883 :     KEY_COMPARE(tunnel_type, rhs.tunnel_type);
     300      314876 :     KEY_COMPARE(label, rhs.label);
     301      290962 :     KEY_COMPARE(identifier, rhs.identifier);
     302      288307 :     return 0;
     303             : }
     304             : 
     305        8133 : void PmsiTunnelSpec::ToCanonical(BgpAttr *attr) {
     306        8133 :     attr->set_pmsi_tunnel(this);
     307        8132 : }
     308             : 
     309         839 : string PmsiTunnelSpec::ToString() const {
     310         839 :     std::ostringstream oss;
     311         839 :     oss << "PmsiTunnel <code: " << int(code);
     312         839 :     oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
     313         839 :     oss << " Tunnel Flags: 0x" << std::hex << int(tunnel_flags) << std::dec;
     314         839 :     oss << " Tunnel Type: " << int(tunnel_type);
     315         839 :     oss << " Label: 0x" << std::hex << int(label) << std::dec;
     316         839 :     oss << " (" << int(label) << ")";
     317         839 :     oss << " Identifier: " << GetIdentifier().to_string();
     318             : 
     319        1678 :     return oss.str();
     320         839 : }
     321             : 
     322           2 : uint32_t PmsiTunnelSpec::GetLabel(const ExtCommunity *ext) const {
     323           2 :     assert(ext);
     324           2 :     bool is_vni = ext->ContainsTunnelEncapVxlan();
     325           2 :     return (is_vni ? label : (label >> 4));
     326             : }
     327             : 
     328        7748 : void PmsiTunnelSpec::SetLabel(uint32_t in_label, const ExtCommunity *ext) {
     329        7748 :     assert(ext);
     330        7748 :     bool is_vni = ext->ContainsTunnelEncapVxlan();
     331        7748 :     label = (is_vni ? in_label : (in_label << 4 | 0x01));
     332        7748 : }
     333             : 
     334       18765 : Ip4Address PmsiTunnelSpec::GetIdentifier() const {
     335       18765 :     if (identifier.size() < 4)
     336        9827 :         return Ip4Address();
     337        8938 :     return Ip4Address(get_value(&identifier[0], 4));
     338             : }
     339             : 
     340       11691 : void PmsiTunnelSpec::SetIdentifier(Ip4Address in_identifier) {
     341       11691 :     identifier.resize(4, 0);
     342       11691 :     const Ip4Address::bytes_type &bytes = in_identifier.to_bytes();
     343       11691 :     std::copy(bytes.begin(), bytes.begin() + 4, identifier.begin());
     344       11691 : }
     345             : 
     346           9 : string PmsiTunnelSpec::GetTunnelTypeString() const {
     347           9 :     switch (tunnel_type) {
     348           1 :     case RsvpP2mpLsp:
     349           1 :         return "RsvpP2mpLsp";
     350           1 :     case LdpP2mpLsp:
     351           1 :         return "LdpP2mpLsp";
     352           1 :     case PimSsmTree:
     353           1 :         return "PimSsmTree";
     354           1 :     case PimSmTree:
     355           1 :         return "PimSmTree";
     356           1 :     case BidirPimTree:
     357           1 :         return "BidirPimTree";
     358           1 :     case IngressReplication:
     359           1 :         return "IngressReplication";
     360           1 :     case MldpMp2mpLsp:
     361           1 :         return "MldpMp2mpLsp";
     362           1 :     case AssistedReplicationContrail:
     363           1 :         return "AssistedReplication";
     364           1 :     default:
     365           1 :         break;
     366             :     }
     367           2 :     std::ostringstream oss;
     368           1 :     oss << "Unknown(" << int(tunnel_type) << ")";
     369           1 :     return oss.str();
     370             : }
     371             : 
     372           4 : string PmsiTunnelSpec::GetTunnelArTypeString() const {
     373           4 :     switch (tunnel_flags & AssistedReplicationType) {
     374           1 :     case RegularNVE:
     375           1 :         return "RegularNVE";
     376           1 :     case ARReplicator:
     377           1 :         return "ARReplicator";
     378           1 :     case ARLeaf:
     379           1 :         return "ARLeaf";
     380           1 :     default:
     381           1 :         break;
     382             :     }
     383           1 :     return "Unknown";
     384             : }
     385             : 
     386           4 : vector<string> PmsiTunnelSpec::GetTunnelFlagsStrings() const {
     387           4 :     vector<string> flags;
     388           4 :     if (tunnel_flags & LeafInfoRequired) {
     389           2 :         flags.push_back("LeafInfoRequired");
     390             :     }
     391           4 :     if (tunnel_flags & EdgeReplicationSupported) {
     392           2 :         flags.push_back("EdgeReplicationSupported");
     393             :     }
     394           4 :     if (flags.empty()) {
     395           1 :         flags.push_back("None");
     396             :     }
     397           4 :     return flags;
     398           0 : }
     399             : 
     400       17924 : PmsiTunnel::PmsiTunnel(PmsiTunnelDB *pmsi_tunnel_db,
     401       17924 :     const PmsiTunnelSpec &pmsi_spec)
     402       17923 :     : pmsi_tunnel_db_(pmsi_tunnel_db),
     403       17924 :       pmsi_spec_(pmsi_spec) {
     404       17919 :     refcount_ = 0;
     405       17924 :     tunnel_flags_ = pmsi_spec_.tunnel_flags;
     406       17924 :     tunnel_type_ = pmsi_spec_.tunnel_type;
     407       17924 :     label_ = pmsi_spec_.label;
     408       17924 :     identifier_ = pmsi_spec_.GetIdentifier();
     409       17923 : }
     410             : 
     411        4967 : void PmsiTunnel::Remove() {
     412        4967 :     pmsi_tunnel_db_->Delete(this);
     413        4967 : }
     414             : 
     415        2597 : uint32_t PmsiTunnel::GetLabel(const ExtCommunity *ext) const {
     416        2597 :     bool is_vni = false;
     417        2597 :     if (ext)
     418        2585 :         is_vni = ext->ContainsTunnelEncapVxlan();
     419        2597 :     return (is_vni ? label_ : label_ >> 4);
     420             : }
     421             : 
     422        9742 : PmsiTunnelDB::PmsiTunnelDB(BgpServer *server) {
     423        9742 : }
     424             : 
     425        5932 : EdgeDiscoverySpec::EdgeDiscoverySpec()
     426        5932 :     : BgpAttribute(McastEdgeDiscovery, kFlags) {
     427        5931 : }
     428             : 
     429        3861 : EdgeDiscoverySpec::EdgeDiscoverySpec(const BgpAttribute &rhs)
     430        3861 :     : BgpAttribute(rhs) {
     431        3861 : }
     432             : 
     433        4275 : EdgeDiscoverySpec::EdgeDiscoverySpec(const EdgeDiscoverySpec &rhs)
     434        4275 :     : BgpAttribute(BgpAttribute::McastEdgeDiscovery, kFlags) {
     435       14020 :     for (size_t i = 0; i < rhs.edge_list.size(); i++) {
     436        9746 :         Edge *edge = new Edge;
     437        9746 :         *edge = *rhs.edge_list[i];
     438        9746 :         edge_list.push_back(edge);
     439             :     }
     440        4274 : }
     441             : 
     442       23011 : EdgeDiscoverySpec::~EdgeDiscoverySpec() {
     443       14065 :     STLDeleteValues(&edge_list);
     444       22987 : }
     445             : 
     446       10263 : Ip4Address EdgeDiscoverySpec::Edge::GetIp4Address() const {
     447       10263 :     return Ip4Address(get_value(&address[0], 4));
     448             : }
     449             : 
     450      130526 : void EdgeDiscoverySpec::Edge::SetIp4Address(Ip4Address addr) {
     451      130526 :     address.resize(4, 0);
     452      130526 :     const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
     453      130526 :     std::copy(addr_bytes.begin(), addr_bytes.begin() + 4, address.begin());
     454      130526 : }
     455             : 
     456       10263 : void EdgeDiscoverySpec::Edge::GetLabels(
     457             :     uint32_t *first_label, uint32_t *last_label) const {
     458       10263 :     *first_label = labels[0];
     459       10263 :     *last_label = labels[1];
     460       10263 : }
     461             : 
     462      130526 : void EdgeDiscoverySpec::Edge::SetLabels(
     463             :     uint32_t first_label, uint32_t last_label) {
     464      130526 :     labels.push_back(first_label);
     465      130526 :     labels.push_back(last_label);
     466      130526 : }
     467             : 
     468             : struct EdgeDiscoverySpecEdgeCompare {
     469       63710 :     int operator()(const EdgeDiscoverySpec::Edge *lhs,
     470             :                    const EdgeDiscoverySpec::Edge *rhs) const {
     471       63710 :         KEY_COMPARE(lhs->address, rhs->address);
     472       63710 :         KEY_COMPARE(lhs->labels, rhs->labels);
     473       63710 :         return 0;
     474             :     }
     475             : };
     476             : 
     477        2003 : int EdgeDiscoverySpec::CompareTo(const BgpAttribute &rhs_attr) const {
     478        2003 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     479        2003 :     if (ret != 0) return ret;
     480        2003 :     const EdgeDiscoverySpec &rhs =
     481             :             static_cast<const EdgeDiscoverySpec &>(rhs_attr);
     482        2003 :     ret = STLSortedCompare(edge_list.begin(), edge_list.end(),
     483             :                            rhs.edge_list.begin(), rhs.edge_list.end(),
     484             :                            EdgeDiscoverySpecEdgeCompare());
     485        2003 :     return ret;
     486             : }
     487             : 
     488        2152 : void EdgeDiscoverySpec::ToCanonical(BgpAttr *attr) {
     489        2152 :     attr->set_edge_discovery(this);
     490        2152 : }
     491             : 
     492        1255 : string EdgeDiscoverySpec::ToString() const {
     493        1255 :     std::ostringstream oss;
     494        1255 :     oss << "EdgeDiscovery <code: " << int(code);
     495        1255 :     oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
     496        1255 :     int idx = 0;
     497        1255 :     for (EdgeList::const_iterator it = edge_list.begin();
     498        5016 :          it != edge_list.end(); ++it, ++idx) {
     499        3761 :         const Edge *edge = *it;
     500             :         uint32_t first_label, last_label;
     501        3761 :         edge->GetLabels(&first_label, &last_label);
     502        3761 :         oss << " Edge[" << idx << "] = (" << edge->GetIp4Address() << ", ";
     503        3761 :         oss << first_label << "-" << last_label << ")";
     504             :     }
     505             : 
     506        2510 :     return oss.str();
     507        1255 : }
     508             : 
     509       14059 : size_t EdgeDiscoverySpec::EncodeLength() const {
     510       14059 :     size_t sz = 0;
     511       14059 :     for (EdgeList::const_iterator iter = edge_list.begin();
     512      277056 :          iter != edge_list.end(); ++iter) {
     513      262997 :         sz += 2; /* AddressLen + LabelLen */
     514      262997 :         sz += (*iter)->address.size();
     515      262997 :         sz += (*iter)->labels.size() * sizeof(uint32_t);
     516             :     }
     517       14059 :     return sz;
     518             : }
     519             : 
     520        6474 : EdgeDiscovery::Edge::Edge(const EdgeDiscoverySpec::Edge *spec_edge) {
     521        6474 :     address = spec_edge->GetIp4Address();
     522             :     uint32_t first_label, last_label;
     523        6474 :     spec_edge->GetLabels(&first_label, &last_label);
     524        6474 :     label_block = new LabelBlock(first_label, last_label);
     525        6474 : }
     526             : 
     527       56188 : bool EdgeDiscovery::Edge::operator<(const Edge &rhs) const {
     528       56188 :     BOOL_KEY_COMPARE(address, rhs.address);
     529       48768 :     BOOL_KEY_COMPARE(label_block->first(), rhs.label_block->first());
     530       43112 :     BOOL_KEY_COMPARE(label_block->last(), rhs.label_block->last());
     531       43112 :     return false;
     532             : }
     533             : 
     534        3185 : EdgeDiscovery::EdgeDiscovery(EdgeDiscoveryDB *edge_discovery_db,
     535        3185 :     const EdgeDiscoverySpec &edspec)
     536        3184 :     : edge_discovery_db_(edge_discovery_db),
     537        3185 :       edspec_(edspec) {
     538        3184 :     refcount_ = 0;
     539        3179 :     for (EdgeDiscoverySpec::EdgeList::const_iterator it =
     540        9655 :          edspec_.edge_list.begin(); it != edspec_.edge_list.end(); ++it) {
     541        6474 :         Edge *edge = new Edge(*it);
     542        6474 :         edge_list.push_back(edge);
     543             :     }
     544        3179 :     sort(edge_list.begin(), edge_list.end(), EdgeDiscovery::EdgeCompare());
     545        3180 : }
     546             : 
     547        5350 : EdgeDiscovery::~EdgeDiscovery() {
     548        3187 :     STLDeleteValues(&edge_list);
     549        5349 : }
     550             : 
     551             : struct EdgeDiscoveryEdgeCompare {
     552       22258 :     int operator()(const EdgeDiscovery::Edge *lhs,
     553             :                    const EdgeDiscovery::Edge *rhs) const {
     554       22258 :         KEY_COMPARE(*lhs, *rhs);
     555       12964 :         return 0;
     556             :     }
     557             : };
     558             : 
     559      621928 : int EdgeDiscovery::CompareTo(const EdgeDiscovery &rhs) const {
     560      621928 :     int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
     561             :                                   rhs.edge_list.begin(), rhs.edge_list.end(),
     562             :                                   EdgeDiscoveryEdgeCompare());
     563      621928 :     return result;
     564             : }
     565             : 
     566        1880 : void EdgeDiscovery::Remove() {
     567        1880 :     edge_discovery_db_->Delete(this);
     568        1880 : }
     569             : 
     570        9742 : EdgeDiscoveryDB::EdgeDiscoveryDB(BgpServer *server) {
     571        9742 : }
     572             : 
     573        6397 : EdgeForwardingSpec::EdgeForwardingSpec()
     574        6397 :     : BgpAttribute(McastEdgeForwarding, kFlags) {
     575        6396 : }
     576             : 
     577        4650 : EdgeForwardingSpec::EdgeForwardingSpec(const BgpAttribute &rhs)
     578        4650 :     : BgpAttribute(rhs) {
     579        4650 : }
     580             : 
     581        6312 : EdgeForwardingSpec::EdgeForwardingSpec(const EdgeForwardingSpec &rhs)
     582        6312 :     : BgpAttribute(BgpAttribute::McastEdgeForwarding, kFlags) {
     583       11516 :     for (size_t i = 0; i < rhs.edge_list.size(); i++) {
     584        5204 :         Edge *edge = new Edge;
     585        5204 :         *edge = *rhs.edge_list[i];
     586        5204 :         edge_list.push_back(edge);
     587             :     }
     588        6312 : }
     589             : 
     590       27776 : EdgeForwardingSpec:: ~EdgeForwardingSpec() {
     591       17335 :     STLDeleteValues(&edge_list);
     592       27751 : }
     593             : 
     594        5558 : Ip4Address EdgeForwardingSpec::Edge::GetInboundIp4Address() const {
     595        5558 :     return Ip4Address(get_value(&inbound_address[0], 4));
     596             : }
     597             : 
     598        5558 : Ip4Address EdgeForwardingSpec::Edge::GetOutboundIp4Address() const {
     599        5558 :     return Ip4Address(get_value(&outbound_address[0], 4));
     600             : }
     601             : 
     602      126179 : void EdgeForwardingSpec::Edge::SetInboundIp4Address(Ip4Address addr) {
     603      126179 :     inbound_address.resize(4, 0);
     604      126179 :     const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
     605      126179 :     std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
     606             :         inbound_address.begin());
     607      126179 : }
     608             : 
     609      126179 : void EdgeForwardingSpec::Edge::SetOutboundIp4Address(Ip4Address addr) {
     610      126179 :     outbound_address.resize(4, 0);
     611      126179 :     const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
     612      126179 :     std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
     613             :         outbound_address.begin());
     614      126179 : }
     615             : 
     616             : struct EdgeForwardingSpecEdgeCompare {
     617       59919 :     int operator()(const EdgeForwardingSpec::Edge *lhs,
     618             :                    const EdgeForwardingSpec::Edge *rhs) const {
     619       59919 :         KEY_COMPARE(lhs->inbound_address, rhs->inbound_address);
     620       59919 :         KEY_COMPARE(lhs->outbound_address, rhs->outbound_address);
     621       59919 :         KEY_COMPARE(lhs->inbound_label, rhs->inbound_label);
     622       59919 :         KEY_COMPARE(lhs->outbound_label, rhs->outbound_label);
     623       59919 :         return 0;
     624             :     }
     625             : };
     626             : 
     627        1898 : int EdgeForwardingSpec::CompareTo(const BgpAttribute &rhs_attr) const {
     628        1898 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     629        1898 :     if (ret != 0) return ret;
     630        1898 :     const EdgeForwardingSpec &rhs =
     631             :             static_cast<const EdgeForwardingSpec &>(rhs_attr);
     632        1898 :     ret = STLSortedCompare(edge_list.begin(), edge_list.end(),
     633             :                            rhs.edge_list.begin(), rhs.edge_list.end(),
     634             :                            EdgeForwardingSpecEdgeCompare());
     635        1898 :     return ret;
     636             : }
     637             : 
     638        3468 : void EdgeForwardingSpec::ToCanonical(BgpAttr *attr) {
     639        3468 :     attr->set_edge_forwarding(this);
     640        3468 : }
     641             : 
     642        2099 : string EdgeForwardingSpec::ToString() const {
     643        2099 :     std::ostringstream oss;
     644        2099 :     oss << "EdgeForwarding <code: " << int(code);
     645        2099 :     oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
     646        2099 :     int idx = 0;
     647        2099 :     for (EdgeList::const_iterator it = edge_list.begin();
     648        4369 :          it != edge_list.end(); ++it, ++idx) {
     649        2270 :         const Edge *edge = *it;
     650        2270 :         oss << " Edge[" << idx << "] = (";
     651        2270 :         oss << "InAddress=" << edge->GetInboundIp4Address() << ", ";
     652        2270 :         oss << "InLabel=" << edge->inbound_label << ", ";
     653        2270 :         oss << "OutAddress=" << edge->GetOutboundIp4Address() << ", ";
     654        2270 :         oss << "OutLabel=" << edge->outbound_label << ")";
     655             :     }
     656             : 
     657        4198 :     return oss.str();
     658        2099 : }
     659             : 
     660       16260 : size_t EdgeForwardingSpec::EncodeLength() const {
     661       16260 :     size_t sz = 0;
     662       16260 :     for (EdgeList::const_iterator iter = edge_list.begin();
     663      271419 :          iter != edge_list.end(); ++iter) {
     664      255159 :         sz += 1 /* address len */ + 8 /* 2 labels */;
     665      255159 :         sz += (*iter)->inbound_address.size();
     666      255159 :         sz += (*iter)->outbound_address.size();
     667             :     }
     668             : 
     669       16260 :     return sz;
     670             : }
     671             : 
     672        3284 : EdgeForwarding::Edge::Edge(const EdgeForwardingSpec::Edge *spec_edge) {
     673        3284 :     inbound_address = spec_edge->GetInboundIp4Address();
     674        3284 :     outbound_address = spec_edge->GetOutboundIp4Address();
     675        3284 :     inbound_label = spec_edge->inbound_label;
     676        3284 :     outbound_label = spec_edge->outbound_label;
     677        3284 : }
     678             : 
     679       33303 : bool EdgeForwarding::Edge::operator<(const Edge &rhs) const {
     680       33303 :     BOOL_KEY_COMPARE(inbound_address, rhs.inbound_address);
     681       23253 :     BOOL_KEY_COMPARE(outbound_address, rhs.outbound_address);
     682       18587 :     BOOL_KEY_COMPARE(inbound_label, rhs.inbound_label);
     683       16325 :     BOOL_KEY_COMPARE(outbound_label, rhs.outbound_label);
     684       13876 :     return false;
     685             : }
     686             : 
     687        4504 : EdgeForwarding::EdgeForwarding(EdgeForwardingDB *edge_forwarding_db,
     688        4504 :     const EdgeForwardingSpec &efspec)
     689        4504 :     : edge_forwarding_db_(edge_forwarding_db),
     690        4504 :       efspec_(efspec) {
     691        4504 :     refcount_ = 0;
     692        4501 :     for (EdgeForwardingSpec::EdgeList::const_iterator it =
     693        7786 :          efspec_.edge_list.begin(); it != efspec_.edge_list.end(); ++it) {
     694        3284 :         Edge *edge = new Edge(*it);
     695        3284 :         edge_list.push_back(edge);
     696             :     }
     697        4500 :     sort(edge_list.begin(), edge_list.end(), EdgeForwarding::EdgeCompare());
     698        4499 : }
     699             : 
     700        7984 : EdgeForwarding::~EdgeForwarding() {
     701        4504 :     STLDeleteValues(&edge_list);
     702        7983 : }
     703             : 
     704             : struct EdgeForwardingEdgeCompare {
     705       19043 :     int operator()(const EdgeForwarding::Edge *lhs,
     706             :                    const EdgeForwarding::Edge *rhs) const {
     707       19043 :         KEY_COMPARE(*lhs, *rhs);
     708        6938 :         return 0;
     709             :     }
     710             : };
     711             : 
     712      756085 : int EdgeForwarding::CompareTo(const EdgeForwarding &rhs) const {
     713      756085 :     int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
     714             :                                   rhs.edge_list.begin(), rhs.edge_list.end(),
     715             :                                   EdgeForwardingEdgeCompare());
     716      756085 :     return result;
     717             : }
     718             : 
     719        2384 : void EdgeForwarding::Remove() {
     720        2384 :     edge_forwarding_db_->Delete(this);
     721        2384 : }
     722             : 
     723        9742 : EdgeForwardingDB::EdgeForwardingDB(BgpServer *server) {
     724        9742 : }
     725             : 
     726      206075 : bool BgpOListElem::operator<(const BgpOListElem &rhs) const {
     727      206075 :     BOOL_KEY_COMPARE(address, rhs.address);
     728      135770 :     BOOL_KEY_COMPARE(label, rhs.label);
     729      131610 :     BOOL_KEY_COMPARE(encap, rhs.encap);
     730      131600 :     return false;
     731             : }
     732             : 
     733           3 : int BgpOListSpec::CompareTo(const BgpAttribute &rhs_attr) const {
     734           3 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     735           3 :     if (ret != 0) return ret;
     736           3 :     return 0;
     737             : }
     738             : 
     739        3607 : void BgpOListSpec::ToCanonical(BgpAttr *attr) {
     740        3607 :     if (subcode == BgpAttribute::OList) {
     741        3607 :         attr->set_olist(this);
     742           0 :     } else if (subcode == BgpAttribute::LeafOList) {
     743           0 :         attr->set_leaf_olist(this);
     744             :     } else {
     745           0 :         assert(false);
     746             :     }
     747        3607 : }
     748             : 
     749           1 : string BgpOListSpec::ToString() const {
     750           1 :     std::ostringstream oss;
     751           1 :     oss << "OList <subcode: " << int(subcode) << ">";
     752           1 :     int idx = 0;
     753           1 :     for (Elements::const_iterator it = elements.begin();
     754           3 :          it != elements.end(); ++it, ++idx) {
     755           2 :         BgpOListElem elem(*it);
     756           2 :         oss << "OList[" << idx << "] = (";
     757           2 :         oss << "address: " << elem.address << ", ";
     758           2 :         oss << "label: " << elem.label << ", ";
     759           2 :         oss << "encap-list:";
     760           2 :         int eid = 0;
     761           2 :         for (vector<string>::const_iterator e_it = elem.encap.begin();
     762           6 :              e_it != elem.encap.end(); ++e_it, ++eid) {
     763           4 :              oss << " " << *e_it;
     764             :         }
     765           2 :         oss << ")";
     766           2 :     }
     767           2 :     return (oss.str());
     768           1 : }
     769             : 
     770       14268 : BgpOList::BgpOList(BgpOListDB *olist_db, const BgpOListSpec &olist_spec)
     771       14268 :     : olist_db_(olist_db),
     772       14268 :       olist_spec_(olist_spec) {
     773       14266 :     refcount_ = 0;
     774       14267 :     for (BgpOListSpec::Elements::const_iterator it =
     775       37892 :          olist_spec_.elements.begin(); it != olist_spec_.elements.end(); ++it) {
     776       23624 :         BgpOListElem *elem = new BgpOListElem(*it);
     777       23624 :         sort(elem->encap.begin(), elem->encap.end());
     778       23624 :         elements_.push_back(elem);
     779             :     }
     780       14265 :     sort(elements_.begin(), elements_.end(), BgpOListElemCompare());
     781       14263 : }
     782             : 
     783       27512 : BgpOList::~BgpOList() {
     784       14268 :     STLDeleteValues(&elements_);
     785       27511 : }
     786             : 
     787             : struct BgpOListElementCompare {
     788       81206 :     int operator()(const BgpOListElem *lhs, const BgpOListElem *rhs) const {
     789       81206 :         KEY_COMPARE(*lhs, *rhs);
     790       65800 :         return 0;
     791             :     }
     792             : };
     793             : 
     794     1907382 : int BgpOList::CompareTo(const BgpOList &rhs) const {
     795     1907382 :     KEY_COMPARE(olist().subcode, rhs.olist().subcode);
     796     3784700 :     int result = STLSortedCompare(elements().begin(), elements().end(),
     797     3784700 :                                   rhs.elements().begin(), rhs.elements().end(),
     798             :                                   BgpOListElementCompare());
     799     1892350 :     return result;
     800             : }
     801             : 
     802        9781 : void BgpOList::Remove() {
     803        9781 :     olist_db_->Delete(this);
     804        9781 : }
     805             : 
     806        9742 : BgpOListDB::BgpOListDB(BgpServer *server) {
     807        9742 : }
     808             : 
     809           0 : int BgpAttrLabelBlock::CompareTo(const BgpAttribute &rhs_attr) const {
     810           0 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     811           0 :     if (ret != 0) return ret;
     812           0 :     KEY_COMPARE(label_block.get(),
     813             :             static_cast<const BgpAttrLabelBlock &>(rhs_attr).label_block.get());
     814           0 :     return 0;
     815             : }
     816             : 
     817        1033 : void BgpAttrLabelBlock::ToCanonical(BgpAttr *attr) {
     818        1033 :     attr->set_label_block(label_block);
     819        1033 : }
     820             : 
     821           0 : string BgpAttrLabelBlock::ToString() const {
     822             :     char repr[80];
     823           0 :     snprintf(repr, sizeof(repr), "LabelBlock <subcode: %d> : %d-%d",
     824           0 :              subcode, label_block->first(), label_block->last());
     825           0 :     return string(repr);
     826             : }
     827             : 
     828           3 : int BgpAttrSourceRd::CompareTo(const BgpAttribute &rhs_attr) const {
     829           3 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     830           3 :     if (ret != 0) return ret;
     831           3 :     KEY_COMPARE(source_rd,
     832             :             static_cast<const BgpAttrSourceRd &>(rhs_attr).source_rd);
     833           1 :     return 0;
     834             : }
     835             : 
     836       28661 : void BgpAttrSourceRd::ToCanonical(BgpAttr *attr) {
     837       28661 :     attr->set_source_rd(source_rd);
     838       28661 : }
     839             : 
     840           1 : string BgpAttrSourceRd::ToString() const {
     841             :     char repr[80];
     842           1 :     snprintf(repr, sizeof(repr), "SourceRd <subcode: %d> : %s",
     843           2 :              subcode, source_rd.ToString().c_str());
     844           1 :     return string(repr);
     845             : }
     846             : 
     847           3 : int BgpAttrEsi::CompareTo(const BgpAttribute &rhs_attr) const {
     848           3 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     849           3 :     if (ret != 0) return ret;
     850           3 :     KEY_COMPARE(esi, static_cast<const BgpAttrEsi &>(rhs_attr).esi);
     851           1 :     return 0;
     852             : }
     853             : 
     854          59 : void BgpAttrEsi::ToCanonical(BgpAttr *attr) {
     855          59 :     attr->set_esi(esi);
     856          59 : }
     857             : 
     858           1 : string BgpAttrEsi::ToString() const {
     859             :     char repr[80];
     860           1 :     snprintf(repr, sizeof(repr), "Esi <subcode: %d> : %s",
     861           2 :              subcode, esi.ToString().c_str());
     862           1 :     return string(repr);
     863             : }
     864             : 
     865           3 : int BgpAttrParams::CompareTo(const BgpAttribute &rhs_attr) const {
     866           3 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     867           3 :     if (ret != 0) return ret;
     868           3 :     KEY_COMPARE(params, static_cast<const BgpAttrParams &>(rhs_attr).params);
     869           1 :     return 0;
     870             : }
     871             : 
     872           3 : void BgpAttrParams::ToCanonical(BgpAttr *attr) {
     873           3 :     attr->set_params(params);
     874           3 : }
     875             : 
     876           1 : string BgpAttrParams::ToString() const {
     877             :     char repr[80];
     878           1 :     snprintf(repr, sizeof(repr), "Params <subcode: %d> : 0x%016jx",
     879           1 :              subcode, params);
     880           1 :     return string(repr);
     881             : }
     882             : 
     883           3 : int BgpAttrSubProtocol::CompareTo(const BgpAttribute &rhs_attr) const {
     884           3 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     885           3 :     if (ret != 0) return ret;
     886           3 :     KEY_COMPARE(sbp, static_cast<const BgpAttrSubProtocol &>(rhs_attr).sbp);
     887           1 :     return 0;
     888             : }
     889             : 
     890       21988 : void BgpAttrSubProtocol::ToCanonical(BgpAttr *attr) {
     891       21988 :     attr->set_sub_protocol(sbp);
     892       21988 : }
     893             : 
     894           1 : string BgpAttrSubProtocol::ToString() const {
     895             :     char repr[80];
     896           1 :     snprintf(repr, sizeof(repr), "SubProtocol <subcode: %d> : %s",
     897           1 :              subcode, sbp.c_str());
     898           1 :     return string(repr);
     899             : }
     900             : 
     901          38 : BgpAttr::BgpAttr()
     902          38 :     : attr_db_(NULL), origin_(BgpAttrOrigin::INCOMPLETE), nexthop_(),
     903          38 :       med_(0), local_pref_(0), atomic_aggregate_(false),
     904          38 :       aggregator_as_num_(0), aggregator_as4_num_(0), params_(0) {
     905          38 :     refcount_ = 0;
     906          38 : }
     907             : 
     908        5953 : BgpAttr::BgpAttr(BgpAttrDB *attr_db)
     909        5953 :     : attr_db_(attr_db), origin_(BgpAttrOrigin::INCOMPLETE),
     910       11906 :       nexthop_(), med_(0), local_pref_(0), atomic_aggregate_(false),
     911        5953 :       aggregator_as_num_(0), aggregator_as4_num_(0), params_(0) {
     912        5953 :     refcount_ = 0;
     913        5953 : }
     914             : 
     915      389254 : BgpAttr::BgpAttr(BgpAttrDB *attr_db, const BgpAttrSpec &spec)
     916      389254 :     : attr_db_(attr_db), origin_(BgpAttrOrigin::INCOMPLETE),
     917      778507 :       nexthop_(), med_(0),
     918      389253 :       local_pref_(BgpAttrLocalPref::kDefault),
     919      389253 :       atomic_aggregate_(false),
     920      389253 :       aggregator_as_num_(0), aggregator_as4_num_(0), 
     921      389254 :       aggregator_address_(), params_(0) {
     922      389247 :     refcount_ = 0;
     923      389258 :     for (vector<BgpAttribute *>::const_iterator it = spec.begin();
     924     1468654 :          it < spec.end(); it++) {
     925     1079393 :         (*it)->ToCanonical(this);
     926             :     }
     927      389250 : }
     928             : 
     929     3003407 : BgpAttr::BgpAttr(const BgpAttr &rhs)
     930     3003407 :     : attr_db_(rhs.attr_db_), origin_(rhs.origin_), nexthop_(rhs.nexthop_),
     931     3003082 :       med_(rhs.med_), local_pref_(rhs.local_pref_),
     932     3003082 :       atomic_aggregate_(rhs.atomic_aggregate_),
     933     3003082 :       aggregator_as_num_(rhs.aggregator_as_num_),
     934     3003082 :       aggregator_as4_num_(rhs.aggregator_as4_num_),
     935     3003082 :       aggregator_address_(rhs.aggregator_address_),
     936     3002924 :       originator_id_(rhs.originator_id_),
     937     3002862 :       source_rd_(rhs.source_rd_), esi_(rhs.esi_), params_(rhs.params_),
     938     3002761 :       as_path_(rhs.as_path_),
     939     3003418 :       aspath_4byte_(rhs.aspath_4byte_),
     940     3003337 :       as4_path_(rhs.as4_path_),
     941     3003134 :       cluster_list_(rhs.cluster_list_),
     942     3003070 :       community_(rhs.community_),
     943     3002992 :       ext_community_(rhs.ext_community_),
     944     3003856 :       large_community_(rhs.large_community_),
     945     3003469 :       deferred_large_spec_(nullptr),
     946     3002877 :       origin_vn_path_(rhs.origin_vn_path_),
     947     3002784 :       pmsi_tunnel_(rhs.pmsi_tunnel_),
     948     3002677 :       edge_discovery_(rhs.edge_discovery_),
     949     3002551 :       edge_forwarding_(rhs.edge_forwarding_),
     950     3002473 :       label_block_(rhs.label_block_),
     951     3002425 :       olist_(rhs.olist_),
     952     3002343 :       leaf_olist_(rhs.leaf_olist_),
     953     6005675 :       sub_protocol_(rhs.sub_protocol_) {
     954     3002062 :     refcount_ = 0;
     955     3003958 : }
     956             : 
     957       19036 : void BgpAttr::set_as_path(AsPathPtr aspath) {
     958       19036 :     as_path_ = aspath;
     959       19036 : }
     960             : 
     961      360731 : void BgpAttr::set_as_path(const AsPathSpec *spec) {
     962      360731 :     if (spec) {
     963      360601 :         as_path_ = attr_db_->server()->aspath_db()->Locate(*spec);
     964             :     } else {
     965         130 :         as_path_ = NULL;
     966             :     }
     967      360773 : }
     968             : 
     969           0 : void BgpAttr::set_as4_path(As4PathPtr aspath) {
     970           0 :     as4_path_ = aspath;
     971           0 : }
     972             : 
     973         491 : void BgpAttr::set_as4_path(const As4PathSpec *spec) {
     974         491 :     if (spec) {
     975         457 :         as4_path_ = attr_db_->server()->as4path_db()->Locate(*spec);
     976             :     } else {
     977          34 :         as4_path_ = NULL;
     978             :     }
     979         491 : }
     980             : 
     981           0 : void BgpAttr::set_aspath_4byte(AsPath4BytePtr aspath) {
     982           0 :     aspath_4byte_ = aspath;
     983           0 : }
     984             : 
     985         549 : void BgpAttr::set_aspath_4byte(const AsPath4ByteSpec *spec) {
     986         549 :     if (spec) {
     987         489 :         aspath_4byte_ = attr_db_->server()->aspath_4byte_db()->Locate(*spec);
     988             :     } else {
     989          60 :         aspath_4byte_ = NULL;
     990             :     }
     991         549 : }
     992             : 
     993      201641 : void BgpAttr::set_cluster_list(const ClusterListSpec *spec) {
     994      201641 :     if (spec) {
     995          18 :         cluster_list_ = attr_db_->server()->cluster_list_db()->Locate(*spec);
     996             :     } else {
     997      201623 :         cluster_list_ = NULL;
     998             :     }
     999      201639 : }
    1000             : 
    1001       24553 : void BgpAttr::set_community(CommunityPtr comm) {
    1002       24553 :     community_ = comm;
    1003       24553 : }
    1004             : 
    1005        4325 : void BgpAttr::set_community(const CommunitySpec *comm) {
    1006        4325 :     if (comm) {
    1007        4325 :         community_ = attr_db_->server()->comm_db()->Locate(*comm);
    1008             :     } else {
    1009           0 :         community_ = NULL;
    1010             :     }
    1011        4325 : }
    1012             : 
    1013      996886 : void BgpAttr::set_ext_community(ExtCommunityPtr extcomm) {
    1014      996886 :     ext_community_ = extcomm;
    1015      996902 : }
    1016             : 
    1017      183626 : void BgpAttr::set_ext_community(const ExtCommunitySpec *extcomm) {
    1018      183626 :     if (extcomm) {
    1019      183627 :         LargeCommunitySpec large_spec = LargeCommunitySpec::FromTag(*extcomm);
    1020      183625 :         set_large_community(&large_spec);
    1021             :         
    1022      183627 :         if (large_spec.communities.size()) {
    1023             :             ExtCommunitySpec new_comms =
    1024           4 :                 LargeCommunitySpec::RemoveTags(*extcomm);
    1025             :             ext_community_ =
    1026           4 :                 attr_db_->server()->extcomm_db()->Locate(new_comms);
    1027           4 :             return;
    1028           4 :         }
    1029      183622 :         ext_community_ = attr_db_->server()->extcomm_db()->Locate(*extcomm);
    1030      183628 :     } else {
    1031           0 :         ext_community_ = NULL;
    1032             :     }
    1033             : }
    1034             : 
    1035       18740 : void BgpAttr::set_large_community(LargeCommunityPtr largecomm) {
    1036       18740 :     large_community_ = largecomm;
    1037       18740 : }
    1038             : 
    1039      183669 : void BgpAttr::set_large_community(const LargeCommunitySpec *largecomm) {
    1040      183669 :     if (largecomm) {
    1041      183669 :         if (!bool(deferred_large_spec_)) {
    1042      183626 :             deferred_large_spec_.reset(new LargeCommunitySpec);
    1043      183625 :             deferred_large_spec_->communities = largecomm->communities;
    1044             :         } else {
    1045          88 :             deferred_large_spec_->communities.insert(
    1046          88 :                 deferred_large_spec_->communities.end(),
    1047             :                 largecomm->communities.begin(),
    1048             :                 largecomm->communities.end());
    1049             :         }
    1050             :         large_community_ =
    1051      183669 :             attr_db_->server()->largecomm_db()->Locate(*deferred_large_spec_);
    1052             :     } else {
    1053           0 :         large_community_ = NULL;
    1054             :     }
    1055      183671 : }
    1056             : 
    1057       18741 : void BgpAttr::set_origin_vn_path(OriginVnPathPtr ovnpath) {
    1058       18741 :     origin_vn_path_ = ovnpath;
    1059       18741 : }
    1060             : 
    1061         723 : void BgpAttr::set_origin_vn_path(const OriginVnPathSpec *spec) {
    1062         723 :     if (spec) {
    1063         723 :         origin_vn_path_ = attr_db_->server()->ovnpath_db()->Locate(*spec);
    1064             :     } else {
    1065           0 :         origin_vn_path_ = NULL;
    1066             :     }
    1067         723 : }
    1068             : 
    1069       16890 : void BgpAttr::set_pmsi_tunnel(const PmsiTunnelSpec *pmsi_spec) {
    1070       16890 :     if (pmsi_spec) {
    1071       16890 :         pmsi_tunnel_ = attr_db_->server()->pmsi_tunnel_db()->Locate(*pmsi_spec);
    1072             :     } else {
    1073           0 :         pmsi_tunnel_ = NULL;
    1074             :     }
    1075       16889 : }
    1076             : 
    1077        2153 : void BgpAttr::set_edge_discovery(const EdgeDiscoverySpec *edspec) {
    1078        2153 :     if (edspec) {
    1079             :         edge_discovery_ =
    1080        2153 :             attr_db_->server()->edge_discovery_db()->Locate(*edspec);
    1081             :     } else {
    1082           0 :         edge_discovery_ = NULL;
    1083             :     }
    1084        2153 : }
    1085             : 
    1086        3470 : void BgpAttr::set_edge_forwarding(const EdgeForwardingSpec *efspec) {
    1087        3470 :     if (efspec) {
    1088             :         edge_forwarding_ =
    1089        3470 :             attr_db_->server()->edge_forwarding_db()->Locate(*efspec);
    1090             :     } else {
    1091           0 :         edge_forwarding_ = NULL;
    1092             :     }
    1093        3470 : }
    1094             : 
    1095        1034 : void BgpAttr::set_label_block(LabelBlockPtr label_block) {
    1096        1034 :     label_block_ = label_block;
    1097        1034 : }
    1098             : 
    1099        8493 : void BgpAttr::set_olist(const BgpOListSpec *olist_spec) {
    1100        8493 :     if (olist_spec) {
    1101        8493 :         olist_ = attr_db_->server()->olist_db()->Locate(*olist_spec);
    1102             :     } else {
    1103           0 :         olist_ = NULL;
    1104             :     }
    1105        8493 : }
    1106             : 
    1107        4731 : void BgpAttr::set_leaf_olist(const BgpOListSpec *leaf_olist_spec) {
    1108        4731 :     if (leaf_olist_spec) {
    1109        4731 :         leaf_olist_ = attr_db_->server()->olist_db()->Locate(*leaf_olist_spec);
    1110             :     } else {
    1111           0 :         leaf_olist_ = NULL;
    1112             :     }
    1113        4731 : }
    1114             : 
    1115     9319923 : int BgpAttr::max_as_path_count() const {
    1116     9319923 :     int as_count = as_path_count();
    1117     9319902 :     int as4_count = aspath_4byte_count();
    1118     9319890 :     return as_count > as4_count ? as_count : as4_count;
    1119             : }
    1120             : 
    1121       98206 : bool BgpAttr::IsAsPathEmpty() const {
    1122       98206 :     if (as_path_ && !as_path_->empty())
    1123         332 :         return false;
    1124       97875 :     if (aspath_4byte_ && !aspath_4byte_->empty())
    1125          86 :         return false;
    1126       97789 :     return true;
    1127             : }
    1128             : 
    1129        5606 : string BgpAttr::OriginToString(BgpAttrOrigin::OriginType origin) {
    1130        5606 :     switch (origin) {
    1131        5249 :     case BgpAttrOrigin::IGP:
    1132        5249 :         return "igp";
    1133             :         break;
    1134           3 :     case BgpAttrOrigin::EGP:
    1135           3 :         return "egp";
    1136             :         break;
    1137         353 :     case BgpAttrOrigin::INCOMPLETE:
    1138         353 :         return "incomplete";
    1139             :         break;
    1140             :     }
    1141           1 :     return "unknown";
    1142             : }
    1143             : 
    1144       20430 : BgpAttrOrigin::OriginType BgpAttr::OriginFromString(
    1145             :         const string &bgp_origin_type) {
    1146       20430 :     if(bgp_origin_type ==  "IGP"){
    1147       20427 :         return BgpAttrOrigin::IGP;
    1148           3 :     } else if( bgp_origin_type ==  "EGP") {
    1149           2 :         return BgpAttrOrigin::EGP;
    1150             :     }
    1151           1 :     return BgpAttrOrigin::INCOMPLETE;
    1152             : }
    1153             : 
    1154        5603 : string BgpAttr::origin_string() const {
    1155        5603 :     return OriginToString(origin());
    1156             : }
    1157             : 
    1158        2887 : Address::Family BgpAttr::nexthop_family() const {
    1159        2887 :     if (nexthop_.is_v6()) {
    1160         325 :         return Address::INET6;
    1161             :     } else {
    1162        2562 :         return Address::INET;
    1163             :     }
    1164             : }
    1165             : 
    1166     2646480 : as_t BgpAttr::neighbor_as() const {
    1167     2646480 :     if (as_path_.get())
    1168      487118 :         return as_path_->neighbor_as();
    1169     2159352 :     if (aspath_4byte_.get())
    1170         219 :         return aspath_4byte_->neighbor_as();
    1171     2159137 :     return 0;
    1172             : }
    1173             : 
    1174     9411953 : uint32_t BgpAttr::sequence_number() const {
    1175     9411953 :     if (!ext_community_)
    1176     1136612 :         return 0;
    1177     8275351 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1178     8275357 :          ext_community_->communities().begin();
    1179    28946121 :          it != ext_community_->communities().end(); ++it) {
    1180    20675036 :         if (ExtCommunity::is_mac_mobility(*it)) {
    1181        4321 :             MacMobility mm(*it);
    1182        4321 :             return mm.sequence_number();
    1183             :         }
    1184             :     }
    1185     8270939 :     return 0;
    1186             : }
    1187             : 
    1188     4705995 : bool BgpAttr::evpn_sticky_mac() const {
    1189     4705995 :     if (!ext_community_)
    1190      568309 :         return 0;
    1191     4137687 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1192     4137699 :          ext_community_->communities().begin();
    1193    14473629 :          it != ext_community_->communities().end(); ++it) {
    1194    10338098 :         if (ExtCommunity::is_mac_mobility(*it)) {
    1195        2180 :             MacMobility mm(*it);
    1196        2180 :             return mm.sticky();
    1197             :         }
    1198             :     }
    1199     4135474 :     return 0;
    1200             : }
    1201             : 
    1202     4706036 : bool BgpAttr::etree_leaf() const {
    1203     4706036 :     if (!ext_community_)
    1204      568309 :         return 0;
    1205     4137719 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1206     4137713 :          ext_community_->communities().begin();
    1207    14328632 :          it != ext_community_->communities().end(); ++it) {
    1208    10264265 :         if (ExtCommunity::is_etree(*it)) {
    1209       73394 :             ETree etree(*it);
    1210       73393 :             return etree.leaf();
    1211             :         }
    1212             :     }
    1213     4064262 :     return 0;
    1214             : }
    1215             : 
    1216          52 : bool BgpAttr::evpn_single_active() const {
    1217          52 :     if (!ext_community_)
    1218           0 :         return false;
    1219          52 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1220          52 :          ext_community_->communities().begin();
    1221         104 :          it != ext_community_->communities().end(); ++it) {
    1222         104 :         if (ExtCommunity::is_esi_label(*it)) {
    1223          52 :             EsiLabel esi_label(*it);
    1224          52 :             return esi_label.single_active();
    1225             :         }
    1226             :     }
    1227           0 :     return true;
    1228             : }
    1229             : 
    1230      462824 : MacAddress BgpAttr::mac_address() const {
    1231      462824 :     if (!ext_community_)
    1232       13726 :         return MacAddress::kZeroMac;
    1233      449116 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1234      449130 :          ext_community_->communities().begin();
    1235     3187596 :          it != ext_community_->communities().end(); ++it) {
    1236     2738521 :         if (ExtCommunity::is_router_mac(*it)) {
    1237          22 :             RouterMac router_mac(*it);
    1238          22 :             return router_mac.mac_address();
    1239             :         }
    1240             :     }
    1241      449038 :     return MacAddress::kZeroMac;
    1242             : }
    1243             : 
    1244      438955 : void BgpAttr::Remove() {
    1245      438955 :     attr_db_->Delete(this);
    1246      438957 : }
    1247             : 
    1248      449568 : int BgpAttr::IsAsPathLoop(as_t asn, uint8_t max_loop_count) const {
    1249      449568 :     if (as_path() && as_path()->path().AsPathLoop(asn, max_loop_count)) {
    1250      136307 :         return true;
    1251             :     }
    1252      313461 :     if (aspath_4byte() &&
    1253         194 :            aspath_4byte()->path().AsPathLoop(asn, max_loop_count)) {
    1254          50 :         return true;
    1255             :     }
    1256      313235 :     if (asn > AS2_MAX && as4_path() &&
    1257          20 :            as4_path()->path().AsPathLoop(asn, max_loop_count)) {
    1258           4 :         return true;
    1259             :     }
    1260      313211 :     return false;
    1261             : }
    1262             : 
    1263    25381107 : int BgpAttr::CompareTo(const BgpAttr &rhs) const {
    1264    25381107 :     KEY_COMPARE(origin_, rhs.origin_);
    1265    23643970 :     KEY_COMPARE(nexthop_, rhs.nexthop_);
    1266    15851166 :     KEY_COMPARE(med_, rhs.med_);
    1267    15069654 :     KEY_COMPARE(local_pref_, rhs.local_pref_);
    1268    14663294 :     KEY_COMPARE(atomic_aggregate_, rhs.atomic_aggregate_);
    1269    14663294 :     KEY_COMPARE(aggregator_as_num_, rhs.aggregator_as_num_);
    1270    14663102 :     KEY_COMPARE(aggregator_as4_num_, rhs.aggregator_as4_num_);
    1271    14662974 :     KEY_COMPARE(aggregator_address_, rhs.aggregator_address_);
    1272    14665991 :     KEY_COMPARE(originator_id_, rhs.originator_id_);
    1273    14664620 :     KEY_COMPARE(pmsi_tunnel_.get(), rhs.pmsi_tunnel_.get());
    1274    14312258 :     KEY_COMPARE(edge_discovery_.get(), rhs.edge_discovery_.get());
    1275    14249049 :     KEY_COMPARE(edge_forwarding_.get(), rhs.edge_forwarding_.get());
    1276    14184503 :     KEY_COMPARE(esi_, rhs.esi_);
    1277    14184325 :     KEY_COMPARE(params_, rhs.params_);
    1278    14184320 :     KEY_COMPARE(source_rd_, rhs.source_rd_);
    1279    10224832 :     KEY_COMPARE(label_block_.get(), rhs.label_block_.get());
    1280    10226680 :     KEY_COMPARE(olist_.get(), rhs.olist_.get());
    1281    10165975 :     KEY_COMPARE(leaf_olist_.get(), rhs.leaf_olist_.get());
    1282    10145520 :     KEY_COMPARE(as_path_.get(), rhs.as_path_.get());
    1283     9855467 :     KEY_COMPARE(aspath_4byte_.get(), rhs.aspath_4byte_.get());
    1284     9854367 :     KEY_COMPARE(as4_path_.get(), rhs.as4_path_.get());
    1285     9853438 :     KEY_COMPARE(cluster_list_.get(), rhs.cluster_list_.get());
    1286     9853347 :     KEY_COMPARE(community_.get(), rhs.community_.get());
    1287     9609323 :     KEY_COMPARE(ext_community_.get(), rhs.ext_community_.get());
    1288     7128054 :     KEY_COMPARE(large_community_.get(), rhs.large_community_.get());
    1289     7113337 :     KEY_COMPARE(origin_vn_path_.get(), rhs.origin_vn_path_.get());
    1290     7037589 :     KEY_COMPARE(sub_protocol_, rhs.sub_protocol_);
    1291     7021759 :     return 0;
    1292             : }
    1293             : 
    1294           0 : std::size_t hash_value(BgpAttr const &attr) {
    1295           0 :     size_t hash = 0;
    1296             : 
    1297           0 :     boost::hash_combine(hash, attr.origin_);
    1298           0 :     boost::hash_combine(hash, attr.nexthop_.to_string());
    1299           0 :     boost::hash_combine(hash, attr.med_);
    1300           0 :     boost::hash_combine(hash, attr.local_pref_);
    1301           0 :     boost::hash_combine(hash, attr.atomic_aggregate_);
    1302           0 :     boost::hash_combine(hash, attr.aggregator_as_num_);
    1303           0 :     boost::hash_combine(hash, attr.aggregator_as4_num_);
    1304           0 :     boost::hash_combine(hash, attr.aggregator_address_.to_string());
    1305           0 :     boost::hash_combine(hash, attr.originator_id_.to_string());
    1306           0 :     boost::hash_combine(hash, attr.params_);
    1307           0 :     boost::hash_combine(hash, attr.source_rd_.ToString());
    1308           0 :     boost::hash_combine(hash, attr.esi_.ToString());
    1309             : 
    1310           0 :     if (attr.label_block_) {
    1311           0 :         boost::hash_combine(hash, attr.label_block_->first());
    1312           0 :         boost::hash_combine(hash, attr.label_block_->last());
    1313             :     }
    1314             : 
    1315           0 :     if (attr.olist_) {
    1316           0 :         boost::hash_range(hash, attr.olist_->elements().begin(),
    1317           0 :                           attr.olist_->elements().end());
    1318             :     }
    1319           0 :     if (attr.leaf_olist_) {
    1320           0 :         boost::hash_range(hash, attr.leaf_olist_->elements().begin(),
    1321           0 :                           attr.leaf_olist_->elements().end());
    1322             :     }
    1323             : 
    1324           0 :     if (attr.as_path_) boost::hash_combine(hash, *attr.as_path_);
    1325           0 :     if (attr.aspath_4byte_) boost::hash_combine(hash, *attr.aspath_4byte_);
    1326           0 :     if (attr.as4_path_) boost::hash_combine(hash, *attr.as4_path_);
    1327           0 :     if (attr.community_) boost::hash_combine(hash, *attr.community_);
    1328           0 :     if (attr.ext_community_) boost::hash_combine(hash, *attr.ext_community_);
    1329           0 :     if (attr.large_community_) boost::hash_combine(hash, *attr.large_community_);
    1330           0 :     if (attr.origin_vn_path_) boost::hash_combine(hash, *attr.origin_vn_path_);
    1331           0 :     if (!attr.sub_protocol_.empty()) {
    1332           0 :         boost::hash_combine(hash, attr.sub_protocol_);
    1333             :     }
    1334             : 
    1335           0 :     return hash;
    1336             : }
    1337             : 
    1338        9742 : BgpAttrDB::BgpAttrDB(BgpServer *server) : server_(server) {
    1339        9742 : }
    1340             : 
    1341             : // Return a clone of attribute with updated aspath.
    1342       19036 : BgpAttrPtr BgpAttrDB::ReplaceAsPathAndLocate(const BgpAttr *attr,
    1343             :                                              AsPathPtr aspath) {
    1344       19036 :     BgpAttr *clone = new BgpAttr(*attr);
    1345       19036 :     clone->set_as_path(aspath);
    1346       19036 :     return Locate(clone);
    1347             : }
    1348             : 
    1349             : // Return a clone of attribute with updated community.
    1350       19066 : BgpAttrPtr BgpAttrDB::ReplaceCommunityAndLocate(const BgpAttr *attr,
    1351             :                                                 CommunityPtr community) {
    1352       19066 :     BgpAttr *clone = new BgpAttr(*attr);
    1353       19066 :     clone->set_community(community);
    1354       19066 :     return Locate(clone);
    1355             : }
    1356             : 
    1357             : //Return a clone of attribute with updated origin
    1358           4 : BgpAttrPtr BgpAttrDB::ReplaceOriginAndLocate(const BgpAttr *attr,
    1359             :                                              BgpAttrOrigin::OriginType origin) {
    1360           4 :     BgpAttr *clone = new BgpAttr(*attr);
    1361           4 :     clone->set_origin(origin);
    1362           4 :     return Locate(clone);
    1363             : }
    1364             : 
    1365             : // Return a clone of attribute with updated extended community.
    1366      996697 : BgpAttrPtr BgpAttrDB::ReplaceExtCommunityAndLocate(const BgpAttr *attr,
    1367             :                                                    ExtCommunityPtr extcomm) {
    1368      996697 :     BgpAttr *clone = new BgpAttr(*attr);
    1369      996896 :     clone->set_ext_community(extcomm);
    1370      996897 :     return Locate(clone);
    1371             : }
    1372             : 
    1373             : // Return a clone of attribute with updated large community.
    1374       18740 : BgpAttrPtr BgpAttrDB::ReplaceLargeCommunityAndLocate(
    1375             :     const BgpAttr *attr, LargeCommunityPtr largecomm) {
    1376       18740 :     BgpAttr *clone = new BgpAttr(*attr);
    1377       18740 :     clone->set_large_community(largecomm);
    1378       18740 :     return Locate(clone);
    1379             : }
    1380             : 
    1381             : // Return a clone of attribute with updated origin vn path.
    1382       18741 : BgpAttrPtr BgpAttrDB::ReplaceOriginVnPathAndLocate(const BgpAttr *attr,
    1383             :                                                    OriginVnPathPtr ovnpath) {
    1384       18741 :     BgpAttr *clone = new BgpAttr(*attr);
    1385       18741 :     clone->set_origin_vn_path(ovnpath);
    1386       18741 :     return Locate(clone);
    1387             : }
    1388             : 
    1389             : // Return a clone of attribute with updated local preference.
    1390          18 : BgpAttrPtr BgpAttrDB::ReplaceLocalPreferenceAndLocate(const BgpAttr *attr,
    1391             :                                                       uint32_t local_pref) {
    1392          18 :     BgpAttr *clone = new BgpAttr(*attr);
    1393          18 :     clone->set_local_pref(local_pref);
    1394          18 :     return Locate(clone);
    1395             : }
    1396             : 
    1397             : // Return a clone of attribute with updated originator id.
    1398           1 : BgpAttrPtr BgpAttrDB::ReplaceOriginatorIdAndLocate(const BgpAttr *attr,
    1399             :                                                    Ip4Address originator_id) {
    1400           1 :     BgpAttr *clone = new BgpAttr(*attr);
    1401           1 :     clone->set_originator_id(originator_id);
    1402           1 :     return Locate(clone);
    1403             : }
    1404             : 
    1405             : // Return a clone of attribute with updated source rd.
    1406      595219 : BgpAttrPtr BgpAttrDB::ReplaceSourceRdAndLocate(const BgpAttr *attr,
    1407             :     const RouteDistinguisher &source_rd) {
    1408      595219 :     BgpAttr *clone = new BgpAttr(*attr);
    1409      595266 :     clone->set_source_rd(source_rd);
    1410      595254 :     return Locate(clone);
    1411             : }
    1412             : 
    1413             : // Return a clone of attribute with updated esi.
    1414       17817 : BgpAttrPtr BgpAttrDB::ReplaceEsiAndLocate(const BgpAttr *attr,
    1415             :                                           const EthernetSegmentId &esi) {
    1416       17817 :     BgpAttr *clone = new BgpAttr(*attr);
    1417       17817 :     clone->set_esi(esi);
    1418       17817 :     return Locate(clone);
    1419             : }
    1420             : 
    1421             : // Return a clone of attribute with updated olist.
    1422        4886 : BgpAttrPtr BgpAttrDB::ReplaceOListAndLocate(const BgpAttr *attr,
    1423             :     const BgpOListSpec *olist_spec) {
    1424        4886 :     assert(olist_spec->subcode == BgpAttribute::OList);
    1425        4886 :     BgpAttr *clone = new BgpAttr(*attr);
    1426        4886 :     clone->set_olist(olist_spec);
    1427        4886 :     return Locate(clone);
    1428             : }
    1429             : 
    1430             : // Return a clone of attribute with updated leaf olist.
    1431        4731 : BgpAttrPtr BgpAttrDB::ReplaceLeafOListAndLocate(const BgpAttr *attr,
    1432             :     const BgpOListSpec *leaf_olist_spec) {
    1433        4731 :     assert(leaf_olist_spec->subcode == BgpAttribute::LeafOList);
    1434        4731 :     BgpAttr *clone = new BgpAttr(*attr);
    1435        4731 :     clone->set_leaf_olist(leaf_olist_spec);
    1436        4731 :     return Locate(clone);
    1437             : }
    1438             : 
    1439             : // Return a clone of attribute with updated sub-protocol.
    1440        2039 : BgpAttrPtr BgpAttrDB::ReplaceSubProtocolAndLocate(const BgpAttr *attr,
    1441             :     const string &sbp) {
    1442        2039 :     BgpAttr *clone = new BgpAttr(*attr);
    1443        2039 :     clone->set_sub_protocol(sbp);
    1444        2039 :     return Locate(clone);
    1445             : }
    1446             : 
    1447             : 
    1448             : // Return a clone of attribute with updated pmsi tunnel.
    1449        8757 : BgpAttrPtr BgpAttrDB::ReplacePmsiTunnelAndLocate(const BgpAttr *attr,
    1450             :     const PmsiTunnelSpec *pmsi_spec) {
    1451        8757 :     BgpAttr *clone = new BgpAttr(*attr);
    1452        8757 :     clone->set_pmsi_tunnel(pmsi_spec);
    1453        8757 :     return Locate(clone);
    1454             : }
    1455             : 
    1456             : // Return a clone of attribute with updated nexthop.
    1457      339294 : BgpAttrPtr BgpAttrDB::ReplaceNexthopAndLocate(const BgpAttr *attr,
    1458             :     const IpAddress &addr) {
    1459      339294 :     BgpAttr *clone = new BgpAttr(*attr);
    1460      339300 :     clone->set_nexthop(addr);
    1461      339299 :     return Locate(clone);
    1462             : }

Generated by: LCOV version 1.14