mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-17 08:38:42 +00:00
Merge branch 'master' into add-path
This commit is contained in:
commit
283c7dfada
15
NEWS
15
NEWS
@ -1,12 +1,23 @@
|
||||
Version 1.3.12 (2013-11-23)
|
||||
Version 1.4.0 (2013-11-25)
|
||||
o BFD protocol (RFC 5880).
|
||||
o BFD support for OSPF and BGP.
|
||||
o New 'allow local as' option for BGP.
|
||||
o Filters allows setting gw, ifname and ifindex.
|
||||
o Filter operator 'delete/filter' extended to bgp_paths.
|
||||
o Filter operator 'len' extended to [e]clists.
|
||||
o PID file support.
|
||||
o BIRD client now allows shorthands for noninteractive commands.
|
||||
o Flag -P for PID file support.
|
||||
o Flag -f added to force BIRD to run in foreground.
|
||||
o Protocol export/import/receive limits are checked during reconfiguration.
|
||||
o Several bugfixes and minor improvements.
|
||||
o Several minor but incompatible changes:
|
||||
- IBGP is multihop by default.
|
||||
- Changes primary address selection on BSD to the first one.
|
||||
- Integers in filters are handled as unsigned.
|
||||
- ISO 8601 time formats used by default.
|
||||
- Import of device routes from kernel protocol allowed.
|
||||
- Last state change now tracks just protocol state change.
|
||||
- Minor changes to default router ID calculation.
|
||||
|
||||
Version 1.3.11 (2013-07-27)
|
||||
o OSPF stub router option (RFC 3137).
|
||||
|
@ -137,6 +137,21 @@ submit_server_command(char *cmd)
|
||||
server_send(cmd);
|
||||
}
|
||||
|
||||
static inline void
|
||||
submit_init_command(char *cmd_raw)
|
||||
{
|
||||
char *cmd = cmd_expand(cmd_raw);
|
||||
|
||||
if (!cmd)
|
||||
{
|
||||
cleanup();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
submit_server_command(cmd);
|
||||
free(cmd);
|
||||
}
|
||||
|
||||
void
|
||||
submit_command(char *cmd_raw)
|
||||
{
|
||||
@ -165,7 +180,7 @@ init_commands(void)
|
||||
{
|
||||
/* First transition - client received hello from BIRD
|
||||
and there is waiting initial command */
|
||||
submit_server_command(init_cmd);
|
||||
submit_init_command(init_cmd);
|
||||
init_cmd = NULL;
|
||||
return;
|
||||
}
|
||||
|
@ -96,7 +96,8 @@ config_alloc(byte *name)
|
||||
cfg_mem = c->mem = l;
|
||||
c->file_name = cfg_strdup(name);
|
||||
c->load_time = now;
|
||||
c->tf_base.fmt1 = c->tf_log.fmt1 = "%d-%m-%Y %T";
|
||||
c->tf_route = c->tf_proto = (struct timeformat){"%T", "%F", 20*3600};
|
||||
c->tf_base = c->tf_log = (struct timeformat){"%F %T", NULL, 0};
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -256,7 +256,10 @@ which allows you to talk with BIRD in an extensive way.
|
||||
<p>In the config, everything on a line after <cf/#/ or inside <cf>/*
|
||||
*/</cf> is a comment, whitespace characters are treated as a single space. If there's a variable number of options, they are grouped using
|
||||
the <cf/{ }/ brackets. Each option is terminated by a <cf/;/. Configuration
|
||||
is case sensitive.
|
||||
is case sensitive. There are two ways how to name symbols (like protocol names, filter names, constats etc.). You can either use
|
||||
a simple string starting with a letter followed by any combination of letters and numbers (e.g. "R123", "myfilter", "bgp5") or you
|
||||
can enclose the name into apostrophes (<cf/'/) and than you can use any combination of numbers, letters. hyphens, dots and colons
|
||||
(e.g. "'1:strange-name'", "'-NAME-'", "'cool::name'").
|
||||
|
||||
<p>Here is an example of a simple config file. It enables
|
||||
synchronization of routing tables with OS kernel, scans for
|
||||
@ -377,7 +380,7 @@ protocol rip {
|
||||
"<m/format1/" is a format string using <it/strftime(3)/
|
||||
notation (see <it/man strftime/ for details). <m/limit> and
|
||||
"<m/format2/" allow to specify the second format string for
|
||||
times in past deeper than <m/limit/ seconds. There are two
|
||||
times in past deeper than <m/limit/ seconds. There are few
|
||||
shorthands: <cf/iso long/ is a ISO 8601 date/time format
|
||||
(YYYY-MM-DD hh:mm:ss) that can be also specified using <cf/"%F
|
||||
%T"/. <cf/iso short/ is a variant of ISO 8601 that uses just
|
||||
@ -385,11 +388,15 @@ protocol rip {
|
||||
the past) and the date format (YYYY-MM-DD) for far times. This
|
||||
is a shorthand for <cf/"%T" 72000 "%F"/.
|
||||
|
||||
By default, BIRD uses an short, ad-hoc format for <cf/route/
|
||||
and <cf/protocol/ times, and a <cf/iso long/ similar format
|
||||
(DD-MM-YYYY hh:mm:ss) for <cf/base/ and <cf/log/. These
|
||||
defaults are here for a compatibility with older versions
|
||||
and might change in the future.
|
||||
By default, BIRD uses the <cf/iso short/ format for <cf/route/ and
|
||||
<cf/protocol/ times, and the <cf/iso long/ format for <cf/base/ and
|
||||
<cf/log/ times.
|
||||
|
||||
In pre-1.4.0 versions, BIRD used an short, ad-hoc format for
|
||||
<cf/route/ and <cf/protocol/ times, and a <cf/iso long/ similar format
|
||||
(DD-MM-YYYY hh:mm:ss) for <cf/base/ and <cf/log/. These timeformats
|
||||
could be set by <cf/old short/ and <cf/old long/ compatibility
|
||||
shorthands.
|
||||
|
||||
<tag>table <m/name/ [sorted]</tag>
|
||||
Create a new routing table. The default routing table is
|
||||
@ -922,9 +929,10 @@ incompatible with each other (that is to prevent you from shooting in the foot).
|
||||
<cf/true/ and <cf/false/. Boolean is the only type you can use in
|
||||
<cf/if/ statements.
|
||||
|
||||
<tag/int/ This is a general integer type, you can expect it to store
|
||||
signed values from -2000000000 to +2000000000. Overflows are not
|
||||
checked. You can use <cf/0x1234/ syntax to write hexadecimal values.
|
||||
<tag/int/ This is a general integer type. It is an unsigned 32bit type;
|
||||
i.e., you can expect it to store values from 0 to 4294967295.
|
||||
Overflows are not checked. You can use <cf/0x1234/ syntax to write
|
||||
hexadecimal values.
|
||||
|
||||
<tag/pair/ This is a pair of two short integers. Each component can have
|
||||
values from 0 to 65535. Literals of this type are written as
|
||||
@ -1532,33 +1540,37 @@ This allows to set routing policy and all the other parameters differently
|
||||
for each neighbor using the following configuration parameters:
|
||||
|
||||
<descrip>
|
||||
<tag>local [<m/ip/] as <m/number/</tag> Define which AS we
|
||||
are part of. (Note that contrary to other IP routers, BIRD is
|
||||
able to act as a router located in multiple AS'es
|
||||
simultaneously, but in such cases you need to tweak the BGP
|
||||
paths manually in the filters to get consistent behavior.)
|
||||
Optional <cf/ip/ argument specifies a source address,
|
||||
equivalent to the <cf/source address/ option (see below).
|
||||
<tag>local [<m/ip/] as <m/number/</tag> Define which AS we are part
|
||||
of. (Note that contrary to other IP routers, BIRD is able to act as a
|
||||
router located in multiple AS'es simultaneously, but in such cases you
|
||||
need to tweak the BGP paths manually in the filters to get consistent
|
||||
behavior.) Optional <cf/ip/ argument specifies a source address,
|
||||
equivalent to the <cf/source address/ option (see below). This
|
||||
parameter is mandatory.
|
||||
|
||||
<tag>neighbor <m/ip/ as <m/number/</tag> Define neighboring router this
|
||||
instance will be talking to and what AS it's located in. In case the
|
||||
neighbor is in the same AS as we are, we automatically switch to iBGP.
|
||||
This parameter is mandatory.
|
||||
|
||||
<tag>neighbor <m/ip/ as <m/number/</tag> Define neighboring router
|
||||
this instance will be talking to and what AS it's located in. Unless
|
||||
you use the <cf/multihop/ clause, it must be directly connected to one
|
||||
of your router's interfaces. In case the neighbor is in the same AS
|
||||
as we are, we automatically switch to iBGP. This parameter is mandatory.
|
||||
<tag>direct</tag> Specify that the neighbor is directly connected. The
|
||||
IP address of the neighbor must be from a directly reachable IP range
|
||||
(i.e. associated with one of your router's interfaces), otherwise the
|
||||
BGP session wouldn't start but it would wait for such interface to
|
||||
appear. The alternative is the <cf/multihop/ option. Default: enabled
|
||||
for eBGP.
|
||||
|
||||
<tag>multihop [<m/number/]</tag> Configure multihop BGP
|
||||
session to a neighbor that isn't directly connected.
|
||||
Accurately, this option should be used if the configured
|
||||
neighbor IP address does not match with any local network
|
||||
subnets. Such IP address have to be reachable through system
|
||||
routing table. For multihop BGP it is recommended to
|
||||
explicitly configure <cf/source address/ to have it
|
||||
stable. Optional <cf/number/ argument can be used to specify
|
||||
the number of hops (used for TTL). Note that the number of
|
||||
networks (edges) in a path is counted, i.e. if two BGP
|
||||
speakers are separated by one router, the number of hops is
|
||||
2. Default: switched off.
|
||||
<tag>multihop [<m/number/]</tag> Configure multihop BGP session to a
|
||||
neighbor that isn't directly connected. Accurately, this option should
|
||||
be used if the configured neighbor IP address does not match with any
|
||||
local network subnets. Such IP address have to be reachable through
|
||||
system routing table. The alternative is the <cf/direct/ option. For
|
||||
multihop BGP it is recommended to explicitly configure the source
|
||||
address to have it stable. Optional <cf/number/ argument can be used to
|
||||
specify the number of hops (used for TTL). Note that the number of
|
||||
networks (edges) in a path is counted; i.e., if two BGP speakers are
|
||||
separated by one router, the number of hops is 2. Default: enabled for
|
||||
iBGP.
|
||||
|
||||
<tag>source address <m/ip/</tag> Define local address we
|
||||
should use for next hop calculation and as a source address
|
||||
@ -1605,8 +1617,8 @@ for each neighbor using the following configuration parameters:
|
||||
table, and was used in older versions of BIRD, but does not
|
||||
handle well nontrivial iBGP setups and multihop. Recursive
|
||||
mode is incompatible with <ref id="dsc-sorted" name="sorted
|
||||
tables">. Default: <cf/direct/ for singlehop eBGP,
|
||||
<cf/recursive/ otherwise.
|
||||
tables">. Default: <cf/direct/ for direct sessions,
|
||||
<cf/recursive/ for multihop sessions.
|
||||
|
||||
<tag>igp table <m/name/</tag> Specifies a table that is used
|
||||
as an IGP routing table. Default: the same as the table BGP is
|
||||
|
@ -53,6 +53,7 @@ Reply codes of BIRD command-line interface
|
||||
1017 Show ospf lsadb
|
||||
1018 Show memory
|
||||
1019 Show ROA list
|
||||
1020 Show BFD sessions
|
||||
|
||||
8000 Reply too long
|
||||
8001 Route not found
|
||||
|
@ -90,12 +90,6 @@ pm_format(struct f_path_mask *p, buffer *buf)
|
||||
buffer_puts(buf, "=]");
|
||||
}
|
||||
|
||||
static inline int
|
||||
int_cmp(int i1, int i2)
|
||||
{
|
||||
return (i1 > i2) - (i1 < i2);
|
||||
}
|
||||
|
||||
static inline int
|
||||
uint_cmp(uint i1, uint i2)
|
||||
{
|
||||
@ -146,7 +140,6 @@ val_compare(struct f_val v1, struct f_val v2)
|
||||
case T_ENUM:
|
||||
case T_INT:
|
||||
case T_BOOL:
|
||||
return int_cmp(v1.val.i, v2.val.i);
|
||||
case T_PAIR:
|
||||
case T_QUAD:
|
||||
return uint_cmp(v1.val.i, v2.val.i);
|
||||
@ -157,7 +150,7 @@ val_compare(struct f_val v1, struct f_val v2)
|
||||
case T_PREFIX:
|
||||
if (rc = ipa_compare(v1.val.px.ip, v2.val.px.ip))
|
||||
return rc;
|
||||
return int_cmp(v1.val.px.len, v2.val.px.len);
|
||||
return uint_cmp(v1.val.px.len, v2.val.px.len);
|
||||
case T_STRING:
|
||||
return strcmp(v1.val.s, v2.val.s);
|
||||
default:
|
||||
@ -442,16 +435,16 @@ val_format(struct f_val v, buffer *buf)
|
||||
{
|
||||
case T_VOID: buffer_puts(buf, "(void)"); return;
|
||||
case T_BOOL: buffer_puts(buf, v.val.i ? "TRUE" : "FALSE"); return;
|
||||
case T_INT: buffer_print(buf, "%d", v.val.i); return;
|
||||
case T_INT: buffer_print(buf, "%u", v.val.i); return;
|
||||
case T_STRING: buffer_print(buf, "%s", v.val.s); return;
|
||||
case T_IP: buffer_print(buf, "%I", v.val.px.ip); return;
|
||||
case T_PREFIX: buffer_print(buf, "%I/%d", v.val.px.ip, v.val.px.len); return;
|
||||
case T_PAIR: buffer_print(buf, "(%d,%d)", v.val.i >> 16, v.val.i & 0xffff); return;
|
||||
case T_PAIR: buffer_print(buf, "(%u,%u)", v.val.i >> 16, v.val.i & 0xffff); return;
|
||||
case T_QUAD: buffer_print(buf, "%R", v.val.i); return;
|
||||
case T_EC: ec_format(buf2, v.val.ec); buffer_print(buf, "%s", buf2); return;
|
||||
case T_PREFIX_SET: trie_format(v.val.ti, buf); return;
|
||||
case T_SET: tree_format(v.val.t, buf); return;
|
||||
case T_ENUM: buffer_print(buf, "(enum %x)%d", v.type, v.val.i); return;
|
||||
case T_ENUM: buffer_print(buf, "(enum %x)%u", v.type, v.val.i); return;
|
||||
case T_PATH: as_path_format(v.val.ad, buf2, 1000); buffer_print(buf, "(path %s)", buf2); return;
|
||||
case T_CLIST: int_set_format(v.val.ad, 1, -1, buf2, 1000); buffer_print(buf, "(clist %s)", buf2); return;
|
||||
case T_ECLIST: ec_set_format(v.val.ad, -1, buf2, 1000); buffer_print(buf, "(eclist %s)", buf2); return;
|
||||
@ -1167,14 +1160,14 @@ interpret(struct f_inst *what)
|
||||
/* Community (or cluster) list */
|
||||
struct f_val dummy;
|
||||
int arg_set = 0;
|
||||
i = 0;
|
||||
uint n = 0;
|
||||
|
||||
if ((v2.type == T_PAIR) || (v2.type == T_QUAD))
|
||||
i = v2.val.i;
|
||||
n = v2.val.i;
|
||||
#ifndef IPV6
|
||||
/* IP->Quad implicit conversion */
|
||||
else if (v2.type == T_IP)
|
||||
i = ipa_to_u32(v2.val.px.ip);
|
||||
n = ipa_to_u32(v2.val.px.ip);
|
||||
#endif
|
||||
else if ((v2.type == T_SET) && clist_set_type(v2.val.t, &dummy))
|
||||
arg_set = 1;
|
||||
@ -1190,14 +1183,14 @@ interpret(struct f_inst *what)
|
||||
if (arg_set == 1)
|
||||
runtime("Can't add set");
|
||||
else if (!arg_set)
|
||||
res.val.ad = int_set_add(f_pool, v1.val.ad, i);
|
||||
res.val.ad = int_set_add(f_pool, v1.val.ad, n);
|
||||
else
|
||||
res.val.ad = int_set_union(f_pool, v1.val.ad, v2.val.ad);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (!arg_set)
|
||||
res.val.ad = int_set_del(f_pool, v1.val.ad, i);
|
||||
res.val.ad = int_set_del(f_pool, v1.val.ad, n);
|
||||
else
|
||||
res.val.ad = clist_filter(f_pool, v1.val.ad, v2, 0);
|
||||
break;
|
||||
@ -1502,7 +1495,7 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
|
||||
log( L_ERR "Filter %s did not return accept nor reject. Make up your mind", filter->name);
|
||||
return F_ERROR;
|
||||
}
|
||||
DBG( "done (%d)\n", res.val.i );
|
||||
DBG( "done (%u)\n", res.val.i );
|
||||
return res.val.i;
|
||||
}
|
||||
|
||||
@ -1519,7 +1512,7 @@ f_eval(struct f_inst *expr, struct linpool *tmp_pool)
|
||||
return interpret(expr);
|
||||
}
|
||||
|
||||
int
|
||||
uint
|
||||
f_eval_int(struct f_inst *expr)
|
||||
{
|
||||
/* Called independently in parse-time to eval expressions */
|
||||
|
@ -51,7 +51,7 @@ struct f_prefix {
|
||||
struct f_val {
|
||||
int type;
|
||||
union {
|
||||
int i;
|
||||
uint i;
|
||||
u64 ec;
|
||||
/* ip_addr ip; Folded into prefix */
|
||||
struct f_prefix px;
|
||||
@ -108,7 +108,7 @@ struct rte;
|
||||
|
||||
int f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struct linpool *tmp_pool, int flags);
|
||||
struct f_val f_eval(struct f_inst *expr, struct linpool *tmp_pool);
|
||||
int f_eval_int(struct f_inst *expr);
|
||||
uint f_eval_int(struct f_inst *expr);
|
||||
u32 f_eval_asn(struct f_inst *expr);
|
||||
|
||||
char *filter_name(struct filter *filter);
|
||||
|
@ -1,6 +1,6 @@
|
||||
Summary: BIRD Internet Routing Daemon
|
||||
Name: bird
|
||||
Version: 1.3.12
|
||||
Version: 1.4.0
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Networking/Daemons
|
||||
|
12
nest/iface.c
12
nest/iface.c
@ -600,22 +600,10 @@ if_choose_router_id(struct iface_patt *mask, u32 old_id)
|
||||
if (a->scope <= SCOPE_LINK)
|
||||
continue;
|
||||
|
||||
/* FIXME: This should go away */
|
||||
if (a->flags & IA_PEER)
|
||||
continue;
|
||||
|
||||
/* FIXME: This should go away too */
|
||||
if (!mask && (a != i->addr))
|
||||
continue;
|
||||
|
||||
/* Check pattern if specified */
|
||||
if (mask && !iface_patt_match(mask, i, a))
|
||||
continue;
|
||||
|
||||
/* FIXME: This should go away too */
|
||||
if ((i->flags & IF_IGNORE) && !mask)
|
||||
continue;
|
||||
|
||||
/* No pattern or pattern matched */
|
||||
if (!b || ipa_to_u32(a->ip) < ipa_to_u32(b->ip))
|
||||
b = a;
|
||||
|
@ -48,7 +48,6 @@ static void
|
||||
proto_enqueue(list *l, struct proto *p)
|
||||
{
|
||||
add_tail(l, &p->n);
|
||||
p->last_state_change = now;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -363,6 +362,8 @@ proto_init(struct proto_config *c)
|
||||
|
||||
q->proto_state = PS_DOWN;
|
||||
q->core_state = FS_HUNGRY;
|
||||
q->last_state_change = now;
|
||||
|
||||
proto_enqueue(&initial_proto_list, q);
|
||||
if (p == &proto_unix_iface)
|
||||
initial_device_proto = q;
|
||||
@ -1084,6 +1085,7 @@ proto_notify_state(struct proto *p, unsigned ps)
|
||||
return;
|
||||
|
||||
p->proto_state = ps;
|
||||
p->last_state_change = now;
|
||||
|
||||
switch (ps)
|
||||
{
|
||||
|
@ -1070,13 +1070,13 @@ bfd_show_sessions(struct proto *P)
|
||||
|
||||
if (p->p.proto_state != PS_UP)
|
||||
{
|
||||
cli_msg(-1013, "%s: is not up", p->p.name);
|
||||
cli_msg(-1020, "%s: is not up", p->p.name);
|
||||
cli_msg(0, "");
|
||||
return;
|
||||
}
|
||||
|
||||
cli_msg(-1013, "%s:", p->p.name);
|
||||
cli_msg(-1013, "%-25s %-10s %-10s %-10s %8s %8s",
|
||||
cli_msg(-1020, "%s:", p->p.name);
|
||||
cli_msg(-1020, "%-25s %-10s %-10s %-10s %8s %8s",
|
||||
"IP address", "Interface", "State", "Since", "Interval", "Timeout");
|
||||
|
||||
|
||||
@ -1092,7 +1092,7 @@ bfd_show_sessions(struct proto *P)
|
||||
state = (state < 4) ? state : 0;
|
||||
tm_format_datetime(tbuf, &config->tf_proto, s->last_state_change);
|
||||
|
||||
cli_msg(-1013, "%-25I %-10s %-10s %-10s %3u.%03u %3u.%03u",
|
||||
cli_msg(-1020, "%-25I %-10s %-10s %-10s %3u.%03u %3u.%03u",
|
||||
s->addr, ifname, bfd_state_names[state], tbuf,
|
||||
tx_int / 1000, tx_int % 1000, timeout / 1000, timeout % 1000);
|
||||
}
|
||||
|
@ -1009,6 +1009,24 @@ bgp_check_config(struct bgp_config *c)
|
||||
if (c->c.class == SYM_TEMPLATE)
|
||||
return;
|
||||
|
||||
|
||||
/* EBGP direct by default, IBGP multihop by default */
|
||||
if (c->multihop < 0)
|
||||
c->multihop = internal ? 64 : 0;
|
||||
|
||||
/* Different default for gw_mode */
|
||||
if (!c->gw_mode)
|
||||
c->gw_mode = c->multihop ? GW_RECURSIVE : GW_DIRECT;
|
||||
|
||||
/* Different default based on rs_client */
|
||||
if (!c->missing_lladdr)
|
||||
c->missing_lladdr = c->rs_client ? MLL_IGNORE : MLL_SELF;
|
||||
|
||||
/* Disable after error incompatible with restart limit action */
|
||||
if (c->c.in_limit && (c->c.in_limit->action == PLA_RESTART) && c->disable_after_error)
|
||||
c->c.in_limit->action = PLA_DISABLE;
|
||||
|
||||
|
||||
if (!c->local_as)
|
||||
cf_error("Local AS number must be set");
|
||||
|
||||
@ -1024,7 +1042,6 @@ bgp_check_config(struct bgp_config *c)
|
||||
if (internal && c->rs_client)
|
||||
cf_error("Only external neighbor can be RS client");
|
||||
|
||||
|
||||
if (c->multihop && (c->gw_mode == GW_DIRECT))
|
||||
cf_error("Multihop BGP cannot use direct gateway mode");
|
||||
|
||||
@ -1035,20 +1052,6 @@ bgp_check_config(struct bgp_config *c)
|
||||
if (c->multihop && c->bfd && ipa_zero(c->source_addr))
|
||||
cf_error("Multihop BGP with BFD requires specified source address");
|
||||
|
||||
|
||||
/* Different default based on rs_client */
|
||||
if (!c->missing_lladdr)
|
||||
c->missing_lladdr = c->rs_client ? MLL_IGNORE : MLL_SELF;
|
||||
|
||||
/* Different default for gw_mode */
|
||||
if (!c->gw_mode)
|
||||
c->gw_mode = (c->multihop || internal) ? GW_RECURSIVE : GW_DIRECT;
|
||||
|
||||
/* Disable after error incompatible with restart limit action */
|
||||
if (c->c.in_limit && (c->c.in_limit->action == PLA_RESTART) && c->disable_after_error)
|
||||
c->c.in_limit->action = PLA_DISABLE;
|
||||
|
||||
|
||||
if ((c->gw_mode == GW_RECURSIVE) && c->c.table->sorted)
|
||||
cf_error("BGP in recursive mode prohibits sorted table");
|
||||
|
||||
|
@ -34,6 +34,7 @@ CF_ADDTO(proto, bgp_proto '}' { bgp_check_config(BGP_CFG); } )
|
||||
|
||||
bgp_proto_start: proto_start BGP {
|
||||
this_proto = proto_config_new(&proto_bgp, sizeof(struct bgp_config), $1);
|
||||
BGP_CFG->multihop = -1; /* undefined */
|
||||
BGP_CFG->hold_time = 240;
|
||||
BGP_CFG->connect_retry_time = 120;
|
||||
BGP_CFG->initial_hold_time = 240;
|
||||
@ -74,6 +75,7 @@ bgp_proto:
|
||||
| bgp_proto STARTUP HOLD TIME expr ';' { BGP_CFG->initial_hold_time = $5; }
|
||||
| bgp_proto CONNECT RETRY TIME expr ';' { BGP_CFG->connect_retry_time = $5; }
|
||||
| bgp_proto KEEPALIVE TIME expr ';' { BGP_CFG->keepalive_time = $4; }
|
||||
| bgp_proto DIRECT ';' { BGP_CFG->multihop = 0; }
|
||||
| bgp_proto MULTIHOP ';' { BGP_CFG->multihop = 64; }
|
||||
| bgp_proto MULTIHOP expr ';' { BGP_CFG->multihop = $3; if (($3<1) || ($3>255)) cf_error("Multihop must be in range 1-255"); }
|
||||
| bgp_proto NEXT HOP SELF ';' { BGP_CFG->next_hop_self = 1; BGP_CFG->next_hop_keep = 0; }
|
||||
|
@ -472,10 +472,14 @@ ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr)
|
||||
if (! addr)
|
||||
return 0;
|
||||
|
||||
/* a host/loopback address */
|
||||
/* a host address */
|
||||
if (addr->flags & IA_HOST)
|
||||
return 1;
|
||||
|
||||
/* a loopback iface */
|
||||
if (addr->iface->flags & IF_LOOPBACK)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* We cannot properly support multiple OSPF ifaces on real iface
|
||||
* with multiple prefixes, therefore we force OSPF ifaces with
|
||||
|
@ -1058,3 +1058,36 @@ kif_sys_shutdown(struct kif_proto *p)
|
||||
krt_buffer_release(&p->p);
|
||||
}
|
||||
|
||||
|
||||
struct ifa *
|
||||
kif_get_primary_ip(struct iface *i)
|
||||
{
|
||||
#ifndef IPV6
|
||||
static int fd = -1;
|
||||
|
||||
if (fd < 0)
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, i->name, IFNAMSIZ);
|
||||
|
||||
int rv = ioctl(fd, SIOCGIFADDR, (char *) &ifr);
|
||||
if (rv < 0)
|
||||
return NULL;
|
||||
|
||||
ip_addr addr;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
|
||||
memcpy(&addr, &sin->sin_addr.s_addr, sizeof(ip_addr));
|
||||
ipa_ntoh(addr);
|
||||
|
||||
struct ifa *a;
|
||||
WALK_LIST(a, i->addrs)
|
||||
{
|
||||
if (ipa_equal(a->ip, addr))
|
||||
return a;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define _BIRD_CONFIG_H_
|
||||
|
||||
/* BIRD version */
|
||||
#define BIRD_VERSION "1.3.12"
|
||||
#define BIRD_VERSION "1.4.0"
|
||||
|
||||
/* Include parameters determined by configure script */
|
||||
#include "sysdep/autoconf.h"
|
||||
|
@ -27,6 +27,8 @@ static inline void kif_sys_postconfig(struct kif_config *c UNUSED) { }
|
||||
static inline void kif_sys_init_config(struct kif_config *c UNUSED) { }
|
||||
static inline void kif_sys_copy_config(struct kif_config *d UNUSED, struct kif_config *s UNUSED) { }
|
||||
|
||||
static inline struct ifa * kif_get_primary_ip(struct iface *i) { return NULL; }
|
||||
|
||||
|
||||
/* Kernel routes */
|
||||
|
||||
|
@ -862,19 +862,6 @@ nl_parse_route(struct nlmsghdr *h, int scan)
|
||||
else
|
||||
{
|
||||
ra.dest = RTD_DEVICE;
|
||||
|
||||
/*
|
||||
* In Linux IPv6, 'native' device routes have proto
|
||||
* RTPROT_BOOT and not RTPROT_KERNEL (which they have in
|
||||
* IPv4 and which is expected). We cannot distinguish
|
||||
* 'native' and user defined device routes, so we ignore all
|
||||
* such device routes and for consistency, we have the same
|
||||
* behavior in IPv4. Anyway, users should use RTPROT_STATIC
|
||||
* for their 'alien' routes.
|
||||
*/
|
||||
|
||||
if (i->rtm_protocol == RTPROT_BOOT)
|
||||
src = KRT_SRC_KERNEL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -14,7 +14,7 @@ CF_HDR
|
||||
CF_DECLS
|
||||
|
||||
CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG, STDERR, SOFT)
|
||||
CF_KEYWORDS(TIMEFORMAT, ISO, SHORT, LONG, BASE, NAME, CONFIRM, UNDO, CHECK, TIMEOUT)
|
||||
CF_KEYWORDS(TIMEFORMAT, ISO, OLD, SHORT, LONG, BASE, NAME, CONFIRM, UNDO, CHECK, TIMEOUT)
|
||||
|
||||
%type <i> log_mask log_mask_list log_cat cfg_timeout
|
||||
%type <g> log_file
|
||||
@ -96,6 +96,8 @@ timeformat_spec:
|
||||
| timeformat_which TEXT expr TEXT { *$1 = (struct timeformat){$2, $4, $3}; }
|
||||
| timeformat_which ISO SHORT { *$1 = (struct timeformat){"%T", "%F", 20*3600}; }
|
||||
| timeformat_which ISO LONG { *$1 = (struct timeformat){"%F %T", NULL, 0}; }
|
||||
| timeformat_which OLD SHORT { *$1 = (struct timeformat){NULL, NULL, 0}; }
|
||||
| timeformat_which OLD LONG { *$1 = (struct timeformat){"%d-%m-%Y %T", NULL, 0}; }
|
||||
;
|
||||
|
||||
timeformat_base:
|
||||
|
@ -159,6 +159,9 @@ kif_choose_primary(struct iface *i)
|
||||
return a;
|
||||
}
|
||||
|
||||
if (a = kif_get_primary_ip(i))
|
||||
return a;
|
||||
|
||||
return find_preferred_ifa(i, IPA_NONE, IPA_NONE);
|
||||
}
|
||||
|
||||
|
@ -142,5 +142,6 @@ void kif_sys_copy_config(struct kif_config *, struct kif_config *);
|
||||
|
||||
void kif_do_scan(struct kif_proto *);
|
||||
|
||||
struct ifa *kif_get_primary_ip(struct iface *i);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user