extra/quagga: new aport

A free routing daemon replacing Zebra supporting RIP, OSPF and BGP
http://quagga.net/
This commit is contained in:
Natanael Copa 2009-02-19 12:41:00 +00:00
parent ce6f3d73f1
commit 70a0197eae
15 changed files with 1106 additions and 0 deletions

81
extra/quagga/APKBUILD Normal file
View File

@ -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"

33
extra/quagga/bgpd.initd Normal file
View File

@ -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
}

33
extra/quagga/ospf6d.initd Normal file
View File

@ -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
}

33
extra/quagga/ospfd.initd Normal file
View File

@ -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
}

View File

@ -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);
+ }
+ }
+}

View File

@ -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))))

View File

@ -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");

View File

@ -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));

View File

@ -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

View File

@ -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

View File

@ -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

33
extra/quagga/ripd.initd Normal file
View File

@ -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
}

33
extra/quagga/ripngd.initd Normal file
View File

@ -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
}

7
extra/quagga/zebra.confd Normal file
View File

@ -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"

41
extra/quagga/zebra.initd Normal file
View File

@ -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
}