Author: tuexen
Date: Thu Feb  3 19:59:00 2011
New Revision: 218235
URL: http://svn.freebsd.org/changeset/base/218235

Log:
  Make sure that changing the ECN sysctl does not affect
  exisiting associations and endpoints.
  
  MFC after: 3 months.

Modified:
  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/sctputil.c

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Thu Feb  3 19:50:42 2011        
(r218234)
+++ head/sys/netinet/sctp_input.c       Thu Feb  3 19:59:00 2011        
(r218235)
@@ -2719,6 +2719,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->partial_delivery_point = 
(*inp_p)->partial_delivery_point;
                        inp->sctp_context = (*inp_p)->sctp_context;
                        inp->inp_starting_point_for_iterator = NULL;
@@ -5614,7 +5615,8 @@ sctp_common_input_processing(struct mbuf
                 */
        }
        /* take care of ecn */
-       if (stcb->asoc.ecn_allowed && ((ecn_bits & SCTP_CE_BITS) == 
SCTP_CE_BITS)) {
+       if ((stcb->asoc.ecn_allowed == 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      Thu Feb  3 19:50:42 2011        
(r218234)
+++ head/sys/netinet/sctp_output.c      Thu Feb  3 19:59:00 2011        
(r218235)
@@ -3392,10 +3392,11 @@ static uint8_t
 sctp_get_ect(struct sctp_tcb *stcb,
     struct sctp_tmit_chunk *chk)
 {
-       if (SCTP_BASE_SYSCTL(sctp_ecn_enable) == 0)
+       if ((stcb != NULL) && (stcb->asoc.ecn_allowed == 1)) {
+               return (SCTP_ECT0_BIT);
+       } else {
                return (0);
-
-       return (SCTP_ECT0_BIT);
+       }
 }
 
 static int
@@ -3502,17 +3503,9 @@ sctp_lowlevel_chunk_output(struct sctp_i
 
                ip->ip_ttl = inp->ip_inp.inp.inp_ip_ttl;
                ip->ip_len = packet_length;
-               if (stcb) {
-                       if ((stcb->asoc.ecn_allowed) && ecn_ok) {
-                               /* Enable ECN */
-                               ip->ip_tos = ((u_char)(tos_value & 0xfc) | 
sctp_get_ect(stcb, chk));
-                       } else {
-                               /* No ECN */
-                               ip->ip_tos = (u_char)(tos_value & 0xfc);
-                       }
-               } else {
-                       /* no association at all */
-                       ip->ip_tos = (tos_value & 0xfc);
+               ip->ip_tos = tos_value & 0xfc;
+               if (ecn_ok) {
+                       ip->ip_tos |= sctp_get_ect(stcb, chk);
                }
                if (port) {
                        ip->ip_p = IPPROTO_UDP;
@@ -3839,18 +3832,11 @@ sctp_lowlevel_chunk_output(struct sctp_i
                } else {
                        ro = (sctp_route_t *) & net->ro;
                }
-               if (stcb != NULL) {
-                       if ((stcb->asoc.ecn_allowed) && ecn_ok) {
-                               /* Enable ECN */
-                               tosBottom = (((((struct in6pcb 
*)inp)->in6p_flowinfo & 0x0c) | sctp_get_ect(stcb, chk)) << 4);
-                       } else {
-                               /* No ECN */
-                               tosBottom = ((((struct in6pcb 
*)inp)->in6p_flowinfo & 0x0c) << 4);
-                       }
-               } else {
-                       /* we could get no asoc if it is a O-O-T-B packet */
-                       tosBottom = ((((struct in6pcb *)inp)->in6p_flowinfo & 
0x0c) << 4);
+               tosBottom = (((struct in6pcb *)inp)->in6p_flowinfo & 0x0c);
+               if (ecn_ok) {
+                       tosBottom |= sctp_get_ect(stcb, chk);
                }
+               tosBottom <<= 4;
                ip6h->ip6_flow = htonl(((tosTop << 24) | ((tosBottom | flowTop) 
<< 16) | flowBottom));
                if (port) {
                        ip6h->ip6_nxt = IPPROTO_UDP;
@@ -4247,7 +4233,7 @@ sctp_send_initiate(struct sctp_inpcb *in
                stcb->asoc.cookie_preserve_req = 0;
        }
        /* ECN parameter */
-       if (SCTP_BASE_SYSCTL(sctp_ecn_enable) == 1) {
+       if (stcb->asoc.ecn_allowed == 1) {
                ecn->ph.param_type = htons(SCTP_ECN_CAPABLE);
                ecn->ph.param_length = htons(sizeof(*ecn));
                SCTP_BUF_LEN(m) += sizeof(*ecn);
@@ -5350,7 +5336,8 @@ do_a_abort:
        ecn = (struct sctp_ecn_supported_param *)((caddr_t)ali + sizeof(*ali));
 
        /* ECN parameter */
-       if (SCTP_BASE_SYSCTL(sctp_ecn_enable) == 1) {
+       if (((asoc != NULL) && (asoc->ecn_allowed == 1)) ||
+           (inp->sctp_ecn_enable == 1)) {
                ecn->ph.param_type = htons(SCTP_ECN_CAPABLE);
                ecn->ph.param_length = htons(sizeof(*ecn));
                SCTP_BUF_LEN(m) += sizeof(*ecn);

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c Thu Feb  3 19:50:42 2011        (r218234)
+++ head/sys/netinet/sctp_pcb.c Thu Feb  3 19:59:00 2011        (r218235)
@@ -2399,6 +2399,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);
        /* 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) {
@@ -5899,6 +5900,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;
 
        /* First get the destination address setup too. */
        memset(&sin, 0, sizeof(sin));
@@ -5959,7 +5961,7 @@ sctp_load_addresses_from_init(struct sct
                sa = altsa;
        }
        /* Turn off ECN until we get through all params */
-       stcb->asoc.ecn_allowed = 0;
+       ecn_allowed = 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;
@@ -6192,7 +6194,7 @@ sctp_load_addresses_from_init(struct sct
                                }
                        }
                } else if (ptype == SCTP_ECN_CAPABLE) {
-                       stcb->asoc.ecn_allowed = 1;
+                       ecn_allowed = 1;
                } else if (ptype == SCTP_ULP_ADAPTATION) {
                        if (stcb->asoc.state != SCTP_STATE_OPEN) {
                                struct sctp_adaptation_layer_indication ai,
@@ -6431,6 +6433,9 @@ next_param:
                        }
                }
        }
+       if (ecn_allowed == 0) {
+               stcb->asoc.ecn_allowed = 0;
+       }
        /* 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 Thu Feb  3 19:50:42 2011        (r218234)
+++ head/sys/netinet/sctp_pcb.h Thu Feb  3 19:59:00 2011        (r218235)
@@ -394,6 +394,7 @@ struct sctp_inpcb {
        uint32_t partial_delivery_point;
        uint32_t sctp_context;
        uint32_t sctp_cmt_on_off;
+       uint32_t sctp_ecn_enable;
        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     Thu Feb  3 19:50:42 2011        
(r218234)
+++ head/sys/netinet/sctp_peeloff.c     Thu Feb  3 19:59:00 2011        
(r218235)
@@ -1,5 +1,8 @@
 /*-
  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
+ * Copyright (c) 2008-2011, by Randall Stewart, r...@lakerest.net and
+ *                          Michael Tuexen, tue...@fh-muenster.de
+ *                          All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -113,6 +116,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->partial_delivery_point = inp->partial_delivery_point;
        n_inp->sctp_context = inp->sctp_context;
        n_inp->inp_starting_point_for_iterator = NULL;
@@ -185,6 +189,7 @@ sctp_get_peeloff(struct socket *head, sc
        n_inp->sctp_features = inp->sctp_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->partial_delivery_point = inp->partial_delivery_point;
        n_inp->sctp_context = inp->sctp_context;
        n_inp->inp_starting_point_for_iterator = NULL;

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c Thu Feb  3 19:50:42 2011        (r218234)
+++ head/sys/netinet/sctputil.c Thu Feb  3 19:59:00 2011        (r218235)
@@ -1,5 +1,8 @@
 /*-
  * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
+ * Copyright (c) 2008-2011, by Randall Stewart, r...@lakerest.net and
+ *                          Michael Tuexen, tue...@fh-muenster.de
+ *                          All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -917,6 +920,7 @@ sctp_init_asoc(struct sctp_inpcb *m, str
        asoc->heart_beat_delay = 
TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
        asoc->cookie_life = m->sctp_ep.def_cookie_life;
        asoc->sctp_cmt_on_off = m->sctp_cmt_on_off;
+       asoc->ecn_allowed = m->sctp_ecn_enable;
        asoc->sctp_nr_sack_on_off = (uint8_t) 
SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
        asoc->sctp_cmt_pf = (uint8_t) SCTP_BASE_SYSCTL(sctp_cmt_pf);
        asoc->sctp_frag_point = m->sctp_frag_point;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to