FD.io VPP  v18.01-8-g0eacf49
Vector Packet Processing
l2_binding.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 
16 #include "vom/l2_binding.hpp"
17 #include "vom/l2_binding_cmds.hpp"
18 
19 namespace VOM {
20 /**
21  * A DB of all the L2 Configs
22  */
23 singular_db<l2_binding::key_t, l2_binding> l2_binding::m_db;
24 
25 l2_binding::event_handler l2_binding::m_evh;
26 
27 /*
28  * Make sure these are in sync with the smae enum in VPP
29  */
31  0,
32  "disabled");
34  "push-1");
36  "push-2");
40  5,
41  "translate-1-1");
43  6,
44  "translate-1-2");
46  7,
47  "translate-2-1");
49  5,
50  "translate-2-2");
51 
52 l2_binding::l2_vtr_op_t::l2_vtr_op_t(int v, const std::string s)
53  : enum_base<l2_binding::l2_vtr_op_t>(v, s)
54 {
55 }
56 
57 /**
58  * Construct a new object matching the desried state
59  */
61  : m_itf(itf.singular())
62  , m_bd(bd.singular())
63  , m_binding(0)
64  , m_vtr_op(l2_vtr_op_t::L2_VTR_DISABLED, rc_t::UNSET)
65  , m_vtr_op_tag(0)
66 {
67 }
68 
70  : m_itf(o.m_itf)
71  , m_bd(o.m_bd)
72  , m_binding(0)
73  , m_vtr_op(o.m_vtr_op)
74  , m_vtr_op_tag(o.m_vtr_op_tag)
75 {
76 }
77 
78 const l2_binding::key_t&
80 {
81  return (m_itf->key());
82 }
83 
84 bool
86 {
87  return ((*m_itf == *l.m_itf) && (*m_bd == *l.m_bd));
88 }
89 
90 std::shared_ptr<l2_binding>
92 {
93  return (m_db.find(key));
94 }
95 
96 void
97 l2_binding::sweep()
98 {
99  if (m_binding && handle_t::INVALID != m_itf->handle()) {
100  HW::enqueue(
101  new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), m_bd->id(),
102  interface::type_t::BVI == m_itf->type()));
103  }
104 
105  // no need to undo the VTR operation.
106  HW::write();
107 }
108 
109 void
110 l2_binding::replay()
111 {
112  if (m_binding && handle_t::INVALID != m_itf->handle()) {
113  HW::enqueue(
114  new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_bd->id(),
115  interface::type_t::BVI == m_itf->type()));
116  }
117 
118  if (m_vtr_op && handle_t::INVALID != m_itf->handle()) {
119  HW::enqueue(new l2_binding_cmds::set_vtr_op_cmd(m_vtr_op, m_itf->handle(),
120  m_vtr_op_tag));
121  }
122 }
123 
125 {
126  sweep();
127 
128  // not in the DB anymore.
129  m_db.release(m_itf->key(), this);
130 }
131 
132 std::string
134 {
135  std::ostringstream s;
136  s << "L2-binding:[" << m_itf->to_string() << " " << m_bd->to_string() << " "
137  << m_binding.to_string() << "]";
138 
139  return (s.str());
140 }
141 
142 void
143 l2_binding::set(const l2_vtr_op_t& op, uint16_t tag)
144 {
145  assert(rc_t::UNSET == m_vtr_op.rc());
146  m_vtr_op.set(rc_t::NOOP);
147  m_vtr_op.update(op);
148  m_vtr_op_tag = tag;
149 }
150 
151 void
152 l2_binding::update(const l2_binding& desired)
153 {
154  /*
155  * the desired state is always that the interface should be created
156  */
157  if (rc_t::OK != m_binding.rc()) {
158  HW::enqueue(
159  new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_bd->id(),
160  interface::type_t::BVI == m_itf->type()));
161  } else if (!(*m_bd == *desired.m_bd)) {
162  /*
163  * re-binding to a different BD. do unbind, bind.
164  */
165  HW::enqueue(
166  new l2_binding_cmds::unbind_cmd(m_binding, m_itf->handle(), m_bd->id(),
167  interface::type_t::BVI == m_itf->type()));
168  m_bd = desired.m_bd;
169  HW::enqueue(
170  new l2_binding_cmds::bind_cmd(m_binding, m_itf->handle(), m_bd->id(),
171  interface::type_t::BVI == m_itf->type()));
172  }
173 
174  /*
175  * set the VTR operation if request
176  */
177  if (m_vtr_op.update(desired.m_vtr_op)) {
178  HW::enqueue(new l2_binding_cmds::set_vtr_op_cmd(m_vtr_op, m_itf->handle(),
179  m_vtr_op_tag));
180  }
181 }
182 
183 std::shared_ptr<l2_binding>
184 l2_binding::find_or_add(const l2_binding& temp)
185 {
186  return (m_db.find_or_add(temp.m_itf->key(), temp));
187 }
188 
189 std::shared_ptr<l2_binding>
191 {
192  return find_or_add(*this);
193 }
194 
195 void
196 l2_binding::dump(std::ostream& os)
197 {
198  m_db.dump(os);
199 }
200 
201 l2_binding::event_handler::event_handler()
202 {
203  OM::register_listener(this);
204  inspect::register_handler({ "l2" }, "L2 bindings", this);
205 }
206 
207 void
208 l2_binding::event_handler::handle_replay()
209 {
210  m_db.replay();
211 }
212 
213 void
214 l2_binding::event_handler::handle_populate(const client_db::key_t& key)
215 {
216  /**
217  * This is done while populating the bridge-domain
218  */
219 }
220 
222 l2_binding::event_handler::order() const
223 {
224  return (dependency_t::BINDING);
225 }
226 
227 void
228 l2_binding::event_handler::show(std::ostream& os)
229 {
230  m_db.dump(os);
231 }
232 }
233 
234 /*
235  * fd.io coding-style-patch-verification: ON
236  *
237  * Local Variables:
238  * eval: (c-set-style "mozilla")
239  * End:
240  */
binding< l2_list > l2_binding
Typedef the L2 binding type.
static const rc_t NOOP
The HW write/update action was/has not been attempted.
Definition: types.hpp:101
A Clas representing the binding of an L2 interface to a bridge-domain and the properties of that bind...
Definition: l2_binding.hpp:32
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 const l2_vtr_op_t L2_VTR_PUSH_1
Definition: l2_binding.hpp:46
static const l2_vtr_op_t L2_VTR_POP_1
Definition: l2_binding.hpp:48
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
static const l2_vtr_op_t L2_VTR_DISABLED
Definition: l2_binding.hpp:45
static const l2_vtr_op_t L2_VTR_TRANSLATE_1_2
Definition: l2_binding.hpp:51
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:225
Error codes that VPP will return during a HW write.
Definition: types.hpp:84
static std::shared_ptr< l2_binding > find(const key_t &key)
Static function to find the bridge_domain in the model.
Definition: l2_binding.cpp:91
bool operator==(const l2_binding &l) const
Comparison operator - for UT.
Definition: l2_binding.cpp:85
static const handle_t INVALID
A value of an interface handle_t that means the itf does not exist.
Definition: types.hpp:199
std::string to_string() const
convert to string format for debug purposes
Definition: hw.hpp:160
static const l2_vtr_op_t L2_VTR_PUSH_2
Definition: l2_binding.hpp:47
A functor class that binds L2 configuration to an interface.
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:118
std::string to_string() const
convert to string format for debug purposes
Definition: l2_binding.cpp:133
#define v
Definition: acl.c:341
const key_t & key() const
Return the binding&#39;s key.
Definition: l2_binding.cpp:79
static const l2_vtr_op_t L2_VTR_TRANSLATE_2_1
Definition: l2_binding.hpp:52
interface::key_t key_t
Key type for an L2 binding in the singular DB.
Definition: l2_binding.hpp:38
std::shared_ptr< l2_binding > singular() const
Return the &#39;singular instance&#39; of the L2 config that matches this object.
Definition: l2_binding.cpp:190
A representation of an interface in VPP.
Definition: interface.hpp:41
A base class for all object_base in the VPP object_base-Model.
~l2_binding()
Destructor.
Definition: l2_binding.cpp:124
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
A cmd class that Unbinds L2 configuration from an interface.
static const rc_t OK
The HW write was successfull.
Definition: types.hpp:106
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:189
void set(const l2_vtr_op_t &op, uint16_t tag)
Set the VTR operation on the binding/interface.
Definition: l2_binding.cpp:143
l2_vtr_op_t
Definition: l2_vtr.h:27
Then L2/objects that bind to interfaces, BD, ACLS, etc.
static const l2_vtr_op_t L2_VTR_TRANSLATE_2_2
Definition: l2_binding.hpp:53
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
static const rc_t UNSET
The value un-set.
Definition: types.hpp:96
Definition: hash.c:482
static const type_t BVI
A brideged Virtual interface (aka SVI or IRB)
Definition: interface.hpp:67
l2_binding(const interface &itf, const bridge_domain &bd)
Construct a new object matching the desried state.
Definition: l2_binding.cpp:60
void show(char *chroot_path, int verbose)
Definition: svmtool.c:105
l2_vtr_op_t(const l2_vtr_op_t &l)=default
static const l2_vtr_op_t L2_VTR_TRANSLATE_1_1
Definition: l2_binding.hpp:50
A cmd class sets the VTR operation.
static void dump(std::ostream &os)
Dump all l2_bindings into the stream provided.
Definition: l2_binding.cpp:196
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:124
static const l2_vtr_op_t L2_VTR_POP_2
Definition: l2_binding.hpp:49