OpenSDN source code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bgp_xmpp_rtarget_manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved.
3  */
5 
6 #include <utility>
7 #include <vector>
8 
9 #include <boost/foreach.hpp>
10 
11 #include "bgp/ipeer.h"
12 #include "bgp/bgp_peer_types.h"
13 #include "bgp/bgp_server.h"
14 #include "bgp/bgp_xmpp_channel.h"
16 
17 using std::make_pair;
18 using std::pair;
19 using std::string;
20 using std::vector;
21 
23  bgp_xmpp_channel_(bgp_xmpp_channel) {
24 }
25 
27 }
28 
31 }
32 
34  RoutingInstance *instance) const {
35  return bgp_xmpp_channel_->IsSubscriptionGrStale(instance);
36 }
37 
39  RoutingInstance *instance) const {
41 }
42 
45 }
46 
48  return bgp_xmpp_channel_->Peer();
49 }
50 
52  RoutingInstanceMgr *instance_mgr =
54  RoutingInstance *master = instance_mgr->GetDefaultRoutingInstance();
55  BgpTable *table = master->GetTable(Address::RTARGET);
56  assert(table);
57  table->Enqueue(req);
58 }
59 
61  BgpAttrSpec attrs;
63  attrs.push_back(&nexthop);
65  attrs.push_back(&origin);
66  return bgp_xmpp_channel_->bgp_server()->attr_db()->Locate(attrs);
67 }
68 
71 }
72 
75  return bgp_xmpp_channel_->GetSubscribedRTargets(instance);
76 }
77 
79  const RouteTarget &rtarget) const {
80  PublishedRTargetRoutes::const_iterator rt_loc =
81  rtarget_routes_.find(rtarget);
82  if (rt_loc == rtarget_routes_.end() || rt_loc->second.empty())
83  return 0;
84 
85  // Route is [llgr-]stale only if it is stale for all instances in the set.
86  uint32_t flags = BgpPath::Stale | BgpPath::LlgrStale;
87  BOOST_FOREACH(RoutingInstance *routing_instance, rt_loc->second) {
88  if (!IsSubscriptionGrStale(routing_instance))
89  flags &= ~BgpPath::Stale;
90  if (!IsSubscriptionLlgrStale(routing_instance))
91  flags &= ~BgpPath::LlgrStale;
92  if (!flags)
93  break;
94  }
95 
96  return flags;
97 }
98 
100  const RouteTarget &rtarget,
101  BgpAttrPtr attr, bool add_change,
102  uint32_t flags) const {
103  if (add_change && delete_in_progress())
104  return;
105 
106  DBRequest req;
107  RTargetPrefix rt_prefix(asn, rtarget);
108  req.key.reset(new RTargetTable::RequestKey(rt_prefix, Peer()));
109  if (add_change) {
110  // Find correct rtarget route flags if not already known.
111  if (!flags)
112  flags = GetRTargetRouteFlag(rtarget);
113  req.data.reset(new RTargetTable::RequestData(attr, flags, 0, 0, 0));
115  } else {
117  }
118  Enqueue(&req);
119 }
120 
122  as_t old_local_asn) const {
123  if (local_autonomous_system() == (int)old_local_asn)
124  return;
125  if (IsSubscriptionEmpty())
126  return;
127 
128  // Delete the route and add with new local ASN
130  for (PublishedRTargetRoutes::const_iterator it = rtarget_routes_.begin();
131  it != rtarget_routes_.end(); it++) {
132  RTargetRouteOp(old_local_asn, it->first, NULL, false);
133  RTargetRouteOp(local_autonomous_system(), it->first, attr, true);
134  }
135 }
136 
138  const RouteTarget &rtarget, BgpAttrPtr attr) {
139  PublishedRTargetRoutes::iterator rt_loc = rtarget_routes_.find(rtarget);
140  if (rt_loc == rtarget_routes_.end()) {
141  pair<PublishedRTargetRoutes::iterator, bool> ret =
142  rtarget_routes_.insert(make_pair(rtarget, RoutingInstanceList()));
143 
144  rt_loc = ret.first;
145 
146  // Send rtarget route ADD
147  RTargetRouteOp(local_autonomous_system(), rtarget, attr, true);
148  }
149  rt_loc->second.insert(rtinstance);
150 }
151 
153  RoutingInstance *rtinstance, const RouteTarget &rtarget) {
154  PublishedRTargetRoutes::iterator rt_loc = rtarget_routes_.find(rtarget);
155  assert(rt_loc != rtarget_routes_.end());
156  assert(rt_loc->second.erase(rtinstance));
157  if (rt_loc->second.empty()) {
158  rtarget_routes_.erase(rtarget);
159  // Send rtarget route DELETE
160  RTargetRouteOp(local_autonomous_system(), rtarget, NULL, false);
161  }
162 }
163 
165  RoutingInstance *rt_instance, RouteTargetList *targets) {
166  // Import list in the routing instance
167  const RouteTargetList &new_list = rt_instance->GetImportList();
168 
169  // Previous route target list for which the rtarget route was added
170  RouteTargetList *current = targets;
171  RouteTargetList::iterator cur_next_it, cur_it;
172  cur_it = cur_next_it = current->begin();
173  RouteTargetList::const_iterator new_it = new_list.begin();
174 
175  pair<RouteTargetList::iterator, bool> r;
177  while (cur_it != current->end() && new_it != new_list.end()) {
178  if (*new_it < *cur_it) {
179  r = current->insert(*new_it);
180  assert(r.second);
181  AddNewRTargetRoute(rt_instance, *new_it, attr);
182  new_it++;
183  } else if (*new_it > *cur_it) {
184  cur_next_it++;
185  DeleteRTargetRoute(rt_instance, *cur_it);
186  current->erase(cur_it);
187  cur_it = cur_next_it;
188  } else {
189  // Update
190  cur_it++;
191  new_it++;
192  }
193  cur_next_it = cur_it;
194  }
195  for (; new_it != new_list.end(); ++new_it) {
196  r = current->insert(*new_it);
197  assert(r.second);
198  AddNewRTargetRoute(rt_instance, *new_it, attr);
199  }
200  for (cur_next_it = cur_it;
201  cur_it != current->end();
202  cur_it = cur_next_it) {
203  cur_next_it++;
204  DeleteRTargetRoute(rt_instance, *cur_it);
205  current->erase(cur_it);
206  }
207 }
208 
210  RoutingInstance *routing_instance, const RouteTargetList &targets,
211  uint32_t flags) const {
213  BOOST_FOREACH(RouteTarget rtarget, targets) {
214  // Update route target route [llgr-]stale flag status.
215  RTargetRouteOp(local_autonomous_system(), rtarget, attr, true, flags);
216  }
217 }
218 
220  if (rtarget_routes_.empty())
221  return;
222 
223  for (PublishedRTargetRoutes::iterator it = rtarget_routes_.begin();
224  it != rtarget_routes_.end(); it++) {
225  RTargetRouteOp(local_autonomous_system(), it->first, NULL, false);
226  }
227  rtarget_routes_.clear();
228 }
229 
230 void BgpXmppRTargetManager::Stale(const RouteTargetList &targets) const {
232 
233  // Update route targets to clear STALE flag.
234  BOOST_FOREACH(RouteTarget rtarget, targets) {
235  PublishedRTargetRoutes::const_iterator rt_loc =
236  rtarget_routes_.find(rtarget);
237  assert(rt_loc != rtarget_routes_.end());
238 
239  // Send rtarget route ADD
240  RTargetRouteOp(local_autonomous_system(), rtarget, attr, true);
241  }
242 }
243 
244 // Add/Delete rtarget route for import route target of the routing instance.
246  bool add_change) {
247  if (IsSubscriptionEmpty())
248  return;
249 
250  if (add_change) {
251  BOOST_FOREACH(RouteTarget rtarget, GetSubscribedRTargets(rt_instance)) {
252  AddNewRTargetRoute(rt_instance, rtarget, GetRouteTargetRouteAttr());
253  }
254  } else {
255  BOOST_FOREACH(RouteTarget rtarget, GetSubscribedRTargets(rt_instance)) {
256  DeleteRTargetRoute(rt_instance, rtarget);
257  }
258  }
259 }
260 
261 void BgpXmppRTargetManager::FillInfo(BgpNeighborRoutingInstance *instance,
262  const RouteTargetList &targets) const {
263  vector<string> import_targets;
264  BOOST_FOREACH(RouteTarget rt, targets) {
265  import_targets.push_back(rt.ToString());
266  }
267  instance->set_import_targets(import_targets);
268 }
virtual const RouteTargetList & GetSubscribedRTargets(RoutingInstance *instance) const
const RouteTargetList & GetImportList() const
BgpTable * GetTable(Address::Family fmly)
TypePtr Locate(Type *attr)
virtual bool IsSubscriptionGrStale(RoutingInstance *instance) const
virtual bool IsSubscriptionLlgrStale(RoutingInstance *instance) const
void AddNewRTargetRoute(RoutingInstance *rtinstance, const RouteTarget &rtarget, BgpAttrPtr attr)
BgpXmppChannel * bgp_xmpp_channel_
std::unique_ptr< DBRequestData > data
Definition: db_table.h:49
virtual void Enqueue(DBRequest *req) const
RoutingInstanceMgr * routing_instance_mgr()
Definition: bgp_server.h:102
bool IsSubscriptionEmpty() const
bool Enqueue(DBRequest *req)
Definition: db_table.cc:194
std::vector< BgpAttribute * > BgpAttrSpec
Definition: bgp_attr.h:822
RoutingInstance * GetDefaultRoutingInstance()
void FillInfo(BgpNeighborRoutingInstance *instance, const RouteTargetList &targets) const
std::set< RouteTarget > RouteTargetList
virtual BgpAttrPtr GetRouteTargetRouteAttr() const
const RoutingInstance::RouteTargetList & GetSubscribedRTargets(RoutingInstance *instance) const
virtual int local_autonomous_system() const
PublishedRTargetRoutes rtarget_routes_
uint32_t as_t
Definition: bgp_common.h:21
void Stale(const RouteTargetList &targets) const
Definition: ipeer.h:186
as_t local_autonomous_system() const
Definition: bgp_server.h:207
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
std::unique_ptr< DBRequestKey > key
Definition: db_table.h:48
bool delete_in_progress() const
DBOperation oper
Definition: db_table.h:42
std::set< RoutingInstance * > RoutingInstanceList
void ASNUpdateCallback(as_t old_asn, as_t old_local_asn) const
BgpServer * bgp_server()
BgpXmppRTargetManager(BgpXmppChannel *bgp_xmpp_channel)
uint32_t bgp_identifier() const
Definition: bgp_server.h:208
virtual void RTargetRouteOp(as_t asn, const RouteTarget &rtarget, BgpAttrPtr attr, bool add_change, uint32_t flags=0) const
BgpAttrDB * attr_db()
Definition: bgp_server.h:181
bool IsSubscriptionLlgrStale(RoutingInstance *instance) const
std::string ToString() const
bool IsSubscriptionGrStale(RoutingInstance *instance) const
virtual bool delete_in_progress() const
virtual const IPeer * Peer() const
void RoutingInstanceCallback(RoutingInstance *rt_instance, RouteTargetList *targets)
void DeleteRTargetRoute(RoutingInstance *rtinstance, const RouteTarget &rtarget)
virtual bool IsSubscriptionEmpty() const
void UpdateRouteTargetRouteFlag(RoutingInstance *routing_instance, const RouteTargetList &targets, uint32_t flags) const
void PublishRTargetRoute(RoutingInstance *rt_instance, bool add_change)
uint32_t GetRTargetRouteFlag(const RouteTarget &rtarget) const