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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include "vom/gbp_bridge_domain.hpp"
17 #include "vom/gbp_bridge_domain_cmds.hpp"
18 #include "vom/interface.hpp"
19 #include "vom/l2_binding.hpp"
20 #include "vom/singular_db_funcs.hpp"
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(
28 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UU_FWD_DROP(
31 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::MCAST_DROP(
34 const gbp_bridge_domain::flags_t gbp_bridge_domain::flags_t::UCAST_ARP(
38 gbp_bridge_domain::flags_t::flags_t(int v, const std::string& s)
39 : enum_base<gbp_bridge_domain::flags_t>(v, s)
44 * A DB of al the interfaces, key on the name
46 singular_db<uint32_t, gbp_bridge_domain> gbp_bridge_domain::m_db;
48 gbp_bridge_domain::event_handler gbp_bridge_domain::m_evh;
51 * Construct a new object matching the desried state
53 gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd,
54 const gbp_route_domain& rd,
60 , m_bvi(bvi.singular())
67 gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd,
68 const gbp_route_domain& rd,
70 const interface& uu_fwd,
71 const interface& bm_flood,
76 , m_bvi(bvi.singular())
77 , m_uu_fwd(uu_fwd.singular())
78 , m_bm_flood(bm_flood.singular())
83 gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd,
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,
94 , m_bm_flood(bm_flood)
98 m_bvi = m_bvi->singular();
100 m_uu_fwd = m_uu_fwd->singular();
102 m_bm_flood = m_bm_flood->singular();
105 gbp_bridge_domain::gbp_bridge_domain(const bridge_domain& bd,
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)
112 , m_bd(bd.singular())
113 , m_rd(rd.singular())
114 , m_bvi(bvi.singular())
116 , m_bm_flood(bm_flood)
120 m_uu_fwd = m_uu_fwd->singular();
122 m_bm_flood = m_bm_flood->singular();
125 gbp_bridge_domain::gbp_bridge_domain(const gbp_bridge_domain& bd)
130 , m_uu_fwd(bd.m_uu_fwd)
131 , m_bm_flood(bd.m_bm_flood)
132 , m_flags(bd.m_flags)
136 const gbp_bridge_domain::key_t
137 gbp_bridge_domain::key() const
139 return (m_bd->key());
143 gbp_bridge_domain::id() const
148 const std::shared_ptr<bridge_domain>
149 gbp_bridge_domain::get_bridge_domain() const
154 const std::shared_ptr<interface>
155 gbp_bridge_domain::get_bvi() const
161 gbp_bridge_domain::operator==(const gbp_bridge_domain& b) const
165 if (m_bvi && b.m_bvi)
166 equal &= (m_bvi->key() == b.m_bvi->key());
167 else if (!m_bvi && !b.m_bvi)
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)
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)
186 return ((m_bd->key() == b.m_bd->key()) && equal);
190 gbp_bridge_domain::sweep()
192 if (rc_t::OK == m_id.rc()) {
193 HW::enqueue(new gbp_bridge_domain_cmds::delete_cmd(m_id));
199 gbp_bridge_domain::replay()
201 if (rc_t::OK == m_id.rc()) {
202 HW::enqueue(new gbp_bridge_domain_cmds::create_cmd(
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));
209 gbp_bridge_domain::~gbp_bridge_domain()
213 // not in the DB anymore.
214 m_db.release(m_id.data(), this);
218 gbp_bridge_domain::to_string() const
220 std::ostringstream s;
221 s << "gbp-bridge-domain:[" << m_bd->to_string()
222 << " flags:" << m_flags.to_string();
225 s << " bvi:" << m_bvi->to_string();
227 s << " uu-fwd:" << m_uu_fwd->to_string();
234 std::shared_ptr<gbp_bridge_domain>
235 gbp_bridge_domain::find(const key_t& key)
237 return (m_db.find(key));
241 gbp_bridge_domain::update(const gbp_bridge_domain& desired)
244 * the desired state is always that the interface should be created
246 if (rc_t::OK != m_id.rc()) {
247 HW::enqueue(new gbp_bridge_domain_cmds::create_cmd(
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));
254 std::shared_ptr<gbp_bridge_domain>
255 gbp_bridge_domain::find_or_add(const gbp_bridge_domain& temp)
257 return (m_db.find_or_add(temp.m_id.data(), temp));
260 std::shared_ptr<gbp_bridge_domain>
261 gbp_bridge_domain::singular() const
263 return find_or_add(*this);
267 gbp_bridge_domain::dump(std::ostream& os)
273 gbp_bridge_domain::event_handler::handle_populate(const client_db::key_t& key)
276 * dump GBP Bridge domains
278 std::shared_ptr<gbp_bridge_domain_cmds::dump_cmd> cmd =
279 std::make_shared<gbp_bridge_domain_cmds::dump_cmd>();
284 for (auto& record : *cmd) {
285 auto& payload = record.get_payload();
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);
296 flags_t flags = gbp_bridge_domain::flags_t::NONE;
297 if (payload.bd.flags & GBP_BD_API_FLAG_DO_NOT_LEARN)
298 flags |= gbp_bridge_domain::flags_t::DO_NOT_LEARN;
299 if (payload.bd.flags & GBP_BD_API_FLAG_UU_FWD_DROP)
300 flags |= gbp_bridge_domain::flags_t::UU_FWD_DROP;
301 if (payload.bd.flags & GBP_BD_API_FLAG_MCAST_DROP)
302 flags |= gbp_bridge_domain::flags_t::MCAST_DROP;
303 if (payload.bd.flags & GBP_BD_API_FLAG_UCAST_ARP)
304 flags |= gbp_bridge_domain::flags_t::UCAST_ARP;
306 if (uu_fwd && bm_flood && bvi && grd) {
307 gbp_bridge_domain bd(payload.bd.bd_id, *grd, bvi, uu_fwd, bm_flood,
310 VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string();
312 gbp_bridge_domain bd(payload.bd.bd_id, *grd, *bvi, flags);
314 VOM_LOG(log_level_t::DEBUG) << "dump: " << bd.to_string();
316 VOM_LOG(log_level_t::ERROR)
317 << "no BVI:" << payload.bd.bvi_sw_if_index
318 << " nor uu-fwd:" << payload.bd.uu_fwd_sw_if_index;
323 gbp_bridge_domain::event_handler::event_handler()
325 OM::register_listener(this);
326 inspect::register_handler({ "gbd", "gbridge" }, "GBP Bridge Domains", this);
330 gbp_bridge_domain::event_handler::handle_replay()
336 gbp_bridge_domain::event_handler::order() const
338 /* order after gbp-route-domains */
339 return (dependency_t::ACL);
343 gbp_bridge_domain::event_handler::show(std::ostream& os)
350 * fd.io coding-style-patch-verification: ON
353 * eval: (c-set-style "mozilla")