summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lists.h2
-rw-r--r--proto/babel/babel.c30
-rw-r--r--proto/babel/babel.h3
3 files changed, 22 insertions, 13 deletions
diff --git a/lib/lists.h b/lib/lists.h
index 066eafbb..479f4ed1 100644
--- a/lib/lists.h
+++ b/lib/lists.h
@@ -59,6 +59,8 @@ typedef union list { /* In fact two overlayed nodes */
/* WALK_LIST_FIRST supposes that called code removes each processed node */
#define WALK_LIST_FIRST(n,list) \
while(n=HEAD(list), (NODE (n))->next)
+#define WALK_LIST_FIRST2(n,pos,list) \
+ while(n=SKIP_BACK(typeof(*n),pos,HEAD(list)), (n)->pos.next)
#define WALK_LIST_BACKWARDS(n,list) for(n=TAIL(list);(NODE (n))->prev; \
n=(void *)((NODE (n))->prev))
#define WALK_LIST_BACKWARDS_DELSAFE(n,prv,list) \
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 25d8e330..fdebc352 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -56,13 +56,6 @@ static void babel_update_cost(struct babel_neighbor *n);
static inline void babel_kick_timer(struct babel_proto *p);
static inline void babel_iface_kick_timer(struct babel_iface *ifa);
-static inline void babel_lock_neighbor(struct babel_neighbor *nbr)
-{ if (nbr) nbr->uc++; }
-
-static inline void babel_unlock_neighbor(struct babel_neighbor *nbr)
-{ if (nbr && !--nbr->uc) mb_free(nbr); }
-
-
/*
* Functions to maintain data structures
*/
@@ -316,8 +309,9 @@ babel_add_seqno_request(struct babel_proto *p, struct babel_entry *e,
return;
/* Found older */
- babel_unlock_neighbor(sr->nbr);
rem_node(NODE sr);
+ rem_node(&sr->nbr_node);
+
goto found;
}
@@ -330,7 +324,10 @@ found:
sr->hop_count = hop_count;
sr->count = 0;
sr->expires = current_time() + BABEL_SEQNO_REQUEST_EXPIRY;
- babel_lock_neighbor(sr->nbr = nbr);
+
+ if (sr->nbr = nbr)
+ add_tail(&nbr->requests, &sr->nbr_node);
+
add_tail(&e->requests, NODE sr);
babel_send_seqno_request(p, e, sr);
@@ -339,7 +336,9 @@ found:
static void
babel_remove_seqno_request(struct babel_proto *p, struct babel_seqno_request *sr)
{
- babel_unlock_neighbor(sr->nbr);
+ if (sr->nbr)
+ rem_node(&sr->nbr_node);
+
rem_node(NODE sr);
sl_free(p->seqno_slab, sr);
}
@@ -427,7 +426,7 @@ babel_get_neighbor(struct babel_iface *ifa, ip_addr addr)
nbr->txcost = BABEL_INFINITY;
nbr->cost = BABEL_INFINITY;
init_list(&nbr->routes);
- babel_lock_neighbor(nbr);
+ init_list(&nbr->requests);
add_tail(&ifa->neigh_list, NODE nbr);
return nbr;
@@ -448,9 +447,16 @@ babel_flush_neighbor(struct babel_proto *p, struct babel_neighbor *nbr)
babel_flush_route(p, r);
}
+ struct babel_seqno_request *sr;
+ WALK_LIST_FIRST2(sr, nbr_node, nbr->requests)
+ {
+ sr->nbr = NULL;
+ rem_node(&sr->nbr_node);
+ }
+
nbr->ifa = NULL;
rem_node(NODE nbr);
- babel_unlock_neighbor(nbr);
+ mb_free(nbr);
}
static void
diff --git a/proto/babel/babel.h b/proto/babel/babel.h
index e075024c..09bf530c 100644
--- a/proto/babel/babel.h
+++ b/proto/babel/babel.h
@@ -198,7 +198,6 @@ struct babel_neighbor {
struct babel_iface *ifa;
ip_addr addr;
- uint uc; /* Reference counter for seqno requests */
u16 rxcost; /* Sent in last IHU */
u16 txcost; /* Received in last IHU */
u16 cost; /* Computed neighbor cost */
@@ -212,6 +211,7 @@ struct babel_neighbor {
btime ihu_expiry;
list routes; /* Routes this neighbour has sent us (struct babel_route) */
+ list requests; /* Seqno requests bound to this neighbor */
};
struct babel_source {
@@ -241,6 +241,7 @@ struct babel_route {
struct babel_seqno_request {
node n;
+ node nbr_node;
u64 router_id;
u16 seqno;
u8 hop_count;