|
xorp
|
00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*- 00002 // vim:set sts=4 ts=8: 00003 00004 // Copyright (c) 2001-2011 XORP, Inc and Others 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/route_table_filter.hh,v 1.33 2008/11/08 06:14:39 mjh Exp $ 00022 00023 #ifndef __BGP_ROUTE_TABLE_FILTER_HH__ 00024 #define __BGP_ROUTE_TABLE_FILTER_HH__ 00025 00026 00027 00028 #include "route_table_base.hh" 00029 #include "next_hop_resolver.hh" 00030 #include "peer_data.hh" 00031 00041 template<class A> 00042 class BGPRouteFilter { 00043 public: 00044 BGPRouteFilter() {}; 00045 virtual ~BGPRouteFilter() {} 00046 00047 /* "modified" is needed because we need to know whether we should 00048 free the rtmsg or not if we modify the route. If this 00049 filterbank has modified it, and then modifies it again, then we 00050 should free the rtmsg. Otherwise it's the responsibility of 00051 whoever created the rtmsg*/ 00052 virtual bool 00053 filter(InternalMessage<A>& rtmsg) const = 0; 00054 protected: 00055 #if 0 00056 void propagate_flags(const InternalMessage<A> *rtmsg, 00057 InternalMessage<A> *new_rtmsg) const; 00058 00059 void propagate_flags(const SubnetRoute<A>& route, 00060 SubnetRoute<A>& new_route) const; 00061 virtual void drop_message(const InternalMessage<A> *rtmsg, 00062 bool &modified) const ; 00063 #endif 00064 private: 00065 }; 00066 00067 00073 template<class A> 00074 class AggregationFilter : public BGPRouteFilter<A> { 00075 public: 00076 AggregationFilter(bool is_ibgp); 00077 bool filter(InternalMessage<A>& rtmsg) const ; 00078 private: 00079 bool _is_ibgp; 00080 }; 00081 00082 00095 template<class A> 00096 class SimpleASFilter : public BGPRouteFilter<A> { 00097 public: 00098 SimpleASFilter(const AsNum &as_num); 00099 bool filter(InternalMessage<A>& rtmsg) const ; 00100 private: 00101 AsNum _as_num; 00102 }; 00103 00104 00115 template<class A> 00116 class RRInputFilter : public BGPRouteFilter<A> { 00117 public: 00118 RRInputFilter(IPv4 bgp_id, IPv4 cluster_id); 00119 bool filter(InternalMessage<A>& rtmsg) const ; 00120 private: 00121 IPv4 _bgp_id; 00122 IPv4 _cluster_id; 00123 }; 00124 00125 00136 template<class A> 00137 class ASPrependFilter : public BGPRouteFilter<A> { 00138 public: 00139 ASPrependFilter(const AsNum &as_num, bool is_confederation_peer); 00140 bool filter(InternalMessage<A>& rtmsg) const; 00141 private: 00142 AsNum _as_num; 00143 bool _is_confederation_peer; 00144 }; 00145 00146 00159 template<class A> 00160 class NexthopRewriteFilter : public BGPRouteFilter<A> { 00161 public: 00162 NexthopRewriteFilter(const A &local_nexthop, bool directly_connected, 00163 const IPNet<A> &subnet); 00164 bool filter(InternalMessage<A>& rtmsg) const ; 00165 private: 00166 A _local_nexthop; 00167 bool _directly_connected; 00168 IPNet<A> _subnet; 00169 }; 00170 00171 00182 template<class A> 00183 class NexthopPeerCheckFilter : public BGPRouteFilter<A> { 00184 public: 00185 NexthopPeerCheckFilter(const A &local_nexthop, const A &peer_address); 00186 bool filter(InternalMessage<A>& rtmsg) const ; 00187 private: 00188 A _local_nexthop; 00189 A _peer_address; 00190 }; 00191 00192 00202 template<class A> 00203 class IBGPLoopFilter : public BGPRouteFilter<A> { 00204 public: 00205 IBGPLoopFilter(); 00206 bool filter(InternalMessage<A>& rtmsg) const ; 00207 private: 00208 }; 00209 00210 00223 template<class A> 00224 class RRIBGPLoopFilter : public BGPRouteFilter<A> { 00225 public: 00226 RRIBGPLoopFilter(bool rr_client, IPv4 bgp_id, IPv4 cluster_id); 00227 bool filter(InternalMessage<A>& rtmsg) const ; 00228 private: 00229 bool _rr_client; 00230 IPv4 _bgp_id; 00231 IPv4 _cluster_id; 00232 }; 00233 00242 template<class A> 00243 class RRPurgeFilter : public BGPRouteFilter<A> { 00244 public: 00245 RRPurgeFilter(); 00246 bool filter(InternalMessage<A>& rtmsg) const ; 00247 private: 00248 }; 00249 00258 template<class A> 00259 class LocalPrefInsertionFilter : public BGPRouteFilter<A> { 00260 public: 00261 LocalPrefInsertionFilter(uint32_t default_local_pref); 00262 bool filter(InternalMessage<A>& rtmsg) const ; 00263 private: 00264 uint32_t _default_local_pref; 00265 }; 00266 00267 00277 template<class A> 00278 class LocalPrefRemovalFilter : public BGPRouteFilter<A> { 00279 public: 00280 LocalPrefRemovalFilter(); 00281 bool filter(InternalMessage<A>& rtmsg) const ; 00282 private: 00283 }; 00284 00285 00294 template<class A> 00295 class MEDInsertionFilter : public BGPRouteFilter<A> { 00296 public: 00297 MEDInsertionFilter(NextHopResolver<A>& next_hop_resolver); 00298 bool filter(InternalMessage<A>& rtmsg) const ; 00299 private: 00300 NextHopResolver<A>& _next_hop_resolver; 00301 }; 00302 00311 template<class A> 00312 class MEDRemovalFilter : public BGPRouteFilter<A> { 00313 public: 00314 MEDRemovalFilter(); 00315 bool filter(InternalMessage<A>& rtmsg) const ; 00316 private: 00317 }; 00318 00326 template<class A> 00327 class KnownCommunityFilter : public BGPRouteFilter<A> { 00328 public: 00329 KnownCommunityFilter(PeerType peer_type); 00330 bool filter(InternalMessage<A>& rtmsg) const ; 00331 private: 00332 PeerType _peer_type; 00333 }; 00334 00345 template<class A> 00346 class UnknownFilter : public BGPRouteFilter<A> { 00347 public: 00348 UnknownFilter(); 00349 bool filter(InternalMessage<A>& rtmsg) const ; 00350 private: 00351 }; 00352 00353 00364 template<class A> 00365 class OriginateRouteFilter : public BGPRouteFilter<A> { 00366 public: 00367 OriginateRouteFilter(const AsNum &as_num, PeerType peer_type); 00368 bool filter(InternalMessage<A>& rtmsg) const ; 00369 private: 00370 AsNum _as_num; 00371 PeerType _peer_type; 00372 }; 00373 00384 template<class A> 00385 class FilterVersion { 00386 public: 00387 FilterVersion(NextHopResolver<A>& next_hop_resolver); 00388 ~FilterVersion(); 00389 void set_genid(uint32_t genid) {_genid = genid;} 00390 int add_aggregation_filter(bool is_ibgp); 00391 int add_simple_AS_filter(const AsNum &asn); 00392 int add_route_reflector_input_filter(IPv4 bgp_id, IPv4 cluster_id); 00393 int add_AS_prepend_filter(const AsNum &asn, bool is_confederation_peer); 00394 int add_nexthop_rewrite_filter(const A& nexthop, 00395 bool directly_connected, 00396 const IPNet<A> &subnet); 00397 int add_nexthop_peer_check_filter(const A& nexthop, 00398 const A& peer_address); 00399 int add_ibgp_loop_filter(); 00400 int add_route_reflector_ibgp_loop_filter(bool client, 00401 IPv4 bgp_id, 00402 IPv4 cluster_id); 00403 int add_route_reflector_purge_filter(); 00404 int add_localpref_insertion_filter(uint32_t default_local_pref); 00405 int add_localpref_removal_filter(); 00406 int add_med_insertion_filter(); 00407 int add_med_removal_filter(); 00408 int add_known_community_filter(PeerType peer_type); 00409 int add_unknown_filter(); 00410 int add_originate_route_filter(const AsNum &asn, PeerType peer_type); 00411 bool apply_filters(InternalMessage<A>& rtmsg, int ref_change); 00412 int ref_count() const {return _ref_count;} 00413 uint32_t genid() const {return _genid;} 00414 bool used() const {return _used;} 00415 private: 00416 uint32_t _genid; 00417 bool _used; 00418 list <BGPRouteFilter<A> *> _filters; 00419 int _ref_count; 00420 NextHopResolver<A>& _next_hop_resolver; 00421 }; 00422 00450 template<class A> 00451 class FilterTable : public BGPRouteTable<A> { 00452 public: 00453 FilterTable(string tablename, 00454 Safi safi, 00455 BGPRouteTable<A> *parent, 00456 NextHopResolver<A>& next_hop_resolver); 00457 ~FilterTable(); 00458 void reconfigure_filter(); 00459 00460 int add_route(InternalMessage<A> &rtmsg, 00461 BGPRouteTable<A> *caller); 00462 int replace_route(InternalMessage<A> &old_rtmsg, 00463 InternalMessage<A> &new_rtmsg, 00464 BGPRouteTable<A> *caller); 00465 int delete_route(InternalMessage<A> &rtmsg, 00466 BGPRouteTable<A> *caller); 00467 int route_dump(InternalMessage<A> &rtmsg, 00468 BGPRouteTable<A> *caller, 00469 const PeerHandler *dump_peer); 00470 int push(BGPRouteTable<A> *caller); 00471 const SubnetRoute<A> *lookup_route(const IPNet<A> &net, 00472 uint32_t& genid, 00473 FPAListRef& pa_list) const; 00474 void route_used(const SubnetRoute<A>* route, bool in_use); 00475 00476 RouteTableType type() const {return FILTER_TABLE;} 00477 string str() const; 00478 00479 /* mechanisms to implement flow control in the output plumbing */ 00480 bool get_next_message(BGPRouteTable<A> *next_table); 00481 00482 int add_aggregation_filter(bool is_ibgp); 00483 int add_simple_AS_filter(const AsNum &asn); 00484 int add_route_reflector_input_filter(IPv4 bgp_id, IPv4 cluster_id); 00485 int add_AS_prepend_filter(const AsNum &asn, bool is_confederation_peer); 00486 int add_nexthop_rewrite_filter(const A& nexthop, 00487 bool directly_connected, 00488 const IPNet<A> &subnet); 00489 int add_nexthop_peer_check_filter(const A& nexthop, 00490 const A& peer_address); 00491 int add_ibgp_loop_filter(); 00492 int add_route_reflector_ibgp_loop_filter(bool client, 00493 IPv4 bgp_id, 00494 IPv4 cluster_id); 00495 int add_route_reflector_purge_filter(); 00496 int add_localpref_insertion_filter(uint32_t default_local_pref); 00497 int add_localpref_removal_filter(); 00498 int add_med_insertion_filter(); 00499 int add_med_removal_filter(); 00500 int add_known_community_filter(PeerType peer_type); 00501 int add_unknown_filter(); 00502 int add_originate_route_filter(const AsNum &asn, PeerType peer_type); 00503 void do_versioning() {_do_versioning = true;} 00504 00505 private: 00506 bool apply_filters(InternalMessage<A>& rtmsg, int ref_change); 00507 bool apply_filters(InternalMessage<A>& rtmsg) const; 00508 void drop_message(const InternalMessage<A> *rtmsg) const ; 00509 map <uint32_t, FilterVersion<A>* > _filter_versions; 00510 set <uint32_t> _deleted_filters; /* kept as a sanity check */ 00511 FilterVersion<A>* _current_filter; 00512 NextHopResolver<A>& _next_hop_resolver; 00513 bool _do_versioning; 00514 }; 00515 00516 #endif // __BGP_ROUTE_TABLE_FILTER_HH__