diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2010-02-26 10:55:58 +0100 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2010-02-26 10:55:58 +0100 |
commit | ff2857b03db854f99902766ad842aaa5fa29ec3c (patch) | |
tree | 8484bfcabaa9805fab2ae188a6855314192d92e1 /nest/neighbor.c | |
parent | e81b440f6878605edd19ed62441648ac71260881 (diff) |
Many changes in (mainly) kernel syncers.
- BSD kernel syncer is now self-conscious and can learn alien routes
- important bugfix in BSD kernel syncer (crash after protocol restart)
- many minor changes and bugfixes in kernel syncers and neighbor cache
- direct protocol does not generate host and link local routes
- min_scope check is removed, all routes have SCOPE_UNIVERSE by default
- also fixes some remaining compiler warnings
Diffstat (limited to 'nest/neighbor.c')
-rw-r--r-- | nest/neighbor.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/nest/neighbor.c b/nest/neighbor.c index a44667f5..25b98dbd 100644 --- a/nest/neighbor.c +++ b/nest/neighbor.c @@ -112,12 +112,12 @@ neighbor * neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags) { neighbor *n; - int class, scope = SCOPE_HOST; + int class, scope = -1; ; unsigned int h = neigh_hash(p, a); struct iface *i; WALK_LIST(n, neigh_hash_table[h]) /* Search the cache */ - if (n->proto == p && ipa_equal(*a, n->addr)) + if (n->proto == p && ipa_equal(*a, n->addr) && (!ifa || (ifa == n->iface))) return n; class = ipa_classify(*a); @@ -129,7 +129,12 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags) return NULL; /* Bad scope or a somecast */ if (ifa) - scope = if_connected(a, ifa); + { + scope = if_connected(a, ifa); + + if ((scope < 0) && (flags & NEF_ONLINK)) + scope = class & IADDR_SCOPE_MASK; + } else WALK_LIST(i, iface_list) if ((scope = if_connected(a, i)) >= 0) @@ -138,22 +143,28 @@ neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags) break; } - if (!ifa && !(flags & NEF_STICKY)) + /* scope < 0 means i don't know neighbor */ + /* scope >= 0 implies ifa != NULL */ + + if ((scope < 0) && !(flags & NEF_STICKY)) return NULL; n = sl_alloc(neigh_slab); n->addr = *a; - n->iface = ifa; - if (ifa) + if (scope >= 0) { add_tail(&neigh_hash_table[h], &n->n); add_tail(&ifa->neighbors, &n->if_n); } else { + /* sticky flag does not work for link-local neighbors; + fortunately, we don't use this combination */ add_tail(&sticky_neigh_list, &n->n); + ifa = NULL; scope = 0; } + n->iface = ifa; n->proto = p; n->data = NULL; n->aux = 0; |