aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/fib_rules.h2
-rw-r--r--include/linux/rtnetlink.h2
-rw-r--r--ip/iproute.c10
-rw-r--r--ip/iprule.c24
4 files changed, 35 insertions, 3 deletions
diff --git a/include/linux/fib_rules.h b/include/linux/fib_rules.h
index 51da65b6..106d35f9 100644
--- a/include/linux/fib_rules.h
+++ b/include/linux/fib_rules.h
@@ -49,6 +49,8 @@ enum {
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 d5b7fddf..4ee1f372 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -283,6 +283,8 @@ enum rtattr_type_t {
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 5cd313ed..8dc0bc8a 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -62,7 +62,7 @@ static void usage(void)
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 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
}
}
+ 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 @@ int iproute_get(int argc, char **argv)
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 a5fcd432..3ea0e81e 100644
--- a/ip/iprule.c
+++ b/ip/iprule.c
@@ -34,7 +34,7 @@ static void usage(void)
{
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 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
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 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
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 @@ static int iprule_modify(int cmd, int argc, char **argv)
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;