Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'master' of https://github.com/i-maravic/xorp.ct

  • Loading branch information...
commit 277de9cc102fad981d161a104a3531c28d437532 2 parents 3e39c91 + 8ce7308
@greearb authored
Showing with 1,913 additions and 2,050 deletions.
  1. +16 −0 xorp/SConstruct
  2. +38 −20 xorp/libxorp/ipnet.hh
  3. +2 −24 xorp/libxorp/ipv4.cc
  4. +40 −2 xorp/libxorp/ipv4.hh
  5. +2 −63 xorp/libxorp/ipv6.cc
  6. +72 −2 xorp/libxorp/ipv6.hh
  7. +100 −0 xorp/libxorp/memory_pool.hh
  8. +46 −0 xorp/libxorp/nexthop.cc
  9. +24 −2 xorp/libxorp/nexthop.hh
  10. +91 −24 xorp/libxorp/tests/test_trie.cc
  11. +36 −11 xorp/libxorp/trie.hh
  12. +5 −1 xorp/libxorp/xlog.h
  13. +3 −0  xorp/policy/backend/policy_redist_map.cc
  14. +0 −2  xorp/rib/SConscript
  15. +4 −2 xorp/rib/parser.cc
  16. +1 −1  xorp/rib/parser_direct_cmds.hh
  17. +2 −3 xorp/rib/protocol.cc
  18. +1 −1  xorp/rib/protocol.hh
  19. +120 −461 xorp/rib/rib.cc
  20. +24 −112 xorp/rib/rib.hh
  21. +95 −12 xorp/rib/route.cc
  22. +67 −34 xorp/rib/route.hh
  23. +2 −4 xorp/rib/rt_tab_base.cc
  24. +13 −16 xorp/rib/rt_tab_base.hh
  25. +43 −126 xorp/rib/rt_tab_deletion.cc
  26. +73 −43 xorp/rib/rt_tab_deletion.hh
  27. +447 −466 xorp/rib/rt_tab_extint.cc
  28. +53 −25 xorp/rib/rt_tab_extint.hh
  29. +17 −29 xorp/rib/rt_tab_log.cc
  30. +10 −13 xorp/rib/rt_tab_log.hh
  31. +44 −80 xorp/rib/rt_tab_origin.cc
  32. +73 −45 xorp/rib/rt_tab_origin.hh
  33. +43 −112 xorp/rib/rt_tab_pol_conn.cc
  34. +9 −9 xorp/rib/rt_tab_pol_conn.hh
  35. +37 −56 xorp/rib/rt_tab_pol_redist.cc
  36. +8 −10 xorp/rib/rt_tab_pol_redist.hh
  37. +57 −48 xorp/rib/rt_tab_redist.cc
  38. +15 −11 xorp/rib/rt_tab_redist.hh
  39. +58 −33 xorp/rib/rt_tab_register.cc
  40. +29 −57 xorp/rib/rt_tab_register.hh
  41. +22 −0 xorp/rib/tests/commands
  42. +8 −20 xorp/rib/tests/rt_tab_expect.cc
  43. +12 −6 xorp/rib/tests/rt_tab_expect.hh
  44. +12 −16 xorp/rib/tests/test_deletion.cc
  45. +25 −22 xorp/rib/tests/test_redist.cc
  46. +12 −6 xorp/rib/tests/test_register.cc
  47. +0 −20 xorp/rtrmgr/template.ll
  48. +2 −0  xorp/site_scons/config/allconfig.py
View
16 xorp/SConstruct
@@ -83,6 +83,7 @@ vars.AddVariables(
BoolVariable('disable_otherlogs', 'Force disable other logs', False),
BoolVariable('disable_profile', 'Disable Xorp Profiler feature', False),
BoolVariable('disable_werror', 'Disable -Werror compiler flag', False),
+ BoolVariable('disable_assert', 'Force disabling assertions - use with caution', False),
BoolVariable('enable_lex_hack', 'Works around lex/yacc issues on FreeBSD', False),
BoolVariable('enable_builddirrun', 'Enable Xorp to run from BUILD_DIR', False),
BoolVariable('enable_boost', 'Use BOOST', False),
@@ -298,6 +299,7 @@ print 'Disable fatal logs : ', env['disable_fatallogs']
print 'Disable info logs : ', env['disable_infologs']
print 'Disable assert logs : ', env['disable_assertlogs']
print 'Disable other logs : ', env['disable_otherlogs']
+print 'Disable assert: ', env['disable_assert']
env['CONFIGURELOG'] = str(builddir) + os.sep + 'config.log'
@@ -604,6 +606,20 @@ if tst and not ((tst == "no") or (tst == "false")):
else:
env['disable_otherlogs'] = False
+tst = ARGUMENTS.get('disable_assert', False)
+if tst and not ((tst == "no") or (tst == "false")):
+ env['disable_assert'] = True
+ env['disable_werror'] = True
+ env['disable_otherlogs'] = True
+ env['disable_assertlogs'] = True
+ env['disable_infologs'] = True
+ env['disable_fatallogs'] = True
+ env['disable_tracelogs'] = True
+ env['disable_errorlogs'] = True
+ env['disable_warninglogs'] = True
+else:
+ env['disable_assert'] = False
+
########## start configure magic
if env.has_key('LIBS'):
View
58 xorp/libxorp/ipnet.hh
@@ -9,13 +9,13 @@
// Redistribution and/or modification of this program under the terms of
// any other version of the GNU Lesser General Public License is not
// permitted.
-//
+//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU Lesser General Public License, Version 2.1, a copy of
// which can be found in the XORP LICENSE.lgpl file.
-//
+//
// XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
@@ -104,8 +104,8 @@ public:
* right-hand operand.
*/
bool operator==(const IPNet& other) const {
- return ((prefix_len() == other.prefix_len()) &&
- (masked_addr() == other.masked_addr()));
+ return ((_prefix_len == other._prefix_len) &&
+ (_masked_addr == other._masked_addr));
}
/**
@@ -456,7 +456,8 @@ private:
/* ------------------------------------------------------------------------- */
/* Deferred method definitions */
-template <class A> bool
+template <class A>
+inline bool
IPNet<A>::operator<(const IPNet& other) const
{
#if 1
@@ -548,23 +549,38 @@ IPNet<A>::is_overlap(const IPNet<A>& other) const
return (other.masked_addr() == masked_addr());
}
-template <class A> bool
-IPNet<A>::contains(const IPNet<A>& other) const
+template <>
+inline bool
+IPNet<IPv4>::contains(const IPv4& addr) const
{
- if (masked_addr().af() != other.masked_addr().af())
- return (false);
+ return addr.mask_by_prefix_len_uint(_prefix_len) == _masked_addr.addr();
+}
- if (prefix_len() > other.prefix_len()) {
+template <>
+inline bool
+IPNet<IPv6>::contains(const IPv6& addr) const
+{
+ uint32_t prefixed_addr[4];
+ addr.mask_by_prefix_len_uint(_prefix_len, prefixed_addr);
+ return ((prefixed_addr[0] == _masked_addr.addr()[0])
+ && (prefixed_addr[1] == _masked_addr.addr()[1])
+ && (prefixed_addr[2] == _masked_addr.addr()[2])
+ && (prefixed_addr[3] == _masked_addr.addr()[3]));
+}
+
+template <class A>
+inline bool
+IPNet<A>::contains(const IPNet<A>& other) const
+{
+ if (_prefix_len > other._prefix_len)
// I have smaller prefix size, hence I don't contain other.
return (false);
- }
- if (prefix_len() < other.prefix_len()) {
- // I have bigger prefix size
- IPNet other_masked(other.masked_addr(), prefix_len());
- return (other_masked.masked_addr() == masked_addr());
- }
- // Same prefix size
- return (other.masked_addr() == masked_addr());
+
+ if (_prefix_len == other._prefix_len)
+ return (other._masked_addr == _masked_addr);
+
+ // I have bigger prefix size
+ return (contains(other._masked_addr));
}
template <class A> void
@@ -591,7 +607,8 @@ IPNet<A>::initialize_from_string(const char *cp)
_masked_addr = A(addr.c_str()).mask_by_prefix_len(_prefix_len);
}
-template <class A> IPNet<A>&
+template <class A>
+inline IPNet<A>&
IPNet<A>::operator--()
{
_masked_addr = _masked_addr >> (_masked_addr.addr_bitlen() - _prefix_len);
@@ -600,7 +617,8 @@ IPNet<A>::operator--()
return (*this);
}
-template <class A> IPNet<A>&
+template <class A>
+inline IPNet<A>&
IPNet<A>::operator++()
{
_masked_addr = _masked_addr >> (_masked_addr.addr_bitlen() - _prefix_len);
View
26 xorp/libxorp/ipv4.cc
@@ -8,13 +8,13 @@
// Redistribution and/or modification of this program under the terms of
// any other version of the GNU Lesser General Public License is not
// permitted.
-//
+//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU Lesser General Public License, Version 2.1, a copy of
// which can be found in the XORP LICENSE.lgpl file.
-//
+//
// XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
@@ -219,12 +219,6 @@ IPv4::operator>>(uint32_t right_shift) const
return IPv4(htonl(tmp_addr));
}
-bool
-IPv4::operator<(const IPv4& other) const
-{
- return ntohl(_addr) < ntohl(other._addr);
-}
-
IPv4
IPv4::make_prefix(uint32_t mask_len) throw (InvalidNetmaskLength)
{
@@ -251,22 +245,6 @@ IPv4::mask_len() const
return ctr;
}
-IPv4&
-IPv4::operator--()
-{
- uint32_t tmp_addr = ntohl(_addr) - 1;
- _addr = htonl(tmp_addr);
- return *this;
-}
-
-IPv4&
-IPv4::operator++()
-{
- uint32_t tmp_addr = ntohl(_addr) + 1;
- _addr = htonl(tmp_addr);
- return *this;
-}
-
string
IPv4::str() const
{
View
42 xorp/libxorp/ipv4.hh
@@ -9,13 +9,13 @@
// Redistribution and/or modification of this program under the terms of
// any other version of the GNU Lesser General Public License is not
// permitted.
-//
+//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU Lesser General Public License, Version 2.1, a copy of
// which can be found in the XORP LICENSE.lgpl file.
-//
+//
// XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
@@ -612,6 +612,8 @@ public:
*/
static IPv4 make_prefix(uint32_t mask_len) throw (InvalidNetmaskLength);
+ static uint32_t make_prefix_uint(uint32_t mask_len) throw (InvalidNetmaskLength);
+
/**
* Make an IPv4 address prefix.
*
@@ -624,6 +626,11 @@ public:
return (*this) & make_prefix(mask_len);
}
+ uint32_t mask_by_prefix_len_uint(uint32_t mask_len) const
+ throw (InvalidNetmaskLength) {
+ return this->_addr & make_prefix_uint(mask_len);
+ }
+
/**
* Get the mask length.
*
@@ -748,6 +755,31 @@ IPv4::bits(uint32_t lsb, uint32_t len) const
}
inline uint32_t
+IPv4::make_prefix_uint(uint32_t mask_len) throw (InvalidNetmaskLength)
+{
+ if (mask_len > 32)
+ xorp_throw(InvalidNetmaskLength, mask_len);
+ uint32_t m = (mask_len == 0) ? 0 : ((~0U) << (32 - mask_len));
+ return htonl(m);
+}
+
+inline IPv4&
+IPv4::operator--()
+{
+ uint32_t tmp_addr = ntohl(_addr) - 1;
+ _addr = htonl(tmp_addr);
+ return *this;
+}
+
+inline IPv4&
+IPv4::operator++()
+{
+ uint32_t tmp_addr = ntohl(_addr) + 1;
+ _addr = htonl(tmp_addr);
+ return *this;
+}
+
+inline uint32_t
IPv4::bit_count() const
{
// XXX: no need for ntohl()
@@ -760,6 +792,12 @@ IPv4::leading_zero_count() const
return (xorp_leading_zero_count_uint32(ntohl(_addr)));
}
+inline bool
+IPv4::operator<(const IPv4& other) const
+{
+ return ntohl(_addr) < ntohl(other._addr);
+}
+
struct IPv4Constants {
static const IPv4 zero,
any,
View
65 xorp/libxorp/ipv6.cc
@@ -8,13 +8,13 @@
// Redistribution and/or modification of this program under the terms of
// any other version of the GNU Lesser General Public License is not
// permitted.
-//
+//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU Lesser General Public License, Version 2.1, a copy of
// which can be found in the XORP LICENSE.lgpl file.
-//
+//
// XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
@@ -329,67 +329,6 @@ IPv6::operator>>(uint32_t rs) const
return IPv6(tmp_addr);
}
-bool
-IPv6::operator<(const IPv6& other) const
-{
- int i;
- x_static_assert(sizeof(_addr) == 16);
-
- for (i = 0; i < 3; i++) { // XXX: Loop ends intentionally at 3 not 4
- if (_addr[i] != other._addr[i])
- break;
- }
- return ntohl(_addr[i]) < ntohl(other._addr[i]);
-}
-
-bool
-IPv6::operator==(const IPv6& other) const
-{
- return ((_addr[0] == other._addr[0])
- && (_addr[1] == other._addr[1])
- && (_addr[2] == other._addr[2])
- && (_addr[3] == other._addr[3]));
-}
-
-bool
-IPv6::operator!=(const IPv6& other) const
-{
- return ((_addr[0] != other._addr[0])
- || (_addr[1] != other._addr[1])
- || (_addr[2] != other._addr[2])
- || (_addr[3] != other._addr[3]));
-}
-
-IPv6&
-IPv6::operator--()
-{
- for (int i = 3; i >= 0; i--) {
- if (_addr[i] == 0) {
- _addr[i] = 0xffffffffU;
- } else {
- uint32_t tmp_addr = ntohl(_addr[i]) - 1;
- _addr[i] = htonl(tmp_addr);
- return *this;
- }
- }
- return *this;
-}
-
-IPv6&
-IPv6::operator++()
-{
- for (int i = 3; i >= 0; i--) {
- if (_addr[i] == 0xffffffffU) {
- _addr[i] = 0;
- } else {
- uint32_t tmp_addr = ntohl(_addr[i]) + 1;
- _addr[i] = htonl(tmp_addr);
- return *this;
- }
- }
- return *this;
-}
-
static uint32_t
init_prefixes(IPv6* v6prefix)
{
View
74 xorp/libxorp/ipv6.hh
@@ -9,13 +9,13 @@
// Redistribution and/or modification of this program under the terms of
// any other version of the GNU Lesser General Public License is not
// permitted.
-//
+//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU Lesser General Public License, Version 2.1, a copy of
// which can be found in the XORP LICENSE.lgpl file.
-//
+//
// XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
@@ -514,6 +514,15 @@ public:
return (*this) & make_prefix(prefix_len);
}
+ void mask_by_prefix_len_uint(uint32_t prefix_len, uint32_t* masked_addr) const
+ throw (InvalidNetmaskLength) {
+ const IPv6& other = make_prefix(prefix_len);
+ masked_addr[0] = _addr[0] & other._addr[0];
+ masked_addr[1] = _addr[1] & other._addr[1];
+ masked_addr[2] = _addr[2] & other._addr[2];
+ masked_addr[3] = _addr[3] & other._addr[3];
+ }
+
/**
* Get the mask length.
*
@@ -661,6 +670,67 @@ IPv6::leading_zero_count() const
return (r);
}
+inline bool
+IPv6::operator<(const IPv6& other) const
+{
+ int i;
+ x_static_assert(sizeof(_addr) == 16);
+
+ for (i = 0; i < 3; i++) { // XXX: Loop ends intentionally at 3 not 4
+ if (_addr[i] != other._addr[i])
+ break;
+ }
+ return ntohl(_addr[i]) < ntohl(other._addr[i]);
+}
+
+inline bool
+IPv6::operator==(const IPv6& other) const
+{
+ return ((_addr[0] == other._addr[0])
+ && (_addr[1] == other._addr[1])
+ && (_addr[2] == other._addr[2])
+ && (_addr[3] == other._addr[3]));
+}
+
+inline bool
+IPv6::operator!=(const IPv6& other) const
+{
+ return ((_addr[0] != other._addr[0])
+ || (_addr[1] != other._addr[1])
+ || (_addr[2] != other._addr[2])
+ || (_addr[3] != other._addr[3]));
+}
+
+inline IPv6&
+IPv6::operator--()
+{
+ for (int i = 3; i >= 0; i--) {
+ if (_addr[i] == 0) {
+ _addr[i] = 0xffffffffU;
+ } else {
+ uint32_t tmp_addr = ntohl(_addr[i]) - 1;
+ _addr[i] = htonl(tmp_addr);
+ return *this;
+ }
+ }
+ return *this;
+}
+
+inline IPv6&
+IPv6::operator++()
+{
+ for (int i = 3; i >= 0; i--) {
+ if (_addr[i] == 0xffffffffU) {
+ _addr[i] = 0;
+ } else {
+ uint32_t tmp_addr = ntohl(_addr[i]) + 1;
+ _addr[i] = htonl(tmp_addr);
+ return *this;
+ }
+ }
+ return *this;
+}
+
struct IPv6Constants {
static const IPv6 zero,
any,
View
100 xorp/libxorp/memory_pool.hh
@@ -0,0 +1,100 @@
+// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
+// vim:set sts=4 ts=8:
+
+// Copyright (c) 2012 XORP, Inc and Others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, Version 2, June
+// 1991 as published by the Free Software Foundation. Redistribution
+// and/or modification of this program under the terms of any other
+// version of the GNU General Public License is not permitted.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
+// see the GNU General Public License, Version 2, a copy of which can be
+// found in the XORP LICENSE.gpl file.
+//
+// XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
+// http://xorp.net
+
+#ifndef _LIBXORP_MEMORY_POOL_HH_
+#define _LIBXORP_MEMORY_POOL_HH_
+
+#include "xorp.h"
+
+template <class T, size_t EXPANSION_SIZE = 100>
+class MemoryPool : public NONCOPYABLE {
+public:
+ MemoryPool();
+ ~MemoryPool();
+
+ //Allocate element of type T from free list
+ void* alloc();
+
+ // Return element to the free list
+ void free(void* doomed);
+private:
+ // next element on the free list
+ MemoryPool<T, EXPANSION_SIZE>* _next;
+
+ // Add free elements to the list
+ void expand_free_list();
+
+ size_t _size;
+};
+
+template <class T, size_t EXPANSION_SIZE>
+MemoryPool<T, EXPANSION_SIZE>::MemoryPool() :
+ _size((sizeof(T) > sizeof(MemoryPool<T, EXPANSION_SIZE>)) ? sizeof(T) :sizeof(MemoryPool<T, EXPANSION_SIZE>))
+{
+ expand_free_list();
+}
+
+template <class T, size_t EXPANSION_SIZE>
+MemoryPool<T, EXPANSION_SIZE>::~MemoryPool()
+{
+ for (MemoryPool<T, EXPANSION_SIZE> *nextPtr = _next; nextPtr != NULL; nextPtr = _next) {
+ _next = _next->_next;
+ delete [] reinterpret_cast<char* >(nextPtr);
+ }
+}
+
+template <class T, size_t EXPANSION_SIZE>
+inline void*
+MemoryPool<T, EXPANSION_SIZE>::alloc()
+{
+ if (!_next)
+ expand_free_list();
+
+ MemoryPool<T, EXPANSION_SIZE>* head = _next;
+ _next = head->_next;
+ return head;
+}
+
+template <class T, size_t EXPANSION_SIZE>
+inline void
+MemoryPool<T, EXPANSION_SIZE>::free(void* doomed)
+{
+ MemoryPool<T, EXPANSION_SIZE>* head = reinterpret_cast<MemoryPool<T, EXPANSION_SIZE>* >(doomed);
+
+ head->_next = _next;
+ _next = head;
+}
+
+template <class T, size_t EXPANSION_SIZE>
+inline void
+MemoryPool<T, EXPANSION_SIZE>::expand_free_list()
+{
+ // We must allocate object large enough to contain the next pointer
+ MemoryPool<T, EXPANSION_SIZE>* runner = reinterpret_cast<MemoryPool<T, EXPANSION_SIZE>* >(new char[_size]);
+
+ _next = runner;
+ for (size_t i = 0; i < EXPANSION_SIZE; ++i) {
+ runner->_next = reinterpret_cast<MemoryPool<T, EXPANSION_SIZE>* >(new char[_size]);
+ runner = runner->_next;
+ }
+ runner->_next = NULL;
+}
+
+#endif /* MEMORY_POOL_HH_ */
View
46 xorp/libxorp/nexthop.cc
@@ -70,6 +70,29 @@ IPPeerNextHop<A>::IPPeerNextHop(const A& from_ipaddr)
}
template<class A>
+void*
+IPPeerNextHop<A>::operator new(size_t/* size*/)
+{
+ return memory_pool().alloc();
+}
+
+template<class A>
+void
+IPPeerNextHop<A>::operator delete(void* ptr)
+{
+ memory_pool().free(ptr);
+}
+
+template<class A>
+inline
+MemoryPool<IPPeerNextHop<A> >&
+IPPeerNextHop<A>::memory_pool()
+{
+ static MemoryPool<IPPeerNextHop<A> > mp;
+ return mp;
+}
+
+template<class A>
IPEncapsNextHop<A>::IPEncapsNextHop(const A& from_ipaddr)
: IPNextHop<A>(from_ipaddr)
{
@@ -81,6 +104,29 @@ IPExternalNextHop<A>::IPExternalNextHop(const A& from_ipaddr)
{
}
+template<class A>
+void*
+IPExternalNextHop<A>::operator new(size_t/* size*/)
+{
+ return memory_pool().alloc();
+}
+
+template<class A>
+void
+IPExternalNextHop<A>::operator delete(void* ptr)
+{
+ memory_pool().free(ptr);
+}
+
+template<class A>
+inline
+MemoryPool<IPExternalNextHop<A> >&
+IPExternalNextHop<A>::memory_pool()
+{
+ static MemoryPool<IPExternalNextHop<A> > mp;
+ return mp;
+}
+
template <class A>
DiscardNextHop<A>::DiscardNextHop()
: IPNextHop<A>(A::ZERO())
View
26 xorp/libxorp/nexthop.hh
@@ -28,6 +28,7 @@
#include "ipv4.hh"
#include "ipv6.hh"
#include "ipvx.hh"
+#include "memory_pool.hh"
// NextHop is a generic next hop object.
// PeerNextHop is for next hops that are local peers.
@@ -115,6 +116,8 @@ public:
*/
IPNextHop(const A &from_ipaddr);
+ virtual ~IPNextHop() { }
+
#ifdef XORP_USE_USTL
IPNextHop() { }
#endif
@@ -134,6 +137,12 @@ public:
*/
string str() const;
+ /**
+ * Returns pointer to copy of IPNextHop
+ *
+ * Callers ARE RESPONSIBLE for freeing the memory
+ */
+
protected:
const A _addr;
};
@@ -171,8 +180,13 @@ public:
*/
int type() const { return PEER_NEXTHOP; }
-private:
+ IPPeerNextHop* get_copy() { return new IPPeerNextHop<A>(*this); }
+
+ void* operator new(size_t size);
+ void operator delete(void* ptr);
+private:
+ static MemoryPool<IPPeerNextHop<A> >& memory_pool();
};
typedef IPPeerNextHop<IPv4> IPv4PeerNextHop;
@@ -204,6 +218,7 @@ public:
*/
int type() const { return ENCAPS_NEXTHOP; }
+
private:
//_cached_peer is the cached copy of the local peer we send the
//encapsulated packet to.
@@ -248,8 +263,13 @@ public:
*/
int type() const { return EXTERNAL_NEXTHOP; }
-private:
+ IPExternalNextHop* get_copy() { return new IPExternalNextHop<A>(*this); }
+
+ void* operator new(size_t size);
+ void operator delete(void* ptr);
+private:
+ static MemoryPool<IPExternalNextHop<A> >& memory_pool();
};
typedef IPExternalNextHop<IPv4> IPv4ExternalNextHop;
@@ -277,6 +297,7 @@ public:
*/
int type() const { return DISCARD_NEXTHOP; }
+
private:
};
@@ -302,6 +323,7 @@ public:
*/
int type() const { return UNREACHABLE_NEXTHOP; }
+
private:
};
View
115 xorp/libxorp/tests/test_trie.cc
@@ -9,13 +9,13 @@
// Redistribution and/or modification of this program under the terms of
// any other version of the GNU Lesser General Public License is not
// permitted.
-//
+//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
// see the GNU Lesser General Public License, Version 2.1, a copy of
// which can be found in the XORP LICENSE.lgpl file.
-//
+//
// XORP, Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
// http://xorp.net
@@ -124,7 +124,7 @@ void test_upper_bound(IPv4 test_addr, IPv4 test_answer) {
print_passed(result.str());
} else {
print_failed("");
- printf("answer should be %s, result was %s\n",
+ printf("answer should be %s, result was %s\n",
test_answer.str().c_str(), result.str().c_str());
trie.print();
abort();
@@ -142,7 +142,7 @@ void test_lower_bound(IPv4 test_addr, IPv4 test_answer) {
print_passed(result.str());
} else {
print_failed("");
- printf("Fail: answer should be %s, result was %s\n",
+ printf("Fail: answer should be %s, result was %s\n",
test_answer.str().c_str(), result.str().c_str());
trie.print();
abort();
@@ -202,7 +202,7 @@ void test_upper_bound6(IPv6 test_addr, IPv6 test_answer) {
print_passed(result.str());
} else {
print_failed("");
- printf("Fail: answer should be %s, result was %s\n",
+ printf("Fail: answer should be %s, result was %s\n",
test_answer.str().c_str(), result.str().c_str());
trie.print();
abort();
@@ -216,19 +216,22 @@ test_find_subtree()
printf("Find subtree\n");
Trie<IPv4, string> trie_subtree;
-
+
IPv4Net n1(IPv4("169.229.0.136"), 29);
trie_subtree.insert(n1, "169.229.0.136/29");
IPv4Net n2(IPv4("192.150.187.0"), 25);
trie_subtree.insert(n2, "192.150.187.0/25");
-
+
IPv4Net n3(IPv4("192.168.254.2"), 32);
trie_subtree.insert(n3, "192.168.254.2/32");
IPv4Net n4(IPv4("192.168.254.3"), 32);
trie_subtree.insert(n4, "192.168.254.3/32");
+ IPv4Net n5(IPv4("192.168.254.4"), 32);
+ trie_subtree.insert(n5, "192.168.254.4/32");
+
trie_subtree.print();
IPv4Net nsearch1(IPv4("192.150.187.248"), 29);
@@ -241,8 +244,8 @@ test_find_subtree()
abort();
}
- IPv4Net n5(IPv4("192.150.187.248"), 29);
- trie_subtree.insert(n5, "192.150.187.248/29");
+ IPv4Net n6(IPv4("192.150.187.248"), 29);
+ trie_subtree.insert(n6, "192.150.187.248/29");
IPv4Net nsearch2(IPv4("192.150.187.0"), 25);
trie_subtree.erase(n2);
@@ -256,6 +259,70 @@ test_find_subtree()
abort();
}
+ IPv4Net nsearchReally(IPv4("192.168.254.0"), 24);
+ iter = trie_subtree.search_subtree(nsearchReally);
+ int i = 0;
+ printf("--- Results for %s\n", nsearchReally.str().c_str());
+ for( ; iter != trie_subtree.end(); iter++) {
+ i++;
+ printf("subtree = %s\n", iter.payload().c_str());
+ }
+ printf("---\n");
+
+ if (i != 3) {
+ print_failed("");
+ printf("We expected three entries to be found and we found %d", i);
+ abort();
+ }
+
+ IPv4Net nsearchReally2(IPv4("192.0.0.0"), 8);
+ iter = trie_subtree.search_subtree(nsearchReally2);
+
+ printf("--- Results for %s\n", nsearchReally2.str().c_str());
+ for(i = 0; iter != trie_subtree.end(); iter++) {
+ i++;
+ printf("subtree = %s\n", iter.payload().c_str());
+ }
+ printf("---\n");
+
+ if (i != 4) {
+ print_failed("");
+ printf("We expected four entries to be found and we found %d", i);
+ abort();
+ }
+
+ IPv4Net nsearchReally3(IPv4("192.168.254.0"), 30);
+ iter = trie_subtree.search_subtree(nsearchReally3);
+
+ printf("--- Results for %s\n", nsearchReally3.str().c_str());
+ for(i = 0; iter != trie_subtree.end(); iter++) {
+ i++;
+ printf("subtree = %s\n", iter.payload().c_str());
+ }
+ printf("---\n");
+
+ if (i != 2) {
+ print_failed("");
+ printf("We expected two entries to be found and we found %d", i);
+ abort();
+ }
+
+ IPv4Net nsearchReally4(IPv4("192.168.254.4"), 31);
+ iter = trie_subtree.search_subtree(nsearchReally4);
+
+ printf("--- Results for %s\n", nsearchReally4.str().c_str());
+ for(i = 0; iter != trie_subtree.end(); iter++) {
+ i++;
+ printf("subtree = %s\n", iter.payload().c_str());
+ }
+ printf("---\n");
+
+ if (i != 1) {
+ print_failed("");
+ printf("We expected one entrie to be found and we found %d", i);
+ abort();
+ }
+
print_passed("");
}
@@ -407,7 +474,7 @@ int main() {
IPv4Net n9(IPv4("1.2.2.0"), 24);
trie.insert(n9, &d9);
trie.print();
-
+
trie.erase(n9);
trie.erase(n2);
@@ -460,7 +527,7 @@ int main() {
test_lower_bound(IPv4("1.0.0.1"), IPv4("0.0.0.0"));
test_upper_bound(IPv4("1.3.128.1"), IPv4("255.255.255.255"));
test_upper_bound(IPv4("1.2.2.1"), IPv4("1.2.2.255"));
-
+
trie.print();
Trie<IPv4, IPv4RouteEntry*>::iterator iter;
IPv4Net subroot(IPv4("1.2.0.0"), 21);
@@ -498,7 +565,7 @@ int main() {
iter++;
}
-
+
trie.insert(n10, &d10);
trie.insert(n1, &d1);
trie.insert(n9, &d9);
@@ -516,7 +583,7 @@ int main() {
iter++;
}
- //-------------------------------------------------------
+ //-------------------------------------------------------
printf("Test replacement of interior node\n");
@@ -525,13 +592,13 @@ int main() {
trie.insert(n13, &d13);
trie.print();
- //-------------------------------------------------------
+ //-------------------------------------------------------
printf("==================\nTest of begin()\n");
trie.erase(n11);
trie.erase(n10);
trie.print();
- //-------------------------------------------------------
+ //-------------------------------------------------------
printf("==================\nTest of lower_bound()\n");
trie.print();
iter = trie.lower_bound(n1); /*1.2.1.0/24*/
@@ -543,23 +610,23 @@ int main() {
iter = trie.lower_bound(n13); /*1.2.2.0/23*/
assert(iter.key() == n13);
- iter = trie.lower_bound(IPNet<IPv4>("1.2.1.128/25"));
+ iter = trie.lower_bound(IPNet<IPv4>("1.2.1.128/25"));
assert(iter.key() == n1); /*1.2.1.0/24*/
- iter = trie.lower_bound(IPNet<IPv4>("1.2.4.128/25"));
+ iter = trie.lower_bound(IPNet<IPv4>("1.2.4.128/25"));
assert(iter == trie.end());
- iter = trie.lower_bound(IPNet<IPv4>("1.2.1.0/23"));
+ iter = trie.lower_bound(IPNet<IPv4>("1.2.1.0/23"));
assert(iter.key() == n9); /*1.2.2.0/24*/
- iter = trie.lower_bound(IPNet<IPv4>("1.0.0.0/24"));
+ iter = trie.lower_bound(IPNet<IPv4>("1.0.0.0/24"));
if (iter != trie.end())
printf("iter.key = %s\n", iter.key().str().c_str());
else
printf("iter = end\n");
assert(iter.key() == n1); /*1.2.1.0/24*/
- //-------------------------------------------------------
+ //-------------------------------------------------------
printf("Test /32 prefix works\n");
@@ -579,7 +646,7 @@ int main() {
// inserting a list of unsorted subnets and check that the iterator
// retrieves them in the proper order.
- Trie<IPv4, IPv4RouteEntry*, TriePreOrderIterator<IPv4, IPv4RouteEntry*> >
+ Trie<IPv4, IPv4RouteEntry*, TriePreOrderIterator<IPv4, IPv4RouteEntry*> >
preotrie;
const char * subnets[] = { "1.2.0.0/16",
"1.2.0.0/20",
@@ -611,7 +678,7 @@ int main() {
printf("adding n20: %s route: %p\n", n20.str().c_str(), &d20);
preotrie.insert(n20, &d20);
- //-------------------------------------------------------
+ //-------------------------------------------------------
printf("-----------\n");
printf("Test of prefix increment (++ti)\n");
printf("-----------\n");
@@ -636,11 +703,11 @@ int main() {
}
print_passed("");
- //-------------------------------------------------------
+ //-------------------------------------------------------
printf("-----------\n");
printf("Test of postfix increment (ti++)\n");
printf("-----------\n");
- subnetidx = 0;
+ subnetidx = 0;
for (ti = preotrie.begin() ; ti != preotrie.end() ; ++ti) {
printf("*** node: %-26s %s\n",
ti.cur()->k().str().c_str(),
View
47 xorp/libxorp/trie.hh
@@ -244,6 +244,8 @@ public:
lo = x->high(); ++lo;
hi = n->_right->low(); --hi;
} else if (a <= n->_right->_k.top_addr()) { // case 4:
+ if (n->_left && a > n->_left->_k.top_addr())
+ lo = n->_left->high(); ++lo;
n = n->_right; // and continue
} else { // case 5:
lo = n->_right->high(); ++lo;
@@ -384,6 +386,10 @@ public:
return (_cur == x._cur);
}
+ bool operator!=(const TriePostOrderIterator & x) const {
+ return (_cur != x._cur);
+ }
+
bool has_payload() const { return _cur->has_payload(); }
Payload & payload() { return _cur->p(); };
const Payload & payload() const { return _cur->p(); };
@@ -483,6 +489,10 @@ public:
return (_cur == x._cur);
}
+ bool operator!=(const TriePreOrderIterator & x) const {
+ return (_cur != x._cur);
+ }
+
bool has_payload() const { return _cur->has_payload(); }
Payload & payload() { return _cur->p(); };
const Payload & payload() const { return _cur->p(); };
@@ -532,11 +542,14 @@ public:
iterator insert(const Key & net, const Payload& p) {
bool replaced = false;
Node *out = Node::insert(&_root, net, p, replaced);
- if (replaced) {
- fprintf(stderr, "overwriting a full node"); //XXX
- } else {
+ if (!replaced) {
_payload_count++;
}
+#ifdef DEBUG_LOGGING
+ else {
+ fprintf(stderr, "overwriting a full node"); //XXX
+ }
+#endif
return iterator(out);
}
@@ -661,7 +674,8 @@ public:
}
#endif // compatibility
- int route_count() const { return _payload_count; }
+ int route_count() const { return static_cast<int>(_payload_count); }
+ size_t size() const { return _payload_count; }
bool empty() const { return (_payload_count == 0); }
@@ -674,7 +688,7 @@ private:
}
Node *_root;
- int _payload_count;
+ size_t _payload_count;
};
@@ -853,13 +867,13 @@ TrieNode<A, Payload>::erase()
* that contains the desired key and has a Payload
*/
template <class A, class Payload>
-TrieNode<A, Payload> *
+inline TrieNode<A, Payload> *
TrieNode<A,Payload>::find(const Key &key)
{
TrieNode * cand = NULL;
TrieNode * r = this;
- for ( ; r && r->_k.contains(key) ; ) {
+ while(r && r->_k.contains(key)) {
if (r->_p)
cand = r; // we have a candidate.
if (r->_left && r->_left->_k.contains(key))
@@ -930,13 +944,24 @@ TrieNode<A,Payload>::find_subtree(const Key &key)
TrieNode *cand = r && key.contains(r->_k) ? r : NULL;
for ( ; r && r->_k.contains(key) ; ) {
- if (key.contains(r->_k))
- cand = r; // we have a candidate.
+ if (key.contains(r->_k)) {
+ cand = r; // we have a candidate.
+ break; // and we don't need to search any more!
+ }
if (r->_left && r->_left->_k.contains(key))
r = r->_left;
- else // should check that right contains(key), but
- r = r->_right; // the loop condition will do it for us.
+ else if (r->_right && r->_right->_k.contains(key))
+ r = r->_right;
+ else if (r->_left && key.contains(r->_left->_k)) {
+ cand = r->_left;
+ break;
+ } else if (r->_right && key.contains(r->_right->_k)) {
+ cand = r->_right;
+ break;
+ } else
+ break;
}
+
return cand;
}
View
6 xorp/libxorp/xlog.h
@@ -345,6 +345,9 @@ void _xlog_with_level(int log_level,
#define XLOG_RTRMGR_ONLY_NO_PREAMBLE(fmt...) do{}while(0)
#endif
+#ifdef NO_ASSERT
+#define XLOG_ASSERT(assertion) do {} while(0)
+#else
#ifdef L_ASSERT
/**
* XORP replacement for assert(3).
@@ -362,7 +365,8 @@ void _xlog_with_level(int log_level,
} while (0)
#else
# define XLOG_ASSERT(assertion) assert(assertion)
-#endif
+#endif /* L_ASSERT */
+#endif /* NO_ASSERT */
/**
* A marker that can be used to indicate code that should never be executed.
View
3  xorp/policy/backend/policy_redist_map.cc
@@ -35,6 +35,9 @@ PolicyRedistMap::~PolicyRedistMap() {
void
PolicyRedistMap::remove(const string& protocol)
{
+ Map::iterator i = _map.find(protocol);
+ if (i != _map.end())
+ delete i->second;
_map.erase(protocol);
}
View
2  xorp/rib/SConscript
@@ -110,8 +110,6 @@ libxorp_rib_srcs = [
'rt_tab_base.cc',
'rt_tab_deletion.cc',
'rt_tab_extint.cc',
- 'rt_tab_log.cc',
- 'rt_tab_merged.cc',
'rt_tab_origin.cc',
'rt_tab_pol_conn.cc',
'rt_tab_pol_redist.cc',
View
6 xorp/rib/parser.cc
@@ -30,6 +30,7 @@
#include "parser.hh"
+static uint32_t MAX_WORDS = 20;
// ----------------------------------------------------------------------------
// Argument Parsing methods
@@ -275,14 +276,14 @@ Parser::parse(const string& s) const
debug_msg("Best match: %s\n", rpair->first.c_str());
Command* cmd = rpair->second;
- vector<string> words(10);
+ vector<string> words(MAX_WORDS);
int wcount = split_into_words(str, words);
// Accept empty lines
if (wcount == 0)
return XORP_OK;
- vector<string> template_words(10);
+ vector<string> template_words(MAX_WORDS);
int twcount = split_into_words(rpair->first, template_words);
try {
@@ -355,6 +356,7 @@ Parser::split_into_words(const string& str, vector<string>& words) const
break;
}
} catch (out_of_range) {
+ throw Parse_error("Max Word limit is reached\n");
}
return word;
}
View
2  xorp/rib/parser_direct_cmds.hh
@@ -36,7 +36,7 @@ public:
// On the context of this test code, we don't care whether it's an
// IGP or an EGP, because we do the plumbing explicitly. So it's
// safe to just say it's an IGP, even if its not.
- return _rib.new_origin_table(_tablename, "", "", _admin_distance, IGP);
+ return _rib.new_origin_table<IGP>(_tablename, "", "", _admin_distance);
}
private:
RIB<IPv4>& _rib;
View
5 xorp/rib/protocol.cc
@@ -28,11 +28,10 @@
#include "protocol.hh"
-Protocol::Protocol(const string& name, ProtocolType protocol_type,
- uint32_t genid)
+Protocol::Protocol(const string& name, ProtocolType protocol_type)
: _name(name),
_protocol_type(protocol_type),
- _genid(genid)
+ _genid(0)
{
}
View
2  xorp/rib/protocol.hh
@@ -53,7 +53,7 @@ public:
* protocol goes down and comes up, the genid should be
* incremented).
*/
- Protocol(const string& name, ProtocolType protocol_type, uint32_t genid);
+ Protocol(const string& name, ProtocolType protocol_type);
/**
* @return the protocol type.
View
581 xorp/rib/rib.cc
@@ -31,30 +31,6 @@
#include "rib.hh"
-// ----------------------------------------------------------------------------
-// Inline table utility methods
-
-template <typename A>
-struct table_has_name {
- table_has_name(const string& name) : _n(name) {}
- bool operator() (const RouteTable<A>* rt) const {
- return rt->tablename() == _n;
- }
-private:
- const string& _n;
-};
-
-template <typename A, typename T>
-struct table_has_name_and_type {
- table_has_name_and_type(const string& name) : _n(name) {}
- bool operator() (const RouteTable<A>* rt) const {
- const T* t = dynamic_cast<const T*>(rt);
- return (t != 0) && (rt->tablename() == _n);
- }
-private:
- const string& _n;
-};
-
template <typename A>
inline OriginTable<A>*
RIB<A>::find_origin_table(const string& tablename)
@@ -75,6 +51,20 @@ RIB<A>::find_origin_table(const string& tablename)
}
template <typename A>
+template <ProtocolType protocol_type>
+inline OriginTable<A>*
+RIB<A>::find_origin_table_smart(const string& tablename)
+{
+ switch (protocol_type) {
+ case IGP:
+ return find_igp_origin_table(tablename);
+ case EGP:
+ return find_egp_origin_table(tablename);
+ }
+ return NULL;
+}
+
+template <typename A>
inline OriginTable<A>*
RIB<A>::find_igp_origin_table(const string& tablename)
{
@@ -103,20 +93,6 @@ RIB<A>::find_egp_origin_table(const string& tablename)
}
template <typename A>
-inline MergedTable<A>*
-RIB<A>::find_merged_table(const string& tablename)
-{
- typename MergedTableMap::iterator li;
-
- li = _merged_tables.find(tablename);
-
- if (li == _merged_tables.end())
- return NULL;
-
- return li->second;
-}
-
-template <typename A>
inline RedistTable<A>*
RIB<A>::find_redist_table(const string& tablename)
{
@@ -151,12 +127,12 @@ template <typename A>
Protocol*
RIB<A>::find_protocol(const string& protocol)
{
- typename map<string, Protocol* >::iterator mi = _protocols.find(protocol);
+ OriginTable<A>* ot = find_origin_table(protocol);
- if (mi == _protocols.end()) {
- return NULL;
- }
- return mi->second;
+ if (ot)
+ return &(ot->protocol());
+
+ return NULL;
}
template <typename A>
@@ -202,19 +178,6 @@ RIB<A>::add_table(RedistTable<A>* table)
}
template <typename A>
-inline int
-RIB<A>::add_table(MergedTable<A>* table)
-{
- const string& tablename = table->tablename();
- if (find_merged_table(tablename) != NULL) {
- XLOG_WARNING("add_table: table %s already exists", tablename.c_str());
- return XORP_ERROR;
- }
- _merged_tables[tablename] = table;
- return XORP_OK;
-}
-
-template <typename A>
int
RIB<A>::set_protocol_admin_distance(const string& protocol_name,
const uint32_t& admin_distance)
@@ -228,7 +191,10 @@ RIB<A>::set_protocol_admin_distance(const string& protocol_name,
protocol_name.c_str());
return XORP_ERROR;
} else if (NULL != ot && ot->route_count() == 0) {
- ot->change_admin_distance(admin_distance);
+ int ret;
+ ret = _ext_int_table->change_admin_distance(ot, admin_distance);
+ if (ret == XORP_ERROR)
+ return XORP_ERROR;
}
}
_admin_distances[protocol_name] = admin_distance;
@@ -252,56 +218,16 @@ RIB<A>::get_protocol_admin_distance(const string& protocol_name)
template <typename A>
inline IPExternalNextHop<A>*
-RIB<A>::find_external_nexthop(const A& addr)
+RIB<A>::create_external_nexthop(const A& addr)
{
- typename map<A, IPExternalNextHop<A> >::iterator mi;
-
- mi = _external_nexthops.find(addr);
- if (mi == _external_nexthops.end())
- return NULL;
- return &mi->second;
+ return new IPExternalNextHop<A>(addr);
}
template <typename A>
inline IPPeerNextHop<A>*
-RIB<A>::find_peer_nexthop(const A& addr)
+RIB<A>::create_peer_nexthop(const A& addr)
{
- typename map<A, IPPeerNextHop<A> >::iterator mi;
-
- mi = _peer_nexthops.find(addr);
- if (mi == _peer_nexthops.end())
- return NULL;
- return &mi->second;
-}
-
-template <typename A>
-inline IPExternalNextHop<A>*
-RIB<A>::find_or_create_external_nexthop(const A& addr)
-{
- IPExternalNextHop<A>* nexthop = find_external_nexthop(addr);
- if (nexthop != NULL)
- return nexthop;
-
- typedef map<A, IPExternalNextHop<A> > C; // for convenience
- typename C::value_type vt(addr, IPExternalNextHop<A>(addr));
- typename C::iterator iter;
- iter = _external_nexthops.insert(_external_nexthops.end(), vt);
- return &iter->second;
-}
-
-template <typename A>
-inline IPPeerNextHop<A>*
-RIB<A>::find_or_create_peer_nexthop(const A& addr)
-{
- IPPeerNextHop<A>* nexthop = find_peer_nexthop(addr);
- if (nexthop != NULL)
- return nexthop;
-
- typedef map<A, IPPeerNextHop<A> > C; // for convenience
- typename C::value_type vt(addr, addr);
- typename C::iterator iter;
- iter = _peer_nexthops.insert(_peer_nexthops.end(), vt);
- return &iter->second;
+ return new IPPeerNextHop<A>(addr);
}
// ----------------------------------------------------------------------------
@@ -369,6 +295,9 @@ RIB<A>::~RIB()
// Just set the pointer to NULL here
_connected_origin_table = NULL;
+ delete _ext_int_table;
+ _ext_int_table = NULL;
+
while (! _igp_origin_tables.empty()) {
delete _igp_origin_tables.begin()->second;
_igp_origin_tables.erase(_igp_origin_tables.begin());
@@ -384,11 +313,6 @@ RIB<A>::~RIB()
_redist_tables.erase(_redist_tables.begin());
}
- while (! _merged_tables.empty()) {
- delete _merged_tables.begin()->second;
- _merged_tables.erase(_merged_tables.begin());
- }
-
delete _register_table;
_register_table = NULL;
@@ -398,14 +322,6 @@ RIB<A>::~RIB()
delete _policy_redist_table;
_policy_redist_table = NULL;
- delete _ext_int_table;
- _ext_int_table = NULL;
-
- while (! _protocols.empty()) {
- delete _protocols.begin()->second;
- _protocols.erase(_protocols.begin());
- }
-
while (_vifs.empty() == false) {
delete _vifs.begin()->second;
_vifs.erase(_vifs.begin());
@@ -422,11 +338,13 @@ list<string>
RIB<A>::registered_protocol_names() const
{
list<string> names;
- map<string, Protocol* >::const_iterator iter;
+ typename OriginTableMap::const_iterator iter;
- for (iter = _protocols.begin(); iter != _protocols.end(); ++iter) {
+ for (iter = _igp_origin_tables.begin(); iter != _igp_origin_tables.end(); ++iter)
+ names.push_back(iter->first);
+
+ for (iter = _egp_origin_tables.begin(); iter != _egp_origin_tables.end(); ++iter)
names.push_back(iter->first);
- }
return (names);
}
@@ -435,15 +353,14 @@ template <typename A>
void
RIB<A>::initialize(RegisterServer& register_server)
{
- if (initialize_register(register_server) != XORP_OK) {
- XLOG_FATAL("Could not initialize register table for %s",
- name().c_str());
- }
+ // Unconditionally plumb ExtInt table if it doesn't exist
+ // All wining IGP, EGP and overall routes are cached in ExtInt table,
+ // so we could perform faster lookup
+ initialize_ext_int();
- if (initialize_policy_redist() != XORP_OK) {
- XLOG_FATAL("Could not initialize policy redistribution table for %s",
- name().c_str());
- }
+ initialize_register(register_server);
+
+ initialize_policy_redist();
//
// XXX: we must initialize the final RedistTable after the
@@ -468,22 +385,15 @@ template <typename A>
int
RIB<A>::initialize_policy_redist()
{
- if (_register_table == NULL) {
- XLOG_ERROR("Register table is not yet initialized");
- return XORP_ERROR;
- }
-
- if (_policy_redist_table != NULL) {
- return XORP_OK; // done already
- }
+ XLOG_ASSERT(_register_table != NULL && _policy_redist_table == NULL);
_policy_redist_table =
new PolicyRedistTable<A>(_register_table, _rib_manager.xrl_router(),
_rib_manager.policy_redist_map(),
_multicast);
- if (_final_table == NULL || _final_table == _register_table)
- _final_table = _policy_redist_table;
+ XLOG_ASSERT(_final_table == _register_table);
+ _final_table = _policy_redist_table;
return XORP_OK;
}
@@ -492,17 +402,12 @@ template <typename A>
int
RIB<A>::initialize_redist_all(const string& all)
{
- if (_policy_redist_table == NULL) {
- XLOG_ERROR("Policy redist table is not yet initialized");
- return XORP_ERROR;
- }
+ XLOG_ASSERT(_policy_redist_table != NULL);
- if (find_redist_table(redist_tablename(all)) != NULL) {
- return XORP_OK; // RedistTable already exists, no sweat
- }
+ XLOG_ASSERT(find_redist_table(redist_tablename(all)) == NULL);
+
+ RedistTable<A>* r = new RedistTable<A>(redist_tablename(all), _policy_redist_table);
- RedistTable<A>* r;
- r = new RedistTable<A>(redist_tablename(all), _policy_redist_table);
if (add_table(r) != XORP_OK) {
delete r;
return XORP_ERROR;
@@ -511,8 +416,24 @@ RIB<A>::initialize_redist_all(const string& all)
//
// Set the RedistTable as the final table
//
- if (_final_table == NULL || _final_table == _policy_redist_table)
- _final_table = r;
+ XLOG_ASSERT(_final_table == _policy_redist_table);
+ _final_table = r;
+
+ return XORP_OK;
+}
+
+
+template <typename A>
+int
+RIB<A>::initialize_ext_int()
+{
+ XLOG_ASSERT(!_ext_int_table);
+
+ _ext_int_table = new ExtIntTable<A>();
+
+ XLOG_ASSERT(_final_table == NULL);
+
+ _final_table = _ext_int_table;
return XORP_OK;
}
@@ -521,44 +442,38 @@ template <typename A>
int
RIB<A>::initialize_register(RegisterServer& register_server)
{
- if (_register_table != NULL) {
- XLOG_WARNING("Register table already initialized.");
- return XORP_ERROR;
- }
+ XLOG_ASSERT(!_register_table);
- RegisterTable<A>* rt;
- rt = new RegisterTable<A>("RegisterTable", register_server, _multicast);
+ _register_table = new RegisterTable<A>("RegisterTable", register_server, _multicast);
- _register_table = rt;
+ XLOG_ASSERT(_final_table == _ext_int_table);
+
+ _register_table->set_parent(_ext_int_table);
+ _ext_int_table->set_next_table(_register_table);
+ _final_table = _register_table;
- if (_final_table == NULL) {
- _final_table = _register_table;
- } else {
- _final_table->replumb(NULL, _register_table);
- _register_table->set_next_table(_final_table);
- }
return XORP_OK;
}
template <typename A>
+template <ProtocolType protocol_type>
int
RIB<A>::new_origin_table(const string& tablename,
const string& target_class,
const string& target_instance,
- uint32_t admin_distance,
- ProtocolType protocol_type)
+ uint16_t admin_distance)
{
- OriginTable<A>* ot = new OriginTable<A>(tablename, admin_distance,
- protocol_type, _eventloop);
+ OriginTable<A>* ot = NULL;
+
+ ot = new TypedOriginTable<A, protocol_type>(tablename, admin_distance, _eventloop);
+
if (ot == NULL || add_table(ot) != XORP_OK) {
XLOG_WARNING("Could not add origin table %s", tablename.c_str());
delete ot;
return XORP_ERROR;
}
- if (_final_table == NULL) {
- _final_table = ot;
- }
+ XLOG_ASSERT(_final_table);
//
// Store the XRL target instance, so we know which OriginTable to
@@ -866,19 +781,6 @@ RIB<A>::add_route(const string& tablename,
// Sanity check - we should have initialized RIB
XLOG_ASSERT(_connected_origin_table);
- Protocol* protocol = find_protocol(tablename);
- if (protocol == NULL) {
- if (_errors_are_fatal) {
- XLOG_FATAL("Attempting to add route with unknown protocol \"%s\".",
- tablename.c_str());
- } else {
- XLOG_ERROR("Attempting to add route with unknown protocol \"%s\".",
- tablename.c_str());
-
- return XORP_ERROR;
- }
- }
-
OriginTable<A>* ot = find_origin_table(tablename);
if (ot == NULL) {
if (_errors_are_fatal) {
@@ -890,6 +792,7 @@ RIB<A>::add_route(const string& tablename,
return XORP_ERROR;
}
}
+ const Protocol& protocol = ot->protocol();
RibVif<A>* vif = NULL;
IPNextHop<A>* nexthop = NULL;
@@ -909,9 +812,8 @@ RIB<A>::add_route(const string& tablename,
return XORP_ERROR;
}
- IPNextHop<A>* nexthop = find_or_create_peer_nexthop(nexthop_addr);
- ot->add_route(new IPRouteEntry<A>(net, vif, nexthop, protocol,
- metric, policytags));
+ IPNextHop<A>* nexthop = create_peer_nexthop(nexthop_addr);
+ ot->add_route(new IPRouteEntry<A>(net, vif, nexthop, &protocol, metric, policytags));
flush();
return XORP_OK;
}
@@ -919,14 +821,14 @@ RIB<A>::add_route(const string& tablename,
//
// Search for a route to a directly-connected destination
//
- const IPRouteEntry<A>* re = _connected_origin_table->lookup_route(nexthop_addr);
+ const IPRouteEntry<A>* re = _connected_origin_table->lookup_ip_route(nexthop_addr);
if (re != NULL)
// We found a route for the nexthop
vif = re->vif();
if (vif != NULL)
- nexthop = find_or_create_peer_nexthop(nexthop_addr);
- else if (vif == NULL && protocol->protocol_type() == IGP) {
+ nexthop = create_peer_nexthop(nexthop_addr);
+ else if (vif == NULL && ot->protocol_type() == IGP) {
debug_msg("**not directly connected route found for nexthop\n");
//
// XXX: If the route came from an IGP, then we must have
@@ -937,13 +839,13 @@ RIB<A>::add_route(const string& tablename,
"interface toward the next-hop router", tablename.c_str(), net.str().c_str(), nexthop_addr.str().c_str());
return XORP_ERROR;
} else
- nexthop = find_or_create_external_nexthop(nexthop_addr);
+ nexthop = create_external_nexthop(nexthop_addr);
XLOG_ASSERT(nexthop->addr() == nexthop_addr);
//
// Add the route
//
- ot->add_route(new IPRouteEntry<A>(net, vif, nexthop, protocol, metric, policytags));
+ ot->add_route(new IPRouteEntry<A>(net, vif, nexthop, &protocol, metric, policytags));
flush();
return XORP_OK;
@@ -965,7 +867,7 @@ RIB<A>::replace_route(const string& tablename,
if (NULL == ot)
return XORP_ERROR; // Table is not an origin table
- int response = ot->delete_route(net);
+ int response = ot->delete_route(net, true);
if (response != XORP_OK)
return response;
@@ -1009,10 +911,11 @@ RIB<A>::verify_route(const A& lookup_addr,
RibVerifyType matchtype)
{
const IPRouteEntry<A>* re;
+ int return_value = (matchtype == RibVerifyType(MISS) ? XORP_OK : XORP_ERROR);
// 1. Check for an expected route miss.
// 2. Check table entry validity and existence.
- re = _final_table->lookup_route(lookup_addr);
+ re = _ext_int_table->lookup_route(lookup_addr);
if (re == NULL || re->vif() == NULL) {
if (matchtype == RibVerifyType(MISS)) {
debug_msg("****ROUTE MISS SUCCESSFULLY VERIFIED****\n");
@@ -1063,7 +966,7 @@ RIB<A>::verify_route(const A& lookup_addr,
debug_msg("NextHop: Exp: %s != Got: %s\n",
nexthop_addr.str().c_str(),
route_nexthop->addr().str().c_str());
- return XORP_ERROR;
+ return return_value;
} else {
debug_msg("NextHop: Exp: %s != Got: %s\n",
nexthop_addr.str().c_str(),
@@ -1072,7 +975,7 @@ RIB<A>::verify_route(const A& lookup_addr,
if (ifname != re->vif()->name()) {
XLOG_ERROR("Interface \"%s\" does not match expected \"%s\".",
re->vif()->str().c_str(), ifname.c_str());
- return XORP_ERROR;
+ return return_value;
} else {
debug_msg("Ifname: Exp: %s == Got: %s\n",
ifname.c_str(),
@@ -1081,12 +984,16 @@ RIB<A>::verify_route(const A& lookup_addr,
if (metric != re->metric()) {
XLOG_ERROR("Metric \"%u\" does not match expected \"%u\".",
XORP_UINT_CAST(re->metric()), XORP_UINT_CAST(metric));
- return XORP_ERROR;
+ return return_value;
} else {
debug_msg("Metric: Exp: %u == Got: %u\n",
XORP_UINT_CAST(metric),
XORP_UINT_CAST(re->metric()));
}
+ if (matchtype == RibVerifyType(MISS)) {
+ XLOG_ERROR("****We got valid IP route, but we expected MISS****\n");
+ return XORP_ERROR;
+ }
debug_msg("****IP ROUTE SUCCESSFULLY VERIFIED****\n");
return XORP_OK;
}
@@ -1097,7 +1004,7 @@ RIB<A>::lookup_route(const A& lookupaddr)
{
debug_msg("looking up %s\n", lookupaddr.str().c_str());
- const IPRouteEntry<A>* re = _final_table->lookup_route(lookupaddr);
+ const IPRouteEntry<A>* re = _ext_int_table->lookup_route(lookupaddr);
// Case 1: Route miss. Return the null IP address.
// Vif cannot be NULL for a valid route.
if (re == NULL || re->vif() == NULL)
@@ -1134,7 +1041,7 @@ template <typename A>
RouteRange<A>*
RIB<A>::route_range_lookup(const A& lookupaddr)
{
- return _final_table->lookup_route_range(lookupaddr);
+ return _ext_int_table->lookup_route_range(lookupaddr);
}
template <typename A>
@@ -1167,7 +1074,7 @@ RIB<A>::add_igp_table(const string& tablename,
const string& target_instance)
{
debug_msg("add_igp_table %s\n", tablename.c_str());
- int r = add_origin_table(tablename, target_class, target_instance, IGP);
+ int r = add_origin_table<IGP>(tablename, target_class, target_instance);
if (r != XORP_OK)
return r;
@@ -1180,10 +1087,10 @@ RIB<A>::add_igp_table(const string& tablename,
delete_origin_table(tablename, target_class, target_instance);
return r;
}
- RedistTable<A>* rt = find_redist_table(redist_tablename(tablename));
- XLOG_ASSERT(rt != NULL);
if (tablename == "connected") {
+ RedistTable<A>* rt = find_redist_table(redist_tablename(tablename));
+ XLOG_ASSERT(rt != NULL);
r = add_policy_connected_table(rt);
if (r != XORP_OK) {
delete_origin_table(tablename, target_class, target_instance);
@@ -1204,24 +1111,11 @@ RIB<A>::add_egp_table(const string& tablename,
const string& target_instance)
{
debug_msg("add_egp_table %s\n", tablename.c_str());
- int r = add_origin_table(tablename, target_class, target_instance, EGP);
+ int r = add_origin_table<EGP>(tablename, target_class, target_instance);
if (r != XORP_OK) {
return r;
}
-#if 0
- // XXX For now we unconditionally plumb a RedistTable behind each
- // OriginTable. We need this because the RedistTable needs to
- // track the routes within the OriginTable in order to be able to
- // render a dump when another protocol requests redistribution.
- r = add_redist_table(tablename);
- if (r != XORP_OK) {
- delete_origin_table(tablename, target_class, target_instance);
- return r;
- }
- RouteTable<A>* rt = find_table(redist_tablename(tablename));
- XLOG_ASSERT(rt != NULL);
-#endif
return r;
}
@@ -1269,157 +1163,12 @@ RIB<A>::add_redist_table(RouteTable<A>* parent)
template <typename A>
int
-RIB<A>::plumb_ahead_of_ext_int(OriginTable<A>*& ot)
-{
- //
- // We are going to need to create an ExtInt table.
- //
- // Find the appropriate existng table to be a parent
- // of the ExtIntTable.
- //
- RouteTable<A>* next_table = track_back(_final_table,
- REDIST_TABLE | POLICY_REDIST_TABLE | REGISTER_TABLE);
- RouteTable<A>* existing_table = next_table->parent();
- if (ot->protocol_type() == IGP) {
- _ext_int_table = new ExtIntTable<A>(existing_table, ot);
- } else {
- _ext_int_table = new ExtIntTable<A>(ot, existing_table);
- }
-
- if (_final_table->type()
- & (REDIST_TABLE | POLICY_REDIST_TABLE | REGISTER_TABLE)) {
- _ext_int_table->set_next_table(next_table);
- next_table->replumb(existing_table, _ext_int_table);
- } else {
- _final_table = _ext_int_table;
- }
- return XORP_OK;
-}
-
-template <typename A>
-int
-RIB<A>::plumb_ahead_of_merged(OriginTable<A>*& ot,
- RouteTable<A>* existing_table)
-{
- //
- // We're going to need to create a MergedTable
- //
- RouteTable<A>* next_table = existing_table->next_table();
-
- // Skip past any RedistTables
- RouteTable<A>* new_prev_table = track_forward(existing_table,
- (REDIST_TABLE |
- POLICY_CONNECTED_TABLE));
- if (new_prev_table != existing_table) {
- existing_table = new_prev_table;
- next_table = existing_table->next_table();
- }
-
- MergedTable<A>* merged_table = new MergedTable<A>(existing_table, ot);
- if (merged_table == NULL || add_table(merged_table) != XORP_OK) {
- delete merged_table;
- return XORP_ERROR;
- }
-
- merged_table->set_next_table(next_table);
- if (next_table != NULL)
- next_table->replumb(existing_table, merged_table);
-
- //
- // It's possible existing_table was the last table - if so, then it
- // isn't anymore.
- //
- if (_final_table == existing_table)
- _final_table = merged_table;
-
- return XORP_OK;
-
-}
-
-template <typename A>
-int
-RIB<A>::plumb_ahead_of_first(OriginTable<A>*& ot)
-{
- //
- // There are tables, but neither IGP or EGP origin tables
- // Therefore the final table must be a RedistTable
- // or a RegisterTable.
- //
- if ((_final_table->type() & (REDIST_TABLE | POLICY_REDIST_TABLE | REGISTER_TABLE)) == 0)
- XLOG_UNREACHABLE();
-
- //
- // There may be existing single-parent tables before the
- // final table such as RegisterTable - track back to be
- // first of them.
- //
- RouteTable<A>* rt = track_back(_final_table,
- REDIST_TABLE
- | POLICY_REDIST_TABLE
- | REGISTER_TABLE);
-
- //
- // Plumb our new table in ahead of the first single-parent
- // table.
- //
- rt->replumb(NULL, ot);
- ot->set_next_table(rt);
- return XORP_OK;
-
-}
-
-template <typename A>
-int
-RIB<A>::plumb_origin_table(OriginTable<A>*& ot,
- OriginTable<A>* existing_igp_table,
- OriginTable<A>* existing_egp_table)
+RIB<A>::plumb_origin_table(OriginTable<A>*& ot)
{
// XXX: the table was created by new_origin_table() above, so it must exist
- XLOG_ASSERT(ot != NULL);
- if (_final_table == ot) {
- //
- // This is the first table, so no need to plumb anything.
- //
- debug_msg("first table\n");
- return XORP_OK;
- }
+ XLOG_ASSERT(ot != NULL && _final_table != ot);
- //
- // There are existing tables, so we need to do some plumbing
- //
- // Three possibilities:
- // 1. There are no existing tables of the same protocol type as the protocol type
- // of the table that we're plumbing
- //
- // -> Add ExtInt table and plumb the origin table ahead of ext int table
- // 2. There are both existing EGP and existing IGP tables
- //
- // -> Add Merged table and plumb the origin table ahead of merged table
- // 3. there aren't existing IGP and existing EGP tables
- //
- // -> Plumb origin table ahead of currently first table
- //
-
- //
- // Depending on which tables already exist, we may need to create
- // a MergedTable or an ExtInt table.
- //
- ProtocolType protocol_type = (ProtocolType) ot->protocol_type();
- if ((!existing_igp_table && (protocol_type == IGP)) ||
- (!existing_egp_table && (protocol_type == EGP))) {
- //
- // Sanity check: we've found an ExtIntTable, when there
- // weren't both IGP and EGP tables.
- //
- XLOG_ASSERT(!_ext_int_table);
-
- if (!existing_egp_table && !existing_igp_table)
- return plumb_ahead_of_first(ot);
- else
- return plumb_ahead_of_ext_int(ot);
- } else
- return plumb_ahead_of_merged(ot, (protocol_type == IGP) ?
- existing_igp_table : existing_egp_table);
+ return _ext_int_table->add_protocol_table(ot);
}
//
@@ -1427,38 +1176,21 @@ RIB<A>::plumb_origin_table(OriginTable<A>*& ot,
//
template <typename A>
+template <ProtocolType protocol_type>
int
RIB<A>::add_origin_table(const string& tablename,
const string& target_class,
- const string& target_instance,
- ProtocolType protocol_type)
+ const string& target_instance)
{
debug_msg("add_origin_table %s type: %d\n",
tablename.c_str(), protocol_type);
- Protocol* protocol = find_protocol(tablename);
- if (protocol == NULL) {
- protocol = new Protocol(tablename, protocol_type, 0);
- _protocols[tablename] = protocol;
- } else {
- protocol->increment_genid();
- }
-
// Check if table exists and check type if so
OriginTable<A>* ot = NULL;
- switch (protocol_type) {
- case IGP:
- ot = find_igp_origin_table(tablename);
- break;
- case EGP:
- ot = find_egp_origin_table(tablename);
- break;
- default:
- XLOG_UNREACHABLE();
- break;
- }
+ ot = find_origin_table_smart<protocol_type>(tablename);
if (ot != NULL) {
+ ot->protocol().increment_genid();
//
// Table already exists, hence use it.
//
@@ -1475,33 +1207,15 @@ RIB<A>::add_origin_table(const string& tablename,
return XORP_OK;
}
- //
- // Find first IGP and EGP origin table
- // This is needed for plumbing new origin table
- //
- OriginTable<A>* existing_igp_table = !_igp_origin_tables.empty() ? _igp_origin_tables.begin()->second : NULL;
- OriginTable<A>* existing_egp_table = !_egp_origin_tables.empty() ? _egp_origin_tables.begin()->second : NULL;
-
-
- if (new_origin_table(tablename, target_class, target_instance,
- get_protocol_admin_distance(tablename), protocol_type) != XORP_OK) {
+ if (new_origin_table<protocol_type>(tablename, target_class, target_instance,
+ get_protocol_admin_distance(tablename)) != XORP_OK) {
debug_msg("new_origin_table failed\n");
return XORP_ERROR;
}
- switch (protocol_type) {
- case IGP:
- ot = find_igp_origin_table(tablename);
- break;
- case EGP:
- ot = find_egp_origin_table(tablename);
- break;
- default:
- XLOG_UNREACHABLE();
- break;
- }
+ ot = find_origin_table_smart<protocol_type>(tablename);
- return plumb_origin_table(ot, existing_igp_table, existing_egp_table);
+ return plumb_origin_table(ot);
}
template <typename A>
@@ -1572,61 +1286,16 @@ RIB<A>::target_death(const string& target_class,
}
}
-//
-// Given a single-parent table, track back to the last matching table
-// before this one.
-//
-template <typename A>
-RouteTable<A>*
-RIB<A>::track_back(RouteTable<A>* rt, int typemask) const
-{
- if (rt == NULL || (rt->type() & typemask) == 0) {
- return rt;
- }
-
- for (RouteTable<A>* parent = rt->parent();
- parent && (parent->type() & typemask);
- parent = rt->parent()) {
- rt = parent;
- }
- return rt;
-}
-
-//
-// Track forward to the last matching table, or return this table if
-// the next table doesn't match.
-//
-template <typename A>
-RouteTable<A>*
-RIB<A>::track_forward(RouteTable<A>* rt, int typemask) const
-{
- RouteTable<A>* next;
- if (NULL == rt)
- // XXX: not the same test as track back (deliberate ?)
- return rt;
-
- next = rt->next_table();
-
- while (next != NULL) {
- if ((next->type() & typemask) != 0) {
- rt = next;
- next = rt->next_table();
- } else
- return rt;
- }
-
- return rt;
-}
-
#ifdef DEBUG_LOGGING
template <class A>
struct print_from_pair {
- print_from_pair() {}
+ print_from_pair(string s = "###"): _separator(s) {}
void operator() (const pair<const string, A*>& table_pair) const {
- cout << table_pair.second->str() << "###" << endl;
+ cout << table_pair.second->str() << _separator << endl;
}
+protected:
+ string _separator;
};
-
#endif
template <typename A>
@@ -1640,11 +1309,6 @@ RIB<A>::print_rib() const
print_from_pair<RouteTable<A> >());
cout << "==============================================================" << endl;
- cout << "Merged table count " << _merged_tables.size() << endl;
- for_each(_merged_tables.begin(), _merged_tables.end(),
- print_from_pair<RouteTable<A> >());
-
- cout << "==============================================================" << endl;
cout << "IGP table count " << _igp_origin_tables.size() << endl;
for_each(_igp_origin_tables.begin(), _igp_origin_tables.end(),
print_from_pair<RouteTable<A> >());
@@ -1672,11 +1336,6 @@ RIB<A>::print_rib() const
cout << "==============================================================" << endl;
- cout << "Protocols: " << endl;