]>
git.ipfire.org Git - thirdparty/bird.git/blob - nest/neighbor.c
2 * BIRD -- Neighbor Cache
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
12 * Most routing protocols need to associate their internal state data with
13 * neighboring routers, check whether an address given as the next hop
14 * attribute of a route is really an address of a directly connected host
15 * and which interface is it connected through. Also, they often need to
16 * be notified when a neighbor ceases to exist or when their long awaited
17 * neighbor becomes connected. The neighbor cache is there to solve all
20 * The neighbor cache maintains a collection of neighbor entries. Each
21 * entry represents one IP address corresponding to either our directly
22 * connected neighbor or our own end of the link (when the scope of the
23 * address is set to %SCOPE_HOST) together with per-neighbor data belonging to a
26 * Active entries represent known neighbors and are stored in a hash
27 * table (to allow fast retrieval based on the IP address of the node) and
28 * two linked lists: one global and one per-interface (allowing quick
29 * processing of interface change events). Inactive entries exist only
30 * when the protocol has explicitly requested it via the %NEF_STICKY
31 * flag because it wishes to be notified when the node will again become
32 * a neighbor. Such entries are enqueued in a special list which is walked
33 * whenever an interface changes its state to up. Neighbor entry VRF
34 * association is implied by respective protocol.
36 * When a neighbor event occurs (a neighbor gets disconnected or a sticky
37 * inactive neighbor becomes connected), the protocol hook neigh_notify()
38 * is called to advertise the change.
43 #include "nest/bird.h"
44 #include "nest/iface.h"
45 #include "nest/protocol.h"
46 #include "lib/resource.h"
48 #define NEIGH_HASH_SIZE 256
50 static slab
*neigh_slab
;
51 static list sticky_neigh_list
, neigh_hash_table
[NEIGH_HASH_SIZE
];
54 neigh_hash(struct proto
*p
, ip_addr
*a
)
56 return (p
->hash_key
^ ipa_hash(*a
)) & (NEIGH_HASH_SIZE
-1);
60 if_connected(ip_addr
*a
, struct iface
*i
, struct ifa
**ap
)
64 if (!(i
->flags
& IF_UP
))
70 WALK_LIST(b
, i
->addrs
)
74 if (ipa_equal(*a
, b
->ip
))
76 if (b
->flags
& IA_PEER
)
78 if (ipa_equal(*a
, b
->opposite
))
83 if (ipa_in_net(*a
, b
->prefix
, b
->pxlen
))
86 if ((b
->pxlen
< (BITS_PER_IP_ADDRESS
- 1)) &&
87 (ipa_equal(*a
, b
->prefix
) || /* Network address */
88 ipa_equal(*a
, b
->brd
))) /* Broadcast */
105 * neigh_find - find or create a neighbor entry.
106 * @p: protocol which asks for the entry.
107 * @a: pointer to IP address of the node to be searched for.
108 * @flags: 0 or %NEF_STICKY if you want to create a sticky entry.
110 * Search the neighbor cache for a node with given IP address. If
111 * it's found, a pointer to the neighbor entry is returned. If no
112 * such entry exists and the node is directly connected on
113 * one of our active interfaces, a new entry is created and returned
114 * to the caller with protocol-dependent fields initialized to zero.
115 * If the node is not connected directly or *@a is not a valid unicast
116 * IP address, neigh_find() returns %NULL.
119 neigh_find(struct proto
*p
, ip_addr
*a
, unsigned flags
)
121 return neigh_find2(p
, a
, NULL
, flags
);
126 neigh_find2(struct proto
*p
, ip_addr
*a
, struct iface
*ifa
, unsigned flags
)
129 int class, scope
= -1;
130 uint h
= neigh_hash(p
, a
);
134 WALK_LIST(n
, neigh_hash_table
[h
]) /* Search the cache */
135 if (n
->proto
== p
&& ipa_equal(*a
, n
->addr
) && (!ifa
|| (ifa
== n
->iface
)))
138 class = ipa_classify(*a
);
139 if (class < 0) /* Invalid address */
141 if (((class & IADDR_SCOPE_MASK
) == SCOPE_HOST
) ||
142 (((class & IADDR_SCOPE_MASK
) == SCOPE_LINK
) && (ifa
== NULL
)) ||
143 !(class & IADDR_HOST
))
144 return NULL
; /* Bad scope or a somecast */
148 scope
= if_connected(a
, ifa
, &addr
);
151 if ((scope
< 0) && (flags
& NEF_ONLINK
))
152 scope
= class & IADDR_SCOPE_MASK
;
155 WALK_LIST(i
, iface_list
)
156 if ((!p
->vrf
|| p
->vrf
== i
->master
) &&
157 ((scope
= if_connected(a
, i
, &addr
)) >= 0))
163 /* scope < 0 means i don't know neighbor */
164 /* scope >= 0 implies ifa != NULL */
166 if ((scope
< 0) && !(flags
& NEF_STICKY
))
169 n
= sl_alloc(neigh_slab
);
173 add_tail(&neigh_hash_table
[h
], &n
->n
);
174 add_tail(&ifa
->neighbors
, &n
->if_n
);
178 add_tail(&sticky_neigh_list
, &n
->n
);
192 * neigh_dump - dump specified neighbor entry.
193 * @n: the entry to dump
195 * This functions dumps the contents of a given neighbor entry
199 neigh_dump(neighbor
*n
)
201 debug("%p %I ", n
, n
->addr
);
203 debug("%s ", n
->iface
->name
);
206 debug("%s %p %08x scope %s", n
->proto
->name
, n
->data
, n
->aux
, ip_scope_text(n
->scope
));
207 if (n
->flags
& NEF_STICKY
)
213 * neigh_dump_all - dump all neighbor entries.
215 * This function dumps the contents of the neighbor cache to
224 debug("Known neighbors:\n");
225 WALK_LIST(n
, sticky_neigh_list
)
227 for(i
=0; i
<NEIGH_HASH_SIZE
; i
++)
228 WALK_LIST(n
, neigh_hash_table
[i
])
234 neigh_up(neighbor
*n
, struct iface
*i
, int scope
, struct ifa
*a
)
239 add_tail(&i
->neighbors
, &n
->if_n
);
241 add_tail(&neigh_hash_table
[neigh_hash(n
->proto
, &n
->addr
)], &n
->n
);
242 DBG("Waking up sticky neighbor %I\n", n
->addr
);
243 if (n
->proto
->neigh_notify
&& n
->proto
->core_state
!= FS_FLUSHING
)
244 n
->proto
->neigh_notify(n
);
248 neigh_down(neighbor
*n
)
250 DBG("Flushing neighbor %I on %s\n", n
->addr
, n
->iface
->name
);
252 if (! (n
->flags
& NEF_BIND
))
256 if (n
->proto
->neigh_notify
&& n
->proto
->core_state
!= FS_FLUSHING
)
257 n
->proto
->neigh_notify(n
);
259 if (n
->flags
& NEF_STICKY
)
261 add_tail(&sticky_neigh_list
, &n
->n
);
263 /* Respawn neighbor if there is another matching prefix */
269 WALK_LIST(i
, iface_list
)
270 if ((scope
= if_connected(&n
->addr
, i
, &a
)) >= 0)
272 neigh_up(n
, i
, scope
, a
);
277 sl_free(neigh_slab
, n
);
282 * neigh_if_up: notify neighbor cache about interface up event
283 * @i: interface in question
285 * Tell the neighbor cache that a new interface became up.
287 * The neighbor cache wakes up all inactive sticky neighbors with
288 * addresses belonging to prefixes of the interface @i.
291 neigh_if_up(struct iface
*i
)
297 WALK_LIST_DELSAFE(n
, next
, sticky_neigh_list
)
298 if ((!n
->iface
|| n
->iface
== i
) &&
299 ((scope
= if_connected(&n
->addr
, i
, &a
)) >= 0))
300 neigh_up(n
, i
, scope
, a
);
304 * neigh_if_down - notify neighbor cache about interface down event
305 * @i: the interface in question
307 * Notify the neighbor cache that an interface has ceased to exist.
309 * It causes all entries belonging to neighbors connected to this interface
313 neigh_if_down(struct iface
*i
)
317 WALK_LIST_DELSAFE(x
, y
, i
->neighbors
)
318 neigh_down(SKIP_BACK(neighbor
, if_n
, x
));
322 * neigh_if_link - notify neighbor cache about interface link change
323 * @i: the interface in question
325 * Notify the neighbor cache that an interface changed link state.
326 * All owners of neighbor entries connected to this interface are
330 neigh_if_link(struct iface
*i
)
334 WALK_LIST_DELSAFE(x
, y
, i
->neighbors
)
336 neighbor
*n
= SKIP_BACK(neighbor
, if_n
, x
);
337 if (n
->proto
->neigh_notify
&& n
->proto
->core_state
!= FS_FLUSHING
)
338 n
->proto
->neigh_notify(n
);
343 * neigh_ifa_update: notify neighbor cache about interface address add or remove event
344 * @a: interface address in question
346 * Tell the neighbor cache that an address was added or removed.
348 * The neighbor cache wakes up all inactive sticky neighbors with
349 * addresses belonging to prefixes of the interface belonging to @ifa
350 * and causes all unreachable neighbors to be flushed.
353 neigh_ifa_update(struct ifa
*a
)
355 struct iface
*i
= a
->iface
;
358 /* Remove all neighbors whose scope has changed */
359 WALK_LIST_DELSAFE(x
, y
, i
->neighbors
)
362 neighbor
*n
= SKIP_BACK(neighbor
, if_n
, x
);
363 if (if_connected(&n
->addr
, i
, &aa
) != n
->scope
)
367 /* Wake up all sticky neighbors that are reachable now */
372 neigh_prune_one(neighbor
*n
)
374 if (n
->proto
->proto_state
!= PS_DOWN
)
379 sl_free(neigh_slab
, n
);
383 * neigh_prune - prune neighbor cache
385 * neigh_prune() examines all neighbor entries cached and removes those
386 * corresponding to inactive protocols. It's called whenever a protocol
387 * is shut down to get rid of all its heritage.
396 DBG("Pruning neighbors\n");
397 for(i
=0; i
<NEIGH_HASH_SIZE
; i
++)
398 WALK_LIST_DELSAFE(n
, m
, neigh_hash_table
[i
])
400 WALK_LIST_DELSAFE(n
, m
, sticky_neigh_list
)
405 * neigh_init - initialize the neighbor cache.
406 * @if_pool: resource pool to be used for neighbor entries.
408 * This function is called during BIRD startup to initialize
409 * the neighbor cache module.
412 neigh_init(pool
*if_pool
)
416 neigh_slab
= sl_new(if_pool
, sizeof(neighbor
));
417 init_list(&sticky_neigh_list
);
418 for(i
=0; i
<NEIGH_HASH_SIZE
; i
++)
419 init_list(&neigh_hash_table
[i
]);