OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tsn_elector.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include <boost/uuid/uuid_io.hpp>
6 #include <cmn/agent_cmn.h>
7 
8 #include <base/logging.h>
9 #include <init/agent_param.h>
10 #include <oper/operdb_init.h>
11 #include <oper/route_common.h>
12 #include <oper/vrf.h>
13 #include <oper/tsn_elector.h>
14 #include <oper/bridge_route.h>
17 #include <oper/nexthop.h>
18 #include <oper/multicast.h>
19 
20 using namespace std;
21 
23  TsnElector *elector) :
24  inet4_table_(inet4_table) {
25  inet4_id_ = inet4_table->Register(boost::bind(&TsnElector::RouteNotify,
26  elector, _1, _2));
27 }
28 
31 }
32 
33 TsnElectorWalker::TsnElectorWalker(const std::string &name, Agent *agent) :
34  AgentRouteWalker(name, agent) {
35 }
36 
38 }
39 
41  DBEntryBase *e) {
42  BridgeRouteEntry *bridge_entry =
43  dynamic_cast<BridgeRouteEntry*>(e);
44  if (!bridge_entry || !bridge_entry->is_multicast())
45  return true;
46 
47  AgentPath *evpn_path = NULL;
48  for (Route::PathList::iterator it = bridge_entry->GetPathList().begin();
49  it != bridge_entry->GetPathList().end(); it++) {
50  AgentPath *path = static_cast<AgentPath *>(it.operator->());
51  if (path->peer()->GetType() != Peer::BGP_PEER)
52  continue;
53  const CompositeNH *cnh = dynamic_cast<const CompositeNH *>(path->nexthop());
54  if (!cnh)
55  continue;
56 
57  if (cnh->composite_nh_type() != Composite::EVPN)
58  continue;
59 
60  if (!evpn_path)
61  evpn_path = path;
62  path->set_inactive(!master_);
63  }
64 
65  if (evpn_path && bridge_entry->ReComputePathAdd(evpn_path))
66  partition->Notify(bridge_entry);
67  return true;
68 }
69 
71  master_ = false;
72  StartVrfWalk();
73 }
74 
76  master_ = true;
77  StartVrfWalk();
78 }
79 
80 TsnElector::TsnElector(Agent *agent) : agent_(agent),
81  vrf_listener_id_(), active_tsn_servers_() {
83  walker_.reset(new TsnElectorWalker("TsnElectorWalker", agent));
84  }
85 }
86 
88 }
89 
91  return (agent_->params()->agent_mode() ==
93 }
94 
97  return;
99  boost::bind(&TsnElector::Notify, this, _1, _2));
101  RegisterWalker(static_cast<AgentRouteWalker *>(walker_.get()));
102 }
103 
105  VrfEntry *vrf = dynamic_cast<VrfEntry *>(e);
106  TsnElectorState *state = dynamic_cast<TsnElectorState *>(vrf->
107  GetState(partition->parent(), vrf_listener_id_));
108  if (vrf->GetName().compare(agent_->fabric_policy_vrf_name()) != 0)
109  return;
110 
111  if (vrf->IsDeleted()) {
112  if (state) {
113  vrf->ClearState(partition->parent(), vrf_listener_id_);
114  delete state;
115  }
116  return;
117  }
118 
119  if (!state) {
120  state = new TsnElectorState(vrf->GetInet4UnicastRouteTable(), this);
121  vrf->SetState(partition->parent(), vrf_listener_id_, state);
122  }
123  return;
124 }
125 
127  const InetUnicastRouteEntry *rt =
128  static_cast<const InetUnicastRouteEntry*>(e);
129 
130  if (!agent_->params()->IsConfiguredTsnHostRoute(rt->prefix_address().to_string()))
131  return;
132 
133  const string rt_addr_str = rt->GetAddressString();
134  std::vector<std::string>::iterator it =
135  std::find(active_tsn_servers_.begin(), active_tsn_servers_.end(),
136  rt_addr_str);
137  std::string master = "";
138  if (!active_tsn_servers_.empty()) {
139  master = active_tsn_servers_.front();
140  }
141  if (rt->IsDeleted()) {
142  if (it == active_tsn_servers_.end())
143  return;
144  active_tsn_servers_.erase(it);
145  } else {
146  if (it != active_tsn_servers_.end())
147  return;
148  active_tsn_servers_.push_back(rt_addr_str);
149  }
150  std::sort(active_tsn_servers_.begin(), active_tsn_servers_.end());
151  std::string new_master = "";
152  if (!active_tsn_servers_.empty()) {
153  new_master = active_tsn_servers_.front();
154  }
155  if (master == new_master)
156  return;
157 
158  std::string vhost_addr = agent_->params()->vhost_addr().to_string();
159  if (master == vhost_addr) {
161  }
162  if (new_master == vhost_addr) {
164  }
165 }
166 
169  return;
172  ReleaseWalker(walker_.get());
173  walker_.reset(NULL);
174 }
175 
176 bool TsnElector::IsMaster() const {
177  if (active_tsn_servers_.empty())
178  return false;
179  return (active_tsn_servers_.front().compare(
180  agent_->params()->vhost_addr().to_string()) == 0);
181 }
182 
184 const {
185  return agent_->oper_db()->multicast()->physical_devices();
186 }
MulticastHandler * multicast() const
Definition: operdb_init.h:53
virtual const std::string GetAddressString() const
TsnElectorState(AgentRouteTable *table, TsnElector *elector)
Definition: tsn_elector.cc:22
TsnElectorWalker(const std::string &name, Agent *agent)
Definition: tsn_elector.cc:33
virtual ~TsnElectorState()
Definition: tsn_elector.cc:29
AgentRouteTable * inet4_table_
Definition: tsn_elector.h:17
Definition: vrf.h:86
bool IsTsnNoForwardingEnabled() const
Definition: tsn_elector.cc:90
AgentRouteWalkerPtr walker_
Definition: tsn_elector.h:60
Agent supports multiple route tables - Inet-unicast (IPv4/IPv6), Inet-multicast, bridge, EVPN (Type2/Type5). This base class contains common code for all types of route tables.
Definition: agent_route.h:109
virtual ~TsnElector()
Definition: tsn_elector.cc:87
bool IsDeleted() const
Definition: db_entry.h:49
void LeaveTsnMastership()
Definition: tsn_elector.cc:70
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:22
bool IsConfiguredTsnHostRoute(std::string addr) const
bool is_multicast() const
Definition: agent_route.h:274
const ManagedPhysicalDevicesList & physical_devices() const
Definition: multicast.h:429
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable() const
Definition: vrf.cc:319
DBTableBase * parent()
const string & GetName() const
Definition: vrf.h:100
const Ip4Address & vhost_addr() const
Definition: agent_param.h:184
void Unregister(ListenerId listener)
Definition: db_table.cc:186
TsnElectorWalker * walker()
Definition: tsn_elector.h:53
OperDB * oper_db() const
Definition: agent.cc:1013
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:181
virtual bool RouteWalkNotify(DBTablePartBase *partition, DBEntryBase *e)
Definition: tsn_elector.cc:40
const Type GetType() const
Definition: peer.h:87
NextHop * nexthop() const
Definition: agent_path.cc:87
const ManagedPhysicalDevicesList & ManagedPhysicalDevices() const
Definition: tsn_elector.cc:183
void Register()
Definition: tsn_elector.cc:95
Definition: agent.h:358
AgentRouteWalkerManager * agent_route_walk_manager() const
Definition: operdb_init.h:91
virtual bool ReComputePathAdd(AgentPath *path)
TsnElector(Agent *agent)
Definition: tsn_elector.cc:80
DBTable::ListenerId vrf_listener_id_
Definition: tsn_elector.h:58
const Peer * peer() const
Definition: agent_path.h:263
void Notify(DBTablePartBase *partition, DBEntryBase *e)
Definition: tsn_elector.cc:104
void Shutdown()
Definition: tsn_elector.cc:167
COMPOSITETYPE composite_nh_type() const
Definition: nexthop.h:1842
AgentParam * params() const
Definition: agent.h:1218
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:73
virtual const PrefixType & prefix_address() const
Returns the value of a stored prefix address (IPv4, IPv6 or MAC address)
Definition: agent_route.h:375
void RouteNotify(DBTablePartBase *partition, DBEntryBase *e)
Definition: tsn_elector.cc:126
std::vector< std::string > ManagedPhysicalDevicesList
Definition: tsn_elector.h:36
VrfTable * vrf_table() const
Definition: agent.h:485
void set_inactive(bool inactive)
Definition: agent_path.h:421
void AcquireTsnMastership()
Definition: tsn_elector.cc:75
bool IsMaster() const
Definition: tsn_elector.cc:176
virtual ~TsnElectorWalker()
Definition: tsn_elector.cc:37
DBTable::ListenerId inet4_id_
Definition: tsn_elector.h:16
const Agent * agent_
Definition: tsn_elector.h:57
AgentMode agent_mode() const
Definition: agent_param.h:380
void Notify(DBEntryBase *entry)
std::vector< std::string > active_tsn_servers_
Definition: tsn_elector.h:59
const PathList & GetPathList() const
Definition: route.h:46
const std::string & fabric_policy_vrf_name() const
Definition: agent.h:908