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(cd | ||
