FD.io VPP  v18.01-8-g0eacf49
Vector Packet Processing
prefix.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 #include <sstream>
18 
19 #include "vom/prefix.hpp"
20 
21 namespace VOM {
22 /*
23  * Keep this in sync with VPP's fib_protocol_t
24  */
25 const l3_proto_t l3_proto_t::IPV4(0, "ipv4");
26 const l3_proto_t l3_proto_t::IPV6(1, "ipv6");
27 const l3_proto_t l3_proto_t::MPLS(2, "mpls");
28 
29 l3_proto_t::l3_proto_t(int v, const std::string& s)
30  : enum_base<l3_proto_t>(v, s)
31 {
32 }
33 
34 bool
36 {
37  return (*this == IPV6);
38 }
39 
40 bool
42 {
43  return (*this == IPV4);
44 }
45 
46 const l3_proto_t&
47 l3_proto_t::from_address(const boost::asio::ip::address& addr)
48 {
49  if (addr.is_v6()) {
50  return IPV6;
51  }
52 
53  return IPV4;
54 }
55 
56 std::ostream&
57 operator<<(std::ostream& os, const l3_proto_t& l3p)
58 {
59  os << l3p.to_string();
60  return os;
61 }
62 
63 /*
64  * Keep this in sync with VPP's dpo_proto_t
65  */
66 const nh_proto_t nh_proto_t::IPV4(0, "ipv4");
67 const nh_proto_t nh_proto_t::IPV6(1, "ipv6");
68 const nh_proto_t nh_proto_t::MPLS(2, "mpls");
69 const nh_proto_t nh_proto_t::ETHERNET(3, "ethernet");
70 
71 nh_proto_t::nh_proto_t(int v, const std::string& s)
73 {
74 }
75 
76 const nh_proto_t&
77 nh_proto_t::from_address(const boost::asio::ip::address& addr)
78 {
79  if (addr.is_v6()) {
80  return IPV6;
81  }
82 
83  return IPV4;
84 }
85 
86 /**
87  * The all Zeros prefix
88  */
89 const route::prefix_t route::prefix_t::ZERO("0.0.0.0", 0);
91 
92 route::prefix_t::prefix_t(const boost::asio::ip::address& addr, uint8_t len)
93  : m_addr(addr)
94  , m_len(len)
95 {
96 }
97 
98 route::prefix_t::prefix_t(const boost::asio::ip::address& addr)
99  : m_addr(addr)
100  , m_len(VOM::mask_width(addr))
101 {
102 }
103 
104 route::prefix_t::prefix_t(const std::string& s, uint8_t len)
105  : m_addr(boost::asio::ip::address::from_string(s))
106  , m_len(len)
107 {
108 }
109 
111  : m_addr(o.m_addr)
112  , m_len(o.m_len)
113 {
114 }
115 
117  : m_addr()
118  , m_len(0)
119 {
120 }
121 
123 {
124 }
125 
128 {
129  m_addr = o.m_addr;
130  m_len = o.m_len;
131 
132  return (*this);
133 }
134 
135 const boost::asio::ip::address&
137 {
138  return (m_addr);
139 }
140 
141 uint8_t
143 {
144  return (m_len);
145 }
146 
147 bool
149 {
150  if (m_len == o.m_len) {
151  return (m_addr < o.m_addr);
152  } else {
153  return (m_len < o.m_len);
154  }
155 }
156 
157 bool
159 {
160  return (m_len == o.m_len && m_addr == o.m_addr);
161 }
162 
163 bool
165 {
166  return (!(*this == o));
167 }
168 
169 std::string
171 {
172  std::ostringstream s;
173 
174  s << m_addr.to_string() << "/" << std::to_string(m_len);
175 
176  return (s.str());
177 }
178 
179 boost::asio::ip::address
180 from_bytes(uint8_t is_ip6, uint8_t* bytes)
181 {
182  boost::asio::ip::address addr;
183 
184  if (is_ip6) {
185  std::array<uint8_t, 16> a;
186  std::copy(bytes, bytes + 16, std::begin(a));
187  boost::asio::ip::address_v6 v6(a);
188  addr = v6;
189  } else {
190  std::array<uint8_t, 4> a;
191  std::copy(bytes, bytes + 4, std::begin(a));
192  boost::asio::ip::address_v4 v4(a);
193  addr = v4;
194  }
195 
196  return (addr);
197 }
198 
199 route::prefix_t::prefix_t(uint8_t is_ip6, uint8_t* addr, uint8_t len)
200  : m_addr(from_bytes(is_ip6, addr))
201  , m_len(len)
202 {
203 }
204 void
205 to_bytes(const boost::asio::ip::address_v6& addr, uint8_t* array)
206 {
207  memcpy(array, addr.to_bytes().data(), 16);
208 }
209 
210 void
211 to_bytes(const boost::asio::ip::address_v4& addr, uint8_t* array)
212 {
213  memcpy(array, addr.to_bytes().data(), 4);
214 }
215 
216 void
217 to_bytes(const boost::asio::ip::address& addr, uint8_t* is_ip6, uint8_t* array)
218 {
219  if (addr.is_v6()) {
220  *is_ip6 = 1;
221  to_bytes(addr.to_v6(), array);
222  } else {
223  *is_ip6 = 0;
224  to_bytes(addr.to_v4(), array);
225  }
226 }
227 
228 uint32_t
229 mask_width(const boost::asio::ip::address& addr)
230 {
231  if (addr.is_v6()) {
232  return 128;
233  }
234  return 32;
235 }
236 
237 void
238 route::prefix_t::to_vpp(uint8_t* is_ip6, uint8_t* addr, uint8_t* len) const
239 {
240  *len = m_len;
241  to_bytes(m_addr, is_ip6, addr);
242 }
243 
246 {
247  if (m_addr.is_v6()) {
248  return (l3_proto_t::IPV6);
249  } else {
250  return (l3_proto_t::IPV4);
251  }
252 
253  return (l3_proto_t::IPV4);
254 }
255 
256 std::ostream&
257 operator<<(std::ostream& os, const route::prefix_t& pfx)
258 {
259  os << pfx.to_string();
260 
261  return (os);
262 }
263 
264 boost::asio::ip::address_v4
265 operator|(const boost::asio::ip::address_v4& addr1,
266  const boost::asio::ip::address_v4& addr2)
267 {
268  uint32_t a;
269  a = addr1.to_ulong() | addr2.to_ulong();
270  boost::asio::ip::address_v4 addr(a);
271  return (addr);
272 }
273 
274 boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1,
275  const boost::asio::ip::address_v4& addr2)
276 {
277  uint32_t a;
278  a = addr1.to_ulong() & addr2.to_ulong();
279  boost::asio::ip::address_v4 addr(a);
280  return (addr);
281 }
282 
283 boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1)
284 {
285  uint32_t a;
286  a = ~addr1.to_ulong();
287  boost::asio::ip::address_v4 addr(a);
288  return (addr);
289 }
290 
291 boost::asio::ip::address_v6
292 operator|(const boost::asio::ip::address_v6& addr1,
293  const boost::asio::ip::address_v6& addr2)
294 {
295  boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes();
296  boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes();
297 
298  for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
299  ii < b1.max_size(); ii++) {
300  b1[ii] |= b2[ii];
301  }
302 
303  boost::asio::ip::address_v6 addr(b1);
304  return (addr);
305 }
306 
307 boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1,
308  const boost::asio::ip::address_v6& addr2)
309 {
310  boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes();
311  boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes();
312 
313  for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
314  ii < b1.max_size(); ii++) {
315  b1[ii] &= b2[ii];
316  }
317 
318  boost::asio::ip::address_v6 addr(b1);
319  return (addr);
320 }
321 
322 boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1)
323 {
324  boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes();
325 
326  for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
327  ii < b1.max_size(); ii++) {
328  b1[ii] = ~b1[ii];
329  }
330 
331  boost::asio::ip::address_v6 addr(b1);
332  return (addr);
333 }
334 boost::asio::ip::address
335 operator|(const boost::asio::ip::address& addr1,
336  const boost::asio::ip::address& addr2)
337 {
338  if (addr1.is_v6())
339  return (addr1.to_v6() | addr2.to_v6());
340  else
341  return (addr1.to_v4() | addr2.to_v4());
342 }
343 
344 boost::asio::ip::address operator&(const boost::asio::ip::address& addr1,
345  const boost::asio::ip::address& addr2)
346 {
347  if (addr1.is_v6())
348  return (addr1.to_v6() & addr2.to_v6());
349  else
350  return (addr1.to_v4() & addr2.to_v4());
351 }
352 
353 boost::asio::ip::address operator~(const boost::asio::ip::address& addr1)
354 {
355  if (addr1.is_v6())
356  return ~(addr1.to_v6());
357  else
358  return ~(addr1.to_v4());
359 }
360 
361 boost::asio::ip::address
363 {
364  if (m_addr.is_v6()) {
365  boost::asio::ip::address_v6::bytes_type b =
367 
368  uint8_t n_bits = mask_width();
369 
370  for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
371  ii < b.max_size(); ii++) {
372  for (int8_t bit = 7; bit >= 0 && n_bits; bit--) {
373  b[ii] |= (1 << bit);
374  n_bits--;
375  }
376  if (!n_bits)
377  break;
378  }
379 
380  return (boost::asio::ip::address_v6(b));
381  } else {
382  uint32_t a;
383 
384  a = ~((1 << (32 - mask_width())) - 1);
385 
386  return (boost::asio::ip::address_v4(a));
387  }
388 }
389 
392 {
393  prefix_t pfx(*this);
394 
395  pfx.m_addr = pfx.m_addr & pfx.mask();
396 
397  return (pfx);
398 }
399 
402 {
403  prefix_t pfx(*this);
404 
405  pfx.m_addr = pfx.m_addr | ~pfx.mask();
406 
407  return (pfx);
408 }
409 
410 }; // namespace VOM
411 
412 /*
413  * fd.io coding-style-patch-verification: ON
414  *
415  * Local Variables:
416  * eval: (c-set-style "mozilla")
417  * End:
418  */
a
Definition: bitmap.h:516
bool operator<(const prefix_t &o) const
Less than operator.
Definition: prefix.cpp:148
l3_proto_t l3_proto() const
Get the L3 protocol.
Definition: prefix.cpp:245
static const nh_proto_t IPV6
Definition: prefix.hpp:64
static const nh_proto_t IPV4
Definition: prefix.hpp:63
static const prefix_t ZEROv6
The all Zeros v6 prefix.
Definition: prefix.hpp:168
boost::asio::ip::address mask() const
Return a address representation of the mask, e.g.
Definition: prefix.cpp:362
Types belonging to Routing.
Definition: prefix.hpp:32
static const nh_proto_t & from_address(const boost::asio::ip::address &addr)
Definition: prefix.cpp:77
bool operator!=(const prefix_t &o) const
not equal opartor
Definition: prefix.cpp:164
static const l3_proto_t MPLS
Definition: prefix.hpp:37
prefix_t low() const
get the lowest address in the prefix
Definition: prefix.cpp:391
std::ostream & operator<<(std::ostream &os, const ip_route::key_t &key)
Definition: route.cpp:474
A next-hop protocol describes the protocol of a peer to which packets are sent after matching a route...
Definition: prefix.hpp:60
bool is_ipv4()
Definition: prefix.cpp:41
static const l3_proto_t IPV4
Definition: prefix.hpp:35
static const l3_proto_t IPV6
Definition: prefix.hpp:36
void to_bytes(const boost::asio::ip::address_v6 &addr, uint8_t *array)
Definition: prefix.cpp:205
std::string to_string() const
convert to string format for debug purposes
Definition: prefix.cpp:170
boost::asio::ip::address_v4 operator|(const boost::asio::ip::address_v4 &addr1, const boost::asio::ip::address_v4 &addr2)
Definition: prefix.cpp:265
prefix_t high() const
Get the highest address in the prefix.
Definition: prefix.cpp:401
#define v
Definition: acl.c:341
boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4 &addr1)
Definition: prefix.cpp:283
prefix_t()
Default Constructor - creates ::/0.
Definition: prefix.cpp:116
word any
Definition: types.h:139
void to_vpp(uint8_t *is_ip6, uint8_t *addr, uint8_t *len) const
Convert the prefix into VPP API parameters.
Definition: prefix.cpp:238
boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4 &addr1, const boost::asio::ip::address_v4 &addr2)
Definition: prefix.cpp:274
prefix_t & operator=(const prefix_t &)
Assignement.
Definition: prefix.cpp:127
boost::asio::ip::address from_bytes(uint8_t is_ip6, uint8_t *bytes)
Convert a VPP byte stinrg into a boost addresss.
Definition: prefix.cpp:180
bool operator==(const prefix_t &o) const
equals operator
Definition: prefix.cpp:158
std::ostream & operator<<(std::ostream &os, const std::pair< direction_t, interface::key_t > &key)
static const l3_proto_t & from_address(const boost::asio::ip::address &addr)
Definition: prefix.cpp:47
static const nh_proto_t MPLS
Definition: prefix.hpp:65
The VPP Object Model (VOM) library.
Definition: acl_binding.cpp:19
static const prefix_t ZERO
The all Zeros prefix.
Definition: prefix.hpp:163
uint8_t mask_width() const
Get the network mask width.
Definition: prefix.cpp:142
const std::string & to_string() const
convert to string format for debug purposes
Definition: enum_base.hpp:36
const boost::asio::ip::address & address() const
Get the address.
Definition: prefix.cpp:136
vhost_vring_addr_t addr
Definition: vhost-user.h:83
A prefix defintion.
Definition: prefix.hpp:91
~prefix_t()
Destructor.
Definition: prefix.cpp:122
static const nh_proto_t ETHERNET
Definition: prefix.hpp:66
bool is_ipv6()
Definition: prefix.cpp:35