summaryrefslogtreecommitdiffstats
path: root/include/net/tc_act
diff options
context:
space:
mode:
authorVlad Buslov <vladbu@mellanox.com>2019-08-26 16:45:05 +0300
committerDavid S. Miller <davem@davemloft.net>2019-08-26 14:17:43 -0700
commit1444c175a37443d3f6d3db825df050741452c3c3 (patch)
treed10f8fff01a65b1113b440b0e174458c16d87d75 /include/net/tc_act
parent5a6ff4b13d598573fc954f672cd2a267b76a01ec (diff)
downloadlinux-stable-1444c175a37443d3f6d3db825df050741452c3c3.tar.gz
linux-stable-1444c175a37443d3f6d3db825df050741452c3c3.tar.bz2
linux-stable-1444c175a37443d3f6d3db825df050741452c3c3.zip
net: sched: copy tunnel info when setting flow_action entry->tunnel
In order to remove dependency on rtnl lock, modify tc_setup_flow_action() to copy tunnel info, instead of just saving pointer to tunnel_key action tunnel info. This is necessary to prevent concurrent action overwrite from releasing tunnel info while it is being used by rtnl-unlocked driver. Implement helper tcf_tunnel_info_copy() that is used to copy tunnel info with all its options to dynamically allocated memory block. Modify tc_cleanup_flow_action() to free dynamically allocated tunnel info. Signed-off-by: Vlad Buslov <vladbu@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/tc_act')
-rw-r--r--include/net/tc_act/tc_tunnel_key.h17
1 files changed, 17 insertions, 0 deletions
diff --git a/include/net/tc_act/tc_tunnel_key.h b/include/net/tc_act/tc_tunnel_key.h
index 7c3f777c168c..0689d9bcdf84 100644
--- a/include/net/tc_act/tc_tunnel_key.h
+++ b/include/net/tc_act/tc_tunnel_key.h
@@ -59,4 +59,21 @@ static inline struct ip_tunnel_info *tcf_tunnel_info(const struct tc_action *a)
return NULL;
#endif
}
+
+static inline struct ip_tunnel_info *
+tcf_tunnel_info_copy(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ struct ip_tunnel_info *tun = tcf_tunnel_info(a);
+
+ if (tun) {
+ size_t tun_size = sizeof(*tun) + tun->options_len;
+ struct ip_tunnel_info *tun_copy = kmemdup(tun, tun_size,
+ GFP_KERNEL);
+
+ return tun_copy;
+ }
+#endif
+ return NULL;
+}
#endif /* __NET_TC_TUNNEL_KEY_H */