]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ip: support RFC4191 router preference
authorLubomir Rintel <lkundrak@v3.sk>
Mon, 16 Mar 2015 15:01:47 +0000 (16:01 +0100)
committerStephen Hemminger <shemming@brocade.com>
Tue, 24 Mar 2015 22:45:23 +0000 (15:45 -0700)
This allows querying and setting the route preference. It's usually set from
the IPv6 Neighbor Discovery Router Advertisement messages.

Introduced in "ipv6: expose RFC4191 route preference via rtnetlink", enqueued
for Linux 4.1.

Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
doc/ip-cref.tex
ip/iproute.c
man/man8/ip-route.8.in

index e7a79a5d24c846d652d21aafa51f0e3edd67369d..ea147950ff4af1795301db26a1ed937120bf76a0 100644 (file)
@@ -1432,6 +1432,17 @@ database.
 even if it does not match any interface prefix. One application of this
 option may be found in~\cite{IP-TUNNELS}.
 
+\item \verb|pref PREF|
+
+--- the IPv6 route preference.
+\verb|PREF| PREF is a string specifying the route preference as defined in
+RFC4191 for Router Discovery messages. Namely:
+\begin{itemize}
+\item \verb|low| --- the route has a lowest priority.
+\item \verb|medium| --- the route has a default priority.
+\item \verb|high| --- the route has a highest priority.
+\end{itemize}
+
 \end{itemize}
 
 
index e086b1f54ee53486da9c550164e8c54cbbfbd59c..132a83a7a139333014208fe6e04a919503befc39 100644 (file)
@@ -23,6 +23,7 @@
 #include <netinet/ip.h>
 #include <arpa/inet.h>
 #include <linux/in_route.h>
+#include <linux/icmpv6.h>
 #include <errno.h>
 
 #include "rt_names.h"
@@ -83,12 +84,14 @@ static void usage(void)
        fprintf(stderr, "           [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n");
        fprintf(stderr, "           [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n");
        fprintf(stderr, "           [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ]\n");
+       fprintf(stderr, "           [ pref PREF ]\n");
        fprintf(stderr, "TYPE := [ unicast | local | broadcast | multicast | throw |\n");
        fprintf(stderr, "          unreachable | prohibit | blackhole | nat ]\n");
        fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n");
        fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n");
        fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n");
        fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n");
+       fprintf(stderr, "PREF := [ low | medium | high ]\n");
        fprintf(stderr, "TIME := NUMBER[s|ms]\n");
        fprintf(stderr, "BOOL := [1|0]\n");
        fprintf(stderr, "FEATURES := ecn\n");
@@ -671,6 +674,24 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
                        nh = RTNH_NEXT(nh);
                }
        }
+       if (tb[RTA_PREF]) {
+               unsigned int pref = rta_getattr_u8(tb[RTA_PREF]);
+               fprintf(fp, " pref ");
+
+               switch (pref) {
+               case ICMPV6_ROUTER_PREF_LOW:
+                       fprintf(fp, "low");
+                       break;
+               case ICMPV6_ROUTER_PREF_MEDIUM:
+                       fprintf(fp, "medium");
+                       break;
+               case ICMPV6_ROUTER_PREF_HIGH:
+                       fprintf(fp, "high");
+                       break;
+               default:
+                       fprintf(fp, "%u", pref);
+               }
+       }
        fprintf(fp, "\n");
        fflush(fp);
        return 0;
@@ -854,7 +875,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
                        req.r.rtm_tos = tos;
                } else if (matches(*argv, "metric") == 0 ||
                           matches(*argv, "priority") == 0 ||
-                          matches(*argv, "preference") == 0) {
+                          strcmp(*argv, "preference") == 0) {
                        __u32 metric;
                        NEXT_ARG();
                        if (get_u32(&metric, *argv, 0))
@@ -1051,6 +1072,18 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
                           strcmp(*argv, "oif") == 0) {
                        NEXT_ARG();
                        d = *argv;
+               } else if (matches(*argv, "pref") == 0) {
+                       __u8 pref;
+                       NEXT_ARG();
+                       if (strcmp(*argv, "low") == 0)
+                               pref = ICMPV6_ROUTER_PREF_LOW;
+                       else if (strcmp(*argv, "medium") == 0)
+                               pref = ICMPV6_ROUTER_PREF_MEDIUM;
+                       else if (strcmp(*argv, "high") == 0)
+                               pref = ICMPV6_ROUTER_PREF_HIGH;
+                       else if (get_u8(&pref, *argv, 0))
+                               invarg("\"pref\" value is invalid\n", *argv);
+                       addattr8(&req.n, sizeof(req), RTA_PREF, pref);
                } else {
                        int type;
                        inet_prefix dst;
index 1163536d0e9c900c5dee82c9b9258fd292d1d8fc..7fee69f111d69b7c962f0993a3d8cbcf7c8442b9 100644 (file)
@@ -129,6 +129,8 @@ replace " } "
 .IR BOOL " ] [ "
 .B  congctl
 .IR NAME " ]"
+.B  pref
+.IR PREF " ]"
 
 .ti -8
 .IR TYPE " := [ "
@@ -158,6 +160,10 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
 .IR FEATURES " := [ "
 .BR ecn " | ]"
 
+.ti -8
+.IR PREF " := [ "
+.BR low " | " medium " | " high " ]"
+
 
 .SH DESCRIPTION
 .B ip route
@@ -562,6 +568,28 @@ to assign (or not to assign) protocol tags.
 .B onlink
 pretend that the nexthop is directly attached to this link,
 even if it does not match any interface prefix.
+
+.TP
+.BI pref " PREF"
+the IPv6 route preference.
+.I PREF
+is a string specifying the route preference as defined in RFC4191 for Router
+Discovery messages. Namely:
+
+.in +8
+.B low
+- the route has a lowest priority
+.sp
+
+.B medium
+- the route has a default priority
+.sp
+
+.B high
+- the route has a highest priority
+.sp
+
+.in -8
 .RE
 
 .TP