diff options
-rw-r--r-- | extra/quagga/APKBUILD | 81 | ||||
-rw-r--r-- | extra/quagga/bgpd.initd | 33 | ||||
-rw-r--r-- | extra/quagga/ospf6d.initd | 33 | ||||
-rw-r--r-- | extra/quagga/ospfd.initd | 33 | ||||
-rw-r--r-- | extra/quagga/quagga-0.99.11-checksum.patch | 654 | ||||
-rw-r--r-- | extra/quagga/quagga-0.99.11-del-routes.patch | 44 | ||||
-rw-r--r-- | extra/quagga/quagga-0.99.11-ipv6-only.patch | 29 | ||||
-rw-r--r-- | extra/quagga/quagga-0.99.11-ipv6.patch | 19 | ||||
-rw-r--r-- | extra/quagga/quagga-0.99.11-link-libcap.patch | 24 | ||||
-rw-r--r-- | extra/quagga/quagga-0.99.11-zombie.patch | 29 | ||||
-rw-r--r-- | extra/quagga/quagga.install | 13 | ||||
-rw-r--r-- | extra/quagga/ripd.initd | 33 | ||||
-rw-r--r-- | extra/quagga/ripngd.initd | 33 | ||||
-rw-r--r-- | extra/quagga/zebra.confd | 7 | ||||
-rw-r--r-- | extra/quagga/zebra.initd | 41 |
15 files changed, 1106 insertions, 0 deletions
diff --git a/extra/quagga/APKBUILD b/extra/quagga/APKBUILD new file mode 100644 index 00000000..04f33d40 --- /dev/null +++ b/extra/quagga/APKBUILD @@ -0,0 +1,81 @@ +# Maintainer: Natanael Copa <ncopa@alpinelinux.org> +pkgname=quagga +pkgver=0.99.11 +pkgrel=4 +pkgdesc="A free routing daemon replacing Zebra supporting RIP, OSPF and BGP." +url="http://quagga.net/" +license="GPL-2" +depends="uclibc readline ncurses" +makedepends="readline-dev ncurses-dev + autoconf automake libtool" +install=quagga.install +subpackages="$pkgname-dev $pkgname-doc" +source="http://www.quagga.net/download/$pkgname-$pkgver.tar.gz + $pkgname-0.99.11-link-libcap.patch + $pkgname-0.99.11-ipv6.patch + $pkgname-0.99.11-checksum.patch + $pkgname-0.99.11-ipv6-only.patch + $pkgname-0.99.11-del-routes.patch + $pkgname-0.99.11-zombie.patch + bgpd.initd + ospf6d.initd + ospfd.initd + ripd.initd + ripngd.initd + zebra.initd + zebra.confd + $install + " + +build() { + cd "$srcdir"/$pkgname-$pkgver + for i in ../*.patch; do + msg "Applying $i..." + patch -p1 < $i || return 1 + done + + msg "Running autotools..." + aclocal || return 1 + autoconf || return 1 + automake || return 1 + libtoolize || return 1 + + ./configure --prefix=/usr \ + --disable-static \ + --enable-ipv6 \ + --enable-ospf6d \ + --enable-rtadv \ + --enable-user=quagga \ + --enable-group=quagga \ + --enable-vty-group=quagga \ + --enable-vtysh \ + --sysconfdir=/etc/quagga \ + --enable-exampledir=/usr/share/doc/quagga/ \ + --localstatedir=/var/run/quagga \ + || return 1 + +# --with-cflags="${CFLAGS}" \ + make || return 1 + make DESTDIR="$pkgdir" install + + install -d "$pkgdir"/var/run/quagga + for i in zebra ripd ospfd bgpd ripngd ospf6d; do + install -Dm755 "$srcdir"/$i.initd "$pkgdir"/etc/init.d/$i + done + install -Dm644 "$srcdir/zebra.confd" "$pkgdir"/etc/conf.d/zebra +} +md5sums="903e40c744730ad4d62bee872eeb813b quagga-0.99.11.tar.gz +8f99d41a8ed79e51704e8f655d255f29 quagga-0.99.11-link-libcap.patch +d73000d128eaf20a17ffb15b5ca1805a quagga-0.99.11-ipv6.patch +7e1c0152d4733b713613e10df207e3a9 quagga-0.99.11-checksum.patch +44c517e988273e0e5076d24f3959a125 quagga-0.99.11-ipv6-only.patch +1cbcf60a637b2577dee4d6df711e1247 quagga-0.99.11-del-routes.patch +ce345725f2e7240cebe0fd5ac2b2fc48 quagga-0.99.11-zombie.patch +cc109a746273bc0d6aee9d758e7524ab bgpd.initd +44547b687343ebfed7524cebc5626067 ospf6d.initd +89b0cf4e70172bfcd195b2869cae28da ospfd.initd +39b8cb21b55de53af38c94c2f5d85917 ripd.initd +120ab1b53975ec86e78266f31e935ab6 ripngd.initd +6d51e9fca8d206a6d9d1d9fde793b48f zebra.initd +c38e884372406e9e59616e436cd26388 zebra.confd +6d2ca71d32ed9d9517f7779986db91da quagga.install" diff --git a/extra/quagga/bgpd.initd b/extra/quagga/bgpd.initd new file mode 100644 index 00000000..b6104235 --- /dev/null +++ b/extra/quagga/bgpd.initd @@ -0,0 +1,33 @@ +#!/sbin/runscript +# Copyright 1999-2003 DataCore GmbH, Amir Guindehi +# Distributed under the terms of the GNU General Public License, v2 or later +# $Header: /var/cvsroot/gentoo-x86/net-misc/quagga/files/bgpd.init,v 1.1 2005/09/14 11:11:08 mrness Exp $ + +depend() { + need net zebra +} + +checkconfig() { + if [ ! -e /etc/quagga/bgpd.conf ] ; then + eerror "You need to create /etc/quagga/bgpd.conf first." + eerror "An example can be found in /etc/quagga/samples/bgpd.conf.sample" + return 1 + fi +} + +start() { + checkconfig || return 1 + ebegin "Starting bgpd" + start-stop-daemon --start --quiet --exec /usr/sbin/bgpd \ + -- -d -f /etc/quagga/bgpd.conf \ + --pid_file /var/run/quagga/bgpd.pid + result=$? + eend $result +} + +stop() { + ebegin "Stopping bgpd" + start-stop-daemon --stop --quiet --pidfile /var/run/quagga/bgpd.pid + result=$? + eend $result +} diff --git a/extra/quagga/ospf6d.initd b/extra/quagga/ospf6d.initd new file mode 100644 index 00000000..6edafe5f --- /dev/null +++ b/extra/quagga/ospf6d.initd @@ -0,0 +1,33 @@ +#!/sbin/runscript +# Copyright 1999-2003 DataCore GmbH, Amir Guindehi +# Distributed under the terms of the GNU General Public License, v2 or later +# $Header: /var/cvsroot/gentoo-x86/net-misc/quagga/files/ospf6d.init,v 1.1 2005/09/14 11:11:08 mrness Exp $ + +depend() { + need net zebra +} + +checkconfig() { + if [ ! -e /etc/quagga/ospf6d.conf ] ; then + eerror "You need to create /etc/quagga/ospf6d.conf first." + eerror "An example can be found in /etc/quagga/samples/ospf6d.conf.sample" + return 1 + fi +} + +start() { + checkconfig || return 1 + ebegin "Starting ospf6d" + start-stop-daemon --start --quiet --exec /usr/sbin/ospf6d \ + -- -d -f /etc/quagga/ospf6d.conf \ + --pid_file /var/run/quagga/ospf6d.pid + result=$? + eend $result +} + +stop() { + ebegin "Stopping ospf6d" + start-stop-daemon --stop --quiet --pidfile /var/run/quagga/ospf6d.pid + result=$? + eend $result +} diff --git a/extra/quagga/ospfd.initd b/extra/quagga/ospfd.initd new file mode 100644 index 00000000..f67ca2c1 --- /dev/null +++ b/extra/quagga/ospfd.initd @@ -0,0 +1,33 @@ +#!/sbin/runscript +# Copyright 1999-2003 DataCore GmbH, Amir Guindehi +# Distributed under the terms of the GNU General Public License, v2 or later +# $Header: /var/cvsroot/gentoo-x86/net-misc/quagga/files/ospfd.init,v 1.1 2005/09/14 11:11:08 mrness Exp $ + +depend() { + need net zebra +} + +checkconfig() { + if [ ! -e /etc/quagga/ospfd.conf ] ; then + eerror "You need to create /etc/quagga/ospfd.conf first." + eerror "An example can be found in /etc/quagga/samples/ospfd.conf.sample" + return 1 + fi +} + +start() { + checkconfig || return 1 + ebegin "Starting ospfd" + start-stop-daemon --start --quiet --exec /usr/sbin/ospfd \ + -- -d -f /etc/quagga/ospfd.conf \ + --pid_file /var/run/quagga/ospfd.pid + result=$? + eend $result +} + +stop() { + ebegin "Stopping ospfd" + start-stop-daemon --stop --quiet --pidfile /var/run/quagga/ospfd.pid + result=$? + eend $result +} diff --git a/extra/quagga/quagga-0.99.11-checksum.patch b/extra/quagga/quagga-0.99.11-checksum.patch new file mode 100644 index 00000000..c8480ac5 --- /dev/null +++ b/extra/quagga/quagga-0.99.11-checksum.patch @@ -0,0 +1,654 @@ +From: Paul Jakma <paul.jakma@sun.com> +Date: Sun, 16 Nov 2008 18:34:19 +0000 (+0000) +Subject: [lib] Switch Fletcher checksum back to old ospfd version +X-Git-Url: http://code.quagga.net/cgi-bin/gitweb.cgi?p=quagga.git;a=commitdiff_plain;h=5d4b8cf2faba9f5386810a7c70837e5b7fae3572 + +[lib] Switch Fletcher checksum back to old ospfd version + +* lib/checksum.c: (fletcher_checksum) Switch the second phase of the checksum + back to the old ospfd logic. + + The isisd-derived version: + + a) is very hard to follow + b) had some kind of subtle bug that caused it be wrong when c0=0 and c1=254 + (potentially fixable by doing the mods before adjusting x and y) + + Additionally: + + - explicitely cast expressions using non-internal variables to int, to ensure + the result is signed. + - defensively change the length argument to 'size_t', to ensure the code + works with that argument being unsigned.. + + Thanks to Joakim Tjernlund for the investigative work into this bug. + +* tests/test-checksum.c: new file to exercise the checksum code. +--- + +diff --git a/lib/checksum.c b/lib/checksum.c +index 88ec72a..f6d74d3 100644 +--- a/lib/checksum.c ++++ b/lib/checksum.c +@@ -52,34 +52,31 @@ in_cksum(void *parg, int nbytes) + /* To be consistent, offset is 0-based index, rather than the 1-based + index required in the specification ISO 8473, Annex C.1 */ + u_int16_t +-fletcher_checksum(u_char * buffer, int len, u_int16_t offset) ++fletcher_checksum(u_char * buffer, const size_t len, const uint16_t offset) + { + u_int8_t *p; +- int x; +- int y; +- u_int32_t mul; +- u_int32_t c0; +- u_int32_t c1; ++ int x, y, c0, c1; + u_int16_t checksum; + u_int16_t *csum; +- int i, init_len, partial_len; +- ++ size_t partial_len, i, left = len; ++ + checksum = 0; + ++ assert (offset < len); ++ + /* + * Zero the csum in the packet. + */ + csum = (u_int16_t *) (buffer + offset); +- *(csum) = checksum; ++ *(csum) = 0; + + p = buffer; + c0 = 0; + c1 = 0; +- init_len = len; + +- while (len != 0) ++ while (left != 0) + { +- partial_len = MIN(len, MODX); ++ partial_len = MIN(left, MODX); + + for (i = 0; i < partial_len; i++) + { +@@ -90,27 +87,18 @@ fletcher_checksum(u_char * buffer, int len, u_int16_t offset) + c0 = c0 % 255; + c1 = c1 % 255; + +- len -= partial_len; ++ left -= partial_len; + } +- +- mul = (init_len - offset)*(c0); +- +- x = mul - c0 - c1; +- y = c1 - mul - 1; +- +- if (y > 0) +- y++; +- if (x < 0) +- x--; +- +- x %= 255; +- y %= 255; +- +- if (x == 0) +- x = 255; +- if (y == 0) +- y = 1; +- ++ ++ /* The cast is important, to ensure the mod is taken as a signed value. */ ++ x = ((int)(len - offset - 1) * c0 - c1) % 255; ++ ++ if (x <= 0) ++ x += 255; ++ y = 510 - c0 - x; ++ if (y > 255) ++ y -= 255; ++ + /* + * Now we write this to the packet. + * We could skip this step too, since the checksum returned would +diff --git a/lib/checksum.h b/lib/checksum.h +index d3ce930..da1d3cb 100644 +--- a/lib/checksum.h ++++ b/lib/checksum.h +@@ -1,2 +1,2 @@ + extern int in_cksum(void *, int); +-extern u_int16_t fletcher_checksum(u_char * buffer, int len, u_int16_t offset); ++extern u_int16_t fletcher_checksum(u_char *, const size_t len, const uint16_t offset); +diff --git a/tests/Makefile.am b/tests/Makefile.am +index c93fa08..4ab507b 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -6,7 +6,7 @@ AM_LDFLAGS = $(PILDFLAGS) + + noinst_PROGRAMS = testsig testbuffer testmemory heavy heavywq heavythread \ + aspathtest testprivs teststream testbgpcap ecommtest \ +- testbgpmpattr ++ testbgpmpattr testchecksum + + testsig_SOURCES = test-sig.c + testbuffer_SOURCES = test-buffer.c +@@ -20,6 +20,7 @@ aspathtest_SOURCES = aspath_test.c + testbgpcap_SOURCES = bgp_capability_test.c + ecommtest_SOURCES = ecommunity_test.c + testbgpmpattr_SOURCES = bgp_mp_attr_test.c ++testchecksum_SOURCES = test-checksum.c + + testsig_LDADD = ../lib/libzebra.la @LIBCAP@ + testbuffer_LDADD = ../lib/libzebra.la @LIBCAP@ +@@ -33,3 +34,4 @@ aspathtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a + testbgpcap_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a + ecommtest_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a + testbgpmpattr_LDADD = ../lib/libzebra.la @LIBCAP@ -lm ../bgpd/libbgp.a ++testchecksum_LDADD = ../lib/libzebra.la @LIBCAP@ +diff --git a/tests/test-checksum.c b/tests/test-checksum.c +new file mode 100644 +index 0000000..d218840 +--- /dev/null ++++ b/tests/test-checksum.c +@@ -0,0 +1,499 @@ ++#include <zebra.h> ++#include <stdlib.h> ++#include <time.h> ++ ++#include "checksum.h" ++ ++struct thread_master *master; ++ ++struct acc_vals { ++ int c0; ++ int c1; ++}; ++ ++struct csum_vals { ++ struct acc_vals a; ++ int x; ++ int y; ++}; ++ ++static struct csum_vals ospfd_vals, isisd_vals; ++ ++typedef size_t testsz_t; ++typedef uint16_t testoff_t; ++ ++/* Fletcher Checksum -- Refer to RFC1008. */ ++#define MODX 4102 ++ ++/* Accumulator phase of checksum */ ++static ++struct acc_vals ++accumulate (u_char *buffer, testsz_t len, testoff_t off) ++{ ++ u_int8_t *p; ++ u_int16_t *csum; ++ int i, init_len, partial_len; ++ struct acc_vals ret; ++ ++ csum = (u_int16_t *) (buffer + off); ++ *(csum) = 0; ++ ++ p = buffer; ++ ret.c0 = 0; ++ ret.c1 = 0; ++ init_len = len; ++ ++ while (len != 0) ++ { ++ partial_len = MIN(len, MODX); ++ ++ for (i = 0; i < partial_len; i++) ++ { ++ ret.c0 = ret.c0 + *(p++); ++ ret.c1 += ret.c0; ++ } ++ ++ ret.c0 = ret.c0 % 255; ++ ret.c1 = ret.c1 % 255; ++ ++ len -= partial_len; ++ } ++ return ret; ++} ++ ++/* The final reduction phase. ++ * This one should be the original ospfd version ++ */ ++static u_int16_t ++reduce_ospfd (struct csum_vals *vals, testsz_t len, testoff_t off) ++{ ++#define x vals->x ++#define y vals->y ++#define c0 vals->a.c0 ++#define c1 vals->a.c1 ++ ++ x = ((len - off - 1) * c0 - c1) % 255; ++ ++ if (x <= 0) ++ x += 255; ++ y = 510 - c0 - x; ++ if (y > 255) ++ y -= 255; ++ ++ /* take care endian issue. */ ++ return htons ((x << 8) + y); ++#undef x ++#undef y ++#undef c0 ++#undef c1 ++} ++ ++/* slightly different concatenation */ ++static u_int16_t ++reduce_ospfd1 (struct csum_vals *vals, testsz_t len, testoff_t off) ++{ ++#define x vals->x ++#define y vals->y ++#define c0 vals->a.c0 ++#define c1 vals->a.c1 ++ ++ x = ((len - off - 1) * c0 - c1) % 255; ++ if (x <= 0) ++ x += 255; ++ y = 510 - c0 - x; ++ if (y > 255) ++ y -= 255; ++ ++ /* take care endian issue. */ ++ return htons ((x << 8) | (y & 0xff)); ++#undef x ++#undef y ++#undef c0 ++#undef c1 ++} ++ ++/* original isisd version */ ++static u_int16_t ++reduce_isisd (struct csum_vals *vals, testsz_t len, testoff_t off) ++{ ++#define x vals->x ++#define y vals->y ++#define c0 vals->a.c0 ++#define c1 vals->a.c1 ++ u_int32_t mul; ++ ++ mul = (len - off)*(c0); ++ x = mul - c0 - c1; ++ y = c1 - mul - 1; ++ ++ if (y > 0) ++ y++; ++ if (x < 0) ++ x--; ++ ++ x %= 255; ++ y %= 255; ++ ++ if (x == 0) ++ x = 255; ++ if (y == 0) ++ y = 1; ++ ++ return htons ((x << 8) | (y & 0xff)); ++ ++#undef x ++#undef y ++#undef c0 ++#undef c1 ++} ++ ++/* Is the -1 in y wrong perhaps? */ ++static u_int16_t ++reduce_isisd_yfix (struct csum_vals *vals, testsz_t len, testoff_t off) ++{ ++#define x vals->x ++#define y vals->y ++#define c0 vals->a.c0 ++#define c1 vals->a.c1 ++ u_int32_t mul; ++ ++ mul = (len - off)*(c0); ++ x = mul - c0 - c1; ++ y = c1 - mul; ++ ++ if (y > 0) ++ y++; ++ if (x < 0) ++ x--; ++ ++ x %= 255; ++ y %= 255; ++ ++ if (x == 0) ++ x = 255; ++ if (y == 0) ++ y = 1; ++ ++ return htons ((x << 8) | (y & 0xff)); ++ ++#undef x ++#undef y ++#undef c0 ++#undef c1 ++} ++ ++/* Move the mods yp */ ++static u_int16_t ++reduce_isisd_mod (struct csum_vals *vals, testsz_t len, testoff_t off) ++{ ++#define x vals->x ++#define y vals->y ++#define c0 vals->a.c0 ++#define c1 vals->a.c1 ++ u_int32_t mul; ++ ++ mul = (len - off)*(c0); ++ x = mul - c1 - c0; ++ y = c1 - mul - 1; ++ ++ x %= 255; ++ y %= 255; ++ ++ if (y > 0) ++ y++; ++ if (x < 0) ++ x--; ++ ++ if (x == 0) ++ x = 255; ++ if (y == 0) ++ y = 1; ++ ++ return htons ((x << 8) | (y & 0xff)); ++ ++#undef x ++#undef y ++#undef c0 ++#undef c1 ++} ++ ++/* Move the mods up + fix y */ ++static u_int16_t ++reduce_isisd_mody (struct csum_vals *vals, testsz_t len, testoff_t off) ++{ ++#define x vals->x ++#define y vals->y ++#define c0 vals->a.c0 ++#define c1 vals->a.c1 ++ u_int32_t mul; ++ ++ mul = (len - off)*(c0); ++ x = mul - c0 - c1; ++ y = c1 - mul; ++ ++ x %= 255; ++ y %= 255; ++ ++ if (y > 0) ++ y++; ++ if (x < 0) ++ x--; ++ ++ if (x == 0) ++ x = 255; ++ if (y == 0) ++ y = 1; ++ ++ return htons ((x << 8) | (y & 0xff)); ++ ++#undef x ++#undef y ++#undef c0 ++#undef c1 ++} ++ ++struct reductions_t { ++ const char *name; ++ u_int16_t (*f) (struct csum_vals *, testsz_t, testoff_t); ++} reducts[] = { ++ { .name = "ospfd", .f = reduce_ospfd }, ++ { .name = "ospfd-1", .f = reduce_ospfd1 }, ++ { .name = "isisd", .f = reduce_isisd }, ++ { .name = "isisd-yfix", .f = reduce_isisd_yfix }, ++ { .name = "isisd-mod", .f = reduce_isisd_mod }, ++ { .name = "isisd-mody", .f = reduce_isisd_mody }, ++ { NULL, NULL }, ++}; ++ ++/* The original ospfd checksum */ ++static u_int16_t ++ospfd_checksum (u_char *buffer, testsz_t len, testoff_t off) ++{ ++ u_char *sp, *ep, *p, *q; ++ int c0 = 0, c1 = 0; ++ int x, y; ++ u_int16_t checksum, *csum; ++ ++ csum = (u_int16_t *) (buffer + off); ++ *(csum) = 0; ++ ++ sp = buffer; ++ ++ for (ep = sp + len; sp < ep; sp = q) ++ { ++ q = sp + MODX; ++ if (q > ep) ++ q = ep; ++ for (p = sp; p < q; p++) ++ { ++ c0 += *p; ++ c1 += c0; ++ } ++ c0 %= 255; ++ c1 %= 255; ++ } ++ ++ ospfd_vals.a.c0 = c0; ++ ospfd_vals.a.c1 = c1; ++ ++ //printf ("%s: len %u, off %u, c0 %d, c1 %d\n", ++ // __func__, len, off, c0, c1); ++ ++ x = ((int)(len - off - 1) * (int)c0 - (int)c1) % 255; ++ ++ if (x <= 0) ++ x += 255; ++ y = 510 - c0 - x; ++ if (y > 255) ++ y -= 255; ++ ++ ospfd_vals.x = x; ++ ospfd_vals.y = y; ++ ++ buffer[off] = x; ++ buffer[off + 1] = y; ++ ++ /* take care endian issue. */ ++ checksum = htons ((x << 8) | (y & 0xff)); ++ ++ return (checksum); ++} ++ ++/* the original, broken isisd checksum */ ++static u_int16_t ++iso_csum_create (u_char * buffer, testsz_t len, testoff_t off) ++{ ++ ++ u_int8_t *p; ++ int x; ++ int y; ++ u_int32_t mul; ++ u_int32_t c0; ++ u_int32_t c1; ++ u_int16_t checksum, *csum; ++ int i, init_len, partial_len; ++ ++ checksum = 0; ++ ++ csum = (u_int16_t *) (buffer + off); ++ *(csum) = checksum; ++ ++ p = buffer; ++ c0 = 0; ++ c1 = 0; ++ init_len = len; ++ ++ while (len != 0) ++ { ++ partial_len = MIN(len, MODX); ++ ++ for (i = 0; i < partial_len; i++) ++ { ++ c0 = c0 + *(p++); ++ c1 += c0; ++ } ++ ++ c0 = c0 % 255; ++ c1 = c1 % 255; ++ ++ len -= partial_len; ++ } ++ ++ isisd_vals.a.c0 = c0; ++ isisd_vals.a.c1 = c1; ++ ++ mul = (init_len - off) * c0; ++ ++ x = mul - c1 - c0; ++ y = c1 - mul - 1; ++ ++ if (y > 0) ++ y++; ++ if (x < 0) ++ x--; ++ ++ x %= 255; ++ y %= 255; ++ ++ if (x == 0) ++ x = 255; ++ if (y == 0) ++ y = 1; ++ ++ isisd_vals.x = x; ++ isisd_vals.y = y; ++ ++ checksum = htons((x << 8) | (y & 0xFF)); ++ ++ *(csum) = checksum; ++ ++ /* return the checksum for user usage */ ++ return checksum; ++} ++ ++static int ++verify (u_char * buffer, testsz_t len) ++{ ++ u_int8_t *p; ++ u_int32_t c0; ++ u_int32_t c1; ++ u_int16_t checksum; ++ int i, partial_len; ++ ++ p = buffer; ++ checksum = 0; ++ ++ c0 = 0; ++ c1 = 0; ++ ++ while (len) ++ { ++ partial_len = MIN(len, 5803); ++ ++ for (i = 0; i < partial_len; i++) ++ { ++ c0 = c0 + *(p++); ++ c1 += c0; ++ } ++ c0 = c0 % 255; ++ c1 = c1 % 255; ++ ++ len -= partial_len; ++ } ++ ++ if (c0 == 0 && c1 == 0) ++ return 0; ++ ++ return 1; ++} ++ ++int ++main(int argc, char **argv) ++{ ++/* 60017 65629 702179 */ ++#define MAXDATALEN 60017 ++#define BUFSIZE MAXDATALEN + sizeof(u_int16_t) ++ u_char buffer[BUFSIZE]; ++ int exercise = 0; ++#define EXERCISESTEP 257 ++ ++ srandom (time (NULL)); ++ ++ while (1) { ++ u_int16_t ospfd, isisd, lib; ++ ++ exercise += EXERCISESTEP; ++ exercise %= MAXDATALEN; ++ ++ for (int i = 0; i < exercise; i += sizeof (long int)) { ++ long int rand = random (); ++ ++ for (int j = sizeof (long int); j > 0; j--) ++ buffer[i + (sizeof (long int) - j)] = (rand >> (j * 8)) & 0xff; ++ } ++ ++ ospfd = ospfd_checksum (buffer, exercise + sizeof(u_int16_t), exercise); ++ if (verify (buffer, exercise + sizeof(u_int16_t))) ++ printf ("verify: ospfd failed\n"); ++ isisd = iso_csum_create (buffer, exercise + sizeof(u_int16_t), exercise); ++ if (verify (buffer, exercise + sizeof(u_int16_t))) ++ printf ("verify: isisd failed\n"); ++ lib = fletcher_checksum (buffer, exercise + sizeof(u_int16_t), exercise); ++ if (verify (buffer, exercise + sizeof(u_int16_t))) ++ printf ("verify: lib failed\n"); ++ ++ if (ospfd != lib) { ++ printf ("Mismatch in values at size %u\n" ++ "ospfd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n" ++ "isisd: 0x%04x\tc0: %d\tc1: %d\tx: %d\ty: %d\n" ++ "lib: 0x%04x\n", ++ exercise, ++ ospfd, ospfd_vals.a.c0, ospfd_vals.a.c1, ospfd_vals.x, ospfd_vals.y, ++ isisd, isisd_vals.a.c0, isisd_vals.a.c1, isisd_vals.x, isisd_vals.y, ++ lib ++ ); ++ ++ /* Investigate reduction phase discrepencies */ ++ if (ospfd_vals.a.c0 == isisd_vals.a.c0 ++ && ospfd_vals.a.c1 == isisd_vals.a.c1) { ++ printf ("\n"); ++ for (int i = 0; reducts[i].name != NULL; i++) { ++ ospfd = reducts[i].f (&ospfd_vals, ++ exercise + sizeof (u_int16_t), ++ exercise); ++ printf ("%20s: x: %02x, y %02x, checksum 0x%04x\n", ++ reducts[i].name, ospfd_vals.x & 0xff, ospfd_vals.y & 0xff, ospfd); ++ } ++ } ++ ++ printf ("\n u_char testdata [] = {\n "); ++ for (int i = 0; i < exercise; i++) { ++ printf ("0x%02x,%s", ++ buffer[i], ++ (i + 1) % 8 ? " " : "\n "); ++ } ++ printf ("\n}\n"); ++ exit (1); ++ } ++ } ++} diff --git a/extra/quagga/quagga-0.99.11-del-routes.patch b/extra/quagga/quagga-0.99.11-del-routes.patch new file mode 100644 index 00000000..72ee8992 --- /dev/null +++ b/extra/quagga/quagga-0.99.11-del-routes.patch @@ -0,0 +1,44 @@ +From http://lists.quagga.net/pipermail/quagga-dev/2009-January/006362.html + +If there are two paralell PtP links to the same router: + C * 192.168.101.112/32 is directly connected, p1-4-19-4-20 + C>* 192.168.101.112/32 is directly connected, p1-4-17-4-18 +and the cable is to one of the ppp links is pulled, Zebra +deletes both routes instead of just the one that got yanked. +This fixes it to only delete the route to the interface that +got yanked. +--- +This fix was suggested by lsorense at csclub.uwaterloo.ca (Lennart Sorensen) +who had a similar problem. See [quagga-dev 6355] + + zebra/zebra_rib.c | 9 ++++++++- + 1 files changed, 8 insertions(+), 1 deletions(-) + +diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c +index 90db932..7a37387 100644 +--- a/zebra/zebra_rib.c ++++ b/zebra/zebra_rib.c +@@ -1896,6 +1896,13 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p, + inet_ntoa (*gate), + ifindex); + ++ if (IS_ZEBRA_DEBUG_KERNEL && !gate) ++ zlog_debug ("rib_delete_ipv4(): route delete %s/%d directly, %s ifindex %d", ++ inet_ntop (AF_INET, &p->prefix, buf1, BUFSIZ), ++ p->prefixlen, ++ ifindex2ifname(ifindex), ++ ifindex); ++ + /* Lookup route node. */ + rn = route_node_lookup (table, (struct prefix *) p); + if (! rn) +@@ -1942,7 +1949,7 @@ rib_delete_ipv4 (int type, int flags, struct prefix_ipv4 *p, + break; + } + /* Make sure that the route found has the same gateway. */ +- else if (gate == NULL || ++ else if (gate != NULL && + ((nexthop = rib->nexthop) && + (IPV4_ADDR_SAME (&nexthop->gate.ipv4, gate) || + IPV4_ADDR_SAME (&nexthop->rgate.ipv4, gate)))) + diff --git a/extra/quagga/quagga-0.99.11-ipv6-only.patch b/extra/quagga/quagga-0.99.11-ipv6-only.patch new file mode 100644 index 00000000..53636d6b --- /dev/null +++ b/extra/quagga/quagga-0.99.11-ipv6-only.patch @@ -0,0 +1,29 @@ +On Linux the default behaviour of getaddrinfo is to provide both IPV4 and IPV6 +addresses if available. But the default behaviour of binding to an IPV6 address +is to handle both the native IPV6 address and IPV4 to IPV6 mapped addresses. +Without this patch what happens is: + 1. First address is IPV6, bind succeeds. + 2. Second address is IPV4, bind fails (port already used by IPV6) + 3. incoming connections come in on IPV6 listen socket, as IPV4 mapped + addresses then BGP gets confused because of client with unexpected address. + +The fix is to force IPV6 socket as IPV6 only. + +--- a/bgpd/bgp_network.c 2008-08-27 17:59:20.000000000 -0700 ++++ b/bgpd/bgp_network.c 2008-08-27 18:02:46.000000000 -0700 +@@ -412,6 +412,15 @@ bgp_socket (struct bgp *bgp, unsigned sh + setsockopt_ipv4_tos (sock, IPTOS_PREC_INTERNETCONTROL); + #endif + ++#ifdef IPV6_V6ONLY ++ /* Want only IPV6 on ipv6 socket (not mapped addresses) */ ++ if (ainfo->ai_family == AF_INET6) { ++ int on = 1; ++ setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, ++ (void *) &on, sizeof (on)); ++ } ++#endif ++ + if (bgpd_privs.change (ZPRIVS_RAISE) ) + zlog_err ("bgp_socket: could not raise privs"); + diff --git a/extra/quagga/quagga-0.99.11-ipv6.patch b/extra/quagga/quagga-0.99.11-ipv6.patch new file mode 100644 index 00000000..b7b0b3d2 --- /dev/null +++ b/extra/quagga/quagga-0.99.11-ipv6.patch @@ -0,0 +1,19 @@ +diff -Nru quagga-0.99.11.orig/lib/sockopt.c quagga-0.99.11/lib/sockopt.c +--- quagga-0.99.11.orig/lib/sockopt.c 2008-09-05 14:27:26.000000000 +0000 ++++ quagga-0.99.11/lib/sockopt.c 2008-10-13 21:46:13.000000000 +0000 +@@ -530,6 +530,7 @@ + return -1; + }; + ++#ifdef HAVE_IPV6 + /* If this does not work, then all users of this sockopt will need to + * differentiate between IPv4 and IPv6, and keep seperate sockets for + * each. +@@ -546,6 +547,7 @@ + su2->sin6.sin6_addr.s6_addr32[2] = htonl(0xffff); + memcpy (&su2->sin6.sin6_addr.s6_addr32[3], &su->sin.sin_addr, 4); + } ++#endif /* HAVE_IPV6 */ + } + + memset (&md5sig, 0, sizeof (md5sig)); diff --git a/extra/quagga/quagga-0.99.11-link-libcap.patch b/extra/quagga/quagga-0.99.11-link-libcap.patch new file mode 100644 index 00000000..2c1b868d --- /dev/null +++ b/extra/quagga/quagga-0.99.11-link-libcap.patch @@ -0,0 +1,24 @@ +diff -ur quagga-0.99.11.orig/lib/Makefile.am quagga-0.99.11/lib/Makefile.am +--- quagga-0.99.11.orig/lib/Makefile.am 2008-09-24 15:22:43.000000000 +0000 ++++ quagga-0.99.11/lib/Makefile.am 2008-10-09 20:29:17.000000000 +0000 +@@ -18,7 +18,7 @@ + + libzebra_la_DEPENDENCIES = @LIB_REGEX@ + +-libzebra_la_LIBADD = @LIB_REGEX@ ++libzebra_la_LIBADD = @LIB_REGEX@ @LIBCAP@ + + pkginclude_HEADERS = \ + buffer.h checksum.h command.h filter.h getopt.h hash.h \ +diff -ur quagga-0.99.11.orig/zebra/Makefile.am quagga-0.99.11/zebra/Makefile.am +--- quagga-0.99.11.orig/zebra/Makefile.am 2008-09-05 14:27:26.000000000 +0000 ++++ quagga-0.99.11/zebra/Makefile.am 2008-10-09 20:29:17.000000000 +0000 +@@ -39,7 +39,7 @@ + connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \ + interface.h ipforward.h irdp.h router-id.h kernel_socket.h + +-zebra_LDADD = $(otherobj) $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la ++zebra_LDADD = $(otherobj) ../lib/libzebra.la $(LIBCAP) $(LIB_IPV6) + + testzebra_LDADD = $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la + diff --git a/extra/quagga/quagga-0.99.11-zombie.patch b/extra/quagga/quagga-0.99.11-zombie.patch new file mode 100644 index 00000000..ad562df0 --- /dev/null +++ b/extra/quagga/quagga-0.99.11-zombie.patch @@ -0,0 +1,29 @@ + +Currently, when accepting the connection, it can be left as zombie, +when the peer just initiates a connection, but never sends data (and +the TCP connection end packets are lost). This happens because for +accepted connections a temporary new peer entry is created until OPEN +message is exchanged, and this temporary peer entry does not get the +hold time parameter set at all. + +Signed-off-by: Timo Teras <timo.teras@iki.fi> +--- + bgpd/bgp_network.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c +index 5dbd487..9a4c36d 100644 +--- a/bgpd/bgp_network.c ++++ b/bgpd/bgp_network.c +@@ -185,6 +185,8 @@ bgp_accept (struct thread *thread) + peer->fd = bgp_sock; + peer->status = Active; + peer->local_id = peer1->local_id; ++ peer->v_holdtime = peer1->v_holdtime; ++ peer->v_keepalive = peer1->v_keepalive; + + /* Make peer's address string. */ + sockunion2str (&su, buf, SU_ADDRSTRLEN); +-- +1.5.6.3 + diff --git a/extra/quagga/quagga.install b/extra/quagga/quagga.install new file mode 100644 index 00000000..a69fe81a --- /dev/null +++ b/extra/quagga/quagga.install @@ -0,0 +1,13 @@ +#!/bin/sh + +case "$1" in + pre_install) + adduser -H -h /var/empty -s /bin/false -D quagga 2>/dev/null + mkdir -p var/empty + chown root:root var/empty + chown quagga:quagga /var/run/quagga + ;; +esac +exit 0 + + diff --git a/extra/quagga/ripd.initd b/extra/quagga/ripd.initd new file mode 100644 index 00000000..987d6ec4 --- /dev/null +++ b/extra/quagga/ripd.initd @@ -0,0 +1,33 @@ +#!/sbin/runscript +# Copyright 1999-2003 DataCore GmbH, Amir Guindehi +# Distributed under the terms of the GNU General Public License, v2 or later +# $Header: /var/cvsroot/gentoo-x86/net-misc/quagga/files/ripd.init,v 1.1 2005/09/14 11:11:08 mrness Exp $ + +depend() { + need net zebra +} + +checkconfig() { + if [ ! -e /etc/quagga/ripd.conf ] ; then + eerror "You need to create /etc/quagga/ripd.conf first." + eerror "An example can be found in /etc/quagga/samples/ripd.conf.sample" + return 1 + fi +} + +start() { + checkconfig || return 1 + ebegin "Starting ripd" + start-stop-daemon --start --quiet --exec /usr/sbin/ripd \ + -- -d -f /etc/quagga/ripd.conf \ + --pid_file /var/run/quagga/ripd.pid + result=$? + eend $result +} + +stop() { + ebegin "Stopping ripd" + start-stop-daemon --stop --quiet --pidfile /var/run/quagga/ripd.pid + result=$? + eend $result +} diff --git a/extra/quagga/ripngd.initd b/extra/quagga/ripngd.initd new file mode 100644 index 00000000..9bf2ff2a --- /dev/null +++ b/extra/quagga/ripngd.initd @@ -0,0 +1,33 @@ +#!/sbin/runscript +# Copyright 1999-2003 DataCore GmbH, Amir Guindehi +# Distributed under the terms of the GNU General Public License, v2 or later +# $Header: /var/cvsroot/gentoo-x86/net-misc/quagga/files/ripngd.init,v 1.1 2005/09/14 11:11:08 mrness Exp $ + +depend() { + need net zebra +} + +checkconfig() { + if [ ! -e /etc/quagga/ripngd.conf ] ; then + eerror "You need to create /etc/quagga/ripngd.conf first." + eerror "An example can be found in /etc/quagga/samples/ripngd.conf.sample" + return 1 + fi +} + +start() { + checkconfig || return 1 + ebegin "Starting ripngd" + start-stop-daemon --start --quiet --exec /usr/sbin/ripngd \ + -- -d -f /etc/quagga/ripngd.conf \ + --pid_file /var/run/quagga/ripngd.pid + result=$? + eend $result +} + +stop() { + ebegin "Stopping ripngd" + start-stop-daemon --stop --quiet --pidfile /var/run/quagga/ripngd.pid + result=$? + eend $result +} diff --git a/extra/quagga/zebra.confd b/extra/quagga/zebra.confd new file mode 100644 index 00000000..a5256acd --- /dev/null +++ b/extra/quagga/zebra.confd @@ -0,0 +1,7 @@ +# Additional command-line parameters to run zebra with: +# -k, --keep_kernel Don't delete old routes which installed by zebra. +# -l, --log_mode number Set verbose log mode flag +# -A, --vty_addr addr Set vty's bind address +# -P, --vty_port port Set vty's port number +# -r, --retain When program terminates, retain added route by zebra. +ZEBRA_OPTS="-l 255" diff --git a/extra/quagga/zebra.initd b/extra/quagga/zebra.initd new file mode 100644 index 00000000..5ca8ef58 --- /dev/null +++ b/extra/quagga/zebra.initd @@ -0,0 +1,41 @@ +#!/sbin/runscript +# Copyright 1999-2004 Gentoo Foundation +# Distributed under the terms of the GNU General Public License, v2 or later +# $Header: /var/cvsroot/gentoo-x86/net-misc/quagga/files/zebra.init,v 1.2 2007/02/25 09:57:18 mrness Exp $ + +depend() { + need net +} + +checkconfig() { + if [ ! -e /etc/quagga/zebra.conf ] ; then + eerror "You need to create /etc/quagga/zebra.conf first." + eerror "An example can be found in /etc/quagga/samples/zebra.conf.sample" + return 1 + fi +} + +cleanup() { + ebegin "Cleaning up stale zebra routes..." + ip route flush proto zebra + eend $? +} + +start() { + checkconfig || return 1 + cleanup + + ebegin "Starting zebra" + start-stop-daemon --start --quiet --exec /usr/sbin/zebra \ + -- -d -f /etc/quagga/zebra.conf ${ZEBRA_OPTS} \ + --pid_file /var/run/quagga/zebra.pid + result=$? + eend $result +} + +stop() { + ebegin "Stopping zebra" + start-stop-daemon --stop --quiet --pidfile /var/run/quagga/zebra.pid + result=$? + eend $result +} |