On Tue, Aug 06, 2019 at 11:17:04PM +0200, Sebastian Benoit wrote: > 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. >
needs more yak shaving > > 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; This is a prefix information option (type 3) not a route information option (type 24). Option 3 does not have a 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; eek, just treat it as a number? > } 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; > + } > + ; see above, we are announcing prefix information, not route information > +preftype : LOW { > + $$ = RA_PREFIXOPT_PREF_LOW; > + } > + | MEDIUM { > + $$ = RA_PREFIXOPT_PREF_MEDIUM; > + } > + | HIGH { > + $$ = RA_PREFIXOPT_PREF_HIGH; > + } please use the defines from icmp6.h: #define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */ #define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */ #define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */ #define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */ > ; > 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); make this an in ^ > 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) ^ and here > +{ > + 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"; use the defines from icmp6.h > + } > +} > + > 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) this does not work, if you set the default in the config file (medium) it will never get printed since it's 0, but maybe that's your intention? I'd store ND_RA_FLAG_RTPREF_RSV as default and map it to medium when building the packet. Then you can match on it here. > + 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)); Prefix Information, not Route Information > } > > 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. Prefix Information vs. Route Informatiuon > .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. */ ^ make it an int > 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 */ Prefix Information vs. Route Information > }; > > +/* > + 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 > + see above, use the defines from icmp6.h > struct ra_iface_conf { > SIMPLEQ_ENTRY(ra_iface_conf) entry; > struct ra_options_conf ra_options; -- I'm not entirely sure you are real.