FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
gbp_bridge_domain.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
18 #include "vom/interface.hpp"
19 #include "vom/l2_binding.hpp"
21 
22 namespace VOM {
23 
24 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::NONE(0, "none");
25 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::DO_NOT_LEARN(
26  1,
27  "do-not-learn");
28 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UU_FWD_DROP(
29  2,
30  "uu-fwd-drop");
31 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::MCAST_DROP(
32  4,
33  "mcast-drop");
34 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UCAST_ARP(
35  8,
36  "ucast-arp");
37 
38 gbp_bridge_domain::flags_t::flags_t(int v, const std::string& s)
39  : enum_base<gbp_bridge_domain::flags_t>(v, s)
40 {
41 }
42 
43 /**
44  * A DB of al the interfaces, key on the name
45  */
46 singular_db<uint32_t, gbp_bridge_domain> gbp_bridge_domain::m_db;
47 
48 gbp_bridge_domain::event_handler gbp_bridge_domain::m_evh;
49 
50 /**
51  * Construct a new object matching the desried state
52  */
54  const interface& bvi,
55  const flags_t& flags)
56  : m_id(bd.id())
57  , m_bd(bd.singular())
58  , m_bvi(bvi.singular())
59  , m_uu_fwd()
60  , m_bm_flood()
61  , m_flags(flags)
62 {
63 }
64 
66  const interface& bvi,
67  const interface& uu_fwd,
68  const interface& bm_flood,
69  const flags_t& flags)
70  : m_id(bd.id())
71  , m_bd(bd.singular())
72  , m_bvi(bvi.singular())
73  , m_uu_fwd(uu_fwd.singular())
74  , m_bm_flood(bm_flood.singular())
75  , m_flags(flags)
76 {
77 }
78 
80  const std::shared_ptr<interface> bvi,
81  const std::shared_ptr<interface> uu_fwd,
82  const std::shared_ptr<interface> bm_flood,
83  const flags_t& flags)
84  : m_id(bd.id())
85  , m_bd(bd.singular())
86  , m_bvi(bvi)
87  , m_uu_fwd(uu_fwd)
88  , m_bm_flood(bm_flood)
89  , m_flags(flags)
90 {
91  if (m_bvi)
92  m_bvi = m_bvi->singular();
93  if (m_uu_fwd)
94  m_uu_fwd = m_uu_fwd->singular();
95  if (m_bm_flood)
96  m_bm_flood = m_bm_flood->singular();
97 }
98 
100  const interface& bvi,
101  const std::shared_ptr<interface> uu_fwd,
102  const std::shared_ptr<interface> bm_flood,
103  const flags_t& flags)
104  : m_id(bd.id())
105  , m_bd(bd.singular())
106  , m_bvi(bvi.singular())
107  , m_uu_fwd(uu_fwd)
108  , m_bm_flood(bm_flood)
109  , m_flags(flags)
110 {
111  if (m_uu_fwd)
112  m_uu_fwd = m_uu_fwd->singular();
113  if (m_bm_flood)
114  m_bm_flood = m_bm_flood->singular();
115 }
116 
118  : m_id(bd.id())
119  , m_bd(bd.m_bd)
120  , m_bvi(bd.m_bvi)
121  , m_uu_fwd(bd.m_uu_fwd)
122  , m_bm_flood(bd.m_bm_flood)
123  , m_flags(bd.m_flags)
124 {
125 }
126 
129 {
130  return (m_bd->key());
131 }
132 
133 uint32_t
135 {
136  return (m_bd->id());
137 }
138 
139 const std::shared_ptr<bridge_domain>
141 {
142  return m_bd;
143 }
144 
145 const std::shared_ptr<interface>
147 {
148  return m_bvi;
149 }
150 
151 bool
153 {
154  bool equal = true;
155 
156  if (m_bvi && b.m_bvi)
157  equal &= (m_bvi->key() == b.m_bvi->key());
158  else if (!m_bvi && !b.m_bvi)
159  ;
160  else
161  equal = false;
162 
163  if (m_uu_fwd && b.m_uu_fwd)
164  equal &= (m_uu_fwd->key() == b.m_uu_fwd->key());
165  else if (!m_uu_fwd && !b.m_uu_fwd)
166  ;
167  else
168  equal = false;
169 
170  if (m_bm_flood && b.m_bm_flood)
171  equal &= (m_bm_flood->key() == b.m_bm_flood->key());
172  else if (!m_bm_flood && !b.m_bm_flood)
173  ;
174  else
175  equal = false;
176 
177  return ((m_bd->key() == b.m_bd->key()) && equal);
178 }
179 
180 void
181 gbp_bridge_domain::sweep()
182 {
183  if (rc_t::OK == m_id.rc()) {
185  }
186  HW::write();
187 }
188 
189 void
191 {
192  if (rc_t::OK == m_id.rc()) {
194  m_id, (m_bvi ? m_bvi->handle() : handle_t::INVALID),
195  (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID),
196  (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags));
197  }
198 }
199 
201 {
202  sweep();
203 
204  // not in the DB anymore.
205  m_db.release(m_id.data(), this);
206 }
207 
208 std::string
210 {
211  std::ostringstream s;
212  s << "gbp-bridge-domain:[" << m_bd->to_string()
213  << " flags:" << m_flags.to_string();
214 
215  if (m_bvi)
216  s << " bvi:" << m_bvi->to_string();
217  if (m_uu_fwd)
218  s << " uu-fwd:" << m_uu_fwd->to_string();
219 
220  s << "]";
221 
222  return (s.str());
223 }
224 
225 std::shared_ptr<gbp_bridge_domain>
227 {
228  return (m_db.find(key));
229 }
230 
231 void
232 gbp_bridge_domain::update(const gbp_bridge_domain& desired)
233 {
234  /*
235  * the desired state is always that the interface should be created
236  */
237  if (rc_t::OK != m_id.rc()) {
239  m_id, (m_bvi ? m_bvi->handle() : handle_t::INVALID),
240  (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID),
241  (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags));
242  }
243 }
244 
245 std::shared_ptr<gbp_bridge_domain>
246 gbp_bridge_domain::find_or_add(const gbp_bridge_domain& temp)
247 {
248  return (m_db.find_or_add(temp.m_id.data(), temp));
249 }
250 
251 std::shared_ptr<gbp_bridge_domain>
253 {
254  return find_or_add(*this);
255 }
256 
257 void
258 gbp_bridge_domain::dump(std::ostream& os)
259 {
260  db_dump(m_db, os);
261 }
262 
263 void
264 gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key)
265 {
266  /*
267  * dump GBP Bridge domains
268  */
269  std::shared_ptr<gbp_bridge_domain_cmds::dump_cmd> cmd =
270  std::make_shared<gbp_bridge_domain_cmds::dump_cmd>();
271 
272  HW::enqueue(cmd);
273  HW::write();
274 
275  for (auto& record : *cmd) {
276  auto& payload = record.get_payload();
277 
278  std::shared_ptr<interface> uu_fwd =
279  interface::find(payload.bd.uu_fwd_sw_if_index);
280  std::shared_ptr<interface> bm_flood =
281  interface::find(payload.bd.bm_flood_sw_if_index);
282  std::shared_ptr<interface> bvi =
283  interface::find(payload.bd.bvi_sw_if_index);
284 
286  if (payload.bd.flags & GBP_BD_API_FLAG_DO_NOT_LEARN)
288  if (payload.bd.flags & GBP_BD_API_FLAG_UU_FWD_DROP)
290  if (payload.bd.flags & GBP_BD_API_FLAG_MCAST_DROP)
292  if (payload.bd.flags & GBP_BD_API_FLAG_UCAST_ARP)
294 
295  if (uu_fwd && bm_flood && bvi) {
296  gbp_bridge_domain bd(payload.bd.bd_id, bvi, uu_fwd, bm_flood, flags);
297  OM::commit(key, bd);
298  VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string();
299  } else if (bvi) {
300  gbp_bridge_domain bd(payload.bd.bd_id, *bvi, flags);
301  OM::commit(key, bd);
302  VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string();
303  } else {
305  << "no BVI:" << payload.bd.bvi_sw_if_index
306  << " nor uu-fwd:" << payload.bd.uu_fwd_sw_if_index;
307  }
308  }
309 }
310 
312 {
313  OM::register_listener(this);
314  inspect::register_handler({ "gbd", "gbridge" }, "GBP Bridge Domains", this);
315 }
316 
317 void
318 gbp_bridge_domain::event_handler::handle_replay()
319 {
320  m_db.replay();
321 }
322 
324 gbp_bridge_domain::event_handler::order() const
325 {
327 }
328 
329 void
331 {
332  db_dump(m_db, os);
333 }
334 }
335 
336 /*
337  * fd.io coding-style-patch-verification: ON
338  *
339  * Local Variables:
340  * eval: (c-set-style "mozilla")
341  * End:
342  */
u32 flags
Definition: vhost_user.h:115
#define VOM_LOG(lvl)
Definition: logger.hpp:181
void db_dump(const DB &db, std::ostream &os)
Print each of the objects in the DB into the stream provided.
const std::string key_t
In the opflex world each entity is known by a URI which can be converted into a string.
Definition: client_db.hpp:51
static std::shared_ptr< interface > find(const handle_t &h)
The the singular instance of the interface in the DB by handle.
Definition: interface.cpp:531
A cmd class that Delete an Bridge-Domain.
static void register_handler(const std::vector< std::string > &cmds, const std::string &help, command_handler *ch)
Register a command handler for inspection.
Definition: inspect.cpp:85
const std::shared_ptr< bridge_domain > get_bridge_domain() const
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:255
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:119
static const log_level_t DEBUG
Definition: logger.hpp:32
static void dump(std::ostream &os)
Dump all bridge_domain-doamin into the stream provided.
gbp_bridge_domain(const bridge_domain &bd, const interface &bvi, const flags_t &flags=flags_t::NONE)
Construct a GBP bridge_domain.
static const handle_t INVALID
A value of an interface handle_t that means the itf does not exist.
Definition: types.hpp:268
virtual tables - tables with a dependency on another table
T & data()
Return the data read/written.
Definition: hw.hpp:109
std::shared_ptr< gbp_bridge_domain > singular() const
Return the matching &#39;singular instance&#39;.
void replay(void)
replay the object to create it in hardware
static std::shared_ptr< gbp_bridge_domain > find(const key_t &k)
Find the instnace of the bridge_domain domain in the OM.
const std::shared_ptr< interface > get_bvi() const
bool operator==(const gbp_bridge_domain &bdae) const
comparison operator
A command class that creates an Bridge-Domain.
A entry in the ARP termination table of a Bridge Domain.
bridge_domain::key_t key_t
The key for a bridge_domain is the pair of EPG-IDs.
A representation of an interface in VPP.
Definition: interface.hpp:41
A base class for all object_base in the VPP object_base-Model.
const std::string & to_string() const
convert to string format for debug purposes
Definition: enum_base.hpp:36
static rc_t commit(const client_db::key_t &key, const OBJ &obj)
Make the State in VPP reflect the expressed desired state.
Definition: om.hpp:202
void event_handler(void *tls_async)
Definition: tls_async.c:340
dependency_t
There needs to be a strict order in which object types are read from VPP (at boot time) and replayed ...
Definition: types.hpp:43
static const rc_t OK
The HW write was successfull.
Definition: types.hpp:109
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:212
static const log_level_t ERROR
Definition: logger.hpp:29
std::string to_string() const
Convert to string for debugging.
const key_t key() const
Return the object&#39;s key.
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
A representation of a method call to VPP.
Definition: cmd.hpp:32
void show(char *chroot_path, int verbose)
Definition: svmtool.c:105
u32 id
Definition: udp.api:45
typedef gbp_bridge_domain
Definition: gbp.api:32
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:127
uint32_t id() const
Return the bridge domain&#39;s VPP ID.