diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2007-03-14 19:45:19 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 01:25:57 -0400 |
commit | c8e2078cfe414a99cf6f2f2f1d78c7e75392e9d4 (patch) | |
tree | 35f283c122ef0e82f0a76f7d42591ecaf77aa3f0 /net | |
parent | 5c8ce7c92106434d2bdc9d5dfa5f62bf4546b296 (diff) |
[NETFILTER]: ctnetlink: add support for internal tcp connection tracking flags handling
This patch let userspace programs set the IP_CT_TCP_BE_LIBERAL flag to
force the pickup of established connections.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index a1363626bccc..8439768f9d1c 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -1101,11 +1101,26 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa, | |||
1101 | const struct nf_conn *ct) | 1101 | const struct nf_conn *ct) |
1102 | { | 1102 | { |
1103 | struct nfattr *nest_parms; | 1103 | struct nfattr *nest_parms; |
1104 | struct nf_ct_tcp_flags tmp = {}; | ||
1104 | 1105 | ||
1105 | read_lock_bh(&tcp_lock); | 1106 | read_lock_bh(&tcp_lock); |
1106 | nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP); | 1107 | nest_parms = NFA_NEST(skb, CTA_PROTOINFO_TCP); |
1107 | NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t), | 1108 | NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t), |
1108 | &ct->proto.tcp.state); | 1109 | &ct->proto.tcp.state); |
1110 | |||
1111 | NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL, sizeof(u_int8_t), | ||
1112 | &ct->proto.tcp.seen[0].td_scale); | ||
1113 | |||
1114 | NFA_PUT(skb, CTA_PROTOINFO_TCP_WSCALE_REPLY, sizeof(u_int8_t), | ||
1115 | &ct->proto.tcp.seen[1].td_scale); | ||
1116 | |||
1117 | tmp.flags = ct->proto.tcp.seen[0].flags; | ||
1118 | NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL, | ||
1119 | sizeof(struct nf_ct_tcp_flags), &tmp); | ||
1120 | |||
1121 | tmp.flags = ct->proto.tcp.seen[1].flags; | ||
1122 | NFA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY, | ||
1123 | sizeof(struct nf_ct_tcp_flags), &tmp); | ||
1109 | read_unlock_bh(&tcp_lock); | 1124 | read_unlock_bh(&tcp_lock); |
1110 | 1125 | ||
1111 | NFA_NEST_END(skb, nest_parms); | 1126 | NFA_NEST_END(skb, nest_parms); |
@@ -1118,7 +1133,11 @@ nfattr_failure: | |||
1118 | } | 1133 | } |
1119 | 1134 | ||
1120 | static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = { | 1135 | static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = { |
1121 | [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t), | 1136 | [CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t), |
1137 | [CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] = sizeof(u_int8_t), | ||
1138 | [CTA_PROTOINFO_TCP_WSCALE_REPLY-1] = sizeof(u_int8_t), | ||
1139 | [CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1] = sizeof(struct nf_ct_tcp_flags), | ||
1140 | [CTA_PROTOINFO_TCP_FLAGS_REPLY-1] = sizeof(struct nf_ct_tcp_flags) | ||
1122 | }; | 1141 | }; |
1123 | 1142 | ||
1124 | static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct) | 1143 | static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct) |
@@ -1142,6 +1161,30 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct) | |||
1142 | write_lock_bh(&tcp_lock); | 1161 | write_lock_bh(&tcp_lock); |
1143 | ct->proto.tcp.state = | 1162 | ct->proto.tcp.state = |
1144 | *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]); | 1163 | *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]); |
1164 | |||
1165 | if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) { | ||
1166 | struct nf_ct_tcp_flags *attr = | ||
1167 | NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]); | ||
1168 | ct->proto.tcp.seen[0].flags &= ~attr->mask; | ||
1169 | ct->proto.tcp.seen[0].flags |= attr->flags & attr->mask; | ||
1170 | } | ||
1171 | |||
1172 | if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]) { | ||
1173 | struct nf_ct_tcp_flags *attr = | ||
1174 | NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]); | ||
1175 | ct->proto.tcp.seen[1].flags &= ~attr->mask; | ||
1176 | ct->proto.tcp.seen[1].flags |= attr->flags & attr->mask; | ||
1177 | } | ||
1178 | |||
1179 | if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1] && | ||
1180 | tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1] && | ||
1181 | ct->proto.tcp.seen[0].flags & IP_CT_TCP_FLAG_WINDOW_SCALE && | ||
1182 | ct->proto.tcp.seen[1].flags & IP_CT_TCP_FLAG_WINDOW_SCALE) { | ||
1183 | ct->proto.tcp.seen[0].td_scale = *(u_int8_t *) | ||
1184 | NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL-1]); | ||
1185 | ct->proto.tcp.seen[1].td_scale = *(u_int8_t *) | ||
1186 | NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]); | ||
1187 | } | ||
1145 | write_unlock_bh(&tcp_lock); | 1188 | write_unlock_bh(&tcp_lock); |
1146 | 1189 | ||
1147 | return 0; | 1190 | return 0; |