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