diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-02-04 21:41:52 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-03-07 11:40:44 -0500 |
commit | 076a0ca02644657b13e4af363f487ced2942e9cb (patch) | |
tree | b73f2a82a0c12486b8fa308d7667f1d51183633b | |
parent | b8c5e52c13edc99ce192d78c8a7fe2fd626ac643 (diff) |
netfilter: ctnetlink: add NAT support for expectations
This patch adds the missing bits to create expectations that
are created in NAT setups.
-rw-r--r-- | include/linux/netfilter/nfnetlink_conntrack.h | 9 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 68 |
2 files changed, 75 insertions, 2 deletions
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h index 557a0cfb1433..a2f1f483ecc9 100644 --- a/include/linux/netfilter/nfnetlink_conntrack.h +++ b/include/linux/netfilter/nfnetlink_conntrack.h | |||
@@ -174,10 +174,19 @@ enum ctattr_expect { | |||
174 | CTA_EXPECT_ZONE, | 174 | CTA_EXPECT_ZONE, |
175 | CTA_EXPECT_FLAGS, | 175 | CTA_EXPECT_FLAGS, |
176 | CTA_EXPECT_CLASS, | 176 | CTA_EXPECT_CLASS, |
177 | CTA_EXPECT_NAT, | ||
177 | __CTA_EXPECT_MAX | 178 | __CTA_EXPECT_MAX |
178 | }; | 179 | }; |
179 | #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1) | 180 | #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1) |
180 | 181 | ||
182 | enum ctattr_expect_nat { | ||
183 | CTA_EXPECT_NAT_UNSPEC, | ||
184 | CTA_EXPECT_NAT_DIR, | ||
185 | CTA_EXPECT_NAT_TUPLE, | ||
186 | __CTA_EXPECT_NAT_MAX | ||
187 | }; | ||
188 | #define CTA_EXPECT_NAT_MAX (__CTA_EXPECT_NAT_MAX - 1) | ||
189 | |||
181 | enum ctattr_help { | 190 | enum ctattr_help { |
182 | CTA_HELP_UNSPEC, | 191 | CTA_HELP_UNSPEC, |
183 | CTA_HELP_NAME, | 192 | CTA_HELP_NAME, |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index b6ea39770c80..845c8ca28563 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -1675,7 +1675,10 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, | |||
1675 | struct nf_conn *master = exp->master; | 1675 | struct nf_conn *master = exp->master; |
1676 | long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ; | 1676 | long timeout = ((long)exp->timeout.expires - (long)jiffies) / HZ; |
1677 | struct nf_conn_help *help; | 1677 | struct nf_conn_help *help; |
1678 | 1678 | #ifdef CONFIG_NF_NAT_NEEDED | |
1679 | struct nlattr *nest_parms; | ||
1680 | struct nf_conntrack_tuple nat_tuple = {}; | ||
1681 | #endif | ||
1679 | if (timeout < 0) | 1682 | if (timeout < 0) |
1680 | timeout = 0; | 1683 | timeout = 0; |
1681 | 1684 | ||
@@ -1688,6 +1691,25 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, | |||
1688 | CTA_EXPECT_MASTER) < 0) | 1691 | CTA_EXPECT_MASTER) < 0) |
1689 | goto nla_put_failure; | 1692 | goto nla_put_failure; |
1690 | 1693 | ||
1694 | #ifdef CONFIG_NF_NAT_NEEDED | ||
1695 | if (exp->saved_ip || exp->saved_proto.all) { | ||
1696 | nest_parms = nla_nest_start(skb, CTA_EXPECT_NAT | NLA_F_NESTED); | ||
1697 | if (!nest_parms) | ||
1698 | goto nla_put_failure; | ||
1699 | |||
1700 | NLA_PUT_BE32(skb, CTA_EXPECT_NAT_DIR, htonl(exp->dir)); | ||
1701 | |||
1702 | nat_tuple.src.l3num = nf_ct_l3num(master); | ||
1703 | nat_tuple.src.u3.ip = exp->saved_ip; | ||
1704 | nat_tuple.dst.protonum = nf_ct_protonum(master); | ||
1705 | nat_tuple.src.u = exp->saved_proto; | ||
1706 | |||
1707 | if (ctnetlink_exp_dump_tuple(skb, &nat_tuple, | ||
1708 | CTA_EXPECT_NAT_TUPLE) < 0) | ||
1709 | goto nla_put_failure; | ||
1710 | nla_nest_end(skb, nest_parms); | ||
1711 | } | ||
1712 | #endif | ||
1691 | NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)); | 1713 | NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)); |
1692 | NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)); | 1714 | NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)); |
1693 | NLA_PUT_BE32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)); | 1715 | NLA_PUT_BE32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)); |
@@ -1858,6 +1880,7 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { | |||
1858 | [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, | 1880 | [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, |
1859 | [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, | 1881 | [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, |
1860 | [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, | 1882 | [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, |
1883 | [CTA_EXPECT_NAT] = { .type = NLA_NESTED }, | ||
1861 | }; | 1884 | }; |
1862 | 1885 | ||
1863 | static int | 1886 | static int |
@@ -2033,6 +2056,41 @@ ctnetlink_change_expect(struct nf_conntrack_expect *x, | |||
2033 | return -EOPNOTSUPP; | 2056 | return -EOPNOTSUPP; |
2034 | } | 2057 | } |
2035 | 2058 | ||
2059 | static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = { | ||
2060 | [CTA_EXPECT_NAT_DIR] = { .type = NLA_U32 }, | ||
2061 | [CTA_EXPECT_NAT_TUPLE] = { .type = NLA_NESTED }, | ||
2062 | }; | ||
2063 | |||
2064 | static int | ||
2065 | ctnetlink_parse_expect_nat(const struct nlattr *attr, | ||
2066 | struct nf_conntrack_expect *exp, | ||
2067 | u_int8_t u3) | ||
2068 | { | ||
2069 | #ifdef CONFIG_NF_NAT_NEEDED | ||
2070 | struct nlattr *tb[CTA_EXPECT_NAT_MAX+1]; | ||
2071 | struct nf_conntrack_tuple nat_tuple = {}; | ||
2072 | int err; | ||
2073 | |||
2074 | nla_parse_nested(tb, CTA_EXPECT_NAT_MAX, attr, exp_nat_nla_policy); | ||
2075 | |||
2076 | if (!tb[CTA_EXPECT_NAT_DIR] || !tb[CTA_EXPECT_NAT_TUPLE]) | ||
2077 | return -EINVAL; | ||
2078 | |||
2079 | err = ctnetlink_parse_tuple((const struct nlattr * const *)tb, | ||
2080 | &nat_tuple, CTA_EXPECT_NAT_TUPLE, u3); | ||
2081 | if (err < 0) | ||
2082 | return err; | ||
2083 | |||
2084 | exp->saved_ip = nat_tuple.src.u3.ip; | ||
2085 | exp->saved_proto = nat_tuple.src.u; | ||
2086 | exp->dir = ntohl(nla_get_be32(tb[CTA_EXPECT_NAT_DIR])); | ||
2087 | |||
2088 | return 0; | ||
2089 | #else | ||
2090 | return -EOPNOTSUPP; | ||
2091 | #endif | ||
2092 | } | ||
2093 | |||
2036 | static int | 2094 | static int |
2037 | ctnetlink_create_expect(struct net *net, u16 zone, | 2095 | ctnetlink_create_expect(struct net *net, u16 zone, |
2038 | const struct nlattr * const cda[], | 2096 | const struct nlattr * const cda[], |
@@ -2133,9 +2191,15 @@ ctnetlink_create_expect(struct net *net, u16 zone, | |||
2133 | memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3)); | 2191 | memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3)); |
2134 | exp->mask.src.u.all = mask.src.u.all; | 2192 | exp->mask.src.u.all = mask.src.u.all; |
2135 | 2193 | ||
2194 | if (cda[CTA_EXPECT_NAT]) { | ||
2195 | err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT], | ||
2196 | exp, u3); | ||
2197 | if (err < 0) | ||
2198 | goto err_out; | ||
2199 | } | ||
2136 | err = nf_ct_expect_related_report(exp, pid, report); | 2200 | err = nf_ct_expect_related_report(exp, pid, report); |
2201 | err_out: | ||
2137 | nf_ct_expect_put(exp); | 2202 | nf_ct_expect_put(exp); |
2138 | |||
2139 | out: | 2203 | out: |
2140 | nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); | 2204 | nf_ct_put(nf_ct_tuplehash_to_ctrack(h)); |
2141 | return err; | 2205 | return err; |