FD.io VPP  v19.08-27-gf4dcae4
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 gbp_route_domain& rd,
55  const interface& bvi,
56  const flags_t& flags)
57  : m_id(bd.id())
58  , m_bd(bd.singular())
59  , m_rd(rd.singular())
60  , m_bvi(bvi.singular())
61  , m_uu_fwd()
62  , m_bm_flood()
63  , m_flags(flags)
64 {
65 }
66 
68  const gbp_route_domain& rd,
69  const interface& bvi,
70  const interface& uu_fwd,
71  const interface& bm_flood,
72  const flags_t& flags)
73  : m_id(bd.id())
74  , m_bd(bd.singular())
75  , m_rd(rd.singular())
76  , m_bvi(bvi.singular())
77  , m_uu_fwd(uu_fwd.singular())
78  , m_bm_flood(bm_flood.singular())
79  , m_flags(flags)
80 {
81 }
82 
84  const gbp_route_domain& rd,
85  const std::shared_ptr<interface> bvi,
86  const std::shared_ptr<interface> uu_fwd,
87  const std::shared_ptr<interface> bm_flood,
88  const flags_t& flags)
89  : m_id(bd.id())
90  , m_bd(bd.singular())
91  , m_rd(rd.singular())
92  , m_bvi(bvi)
93  , m_uu_fwd(uu_fwd)
94  , m_bm_flood(bm_flood)
95  , m_flags(flags)
96 {
97  if (m_bvi)
98  m_bvi = m_bvi->singular();
99  if (m_uu_fwd)
100  m_uu_fwd = m_uu_fwd->singular();
101  if (m_bm_flood)
102  m_bm_flood = m_bm_flood->singular();
103 }
104 
106  const gbp_route_domain& rd,
107  const interface& bvi,
108  const std::shared_ptr<interface> uu_fwd,
109  const std::shared_ptr<interface> bm_flood,
110  const flags_t& flags)
111  : m_id(bd.id())
112  , m_bd(bd.singular())
113  , m_rd(rd.singular())
114  , m_bvi(bvi.singular())
115  , m_uu_fwd(uu_fwd)
116  , m_bm_flood(bm_flood)
117  , m_flags(flags)
118 {
119  if (m_uu_fwd)
120  m_uu_fwd = m_uu_fwd->singular();
121  if (m_bm_flood)
122  m_bm_flood = m_bm_flood->singular();
123 }
124 
126  : m_id(bd.id())
127  , m_bd(bd.m_bd)
128  , m_rd(bd.m_rd)
129  , m_bvi(bd.m_bvi)
130  , m_uu_fwd(bd.m_uu_fwd)
131  , m_bm_flood(bd.m_bm_flood)
132  , m_flags(bd.m_flags)
133 {
134 }
135 
138 {
139  return (m_bd->key());
140 }
141 
142 uint32_t
144 {
145  return (m_bd->id());
146 }
147 
148 const std::shared_ptr<bridge_domain>
150 {
151  return m_bd;
152 }
153 
154 const std::shared_ptr<interface>
156 {
157  return m_bvi;
158 }
159 
160 bool
162 {
163  bool equal = true;
164 
165  if (m_bvi && b.m_bvi)
166  equal &= (m_bvi->key() == b.m_bvi->key());
167  else if (!m_bvi && !b.m_bvi)
168  ;
169  else
170  equal = false;
171 
172  if (m_uu_fwd && b.m_uu_fwd)
173  equal &= (m_uu_fwd->key() == b.m_uu_fwd->key());
174  else if (!m_uu_fwd && !b.m_uu_fwd)
175  ;
176  else
177  equal = false;
178 
179  if (m_bm_flood && b.m_bm_flood)
180  equal &= (m_bm_flood->key() == b.m_bm_flood->key());
181  else if (!m_bm_flood && !b.m_bm_flood)
182  ;
183  else
184  equal = false;
185 
186  return ((m_bd->key() == b.m_bd->key()) && equal);
187 }
188 
189 void
190 gbp_bridge_domain::sweep()
191 {
192  if (rc_t::OK == m_id.rc()) {
194  }
195  HW::write();
196 }
197 
198 void
200 {
201  if (rc_t::OK == m_id.rc()) {
203  m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID),
204  (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID),
205  (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags));
206  }
207 }
208 
210 {
211  sweep();
212 
213  // not in the DB anymore.
214  m_db.release(m_id.data(), this);
215 }
216 
217 std::string
219 {
220  std::ostringstream s;
221  s << "gbp-bridge-domain:[" << m_bd->to_string()
222  << " flags:" << m_flags.to_string();
223 
224  if (m_bvi)
225  s << " bvi:" << m_bvi->to_string();
226  if (m_uu_fwd)
227  s << " uu-fwd:" << m_uu_fwd->to_string();
228 
229  s << "]";
230 
231  return (s.str());
232 }
233 
234 std::shared_ptr<gbp_bridge_domain>
236 {
237  return (m_db.find(key));
238 }
239 
240 void
241 gbp_bridge_domain::update(const gbp_bridge_domain& desired)
242 {
243  /*
244  * the desired state is always that the interface should be created
245  */
246  if (rc_t::OK != m_id.rc()) {
248  m_id, m_rd->id(), (m_bvi ? m_bvi->handle() : handle_t::INVALID),
249  (m_uu_fwd ? m_uu_fwd->handle() : handle_t::INVALID),
250  (m_bm_flood ? m_bm_flood->handle() : handle_t::INVALID), m_flags));
251  }
252 }
253 
254 std::shared_ptr<gbp_bridge_domain>
255 gbp_bridge_domain::find_or_add(const gbp_bridge_domain& temp)
256 {
257  return (m_db.find_or_add(temp.m_id.data(), temp));
258 }
259 
260 std::shared_ptr<gbp_bridge_domain>
262 {
263  return find_or_add(*this);
264 }
265 
266 void
267 gbp_bridge_domain::dump(std::ostream& os)
268 {
269  db_dump(m_db, os);
270 }
271 
272 void
273 gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key)
274 {
275  /*
276  * dump GBP Bridge domains
277  */
278  std::shared_ptr<gbp_bridge_domain_cmds::dump_cmd> cmd =
279  std::make_shared<gbp_bridge_domain_cmds::dump_cmd>();
280 
281  HW::enqueue(cmd);
282  HW::write();
283 
284  for (auto& record : *cmd) {
285  auto& payload = record.get_payload();
286 
287  std::shared_ptr<interface> uu_fwd =
288  interface::find(payload.bd.uu_fwd_sw_if_index);
289  std::shared_ptr<interface> bm_flood =
290  interface::find(payload.bd.bm_flood_sw_if_index);
291  std::shared_ptr<interface> bvi =
292  interface::find(payload.bd.bvi_sw_if_index);
293  std::shared_ptr<gbp_route_domain> grd =
294  gbp_route_domain::find(payload.bd.rd_id);
295 
297  if (payload.bd.flags & GBP_BD_API_FLAG_DO_NOT_LEARN)
299  if (payload.bd.flags & GBP_BD_API_FLAG_UU_FWD_DROP)
301  if (payload.bd.flags & GBP_BD_API_FLAG_MCAST_DROP)
303  if (payload.bd.flags & GBP_BD_API_FLAG_UCAST_ARP)
305 
306  if (uu_fwd && bm_flood && bvi && grd) {
307  gbp_bridge_domain bd(payload.bd.bd_id, *grd, bvi, uu_fwd, bm_flood,
308  flags);
309  OM::commit(key, bd);
310  VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string();
311  } else if (bvi) {
312  gbp_bridge_domain bd(payload.bd.bd_id, *grd, *bvi, flags);
313  OM::commit(key, bd);
314  VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string();
315  } else {
317  << "no BVI:" << payload.bd.bvi_sw_if_index
318  << " nor uu-fwd:" << payload.bd.uu_fwd_sw_if_index;
319  }
320  }
321 }
322 
324 {
325  OM::register_listener(this);
326  inspect::register_handler({ "gbd", "gbridge" }, "GBP Bridge Domains", this);
327 }
328 
329 void
330 gbp_bridge_domain::event_handler::handle_replay()
331 {
332  m_db.replay();
333 }
334 
336 gbp_bridge_domain::event_handler::order() const
337 {
338  /* order after gbp-route-domains */
339  return (dependency_t::ACL);
340 }
341 
342 void
344 {
345  db_dump(m_db, os);
346 }
347 }
348 
349 /*
350  * fd.io coding-style-patch-verification: ON
351  *
352  * Local Variables:
353  * eval: (c-set-style "mozilla")
354  * End:
355  */
u32 flags
Definition: vhost_user.h:141
#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:538
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
uint32_t id() const
Return the bridge domain&#39;s VPP ID.
bool operator==(const gbp_bridge_domain &bdae) const
comparison operator
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:255
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.
static const handle_t INVALID
A value of an interface handle_t that means the itf does not exist.
Definition: types.hpp:268
std::shared_ptr< gbp_bridge_domain > singular() const
Return the matching &#39;singular instance&#39;.
const std::shared_ptr< interface > get_bvi() const
T & data()
Return the data read/written.
Definition: hw.hpp:109
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< bridge_domain > get_bridge_domain() const
A command class that creates an Bridge-Domain.
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:119
A entry in the ARP termination table of a Bridge Domain.
const key_t key() const
Return the object&#39;s key.
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.
gbp_bridge_domain(const bridge_domain &bd, const gbp_route_domain &rd, const interface &bvi, const flags_t &flags=flags_t::NONE)
Construct a GBP bridge_domain.
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
A entry in the ARP termination table of a Route Domain.
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
std::string to_string() const
Convert to string for debugging.
A representation of a method call to VPP.
Definition: cmd.hpp:32
static std::shared_ptr< gbp_route_domain > find(const key_t &k)
Find the instnace of the route_domain domain in the OM.
void show(char *chroot_path, int verbose)
Definition: svmtool.c:105
const std::string & to_string() const
convert to string format for debug purposes
Definition: enum_base.hpp:36
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