bgpd: optimize aspath string representation and assegments handling

* bgp_aspath.h: Add str_len to struct aspath.
* bgp_aspath.c: Save the aspath string representation length and use it
  instead of strlen().
  (aspath_make_str_count) assign the string buffer directly for
  consistency with the string length and change the return type to void.
  (aspath_dup) use str_len and copy the string instead of calling
  aspath_make_str_count().
  (assegment_data_new) change from XCALLOC to XMALLOC. All users initialize
  the memory before use.
  (assegment_data_free) unused, removed.
  (aspath_intern) check that there's always a ->str pointer.
  (aspath_hash_alloc) reuse assegments and string representation instead of
  copying them.
  (aspath_parse) now aspath_hash_alloc does not dupes memory, free the
  temporary structures only if the aspath it is in the hash.
  (aspath_cmp_left) remove useless NULL initialization.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: optimize bgp_nexthop_self()

  This function scores 2nd, profiling a full internet table load. It's called
for every prefix received.
  Instead of looping in the interface lists comparing addresses use a hash
to mantain them.

* bgpd.c: Init the own address hash.
* bgp_nexthop.c: Introduce methods to maintain an own address hash.
  (bgp_connected_add) add addresses to the hash.
  (bgp_connected_delete) delete addresses from the hash.
  (bgp_nexthop_self) lookup addresses in the hash. Removed the unused afi_t
  parameter.
* bgp_route.c: (bgp_update_main) Micro-optimization, rearranged condition to
  not lookup the hash for bogus nexthops (0.0.0.0 or a class D/E address)

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: debug buffers cleanup and optimization

Just the first change pushes bgp_update_receive() from 6th to ~14th on a
full internet table load profiling session.

* bgp_debug.c: (bgp_update_receive) The attrstr initialization is expensive,
  moved under the debug conditional where it is used and just initialize the
  first char to NULL.
  (bgp_update_default_send) Initialize attrstr needed for bgp_dump_attr().
  Moved some buffers used for printing IP[4|6] addresses under the debug
  conditionals that use them and reduced its size.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: remove calls to peer_sort() from fast-path

  peer_sort() it's called so much as to be annoying. In the assumption
that the 'sort' of the peer doesn't change during an established session,
I have changed all calls to peer_sort() in the 'fast-path' to only check
the 'sort'. All the calls from the vty and such still recalculate the sort
and store it in the peer.

  There's a lot of other calls to peer_sort() that could be changed but some
maube tricky, someone more knowledgeable may try to reduce them.

  This hits peer_sort() from 5th out of the stadium^H^H list on a full
internet table loading profiling session.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: optimize loops on [e]community_hash_make()

  This change reduces loop count. Less jumps.

* bgp_community.c: One loop per community.
* bgp_ecommunity.c: One loop per ecommunity.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: optimize bgp_info_cmp()

* bgp_route.c: (bgp_info_cmp) Reduce indirections, precalculate some
  values that are used several times, reduce conditionals.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: remove some useless initializations

* bgp_attr.c: (bgp_attr_default_intern) bgp_attr_default_set() already
  initializes the memory. Fixes a struct attr_extra leak.
* bgp_route.c: Remove useless on stack struct initializations.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: reduce attrhash_make_key() indirections

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: use on stack struct attr_extra on bgp_attr_aggregate_intern()

Reduce memory heap fragmentation and pressure on the memory allocator.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: cleanup bgp_attr_unintern()

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: use on stack struct attr_extra in bgp_attr_unintern()

  Reduce memory heap fragmentation and pressure on the memory allocator.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: fix struct attr_extra leak in bgp_default_originate()

  The call to bgp_attr_default_set() above creates the attr_extra struct,
but the attr.extra = NULL initialization was leaking it.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: use on stack struct attr_extra in bgp_update_receive()

Reduce memory heap fragmentation and pressure on the memory allocator.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: reduce struct attr_extra allocations/freeing

Try to use on stack structs for temporary uses.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: Remove useless initialization

It's initialized below

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: optimize holdtime timer cancelling

* bgp_packet.c: (bgp_update_receive) for every update received we queue
  an event just to cancel the holdtime timer, done in bgp_fsm_update().
  Instead cancel the timer directly an avoid a scheduling pass.

  This incidently fixes another problem found on a slow box, where thousands
of events threads were queued, and run, but never freed, because they are
moved to the unused list that grows without bounds.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: optimize bgp_update_main() in the soft_reconfig case

Avoids 3 checks per call.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: optimize bgp_aggregate_[increment|decrement]()

  If there were no aggregates configured this functions were allocating
and freeing a struct bgp_node for every call, and it's called for every
prefix received.

* bgp_route.c: Bail out early if the there are no aggregates configured.
  Change from bgp_node_get() to bgp_node_lookup() that does not allocate
  a new struct bgp_node if not found.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
micro-op bgp_node_[get|lookup]() and route_node_[get|lookup]()

  Reduce indirection for values that doesn't change in the loop.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
[adjusted after dropping previous patch]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib: remove RUSAGE_T from struct thread

* thread.c: It's only temporarily used in thread_call() to calculate the
  diffs. Saves 80 bytes per copy.

Signed-off-by: Jorge Boncompte [DTI2] <jorge@dti2.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>