On Tue, Aug 06, 2019 at 11:17:04PM +0200, Sebastian Benoit wrote:
> Caleb([email protected]) 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.