mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-25 10:19:47 +00:00
netfilter: conntrack: unify established states for SCTP paths
commita44b765148
upstream. An SCTP endpoint can start an association through a path and tear it down over another one. That means the initial path will not see the shutdown sequence, and the conntrack entry will remain in ESTABLISHED state for 5 days. By merging the HEARTBEAT_ACKED and ESTABLISHED states into one ESTABLISHED state, there remains no difference between a primary or secondary path. The timeout for the merged ESTABLISHED state is set to 210 seconds (hb_interval * max_path_retrans + rto_max). So, even if a path doesn't see the shutdown sequence, it will expire in a reasonable amount of time. With this change in place, there is now more than one state from which we can transition to ESTABLISHED, COOKIE_ECHOED and HEARTBEAT_SENT, so handle the setting of ASSURED bit whenever a state change has happened and the new state is ESTABLISHED. Removed the check for dir==REPLY since the transition to ESTABLISHED can happen only in the reply direction. Fixes:9fb9cbb108
("[NETFILTER]: Add nf_conntrack subsystem.") Signed-off-by: Sriram Yagnaraman <sriram.yagnaraman@est.tech> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8770cd9d7c
commit
f571e34005
4 changed files with 41 additions and 64 deletions
|
@ -15,7 +15,7 @@ enum sctp_conntrack {
|
||||||
SCTP_CONNTRACK_SHUTDOWN_RECD,
|
SCTP_CONNTRACK_SHUTDOWN_RECD,
|
||||||
SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
|
SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
|
||||||
SCTP_CONNTRACK_HEARTBEAT_SENT,
|
SCTP_CONNTRACK_HEARTBEAT_SENT,
|
||||||
SCTP_CONNTRACK_HEARTBEAT_ACKED,
|
SCTP_CONNTRACK_HEARTBEAT_ACKED, /* no longer used */
|
||||||
SCTP_CONNTRACK_MAX
|
SCTP_CONNTRACK_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ enum ctattr_timeout_sctp {
|
||||||
CTA_TIMEOUT_SCTP_SHUTDOWN_RECD,
|
CTA_TIMEOUT_SCTP_SHUTDOWN_RECD,
|
||||||
CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
|
CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
|
||||||
CTA_TIMEOUT_SCTP_HEARTBEAT_SENT,
|
CTA_TIMEOUT_SCTP_HEARTBEAT_SENT,
|
||||||
CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED,
|
CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED, /* no longer used */
|
||||||
__CTA_TIMEOUT_SCTP_MAX
|
__CTA_TIMEOUT_SCTP_MAX
|
||||||
};
|
};
|
||||||
#define CTA_TIMEOUT_SCTP_MAX (__CTA_TIMEOUT_SCTP_MAX - 1)
|
#define CTA_TIMEOUT_SCTP_MAX (__CTA_TIMEOUT_SCTP_MAX - 1)
|
||||||
|
|
|
@ -27,22 +27,16 @@
|
||||||
#include <net/netfilter/nf_conntrack_ecache.h>
|
#include <net/netfilter/nf_conntrack_ecache.h>
|
||||||
#include <net/netfilter/nf_conntrack_timeout.h>
|
#include <net/netfilter/nf_conntrack_timeout.h>
|
||||||
|
|
||||||
/* FIXME: Examine ipfilter's timeouts and conntrack transitions more
|
|
||||||
closely. They're more complex. --RR
|
|
||||||
|
|
||||||
And so for me for SCTP :D -Kiran */
|
|
||||||
|
|
||||||
static const char *const sctp_conntrack_names[] = {
|
static const char *const sctp_conntrack_names[] = {
|
||||||
"NONE",
|
[SCTP_CONNTRACK_NONE] = "NONE",
|
||||||
"CLOSED",
|
[SCTP_CONNTRACK_CLOSED] = "CLOSED",
|
||||||
"COOKIE_WAIT",
|
[SCTP_CONNTRACK_COOKIE_WAIT] = "COOKIE_WAIT",
|
||||||
"COOKIE_ECHOED",
|
[SCTP_CONNTRACK_COOKIE_ECHOED] = "COOKIE_ECHOED",
|
||||||
"ESTABLISHED",
|
[SCTP_CONNTRACK_ESTABLISHED] = "ESTABLISHED",
|
||||||
"SHUTDOWN_SENT",
|
[SCTP_CONNTRACK_SHUTDOWN_SENT] = "SHUTDOWN_SENT",
|
||||||
"SHUTDOWN_RECD",
|
[SCTP_CONNTRACK_SHUTDOWN_RECD] = "SHUTDOWN_RECD",
|
||||||
"SHUTDOWN_ACK_SENT",
|
[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = "SHUTDOWN_ACK_SENT",
|
||||||
"HEARTBEAT_SENT",
|
[SCTP_CONNTRACK_HEARTBEAT_SENT] = "HEARTBEAT_SENT",
|
||||||
"HEARTBEAT_ACKED",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SECS * HZ
|
#define SECS * HZ
|
||||||
|
@ -54,12 +48,11 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
|
||||||
[SCTP_CONNTRACK_CLOSED] = 10 SECS,
|
[SCTP_CONNTRACK_CLOSED] = 10 SECS,
|
||||||
[SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
|
[SCTP_CONNTRACK_COOKIE_WAIT] = 3 SECS,
|
||||||
[SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
|
[SCTP_CONNTRACK_COOKIE_ECHOED] = 3 SECS,
|
||||||
[SCTP_CONNTRACK_ESTABLISHED] = 5 DAYS,
|
[SCTP_CONNTRACK_ESTABLISHED] = 210 SECS,
|
||||||
[SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
|
[SCTP_CONNTRACK_SHUTDOWN_SENT] = 300 SECS / 1000,
|
||||||
[SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
|
[SCTP_CONNTRACK_SHUTDOWN_RECD] = 300 SECS / 1000,
|
||||||
[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
|
[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT] = 3 SECS,
|
||||||
[SCTP_CONNTRACK_HEARTBEAT_SENT] = 30 SECS,
|
[SCTP_CONNTRACK_HEARTBEAT_SENT] = 30 SECS,
|
||||||
[SCTP_CONNTRACK_HEARTBEAT_ACKED] = 210 SECS,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SCTP_FLAG_HEARTBEAT_VTAG_FAILED 1
|
#define SCTP_FLAG_HEARTBEAT_VTAG_FAILED 1
|
||||||
|
@ -73,7 +66,6 @@ static const unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] = {
|
||||||
#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
|
#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD
|
||||||
#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
|
#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
|
||||||
#define sHS SCTP_CONNTRACK_HEARTBEAT_SENT
|
#define sHS SCTP_CONNTRACK_HEARTBEAT_SENT
|
||||||
#define sHA SCTP_CONNTRACK_HEARTBEAT_ACKED
|
|
||||||
#define sIV SCTP_CONNTRACK_MAX
|
#define sIV SCTP_CONNTRACK_MAX
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -96,9 +88,6 @@ SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
|
||||||
CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
|
CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
|
||||||
the SHUTDOWN chunk. Connection is closed.
|
the SHUTDOWN chunk. Connection is closed.
|
||||||
HEARTBEAT_SENT - We have seen a HEARTBEAT in a new flow.
|
HEARTBEAT_SENT - We have seen a HEARTBEAT in a new flow.
|
||||||
HEARTBEAT_ACKED - We have seen a HEARTBEAT-ACK in the direction opposite to
|
|
||||||
that of the HEARTBEAT chunk. Secondary connection is
|
|
||||||
established.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* TODO
|
/* TODO
|
||||||
|
@ -115,33 +104,33 @@ cookie echoed to closed.
|
||||||
static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
|
static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
|
||||||
{
|
{
|
||||||
/* ORIGINAL */
|
/* ORIGINAL */
|
||||||
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
|
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */
|
||||||
/* init */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCW, sHA},
|
/* init */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCW},
|
||||||
/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
|
/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},
|
||||||
/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
|
/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
|
||||||
/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL, sSS},
|
/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL},
|
||||||
/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA, sHA},
|
/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA},
|
||||||
/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't have Stale cookie*/
|
/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/
|
||||||
/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* 5.2.4 - Big TODO */
|
/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */
|
||||||
/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't come in orig dir */
|
/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */
|
||||||
/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL, sHA},
|
/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL},
|
||||||
/* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
|
/* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
|
||||||
/* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA}
|
/* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* REPLY */
|
/* REPLY */
|
||||||
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
|
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS */
|
||||||
/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* INIT in sCL Big TODO */
|
/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* INIT in sCL Big TODO */
|
||||||
/* init_ack */ {sIV, sCW, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
|
/* init_ack */ {sIV, sCW, sCW, sCE, sES, sSS, sSR, sSA, sIV},
|
||||||
/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV, sCL},
|
/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV},
|
||||||
/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV, sSR},
|
/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV},
|
||||||
/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV, sHA},
|
/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV},
|
||||||
/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV, sHA},
|
/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV},
|
||||||
/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* Can't come in reply dir */
|
/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */
|
||||||
/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV, sHA},
|
/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV},
|
||||||
/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV, sHA},
|
/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV},
|
||||||
/* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
|
/* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS},
|
||||||
/* heartbeat_ack*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHA, sHA}
|
/* heartbeat_ack*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sES},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -508,8 +497,12 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
|
||||||
}
|
}
|
||||||
|
|
||||||
ct->proto.sctp.state = new_state;
|
ct->proto.sctp.state = new_state;
|
||||||
if (old_state != new_state)
|
if (old_state != new_state) {
|
||||||
nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
|
nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
|
||||||
|
if (new_state == SCTP_CONNTRACK_ESTABLISHED &&
|
||||||
|
!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
|
||||||
|
nf_conntrack_event_cache(IPCT_ASSURED, ct);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&ct->lock);
|
spin_unlock_bh(&ct->lock);
|
||||||
|
|
||||||
|
@ -523,14 +516,6 @@ int nf_conntrack_sctp_packet(struct nf_conn *ct,
|
||||||
|
|
||||||
nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
|
nf_ct_refresh_acct(ct, ctinfo, skb, timeouts[new_state]);
|
||||||
|
|
||||||
if (old_state == SCTP_CONNTRACK_COOKIE_ECHOED &&
|
|
||||||
dir == IP_CT_DIR_REPLY &&
|
|
||||||
new_state == SCTP_CONNTRACK_ESTABLISHED) {
|
|
||||||
pr_debug("Setting assured bit\n");
|
|
||||||
set_bit(IPS_ASSURED_BIT, &ct->status);
|
|
||||||
nf_conntrack_event_cache(IPCT_ASSURED, ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
|
|
|
@ -581,7 +581,6 @@ enum nf_ct_sysctl_index {
|
||||||
NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_RECD,
|
NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_RECD,
|
||||||
NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
|
NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
|
||||||
NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_SENT,
|
NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_SENT,
|
||||||
NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_ACKED,
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NF_CT_PROTO_DCCP
|
#ifdef CONFIG_NF_CT_PROTO_DCCP
|
||||||
NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST,
|
NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST,
|
||||||
|
@ -851,12 +850,6 @@ static struct ctl_table nf_ct_sysctl_table[] = {
|
||||||
.mode = 0644,
|
.mode = 0644,
|
||||||
.proc_handler = proc_dointvec_jiffies,
|
.proc_handler = proc_dointvec_jiffies,
|
||||||
},
|
},
|
||||||
[NF_SYSCTL_CT_PROTO_TIMEOUT_SCTP_HEARTBEAT_ACKED] = {
|
|
||||||
.procname = "nf_conntrack_sctp_timeout_heartbeat_acked",
|
|
||||||
.maxlen = sizeof(unsigned int),
|
|
||||||
.mode = 0644,
|
|
||||||
.proc_handler = proc_dointvec_jiffies,
|
|
||||||
},
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_NF_CT_PROTO_DCCP
|
#ifdef CONFIG_NF_CT_PROTO_DCCP
|
||||||
[NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST] = {
|
[NF_SYSCTL_CT_PROTO_TIMEOUT_DCCP_REQUEST] = {
|
||||||
|
@ -985,7 +978,6 @@ static void nf_conntrack_standalone_init_sctp_sysctl(struct net *net,
|
||||||
XASSIGN(SHUTDOWN_RECD, sn);
|
XASSIGN(SHUTDOWN_RECD, sn);
|
||||||
XASSIGN(SHUTDOWN_ACK_SENT, sn);
|
XASSIGN(SHUTDOWN_ACK_SENT, sn);
|
||||||
XASSIGN(HEARTBEAT_SENT, sn);
|
XASSIGN(HEARTBEAT_SENT, sn);
|
||||||
XASSIGN(HEARTBEAT_ACKED, sn);
|
|
||||||
#undef XASSIGN
|
#undef XASSIGN
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue