Thanks to Baptiste Jonglez for the patch.
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
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
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:
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); }
| 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;
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);
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);
* Supported standards:
* - RFC 4861 - main RA standard
* - RFC 6106 - DNS extensions (RDDNS, DNSSL)
+ * - RFC 4191 (partial) - Default Router Preference
*/
static void
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
#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