fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n");
fprintf(stderr, " [ mark NUMBER ] [ vrf NAME ]\n");
+ fprintf(stderr, " [ 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 ] [ vrf NAME ] [ proto RTPROTO ]\n");
fprintf(fp, "%s ",
rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
}
+
+ if (tb[RTA_UID])
+ fprintf(fp, "uid %u ", rta_getattr_u32(tb[RTA_UID]));
+
if ((r->rtm_flags&RTM_F_CLONED) && r->rtm_family == AF_INET) {
__u32 flags = r->rtm_flags&~0xFFFF;
int first = 1;
if (!name_is_vrf(*argv))
invarg("Invalid VRF\n", *argv);
odev = *argv;
+ } else if (matches(*argv, "uid") == 0) {
+ uid_t uid;
+
+ NEXT_ARG();
+ if (get_unsigned(&uid, *argv, 0))
+ invarg("invalid UID\n", *argv);
+ addattr32(&req.n, sizeof(req), RTA_UID, uid);
} else {
inet_prefix addr;
" ip rule [ list [ SELECTOR ]]\n"
"SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n"
" [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]\n"
+ " [ uidrange NUMBER-NUMBER ]\n"
"ACTION := [ table TABLE_ID ]\n"
" [ nat ADDRESS ]\n"
" [ realms [SRCREALM/]DSTREALM ]\n"
{
int not;
int l3mdev;
- int iifmask, oifmask;
+ int iifmask, oifmask, uidrange;
unsigned int tb;
unsigned int tos, tosmask;
unsigned int pref, prefmask;
unsigned int fwmark, fwmask;
char iif[IFNAMSIZ];
char oif[IFNAMSIZ];
+ struct fib_rule_uid_range range;
inet_prefix src;
inet_prefix dst;
} filter;
if (filter.l3mdev && !(tb[FRA_L3MDEV] && rta_getattr_u8(tb[FRA_L3MDEV])))
return false;
+ if (filter.uidrange) {
+ struct fib_rule_uid_range *r = RTA_DATA(tb[FRA_UID_RANGE]);
+
+ if (!tb[FRA_UID_RANGE] ||
+ r->start != filter.range.start ||
+ r->end != filter.range.end)
+ return false;
+ }
+
table = rtm_get_table(r, tb);
if (filter.tb > 0 && filter.tb ^ table)
return false;
fprintf(fp, "lookup [l3mdev-table] ");
}
+ if (tb[FRA_UID_RANGE]) {
+ struct fib_rule_uid_range *r = RTA_DATA(tb[FRA_UID_RANGE]);
+
+ fprintf(fp, "uidrange %u-%u ", r->start, r->end);
+ }
+
table = rtm_get_table(r, tb);
if (table) {
fprintf(fp, "lookup %s ",
filter.oifmask = 1;
} else if (strcmp(*argv, "l3mdev") == 0) {
filter.l3mdev = 1;
+ } else if (strcmp(*argv, "uidrange") == 0) {
+ NEXT_ARG();
+ filter.uidrange = 1;
+ if (sscanf(*argv, "%u-%u",
+ &filter.range.start,
+ &filter.range.end) != 2)
+ invarg("invalid UID range\n", *argv);
+
} else if (matches(*argv, "lookup") == 0 ||
matches(*argv, "table") == 0) {
__u32 tid;
addattr8(&req.n, sizeof(req), FRA_L3MDEV, 1);
table_ok = 1;
l3mdev_rule = 1;
+ } else if (strcmp(*argv, "uidrange") == 0) {
+ struct fib_rule_uid_range r;
+
+ NEXT_ARG();
+ if (sscanf(*argv, "%u-%u", &r.start, &r.end) != 2)
+ invarg("invalid UID range\n", *argv);
+ addattr_l(&req.n, sizeof(req), FRA_UID_RANGE, &r,
+ sizeof(r));
} else if (strcmp(*argv, "nat") == 0 ||
matches(*argv, "map-to") == 0) {
NEXT_ARG();