FD.io VPP  v21.01.1
Vector Packet Processing
interface_factory.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 <boost/algorithm/string.hpp>
17 
18 #include "vom/bond_interface.hpp"
19 #include "vom/bond_member.hpp"
21 #include "vom/sub_interface.hpp"
22 #include "vom/tap_interface.hpp"
23 
24 namespace VOM {
25 std::shared_ptr<interface>
26 interface_factory::new_interface(const vapi_payload_sw_interface_details& vd)
27 {
28  std::shared_ptr<interface> sp;
29 
30  /**
31  * Determine the interface type from the name and VLAN attributes
32  */
33  std::string name = reinterpret_cast<const char*>(vd.interface_name);
34  std::string device_type =
35  reinterpret_cast<const char*>(vd.interface_dev_type);
39  handle_t hdl(vd.sw_if_index);
40  l2_address_t l2_address(vd.l2_address, 6);
41  std::string tag = "";
42 
43  if (interface::type_t::UNKNOWN == type) {
44  return sp;
45  }
46 
47  sp = interface::find(hdl);
48  if (sp) {
49  sp->set(state);
50  sp->set(l2_address);
51  if (!tag.empty())
52  sp->set(tag);
53  return sp;
54  }
55 
56  /*
57  * If here, Fall back to old routine
58  */
59  if (interface::type_t::AFPACKET == type) {
60  /*
61  * need to strip VPP's "host-" prefix from the interface name
62  */
63  name = name.substr(5);
64  }
65  /**
66  * if the tag is set, then we wrote that to specify a name to make
67  * the interface type more specific
68  */
69  if (vd.tag[0] != 0) {
70  tag = std::string(reinterpret_cast<const char*>(vd.tag));
71  }
72 
73  if (!tag.empty() && interface::type_t::LOOPBACK == type) {
74  name = tag;
75  type = interface::type_t::from_string(name);
76  }
77 
78  /*
79  * pull out the other special cases
80  */
81  if (interface::type_t::TAPV2 == type) {
82  /*
83  * TAP interfaces
84  */
85  sp = interface::find(hdl);
86  if (sp && !tag.empty())
87  sp->set(tag);
88  } else if (interface::type_t::PIPE == type) {
89  /*
90  * there's not enough information in a SW interface record to
91  * construct a pipe. so skip it. They have
92  * their own dump routines
93  */
94  } else if ((name.find(".") != std::string::npos) && (0 != vd.sub_id)) {
95  /*
96  * Sub-interface
97  * split the name into the parent and VLAN
98  */
99  std::vector<std::string> parts;
100  std::shared_ptr<interface> parent;
101  boost::split(parts, name, boost::is_any_of("."));
102 
103  if ((parent = interface::find(parts[0])))
104  sp = sub_interface(*parent, state, vd.sub_id).singular();
105  else {
106  interface parent_itf(parts[0], type, state, tag);
107  sp = sub_interface(parent_itf, state, vd.sub_id).singular();
108  }
109  } else if (interface::type_t::VXLAN == type) {
110  /*
111  * there's not enough information in a SW interface record to
112  * construct a VXLAN tunnel. so skip it. They have
113  * their own dump routines
114  */
115  } else if (interface::type_t::VHOST == type) {
116  /*
117  * vhost interface already exist in db, look for it using
118  * sw_if_index
119  */
120  } else if (interface::type_t::BOND == type) {
121  sp = bond_interface(
122  name, state, l2_address, bond_interface::mode_t::UNSPECIFIED)
123  .singular();
124  } else {
125  sp = interface(name, type, state, tag).singular();
126  sp->set(l2_address);
127  }
128 
129  /*
130  * set the handle on the intterface - N.B. this is the sigluar instance
131  * not a stack local.
132  */
133  if (sp)
134  sp->set(hdl);
135 
136  return (sp);
137 }
138 
139 std::shared_ptr<interface>
141  const vapi_payload_sw_interface_vhost_user_details& vd)
142 {
143  std::shared_ptr<interface> sp;
144  std::string name = reinterpret_cast<const char*>(vd.sock_filename);
145  handle_t hdl(vd.sw_if_index);
146 
148  .singular();
149  sp->set(hdl);
150  return (sp);
151 }
152 
153 std::shared_ptr<interface>
155  const vapi_payload_af_packet_details& vd)
156 {
157  std::shared_ptr<interface> sp;
158  std::string name = reinterpret_cast<const char*>(vd.host_if_name);
159  handle_t hdl(vd.sw_if_index);
160 
161  sp =
163  .singular();
164  sp->set(hdl);
165  return (sp);
166 }
167 
168 std::shared_ptr<tap_interface>
170  const vapi_payload_sw_interface_tap_v2_details& vd)
171 {
172  std::shared_ptr<tap_interface> sp;
173  handle_t hdl(vd.sw_if_index);
174  std::string name = reinterpret_cast<const char*>(vd.host_if_name);
177 
178  if (vd.host_ip4_prefix.len)
179  pfx = route::prefix_t(
180  0, (uint8_t*)vd.host_ip4_prefix.address, vd.host_ip4_prefix.len);
181  else if (vd.host_ip6_prefix.len)
182  pfx = route::prefix_t(
183  1, (uint8_t*)vd.host_ip6_prefix.address, vd.host_ip6_prefix.len);
184 
185  l2_address_t l2_address(vd.host_mac_addr, 6);
186  sp = tap_interface(name, interface::admin_state_t::UP, pfx, l2_address)
187  .singular();
188 
189  sp->set(hdl);
190 
191  return (sp);
192 }
193 
194 std::shared_ptr<bond_interface>
196  const vapi_payload_sw_interface_bond_details& vd)
197 {
198  std::shared_ptr<bond_interface> sp;
199  std::string name = reinterpret_cast<const char*>(vd.interface_name);
200  handle_t hdl(vd.sw_if_index);
204  sp = bond_interface::find(hdl);
205  if (sp) {
206  sp->set(mode);
207  sp->set(lb);
208  }
209  return (sp);
210 }
211 
214  const vapi_payload_sw_interface_slave_details& vd)
215 {
216  std::shared_ptr<bond_member> sp;
217  std::string name = reinterpret_cast<const char*>(vd.interface_name);
218  handle_t hdl(vd.sw_if_index);
221  bond_member::rate_t rate =
222  bond_member::rate_t::from_numeric_val(vd.is_long_timeout);
223  std::shared_ptr<interface> itf = interface::find(hdl);
224  bond_member bm(*itf, mode, rate);
225  return (bm);
226 }
227 
228 std::shared_ptr<pipe>
229 interface_factory::new_pipe_interface(const vapi_payload_pipe_details& payload)
230 {
231  std::shared_ptr<pipe> sp;
232 
233  handle_t hdl(payload.sw_if_index);
234  pipe::handle_pair_t hdl_pair(payload.pipe_sw_if_index[0],
235  payload.pipe_sw_if_index[1]);
236 
237  sp = pipe(payload.instance, interface::admin_state_t::UP).singular();
238 
239  sp->set(hdl);
240  sp->set_ends(hdl_pair);
241 
242  return (sp);
243 }
244 
245 }; // namespace VOM
246 
247 /*
248  * fd.io coding-style-patch-verification: OFF
249  *
250  * Local Variables:
251  * eval: (c-set-style "mozilla")
252  * End:
253  */
A member interface mode.
Definition: bond_member.hpp:32
A Pipe interface.
Definition: pipe.hpp:31
A tap-interface.
static const type_t AFPACKET
AF-Packet interface type.
Definition: interface.hpp:88
static const type_t BOND
bond interface type
Definition: interface.hpp:111
static std::shared_ptr< interface > find(const handle_t &h)
The the singular instance of the interface in the DB by handle.
Definition: interface.cpp:538
const char *const string
Definition: cJSON.h:172
A Sub-interface.
static std::shared_ptr< pipe > new_pipe_interface(const vapi_payload_pipe_details &payload)
static const type_t PIPE
pipe-parent type
Definition: interface.hpp:116
vhost_vring_addr_t addr
Definition: vhost_user.h:111
A bond-member.
Definition: bond_member.hpp:26
static const lb_t from_numeric_val(uint8_t v)
Convert VPP&#39;s value of the bond to a lb.
A bond interface load balance.
Type def of a L2 address as read from VPP.
Definition: types.hpp:339
static std::shared_ptr< interface > new_af_packet_interface(const vapi_payload_af_packet_details &vd)
vl_api_fib_path_type_t type
Definition: fib_types.api:123
static std::shared_ptr< interface > new_interface(const vapi_payload_sw_interface_details &vd)
Factory method to construct a new interface from the VPP record.
static const mode_t UNSPECIFIED
Unspecified bond interface mode.
std::shared_ptr< sub_interface > singular() const
Return the matching &#39;singular instance&#39; of the sub-interface.
vl_api_tunnel_mode_t mode
Definition: gre.api:48
static std::shared_ptr< interface > new_vhost_user_interface(const vapi_payload_sw_interface_vhost_user_details &vd)
A bond-interface.
static const mode_t from_numeric_val(uint8_t v)
Convert VPP&#39;s value of the bond to a mode.
Definition: bond_member.cpp:93
static const rate_t from_numeric_val(uint8_t v)
Convert VPP&#39;s value of the bond to a mode.
static admin_state_t from_int(uint8_t val)
Convert VPP&#39;s numerical value to enum type.
static bond_member new_bond_member_interface(const vapi_payload_sw_interface_slave_details &vd)
The admin state of the interface.
Definition: interface.hpp:138
static std::shared_ptr< tap_interface > new_tap_interface(const vapi_payload_sw_interface_tap_v2_details &vd)
A representation of an interface in VPP.
Definition: interface.hpp:41
A type declaration of an interface handle in VPP.
Definition: types.hpp:233
string name[64]
Definition: ip.api:44
A bond interface mode.
std::shared_ptr< interface > singular() const
Return the matching&#39;singular&#39; of the interface.
Definition: interface.cpp:526
manual_print typedef address
Definition: ip_types.api:96
static type_t from_string(const std::string &str)
Convert VPP&#39;s name of the interface to a type.
std::shared_ptr< bond_interface > singular() const
Return the matching &#39;singular instance&#39; of the BOND interface.
static const type_t UNKNOWN
Unknown type.
Definition: interface.hpp:72
std::pair< handle_t, handle_t > handle_pair_t
Definition: pipe.hpp:34
A member interface rate.
Definition: bond_member.hpp:58
An interface type.
Definition: interface.hpp:67
static const type_t VXLAN
VXLAN interface.
Definition: interface.hpp:80
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
static const admin_state_t UP
Admin UP state.
Definition: interface.hpp:147
std::shared_ptr< pipe > singular() const
Return the matching &#39;singular instance&#39; of the sub-interface.
Definition: pipe.cpp:87
static const prefix_t ZERO
The all Zeros prefix.
Definition: prefix.hpp:205
static const admin_state_t DOWN
Admin DOWN state.
Definition: interface.hpp:143
vl_api_dhcp_client_state_t state
Definition: dhcp.api:201
static std::shared_ptr< bond_interface > find(const handle_t &hdl)
The the singular instance of the bond interface in the DB by handle.
static const type_t TAPV2
TAPv2 interface type.
Definition: interface.hpp:101
static const mode_t from_numeric_val(uint8_t v)
Convert VPP&#39;s value of the bond to a mode.
std::shared_ptr< tap_interface > singular() const
Return the matching &#39;singular instance&#39; of the TAP interface.
static const type_t LOOPBACK
loopback interface type
Definition: interface.hpp:92
static const type_t VHOST
vhost-user interface type
Definition: interface.hpp:106
A prefix defintion.
Definition: prefix.hpp:131
static std::shared_ptr< bond_interface > new_bond_interface(const vapi_payload_sw_interface_bond_details &vd)