am c0ed926d: am 39c15e7b: Merge "Support experimental UID range routing."

* commit 'c0ed926d42a0d24095991bc1df603e629b9a7323':
  Support experimental UID range routing.
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index 51da65b..106d35f 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -49,6 +49,8 @@
 	FRA_TABLE,	/* Extended table id */
 	FRA_FWMASK,	/* mask for netfilter mark */
 	FRA_OIFNAME,
+	FRA_UID_START,
+	FRA_UID_END,
 	__FRA_MAX
 };
 
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index d5b7fdd..4ee1f37 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -283,6 +283,8 @@
 	RTA_MP_ALGO, /* no longer used */
 	RTA_TABLE,
 	RTA_MARK,
+	RTA_MFC_STATS, /* not used - backported from the future */
+	RTA_UID,
 	__RTA_MAX
 };
 
diff --git a/ip/iproute.c b/ip/iproute.c
index 5cd313e..8dc0bc8 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -62,7 +62,7 @@
 	fprintf(stderr, "       ip route restore\n");
 	fprintf(stderr, "       ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
 	fprintf(stderr, "                            [ oif STRING ]  [ tos TOS ]\n");
-	fprintf(stderr, "                            [ mark NUMBER ]\n");
+	fprintf(stderr, "                            [ mark NUMBER ] [ uid NUMBER ]\n");
 	fprintf(stderr, "       ip route { add | del | change | append | replace } ROUTE\n");
 	fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n");
 	fprintf(stderr, "            [ table TABLE_ID ] [ proto RTPROTO ]\n");
@@ -423,6 +423,9 @@
 		}
 	}
 
+	if (tb[RTA_UID])
+		fprintf(fp, " uid %u ", rta_getattr_u32(tb[RTA_UID]));
+
 	if (tb[RTA_FLOW] && filter.realmmask != ~0U) {
 		__u32 to = rta_getattr_u32(tb[RTA_FLOW]);
 		__u32 from = to>>16;
@@ -1401,6 +1404,11 @@
 			   strcmp(*argv, "dev") == 0) {
 			NEXT_ARG();
 			odev = *argv;
+		} else if (matches(*argv, "uid") == 0) {
+		        uid_t uid;
+			NEXT_ARG();
+			get_unsigned(&uid, *argv, 0);
+			addattr32(&req.n, sizeof(req), RTA_UID, uid);
 		} else if (matches(*argv, "notify") == 0) {
 			req.r.rtm_flags |= RTM_F_NOTIFY;
 		} else if (matches(*argv, "connected") == 0) {
diff --git a/ip/iprule.c b/ip/iprule.c
index a5fcd43..3ea0e81 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -34,7 +34,7 @@
 {
 	fprintf(stderr, "Usage: ip rule [ list | add | del | flush ] SELECTOR ACTION\n");
 	fprintf(stderr, "SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n");
-	fprintf(stderr, "            [ iif STRING ] [ oif STRING ] [ pref NUMBER ]\n");
+	fprintf(stderr, "            [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ uidrange UID1-UID2 ]\n");
 	fprintf(stderr, "ACTION := [ table TABLE_ID ]\n");
 	fprintf(stderr, "          [ prohibit | reject | unreachable ]\n");
 	fprintf(stderr, "          [ realms [SRCREALM/]DSTREALM ]\n");
@@ -49,7 +49,7 @@
 	struct rtmsg *r = NLMSG_DATA(n);
 	int len = n->nlmsg_len;
 	int host_len = -1;
-	__u32 table;
+	__u32 table, uid_start, uid_end;
 	struct rtattr * tb[FRA_MAX+1];
 	char abuf[256];
 	SPRINT_BUF(b1);
@@ -152,6 +152,19 @@
 			fprintf(fp, "[detached] ");
 	}
 
+	if (tb[FRA_UID_START] || tb[FRA_UID_END]) {
+		fprintf(fp, "uidrange ");
+		if (tb[FRA_UID_START])
+			fprintf(fp, "%u", rta_getattr_u32(tb[FRA_UID_START]));
+		else
+			fprintf(fp, "???");
+
+		if (tb[FRA_UID_END])
+			fprintf(fp, "-%u ", rta_getattr_u32(tb[FRA_UID_END]));
+		else
+			fprintf(fp, "-??? ");
+	}
+
 	table = rtm_get_table(r, tb);
 	if (table)
 		fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
@@ -323,6 +336,13 @@
 			fprintf(stderr, "Warning: route NAT is deprecated\n");
 			addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv));
 			req.r.rtm_type = RTN_NAT;
+		} else if (strcmp(*argv, "uidrange") == 0) {
+			__u32 uid_start, uid_end;
+			NEXT_ARG();
+			if (sscanf(*argv, "%u-%u", &uid_start, &uid_end) != 2)
+				invarg("UID range is invalid\n", *argv);
+			addattr32(&req.n, sizeof(req), FRA_UID_START, uid_start);
+			addattr32(&req.n, sizeof(req), FRA_UID_END, uid_end);
 		} else {
 			int type;