From c83876265eeae3591bfe90375503728e633cb807 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Thu, 11 Feb 2010 22:27:06 +0100 Subject: Fixes a tricky bug in the pipe protocol. When uncofiguring the pipe and the peer table, the peer table was unlocked when pipe protocol state changed to down/flushing and not to down/hungry. This leads to the removal of the peer table before the routes from the pipe were flushed. The fix leads to adding some pipe-specific hacks to the nest, but this seems inevitable. --- nest/proto.c | 11 +++++++++++ nest/protocol.h | 14 ++++++++++++++ nest/rt-table.c | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'nest') diff --git a/nest/proto.c b/nest/proto.c index 870eddd..c6b7e63 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -133,6 +133,11 @@ proto_init_instance(struct proto *p) p->attn = ev_new(p->pool); p->attn->data = p; rt_lock_table(p->table); + +#ifdef CONFIG_PIPE + if (proto_is_pipe(p)) + rt_lock_table(pipe_get_peer_table(p)); +#endif } /** @@ -583,6 +588,12 @@ proto_fell_down(struct proto *p) bzero(&p->stats, sizeof(struct proto_stats)); rt_unlock_table(p->table); + +#ifdef CONFIG_PIPE + if (proto_is_pipe(p)) + rt_unlock_table(pipe_get_peer_table(p)); +#endif + proto_rethink_goal(p); } diff --git a/nest/protocol.h b/nest/protocol.h index 5a69b33..99d8dc8 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -334,4 +334,18 @@ struct announce_hook { struct announce_hook *proto_add_announce_hook(struct proto *, struct rtable *); +/* + * Some pipe-specific nest hacks + */ + +#ifdef CONFIG_PIPE + +static inline int proto_is_pipe(struct proto *p) +{ return p->proto == &proto_pipe; } + +struct rtable *pipe_get_peer_table(struct proto *p); + +#endif + + #endif diff --git a/nest/rt-table.c b/nest/rt-table.c index 413675c..fee5718 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -642,7 +642,7 @@ rte_update(rtable *table, net *net, struct proto *p, struct proto *src, rte *new /* Do not filter routes going through the pipe, they are filtered in the export filter only. */ #ifdef CONFIG_PIPE - if (p->proto == &proto_pipe) + if (proto_is_pipe(p)) filter = FILTER_ACCEPT; #endif -- cgit v1.2.3