]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - net/netfilter/nf_nat_core.c
netfilter: nat: fix src map lookup
[mirror_ubuntu-artful-kernel.git] / net / netfilter / nf_nat_core.c
index 6c72922d20caee83f498cb02cdce0c46899a1c22..eb541786ccb7c79b3498477dfefc2927368f1a6f 100644 (file)
@@ -222,20 +222,21 @@ find_appropriate_src(struct net *net,
                .tuple = tuple,
                .zone = zone
        };
-       struct rhlist_head *hl;
+       struct rhlist_head *hl, *h;
 
        hl = rhltable_lookup(&nf_nat_bysource_table, &key,
                             nf_nat_bysource_params);
-       if (!hl)
-               return 0;
 
-       ct = container_of(hl, typeof(*ct), nat_bysource);
+       rhl_for_each_entry_rcu(ct, h, hl, nat_bysource) {
+               nf_ct_invert_tuplepr(result,
+                                    &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+               result->dst = tuple->dst;
 
-       nf_ct_invert_tuplepr(result,
-                            &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
-       result->dst = tuple->dst;
+               if (in_range(l3proto, l4proto, result, range))
+                       return 1;
+       }
 
-       return in_range(l3proto, l4proto, result, range);
+       return 0;
 }
 
 /* For [FUTURE] fragmentation handling, we want the least-used
@@ -582,12 +583,8 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
                .l3proto = l3proto,
                .l4proto = l4proto,
        };
-       struct net *net;
 
-       rtnl_lock();
-       for_each_net(net)
-               nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean, 0, 0);
-       rtnl_unlock();
+       nf_ct_iterate_destroy(nf_nat_proto_remove, &clean);
 }
 
 static void nf_nat_l3proto_clean(u8 l3proto)
@@ -595,13 +592,8 @@ static void nf_nat_l3proto_clean(u8 l3proto)
        struct nf_nat_proto_clean clean = {
                .l3proto = l3proto,
        };
-       struct net *net;
-
-       rtnl_lock();
 
-       for_each_net(net)
-               nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean, 0, 0);
-       rtnl_unlock();
+       nf_ct_iterate_destroy(nf_nat_proto_remove, &clean);
 }
 
 /* Protocol registration. */
@@ -822,17 +814,6 @@ nfnetlink_parse_nat_setup(struct nf_conn *ct,
 }
 #endif
 
-static void __net_exit nf_nat_net_exit(struct net *net)
-{
-       struct nf_nat_proto_clean clean = {};
-
-       nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean, 0, 0);
-}
-
-static struct pernet_operations nf_nat_net_ops = {
-       .exit = nf_nat_net_exit,
-};
-
 static struct nf_ct_helper_expectfn follow_master_nat = {
        .name           = "nat-follow-master",
        .expectfn       = nf_nat_follow_master,
@@ -853,10 +834,6 @@ static int __init nf_nat_init(void)
                return ret;
        }
 
-       ret = register_pernet_subsys(&nf_nat_net_ops);
-       if (ret < 0)
-               goto cleanup_extend;
-
        nf_ct_helper_expectfn_register(&follow_master_nat);
 
        BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
@@ -867,18 +844,15 @@ static int __init nf_nat_init(void)
        RCU_INIT_POINTER(nf_nat_decode_session_hook, __nf_nat_decode_session);
 #endif
        return 0;
-
- cleanup_extend:
-       rhltable_destroy(&nf_nat_bysource_table);
-       nf_ct_extend_unregister(&nat_extend);
-       return ret;
 }
 
 static void __exit nf_nat_cleanup(void)
 {
+       struct nf_nat_proto_clean clean = {};
        unsigned int i;
 
-       unregister_pernet_subsys(&nf_nat_net_ops);
+       nf_ct_iterate_destroy(nf_nat_proto_clean, &clean);
+
        nf_ct_extend_unregister(&nat_extend);
        nf_ct_helper_expectfn_unregister(&follow_master_nat);
        RCU_INIT_POINTER(nfnetlink_parse_nat_setup_hook, NULL);