xorp

subnet_route.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 // vim:set sts=4 ts=8:
00003 
00004 // Copyright (c) 2001-2009 XORP, Inc.
00005 //
00006 // This program is free software; you can redistribute it and/or modify
00007 // it under the terms of the GNU General Public License, Version 2, June
00008 // 1991 as published by the Free Software Foundation. Redistribution
00009 // and/or modification of this program under the terms of any other
00010 // version of the GNU General Public License is not permitted.
00011 // 
00012 // This program is distributed in the hope that it will be useful, but
00013 // WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00015 // see the GNU General Public License, Version 2, a copy of which can be
00016 // found in the XORP LICENSE.gpl file.
00017 // 
00018 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00019 // http://xorp.net
00020 
00021 // $XORP: xorp/bgp/subnet_route.hh,v 1.28 2008/11/08 06:14:40 mjh Exp $
00022 
00023 #ifndef __BGP_SUBNET_ROUTE_HH__
00024 #define __BGP_SUBNET_ROUTE_HH__
00025 
00026 #include "path_attribute.hh"
00027 #include "attribute_manager.hh"
00028 #include "libxorp/xorp.h"
00029 #include "libxorp/ipv4net.hh"
00030 #include "libxorp/ipv6net.hh"
00031 
00032 #include "policy/backend/policytags.hh"
00033 #include "policy/backend/policy_filter.hh"
00034 
00035 #define SRF_IN_USE      0x00000001
00036 #define SRF_WINNER      0x00000002
00037 #define SRF_FILTERED        0x00000004
00038 #define SRF_DELETED     0x00000008
00039 #define SRF_NH_RESOLVED     0x00000010
00040 #define SRF_AGGR_BRIEF_MODE 0x00000080
00041 #define SRF_AGGR_PREFLEN_MASK   0x0000ff00
00042 #define SRF_REFCOUNT        0xffff0000
00043 
00044 // Aggregation flags
00045 // XXX Marko any better ideas where to put those?
00046 #define SR_AGGR_IGNORE          0xff
00047 #define SR_AGGR_IBGP_ONLY       0xe0
00048 #define SR_AGGR_EBGP_AGGREGATE      0xd0
00049 #define SR_AGGR_EBGP_NOT_AGGREGATED 0xd1
00050 #define SR_AGGR_EBGP_WAS_AGGREGATED 0xd2
00051 
00052 //Defining paranoid emables some additional checks to ensure we don't
00053 //try to reuse deleted data, or follow an obsolete parent_route
00054 //pointer.
00055 template<class A>
00056 class SubnetRouteRef;
00057 template<class A>
00058 class SubnetRouteConstRef;
00059 
00060 class RouteMetaData {
00061 public:
00062     RouteMetaData(const RouteMetaData& metadata);
00063 
00064     RouteMetaData();
00065 
00066     ~RouteMetaData() {
00067     // prevent accidental reuse after deletion
00068     _flags = 0xffffffff;
00069     }
00070 
00077     inline bool in_use() const {return (_flags & SRF_IN_USE) != 0;}
00078 
00087     void set_in_use(bool used) {
00088     if (used) {
00089         _flags |= SRF_IN_USE;
00090     } else {
00091         _flags &= ~SRF_IN_USE;
00092     }
00093     }
00094 
00103     inline bool is_winner() const {return (_flags & SRF_WINNER) != 0;}
00104 
00115     void set_is_winner(uint32_t igp_metric) {
00116     _flags |= SRF_WINNER;
00117     _igp_metric = igp_metric;
00118     }
00119 
00125     inline void set_is_not_winner() {
00126     _flags &= ~SRF_WINNER;
00127     }
00128 
00132     void set_nexthop_resolved(bool resolvable) {
00133     if (resolvable) {
00134         _flags |= SRF_NH_RESOLVED;
00135     } else {
00136         _flags &= ~SRF_NH_RESOLVED;
00137     }
00138     }
00139 
00144     inline bool nexthop_resolved() const {
00145     return (_flags & SRF_NH_RESOLVED) != 0;
00146     }
00147 
00153     inline bool is_filtered() const {return (_flags & SRF_FILTERED) != 0;}
00154 
00163     void set_filtered(bool filtered) {
00164     if (filtered) {
00165         _flags |= SRF_FILTERED;
00166     } else {
00167         _flags &= ~SRF_FILTERED;
00168     }
00169     }
00170 
00176     inline bool is_deleted() const {return (_flags & SRF_DELETED) != 0;}
00177 
00178     inline void set_deleted() {_flags |= SRF_DELETED;}
00179 
00185     inline uint32_t igp_metric() const {return _igp_metric;}
00186 
00187     inline void set_igp_metric(uint32_t igp_metric) {
00188     _igp_metric = igp_metric;
00189     }
00190 
00191     inline void dont_aggregate() {
00192     _flags |= SRF_AGGR_PREFLEN_MASK;
00193     }
00194 
00195     inline uint16_t refcount() const { 
00196     return (_flags & SRF_REFCOUNT) >> 16; 
00197     }
00198 
00199     //set our reference count to one (our own self-reference)
00200     //and clear the deleted flag
00201     inline void reset_flags() {
00202     _flags ^= (_flags & (SRF_REFCOUNT | SRF_DELETED));
00203     }
00204 
00208     inline const PolicyTags& policytags() const {
00209     return _policytags;
00210     }
00211 
00217     inline void set_policytags(const PolicyTags& tags) {
00218     _policytags = tags;
00219     }
00220 
00221     inline const RefPf& policyfilter(uint32_t i) const {
00222     return _pfilter[i];
00223     }
00224 
00225     inline void set_policyfilter(uint32_t i, const RefPf& pf) {
00226     _pfilter[i] = pf;
00227     }
00228     
00232     void set_aggr_brief_mode() {
00233     _flags |= SRF_AGGR_BRIEF_MODE;
00234     }
00235 
00239     void clear_aggr_brief_mode() {
00240     _flags &= ~SRF_AGGR_BRIEF_MODE;
00241     }
00242 
00246     bool aggr_brief_mode() const {
00247     return (_flags & SRF_AGGR_BRIEF_MODE);
00248     }
00249 
00256     void set_aggr_prefix_len(uint32_t preflen) {
00257     _flags = (_flags & ~SRF_AGGR_PREFLEN_MASK) | 
00258          ((preflen << 8) & SRF_AGGR_PREFLEN_MASK);
00259     }
00260 
00265     uint32_t aggr_prefix_len() const {
00266     return (_flags & SRF_AGGR_PREFLEN_MASK) >> 8;
00267     }
00268 
00269     bool bump_refcount(int delta) {
00270     XLOG_ASSERT(delta == 1 || delta == -1);
00271     uint16_t refs = refcount();
00272     if (delta == 1) {
00273         XLOG_ASSERT(refs < 0xffff);
00274     } else {
00275         XLOG_ASSERT(refs > 0);
00276     }
00277     refs += delta;
00278 
00279     //re-insert the new ref count
00280     _flags = (_flags ^ (_flags&SRF_REFCOUNT)) | (refs << 16);
00281 
00282     //handle delayed deletion
00283     if ((refs==0) && ((_flags & SRF_DELETED) != 0)) {
00284         return true;
00285     }
00286     return false;
00287     }
00288 
00289 private:
00309     uint32_t _flags;
00310 
00316     uint32_t _igp_metric;
00317 
00318     PolicyTags _policytags;
00319     RefPf _pfilter[3];
00320 };
00321 
00343 template<class A>
00344 class SubnetRoute
00345 {
00346     friend class SubnetRouteRef<A>;
00347     friend class SubnetRouteConstRef<A>;
00348 public:
00352     SubnetRoute(const SubnetRoute<A>& route_to_clone);
00353 
00366     SubnetRoute(const IPNet<A> &net, 
00367         PAListRef<A> attributes,
00368         const SubnetRoute<A>* parent_route);
00369 
00384     SubnetRoute(const IPNet<A> &net, 
00385         PAListRef<A> attributes,
00386         const SubnetRoute<A>* parent_route,
00387         uint32_t igp_metric);
00388 
00398     bool operator==(const SubnetRoute<A>& them) const;
00399 
00403     const IPNet<A>& net() const {return _net;}
00404 
00405 #if 0
00406 
00409     // remove this because we shouldn't be pulling attributes directly
00410     // out of the stored version - use a FastPathAttributeList
00411     // instead.
00412     const A& nexthop() const {return _attributes.nexthop();}
00413 #endif
00414 
00418     PAListRef<A> attributes() const {return _attributes;}
00419 
00426     bool in_use() const {return _metadata.in_use();}
00427 
00436     void set_in_use(bool used) const;
00437 
00446     bool is_winner() const {return _metadata.is_winner();}
00447 
00458     void set_is_winner(uint32_t igp_metric) const;
00459 
00465     void set_is_not_winner() const;
00466 
00470     void set_nexthop_resolved(bool resolved) const;
00471 
00476     bool nexthop_resolved() const {return _metadata.nexthop_resolved();}
00477 
00483     bool is_filtered() const {return _metadata.is_filtered();}
00484 
00493     void set_filtered(bool filtered) const;
00494 
00500     bool is_deleted() const {return _metadata.is_deleted();}
00501 
00505     string str() const;
00506 
00507 
00513     uint32_t igp_metric() const {return _metadata.igp_metric();}
00514 
00520     const SubnetRoute<A> *original_route() const {
00521     if (_parent_route)
00522         return _parent_route;
00523     else
00524         return this;
00525     }
00526 
00532     const SubnetRoute<A>* parent_route() const { return _parent_route; }
00533 
00540     void set_parent_route(const SubnetRoute<A> *parent);
00541 
00550     void unref() const;
00551 
00552     uint16_t refcount() const { return _metadata.refcount(); }
00553 
00557     const PolicyTags& policytags() const {
00558     return _metadata.policytags();
00559     }
00560 
00566     void set_policytags(const PolicyTags& tags) const {
00567     _metadata.set_policytags(tags);
00568     }
00569 
00570     const RefPf& policyfilter(uint32_t i) const;
00571     void set_policyfilter(uint32_t i, const RefPf& pf) const;
00572     
00576     void set_aggr_brief_mode() const {
00577     _metadata.set_aggr_brief_mode();
00578     }
00579 
00583     void clear_aggr_brief_mode() const {
00584     _metadata.clear_aggr_brief_mode();
00585     }
00586 
00590     bool aggr_brief_mode() const {
00591     return _metadata.aggr_brief_mode();
00592     }
00593 
00600     void set_aggr_prefix_len(uint32_t preflen) {
00601     _metadata.set_aggr_prefix_len(preflen);
00602     }
00603 
00608     uint32_t aggr_prefix_len() const {
00609     return _metadata.aggr_prefix_len();
00610     }
00611 
00612 protected:
00621     ~SubnetRoute();
00622 private:
00623 
00624     void bump_refcount(int delta) const {
00625     if (_metadata.bump_refcount(delta))
00626         delete this;
00627     }
00628 
00629     // Copyable, but not assignable.
00630     const SubnetRoute<A>& operator=(const SubnetRoute<A>&);
00631 
00635     IPNet<A> _net;
00636 
00642     PAListRef<A> _attributes;
00643 
00649     const SubnetRoute<A> *_parent_route;
00650 
00651     mutable RouteMetaData _metadata;
00652 };
00653 
00654 
00663 template<class A>
00664 class SubnetRouteRef
00665 {
00666 public:
00667     SubnetRouteRef(SubnetRoute<A>* route) : _route(route)
00668     {
00669     if (_route)
00670         _route->bump_refcount(1);
00671     }
00672     SubnetRouteRef(const SubnetRouteRef<A>& ref)
00673     {
00674     _route = ref._route;
00675     if (_route)
00676         _route->bump_refcount(1);
00677     }
00678     ~SubnetRouteRef() {
00679     if (_route)
00680         _route->bump_refcount(-1);
00681     }
00682     SubnetRoute<A>* route() const {return _route;}
00683 private:
00684     //_route can be NULL
00685     SubnetRoute<A>* _route;
00686 };
00687 
00696 template<class A>
00697 class SubnetRouteConstRef 
00698 {
00699 public:
00700     SubnetRouteConstRef(const SubnetRoute<A>* route) : _route(route)
00701     {
00702     if (_route)
00703         _route->bump_refcount(1);
00704     }
00705     SubnetRouteConstRef(const SubnetRouteConstRef<A>& ref)
00706     {
00707     _route = ref._route;
00708     if (_route)
00709         _route->bump_refcount(1);
00710     }
00711     ~SubnetRouteConstRef() {
00712     if (_route)
00713         _route->bump_refcount(-1);
00714     }
00715     const SubnetRoute<A>* route() const {return _route;}
00716 private:
00717     //_route can be NULL
00718     const SubnetRoute<A>* _route;
00719 };
00720 
00721 #endif // __BGP_SUBNET_ROUTE_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations