The pipe cleanup.
This commit is contained in:
parent
2d45e09f58
commit
f98e291579
11 changed files with 69 additions and 36 deletions
|
@ -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
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue