OpenSDN source code
bgp_ribout.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef SRC_BGP_BGP_RIBOUT_H_
6 #define SRC_BGP_BGP_RIBOUT_H_
7 
8 #include <boost/scoped_ptr.hpp>
9 #include <boost/intrusive/slist.hpp>
10 
11 #include <algorithm>
12 #include <string>
13 #include <vector>
14 
15 #include "base/bitset.h"
16 #include "base/index_map.h"
17 #include "bgp/bgp_attr.h"
18 #include "bgp/bgp_proto.h"
19 #include "bgp/bgp_rib_policy.h"
20 #include "db/db_entry.h"
21 #include "net/tunnel_encap_type.h"
22 
23 class IPeer;
24 class IPeerUpdate;
25 class RibOutUpdates;
26 class ShowRibOutStatistics;
27 class BgpTable;
28 class BgpExport;
29 class BgpRoute;
30 class BgpUpdateSender;
31 class RouteUpdate;
32 class UpdateInfoSList;
33 
34 //
35 // This class represents the attributes for a ribout entry, including the
36 // label. It is essentially a combination of a smart pointer to BgpAttr
37 // and a label. The label is not included in BgpAttr in order to maximize
38 // sharing of the BgpAttr.
39 //
40 class RibOutAttr {
41 public:
42  // This nested class represents an ecmp element for a ribout entry. A
43  // ribout entry keeps a vector of these elements. Each element stores
44  // all per nexthop properties in addition to the nexthop address and
45  // label.
46  //
47  // The origin_vn_index keeps track of the index of the VN from which
48  // the BgpPath originated. A value of -1 means that the VN is unknown.
49  class NextHop {
50  public:
51  NextHop(const BgpTable *table, IpAddress address,
52  const MacAddress &mac, uint32_t label, uint32_t l3_label,
53  const ExtCommunity *ext_community,
54  const LargeCommunity *large_community, bool vrf_originated);
55 
56  const IpAddress address() const { return address_; }
57  const MacAddress &mac() const { return mac_; }
58  uint32_t label() const { return label_; }
59  uint32_t l3_label() const { return l3_label_; }
60  const Ip4Address &source_address() const { return source_address_; }
61  int origin_vn_index() const { return origin_vn_index_; }
62  std::vector<std::string> encap() const { return encap_; }
63  std::vector<uint64_t> tag_list() const { return tag_list_; }
64 
65  int CompareTo(const NextHop &rhs) const;
66  bool operator==(const NextHop &rhs) const;
67  bool operator!=(const NextHop &rhs) const;
68  bool operator<(const NextHop &rhs) const;
69 
70  private:
73  uint32_t label_;
74  uint32_t l3_label_;
77  std::vector<std::string> encap_;
78  std::vector<uint64_t> tag_list_;
79  };
80 
81  typedef std::vector<NextHop> NextHopList;
82 
83  RibOutAttr();
84  RibOutAttr(const RibOutAttr &rhs);
85  RibOutAttr(const BgpRoute *route, const BgpAttr *attr, bool is_xmpp);
86  RibOutAttr(const BgpTable *table, const BgpAttr *attr, uint32_t label,
87  uint32_t l3_label = 0, bool is_xmpp = false);
88  RibOutAttr(const BgpTable *table, const BgpRoute *route,
89  const BgpAttr *attr, uint32_t label, bool include_nh = true,
90  bool is_xmpp = false);
91 
92  RibOutAttr &operator=(const RibOutAttr &rhs);
93  bool operator==(const RibOutAttr &rhs) const { return CompareTo(rhs) == 0; }
94  bool operator!=(const RibOutAttr &rhs) const { return CompareTo(rhs) != 0; }
95  bool IsReachable() const { return attr_out_.get() != NULL; }
96 
97  const NextHopList &nexthop_list() const { return nexthop_list_; }
98  const BgpAttr *attr() const { return attr_out_.get(); }
99  void set_attr(const BgpTable *table, const BgpAttrPtr &attrp) {
100  set_attr(table, attrp, 0, 0, false, false);
101  }
102  void set_attr(const BgpTable *table, const BgpAttrPtr &attrp,
103  uint32_t label) {
104  set_attr(table, attrp, label, 0, false, false);
105  }
106  void set_attr(const BgpTable *table, const BgpAttrPtr &attrp,
107  uint32_t label, uint32_t l3_label, bool vrf_originated, bool is_xmpp);
110  }
111 
112  void clear() {
113  attr_out_.reset();
114  nexthop_list_.clear();
115  }
116  uint32_t label() const {
117  return nexthop_list_.empty() ? label_ : nexthop_list_[0].label();
118  }
119  uint32_t l3_label() const {
120  return nexthop_list_.empty() ? l3_label_ : nexthop_list_[0].l3_label();
121  }
122  const Ip4Address &source_address() const { return source_address_; }
124  bool is_xmpp() const { return is_xmpp_; }
125  bool vrf_originated() const { return vrf_originated_; }
126  const std::string &repr() const { return repr_; }
127  void set_repr(const std::string &repr, size_t pos = 0) const {
128  repr_.clear();
129  repr_.append(repr, pos, std::string::npos);
130  }
131 
132 private:
133  int CompareTo(const RibOutAttr &rhs) const;
134 
137  uint32_t label_;
138  uint32_t l3_label_;
140  bool is_xmpp_;
142  mutable std::string repr_;
143 };
144 
145 //
146 // This class represents a bitset of peers within a RibOut. This is distinct
147 // from the GroupPeerSet in order to allow it to be denser. This is possible
148 // because not every peer in the group may be interested in every RibOut.
149 //
150 class RibPeerSet : public BitSet {
151 };
152 
153 //
154 // This class represents information for a particular prefix that has been
155 // advertised to a set of peers.
156 //
157 // An AdvertiseInfo is part of a intrusive singly linked list container in
158 // the RouteState. The RibPeerSet represents the set of peers to which the
159 // prefix has been advertised and the RibOutAttr represents the associated
160 // attributes. This representation allows us to keep track of a different
161 // set of attributes for each set of peers.
162 //
165  explicit AdvertiseInfo(const RibOutAttr *roattr) : roattr(*roattr) { }
167  : bitset(rhs.bitset), roattr(rhs.roattr) {
168  }
169 
170  // Intrusive slist node for RouteState.
171  boost::intrusive::slist_member_hook<> slist_node;
172 
175 };
176 
177 //
178 // Disposer for AdvertiseInfo.
179 //
181  void operator()(AdvertiseInfo *ainfo) { delete ainfo; }
182 };
183 
184 //
185 // Wrapper for intrusive slist of AdvertiseInfos. Destructor automatically
186 // deletes any elements still on the slist.
187 //
188 // TBD: create a class template.
189 //
191 public:
192  typedef boost::intrusive::member_hook<
194  boost::intrusive::slist_member_hook<>,
196  > Node;
197  typedef boost::intrusive::slist<
199  Node,
200  boost::intrusive::linear<true>
201  > List;
202 
204  ~AdvertiseSList() { list_.clear_and_dispose(AdvertiseInfoDisposer()); }
205 
206  List *operator->() { return &list_; }
207  const List *operator->() const { return &list_; }
208  const List &list() const { return list_; }
209  void swap(AdvertiseSList &adv_slist) { list_.swap(adv_slist.list_); }
210 
211 private:
213 };
214 
215 //
216 // This class represents per prefix information that been advertised to
217 // the peers in a RibOut.
218 //
219 // A RouteState is derived from a DBState which means that it is part of
220 // the state map within a DBEntry. This allows the RouteState to be
221 // associated with a DBEntry using the listener id of the RibOut as the
222 // index. In the steady state i.e. when there are no pending updates the
223 // DBEntry maps the listener id for the RibOut to a RouteState.
224 //
225 // A RouteState maintains a singly linked list of AdvertiseInfo entries
226 // to keep track of the attributes that have been advertised to each set
227 // of peers.
228 //
229 class RouteState : public DBState {
230 public:
231  RouteState();
232 
233  void SetHistory(AdvertiseSList &history) {
234  assert(advertised_->empty());
235  advertised_.swap(history);
236  }
237  void SwapHistory(AdvertiseSList &history) {
238  advertised_.swap(history);
239  }
240  void MoveHistory(RouteUpdate *rt_update);
241  const AdvertiseInfo *FindHistory(const RibOutAttr &roattr) const;
242  bool CompareUpdateInfo(const UpdateInfoSList &uinfo_slist) const;
243 
244  const AdvertiseSList &Advertised() const { return advertised_; }
246 
247 private:
250 };
251 
252 //
253 // This class represents per-table state for a collection of peers with the
254 // same export policy. It is effectively a combination of RibExportPolicy
255 // and BgpTable. A RibOut has a 1:N association with RibOutUpdates wherein
256 // one entry is created per DB partition.
257 //
258 // A RibOut maintains a PeerStateMap to facilitate allocation and lookup of
259 // a bit index per peer in the RibOut.
260 //
261 class RibOut {
262 public:
263  class PeerIterator {
264  public:
265  PeerIterator(const RibOut *ribout, const RibPeerSet &peer_set)
266  : ribout_(ribout), peer_set_(peer_set) {
268  }
269  bool HasNext() const {
270  return index_ != RibPeerSet::npos;
271  }
275  return ptr;
276  }
277  int index() const { return index_; }
278 
279  private:
280  const RibOut *ribout_;
282  size_t index_;
283  };
284 
286  const RibExportPolicy &policy);
287  ~RibOut();
288 
289  void RegisterListener();
290  void Register(IPeerUpdate *peer);
291  void Unregister(IPeerUpdate *peer);
292  bool IsRegistered(IPeerUpdate *peer);
293  void Deactivate(IPeerUpdate *peer);
294  bool IsActive(IPeerUpdate *peer) const;
295  void BuildSendReadyBitSet(const RibPeerSet &peerset,
296  RibPeerSet *mready) const;
297 
298  IPeerUpdate *GetPeer(int index) const;
299  int GetPeerIndex(IPeerUpdate *peer) const;
300 
301  // Returns a bitmask with all the peers that are advertising this RibOut.
302  const RibPeerSet &PeerSet() const;
303  void GetSubsetPeerSet(RibPeerSet *peerset, const IPeerUpdate *cpeer) const;
304 
305  BgpTable *table() { return table_; }
306  const BgpTable *table() const { return table_; }
308 
309  const RibExportPolicy &ExportPolicy() const { return policy_; }
310 
311  int RouteAdvertiseCount(const BgpRoute *rt) const;
312  uint32_t GetQueueSize() const;
313 
315  const std::string &ToString() const { return name_; }
316 
317  RibOutUpdates *updates(int idx) { return updates_[idx]; }
318  const RibOutUpdates *updates(int idx) const { return updates_[idx]; }
319  BgpExport *bgp_export() { return bgp_export_.get(); }
320 
322  as_t peer_as() const { return policy_.as_number; }
323  as_t local_as() const { return policy_.local_as_number; }
324  bool as_override() const { return policy_.as_override; }
325  bool llgr() const { return policy_.llgr; }
326  bool as4_supported() const { return policy_.as4_supported; }
327  void set_as4_supported(bool as4) { policy_.as4_supported = as4; }
328  const IpAddress &nexthop() const { return policy_.nexthop; }
329  bool IsEncodingXmpp() const {
331  }
332  bool IsEncodingBgp() const {
334  }
335  std::string EncodingString() const {
336  return IsEncodingXmpp() ? "XMPP" : "BGP";
337  }
338  bool remove_private_enabled() const {
340  }
341  bool remove_private_all() const { return policy_.remove_private.all; }
342  bool remove_private_replace() const {
344  }
347  }
348  uint32_t cluster_id() const { return policy_.cluster_id; }
349 
350  void FillStatisticsInfo(std::vector<ShowRibOutStatistics> *sros_list) const;
351 
352 private:
353  struct PeerState {
354  explicit PeerState(IPeerUpdate *key) : peer(key), index(-1) {
355  }
356  void set_index(int idx) { index = idx; }
358  int index;
359  };
361 
365  std::string name_;
369  std::vector<RibOutUpdates *> updates_;
370  boost::scoped_ptr<BgpExport> bgp_export_;
371 
373 };
374 
375 #endif // SRC_BGP_BGP_RIBOUT_H_
boost::asio::ip::address IpAddress
Definition: address.h:13
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:998
uint32_t as_t
Definition: bgp_common.h:21
boost::intrusive::slist< AdvertiseInfo, Node, boost::intrusive::linear< true > > List
Definition: bgp_ribout.h:201
void swap(AdvertiseSList &adv_slist)
Definition: bgp_ribout.h:209
boost::intrusive::member_hook< AdvertiseInfo, boost::intrusive::slist_member_hook<>, &AdvertiseInfo::slist_node > Node
Definition: bgp_ribout.h:196
List * operator->()
Definition: bgp_ribout.h:206
const List * operator->() const
Definition: bgp_ribout.h:207
const List & list() const
Definition: bgp_ribout.h:208
Definition: bitset.h:17
static const size_t npos
Definition: bitset.h:19
size_t find_first() const
Definition: bitset.cc:242
size_t find_next(size_t pos) const
Definition: bitset.cc:255
int ListenerId
Definition: db_table.h:62
Definition: ipeer.h:186
This class represents an array of BGP Large Community values. A LargeCommunity consists of one or mor...
Definition: community.h:556
IpAddress address_
Definition: bgp_ribout.h:71
uint32_t label() const
Definition: bgp_ribout.h:58
bool operator<(const NextHop &rhs) const
Definition: bgp_ribout.cc:81
int CompareTo(const NextHop &rhs) const
Definition: bgp_ribout.cc:55
bool operator==(const NextHop &rhs) const
Definition: bgp_ribout.cc:73
MacAddress mac_
Definition: bgp_ribout.h:72
uint32_t l3_label() const
Definition: bgp_ribout.h:59
NextHop(const BgpTable *table, IpAddress address, const MacAddress &mac, uint32_t label, uint32_t l3_label, const ExtCommunity *ext_community, const LargeCommunity *large_community, bool vrf_originated)
Definition: bgp_ribout.cc:29
std::vector< std::string > encap_
Definition: bgp_ribout.h:77
std::vector< uint64_t > tag_list() const
Definition: bgp_ribout.h:63
bool operator!=(const NextHop &rhs) const
Definition: bgp_ribout.cc:77
std::vector< std::string > encap() const
Definition: bgp_ribout.h:62
std::vector< uint64_t > tag_list_
Definition: bgp_ribout.h:78
const MacAddress & mac() const
Definition: bgp_ribout.h:57
int origin_vn_index() const
Definition: bgp_ribout.h:61
const IpAddress address() const
Definition: bgp_ribout.h:56
uint32_t l3_label_
Definition: bgp_ribout.h:74
Ip4Address source_address_
Definition: bgp_ribout.h:75
const Ip4Address & source_address() const
Definition: bgp_ribout.h:60
int CompareTo(const RibOutAttr &rhs) const
Definition: bgp_ribout.cc:210
std::string repr_
Definition: bgp_ribout.h:142
void set_source_address(Ip4Address source_address)
Definition: bgp_ribout.h:108
const BgpAttr * attr() const
Definition: bgp_ribout.h:98
Ip4Address source_address_
Definition: bgp_ribout.h:139
const Ip4Address & source_address() const
Definition: bgp_ribout.h:122
bool vrf_originated() const
Definition: bgp_ribout.h:125
void set_attr(const BgpTable *table, const BgpAttrPtr &attrp, uint32_t label)
Definition: bgp_ribout.h:102
bool is_xmpp_
Definition: bgp_ribout.h:140
bool IsReachable() const
Definition: bgp_ribout.h:95
RibOutAttr & operator=(const RibOutAttr &rhs)
Definition: bgp_ribout.cc:195
uint32_t l3_label() const
Definition: bgp_ribout.h:119
uint32_t l3_label_
Definition: bgp_ribout.h:138
std::vector< NextHop > NextHopList
Definition: bgp_ribout.h:81
bool vrf_originated_
Definition: bgp_ribout.h:141
const NextHopList & nexthop_list() const
Definition: bgp_ribout.h:97
BgpAttrPtr attr_out_
Definition: bgp_ribout.h:135
bool operator==(const RibOutAttr &rhs) const
Definition: bgp_ribout.h:93
void set_repr(const std::string &repr, size_t pos=0) const
Definition: bgp_ribout.h:127
uint32_t label_
Definition: bgp_ribout.h:137
void clear()
Definition: bgp_ribout.h:112
bool operator!=(const RibOutAttr &rhs) const
Definition: bgp_ribout.h:94
uint32_t label() const
Definition: bgp_ribout.h:116
Ip4Address * source_address()
Definition: bgp_ribout.h:123
bool is_xmpp() const
Definition: bgp_ribout.h:124
const std::string & repr() const
Definition: bgp_ribout.h:126
void set_attr(const BgpTable *table, const BgpAttrPtr &attrp)
Definition: bgp_ribout.h:99
NextHopList nexthop_list_
Definition: bgp_ribout.h:136
IPeerUpdate * Next()
Definition: bgp_ribout.h:272
bool HasNext() const
Definition: bgp_ribout.h:269
PeerIterator(const RibOut *ribout, const RibPeerSet &peer_set)
Definition: bgp_ribout.h:265
const RibPeerSet & peer_set_
Definition: bgp_ribout.h:281
const RibOut * ribout_
Definition: bgp_ribout.h:280
int index() const
Definition: bgp_ribout.h:277
std::string name_
Definition: bgp_ribout.h:365
bool IsEncodingBgp() const
Definition: bgp_ribout.h:332
void set_as4_supported(bool as4)
Definition: bgp_ribout.h:327
void Register(IPeerUpdate *peer)
Definition: bgp_ribout.cc:365
RibOutUpdates * updates(int idx)
Definition: bgp_ribout.h:317
BgpProto::BgpPeerType peer_type() const
Definition: bgp_ribout.h:321
const RibExportPolicy & ExportPolicy() const
Definition: bgp_ribout.h:309
const RibPeerSet & PeerSet() const
Definition: bgp_ribout.cc:512
uint32_t cluster_id() const
Definition: bgp_ribout.h:348
void RegisterListener()
Definition: bgp_ribout.cc:351
int RouteAdvertiseCount(const BgpRoute *rt) const
Definition: bgp_ribout.cc:448
void GetSubsetPeerSet(RibPeerSet *peerset, const IPeerUpdate *cpeer) const
Definition: bgp_ribout.cc:520
BgpTable * table()
Definition: bgp_ribout.h:305
int listener_id_
Definition: bgp_ribout.h:368
BgpUpdateSender * sender()
Definition: bgp_ribout.h:307
const BgpTable * table() const
Definition: bgp_ribout.h:306
void FillStatisticsInfo(std::vector< ShowRibOutStatistics > *sros_list) const
Definition: bgp_ribout.cc:553
uint32_t GetQueueSize() const
Definition: bgp_ribout.cc:493
IPeerUpdate * GetPeer(int index) const
Definition: bgp_ribout.cc:533
as_t local_as() const
Definition: bgp_ribout.h:323
bool llgr() const
Definition: bgp_ribout.h:325
PeerStateMap state_map_
Definition: bgp_ribout.h:366
int GetPeerIndex(IPeerUpdate *peer) const
Definition: bgp_ribout.cc:544
bool remove_private_peer_loop_check() const
Definition: bgp_ribout.h:345
BgpExport * bgp_export()
Definition: bgp_ribout.h:319
RibExportPolicy policy_
Definition: bgp_ribout.h:364
bool IsActive(IPeerUpdate *peer) const
Definition: bgp_ribout.cc:426
bool as_override() const
Definition: bgp_ribout.h:324
bool as4_supported() const
Definition: bgp_ribout.h:326
IndexMap< IPeerUpdate *, PeerState, RibPeerSet > PeerStateMap
Definition: bgp_ribout.h:360
const RibOutUpdates * updates(int idx) const
Definition: bgp_ribout.h:318
RibPeerSet active_peerset_
Definition: bgp_ribout.h:367
DISALLOW_COPY_AND_ASSIGN(RibOut)
const std::string & ToString() const
Definition: bgp_ribout.h:315
bool remove_private_all() const
Definition: bgp_ribout.h:341
void Unregister(IPeerUpdate *peer)
Definition: bgp_ribout.cc:386
const IpAddress & nexthop() const
Definition: bgp_ribout.h:328
std::string EncodingString() const
Definition: bgp_ribout.h:335
as_t peer_as() const
Definition: bgp_ribout.h:322
bool IsRegistered(IPeerUpdate *peer)
Definition: bgp_ribout.cc:406
boost::scoped_ptr< BgpExport > bgp_export_
Definition: bgp_ribout.h:370
bool remove_private_replace() const
Definition: bgp_ribout.h:342
DBTableBase::ListenerId listener_id() const
Definition: bgp_ribout.h:314
std::vector< RibOutUpdates * > updates_
Definition: bgp_ribout.h:369
bool IsEncodingXmpp() const
Definition: bgp_ribout.h:329
void BuildSendReadyBitSet(const RibPeerSet &peerset, RibPeerSet *mready) const
Definition: bgp_ribout.cc:434
RibOut(BgpTable *table, BgpUpdateSender *sender, const RibExportPolicy &policy)
Definition: bgp_ribout.cc:305
void Deactivate(IPeerUpdate *peer)
Definition: bgp_ribout.cc:419
BgpTable * table_
Definition: bgp_ribout.h:362
BgpUpdateSender * sender_
Definition: bgp_ribout.h:363
bool remove_private_enabled() const
Definition: bgp_ribout.h:338
AdvertiseSList advertised_
Definition: bgp_ribout.h:248
DISALLOW_COPY_AND_ASSIGN(RouteState)
void SwapHistory(AdvertiseSList &history)
Definition: bgp_ribout.h:237
bool CompareUpdateInfo(const UpdateInfoSList &uinfo_slist) const
Definition: bgp_ribout.cc:284
AdvertiseSList & Advertised()
Definition: bgp_ribout.h:245
void SetHistory(AdvertiseSList &history)
Definition: bgp_ribout.h:233
const AdvertiseInfo * FindHistory(const RibOutAttr &roattr) const
Definition: bgp_ribout.cc:265
const AdvertiseSList & Advertised() const
Definition: bgp_ribout.h:244
void MoveHistory(RouteUpdate *rt_update)
Definition: bgp_ribout.cc:256
void operator()(AdvertiseInfo *ainfo)
Definition: bgp_ribout.h:181
RibOutAttr roattr
Definition: bgp_ribout.h:174
boost::intrusive::slist_member_hook slist_node
Definition: bgp_ribout.h:171
RibPeerSet bitset
Definition: bgp_ribout.h:173
AdvertiseInfo(const RibOutAttr *roattr)
Definition: bgp_ribout.h:165
AdvertiseInfo(const AdvertiseInfo &rhs)
Definition: bgp_ribout.h:166
IpAddress nexthop
BgpProto::BgpPeerType type
RemovePrivatePolicy remove_private
uint32_t cluster_id
void set_index(int idx)
Definition: bgp_ribout.h:356
IPeerUpdate * peer
Definition: bgp_ribout.h:357
PeerState(IPeerUpdate *key)
Definition: bgp_ribout.h:354