blob: 4118f74065a92ea7f2145dfca03337e5f2e9426d [file] [log] [blame]
Neale Ranns812ed392017-10-16 04:20:13 -07001/*
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
16#include "vom/l2_binding.hpp"
Neale Ranns9ef1c0a2017-11-03 04:39:05 -070017#include "vom/l2_binding_cmds.hpp"
Neale Ranns756cd942018-04-06 09:18:11 -070018#include "vom/singular_db_funcs.hpp"
Neale Ranns812ed392017-10-16 04:20:13 -070019
20namespace VOM {
21/**
22 * A DB of all the L2 Configs
23 */
Neale Rannsfd920602017-11-23 12:15:00 -080024singular_db<l2_binding::key_t, l2_binding> l2_binding::m_db;
Neale Ranns812ed392017-10-16 04:20:13 -070025
26l2_binding::event_handler l2_binding::m_evh;
27
28/*
29 * Make sure these are in sync with the smae enum in VPP
30 */
31const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_DISABLED(
32 0,
33 "disabled");
34const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_PUSH_1(1,
35 "push-1");
36const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_PUSH_2(2,
37 "push-2");
38const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_POP_1(3, "pop-1");
39const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_POP_2(4, "pop-2");
40const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_TRANSLATE_1_1(
41 5,
42 "translate-1-1");
43const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_TRANSLATE_1_2(
44 6,
45 "translate-1-2");
46const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_TRANSLATE_2_1(
47 7,
48 "translate-2-1");
49const l2_binding::l2_vtr_op_t l2_binding::l2_vtr_op_t::L2_VTR_TRANSLATE_2_2(
50 5,
51 "translate-2-2");
52
53l2_binding::l2_vtr_op_t::l2_vtr_op_t(int v, const std::string s)
54 : enum_base<l2_binding::l2_vtr_op_t>(v, s)
55{
56}
57
58/**
59 * Construct a new object matching the desried state
60 */
61l2_binding::l2_binding(const interface& itf, const bridge_domain& bd)
62 : m_itf(itf.singular())
63 , m_bd(bd.singular())
64 , m_binding(0)
65 , m_vtr_op(l2_vtr_op_t::L2_VTR_DISABLED, rc_t::UNSET)
66 , m_vtr_op_tag(0)
67{
68}
69
70l2_binding::l2_binding(const l2_binding& o)
71 : m_itf(o.m_itf)
72 , m_bd(o.m_bd)
73 , m_binding(0)
74 , m_vtr_op(o.m_vtr_op)
75 , m_vtr_op_tag(o.m_vtr_op_tag)
76{
77}
78
Neale Rannsfd920602017-11-23 12:15:00 -080079const l2_binding::key_t&
80l2_binding::key() const
81{
82 return (m_itf->key());
83}
84
85bool
86l2_binding::operator==(const l2_binding& l) const
87{
88 return ((*m_itf == *l.m_itf) && (*m_bd == *l.m_bd));
89}
90
91std::shared_ptr<l2_binding>
92l2_binding::find(const key_t& key)
93{
94 return (m_db.find(key));
95}
96
Neale Ranns812ed392017-10-16 04:20:13 -070097void
98l2_binding::sweep()
99{
100 if (m_binding && handle_t::INVALID != m_itf->handle()) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -0700101 HW::enqueue(
102 new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), m_bd->id(),
103 interface::type_t::BVI == m_itf->type()));
Neale Ranns812ed392017-10-16 04:20:13 -0700104 }
105
106 // no need to undo the VTR operation.
107 HW::write();
108}
109
110void
111l2_binding::replay()
112{
113 if (m_binding && handle_t::INVALID != m_itf->handle()) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -0700114 HW::enqueue(
115 new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_bd->id(),
116 interface::type_t::BVI == m_itf->type()));
Neale Ranns812ed392017-10-16 04:20:13 -0700117 }
118
119 if (m_vtr_op && handle_t::INVALID != m_itf->handle()) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -0700120 HW::enqueue(new l2_binding_cmds::set_vtr_op_cmd(m_vtr_op, m_itf->handle(),
121 m_vtr_op_tag));
Neale Ranns812ed392017-10-16 04:20:13 -0700122 }
123}
124
125l2_binding::~l2_binding()
126{
127 sweep();
128
129 // not in the DB anymore.
Neale Rannsfd920602017-11-23 12:15:00 -0800130 m_db.release(m_itf->key(), this);
Neale Ranns812ed392017-10-16 04:20:13 -0700131}
132
133std::string
134l2_binding::to_string() const
135{
136 std::ostringstream s;
Neale Rannsfd920602017-11-23 12:15:00 -0800137 s << "L2-binding:[" << m_itf->to_string() << " " << m_bd->to_string() << " "
Neale Ranns812ed392017-10-16 04:20:13 -0700138 << m_binding.to_string() << "]";
139
140 return (s.str());
141}
142
143void
144l2_binding::set(const l2_vtr_op_t& op, uint16_t tag)
145{
146 assert(rc_t::UNSET == m_vtr_op.rc());
147 m_vtr_op.set(rc_t::NOOP);
148 m_vtr_op.update(op);
149 m_vtr_op_tag = tag;
150}
151
152void
153l2_binding::update(const l2_binding& desired)
154{
155 /*
Neale Ranns088f0e22017-12-01 00:19:43 -0800156 * the desired state is always that the interface should be created
157 */
Neale Ranns812ed392017-10-16 04:20:13 -0700158 if (rc_t::OK != m_binding.rc()) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -0700159 HW::enqueue(
160 new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_bd->id(),
161 interface::type_t::BVI == m_itf->type()));
Neale Ranns088f0e22017-12-01 00:19:43 -0800162 } else if (!(*m_bd == *desired.m_bd)) {
163 /*
164 * re-binding to a different BD. do unbind, bind.
165 */
166 HW::enqueue(
167 new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), m_bd->id(),
168 interface::type_t::BVI == m_itf->type()));
169 m_bd = desired.m_bd;
170 HW::enqueue(
171 new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_bd->id(),
172 interface::type_t::BVI == m_itf->type()));
Neale Ranns812ed392017-10-16 04:20:13 -0700173 }
174
175 /*
Neale Ranns088f0e22017-12-01 00:19:43 -0800176 * set the VTR operation if request
177 */
Neale Ranns812ed392017-10-16 04:20:13 -0700178 if (m_vtr_op.update(desired.m_vtr_op)) {
Neale Ranns9ef1c0a2017-11-03 04:39:05 -0700179 HW::enqueue(new l2_binding_cmds::set_vtr_op_cmd(m_vtr_op, m_itf->handle(),
180 m_vtr_op_tag));
Neale Ranns812ed392017-10-16 04:20:13 -0700181 }
182}
183
184std::shared_ptr<l2_binding>
185l2_binding::find_or_add(const l2_binding& temp)
186{
Neale Rannsfd920602017-11-23 12:15:00 -0800187 return (m_db.find_or_add(temp.m_itf->key(), temp));
Neale Ranns812ed392017-10-16 04:20:13 -0700188}
189
190std::shared_ptr<l2_binding>
191l2_binding::singular() const
192{
193 return find_or_add(*this);
194}
195
196void
197l2_binding::dump(std::ostream& os)
198{
Neale Ranns756cd942018-04-06 09:18:11 -0700199 db_dump(m_db, os);
Neale Ranns812ed392017-10-16 04:20:13 -0700200}
201
202l2_binding::event_handler::event_handler()
203{
204 OM::register_listener(this);
205 inspect::register_handler({ "l2" }, "L2 bindings", this);
206}
207
208void
209l2_binding::event_handler::handle_replay()
210{
211 m_db.replay();
212}
213
214void
215l2_binding::event_handler::handle_populate(const client_db::key_t& key)
216{
217 /**
Neale Ranns1d781552017-11-27 04:52:35 -0800218 * This is done while populating the bridge-domain
219 */
Neale Ranns812ed392017-10-16 04:20:13 -0700220}
221
222dependency_t
223l2_binding::event_handler::order() const
224{
225 return (dependency_t::BINDING);
226}
227
228void
229l2_binding::event_handler::show(std::ostream& os)
230{
Neale Ranns756cd942018-04-06 09:18:11 -0700231 db_dump(m_db, os);
Neale Ranns812ed392017-10-16 04:20:13 -0700232}
233}
234
235/*
236 * fd.io coding-style-patch-verification: ON
237 *
238 * Local Variables:
239 * eval: (c-set-style "mozilla")
240 * End:
241 */