diff options
-rw-r--r-- | nest/Doc | 9 | ||||
-rw-r--r-- | nest/locks.c | 47 | ||||
-rw-r--r-- | nest/neighbor.c | 91 |
3 files changed, 147 insertions, 0 deletions
@@ -1 +1,10 @@ H Core +S neighbor.c +#S cli.c +#S iface.c +S locks.c +#S proto.c +#S rt-attr.c +#S rt-dev.c +S rt-fib.c +#S rt-table.c diff --git a/nest/locks.c b/nest/locks.c index 19a5df0..c1f7331 100644 --- a/nest/locks.c +++ b/nest/locks.c @@ -6,6 +6,28 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ +/** + * DOC: Object locks + * + * The lock module provides a simple mechanism for avoiding conflicts between + * various protocols which would like to use a single physical resource (for + * example a network port). It would be easy to say that such collisions can + * occur only when the user specifies an invalid configuration and therefore + * he deserves to get what he has asked for, but unfortunately they can also + * arise legitimately when the daemon is reconfigured and there exists (although + * for a short time period only) an old protocol being shut down and a new one + * willing to start up on the same interface. + * + * The solution is very simple: when any protocol wishes to use a network port + * or some other non-shareable resource, it asks the core to lock it and doesn't + * use the resource until it's notified that it has acquired the lock. + * + * Object locks are represented by &object_lock which is in turn a kind of + * resource. Lockable resources are uniquely determined by resource type + * (%OBJLOCK_UDP for a UDP port etc.), IP address (usually a broadcast or + * multicast address the port is bound to), port number and interface. + */ + #undef LOCAL_DEBUG #include "nest/bird.h" @@ -78,6 +100,14 @@ static struct resclass olock_class = { olock_dump }; +/** + * olock_new - create an object lock + * @p: resource pool to create the lock in. + * + * The olock_new() function creates a new resource of type &object_lock + * and returns a pointer to it. After filling in the structure, the caller + * should call olock_acquire() to do the real locking. + */ struct object_lock * olock_new(pool *p) { @@ -88,6 +118,17 @@ olock_new(pool *p) return l; } +/** + * olock_acquire - acquire a lock + * @l: the lock to acquire + * + * This function attempts to acquire exclusive access to the non-shareable + * resource described by the lock @l. It returns immediately, but as soon + * as the resource becomes available, it calls the hook() function set up + * by the caller. + * + * When you want to release the resource, just rfree() the lock. + */ void olock_acquire(struct object_lock *l) { @@ -134,6 +175,12 @@ olock_run_event(void *unused) } } +/** + * olock_init - initialize the object lock mechanism + * + * This function is called during BIRD startup. It initializes + * all the internal data structures of the lock module. + */ void olock_init(void) { diff --git a/nest/neighbor.c b/nest/neighbor.c index 0c7a4ae..89c19ba 100644 --- a/nest/neighbor.c +++ b/nest/neighbor.c @@ -6,6 +6,37 @@ * Can be freely distributed and used under the terms of the GNU GPL. */ +/** + * DOC: Neighbor cache + * + * Most routing protocols need to associate their internal state data with + * neighboring routers, check whether an address given as the next hop + * attribute of a route is really an address of a directly connected host + * and which interface is it connected through. Also, they often need to + * be notified when a neighbor ceases to exist or when their long awaited + * neighbor becomes connected. The neighbor cache is there to solve all + * these problems. + * + * The neighbor cache maintains a collection of neighbor entries. Each + * entry represents one IP address corresponding to either our directly + * connected neighbor or our own end of the link (when the scope of the + * address is set to %SCOPE_HOST) together with data belonging to a + * single protocol. + * + * Active entries represent known neighbors and are stored in a hash + * table (to allow fast retrieval based on IP address of the node) and + * two linked lists: one global and one per-interface (allowing quick + * processing of interface change events). Inactive entries exist only + * when the protocol has explicitly requested it via the %NEF_STICKY + * flag because it wishes to be notified when the node will again become + * a neighbor. Such entries are enqueued in a special list which is walked + * whenever an interface becomes up. + * + * When a neighbor event occurs (a neighbor gets disconnected or a sticky + * inactive neighbor becomes connected), the protocol hook neigh_notify() + * is called to advertise the change. + */ + #undef LOCAL_DEBUG #include "nest/bird.h" @@ -54,6 +85,21 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */ return -1; } +/** + * neigh_find - find or create a neighbor entry. + * @p: protocol which asks for the entry. + * @a: pointer to IP address of the node to be searched for. + * @flags: 0 or %NEF_STICKY if you want to create a sticky entry. + * + * Search the neighbor cache for a node with given IP address. If + * it's found, a pointer to the neighbor entry is returned. If no + * such entry exists and the node is directly connected on + * one of our active interfaces, a new entry is created and returned + * to the caller with protocol-dependent fields initialized to zero. + * If the node is not connected directly or *@a is not a valid unicast + * IP address, neigh_find() returns %NULL. + */ + neighbor * neigh_find(struct proto *p, ip_addr *a, unsigned flags) { @@ -104,6 +150,13 @@ neigh_find(struct proto *p, ip_addr *a, unsigned flags) return n; } +/** + * neigh_dump - dump specified neighbor entry. + * @n: the entry to dump + * + * This functions dumps the contents of a given neighbor entry + * to debug output. + */ void neigh_dump(neighbor *n) { @@ -118,6 +171,12 @@ neigh_dump(neighbor *n) debug("\n"); } +/** + * neigh_dump_all - dump all neighbor entries. + * + * This function dumps the contents of the neighbor cache to + * debug output. + */ void neigh_dump_all(void) { @@ -133,6 +192,15 @@ neigh_dump_all(void) debug("\n"); } +/** + * neigh_if_up: notify neighbor cache about interface up event + * @i: interface in question + * + * Tell the neighbor cache that a new interface became up. + * + * The neighbor cache wakes up all inactive sticky neighbors with + * addresses belonging to prefixes of the interface @i. + */ void neigh_if_up(struct iface *i) { @@ -153,6 +221,15 @@ neigh_if_up(struct iface *i) } } +/** + * neigh_if_down - notify neighbor cache about interface down event + * @i: the interface in question + * + * Notify the neighbor cache that an interface has ceased to exist. + * + * It causes all entries belonging to neighbors connected to this interface + * to be flushed. + */ void neigh_if_down(struct iface *i) { @@ -185,6 +262,13 @@ neigh_prune_one(neighbor *n) sl_free(neigh_slab, n); } +/** + * neigh_prune - prune neighbor cache + * + * neigh_prune() examines all neighbor entries cached and removes those + * corresponding to inactive protocols. It's called whenever a protocol + * is shut down to get rid of all its heritage. + */ void neigh_prune(void) { @@ -200,6 +284,13 @@ neigh_prune(void) neigh_prune_one(n); } +/** + * neigh_init - initialize the neighbor cache. + * @if_pool: resource pool to be used for neighbor entries. + * + * This function is called during BIRD startup to initialize + * the neighbor cache module. + */ void neigh_init(pool *if_pool) { |