aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c53
1 files changed, 22 insertions, 31 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 01bd7cab9367..af152e3623dc 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -629,7 +629,7 @@ static const size_t cta_min_nat[CTA_NAT_MAX] = {
629}; 629};
630 630
631static inline int 631static inline int
632ctnetlink_parse_nat(struct nfattr *cda[], 632ctnetlink_parse_nat(struct nfattr *nat,
633 const struct ip_conntrack *ct, struct ip_nat_range *range) 633 const struct ip_conntrack *ct, struct ip_nat_range *range)
634{ 634{
635 struct nfattr *tb[CTA_NAT_MAX]; 635 struct nfattr *tb[CTA_NAT_MAX];
@@ -639,7 +639,7 @@ ctnetlink_parse_nat(struct nfattr *cda[],
639 639
640 memset(range, 0, sizeof(*range)); 640 memset(range, 0, sizeof(*range));
641 641
642 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]); 642 nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
643 643
644 if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat)) 644 if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
645 return -EINVAL; 645 return -EINVAL;
@@ -854,39 +854,30 @@ ctnetlink_change_status(struct ip_conntrack *ct, struct nfattr *cda[])
854 /* ASSURED bit can only be set */ 854 /* ASSURED bit can only be set */
855 return -EINVAL; 855 return -EINVAL;
856 856
857 if (cda[CTA_NAT-1]) { 857 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
858#ifndef CONFIG_IP_NF_NAT_NEEDED 858#ifndef CONFIG_IP_NF_NAT_NEEDED
859 return -EINVAL; 859 return -EINVAL;
860#else 860#else
861 unsigned int hooknum;
862 struct ip_nat_range range; 861 struct ip_nat_range range;
863 862
864 if (ctnetlink_parse_nat(cda, ct, &range) < 0) 863 if (cda[CTA_NAT_DST-1]) {
865 return -EINVAL; 864 if (ctnetlink_parse_nat(cda[CTA_NAT_DST-1], ct,
866 865 &range) < 0)
867 DEBUGP("NAT: %u.%u.%u.%u-%u.%u.%u.%u:%u-%u\n", 866 return -EINVAL;
868 NIPQUAD(range.min_ip), NIPQUAD(range.max_ip), 867 if (ip_nat_initialized(ct,
869 htons(range.min.all), htons(range.max.all)); 868 HOOK2MANIP(NF_IP_PRE_ROUTING)))
870 869 return -EEXIST;
871 /* This is tricky but it works. ip_nat_setup_info needs the 870 ip_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
872 * hook number as parameter, so let's do the correct 871 }
873 * conversion and run away */ 872 if (cda[CTA_NAT_SRC-1]) {
874 if (status & IPS_SRC_NAT_DONE) 873 if (ctnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct,
875 hooknum = NF_IP_POST_ROUTING; /* IP_NAT_MANIP_SRC */ 874 &range) < 0)
876 else if (status & IPS_DST_NAT_DONE) 875 return -EINVAL;
877 hooknum = NF_IP_PRE_ROUTING; /* IP_NAT_MANIP_DST */ 876 if (ip_nat_initialized(ct,
878 else 877 HOOK2MANIP(NF_IP_POST_ROUTING)))
879 return -EINVAL; /* Missing NAT flags */ 878 return -EEXIST;
880 879 ip_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
881 DEBUGP("NAT status: %lu\n", 880 }
882 status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
883
884 if (ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
885 return -EEXIST;
886 ip_nat_setup_info(ct, &range, hooknum);
887
888 DEBUGP("NAT status after setup_info: %lu\n",
889 ct->status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
890#endif 881#endif
891 } 882 }
892 883
@@ -1106,7 +1097,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1106 /* implicit 'else' */ 1097 /* implicit 'else' */
1107 1098
1108 /* we only allow nat config for new conntracks */ 1099 /* we only allow nat config for new conntracks */
1109 if (cda[CTA_NAT-1]) { 1100 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
1110 err = -EINVAL; 1101 err = -EINVAL;
1111 goto out_unlock; 1102 goto out_unlock;
1112 } 1103 }