diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-08-07 13:12:34 -0400 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-08-13 09:48:20 -0400 |
commit | 0ef71ee1a5b92c038abefd8991d5368e6031d7de (patch) | |
tree | 7940cfac3eff98440fa28be4ba17fcebf8d5ca20 | |
parent | c655bc6896b94ee0223393f26155c6daf1e2d148 (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.c | 156 |
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 | ||
2738 | static int | 2738 | static struct nf_conntrack_expect * |
2739 | ctnetlink_create_expect(struct net *net, u16 zone, | 2739 | ctnetlink_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; |
2856 | err_out: | 2806 | err_out: |
2857 | nf_ct_expect_put(exp); | 2807 | nf_ct_expect_put(exp); |
2858 | out: | 2808 | return ERR_PTR(err); |
2859 | nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); | 2809 | } |
2810 | |||
2811 | static int | ||
2812 | ctnetlink_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; | ||
2874 | err_exp: | ||
2875 | nf_ct_expect_put(exp); | ||
2876 | err_ct: | ||
2877 | nf_ct_put(ct); | ||
2860 | return err; | 2878 | return err; |
2861 | } | 2879 | } |
2862 | 2880 | ||