IPv4 multipath algorithm selection support
diff --git a/ip/iproute.c b/ip/iproute.c
index b2ddb6e..5101178 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -28,6 +28,7 @@
 #include <netinet/ip.h>
 #include <arpa/inet.h>
 #include <linux/in_route.h>
+#include <linux/ip_mp_alg.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -53,6 +54,7 @@
 	fprintf(stderr, "NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]\n");
 	fprintf(stderr, "             [ table TABLE_ID ] [ proto RTPROTO ]\n");
 	fprintf(stderr, "             [ scope SCOPE ] [ metric METRIC ]\n");
+	fprintf(stderr, "             [ mpath MP_ALGO ]\n");
 	fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n");
 	fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n");
 	fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n");
@@ -64,6 +66,7 @@
 	fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n");
 	fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n");
 	fprintf(stderr, "FLAGS := [ equalize ]\n");
+	fprintf(stderr, "MP_ALGO := { rr | drr | random | wrandom }\n");
 	fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n");
 	fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n");
 	exit(-1);
@@ -93,6 +96,14 @@
 	inet_prefix msrc;
 } filter;
 
+static char *mp_alg_names[IP_MP_ALG_MAX+1] = {
+	[IP_MP_ALG_NONE] = "none",
+	[IP_MP_ALG_RR] = "rr",
+	[IP_MP_ALG_DRR] = "drr",
+	[IP_MP_ALG_RANDOM] = "random",
+	[IP_MP_ALG_WRANDOM] = "wrandom"
+};
+
 static int flush_update(void)
 {
 	if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
@@ -324,6 +335,15 @@
 		SPRINT_BUF(b1);
 		fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
 	}
+
+	if (tb[RTA_MP_ALGO]) {
+		__u32 mp_alg = *(__u32*) RTA_DATA(tb[RTA_MP_ALGO]);
+		if (mp_alg > IP_MP_ALG_NONE) {
+			fprintf(fp, "mpath %s ",
+			    mp_alg < IP_MP_ALG_MAX ? mp_alg_names[mp_alg] : "unknown");
+		}
+	}
+
 	if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) {
 		fprintf(fp, "via %s ", 
 			format_host(r->rtm_family,
@@ -828,6 +848,18 @@
 			   strcmp(*argv, "oif") == 0) {
 			NEXT_ARG();
 			d = *argv;
+		} else if (strcmp(*argv, "mpath") == 0 ||
+			   strcmp(*argv, "mp") == 0) {
+			int i;
+			__u32 mp_alg = IP_MP_ALG_NONE;
+
+			NEXT_ARG();
+			for (i = 1; i < ARRAY_SIZE(mp_alg_names); i++)
+				if (strcmp(*argv, mp_alg_names[i]) == 0)
+					mp_alg = i;
+			if (mp_alg == IP_MP_ALG_NONE)
+				invarg("\"mpath\" value is invalid\n", *argv);
+			addattr_l(&req.n, sizeof(req), RTA_MP_ALGO, &mp_alg, sizeof(mp_alg));
 		} else {
 			int type;
 			inet_prefix dst;