diff mbox series

[RFC,net-next,2/4] ipv6: fib6_rules: support for match on sport, dport and ip proto

Message ID 1518387989-33735-3-git-send-email-roopa@cumulusnetworks.com
State RFC, archived
Delegated to: David Miller
Headers show
Series None | expand

Commit Message

Roopa Prabhu Feb. 11, 2018, 10:26 p.m. UTC
From: Roopa Prabhu <roopa@cumulusnetworks.com>

Add support to match on src port, dst port and ip protocol.

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
---
 net/ipv6/fib6_rules.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 46 insertions(+), 3 deletions(-)
diff mbox series

Patch

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 = {