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>
Merge branch 'master' into quagga-osr-patches
Merge branch 'master' into quagga-osr-patches
isisd: drop hellos without supported protocol list

isisd should not form adjacencies on receiving an IS-IS Hello without a
list of supported protocols (cf. RFC 1195 s4.4 p32 "Maintaining Router
Adjacencies")
isisd: do not add >63 IP addresses to hello

RFC1195 s4.2 "Multiple IP Addresses per Interface" explicitly forbids us
from adding multiple tuples of IP addresses, putting a hard cutoff at 63
IP addresses.

* isisd/isis_tlv.c: cut off (and return success) at 63 addrs.
isisd: refuse adjacencies with our own system ID

isisd would form an adjacency with another router despite the system IDs
being identical.  This would later cause an assertion failure like this:

  assertion=0x555555596db8 "isis_find_vertex (spftree->paths, id, vtype) == ((void *)0)",
  file=0x555555596c60 "isis_spf.c", line=515, function=0x555555597900 "isis_spf_add2tent") at log.c:619

which is caused by trying to add a path expected to not exist, but
suddenly colliding due to the duplicate system ID.

* isis_pdu.c: check for system ID collision on receiving Hello
Revert "isisd: drop hellos without supported protocol list"

This reverts commit 2023a8c6d109c81256d63b202ef5767976906c0e.

better patch up next.
isisd: drop hellos without supported protocol list

isisd should not form adjacencies on receiving an IS-IS Hello without a
list of supported protocols (cf. RFC 1195 s4.4 p32 "Maintaining Router
Adjacencies")
isisd: fix spftree_area_del typo causing SEGV

spftree_area_del didn't clear the IPv6 L2 spftree due to a simple typo,
leading to a SEGV on shutdown when the still-armed timer would try to
run an IPv6 L2 SPF calculation with its data free'd already.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
isisd: initialize metric-style as narrow

Let isisd metric-style default to narrow so it actually implements
the behaviour isis_config_write() expects.

This allows a narrow metric style to be safed. Before this patch, that
was not possible because isis_config_write() does not produce a
statement for narrow metric style, assuming it is the default. Once
isisd was restarted, the metric style would then default back to wide.

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Revert "isisd: initialize metric-style as narrow"

This reverts commit 6e1a7aa3c047e27e97b0c68e59cb8897731c5ba4.

Better patch up next.
isisd: save metric-style narrow

isisd defaults to wide metric style. So if narrow metric style is
configured, a matching setting should be written to the configuration,
allowing a narrow metric-style setting to be saved.

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
isisd: always join all IS-IS multicast groups

The socket is only created once when an interface is brought up, and the
multicast groups were joined according to configuration at that point.
This breaks when later switching an interface to another IS-IS level.

Since, for a separate conformance issue (ANVL ISIS-6.4), we should be
inspecting the destination address anyway, the simplest fix here is to
just join all groups unconditionally.  There shouldn't be much traffic
on these anyway, worst case we might be picking up some unrelated
multicast groups due to NIC filter aliasing though...
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.