diff options
author | tuexen <tuexen@FreeBSD.org> | 2016-01-16 14:41:44 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2016-01-16 14:41:44 +0000 |
commit | 9b0e77811d60c22821172c855fb8186925eb6af4 (patch) | |
tree | e5d85483051dc50656e3439d2b1dbb927eb841fe /sys/netinet | |
parent | 65380e690e927bda1081b63c1ac0aaafe11f376d (diff) | |
download | FreeBSD-src-9b0e77811d60c22821172c855fb8186925eb6af4.zip FreeBSD-src-9b0e77811d60c22821172c855fb8186925eb6af4.tar.gz |
MFC r287282:
Fix the exporting of SCTP association states to userland. Without this,
associations in SHUTDOWN-PENDING were never reported correctly.
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/sctp_constants.h | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_sysctl.c | 2 | ||||
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 7 | ||||
-rw-r--r-- | sys/netinet/sctputil.c | 43 | ||||
-rw-r--r-- | sys/netinet/sctputil.h | 3 |
5 files changed, 49 insertions, 8 deletions
diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index d90bd25..135d46c 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -458,7 +458,7 @@ __FBSDID("$FreeBSD$"); /* - * SCTP states for internal state machine XXX (should match "user" values) + * SCTP states for internal state machine */ #define SCTP_STATE_EMPTY 0x0000 #define SCTP_STATE_INUSE 0x0001 diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c index 6eef6b9..1b35af7 100644 --- a/sys/netinet/sctp_sysctl.c +++ b/sys/netinet/sctp_sysctl.c @@ -453,7 +453,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HANDLER_ARGS) if (stcb->asoc.primary_destination != NULL) xstcb.primary_addr = stcb->asoc.primary_destination->ro._l_addr; xstcb.heartbeat_interval = stcb->asoc.heart_beat_delay; - xstcb.state = SCTP_GET_STATE(&stcb->asoc); /* FIXME */ + xstcb.state = (uint32_t) sctp_map_assoc_state(stcb->asoc.state); /* 7.0 does not support these */ xstcb.assoc_id = sctp_get_associd(stcb); xstcb.peers_rwnd = stcb->asoc.peers_rwnd; diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 76a2857..78f4508 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -2668,12 +2668,7 @@ flags_out: error = EINVAL; break; } - /* - * I think passing the state is fine since - * sctp_constants.h will be available to the user - * land. - */ - sstat->sstat_state = stcb->asoc.state; + sstat->sstat_state = sctp_map_assoc_state(stcb->asoc.state); sstat->sstat_assoc_id = sctp_get_associd(stcb); sstat->sstat_rwnd = stcb->asoc.peers_rwnd; sstat->sstat_unackdata = stcb->asoc.sent_queue_cnt; diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 069ed34..3030994 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -893,6 +893,49 @@ sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int ch return (x); } +int32_t +sctp_map_assoc_state(int kernel_state) +{ + int32_t user_state; + + if (kernel_state & SCTP_STATE_WAS_ABORTED) { + user_state = SCTP_CLOSED; + } else if (kernel_state & SCTP_STATE_SHUTDOWN_PENDING) { + user_state = SCTP_SHUTDOWN_PENDING; + } else { + switch (kernel_state & SCTP_STATE_MASK) { + case SCTP_STATE_EMPTY: + user_state = SCTP_CLOSED; + break; + case SCTP_STATE_INUSE: + user_state = SCTP_CLOSED; + break; + case SCTP_STATE_COOKIE_WAIT: + user_state = SCTP_COOKIE_WAIT; + break; + case SCTP_STATE_COOKIE_ECHOED: + user_state = SCTP_COOKIE_ECHOED; + break; + case SCTP_STATE_OPEN: + user_state = SCTP_ESTABLISHED; + break; + case SCTP_STATE_SHUTDOWN_SENT: + user_state = SCTP_SHUTDOWN_SENT; + break; + case SCTP_STATE_SHUTDOWN_RECEIVED: + user_state = SCTP_SHUTDOWN_RECEIVED; + break; + case SCTP_STATE_SHUTDOWN_ACK_SENT: + user_state = SCTP_SHUTDOWN_ACK_SENT; + break; + default: + user_state = SCTP_CLOSED; + break; + } + } + return (user_state); +} + int sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint32_t override_tag, uint32_t vrf_id) diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index 7df0a6c..82de736 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -67,6 +67,9 @@ void /* * Function prototypes */ +int32_t +sctp_map_assoc_state(int); + uint32_t sctp_get_ifa_hash_val(struct sockaddr *addr); |