FD.io VPP  v19.04.4-rc0-5-ge88582fac
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 
41  uint32_t vni)
42  : src(src)
43  , dst(dst)
44  , vni(vni)
45 {
46 }
47 
49  : src()
50  , dst()
51  , vni(0)
52 {
53 }
54 
55 bool
57 {
58  return ((src == other.src) && (dst == other.dst) && (vni == other.vni));
59 }
60 
61 std::string
63 {
64  std::ostringstream s;
65 
66  s << "ep:["
67  << "src:" << src.to_string() << " dst:" << dst.to_string() << " vni:" << vni
68  << "]";
69 
70  return (s.str());
71 }
72 
73 std::string
74 vxlan_tunnel::mk_name(const boost::asio::ip::address& src,
76  const mode_t& mode,
77  uint32_t vni)
78 {
79  std::ostringstream s;
80 
81  s << VXLAN_TUNNEL_NAME << "-" << mode.to_string() << "-" << src << "-" << dst
82  << ":" << vni;
83 
84  return (s.str());
85 }
86 
88  const boost::asio::ip::address& dst,
89  uint32_t vni,
90  const mode_t& mode)
91  : interface(mk_name(src, dst, mode, vni),
92  interface::type_t::VXLAN,
94  , m_tep(src, dst, vni)
95  , m_mode(mode)
96  , m_mcast_itf()
97  , m_rd()
98  , m_table_id(route::DEFAULT_TABLE)
99 {
100 }
101 
103  const boost::asio::ip::address& dst,
104  uint32_t vni,
105  const interface& mcast_itf,
106  const mode_t& mode)
107  : interface(mk_name(src, dst, mode, vni),
108  interface::type_t::VXLAN,
110  , m_tep(src, dst, vni)
111  , m_mode(mode)
112  , m_mcast_itf(mcast_itf.singular())
113  , m_rd()
114  , m_table_id(route::DEFAULT_TABLE)
115 {
116 }
117 
119  const boost::asio::ip::address& dst,
120  uint32_t vni,
121  const route_domain& rd,
122  const mode_t& mode)
123  : interface(mk_name(src, dst, mode, vni),
124  interface::type_t::VXLAN,
126  , m_tep(src, dst, vni)
127  , m_mode(mode)
128  , m_mcast_itf()
129  , m_rd(rd.singular())
130  , m_table_id(m_rd->table_id())
131 {
132 }
133 
135  : interface(o)
136  , m_tep(o.m_tep)
137  , m_mode(o.m_mode)
138  , m_mcast_itf(o.m_mcast_itf)
139  , m_rd(o.m_rd)
140  , m_table_id(o.m_table_id)
141 {
142 }
143 
144 bool
146 {
147  return ((m_tep == other.m_tep) && (m_mode == other.m_mode) &&
148  (m_mcast_itf == other.m_mcast_itf));
149 }
150 
151 const handle_t&
153 {
154  return (m_hdl.data());
155 }
156 
157 std::shared_ptr<vxlan_tunnel>
159 {
160  return std::dynamic_pointer_cast<vxlan_tunnel>(m_db.find(k));
161 }
162 
163 void
164 vxlan_tunnel::sweep()
165 {
166  if (m_hdl) {
167  if (mode_t::STANDARD == m_mode)
169  else if (mode_t::GBP_L2 == m_mode || mode_t::GBP_L3 == m_mode)
171  }
172  HW::write();
173 }
174 
175 void
176 vxlan_tunnel::replay()
177 {
178  if (m_hdl) {
179  if (mode_t::STANDARD == m_mode)
181  m_hdl, name(), m_tep,
182  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
183  else if (mode_t::GBP_L2 == m_mode)
185  m_hdl, name(), m_tep, true,
186  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
187  else if (mode_t::GBP_L3 == m_mode)
189  m_hdl, name(), m_tep, false,
190  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
191  }
192  if (m_rd && (m_rd->table_id() != route::DEFAULT_TABLE)) {
193  HW::enqueue(
195  HW::enqueue(
197  }
198 }
199 
201 {
202  sweep();
203  release();
204 }
205 
206 std::string
208 {
209  std::ostringstream s;
210  s << "vxlan-tunnel: " << m_hdl.to_string() << " " << m_mode.to_string() << " "
211  << m_tep.to_string();
212  if (m_mcast_itf)
213  s << " " << m_mcast_itf->to_string();
214 
215  return (s.str());
216 }
217 
218 void
219 vxlan_tunnel::update(const vxlan_tunnel& desired)
220 {
221  /*
222  * the desired state is always that the interface should be created
223  */
224  if (rc_t::OK != m_hdl.rc()) {
225  if (mode_t::STANDARD == m_mode)
227  m_hdl, name(), m_tep,
228  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
229  else if (mode_t::GBP_L2 == m_mode)
231  m_hdl, name(), m_tep, true,
232  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
233  else if (mode_t::GBP_L3 == m_mode)
235  m_hdl, name(), m_tep, false,
236  (m_mcast_itf ? m_mcast_itf->handle() : handle_t::INVALID)));
237  }
238  if (!m_table_id && m_rd) {
239  HW::enqueue(
241  HW::enqueue(
243  }
244 }
245 
246 std::shared_ptr<vxlan_tunnel>
248 {
249  return std::dynamic_pointer_cast<vxlan_tunnel>(singular_i());
250 }
251 
252 std::shared_ptr<interface>
253 vxlan_tunnel::singular_i() const
254 {
255  return m_db.find_or_add(key(), *this);
256 }
257 
258 void
259 vxlan_tunnel::event_handler::handle_populate(const client_db::key_t& key)
260 {
261  /*
262  * dump VPP current states
263  */
264  {
265  std::shared_ptr<vxlan_tunnel_cmds::dump_cmd> cmd =
266  std::make_shared<vxlan_tunnel_cmds::dump_cmd>();
267 
268  HW::enqueue(cmd);
269  HW::write();
270 
271  for (auto& record : *cmd) {
272  auto& payload = record.get_payload();
273  handle_t hdl(payload.sw_if_index);
275  from_bytes(payload.is_ipv6, payload.src_address);
277  from_bytes(payload.is_ipv6, payload.dst_address);
278 
279  std::shared_ptr<vxlan_tunnel> vt =
280  vxlan_tunnel(src, dst, payload.vni).singular();
281  vt->set(hdl);
282 
283  VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string();
284 
285  OM::commit(key, *vt);
286  }
287  }
288  {
289  std::shared_ptr<vxlan_gbp_tunnel_cmds::dump_cmd> cmd =
290  std::make_shared<vxlan_gbp_tunnel_cmds::dump_cmd>();
291 
292  HW::enqueue(cmd);
293  HW::write();
294 
295  for (auto& record : *cmd) {
296  auto& payload = record.get_payload();
297  handle_t hdl(payload.tunnel.sw_if_index);
298  boost::asio::ip::address src = from_api(payload.tunnel.src);
299  boost::asio::ip::address dst = from_api(payload.tunnel.dst);
300 
301  std::shared_ptr<vxlan_tunnel> vt =
302  vxlan_tunnel(src, dst, payload.tunnel.vni,
303  (payload.tunnel.mode == VXLAN_GBP_API_TUNNEL_MODE_L2
305  : mode_t::GBP_L3))
306  .singular();
307  vt->set(hdl);
308 
309  VOM_LOG(log_level_t::DEBUG) << "dump: " << vt->to_string();
310 
311  OM::commit(key, *vt);
312  }
313  }
314 }
315 
317 {
318  OM::register_listener(this);
319  inspect::register_handler({ "vxlan" }, "VXLAN Tunnels", this);
320 }
321 
322 void
323 vxlan_tunnel::event_handler::handle_replay()
324 {
325  // replay is handled from the interface DB
326 }
327 
329 vxlan_tunnel::event_handler::order() const
330 {
332 }
333 
334 void
335 vxlan_tunnel::event_handler::show(std::ostream& os)
336 {
337  // dumped by the interface handler
338 }
339 
340 }; // namespace VOM
341 
342 /*
343  * fd.io coding-style-patch-verification: ON
344  *
345  * Local Variables:
346  * eval: (c-set-style "mozilla")
347  * End:
348  */
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:233
typedef address
Definition: ip_types.api:30
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
HW::item< handle_t > m_hdl
The SW interface handle VPP has asigned to the interface.
Definition: interface.hpp:535
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.
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
vl_api_ip4_address_t dst
Definition: ipsec_gre.api:39
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:567
const std::string & name() const
Return the interface type.
Definition: interface.cpp:264
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:87
A functor class that creates an VXLAN tunnel.
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
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
vl_api_vxlan_gbp_api_tunnel_mode_t mode
Definition: vxlan_gbp.api:44
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:340
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
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:193
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 vni
Definition: vxlan_gbp.api:42
std::shared_ptr< vxlan_tunnel > singular() const
Return the matching &#39;singular instance&#39;.
void show(char *chroot_path, int verbose)
Definition: svmtool.c:105
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:270
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