mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 12:21:37 +00:00
[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>
This commit is contained in:
parent
5c8ce7c921
commit
c8e2078cfe
@ -30,6 +30,11 @@ enum tcp_conntrack {
|
||||
/* Be liberal in window checking */
|
||||
#define IP_CT_TCP_FLAG_BE_LIBERAL 0x08
|
||||
|
||||
struct nf_ct_tcp_flags {
|
||||
u_int8_t flags;
|
||||
u_int8_t mask;
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct ip_ct_tcp_state {
|
||||
|
@ -83,6 +83,10 @@ enum ctattr_protoinfo {
|
||||
enum ctattr_protoinfo_tcp {
|
||||
CTA_PROTOINFO_TCP_UNSPEC,
|
||||
CTA_PROTOINFO_TCP_STATE,
|
||||
CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
|
||||
CTA_PROTOINFO_TCP_WSCALE_REPLY,
|
||||
CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
|
||||
CTA_PROTOINFO_TCP_FLAGS_REPLY,
|
||||
__CTA_PROTOINFO_TCP_MAX
|
||||
};
|
||||
#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1)
|
||||
|
@ -1101,11 +1101,26 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
|
||||
const struct nf_conn *ct)
|
||||
{
|
||||
struct nfattr *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),
|
||||
&ct->proto.tcp.state);
|
||||
|
||||
NFA_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),
|
||||
&ct->proto.tcp.seen[1].td_scale);
|
||||
|
||||
tmp.flags = ct->proto.tcp.seen[0].flags;
|
||||
NFA_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,
|
||||
sizeof(struct nf_ct_tcp_flags), &tmp);
|
||||
read_unlock_bh(&tcp_lock);
|
||||
|
||||
NFA_NEST_END(skb, nest_parms);
|
||||
@ -1118,7 +1133,11 @@ nfattr_failure:
|
||||
}
|
||||
|
||||
static const size_t cta_min_tcp[CTA_PROTOINFO_TCP_MAX] = {
|
||||
[CTA_PROTOINFO_TCP_STATE-1] = sizeof(u_int8_t),
|
||||
[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 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)
|
||||
write_lock_bh(&tcp_lock);
|
||||
ct->proto.tcp.state =
|
||||
*(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_TCP_STATE-1]);
|
||||
|
||||
if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]) {
|
||||
struct nf_ct_tcp_flags *attr =
|
||||
NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL-1]);
|
||||
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]) {
|
||||
struct nf_ct_tcp_flags *attr =
|
||||
NFA_DATA(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY-1]);
|
||||
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] &&
|
||||
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]);
|
||||
ct->proto.tcp.seen[1].td_scale = *(u_int8_t *)
|
||||
NFA_DATA(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY-1]);
|
||||
}
|
||||
write_unlock_bh(&tcp_lock);
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user