Revert "ospfd: Do not fall back to intervening router."

This reverts commit 9289c6ff55cd96c943d23e43fc9e5f987aa965ed.

The commit reverted an earlier change which was fixed a bug that caused
black-holes to remote destinations with multiple paths, that could occur
during convergence. Overall, the previous code is more correct.
zebra: make static routes respect table setting

Make static routes respect non-default routing tables.

BEFORE PATCH
------------

! in zebra.conf
table 1

! add static route
vtysh> ip route 10.0.0.0/30 eth0

cumulus@net-top0:~$ ip route
default via 192.168.0.2 dev eth0
10.0.0.0/30 dev eth0  proto zebra
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.15

! nothing in table 1
cumulus@net-top0:~$ ip route show table 1

AFTER PATCH
-----------

! in zebra.conf
table 1

! add static route
vtysh> ip route 10.0.0.0/30 eth0

cumulus@net-top0:~$ ip route
default via 192.168.0.2 dev eth0
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.15

! static route in table 1
cumulus@net-top0:~$ ip route show table 1
10.0.0.0/30 dev eth0  proto zebra

Signed-off-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib: improve fletcher checksum validation

OVERVIEW

The checksum used in OSPF (rfc2328) is specified in rc905 annex B.  There is an
sample implementation in rfc1008 which forms the basis of the quagga
implementation.  This algorithm works perfectly when generating a checksum;
however, validation is a bit problematic.

The following LSA (generated by a non-quagga implementation) is received by
quagga and marked with an invalid checksum; however, it passes both the rfc905
and rfc1008 validation checks.

static uint8_t lsa_10_121_233_29[] = {
   0x0e, 0x10, 0x02, 0x03,
   0x09, 0x00, 0x35, 0x40,
   0x0a, 0x79, 0xe9, 0x1d,
   0x80, 0x00, 0x00, 0x03,
   0x00, 0x8a, 0x00, 0x1c,
   0xff, 0xff, 0xff, 0xe0,
   0x00, 0x00, 0x36, 0xb0
};

LS Type: Summary-LSA (IP network)
   LS Age: 3600 seconds
   Do Not Age: False
   Options: 0x02 (E)
   Link-State Advertisement Type: Summary-LSA (IP network) (3)
   Link State ID: 9.0.53.64
   Advertising Router: 10.121.233.29 (10.121.233.29)
   LS Sequence Number: 0x80000003
   LS Checksum: 0x008a
   Length: 28
   Netmask: 255.255.255.224
   Metric: 14000

You'll note that one byte of the checksum is 0x00; quagga would calculate the
checksum as 0xff8a.

It can be argued that the sourcing implementation generates an incorrect
checksum; however, rfc905 indicates that, for 1's complement arithmetic, the
value 255 shall be regarded as 0, thus either values are valid.

EXPLANATION

The quagga ospfd and ospf6d implementations operate by copying the PDU's
existing checksum in a holding variable, calculating the checksum, and comparing
the resulting checksum to the original.  As a note, this implementation has the
side effect of modifying the contents of the PDU.

Evaluation of both rfc905 and rfc1008 shows that checksum validation should
involve calculating the sum over the PDU and checking that both resulting C0 and
C1 values are zero.  This behavior is enacted in the rfc1008 implementation by
calling encodecc with k = 0 (checksum offset); however, this functionality had
been omitted from the quagga implementation.

PATCH

This patch adds the ability to call the quagga's fletcher_checksum() with a
checksum offset value of 0xffff (aka FLETCHER_CHECKSUM_VALIDATE) which returns
the sum over the buffer (a value of 0 indicates a valid checksum).  This is
similar to the mechanism in rfc1008 when called with k = 0.  The patch also
introduces ospf_lsa_checksum_valid().

ospf6d had it's own implementation of the fletcher checksum in
ospf6_lsa_checksum(); it's the same algorithm as in fletcher_checksum().  This
patch removes the local implementation in favor of the library's as well as creates
and uses ospf6_lsa_checksum_valid().

quagga's ISIS implementation suffers from the same problem; however, I do not
have the facilities to validate a fix to ISIS, thus this change has been left to
the ISIS maintainers.  The function iso_csum_verify() should be reduced to
running the fletcher checksum over the buffer using an offset of 0.

Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
ospfd: blackhole route removal for area range

ISSUE

When an area range is created in which there the sub-area has routes that are
smaller than the range, an ABR creates a blackhole route to cover the range.
When the range is removed, the blackhole route is not removed.

--A----B----C---

B is an ABR with A in area 1 and C in area 0.  If A advertises `10.2.0.0/30` and
`10.2.0.4/30` and B is configured with `area 0.0.0.1 range 10.2.0.0/29` a
blackhole is created on B (`blackhole 10.2.0.0/29 proto zebra`).  When the
area/range is removed via the command line, the blackhole remains in existence
even though the "range" route is removed from area 0 and the individual routes
are propagated.

PATCH

The reason for this behavior is that, prior to this patch, the range is deleted
from the area's list, so when ospf_abr_manage_discard_routes() gets called,
there is nothing to clean up.  The patch removes the discard route as part of
the processing of the command line (ospf_area_range_unset()).

Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
ospfd: ABR algorithm not propagating MAXAGE LSAs into area

When a range (or sub-range) is deleted, the area is notified by propagating a
MAXAGE LSA.  This LSA stays in the database for a while to both insure
propagation as well as in the off chance that it's useful in the near future.

Unfortunately, the ABR algorithm was treating these MAXAGE LSAs as unchanged and
not propagating them within the areas.

Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
ospfd: respect max-metric over configured cost for summary LSAs

ISSUE

When max-metric router-lsa administrative is invoked on an ABR created with...
area <area> range <addr/mask>
the summary LSAs are sent out with 65535 (max-metric) added to the normal cost.

When max-metric router-lsa administrative is invoked on an ABR created with...
area <area> range <addr/mask> cost <cost>
the summary LSAs are sent out with <cost> (the max-metric is ignored).  This
second behavior effectively incapacitates the max-metric function.

PATCH

This patch evaluates the state of the router and if it's isolated as a stub
router (rfc3137) via `max-metric router-lsa`, we unconditionally uses the
value of 0xff0000 when advertising summary LSAs.

Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com>
Reviewed-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib: improve sanity checks in stream_set_endp()

  * lib/stream.c: (stream_set_endp) Add checks to make sure that the
    supplied 'endp' is within the 'size' of the stream, and that the
    current read pointer 'getp' is not beyond the specified 'endp'.
isisd: tighten checks on ISIS pdu length

  * isisd/isis_pdu.c: Fix problem where isisd would crash if it
    received a LAN IIH with the 'pdu length' field set to zero.
    Similar problems can occur in parsing other ISIS PDUs as well --
    check that the PDU length in an ISIS hello, LSP or SNP packet is
    at least as big as the size of the respective fixed header.
isisd: fix null pointer dereference in send_lsp()

  * isisd/isis_pdu.c: (send_lsp) Handle case where there are no LSPs
    on the LSP transmission queue. This can happen if, for instance,
    the queue is cleared because of protocol events before the
    send_lsp thread gets a chance to run.
isisd: pull up invalid prefix assert()

processing invalid prefixes causes isisd to assert() or otherwise
misbehave in ip_masklen/apply_mask.  pull up the assert() to indicate
better there's broken data in isisd's LSDB.

  * isisd/isis_spf.c: assert() prefix lengths

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
isisd: don't process invalid prefixes from TLVs

it's possible to feed invalid prefixes (1.2.3.4/40 or dead::beef/200) on
IS-IS.  if this is not checked, it will later cause an assert in
processing.  let's simply abort processing the TLV if the prefix is
invalid.

  * isisd/isis_tlv.c: check prefix lengths for validity

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib: add array_size() helper

implement array_size as sizeof(array) / sizeof(array element)

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
isisd: don't overrun list of protocols

isisd currently has a list of supported protocols as a fixed array of
size 4.  this can be overran, leading to an overwrite of the ipv4_addrs
pointer.

  * isisd/isis_pdu.c: don't accept more protocols than there's space for

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
*: use array_size() helper macro

Use the array_size() helper macro.  Replaces several instances of local
macros with the same definition.

Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
lib: treat OSX as BSD for IP_HDRINCL (BZ#739)

Mac OS X needs HAVE_IP_HDRINCL_BSD_ORDER defined like BSD. If it's not
defined, it'll fail like this:

  *** sendmsg in ospf_write failed to 224.0.0.5, id 0, off 0, len 64,
  interface en0, mtu 1500: Invalid argument

Which is caused by reordering iph->ip_len in
sockopt_iphdrincl_swab_htosys.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: flock() dump files (BZ#742)

flock()ing the BGP dump files helps consumers determine when they're
safe to read.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
build: reorder libraries to address linker error

The linker on some systems (for example, Ubuntu 12.04 LTS x86_64)
appears to be sensitive to the order in which libraries are
specified. On these systems, if a library 'A' depends on a library
'B', it has to be specified before 'B' when linking an executable.

  * zebra/Makefile.am: Make sure LIBCAP comes after libzebra.

  * tests/Makefile.am: Ensure libm comes after libbgp.

Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd: CVE-2012-1820, DoS in bgp_capability_orf()

An ORF (code 3) capability TLV is defined to contain exactly one
AFI/SAFI block. Function bgp_capability_orf(), which parses ORF
capability TLV, uses do-while cycle to call its helper function
bgp_capability_orf_entry(), which actually processes the AFI/SAFI data
block. The call is made at least once and repeated as long as the input
buffer has enough data for the next call.

The helper function, bgp_capability_orf_entry(), uses "Number of ORFs"
field of the provided AFI/SAFI block to verify, if it fits the input
buffer. However, the check is made based on the total length of the ORF
TLV regardless of the data already consumed by the previous helper
function call(s). This way, the check condition is only valid for the
first AFI/SAFI block inside an ORF capability TLV.

For the subsequent calls of the helper function, if any are made, the
check condition may erroneously tell, that the current "Number of ORFs"
field fits the buffer boundary, where in fact it does not. This makes it
possible to trigger an assertion by feeding an OPEN message with a
specially-crafted malformed ORF capability TLV.

This commit fixes the vulnerability by making the implementation follow
the spec.
tests: fix missing array_size() include

 * tests/test-sig.c: add #include "lib/memory.h" to get array_size()

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
build: compile tests/ by default

Broke the tests again... let's just build them by default so it's easier
to notice.  If anyone doesn't want to build tests, there's
--disable-tests.

NB: tests will be neither run nor installed.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>