]> git.ipfire.org Git - thirdparty/bird.git/blame - nest/neighbor.c
Bison: A bit more verbose error messages in config.
[thirdparty/bird.git] / nest / neighbor.c
CommitLineData
85053fce
MM
1/*
2 * BIRD -- Neighbor Cache
3 *
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
586c1800
OZ
5 * (c) 2008--2018 Ondrej Zajicek <santiago@crfreenet.org>
6 * (c) 2008--2018 CZ.NIC z.s.p.o.
85053fce
MM
7 *
8 * Can be freely distributed and used under the terms of the GNU GPL.
9 */
10
1f495723
MM
11/**
12 * DOC: Neighbor cache
13 *
14 * Most routing protocols need to associate their internal state data with
586c1800
OZ
15 * neighboring routers, check whether an address given as the next hop attribute
16 * of a route is really an address of a directly connected host and which
17 * interface is it connected through. Also, they often need to be notified when
18 * a neighbor ceases to exist or when their long awaited neighbor becomes
19 * connected. The neighbor cache is there to solve all these problems.
1f495723 20 *
586c1800
OZ
21 * The neighbor cache maintains a collection of neighbor entries. Each entry
22 * represents one IP address corresponding to either our directly connected
23 * neighbor or our own end of the link (when the scope of the address is set to
24 * %SCOPE_HOST) together with per-neighbor data belonging to a single protocol.
25 * A neighbor entry may be bound to a specific interface, which is required for
26 * link-local IP addresses and optional for global IP addresses.
1f495723 27 *
586c1800
OZ
28 * Neighbor cache entries are stored in a hash table, which is indexed by triple
29 * (protocol, IP, requested-iface), so if both regular and iface-bound neighbors
30 * are requested, they are represented by two neighbor cache entries. Active
31 * entries are also linked in per-interface list (allowing quick processing of
32 * interface change events). Inactive entries exist only when the protocol has
33 * explicitly requested it via the %NEF_STICKY flag because it wishes to be
34 * notified when the node will again become a neighbor. Such entries are instead
35 * linked in a special list, which is walked whenever an interface changes its
36 * state to up. Neighbor entry VRF association is implied by respective
37 * protocol.
38 *
39 * Besides the already mentioned %NEF_STICKY flag, there is also %NEF_ONLINK,
40 * which specifies that neighbor should be considered reachable on given iface
41 * regardless of associated address ranges, and %NEF_IFACE, which represents
42 * pseudo-neighbor entry for whole interface (and uses %IPA_NONE IP address).
1f495723
MM
43 *
44 * When a neighbor event occurs (a neighbor gets disconnected or a sticky
586c1800
OZ
45 * inactive neighbor becomes connected), the protocol hook neigh_notify() is
46 * called to advertise the change.
1f495723
MM
47 */
48
6b9fa320 49#undef LOCAL_DEBUG
85053fce
MM
50
51#include "nest/bird.h"
52#include "nest/iface.h"
53#include "nest/protocol.h"
586c1800 54#include "lib/hash.h"
85053fce
MM
55#include "lib/resource.h"
56
57#define NEIGH_HASH_SIZE 256
04632fd7 58#define NEIGH_HASH_OFFSET 24
85053fce
MM
59
60static slab *neigh_slab;
586c1800 61static list neigh_hash_table[NEIGH_HASH_SIZE], sticky_neigh_list;
85053fce 62
ae80a2de 63static inline uint
586c1800 64neigh_hash(struct proto *p, ip_addr a, struct iface *i)
85053fce 65{
586c1800 66 return (p->hash_key ^ ipa_hash(a) ^ ptr_hash(i)) >> NEIGH_HASH_OFFSET;
85053fce
MM
67}
68
200accf3 69static int
586c1800 70if_connected(ip_addr a, struct iface *i, struct ifa **ap, uint flags)
85053fce
MM
71{
72 struct ifa *b;
73
586c1800
OZ
74 /* Handle iface pseudo-neighbors */
75 if (flags & NEF_IFACE)
76 return *ap = NULL, (i->flags & IF_UP) ? SCOPE_HOST : -1;
77
78 /* Host addresses match even if iface is down */
79 WALK_LIST(b, i->addrs)
80 if (ipa_equal(a, b->ip))
81 return *ap = b, SCOPE_HOST;
82
83 /* Rest do not match if iface is down */
85053fce 84 if (!(i->flags & IF_UP))
586c1800 85 return *ap = NULL, -1;
2d0b7e24 86
586c1800 87 /* Regular neighbors */
85053fce 88 WALK_LIST(b, i->addrs)
586c1800
OZ
89 {
90 if (b->flags & IA_PEER)
85053fce 91 {
586c1800
OZ
92 if (ipa_equal(a, b->opposite))
93 return *ap = b, b->scope;
94 }
95 else
96 {
97 if (ipa_in_netX(a, &b->prefix))
98 {
99 /* Do not allow IPv4 network and broadcast addresses */
100 if (ipa_is_ip4(a) &&
101 (net_pxlen(&b->prefix) < (IP4_MAX_PREFIX_LENGTH - 1)) &&
102 (ipa_equal(a, net_prefix(&b->prefix)) || /* Network address */
103 ipa_equal(a, b->brd))) /* Broadcast */
104 return *ap = NULL, -1;
105
106 return *ap = b, b->scope;
85053fce 107 }
586c1800
OZ
108 }
109 }
110
111 /* Handle ONLINK flag */
112 if (flags & NEF_ONLINK)
113 return *ap = NULL, ipa_classify(a) & IADDR_SCOPE_MASK;
2d0b7e24 114
586c1800 115 return *ap = NULL, -1;
85053fce
MM
116}
117
586c1800
OZ
118static inline int
119if_connected_any(ip_addr a, struct iface *vrf, struct iface **iface, struct ifa **addr, uint flags)
061ab802 120{
586c1800
OZ
121 struct iface *i;
122 struct ifa *b;
123 int s, scope = -1;
124
125 *iface = NULL;
126 *addr = NULL;
127
128 /* Get first match, but prefer SCOPE_HOST to other matches */
129 WALK_LIST(i, iface_list)
130 if ((!vrf || vrf == i->master) && ((s = if_connected(a, i, &b, flags)) >= 0))
131 if ((scope < 0) || ((scope > SCOPE_HOST) && (s == SCOPE_HOST)))
132 {
133 *iface = i;
134 *addr = b;
135 scope = s;
136 }
be862406 137
586c1800
OZ
138 return scope;
139}
061ab802 140
586c1800
OZ
141/**
142 * neigh_find - find or create a neighbor entry
143 * @p: protocol which asks for the entry
144 * @a: IP address of the node to be searched for
145 * @iface: optionally bound neighbor to this iface (may be NULL)
146 * @flags: %NEF_STICKY for sticky entry, %NEF_ONLINK for onlink entry
147 *
148 * Search the neighbor cache for a node with given IP address. Iface can be
149 * specified for link-local addresses or for cases, where neighbor is expected
150 * on given interface. If it is found, a pointer to the neighbor entry is
151 * returned. If no such entry exists and the node is directly connected on one
152 * of our active interfaces, a new entry is created and returned to the caller
153 * with protocol-dependent fields initialized to zero. If the node is not
154 * connected directly or *@a is not a valid unicast IP address, neigh_find()
155 * returns %NULL.
156 */
061ab802 157neighbor *
586c1800 158neigh_find(struct proto *p, ip_addr a, struct iface *iface, uint flags)
85053fce
MM
159{
160 neighbor *n;
8ecbaf9c 161 int class, scope = -1;
586c1800
OZ
162 uint h = neigh_hash(p, a, iface);
163 struct iface *ifreq = iface;
164 struct ifa *addr = NULL;
85053fce
MM
165
166 WALK_LIST(n, neigh_hash_table[h]) /* Search the cache */
586c1800 167 if ((n->proto == p) && ipa_equal(n->addr, a) && (n->ifreq == iface))
85053fce
MM
168 return n;
169
586c1800
OZ
170 if (flags & NEF_IFACE)
171 {
172 if (ipa_nonzero(a) || !iface)
173 return NULL;
174 }
175 else
176 {
177 class = ipa_classify(a);
178 if (class < 0) /* Invalid address */
179 return NULL;
180 if (((class & IADDR_SCOPE_MASK) == SCOPE_HOST) ||
181 (((class & IADDR_SCOPE_MASK) == SCOPE_LINK) && !iface) ||
182 !(class & IADDR_HOST))
183 return NULL; /* Bad scope or a somecast */
184 }
85053fce 185
586c1800
OZ
186 if ((flags & NEF_ONLINK) && !iface)
187 return NULL;
ff2857b0 188
586c1800
OZ
189 if (iface)
190 {
191 scope = if_connected(a, iface, &addr, flags);
192 iface = (scope < 0) ? NULL : iface;
193 }
be862406 194 else
586c1800 195 scope = if_connected_any(a, p->vrf, &iface, &addr, flags);
be862406 196
ff2857b0 197 /* scope < 0 means i don't know neighbor */
586c1800 198 /* scope >= 0 <=> iface != NULL */
ff2857b0
OZ
199
200 if ((scope < 0) && !(flags & NEF_STICKY))
85053fce
MM
201 return NULL;
202
203 n = sl_alloc(neigh_slab);
5ffb62dd
OZ
204 memset(n, 0, sizeof(neighbor));
205
586c1800
OZ
206 add_tail(&neigh_hash_table[h], &n->n);
207 add_tail((scope >= 0) ? &iface->neighbors : &sticky_neigh_list, &n->if_n);
208 n->addr = a;
2d0b7e24 209 n->ifa = addr;
586c1800
OZ
210 n->iface = iface;
211 n->ifreq = ifreq;
85053fce 212 n->proto = p;
85053fce 213 n->flags = flags;
0f32f2a6 214 n->scope = scope;
5ffb62dd
OZ
215
216 return n;
217}
218
1f495723
MM
219/**
220 * neigh_dump - dump specified neighbor entry.
221 * @n: the entry to dump
222 *
586c1800 223 * This functions dumps the contents of a given neighbor entry to debug output.
1f495723 224 */
85053fce
MM
225void
226neigh_dump(neighbor *n)
227{
586c1800
OZ
228 debug("%p %I %s %s ", n, n->addr,
229 n->iface ? n->iface->name : "[]",
230 n->ifreq ? n->ifreq->name : "[]");
0f32f2a6 231 debug("%s %p %08x scope %s", n->proto->name, n->data, n->aux, ip_scope_text(n->scope));
85053fce
MM
232 if (n->flags & NEF_STICKY)
233 debug(" STICKY");
586c1800
OZ
234 if (n->flags & NEF_ONLINK)
235 debug(" ONLINK");
85053fce
MM
236 debug("\n");
237}
238
1f495723
MM
239/**
240 * neigh_dump_all - dump all neighbor entries.
241 *
586c1800 242 * This function dumps the contents of the neighbor cache to debug output.
1f495723 243 */
85053fce
MM
244void
245neigh_dump_all(void)
246{
247 neighbor *n;
248 int i;
249
250 debug("Known neighbors:\n");
85053fce 251 for(i=0; i<NEIGH_HASH_SIZE; i++)
18c031fa
MM
252 WALK_LIST(n, neigh_hash_table[i])
253 neigh_dump(n);
85053fce
MM
254 debug("\n");
255}
256
586c1800
OZ
257static inline void
258neigh_notify(neighbor *n)
259{
260 if (n->proto->neigh_notify && (n->proto->proto_state != PS_STOP))
261 n->proto->neigh_notify(n);
262}
263
cf7f0645 264static void
586c1800 265neigh_up(neighbor *n, struct iface *i, struct ifa *a, int scope)
cf7f0645 266{
5ffb62dd 267 DBG("Waking up sticky neighbor %I\n", n->addr);
cf7f0645 268 n->iface = i;
2d0b7e24 269 n->ifa = a;
cf7f0645 270 n->scope = scope;
5ffb62dd 271
586c1800
OZ
272 rem_node(&n->if_n);
273 add_tail(&i->neighbors, &n->if_n);
5ffb62dd 274
586c1800 275 neigh_notify(n);
cf7f0645
OZ
276}
277
278static void
279neigh_down(neighbor *n)
280{
f83ce94d 281 DBG("Flushing neighbor %I on %s\n", n->addr, n->iface->name);
586c1800 282 n->iface = NULL;
2d0b7e24 283 n->ifa = NULL;
69a8259c 284 n->scope = -1;
5ffb62dd 285
586c1800
OZ
286 rem_node(&n->if_n);
287 add_tail(&sticky_neigh_list, &n->if_n);
5ffb62dd 288
586c1800
OZ
289 neigh_notify(n);
290}
5ffb62dd 291
586c1800
OZ
292static inline void
293neigh_free(neighbor *n)
294{
295 rem_node(&n->n);
296 rem_node(&n->if_n);
297 sl_free(neigh_slab, n);
298}
299
300/**
301 * neigh_update: update neighbor entry w.r.t. change on specific iface
302 * @n: neighbor to update
303 * @iface: changed iface
304 *
305 * The function recalculates state of the neighbor entry @n assuming that only
306 * the interface @iface may changed its state or addresses. Then, appropriate
307 * actions are executed (the neighbor goes up, down, up-down, or just notified).
308 */
309void
310neigh_update(neighbor *n, struct iface *iface)
311{
312 struct ifa *ifa = NULL;
313 int scope = -1;
314
315 /* Iface-bound neighbors ignore other ifaces */
316 if (n->ifreq && (n->ifreq != iface))
317 return;
318
319 /* VRF-bound neighbors ignore changes in other VRFs */
320 if (n->proto->vrf && (n->proto->vrf != iface->master))
321 return;
322
323 scope = if_connected(n->addr, iface, &ifa, n->flags);
324
325 /* When neighbor is going down, try to respawn it on other ifaces */
326 if ((scope < 0) && (n->scope >= 0) && !n->ifreq && (n->flags & NEF_STICKY))
327 scope = if_connected_any(n->addr, n->proto->vrf, &iface, &ifa, n->flags);
328
329 /* No change or minor change - ignore or notify */
330 if ((scope == n->scope) && (iface == n->iface))
331 {
332 if (ifa != n->ifa)
8ecbaf9c 333 {
586c1800
OZ
334 n->ifa = ifa;
335 neigh_notify(n);
8ecbaf9c 336 }
5ffb62dd 337
586c1800
OZ
338 return;
339 }
340
341 /* Major change - going down and/or going up */
342
343 if (n->scope >= 0)
344 neigh_down(n);
345
346 if ((n->scope < 0) && !(n->flags & NEF_STICKY))
347 {
348 neigh_free(n);
349 return;
350 }
351
352 if (scope >= 0)
353 neigh_up(n, iface, ifa, scope);
cf7f0645
OZ
354}
355
356
1f495723
MM
357/**
358 * neigh_if_up: notify neighbor cache about interface up event
359 * @i: interface in question
360 *
361 * Tell the neighbor cache that a new interface became up.
362 *
363 * The neighbor cache wakes up all inactive sticky neighbors with
364 * addresses belonging to prefixes of the interface @i.
365 */
85053fce
MM
366void
367neigh_if_up(struct iface *i)
368{
5ffb62dd
OZ
369 neighbor *n;
370 node *x, *y;
85053fce 371
586c1800
OZ
372 WALK_LIST2_DELSAFE(n, x, y, sticky_neigh_list, if_n)
373 neigh_update(n, i);
85053fce
MM
374}
375
1f495723
MM
376/**
377 * neigh_if_down - notify neighbor cache about interface down event
378 * @i: the interface in question
379 *
380 * Notify the neighbor cache that an interface has ceased to exist.
381 *
586c1800 382 * It causes all neighbors connected to this interface to be updated or removed.
1f495723 383 */
85053fce
MM
384void
385neigh_if_down(struct iface *i)
386{
5ffb62dd 387 neighbor *n;
85053fce
MM
388 node *x, *y;
389
5ffb62dd 390 WALK_LIST2_DELSAFE(n, x, y, i->neighbors, if_n)
586c1800 391 neigh_update(n, i);
85053fce
MM
392}
393
fe181e7c
OZ
394/**
395 * neigh_if_link - notify neighbor cache about interface link change
396 * @i: the interface in question
397 *
586c1800
OZ
398 * Notify the neighbor cache that an interface changed link state. All owners of
399 * neighbor entries connected to this interface are notified.
fe181e7c 400 */
fe181e7c
OZ
401void
402neigh_if_link(struct iface *i)
403{
5ffb62dd 404 neighbor *n;
fe181e7c
OZ
405 node *x, *y;
406
5ffb62dd 407 WALK_LIST2_DELSAFE(n, x, y, i->neighbors, if_n)
586c1800 408 neigh_notify(n);
fe181e7c
OZ
409}
410
cf7f0645
OZ
411/**
412 * neigh_ifa_update: notify neighbor cache about interface address add or remove event
8e433d6a 413 * @a: interface address in question
cf7f0645
OZ
414 *
415 * Tell the neighbor cache that an address was added or removed.
416 *
417 * The neighbor cache wakes up all inactive sticky neighbors with
418 * addresses belonging to prefixes of the interface belonging to @ifa
419 * and causes all unreachable neighbors to be flushed.
420 */
421void
422neigh_ifa_update(struct ifa *a)
423{
424 struct iface *i = a->iface;
5ffb62dd 425 neighbor *n;
586c1800 426 node *x, *y;
5ffb62dd 427
586c1800 428 /* Update all neighbors whose scope has changed */
5ffb62dd 429 WALK_LIST2_DELSAFE(n, x, y, i->neighbors, if_n)
586c1800 430 neigh_update(n, i);
cf7f0645
OZ
431
432 /* Wake up all sticky neighbors that are reachable now */
586c1800
OZ
433 WALK_LIST2_DELSAFE(n, x, y, sticky_neigh_list, if_n)
434 neigh_update(n, i);
cf7f0645
OZ
435}
436
18c031fa
MM
437static inline void
438neigh_prune_one(neighbor *n)
439{
d6a836f8 440 if (n->proto->proto_state != PS_DOWN)
18c031fa 441 return;
586c1800
OZ
442
443 neigh_free(n);
18c031fa
MM
444}
445
1f495723
MM
446/**
447 * neigh_prune - prune neighbor cache
448 *
449 * neigh_prune() examines all neighbor entries cached and removes those
450 * corresponding to inactive protocols. It's called whenever a protocol
451 * is shut down to get rid of all its heritage.
452 */
85053fce
MM
453void
454neigh_prune(void)
455{
456 neighbor *n;
457 node *m;
458 int i;
459
460 DBG("Pruning neighbors\n");
461 for(i=0; i<NEIGH_HASH_SIZE; i++)
462 WALK_LIST_DELSAFE(n, m, neigh_hash_table[i])
18c031fa 463 neigh_prune_one(n);
85053fce
MM
464}
465
1f495723
MM
466/**
467 * neigh_init - initialize the neighbor cache.
468 * @if_pool: resource pool to be used for neighbor entries.
469 *
470 * This function is called during BIRD startup to initialize
471 * the neighbor cache module.
472 */
85053fce
MM
473void
474neigh_init(pool *if_pool)
475{
85053fce 476 neigh_slab = sl_new(if_pool, sizeof(neighbor));
5ffb62dd 477
5ffb62dd 478 for(int i = 0; i < NEIGH_HASH_SIZE; i++)
85053fce 479 init_list(&neigh_hash_table[i]);
586c1800
OZ
480
481 init_list(&sticky_neigh_list);
85053fce 482}