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;
|
inet_prefix dst;
|
||||||
int protocol;
|
int protocol;
|
||||||
int protocolmask;
|
int protocolmask;
|
||||||
|
struct fib_rule_port_range sport;
|
||||||
|
struct fib_rule_port_range dport;
|
||||||
|
__u8 ipproto;
|
||||||
} filter;
|
} filter;
|
||||||
|
|
||||||
static inline int frh_get_table(struct fib_rule_hdr *frh, struct rtattr **tb)
|
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;
|
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);
|
table = frh_get_table(frh, tb);
|
||||||
if (filter.tb > 0 && filter.tb ^ table)
|
if (filter.tb > 0 && filter.tb ^ table)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -607,6 +643,36 @@ static int iprule_list_flush_or_save(int argc, char **argv, int action)
|
||||||
filter.protocolmask = 0;
|
filter.protocolmask = 0;
|
||||||
}
|
}
|
||||||
filter.protocol = prot;
|
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{
|
} else{
|
||||||
if (matches(*argv, "dst") == 0 ||
|
if (matches(*argv, "dst") == 0 ||
|
||||||
matches(*argv, "to") == 0) {
|
matches(*argv, "to") == 0) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue