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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <boost/algorithm/string.hpp>
19 #include "vom/prefix.hpp"
23 * Keep this in sync with VPP's fib_protocol_t
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");
29 l3_proto_t::l3_proto_t(int v, const std::string& s)
30 : enum_base<l3_proto_t>(v, s)
37 return (*this == IPV6);
43 return (*this == IPV4);
47 l3_proto_t::from_address(const boost::asio::ip::address& addr)
57 * Keep this in sync with VPP's dpo_proto_t
59 const nh_proto_t nh_proto_t::IPV4(0, "ipv4");
60 const nh_proto_t nh_proto_t::IPV6(1, "ipv6");
61 const nh_proto_t nh_proto_t::MPLS(2, "mpls");
62 const nh_proto_t nh_proto_t::ETHERNET(3, "ethernet");
64 nh_proto_t::nh_proto_t(int v, const std::string& s)
65 : enum_base<nh_proto_t>(v, s)
70 nh_proto_t::from_address(const boost::asio::ip::address& addr)
80 * The all Zeros prefix
82 const route::prefix_t route::prefix_t::ZERO("0.0.0.0", 0);
83 const route::prefix_t route::prefix_t::ZEROv6("::", 0);
85 route::prefix_t::prefix_t(const boost::asio::ip::address& addr, uint8_t len)
91 route::prefix_t::prefix_t(const boost::asio::ip::address& addr)
93 , m_len(VOM::mask_width(addr))
97 route::prefix_t::prefix_t(const std::string& s, uint8_t len)
98 : m_addr(boost::asio::ip::address::from_string(s))
103 route::prefix_t::prefix_t(const prefix_t& o)
109 route::prefix_t::prefix_t()
115 route::prefix_t::~prefix_t()
120 route::prefix_t::operator=(const route::prefix_t& o)
128 const boost::asio::ip::address&
129 route::prefix_t::address() const
135 route::prefix_t::mask_width() const
141 route::prefix_t::operator<(const route::prefix_t& o) const
143 if (m_len == o.m_len) {
144 return (m_addr < o.m_addr);
146 return (m_len < o.m_len);
151 route::prefix_t::operator==(const route::prefix_t& o) const
153 return (m_len == o.m_len && m_addr == o.m_addr);
157 route::prefix_t::operator!=(const route::prefix_t& o) const
159 return (!(*this == o));
163 route::prefix_t::to_string() const
165 std::ostringstream s;
167 s << m_addr.to_string() << "/" << std::to_string(m_len);
172 boost::asio::ip::address
173 from_bytes(uint8_t is_ip6, uint8_t* bytes)
175 boost::asio::ip::address addr;
178 std::array<uint8_t, 16> a;
179 std::copy(bytes, bytes + 16, std::begin(a));
180 boost::asio::ip::address_v6 v6(a);
183 std::array<uint8_t, 4> a;
184 std::copy(bytes, bytes + 4, std::begin(a));
185 boost::asio::ip::address_v4 v4(a);
192 route::prefix_t::prefix_t(uint8_t is_ip6, uint8_t* addr, uint8_t len)
193 : m_addr(from_bytes(is_ip6, addr))
198 to_bytes(const boost::asio::ip::address_v6& addr, uint8_t* array)
200 memcpy(array, addr.to_bytes().data(), 16);
204 to_bytes(const boost::asio::ip::address_v4& addr, uint8_t* array)
206 memcpy(array, addr.to_bytes().data(), 4);
210 to_bytes(const boost::asio::ip::address& addr, uint8_t* is_ip6, uint8_t* array)
214 to_bytes(addr.to_v6(), array);
217 to_bytes(addr.to_v4(), array);
222 mask_width(const boost::asio::ip::address& addr)
231 route::prefix_t::to_vpp(uint8_t* is_ip6, uint8_t* addr, uint8_t* len) const
234 to_bytes(m_addr, is_ip6, addr);
238 route::prefix_t::l3_proto() const
240 if (m_addr.is_v6()) {
241 return (l3_proto_t::IPV6);
243 return (l3_proto_t::IPV4);
246 return (l3_proto_t::IPV4);
250 operator<<(std::ostream& os, const route::prefix_t& pfx)
252 os << pfx.to_string();
257 boost::asio::ip::address_v4
258 operator|(const boost::asio::ip::address_v4& addr1,
259 const boost::asio::ip::address_v4& addr2)
262 a = addr1.to_ulong() | addr2.to_ulong();
263 boost::asio::ip::address_v4 addr(a);
267 boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1,
268 const boost::asio::ip::address_v4& addr2)
271 a = addr1.to_ulong() & addr2.to_ulong();
272 boost::asio::ip::address_v4 addr(a);
276 boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1)
279 a = ~addr1.to_ulong();
280 boost::asio::ip::address_v4 addr(a);
284 boost::asio::ip::address_v4
285 route::prefix_t::mask() const
289 a = ~((1 << mask_width()) - 1);
290 boost::asio::ip::address_v4 addr(a);
294 boost::asio::ip::address_v4
295 route::prefix_t::low() const
297 boost::asio::ip::address_v4 low;
298 low = address().to_v4() & mask();
302 boost::asio::ip::address_v4
303 route::prefix_t::high() const
305 boost::asio::ip::address_v4 high;
306 high = address().to_v4() | ~mask();
311 * fd.io coding-style-patch-verification: ON
314 * eval: (c-set-style "mozilla")