Author: tuexen
Date: Sat Jan 16 14:41:44 2016
New Revision: 294149
URL: https://svnweb.freebsd.org/changeset/base/294149

Log:
  MFC r287282:
  Fix the exporting of SCTP association states to userland. Without this,
  associations in SHUTDOWN-PENDING were never reported correctly.

Modified:
  stable/10/sys/netinet/sctp_constants.h
  stable/10/sys/netinet/sctp_sysctl.c
  stable/10/sys/netinet/sctp_usrreq.c
  stable/10/sys/netinet/sctputil.c
  stable/10/sys/netinet/sctputil.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/netinet/sctp_constants.h
==============================================================================
--- stable/10/sys/netinet/sctp_constants.h      Sat Jan 16 12:50:00 2016        
(r294148)
+++ stable/10/sys/netinet/sctp_constants.h      Sat Jan 16 14:41:44 2016        
(r294149)
@@ -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

Modified: stable/10/sys/netinet/sctp_sysctl.c
==============================================================================
--- stable/10/sys/netinet/sctp_sysctl.c Sat Jan 16 12:50:00 2016        
(r294148)
+++ stable/10/sys/netinet/sctp_sysctl.c Sat Jan 16 14:41:44 2016        
(r294149)
@@ -453,7 +453,7 @@ sctp_sysctl_handle_assoclist(SYSCTL_HAND
                        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;

Modified: stable/10/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/10/sys/netinet/sctp_usrreq.c Sat Jan 16 12:50:00 2016        
(r294148)
+++ stable/10/sys/netinet/sctp_usrreq.c Sat Jan 16 14:41:44 2016        
(r294149)
@@ -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;

Modified: stable/10/sys/netinet/sctputil.c
==============================================================================
--- stable/10/sys/netinet/sctputil.c    Sat Jan 16 12:50:00 2016        
(r294148)
+++ stable/10/sys/netinet/sctputil.c    Sat Jan 16 14:41:44 2016        
(r294149)
@@ -893,6 +893,49 @@ sctp_select_a_tag(struct sctp_inpcb *inp
        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)

Modified: stable/10/sys/netinet/sctputil.h
==============================================================================
--- stable/10/sys/netinet/sctputil.h    Sat Jan 16 12:50:00 2016        
(r294148)
+++ stable/10/sys/netinet/sctputil.h    Sat Jan 16 14:41:44 2016        
(r294149)
@@ -67,6 +67,9 @@ void
 /*
  * Function prototypes
  */
+int32_t
+sctp_map_assoc_state(int);
+
 uint32_t
 sctp_get_ifa_hash_val(struct sockaddr *addr);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to