Commit f98e2915 authored by Ondřej Zajíček's avatar Ondřej Zajíček

The pipe cleanup.

parent 2d45e09f
......@@ -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
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,
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.
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
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,
......@@ -1460,8 +1473,10 @@ another one.
<sect1>Configuration
<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.
<tag>mode opaque|transparent</tag> Specifies the mode for the pipe to work in. Default is opaque.
</descrip>
<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
* @p: protocol instance
* @net: a network entry
* @new: new optimal route for the network
* @old: old optimal route for the network
* @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
......@@ -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
* 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)
{ 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); }
rte *rte_find(net *net, struct proto *p);
rte *rte_get_temp(struct rta *);
void rte_update(rtable *tab, net *net, struct proto *p, rte *new);
void rte_update2(rtable *tab, net *net, struct proto *p, struct proto *src, rte *new);
void rte_update(rtable *tab, net *net, struct proto *p, struct proto *src, rte *new);
void rte_discard(rtable *tab, rte *old);
void rte_dump(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");
return;
}
rte_update(p->table, n, p, NULL);
rte_update(p->table, n, p, p, NULL);
}
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->net = n;
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
*
* 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
* 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.
* Route announcement of type RA_ANY si generated when any route (in
* routing table @tab) changes In that case @old stores the old route
* from the same protocol.
*
* For each appropriate protocol, we first call its import_control()
* 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
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
* @net: network node
* @p: protocol submitting the update
* @src: protocol originating the update
* @new: a &rte representing the new route or %NULL for route removal.
*
* 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
* 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,
* 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
......@@ -474,7 +489,7 @@ rte_update_unlock(void)
* stores the temporary attributes back to the &rte.
*
* 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),
* recalculate the optimal route for this destination and finally broadcast
* 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()
* finishes.
*/
void
rte_update(rtable *table, net *net, struct proto *p, rte *new)
{
rte_update2(table, net, p, p, new);
}
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;
......
......@@ -705,7 +705,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
DECODE_PREFIX(withdrawn, withdrawn_len);
DBG("Withdraw %I/%d\n", 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 */
......@@ -724,7 +724,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
n = net_get(p->p.table, prefix, pxlen);
e->net = n;
e->pflags = 0;
rte_update(p->p.table, n, &p->p, e);
rte_update(p->p.table, n, &p->p, &p->p, e);
}
}
bad:
......@@ -783,7 +783,7 @@ bgp_do_rx_update(struct bgp_conn *conn,
DECODE_PREFIX(x, len);
DBG("Withdraw %I/%d\n", 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);
e->net = n;
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);
}
......
......@@ -1003,11 +1003,11 @@ again1:
e->pref = p->preference;
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);
rte_update(p->table, ne, p, e);
rte_update(p->table, ne, p, p, e);
}
else
{
rte_update(p->table, ne, p, NULL);
rte_update(p->table, ne, p, p, NULL);
FIB_ITERATE_PUT(&fit, nftmp);
fib_delete(fib, nftmp);
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;
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;
}
......
......@@ -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) ||
(ipa_equal(old->attrs->from, new->attrs->from) &&
(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->net = n;
e->pflags = 0;
rte_update(p->table, n, p, e);
rte_update(p->table, n, p, p, e);
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);
n = net_find(p->table, r->net, r->masklen);
if (n)
rte_update(p->table, n, p, NULL);
rte_update(p->table, n, p, p, NULL);
r->installed = 0;
}
......
......@@ -280,7 +280,7 @@ krt_learn_announce_update(struct krt_proto *p, rte *e)
ee->pflags = 0;
ee->pref = p->p.preference;
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
......@@ -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);
if (n)
rte_update(p->p.table, n, &p->p, NULL);
rte_update(p->p.table, n, &p->p, &p->p, NULL);
}
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment