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-18 01:51:13 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      402234 :     AsPathSpec() : BgpAttribute(BgpAttribute::AsPath, kFlags) {}
      34      124019 :     explicit AsPathSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
      35      472108 :     explicit AsPathSpec(const AsPathSpec &rhs) :
      36      472108 :             BgpAttribute(BgpAttribute::AsPath, kFlags) {
      37      857984 :         for (size_t i = 0; i < rhs.path_segments.size(); i++) {
      38      385910 :             PathSegment *ps = new PathSegment;
      39      385899 :             *ps = *rhs.path_segments[i];
      40      385861 :             path_segments.push_back(ps);
      41             :         }
      42      472024 :     }
      43     1455463 :     ~AsPathSpec() {
      44      998403 :         STLDeleteValues(&path_segments);
      45     1455371 :     }
      46             :     struct PathSegment : public ParseObject {
      47     1286765 :         int CompareTo(const PathSegment &rhs) const {
      48     1286765 :             KEY_COMPARE(path_segment_type, rhs.path_segment_type);
      49     1286765 :             KEY_COMPARE(path_segment, rhs.path_segment);
      50      604405 :             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      362512 :     explicit AsPath(AsPathDB *aspath_db, const AsPathSpec &spec)
      88      362512 :         : aspath_db_(aspath_db), path_(spec) {
      89      362504 :         refcount_ = 0;
      90      659797 :         for (size_t i = 0; i < path_.path_segments.size(); i++) {
      91      297233 :             AsPathSpec::PathSegment *ps = path_.path_segments[i];
      92      297232 :             if (ps->path_segment_type == AsPathSpec::PathSegment::AS_SET) {
      93          45 :                 std::sort(ps->path_segment.begin(), ps->path_segment.end());
      94             :             }
      95             :         }
      96      362521 :     }
      97      724094 :     virtual ~AsPath() { }
      98             :     virtual void Remove();
      99      762430 :     int AsCount() const {
     100      762430 :         int count = 0;
     101      762430 :         std::vector<AsPathSpec::PathSegment *>::const_iterator i;
     102     1377259 :         for (i = path_.path_segments.begin(); i < path_.path_segments.end();
     103      614824 :                 i++) {
     104      614832 :             if ((*i)->path_segment_type == AsPathSpec::PathSegment::AS_SET) {
     105          20 :                 count++;
     106             :             } else {
     107      614810 :                 count += (*i)->path_segment.size();
     108             :             }
     109             :         }
     110      762652 :         return count;
     111             :     }
     112             : 
     113     2933300 :     int CompareTo(const AsPath &rhs) const {
     114     2933300 :         const std::vector<AsPathSpec::PathSegment *> &lps = path_.path_segments;
     115     2933300 :         const std::vector<AsPathSpec::PathSegment *> &rps =
     116             :                 rhs.path_.path_segments;
     117             : 
     118     2933300 :         KEY_COMPARE(lps.size(), rps.size());
     119             : 
     120     2930936 :         std::vector<AsPathSpec::PathSegment *>::const_iterator i, j;
     121     3525349 :         for (i = lps.begin(), j = rps.begin(); i < lps.end(); i++, j++) {
     122     1276760 :             int ret = (*i)->CompareTo(**j);
     123     1276803 :             if (ret != 0) return ret;
     124             :         }
     125     2248576 :         return 0;
     126             :     }
     127      597577 :     const AsPathSpec &path() const { return path_; }
     128         450 :     bool empty() const { return path_.path_segments.empty(); }
     129      492094 :     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     3117489 : inline int intrusive_ptr_add_ref(const AsPath *cpath) {
     148     6234978 :     return cpath->refcount_.fetch_add(1);
     149             : }
     150             : 
     151     1124317 : inline int intrusive_ptr_del_ref(const AsPath *cpath) {
     152     2248634 :     return cpath->refcount_.fetch_sub(1);
     153             : }
     154             : 
     155     1993784 : inline void intrusive_ptr_release(const AsPath *cpath) {
     156     1993784 :     int prev = cpath->refcount_.fetch_sub(1);
     157     1993784 :     if (prev == 1) {
     158        8200 :         AsPath *path = const_cast<AsPath *>(cpath);
     159        8200 :         path->Remove();
     160        8200 :         assert(path->refcount_ == 0);
     161        8200 :         delete path;
     162             :     }
     163     1993784 : }
     164             : 
     165             : typedef boost::intrusive_ptr<const AsPath> AsPathPtr;
     166             : 
     167             : struct AsPathCompare {
     168     2933298 :     bool operator()(const AsPath *lhs, const AsPath *rhs) const {
     169     2933298 :         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         787 :     AsPath4ByteSpec() : BgpAttribute(BgpAttribute::AsPath, kFlags) {}
     190          69 :     explicit AsPath4ByteSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
     191         560 :     explicit AsPath4ByteSpec(const AsPath4ByteSpec &rhs) :
     192         560 :             BgpAttribute(BgpAttribute::AsPath, kFlags) {
     193        1033 :         for (size_t i = 0; i < rhs.path_segments.size(); i++) {
     194         473 :             PathSegment *ps = new PathSegment;
     195         473 :             *ps = *rhs.path_segments[i];
     196         473 :             path_segments.push_back(ps);
     197             :         }
     198         560 :     }
     199        1974 :     ~AsPath4ByteSpec() {
     200        1413 :         STLDeleteValues(&path_segments);
     201        1974 :     }
     202             :     struct PathSegment : public ParseObject {
     203        1581 :         int CompareTo(const PathSegment &rhs) const {
     204        1581 :             KEY_COMPARE(path_segment_type, rhs.path_segment_type);
     205        1581 :             KEY_COMPARE(path_segment, rhs.path_segment);
     206         865 :             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         485 :     explicit AsPath4Byte(AsPath4ByteDB *aspath_db, const AsPath4ByteSpec &spec)
     244         485 :         : aspath_db_(aspath_db), path_(spec) {
     245         485 :         refcount_ = 0;
     246         916 :         for (size_t i = 0; i < path_.path_segments.size(); i++) {
     247         431 :             AsPath4ByteSpec::PathSegment *ps = path_.path_segments[i];
     248         431 :             if (ps->path_segment_type == AsPath4ByteSpec::PathSegment::AS_SET) {
     249          49 :                 std::sort(ps->path_segment.begin(), ps->path_segment.end());
     250             :             }
     251             :         }
     252         485 :     }
     253         970 :     virtual ~AsPath4Byte() { }
     254             :     virtual void Remove();
     255         496 :     int AsCount() const {
     256         496 :         int count = 0;
     257         496 :         std::vector<AsPath4ByteSpec::PathSegment *>::const_iterator i;
     258         812 :         for (i = path_.path_segments.begin(); i < path_.path_segments.end();
     259         316 :                 i++) {
     260         316 :             if ((*i)->path_segment_type ==
     261             :                              AsPath4ByteSpec::PathSegment::AS_SET) {
     262           0 :                 count++;
     263             :             } else {
     264         316 :                 count += (*i)->path_segment.size();
     265             :             }
     266             :         }
     267         496 :         return count;
     268             :     }
     269             : 
     270        1789 :     int CompareTo(const AsPath4Byte &rhs) const {
     271        1789 :         const std::vector<AsPath4ByteSpec::PathSegment *> &lps =
     272             :                 path_.path_segments;
     273        1789 :         const std::vector<AsPath4ByteSpec::PathSegment *> &rps =
     274             :                 rhs.path_.path_segments;
     275             : 
     276        1789 :         KEY_COMPARE(lps.size(), rps.size());
     277             : 
     278        1686 :         std::vector<AsPath4ByteSpec::PathSegment *>::const_iterator i, j;
     279        2548 :         for (i = lps.begin(), j = rps.begin(); i < lps.end(); i++, j++) {
     280        1578 :             int ret = (*i)->CompareTo(**j);
     281        1578 :             if (ret != 0) return ret;
     282             :         }
     283         970 :         return 0;
     284             :     }
     285         933 :     const AsPath4ByteSpec &path() const { return path_; }
     286          86 :     bool empty() const { return path_.path_segments.empty(); }
     287         225 :     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        1551 : inline int intrusive_ptr_add_ref(const AsPath4Byte *cpath) {
     306        3102 :     return cpath->refcount_.fetch_add(1);
     307             : }
     308             : 
     309         485 : inline int intrusive_ptr_del_ref(const AsPath4Byte *cpath) {
     310         970 :     return cpath->refcount_.fetch_sub(1);
     311             : }
     312             : 
     313        1066 : inline void intrusive_ptr_release(const AsPath4Byte *cpath) {
     314        1066 :     int prev = cpath->refcount_.fetch_sub(1);
     315        1066 :     if (prev == 1) {
     316         330 :         AsPath4Byte *path = const_cast<AsPath4Byte *>(cpath);
     317         330 :         path->Remove();
     318         330 :         assert(path->refcount_ == 0);
     319         330 :         delete path;
     320             :     }
     321        1066 : }
     322             : 
     323             : typedef boost::intrusive_ptr<const AsPath4Byte> AsPath4BytePtr;
     324             : 
     325             : struct AsPath4ByteCompare {
     326        1789 :     bool operator()(const AsPath4Byte *lhs, const AsPath4Byte *rhs) const {
     327        1789 :         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         455 :     As4PathSpec() : BgpAttribute(BgpAttribute::As4Path, kFlags) {}
     350           5 :     explicit As4PathSpec(const BgpAttribute &rhs) : BgpAttribute(rhs) {}
     351         472 :     explicit As4PathSpec(const As4PathSpec &rhs) :
     352         472 :             BgpAttribute(BgpAttribute::As4Path, kFlags) {
     353         951 :         for (size_t i = 0; i < rhs.path_segments.size(); i++) {
     354         479 :             PathSegment *ps = new PathSegment;
     355         479 :             *ps = *rhs.path_segments[i];
     356         479 :             path_segments.push_back(ps);
     357             :         }
     358         472 :     }
     359        1394 :     ~As4PathSpec() {
     360         932 :         STLDeleteValues(&path_segments);
     361        1394 :     }
     362             :     struct PathSegment : public ParseObject {
     363        1806 :         int CompareTo(const PathSegment &rhs) const {
     364        1806 :             KEY_COMPARE(path_segment_type, rhs.path_segment_type);
     365        1806 :             KEY_COMPARE(path_segment, rhs.path_segment);
     366         927 :             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         456 :     explicit As4Path(As4PathDB *aspath_db, const As4PathSpec &spec)
     404         456 :         : aspath_db_(aspath_db), path_(spec) {
     405         456 :         refcount_ = 0;
     406         919 :         for (size_t i = 0; i < path_.path_segments.size(); i++) {
     407         463 :             As4PathSpec::PathSegment *ps = path_.path_segments[i];
     408         463 :             if (ps->path_segment_type == As4PathSpec::PathSegment::AS_SET) {
     409          32 :                 std::sort(ps->path_segment.begin(), ps->path_segment.end());
     410             :             }
     411             :         }
     412         456 :     }
     413         912 :     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        1891 :     int CompareTo(const As4Path &rhs) const {
     430        1891 :         const std::vector<As4PathSpec::PathSegment *> &lps = path_.path_segments;
     431        1891 :         const std::vector<As4PathSpec::PathSegment *> &rps =
     432             :                 rhs.path_.path_segments;
     433             : 
     434        1891 :         KEY_COMPARE(lps.size(), rps.size());
     435             : 
     436        1791 :         std::vector<As4PathSpec::PathSegment *>::const_iterator i, j;
     437        2717 :         for (i = lps.begin(), j = rps.begin(); i < lps.end(); i++, j++) {
     438        1805 :             int ret = (*i)->CompareTo(**j);
     439        1805 :             if (ret != 0) return ret;
     440             :         }
     441         912 :         return 0;
     442             :     }
     443         538 :     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        1177 : inline int intrusive_ptr_add_ref(const As4Path *cpath) {
     464        2354 :     return cpath->refcount_.fetch_add(1);
     465             : }
     466             : 
     467         456 : inline int intrusive_ptr_del_ref(const As4Path *cpath) {
     468         912 :     return cpath->refcount_.fetch_sub(1);
     469             : }
     470             : 
     471         721 : inline void intrusive_ptr_release(const As4Path *cpath) {
     472         721 :     int prev = cpath->refcount_.fetch_sub(1);
     473         721 :     if (prev == 1) {
     474         439 :         As4Path *path = const_cast<As4Path *>(cpath);
     475         439 :         path->Remove();
     476         439 :         assert(path->refcount_ == 0);
     477         439 :         delete path;
     478             :     }
     479         721 : }
     480             : 
     481             : typedef boost::intrusive_ptr<const As4Path> As4PathPtr;
     482             : 
     483             : struct As4PathCompare {
     484        1891 :     bool operator()(const As4Path *lhs, const As4Path *rhs) const {
     485        1891 :         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