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;

Reply via email to