summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2012-12-12isisd: address Coverity warningsDavid Lamparter
this fixes a bunch of issues found by Coverity SCAN and flagged as "high" impact -- although, they're all rather minute issues. * isisd/isis_adjacency.c: one superfluous check, one possible NULL deref * isisd/isis_circuit.c: two prefix memory leaks * isisd/isis_csm.c: one missing break * isisd/isis_lsp.c: one possible NULL deref * isisd/isis_pfpacket.c: one error-case fd leak * isisd/isis_route.c: one isis_route_info memory leak * isisd/isis_routemap.c: one... fnord * isisd/isis_tlv.c: one infinite loop Reported-by: Coverity SCAN Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-12-12isisd: always join all IS-IS multicast groupsDavid Lamparter
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... Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Tested-by: Martin Winter <mwinter@opensourcerouting.org>
2012-12-12isisd: save metric-style narrowChristian Franke
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> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-12-12isisd: fix spftree_area_del typo causing SEGVDavid Lamparter
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>
2012-12-12isisd: drop hellos without supported protocol listDavid Lamparter
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") Also fixes memleaks in these error cases. * isisd/isis_pdu.c: improve TLVFLAG_NLPID handling Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Tested-by: Martin Winter <mwinter@opensourcerouting.org>
2012-12-12isisd: refuse adjacencies with our own system IDDavid Lamparter
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 Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-12-12isisd: do not add >63 IP addresses to helloDavid Lamparter
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. Signed-off-by: David Lamparter <equinox@opensourcerouting.org> Tested-by: Martin Winter <mwinter@opensourcerouting.org>
2012-12-12build: include git infoDavid Lamparter
If enabled with --with-pkg-gitversion on ./configure, this will append git version strings and branch information at the following places: - overall version number: 0.99.21-g0123456 - login motd and show version: tag information + git id + branches Sample output: Hello, this is Quagga (version 0.99.21-g14b49ad-dirty). Copyright 1996-2005 Kunihiro Ishiguro, et al. This is a git build of quagga_0_99_21_release-106-g14b49ad-dirty Associated branch(es): local:master [v2]: fix build without gitinfo (add "else" branch) [v2]: fix for repos without any tags (different git describe output) Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30zebra: include intf when sending IPv4 nexthop to FPMAvneesh Sachdev
* zebra/zebra_fpm_netlink.c Change the zebra FPM code to include an interface index when encoding a nexthop even if the protocol only provided a gateway address (e.g, NEXTHOP_TYPE_IPV4). Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30doc: add blurbs on zebra FPM interface and commandsAvneesh Sachdev
Update documentation with some text on the zebra interface to the optional Forwarding Path Manager component, and the related cli commands. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30zebra: add module to communicate routes to FPMAvneesh Sachdev
Enhance zebra to send routes to the (optional) Forwarding Path Manager component using the interface defined by fpm/fpm.h. * configure.ac - Add --enable-fpm flag. The FPM-related code in zebra is activated only if the build is configured with '--enable-fpm'. - Add HAVE_NETLINK automake conditional. This allows us to conditionally build netlink-dependent C code. * zebra/{rib.h,zebra_rib.c} - Add the 'fpm_q_entries' field to the rib_dest_t structure. This allows dests to be placed on the fpm queue. - Define a couple new rib_dest_t flags that hold FPM-related state. - Invoke the zfpm_trigger_update() function for a route_node whenever the information to be sent to the FPM changes. - rib_can_delete_dest(): Return FALSE if we have to update the FPM about the given dest. This ensures that the dest is not deleted even if there are no ribs hanging off of it. * zebra/zebra_fpm.c This file holds most of the code for interacting with the FPM. - If quagga was configured with '--enable-fpm', periodically try to connect to the FPM. - When the connection comes up, enqueue all relevent dests to the FPM queue. - When the FPM socket is readable, dequeue the next rib_dest_t from the FPM queue, encode it in to a message and send the message to the FPM. - When the connection to the FPM goes down, remove all dests from the FPM queue, and then start trying to connect to the FPM again. - Expose the following new operational commands: show zebra fpm stats clear zebra fpm stats * zebra/zebra_fpm_netlink.c - zfpm_netlink_encode_route(): Function to encode information about a rib_dest_t in netlink format. * zebra/zebra_fpm_private.h Private header file for the zebra FPM module. * zebra/zebra_fpm.h Header file exported by zebra FPM module to the rest of zebra. * zebra/debug.c Add the 'debug zebra fpm' command. * zebra/main.c Initialize the zebra-FPM code on startup. * zebra/misc_null.c Add stub for zfpm_trigger_update(). * zebra/Makefile.am - Include new file zebra_fpm.c in build. - Include zebra_fpm_netlink.c in build if HAVE_NETLINK is defined. * vtysh/Makefile.am Include zebra_fpm.c in list of files that define cli commands. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30fpm: Add public header for Forwarding Plane ManagerAvneesh Sachdev
The Forwarding Plane Manager (FPM) is an optional component that may be used in scenarios where the router has a forwarding path that is distinct from the kernel, commonly a hardware-based fast path. It is responsible for programming forwarding information (such as routes and nexthops) in the fast path. In Quagga, the Routing Information Base is maintained in the 'zebra' infrastructure daemon. Routing protocols communicate their best routes to zebra, and zebra computes the best route across protocols for each prefix. This latter information comprises the bulk of the Forwarding Information Base. The new header file added by this patch, 'fpm/fpm.h', defines a point-to-point interface using which zebra can update the FPM about changes in routes. The communication takes place over a stream socket. The FPM listens on a well-known TCP port, and zebra initiates the connection. All messages sent over the connection start with a short 'FPM header'. In the case of route add/delete messages, the header is followed by a netlink message. Zebra should send a complete copy of the forwarding table(s) to the FPM, including routes that it may have picked up from the kernel. The FPM interface uses replace semantics. That is, if a 'route add' message for a prefix is followed by another 'route add' message, the information in the second message is complete by itself, and replaces the information sent in the first message. If the connection to the FPM goes down for some reason, the client (zebra) should send the FPM a complete copy of the forwarding table(s) when it reconnects. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30lib: bring in sys/queue.h from FreeBSD treeAvneesh Sachdev
Bring in sys/queue.h from the FreeBSD tree as lib/queue.h. This header implements lists of various flavors using inline linkages. The imported file corresponds to SVN revision 221843 (url below) and is available under the terms of the New BSD license (3-clause). http://svnweb.freebsd.org/base/head/sys/sys/queue.h?revision=221843 Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30zebra: extern/extract some functions from rt_netlink.cAvneesh Sachdev
* zebra/{rib.h,zebra_rib.c} Add nexthop_type_to_str(), which returns a human-readable string corresponding to a nexthop type. * zebra/rt_netlink.[hc] - Add new header file that exposes some existing and new netlink-related functions from rt_netlink.c to the rest of zebra. addattr32 addattr_l rta_addattr_l nl_msg_type_to_str (new) nl_rtproto_to_str (new) - Use nexthop_type_to_str() instead of the static array 'nexthop_types_desc'. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30zebra: add iterator for walking all tables in RIBAvneesh Sachdev
* lib/zebra.h Add macro ZEBRA_NUM_OF, which returns the number of elements in a static array. * zebra/rib.h Add the rib_tables_iter_t structure and associated functions, which allow one to walk all tables in the rib. * zebra/zebra_rib.c - Add vrf_id_get_next() to retrieve the first VRF id (if any) that is greater than a given VRF id. - Add rib_tables_iter_next(). Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30zebra: add way to determine VRF/AFI/SAFI of tableAvneesh Sachdev
Add some code that allows us to determine which VRF and AFI/SAFI a given RIB table corresponds to. * zebra/rib.h Add rib_table_info_t structure, which contains information about the VRF, AFI and SAFI that a table is for. * zebra/zebra_rib.c - Add the vrf_table_create() function, which creates a table and sets its 'info' pointer to a newly created rib_table_info_t. The 'info' pointer allows us to go from a route_node or a table to the associated vrf. - vrf_alloc(): Use vrf_create_table() to create tables. * lib/memtypes.c Add memory type for rib_table_info_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30zebra: add structure to hold per-prefix state in RIBAvneesh Sachdev
Add the rib_dest_t structure to hold per-prefix state in the routing information base. This gives us an appropriate place to maintain the queueing state of a route_node. Queuing state was previously being stored on the first rib in the list of ribs hanging off the route_node. * zebra/rib.h - Add new structure rib_dest_t. - Remove the rn_status field from 'struct rib', it is no longer required. - Add macros (RNODE_FOREACH_RIB, RNODE_FOREACH_RIB_SAFE) for walking all 'struct ribs' corresponding to a route_node. These hide the fact that there is an intermediate rib_dest_t structure. - Add a few utility inlines to go between a rib_dest_t and associated structures. * zebra/zebra_rib.c - rib_link()/rib_unlink() Tweak for new behavior, where the 'info' pointer of a route_node points to a rib_dest_t. The list of ribs for a prefix now hangs off of the dest. Change the way we ref count route_nodes. We now hold a single ref count on a route_node if there is a corresponding rib_dest_t. - Maintain the queuing state of a route_node on the flags field of the rib_dest_t. - Add the rib_gc_dest() function, which deletes a rib_dest_t if it is no longer required. A rib_dest_t can be deleted iff there are no struct ribs hanging off of it. - Call rib_gc_dest() any time we unlink a rib from the rib_dest_t. Currently we only need to call it once, just before we return from rib_process(). * zebra/{redistribute,zebra_rib,zebra_snmp,zebra_vty}.c Use new macros to walk over route_node ribs. * lib/memtypes.c Add memory type for rib_dest_t. Signed-off-by: Avneesh Sachdev <avneesh@opensourcerouting.org> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30bgpd: document bgp neighbor local-as peer commandAndrew Certain
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30bgpd: Fixed out-of-date commentAndrew Certain
When going through the code to write the documentation for local-as, I discovered that one of the comments was out-of-date. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-30bgpd: add replace-as modifier for BGP neighborAndrew Certain
Added replace-as modifier for BGP neighbors when using local-as. If the replace-as modifier is specified, only the replacement AS as specified by the local-as modifier is prepended to the AS_PATH, not the process's AS. In bgp_attr.c, I decided that if (peer->change_local_as) { /* If replace-as is specified, we only use the change_local_as when advertising routes. */ if( ! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ) { aspath = aspath_add_seq (aspath, peer->local_as); } aspath = aspath_add_seq (aspath, peer->change_local_as); } else { aspath = aspath_add_seq (aspath, peer->local_as); } was clearer than the alternative that didn't duplicate the prepending of the process's AS: /* First, append the process local AS unless we have an alternate local_as * and we're replacing it (as opposed to just prepending it). */ if (! (peer->change_local_as && CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ) ) { aspath = aspath_add_seq (aspath, peer->local_as); } if (peer->change_local_as) aspath = aspath_add_seq (aspath, peer->change_local_as); } But I could be convinced otherwise. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-05lib: Implement monotonically increasing clock for Darwin.Hasso Tepper
There is no Posix CLOCK_MONOTONIC in Darwin, but monotonically increasing clock can be implemented using mach_absolute_time(). Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-05isisd: clock_gettime() -> quagga_gettime() conversion.Hasso Tepper
* isisd/isis_spf.c: Use portable quagga_gettime() like the rest of the Quagga code. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-05ospfd: remove some buggy extra ';' symbols.Hasso Tepper
* ospfd/ospf_apiserver.c: extra ; causing lookup to fail always * ospfd/ospf_lsa.c: extra ; causing debug output even when disabled Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-05build: check actually-used BSD link state fieldsDoug VanLeuven
ifi_link_state missing in OS X. There could be other *BSD's that haven't implemented it and possibly affects older implementations. The existing HAVE_BSD_LINK_DETECT configure.ac check is only confirming the link state detection using ifmediareq.ifm_status found in <net/if_media.h>. This is the link state detection used in zebra/ioctl.c. Later, *BSD redefined struct if_data in <net/if.h> and included link state detection. This is the method used in zebra/kernel_socket.c Additional test defined in config.ac to test for member struct if_data.ifi_link_state defined in <net/if.h> separate from test for <net/if_media.h> ifmediareq.ifm_status Fixed #ifdef's in zebra/kernel_socket.c to use the new #define No impact on older function calls in zebra/ioctl.c Tested on 64bit OS X 10.7, FreeBSD 9.0 amd64 & i386 (32bit) using gcc & clang. Tested on linux 64bit. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-05zebra: kernel_socket: fix overflow in RTA_ADDR & RTA_ATTRDoug VanLeuven
In zebra/kernel_socket.c, copying sockaddr from *_msghdr: There are really 2 different lengths that need to be determined. 1) the length required to point to the next sockaddr in the mesg buffer which might include any required padding and 2) the actual length of the sockaddr data that needs to be copied into the destination field. They may or may not be the same value. Sizeof sockaddr_in6 is 28, which to pad for alignment purposes on 32 bit systems with a long of 4 bytes is evenly divided and requires no padding. On 64 bit systems, with a long of 8 it is padded with 4 extra bytes.So the current RTA_* macros are copying 32 bytes into a 28 byte field on 64 bitsystems, where the field overflow did not occur on the 32 bit systems. Since using sa_len required the use of an #ifdef which couldn't be used directly inside a #define, it made sense to move the copy into the function to allow typdef checking throughout and eliminate the hack to suppress compiler warnings. Fixed declaration of cp in ifm_read after compiler noticed type mismatch. Tested on 64bit OS X 10.7, FreeBSD 9.0 amd64 & i386 (32bit) using gcc & clang Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-05zebra: kernel_socket: fix 64bit MacOS X alignmentDoug VanLeuven
In OS X 10.7 zebra crashed on invalid execution address. sockaddr padding in *_msghdr is observed to be 4 bytes in 64bit OS X. The ROUNDUP macro assumed alignment on sizeof(long) which allocates 8 bytes on 64bit systems, 4 bytes on 32bit systems which is true for BSD generally. Test for Apple and use sizeof(int) which allocates 4 bytes on 32 & 64bit systems. Tested on 64bit OS X 10.7, FreeBSD 9.0 amd64 & i386 (32bit) using gcc & clang Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-03doc: update installation instructionsDavid Lamparter
configure parameters have changed quite a bit, several options are enabled by default now and there's --disable-tests. Update documentation to match. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-03build: compile tests/ by defaultDavid Lamparter
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>
2012-11-03tests: fix missing array_size() includeDavid Lamparter
* tests/test-sig.c: add #include "lib/memory.h" to get array_size() Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-01bgpd: CVE-2012-1820, DoS in bgp_capability_orf()Denis Ovsienko
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.
2012-11-01build: reorder libraries to address linker errorAvneesh Sachdev
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>
2012-11-01bgpd: flock() dump files (BZ#742)Daniel Kozlowski
flock()ing the BGP dump files helps consumers determine when they're safe to read. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-11-01lib: treat OSX as BSD for IP_HDRINCL (BZ#739)Doug VanLeuven
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>
2012-10-25*: use array_size() helper macroBalaji.G
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>
2012-10-25isisd: don't overrun list of protocolsDavid Lamparter
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>
2012-10-25lib: add array_size() helperDavid Lamparter
implement array_size as sizeof(array) / sizeof(array element) Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-10-25isisd: don't process invalid prefixes from TLVsDavid Lamparter
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>
2012-10-25isisd: pull up invalid prefix assert()David Lamparter
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>
2012-10-25isisd: fix null pointer dereference in send_lsp()Avneesh Sachdev
* 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.
2012-10-25isisd: tighten checks on ISIS pdu lengthAvneesh Sachdev
* 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.
2012-10-25lib: improve sanity checks in stream_set_endp()Avneesh Sachdev
* 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'.
2012-10-25ospfd: respect max-metric over configured cost for summary LSAsJR Rivers
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>
2012-10-25ospfd: ABR algorithm not propagating MAXAGE LSAs into areaJR Rivers
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>
2012-10-25ospfd: blackhole route removal for area rangeJR Rivers
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>
2012-10-25lib: improve fletcher checksum validationJR Rivers
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>
2012-10-25zebra: make static routes respect table settingNolan Leake
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>
2012-10-19Revert "ospfd: Do not fall back to intervening router."Paul Jakma
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.
2012-09-26lib/table: add route_table_get_next() and iteratorAvneesh Sachdev
* lib/table.[ch] - Add a function (route_table_get_next()) to get the route_node in a tree that succeeds a given prefix in iteration order. This allows one to reliably walk nodes in a tree while allowing modifications, and is useful for achieving scale and performance. Other approaches are also possible -- the main plus point of this one is that it does not require any state about the walk to be maintained in the table data structures. - Add an iterator for walking the nodes in a tree. This introduces a new structure (route_table_iter_t) and the following main functions. route_table_iter_init() route_table_iter_pause() route_table_iter_next() route_table_iter_cleanup() The iterator normally uses node pointers and the existing route_next() function to walk nodes efficiently. When an iteration is 'paused' with route_table_iter_pause(), it stores the last prefix processed. The next call to route_table_iter_next() transparently invokes route_table_get_next() with the prefix to resume iteration. * bgpd/bgp_table.[ch] Add wrappers for the new table features described above. * tests/table_test.c Add tests for the new table code. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-09-26bgpd: make bgp_table a wrapper around table libraryAvneesh Sachdev
Make the BGP table code a thin wrapper around the table implementation in libzebra. * bgpd/bgp_table.[ch] - Use the ROUTE_NODE_FIELDS macro to embed the fields of a route_node in the bgp_node structure. - Add a route_table field to the bgp_table structure. Initialize the route_table with a delegate, such that the nodes in the table are bgp_node structures. - Add inline wrappers that call route_table functions underneath, and accept/return the correct BGP types. * bgpd/bgp_route.c Change some code to use inline wrappers instead of accessing fields of nodes/tables directly. The latter does not always work because the types of some fields need to be translated now. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-09-26lib: prepare table code for reuse by bgp_tableAvneesh Sachdev
* lib/table.[ch] - Add a macro (ROUTE_NODE_FIELDS) that expands to all the fields of a route_node structure. - Add the route_table_delegate_t structure, a function vector which allows clients to customize the behavior of one or more tables. The delegate currently contains the 'create_node' and 'destroy_node' functions, and hence enables a table to use an alternative node structure. The alternative node is expected to embed the fields of a route_node using ROUTE_NODE_FIELDS. - Add route_table_init_with_delegate() to create a new table with a given delegate. - Make route_table_init() a thin wrapper around route_table_init_with_delegate(). The delegate it passes in simply creates/destroys route_node structures as before. - Add a user data pointer (info) to the route_table structure. This can be used by a client to keep per-table state. Signed-off-by: David Lamparter <equinox@opensourcerouting.org>