aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
authorFlavio Leitner <fbl@redhat.com>2019-04-17 10:46:17 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2019-04-30 08:19:56 -0400
commitfec9c271b8f1bde1086be5aa415cdb586e0dc800 (patch)
tree52245b89381ed3290fe55738b4243236d3e4cf08 /net/openvswitch
parent53b11308a1b53d7e98f65dfd5faea124df99ca14 (diff)
openvswitch: load and reference the NAT helper.
This improves the original commit 17c357efe5ec ("openvswitch: load NAT helper") where it unconditionally tries to load the module for every flow using NAT, so not efficient when loading multiple flows. It also doesn't hold any references to the NAT module while the flow is active. This change fixes those problems. It will try to load the module only if it's not present. It grabs a reference to the NAT module and holds it while the flow is active. Finally, an error message shows up if either actions above fails. Fixes: 17c357efe5ec ("openvswitch: load NAT helper") Signed-off-by: Flavio Leitner <fbl@redhat.com> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/conntrack.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index bded32144619..c4128082f88b 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -1307,6 +1307,7 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
1307{ 1307{
1308 struct nf_conntrack_helper *helper; 1308 struct nf_conntrack_helper *helper;
1309 struct nf_conn_help *help; 1309 struct nf_conn_help *help;
1310 int ret = 0;
1310 1311
1311 helper = nf_conntrack_helper_try_module_get(name, info->family, 1312 helper = nf_conntrack_helper_try_module_get(name, info->family,
1312 key->ip.proto); 1313 key->ip.proto);
@@ -1321,13 +1322,21 @@ static int ovs_ct_add_helper(struct ovs_conntrack_info *info, const char *name,
1321 return -ENOMEM; 1322 return -ENOMEM;
1322 } 1323 }
1323 1324
1325#ifdef CONFIG_NF_NAT_NEEDED
1326 if (info->nat) {
1327 ret = nf_nat_helper_try_module_get(name, info->family,
1328 key->ip.proto);
1329 if (ret) {
1330 nf_conntrack_helper_put(helper);
1331 OVS_NLERR(log, "Failed to load \"%s\" NAT helper, error: %d",
1332 name, ret);
1333 return ret;
1334 }
1335 }
1336#endif
1324 rcu_assign_pointer(help->helper, helper); 1337 rcu_assign_pointer(help->helper, helper);
1325 info->helper = helper; 1338 info->helper = helper;
1326 1339 return ret;
1327 if (info->nat)
1328 request_module("ip_nat_%s", name);
1329
1330 return 0;
1331} 1340}
1332 1341
1333#if IS_ENABLED(CONFIG_NF_NAT) 1342#if IS_ENABLED(CONFIG_NF_NAT)
@@ -1801,8 +1810,13 @@ void ovs_ct_free_action(const struct nlattr *a)
1801 1810
1802static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info) 1811static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info)
1803{ 1812{
1804 if (ct_info->helper) 1813 if (ct_info->helper) {
1814#ifdef CONFIG_NF_NAT_NEEDED
1815 if (ct_info->nat)
1816 nf_nat_helper_put(ct_info->helper);
1817#endif
1805 nf_conntrack_helper_put(ct_info->helper); 1818 nf_conntrack_helper_put(ct_info->helper);
1819 }
1806 if (ct_info->ct) { 1820 if (ct_info->ct) {
1807 if (ct_info->timeout[0]) 1821 if (ct_info->timeout[0])
1808 nf_ct_destroy_timeout(ct_info->ct); 1822 nf_ct_destroy_timeout(ct_info->ct);