Caleb(enlightened.des...@gmail.com) on 2019.08.06 08:05:48 -0700: > How do I publish default router preferences as defined in RFC 4191 > (https://tools.ietf.org/html/rfc4191) using rad in OpenBSD 6.5? > I've read the friendly rad.conf man page > (https://man.openbsd.org/rad.conf.5) and scanned the source > (https://github.com/openbsd/src/tree/master/usr.sbin/rad) with no > success.
You can't, because it was not implemented. That is, until now. I wrote a patch, which you can test if you like. It's completly untested though. diff --git usr.sbin/rad/frontend.c usr.sbin/rad/frontend.c index 8178b058629..75723797fcf 100644 --- usr.sbin/rad/frontend.c +++ usr.sbin/rad/frontend.c @@ -1016,6 +1016,8 @@ build_packet(struct ra_iface *ra_iface) ra->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED; if (ra_options_conf->o_flag) ra->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER; + ra->nd_ra_flags_reserved |= + ra_options_conf->preference; if (ra_iface->removed) /* tell clients that we are no longer a default router */ ra->nd_ra_router_lifetime = 0; @@ -1048,6 +1050,8 @@ build_packet(struct ra_iface *ra_iface) if (ra_prefix_conf->aflag) ndopt_pi->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; + ndopt_pi->nd_opt_pi_flags_reserved |= + ra_prefix_conf->preference; ndopt_pi->nd_opt_pi_valid_time = htonl(ra_prefix_conf->vltime); ndopt_pi->nd_opt_pi_preferred_time = htonl(ra_prefix_conf->pltime); diff --git usr.sbin/rad/parse.y usr.sbin/rad/parse.y index 004e5e22f92..b004ab37356 100644 --- usr.sbin/rad/parse.y +++ usr.sbin/rad/parse.y @@ -106,6 +106,7 @@ typedef struct { union { int64_t number; char *string; + short pref; } v; int lineno; } YYSTYPE; @@ -117,11 +118,13 @@ typedef struct { %token CONFIGURATION OTHER LIFETIME REACHABLE TIME RETRANS TIMER %token AUTO PREFIX VALID PREFERRED LIFETIME ONLINK AUTONOMOUS %token ADDRESS_CONFIGURATION DNS NAMESERVER SEARCH MTU +%token PREFERENCE LOW MEDIUM HIGH %token <v.string> STRING %token <v.number> NUMBER %type <v.number> yesno %type <v.string> string +%type <v.pref> preftype %% @@ -213,6 +216,9 @@ ra_opt_block : DEFAULT ROUTER yesno { | MTU NUMBER { ra_options->mtu = $2; } + | PREFERENCE preftype { + ra_options->preference = $2; + } | DNS dns_block ; @@ -298,6 +304,19 @@ ra_prefixoptsl : VALID LIFETIME NUMBER { | AUTONOMOUS ADDRESS_CONFIGURATION yesno { ra_prefix_conf->aflag = $3; } + | PREFERENCE preftype { + ra_prefix_conf->preference = $2; + } + ; +preftype : LOW { + $$ = RA_PREFIXOPT_PREF_LOW; + } + | MEDIUM { + $$ = RA_PREFIXOPT_PREF_MEDIUM; + } + | HIGH { + $$ = RA_PREFIXOPT_PREF_HIGH; + } ; dns_block : '{' optnl dnsopts_l '}' | '{' optnl '}' @@ -425,17 +444,21 @@ lookup(char *s) {"configuration", CONFIGURATION}, {"default", DEFAULT}, {"dns", DNS}, + {"high", HIGH}, {"hop", HOP}, {"include", INCLUDE}, {"interface", RA_IFACE}, {"lifetime", LIFETIME}, {"limit", LIMIT}, + {"low", LOW}, {"managed", MANAGED}, + {"medium", MEDIUM}, {"mtu", MTU}, {"nameserver", NAMESERVER}, {"no", NO}, {"on-link", ONLINK}, {"other", OTHER}, + {"preference", PREFERENCE}, {"preferred", PREFERRED}, {"prefix", PREFIX}, {"reachable", REACHABLE}, diff --git usr.sbin/rad/printconf.c usr.sbin/rad/printconf.c index d42890da518..e063daaa19f 100644 --- usr.sbin/rad/printconf.c +++ usr.sbin/rad/printconf.c @@ -34,6 +34,7 @@ #include "rad.h" const char* yesno(int); +const char* preference(short); void print_ra_options(const char*, const struct ra_options_conf*); void print_prefix_options(const char*, const struct ra_prefix_conf*); @@ -43,6 +44,21 @@ yesno(int flag) return flag ? "yes" : "no"; } +const char* +preference(short p) +{ + switch (p) { + case RA_PREFIXOPT_PREF_LOW: + return "low"; + case RA_PREFIXOPT_PREF_MEDIUM: + return "medium"; + case RA_PREFIXOPT_PREF_HIGH: + return "high"; + default: + return "invalid"; + } +} + void print_ra_options(const char *indent, const struct ra_options_conf *ra_options) { @@ -60,6 +76,9 @@ print_ra_options(const char *indent, const struct ra_options_conf *ra_options) printf("%sretrans timer %u\n", indent, ra_options->retrans_timer); if (ra_options->mtu > 0) printf("%smtu %u\n", indent, ra_options->mtu); + if (ra_options->preference > 0) + printf("%spreference %s\n", indent, + preference(ra_options->preference)); if (!SIMPLEQ_EMPTY(&ra_options->ra_rdnss_list) || !SIMPLEQ_EMPTY(&ra_options->ra_dnssl_list)) { @@ -95,6 +114,8 @@ print_prefix_options(const char *indent, const struct ra_prefix_conf printf("%son-link %s\n", indent, yesno(ra_prefix_conf->lflag)); printf("%sautonomous address-configuration %s\n", indent, yesno(ra_prefix_conf->aflag)); + printf("%spreference %s\n", indent, + preference(ra_prefix_conf->preference)); } void diff --git usr.sbin/rad/rad.conf.5 usr.sbin/rad/rad.conf.5 index f651a715d1a..888a8f79b76 100644 --- usr.sbin/rad/rad.conf.5 +++ usr.sbin/rad/rad.conf.5 @@ -107,6 +107,11 @@ The default is 1800 seconds. .\" XXX .\" .It Ic retrans timer Ar number .\" XXX +.It Ic preference Pq Ic low Ns | Ns Ic medium Ns | Ns Ic high +Specify the router preference that is communicated to hosts through +router advertisements. +It can be used to communicate a prefered default router to IPv6 hosts. +The default is medium. .El .Sh INTERFACES A list of interfaces or interface groups to send advertisments on: @@ -147,6 +152,9 @@ The default is 604800. The valid lifetime (vltime) in seconds for addresses generated from this prefix. The default is 2592000. +.It Ic preference Pq Ic low Ns | Ns Ic medium Ns | Ns Ic high +The preference of the prefix is low, medium or high. +The default is medium. .El .Sh FILES .Bl -tag -width "/etc/rad.conf" -compact diff --git usr.sbin/rad/rad.h usr.sbin/rad/rad.h index 2bbf7c8ed5c..9508783da2e 100644 --- usr.sbin/rad/rad.h +++ usr.sbin/rad/rad.h @@ -93,6 +93,7 @@ struct ra_options_conf { int m_flag; /* managed address conf flag */ int o_flag; /* other conf flag */ int router_lifetime; /* default router lifetime */ + short preference; /* rfc4191 def. router pref. */ uint32_t reachable_time; uint32_t retrans_timer; uint32_t mtu; @@ -112,8 +113,17 @@ struct ra_prefix_conf { uint32_t pltime; /* prefered lifetime */ int lflag; /* on-link flag*/ int aflag; /* autonom. addr flag */ + short preference; /* preference rfc4191 */ }; +/* + RFC4191 preference values, in the middle of the 8bit reserved field. + 01 High, 00 Medium (default), 11 Low, 10 Reserved - MUST NOT be sent +*/ +#define RA_PREFIXOPT_PREF_LOW 0x18 +#define RA_PREFIXOPT_PREF_MEDIUM 0x00 +#define RA_PREFIXOPT_PREF_HIGH 0x08 + struct ra_iface_conf { SIMPLEQ_ENTRY(ra_iface_conf) entry; struct ra_options_conf ra_options;