ip: support UID range routing.
- Support adding, deleting and showing IP rules with UID ranges.
- Support querying per-UID routes via "ip route get uid <UID>".
UID range routing was added to net-next in 4fb7450683 ("Merge
branch 'uid-routing'")
Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
This commit is contained in:
parent
512caeb273
commit
82252cdc50
12
ip/iproute.c
12
ip/iproute.c
|
|
@ -68,6 +68,7 @@ static void usage(void)
|
||||||
fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
|
fprintf(stderr, " ip route get ADDRESS [ from ADDRESS iif STRING ]\n");
|
||||||
fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n");
|
fprintf(stderr, " [ oif STRING ] [ tos TOS ]\n");
|
||||||
fprintf(stderr, " [ mark NUMBER ] [ vrf NAME ]\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, " ip route { add | del | change | append | replace } ROUTE\n");
|
||||||
fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n");
|
fprintf(stderr, "SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ]\n");
|
||||||
fprintf(stderr, " [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]\n");
|
fprintf(stderr, " [ table TABLE_ID ] [ vrf NAME ] [ proto RTPROTO ]\n");
|
||||||
|
|
@ -471,6 +472,10 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
||||||
fprintf(fp, "%s ",
|
fprintf(fp, "%s ",
|
||||||
rtnl_rtrealm_n2a(to, b1, sizeof(b1)));
|
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) {
|
if ((r->rtm_flags&RTM_F_CLONED) && r->rtm_family == AF_INET) {
|
||||||
__u32 flags = r->rtm_flags&~0xFFFF;
|
__u32 flags = r->rtm_flags&~0xFFFF;
|
||||||
int first = 1;
|
int first = 1;
|
||||||
|
|
@ -1684,6 +1689,13 @@ static int iproute_get(int argc, char **argv)
|
||||||
if (!name_is_vrf(*argv))
|
if (!name_is_vrf(*argv))
|
||||||
invarg("Invalid VRF\n", *argv);
|
invarg("Invalid VRF\n", *argv);
|
||||||
odev = *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 {
|
} else {
|
||||||
inet_prefix addr;
|
inet_prefix addr;
|
||||||
|
|
||||||
|
|
|
||||||
35
ip/iprule.c
35
ip/iprule.c
|
|
@ -46,6 +46,7 @@ static void usage(void)
|
||||||
" ip rule [ list [ SELECTOR ]]\n"
|
" ip rule [ list [ SELECTOR ]]\n"
|
||||||
"SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n"
|
"SELECTOR := [ not ] [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK[/MASK] ]\n"
|
||||||
" [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]\n"
|
" [ iif STRING ] [ oif STRING ] [ pref NUMBER ] [ l3mdev ]\n"
|
||||||
|
" [ uidrange NUMBER-NUMBER ]\n"
|
||||||
"ACTION := [ table TABLE_ID ]\n"
|
"ACTION := [ table TABLE_ID ]\n"
|
||||||
" [ nat ADDRESS ]\n"
|
" [ nat ADDRESS ]\n"
|
||||||
" [ realms [SRCREALM/]DSTREALM ]\n"
|
" [ realms [SRCREALM/]DSTREALM ]\n"
|
||||||
|
|
@ -61,13 +62,14 @@ static struct
|
||||||
{
|
{
|
||||||
int not;
|
int not;
|
||||||
int l3mdev;
|
int l3mdev;
|
||||||
int iifmask, oifmask;
|
int iifmask, oifmask, uidrange;
|
||||||
unsigned int tb;
|
unsigned int tb;
|
||||||
unsigned int tos, tosmask;
|
unsigned int tos, tosmask;
|
||||||
unsigned int pref, prefmask;
|
unsigned int pref, prefmask;
|
||||||
unsigned int fwmark, fwmask;
|
unsigned int fwmark, fwmask;
|
||||||
char iif[IFNAMSIZ];
|
char iif[IFNAMSIZ];
|
||||||
char oif[IFNAMSIZ];
|
char oif[IFNAMSIZ];
|
||||||
|
struct fib_rule_uid_range range;
|
||||||
inet_prefix src;
|
inet_prefix src;
|
||||||
inet_prefix dst;
|
inet_prefix dst;
|
||||||
} filter;
|
} filter;
|
||||||
|
|
@ -151,6 +153,15 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
||||||
if (filter.l3mdev && !(tb[FRA_L3MDEV] && rta_getattr_u8(tb[FRA_L3MDEV])))
|
if (filter.l3mdev && !(tb[FRA_L3MDEV] && rta_getattr_u8(tb[FRA_L3MDEV])))
|
||||||
return false;
|
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);
|
table = rtm_get_table(r, tb);
|
||||||
if (filter.tb > 0 && filter.tb ^ table)
|
if (filter.tb > 0 && filter.tb ^ table)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -259,6 +270,12 @@ int print_rule(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
|
||||||
fprintf(fp, "lookup [l3mdev-table] ");
|
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);
|
table = rtm_get_table(r, tb);
|
||||||
if (table) {
|
if (table) {
|
||||||
fprintf(fp, "lookup %s ",
|
fprintf(fp, "lookup %s ",
|
||||||
|
|
@ -463,6 +480,14 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
|
||||||
filter.oifmask = 1;
|
filter.oifmask = 1;
|
||||||
} else if (strcmp(*argv, "l3mdev") == 0) {
|
} else if (strcmp(*argv, "l3mdev") == 0) {
|
||||||
filter.l3mdev = 1;
|
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 ||
|
} else if (matches(*argv, "lookup") == 0 ||
|
||||||
matches(*argv, "table") == 0) {
|
matches(*argv, "table") == 0) {
|
||||||
__u32 tid;
|
__u32 tid;
|
||||||
|
|
@ -680,6 +705,14 @@ static int iprule_modify(int cmd, int argc, char **argv)
|
||||||
addattr8(&req.n, sizeof(req), FRA_L3MDEV, 1);
|
addattr8(&req.n, sizeof(req), FRA_L3MDEV, 1);
|
||||||
table_ok = 1;
|
table_ok = 1;
|
||||||
l3mdev_rule = 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 ||
|
} else if (strcmp(*argv, "nat") == 0 ||
|
||||||
matches(*argv, "map-to") == 0) {
|
matches(*argv, "map-to") == 0) {
|
||||||
NEXT_ARG();
|
NEXT_ARG();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue