OpenSDN source code
routing_policy.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved.
3  * Copyright Contributors to the OpenSDN project
4  */
5 
7 
8 #include <boost/assign/list_of.hpp>
9 #include <boost/foreach.hpp>
10 
11 #include "base/task_annotations.h"
12 #include "base/task_trigger.h"
13 #include "bgp/bgp_config.h"
14 #include "bgp/bgp_factory.h"
15 #include "bgp/bgp_server.h"
16 #include "bgp/bgp_table.h"
20 
21 
23 public:
24  explicit DeleteActor(RoutingPolicyMgr *manager)
25  : LifetimeActor(manager->server_->lifetime_manager()),
26  manager_(manager) {
27  }
28  virtual bool MayDelete() const {
29  return true;
30  }
31  virtual void Shutdown() {
32  }
33  virtual void Destroy() {
34  // memory is deallocated by BgpServer scoped_ptr.
36  }
37 
38 private:
40 };
41 
43  server_(server),
44  deleter_(new DeleteActor(this)),
45  server_delete_ref_(this, server->deleter()),
46  trace_buf_(SandeshTraceBufferCreate("RoutingPolicyMgr", 500)) {
47 }
48 
50 }
51 
53  deleter_->Delete();
54 }
55 
57  return deleter_.get();
58 }
59 
61  return deleter()->IsDeleted();
62 }
63 
65  const BgpRoutingPolicyConfig *config) {
66  RoutingPolicy *policy = GetRoutingPolicy(config->name());
67 
68  if (policy) {
69  if (policy->deleted()) {
70  return NULL;
71  }
72  return policy;
73  }
74 
75  policy = BgpStaticObjectFactory::Create<RoutingPolicy>(
76  config->name(), server_, this, config);
77  routing_policies_.insert(std::make_pair(config->name(), policy));
78  policy->ProcessConfig();
79 
80  return policy;
81 }
82 
84  const BgpRoutingPolicyConfig *config) {
85  CHECK_CONCURRENCY("bgp::Config");
86 
87  RoutingPolicy *policy = GetRoutingPolicy(config->name());
88  if (policy && policy->deleted()) {
89  return;
90  } else if (!policy) {
91  return;
92  }
93 
94  policy->UpdateConfig(config);
95 }
96 
97 //
98 // Concurrency: BGP Config task
99 //
100 // Trigger deletion of a particular routing-policy
101 //
102 void RoutingPolicyMgr::DeleteRoutingPolicy(const std::string &name) {
103  CHECK_CONCURRENCY("bgp::Config");
104 
105  RoutingPolicy *policy = GetRoutingPolicy(name);
106 
107  if (policy && policy->deleted()) {
108  return;
109  } else if (!policy) {
110  return;
111  }
112 
113  policy->ClearConfig();
114 
115  policy->ManagedDelete();
116 }
117 
118 //
119 // Concurrency: Called from BGP config task manager
120 //
122  CHECK_CONCURRENCY("bgp::Config");
123 
124  const std::string name = policy->name();
125  routing_policies_.erase(name);
126  delete policy;
127 
128  if (deleted()) return;
129 
130  const BgpRoutingPolicyConfig *config
132  if (config) {
133  CreateRoutingPolicy(config);
134  return;
135  }
136 }
137 
138 // Given a routing instance re-evaluate routes/paths by applying routing policy
139 // Walks all the tables of the given routing instance and apply the policy
140 // This function puts the table into the walk request queue and triggers the
141 // task to start the actual walk
143  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
144 
145  std::scoped_lock lock(mutex_);
146  BOOST_FOREACH(RoutingInstance::RouteTableList::value_type &entry,
147  instance->GetTables()) {
148  BgpTable *table = entry.second;
149  if (table->IsRoutingPolicySupported())
150  RequestWalk(table);
151  }
152 }
153 
154 // On a given path of the route, apply the policy
156  const RoutingPolicy *policy, const BgpRoute *route,
157  const BgpPath *path, BgpAttr *attr) const {
158  return (*policy)(route, path, attr);
159 }
160 
161 //
162 // Concurrency: Called in the context of the DB partition task.
163 // On a given route, apply routing policy
164 // Walk through all the paths of the given route, and evaluate the result of the
165 // routing policy
166 //
168  DBEntryBase *entry) {
169  CHECK_CONCURRENCY("db::DBTable");
170 
171  BgpTable *table = static_cast<BgpTable *>(root->parent());
172  BgpRoute *route = static_cast<BgpRoute *>(entry);
173  const RoutingInstance *rtinstance = table->routing_instance();
174  if (route->IsDeleted()) return true;
175 
176  bool sort_and_notify = false;
177  const Path *prev_front = route->front();
178  for (Route::PathList::iterator it = route->GetPathList().begin();
179  it != route->GetPathList().end(); ++it) {
180  BgpPath *path = static_cast<BgpPath *>(it.operator->());
181  uint32_t old_flags = path->GetFlags();
182  const BgpAttr *old_attr = path->GetAttr();
183  rtinstance->ProcessRoutingPolicy(route, path);
184  if ((sort_and_notify == false) &&
185  (old_flags != path->GetFlags() || old_attr != path->GetAttr())) {
186  sort_and_notify = true;
187  }
188  }
189 
190  if (sort_and_notify) {
191  route->Sort(&BgpTable::PathSelection, prev_front);
192  root->Notify(entry);
193  }
194  return true;
195 }
196 
197 //
198 //
200  const RoutingPolicyConfigList &cfg_list,
201  RoutingPolicyAttachList *oper_list) {
202  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
203 
204  std::scoped_lock lock(mutex_);
205  bool update_policy = false;
206  // Number of routing policies is different
207  if (oper_list->size() != cfg_list.size())
208  update_policy = true;
209 
210  RoutingPolicyAttachList::iterator oper_it = oper_list->begin(), oper_next;
211  RoutingPolicyConfigList::const_iterator config_it = cfg_list.begin();
212  while (oper_it != oper_list->end() &&
213  config_it != cfg_list.end()) {
214  // Compare the configured routing policies on the routing-instance
215  // with operational data.
216  if (oper_it->first->name() == config_it->routing_policy_) {
217  if (oper_it->second != oper_it->first->generation()) {
218  // Policy content is updated
219  oper_it->second = oper_it->first->generation();
220  update_policy = true;
221  }
222  ++oper_it;
223  ++config_it;
224  } else {
225  // Policy Order is updated or new policy is added
226  // or policy is deleted
227  RoutingPolicy *policy =
228  GetRoutingPolicy(config_it->routing_policy_);
229  if (policy) {
230  *oper_it = std::make_pair(policy, policy->generation());
231  ++oper_it;
232  ++config_it;
233  update_policy = true;
234  } else {
235  // points to routing policy that doesn't exists
236  // will revisit in next config notification
237  ++config_it;
238  }
239  }
240  }
241  for (oper_next = oper_it; oper_it != oper_list->end();
242  oper_it = oper_next) {
243  // Existing policy(ies) are removed
244  ++oper_next;
245  oper_list->erase(oper_it);
246  update_policy = true;
247  }
248  for (; config_it != cfg_list.end(); ++config_it) {
249  // new policy(ies) are added
250  RoutingPolicy *policy = GetRoutingPolicy(config_it->routing_policy_);
251  if (policy) {
252  oper_list->push_back(std::make_pair(policy, policy->generation()));
253  }
254  update_policy = true;
255  }
256 
257  return update_policy;
258 }
259 
260 void
262  CHECK_CONCURRENCY("bgp::Config", "bgp::ConfigHelper");
263  RoutingPolicyWalkRequests::iterator it = routing_policy_sync_.find(table);
264  if (it == routing_policy_sync_.end()) {
265  DBTable::DBTableWalkRef walk_ref = table->AllocWalker(
266  boost::bind(&RoutingPolicyMgr::EvaluateRoutingPolicy, this, _1, _2),
267  boost::bind(&RoutingPolicyMgr::WalkDone, this, _2));
268  table->WalkTable(walk_ref);
269  routing_policy_sync_.insert(std::make_pair(table, walk_ref));
270  } else {
271  table->WalkAgain(it->second);
272  }
273 }
274 
275 void
277  CHECK_CONCURRENCY("db::Walker");
278  BgpTable *table = static_cast<BgpTable *>(dbtable);
279  RoutingPolicyWalkRequests::iterator it = routing_policy_sync_.find(table);
280  assert(it != routing_policy_sync_.end());
281  DBTable::DBTableWalkRef walk_ref = it->second;
282  routing_policy_sync_.erase(it);
283  table->ReleaseWalker(walk_ref);
284 }
285 
287 public:
289  : LifetimeActor(server->lifetime_manager()), parent_(parent) {
290  }
291  virtual bool MayDelete() const {
292  return parent_->MayDelete();
293  }
294  virtual void Shutdown() {
295  parent_->Shutdown();
296  }
297  virtual void Destroy() {
299  }
300 
301 private:
303 };
304 
305 RoutingPolicy::RoutingPolicy(std::string name, BgpServer *server,
306  RoutingPolicyMgr *mgr,
307  const BgpRoutingPolicyConfig *config)
308  : name_(name), server_(server), mgr_(mgr), config_(config),
309  deleter_(new DeleteActor(server, this)),
310  manager_delete_ref_(this, mgr->deleter()), generation_(0) {
311  refcount_ = 0;
312 }
313 
315  terms_.clear();
316 }
317 
319  const RoutingPolicyTermConfig &cfg_term) {
320  PolicyTerm::ActionList actions;
321  PolicyTerm::MatchList matches;
322 
323  if (!cfg_term.match.community_match.empty()) {
324  MatchCommunity *community = new MatchCommunity(
325  cfg_term.match.community_match,
326  cfg_term.match.community_match_all);
327  matches.push_back(community);
328  }
329 
330  if (!cfg_term.match.ext_community_match.empty()) {
331  MatchExtCommunity *ext_community = new MatchExtCommunity(
332  cfg_term.match.ext_community_match,
333  cfg_term.match.ext_community_match_all);
334  matches.push_back(ext_community);
335  }
336 
337  if (!cfg_term.match.protocols_match.empty()) {
338  MatchProtocol *protocol =
339  new MatchProtocol(cfg_term.match.protocols_match);
340  matches.push_back(protocol);
341  }
342 
343  if (!cfg_term.match.prefixes_to_match.empty()) {
344  PrefixMatchConfigList inet_prefix_list;
345  PrefixMatchConfigList inet6_prefix_list;
346  BOOST_FOREACH(PrefixMatchConfig match,
347  cfg_term.match.prefixes_to_match) {
348  boost::system::error_code ec;
349  Ip4Address ip4;
350  int plen;
351  ec = Ip4PrefixParse(match.prefix_to_match, &ip4, &plen);
352  if (ec.value() == 0) {
353  inet_prefix_list.push_back(match);
354  } else {
355  Ip6Address ip6;
356  ec = Inet6PrefixParse(match.prefix_to_match, &ip6, &plen);
357  if (ec.value() == 0) {
358  inet6_prefix_list.push_back(match);
359  }
360  }
361  }
362  if (!inet_prefix_list.empty()) {
363  MatchPrefixInet *prefix = new MatchPrefixInet(inet_prefix_list);
364  matches.push_back(prefix);
365  }
366  if (!inet6_prefix_list.empty()) {
367  MatchPrefixInet6 *prefix = new MatchPrefixInet6(inet6_prefix_list);
368  matches.push_back(prefix);
369  }
370  }
371 
372  // Build the Action object
375  actions.push_back(action);
376  } else if (cfg_term.action.action == RoutingPolicyActionConfig::NEXT_TERM) {
378  actions.push_back(action);
379  } else if (cfg_term.action.action == RoutingPolicyActionConfig::ACCEPT) {
381  actions.push_back(action);
382  }
383 
384  if (!cfg_term.action.update.aspath_expand.empty()) {
385  UpdateAsPath *expand_aspath =
386  new UpdateAsPath(cfg_term.action.update.aspath_expand);
387  actions.push_back(expand_aspath);
388  }
389 
390  if (!cfg_term.action.update.community_set.empty()) {
391  UpdateCommunity *set_comm =
392  new UpdateCommunity(cfg_term.action.update.community_set, "set");
393  actions.push_back(set_comm);
394  }
395 
396  if (!cfg_term.action.update.community_remove.empty()) {
397  UpdateCommunity *remove_comm =
398  new UpdateCommunity(cfg_term.action.update.community_remove, "remove");
399  actions.push_back(remove_comm);
400  }
401 
402  if (!cfg_term.action.update.community_add.empty()) {
403  UpdateCommunity *add_comm =
404  new UpdateCommunity(cfg_term.action.update.community_add, "add");
405  actions.push_back(add_comm);
406  }
407 
408  if (!cfg_term.action.update.ext_community_set.empty()) {
409  UpdateExtCommunity *set_comm = new UpdateExtCommunity(
410  cfg_term.action.update.ext_community_set, "set");
411  actions.push_back(set_comm);
412  }
413 
414  if (!cfg_term.action.update.ext_community_remove.empty()) {
415  UpdateExtCommunity *remove_comm = new UpdateExtCommunity(
416  cfg_term.action.update.ext_community_remove, "remove");
417  actions.push_back(remove_comm);
418  }
419 
420  if (!cfg_term.action.update.ext_community_add.empty()) {
421  UpdateExtCommunity *add_comm = new UpdateExtCommunity(
422  cfg_term.action.update.ext_community_add, "add");
423  actions.push_back(add_comm);
424  }
425 
426  if (cfg_term.action.update.local_pref) {
427  UpdateLocalPref *local_pref =
428  new UpdateLocalPref(cfg_term.action.update.local_pref);
429  actions.push_back(local_pref);
430  }
431 
432  if (cfg_term.action.update.med) {
433  UpdateMed *med =
434  new UpdateMed(cfg_term.action.update.med);
435  actions.push_back(med);
436  }
437 
438  PolicyTermPtr ret_term;
439  if (!actions.empty() || !matches.empty()) {
440  ret_term = PolicyTermPtr(new PolicyTerm());
441  ret_term->set_actions(actions);
442  ret_term->set_matches(matches);
443  }
444 
445  return ret_term;
446 }
447 
449  BOOST_FOREACH(const RoutingPolicyTermConfig cfg_term, config_->terms()) {
450  // Build each terms and insert to operational data
451  PolicyTermPtr term = BuildTerm(cfg_term);
452  if (term)
453  add_term(term);
454  }
455 }
456 
457 //
458 // Reprogram policy terms based on new config.
459 // If the policy term has changed (number of terms got updated, or new term is
460 // added or earlier term is deleted or existing term is updated), increment the
461 // generation number to indicate the update
462 //
464  CHECK_CONCURRENCY("bgp::Config");
465  config_ = cfg;
466  bool update_policy = false;
467  if (terms()->size() != config_->terms().size())
468  update_policy = true;
469 
470  RoutingPolicyTermList::iterator oper_it = terms()->begin(), oper_next;
471  BgpRoutingPolicyConfig::RoutingPolicyTermList::const_iterator
472  config_it = config_->terms().begin();
473  while (oper_it != terms()->end() && config_it != config_->terms().end()) {
474  PolicyTermPtr term = BuildTerm(*config_it);
475  if (**oper_it == *term) {
476  ++oper_it;
477  ++config_it;
478  } else {
479  if (term) {
480  *oper_it = term;
481  update_policy = true;
482  ++oper_it;
483  ++config_it;
484  } else {
485  ++config_it;
486  }
487  }
488  }
489  for (oper_next = oper_it; oper_it != terms()->end(); oper_it = oper_next) {
490  ++oper_next;
491  terms()->erase(oper_it);
492  update_policy = true;
493  }
494  for (; config_it != config_->terms().end(); ++config_it) {
495  PolicyTermPtr term = BuildTerm(*config_it);
496  if (term)
497  add_term(term);
498  update_policy = true;
499  }
500 
501  if (update_policy) generation_++;
502 }
503 
505  CHECK_CONCURRENCY("bgp::Config");
506  config_ = NULL;
507 }
508 
510  deleter_->Delete();
511 }
512 
514  CHECK_CONCURRENCY("bgp::Config");
515  ClearConfig();
516 }
517 
519  return (refcount_ == 0);
520 }
521 
523  return deleter_.get();
524 }
525 
527  return deleter_.get();
528 }
529 
531  return deleter()->IsDeleted();
532 }
533 
534 //
535 // Attempt to enqueue a delete for the RoutingPolicy.
536 //
538  if (!deleter_->IsDeleted())
539  return;
540  deleter_->RetryDelete();
541 }
542 
544  const BgpPath *path, BgpAttr *attr) const {
545  BOOST_FOREACH(PolicyTermPtr term, terms()) {
546  bool terminal = term->terminal();
547  bool matched = term->ApplyTerm(route, path, attr);
548  if (matched && terminal) {
549  return std::make_pair(terminal,
550  (*term->actions().begin())->accept());
551  }
552  }
553  return std::make_pair(false, true);
554 }
555 
557 }
558 
562 }
563 
564 bool PolicyTerm::terminal() const {
565  if (!actions().empty())
566  return (*actions().begin())->terminal();
567  return false;
568 }
569 
570 bool PolicyTerm::ApplyTerm(const BgpRoute *route, const BgpPath *path,
571  BgpAttr *attr) const {
572  bool matched = true;
573  BOOST_FOREACH(RoutingPolicyMatch *match, matches()) {
574  if (!(*match)(route, path, attr)) {
575  matched = false;
576  break;
577  }
578  }
579  if (matched) {
580  bool first = true;
581  BOOST_FOREACH(RoutingPolicyAction *action, actions()) {
582  // First action defines what to do with the route
583  // accept/reject/next-term
584  if (first) {
585  if (action->terminal()) {
586  if (!action->accept()) {
587  // out_attr is unaltered
588  break;
589  }
590  }
591  first = false;
592  } else {
593  RoutingPolicyUpdateAction *update =
594  static_cast<RoutingPolicyUpdateAction *>(action);
595  (*update)(attr);
596  }
597  }
598  }
599  return matched;
600 }
601 
602 // Compare two terms
603 bool PolicyTerm::operator==(const PolicyTerm &rhs) const {
604  // Different number of match conditions
605  if (matches().size() != rhs.matches().size()) return false;
606  // Different number of actions conditions
607  if (actions().size() != rhs.actions().size()) return false;
608 
609  // Walk the list of match conditions and compare each match
610  for (MatchList::const_iterator rhs_matches_cit = rhs.matches().begin(),
611  lhs_matches_cit = matches().begin();
612  lhs_matches_cit != matches().end();
613  lhs_matches_cit++, rhs_matches_cit++) {
614  if (**rhs_matches_cit != **lhs_matches_cit)
615  return false;
616  }
617 
618  // Walk the list of actions and compare each action
619  for (ActionList::const_iterator lhs_actions_cit = actions().begin(),
620  rhs_actions_cit = rhs.actions().begin();
621  lhs_actions_cit != actions().end();
622  lhs_actions_cit++, rhs_actions_cit++) {
623  if (**rhs_actions_cit != **lhs_actions_cit)
624  return false;
625  }
626  return true;
627 }
boost::system::error_code Inet6PrefixParse(const string &str, Ip6Address *addr, int *plen)
Definition: address.cc:145
boost::system::error_code Ip4PrefixParse(const string &str, Ip4Address *addr, int *plen)
Definition: address.cc:108
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:16
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:15
std::vector< RoutingPolicyAttachInfo > RoutingPolicyConfigList
Definition: bgp_common.h:41
std::list< RoutingPolicyInfo > RoutingPolicyAttachList
Definition: bgp_common.h:48
std::vector< PrefixMatchConfig > PrefixMatchConfigList
Definition: bgp_config.h:359
virtual const BgpRoutingPolicyConfig * FindRoutingPolicy(const std::string &name) const =0
uint32_t GetFlags() const
Definition: bgp_path.h:101
const BgpAttr * GetAttr() const
Definition: bgp_path.h:88
const std::string & name() const
Definition: bgp_config.h:406
const RoutingPolicyTermList & terms() const
Definition: bgp_config.h:411
BgpConfigManager * config_manager()
Definition: bgp_server.h:105
RoutingInstance * routing_instance()
Definition: bgp_table.h:148
static bool PathSelection(const Path &path1, const Path &path2)
Definition: bgp_table.cc:825
virtual bool IsRoutingPolicySupported() const
Definition: bgp_table.h:111
bool IsDeleted() const
Definition: db_entry.h:49
DBTableBase * parent()
void Notify(DBEntryBase *entry)
void WalkAgain(DBTableWalkRef walk)
Definition: db_table.cc:658
DBTableWalkRef AllocWalker(WalkFn walk_fn, WalkCompleteFn walk_complete)
Definition: db_table.cc:640
void WalkTable(DBTableWalkRef walk)
Definition: db_table.cc:652
void ReleaseWalker(DBTableWalkRef &walk)
Definition: db_table.cc:646
boost::intrusive_ptr< DBTableWalk > DBTableWalkRef
Definition: db_table.h:170
bool IsDeleted() const
Definition: lifetime.h:132
void Reset(LifetimeActor *actor)
Definition: lifetime.h:83
Definition: path.h:11
std::vector< RoutingPolicyMatch * > MatchList
MatchList matches_
std::vector< RoutingPolicyAction * > ActionList
autogen::PolicyAction action
bool terminal() const
bool operator==(const PolicyTerm &term) const
ActionList actions_
const MatchList & matches() const
const ActionList & actions() const
bool ApplyTerm(const BgpRoute *route, const BgpPath *path, BgpAttr *attr) const
autogen::PolicyMatch match
void Sort(Compare compare, const Path *prev_front)
Definition: route.cc:41
const PathList & GetPathList() const
Definition: route.h:47
const Path * front() const
Definition: route.cc:17
bool ProcessRoutingPolicy(const BgpRoute *route, BgpPath *path) const
RouteTableList & GetTables()
virtual bool MayDelete() const
DeleteActor(RoutingPolicyMgr *manager)
void DestroyRoutingPolicy(RoutingPolicy *policy)
bool EvaluateRoutingPolicy(DBTablePartBase *root, DBEntryBase *entry)
void UpdateRoutingPolicy(const BgpRoutingPolicyConfig *config)
bool UpdateRoutingPolicyList(const RoutingPolicyConfigList &cfg_list, RoutingPolicyAttachList *oper_list)
BgpServer * server_
RoutingPolicyWalkRequests routing_policy_sync_
void ApplyRoutingPolicy(RoutingInstance *instance)
LifetimeRef< RoutingPolicyMgr > server_delete_ref_
RoutingPolicyList routing_policies_
boost::scoped_ptr< DeleteActor > deleter_
RoutingPolicy::PolicyResult ExecuteRoutingPolicy(const RoutingPolicy *policy, const BgpRoute *route, const BgpPath *path, BgpAttr *attr) const
void RequestWalk(BgpTable *table)
void WalkDone(DBTableBase *dbtable)
virtual RoutingPolicy * CreateRoutingPolicy(const BgpRoutingPolicyConfig *config)
virtual ~RoutingPolicyMgr()
virtual void DeleteRoutingPolicy(const std::string &name)
RoutingPolicyMgr(BgpServer *server)
RoutingPolicy * GetRoutingPolicy(const std::string &name)
BgpServer * server()
LifetimeActor * deleter()
DeleteActor(BgpServer *server, RoutingPolicy *parent)
virtual bool MayDelete() const
BgpServer * server()
const std::string & name() const
RoutingPolicyTermList * terms()
uint32_t generation() const
void UpdateConfig(const BgpRoutingPolicyConfig *config)
virtual ~RoutingPolicy()
bool deleted() const
LifetimeActor * deleter()
PolicyTermPtr BuildTerm(const RoutingPolicyTermConfig &term)
const BgpRoutingPolicyConfig * config_
PolicyResult operator()(const BgpRoute *route, const BgpPath *path, BgpAttr *attr) const
RoutingPolicyTermList terms_
uint32_t generation_
void add_term(PolicyTermPtr term)
RoutingPolicy(std::string name, BgpServer *server, RoutingPolicyMgr *mgr, const BgpRoutingPolicyConfig *config)
bool MayDelete() const
std::pair< bool, bool > PolicyResult
RoutingPolicyMgr * mgr_
std::atomic< uint32_t > refcount_
boost::shared_ptr< PolicyTerm > PolicyTermPtr
boost::scoped_ptr< DeleteActor > deleter_
static ExtCommunityPtr UpdateExtCommunity(BgpServer *server, const RoutingInstance *rtinstance, const ExtCommunity *ext_community, const ExtCommunity::ExtCommunityList &export_list)
MatchPrefix< PrefixMatchInet6 > MatchPrefixInet6
MatchPrefix< PrefixMatchInet > MatchPrefixInet
SandeshTraceBufferPtr SandeshTraceBufferCreate(const std::string &buf_name, size_t buf_size, bool trace_enable=true)
Definition: sandesh_trace.h:47
CommunityList ext_community_set
Definition: bgp_config.h:376
CommunityList ext_community_add
Definition: bgp_config.h:377
CommunityList community_set
Definition: bgp_config.h:373
uint32_t local_pref
Definition: bgp_config.h:379
CommunityList community_remove
Definition: bgp_config.h:375
AsnList aspath_expand
Definition: bgp_config.h:372
CommunityList ext_community_remove
Definition: bgp_config.h:378
uint32_t med
Definition: bgp_config.h:380
CommunityList community_add
Definition: bgp_config.h:374
std::string prefix_to_match
Definition: bgp_config.h:355
ProtocolList protocols_match
Definition: bgp_config.h:362
CommunityList community_match
Definition: bgp_config.h:364
PrefixMatchConfigList prefixes_to_match
Definition: bgp_config.h:363
CommunityList ext_community_match
Definition: bgp_config.h:366
RoutingPolicyMatchConfig match
Definition: bgp_config.h:395
RoutingPolicyActionConfig action
Definition: bgp_config.h:396
#define CHECK_CONCURRENCY(...)
void STLDeleteValues(Container *container)
Definition: util.h:102