aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-05-29 21:24:39 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-18 00:29:01 -0400
commit3726add76643c715d437aceda320d319153b6113 (patch)
tree70b343ab57ae6575ebc2828cc1e8bab24c4df120
parent997ae831ade74bdaed4172b1c02060b9efd6e206 (diff)
[NETFILTER]: ctnetlink: fix NAT configuration
The current configuration only allows to configure one manip and overloads conntrack status flags with netlink semantic. Signed-off-by: Patrick Mchardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/netfilter/nfnetlink_conntrack.h4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c53
-rw-r--r--net/netfilter/nf_conntrack_netlink.c53
3 files changed, 47 insertions, 63 deletions
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index 668ec946c8e2..b5883ccee295 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -27,13 +27,15 @@ enum ctattr_type {
27 CTA_STATUS, 27 CTA_STATUS,
28 CTA_PROTOINFO, 28 CTA_PROTOINFO,
29 CTA_HELP, 29 CTA_HELP,
30 CTA_NAT, 30 CTA_NAT_SRC,
31#define CTA_NAT CTA_NAT_SRC /* backwards compatibility */
31 CTA_TIMEOUT, 32 CTA_TIMEOUT,
32 CTA_MARK, 33 CTA_MARK,
33 CTA_COUNTERS_ORIG, 34 CTA_COUNTERS_ORIG,
34 CTA_COUNTERS_REPLY, 35 CTA_COUNTERS_REPLY,
35 CTA_USE, 36 CTA_USE,
36 CTA_ID, 37 CTA_ID,
38 CTA_NAT_DST,
37 __CTA_MAX 39 __CTA_MAX
38}; 40};
39#define CTA_MAX (__CTA_MAX - 1) 41#define CTA_MAX (__CTA_MAX - 1)
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 }
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index bd10eb944b65..8f27fe9446f2 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -641,7 +641,7 @@ static const size_t cta_min_nat[CTA_NAT_MAX] = {
641}; 641};
642 642
643static inline int 643static inline int
644ctnetlink_parse_nat(struct nfattr *cda[], 644ctnetlink_parse_nat(struct nfattr *nat,
645 const struct nf_conn *ct, struct ip_nat_range *range) 645 const struct nf_conn *ct, struct ip_nat_range *range)
646{ 646{
647 struct nfattr *tb[CTA_NAT_MAX]; 647 struct nfattr *tb[CTA_NAT_MAX];
@@ -651,7 +651,7 @@ ctnetlink_parse_nat(struct nfattr *cda[],
651 651
652 memset(range, 0, sizeof(*range)); 652 memset(range, 0, sizeof(*range));
653 653
654 nfattr_parse_nested(tb, CTA_NAT_MAX, cda[CTA_NAT-1]); 654 nfattr_parse_nested(tb, CTA_NAT_MAX, nat);
655 655
656 if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat)) 656 if (nfattr_bad_size(tb, CTA_NAT_MAX, cta_min_nat))
657 return -EINVAL; 657 return -EINVAL;
@@ -866,39 +866,30 @@ ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
866 /* ASSURED bit can only be set */ 866 /* ASSURED bit can only be set */
867 return -EINVAL; 867 return -EINVAL;
868 868
869 if (cda[CTA_NAT-1]) { 869 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
870#ifndef CONFIG_IP_NF_NAT_NEEDED 870#ifndef CONFIG_IP_NF_NAT_NEEDED
871 return -EINVAL; 871 return -EINVAL;
872#else 872#else
873 unsigned int hooknum;
874 struct ip_nat_range range; 873 struct ip_nat_range range;
875 874
876 if (ctnetlink_parse_nat(cda, ct, &range) < 0) 875 if (cda[CTA_NAT_DST-1]) {
877 return -EINVAL; 876 if (ctnetlink_parse_nat(cda[CTA_NAT_DST-1], ct,
878 877 &range) < 0)
879 DEBUGP("NAT: %u.%u.%u.%u-%u.%u.%u.%u:%u-%u\n", 878 return -EINVAL;
880 NIPQUAD(range.min_ip), NIPQUAD(range.max_ip), 879 if (ip_nat_initialized(ct,
881 htons(range.min.all), htons(range.max.all)); 880 HOOK2MANIP(NF_IP_PRE_ROUTING)))
882 881 return -EEXIST;
883 /* This is tricky but it works. ip_nat_setup_info needs the 882 ip_nat_setup_info(ct, &range, hooknum);
884 * hook number as parameter, so let's do the correct 883 }
885 * conversion and run away */ 884 if (cda[CTA_NAT_SRC-1]) {
886 if (status & IPS_SRC_NAT_DONE) 885 if (ctnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct,
887 hooknum = NF_IP_POST_ROUTING; /* IP_NAT_MANIP_SRC */ 886 &range) < 0)
888 else if (status & IPS_DST_NAT_DONE) 887 return -EINVAL;
889 hooknum = NF_IP_PRE_ROUTING; /* IP_NAT_MANIP_DST */ 888 if (ip_nat_initialized(ct,
890 else 889 HOOK2MANIP(NF_IP_POST_ROUTING)))
891 return -EINVAL; /* Missing NAT flags */ 890 return -EEXIST;
892 891 ip_nat_setup_info(ct, &range, hooknum);
893 DEBUGP("NAT status: %lu\n", 892 }
894 status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
895
896 if (ip_nat_initialized(ct, HOOK2MANIP(hooknum)))
897 return -EEXIST;
898 ip_nat_setup_info(ct, &range, hooknum);
899
900 DEBUGP("NAT status after setup_info: %lu\n",
901 ct->status & (IPS_NAT_MASK | IPS_NAT_DONE_MASK));
902#endif 893#endif
903 } 894 }
904 895
@@ -1122,7 +1113,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1122 /* implicit 'else' */ 1113 /* implicit 'else' */
1123 1114
1124 /* we only allow nat config for new conntracks */ 1115 /* we only allow nat config for new conntracks */
1125 if (cda[CTA_NAT-1]) { 1116 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
1126 err = -EINVAL; 1117 err = -EINVAL;
1127 goto out_unlock; 1118 goto out_unlock;
1128 } 1119 }