aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-08-07 13:12:34 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2013-08-13 09:48:20 -0400
commit0ef71ee1a5b92c038abefd8991d5368e6031d7de (patch)
tree7940cfac3eff98440fa28be4ba17fcebf8d5ca20
parentc655bc6896b94ee0223393f26155c6daf1e2d148 (diff)
netfilter: ctnetlink: refactor ctnetlink_create_expect
This patch refactors ctnetlink_create_expect by spliting it in two chunks. As a result, we have a new function ctnetlink_alloc_expect to allocate and to setup the expectation from ctnetlink. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/nf_conntrack_netlink.c156
1 files changed, 87 insertions, 69 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index e842c0ded79d..9aaa68bbbcdb 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -2735,76 +2735,26 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr,
2735#endif 2735#endif
2736} 2736}
2737 2737
2738static int 2738static struct nf_conntrack_expect *
2739ctnetlink_create_expect(struct net *net, u16 zone, 2739ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
2740 const struct nlattr * const cda[], 2740 struct nf_conntrack_helper *helper,
2741 u_int8_t u3, 2741 struct nf_conntrack_tuple *tuple,
2742 u32 portid, int report) 2742 struct nf_conntrack_tuple *mask)
2743{ 2743{
2744 struct nf_conntrack_tuple tuple, mask, master_tuple; 2744 u_int32_t class = 0;
2745 struct nf_conntrack_tuple_hash *h = NULL;
2746 struct nf_conntrack_expect *exp; 2745 struct nf_conntrack_expect *exp;
2747 struct nf_conn *ct;
2748 struct nf_conn_help *help; 2746 struct nf_conn_help *help;
2749 struct nf_conntrack_helper *helper = NULL; 2747 int err;
2750 u_int32_t class = 0;
2751 int err = 0;
2752
2753 /* caller guarantees that those three CTA_EXPECT_* exist */
2754 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
2755 if (err < 0)
2756 return err;
2757 err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
2758 if (err < 0)
2759 return err;
2760 err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
2761 if (err < 0)
2762 return err;
2763
2764 /* Look for master conntrack of this expectation */
2765 h = nf_conntrack_find_get(net, zone, &master_tuple);
2766 if (!h)
2767 return -ENOENT;
2768 ct = nf_ct_tuplehash_to_ctrack(h);
2769
2770 /* Look for helper of this expectation */
2771 if (cda[CTA_EXPECT_HELP_NAME]) {
2772 const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
2773
2774 helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
2775 nf_ct_protonum(ct));
2776 if (helper == NULL) {
2777#ifdef CONFIG_MODULES
2778 if (request_module("nfct-helper-%s", helpname) < 0) {
2779 err = -EOPNOTSUPP;
2780 goto out;
2781 }
2782
2783 helper = __nf_conntrack_helper_find(helpname,
2784 nf_ct_l3num(ct),
2785 nf_ct_protonum(ct));
2786 if (helper) {
2787 err = -EAGAIN;
2788 goto out;
2789 }
2790#endif
2791 err = -EOPNOTSUPP;
2792 goto out;
2793 }
2794 }
2795 2748
2796 if (cda[CTA_EXPECT_CLASS] && helper) { 2749 if (cda[CTA_EXPECT_CLASS] && helper) {
2797 class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS])); 2750 class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
2798 if (class > helper->expect_class_max) { 2751 if (class > helper->expect_class_max)
2799 err = -EINVAL; 2752 return ERR_PTR(-EINVAL);
2800 goto out;
2801 }
2802 } 2753 }
2803 exp = nf_ct_expect_alloc(ct); 2754 exp = nf_ct_expect_alloc(ct);
2804 if (!exp) { 2755 if (!exp)
2805 err = -ENOMEM; 2756 return ERR_PTR(-ENOMEM);
2806 goto out; 2757
2807 }
2808 help = nfct_help(ct); 2758 help = nfct_help(ct);
2809 if (!help) { 2759 if (!help) {
2810 if (!cda[CTA_EXPECT_TIMEOUT]) { 2760 if (!cda[CTA_EXPECT_TIMEOUT]) {
@@ -2842,21 +2792,89 @@ ctnetlink_create_expect(struct net *net, u16 zone,
2842 exp->class = class; 2792 exp->class = class;
2843 exp->master = ct; 2793 exp->master = ct;
2844 exp->helper = helper; 2794 exp->helper = helper;
2845 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); 2795 exp->tuple = *tuple;
2846 memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3)); 2796 exp->mask.src.u3 = mask->src.u3;
2847 exp->mask.src.u.all = mask.src.u.all; 2797 exp->mask.src.u.all = mask->src.u.all;
2848 2798
2849 if (cda[CTA_EXPECT_NAT]) { 2799 if (cda[CTA_EXPECT_NAT]) {
2850 err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT], 2800 err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT],
2851 exp, u3); 2801 exp, nf_ct_l3num(ct));
2852 if (err < 0) 2802 if (err < 0)
2853 goto err_out; 2803 goto err_out;
2854 } 2804 }
2855 err = nf_ct_expect_related_report(exp, portid, report); 2805 return exp;
2856err_out: 2806err_out:
2857 nf_ct_expect_put(exp); 2807 nf_ct_expect_put(exp);
2858out: 2808 return ERR_PTR(err);
2859 nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); 2809}
2810
2811static int
2812ctnetlink_create_expect(struct net *net, u16 zone,
2813 const struct nlattr * const cda[],
2814 u_int8_t u3, u32 portid, int report)
2815{
2816 struct nf_conntrack_tuple tuple, mask, master_tuple;
2817 struct nf_conntrack_tuple_hash *h = NULL;
2818 struct nf_conntrack_helper *helper = NULL;
2819 struct nf_conntrack_expect *exp;
2820 struct nf_conn *ct;
2821 int err;
2822
2823 /* caller guarantees that those three CTA_EXPECT_* exist */
2824 err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
2825 if (err < 0)
2826 return err;
2827 err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
2828 if (err < 0)
2829 return err;
2830 err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
2831 if (err < 0)
2832 return err;
2833
2834 /* Look for master conntrack of this expectation */
2835 h = nf_conntrack_find_get(net, zone, &master_tuple);
2836 if (!h)
2837 return -ENOENT;
2838 ct = nf_ct_tuplehash_to_ctrack(h);
2839
2840 if (cda[CTA_EXPECT_HELP_NAME]) {
2841 const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
2842
2843 helper = __nf_conntrack_helper_find(helpname, u3,
2844 nf_ct_protonum(ct));
2845 if (helper == NULL) {
2846#ifdef CONFIG_MODULES
2847 if (request_module("nfct-helper-%s", helpname) < 0) {
2848 err = -EOPNOTSUPP;
2849 goto err_ct;
2850 }
2851 helper = __nf_conntrack_helper_find(helpname, u3,
2852 nf_ct_protonum(ct));
2853 if (helper) {
2854 err = -EAGAIN;
2855 goto err_ct;
2856 }
2857#endif
2858 err = -EOPNOTSUPP;
2859 goto err_ct;
2860 }
2861 }
2862
2863 exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask);
2864 if (IS_ERR(exp)) {
2865 err = PTR_ERR(exp);
2866 goto err_ct;
2867 }
2868
2869 err = nf_ct_expect_related_report(exp, portid, report);
2870 if (err < 0)
2871 goto err_exp;
2872
2873 return 0;
2874err_exp:
2875 nf_ct_expect_put(exp);
2876err_ct:
2877 nf_ct_put(ct);
2860 return err; 2878 return err;
2861} 2879}
2862 2880