Merge branch 'master' of ssh://git.nic.cz/bird
This commit is contained in:
commit
2795700c31
6 changed files with 69 additions and 31 deletions
|
@ -426,24 +426,37 @@ to zero to disable it. An empty <cf><m/switch/</cf> is equivalent to <cf/on/
|
||||||
uses global router id.
|
uses global router id.
|
||||||
|
|
||||||
<tag>import all | none | filter <m/name/ | filter { <m/filter commands/ } | where <m/filter expression/</tag>
|
<tag>import all | none | filter <m/name/ | filter { <m/filter commands/ } | where <m/filter expression/</tag>
|
||||||
Specify a filter to be used for filtering routes coming from the protocol to the routing table. <cf/all/ is shorthand for <cf/where true/ and <cf/none/ is shorthand for <cf/where false/. Default: <cf/all/.
|
Specify a filter to be used for filtering routes coming from
|
||||||
|
the protocol to the routing table. <cf/all/ is shorthand for
|
||||||
|
<cf/where true/ and <cf/none/ is shorthand for
|
||||||
|
<cf/where false/. Default: <cf/all/.
|
||||||
|
|
||||||
<tag>export <m/filter/</tag> This is similar to the <cf>import</cf> keyword, except that it
|
<tag>export <m/filter/</tag>
|
||||||
works in the direction from the routing table to the protocol. Default: <cf/none/.
|
This is similar to the <cf>import</cf> keyword, except that it
|
||||||
|
works in the direction from the routing table to the protocol.
|
||||||
|
Default: <cf/none/.
|
||||||
|
|
||||||
<tag>import limit <m/number/ [exceed warn | block | restart | disable]</tag>
|
<tag>import limit <m/number/ [action warn | block | restart | disable]</tag>
|
||||||
Specify an import route limit (a maximum number of routes
|
Specify an import route limit (a maximum number of routes
|
||||||
imported from the protocol) and optionally the action to be
|
imported from the protocol) and optionally the action to be
|
||||||
taken when the limit is hit. Warn action just prints warning
|
taken when the limit is hit. Warn action just prints warning
|
||||||
log message. Block action ignores new routes coming from the
|
log message. Block action ignores new routes coming from the
|
||||||
protocol. Restart and disable actions shut the protocol down
|
protocol. Restart and disable actions shut the protocol down
|
||||||
like appropriate commands. Disable is the default action if an
|
like appropriate commands. Disable is the default action if an
|
||||||
action is not explicitly specified. Default: <cf/none/.
|
action is not explicitly specified. Note that limits are reset
|
||||||
|
during protocol reconfigure, reload or restart.
|
||||||
|
Default: <cf/none/.
|
||||||
|
|
||||||
<tag>export limit <m/number/ [exceed warn | block | restart | disable]</tag>
|
<tag>export limit <m/number/ [action warn | block | restart | disable]</tag>
|
||||||
Specify an export route limit, works similarly to
|
Specify an export route limit, works similarly to
|
||||||
the <cf>import limit</cf> option, but for the routes exported
|
the <cf>import limit</cf> option, but for the routes exported
|
||||||
to the protocol. Default: <cf/none/.
|
to the protocol. This option is experimental, there are some
|
||||||
|
problems in details of its behavior -- the number of exported
|
||||||
|
routes can temporarily exceed the limit without triggering it
|
||||||
|
during protocol reload, exported routes counter ignores route
|
||||||
|
blocking and block action also blocks route updates of alread
|
||||||
|
accepted routes -- and these details will probably change in
|
||||||
|
the future. Default: <cf/none/.
|
||||||
|
|
||||||
<tag>description "<m/text/"</tag> This is an optional
|
<tag>description "<m/text/"</tag> This is an optional
|
||||||
description of the protocol. It is displayed as a part of the
|
description of the protocol. It is displayed as a part of the
|
||||||
|
|
|
@ -44,7 +44,7 @@ CF_DECLS
|
||||||
|
|
||||||
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
|
CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
|
||||||
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
|
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
|
||||||
CF_KEYWORDS(EXCEED, LIMIT, WARN, BLOCK, RESTART, DISABLE)
|
CF_KEYWORDS(LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE)
|
||||||
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
|
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
|
||||||
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
|
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
|
||||||
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
|
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION)
|
||||||
|
@ -194,10 +194,10 @@ imexport:
|
||||||
|
|
||||||
limit_action:
|
limit_action:
|
||||||
/* default */ { $$ = PLA_DISABLE; }
|
/* default */ { $$ = PLA_DISABLE; }
|
||||||
| EXCEED WARN { $$ = PLA_WARN; }
|
| ACTION WARN { $$ = PLA_WARN; }
|
||||||
| EXCEED BLOCK { $$ = PLA_BLOCK; }
|
| ACTION BLOCK { $$ = PLA_BLOCK; }
|
||||||
| EXCEED RESTART { $$ = PLA_RESTART; }
|
| ACTION RESTART { $$ = PLA_RESTART; }
|
||||||
| EXCEED DISABLE { $$ = PLA_DISABLE; }
|
| ACTION DISABLE { $$ = PLA_DISABLE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
limit_spec:
|
limit_spec:
|
||||||
|
|
|
@ -387,7 +387,8 @@ struct proto_limit {
|
||||||
|
|
||||||
void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, u32 rt_count);
|
void proto_notify_limit(struct announce_hook *ah, struct proto_limit *l, u32 rt_count);
|
||||||
|
|
||||||
static inline void proto_reset_limit(struct proto_limit *l)
|
static inline void
|
||||||
|
proto_reset_limit(struct proto_limit *l)
|
||||||
{
|
{
|
||||||
if (l)
|
if (l)
|
||||||
l->state = PLS_INITIAL;
|
l->state = PLS_INITIAL;
|
||||||
|
|
|
@ -269,27 +269,52 @@ do_rte_announce(struct announce_hook *ah, int type UNUSED, net *net, rte *new, r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME - This is broken because of incorrect 'old' value (see above) */
|
/*
|
||||||
if (!new && !old)
|
* Export route limits has several problems. Because exp_routes
|
||||||
return;
|
* counter is reset before refeed, we don't really know whether
|
||||||
|
* limit is breached and whether the update is new or not Therefore
|
||||||
|
* the number of really exported routes may exceed the limit
|
||||||
|
* temporarily (routes exported before and new routes in refeed).
|
||||||
|
*
|
||||||
|
* Minor advantage is that if the limit is decreased and refeed is
|
||||||
|
* requested, the number of exported routes really decrease.
|
||||||
|
*
|
||||||
|
* Second problem is that with export limits, we don't know whether
|
||||||
|
* old was really exported (it might be blocked by limit). When a
|
||||||
|
* withdraw is exported, we announce it even when the previous
|
||||||
|
* update was blocked. This is not a big issue, but the same problem
|
||||||
|
* is in updating exp_routes counter. Therefore, to be consistent in
|
||||||
|
* increases and decreases of exp_routes, we count exported routes
|
||||||
|
* regardless of blocking by limits.
|
||||||
|
*
|
||||||
|
* Similar problem is in handling updates - when a new route is
|
||||||
|
* received and blocking is active, the route would be blocked, but
|
||||||
|
* when an update for the route will be received later, the update
|
||||||
|
* would be propagated (as old != NULL). Therefore, we have to block
|
||||||
|
* also non-new updates (contrary to import blocking).
|
||||||
|
*/
|
||||||
|
|
||||||
struct proto_limit *l = ah->out_limit;
|
struct proto_limit *l = ah->out_limit;
|
||||||
if (l && new && (!old || refeed))
|
if (l && new)
|
||||||
{
|
{
|
||||||
if (stats->exp_routes >= l->limit)
|
if ((!old || refeed) && (stats->exp_routes >= l->limit))
|
||||||
proto_notify_limit(ah, l, stats->exp_routes);
|
proto_notify_limit(ah, l, stats->exp_routes);
|
||||||
|
|
||||||
if (l->state == PLS_BLOCKED)
|
if (l->state == PLS_BLOCKED)
|
||||||
{
|
{
|
||||||
/* Exported route counter ignores whether the route was
|
stats->exp_routes++; /* see note above */
|
||||||
blocked by limit, to be consistent when limits change */
|
|
||||||
stats->exp_routes++;
|
|
||||||
stats->exp_updates_rejected++;
|
stats->exp_updates_rejected++;
|
||||||
rte_trace_out(D_FILTERS, p, new, "rejected [limit]");
|
rte_trace_out(D_FILTERS, p, new, "rejected [limit]");
|
||||||
goto done;
|
if (new != new0)
|
||||||
|
rte_free(new);
|
||||||
|
new = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME - This is broken because of incorrect 'old' value (see above) */
|
||||||
|
if (!new && !old)
|
||||||
|
return;
|
||||||
|
|
||||||
if (new)
|
if (new)
|
||||||
stats->exp_updates_accepted++;
|
stats->exp_updates_accepted++;
|
||||||
else
|
else
|
||||||
|
@ -325,7 +350,6 @@ do_rte_announce(struct announce_hook *ah, int type UNUSED, net *net, rte *new, r
|
||||||
else
|
else
|
||||||
p->rt_notify(p, ah->table, net, new, old, new->attrs->eattrs);
|
p->rt_notify(p, ah->table, net, new, old, new->attrs->eattrs);
|
||||||
|
|
||||||
done:
|
|
||||||
if (new && new != new0) /* Discard temporary rte's */
|
if (new && new != new0) /* Discard temporary rte's */
|
||||||
rte_free(new);
|
rte_free(new);
|
||||||
if (old && old != old0)
|
if (old && old != old0)
|
||||||
|
@ -1781,14 +1805,14 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
|
||||||
d->net_counter++;
|
d->net_counter++;
|
||||||
for(e=n->routes; e; e=e->next)
|
for(e=n->routes; e; e=e->next)
|
||||||
{
|
{
|
||||||
struct ea_list *tmpa, *old_tmpa;
|
struct ea_list *tmpa;
|
||||||
struct proto *p0 = e->attrs->proto;
|
struct proto *p0 = e->attrs->proto;
|
||||||
struct proto *p1 = d->export_protocol;
|
struct proto *p1 = d->export_protocol;
|
||||||
struct proto *p2 = d->show_protocol;
|
struct proto *p2 = d->show_protocol;
|
||||||
d->rt_counter++;
|
d->rt_counter++;
|
||||||
ee = e;
|
ee = e;
|
||||||
rte_update_lock(); /* We use the update buffer for filtering */
|
rte_update_lock(); /* We use the update buffer for filtering */
|
||||||
old_tmpa = tmpa = p0->make_tmp_attrs ? p0->make_tmp_attrs(e, rte_update_pool) : NULL;
|
tmpa = p0->make_tmp_attrs ? p0->make_tmp_attrs(e, rte_update_pool) : NULL;
|
||||||
ok = (d->filter == FILTER_ACCEPT || f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) <= F_ACCEPT);
|
ok = (d->filter == FILTER_ACCEPT || f_run(d->filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) <= F_ACCEPT);
|
||||||
if (p2 && p2 != p0) ok = 0;
|
if (p2 && p2 != p0) ok = 0;
|
||||||
if (ok && d->export_mode)
|
if (ok && d->export_mode)
|
||||||
|
|
|
@ -1145,16 +1145,16 @@ show_lsa_sum_net(struct top_hash_entry *he)
|
||||||
static inline void
|
static inline void
|
||||||
show_lsa_sum_rt(struct top_hash_entry *he)
|
show_lsa_sum_rt(struct top_hash_entry *he)
|
||||||
{
|
{
|
||||||
u32 dst_rid, options;
|
u32 dst_rid;
|
||||||
|
|
||||||
#ifdef OSPFv2
|
#ifdef OSPFv2
|
||||||
struct ospf_lsa_sum *ls = he->lsa_body;
|
struct ospf_lsa_sum *ls = he->lsa_body;
|
||||||
dst_rid = he->lsa.id;
|
dst_rid = he->lsa.id;
|
||||||
options = 0;
|
// options = 0;
|
||||||
#else /* OSPFv3 */
|
#else /* OSPFv3 */
|
||||||
struct ospf_lsa_sum_rt *ls = he->lsa_body;
|
struct ospf_lsa_sum_rt *ls = he->lsa_body;
|
||||||
dst_rid = ls->drid;
|
dst_rid = ls->drid;
|
||||||
options = ls->options & OPTIONS_MASK;
|
// options = ls->options & OPTIONS_MASK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cli_msg(-1016, "\t\txrouter %R metric %u", dst_rid, ls->metric);
|
cli_msg(-1016, "\t\txrouter %R metric %u", dst_rid, ls->metric);
|
||||||
|
|
|
@ -798,7 +798,7 @@ originate_sum_net_lsa(struct ospf_area *oa, struct fib_node *fn, int metric)
|
||||||
|
|
||||||
body = originate_sum_net_lsa_body(po, &lsa.length, fn, metric);
|
body = originate_sum_net_lsa_body(po, &lsa.length, fn, metric);
|
||||||
lsasum_calculate(&lsa, body);
|
lsasum_calculate(&lsa, body);
|
||||||
en = lsa_install_new(po, &lsa, dom, body);
|
lsa_install_new(po, &lsa, dom, body);
|
||||||
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,7 +835,7 @@ originate_sum_rt_lsa(struct ospf_area *oa, struct fib_node *fn, int metric, u32
|
||||||
|
|
||||||
body = originate_sum_rt_lsa_body(po, &lsa.length, lsa.id, metric, options);
|
body = originate_sum_rt_lsa_body(po, &lsa.length, lsa.id, metric, options);
|
||||||
lsasum_calculate(&lsa, body);
|
lsasum_calculate(&lsa, body);
|
||||||
en = lsa_install_new(po, &lsa, dom, body);
|
lsa_install_new(po, &lsa, dom, body);
|
||||||
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1117,7 +1117,7 @@ originate_ext_lsa(struct ospf_area *oa, struct fib_node *fn, int src,
|
||||||
if (src)
|
if (src)
|
||||||
fn->x1 = src;
|
fn->x1 = src;
|
||||||
|
|
||||||
en = lsa_install_new(po, &lsa, dom, body);
|
lsa_install_new(po, &lsa, dom, body);
|
||||||
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1);
|
||||||
|
|
||||||
if (po->ebit == 0)
|
if (po->ebit == 0)
|
||||||
|
|
Loading…
Reference in a new issue