aboutsummaryrefslogtreecommitdiffstats
path: root/ip/iproute.c
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2015-03-16 16:01:47 +0100
committerStephen Hemminger <shemming@brocade.com>2015-03-24 15:45:23 -0700
commit194e9b855d05310cb3c400b1ca7fce3deca7c96a (patch)
treee63624a4bc0647908520202ff4a63ec348e3ce6c /ip/iproute.c
parentdacc5d4197c1f8ac12938a594f7e4131cb937cb2 (diff)
downloadplatform_external_iproute2-194e9b855d05310cb3c400b1ca7fce3deca7c96a.tar.gz
platform_external_iproute2-194e9b855d05310cb3c400b1ca7fce3deca7c96a.tar.bz2
platform_external_iproute2-194e9b855d05310cb3c400b1ca7fce3deca7c96a.zip
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: Lubomir Rintel <lkundrak@v3.sk>
Diffstat (limited to 'ip/iproute.c')
-rw-r--r--ip/iproute.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/ip/iproute.c b/ip/iproute.c
index e086b1f5..132a83a7 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -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;