VOM: prefix bit fiddling
Change-Id: I4fbf4a574f455628d56e78cefc1a76adc06bc801 Signed-off-by: Neale Ranns <neale.ranns@cisco.com>
This commit is contained in:
@ -281,32 +281,127 @@ boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1)
|
||||
return (addr);
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v4
|
||||
route::prefix_t::mask() const
|
||||
boost::asio::ip::address_v6
|
||||
operator|(const boost::asio::ip::address_v6& addr1,
|
||||
const boost::asio::ip::address_v6& addr2)
|
||||
{
|
||||
uint32_t a;
|
||||
boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes();
|
||||
boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes();
|
||||
|
||||
a = ~((1 << mask_width()) - 1);
|
||||
boost::asio::ip::address_v4 addr(a);
|
||||
for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
|
||||
ii < b1.max_size(); ii++) {
|
||||
b1[ii] |= b2[ii];
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v6 addr(b1);
|
||||
return (addr);
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v4
|
||||
route::prefix_t::low() const
|
||||
boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1,
|
||||
const boost::asio::ip::address_v6& addr2)
|
||||
{
|
||||
boost::asio::ip::address_v4 low;
|
||||
low = address().to_v4() & mask();
|
||||
return (low);
|
||||
boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes();
|
||||
boost::asio::ip::address_v6::bytes_type b2 = addr2.to_bytes();
|
||||
|
||||
for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
|
||||
ii < b1.max_size(); ii++) {
|
||||
b1[ii] &= b2[ii];
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v6 addr(b1);
|
||||
return (addr);
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v4
|
||||
boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1)
|
||||
{
|
||||
boost::asio::ip::address_v6::bytes_type b1 = addr1.to_bytes();
|
||||
|
||||
for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
|
||||
ii < b1.max_size(); ii++) {
|
||||
b1[ii] = ~b1[ii];
|
||||
}
|
||||
|
||||
boost::asio::ip::address_v6 addr(b1);
|
||||
return (addr);
|
||||
}
|
||||
boost::asio::ip::address
|
||||
operator|(const boost::asio::ip::address& addr1,
|
||||
const boost::asio::ip::address& addr2)
|
||||
{
|
||||
if (addr1.is_v6())
|
||||
return (addr1.to_v6() | addr2.to_v6());
|
||||
else
|
||||
return (addr1.to_v4() | addr2.to_v4());
|
||||
}
|
||||
|
||||
boost::asio::ip::address operator&(const boost::asio::ip::address& addr1,
|
||||
const boost::asio::ip::address& addr2)
|
||||
{
|
||||
if (addr1.is_v6())
|
||||
return (addr1.to_v6() & addr2.to_v6());
|
||||
else
|
||||
return (addr1.to_v4() & addr2.to_v4());
|
||||
}
|
||||
|
||||
boost::asio::ip::address operator~(const boost::asio::ip::address& addr1)
|
||||
{
|
||||
if (addr1.is_v6())
|
||||
return ~(addr1.to_v6());
|
||||
else
|
||||
return ~(addr1.to_v4());
|
||||
}
|
||||
|
||||
boost::asio::ip::address
|
||||
route::prefix_t::mask() const
|
||||
{
|
||||
if (m_addr.is_v6()) {
|
||||
boost::asio::ip::address_v6::bytes_type b =
|
||||
boost::asio::ip::address_v6::any().to_bytes();
|
||||
|
||||
uint8_t n_bits = mask_width();
|
||||
|
||||
for (boost::asio::ip::address_v6::bytes_type::size_type ii = 0;
|
||||
ii < b.max_size(); ii++) {
|
||||
for (int8_t bit = 7; bit >= 0 && n_bits; bit--) {
|
||||
b[ii] |= (1 << bit);
|
||||
n_bits--;
|
||||
}
|
||||
if (!n_bits)
|
||||
break;
|
||||
}
|
||||
|
||||
return (boost::asio::ip::address_v6(b));
|
||||
} else {
|
||||
uint32_t a;
|
||||
|
||||
a = ~((1 << (32 - mask_width())) - 1);
|
||||
|
||||
return (boost::asio::ip::address_v4(a));
|
||||
}
|
||||
}
|
||||
|
||||
route::prefix_t
|
||||
route::prefix_t::low() const
|
||||
{
|
||||
prefix_t pfx(*this);
|
||||
|
||||
pfx.m_addr = pfx.m_addr & pfx.mask();
|
||||
|
||||
return (pfx);
|
||||
}
|
||||
|
||||
route::prefix_t
|
||||
route::prefix_t::high() const
|
||||
{
|
||||
boost::asio::ip::address_v4 high;
|
||||
high = address().to_v4() | ~mask();
|
||||
return (high);
|
||||
}
|
||||
prefix_t pfx(*this);
|
||||
|
||||
pfx.m_addr = pfx.m_addr | ~pfx.mask();
|
||||
|
||||
return (pfx);
|
||||
}
|
||||
|
||||
}; // namespace VOM
|
||||
|
||||
/*
|
||||
* fd.io coding-style-patch-verification: ON
|
||||
*
|
||||
|
@ -170,17 +170,17 @@ public:
|
||||
/**
|
||||
* Return a address representation of the mask, e.g. 255.255.0.0
|
||||
*/
|
||||
boost::asio::ip::address_v4 mask() const;
|
||||
boost::asio::ip::address mask() const;
|
||||
|
||||
/**
|
||||
* get the lowest address in the prefix
|
||||
*/
|
||||
boost::asio::ip::address_v4 low() const;
|
||||
prefix_t low() const;
|
||||
|
||||
/**
|
||||
* Get the highest address in the prefix
|
||||
*/
|
||||
boost::asio::ip::address_v4 high() const;
|
||||
prefix_t high() const;
|
||||
|
||||
/**
|
||||
* Get the L3 protocol
|
||||
@ -208,6 +208,22 @@ boost::asio::ip::address_v4 operator&(const boost::asio::ip::address_v4& addr1,
|
||||
|
||||
boost::asio::ip::address_v4 operator~(const boost::asio::ip::address_v4& addr1);
|
||||
|
||||
boost::asio::ip::address_v6 operator|(const boost::asio::ip::address_v6& addr1,
|
||||
const boost::asio::ip::address_v6& addr2);
|
||||
|
||||
boost::asio::ip::address_v6 operator&(const boost::asio::ip::address_v6& addr1,
|
||||
const boost::asio::ip::address_v6& addr2);
|
||||
|
||||
boost::asio::ip::address_v6 operator~(const boost::asio::ip::address_v6& addr1);
|
||||
|
||||
boost::asio::ip::address operator|(const boost::asio::ip::address& addr1,
|
||||
const boost::asio::ip::address& addr2);
|
||||
|
||||
boost::asio::ip::address operator&(const boost::asio::ip::address& addr1,
|
||||
const boost::asio::ip::address& addr2);
|
||||
|
||||
boost::asio::ip::address operator~(const boost::asio::ip::address& addr1);
|
||||
|
||||
/**
|
||||
* Ostream printer for prefix_t
|
||||
*/
|
||||
|
@ -101,8 +101,8 @@ route_domain::to_string() const
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "route-domain:["
|
||||
<< "table-id:" << m_table_id << " v4:" << m_hw_v4 << " v6:" << m_hw_v6
|
||||
<< "]";
|
||||
<< "table-id:" << m_table_id << " v4:" << m_hw_v4.to_string()
|
||||
<< " v6:" << m_hw_v6.to_string() << "]";
|
||||
|
||||
return (s.str());
|
||||
}
|
||||
|
@ -472,7 +472,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(VppOM_test)
|
||||
BOOST_AUTO_TEST_SUITE(vom)
|
||||
|
||||
#define TRY_CHECK_RC(stmt) \
|
||||
{ \
|
||||
@ -1594,4 +1594,42 @@ BOOST_AUTO_TEST_CASE(test_interface_route_domain_change) {
|
||||
TRY_CHECK(OM::remove(rene));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_prefixes) {
|
||||
route::prefix_t p6_s_16(boost::asio::ip::address::from_string("2001::"), 16);
|
||||
|
||||
BOOST_CHECK(p6_s_16.mask() == boost::asio::ip::address::from_string("ffff::"));
|
||||
|
||||
route::prefix_t p6_s_17(boost::asio::ip::address::from_string("2001:ff00::"), 17);
|
||||
|
||||
BOOST_CHECK(p6_s_17.mask() == boost::asio::ip::address::from_string("ffff:8000::"));
|
||||
BOOST_CHECK(p6_s_17.low().address() == boost::asio::ip::address::from_string("2001:8000::"));
|
||||
|
||||
route::prefix_t p6_s_15(boost::asio::ip::address::from_string("2001:ff00::"), 15);
|
||||
BOOST_CHECK(p6_s_15.mask() == boost::asio::ip::address::from_string("fffe::"));
|
||||
BOOST_CHECK(p6_s_15.low().address() == boost::asio::ip::address::from_string("2000::"));
|
||||
|
||||
route::prefix_t p4_s_16(boost::asio::ip::address::from_string("192.168.0.0"), 16);
|
||||
|
||||
BOOST_CHECK(p4_s_16.mask() == boost::asio::ip::address::from_string("255.255.0.0"));
|
||||
|
||||
route::prefix_t p4_s_17(boost::asio::ip::address::from_string("192.168.127.0"), 17);
|
||||
|
||||
BOOST_CHECK(p4_s_17.mask() == boost::asio::ip::address::from_string("255.255.128.0"));
|
||||
BOOST_CHECK(p4_s_17.low().address() == boost::asio::ip::address::from_string("192.168.0.0"));
|
||||
BOOST_CHECK(p4_s_17.high().address() == boost::asio::ip::address::from_string("192.168.127.255"));
|
||||
|
||||
route::prefix_t p4_s_15(boost::asio::ip::address::from_string("192.168.255.255"), 15);
|
||||
|
||||
BOOST_CHECK(p4_s_15.mask() == boost::asio::ip::address::from_string("255.254.0.0"));
|
||||
BOOST_CHECK(p4_s_15.low().address() == boost::asio::ip::address::from_string("192.168.0.0"));
|
||||
BOOST_CHECK(p4_s_15.high().address() == boost::asio::ip::address::from_string("192.169.255.255"));
|
||||
|
||||
route::prefix_t p4_s_32(boost::asio::ip::address::from_string("192.168.1.1"), 32);
|
||||
|
||||
BOOST_CHECK(p4_s_32.mask() == boost::asio::ip::address::from_string("255.255.255.255"));
|
||||
BOOST_CHECK(p4_s_32.low().address() == boost::asio::ip::address::from_string("192.168.1.1"));
|
||||
BOOST_CHECK(p4_s_32.high().address() == boost::asio::ip::address::from_string("192.168.1.1"));
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
Reference in New Issue
Block a user