diff options
Diffstat (limited to 'nest')
-rw-r--r-- | nest/proto-hooks.c | 3 | ||||
-rw-r--r-- | nest/proto.c | 5 | ||||
-rw-r--r-- | nest/protocol.h | 11 | ||||
-rw-r--r-- | nest/rt-table.c | 24 |
4 files changed, 22 insertions, 21 deletions
diff --git a/nest/proto-hooks.c b/nest/proto-hooks.c index c30b1070..3d19e3fe 100644 --- a/nest/proto-hooks.c +++ b/nest/proto-hooks.c @@ -178,13 +178,14 @@ void ifa_notify(struct proto *p, unsigned flags, struct ifa *a) /** * rt_notify - notify instance about routing table change * @p: protocol instance + * @table: a routing table * @net: a network entry * @new: new route for the network * @old: old route for the network * @attrs: extended attributes associated with the @new entry * * The rt_notify() hook is called to inform the protocol instance about - * changes in the routing table it's connected to, that is a route @old + * changes in the connected routing table @table, that is a route @old * belonging to network @net being replaced by a new route @new with * extended attributes @attrs. Either @new or @old or both can be %NULL * if the corresponding route doesn't exist. diff --git a/nest/proto.c b/nest/proto.c index a7e4e0c9..57c2aa13 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -133,11 +133,6 @@ 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 } /** diff --git a/nest/protocol.h b/nest/protocol.h index 876427ab..82f3766f 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -16,6 +16,7 @@ struct iface; struct ifa; +struct rtable; struct rte; struct neighbor; struct rta; @@ -162,7 +163,7 @@ struct proto { void (*if_notify)(struct proto *, unsigned flags, struct iface *i); void (*ifa_notify)(struct proto *, unsigned flags, struct ifa *a); - void (*rt_notify)(struct proto *, struct network *net, struct rte *new, struct rte *old, struct ea_list *attrs); + void (*rt_notify)(struct proto *, struct rtable *table, struct network *net, struct rte *new, struct rte *old, struct ea_list *attrs); void (*neigh_notify)(struct neighbor *neigh); struct ea_list *(*make_tmp_attrs)(struct rte *rt, struct linpool *pool); void (*store_tmp_attrs)(struct rte *rt, struct ea_list *attrs); @@ -339,13 +340,7 @@ struct announce_hook *proto_add_announce_hook(struct proto *, struct rtable *); */ #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); -struct proto_stats *pipe_get_peer_stats(struct proto *p); - +#include "proto/pipe/pipe.h" #endif diff --git a/nest/rt-table.c b/nest/rt-table.c index c9e421e9..72a1cb0e 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -161,6 +161,7 @@ static inline void do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, ea_list *tmpa, int class, int refeed) { struct proto *p = a->proto; + struct filter *filter = p->out_filter; struct proto_stats *stats = &p->stats; rte *new0 = new; rte *old0 = old; @@ -168,6 +169,15 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, int fast_exit_hack = 0; +#ifdef CONFIG_PIPE + /* The secondary direction of the pipe */ + if (proto_is_pipe(p) && (p->table != a->table)) + { + filter = p->in_filter; + stats = pipe_get_peer_stats(p); + } +#endif + if (new) { stats->exp_updates_received++; @@ -186,8 +196,8 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, } else if (ok) rte_trace_out(D_FILTERS, p, new, "forced accept by protocol"); - else if (p->out_filter == FILTER_REJECT || - p->out_filter && f_run(p->out_filter, &new, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT) + else if (filter == FILTER_REJECT || + filter && f_run(filter, &new, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT) { stats->exp_updates_filtered++; drop_reason = "filtered out"; @@ -230,13 +240,13 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, if (old && !refeed) { - if (p->out_filter == FILTER_REJECT) + if (filter == FILTER_REJECT) old = NULL; else { ea_list *tmpb = p->make_tmp_attrs ? p->make_tmp_attrs(old, rte_update_pool) : NULL; ok = p->import_control ? p->import_control(p, &old, &tmpb, rte_update_pool) : 0; - if (ok < 0 || (!ok && p->out_filter && f_run(p->out_filter, &old, &tmpb, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)) + if (ok < 0 || (!ok && filter && f_run(filter, &old, &tmpb, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT)) { if (old != old0) rte_free(old); @@ -271,18 +281,18 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old, rte_trace_out(D_ROUTES, p, old, "removed"); } if (!new) - p->rt_notify(p, net, NULL, old, NULL); + p->rt_notify(p, a->table, net, NULL, old, NULL); else if (tmpa) { ea_list *t = tmpa; while (t->next) t = t->next; t->next = new->attrs->eattrs; - p->rt_notify(p, net, new, old, tmpa); + p->rt_notify(p, a->table, net, new, old, tmpa); t->next = NULL; } else - p->rt_notify(p, net, new, old, new->attrs->eattrs); + p->rt_notify(p, a->table, net, new, old, new->attrs->eattrs); if (new && new != new0) /* Discard temporary rte's */ rte_free(new); if (old && old != old0) |