Modified the neighbor cache to remember local addresses as well.

neighbor->scope now contains proper address scope which is zero (SCOPE_HOST)
for local addresses, higher (SCOPE_LINK, ..., SCOPE_UNIVERSE) for remote ones.
This commit is contained in:
Martin Mares 2000-06-01 12:58:04 +00:00
parent 56ca7acd3a
commit 0f32f2a65a
2 changed files with 15 additions and 15 deletions

View file

@ -102,6 +102,7 @@ typedef struct neighbor {
void *data; /* Protocol-specific data */ void *data; /* Protocol-specific data */
unsigned aux; /* Protocol-specific data */ unsigned aux; /* Protocol-specific data */
unsigned flags; unsigned flags;
unsigned scope; /* Address scope, SCOPE_HOST when it's our own address */
} neighbor; } neighbor;
#define NEF_STICKY 1 #define NEF_STICKY 1

View file

@ -30,15 +30,15 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */
struct ifa *b; struct ifa *b;
if (!(i->flags & IF_UP)) if (!(i->flags & IF_UP))
return 0; return -1;
WALK_LIST(b, i->addrs) WALK_LIST(b, i->addrs)
{ {
if (ipa_equal(*a, b->ip)) if (ipa_equal(*a, b->ip))
return -1; return SCOPE_HOST;
if (b->flags & IA_UNNUMBERED) if (b->flags & IA_UNNUMBERED)
{ {
if (ipa_equal(*a, b->opposite)) if (ipa_equal(*a, b->opposite))
return 1; return b->scope;
} }
else else
{ {
@ -47,18 +47,18 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */
if (ipa_equal(*a, b->prefix) || /* Network address */ if (ipa_equal(*a, b->prefix) || /* Network address */
ipa_equal(*a, b->brd)) /* Broadcast */ ipa_equal(*a, b->brd)) /* Broadcast */
return -1; return -1;
return 1; return b->scope;
} }
} }
} }
return 0; return -1;
} }
neighbor * neighbor *
neigh_find(struct proto *p, ip_addr *a, unsigned flags) neigh_find(struct proto *p, ip_addr *a, unsigned flags)
{ {
neighbor *n; neighbor *n;
int class; int class, scope = SCOPE_HOST;
unsigned int h = neigh_hash(p, a); unsigned int h = neigh_hash(p, a);
struct iface *i, *j; struct iface *i, *j;
@ -75,14 +75,10 @@ neigh_find(struct proto *p, ip_addr *a, unsigned flags)
j = NULL; j = NULL;
WALK_LIST(i, iface_list) WALK_LIST(i, iface_list)
switch (if_connected(a, i)) if ((scope = if_connected(a, i)) >= 0)
{ {
case -1: j = i;
return NULL; break;
case 1:
if (!j)
j = i;
/* Fall-thru */
} }
if (!j && !(flags & NEF_STICKY)) if (!j && !(flags & NEF_STICKY))
return NULL; return NULL;
@ -101,6 +97,7 @@ neigh_find(struct proto *p, ip_addr *a, unsigned flags)
n->data = NULL; n->data = NULL;
n->aux = 0; n->aux = 0;
n->flags = flags; n->flags = flags;
n->scope = scope;
return n; return n;
} }
@ -112,7 +109,7 @@ neigh_dump(neighbor *n)
debug("%s ", n->iface->name); debug("%s ", n->iface->name);
else else
debug("[] "); debug("[] ");
debug("%s %p %08x", n->proto->name, n->data, n->aux); debug("%s %p %08x scope %s", n->proto->name, n->data, n->aux, ip_scope_text(n->scope));
if (n->flags & NEF_STICKY) if (n->flags & NEF_STICKY)
debug(" STICKY"); debug(" STICKY");
debug("\n"); debug("\n");
@ -137,11 +134,13 @@ void
neigh_if_up(struct iface *i) neigh_if_up(struct iface *i)
{ {
neighbor *n, *next; neighbor *n, *next;
int scope;
WALK_LIST_DELSAFE(n, next, sticky_neigh_list) WALK_LIST_DELSAFE(n, next, sticky_neigh_list)
if (if_connected(&n->addr, i) > 0) if ((scope = if_connected(&n->addr, i)) >= 0)
{ {
n->iface = i; n->iface = i;
n->scope = scope;
add_tail(&i->neighbors, &n->if_n); add_tail(&i->neighbors, &n->if_n);
rem_node(&n->n); rem_node(&n->n);
add_tail(&neigh_hash_table[neigh_hash(n->proto, &n->addr)], &n->n); add_tail(&neigh_hash_table[neigh_hash(n->proto, &n->addr)], &n->n);