ip rule: Add ipproto and port range to filter list
Allow ip rule dumps and flushes to filter based on ipproto, sport and dport. Example: $ ip ru ls ipproto udp 99: from all to 8.8.8.8 ipproto udp dport 53 lookup 1001 $ ip ru ls dport 53 99: from all to 8.8.8.8 ipproto udp dport 53 lookup 1001 Signed-off-by: David Ahern <dsahern@gmail.com>
This commit is contained in:
parent
70bc1f6550
commit
b2e8bf1584
66
ip/iprule.c
66
ip/iprule.c
|
|
@ -78,6 +78,9 @@ static struct
|
|||
inet_prefix dst;
|
||||
int protocol;
|
||||
int protocolmask;
|
||||
struct fib_rule_port_range sport;
|
||||
struct fib_rule_port_range dport;
|
||||
__u8 ipproto;
|
||||
} filter;
|
||||
|
||||
static inline int frh_get_table(struct fib_rule_hdr *frh, struct rtattr **tb)
|
||||
|
|
@ -174,6 +177,39 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (filter.ipproto) {
|
||||
__u8 ipproto = 0;
|
||||
|
||||
if (tb[FRA_IP_PROTO])
|
||||
ipproto = rta_getattr_u8(tb[FRA_IP_PROTO]);
|
||||
if (filter.ipproto != ipproto)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filter.sport.start) {
|
||||
const struct fib_rule_port_range *r;
|
||||
|
||||
if (!tb[FRA_SPORT_RANGE])
|
||||
return false;
|
||||
|
||||
r = RTA_DATA(tb[FRA_SPORT_RANGE]);
|
||||
if (r->start != filter.sport.start ||
|
||||
r->end != filter.sport.end)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filter.dport.start) {
|
||||
const struct fib_rule_port_range *r;
|
||||
|
||||
if (!tb[FRA_DPORT_RANGE])
|
||||
return false;
|
||||
|
||||
r = RTA_DATA(tb[FRA_DPORT_RANGE]);
|
||||
if (r->start != filter.dport.start ||
|
||||
r->end != filter.dport.end)
|
||||
return false;
|
||||
}
|
||||
|
||||
table = frh_get_table(frh, tb);
|
||||
if (filter.tb > 0 && filter.tb ^ table)
|
||||
return false;
|
||||
|
|
@ -607,6 +643,36 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
|
|||
filter.protocolmask = 0;
|
||||
}
|
||||
filter.protocol = prot;
|
||||
} else if (strcmp(*argv, "ipproto") == 0) {
|
||||
int ipproto;
|
||||
|
||||
NEXT_ARG();
|
||||
ipproto = inet_proto_a2n(*argv);
|
||||
if (ipproto < 0)
|
||||
invarg("Invalid \"ipproto\" value\n", *argv);
|
||||
filter.ipproto = ipproto;
|
||||
} else if (strcmp(*argv, "sport") == 0) {
|
||||
struct fib_rule_port_range r;
|
||||
int ret;
|
||||
|
||||
NEXT_ARG();
|
||||
ret = sscanf(*argv, "%hu-%hu", &r.start, &r.end);
|
||||
if (ret == 1)
|
||||
r.end = r.start;
|
||||
else if (ret != 2)
|
||||
invarg("invalid port range\n", *argv);
|
||||
filter.sport = r;
|
||||
} else if (strcmp(*argv, "dport") == 0) {
|
||||
struct fib_rule_port_range r;
|
||||
int ret;
|
||||
|
||||
NEXT_ARG();
|
||||
ret = sscanf(*argv, "%hu-%hu", &r.start, &r.end);
|
||||
if (ret == 1)
|
||||
r.end = r.start;
|
||||
else if (ret != 2)
|
||||
invarg("invalid dport range\n", *argv);
|
||||
filter.dport = r;
|
||||
} else{
|
||||
if (matches(*argv, "dst") == 0 ||
|
||||
matches(*argv, "to") == 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue