Author: tuexen
Date: Sat Aug  2 17:35:13 2014
New Revision: 269436
URL: http://svnweb.freebsd.org/changeset/base/269436

Log:
  Cleanup the ECN configuration handling and provide an SCTP socket
  option for controlling ECN on future associations and get the
  status on current associations.
  A simialar pattern will be used for controlling SCTP extensions in
  upcoming commits.

Modified:
  head/lib/libc/net/sctp_sys_calls.c
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_pcb.h
  head/sys/netinet/sctp_peeloff.c
  head/sys/netinet/sctp_structs.h
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet/sctputil.c

Modified: head/lib/libc/net/sctp_sys_calls.c
==============================================================================
--- head/lib/libc/net/sctp_sys_calls.c  Sat Aug  2 17:18:47 2014        
(r269435)
+++ head/lib/libc/net/sctp_sys_calls.c  Sat Aug  2 17:35:13 2014        
(r269436)
@@ -350,6 +350,9 @@ sctp_opt_info(int sd, sctp_assoc_t id, i
        case SCTP_REMOTE_UDP_ENCAPS_PORT:
                ((struct sctp_udpencaps *)arg)->sue_assoc_id = id;
                break;
+       case SCTP_ECN_SUPPORTED:
+               ((struct sctp_assoc_value *)arg)->assoc_id = id;
+               break;
        case SCTP_MAX_BURST:
                ((struct sctp_assoc_value *)arg)->assoc_id = id;
                break;

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h     Sat Aug  2 17:18:47 2014        (r269435)
+++ head/sys/netinet/sctp.h     Sat Aug  2 17:35:13 2014        (r269436)
@@ -121,6 +121,7 @@ struct sctp_paramhdr {
 #define SCTP_DEFAULT_PRINFO             0x00000022
 #define SCTP_PEER_ADDR_THLDS            0x00000023
 #define SCTP_REMOTE_UDP_ENCAPS_PORT     0x00000024
+#define SCTP_ECN_SUPPORTED              0x00000025
 
 /*
  * read-only options

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Sat Aug  2 17:18:47 2014        
(r269435)
+++ head/sys/netinet/sctp_input.c       Sat Aug  2 17:35:13 2014        
(r269436)
@@ -2785,7 +2785,7 @@ sctp_handle_cookie_echo(struct mbuf *m, 
                        inp->sctp_socket = so;
                        inp->sctp_frag_point = (*inp_p)->sctp_frag_point;
                        inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
-                       inp->sctp_ecn_enable = (*inp_p)->sctp_ecn_enable;
+                       inp->ecn_supported = (*inp_p)->ecn_supported;
                        inp->partial_delivery_point = 
(*inp_p)->partial_delivery_point;
                        inp->sctp_context = (*inp_p)->sctp_context;
                        inp->local_strreset_support = 
(*inp_p)->local_strreset_support;
@@ -5898,7 +5898,7 @@ sctp_common_input_processing(struct mbuf
        }
        /* take care of ecn */
        if ((data_processed == 1) &&
-           (stcb->asoc.ecn_allowed == 1) &&
+           (stcb->asoc.ecn_supported == 1) &&
            ((ecn_bits & SCTP_CE_BITS) == SCTP_CE_BITS)) {
                /* Yep, we need to add a ECNE */
                sctp_send_ecn_echo(stcb, net, high_tsn);

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c      Sat Aug  2 17:18:47 2014        
(r269435)
+++ head/sys/netinet/sctp_output.c      Sat Aug  2 17:35:13 2014        
(r269436)
@@ -3914,7 +3914,7 @@ sctp_add_cookie(struct mbuf *init, int i
 static uint8_t
 sctp_get_ect(struct sctp_tcb *stcb)
 {
-       if ((stcb != NULL) && (stcb->asoc.ecn_allowed == 1)) {
+       if ((stcb != NULL) && (stcb->asoc.ecn_supported == 1)) {
                return (SCTP_ECT0_BIT);
        } else {
                return (0);
@@ -4785,7 +4785,7 @@ sctp_send_initiate(struct sctp_inpcb *in
                chunk_len += parameter_len;
        }
        /* ECN parameter */
-       if (stcb->asoc.ecn_allowed == 1) {
+       if (stcb->asoc.ecn_supported == 1) {
                parameter_len = (uint16_t) sizeof(struct sctp_paramhdr);
                ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+chunk_len);
                ph->param_type = htons(SCTP_ECN_CAPABLE);
@@ -5882,8 +5882,8 @@ do_a_abort:
                chunk_len += parameter_len;
        }
        /* ECN parameter */
-       if (((asoc != NULL) && (asoc->ecn_allowed == 1)) ||
-           ((asoc == NULL) && (inp->sctp_ecn_enable == 1))) {
+       if (((asoc != NULL) && (asoc->ecn_supported == 1)) ||
+           ((asoc == NULL) && (inp->ecn_supported == 1))) {
                parameter_len = (uint16_t) sizeof(struct sctp_paramhdr);
                ph = (struct sctp_paramhdr *)(mtod(m, caddr_t)+chunk_len);
                ph->param_type = htons(SCTP_ECN_CAPABLE);

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c Sat Aug  2 17:18:47 2014        (r269435)
+++ head/sys/netinet/sctp_pcb.c Sat Aug  2 17:35:13 2014        (r269436)
@@ -2483,7 +2483,7 @@ sctp_inpcb_alloc(struct socket *so, uint
        inp->partial_delivery_point = SCTP_SB_LIMIT_RCV(so) >> 
SCTP_PARTIAL_DELIVERY_SHIFT;
        inp->sctp_frag_point = SCTP_DEFAULT_MAXSEGMENT;
        inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
-       inp->sctp_ecn_enable = SCTP_BASE_SYSCTL(sctp_ecn_enable);
+       inp->ecn_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_ecn_enable);
        /* init the small hash table we use to track asocid <-> tcb */
        inp->sctp_asocidhash = SCTP_HASH_INIT(SCTP_STACK_VTAG_HASH_SIZE, 
&inp->hashasocidmark);
        if (inp->sctp_asocidhash == NULL) {
@@ -6081,7 +6081,7 @@ sctp_load_addresses_from_init(struct sct
        sctp_key_t *new_key;
        uint32_t keylen;
        int got_random = 0, got_hmacs = 0, got_chklist = 0;
-       uint8_t ecn_allowed;
+       uint8_t ecn_supported;
 
 #ifdef INET
        struct sockaddr_in sin;
@@ -6111,7 +6111,7 @@ sctp_load_addresses_from_init(struct sct
                sa = src;
        }
        /* Turn off ECN until we get through all params */
-       ecn_allowed = 0;
+       ecn_supported = 0;
        TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
                /* mark all addresses that we have currently on the list */
                net->dest_state |= SCTP_ADDR_NOT_IN_ASSOC;
@@ -6360,7 +6360,7 @@ sctp_load_addresses_from_init(struct sct
                } else
 #endif
                if (ptype == SCTP_ECN_CAPABLE) {
-                       ecn_allowed = 1;
+                       ecn_supported = 1;
                } else if (ptype == SCTP_ULP_ADAPTATION) {
                        if (stcb->asoc.state != SCTP_STATE_OPEN) {
                                struct sctp_adaptation_layer_indication ai,
@@ -6612,9 +6612,7 @@ next_param:
                        }
                }
        }
-       if (ecn_allowed == 0) {
-               stcb->asoc.ecn_allowed = 0;
-       }
+       stcb->asoc.ecn_supported &= ecn_supported;
        /* validate authentication required parameters */
        if (got_random && got_hmacs) {
                stcb->asoc.peer_supports_auth = 1;

Modified: head/sys/netinet/sctp_pcb.h
==============================================================================
--- head/sys/netinet/sctp_pcb.h Sat Aug  2 17:18:47 2014        (r269435)
+++ head/sys/netinet/sctp_pcb.h Sat Aug  2 17:35:13 2014        (r269436)
@@ -406,7 +406,7 @@ struct sctp_inpcb {
        uint32_t sctp_context;
        uint8_t local_strreset_support;
        uint32_t sctp_cmt_on_off;
-       uint32_t sctp_ecn_enable;
+       uint8_t ecn_supported;
        struct sctp_nonpad_sndrcvinfo def_send;
        /*-
         * These three are here for the sosend_dgram

Modified: head/sys/netinet/sctp_peeloff.c
==============================================================================
--- head/sys/netinet/sctp_peeloff.c     Sat Aug  2 17:18:47 2014        
(r269435)
+++ head/sys/netinet/sctp_peeloff.c     Sat Aug  2 17:35:13 2014        
(r269436)
@@ -118,7 +118,7 @@ sctp_do_peeloff(struct socket *head, str
        n_inp->sctp_mobility_features = inp->sctp_mobility_features;
        n_inp->sctp_frag_point = inp->sctp_frag_point;
        n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
-       n_inp->sctp_ecn_enable = inp->sctp_ecn_enable;
+       n_inp->ecn_supported = inp->ecn_supported;
        n_inp->partial_delivery_point = inp->partial_delivery_point;
        n_inp->sctp_context = inp->sctp_context;
        n_inp->local_strreset_support = inp->local_strreset_support;

Modified: head/sys/netinet/sctp_structs.h
==============================================================================
--- head/sys/netinet/sctp_structs.h     Sat Aug  2 17:18:47 2014        
(r269435)
+++ head/sys/netinet/sctp_structs.h     Sat Aug  2 17:35:13 2014        
(r269436)
@@ -1151,7 +1151,7 @@ struct sctp_association {
         */
 
        /* Flag to tell if ECN is allowed */
-       uint8_t ecn_allowed;
+       uint8_t ecn_supported;
 
        /* Did the peer make the stream config (add out) request */
        uint8_t peer_req_out;

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c      Sat Aug  2 17:18:47 2014        
(r269435)
+++ head/sys/netinet/sctp_usrreq.c      Sat Aug  2 17:35:13 2014        
(r269436)
@@ -3294,6 +3294,33 @@ flags_out:
                        }
                        break;
                }
+       case SCTP_ECN_SUPPORTED:
+               {
+                       struct sctp_assoc_value *av;
+
+                       SCTP_CHECK_AND_CAST(av, optval, struct 
sctp_assoc_value, *optsize);
+                       SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+
+                       if (stcb) {
+                               av->assoc_value = stcb->asoc.ecn_supported;
+                               SCTP_TCB_UNLOCK(stcb);
+                       } else {
+                               if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) 
||
+                                   (inp->sctp_flags & 
SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+                                   (av->assoc_id == SCTP_FUTURE_ASSOC)) {
+                                       SCTP_INP_RLOCK(inp);
+                                       av->assoc_value = inp->ecn_supported;
+                                       SCTP_INP_RUNLOCK(inp);
+                               } else {
+                                       SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP_USRREQ, EINVAL);
+                                       error = EINVAL;
+                               }
+                       }
+                       if (error == 0) {
+                               *optsize = sizeof(struct sctp_assoc_value);
+                       }
+                       break;
+               }
        case SCTP_ENABLE_STREAM_RESET:
                {
                        struct sctp_assoc_value *av;
@@ -5857,6 +5884,35 @@ sctp_setopt(struct socket *so, int optna
                        }
                        break;
                }
+       case SCTP_ECN_SUPPORTED:
+               {
+                       struct sctp_assoc_value *av;
+
+                       SCTP_CHECK_AND_CAST(av, optval, struct 
sctp_assoc_value, optsize);
+                       SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+
+                       if (stcb) {
+                               SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP_USRREQ, EINVAL);
+                               error = EINVAL;
+                               SCTP_TCB_UNLOCK(stcb);
+                       } else {
+                               if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) 
||
+                                   (inp->sctp_flags & 
SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+                                   (av->assoc_id == SCTP_FUTURE_ASSOC)) {
+                                       SCTP_INP_WLOCK(inp);
+                                       if (av->assoc_value == 0) {
+                                               inp->ecn_supported = 0;
+                                       } else {
+                                               inp->ecn_supported = 0;
+                                       }
+                                       SCTP_INP_WUNLOCK(inp);
+                               } else {
+                                       SCTP_LTRACE_ERR_RET(inp, NULL, NULL, 
SCTP_FROM_SCTP_USRREQ, EINVAL);
+                                       error = EINVAL;
+                               }
+                       }
+                       break;
+               }
        default:
                SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, 
ENOPROTOOPT);
                error = ENOPROTOOPT;

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c Sat Aug  2 17:18:47 2014        (r269435)
+++ head/sys/netinet/sctputil.c Sat Aug  2 17:35:13 2014        (r269436)
@@ -904,7 +904,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, s
        asoc->heart_beat_delay = 
TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
        asoc->cookie_life = inp->sctp_ep.def_cookie_life;
        asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
-       asoc->ecn_allowed = inp->sctp_ecn_enable;
+       asoc->ecn_supported = inp->ecn_supported;
        asoc->sctp_nr_sack_on_off = (uint8_t) 
SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
        asoc->sctp_cmt_pf = (uint8_t) 0;
        asoc->sctp_frag_point = inp->sctp_frag_point;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to