summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/bird.sgml31
-rw-r--r--filter/test.conf1
-rw-r--r--nest/config.Y1
-rw-r--r--nest/proto.c1
-rw-r--r--nest/protocol.h8
-rw-r--r--proto/bgp/bgp.c2
6 files changed, 42 insertions, 2 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml
index ceff31d..0c2b8fb 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -297,6 +297,10 @@ to zero to disable it. An empty <cf><m/switch/</cf> is equivalent to <cf/on/
<cf/events/ for events internal to the protocol and
<cf/packets/ for packets sent and received by the protocol. Default: off.
+ <tag>router id <m/IPv4 address/</tag> This option can be used to override global
+ router id for a given protocol. This option is not yet implemented for OSPF
+ protocol. Default: uses global router id.
+
<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/.
@@ -479,7 +483,7 @@ This argument can be omitted if there exists only a single instance.
switch itself to the new configuration, protocols are
reconfigured if possible, restarted otherwise. Changes in
filters usualy lead to restart of affected protocols. If
- <cf/soft> option is used, changes in filters does not cause
+ <cf/soft/ option is used, changes in filters does not cause
BIRD to restart affected protocols, therefore already accepted
routes (according to old filters) would be still propagated,
but new routes would be processed according to the new
@@ -649,6 +653,21 @@ incompatible with each other (that is to prevent you from shooting in the foot).
<tag/bgppath/
BGP path is a list of autonomous system numbers. You can't write literals of this type.
+ There are several special operators on bgppaths:
+
+ <cf><m/P/.first</cf> returns the first ASN (the neighbor ASN) in path <m/P/.
+
+ <cf><m/P/.last</cf> returns the last ASN (the source ASN) in path <m/P/.
+
+ Both <cf/first/ and <cf/last/ return zero if there is no appropriate ASN,
+ for example if the path contains an AS set element as the first (or the last) part.
+
+ <cf><m/P/.len</cf> returns the length of path <m/P/.
+
+ <cf>prepend(<m/P/,<m/A/)</cf> prepends ASN <m/A/ to path <m/P/ and returns the result.
+ Statement <cf><m/P/ = prepend(<m/P/, <m/A/);</cf> can be shortened to
+ <cf><m/P/.prepend(<m/A/);</cf> if <m/P/ is appropriate route attribute
+ (for example <cf/bgp_path/).
<tag/bgpmask/
BGP masks are patterns used for BGP path matching
@@ -662,10 +681,20 @@ incompatible with each other (that is to prevent you from shooting in the foot).
BGP mask expressions can also contain integer expressions enclosed in parenthesis
and integer variables, for example <tt>[= * 4 (1+2) a =]</tt>.
There is also old syntax that uses / .. / instead of [= .. =] and ? instead of *.
+
<tag/clist/
Community list is similar to set of pairs,
except that unlike other sets, it can be modified.
There exist no literals of this type.
+ There are two special operators on clists:
+
+ <cf>add(<m/C/,<m/P/)</cf> adds pair <m/P/ to clist <m/C/ and returns the result.
+
+ <cf>delete(<m/C/,<m/P/)</cf> deletes pair <m/P/ from clist <m/C/ and returns the result.
+
+ Statement <cf><m/C/ = add(<m/C/, <m/P/);</cf> can be shortened to
+ <cf><m/C/.add(<m/P/);</cf> if <m/C/ is appropriate route attribute
+ (for example <cf/bgp_community/). Similarly for <cf/delete/.
</descrip>
diff --git a/filter/test.conf b/filter/test.conf
index f3b7961..7114fd2 100644
--- a/filter/test.conf
+++ b/filter/test.conf
@@ -62,6 +62,7 @@ clist l;
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);
+ print "Should be true: ", p2.len = 5, " ", p2.first = 5, " ", p2.last = 1;
print "5 = ", p2.len;
pm1 = [= 1 2 * 3 4 5 =];
diff --git a/nest/config.Y b/nest/config.Y
index a2c44ab..4721112 100644
--- a/nest/config.Y
+++ b/nest/config.Y
@@ -140,6 +140,7 @@ proto_item:
| IMPORT imexport { this_proto->in_filter = $2; }
| EXPORT imexport { this_proto->out_filter = $2; }
| TABLE rtable { this_proto->table = $2; }
+ | ROUTER ID idval { this_proto->router_id = $3; }
;
imexport:
diff --git a/nest/proto.c b/nest/proto.c
index d079213..7bb1286 100644
--- a/nest/proto.c
+++ b/nest/proto.c
@@ -313,6 +313,7 @@ protos_commit(struct config *new, struct config *old, int force_reconfig, int ty
&& nc->preference == oc->preference
&& nc->disabled == oc->disabled
&& nc->table->table == oc->table->table
+ && proto_get_router_id(nc) == proto_get_router_id(oc)
&& ((type == RECONFIG_SOFT) || filter_same(nc->in_filter, oc->in_filter))
&& ((type == RECONFIG_SOFT) || filter_same(nc->out_filter, oc->out_filter))
&& p->proto_state != PS_DOWN)
diff --git a/nest/protocol.h b/nest/protocol.h
index 0f9d59d..484df84 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -12,6 +12,7 @@
#include "lib/lists.h"
#include "lib/resource.h"
#include "lib/timer.h"
+#include "conf/conf.h"
struct iface;
struct ifa;
@@ -81,6 +82,7 @@ struct proto_config {
struct proto *proto; /* Instance we've created */
char *name;
unsigned debug, preference, disabled; /* Generic parameters */
+ u32 router_id; /* Protocol specific router ID */
struct rtable_config *table; /* Table we're attached to */
struct filter *in_filter, *out_filter; /* Attached filters */
@@ -192,6 +194,12 @@ struct proto *proto_get_named(struct symbol *, struct protocol *);
void proto_xxable(char *, int);
void proto_debug(char *, unsigned int);
+static inline u32
+proto_get_router_id(struct proto_config *pc)
+{
+ return pc->router_id ? pc->router_id : pc->global->router_id;
+}
+
extern list active_proto_list;
/*
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index b76b7f9..b38c6b1 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -689,7 +689,7 @@ bgp_start_locked(struct object_lock *lock)
}
DBG("BGP: Got lock\n");
- p->local_id = cf->c.global->router_id;
+ p->local_id = proto_get_router_id(&cf->c);
p->next_hop = cf->multihop ? cf->multihop_via : cf->remote_ip;
p->neigh = neigh_find(&p->p, &p->next_hop, NEF_STICKY);