From 1a0b02167717b55ed89f5738187b0fc5777000b7 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Tue, 21 Aug 2018 13:25:32 +0000 Subject: [PATCH] Refactor the SHUTDOWN_PENDING state handling. This is not a functional change but a preperation for the upcoming DTrace support. It is necessary to change the state in one logical operation, even if it involves clearing the sub state SHUTDOWN_PENDING. MFC after: 1 month --- sys/netinet/sctp_constants.h | 4 ++-- sys/netinet/sctp_indata.c | 4 ---- sys/netinet/sctp_input.c | 2 -- sys/netinet/sctp_output.c | 2 -- sys/netinet/sctp_pcb.c | 1 - sys/netinet/sctp_timer.c | 1 - sys/netinet/sctp_usrreq.c | 2 -- sys/netinet/sctputil.c | 22 ++++++++++++++++++++++ sys/netinet/sctputil.h | 2 ++ 9 files changed, 26 insertions(+), 14 deletions(-) diff --git a/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h index f654bd7d4cc1..d07381d59b72 100644 --- a/sys/netinet/sctp_constants.h +++ b/sys/netinet/sctp_constants.h @@ -473,11 +473,11 @@ __FBSDID("$FreeBSD$"); #define SCTP_GET_STATE(_stcb) \ ((_stcb)->asoc.state & SCTP_STATE_MASK) #define SCTP_SET_STATE(_stcb, _state) \ - (_stcb)->asoc.state = ((_stcb)->asoc.state & ~SCTP_STATE_MASK) | (_state) + sctp_set_state(_stcb, _state) #define SCTP_CLEAR_SUBSTATE(_stcb, _substate) \ (_stcb)->asoc.state &= ~(_substate) #define SCTP_ADD_SUBSTATE(_stcb, _substate) \ - (_stcb)->asoc.state |= (_substate) + sctp_add_substate(_stcb, _substate) /* SCTP reachability state for each address */ #define SCTP_ADDR_REACHABLE 0x001 diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 4eb216a8131e..3c46ab4ebafe 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -4355,7 +4355,6 @@ again: SCTP_STAT_DECR_GAUGE32(sctps_currestab); } SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); if (asoc->alternate) { netp = asoc->alternate; @@ -4373,7 +4372,6 @@ again: SCTP_STAT_DECR_GAUGE32(sctps_currestab); SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_ACK_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); if (asoc->alternate) { netp = asoc->alternate; @@ -5052,7 +5050,6 @@ hopeless_peer: SCTP_STAT_DECR_GAUGE32(sctps_currestab); } SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); if (asoc->alternate) { netp = asoc->alternate; @@ -5071,7 +5068,6 @@ hopeless_peer: SCTP_STAT_DECR_GAUGE32(sctps_currestab); SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_ACK_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); if (asoc->alternate) { netp = asoc->alternate; diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index 210107c9fd5e..b8a0c31511f8 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -962,7 +962,6 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp, (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT) && (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_SENT)) { SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_RECEIVED); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); /* * notify upper layer that peer has initiated a * shutdown @@ -997,7 +996,6 @@ sctp_handle_shutdown(struct sctp_shutdown_chunk *cp, (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED)) { SCTP_STAT_DECR_GAUGE32(sctps_currestab); } - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); if (SCTP_GET_STATE(stcb) != SCTP_STATE_SHUTDOWN_ACK_SENT) { SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_ACK_SENT); sctp_stop_timers_for_shutdown(stcb); diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 64dd9178f7a1..0e523c2f0ae6 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -6709,7 +6709,6 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, SCTP_STAT_DECR_GAUGE32(sctps_currestab); } SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); sctp_send_shutdown(stcb, net); sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, @@ -13507,7 +13506,6 @@ dataless_eof: SCTP_STAT_DECR_GAUGE32(sctps_currestab); } SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); if (stcb->asoc.alternate) { netp = stcb->asoc.alternate; diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index b02e627ed05c..c83b63b8b507 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -3437,7 +3437,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) SCTP_STAT_DECR_GAUGE32(sctps_currestab); } SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(asoc); if (asoc->asoc.alternate) { netp = asoc->asoc.alternate; diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 83edeccd39fe..8f6422b45ebe 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -1567,7 +1567,6 @@ sctp_autoclose_timer(struct sctp_inpcb *inp, SCTP_STAT_DECR_GAUGE32(sctps_currestab); } SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); if (stcb->asoc.alternate) { netp = stcb->asoc.alternate; diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index 704e470c9c82..7e0517927d64 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -739,7 +739,6 @@ sctp_disconnect(struct socket *so) SCTP_STAT_DECR_GAUGE32(sctps_currestab); } SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); if (stcb->asoc.alternate) { netp = stcb->asoc.alternate; @@ -946,7 +945,6 @@ sctp_shutdown(struct socket *so) /* there is nothing queued to send, so I'm done... */ SCTP_STAT_DECR_GAUGE32(sctps_currestab); SCTP_SET_STATE(stcb, SCTP_STATE_SHUTDOWN_SENT); - SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); sctp_stop_timers_for_shutdown(stcb); sctp_send_shutdown(stcb, netp); sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 27ad68b5872a..1df833328fa7 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -7381,3 +7381,25 @@ sctp_hc_get_mtu(union sctp_sockstore *addr, uint16_t fibnum) } return ((uint32_t)tcp_hc_getmtu(&inc)); } +void +sctp_set_state(struct sctp_tcb *stcb, int new_state) +{ + KASSERT((new_state & ~SCTP_STATE_MASK) == 0, + ("sctp_set_state: Can't set substate (new_state = %x)", + new_state)); + stcb->asoc.state = (stcb->asoc.state & ~SCTP_STATE_MASK) | new_state; + if ((new_state == SCTP_STATE_SHUTDOWN_RECEIVED) || + (new_state == SCTP_STATE_SHUTDOWN_SENT) || + (new_state == SCTP_STATE_SHUTDOWN_ACK_SENT)) { + SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_SHUTDOWN_PENDING); + } +} + +void +sctp_add_substate(struct sctp_tcb *stcb, int substate) +{ + KASSERT((substate & SCTP_STATE_MASK) == 0, + ("sctp_add_substate: Can't set state (substate = %x)", + substate)); + stcb->asoc.state |= substate; +} diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index c7ffc34d1ec8..c12fb210a9a3 100644 --- a/sys/netinet/sctputil.h +++ b/sys/netinet/sctputil.h @@ -388,5 +388,7 @@ void sctp_audit_log(uint8_t, uint8_t); uint32_t sctp_min_mtu(uint32_t, uint32_t, uint32_t); void sctp_hc_set_mtu(union sctp_sockstore *, uint16_t, uint32_t); uint32_t sctp_hc_get_mtu(union sctp_sockstore *, uint16_t); +void sctp_set_state(struct sctp_tcb *, int); +void sctp_add_substate(struct sctp_tcb *, int); #endif /* _KERNEL */ #endif