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

Merge remote-tracking branch 'origin/master' into soft-int

parents 178a197a cfdea7b8
Version 1.4.5 (2014-10-06)
o New 'show route noexport' command option.
o Port option for BGP sessions.
o Better constant handling in set literals.
o Better rate filtering of log messages.
o Several minor bugfixes.
Version 1.4.4 (2014-07-09)
o Extended OSPF multipath support.
o Default router preference for RAdv.
o Significant changes in socket layer.
o Important bugfix in BGP.
o Several minor bugfixes.
Version 1.4.3 (2014-04-14)
o Important bugfix in IPv6 BGP.
......@@ -32,7 +46,7 @@ Version 1.4.0 (2013-11-25)
- 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).
o TTL security for OSPF and RIP.
......
......@@ -646,7 +646,7 @@ cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos)
char *
cf_symbol_class_name(struct symbol *sym)
{
if ((sym->class & 0xff00) == SYM_CONSTANT)
if (cf_symbol_is_constant(sym))
return "constant";
switch (sym->class)
......
......@@ -149,6 +149,10 @@ void cf_pop_scope(void);
struct symbol *cf_walk_symbols(struct config *cf, struct symbol *sym, int *pos);
char *cf_symbol_class_name(struct symbol *sym);
static inline int cf_symbol_is_constant(struct symbol *sym)
{ return (sym->class & 0xff00) == SYM_CONSTANT; }
/* Parser */
int cf_parse(void);
......
......@@ -72,7 +72,7 @@ CF_DECLS
%token <t> TEXT
%type <iface> ipa_scope
%type <i> expr bool pxlen
%type <i> expr bool pxlen ipa_port
%type <i32> expr_us
%type <time> datetime
%type <a> ipa
......@@ -88,7 +88,7 @@ CF_DECLS
%left '!'
%nonassoc '.'
CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US)
CF_KEYWORDS(DEFINE, ON, OFF, YES, NO, S, MS, US, PORT)
CF_GRAMMAR
......@@ -161,6 +161,14 @@ ipa_scope:
| '%' SYM { $$ = if_get_by_name($2->name); }
;
ipa_port:
/* empty */ { $$ = 0; }
| PORT expr {
if (($2 < 1) || ($2 > 65535)) cf_error("Invalid port number");
$$ = $2;
}
;
prefix:
ipa pxlen {
if (!ip_is_prefix($1, $2)) cf_error("Invalid prefix");
......
......@@ -318,7 +318,7 @@ protocol rip {
<p><descrip>
<tag>include "<m/filename/"</tag>
This statement causes inclusion of a new file. <m/Filename/ could also
be a wildcard. The maximal depth is 5. Note that this statement could be
be a wildcard. The maximal depth is 8. Note that this statement could be
used anywhere in the config file, not just as a top-level option.
<tag><label id="dsc-log">log "<m/filename/"|syslog [name <m/name/]|stderr all|{ <m/list of classes/ }</tag>
......@@ -735,7 +735,7 @@ This argument can be omitted if there exists only a single instance.
Show the list of symbols defined in the configuration (names of
protocols, routing tables etc.).
<tag>show route [[for] <m/prefix/|<m/IP/] [table <m/sym/] [filter <m/f/|where <m/c/] [(export|preexport) <m/p/] [protocol <m/p/] [<m/options/]</tag>
<tag>show route [[for] <m/prefix/|<m/IP/] [table <m/sym/] [filter <m/f/|where <m/c/] [(export|preexport|noexport) <m/p/] [protocol <m/p/] [<m/options/]</tag>
Show contents of a routing table (by default of the main one or the
table attached to a respective protocol), that is routes, their metrics
and (in case the <cf/all/ switch is given) all their attributes.
......@@ -750,9 +750,14 @@ This argument can be omitted if there exists only a single instance.
<p>You can also ask for printing only routes processed and accepted by
a given filter (<cf>filter <m/name/</cf> or <cf>filter { <m/filter/ }
</cf> or matching a given condition (<cf>where <m/condition/</cf>).
The <cf/export/ and <cf/preexport/ switches ask for printing of entries
that are exported to the specified protocol. With <cf/preexport/, the
export filter of the protocol is skipped.
The <cf/export/, <cf/preexport/ and <cf/noexport/ switches ask for
printing of routes that are exported to the specified protocol.
With <cf/preexport/, the export filter of the protocol is skipped.
With <cf/noexport/, routes rejected by the export filter are printed
instead. Note that routes not exported to the protocol for other reasons
(e.g. secondary routes or routes imported from that protocol) are not
printed even with <cf/noexport/.
<p>You can also select just routes added by a specific protocol.
<cf>protocol <m/p/</cf>.
......@@ -1004,7 +1009,6 @@ foot).
So <cf>1.2.0.0/16.pxlen = 16</cf> is true.
<tag/ec/
This is a specialized type used to represent BGP extended community
values. It is essentially a 64bit value, literals of this type are
usually written as <cf>(<m/kind/, <m/key/, <m/value/)</cf>, where
......@@ -1014,7 +1018,7 @@ foot).
used kind. Similarly to pairs, ECs can be constructed using expressions
for <cf/key/ and <cf/value/ parts, (e.g. <cf/(ro, myas, 3*10)/, where
<cf/myas/ is an integer variable).
<tag/int|pair|quad|ip|prefix|ec|enum set/
Filters recognize four types of sets. Sets are similar to strings: you
can pass them around but you can't modify them. Literals of type <cf>int
......@@ -1616,7 +1620,7 @@ using the following configuration parameters:
address, equivalent to the <cf/source address/ option (see below). This
parameter is mandatory.
<tag>neighbor <m/ip/ as <m/number/</tag>
<tag>neighbor <m/ip/ [port <m/number/] 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.
......@@ -3036,6 +3040,10 @@ definitions, prefix definitions and DNS definitions:
as a default router. For <cf/sensitive/ option, see <ref id="dsc-trigger" name="trigger">.
Default: 3 * <cf/max ra interval/, <cf/sensitive/ yes.
<tag>default preference low|medium|high</tag>
This option specifies the Default Router Preference value to advertise
to hosts. Default: medium.
<tag>rdnss local <m/switch/</tag>
Use only local (interface-specific) RDNSS definitions for this
interface. Otherwise, both global and local definitions are used. Could
......
......@@ -25,6 +25,23 @@ static inline u32 pair_b(u32 p) { return p & 0xFFFF; }
* to the last item in a list (right ptr). For convenience, even items
* are handled as one-item lists. Lists are merged by f_merge_items().
*/
static int
f_valid_set_type(int type)
{
switch (type)
{
case T_INT:
case T_PAIR:
case T_QUAD:
case T_ENUM:
case T_IP:
case T_EC:
return 1;
default:
return 0;
}
}
static inline struct f_tree *
f_new_item(struct f_val from, struct f_val to)
......@@ -473,10 +490,19 @@ fipa:
*/
set_atom:
expr { $$.type = T_INT; $$.val.i = $1; }
NUM { $$.type = T_INT; $$.val.i = $1; }
| RTRID { $$.type = T_QUAD; $$.val.i = $1; }
| fipa { $$ = $1; }
| ENUM { $$.type = pair_a($1); $$.val.i = pair_b($1); }
| '(' term ')' {
$$ = f_eval($2, cfg_mem);
if (!f_valid_set_type($$.type)) cf_error("Set-incompatible type");
}
| SYM {
if (!cf_symbol_is_constant($1)) cf_error("%s: constant expected", $1->name);
if (!f_valid_set_type(SYM_TYPE($1))) cf_error("%s: set-incompatible type", $1->name);
$$ = *(struct f_val *)($1->def);
}
;
switch_atom:
......
......@@ -493,7 +493,7 @@ f_rta_cow(void)
}
}
static struct rate_limit rl_runtime_err;
static struct tbf rl_runtime_err = TBF_DEFAULT_LOG_LIMITS;
#define runtime(x) do { \
log_rl(&rl_runtime_err, L_ERR "filters, line %d: %s", what->lineno, x); \
......@@ -1492,7 +1492,7 @@ f_run(struct filter *filter, struct rte **rte, struct ea_list **tmp_attrs, struc
if (res.type != T_RETURN) {
log( L_ERR "Filter %s did not return accept nor reject. Make up your mind", filter->name);
log_rl(&rl_runtime_err, L_ERR "Filter %s did not return accept nor reject. Make up your mind", filter->name);
return F_ERROR;
}
DBG( "done (%u)\n", res.val.i );
......
......@@ -13,6 +13,9 @@ define '1a-a1' = (20+10);
define one = 1;
define ten = 10;
define p23 = (2, 3);
define ip1222 = 1.2.2.2;
function onef(int a)
{
return 1;
......@@ -78,7 +81,7 @@ function test_roa()
" ", roa_check(rl, 10.130.130.0/24, 3000) = ROA_VALID;
}
function paths()
function path_test()
bgpmask pm1;
bgpmask pm2;
bgppath p2;
......@@ -98,7 +101,7 @@ eclist el2;
print "Should be true: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 3 ~ p2, " ", p2 ~ [2, 10..20], " ", p2 ~ [4, 10..20];
print "4 = ", p2.len;
p2 = prepend( p2, 5 );
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, 10..20],;
print "Should be false: ", p2 ~ pm1, " ", p2 ~ pm2, " ", 10 ~ p2, " ", p2 ~ [8, ten..(2*ten)];
print "Should be true: ", p2 ~ / ? 4 3 2 1 /, " ", p2, " ", / ? 4 3 2 1 /;
print "Should be true: ", p2 ~ [= * 4 3 * 1 =], " ", p2, " ", [= * 4 3 * 1 =];
print "Should be true: ", p2 ~ [= (3+2) (2*2) 3 2 1 =], " ", p2 ~ mkpath(5, 4);
......@@ -124,7 +127,7 @@ eclist el2;
print "Should be always true: ", l ~ [(*,*)];
l = add( l, (2,one+2) );
print "Community list (1,2) (2,3) ", l;
print "Should be true: ", (2,3) ~ l, " ", l ~ [(1,*)], " ", l ~ [(2,3)]," ", l ~ [(2,2..3)], " ", l ~ [(1,1..2)], " ", l ~ [(1,1)..(1,2)];
print "Should be true: ", (2,3) ~ l, " ", l ~ [(1,*)], " ", l ~ [p23]," ", l ~ [(2,2..3)], " ", l ~ [(1,1..2)], " ", l ~ [(1,1)..(1,2)];
l = add( l, (2,5) );
l = add( l, (5,one) );
l = add( l, (6,one) );
......@@ -361,7 +364,7 @@ string st;
if ( b = true ) then print "Testing bool comparison b = true: ", b;
else { print "*** FAIL: TRUE test failed" ; quitbird; }
ips = [ 1.1.1.0 .. 1.1.1.255, 1.2.2.2];
ips = [ 1.1.1.0 .. 1.1.1.255, ip1222];
print "Testing IP sets: ";
print ips;
print " must be true: ", 1.1.1.0 ~ ips, ",", 1.1.1.100 ~ ips, ",", 1.2.2.2 ~ ips;
......@@ -389,7 +392,7 @@ string st;
i = fifteen();
print "Testing function calls: 15 = ", i;
paths();
path_test();
print "1.2.3.4 = ", onetwo;
......
H Library functions
S ip.c ipv4.c ipv6.c
S lists.c
S checksum.c bitops.c patmatch.c printf.c xmalloc.c
S checksum.c bitops.c patmatch.c printf.c xmalloc.c tbf.c
D resource.sgml
S resource.c
S mempool.c
......
......@@ -19,6 +19,7 @@ resource.c
resource.h
slab.c
socket.h
tbf.c
unaligned.h
xmalloc.c
printf.c
......
......@@ -74,6 +74,38 @@ typedef s64 btime;
#endif
/* Rate limiting */
struct tbf {
bird_clock_t timestamp; /* Last update */
u16 count; /* Available tokens */
u16 burst; /* Max number of tokens */
u16 rate; /* Rate of replenishment */
u16 mark; /* Whether last op was limited */
};
/* Default TBF values for rate limiting log messages */
#define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 }
void tbf_update(struct tbf *f);
static inline int
tbf_limit(struct tbf *f)
{
tbf_update(f);
if (!f->count)
{
f->mark = 1;
return 1;
}
f->count--;
f->mark = 0;
return 0;
}
/* Logging and dying */
typedef struct buffer {
......@@ -94,16 +126,10 @@ typedef struct buffer {
#define LOG_BUFFER_SIZE 1024
struct rate_limit {
bird_clock_t timestamp;
int count;
};
#define log log_msg
void log_commit(int class, buffer *buf);
void log_msg(char *msg, ...);
void log_rl(struct rate_limit *rl, char *msg, ...);
void log_rl(struct tbf *rl, char *msg, ...);
void die(char *msg, ...) NORET;
void bug(char *msg, ...) NORET;
......
......@@ -123,7 +123,7 @@ static size_t
slab_memsize(resource *r)
{
slab *s = (slab *) r;
int cnt = 0;
size_t cnt = 0;
struct sl_obj *o;
WALK_LIST(o, s->objs)
......@@ -346,7 +346,7 @@ static size_t
slab_memsize(resource *r)
{
slab *s = (slab *) r;
int heads = 0;
size_t heads = 0;
struct sl_head *h;
WALK_LIST(h, s->empty_heads)
......
/*
* BIRD Library -- Token Bucket Filter
*
* (c) 2014 Ondrej Zajicek <santiago@crfreenet.org>
* (c) 2014 CZ.NIC z.s.p.o.
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include "nest/bird.h"
void
tbf_update(struct tbf *f)
{
bird_clock_t delta = now - f->timestamp;
if (delta == 0)
return;
f->timestamp = now;
if ((0 < delta) && (delta < f->burst))
{
u32 next = f->count + delta * f->rate;
f->count = MIN(next, f->burst);
}
else
f->count = f->burst;
}
Summary: BIRD Internet Routing Daemon
Name: bird
Version: 1.4.3
Version: 1.4.5
Release: 1
Copyright: GPL
Group: Networking/Daemons
......
......@@ -57,10 +57,10 @@ CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OF
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
CF_KEYWORDS(RECEIVE, LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH, AS)
CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, NOEXPORT, GENERATE, ROA)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC, CLASS, DSCP)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT)
CF_KEYWORDS(GRACEFUL, RESTART, WAIT, MAX, FLUSH, AS)
CF_ENUM(T_ENUM_RTS, RTS_, DUMMY, STATIC, INHERIT, DEVICE, STATIC_DEVICE, REDIRECT,
RIP, OSPF, OSPF_IA, OSPF_EXT1, OSPF_EXT2, BGP, PIPE)
......@@ -77,7 +77,7 @@ CF_ENUM(T_ENUM_ROA, ROA_, UNKNOWN, VALID, INVALID)
%type <ro> roa_args
%type <rot> roa_table_arg
%type <sd> sym_args
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_or_preexport roa_mode limit_action tab_sorted tos
%type <i> proto_start echo_mask echo_size debug_mask debug_list debug_flag mrtdump_mask mrtdump_list mrtdump_flag export_mode roa_mode limit_action tab_sorted tos
%type <ps> proto_patt proto_patt2
%type <g> limit_spec
......@@ -443,7 +443,7 @@ CF_CLI(SHOW INTERFACES SUMMARY,,, [[Show summary of network interfaces]])
{ if_show_summary(); } ;
CF_CLI_HELP(SHOW ROUTE, ..., [[Show routing table]])
CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [filtered] [(export|preexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
CF_CLI(SHOW ROUTE, r_args, [[[<prefix>|for <prefix>|for <ip>] [table <t>] [filter <f>|where <cond>] [all] [primary] [filtered] [(export|preexport|noexport) <p>] [protocol <p>] [stats|count]]], [[Show routing table]])
{ rt_show($3); } ;
r_args:
......@@ -492,7 +492,7 @@ r_args:
$$ = $1;
$$->filtered = 1;
}
| r_args export_or_preexport SYM {
| r_args export_mode SYM {
struct proto_config *c = (struct proto_config *) $3->def;
$$ = $1;
if ($$->export_mode) cf_error("Protocol specified twice");
......@@ -519,9 +519,10 @@ r_args:
}
;
export_or_preexport:
PREEXPORT { $$ = 1; }
| EXPORT { $$ = 2; }
export_mode:
PREEXPORT { $$ = RSEM_PREEXPORT; }
| EXPORT { $$ = RSEM_EXPORT; }
| NOEXPORT { $$ = RSEM_NOEXPORT; }
;
......
......@@ -301,6 +301,12 @@ struct rt_show_data {
};
void rt_show(struct rt_show_data *);
/* Value of export_mode in struct rt_show_data */
#define RSEM_NONE 0 /* Export mode not used */
#define RSEM_PREEXPORT 1 /* Routes ready for export, before filtering */
#define RSEM_EXPORT 2 /* Routes accepted by export filter */
#define RSEM_NOEXPORT 3 /* Routes rejected by export filter */
/*
* Route Attributes
*
......
......@@ -815,7 +815,7 @@ rta_alloc_hash(void)
static inline unsigned int
rta_hash(rta *a)
{
return (((unsigned) a->src) ^ ipa_hash(a->gw) ^
return (((uint) (uintptr_t) a->src) ^ ipa_hash(a->gw) ^
mpnh_hash(a->nexthops) ^ ea_hash(a->eattrs)) & 0xffff;
}
......
......@@ -645,7 +645,7 @@ rte_recalculate(struct announce_hook *ah, net *net, rte *new, ea_list *tmpa, str
struct proto *p = ah->proto;
struct rtable *table = ah->table;
struct proto_stats *stats = ah->stats;
static struct rate_limit rl_pipe;
static struct tbf rl_pipe = TBF_DEFAULT_LOG_LIMITS;
rte *before_old = NULL;
rte *old_best = net->routes;
rte *old = NULL;
......@@ -1367,7 +1367,7 @@ rt_init(void)
static int
rt_prune_step(rtable *tab, int step, int *limit)
{
static struct rate_limit rl_flush;
static struct tbf rl_flush = TBF_DEFAULT_LOG_LIMITS;
struct fib_iterator *fit = &tab->prune_fit;
DBG("Pruning route table %s\n", tab->name);
......@@ -2255,6 +2255,9 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
if (d->export_mode)
{
if (! d->export_protocol->rt_notify)
return;
a = proto_find_announce_hook(d->export_protocol, d->table);
if (!a)
return;
......@@ -2287,18 +2290,20 @@ rt_show_net(struct cli *c, net *n, struct rt_show_data *d)
if (ic < 0)
goto skip;
if (d->export_mode > 1)
if (d->export_mode > RSEM_PREEXPORT)
{
/*
* FIXME - This shows what should be exported according to current
* filters, but not what was really exported. 'configure soft'
* command may change the export filter and do not update routes.
*/
int do_export = (ic > 0) ||
(f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) <= F_ACCEPT);
if (!ic && (f_run(a->out_filter, &e, &tmpa, rte_update_pool, FF_FORCE_TMPATTR) > F_ACCEPT))
if (do_export != (d->export_mode == RSEM_EXPORT))
goto skip;
if (ep->accept_ra_types == RA_ACCEPTED)
if ((d->export_mode == RSEM_EXPORT) && (ep->accept_ra_types == RA_ACCEPTED))
pass = 1;
}
}
......
......@@ -1062,7 +1062,7 @@ bfd_copy_config(struct proto_config *dest, struct proto_config *src)
// struct bfd_config *s = (struct bfd_config *) src;
/* We clean up patt_list and neigh_list, neighbors and ifaces are non-sharable */
init_list(&d->patt_list);
init_list(&d->patt_list);
init_list(&d->neigh_list);
}
......@@ -1071,7 +1071,7 @@ bfd_show_sessions(struct proto *P)
{
byte tbuf[TM_DATETIME_BUFFER_SIZE];
struct bfd_proto *p = (struct bfd_proto *) P;
uint state, diag;
uint state, diag UNUSED;
u32 tx_int, timeout;
const char *ifname;
......
......@@ -680,8 +680,8 @@ bgp_connect(struct bgp_proto *p) /* Enter Connect state and start establishing c
s->type = SK_TCP_ACTIVE;
s->saddr = p->source_addr;
s->daddr = p->cf->remote_ip;
s->dport = p->cf->remote_port;
s->iface = p->neigh ? p->neigh->iface : NULL;
s->dport = BGP_PORT;
s->ttl = p->cf->ttl_security ? 255 : hops;
s->rbsize = BGP_RX_BUFFER_SIZE;
s->tbsize = BGP_TX_BUFFER_SIZE;
......@@ -1016,9 +1016,9 @@ bgp_start(struct proto *P)
lock = p->lock = olock_new(P->pool);
lock->addr = p->cf->remote_ip;
lock->port = p->cf->remote_port;
lock->iface = p->cf->iface;
lock->type = OBJLOCK_TCP;
lock->port = BGP_PORT;
lock->hook = bgp_start_locked;
lock->data = p;
olock_acquire(lock);
......
......@@ -23,6 +23,7 @@ struct bgp_config {
ip_addr remote_ip;
ip_addr source_addr; /* Source address to use */
struct iface *iface; /* Interface for link-local addresses */
u16 remote_port; /* Neighbor destination port */
int multihop; /* Number of hops if multihop */
int ttl_security; /* Enable TTL security [RFC5082] */
int next_hop_self; /* Always set next hop to local IP address */
......
......@@ -60,7 +60,7 @@ bgp_proto:
| bgp_proto proto_item ';'
| bgp_proto LOCAL AS expr ';' { BGP_CFG->local_as = $4; }
| bgp_proto LOCAL ipa AS expr ';' { BGP_CFG->source_addr = $3; BGP_CFG->local_as = $5; }
| bgp_proto NEIGHBOR ipa ipa_scope AS expr ';' {
| bgp_proto NEIGHBOR ipa ipa_scope ipa_port AS expr ';' {
if (ipa_nonzero(BGP_CFG->remote_ip))
cf_error("Only one neighbor per BGP instance is allowed");
if (!ipa_has_link_scope($3) != !$4)
......@@ -68,7 +68,8 @@ bgp_proto:
BGP_CFG->remote_ip = $3;
BGP_CFG->iface = $4;
BGP_CFG->remote_as = $6;
BGP_CFG->remote_port = ($5 > 0) ? $5 : BGP_PORT;
BGP_CFG->remote_as = $7;
}
| bgp_proto RR CLUSTER ID idval ';' { BGP_CFG->rr_cluster_id = $5; }
| bgp_proto RR CLIENT ';' { BGP_CFG->rr_client = 1; }
......
......@@ -22,7 +22,8 @@
#include "bgp.h"
static struct rate_limit rl_rcv_update, rl_snd_update;
static struct tbf rl_rcv_update = TBF_DEFAULT_LOG_LIMITS;
static struct tbf rl_snd_update = TBF_DEFAULT_LOG_LIMITS;
/* Table for state -> RFC 6608 FSM error subcodes */
static byte fsm_err_subcode[BS_MAX] = {
......
......@@ -30,9 +30,9 @@ CF_KEYWORDS(RADV, PREFIX, INTERFACE, MIN, MAX, RA, DELAY, INTERVAL,
MANAGED, OTHER, CONFIG, LINK, MTU, REACHABLE, TIME, RETRANS,
TIMER, CURRENT, HOP, LIMIT, DEFAULT, VALID, PREFERRED, MULT,
LIFETIME, SKIP, ONLINK, AUTONOMOUS, RDNSS, DNSSL, NS, DOMAIN,
LOCAL, TRIGGER, SENSITIVE)
LOCAL, TRIGGER, SENSITIVE, PREFERENCE, LOW, MEDIUM, HIGH)
%type<i> radv_mult radv_sensitive
%type<i> radv_mult radv_sensitive radv_preference
CF_GRAMMAR
......@@ -84,6 +84,7 @@ radv_iface_start:
RADV_IFACE->current_hop_limit = DEFAULT_CURRENT_HOP_LIMIT;
RADV_IFACE->default_lifetime = -1;
RADV_IFACE->default_lifetime_sensitive = 1;
RADV_IFACE->default_preference = RA_PREF_MEDIUM;
};
radv_iface_item:
......@@ -101,6 +102,7 @@ radv_iface_item:
if (($3 < 0) || ($3 > 9000)) cf_error("Default lifetime must be in range 0-9000");
if ($4 != -1) RADV_IFACE->default_lifetime_sensitive = $4;
}
| DEFAULT PREFERENCE radv_preference { RADV_IFACE->default_preference = $3; }
| PREFIX radv_prefix { add_tail(&RADV_IFACE->pref_list, NODE this_radv_prefix); }
| RDNSS { init_list(&radv_dns_list); } radv_rdnss { add_tail_list(&RADV_IFACE->rdnss_list, &radv_dns_list); }
| DNSSL { init_list(&radv_dns_list); } radv_dnssl { add_tail_list(&RADV_IFACE->dnssl_list, &radv_dns_list); }
......@@ -108,6 +110,11 @@ radv_iface_item:
| DNSSL LOCAL bool { RADV_IFACE->dnssl_local = $3; }
;
radv_preference:
LOW { $$ = RA_PREF_LOW; }
| MEDIUM { $$ = RA_PREF_MEDIUM; }
| HIGH { $$ = RA_PREF_HIGH; }
radv_iface_finish:
{
struct radv_iface_config *ic = RADV_IFACE;
......
......@@ -251,10 +251,11 @@ radv_prepare_ra(struct radv_iface *ifa)
pkt->code = 0;
pkt->checksum = 0;
pkt->current_hop_limit = ic->current_hop_limit;
pkt->flags = (ic->managed ? OPT_RA_MANAGED : 0) |
(ic->other_config ? OPT_RA_OTHER_CFG : 0);
pkt->router_lifetime = (ra->active || !ic->default_lifetime_sensitive) ?
htons(ic->default_lifetime) : 0;
pkt->flags = (ic->managed ? OPT_RA_MANAGED : 0) |
(ic->other_config ? OPT_RA_OTHER_CFG : 0) |
(pkt->router_lifetime ? ic->default_preference : 0);
pkt->reachable_time = htonl(ic->reachable_time);
pkt->retrans_timer = htonl(ic->retrans_timer);
buf += sizeof(*pkt);
......@@ -330,10 +331,15 @@ radv_send_ra(struct radv_iface *ifa, int shutdown)
if (shutdown)
{
/* Modify router lifetime to 0, it is not restored because
we suppose that the iface will be removed */
/*
* Modify router lifetime to 0, it is not restored because we suppose that
* the iface will be removed. The preference value also has to be zeroed.
* (RFC 4191 2.2: If router lifetime is 0, the preference value must be 0.)
*/
struct radv_ra_packet *pkt = (void *) ifa->sk->tbuf;
pkt->router_lifetime = 0;
pkt->flags &= ~RA_PREF_MASK;
}
RADV_TRACE(D_PACKETS, "Sending RA via %s", ifa->iface->name);
......
......@@ -40,6 +40,7 @@
* Supported standards:
* - RFC 4861 - main RA standard
* - RFC 6106 - DNS extensions (RDDNS, DNSSL)
* - RFC 4191 (partial) - Default Router Preference
*/
static void
......
......@@ -80,6 +80,7 @@ struct radv_iface_config
u32 current_hop_limit;
u32 default_lifetime;
u8 default_lifetime_sensitive; /* Whether default_lifetime depends on trigger */
u8 default_preference; /* Default Router Preference (RFC 4191) */
};
struct radv_prefix_config
......@@ -144,6 +145,11 @@ struct radv_iface
#define RA_EV_CHANGE 2 /* Change of options or prefixes */
#define RA_EV_RS 3 /* Received RS */
/* Default Router Preferences (RFC 4191) */
#define RA_PREF_LOW 0x18
#define RA_PREF_MEDIUM 0x00
#define RA_PREF_HIGH 0x08
#define RA_PREF_MASK 0x18
#ifdef LOCAL_DEBUG
......
......@@ -261,6 +261,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
msg.rtm.rtm_flags |= RTF_GATEWAY;
msg.rtm.rtm_addrs |= RTA_GATEWAY;
break;
#ifdef RTF_REJECT
case RTD_UNREACHABLE:
#endif
......@@ -280,7 +281,7 @@ krt_send_route(struct krt_proto *p, int cmd, rte *e)
return -1;
}
sockaddr_fill(&dst, BIRD_AF, i->addr->ip, NULL, 0);
sockaddr_fill(&gate, BIRD_AF, i->addr->ip, NULL, 0);
msg.rtm.rtm_addrs |= RTA_GATEWAY;
}
break;
......
......@@ -141,6 +141,7 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
#ifdef IP_SENDSRCADDR
struct cmsghdr *cm;
struct in_addr *sa;
int controllen = 0;
msg->msg_control = cbuf;
msg->msg_controllen = cbuflen;
......@@ -149,11 +150,12 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
cm->cmsg_level = IPPROTO_IP;
cm->cmsg_type = IP_SENDSRCADDR;
cm->cmsg_len = CMSG_LEN(sizeof(*sa));
controllen += CMSG_SPACE(sizeof(*sa));
sa = (struct in_addr *) CMSG_DATA(cm);
*sa = ipa_to_in4(s->saddr);
msg->msg_controllen = cm->cmsg_len;
msg->msg_controllen = controllen;
#endif
}
......
......@@ -7,7 +7,7 @@
#define _BIRD_CONFIG_H_
/* BIRD version */
#define BIRD_VERSION "1.4.3"
#define BIRD_VERSION "1.4.5"
/* Include parameters determined by configure script */
#include "sysdep/autoconf.h"
......
......@@ -151,7 +151,7 @@ nl_get_reply(struct nl_sock *nl)
}
}
static struct rate_limit rl_netlink_err;
static struct tbf rl_netlink_err = TBF_DEFAULT_LOG_LIMITS;