FD.io VPP  v21.06-3-gbb25fbf28
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 
38 vxlan_tunnel::endpoint_t::endpoint_t(const boost::asio::ip::address& src,
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 
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 
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 
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)
173  HW::enqueue(new vxlan_tunnel_cmds::create_cmd(
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)
179  HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd(
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)
186  HW::enqueue(new vxlan_gbp_tunnel_cmds::create_cmd(
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(
195  new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl));
196  HW::enqueue(
197  new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl));
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(
249  new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV4, m_hdl));
250  HW::enqueue(
251  new interface_cmds::set_table_cmd(m_table_id, l3_proto_t::IPV6, m_hdl));
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
315  ? mode_t::GBP_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  */
VOM::vxlan_tunnel::find
static std::shared_ptr< vxlan_tunnel > find(const interface::key_t &k)
Fond the singular instance of the interface in the DB by key.
Definition: vxlan_tunnel.cpp:151
VOM::vxlan_tunnel::endpoint_t::dst
boost::asio::ip::address dst
The destination IP address of the endpoint.
Definition: vxlan_tunnel.hpp:70
VOM::HW::write
static rc_t write()
Write/Execute all commands hitherto enqueued.
Definition: hw.cpp:255
VOM::OM::commit
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
VOM::vxlan_tunnel::mode_t::STANDARD
const static mode_t STANDARD
Definition: vxlan_tunnel.hpp:84
VOM_LOG
#define VOM_LOG(lvl)
Definition: logger.hpp:181
VOM::vxlan_tunnel::endpoint_t::operator==
bool operator==(const endpoint_t &o) const
Comparison operator.
Definition: vxlan_tunnel.cpp:53
VOM
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
VOM::inspect::register_handler
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
VOM::dependency_t
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
VOM::rc_t::OK
const static rc_t OK
The HW write was successfull.
Definition: types.hpp:109
VOM::interface::m_db
static singular_db< key_t, interface > m_db
A map of all interfaces key against the interface's name.
Definition: interface.hpp:572
vni
u32 vni
Definition: flow_types.api:160
VOM::interface::m_hdl
HW::item< handle_t > m_hdl
The SW interface handle VPP has asigned to the interface.
Definition: interface.hpp:540
VOM::l3_proto_t::IPV4
const static l3_proto_t IPV4
Definition: prefix.hpp:55
mode
vl_api_tunnel_mode_t mode
Definition: gre.api:48
VOM::from_bytes
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
VOM::interface::name
const std::string & name() const
Return the interface type.
Definition: interface.cpp:271
VOM::vxlan_tunnel_cmds::create_cmd
A Command class that creates an VXLAN tunnel.
Definition: vxlan_tunnel_cmds.hpp:32
interface_cmds.hpp
VOM::vxlan_tunnel::endpoint_t::vni
uint32_t vni
The VNI of the endpoint.
Definition: vxlan_tunnel.hpp:75
key
typedef key
Definition: ipsec_types.api:88
VOM::vxlan_tunnel::to_string
virtual std::string to_string() const
Debug rpint function.
Definition: vxlan_tunnel.cpp:208
VOM::OM::register_listener
static bool register_listener(listener *listener)
Register a listener of events.
Definition: om.cpp:127
VOM::vxlan_tunnel::mode_t::GBP_L3
const static mode_t GBP_L3
Definition: vxlan_tunnel.hpp:86
VOM::interface::key
const key_t & key() const
Return the interface type.
Definition: interface.cpp:277
VOM::vxlan_tunnel_cmds::delete_cmd
A functor class that creates an VXLAN tunnel.
Definition: vxlan_tunnel_cmds.hpp:69
VOM::enum_base
A template base class for all enum types.
Definition: enum_base.hpp:30
VOM::vxlan_tunnel::endpoint_t::src
boost::asio::ip::address src
The src IP address of the endpoint.
Definition: vxlan_tunnel.hpp:65
VOM::interface
A representation of an interface in VPP.
Definition: interface.hpp:41
VOM::client_db::key_t
const typedef 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
VOM::handle_t
A type declaration of an interface handle in VPP.
Definition: types.hpp:233
VOM::HW::enqueue
static void enqueue(cmd *f)
Enqueue A command for execution.
Definition: hw.cpp:212
address
manual_print typedef address
Definition: ip_types.api:96
VOM::vxlan_tunnel
A representation of a VXLAN Tunnel in VPP.
Definition: vxlan_tunnel.hpp:32
src
vl_api_address_t src
Definition: gre.api:54
VOM::HW::item::to_string
std::string to_string() const
convert to string format for debug purposes
Definition: hw.hpp:161
VOM::log_level_t::DEBUG
const static log_level_t DEBUG
Definition: logger.hpp:32
VOM::vxlan_gbp_tunnel_cmds::delete_cmd
A functor class that creates an VXLAN tunnel.
Definition: vxlan_gbp_tunnel_cmds.hpp:70
singular_db_funcs.hpp
VOM::enum_base::to_string
const std::string & to_string() const
convert to string format for debug purposes
Definition: enum_base.hpp:36
VOM::HW::item::rc
rc_t rc() const
Get the HW return code.
Definition: hw.hpp:119
VOM::HW::item::data
T & data()
Return the data read/written.
Definition: hw.hpp:109
VOM::vxlan_tunnel::handle
const handle_t & handle() const
Return VPP's handle to this object.
Definition: vxlan_tunnel.cpp:145
VOM::interface::type_t
An interface type.
Definition: interface.hpp:67
VOM::vxlan_tunnel::endpoint_t::endpoint_t
endpoint_t()
Default constructor.
Definition: vxlan_tunnel.cpp:46
VOM::vxlan_tunnel::mode_t::GPE
const static mode_t GPE
Definition: vxlan_tunnel.hpp:87
VOM::dependency_t::VIRTUAL_INTERFACE
@ VIRTUAL_INTERFACE
virtual interfaces - those that depend on some real interface
VOM::VXLAN_TUNNEL_NAME
const std::string VXLAN_TUNNEL_NAME
Definition: vxlan_tunnel.cpp:25
table_id
u32 table_id
Definition: wireguard.api:102
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
VOM::vxlan_tunnel::mode_t::GBP_L2
const static mode_t GBP_L2
Definition: vxlan_tunnel.hpp:85
VOM::interface::admin_state_t
The admin state of the interface.
Definition: interface.hpp:138
VOM::vxlan_tunnel::operator==
bool operator==(const vxlan_tunnel &vx) const
comparison operator
Definition: vxlan_tunnel.cpp:138
VOM::vxlan_tunnel::endpoint_t::to_string
std::string to_string() const
Debug print function.
Definition: vxlan_tunnel.cpp:59
logger.hpp
VOM::route_domain
A route-domain is a VRF.
Definition: route_domain.hpp:31
VOM::vxlan_gbp_tunnel_cmds::create_cmd
A Command class that creates an VXLAN tunnel.
Definition: vxlan_gbp_tunnel_cmds.hpp:31
VOM::handle_t::INVALID
const static handle_t INVALID
A value of an interface handle_t that means the itf does not exist.
Definition: types.hpp:268
VOM::vxlan_tunnel::mode_t
mode for the tunnel
Definition: vxlan_tunnel.hpp:81
vxlan_gbp_tunnel_cmds.hpp
VOM::vxlan_tunnel::~vxlan_tunnel
~vxlan_tunnel()
Definition: vxlan_tunnel.cpp:201
vxlan_tunnel.hpp
VOM::vxlan_tunnel::vxlan_tunnel
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.
Definition: vxlan_tunnel.cpp:84
VXLAN_GBP_API_TUNNEL_MODE_L2
@ VXLAN_GBP_API_TUNNEL_MODE_L2
Definition: vxlan_gbp.api:23
VOM::interface::key_t
std::string key_t
The key for interface's key.
Definition: interface.hpp:56
VOM::vxlan_tunnel::singular
std::shared_ptr< vxlan_tunnel > singular() const
Return the matching 'singular instance'.
Definition: vxlan_tunnel.cpp:256
show
void show(char *chroot_path, int verbose)
Definition: svmtool.c:104
VOM::route::DEFAULT_TABLE
const static table_id_t DEFAULT_TABLE
The table-id for the default table.
Definition: prefix.hpp:126
VOM::interface::release
void release()
release/remove an interface form the singular store
Definition: interface.cpp:240
event_handler
void event_handler(void *tls_async)
Definition: tls_async.c:334
vxlan_tunnel_cmds.hpp
VOM::from_api
const neighbour::flags_t from_api(vapi_enum_ip_neighbor_flags f)
Definition: api_types.cpp:36
api_types.hpp
VOM::vxlan_tunnel::endpoint_t
Combaintion of attributes that are a unique key for a VXLAN tunnel.
Definition: vxlan_tunnel.hpp:39
VOM::l3_proto_t::IPV6
const static l3_proto_t IPV6
Definition: prefix.hpp:56
string
const char *const string
Definition: cJSON.h:172