From ec8d7120bf3b8fd47937e9297468e0bb7c1f270c Mon Sep 17 00:00:00 2001 From: Andrea Claudi Date: Wed, 29 May 2019 17:40:35 +0200 Subject: [PATCH] ip rule: Add ipproto and port range to filter list Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1678111 Upstream Status: iproute2.git commit b2e8bf1584605 commit b2e8bf158460568ec5b48cba69f657f95891c901 Author: David Ahern Date: Tue Oct 30 15:03:30 2018 -0700 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 --- ip/iprule.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/ip/iprule.c b/ip/iprule.c index 744d6d88e3433..33160eafa2b33 100644 --- a/ip/iprule.c +++ b/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; @@ -604,6 +640,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) { -- 2.20.1