[Devel] [PATCH RHEL7 COMMIT] ms/net: avoid reference counter overflows on fib_rules in multicast forwarding

Konstantin Khorenko khorenko at virtuozzo.com
Tue Nov 24 08:08:21 PST 2015


The commit is pushed to "branch-rh7-3.10.0-229.7.2.vz7.9.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-229.7.2.vz7.9.13
------>
commit 4aed1b965b2d36d9315d06f9dd58070645e90064
Author: Hannes Frederic Sowa <hannes at stressinduktion.org>
Date:   Tue Nov 24 20:08:21 2015 +0400

    ms/net: avoid reference counter overflows on fib_rules in multicast forwarding
    
    ms commit: 95f4a45de1a0f172b35451fc52283290adb21f6e
    
    Bob Falken reported that after 4G packets, multicast forwarding stopped
    working. This was because of a rule reference counter overflow which
    freed the rule as soon as the overflow happend.
    
    This patch solves this by adding the FIB_LOOKUP_NOREF flag to
    fib_rules_lookup calls. This is safe even from non-rcu locked sections
    as in this case the flag only implies not taking a reference to the rule,
    which we don't need at all.
    
    Rules only hold references to the namespace, which are guaranteed to be
    available during the call of the non-rcu protected function reg_vif_xmit
    because of the interface reference which itself holds a reference to
    the net namespace.
    
    Fixes: f0ad0860d01e47 ("ipv4: ipmr: support multiple tables")
    Fixes: d1db275dd3f6e4 ("ipv6: ip6mr: support multiple tables")
    Reported-by: Bob Falken <NetFestivalHaveFun at gmx.com>
    Cc: Patrick McHardy <kaber at trash.net>
    Cc: Thomas Graf <tgraf at suug.ch>
    Cc: Julian Anastasov <ja at ssi.bg>
    Cc: Eric Dumazet <eric.dumazet at gmail.com>
    Signed-off-by: Hannes Frederic Sowa <hannes at stressinduktion.org>
    Acked-by: Eric Dumazet <edumazet at google.com>
    Signed-off-by: David S. Miller <davem at davemloft.net>
    
    https://jira.sw.ru/browse/PSBM-41453
    
    Signed-off-by: Stanislav Kinsburskiy <skinsbursky at odin.com>
    Reviewed-by: Andrey Ryabinin <aryabinin at virtuozzo.com>
---
 net/ipv4/ipmr.c  | 7 +++++--
 net/ipv6/ip6mr.c | 7 +++++--
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index f74a9c0..ce25a5c 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -157,9 +157,12 @@ static struct mr_table *ipmr_get_table(struct net *net, u32 id)
 static int ipmr_fib_lookup(struct net *net, struct flowi4 *flp4,
 			   struct mr_table **mrt)
 {
-	struct ipmr_result res;
-	struct fib_lookup_arg arg = { .result = &res, };
 	int err;
+	struct ipmr_result res;
+	struct fib_lookup_arg arg = {
+		.result = &res,
+		.flags = FIB_LOOKUP_NOREF,
+	};
 
 	err = fib_rules_lookup(net->ipv4.mr_rules_ops,
 			       flowi4_to_flowi(flp4), 0, &arg);
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 5de4c65..1997df7 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -141,9 +141,12 @@ static struct mr6_table *ip6mr_get_table(struct net *net, u32 id)
 static int ip6mr_fib_lookup(struct net *net, struct flowi6 *flp6,
 			    struct mr6_table **mrt)
 {
-	struct ip6mr_result res;
-	struct fib_lookup_arg arg = { .result = &res, };
 	int err;
+	struct ip6mr_result res;
+	struct fib_lookup_arg arg = {
+		.result = &res,
+		.flags = FIB_LOOKUP_NOREF,
+	};
 
 	err = fib_rules_lookup(net->ipv6.mr6_rules_ops,
 			       flowi6_to_flowi(flp6), 0, &arg);


More information about the Devel mailing list