[PATCH RFC net-next 2/4] ipv6: fib6_rules: support for match on sport, dport and ip proto
From: Roopa Prabhu <hidden>
Date: 2018-02-11 22:26:37
Subsystem:
networking [general], networking [ipv4/ipv6], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds
From: Roopa Prabhu <redacted> Add support to match on src port, dst port and ip protocol. Signed-off-by: Roopa Prabhu <redacted> --- net/ipv6/fib6_rules.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index b240f24..57c0836 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c@@ -28,13 +28,17 @@ struct fib6_rule { struct rt6key src; struct rt6key dst; u8 tclass; + u8 proto; + __be16 sport; + __be16 dport; }; static bool fib6_rule_matchall(const struct fib_rule *rule) { struct fib6_rule *r = container_of(rule, struct fib6_rule, common); - if (r->dst.plen || r->src.plen || r->tclass) + if (r->dst.plen || r->src.plen || r->tclass || r->proto || r->sport || + r->dport) return false; return fib_rule_matchall(rule); }
@@ -223,6 +227,15 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) if (r->tclass && r->tclass != ip6_tclass(fl6->flowlabel)) return 0; + if (r->proto && r->proto != fl6->flowi6_proto) + return 0; + + if (r->sport && r->sport != fl6->fl6_sport) + return 0; + + if (r->dport && r->dport != fl6->fl6_dport) + return 0; + return 1; }
@@ -258,6 +271,15 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, rule6->dst.plen = frh->dst_len; rule6->tclass = frh->tos; + if (tb[FRA_PROTO]) + rule6->proto = nla_get_u8(tb[FRA_PROTO]); + + if (tb[FRA_SPORT]) + rule6->sport = nla_get_be16(tb[FRA_SPORT]); + + if (tb[FRA_DPORT]) + rule6->dport = nla_get_be16(tb[FRA_DPORT]); + net->ipv6.fib6_has_custom_rules = true; err = 0; errout:
@@ -286,6 +308,18 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) return 0; + if (tb[FRA_PROTO] && + (rule6->proto != nla_get_u8(tb[FRA_PROTO]))) + return 0; + + if (tb[FRA_SPORT] && + (rule6->sport != nla_get_be32(tb[FRA_SPORT]))) + return 0; + + if (tb[FRA_DPORT] && + (rule6->dport != nla_get_be32(tb[FRA_DPORT]))) + return 0; + return 1; }
@@ -301,7 +335,13 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb, if ((rule6->dst.plen && nla_put_in6_addr(skb, FRA_DST, &rule6->dst.addr)) || (rule6->src.plen && - nla_put_in6_addr(skb, FRA_SRC, &rule6->src.addr))) + nla_put_in6_addr(skb, FRA_SRC, &rule6->src.addr)) || + (rule6->proto && + nla_put_u8(skb, FRA_PROTO, rule6->proto)) || + (rule6->sport && + nla_put_be16(skb, FRA_SPORT, rule6->sport)) || + (rule6->dport && + nla_put_be16(skb, FRA_DPORT, rule6->dport))) goto nla_put_failure; return 0;
@@ -312,7 +352,10 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb, static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) { return nla_total_size(16) /* dst */ - + nla_total_size(16); /* src */ + + nla_total_size(16) /* src */ + + nla_total_size(1) /* proto */ + + nla_total_size(2) /* sport */ + + nla_total_size(2); /* dport */ } static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = {
--
2.1.4