Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * (C) 1999-2001 Paul `Rusty' Russell
0004  * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
0005  * (C) 2011 Patrick McHardy <kaber@trash.net>
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 
0010 #include <linux/module.h>
0011 #include <linux/skbuff.h>
0012 #include <linux/netfilter.h>
0013 #include <linux/netfilter/x_tables.h>
0014 #include <net/netfilter/nf_nat.h>
0015 
0016 static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
0017 {
0018     const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
0019 
0020     if (mr->rangesize != 1) {
0021         pr_info_ratelimited("multiple ranges no longer supported\n");
0022         return -EINVAL;
0023     }
0024     return nf_ct_netns_get(par->net, par->family);
0025 }
0026 
0027 static int xt_nat_checkentry(const struct xt_tgchk_param *par)
0028 {
0029     return nf_ct_netns_get(par->net, par->family);
0030 }
0031 
0032 static void xt_nat_destroy(const struct xt_tgdtor_param *par)
0033 {
0034     nf_ct_netns_put(par->net, par->family);
0035 }
0036 
0037 static void xt_nat_convert_range(struct nf_nat_range2 *dst,
0038                  const struct nf_nat_ipv4_range *src)
0039 {
0040     memset(&dst->min_addr, 0, sizeof(dst->min_addr));
0041     memset(&dst->max_addr, 0, sizeof(dst->max_addr));
0042     memset(&dst->base_proto, 0, sizeof(dst->base_proto));
0043 
0044     dst->flags   = src->flags;
0045     dst->min_addr.ip = src->min_ip;
0046     dst->max_addr.ip = src->max_ip;
0047     dst->min_proto   = src->min;
0048     dst->max_proto   = src->max;
0049 }
0050 
0051 static unsigned int
0052 xt_snat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
0053 {
0054     const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
0055     struct nf_nat_range2 range;
0056     enum ip_conntrack_info ctinfo;
0057     struct nf_conn *ct;
0058 
0059     ct = nf_ct_get(skb, &ctinfo);
0060     WARN_ON(!(ct != NULL &&
0061          (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
0062           ctinfo == IP_CT_RELATED_REPLY)));
0063 
0064     xt_nat_convert_range(&range, &mr->range[0]);
0065     return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
0066 }
0067 
0068 static unsigned int
0069 xt_dnat_target_v0(struct sk_buff *skb, const struct xt_action_param *par)
0070 {
0071     const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
0072     struct nf_nat_range2 range;
0073     enum ip_conntrack_info ctinfo;
0074     struct nf_conn *ct;
0075 
0076     ct = nf_ct_get(skb, &ctinfo);
0077     WARN_ON(!(ct != NULL &&
0078          (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)));
0079 
0080     xt_nat_convert_range(&range, &mr->range[0]);
0081     return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
0082 }
0083 
0084 static unsigned int
0085 xt_snat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
0086 {
0087     const struct nf_nat_range *range_v1 = par->targinfo;
0088     struct nf_nat_range2 range;
0089     enum ip_conntrack_info ctinfo;
0090     struct nf_conn *ct;
0091 
0092     ct = nf_ct_get(skb, &ctinfo);
0093     WARN_ON(!(ct != NULL &&
0094          (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
0095           ctinfo == IP_CT_RELATED_REPLY)));
0096 
0097     memcpy(&range, range_v1, sizeof(*range_v1));
0098     memset(&range.base_proto, 0, sizeof(range.base_proto));
0099 
0100     return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_SRC);
0101 }
0102 
0103 static unsigned int
0104 xt_dnat_target_v1(struct sk_buff *skb, const struct xt_action_param *par)
0105 {
0106     const struct nf_nat_range *range_v1 = par->targinfo;
0107     struct nf_nat_range2 range;
0108     enum ip_conntrack_info ctinfo;
0109     struct nf_conn *ct;
0110 
0111     ct = nf_ct_get(skb, &ctinfo);
0112     WARN_ON(!(ct != NULL &&
0113          (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)));
0114 
0115     memcpy(&range, range_v1, sizeof(*range_v1));
0116     memset(&range.base_proto, 0, sizeof(range.base_proto));
0117 
0118     return nf_nat_setup_info(ct, &range, NF_NAT_MANIP_DST);
0119 }
0120 
0121 static unsigned int
0122 xt_snat_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
0123 {
0124     const struct nf_nat_range2 *range = par->targinfo;
0125     enum ip_conntrack_info ctinfo;
0126     struct nf_conn *ct;
0127 
0128     ct = nf_ct_get(skb, &ctinfo);
0129     WARN_ON(!(ct != NULL &&
0130          (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
0131           ctinfo == IP_CT_RELATED_REPLY)));
0132 
0133     return nf_nat_setup_info(ct, range, NF_NAT_MANIP_SRC);
0134 }
0135 
0136 static unsigned int
0137 xt_dnat_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
0138 {
0139     const struct nf_nat_range2 *range = par->targinfo;
0140     enum ip_conntrack_info ctinfo;
0141     struct nf_conn *ct;
0142 
0143     ct = nf_ct_get(skb, &ctinfo);
0144     WARN_ON(!(ct != NULL &&
0145          (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)));
0146 
0147     return nf_nat_setup_info(ct, range, NF_NAT_MANIP_DST);
0148 }
0149 
0150 static struct xt_target xt_nat_target_reg[] __read_mostly = {
0151     {
0152         .name       = "SNAT",
0153         .revision   = 0,
0154         .checkentry = xt_nat_checkentry_v0,
0155         .destroy    = xt_nat_destroy,
0156         .target     = xt_snat_target_v0,
0157         .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
0158         .family     = NFPROTO_IPV4,
0159         .table      = "nat",
0160         .hooks      = (1 << NF_INET_POST_ROUTING) |
0161                   (1 << NF_INET_LOCAL_IN),
0162         .me     = THIS_MODULE,
0163     },
0164     {
0165         .name       = "DNAT",
0166         .revision   = 0,
0167         .checkentry = xt_nat_checkentry_v0,
0168         .destroy    = xt_nat_destroy,
0169         .target     = xt_dnat_target_v0,
0170         .targetsize = sizeof(struct nf_nat_ipv4_multi_range_compat),
0171         .family     = NFPROTO_IPV4,
0172         .table      = "nat",
0173         .hooks      = (1 << NF_INET_PRE_ROUTING) |
0174                   (1 << NF_INET_LOCAL_OUT),
0175         .me     = THIS_MODULE,
0176     },
0177     {
0178         .name       = "SNAT",
0179         .revision   = 1,
0180         .checkentry = xt_nat_checkentry,
0181         .destroy    = xt_nat_destroy,
0182         .target     = xt_snat_target_v1,
0183         .targetsize = sizeof(struct nf_nat_range),
0184         .table      = "nat",
0185         .hooks      = (1 << NF_INET_POST_ROUTING) |
0186                   (1 << NF_INET_LOCAL_IN),
0187         .me     = THIS_MODULE,
0188     },
0189     {
0190         .name       = "DNAT",
0191         .revision   = 1,
0192         .checkentry = xt_nat_checkentry,
0193         .destroy    = xt_nat_destroy,
0194         .target     = xt_dnat_target_v1,
0195         .targetsize = sizeof(struct nf_nat_range),
0196         .table      = "nat",
0197         .hooks      = (1 << NF_INET_PRE_ROUTING) |
0198                   (1 << NF_INET_LOCAL_OUT),
0199         .me     = THIS_MODULE,
0200     },
0201     {
0202         .name       = "SNAT",
0203         .revision   = 2,
0204         .checkentry = xt_nat_checkentry,
0205         .destroy    = xt_nat_destroy,
0206         .target     = xt_snat_target_v2,
0207         .targetsize = sizeof(struct nf_nat_range2),
0208         .table      = "nat",
0209         .hooks      = (1 << NF_INET_POST_ROUTING) |
0210                   (1 << NF_INET_LOCAL_IN),
0211         .me     = THIS_MODULE,
0212     },
0213     {
0214         .name       = "DNAT",
0215         .revision   = 2,
0216         .checkentry = xt_nat_checkentry,
0217         .destroy    = xt_nat_destroy,
0218         .target     = xt_dnat_target_v2,
0219         .targetsize = sizeof(struct nf_nat_range2),
0220         .table      = "nat",
0221         .hooks      = (1 << NF_INET_PRE_ROUTING) |
0222                   (1 << NF_INET_LOCAL_OUT),
0223         .me     = THIS_MODULE,
0224     },
0225 };
0226 
0227 static int __init xt_nat_init(void)
0228 {
0229     return xt_register_targets(xt_nat_target_reg,
0230                    ARRAY_SIZE(xt_nat_target_reg));
0231 }
0232 
0233 static void __exit xt_nat_exit(void)
0234 {
0235     xt_unregister_targets(xt_nat_target_reg, ARRAY_SIZE(xt_nat_target_reg));
0236 }
0237 
0238 module_init(xt_nat_init);
0239 module_exit(xt_nat_exit);
0240 
0241 MODULE_LICENSE("GPL");
0242 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
0243 MODULE_ALIAS("ipt_SNAT");
0244 MODULE_ALIAS("ipt_DNAT");
0245 MODULE_ALIAS("ip6t_SNAT");
0246 MODULE_ALIAS("ip6t_DNAT");
0247 MODULE_DESCRIPTION("SNAT and DNAT targets support");