OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
route_aggregator.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef SRC_BGP_ROUTING_INSTANCE_ROUTE_AGGREGATOR_H_
6 #define SRC_BGP_ROUTING_INSTANCE_ROUTE_AGGREGATOR_H_
7 
8 #include <tbb/mutex.h>
9 
10 #include <map>
11 #include <set>
12 
14 
16 #include "bgp/bgp_config.h"
17 #include "bgp/inet/inet_route.h"
18 #include "bgp/inet/inet_table.h"
19 #include "bgp/inet6/inet6_route.h"
20 #include "bgp/inet6/inet6_table.h"
21 
23 
24 template <typename T> class AggregateRoute;
25 
26 template <typename T1, typename T2, typename T3, typename T4>
28  typedef T1 TableT;
29  typedef T2 RouteT;
30  typedef T3 PrefixT;
31  typedef T4 AddressT;
32 };
33 
35  InetTable, InetRoute, Ip4Prefix, Ip4Address> {
36 };
37 
39  Inet6Table, Inet6Route, Inet6Prefix, Ip6Address> {
40 };
41 
43 
44 //
45 // RouteAggregator
46 // ================
47 //
48 // This class implements the route aggregation for control node. It provides
49 // APIs to create/delete/update route aggregation config for a routing instance
50 // An object of this class for the address families that supports route
51 // aggregation is hooked to routing instance. Currently route aggregation is
52 // supported for INET and INET6 address family. Support for multiple address
53 // family is implemented with template for each address family
54 //
55 // RouteAggregator uses BgpConditionListener to track more specific routes of
56 // the configured aggregate prefix and PathResolver to resolve nexthop for
57 // aggregate route
58 //
59 // RouteAggregator uses AddMatchCondition method of BgpConditionListener when
60 // new route-aggregate prefix is created on routing instance.
61 //
62 // AggregateRoute
63 // ================
64 //
65 // AggregateRoute class implements the MatchCondition for BgpConditionListener
66 // and implements the Match() to detect the more specific route.
67 // RouteAggregator stores the match object, AggregateRoute, in
68 // aggregate_route_map_.
69 //
70 // AggregateRoute class stores the contributing routes in "contributors_" list.
71 // Match is executed in db::DBTable task in each partition context.
72 // The contributing routes are maintained per partition to ensure concurrent
73 // access to contributing routes.
74 //
75 // On the successful match, AggregateRoute calls AddContributingRoute or
76 // RemoveContributingRoute based the state and puts the AggregateRoute object
77 // in update_aggregate_list_ and trigger update_list_trigger_
78 // task trigger to process the aggregate route.
79 //
80 // In task trigger method for update_list_trigger_ is
81 // responsible for creating and deleting the Aggregate route.
82 // Aggregate route is added when first contributing route is added to
83 // contributors_ and removed when last contributing route is removed
84 //
85 // RouteAggregator creates the aggregate route with Aggregate as
86 // path source and ResolveNexthop as flags. The BgpAttribute on the aggregate
87 // route contains all the property as specified in the config. Currently,
88 // config supports specifying only the nexthop for the aggregate route.
89 // The "ResolveNexthop" flag on the route triggers the PathResolver module to
90 // resolve the corresponding nexthop and create path with all forwarding info
91 // based on nexthop specified by config.
92 //
93 // AggregateRoute also stores the resulting aggregate route in the object.
94 //
95 // Update of the route-aggregate config:
96 // ====================================
97 //
98 // AggregateRoute provides "UpdateNexthop" method. This method is invoked when
99 // nexthop is updated in route-aggregate config object. This method deletes the
100 // executing RouteAggregation path(and stop path resolution) and invokes path
101 // resolution after updating the BgpAttribute with new nexthop
102 //
103 // Delete of the route-aggregate config:
104 // ====================================
105 //
106 // When route-aggregate is removed from the routing instance for a given prefix,
107 // RouteAggregator invokes RemoveMatchCondition to initiate the delete process.
108 // StopAggregateRouteDone callback indicates the RouteAggregator about
109 // completion of remove process and it triggers unregister_list_trigger_ to
110 // unregister the match condition. StopAggregateRouteDone callback puts the
111 // AggregateRoute object in unregister_aggregate_list_.
112 //
113 // When the route-aggregate for a given prefix is in delete process, the
114 // AggregateRoute is still maintained in the aggregate_route_map_. This will
115 // avoid/ensure new route-aggregate config with same object is handled only
116 // after successful delete completion of previous AggregateRoute match object
117 // unregister_list_trigger_ is executed in bgp::Config task and walks the
118 // unregister_aggregate_list_ to complete the deletion process by calling
119 // UnregisterMatchCondition(). It also triggers ProcessAggregateRouteConfig to
120 // apply new config for pending delete prefixes.
121 //
122 // DBState: RouteAggregatorState:
123 // ============================
124 //
125 // RouteAggregator registers with the BgpTable to set the DBState.
126 // The RouteAggregatorState implements the DBState.
127 // The DBState is added on both matching/contributing route and aggregate route.
128 // A route can be both contributing and aggregating route at the same time.
129 // So two boolean fields are used to indicate the state of the route.
130 // IsContributingRoute()/IsAggregateRoute API exposed by the RouteAggregator
131 // access the DBState on the BgpRoute to return the state.
132 // In addition to the boolean, a reference to the match object is stored in the
133 // DBState. "aggregating_info_" is the match condition object valid for
134 // aggregating route and "contributing_info_" refers to the match condition to
135 // which the route is contributing.
136 //
137 // Lifetime management
138 // ===================
139 //
140 // RouteAggregator takes a delete reference to the parent routing instance and
141 // implements a DeleteActor to manage deletion
142 // MayDelete() method of DeleteActor for RouteAggregator returns false till
143 // 1. aggregate_route_map_ is not empty [To check whether config is deleted]
144 // 2. update_aggregate_list_ is not empty [contributing routes are processed]
145 // 3. unregister_aggregate_list_ is not empty [unregister of Match condition
146 // is complete]
147 // Task triggers update_list_trigger_ and unregister_list_trigger_ will
148 // call RetryDelete() to complete the delete RouteAggregator object
149 //
150 // Concurrency
151 // ===========
152 // bgp::RouteAggregation task runs in exclusion to any task that adds/deletes
153 // path from route. i.e. db::DBTable, bgp::ServiceChain, bgp::StaticRoute and
154 // bgp::ResolverPath.
155 // bgp::RouteAggregation runs in exclusion to bgp::Config task
156 // Match() function of the AggregateRoute class is run in per partition
157 // db::DBTable task. Hence the "contributors_" maintains the contributing routes
158 // in per partition list to allow concurrent access
159 //
160 template <typename T>
162 public:
163  typedef typename T::RouteT RouteT;
164  typedef typename T::PrefixT PrefixT;
165  typedef typename T::AddressT AddressT;
167 
168  // Map of AggregateRoute prefix to the AggregateRoute match object
169  typedef std::map<PrefixT, AggregateRoutePtr> AggregateRouteMap;
170 
171  explicit RouteAggregator(RoutingInstance *instance);
173 
174  virtual void Initialize();
175 
176  // Config
177  virtual void ProcessAggregateRouteConfig();
178  virtual void UpdateAggregateRouteConfig();
179  virtual void FlushAggregateRouteConfig();
180 
181  virtual uint32_t GetAggregateRouteCount() const {
182  return aggregate_route_map_.size();
183  }
185  return aggregate_route_map_;
186  }
187 
188  Address::Family GetFamily() const;
189  AddressT GetAddress(IpAddress addr) const;
190  BgpTable *bgp_table() const;
192  return listener_id_;
193  }
194 
195  bool MayDelete() const;
196  void ManagedDelete();
197  void RetryDelete();
198 
201 
202  virtual bool IsAggregateRoute(const BgpRoute *route) const;
203  virtual bool IsContributingRoute(const BgpRoute *route) const;
204 
205  virtual bool FillAggregateRouteInfo(AggregateRouteEntriesInfo *info,
206  bool summary) const;
207 
208 private:
209  class DeleteActor;
210  typedef std::set<AggregateRoutePtr> AggregateRouteProcessList;
212 
213  int CompareAggregateRoute(typename AggregateRouteMap::iterator loc,
214  AggregateRouteConfigList::iterator it);
215  void AddAggregateRoute(AggregateRouteConfigList::iterator it);
216  void DelAggregateRoute(typename AggregateRouteMap::iterator loc);
217  void UpdateAggregateRoute(typename AggregateRouteMap::iterator loc,
218  AggregateRouteConfigList::iterator it);
219 
221  void RemoveAggregateRoutePrefix(const PrefixT &static_route);
222  void StopAggregateRouteDone(BgpTable *table, ConditionMatch *info);
223 
224  bool ProcessUnregisterList();
225  bool ProcessUpdateList();
226 
227  bool RouteListener(DBTablePartBase *root, DBEntryBase *entry);
228 
230 
231  // Enable/Disable task triggers
232  virtual void DisableRouteAggregateUpdate();
233  virtual void EnableRouteAggregateUpdate();
234  virtual size_t GetUpdateAggregateListSize() const;
235 
236  virtual void DisableUnregResolveTask();
237  virtual void EnableUnregResolveTask();
238  virtual size_t GetUnregResolveListSize() const;
239 
244  boost::scoped_ptr<TaskTrigger> update_list_trigger_;
245  boost::scoped_ptr<TaskTrigger> unregister_list_trigger_;
246  tbb::mutex mutex_;
249  boost::scoped_ptr<DeleteActor> deleter_;
251 
253 };
254 
257 
258 #endif // SRC_BGP_ROUTING_INSTANCE_ROUTE_AGGREGATOR_H_
virtual void ProcessAggregateRouteConfig()
void RemoveAggregateRoutePrefix(const PrefixT &static_route)
const AggregateRouteMap & aggregate_route_map() const
virtual void EnableRouteAggregateUpdate()
virtual bool IsAggregateRoute(const BgpRoute *route) const
virtual void FlushAggregateRouteConfig()
std::map< PrefixT, AggregateRoutePtr > AggregateRouteMap
boost::intrusive_ptr< ConditionMatch > ConditionMatchPtr
bool MayDelete() const
Family
Definition: address.h:24
boost::asio::ip::address IpAddress
Definition: address.h:13
Address::Family GetFamily() const
T::AddressT AddressT
int ListenerId
Definition: db_table.h:62
int CompareAggregateRoute(typename AggregateRouteMap::iterator loc, AggregateRouteConfigList::iterator it)
void DelAggregateRoute(typename AggregateRouteMap::iterator loc)
std::vector< AggregateRouteConfig > AggregateRouteList
Definition: bgp_config.h:427
DBTableBase::ListenerId listener_id_
virtual void DisableUnregResolveTask()
void StopAggregateRouteDone(BgpTable *table, ConditionMatch *info)
BgpConditionListener * condition_listener_
BgpTable * bgp_table() const
DBTableBase::ListenerId listener_id() const
AggregateRouteMap aggregate_route_map_
BgpInstanceConfig::AggregateRouteList AggregateRouteConfigList
std::set< AggregateRoutePtr > AggregateRouteProcessList
AggregateRouteProcessList unregister_aggregate_list_
RouteAggregator(RoutingInstance *instance)
boost::scoped_ptr< TaskTrigger > update_list_trigger_
AddressT GetAddress(IpAddress addr) const
LifetimeRef< RouteAggregator > instance_delete_ref_
void EvaluateAggregateRoute(AggregateRoutePtr entry)
bool RouteListener(DBTablePartBase *root, DBEntryBase *entry)
void UnregisterAndResolveRouteAggregate(AggregateRoutePtr entry)
void UpdateAggregateRoute(typename AggregateRouteMap::iterator loc, AggregateRouteConfigList::iterator it)
virtual size_t GetUpdateAggregateListSize() const
virtual void Initialize()
virtual bool FillAggregateRouteInfo(AggregateRouteEntriesInfo *info, bool summary) const
RouteAggregator< AggregateInet6Route > RouteAggregatorInet6
DISALLOW_COPY_AND_ASSIGN(RouteAggregator)
boost::scoped_ptr< DeleteActor > deleter_
boost::scoped_ptr< TaskTrigger > unregister_list_trigger_
AggregateRoute< T > AggregateRouteT
void LocateAggregateRoutePrefix(const AggregateRouteConfig &cfg)
void AddAggregateRoute(AggregateRouteConfigList::iterator it)
ConditionMatchPtr AggregateRoutePtr
virtual void DisableRouteAggregateUpdate()
RouteAggregator< AggregateInetRoute > RouteAggregatorInet
virtual uint32_t GetAggregateRouteCount() const
virtual bool IsContributingRoute(const BgpRoute *route) const
RoutingInstance * rtinstance_
virtual void EnableUnregResolveTask()
AggregateRouteProcessList update_aggregate_list_
virtual size_t GetUnregResolveListSize() const
RoutingInstance * routing_instance()
virtual void UpdateAggregateRouteConfig()