The pipe cleanup.

This commit is contained in:
Ondrej Zajicek 2009-06-01 14:07:13 +02:00
parent 2d45e09f58
commit f98e291579
11 changed files with 69 additions and 36 deletions

View file

@ -1446,10 +1446,23 @@ and vice versa, depending on what's allowed by the filters. Export filters contr
of routes from the primary table to the secondary one, import filters control the opposite of routes from the primary table to the secondary one, import filters control the opposite
direction. direction.
<p>The Pipe protocol may work in the opaque mode or in the transparent
mode. In the opaque mode, thee Pipe protocol retransmits optimal route
from one table to the other table in a similar way like other
protocols send and receive routes. Retransmitted route will have the
source set to the Pipe protocol, which may limit access to protocol
specific route attributes. The opaque mode is a default mode.
<p>In transparent mode, the Pipe protocol retransmits all routes from
one table to the other table, retaining their original source and
attributes. If import and export filters are set to accept, then both
tables would have the same content. The mode can be set by
<tt/mode/ option.
<p>The primary use of multiple routing tables and the Pipe protocol is for policy routing, <p>The primary use of multiple routing tables and the Pipe protocol is for policy routing,
where handling of a single packet doesn't depend only on its destination address, but also where handling of a single packet doesn't depend only on its destination address, but also
on its source address, source interface, protocol type and other similar parameters. on its source address, source interface, protocol type and other similar parameters.
In many systems (Linux 2.2 being a good example), the kernel allows to enforce routing policies In many systems (Linux being a good example), the kernel allows to enforce routing policies
by defining routing rules which choose one of several routing tables to be used for a packet by defining routing rules which choose one of several routing tables to be used for a packet
according to its parameters. Setting of these rules is outside the scope of BIRD's work according to its parameters. Setting of these rules is outside the scope of BIRD's work
(on Linux, you can use the <tt/ip/ command), but you can create several routing tables in BIRD, (on Linux, you can use the <tt/ip/ command), but you can create several routing tables in BIRD,
@ -1460,8 +1473,10 @@ another one.
<sect1>Configuration <sect1>Configuration
<p><descrip> <p><descrip>
<tag>peer table <m/table/</tag> Define secondary routing table to connect to. The <tag>peer table <m/table/</tag> Defines secondary routing table to connect to. The
primary one is selected by the <cf/table/ keyword. primary one is selected by the <cf/table/ keyword.
<tag>mode opaque|transparent</tag> Specifies the mode for the pipe to work in. Default is opaque.
</descrip> </descrip>
<sect1>Attributes <sect1>Attributes

View file

@ -179,8 +179,8 @@ void ifa_notify(struct proto *p, unsigned flags, struct ifa *a)
* rt_notify - notify instance about routing table change * rt_notify - notify instance about routing table change
* @p: protocol instance * @p: protocol instance
* @net: a network entry * @net: a network entry
* @new: new optimal route for the network * @new: new route for the network
* @old: old optimal route for the network * @old: old route for the network
* @attrs: extended attributes associated with the @new entry * @attrs: extended attributes associated with the @new entry
* *
* The rt_notify() hook is called to inform the protocol instance about * The rt_notify() hook is called to inform the protocol instance about
@ -189,7 +189,16 @@ void ifa_notify(struct proto *p, unsigned flags, struct ifa *a)
* extended attributes @attrs. Either @new or @old or both can be %NULL * extended attributes @attrs. Either @new or @old or both can be %NULL
* if the corresponding route doesn't exist. * if the corresponding route doesn't exist.
* *
* FIXME documentation * If the type of route announcement is RA_OPTIMAL, it is an
* announcement of optimal route change, @new stores the new optimal
* route and @old stores the old optimal route.
*
* If the type of route announcement is RA_ANY, it is an announcement
* of any route change, @new stores the new route and @old stores the
* old route from the same protocol.
*
* @p->accept_ra_types specifies which kind of route announcements
* protocol wants to receive.
*/ */
void rt_notify(struct proto *p, net *net, rte *new, rte *old, ea_list *attrs) void rt_notify(struct proto *p, net *net, rte *new, rte *old, ea_list *attrs)
{ DUMMY; } { DUMMY; }

View file

@ -195,8 +195,7 @@ static inline net *net_find(rtable *tab, ip_addr addr, unsigned len) { return (n
static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); } static inline net *net_get(rtable *tab, ip_addr addr, unsigned len) { return (net *) fib_get(&tab->fib, &addr, len); }
rte *rte_find(net *net, struct proto *p); rte *rte_find(net *net, struct proto *p);
rte *rte_get_temp(struct rta *); rte *rte_get_temp(struct rta *);
void rte_update(rtable *tab, net *net, struct proto *p, rte *new); void rte_update(rtable *tab, net *net, struct proto *p, struct proto *src, rte *new);
void rte_update2(rtable *tab, net *net, struct proto *p, struct proto *src, rte *new);
void rte_discard(rtable *tab, rte *old); void rte_discard(rtable *tab, rte *old);
void rte_dump(rte *); void rte_dump(rte *);
void rte_free(rte *); void rte_free(rte *);

View file

@ -44,7 +44,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
DBG("dev_if_notify: device shutdown: prefix not found\n"); DBG("dev_if_notify: device shutdown: prefix not found\n");
return; return;
} }
rte_update(p->table, n, p, NULL); rte_update(p->table, n, p, p, NULL);
} }
else if (c & IF_CHANGE_UP) else if (c & IF_CHANGE_UP)
{ {
@ -66,7 +66,7 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad)
e = rte_get_temp(a); e = rte_get_temp(a);
e->net = n; e->net = n;
e->pflags = 0; e->pflags = 0;
rte_update(p->table, n, p, e); rte_update(p->table, n, p, p, e);
} }
} }

View file

@ -241,16 +241,24 @@ do_rte_announce(struct announce_hook *a, int type, net *net, rte *new, rte *old,
* @tmpa: a list of temporary attributes belonging to the new route * @tmpa: a list of temporary attributes belonging to the new route
* *
* This function gets a routing table update and announces it * This function gets a routing table update and announces it
* to all protocols connected to the same table by their announcement hooks. * to all protocols that acccepts given type of route announcement
* and are connected to the same table by their announcement hooks.
* *
* previous optimal route for the same network FIXME * Route announcement of type RA_OPTIMAL si generated when optimal
* route (in routing table @tab) changes. In that case @old stores the
* old optimal route.
* *
* For each such protocol, we first call its import_control() hook which * Route announcement of type RA_ANY si generated when any route (in
* performs basic checks on the route (each protocol has a right to veto * routing table @tab) changes In that case @old stores the old route
* or force accept of the route before any filter is asked) and adds default * from the same protocol.
* values of attributes specific to the new protocol (metrics, tags etc.). *
* Then it consults the protocol's export filter and if it accepts the * For each appropriate protocol, we first call its import_control()
* route, the rt_notify() hook of the protocol gets called. * hook which performs basic checks on the route (each protocol has a
* right to veto or force accept of the route before any filter is
* asked) and adds default values of attributes specific to the new
* protocol (metrics, tags etc.). Then it consults the protocol's
* export filter and if it accepts the route, the rt_notify() hook of
* the protocol gets called.
*/ */
static void static void
rte_announce(rtable *tab, int type, net *net, rte *new, rte *old, ea_list *tmpa) rte_announce(rtable *tab, int type, net *net, rte *new, rte *old, ea_list *tmpa)
@ -455,6 +463,7 @@ rte_update_unlock(void)
* @table: table to be updated * @table: table to be updated
* @net: network node * @net: network node
* @p: protocol submitting the update * @p: protocol submitting the update
* @src: protocol originating the update
* @new: a &rte representing the new route or %NULL for route removal. * @new: a &rte representing the new route or %NULL for route removal.
* *
* This function is called by the routing protocols whenever they discover * This function is called by the routing protocols whenever they discover
@ -465,6 +474,12 @@ rte_update_unlock(void)
* rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all * rta_clone()), call rte_get_temp() to obtain a temporary &rte, fill in all
* the appropriate data and finally submit the new &rte by calling rte_update(). * the appropriate data and finally submit the new &rte by calling rte_update().
* *
* @src specifies the protocol that originally created the route and the meaning
* of protocol-dependent data of @new. If @new is not %NULL, @src have to be the
* same value as @new->attrs->proto. @p specifies the protocol that called
* rte_update(). In most cases it is the same protocol as @src. rte_update()
* stores @p in @new->sender;
*
* When rte_update() gets any route, it automatically validates it (checks, * When rte_update() gets any route, it automatically validates it (checks,
* whether the network and next hop address are valid IP addresses and also * whether the network and next hop address are valid IP addresses and also
* whether a normal routing protocol doesn't try to smuggle a host or link * whether a normal routing protocol doesn't try to smuggle a host or link
@ -474,7 +489,7 @@ rte_update_unlock(void)
* stores the temporary attributes back to the &rte. * stores the temporary attributes back to the &rte.
* *
* Now, having a "public" version of the route, we * Now, having a "public" version of the route, we
* automatically find any old route defined by the protocol @p * automatically find any old route defined by the protocol @src
* for network @n, replace it by the new one (or removing it if @new is %NULL), * for network @n, replace it by the new one (or removing it if @new is %NULL),
* recalculate the optimal route for this destination and finally broadcast * recalculate the optimal route for this destination and finally broadcast
* the change (if any) to all routing protocols by calling rte_announce(). * the change (if any) to all routing protocols by calling rte_announce().
@ -483,14 +498,9 @@ rte_update_unlock(void)
* from a special linear pool @rte_update_pool and freed when rte_update() * from a special linear pool @rte_update_pool and freed when rte_update()
* finishes. * finishes.
*/ */
void
rte_update(rtable *table, net *net, struct proto *p, rte *new)
{
rte_update2(table, net, p, p, new);
}
void void
rte_update2(rtable *table, net *net, struct proto *p, struct proto *src, rte *new) rte_update(rtable *table, net *net, struct proto *p, struct proto *src, rte *new)
{ {
ea_list *tmpa = NULL; ea_list *tmpa = NULL;

View file

@ -705,7 +705,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
DECODE_PREFIX(withdrawn, withdrawn_len); DECODE_PREFIX(withdrawn, withdrawn_len);
DBG("Withdraw %I/%d\n", prefix, pxlen); DBG("Withdraw %I/%d\n", prefix, pxlen);
if (n = net_find(p->p.table, prefix, pxlen)) if (n = net_find(p->p.table, prefix, pxlen))
rte_update(p->p.table, n, &p->p, NULL); rte_update(p->p.table, n, &p->p, &p->p, NULL);
} }
if (!attr_len && !nlri_len) /* shortcut */ if (!attr_len && !nlri_len) /* shortcut */
@ -724,7 +724,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
n = net_get(p->p.table, prefix, pxlen); n = net_get(p->p.table, prefix, pxlen);
e->net = n; e->net = n;
e->pflags = 0; e->pflags = 0;
rte_update(p->p.table, n, &p->p, e); rte_update(p->p.table, n, &p->p, &p->p, e);
} }
} }
bad: bad:
@ -783,7 +783,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
DECODE_PREFIX(x, len); DECODE_PREFIX(x, len);
DBG("Withdraw %I/%d\n", prefix, pxlen); DBG("Withdraw %I/%d\n", prefix, pxlen);
if (n = net_find(p->p.table, prefix, pxlen)) if (n = net_find(p->p.table, prefix, pxlen))
rte_update(p->p.table, n, &p->p, NULL); rte_update(p->p.table, n, &p->p, &p->p, NULL);
} }
} }
@ -824,7 +824,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
n = net_get(p->p.table, prefix, pxlen); n = net_get(p->p.table, prefix, pxlen);
e->net = n; e->net = n;
e->pflags = 0; e->pflags = 0;
rte_update(p->p.table, n, &p->p, e); rte_update(p->p.table, n, &p->p, &p->p, e);
} }
rta_free(a); rta_free(a);
} }

View file

@ -1003,11 +1003,11 @@ again1:
e->pref = p->preference; e->pref = p->preference;
DBG("Mod rte type %d - %I/%d via %I on iface %s, met %d\n", DBG("Mod rte type %d - %I/%d via %I on iface %s, met %d\n",
a0.source, nf->fn.prefix, nf->fn.pxlen, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1); a0.source, nf->fn.prefix, nf->fn.pxlen, a0.gw, a0.iface ? a0.iface->name : "(none)", nf->n.metric1);
rte_update(p->table, ne, p, e); rte_update(p->table, ne, p, p, e);
} }
else else
{ {
rte_update(p->table, ne, p, NULL); rte_update(p->table, ne, p, p, NULL);
FIB_ITERATE_PUT(&fit, nftmp); FIB_ITERATE_PUT(&fit, nftmp);
fib_delete(fib, nftmp); fib_delete(fib, nftmp);
goto again1; goto again1;

View file

@ -78,7 +78,7 @@ pipe_send(struct pipe_proto *p, rtable *dest, net *n, rte *new, rte *old, ea_lis
} }
dest->pipe_busy = 1; dest->pipe_busy = 1;
rte_update2(dest, nn, &p->p, (p->mode == PIPE_OPAQUE) ? &p->p : src, e); rte_update(dest, nn, &p->p, (p->mode == PIPE_OPAQUE) ? &p->p : src, e);
dest->pipe_busy = 0; dest->pipe_busy = 0;
} }

View file

@ -268,7 +268,7 @@ rip_rte_update_if_better(rtable *tab, net *net, struct proto *p, rte *new)
if (!old || p->rte_better(new, old) || if (!old || p->rte_better(new, old) ||
(ipa_equal(old->attrs->from, new->attrs->from) && (ipa_equal(old->attrs->from, new->attrs->from) &&
(old->u.rip.metric != new->u.rip.metric)) ) (old->u.rip.metric != new->u.rip.metric)) )
rte_update(tab, net, p, new); rte_update(tab, net, p, p, new);
} }
/* /*

View file

@ -60,7 +60,7 @@ static_install(struct proto *p, struct static_route *r, struct iface *ifa)
e = rte_get_temp(aa); e = rte_get_temp(aa);
e->net = n; e->net = n;
e->pflags = 0; e->pflags = 0;
rte_update(p->table, n, p, e); rte_update(p->table, n, p, p, e);
r->installed = 1; r->installed = 1;
} }
@ -75,7 +75,7 @@ static_remove(struct proto *p, struct static_route *r)
DBG("Removing static route %I/%d\n", r->net, r->masklen); DBG("Removing static route %I/%d\n", r->net, r->masklen);
n = net_find(p->table, r->net, r->masklen); n = net_find(p->table, r->net, r->masklen);
if (n) if (n)
rte_update(p->table, n, p, NULL); rte_update(p->table, n, p, p, NULL);
r->installed = 0; r->installed = 0;
} }

View file

@ -280,7 +280,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
ee->pflags = 0; ee->pflags = 0;
ee->pref = p->p.preference; ee->pref = p->p.preference;
ee->u.krt = e->u.krt; ee->u.krt = e->u.krt;
rte_update(p->p.table, nn, &p->p, ee); rte_update(p->p.table, nn, &p->p, &p->p, ee);
} }
static void static void
@ -288,7 +288,7 @@ krt_learn_announce_delete(struct krt_proto *p, net *n)
{ {
n = net_find(p->p.table, n->n.prefix, n->n.pxlen); n = net_find(p->p.table, n->n.prefix, n->n.pxlen);
if (n) if (n)
rte_update(p->p.table, n, &p->p, NULL); rte_update(p->p.table, n, &p->p, &p->p, NULL);
} }
static void static void