FD.io VPP  v21.01.1
Vector Packet Processing
vxlan_tunnel.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/vxlan_tunnel.hpp"
17 #include "vom/api_types.hpp"
18 #include "vom/interface_cmds.hpp"
19 #include "vom/logger.hpp"
23 
24 namespace VOM {
25 const std::string VXLAN_TUNNEL_NAME = "vxlan-tunnel-itf";
26 
27 vxlan_tunnel::event_handler vxlan_tunnel::m_evh;
28 
33 
34 vxlan_tunnel::mode_t::mode_t(int v, const std::string s)
35  : enum_base<vxlan_tunnel::mode_t>(v, s)
36 {}
37 
40  uint32_t vni)
41  : src(src)
42  , dst(dst)
43  , vni(vni)
44 {}
45 
47  : src()
48  , dst()
49  , vni(0)
50 {}
51 
52 bool
54 {
55  return ((src == other.src) && (dst == other.dst) && (vni == other.vni));
56 }
57 
60 {
61  std::ostringstream s;
62 
63  s << "ep:["
64  << "src:" << src.to_string() << " dst:" << dst.to_string() << " vni:" << vni
65  << "]";
66 
67  return (s.str());
68 }
69 
71 vxlan_tunnel::mk_name(const boost::asio::ip::address& src,
73  const mode_t& mode,
74  uint32_t vni)
75 {
76  std::ostringstream s;
77 
78  s << VXLAN_TUNNEL_NAME << "-" << mode.to_string() << "-" << src << "-" << dst
79  << ":" << vni;
80 
81  return (s.str());
82 }
83 
85  const boost::asio::ip::address& dst,
86  uint32_t vni,
87  const mode_t& mode)
88  : interface(mk_name(src, dst, mode, vni),
89  interface::type_t::VXLAN,
91  , m_tep(src, dst, vni)
92  , m_mode(mode)
93  , m_mcast_itf()
94  , m_rd()
95  , m_table_id(route::DEFAULT_TABLE)
96 {}
97 
99  const boost::asio::ip::address& dst,
100  uint32_t vni,
101  const interface& mcast_itf,
102  const mode_t& mode)
103  : interface(mk_name(src, dst, mode, vni),
104  interface::type_t::VXLAN,
106  , m_tep(src, dst, vni)
107  , m_mode(mode)
108  , m_mcast_itf(mcast_itf.singular())
109  , m_rd()
110  , m_table_id(route::DEFAULT_TABLE)
111 {}
112 
114  const boost::asio::ip::address& dst,
115  uint32_t vni,
116  const route_domain& rd,
117  const mode_t& mode)
118  : interface(mk_name(src, dst, mode, vni),
119  interface::type_t::VXLAN,
121  , m_tep(src, dst, vni)
122  , m_mode(mode)
123  , m_mcast_itf()
124  , m_rd(rd.singular())
125  , m_table_id(m_rd->table_id())
126 {}
127 
129  : interface(o)
130  , m_tep(o.m_tep)
131  , m_mode(o.m_mode)
132  , m_mcast_itf(o.m_mcast_itf)
133  , m_rd(o.m_rd)
134  , m_table_id(o.m_table_id)
135 {}
136 
137 bool
139 {
140  return ((m_tep == other.m_tep) && (m_mode == other.m_mode) &&
141  (m_mcast_itf == other.m_mcast_itf));
142 }
143 
144 const handle_t&
146 {
147  return (m_hdl.data());
148 }
149 
150 std::shared_ptr<vxlan_tunnel>
152 {
153  return std::dynamic_pointer_cast<vxlan_tunnel>(m_db.find(k));
154 }
155 
156 void
157 vxlan_tunnel::sweep()
158 {
159  if (m_hdl) {
160  if (mode_t::STANDARD == m_mode)
162  else if (mode_t::GBP_L2 == m_mode || mode_t::GBP_L3 == m_mode)
164  }
165  HW::write();
166 }
167 
168 void
169 vxlan_tunnel::replay()
170 {
171  if (m_hdl) {
172  if (mode_t::STANDARD == m_mode)
174  m_hdl,
175  name(),
176  m_tep,
177  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
178  else if (mode_t::GBP_L2 == m_mode)
180  m_hdl,
181  name(),
182  m_tep,
183  true,
184  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
185  else if (mode_t::GBP_L3 == m_mode)
187  m_hdl,
188  name(),
189  m_tep,
190  false,
191  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
192  }
193  if (m_rd && (m_rd->table_id() != route::DEFAULT_TABLE)) {
194  HW::enqueue(
196  HW::enqueue(
198  }
199 }
200 
202 {
203  sweep();
204  release();
205 }
206 
209 {
210  std::ostringstream s;
211  s << "vxlan-tunnel: " << m_hdl.to_string() << " " << m_mode.to_string() << " "
212  << m_tep.to_string();
213  if (m_mcast_itf)
214  s << " " << m_mcast_itf->to_string();
215 
216  return (s.str());
217 }
218 
219 void
220 vxlan_tunnel::update(const vxlan_tunnel& desired)
221 {
222  /*
223  * the desired state is always that the interface should be created
224  */
225  if (rc_t::OK != m_hdl.rc()) {
226  if (mode_t::STANDARD == m_mode)
228  m_hdl,
229  name(),
230  m_tep,
231  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
232  else if (mode_t::GBP_L2 == m_mode)
234  m_hdl,
235  name(),
236  m_tep,
237  true,
238  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
239  else if (mode_t::GBP_L3 == m_mode)
241  m_hdl,
242  name(),
243  m_tep,
244  false,
245  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
246  }
247  if (!m_table_id && m_rd) {
248  HW::enqueue(
250  HW::enqueue(
252  }
253 }
254 
255 std::shared_ptr<vxlan_tunnel>
257 {
258  return std::dynamic_pointer_cast<vxlan_tunnel>(singular_i());
259 }
260 
261 std::shared_ptr<interface>
262 vxlan_tunnel::singular_i() const
263 {
264  return m_db.find_or_add(key(), *this);
265 }
266 
267 void
268 vxlan_tunnel::event_handler::handle_populate(const client_db::key_t& key)
269 {
270  /*
271  * dump VPP current states
272  */
273  {
274  std::shared_ptr<vxlan_tunnel_cmds::dump_cmd> cmd =
275  std::make_shared<vxlan_tunnel_cmds::dump_cmd>();
276 
277  HW::enqueue(cmd);
278  HW::write();
279 
280  for (auto& record : *cmd) {
281  auto& payload = record.get_payload();
282  handle_t hdl(payload.sw_if_index);
284  from_bytes(payload.src_address.af, (uint8_t*)&payload.src_address.un);
286  from_bytes(payload.dst_address.af, (uint8_t*)&payload.dst_address.un);
287 
288  std::shared_ptr<vxlan_tunnel> vt =
289  vxlan_tunnel(src, dst, payload.vni).singular();
290  vt->set(hdl);
291 
292  VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string();
293 
294  OM::commit(key, *vt);
295  }
296  }
297  {
298  std::shared_ptr<vxlan_gbp_tunnel_cmds::dump_cmd> cmd =
299  std::make_shared<vxlan_gbp_tunnel_cmds::dump_cmd>();
300 
301  HW::enqueue(cmd);
302  HW::write();
303 
304  for (auto& record : *cmd) {
305  auto& payload = record.get_payload();
306  handle_t hdl(payload.tunnel.sw_if_index);
307  boost::asio::ip::address src = from_api(payload.tunnel.src);
308  boost::asio::ip::address dst = from_api(payload.tunnel.dst);
309 
310  std::shared_ptr<vxlan_tunnel> vt =
311  vxlan_tunnel(src,
312  dst,
313  payload.tunnel.vni,
314  (payload.tunnel.mode == VXLAN_GBP_API_TUNNEL_MODE_L2
316  : mode_t::GBP_L3))
317  .singular();
318  vt->set(hdl);
319 
320  VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string();
321 
322  OM::commit(key, *vt);
323  }
324  }
325 }
326 
328 {
329  OM::register_listener(this);
330  inspect::register_handler({ "vxlan" }, "VXLAN Tunnels", this);
331 }
332 
333 void
334 vxlan_tunnel::event_handler::handle_replay()
335 {
336  // replay is handled from the interface DB
337 }
338 
340 vxlan_tunnel::event_handler::order() const
341 {
343 }
344 
345 void
346 vxlan_tunnel::event_handler::show(std::ostream& os)
347 {
348  // dumped by the interface handler
349 }
350 
351 }; // namespace VOM
352 
353 /*
354  * fd.io coding-style-patch-verification: OFF
355  *
356  * Local Variables:
357  * eval: (c-set-style "mozilla")
358  * End:
359  */
A Command class that creates an VXLAN tunnel.
A representation of a VXLAN Tunnel in VPP.
void release()
release/remove an interface form the singular store
Definition: interface.cpp:240
u16 vni
Definition: flow_types.api:160
const std::string VXLAN_TUNNEL_NAME
static const mode_t GPE
#define VOM_LOG(lvl)
Definition: logger.hpp:181
static std::shared_ptr< vxlan_tunnel > find(const interface::key_t &k)
Fond the singular instance of the interface in the DB by key.
A template base class for all enum types.
Definition: enum_base.hpp:30
Combaintion of attributes that are a unique key for a VXLAN tunnel.
mode for the tunnel
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
virtual interfaces - those that depend on some real interface
const char *const string
Definition: cJSON.h:172
HW::item< handle_t > m_hdl
The SW interface handle VPP has asigned to the interface.
Definition: interface.hpp:540
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
boost::asio::ip::address dst
The destination IP address of the endpoint.
vl_api_address_t src
Definition: gre.api:54
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 const handle_t INVALID
A value of an interface handle_t that means the itf does not exist.
Definition: types.hpp:268
virtual std::string to_string() const
Debug rpint function.
A Command class that creates an VXLAN tunnel.
A route-domain is a VRF.
T & data()
Return the data read/written.
Definition: hw.hpp:109
static const mode_t GBP_L3
std::string to_string() const
convert to string format for debug purposes
Definition: hw.hpp:161
static singular_db< key_t, interface > m_db
A map of all interfaces key against the interface&#39;s name.
Definition: interface.hpp:572
const std::string & name() const
Return the interface type.
Definition: interface.cpp:271
static const l3_proto_t IPV4
Definition: prefix.hpp:55
static const l3_proto_t IPV6
Definition: prefix.hpp:56
static const table_id_t DEFAULT_TABLE
The table-id for the default table.
Definition: prefix.hpp:126
A functor class that creates an VXLAN tunnel.
vl_api_address_t dst
Definition: gre.api:55
vl_api_tunnel_mode_t mode
Definition: gre.api:48
A command class that binds an interface to an L3 table.
The admin state of the interface.
Definition: interface.hpp:138
A representation of an interface in VPP.
Definition: interface.hpp:41
const handle_t & handle() const
Return VPP&#39;s handle to this object.
A type declaration of an interface handle in VPP.
Definition: types.hpp:233
const std::string & to_string() const
convert to string format for debug purposes
Definition: enum_base.hpp:36
endpoint_t()
Default constructor.
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:334
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
manual_print typedef address
Definition: ip_types.api:96
boost::asio::ip::address from_bytes(uint8_t is_ip6, const uint8_t *bytes)
Convert a VPP byte stinrg into a boost addresss.
Definition: prefix.cpp:224
bool operator==(const vxlan_tunnel &vx) const
comparison operator
An interface type.
Definition: interface.hpp:67
static const mode_t STANDARD
bool operator==(const endpoint_t &o) const
Comparison operator.
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
const neighbour::flags_t from_api(vapi_enum_ip_neighbor_flags f)
Definition: api_types.cpp:36
A representation of a method call to VPP.
Definition: cmd.hpp:32
A functor class that creates an VXLAN tunnel.
u32 table_id
Definition: wireguard.api:102
std::shared_ptr< vxlan_tunnel > singular() const
Return the matching &#39;singular instance&#39;.
void show(char *chroot_path, int verbose)
Definition: svmtool.c:104
uint32_t vni
The VNI of the endpoint.
static const mode_t GBP_L2
std::string to_string() const
Debug print function.
const key_t & key() const
Return the interface type.
Definition: interface.cpp:277
std::string key_t
The key for interface&#39;s key.
Definition: interface.hpp:56
vxlan_tunnel(const boost::asio::ip::address &src, const boost::asio::ip::address &dst, uint32_t vni, const mode_t &mode=mode_t::STANDARD)
Construct a new object matching the desried state.
boost::asio::ip::address src
The src IP address of the endpoint.
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:127