LCOV - code coverage report
Current view: top level - bgp - bgp_aspath.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 184 198 92.9 %
Date: 2026-06-04 02:06:09 Functions: 55 58 94.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #ifndef SRC_BGP_BGP_ASPATH_H_
       6             : #define SRC_BGP_BGP_ASPATH_H_
       7             : 
       8             : #include <boost/intrusive_ptr.hpp>
       9             : 
      10             : #include <atomic>
      11             : #include <algorithm>
      12             : #include <set>
      13             : #include <string>
      14             : #include <vector>
      15             : 
      16             : #include "bgp/bgp_attr_base.h"
      17             : #include "bgp/bgp_common.h"
      18             : #include "base/parse_object.h"
      19             : #include "base/util.h"
      20             : 
      21             : class BgpAttr;
      22             : class AsPathDB;
      23             : class As4PathDB;
      24             : class AsPath4ByteDB;
      25             : class BgpServer;
      26             : 
      27             : struct AsPathSpec : public BgpAttribute {
      28             :     static const int kSize = -1;
      29             :     static const uint8_t kFlags = Transitive;
      30             :     static const as2_t kMinPrivateAs = 64512;
      31             :     static const as2_t kMaxPrivateAs = 65534;
      32             : 
      33      403243 :     AsPathSpec() : BgpAttribute(BgpAttribute::AsPath, kFlags) {}
      34      123997 :     explicit AsPathSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
      35      472995 :     explicit AsPathSpec(const AsPathSpec &rhs) :
      36      472995 :             BgpAttribute(BgpAttribute::AsPath, kFlags) {
      37      860051 :         for (size_t i = 0; i < rhs.path_segments.size(); i++) {
      38      387100 :             PathSegment *ps = new PathSegment;
      39      387089 :             *ps = *rhs.path_segments[i];
      40      387046 :             path_segments.push_back(ps);
      41             :         }
      42      472872 :     }
      43     1458285 :     ~AsPathSpec() {
      44     1000311 :         STLDeleteValues(&path_segments);
      45     1458209 :     }
      46             :     struct PathSegment : public ParseObject {
      47     1272477 :         int CompareTo(const PathSegment &rhs) const {
      48     1272477 :             KEY_COMPARE(path_segment_type, rhs.path_segment_type);
      49     1272477 :             KEY_COMPARE(path_segment, rhs.path_segment);
      50      606049 :             return 0;
      51             :         }
      52             : 
      53             :         enum PathSegmentType {
      54             :             AS_SET = 1,
      55             :             AS_SEQUENCE = 2
      56             :         };
      57             :         int path_segment_type;
      58             :         std::vector<as2_t> path_segment;
      59             :     };
      60             : 
      61             :     as2_t AsLeftMost() const;
      62             :     bool AsLeftMostMatch(as2_t as) const;
      63             :     as2_t AsLeftMostPublic() const;
      64             :     bool AsPathLoop(as2_t as, uint8_t max_loop_count = 0) const;
      65         576 :     static bool AsIsPrivate(as2_t as) {
      66         576 :         return as >= kMinPrivateAs && as <= kMaxPrivateAs;
      67             :     }
      68             : 
      69             :     virtual int CompareTo(const BgpAttribute &rhs_attr) const;
      70             :     virtual void ToCanonical(BgpAttr *attr);
      71             :     virtual size_t EncodeLength() const;
      72             :     virtual std::string ToString() const;
      73             :     AsPathSpec *Add(as2_t asn) const;
      74             :     AsPathSpec *Add(const std::vector<as2_t> &asn_list) const;
      75             :     AsPathSpec *Add(const std::vector<as_t> &asn_list) const;
      76             :     AsPathSpec *Replace(as2_t old_asn, as2_t asn) const;
      77             :     AsPathSpec *RemovePrivate(bool all, as2_t asn, as2_t peer_as) const;
      78             : 
      79             :     std::vector<PathSegment *> path_segments;
      80             : };
      81             : 
      82             : class AsPath {
      83             : public:
      84             :     explicit AsPath(AsPathDB *aspath_db) : aspath_db_(aspath_db) {
      85             :         refcount_ = 0;
      86             :     }
      87      363155 :     explicit AsPath(AsPathDB *aspath_db, const AsPathSpec &spec)
      88      363155 :         : aspath_db_(aspath_db), path_(spec) {
      89      363146 :         refcount_ = 0;
      90      661274 :         for (size_t i = 0; i < path_.path_segments.size(); i++) {
      91      298048 :             AsPathSpec::PathSegment *ps = path_.path_segments[i];
      92      298048 :             if (ps->path_segment_type == AsPathSpec::PathSegment::AS_SET) {
      93          45 :                 std::sort(ps->path_segment.begin(), ps->path_segment.end());
      94             :             }
      95             :         }
      96      363181 :     }
      97      725411 :     virtual ~AsPath() { }
      98             :     virtual void Remove();
      99      767898 :     int AsCount() const {
     100      767898 :         int count = 0;
     101      767898 :         std::vector<AsPathSpec::PathSegment *>::const_iterator i;
     102     1388423 :         for (i = path_.path_segments.begin(); i < path_.path_segments.end();
     103      620514 :                 i++) {
     104      620516 :             if ((*i)->path_segment_type == AsPathSpec::PathSegment::AS_SET) {
     105          20 :                 count++;
     106             :             } else {
     107      620504 :                 count += (*i)->path_segment.size();
     108             :             }
     109             :         }
     110      767902 :         return count;
     111             :     }
     112             : 
     113     2065148 :     int CompareTo(const AsPath &rhs) const {
     114     2065148 :         const std::vector<AsPathSpec::PathSegment *> &lps = path_.path_segments;
     115     2065148 :         const std::vector<AsPathSpec::PathSegment *> &rps =
     116             :                 rhs.path_.path_segments;
     117             : 
     118     2065148 :         KEY_COMPARE(lps.size(), rps.size());
     119             : 
     120     2062871 :         std::vector<AsPathSpec::PathSegment *>::const_iterator i, j;
     121     2658925 :         for (i = lps.begin(), j = rps.begin(); i < lps.end(); i++, j++) {
     122     1262471 :             int ret = (*i)->CompareTo(**j);
     123     1262518 :             if (ret != 0) return ret;
     124             :         }
     125     1396439 :         return 0;
     126             :     }
     127      598297 :     const AsPathSpec &path() const { return path_; }
     128         450 :     bool empty() const { return path_.path_segments.empty(); }
     129      496045 :     as2_t neighbor_as() const { return path_.AsLeftMost(); }
     130             : 
     131           0 :     friend std::size_t hash_value(const AsPath &as_path) {
     132           0 :         size_t hash = 0;
     133           0 :         boost::hash_combine(hash, as_path.path().ToString());
     134           0 :         return hash;
     135             :     }
     136             : 
     137             : private:
     138             :     friend int intrusive_ptr_add_ref(const AsPath *cpath);
     139             :     friend int intrusive_ptr_del_ref(const AsPath *cpath);
     140             :     friend void intrusive_ptr_release(const AsPath *cpath);
     141             : 
     142             :     mutable std::atomic<int> refcount_;
     143             :     AsPathDB *aspath_db_;
     144             :     AsPathSpec path_;
     145             : };
     146             : 
     147     2699957 : inline int intrusive_ptr_add_ref(const AsPath *cpath) {
     148     5399914 :     return cpath->refcount_.fetch_add(1);
     149             : }
     150             : 
     151      698237 : inline int intrusive_ptr_del_ref(const AsPath *cpath) {
     152     1396474 :     return cpath->refcount_.fetch_sub(1);
     153             : }
     154             : 
     155     2002397 : inline void intrusive_ptr_release(const AsPath *cpath) {
     156     2002397 :     int prev = cpath->refcount_.fetch_sub(1);
     157     2002397 :     if (prev == 1) {
     158        8219 :         AsPath *path = const_cast<AsPath *>(cpath);
     159        8219 :         path->Remove();
     160        8219 :         assert(path->refcount_ == 0);
     161        8219 :         delete path;
     162             :     }
     163     2002397 : }
     164             : 
     165             : typedef boost::intrusive_ptr<const AsPath> AsPathPtr;
     166             : 
     167             : struct AsPathCompare {
     168     2065146 :     bool operator()(const AsPath *lhs, const AsPath *rhs) const {
     169     2065146 :         return lhs->CompareTo(*rhs) < 0;
     170             :     }
     171             : };
     172             : 
     173             : class AsPathDB : public BgpPathAttributeDB<AsPath, AsPathPtr, AsPathSpec,
     174             :                                            AsPathCompare, AsPathDB> {
     175             : public:
     176             :     explicit AsPathDB(BgpServer *server);
     177             : 
     178             : private:
     179             : };
     180             : 
     181             : struct AsPath4ByteSpec : public BgpAttribute {
     182             :     static const int kSize = -1;
     183             :     static const uint8_t kFlags = Transitive;
     184             :     static const as_t kMinPrivateAs = 64512;
     185             :     static const as_t kMaxPrivateAs = 65534;
     186             :     static const as_t kMinPrivateAs4 = 4200000000;
     187             :     static const as_t kMaxPrivateAs4 = 4294967294;
     188             : 
     189         781 :     AsPath4ByteSpec() : BgpAttribute(BgpAttribute::AsPath, kFlags) {}
     190          69 :     explicit AsPath4ByteSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
     191         554 :     explicit AsPath4ByteSpec(const AsPath4ByteSpec &rhs) :
     192         554 :             BgpAttribute(BgpAttribute::AsPath, kFlags) {
     193        1021 :         for (size_t i = 0; i < rhs.path_segments.size(); i++) {
     194         467 :             PathSegment *ps = new PathSegment;
     195         467 :             *ps = *rhs.path_segments[i];
     196         467 :             path_segments.push_back(ps);
     197             :         }
     198         554 :     }
     199        1962 :     ~AsPath4ByteSpec() {
     200        1401 :         STLDeleteValues(&path_segments);
     201        1962 :     }
     202             :     struct PathSegment : public ParseObject {
     203        1572 :         int CompareTo(const PathSegment &rhs) const {
     204        1572 :             KEY_COMPARE(path_segment_type, rhs.path_segment_type);
     205        1572 :             KEY_COMPARE(path_segment, rhs.path_segment);
     206         853 :             return 0;
     207             :         }
     208             : 
     209             :         enum PathSegmentType {
     210             :             AS_SET = 1,
     211             :             AS_SEQUENCE = 2
     212             :         };
     213             :         int path_segment_type;
     214             :         std::vector<as_t> path_segment;
     215             :     };
     216             : 
     217             :     as_t AsLeftMost() const;
     218             :     bool AsLeftMostMatch(as_t as) const;
     219             :     as_t AsLeftMostPublic() const;
     220             :     bool AsPathLoop(as_t as, uint8_t max_loop_count = 0) const;
     221          92 :     static bool AsIsPrivate(as_t as) {
     222         140 :         return ((as >= kMinPrivateAs && as <= kMaxPrivateAs) ||
     223         140 :             (as >= kMinPrivateAs4 && as <= kMaxPrivateAs4));
     224             :     }
     225             : 
     226             :     virtual int CompareTo(const BgpAttribute &rhs_attr) const;
     227             :     virtual void ToCanonical(BgpAttr *attr);
     228             :     virtual size_t EncodeLength() const;
     229             :     virtual std::string ToString() const;
     230             :     AsPath4ByteSpec *Add(as_t asn) const;
     231             :     AsPath4ByteSpec *Add(const std::vector<as_t> &asn_list) const;
     232             :     AsPath4ByteSpec *Replace(as_t old_asn, as_t asn) const;
     233             :     AsPath4ByteSpec *RemovePrivate(bool all, as_t asn, as_t peer_as) const;
     234             : 
     235             :     std::vector<PathSegment *> path_segments;
     236             : };
     237             : 
     238             : class AsPath4Byte {
     239             : public:
     240             :     explicit AsPath4Byte(AsPath4ByteDB *aspath_db) : aspath_db_(aspath_db) {
     241             :         refcount_ = 0;
     242             :     }
     243         479 :     explicit AsPath4Byte(AsPath4ByteDB *aspath_db, const AsPath4ByteSpec &spec)
     244         479 :         : aspath_db_(aspath_db), path_(spec) {
     245         479 :         refcount_ = 0;
     246         904 :         for (size_t i = 0; i < path_.path_segments.size(); i++) {
     247         425 :             AsPath4ByteSpec::PathSegment *ps = path_.path_segments[i];
     248         425 :             if (ps->path_segment_type == AsPath4ByteSpec::PathSegment::AS_SET) {
     249          49 :                 std::sort(ps->path_segment.begin(), ps->path_segment.end());
     250             :             }
     251             :         }
     252         479 :     }
     253         958 :     virtual ~AsPath4Byte() { }
     254             :     virtual void Remove();
     255         488 :     int AsCount() const {
     256         488 :         int count = 0;
     257         488 :         std::vector<AsPath4ByteSpec::PathSegment *>::const_iterator i;
     258         796 :         for (i = path_.path_segments.begin(); i < path_.path_segments.end();
     259         308 :                 i++) {
     260         308 :             if ((*i)->path_segment_type ==
     261             :                              AsPath4ByteSpec::PathSegment::AS_SET) {
     262           0 :                 count++;
     263             :             } else {
     264         308 :                 count += (*i)->path_segment.size();
     265             :             }
     266             :         }
     267         488 :         return count;
     268             :     }
     269             : 
     270        1780 :     int CompareTo(const AsPath4Byte &rhs) const {
     271        1780 :         const std::vector<AsPath4ByteSpec::PathSegment *> &lps =
     272             :                 path_.path_segments;
     273        1780 :         const std::vector<AsPath4ByteSpec::PathSegment *> &rps =
     274             :                 rhs.path_.path_segments;
     275             : 
     276        1780 :         KEY_COMPARE(lps.size(), rps.size());
     277             : 
     278        1677 :         std::vector<AsPath4ByteSpec::PathSegment *>::const_iterator i, j;
     279        2527 :         for (i = lps.begin(), j = rps.begin(); i < lps.end(); i++, j++) {
     280        1569 :             int ret = (*i)->CompareTo(**j);
     281        1569 :             if (ret != 0) return ret;
     282             :         }
     283         958 :         return 0;
     284             :     }
     285         929 :     const AsPath4ByteSpec &path() const { return path_; }
     286          86 :     bool empty() const { return path_.path_segments.empty(); }
     287         219 :     as_t neighbor_as() const { return path_.AsLeftMost(); }
     288             : 
     289           0 :     friend std::size_t hash_value(const AsPath4Byte &as_path) {
     290           0 :         size_t hash = 0;
     291           0 :         boost::hash_combine(hash, as_path.path().ToString());
     292           0 :         return hash;
     293             :     }
     294             : 
     295             : private:
     296             :     friend int intrusive_ptr_add_ref(const AsPath4Byte *cpath);
     297             :     friend int intrusive_ptr_del_ref(const AsPath4Byte *cpath);
     298             :     friend void intrusive_ptr_release(const AsPath4Byte *cpath);
     299             : 
     300             :     mutable std::atomic<int> refcount_;
     301             :     AsPath4ByteDB *aspath_db_;
     302             :     AsPath4ByteSpec path_;
     303             : };
     304             : 
     305        1533 : inline int intrusive_ptr_add_ref(const AsPath4Byte *cpath) {
     306        3066 :     return cpath->refcount_.fetch_add(1);
     307             : }
     308             : 
     309         479 : inline int intrusive_ptr_del_ref(const AsPath4Byte *cpath) {
     310         958 :     return cpath->refcount_.fetch_sub(1);
     311             : }
     312             : 
     313        1054 : inline void intrusive_ptr_release(const AsPath4Byte *cpath) {
     314        1054 :     int prev = cpath->refcount_.fetch_sub(1);
     315        1054 :     if (prev == 1) {
     316         329 :         AsPath4Byte *path = const_cast<AsPath4Byte *>(cpath);
     317         329 :         path->Remove();
     318         329 :         assert(path->refcount_ == 0);
     319         329 :         delete path;
     320             :     }
     321        1054 : }
     322             : 
     323             : typedef boost::intrusive_ptr<const AsPath4Byte> AsPath4BytePtr;
     324             : 
     325             : struct AsPath4ByteCompare {
     326        1780 :     bool operator()(const AsPath4Byte *lhs, const AsPath4Byte *rhs) const {
     327        1780 :         return lhs->CompareTo(*rhs) < 0;
     328             :     }
     329             : };
     330             : 
     331             : class AsPath4ByteDB : public BgpPathAttributeDB<AsPath4Byte, AsPath4BytePtr,
     332             :                          AsPath4ByteSpec, AsPath4ByteCompare, AsPath4ByteDB> {
     333             : public:
     334             :     explicit AsPath4ByteDB(BgpServer *server);
     335             : 
     336             : private:
     337             : };
     338             : 
     339             : typedef boost::intrusive_ptr<const AsPath4Byte> AsPath4BytePtr;
     340             : 
     341             : struct As4PathSpec : public BgpAttribute {
     342             :     static const int kSize = -1;
     343             :     static const uint8_t kFlags = Transitive|Optional;
     344             :     static const as_t kMinPrivateAs = 64512;
     345             :     static const as_t kMaxPrivateAs = 65534;
     346             :     static const as_t kMinPrivateAs4 = 4200000000;
     347             :     static const as_t kMaxPrivateAs4 = 4294967294;
     348             : 
     349         445 :     As4PathSpec() : BgpAttribute(BgpAttribute::As4Path, kFlags) {}
     350           3 :     explicit As4PathSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
     351         464 :     explicit As4PathSpec(const As4PathSpec &rhs) :
     352         464 :             BgpAttribute(BgpAttribute::As4Path, kFlags) {
     353         935 :         for (size_t i = 0; i < rhs.path_segments.size(); i++) {
     354         471 :             PathSegment *ps = new PathSegment;
     355         471 :             *ps = *rhs.path_segments[i];
     356         471 :             path_segments.push_back(ps);
     357             :         }
     358         464 :     }
     359        1366 :     ~As4PathSpec() {
     360         912 :         STLDeleteValues(&path_segments);
     361        1366 :     }
     362             :     struct PathSegment : public ParseObject {
     363        1788 :         int CompareTo(const PathSegment &rhs) const {
     364        1788 :             KEY_COMPARE(path_segment_type, rhs.path_segment_type);
     365        1788 :             KEY_COMPARE(path_segment, rhs.path_segment);
     366         915 :             return 0;
     367             :         }
     368             : 
     369             :         enum PathSegmentType {
     370             :             AS_SET = 1,
     371             :             AS_SEQUENCE = 2
     372             :         };
     373             :         int path_segment_type;
     374             :         std::vector<as_t> path_segment;
     375             :     };
     376             : 
     377             :     as_t AsLeftMost() const;
     378             :     bool AsLeftMostMatch(as_t as) const;
     379             :     as_t AsLeftMostPublic() const;
     380             :     bool AsPathLoop(as_t as, uint8_t max_loop_count = 0) const;
     381          92 :     static bool AsIsPrivate(as_t as) {
     382          92 :         return ((as >= kMinPrivateAs && as <= kMaxPrivateAs) ||
     383          92 :             (as >= kMinPrivateAs4 && as <= kMaxPrivateAs4));
     384             :     }
     385             : 
     386             :     virtual int CompareTo(const BgpAttribute &rhs_attr) const;
     387             :     virtual void ToCanonical(BgpAttr *attr);
     388             :     virtual size_t EncodeLength() const;
     389             :     virtual std::string ToString() const;
     390             :     As4PathSpec *Add(as_t asn) const;
     391             :     As4PathSpec *Add(const std::vector<as_t> &asn_list) const;
     392             :     As4PathSpec *Replace(as_t old_asn, as_t asn) const;
     393             :     As4PathSpec *RemovePrivate(bool all, as_t asn, as_t peer_as) const;
     394             : 
     395             :     std::vector<PathSegment *> path_segments;
     396             : };
     397             : 
     398             : class As4Path {
     399             : public:
     400             :     explicit As4Path(As4PathDB *aspath_db) : aspath_db_(aspath_db) {
     401             :         refcount_ = 0;
     402             :     }
     403         450 :     explicit As4Path(As4PathDB *aspath_db, const As4PathSpec &spec)
     404         450 :         : aspath_db_(aspath_db), path_(spec) {
     405         450 :         refcount_ = 0;
     406         907 :         for (size_t i = 0; i < path_.path_segments.size(); i++) {
     407         457 :             As4PathSpec::PathSegment *ps = path_.path_segments[i];
     408         457 :             if (ps->path_segment_type == As4PathSpec::PathSegment::AS_SET) {
     409          32 :                 std::sort(ps->path_segment.begin(), ps->path_segment.end());
     410             :             }
     411             :         }
     412         450 :     }
     413         900 :     virtual ~As4Path() { }
     414             :     virtual void Remove();
     415          66 :     int AsCount() const {
     416          66 :         int count = 0;
     417          66 :         std::vector<As4PathSpec::PathSegment *>::const_iterator i;
     418         132 :         for (i = path_.path_segments.begin(); i < path_.path_segments.end();
     419          66 :                 i++) {
     420          66 :             if ((*i)->path_segment_type == As4PathSpec::PathSegment::AS_SET) {
     421           0 :                 count++;
     422             :             } else {
     423          66 :                 count += (*i)->path_segment.size();
     424             :             }
     425             :         }
     426          66 :         return count;
     427             :     }
     428             : 
     429        1873 :     int CompareTo(const As4Path &rhs) const {
     430        1873 :         const std::vector<As4PathSpec::PathSegment *> &lps = path_.path_segments;
     431        1873 :         const std::vector<As4PathSpec::PathSegment *> &rps =
     432             :                 rhs.path_.path_segments;
     433             : 
     434        1873 :         KEY_COMPARE(lps.size(), rps.size());
     435             : 
     436        1773 :         std::vector<As4PathSpec::PathSegment *>::const_iterator i, j;
     437        2687 :         for (i = lps.begin(), j = rps.begin(); i < lps.end(); i++, j++) {
     438        1787 :             int ret = (*i)->CompareTo(**j);
     439        1787 :             if (ret != 0) return ret;
     440             :         }
     441         900 :         return 0;
     442             :     }
     443         535 :     const As4PathSpec &path() const { return path_; }
     444             :     bool empty() const { return path_.path_segments.empty(); }
     445             :     as_t neighbor_as() const { return path_.AsLeftMost(); }
     446             : 
     447           0 :     friend std::size_t hash_value(As4Path const &as_path) {
     448           0 :         size_t hash = 0;
     449           0 :         boost::hash_combine(hash, as_path.path().ToString());
     450           0 :         return hash;
     451             :     }
     452             : 
     453             : private:
     454             :     friend int intrusive_ptr_add_ref(const As4Path *cpath);
     455             :     friend int intrusive_ptr_del_ref(const As4Path *cpath);
     456             :     friend void intrusive_ptr_release(const As4Path *cpath);
     457             : 
     458             :     mutable std::atomic<int> refcount_;
     459             :     As4PathDB *aspath_db_;
     460             :     As4PathSpec path_;
     461             : };
     462             : 
     463        1159 : inline int intrusive_ptr_add_ref(const As4Path *cpath) {
     464        2318 :     return cpath->refcount_.fetch_add(1);
     465             : }
     466             : 
     467         450 : inline int intrusive_ptr_del_ref(const As4Path *cpath) {
     468         900 :     return cpath->refcount_.fetch_sub(1);
     469             : }
     470             : 
     471         709 : inline void intrusive_ptr_release(const As4Path *cpath) {
     472         709 :     int prev = cpath->refcount_.fetch_sub(1);
     473         709 :     if (prev == 1) {
     474         433 :         As4Path *path = const_cast<As4Path *>(cpath);
     475         433 :         path->Remove();
     476         433 :         assert(path->refcount_ == 0);
     477         433 :         delete path;
     478             :     }
     479         709 : }
     480             : 
     481             : typedef boost::intrusive_ptr<const As4Path> As4PathPtr;
     482             : 
     483             : struct As4PathCompare {
     484        1873 :     bool operator()(const As4Path *lhs, const As4Path *rhs) const {
     485        1873 :         return lhs->CompareTo(*rhs) < 0;
     486             :     }
     487             : };
     488             : 
     489             : class As4PathDB : public BgpPathAttributeDB<As4Path, As4PathPtr, As4PathSpec,
     490             :                                            As4PathCompare, As4PathDB> {
     491             : public:
     492             :     explicit As4PathDB(BgpServer *server);
     493             : 
     494             : private:
     495             : };
     496             : 
     497             : typedef boost::intrusive_ptr<const As4Path> As4PathPtr;
     498             : #endif  // SRC_BGP_BGP_ASPATH_H_

Generated by: LCOV version 1.14