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-04 02:06:09 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      184306 : void BgpAttrOrigin::ToCanonical(BgpAttr *attr) {
      29      184306 :     attr->set_origin(static_cast<BgpAttrOrigin::OriginType>(origin));
      30      184306 : }
      31             : 
      32      111181 : string BgpAttrOrigin::ToString() const {
      33             :     char repr[80];
      34      111181 :     snprintf(repr, sizeof(repr), "ORIGIN <code: %d, flags: %02x> : %02x",
      35      111181 :              code, flags, origin);
      36      111181 :     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      191200 : void BgpAttrNextHop::ToCanonical(BgpAttr *attr) {
      48      191200 :     if (v6_nexthop.is_unspecified()) {
      49      188669 :         attr->set_nexthop(Ip4Address(nexthop));
      50             :     } else {
      51        2532 :         attr->set_nexthop(v6_nexthop);
      52             :     }
      53      191200 : }
      54             : 
      55        3012 : string BgpAttrNextHop::ToString() const {
      56             :     char repr[80];
      57        3012 :     snprintf(repr, sizeof(repr), "NEXTHOP <code: %d, flags: %02x> : %04x",
      58        3012 :              code, flags, nexthop);
      59        3012 :     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       76339 : void BgpAttrMultiExitDisc::ToCanonical(BgpAttr *attr) {
      69       76339 :     attr->set_med(med);
      70       76339 : }
      71             : 
      72       51518 : string BgpAttrMultiExitDisc::ToString() const {
      73             :     char repr[80];
      74       51518 :     snprintf(repr, sizeof(repr), "MED <code: %d, flags: %02x> : %d",
      75       51518 :              code, flags, med);
      76       51518 :     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       92234 : void BgpAttrLocalPref::ToCanonical(BgpAttr *attr) {
      87       92234 :     attr->set_local_pref(local_pref);
      88       92234 : }
      89             : 
      90       24031 : string BgpAttrLocalPref::ToString() const {
      91             :     char repr[80];
      92       24031 :     snprintf(repr, sizeof(repr), "LOCAL_PREF <code: %d, flags: %02x> : %d",
      93       24031 :              code, flags, local_pref);
      94       24031 :     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        9743 : ClusterListDB::ClusterListDB(BgpServer *server) {
     244        9743 : }
     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      157947 : void BgpMpNlri::ToCanonical(BgpAttr *attr) {
     264      157947 : }
     265             : 
     266      507216 : size_t BgpMpNlri::EncodeLength() const {
     267      507216 :     size_t sz = 2 /* safi */ + 1 /* afi */ +
     268             :                 1 /* NlriNextHopLength */ +
     269             :                 1 /* Reserved */;
     270      507216 :     sz += nexthop.size();
     271      507219 :     for (vector<BgpProtoPrefix*>::const_iterator iter = nlri.begin();
     272     2858420 :          iter != nlri.end(); ++iter) {
     273     2351214 :         size_t bytes = 0;
     274     2351214 :         if (afi == BgpAf::L2Vpn &&
     275       39794 :             (safi == BgpAf::EVpn || safi == BgpAf::ErmVpn)) {
     276       39794 :             bytes = (*iter)->prefixlen;
     277             :         } else {
     278     2311420 :             bytes = ((*iter)->prefixlen + 7) / 8;
     279             :         }
     280     2351218 :         sz += 1 + bytes;
     281             :     }
     282      507183 :     return sz;
     283             : }
     284             : 
     285       25394 : PmsiTunnelSpec::PmsiTunnelSpec()
     286             :     : BgpAttribute(PmsiTunnel, kFlags),
     287       25394 :       tunnel_flags(0), tunnel_type(0), label(0) {
     288       25393 : }
     289             : 
     290        3008 : PmsiTunnelSpec::PmsiTunnelSpec(const BgpAttribute &rhs)
     291        3008 :     : BgpAttribute(rhs), tunnel_flags(0), tunnel_type(0), label(0) {
     292        3008 : }
     293             : 
     294      473569 : int PmsiTunnelSpec::CompareTo(const BgpAttribute &rhs_attr) const {
     295      473569 :     int ret = BgpAttribute::CompareTo(rhs_attr);
     296      473569 :     if (ret != 0) return ret;
     297      473569 :     const PmsiTunnelSpec &rhs = static_cast<const PmsiTunnelSpec &>(rhs_attr);
     298      473569 :     KEY_COMPARE(tunnel_flags, rhs.tunnel_flags);
     299      461940 :     KEY_COMPARE(tunnel_type, rhs.tunnel_type);
     300      461933 :     KEY_COMPARE(label, rhs.label);
     301      438005 :     KEY_COMPARE(identifier, rhs.identifier);
     302      435287 :     return 0;
     303             : }
     304             : 
     305        8134 : void PmsiTunnelSpec::ToCanonical(BgpAttr *attr) {
     306        8134 :     attr->set_pmsi_tunnel(this);
     307        8134 : }
     308             : 
     309         840 : string PmsiTunnelSpec::ToString() const {
     310         840 :     std::ostringstream oss;
     311         840 :     oss << "PmsiTunnel <code: " << int(code);
     312         840 :     oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
     313         840 :     oss << " Tunnel Flags: 0x" << std::hex << int(tunnel_flags) << std::dec;
     314         840 :     oss << " Tunnel Type: " << int(tunnel_type);
     315         840 :     oss << " Label: 0x" << std::hex << int(label) << std::dec;
     316         840 :     oss << " (" << int(label) << ")";
     317         840 :     oss << " Identifier: " << GetIdentifier().to_string();
     318             : 
     319        1680 :     return oss.str();
     320         840 : }
     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        7749 : void PmsiTunnelSpec::SetLabel(uint32_t in_label, const ExtCommunity *ext) {
     329        7749 :     assert(ext);
     330        7749 :     bool is_vni = ext->ContainsTunnelEncapVxlan();
     331        7749 :     label = (is_vni ? in_label : (in_label << 4 | 0x01));
     332        7749 : }
     333             : 
     334       18768 : Ip4Address PmsiTunnelSpec::GetIdentifier() const {
     335       18768 :     if (identifier.size() < 4)
     336        9826 :         return Ip4Address();
     337        8942 :     return Ip4Address(get_value(&identifier[0], 4));
     338             : }
     339             : 
     340       11692 : void PmsiTunnelSpec::SetIdentifier(Ip4Address in_identifier) {
     341       11692 :     identifier.resize(4, 0);
     342       11692 :     const Ip4Address::bytes_type &bytes = in_identifier.to_bytes();
     343       11692 :     std::copy(bytes.begin(), bytes.begin() + 4, identifier.begin());
     344       11692 : }
     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       17926 : PmsiTunnel::PmsiTunnel(PmsiTunnelDB *pmsi_tunnel_db,
     401       17926 :     const PmsiTunnelSpec &pmsi_spec)
     402       17926 :     : pmsi_tunnel_db_(pmsi_tunnel_db),
     403       17926 :       pmsi_spec_(pmsi_spec) {
     404       17924 :     refcount_ = 0;
     405       17926 :     tunnel_flags_ = pmsi_spec_.tunnel_flags;
     406       17926 :     tunnel_type_ = pmsi_spec_.tunnel_type;
     407       17926 :     label_ = pmsi_spec_.label;
     408       17926 :     identifier_ = pmsi_spec_.GetIdentifier();
     409       17925 : }
     410             : 
     411        4981 : void PmsiTunnel::Remove() {
     412        4981 :     pmsi_tunnel_db_->Delete(this);
     413        4981 : }
     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        9743 : PmsiTunnelDB::PmsiTunnelDB(BgpServer *server) {
     423        9743 : }
     424             : 
     425        5911 : EdgeDiscoverySpec::EdgeDiscoverySpec()
     426        5911 :     : BgpAttribute(McastEdgeDiscovery, kFlags) {
     427        5911 : }
     428             : 
     429        3815 : EdgeDiscoverySpec::EdgeDiscoverySpec(const BgpAttribute &rhs)
     430        3815 :     : BgpAttribute(rhs) {
     431        3815 : }
     432             : 
     433        4161 : EdgeDiscoverySpec::EdgeDiscoverySpec(const EdgeDiscoverySpec &rhs)
     434        4161 :     : BgpAttribute(BgpAttribute::McastEdgeDiscovery, kFlags) {
     435       13561 :     for (size_t i = 0; i < rhs.edge_list.size(); i++) {
     436        9401 :         Edge *edge = new Edge;
     437        9401 :         *edge = *rhs.edge_list[i];
     438        9401 :         edge_list.push_back(edge);
     439             :     }
     440        4160 : }
     441             : 
     442       22736 : EdgeDiscoverySpec::~EdgeDiscoverySpec() {
     443       13882 :     STLDeleteValues(&edge_list);
     444       22715 : }
     445             : 
     446        9912 : Ip4Address EdgeDiscoverySpec::Edge::GetIp4Address() const {
     447        9912 :     return Ip4Address(get_value(&address[0], 4));
     448             : }
     449             : 
     450      130457 : void EdgeDiscoverySpec::Edge::SetIp4Address(Ip4Address addr) {
     451      130457 :     address.resize(4, 0);
     452      130457 :     const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
     453      130457 :     std::copy(addr_bytes.begin(), addr_bytes.begin() + 4, address.begin());
     454      130457 : }
     455             : 
     456        9912 : void EdgeDiscoverySpec::Edge::GetLabels(
     457             :     uint32_t *first_label, uint32_t *last_label) const {
     458        9912 :     *first_label = labels[0];
     459        9912 :     *last_label = labels[1];
     460        9912 : }
     461             : 
     462      130457 : void EdgeDiscoverySpec::Edge::SetLabels(
     463             :     uint32_t first_label, uint32_t last_label) {
     464      130457 :     labels.push_back(first_label);
     465      130457 :     labels.push_back(last_label);
     466      130457 : }
     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        2082 : void EdgeDiscoverySpec::ToCanonical(BgpAttr *attr) {
     489        2082 :     attr->set_edge_discovery(this);
     490        2082 : }
     491             : 
     492        1208 : string EdgeDiscoverySpec::ToString() const {
     493        1208 :     std::ostringstream oss;
     494        1208 :     oss << "EdgeDiscovery <code: " << int(code);
     495        1208 :     oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
     496        1208 :     int idx = 0;
     497        1208 :     for (EdgeList::const_iterator it = edge_list.begin();
     498        4828 :          it != edge_list.end(); ++it, ++idx) {
     499        3620 :         const Edge *edge = *it;
     500             :         uint32_t first_label, last_label;
     501        3620 :         edge->GetLabels(&first_label, &last_label);
     502        3620 :         oss << " Edge[" << idx << "] = (" << edge->GetIp4Address() << ", ";
     503        3620 :         oss << first_label << "-" << last_label << ")";
     504             :     }
     505             : 
     506        2416 :     return oss.str();
     507        1208 : }
     508             : 
     509       13923 : size_t EdgeDiscoverySpec::EncodeLength() const {
     510       13923 :     size_t sz = 0;
     511       13923 :     for (EdgeList::const_iterator iter = edge_list.begin();
     512      276650 :          iter != edge_list.end(); ++iter) {
     513      262727 :         sz += 2; /* AddressLen + LabelLen */
     514      262727 :         sz += (*iter)->address.size();
     515      262727 :         sz += (*iter)->labels.size() * sizeof(uint32_t);
     516             :     }
     517       13923 :     return sz;
     518             : }
     519             : 
     520        6264 : EdgeDiscovery::Edge::Edge(const EdgeDiscoverySpec::Edge *spec_edge) {
     521        6264 :     address = spec_edge->GetIp4Address();
     522             :     uint32_t first_label, last_label;
     523        6264 :     spec_edge->GetLabels(&first_label, &last_label);
     524        6264 :     label_block = new LabelBlock(first_label, last_label);
     525        6264 : }
     526             : 
     527       54256 : bool EdgeDiscovery::Edge::operator<(const Edge &rhs) const {
     528       54256 :     BOOL_KEY_COMPARE(address, rhs.address);
     529       47288 :     BOOL_KEY_COMPARE(label_block->first(), rhs.label_block->first());
     530       41711 :     BOOL_KEY_COMPARE(label_block->last(), rhs.label_block->last());
     531       41711 :     return false;
     532             : }
     533             : 
     534        3116 : EdgeDiscovery::EdgeDiscovery(EdgeDiscoveryDB *edge_discovery_db,
     535        3116 :     const EdgeDiscoverySpec &edspec)
     536        3116 :     : edge_discovery_db_(edge_discovery_db),
     537        3116 :       edspec_(edspec) {
     538        3114 :     refcount_ = 0;
     539        3115 :     for (EdgeDiscoverySpec::EdgeList::const_iterator it =
     540        9378 :          edspec_.edge_list.begin(); it != edspec_.edge_list.end(); ++it) {
     541        6263 :         Edge *edge = new Edge(*it);
     542        6264 :         edge_list.push_back(edge);
     543             :     }
     544        3112 :     sort(edge_list.begin(), edge_list.end(), EdgeDiscovery::EdgeCompare());
     545        3113 : }
     546             : 
     547        5210 : EdgeDiscovery::~EdgeDiscovery() {
     548        3117 :     STLDeleteValues(&edge_list);
     549        5210 : }
     550             : 
     551             : struct EdgeDiscoveryEdgeCompare {
     552       21464 :     int operator()(const EdgeDiscovery::Edge *lhs,
     553             :                    const EdgeDiscovery::Edge *rhs) const {
     554       21464 :         KEY_COMPARE(*lhs, *rhs);
     555       12544 :         return 0;
     556             :     }
     557             : };
     558             : 
     559      363788 : int EdgeDiscovery::CompareTo(const EdgeDiscovery &rhs) const {
     560      363788 :     int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
     561             :                                   rhs.edge_list.begin(), rhs.edge_list.end(),
     562             :                                   EdgeDiscoveryEdgeCompare());
     563      363789 :     return result;
     564             : }
     565             : 
     566        1823 : void EdgeDiscovery::Remove() {
     567        1823 :     edge_discovery_db_->Delete(this);
     568        1823 : }
     569             : 
     570        9743 : EdgeDiscoveryDB::EdgeDiscoveryDB(BgpServer *server) {
     571        9743 : }
     572             : 
     573        6396 : EdgeForwardingSpec::EdgeForwardingSpec()
     574        6396 :     : BgpAttribute(McastEdgeForwarding, kFlags) {
     575        6395 : }
     576             : 
     577        4647 : EdgeForwardingSpec::EdgeForwardingSpec(const BgpAttribute &rhs)
     578        4647 :     : BgpAttribute(rhs) {
     579        4647 : }
     580             : 
     581        6292 : EdgeForwardingSpec::EdgeForwardingSpec(const EdgeForwardingSpec &rhs)
     582        6292 :     : BgpAttribute(BgpAttribute::McastEdgeForwarding, kFlags) {
     583       11512 :     for (size_t i = 0; i < rhs.edge_list.size(); i++) {
     584        5222 :         Edge *edge = new Edge;
     585        5222 :         *edge = *rhs.edge_list[i];
     586        5222 :         edge_list.push_back(edge);
     587             :     }
     588        6290 : }
     589             : 
     590       27745 : EdgeForwardingSpec:: ~EdgeForwardingSpec() {
     591       17320 :     STLDeleteValues(&edge_list);
     592       27716 : }
     593             : 
     594        5588 : Ip4Address EdgeForwardingSpec::Edge::GetInboundIp4Address() const {
     595        5588 :     return Ip4Address(get_value(&inbound_address[0], 4));
     596             : }
     597             : 
     598        5588 : Ip4Address EdgeForwardingSpec::Edge::GetOutboundIp4Address() const {
     599        5588 :     return Ip4Address(get_value(&outbound_address[0], 4));
     600             : }
     601             : 
     602      126191 : void EdgeForwardingSpec::Edge::SetInboundIp4Address(Ip4Address addr) {
     603      126191 :     inbound_address.resize(4, 0);
     604      126191 :     const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
     605      126191 :     std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
     606             :         inbound_address.begin());
     607      126191 : }
     608             : 
     609      126191 : void EdgeForwardingSpec::Edge::SetOutboundIp4Address(Ip4Address addr) {
     610      126191 :     outbound_address.resize(4, 0);
     611      126191 :     const Ip4Address::bytes_type &addr_bytes = addr.to_bytes();
     612      126191 :     std::copy(addr_bytes.begin(), addr_bytes.begin() + 4,
     613             :         outbound_address.begin());
     614      126191 : }
     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        3464 : void EdgeForwardingSpec::ToCanonical(BgpAttr *attr) {
     639        3464 :     attr->set_edge_forwarding(this);
     640        3464 : }
     641             : 
     642        2096 : string EdgeForwardingSpec::ToString() const {
     643        2096 :     std::ostringstream oss;
     644        2096 :     oss << "EdgeForwarding <code: " << int(code);
     645        2096 :     oss << ", flags: 0x" << std::hex << int(flags) << std::dec << ">";
     646        2096 :     int idx = 0;
     647        2096 :     for (EdgeList::const_iterator it = edge_list.begin();
     648        4375 :          it != edge_list.end(); ++it, ++idx) {
     649        2279 :         const Edge *edge = *it;
     650        2279 :         oss << " Edge[" << idx << "] = (";
     651        2279 :         oss << "InAddress=" << edge->GetInboundIp4Address() << ", ";
     652        2279 :         oss << "InLabel=" << edge->inbound_label << ", ";
     653        2279 :         oss << "OutAddress=" << edge->GetOutboundIp4Address() << ", ";
     654        2279 :         oss << "OutLabel=" << edge->outbound_label << ")";
     655             :     }
     656             : 
     657        4192 :     return oss.str();
     658        2096 : }
     659             : 
     660       16231 : size_t EdgeForwardingSpec::EncodeLength() const {
     661       16231 :     size_t sz = 0;
     662       16231 :     for (EdgeList::const_iterator iter = edge_list.begin();
     663      271384 :          iter != edge_list.end(); ++iter) {
     664      255153 :         sz += 1 /* address len */ + 8 /* 2 labels */;
     665      255153 :         sz += (*iter)->inbound_address.size();
     666      255153 :         sz += (*iter)->outbound_address.size();
     667             :     }
     668             : 
     669       16231 :     return sz;
     670             : }
     671             : 
     672        3305 : EdgeForwarding::Edge::Edge(const EdgeForwardingSpec::Edge *spec_edge) {
     673        3305 :     inbound_address = spec_edge->GetInboundIp4Address();
     674        3305 :     outbound_address = spec_edge->GetOutboundIp4Address();
     675        3305 :     inbound_label = spec_edge->inbound_label;
     676        3305 :     outbound_label = spec_edge->outbound_label;
     677        3305 : }
     678             : 
     679       33500 : bool EdgeForwarding::Edge::operator<(const Edge &rhs) const {
     680       33500 :     BOOL_KEY_COMPARE(inbound_address, rhs.inbound_address);
     681       23451 :     BOOL_KEY_COMPARE(outbound_address, rhs.outbound_address);
     682       18678 :     BOOL_KEY_COMPARE(inbound_label, rhs.inbound_label);
     683       16507 :     BOOL_KEY_COMPARE(outbound_label, rhs.outbound_label);
     684       14113 :     return false;
     685             : }
     686             : 
     687        4499 : EdgeForwarding::EdgeForwarding(EdgeForwardingDB *edge_forwarding_db,
     688        4499 :     const EdgeForwardingSpec &efspec)
     689        4498 :     : edge_forwarding_db_(edge_forwarding_db),
     690        4499 :       efspec_(efspec) {
     691        4495 :     refcount_ = 0;
     692        4499 :     for (EdgeForwardingSpec::EdgeList::const_iterator it =
     693        7804 :          efspec_.edge_list.begin(); it != efspec_.edge_list.end(); ++it) {
     694        3305 :         Edge *edge = new Edge(*it);
     695        3305 :         edge_list.push_back(edge);
     696             :     }
     697        4494 :     sort(edge_list.begin(), edge_list.end(), EdgeForwarding::EdgeCompare());
     698        4493 : }
     699             : 
     700        7976 : EdgeForwarding::~EdgeForwarding() {
     701        4500 :     STLDeleteValues(&edge_list);
     702        7976 : }
     703             : 
     704             : struct EdgeForwardingEdgeCompare {
     705       19047 :     int operator()(const EdgeForwarding::Edge *lhs,
     706             :                    const EdgeForwarding::Edge *rhs) const {
     707       19047 :         KEY_COMPARE(*lhs, *rhs);
     708        7057 :         return 0;
     709             :     }
     710             : };
     711             : 
     712     1319548 : int EdgeForwarding::CompareTo(const EdgeForwarding &rhs) const {
     713     1319548 :     int result = STLSortedCompare(edge_list.begin(), edge_list.end(),
     714             :                                   rhs.edge_list.begin(), rhs.edge_list.end(),
     715             :                                   EdgeForwardingEdgeCompare());
     716     1319547 :     return result;
     717             : }
     718             : 
     719        2348 : void EdgeForwarding::Remove() {
     720        2348 :     edge_forwarding_db_->Delete(this);
     721        2348 : }
     722             : 
     723        9743 : EdgeForwardingDB::EdgeForwardingDB(BgpServer *server) {
     724        9743 : }
     725             : 
     726      196057 : bool BgpOListElem::operator<(const BgpOListElem &rhs) const {
     727      196057 :     BOOL_KEY_COMPARE(address, rhs.address);
     728      128971 :     BOOL_KEY_COMPARE(label, rhs.label);
     729      124920 :     BOOL_KEY_COMPARE(encap, rhs.encap);
     730      124914 :     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        3604 : void BgpOListSpec::ToCanonical(BgpAttr *attr) {
     740        3604 :     if (subcode == BgpAttribute::OList) {
     741        3604 :         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        3604 : }
     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       13905 : BgpOList::BgpOList(BgpOListDB *olist_db, const BgpOListSpec &olist_spec)
     771       13905 :     : olist_db_(olist_db),
     772       13905 :       olist_spec_(olist_spec) {
     773       13905 :     refcount_ = 0;
     774       13905 :     for (BgpOListSpec::Elements::const_iterator it =
     775       36711 :          olist_spec_.elements.begin(); it != olist_spec_.elements.end(); ++it) {
     776       22806 :         BgpOListElem *elem = new BgpOListElem(*it);
     777       22806 :         sort(elem->encap.begin(), elem->encap.end());
     778       22806 :         elements_.push_back(elem);
     779             :     }
     780       13905 :     sort(elements_.begin(), elements_.end(), BgpOListElemCompare());
     781       13904 : }
     782             : 
     783       26786 : BgpOList::~BgpOList() {
     784       13905 :     STLDeleteValues(&elements_);
     785       26786 : }
     786             : 
     787             : struct BgpOListElementCompare {
     788       76726 :     int operator()(const BgpOListElem *lhs, const BgpOListElem *rhs) const {
     789       76726 :         KEY_COMPARE(*lhs, *rhs);
     790       62457 :         return 0;
     791             :     }
     792             : };
     793             : 
     794     1123216 : int BgpOList::CompareTo(const BgpOList &rhs) const {
     795     1123216 :     KEY_COMPARE(olist().subcode, rhs.olist().subcode);
     796     2216864 :     int result = STLSortedCompare(elements().begin(), elements().end(),
     797     2216864 :                                   rhs.elements().begin(), rhs.elements().end(),
     798             :                                   BgpOListElementCompare());
     799     1108432 :     return result;
     800             : }
     801             : 
     802        9642 : void BgpOList::Remove() {
     803        9642 :     olist_db_->Delete(this);
     804        9642 : }
     805             : 
     806        9743 : BgpOListDB::BgpOListDB(BgpServer *server) {
     807        9743 : }
     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       28626 : void BgpAttrSourceRd::ToCanonical(BgpAttr *attr) {
     837       28626 :     attr->set_source_rd(source_rd);
     838       28626 : }
     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       21982 : void BgpAttrSubProtocol::ToCanonical(BgpAttr *attr) {
     891       21982 :     attr->set_sub_protocol(sbp);
     892       21982 : }
     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      388747 : BgpAttr::BgpAttr(BgpAttrDB *attr_db, const BgpAttrSpec &spec)
     916      388747 :     : attr_db_(attr_db), origin_(BgpAttrOrigin::INCOMPLETE),
     917      777493 :       nexthop_(), med_(0),
     918      388746 :       local_pref_(BgpAttrLocalPref::kDefault),
     919      388746 :       atomic_aggregate_(false),
     920      388746 :       aggregator_as_num_(0), aggregator_as4_num_(0), 
     921      388747 :       aggregator_address_(), params_(0) {
     922      388741 :     refcount_ = 0;
     923      388750 :     for (vector<BgpAttribute *>::const_iterator it = spec.begin();
     924     1465579 :          it < spec.end(); it++) {
     925     1076846 :         (*it)->ToCanonical(this);
     926             :     }
     927      388742 : }
     928             : 
     929     3025164 : BgpAttr::BgpAttr(const BgpAttr &rhs)
     930     3025164 :     : attr_db_(rhs.attr_db_), origin_(rhs.origin_), nexthop_(rhs.nexthop_),
     931     3024804 :       med_(rhs.med_), local_pref_(rhs.local_pref_),
     932     3024804 :       atomic_aggregate_(rhs.atomic_aggregate_),
     933     3024804 :       aggregator_as_num_(rhs.aggregator_as_num_),
     934     3024804 :       aggregator_as4_num_(rhs.aggregator_as4_num_),
     935     3024804 :       aggregator_address_(rhs.aggregator_address_),
     936     3024624 :       originator_id_(rhs.originator_id_),
     937     3024544 :       source_rd_(rhs.source_rd_), esi_(rhs.esi_), params_(rhs.params_),
     938     3024454 :       as_path_(rhs.as_path_),
     939     3025161 :       aspath_4byte_(rhs.aspath_4byte_),
     940     3025055 :       as4_path_(rhs.as4_path_),
     941     3024869 :       cluster_list_(rhs.cluster_list_),
     942     3024775 :       community_(rhs.community_),
     943     3024704 :       ext_community_(rhs.ext_community_),
     944     3025691 :       large_community_(rhs.large_community_),
     945     3025257 :       deferred_large_spec_(nullptr),
     946     3024571 :       origin_vn_path_(rhs.origin_vn_path_),
     947     3024492 :       pmsi_tunnel_(rhs.pmsi_tunnel_),
     948     3024363 :       edge_discovery_(rhs.edge_discovery_),
     949     3024224 :       edge_forwarding_(rhs.edge_forwarding_),
     950     3024142 :       label_block_(rhs.label_block_),
     951     3024083 :       olist_(rhs.olist_),
     952     3023978 :       leaf_olist_(rhs.leaf_olist_),
     953     6049068 :       sub_protocol_(rhs.sub_protocol_) {
     954     3023663 :     refcount_ = 0;
     955     3025774 : }
     956             : 
     957       19101 : void BgpAttr::set_as_path(AsPathPtr aspath) {
     958       19101 :     as_path_ = aspath;
     959       19101 : }
     960             : 
     961      362266 : void BgpAttr::set_as_path(const AsPathSpec *spec) {
     962      362266 :     if (spec) {
     963      362134 :         as_path_ = attr_db_->server()->aspath_db()->Locate(*spec);
     964             :     } else {
     965         132 :         as_path_ = NULL;
     966             :     }
     967      362316 : }
     968             : 
     969           0 : void BgpAttr::set_as4_path(As4PathPtr aspath) {
     970           0 :     as4_path_ = aspath;
     971           0 : }
     972             : 
     973         484 : void BgpAttr::set_as4_path(const As4PathSpec *spec) {
     974         484 :     if (spec) {
     975         450 :         as4_path_ = attr_db_->server()->as4path_db()->Locate(*spec);
     976             :     } else {
     977          34 :         as4_path_ = NULL;
     978             :     }
     979         484 : }
     980             : 
     981           0 : void BgpAttr::set_aspath_4byte(AsPath4BytePtr aspath) {
     982           0 :     aspath_4byte_ = aspath;
     983           0 : }
     984             : 
     985         536 : void BgpAttr::set_aspath_4byte(const AsPath4ByteSpec *spec) {
     986         536 :     if (spec) {
     987         479 :         aspath_4byte_ = attr_db_->server()->aspath_4byte_db()->Locate(*spec);
     988             :     } else {
     989          57 :         aspath_4byte_ = NULL;
     990             :     }
     991         536 : }
     992             : 
     993      203549 : void BgpAttr::set_cluster_list(const ClusterListSpec *spec) {
     994      203549 :     if (spec) {
     995          18 :         cluster_list_ = attr_db_->server()->cluster_list_db()->Locate(*spec);
     996             :     } else {
     997      203531 :         cluster_list_ = NULL;
     998             :     }
     999      203545 : }
    1000             : 
    1001       25228 : void BgpAttr::set_community(CommunityPtr comm) {
    1002       25228 :     community_ = comm;
    1003       25228 : }
    1004             : 
    1005        4363 : void BgpAttr::set_community(const CommunitySpec *comm) {
    1006        4363 :     if (comm) {
    1007        4363 :         community_ = attr_db_->server()->comm_db()->Locate(*comm);
    1008             :     } else {
    1009           0 :         community_ = NULL;
    1010             :     }
    1011        4363 : }
    1012             : 
    1013     1006880 : void BgpAttr::set_ext_community(ExtCommunityPtr extcomm) {
    1014     1006880 :     ext_community_ = extcomm;
    1015     1006900 : }
    1016             : 
    1017      183366 : void BgpAttr::set_ext_community(const ExtCommunitySpec *extcomm) {
    1018      183366 :     if (extcomm) {
    1019      183366 :         LargeCommunitySpec large_spec = LargeCommunitySpec::FromTag(*extcomm);
    1020      183365 :         set_large_community(&large_spec);
    1021             :         
    1022      183366 :         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      183362 :         ext_community_ = attr_db_->server()->extcomm_db()->Locate(*extcomm);
    1030      183370 :     } else {
    1031           0 :         ext_community_ = NULL;
    1032             :     }
    1033             : }
    1034             : 
    1035       18798 : void BgpAttr::set_large_community(LargeCommunityPtr largecomm) {
    1036       18798 :     large_community_ = largecomm;
    1037       18798 : }
    1038             : 
    1039      183407 : void BgpAttr::set_large_community(const LargeCommunitySpec *largecomm) {
    1040      183407 :     if (largecomm) {
    1041      183409 :         if (!bool(deferred_large_spec_)) {
    1042      183364 :             deferred_large_spec_.reset(new LargeCommunitySpec);
    1043      183364 :             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      183409 :             attr_db_->server()->largecomm_db()->Locate(*deferred_large_spec_);
    1052             :     } else {
    1053           0 :         large_community_ = NULL;
    1054             :     }
    1055      183410 : }
    1056             : 
    1057       18799 : void BgpAttr::set_origin_vn_path(OriginVnPathPtr ovnpath) {
    1058       18799 :     origin_vn_path_ = ovnpath;
    1059       18799 : }
    1060             : 
    1061         760 : void BgpAttr::set_origin_vn_path(const OriginVnPathSpec *spec) {
    1062         760 :     if (spec) {
    1063         760 :         origin_vn_path_ = attr_db_->server()->ovnpath_db()->Locate(*spec);
    1064             :     } else {
    1065           0 :         origin_vn_path_ = NULL;
    1066             :     }
    1067         760 : }
    1068             : 
    1069       16892 : void BgpAttr::set_pmsi_tunnel(const PmsiTunnelSpec *pmsi_spec) {
    1070       16892 :     if (pmsi_spec) {
    1071       16892 :         pmsi_tunnel_ = attr_db_->server()->pmsi_tunnel_db()->Locate(*pmsi_spec);
    1072             :     } else {
    1073           0 :         pmsi_tunnel_ = NULL;
    1074             :     }
    1075       16892 : }
    1076             : 
    1077        2083 : void BgpAttr::set_edge_discovery(const EdgeDiscoverySpec *edspec) {
    1078        2083 :     if (edspec) {
    1079             :         edge_discovery_ =
    1080        2083 :             attr_db_->server()->edge_discovery_db()->Locate(*edspec);
    1081             :     } else {
    1082           0 :         edge_discovery_ = NULL;
    1083             :     }
    1084        2083 : }
    1085             : 
    1086        3466 : void BgpAttr::set_edge_forwarding(const EdgeForwardingSpec *efspec) {
    1087        3466 :     if (efspec) {
    1088             :         edge_forwarding_ =
    1089        3466 :             attr_db_->server()->edge_forwarding_db()->Locate(*efspec);
    1090             :     } else {
    1091           0 :         edge_forwarding_ = NULL;
    1092             :     }
    1093        3466 : }
    1094             : 
    1095        1034 : void BgpAttr::set_label_block(LabelBlockPtr label_block) {
    1096        1034 :     label_block_ = label_block;
    1097        1033 : }
    1098             : 
    1099        8310 : void BgpAttr::set_olist(const BgpOListSpec *olist_spec) {
    1100        8310 :     if (olist_spec) {
    1101        8310 :         olist_ = attr_db_->server()->olist_db()->Locate(*olist_spec);
    1102             :     } else {
    1103           0 :         olist_ = NULL;
    1104             :     }
    1105        8310 : }
    1106             : 
    1107        4551 : void BgpAttr::set_leaf_olist(const BgpOListSpec *leaf_olist_spec) {
    1108        4551 :     if (leaf_olist_spec) {
    1109        4551 :         leaf_olist_ = attr_db_->server()->olist_db()->Locate(*leaf_olist_spec);
    1110             :     } else {
    1111           0 :         leaf_olist_ = NULL;
    1112             :     }
    1113        4551 : }
    1114             : 
    1115     9330558 : int BgpAttr::max_as_path_count() const {
    1116     9330558 :     int as_count = as_path_count();
    1117     9330561 :     int as4_count = aspath_4byte_count();
    1118     9330562 :     return as_count > as4_count ? as_count : as4_count;
    1119             : }
    1120             : 
    1121       99418 : bool BgpAttr::IsAsPathEmpty() const {
    1122       99418 :     if (as_path_ && !as_path_->empty())
    1123         332 :         return false;
    1124       99089 :     if (aspath_4byte_ && !aspath_4byte_->empty())
    1125          86 :         return false;
    1126       99003 :     return true;
    1127             : }
    1128             : 
    1129        5613 : string BgpAttr::OriginToString(BgpAttrOrigin::OriginType origin) {
    1130        5613 :     switch (origin) {
    1131        5253 :     case BgpAttrOrigin::IGP:
    1132        5253 :         return "igp";
    1133             :         break;
    1134           3 :     case BgpAttrOrigin::EGP:
    1135           3 :         return "egp";
    1136             :         break;
    1137         356 :     case BgpAttrOrigin::INCOMPLETE:
    1138         356 :         return "incomplete";
    1139             :         break;
    1140             :     }
    1141           1 :     return "unknown";
    1142             : }
    1143             : 
    1144       20424 : BgpAttrOrigin::OriginType BgpAttr::OriginFromString(
    1145             :         const string &bgp_origin_type) {
    1146       20424 :     if(bgp_origin_type ==  "IGP"){
    1147       20421 :         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        5611 : string BgpAttr::origin_string() const {
    1155        5611 :     return OriginToString(origin());
    1156             : }
    1157             : 
    1158        2910 : Address::Family BgpAttr::nexthop_family() const {
    1159        2910 :     if (nexthop_.is_v6()) {
    1160         325 :         return Address::INET6;
    1161             :     } else {
    1162        2585 :         return Address::INET;
    1163             :     }
    1164             : }
    1165             : 
    1166     2654919 : as_t BgpAttr::neighbor_as() const {
    1167     2654919 :     if (as_path_.get())
    1168      496044 :         return as_path_->neighbor_as();
    1169     2158865 :     if (aspath_4byte_.get())
    1170         219 :         return aspath_4byte_->neighbor_as();
    1171     2158651 :     return 0;
    1172             : }
    1173             : 
    1174     9423523 : uint32_t BgpAttr::sequence_number() const {
    1175     9423523 :     if (!ext_community_)
    1176     1136345 :         return 0;
    1177     8287186 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1178     8287186 :          ext_community_->communities().begin();
    1179    28924164 :          it != ext_community_->communities().end(); ++it) {
    1180    20641074 :         if (ExtCommunity::is_mac_mobility(*it)) {
    1181        4325 :             MacMobility mm(*it);
    1182        4325 :             return mm.sequence_number();
    1183             :         }
    1184             :     }
    1185     8282754 :     return 0;
    1186             : }
    1187             : 
    1188     4711827 : bool BgpAttr::evpn_sticky_mac() const {
    1189     4711827 :     if (!ext_community_)
    1190      568175 :         return 0;
    1191     4143650 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1192     4143668 :          ext_community_->communities().begin();
    1193    14462889 :          it != ext_community_->communities().end(); ++it) {
    1194    10321386 :         if (ExtCommunity::is_mac_mobility(*it)) {
    1195        2182 :             MacMobility mm(*it);
    1196        2182 :             return mm.sticky();
    1197             :         }
    1198             :     }
    1199     4141463 :     return 0;
    1200             : }
    1201             : 
    1202     4711869 : bool BgpAttr::etree_leaf() const {
    1203     4711869 :     if (!ext_community_)
    1204      568176 :         return 0;
    1205     4143695 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1206     4143696 :          ext_community_->communities().begin();
    1207    14317949 :          it != ext_community_->communities().end(); ++it) {
    1208    10247793 :         if (ExtCommunity::is_etree(*it)) {
    1209       73558 :             ETree etree(*it);
    1210       73559 :             return etree.leaf();
    1211             :         }
    1212             :     }
    1213     4070079 :     return 0;
    1214             : }
    1215             : 
    1216          59 : bool BgpAttr::evpn_single_active() const {
    1217          59 :     if (!ext_community_)
    1218           0 :         return false;
    1219          59 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1220          59 :          ext_community_->communities().begin();
    1221         118 :          it != ext_community_->communities().end(); ++it) {
    1222         118 :         if (ExtCommunity::is_esi_label(*it)) {
    1223          59 :             EsiLabel esi_label(*it);
    1224          59 :             return esi_label.single_active();
    1225             :         }
    1226             :     }
    1227           0 :     return true;
    1228             : }
    1229             : 
    1230      463184 : MacAddress BgpAttr::mac_address() const {
    1231      463184 :     if (!ext_community_)
    1232       13766 :         return MacAddress::kZeroMac;
    1233      449390 :     for (ExtCommunity::ExtCommunityList::const_iterator it =
    1234      449407 :          ext_community_->communities().begin();
    1235     3174479 :          it != ext_community_->communities().end(); ++it) {
    1236     2725032 :         if (ExtCommunity::is_router_mac(*it)) {
    1237          22 :             RouterMac router_mac(*it);
    1238          22 :             return router_mac.mac_address();
    1239             :         }
    1240             :     }
    1241      449283 :     return MacAddress::kZeroMac;
    1242             : }
    1243             : 
    1244      438716 : void BgpAttr::Remove() {
    1245      438716 :     attr_db_->Delete(this);
    1246      438721 : }
    1247             : 
    1248      451905 : int BgpAttr::IsAsPathLoop(as_t asn, uint8_t max_loop_count) const {
    1249      451905 :     if (as_path() && as_path()->path().AsPathLoop(asn, max_loop_count)) {
    1250      137337 :         return true;
    1251             :     }
    1252      314906 :     if (aspath_4byte() &&
    1253         192 :            aspath_4byte()->path().AsPathLoop(asn, max_loop_count)) {
    1254          51 :         return true;
    1255             :     }
    1256      314680 :     if (asn > AS2_MAX && as4_path() &&
    1257          20 :            as4_path()->path().AsPathLoop(asn, max_loop_count)) {
    1258           4 :         return true;
    1259             :     }
    1260      314656 :     return false;
    1261             : }
    1262             : 
    1263    25731102 : int BgpAttr::CompareTo(const BgpAttr &rhs) const {
    1264    25731102 :     KEY_COMPARE(origin_, rhs.origin_);
    1265    23968870 :     KEY_COMPARE(nexthop_, rhs.nexthop_);
    1266    16097645 :     KEY_COMPARE(med_, rhs.med_);
    1267    15334508 :     KEY_COMPARE(local_pref_, rhs.local_pref_);
    1268    14932109 :     KEY_COMPARE(atomic_aggregate_, rhs.atomic_aggregate_);
    1269    14932109 :     KEY_COMPARE(aggregator_as_num_, rhs.aggregator_as_num_);
    1270    14931917 :     KEY_COMPARE(aggregator_as4_num_, rhs.aggregator_as4_num_);
    1271    14931789 :     KEY_COMPARE(aggregator_address_, rhs.aggregator_address_);
    1272    14935219 :     KEY_COMPARE(originator_id_, rhs.originator_id_);
    1273    14933699 :     KEY_COMPARE(pmsi_tunnel_.get(), rhs.pmsi_tunnel_.get());
    1274    14578422 :     KEY_COMPARE(edge_discovery_.get(), rhs.edge_discovery_.get());
    1275    14516261 :     KEY_COMPARE(edge_forwarding_.get(), rhs.edge_forwarding_.get());
    1276    14452362 :     KEY_COMPARE(esi_, rhs.esi_);
    1277    14452226 :     KEY_COMPARE(params_, rhs.params_);
    1278    14452221 :     KEY_COMPARE(source_rd_, rhs.source_rd_);
    1279    10456335 :     KEY_COMPARE(label_block_.get(), rhs.label_block_.get());
    1280    10458353 :     KEY_COMPARE(olist_.get(), rhs.olist_.get());
    1281    10400676 :     KEY_COMPARE(leaf_olist_.get(), rhs.leaf_olist_.get());
    1282    10381263 :     KEY_COMPARE(as_path_.get(), rhs.as_path_.get());
    1283    10083507 :     KEY_COMPARE(aspath_4byte_.get(), rhs.aspath_4byte_.get());
    1284    10082550 :     KEY_COMPARE(as4_path_.get(), rhs.as4_path_.get());
    1285    10081575 :     KEY_COMPARE(cluster_list_.get(), rhs.cluster_list_.get());
    1286    10081547 :     KEY_COMPARE(community_.get(), rhs.community_.get());
    1287     9827615 :     KEY_COMPARE(ext_community_.get(), rhs.ext_community_.get());
    1288     7349783 :     KEY_COMPARE(large_community_.get(), rhs.large_community_.get());
    1289     7335080 :     KEY_COMPARE(origin_vn_path_.get(), rhs.origin_vn_path_.get());
    1290     7259126 :     KEY_COMPARE(sub_protocol_, rhs.sub_protocol_);
    1291     7243239 :     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        9743 : BgpAttrDB::BgpAttrDB(BgpServer *server) : server_(server) {
    1339        9743 : }
    1340             : 
    1341             : // Return a clone of attribute with updated aspath.
    1342       19101 : BgpAttrPtr BgpAttrDB::ReplaceAsPathAndLocate(const BgpAttr *attr,
    1343             :                                              AsPathPtr aspath) {
    1344       19101 :     BgpAttr *clone = new BgpAttr(*attr);
    1345       19101 :     clone->set_as_path(aspath);
    1346       19101 :     return Locate(clone);
    1347             : }
    1348             : 
    1349             : // Return a clone of attribute with updated community.
    1350       19131 : BgpAttrPtr BgpAttrDB::ReplaceCommunityAndLocate(const BgpAttr *attr,
    1351             :                                                 CommunityPtr community) {
    1352       19131 :     BgpAttr *clone = new BgpAttr(*attr);
    1353       19131 :     clone->set_community(community);
    1354       19131 :     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     1006861 : BgpAttrPtr BgpAttrDB::ReplaceExtCommunityAndLocate(const BgpAttr *attr,
    1367             :                                                    ExtCommunityPtr extcomm) {
    1368     1006861 :     BgpAttr *clone = new BgpAttr(*attr);
    1369     1006901 :     clone->set_ext_community(extcomm);
    1370     1006879 :     return Locate(clone);
    1371             : }
    1372             : 
    1373             : // Return a clone of attribute with updated large community.
    1374       18798 : BgpAttrPtr BgpAttrDB::ReplaceLargeCommunityAndLocate(
    1375             :     const BgpAttr *attr, LargeCommunityPtr largecomm) {
    1376       18798 :     BgpAttr *clone = new BgpAttr(*attr);
    1377       18798 :     clone->set_large_community(largecomm);
    1378       18798 :     return Locate(clone);
    1379             : }
    1380             : 
    1381             : // Return a clone of attribute with updated origin vn path.
    1382       18799 : BgpAttrPtr BgpAttrDB::ReplaceOriginVnPathAndLocate(const BgpAttr *attr,
    1383             :                                                    OriginVnPathPtr ovnpath) {
    1384       18799 :     BgpAttr *clone = new BgpAttr(*attr);
    1385       18799 :     clone->set_origin_vn_path(ovnpath);
    1386       18799 :     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      605950 : BgpAttrPtr BgpAttrDB::ReplaceSourceRdAndLocate(const BgpAttr *attr,
    1407             :     const RouteDistinguisher &source_rd) {
    1408      605950 :     BgpAttr *clone = new BgpAttr(*attr);
    1409      605986 :     clone->set_source_rd(source_rd);
    1410      605971 :     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        4706 : BgpAttrPtr BgpAttrDB::ReplaceOListAndLocate(const BgpAttr *attr,
    1423             :     const BgpOListSpec *olist_spec) {
    1424        4706 :     assert(olist_spec->subcode == BgpAttribute::OList);
    1425        4706 :     BgpAttr *clone = new BgpAttr(*attr);
    1426        4706 :     clone->set_olist(olist_spec);
    1427        4706 :     return Locate(clone);
    1428             : }
    1429             : 
    1430             : // Return a clone of attribute with updated leaf olist.
    1431        4551 : BgpAttrPtr BgpAttrDB::ReplaceLeafOListAndLocate(const BgpAttr *attr,
    1432             :     const BgpOListSpec *leaf_olist_spec) {
    1433        4551 :     assert(leaf_olist_spec->subcode == BgpAttribute::LeafOList);
    1434        4551 :     BgpAttr *clone = new BgpAttr(*attr);
    1435        4551 :     clone->set_leaf_olist(leaf_olist_spec);
    1436        4551 :     return Locate(clone);
    1437             : }
    1438             : 
    1439             : // Return a clone of attribute with updated sub-protocol.
    1440        2028 : BgpAttrPtr BgpAttrDB::ReplaceSubProtocolAndLocate(const BgpAttr *attr,
    1441             :     const string &sbp) {
    1442        2028 :     BgpAttr *clone = new BgpAttr(*attr);
    1443        2028 :     clone->set_sub_protocol(sbp);
    1444        2028 :     return Locate(clone);
    1445             : }
    1446             : 
    1447             : 
    1448             : // Return a clone of attribute with updated pmsi tunnel.
    1449        8758 : BgpAttrPtr BgpAttrDB::ReplacePmsiTunnelAndLocate(const BgpAttr *attr,
    1450             :     const PmsiTunnelSpec *pmsi_spec) {
    1451        8758 :     BgpAttr *clone = new BgpAttr(*attr);
    1452        8758 :     clone->set_pmsi_tunnel(pmsi_spec);
    1453        8758 :     return Locate(clone);
    1454             : }
    1455             : 
    1456             : // Return a clone of attribute with updated nexthop.
    1457      338909 : BgpAttrPtr BgpAttrDB::ReplaceNexthopAndLocate(const BgpAttr *attr,
    1458             :     const IpAddress &addr) {
    1459      338909 :     BgpAttr *clone = new BgpAttr(*attr);
    1460      338919 :     clone->set_nexthop(addr);
    1461      338914 :     return Locate(clone);
    1462             : }

Generated by: LCOV version 1.14