Implement RFC 4191 default router preference.
authorflorian <florian@openbsd.org>
Tue, 23 Apr 2024 22:11:59 +0000 (22:11 +0000)
committerflorian <florian@openbsd.org>
Tue, 23 Apr 2024 22:11:59 +0000 (22:11 +0000)
OK phessler, kn

(Committing from a ferry somewhere on the English channel. Sadly the
free WiFi does not provide IPv6.)

usr.sbin/rad/frontend.c
usr.sbin/rad/parse.y
usr.sbin/rad/printconf.c
usr.sbin/rad/rad.conf.5
usr.sbin/rad/rad.h

index 352479f..6748e43 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: frontend.c,v 1.44 2024/02/11 21:29:12 bluhm Exp $     */
+/*     $OpenBSD: frontend.c,v 1.45 2024/04/23 22:11:59 florian Exp $   */
 
 /*
  * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -1157,6 +1157,14 @@ build_packet(struct ra_iface *ra_iface)
        else if (ra_options_conf->dfr) {
                ra->nd_ra_router_lifetime =
                    htons(ra_options_conf->router_lifetime);
+               /*
+                * RFC 4191
+                * If the Router Lifetime is zero, the preference value MUST be
+                * set to (00) by the sender and MUST be ignored by the
+                * receiver.
+                */
+               if (ra_options_conf->router_lifetime > 0)
+                       ra->nd_ra_flags_reserved |= ra_options_conf->rtpref;
        }
        ra->nd_ra_reachable = htonl(ra_options_conf->reachable_time);
        ra->nd_ra_retransmit = htonl(ra_options_conf->retrans_timer);
index 6ebd4ee..66cc0c0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: parse.y,v 1.21 2022/10/15 13:27:45 florian Exp $      */
+/*     $OpenBSD: parse.y,v 1.22 2024/04/23 22:11:59 florian Exp $      */
 
 /*
  * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -29,6 +29,7 @@
 #include <sys/stat.h>
 
 #include <netinet/in.h>
+#include <netinet/icmp6.h>
 #include <net/if.h>
 
 #include <arpa/inet.h>
@@ -119,8 +120,8 @@ typedef struct {
 %token RA_IFACE YES NO INCLUDE ERROR
 %token DEFAULT ROUTER HOP LIMIT MANAGED ADDRESS
 %token CONFIGURATION OTHER LIFETIME REACHABLE TIME RETRANS TIMER
-%token AUTO PREFIX VALID PREFERRED LIFETIME ONLINK AUTONOMOUS
-%token ADDRESS_CONFIGURATION DNS NAMESERVER SEARCH MTU NAT64
+%token AUTO PREFIX VALID PREFERENCE PREFERRED LIFETIME ONLINK AUTONOMOUS
+%token ADDRESS_CONFIGURATION DNS NAMESERVER SEARCH MTU NAT64 HIGH MEDIUM LOW
 
 %token <v.string>      STRING
 %token <v.number>      NUMBER
@@ -210,6 +211,15 @@ ra_opt_block       : DEFAULT ROUTER yesno {
                | ROUTER LIFETIME NUMBER {
                        ra_options->router_lifetime = $3;
                }
+               | ROUTER PREFERENCE HIGH {
+                       ra_options->rtpref = ND_RA_FLAG_RTPREF_HIGH;
+               }
+               | ROUTER PREFERENCE MEDIUM {
+                       ra_options->rtpref = ND_RA_FLAG_RTPREF_MEDIUM;
+               }
+               | ROUTER PREFERENCE LOW {
+                       ra_options->rtpref = ND_RA_FLAG_RTPREF_LOW;
+               }
                | REACHABLE TIME NUMBER {
                        ra_options->reachable_time = $3;
                }
@@ -507,18 +517,22 @@ 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},
                {"nat64",               NAT64},
                {"no",                  NO},
                {"on-link",             ONLINK},
                {"other",               OTHER},
+               {"preference",          PREFERENCE},
                {"preferred",           PREFERRED},
                {"prefix",              PREFIX},
                {"reachable",           REACHABLE},
index f664e58..184a5df 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: printconf.c,v 1.7 2022/10/15 13:26:15 florian Exp $   */
+/*     $OpenBSD: printconf.c,v 1.8 2024/04/23 22:11:59 florian Exp $   */
 
 /*
  * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -23,6 +23,7 @@
 #include <sys/uio.h>
 
 #include <netinet/in.h>
+#include <netinet/icmp6.h>
 #include <net/if.h>
 
 #include <arpa/inet.h>
@@ -34,6 +35,7 @@
 #include "rad.h"
 
 const char*    yesno(int);
+const char*    rtpref(int);
 void           print_ra_options(const char*, const struct ra_options_conf*);
 void           print_prefix_options(const char*, const struct ra_prefix_conf*);
 
@@ -43,6 +45,22 @@ yesno(int flag)
        return flag ? "yes" : "no";
 }
 
+const char*
+rtpref(int rtpref)
+{
+       switch (rtpref & ND_RA_FLAG_RTPREF_MASK) {
+       case ND_RA_FLAG_RTPREF_HIGH:
+               return "high";
+       case ND_RA_FLAG_RTPREF_MEDIUM:
+               return "medium";
+       case ND_RA_FLAG_RTPREF_LOW:
+               return "low";
+       default:
+               return "invalid";
+       }
+
+}
+
 void
 print_ra_options(const char *indent, const struct ra_options_conf *ra_options)
 {
@@ -56,6 +74,7 @@ print_ra_options(const char *indent, const struct ra_options_conf *ra_options)
        printf("%smanaged address configuration %s\n", indent,
            yesno(ra_options->m_flag));
        printf("%sother configuration %s\n", indent, yesno(ra_options->o_flag));
+       printf("%srouter preference %s\n", indent, rtpref(ra_options->rtpref));
        printf("%srouter lifetime %d\n", indent, ra_options->router_lifetime);
        printf("%sreachable time %u\n", indent, ra_options->reachable_time);
        printf("%sretrans timer %u\n", indent, ra_options->retrans_timer);
index 3f71a9a..4b45b11 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: rad.conf.5,v 1.21 2023/04/27 16:56:52 phessler Exp $
+.\"    $OpenBSD: rad.conf.5,v 1.22 2024/04/23 22:11:59 florian Exp $
 .\"
 .\" Copyright (c) 2018 Florian Obser <florian@openbsd.org>
 .\" Copyright (c) 2005 Esben Norby <norby@openbsd.org>
@@ -18,7 +18,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: April 27 2023 $
+.Dd $Mdocdate: April 23 2024 $
 .Dt RAD.CONF 5
 .Os
 .Sh NAME
@@ -120,6 +120,9 @@ like NTP servers or DNS name servers.
 The number of seconds this router is a valid default router after receiving
 a router advertisement message.
 The default is 1800 seconds.
+.It Ic router preference Pq Ic high Ns | Ns Ic medium Ns | Ns Ic low
+Indicates whether to prefer this router over other default routers.
+The default is medium.
 .\" .It Ic reachable time Ar number
 .\" XXX
 .\" .It Ic retrans timer Ar number
index 714bb93..787e78c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rad.h,v 1.25 2023/04/27 16:56:52 phessler Exp $       */
+/*     $OpenBSD: rad.h,v 1.26 2024/04/23 22:11:59 florian Exp $        */
 
 /*
  * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -93,6 +93,7 @@ struct ra_options_conf {
        int             cur_hl;                 /* current hop limit */
        int             m_flag;                 /* managed address conf flag */
        int             o_flag;                 /* other conf flag */
+       int             rtpref;                 /* router preference */
        int             router_lifetime;        /* default router lifetime */
        uint32_t        reachable_time;
        uint32_t        retrans_timer;