On Fri, Feb 17, 2012 at 05:09:39PM -0500, David Splittberger wrote:
> So I've just started using bird and just wanted to verify with you all
> what I'm seeing in RIPng. I've scoured the mailing list archives so I'm
> pretty sure this is the same bug that has been reported before but I
> figured I would just see if maybe I've actually got a misconfiguration
> instead.
> protocol rip my_rip2 {
> table t5;
> import filter { print "importing"; accept; };
> export filter { print "exporting"; accept; };
> port 521;
> honor neighbor;
> >>> my_rip1: fe80::215:17ff:fe0d:86f4 send me routing info but he is not
> my neighbor
> I hadn't seen those messages turn up in anyone elses posts to the mailing
> list about RIPng so it's making me think I have a misconfiguration
> somewhere.
First, 'mode broadcast' cannot work with IPv6 (but BIRD should complain
about bad config).
Your messages are specific to 'honor neighbor' option, but the main
problem is in RIPng implementation of BIRD (which is broken from the
beginning).
You can use attached patch to get RIPng work (at least on Linux,
probably also with 'honor neighbor' option, but i didn't checked that).
It contains the patch from Roman Hoog Antink [1], does not contain the
patch from Goesta Smekal [2] (which is needed just for compatibily with
other implementations), but it could be used simuntaneously.
[1]
http://www.mail-archive.com/[email protected]/msg01604.html
[2]
http://www.mail-archive.com/[email protected]/msg01824.html
--
Elen sila lumenn' omentielvo
Ondrej 'SanTiago' Zajicek (email: [email protected])
OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net)
"To err is human -- to blame it on a computer is even more so."
Binary files bird-1.3.6-/bird and bird-1.3.6/bird differ
Binary files bird-1.3.6-/obj/proto/rip/all.o and bird-1.3.6/obj/proto/rip/all.o differ
Binary files bird-1.3.6-/obj/proto/rip/rip.o and bird-1.3.6/obj/proto/rip/rip.o differ
diff -uprN bird-1.3.6-/proto/rip/rip.c bird-1.3.6/proto/rip/rip.c
--- bird-1.3.6-/proto/rip/rip.c 2012-01-10 13:42:47.000000000 +0100
+++ bird-1.3.6/proto/rip/rip.c 2012-02-18 12:48:50.000000000 +0100
@@ -281,7 +281,7 @@ rip_rte_update_if_better(rtable *tab, ne
* bird core with this route.
*/
static void
-advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
+advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme, struct iface *iface )
{
rta *a, A;
rte *r;
@@ -309,7 +309,7 @@ advertise_entry( struct proto *p, struct
/* No need to look if destination looks valid - ie not net 0 or 127 -- core will do for us. */
- neighbor = neigh_find( p, &A.gw, 0 );
+ neighbor = neigh_find2( p, &A.gw, iface, 0 );
if (!neighbor) {
log( L_REMOTE "%s: %I asked me to route %I/%d using not-neighbor %I.", p->name, A.from, b->network, pxlen, A.gw );
return;
@@ -353,7 +353,7 @@ advertise_entry( struct proto *p, struct
* process_block - do some basic check and pass block to advertise_entry
*/
static void
-process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
+process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme, struct iface *iface )
{
#ifndef IPV6
int metric = ntohl( block->metric );
@@ -380,7 +380,7 @@ process_block( struct proto *p, struct r
return;
}
- advertise_entry( p, block, whotoldme );
+ advertise_entry( p, block, whotoldme, iface );
}
#define BAD( x ) { log( L_REMOTE "%s: " x, p->name ); return 1; }
@@ -389,7 +389,7 @@ process_block( struct proto *p, struct r
* rip_process_packet - this is main routine for incoming packets.
*/
static int
-rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr whotoldme, int port )
+rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr whotoldme, int port, struct iface *iface )
{
int i;
int authenticated = 0;
@@ -406,7 +406,7 @@ rip_process_packet( struct proto *p, str
if (P_CF->honor == HO_NEVER)
BAD( "They asked me to send routing table, but I was told not to do it" );
- if ((P_CF->honor == HO_NEIGHBOR) && (!neigh_find( p, &whotoldme, 0 )))
+ if ((P_CF->honor == HO_NEIGHBOR) && (!neigh_find2( p, &whotoldme, iface, 0 )))
BAD( "They asked me to send routing table, but he is not my neighbor" );
rip_sendto( p, whotoldme, port, HEAD(P->interfaces) ); /* no broadcast */
break;
@@ -416,7 +416,7 @@ rip_process_packet( struct proto *p, str
return 1;
}
- if (!(neighbor = neigh_find( p, &whotoldme, 0 )) || neighbor->scope == SCOPE_HOST) {
+ if (!(neighbor = neigh_find2( p, &whotoldme, iface, 0 )) || neighbor->scope == SCOPE_HOST) {
log( L_REMOTE "%s: %I send me routing info but he is not my neighbor", p->name, whotoldme );
return 0;
}
@@ -443,7 +443,7 @@ rip_process_packet( struct proto *p, str
if (packet->heading.version == RIP_V1) /* FIXME (nonurgent): switch to disable this? */
block->netmask = ipa_class_mask(block->network);
#endif
- process_block( p, block, whotoldme );
+ process_block( p, block, whotoldme, iface );
}
break;
case RIPCMD_TRACEON:
@@ -463,12 +463,20 @@ rip_rx(sock *s, int size)
{
struct rip_interface *i = s->data;
struct proto *p = i->proto;
+ struct iface *iface = NULL;
int num;
/* In non-listening mode, just ignore packet */
if (i->mode & IM_NOLISTEN)
return 1;
+#ifdef IPV6
+ if (! i->iface || s->lifindex != i->iface->index)
+ return 1;
+
+ iface = i->iface;
+#endif
+
CHK_MAGIC;
DBG( "RIP: message came: %d bytes from %I via %s\n", size, s->faddr, i->iface ? i->iface->name : "(dummy)" );
size -= sizeof( struct rip_packet_heading );
@@ -477,17 +485,12 @@ rip_rx(sock *s, int size)
num = size / sizeof( struct rip_block );
if (num>PACKET_MAX) BAD( "Too many blocks" );
-#ifdef IPV6
- /* Try to absolutize link scope addresses */
- ipa_absolutize(&s->faddr, &i->iface->addr->ip);
-#endif
-
if (ipa_equal(i->iface->addr->ip, s->faddr)) {
DBG("My own packet\n");
return 1;
}
- rip_process_packet( p, (struct rip_packet *) s->rbuf, num, s->faddr, s->fport );
+ rip_process_packet( p, (struct rip_packet *) s->rbuf, num, s->faddr, s->fport, iface );
return 1;
}
@@ -701,6 +704,7 @@ new_iface(struct proto *p, struct iface
{
rif->sock->ttl = 1;
rif->sock->tos = IP_PREC_INTERNET_CONTROL;
+ rif->sock->flags = SKF_LADDR_RX;
}
if (new) {
@@ -712,7 +716,6 @@ new_iface(struct proto *p, struct iface
rif->sock->daddr = ipa_from_u32(0xe0000009);
#else
rif->sock->daddr = ipa_build(0xff020000, 0, 0, 9);
- rif->sock->saddr = new->addr->ip; /* Does not really work on Linux */
#endif
} else {
rif->sock->daddr = new->addr->brd;