summaryrefslogtreecommitdiffstats
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/proto-hooks.c3
-rw-r--r--nest/proto.c5
-rw-r--r--nest/protocol.h11
-rw-r--r--nest/rt-table.c24
4 files changed, 22 insertions, 21 deletions
diff --git a/nest/proto-hooks.c b/nest/proto-hooks.c
index c30b107..3d19e3f 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 a7e4e0c..57c2aa1 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 876427a..82f3766 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 c9e421e..72a1cb0 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)