ip rule: Add ipproto and port range to filter list
Subsystems (2)
PATCH 1/1 ip rule: Add ipproto and port range to filter list
From: David Ahern <[email protected]>
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 <[email protected]>
--- ip/iprule.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+)
ip/iprule.c +66 -0
@@ -78,6 +78,9 @@ static structinet_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 =0 ; + +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 =0 ; + +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 ) {
Signature · 1 line
2.11.0