Commit 194e9b85 authored by Lubomir Rintel's avatar Lubomir Rintel Committed by Stephen Hemminger

ip: support RFC4191 router preference

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: default avatarLubomir Rintel <lkundrak@v3.sk>
parent dacc5d41
...@@ -1432,6 +1432,17 @@ database. ...@@ -1432,6 +1432,17 @@ database.
even if it does not match any interface prefix. One application of this even if it does not match any interface prefix. One application of this
option may be found in~\cite{IP-TUNNELS}. 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} \end{itemize}
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <netinet/ip.h> #include <netinet/ip.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/in_route.h> #include <linux/in_route.h>
#include <linux/icmpv6.h>
#include <errno.h> #include <errno.h>
#include "rt_names.h" #include "rt_names.h"
...@@ -83,12 +84,14 @@ static void usage(void) ...@@ -83,12 +84,14 @@ static void usage(void)
fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n"); fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n");
fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n"); fprintf(stderr, " [ rto_min TIME ] [ hoplimit NUMBER ] [ initrwnd NUMBER ]\n");
fprintf(stderr, " [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ]\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, "TYPE := [ unicast | local | broadcast | multicast | throw |\n");
fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n"); fprintf(stderr, " unreachable | prohibit | blackhole | nat ]\n");
fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n");
fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n"); fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n");
fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n"); fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n");
fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\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, "TIME := NUMBER[s|ms]\n");
fprintf(stderr, "BOOL := [1|0]\n"); fprintf(stderr, "BOOL := [1|0]\n");
fprintf(stderr, "FEATURES := ecn\n"); fprintf(stderr, "FEATURES := ecn\n");
...@@ -671,6 +674,24 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -671,6 +674,24 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
nh = RTNH_NEXT(nh); 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"); fprintf(fp, "\n");
fflush(fp); fflush(fp);
return 0; return 0;
...@@ -854,7 +875,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) ...@@ -854,7 +875,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
req.r.rtm_tos = tos; req.r.rtm_tos = tos;
} else if (matches(*argv, "metric") == 0 || } else if (matches(*argv, "metric") == 0 ||
matches(*argv, "priority") == 0 || matches(*argv, "priority") == 0 ||
matches(*argv, "preference") == 0) { strcmp(*argv, "preference") == 0) {
__u32 metric; __u32 metric;
NEXT_ARG(); NEXT_ARG();
if (get_u32(&metric, *argv, 0)) if (get_u32(&metric, *argv, 0))
...@@ -1051,6 +1072,18 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) ...@@ -1051,6 +1072,18 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
strcmp(*argv, "oif") == 0) { strcmp(*argv, "oif") == 0) {
NEXT_ARG(); NEXT_ARG();
d = *argv; 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 { } else {
int type; int type;
inet_prefix dst; inet_prefix dst;
......
...@@ -129,6 +129,8 @@ replace " } " ...@@ -129,6 +129,8 @@ replace " } "
.IR BOOL " ] [ " .IR BOOL " ] [ "
.B congctl .B congctl
.IR NAME " ]" .IR NAME " ]"
.B pref
.IR PREF " ]"
.ti -8 .ti -8
.IR TYPE " := [ " .IR TYPE " := [ "
...@@ -158,6 +160,10 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]" ...@@ -158,6 +160,10 @@ throw " | " unreachable " | " prohibit " | " blackhole " | " nat " ]"
.IR FEATURES " := [ " .IR FEATURES " := [ "
.BR ecn " | ]" .BR ecn " | ]"
.ti -8
.IR PREF " := [ "
.BR low " | " medium " | " high " ]"
.SH DESCRIPTION .SH DESCRIPTION
.B ip route .B ip route
...@@ -562,6 +568,28 @@ to assign (or not to assign) protocol tags. ...@@ -562,6 +568,28 @@ to assign (or not to assign) protocol tags.
.B onlink .B onlink
pretend that the nexthop is directly attached to this link, pretend that the nexthop is directly attached to this link,
even if it does not match any interface prefix. 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 .RE
.TP .TP
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment