Commit 586c1800 authored by Ondřej Zajíček's avatar Ondřej Zajíček

Nest: Neighbor cache cleanups

Simplify neighbor cache code, fix several minor bugs, and improve
handling of ONLINK flag.
parent 45f28d85
Pipeline #37418 failed with stages
in 4 minutes and 44 seconds
...@@ -974,7 +974,7 @@ interpret(struct f_inst *what) ...@@ -974,7 +974,7 @@ interpret(struct f_inst *what)
case SA_GW: case SA_GW:
{ {
ip_addr ip = v1.val.ip; ip_addr ip = v1.val.ip;
neighbor *n = neigh_find(rta->src->proto, &ip, 0); neighbor *n = neigh_find(rta->src->proto, ip, NULL, 0);
if (!n || (n->scope == SCOPE_HOST)) if (!n || (n->scope == SCOPE_HOST))
runtime( "Invalid gw address" ); runtime( "Invalid gw address" );
......
...@@ -230,4 +230,11 @@ mem_hash(void *p, uint s) ...@@ -230,4 +230,11 @@ mem_hash(void *p, uint s)
return mem_hash_value(&h); return mem_hash_value(&h);
} }
static inline uint
ptr_hash(void *ptr)
{
uintptr_t p = (uintptr_t) ptr;
return p ^ (p << 8) ^ (p >> 16);
}
#endif #endif
...@@ -124,29 +124,21 @@ typedef struct neighbor { ...@@ -124,29 +124,21 @@ typedef struct neighbor {
ip_addr addr; /* Address of the neighbor */ ip_addr addr; /* Address of the neighbor */
struct ifa *ifa; /* Ifa on related iface */ struct ifa *ifa; /* Ifa on related iface */
struct iface *iface; /* Interface it's connected to */ struct iface *iface; /* Interface it's connected to */
struct iface *ifreq; /* Requested iface, NULL for any */
struct proto *proto; /* Protocol this belongs to */ struct proto *proto; /* Protocol this belongs to */
void *data; /* Protocol-specific data */ void *data; /* Protocol-specific data */
unsigned aux; /* Protocol-specific data */ uint aux; /* Protocol-specific data */
unsigned flags; u16 flags; /* NEF_* flags */
int scope; /* Address scope, -1 for unreachable sticky neighbors, s16 scope; /* Address scope, -1 for unreachable neighbors,
SCOPE_HOST when it's our own address */ SCOPE_HOST when it's our own address */
} neighbor; } neighbor;
#define NEF_STICKY 1 #define NEF_STICKY 1
#define NEF_ONLINK 2 #define NEF_ONLINK 2
#define NEF_BIND 4 /* Used internally for neighbors bound to an iface */ #define NEF_IFACE 4 /* Entry for whole iface */
#define NEF_IFACE 8 /* Neighbors bound to iface */
neighbor *neigh_find(struct proto *, ip_addr *, unsigned flags);
neighbor *neigh_find2(struct proto *p, ip_addr *a, struct iface *ifa, unsigned flags);
neighbor *neigh_find_iface(struct proto *p, struct iface *ifa);
static inline int neigh_connected_to(struct proto *p, ip_addr *a, struct iface *i) neighbor *neigh_find(struct proto *p, ip_addr a, struct iface *ifa, uint flags);
{
neighbor *n = neigh_find(p, a, 0);
return n && n->iface == i;
}
void neigh_dump(neighbor *); void neigh_dump(neighbor *);
void neigh_dump_all(void); void neigh_dump_all(void);
......
This diff is collapsed.
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "lib/string.h" #include "lib/string.h"
#include "conf/conf.h" #include "conf/conf.h"
#include "filter/filter.h" #include "filter/filter.h"
#include "lib/hash.h"
#include "lib/string.h" #include "lib/string.h"
#include "lib/alloca.h" #include "lib/alloca.h"
...@@ -2220,13 +2221,6 @@ rt_feed_channel_abort(struct channel *c) ...@@ -2220,13 +2221,6 @@ rt_feed_channel_abort(struct channel *c)
} }
} }
static inline unsigned
ptr_hash(void *ptr)
{
uintptr_t p = (uintptr_t) ptr;
return p ^ (p << 8) ^ (p >> 16);
}
static inline u32 static inline u32
hc_hash(ip_addr a, rtable *dep) hc_hash(ip_addr a, rtable *dep)
{ {
......
...@@ -775,7 +775,7 @@ bfd_start_neighbor(struct bfd_proto *p, struct bfd_neighbor *n) ...@@ -775,7 +775,7 @@ bfd_start_neighbor(struct bfd_proto *p, struct bfd_neighbor *n)
return; return;
} }
struct neighbor *nb = neigh_find2(&p->p, &n->addr, n->iface, NEF_STICKY); struct neighbor *nb = neigh_find(&p->p, n->addr, n->iface, NEF_STICKY);
if (!nb) if (!nb)
{ {
log(L_ERR "%s: Invalid remote address %I%J", p->p.name, n->addr, n->iface); log(L_ERR "%s: Invalid remote address %I%J", p->p.name, n->addr, n->iface);
......
...@@ -1277,7 +1277,7 @@ bgp_start_locked(struct object_lock *lock) ...@@ -1277,7 +1277,7 @@ bgp_start_locked(struct object_lock *lock)
return; return;
} }
neighbor *n = neigh_find2(&p->p, &cf->remote_ip, cf->iface, NEF_STICKY); neighbor *n = neigh_find(&p->p, cf->remote_ip, cf->iface, NEF_STICKY);
if (!n) if (!n)
{ {
log(L_ERR "%s: Invalid remote address %I%J", p->p.name, cf->remote_ip, cf->iface); log(L_ERR "%s: Invalid remote address %I%J", p->p.name, cf->remote_ip, cf->iface);
...@@ -1521,7 +1521,7 @@ bgp_channel_start(struct channel *C) ...@@ -1521,7 +1521,7 @@ bgp_channel_start(struct channel *C)
if (ipa_zero(c->next_hop_addr)) if (ipa_zero(c->next_hop_addr))
{ {
/* We know the iface for single-hop, we make lookup for multihop */ /* We know the iface for single-hop, we make lookup for multihop */
struct neighbor *nbr = p->neigh ?: neigh_find2(&p->p, &src, NULL, 0); struct neighbor *nbr = p->neigh ?: neigh_find(&p->p, src, NULL, 0);
struct iface *iface = nbr ? nbr->iface : NULL; struct iface *iface = nbr ? nbr->iface : NULL;
if (bgp_channel_is_ipv4(c) && iface && iface->addr4) if (bgp_channel_is_ipv4(c) && iface && iface->addr4)
......
...@@ -744,9 +744,9 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll) ...@@ -744,9 +744,9 @@ bgp_apply_next_hop(struct bgp_parse_state *s, rta *a, ip_addr gw, ip_addr ll)
/* GW_DIRECT -> single_hop -> p->neigh != NULL */ /* GW_DIRECT -> single_hop -> p->neigh != NULL */
if (ipa_nonzero(gw)) if (ipa_nonzero(gw))
nbr = neigh_find2(&p->p, &gw, NULL, 0); nbr = neigh_find(&p->p, gw, NULL, 0);
else if (ipa_nonzero(ll)) else if (ipa_nonzero(ll))
nbr = neigh_find2(&p->p, &ll, p->neigh->iface, 0); nbr = neigh_find(&p->p, ll, p->neigh->iface, 0);
if (!nbr || (nbr->scope == SCOPE_HOST)) if (!nbr || (nbr->scope == SCOPE_HOST))
WITHDRAW(BAD_NEXT_HOP); WITHDRAW(BAD_NEXT_HOP);
......
...@@ -1987,7 +1987,7 @@ again1: ...@@ -1987,7 +1987,7 @@ again1:
for (nh = nf->n.nhs; nh; nh = nh->next) for (nh = nf->n.nhs; nh; nh = nh->next)
if (ipa_nonzero(nh->gw)) if (ipa_nonzero(nh->gw))
{ {
neighbor *ng = neigh_find2(&p->p, &nh->gw, nh->iface, 0); neighbor *ng = neigh_find(&p->p, nh->gw, nh->iface, 0);
if (!ng || (ng->scope == SCOPE_HOST)) if (!ng || (ng->scope == SCOPE_HOST))
{ reset_ri(nf); break; } { reset_ri(nf); break; }
} }
......
...@@ -627,7 +627,7 @@ rip_receive_response(struct rip_proto *p, struct rip_iface *ifa, struct rip_pack ...@@ -627,7 +627,7 @@ rip_receive_response(struct rip_proto *p, struct rip_iface *ifa, struct rip_pack
if (ipa_nonzero(rte.next_hop)) if (ipa_nonzero(rte.next_hop))
{ {
neighbor *nbr = neigh_find2(&p->p, &rte.next_hop, ifa->iface, 0); neighbor *nbr = neigh_find(&p->p, rte.next_hop, ifa->iface, 0);
if (!nbr || (nbr->scope <= 0)) if (!nbr || (nbr->scope <= 0))
rte.next_hop = IPA_NONE; rte.next_hop = IPA_NONE;
} }
......
...@@ -377,7 +377,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s ...@@ -377,7 +377,7 @@ rip_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *net, s
struct rip_neighbor * struct rip_neighbor *
rip_get_neighbor(struct rip_proto *p, ip_addr *a, struct rip_iface *ifa) rip_get_neighbor(struct rip_proto *p, ip_addr *a, struct rip_iface *ifa)
{ {
neighbor *nbr = neigh_find2(&p->p, a, ifa->iface, 0); neighbor *nbr = neigh_find(&p->p, *a, ifa->iface, 0);
if (!nbr || (nbr->scope == SCOPE_HOST) || !rip_iface_link_up(ifa)) if (!nbr || (nbr->scope == SCOPE_HOST) || !rip_iface_link_up(ifa))
return NULL; return NULL;
......
...@@ -205,10 +205,9 @@ static_add_rte(struct static_proto *p, struct static_route *r) ...@@ -205,10 +205,9 @@ static_add_rte(struct static_proto *p, struct static_route *r)
for (r2 = r; r2; r2 = r2->mp_next) for (r2 = r; r2; r2 = r2->mp_next)
{ {
n = ipa_nonzero(r2->via) ? n = neigh_find(&p->p, r2->via, r2->iface, NEF_STICKY |
neigh_find2(&p->p, &r2->via, r2->iface, (r2->onlink ? NEF_ONLINK : 0) |
NEF_STICKY | (r2->onlink ? NEF_ONLINK : 0)) : (ipa_zero(r2->via) ? NEF_IFACE : 0));
neigh_find_iface(&p->p, r2->iface);
if (!n) if (!n)
{ {
......
...@@ -696,8 +696,8 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr ...@@ -696,8 +696,8 @@ nl_parse_multipath(struct nl_parse_state *s, struct krt_proto *p, struct rtattr
rv->flags |= RNF_ONLINK; rv->flags |= RNF_ONLINK;
neighbor *nbr; neighbor *nbr;
nbr = neigh_find2(&p->p, &rv->gw, rv->iface, nbr = neigh_find(&p->p, rv->gw, rv->iface,
(rv->flags & RNF_ONLINK) ? NEF_ONLINK : 0); (rv->flags & RNF_ONLINK) ? NEF_ONLINK : 0);
if (!nbr || (nbr->scope == SCOPE_HOST)) if (!nbr || (nbr->scope == SCOPE_HOST))
return NULL; return NULL;
} }
...@@ -1636,8 +1636,8 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h) ...@@ -1636,8 +1636,8 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
ra->nh.flags |= RNF_ONLINK; ra->nh.flags |= RNF_ONLINK;
neighbor *nbr; neighbor *nbr;
nbr = neigh_find2(&p->p, &(ra->nh.gw), ra->nh.iface, nbr = neigh_find(&p->p, ra->nh.gw, ra->nh.iface,
(ra->nh.flags & RNF_ONLINK) ? NEF_ONLINK : 0); (ra->nh.flags & RNF_ONLINK) ? NEF_ONLINK : 0);
if (!nbr || (nbr->scope == SCOPE_HOST)) if (!nbr || (nbr->scope == SCOPE_HOST))
{ {
log(L_ERR "KRT: Received route %N with strange next-hop %I", net->n.addr, log(L_ERR "KRT: Received route %N with strange next-hop %I", net->n.addr,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment