OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
unicast_mac_local_ovsdb.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 extern "C" {
6 #include <ovsdb_wrapper.h>
7 };
8 #include <cmn/agent.h>
9 #include <oper/vn.h>
10 #include <oper/vrf.h>
11 #include <oper/vxlan.h>
14 #include <ovsdb_client.h>
15 #include <ovsdb_client_idl.h>
16 #include <ovsdb_client_session.h>
17 #include <base/util.h>
18 #include <base/string_util.h>
19 #include <net/mac_address.h>
20 #include <oper/agent_sandesh.h>
21 #include <ovsdb_sandesh.h>
22 #include <ovsdb_types.h>
23 #include <ovsdb_route_peer.h>
24 #include <logical_switch_ovsdb.h>
26 #include <vn_ovsdb.h>
27 
28 using namespace OVSDB;
29 using std::string;
30 
32  const std::string &logical_switch, const std::string &mac) :
33  OvsdbEntry(table), mac_(mac), logical_switch_name_(logical_switch),
34  dest_ip_(""), vrf_(NULL, this) {
35 }
36 
38  const UnicastMacLocalEntry *key) : OvsdbEntry(table), mac_(key->mac_),
39  logical_switch_name_(key->logical_switch_name_), dest_ip_(key->dest_ip_),
40  vrf_(NULL, this) {
41 }
42 
44  struct ovsdb_idl_row *row) : OvsdbEntry(table),
46  logical_switch_name_(ovsdb_wrapper_ucast_mac_local_logical_switch(row)),
47  dest_ip_(), vrf_(NULL, this) {
50 }
51 
53 }
54 
56  UnicastMacLocalOvsdb *table = static_cast<UnicastMacLocalOvsdb *>(table_);
57  OVSDB_TRACE(Trace, "Adding Route " + mac_ + " VN uuid " +
58  logical_switch_name_ + " destination IP " + dest_ip_);
59  VnOvsdbObject *vn_object = table_->client_idl()->vn_ovsdb();
61  VnOvsdbEntry *vn_entry =
62  static_cast<VnOvsdbEntry *>(vn_object->GetReference(&vn_key));
63 
64  // Take vrf reference to genrate withdraw/delete route request
65  vrf_ = vn_entry->vrf();
66  // Add vrf dep in UnicastMacLocalOvsdb
68  this));
69  vxlan_id_ = vn_entry->vxlan_id();
70  boost::system::error_code err;
71  Ip4Address dest = Ip4Address::from_string(dest_ip_, err);
72  table->peer()->AddOvsRoute(vrf_.get(), vxlan_id_, vn_entry->name(),
73  MacAddress(mac_), dest);
74  return true;
75 }
76 
78  UnicastMacLocalOvsdb *table = static_cast<UnicastMacLocalOvsdb *>(table_);
79  OVSDB_TRACE(Trace, "Deleting Route " + mac_ + " VN uuid " +
80  logical_switch_name_ + " destination IP " + dest_ip_);
81  table->vrf_dep_list_.erase(UnicastMacLocalOvsdb::VrfDepEntry(vrf_.get(), this));
82  table->peer()->DeleteOvsRoute(vrf_.get(), vxlan_id_, MacAddress(mac_));
83  // remove vrf reference after deleting route
84  vrf_ = NULL;
85  return true;
86 }
87 
88 bool UnicastMacLocalEntry::IsLess(const KSyncEntry& entry) const {
89  const UnicastMacLocalEntry &ucast =
90  static_cast<const UnicastMacLocalEntry&>(entry);
91  if (mac_ != ucast.mac_)
92  return mac_ < ucast.mac_;
94 }
95 
97  VnOvsdbObject *vn_object = table_->client_idl()->vn_ovsdb();
99  VnOvsdbEntry *vn_entry =
100  static_cast<VnOvsdbEntry *>(vn_object->GetReference(&vn_key));
101  if (!vn_entry->IsResolved()) {
102  OVSDB_TRACE(Trace, "Skipping route add " + mac_ + " VN uuid " +
103  logical_switch_name_ + " destination IP " + dest_ip_ +
104  " due to unavailable VN ");
105  return vn_entry;
106  }
107  return NULL;
108 }
109 
110 const std::string &UnicastMacLocalEntry::mac() const {
111  return mac_;
112 }
113 
114 const std::string &UnicastMacLocalEntry::logical_switch_name() const {
115  return logical_switch_name_;
116 }
117 
118 const std::string &UnicastMacLocalEntry::dest_ip() const {
119  return dest_ip_;
120 }
121 
123  OvsdbObject(idl), peer_(peer) {
125  idl->agent()->task_scheduler()->GetTaskId("Agent::KSync"), 0,
126  boost::bind(&UnicastMacLocalOvsdb::VrfReEval, this, _1));
127  vrf_reeval_queue_->set_name("OVSDB VRF unicast-mac-local event queue");
129  boost::bind(&UnicastMacLocalOvsdb::Notify, this, _1, _2));
130 }
131 
133  delete vrf_reeval_queue_;
134 }
135 
137  return peer_;
138 }
139 
141  struct ovsdb_idl_row *row) {
142  const char *ls_name = ovsdb_wrapper_ucast_mac_local_logical_switch(row);
143  const char *dest_ip = ovsdb_wrapper_ucast_mac_local_dst_ip(row);
144  /* ignore if ls_name is not present */
145  if (ls_name == NULL) {
146  return;
147  }
148 
149  LogicalSwitchTable *l_table = client_idl_->logical_switch_table();
150  l_table->OvsdbUcastLocalMacNotify(op, row);
151 
152  UnicastMacLocalEntry key(this, row);
153  UnicastMacLocalEntry *entry =
154  static_cast<UnicastMacLocalEntry *>(FindActiveEntry(&key));
155  /* trigger delete if dest ip is not available */
156  if (op == OvsdbClientIdl::OVSDB_DEL || dest_ip == NULL) {
157  if (entry != NULL) {
158  entry->ovs_entry_ = NULL;
159  Delete(entry);
160  }
161  } else if (op == OvsdbClientIdl::OVSDB_ADD) {
162  if (entry == NULL) {
163  entry = static_cast<UnicastMacLocalEntry *>(Create(&key));
164  entry->ovs_entry_ = row;
165  }
166  } else {
167  assert(0);
168  }
169 }
170 
171 KSyncEntry *UnicastMacLocalOvsdb::Alloc(const KSyncEntry *key, uint32_t index) {
172  const UnicastMacLocalEntry *k_entry =
173  static_cast<const UnicastMacLocalEntry *>(key);
174  UnicastMacLocalEntry *entry = new UnicastMacLocalEntry(this, k_entry);
175  return entry;
176 }
177 
179  if (vrf_reeval_queue_->deleted()) {
180  // skip Enqueuing entry to deleted workqueue
181  return;
182  }
183 
184  vrf_reeval_queue_->Enqueue(vrf);
185 }
186 
188  // iterate through dependency list and trigger del and add
189  VrfDepList::iterator it =
190  vrf_dep_list_.upper_bound(VrfDepEntry(vrf.get(), NULL));
191  while (it != vrf_dep_list_.end()) {
192  if (it->first != vrf.get()) {
193  break;
194  }
195  UnicastMacLocalEntry *u_entry = it->second;
196  it++;
197  if (u_entry->ovs_entry() != NULL && client_idl() != NULL) {
198  // vrf re-eval for unicast mac local is a catastrophic change
199  // trigger NotifyAddDel on ovs row.
200  client_idl()->NotifyDelAdd(u_entry->ovs_entry());
201  }
202  }
203  return true;
204 }
205 
207  return !(vrf_reeval_queue_->deleted());
208 }
209 
211  // Shutdown the reeval queue on table deletion,
212  // all the unicast MAC Local entries will get
213  // deleted and clear eventually
214  vrf_reeval_queue_->Shutdown();
215 }
216 
218 // Sandesh routines
221  std::string resp_ctx, AgentSandeshArguments &args) :
222  OvsdbSandeshTask(resp_ctx, args) {
223  if (args.Get("ls_name", &ls_name_) == false) {
224  ls_name_ = "";
225  }
226  if (args.Get("mac", &mac_) == false) {
227  mac_ = "";
228  }
229 }
230 
232  std::string resp_ctx, const std::string &ip, uint32_t port,
233  const std::string &ls, const std::string &mac) :
234  OvsdbSandeshTask(resp_ctx, ip, port), ls_name_(ls), mac_(mac) {
235 }
236 
238 }
239 
241  if (!ls_name_.empty()) {
242  args.Add("ls_name", ls_name_);
243  }
244  if (!mac_.empty()) {
245  args.Add("mac", mac_);
246  }
247 }
248 
251  UnicastMacLocalEntry *entry = static_cast<UnicastMacLocalEntry *>(kentry);
252  if (!ls_name_.empty()) {
253  if (entry->logical_switch_name().find(ls_name_) == std::string::npos) {
254  return FilterDeny;
255  }
256  }
257  if (!mac_.empty()) {
258  if (entry->mac().find(mac_) != std::string::npos) {
259  return FilterAllow;
260  }
261  return FilterDeny;
262  }
263  return FilterAllow;
264 }
265 
267  SandeshResponse *resp) {
268  UnicastMacLocalEntry *entry = static_cast<UnicastMacLocalEntry *>(kentry);
269  OvsdbUnicastMacLocalEntry oentry;
270  oentry.set_state(entry->StateString());
271  oentry.set_mac(entry->mac());
272  oentry.set_logical_switch(entry->logical_switch_name());
273  oentry.set_dest_ip(entry->dest_ip());
274  OvsdbUnicastMacLocalResp *u_resp =
275  static_cast<OvsdbUnicastMacLocalResp *>(resp);
276  std::vector<OvsdbUnicastMacLocalEntry> &macs =
277  const_cast<std::vector<OvsdbUnicastMacLocalEntry>&>(u_resp->get_macs());
278  macs.push_back(oentry);
279 }
280 
282  return static_cast<SandeshResponse *>(new OvsdbUnicastMacLocalResp());
283 }
284 
286  OvsdbClientSession *session) {
287  return static_cast<KSyncObject *>(
288  session->client_idl()->unicast_mac_local_ovsdb());
289 }
290 
291 void OvsdbUnicastMacLocalReq::HandleRequest() const {
293  new UnicastMacLocalSandeshTask(context(), get_session_remote_ip(),
294  get_session_remote_port(),
295  get_logical_switch(), get_mac());
297  scheduler->Enqueue(task);
298 }
299 
void NotifyDelAdd(struct ovsdb_idl_row *row)
uint32_t vxlan_id()
Definition: vn_ovsdb.h:44
#define OVSDB_TRACE(obj,...)
UnicastMacLocalSandeshTask(std::string resp_ctx, AgentSandeshArguments &args)
static boost::uuids::uuid StringToUuid(const std::string &str)
Definition: string_util.h:145
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:178
Definition: vrf.h:86
bool IsResolved()
const std::string & dest_ip() const
std::string StateString() const
void Delete(KSyncEntry *entry)
Agent * agent() const
UnicastMacLocalOvsdb(OvsdbClientIdl *idl, OvsPeer *peer)
void EncodeArgs(AgentSandeshArguments &args)
std::pair< VrfEntry *, UnicastMacLocalEntry * > VrfDepEntry
void Register(EntryType type, NotifyCB cb)
bool IsLess(const KSyncEntry &) const
int GetTaskId(const std::string &name)
Definition: task.cc:856
KSyncEntry * FindActiveEntry(KSyncEntry *key)
Definition: ovsdb_object.cc:23
VnOvsdbObject * vn_ovsdb()
struct ovsdb_idl_row * ovs_entry_
Definition: ovsdb_entry.h:53
TaskScheduler * task_scheduler() const
Definition: agent.h:1120
bool Get(const std::string &key, std::string *val) const
static TaskScheduler * GetInstance()
Definition: task.cc:547
void Enqueue(Task *task)
Enqueues a task for running. Starts task if all policy rules are met else puts task in waitq...
Definition: task.cc:636
const std::string & mac() const
Definition: trace.h:220
bool AddOvsRoute(const VrfEntry *vrf, uint32_t vxlan_id, const std::string &dest_vn, const MacAddress &mac, Ip4Address &tor_ip)
UnicastMacLocalEntry(UnicastMacLocalOvsdb *table, const std::string &logical_switch, const std::string &mac)
struct ovsdb_idl_row * ovs_entry()
Definition: ovsdb_entry.h:47
bool Add(const std::string &key, const std::string &val)
KSyncEntry * GetReference(const KSyncEntry *key)
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
KSyncEntry * Create(const KSyncEntry *key)
void Notify(OvsdbClientIdl::Op op, struct ovsdb_idl_row *row)
WorkQueue< VrfEntryRef > * vrf_reeval_queue_
KSyncObject * GetObject(OvsdbClientSession *session)
OvsdbObject * table_
Definition: ovsdb_entry.h:52
const std::string & logical_switch_name() const
void DeleteOvsRoute(VrfEntry *vrf, uint32_t vxlan, const MacAddress &mac)
UnicastMacLocalOvsdb * unicast_mac_local_ovsdb()
FilterResp Filter(KSyncEntry *entry)
char * ovsdb_wrapper_ucast_mac_local_logical_switch(struct ovsdb_idl_row *row)
OvsdbClientIdlPtr client_idl_
Definition: ovsdb_object.h:34
char * ovsdb_wrapper_ucast_mac_local_mac(struct ovsdb_idl_row *row)
const std::string & name()
Definition: vn_ovsdb.h:45
VrfEntry * vrf()
Definition: vn_ovsdb.cc:92
char * ovsdb_wrapper_ucast_mac_local_dst_ip(struct ovsdb_idl_row *row)
void OvsdbUcastLocalMacNotify(OvsdbClientIdl::Op, struct ovsdb_idl_row *)
void UpdateResp(KSyncEntry *kentry, SandeshResponse *resp)
struct task_ task
OvsdbClientIdl * client_idl()
Definition: ovsdb_object.h:31
KSyncEntry * Alloc(const KSyncEntry *key, uint32_t index)