This is defined in RFC 4191. Note that we don't implement this RFC completely, as it also defines a Route Information Option. However, the two extensions are actually independent of each other. --- doc/bird.sgml | 4 ++++ proto/radv/config.Y | 11 +++++++++-- proto/radv/packets.c | 3 ++- proto/radv/radv.c | 1 + proto/radv/radv.h | 6 ++++++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index beacd4b..5343ba8 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -3013,6 +3013,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 to advertise to + hosts. Available since Bird 1.4.4. 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 diff --git a/proto/radv/config.Y b/proto/radv/config.Y index 88a9e29..b8f7e40 100644 --- a/proto/radv/config.Y +++ b/proto/radv/config.Y @@ -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_PREFERENCE_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_PREFERENCE_LOW; } + | MEDIUM { $$ = RA_PREFERENCE_MEDIUM; } + | HIGH { $$ = RA_PREFERENCE_HIGH; } + radv_iface_finish: { struct radv_iface_config *ic = RADV_IFACE; diff --git a/proto/radv/packets.c b/proto/radv/packets.c index 1d7e04f..ae877f5 100644 --- a/proto/radv/packets.c +++ b/proto/radv/packets.c @@ -252,7 +252,8 @@ radv_prepare_ra(struct radv_iface *ifa) 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); + (ic->other_config ? OPT_RA_OTHER_CFG : 0) | + ic->default_preference; pkt->router_lifetime = (ra->active || !ic->default_lifetime_sensitive) ? htons(ic->default_lifetime) : 0; pkt->reachable_time = htonl(ic->reachable_time); diff --git a/proto/radv/radv.c b/proto/radv/radv.c index 9040853..6be7cd8 100644 --- a/proto/radv/radv.c +++ b/proto/radv/radv.c @@ -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 diff --git a/proto/radv/radv.h b/proto/radv/radv.h index f80e453..c58bfc2 100644 --- a/proto/radv/radv.h +++ b/proto/radv/radv.h @@ -80,6 +80,8 @@ 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 from RFC 4191 */ }; struct radv_prefix_config @@ -144,7 +146,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_PREFERENCE_LOW 0x18 +#define RA_PREFERENCE_MEDIUM 0x00 +#define RA_PREFERENCE_HIGH 0x08 #ifdef LOCAL_DEBUG #define RADV_FORCE_DEBUG 1 -- 2.0.0