summaryrefslogtreecommitdiffstats
path: root/net/ipv6/fib6_rules.c
diff options
context:
space:
mode:
authorRoopa Prabhu2018-03-01 04:43:22 +0100
committerDavid S. Miller2018-03-01 04:44:44 +0100
commit5e5d6fed374155ba1a7a5ca5f12fbec2285d06a2 (patch)
tree92e19ce9d5e58ee33bbface8a6b5f4001c28a06c /net/ipv6/fib6_rules.c
parentipv6: route: dissect flow in input path if fib rules need it (diff)
downloadkernel-qcow2-linux-5e5d6fed374155ba1a7a5ca5f12fbec2285d06a2.tar.gz
kernel-qcow2-linux-5e5d6fed374155ba1a7a5ca5f12fbec2285d06a2.tar.xz
kernel-qcow2-linux-5e5d6fed374155ba1a7a5ca5f12fbec2285d06a2.zip
ipv6: route: dissect flow in input path if fib rules need it
Dissect flow in fwd path if fib rules require it. Controlled by a flag to avoid penatly for the common case. Flag is set when fib rules with sport, dport and proto match that require flow dissect are installed. Also passes the dissected hash keys to the multipath hash function when applicable to avoid dissecting the flow again. icmp packets will continue to use inner header for hash calculations. Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com> Acked-by: Paolo Abeni <pabeni@redhat.com> Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/fib6_rules.c')
-rw-r--r--net/ipv6/fib6_rules.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index bcd1f22ac7b1..04e5f523e50f 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -269,12 +269,26 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
rule6->dst.plen = frh->dst_len;
rule6->tclass = frh->tos;
+ if (fib_rule_requires_fldissect(rule))
+ net->ipv6.fib6_rules_require_fldissect++;
+
net->ipv6.fib6_has_custom_rules = true;
err = 0;
errout:
return err;
}
+static int fib6_rule_delete(struct fib_rule *rule)
+{
+ struct net *net = rule->fr_net;
+
+ if (net->ipv6.fib6_rules_require_fldissect &&
+ fib_rule_requires_fldissect(rule))
+ net->ipv6.fib6_rules_require_fldissect--;
+
+ return 0;
+}
+
static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
struct nlattr **tb)
{
@@ -334,6 +348,7 @@ static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = {
.match = fib6_rule_match,
.suppress = fib6_rule_suppress,
.configure = fib6_rule_configure,
+ .delete = fib6_rule_delete,
.compare = fib6_rule_compare,
.fill = fib6_rule_fill,
.nlmsg_payload = fib6_rule_nlmsg_payload,
@@ -361,6 +376,7 @@ static int __net_init fib6_rules_net_init(struct net *net)
goto out_fib6_rules_ops;
net->ipv6.fib6_rules_ops = ops;
+ net->ipv6.fib6_rules_require_fldissect = 0;
out:
return err;