Andrey, please review

23.11.2015 17:08, Stanislav Kinsburskiy пишет:
From: Hannes Frederic Sowa <han...@stressinduktion.org>

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.

Backport: https://jira.sw.ru/browse/PSBM-41453

Fixes: f0ad0860d01e47 ("ipv4: ipmr: support multiple tables")
Fixes: d1db275dd3f6e4 ("ipv6: ip6mr: support multiple tables")
Reported-by: Bob Falken <netfestivalhave...@gmx.com>
Cc: Patrick McHardy <ka...@trash.net>
Cc: Thomas Graf <tg...@suug.ch>
Cc: Julian Anastasov <j...@ssi.bg>
Cc: Eric Dumazet <eric.duma...@gmail.com>
Signed-off-by: Hannes Frederic Sowa <han...@stressinduktion.org>
Acked-by: Eric Dumazet <eduma...@google.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Stanislav Kinsburskiy <skinsbur...@odin.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 aa7bc00..4234b01 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 4b42124..9f44ebc 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);

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to