OpenSDN source code
vrf_ovsdb.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 
6 extern "C" {
7 #include <ovsdb_wrapper.h>
8 };
10 #include <ovsdb_client.h>
11 #include <ovsdb_client_idl.h>
12 #include <ovsdb_client_session.h>
13 #include <logical_switch_ovsdb.h>
14 #include <vrf_ovsdb.h>
16 #include <physical_locator_ovsdb.h>
17 
18 #include <oper/vn.h>
19 #include <oper/vrf.h>
20 #include <oper/nexthop.h>
21 #include <oper/tunnel_nh.h>
22 #include <oper/agent_path.h>
23 #include <oper/bridge_route.h>
24 #include <ovsdb_sandesh.h>
25 #include <ovsdb_types.h>
26 
27 using namespace OVSDB;
28 
30  const std::string &logical_switch) : OvsdbDBEntry(table),
31  logical_switch_name_(logical_switch), route_table_(NULL),
32  oper_route_table_(NULL) {
33 }
34 
36  assert(route_table_ == NULL);
37 }
38 
40  // if table is scheduled for delete, return from here
41  // and wait for delete callback
42  if (table_->delete_scheduled()) {
43  return true;
44  }
45 
46  // create route table and register
47  if (route_table_ == NULL) {
49  logical_switch_name_, this);
50  }
51 
52  if (!stale() && route_table_->GetDBTable() == NULL &&
53  oper_route_table_ != NULL) {
55  }
56  return true;
57 }
58 
60  return Add();
61 }
62 
64  // delete route table.
65  if (route_table_ != NULL) {
67  // while triggering a delete for UnicastMacRemoteTable, wait
68  // for table cleanup to complete to proceed with the KSync
69  // state machine, so that we maintain consistency for remote
70  // MAC table by not allowing two transient route table, one
71  // in process of deletion and other in process of addition
72  // which can lead to inconsistent state in OVSDB-server
73  return false;
74  }
75 
76  return true;
77 }
78 
79 bool VrfOvsdbEntry::Sync(DBEntry *db_entry) {
80  // check if route table is available.
81  const VrfEntry *vrf = static_cast<const VrfEntry *>(db_entry);
82  assert(logical_switch_name_ == UuidToString(vrf->vn()->GetUuid()));
83  if (oper_route_table_ != vrf->GetBridgeRouteTable()) {
85  return true;
86  }
87  return false;
88 }
89 
90 bool VrfOvsdbEntry::IsLess(const KSyncEntry &entry) const {
91  const VrfOvsdbEntry &vrf_entry =
92  static_cast<const VrfOvsdbEntry &>(entry);
93  return (logical_switch_name_.compare(vrf_entry.logical_switch_name_) < 0);
94 }
95 
97  return NULL;
98 }
99 
101  OvsdbDBObject *object = static_cast<OvsdbDBObject*>(GetObject());
102  assert(route_table_ == table);
103  route_table_ = NULL;
104  object->SafeNotifyEvent(this, KSyncEntry::DEL_ACK);
105 }
106 
109  boost::bind(&VrfOvsdbObject::OvsdbNotify, this, _1, _2));
110 }
111 
113 }
114 
116  struct ovsdb_idl_row *row) {
117  const char *mac = ovsdb_wrapper_ucast_mac_remote_mac(row);
118  const char *logical_switch =
120  /* if logical switch is not available ignore notification */
121  if (logical_switch == NULL)
122  return;
123  VrfOvsdbEntry vrf_key(this, logical_switch);
124  VrfOvsdbEntry *vrf_ovsdb = static_cast<VrfOvsdbEntry *>(Find(&vrf_key));
125 
126  if (vrf_ovsdb == NULL) {
127  if (op == OvsdbClientIdl::OVSDB_DEL) {
128  // nothing to do return from here.
129  return;
130  }
131  // if vrf is not available create a stale entry
132  // to accomodate stale unicast remote route
133  vrf_ovsdb = static_cast<VrfOvsdbEntry *>(CreateStale(&vrf_key));
134  }
135 
136  const char *dest_ip = ovsdb_wrapper_ucast_mac_remote_dst_ip(row);
137  UnicastMacRemoteTable *table= vrf_ovsdb->route_table_;
138  UnicastMacRemoteEntry key(table, mac);
139  if (op == OvsdbClientIdl::OVSDB_DEL) {
140  table->NotifyDeleteOvsdb((OvsdbDBEntry*)&key, row);
141  if (dest_ip)
142  key.dest_ip_ = std::string(dest_ip);
143  key.SendTrace(UnicastMacRemoteEntry::DEL_ACK);
144  } else if (op == OvsdbClientIdl::OVSDB_ADD) {
145  table->NotifyAddOvsdb((OvsdbDBEntry*)&key, row);
146  if (dest_ip)
147  key.dest_ip_ = std::string(dest_ip);
148  key.SendTrace(UnicastMacRemoteEntry::ADD_ACK);
149  }
150 }
151 
152 KSyncEntry *VrfOvsdbObject::Alloc(const KSyncEntry *key, uint32_t index) {
153  const VrfOvsdbEntry *k_entry =
154  static_cast<const VrfOvsdbEntry *>(key);
155  VrfOvsdbEntry *entry =
156  new VrfOvsdbEntry(this, k_entry->logical_switch_name_);
157  return entry;
158 }
159 
161  const VrfEntry *entry = static_cast<const VrfEntry *>(db_entry);
162  VrfOvsdbEntry *key =
163  new VrfOvsdbEntry(this, UuidToString(entry->vn()->GetUuid()));
164  return static_cast<KSyncEntry *>(key);
165 }
166 
167 OvsdbDBEntry *VrfOvsdbObject::AllocOvsEntry(struct ovsdb_idl_row *row) {
168  return NULL;
169 }
170 
172  const DBEntry *entry, const OvsdbDBEntry *ovsdb_entry) {
173  const VrfEntry *vrf = static_cast<const VrfEntry *>(entry);
174  // Delete Vrf if vn goes NULL
175  if (vrf->vn() == NULL) {
176  return DBFilterDelete;
177  }
178 
179  if (ovsdb_entry != NULL) {
180  const VrfOvsdbEntry *o_vrf =
181  static_cast<const VrfOvsdbEntry *>(ovsdb_entry);
182  if (o_vrf->logical_switch_name_ != UuidToString(vrf->vn()->GetUuid())) {
183  return DBFilterDelAdd;
184  }
185  }
186 
187  return DBFilterAccept;
188 }
189 
191 // Sandesh routines
194  AgentSandeshArguments &args) :
195  OvsdbSandeshTask(resp_ctx, args) {
196  if (false == args.Get("logical_switch", &logical_switch_)) {
197  logical_switch_ = "";
198  }
199  if (false == args.Get("mac", &mac_)) {
200  mac_ = "";
201  }
202 }
203 
205  std::string resp_ctx, const std::string &ip, uint32_t port,
206  const std::string &logical_switch, const std::string &mac) :
207  OvsdbSandeshTask(resp_ctx, ip, port), logical_switch_(logical_switch),
208  mac_(mac) {
209 }
210 
212 }
213 
215  if (!logical_switch_.empty()) {
216  args.Add("logical_switch", logical_switch_);
217  }
218  if (!mac_.empty()) {
219  args.Add("mac", mac_);
220  }
221 }
222 
224  if (!logical_switch_.empty()) {
225  VrfOvsdbEntry *entry = static_cast<VrfOvsdbEntry *>(kentry);
226  if (entry->logical_switch_name().find(
227  logical_switch_) != std::string::npos) {
228  return FilterAllow;
229  }
230  return FilterDeny;
231  }
232  return FilterAllow;
233 }
234 
236  SandeshResponse *resp) {
237  VrfOvsdbEntry *entry = static_cast<VrfOvsdbEntry *>(kentry);
238  OvsdbVrfEntry ventry;
239  ventry.set_state(entry->StateString());
240  ventry.set_logical_switch(entry->logical_switch_name());
242  entry->logical_switch_name(), mac_);
243  ventry.set_unicast_remote_table(task.EncodeFirstPage());
244  OvsdbVrfResp *vrf_resp = static_cast<OvsdbVrfResp *>(resp);
245 
246  std::vector<OvsdbVrfEntry> &vrf_list =
247  const_cast<std::vector<OvsdbVrfEntry>&>(vrf_resp->get_vrfs());
248  vrf_list.push_back(ventry);
249 }
250 
252  return static_cast<SandeshResponse *>(new OvsdbVrfResp());
253 }
254 
256  return static_cast<KSyncObject *>(session->client_idl()->vrf_ovsdb());
257 }
258 
259 void OvsdbVrfReq::HandleRequest() const {
261  new OvsdbVrfSandeshTask(context(), get_session_remote_ip(),
262  get_session_remote_port(),
263  get_logical_switch(), get_mac());
265  scheduler->Enqueue(task);
266 }
267 
bool Add(const std::string &key, const std::string &val)
bool Get(const std::string &key, std::string *val) const
DBTableBase * GetDBTable()
Definition: ksync_object.h:245
std::string StateString() const
bool stale() const
Definition: ksync_entry.h:180
bool delete_scheduled()
Definition: ksync_object.h:147
KSyncEntry * Find(const KSyncEntry *key)
void SafeNotifyEvent(KSyncEntry *entry, KSyncEntry::KSyncEvent event)
KSyncEntry * CreateStale(const KSyncEntry *key)
VrfOvsdbObject * vrf_ovsdb()
KSyncObject * GetObject() const
Definition: ovsdb_entry.cc:195
OvsdbDBObject * table_
Definition: ovsdb_entry.h:111
OvsdbDBObject * table()
Definition: ovsdb_entry.h:97
OvsdbClientIdlPtr client_idl_
Definition: ovsdb_object.h:84
void NotifyAddOvsdb(OvsdbDBEntry *key, struct ovsdb_idl_row *row)
Definition: ovsdb_object.cc:93
void NotifyDeleteOvsdb(OvsdbDBEntry *key, struct ovsdb_idl_row *row)
OvsdbClientIdl * client_idl()
Definition: ovsdb_object.h:77
KSyncObject * GetObject(OvsdbClientSession *session)
Definition: vrf_ovsdb.cc:255
OvsdbVrfSandeshTask(std::string resp_ctx, AgentSandeshArguments &args)
Definition: vrf_ovsdb.cc:193
void EncodeArgs(AgentSandeshArguments &args)
Definition: vrf_ovsdb.cc:214
void UpdateResp(KSyncEntry *kentry, SandeshResponse *resp)
Definition: vrf_ovsdb.cc:235
FilterResp Filter(KSyncEntry *entry)
Definition: vrf_ovsdb.cc:223
SandeshResponse * Alloc()
Definition: vrf_ovsdb.cc:251
virtual void OvsdbRegisterDBTable(DBTable *tbl)
bool Sync(DBEntry *)
Definition: vrf_ovsdb.cc:79
UnicastMacRemoteTable * route_table_
Definition: vrf_ovsdb.h:68
const std::string & logical_switch_name()
Definition: vrf_ovsdb.h:59
KSyncEntry * UnresolvedReference()
Definition: vrf_ovsdb.cc:96
std::string logical_switch_name_
Definition: vrf_ovsdb.h:67
void TriggerAck(UnicastMacRemoteTable *table)
Definition: vrf_ovsdb.cc:100
AgentRouteTable * oper_route_table_
Definition: vrf_ovsdb.h:69
VrfOvsdbEntry(OvsdbDBObject *table, const std::string &logical_switch)
Definition: vrf_ovsdb.cc:29
bool IsLess(const KSyncEntry &) const
Definition: vrf_ovsdb.cc:90
DBFilterResp OvsdbDBEntryFilter(const DBEntry *entry, const OvsdbDBEntry *ovsdb_entry)
Definition: vrf_ovsdb.cc:171
KSyncEntry * DBToKSyncEntry(const DBEntry *)
Definition: vrf_ovsdb.cc:160
OvsdbDBEntry * AllocOvsEntry(struct ovsdb_idl_row *row)
Definition: vrf_ovsdb.cc:167
void OvsdbNotify(OvsdbClientIdl::Op, struct ovsdb_idl_row *)
Definition: vrf_ovsdb.cc:115
VrfOvsdbObject(OvsdbClientIdl *idl)
Definition: vrf_ovsdb.cc:107
KSyncEntry * Alloc(const KSyncEntry *key, uint32_t index)
Definition: vrf_ovsdb.cc:152
virtual ~VrfOvsdbObject()
Definition: vrf_ovsdb.cc:112
The TaskScheduler keeps track of what tasks are currently schedulable. When a task is enqueued it is ...
Definition: task.h:307
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:662
static TaskScheduler * GetInstance()
Definition: task.cc:574
const boost::uuids::uuid & GetUuid() const
Definition: vn.h:162
Definition: vrf.h:90
AgentRouteTable * GetBridgeRouteTable() const
Definition: vrf.cc:335
VnEntry * vn() const
Definition: vrf.h:105
Definition: agent.h:44
char * ovsdb_wrapper_ucast_mac_remote_dst_ip(struct ovsdb_idl_row *row)
char * ovsdb_wrapper_ucast_mac_remote_logical_switch(struct ovsdb_idl_row *row)
char * ovsdb_wrapper_ucast_mac_remote_mac(struct ovsdb_idl_row *row)
static std::string UuidToString(const boost::uuids::uuid &id)
Definition: string_util.h:139
Definition: task_int.h:11
struct task_ task