aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nf_conntrack_proto_tcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/netfilter/nf_conntrack_proto_tcp.c')
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c122
1 files changed, 60 insertions, 62 deletions
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index eb3fe7401466..c7075345971b 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -831,6 +831,20 @@ static int tcp_packet(struct nf_conn *conntrack,
tuple = &conntrack->tuplehash[dir].tuple;
switch (new_state) {
+ case TCP_CONNTRACK_SYN_SENT:
+ if (old_state < TCP_CONNTRACK_TIME_WAIT)
+ break;
+ if (conntrack->proto.tcp.seen[!dir].flags &
+ IP_CT_TCP_FLAG_CLOSE_INIT) {
+ /* Attempt to reopen a closed connection.
+ * Delete this connection and look up again. */
+ write_unlock_bh(&tcp_lock);
+ if (del_timer(&conntrack->timeout))
+ conntrack->timeout.function((unsigned long)
+ conntrack);
+ return -NF_REPEAT;
+ }
+ /* Fall through */
case TCP_CONNTRACK_IGNORE:
/* Ignored packets:
*
@@ -879,27 +893,6 @@ static int tcp_packet(struct nf_conn *conntrack,
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: invalid state ");
return -NF_ACCEPT;
- case TCP_CONNTRACK_SYN_SENT:
- if (old_state < TCP_CONNTRACK_TIME_WAIT)
- break;
- if ((conntrack->proto.tcp.seen[dir].flags &
- IP_CT_TCP_FLAG_CLOSE_INIT)
- || after(ntohl(th->seq),
- conntrack->proto.tcp.seen[dir].td_end)) {
- /* Attempt to reopen a closed connection.
- * Delete this connection and look up again. */
- write_unlock_bh(&tcp_lock);
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
- return -NF_REPEAT;
- } else {
- write_unlock_bh(&tcp_lock);
- if (LOG_INVALID(IPPROTO_TCP))
- nf_log_packet(pf, 0, skb, NULL, NULL,
- NULL, "nf_ct_tcp: invalid SYN");
- return -NF_ACCEPT;
- }
case TCP_CONNTRACK_CLOSE:
if (index == TCP_RST_SET
&& ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
@@ -1067,93 +1060,96 @@ static int tcp_new(struct nf_conn *conntrack,
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
-static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
+static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
const struct nf_conn *ct)
{
- struct nfattr *nest_parms;
+ struct nlattr *nest_parms;
struct nf_ct_tcp_flags tmp = {};
read_lock_bh(&tcp_lock);
- nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP);
- NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
+ nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED);
+ if (!nest_parms)
+ goto nla_put_failure;
+
+ NLA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
&ct->proto.tcp.state);
- NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t),
+ NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t),
&ct->proto.tcp.seen[0].td_scale);
- NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t),
+ NLA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t),
&ct->proto.tcp.seen[1].td_scale);
tmp.flags = ct->proto.tcp.seen[0].flags;
- NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
+ NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
sizeof(struct nf_ct_tcp_flags), &tmp);
tmp.flags = ct->proto.tcp.seen[1].flags;
- NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
+ NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
sizeof(struct nf_ct_tcp_flags), &tmp);
read_unlock_bh(&tcp_lock);
- NFA_NEST_END(skb, nest_parms);
+ nla_nest_end(skb, nest_parms);
return 0;
-nfattr_failure:
+nla_put_failure:
read_unlock_bh(&tcp_lock);
return -1;
}
-static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
- [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t),
- [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] = sizeof(u_int8_t),
- [CTA_PROTOINFO_TCP_WSCALE_REPLY-1] = sizeof(u_int8_t),
- [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1] = sizeof(struct nf_ct_tcp_flags),
- [CTA_PROTOINFO_TCP_FLAGS_REPLY-1] = sizeof(struct nf_ct_tcp_flags)
+static const struct nla_policy tcp_nla_policy[CTA_PROTOINFO_TCP_MAX+1] = {
+ [CTA_PROTOINFO_TCP_STATE] = { .type = NLA_U8 },
+ [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] = { .type = NLA_U8 },
+ [CTA_PROTOINFO_TCP_WSCALE_REPLY] = { .type = NLA_U8 },
+ [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL] = { .len = sizeof(struct nf_ct_tcp_flags) },
+ [CTA_PROTOINFO_TCP_FLAGS_REPLY] = { .len = sizeof(struct nf_ct_tcp_flags) },
};
-static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
+static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
{
- struct nfattr *attr = cda[CTA_PROTOINFO_TCP-1];
- struct nfattr *tb[CTA_PROTOINFO_TCP_MAX];
+ struct nlattr *attr = cda[CTA_PROTOINFO_TCP];
+ struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1];
+ int err;
/* updates could not contain anything about the private
* protocol info, in that case skip the parsing */
if (!attr)
return 0;
- nfattr_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr);
-
- if (nfattr_bad_size(tb, CTA_PROTOINFO_TCP_MAX, cta_min_tcp))
- return -EINVAL;
+ err = nla_parse_nested(tb, CTA_PROTOINFO_TCP_MAX, attr, tcp_nla_policy);
+ if (err < 0)
+ return err;
- if (!tb[CTA_PROTOINFO_TCP_STATE-1])
+ if (!tb[CTA_PROTOINFO_TCP_STATE])
return -EINVAL;
write_lock_bh(&tcp_lock);
ct->proto.tcp.state =
- *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
+ *(u_int8_t *)nla_data(tb[CTA_PROTOINFO_TCP_STATE]);
- if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) {
+ if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) {
struct nf_ct_tcp_flags *attr =
- NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]);
+ nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]);
ct->proto.tcp.seen[0].flags &= ~attr->mask;
ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask;
}
- if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]) {
+ if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) {
struct nf_ct_tcp_flags *attr =
- NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]);
+ nla_data(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]);
ct->proto.tcp.seen[1].flags &= ~attr->mask;
ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask;
}
- if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] &&
- tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1] &&
+ if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL] &&
+ tb[CTA_PROTOINFO_TCP_WSCALE_REPLY] &&
ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE &&
ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) {
ct->proto.tcp.seen[0].td_scale = *(u_int8_t *)
- NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]);
+ nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]);
ct->proto.tcp.seen[1].td_scale = *(u_int8_t *)
- NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]);
+ nla_data(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);
}
write_unlock_bh(&tcp_lock);
@@ -1384,10 +1380,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 __read_mostly =
.new = tcp_new,
.error = tcp_error,
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
- .to_nfattr = tcp_to_nfattr,
- .from_nfattr = nfattr_to_tcp,
- .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
- .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
+ .to_nlattr = tcp_to_nlattr,
+ .from_nlattr = nlattr_to_tcp,
+ .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
+ .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
.ctl_table_users = &tcp_sysctl_table_users,
@@ -1413,10 +1410,11 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 __read_mostly =
.new = tcp_new,
.error = tcp_error,
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
- .to_nfattr = tcp_to_nfattr,
- .from_nfattr = nfattr_to_tcp,
- .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
- .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
+ .to_nlattr = tcp_to_nlattr,
+ .from_nlattr = nlattr_to_tcp,
+ .tuple_to_nlattr = nf_ct_port_tuple_to_nlattr,
+ .nlattr_to_tuple = nf_ct_port_nlattr_to_tuple,
+ .nla_policy = nf_ct_port_nla_policy,
#endif
#ifdef CONFIG_SYSCTL
.ctl_table_users = &tcp_sysctl_table_users,