Fixes RIPng socket and neighbor handling.
RIPng did not really work because of link-local addresses. Thanks to Roman Hoog Antink for some notes.
This commit is contained in:
parent
117e3c4bbf
commit
f761503760
1 changed files with 18 additions and 15 deletions
|
@ -281,7 +281,7 @@ rip_rte_update_if_better(rtable *tab, net *net, struct proto *p, rte *new)
|
||||||
* bird core with this route.
|
* bird core with this route.
|
||||||
*/
|
*/
|
||||||
static void
|
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;
|
rta *a, A;
|
||||||
rte *r;
|
rte *r;
|
||||||
|
@ -309,7 +309,7 @@ advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
|
||||||
|
|
||||||
/* No need to look if destination looks valid - ie not net 0 or 127 -- core will do for us. */
|
/* 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) {
|
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 );
|
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;
|
return;
|
||||||
|
@ -353,7 +353,7 @@ advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
|
||||||
* process_block - do some basic check and pass block to advertise_entry
|
* process_block - do some basic check and pass block to advertise_entry
|
||||||
*/
|
*/
|
||||||
static void
|
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
|
#ifndef IPV6
|
||||||
int metric = ntohl( block->metric );
|
int metric = ntohl( block->metric );
|
||||||
|
@ -380,7 +380,7 @@ process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
advertise_entry( p, block, whotoldme );
|
advertise_entry( p, block, whotoldme, iface );
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BAD( x ) { log( L_REMOTE "%s: " x, p->name ); return 1; }
|
#define BAD( x ) { log( L_REMOTE "%s: " x, p->name ); return 1; }
|
||||||
|
@ -389,7 +389,7 @@ process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
|
||||||
* rip_process_packet - this is main routine for incoming packets.
|
* rip_process_packet - this is main routine for incoming packets.
|
||||||
*/
|
*/
|
||||||
static int
|
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 i;
|
||||||
int authenticated = 0;
|
int authenticated = 0;
|
||||||
|
@ -406,7 +406,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
|
||||||
if (P_CF->honor == HO_NEVER)
|
if (P_CF->honor == HO_NEVER)
|
||||||
BAD( "They asked me to send routing table, but I was told not to do it" );
|
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" );
|
BAD( "They asked me to send routing table, but he is not my neighbor" );
|
||||||
rip_sendto( p, whotoldme, port, HEAD(P->interfaces) ); /* no broadcast */
|
rip_sendto( p, whotoldme, port, HEAD(P->interfaces) ); /* no broadcast */
|
||||||
break;
|
break;
|
||||||
|
@ -416,7 +416,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
|
||||||
return 1;
|
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 );
|
log( L_REMOTE "%s: %I send me routing info but he is not my neighbor", p->name, whotoldme );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
|
||||||
if (packet->heading.version == RIP_V1) /* FIXME (nonurgent): switch to disable this? */
|
if (packet->heading.version == RIP_V1) /* FIXME (nonurgent): switch to disable this? */
|
||||||
block->netmask = ipa_class_mask(block->network);
|
block->netmask = ipa_class_mask(block->network);
|
||||||
#endif
|
#endif
|
||||||
process_block( p, block, whotoldme );
|
process_block( p, block, whotoldme, iface );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RIPCMD_TRACEON:
|
case RIPCMD_TRACEON:
|
||||||
|
@ -463,12 +463,20 @@ rip_rx(sock *s, int size)
|
||||||
{
|
{
|
||||||
struct rip_interface *i = s->data;
|
struct rip_interface *i = s->data;
|
||||||
struct proto *p = i->proto;
|
struct proto *p = i->proto;
|
||||||
|
struct iface *iface = NULL;
|
||||||
int num;
|
int num;
|
||||||
|
|
||||||
/* In non-listening mode, just ignore packet */
|
/* In non-listening mode, just ignore packet */
|
||||||
if (i->mode & IM_NOLISTEN)
|
if (i->mode & IM_NOLISTEN)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
#ifdef IPV6
|
||||||
|
if (! i->iface || s->lifindex != i->iface->index)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
iface = i->iface;
|
||||||
|
#endif
|
||||||
|
|
||||||
CHK_MAGIC;
|
CHK_MAGIC;
|
||||||
DBG( "RIP: message came: %d bytes from %I via %s\n", size, s->faddr, i->iface ? i->iface->name : "(dummy)" );
|
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 );
|
size -= sizeof( struct rip_packet_heading );
|
||||||
|
@ -477,17 +485,12 @@ rip_rx(sock *s, int size)
|
||||||
num = size / sizeof( struct rip_block );
|
num = size / sizeof( struct rip_block );
|
||||||
if (num>PACKET_MAX) BAD( "Too many blocks" );
|
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)) {
|
if (ipa_equal(i->iface->addr->ip, s->faddr)) {
|
||||||
DBG("My own packet\n");
|
DBG("My own packet\n");
|
||||||
return 1;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -701,6 +704,7 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
|
||||||
{
|
{
|
||||||
rif->sock->ttl = 1;
|
rif->sock->ttl = 1;
|
||||||
rif->sock->tos = IP_PREC_INTERNET_CONTROL;
|
rif->sock->tos = IP_PREC_INTERNET_CONTROL;
|
||||||
|
rif->sock->flags = SKF_LADDR_RX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new) {
|
if (new) {
|
||||||
|
@ -712,7 +716,6 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
|
||||||
rif->sock->daddr = ipa_from_u32(0xe0000009);
|
rif->sock->daddr = ipa_from_u32(0xe0000009);
|
||||||
#else
|
#else
|
||||||
rif->sock->daddr = ipa_build(0xff020000, 0, 0, 9);
|
rif->sock->daddr = ipa_build(0xff020000, 0, 0, 9);
|
||||||
rif->sock->saddr = new->addr->ip; /* Does not really work on Linux */
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
rif->sock->daddr = new->addr->brd;
|
rif->sock->daddr = new->addr->brd;
|
||||||
|
|
Loading…
Reference in a new issue