This patch set makes transmitted packets use per-namespace protocol
parameters such as rto_initial, max_retrans_path, etc.

Signed-off-by: Jan Ariyasu <jan.ariy...@hp.com>
---
 include/net/sctp/structs.h |    5 +++--
 net/sctp/associola.c       |    2 +-
 net/sctp/output.c          |    2 +-
 net/sctp/outqueue.c        |   16 ++++++++++------
 net/sctp/sm_sideeffect.c   |    7 ++++---
 net/sctp/sm_statefuns.c    |    2 +-
 net/sctp/transport.c       |   28 +++++++++++++++++-----------
 7 files changed, 37 insertions(+), 25 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 72d473b..b016da6 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1219,7 +1219,8 @@ struct sctp_transport {
        __u64 hb_nonce;
 };
 
-struct sctp_transport *sctp_transport_new(const union sctp_addr *,
+struct sctp_transport *sctp_transport_new(struct net *net,
+                                         const union sctp_addr *,
                                          gfp_t);
 void sctp_transport_set_owner(struct sctp_transport *,
                              struct sctp_association *);
@@ -1231,7 +1232,7 @@ void sctp_transport_free(struct sctp_transport *);
 void sctp_transport_reset_timers(struct sctp_transport *);
 void sctp_transport_hold(struct sctp_transport *);
 void sctp_transport_put(struct sctp_transport *);
-void sctp_transport_update_rto(struct sctp_transport *, __u32);
+void sctp_transport_update_rto(struct net *, struct sctp_transport *, __u32);
 void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32);
 void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
 void sctp_transport_burst_limited(struct sctp_transport *);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 5b4be66..b778eba 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -681,7 +681,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct 
sctp_association *asoc,
                return peer;
        }
 
-       peer = sctp_transport_new(addr, gfp);
+       peer = sctp_transport_new(net, addr, gfp);
        if (!peer)
                return NULL;
 
diff --git a/net/sctp/output.c b/net/sctp/output.c
index f9c5ffa..93a8b01 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -599,7 +599,7 @@ out:
        return err;
 no_route:
        kfree_skb(nskb);
-       IP_INC_STATS_BH(&init_net, IPSTATS_MIB_OUTNOROUTES);
+       IP_INC_STATS_BH(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES);
 
        /* FIXME: Returning the 'err' will effect all the associations
         * associated with a socket, although only one of the paths of the
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index e7aa177c..1334bad 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -60,7 +60,8 @@
 
 /* Declare internal functions here.  */
 static int sctp_acked(struct sctp_sackhdr *sack, __u32 tsn);
-static void sctp_check_transmitted(struct sctp_outq *q,
+static void sctp_check_transmitted(struct net *net,
+                                  struct sctp_outq *q,
                                   struct list_head *transmitted_queue,
                                   struct sctp_transport *transport,
                                   struct sctp_sackhdr *sack,
@@ -1154,6 +1155,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct 
sctp_sackhdr *sack)
        int count_of_newacks = 0;
        int gap_ack_blocks;
        u8 accum_moved = 0;
+       struct net *net = sock_net(asoc->base.sk);
 
        /* Grab the association's destination address list. */
        transport_list = &asoc->peer.transport_addr_list;
@@ -1210,7 +1212,8 @@ int sctp_outq_sack(struct sctp_outq *q, struct 
sctp_sackhdr *sack)
        /* Run through the retransmit queue.  Credit bytes received
         * and free those chunks that we can.
         */
-       sctp_check_transmitted(q, &q->retransmit, NULL, sack, &highest_new_tsn);
+       sctp_check_transmitted(net, q, &q->retransmit, NULL, sack,
+                               &highest_new_tsn);
 
        /* Run through the transmitted queue.
         * Credit bytes received and free those chunks which we can.
@@ -1218,7 +1221,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct 
sctp_sackhdr *sack)
         * This is a MASSIVE candidate for optimization.
         */
        list_for_each_entry(transport, transport_list, transports) {
-               sctp_check_transmitted(q, &transport->transmitted,
+               sctp_check_transmitted(net, q, &transport->transmitted,
                                       transport, sack, &highest_new_tsn);
                /*
                 * SFR-CACC algorithm:
@@ -1323,7 +1326,8 @@ int sctp_outq_is_empty(const struct sctp_outq *q)
  * transmitted_queue, we print a range: SACKED: TSN1-TSN2, TSN3, TSN4-TSN5.
  * KEPT TSN6-TSN7, etc.
  */
-static void sctp_check_transmitted(struct sctp_outq *q,
+static void sctp_check_transmitted(struct net *net,
+                                  struct sctp_outq *q,
                                   struct list_head *transmitted_queue,
                                   struct sctp_transport *transport,
                                   struct sctp_sackhdr *sack,
@@ -1402,8 +1406,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
                                    tchunk->rtt_in_progress) {
                                        tchunk->rtt_in_progress = 0;
                                        rtt = jiffies - tchunk->sent_at;
-                                       sctp_transport_update_rto(transport,
-                                                                 rtt);
+                                       sctp_transport_update_rto(net,
+                                                       transport, rtt);
                                }
                        }
 
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 35cbbe5..c683d88 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -685,7 +685,8 @@ static void sctp_cmd_hb_timer_update(sctp_cmd_seq_t *cmds,
 }
 
 /* Helper function to handle the reception of an HEARTBEAT ACK.  */
-static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
+static void sctp_cmd_transport_on(struct net *net,
+                                 sctp_cmd_seq_t *cmds,
                                  struct sctp_association *asoc,
                                  struct sctp_transport *t,
                                  struct sctp_chunk *chunk)
@@ -739,7 +740,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds,
                t->rto_pending = 1;
 
        hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data;
-       sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at));
+       sctp_transport_update_rto(net, t, (jiffies - hbinfo->sent_at));
 
        /* Update the heartbeat timer.  */
        if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t)))
@@ -1617,7 +1618,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 
                case SCTP_CMD_TRANSPORT_ON:
                        t = cmd->obj.transport;
-                       sctp_cmd_transport_on(commands, asoc, t, chunk);
+                       sctp_cmd_transport_on(net, commands, asoc, t, chunk);
                        break;
 
                case SCTP_CMD_HB_TIMERS_START:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index b9b6b13..0d4aaa9 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -6043,7 +6043,7 @@ static struct sctp_packet *sctp_ootb_pkt_new(struct net 
*net,
        }
 
        /* Make a transport for the bucket, Eliza... */
-       transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
+       transport = sctp_transport_new(net, sctp_source(chunk), GFP_ATOMIC);
        if (!transport)
                goto nomem;
 
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 856ba86..c4fc596 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -59,10 +59,13 @@
 /* 1st Level Abstractions.  */
 
 /* Initialize a new transport from provided memory.  */
-static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
+static struct sctp_transport *sctp_transport_init(struct net *net,
+                                                 struct sctp_transport *peer,
                                                  const union sctp_addr *addr,
                                                  gfp_t gfp)
 {
+       struct sctp_net_params *net_params = sctp_get_params(net);
+
        /* Copy in the address.  */
        peer->ipaddr = *addr;
        peer->af_specific = sctp_get_af_specific(addr->sa.sa_family);
@@ -76,7 +79,7 @@ static struct sctp_transport *sctp_transport_init(struct 
sctp_transport *peer,
         * given destination transport address, set RTO to the protocol
         * parameter 'RTO.Initial'.
         */
-       peer->rto = msecs_to_jiffies(sctp_rto_initial);
+       peer->rto = msecs_to_jiffies(net_params->rto_initial);
 
        peer->last_time_heard = jiffies;
        peer->last_time_ecne_reduced = jiffies;
@@ -86,8 +89,8 @@ static struct sctp_transport *sctp_transport_init(struct 
sctp_transport *peer,
                            SPP_SACKDELAY_ENABLE;
 
        /* Initialize the default path max_retrans.  */
-       peer->pathmaxrxt  = sctp_max_retrans_path;
-       peer->pf_retrans  = sctp_pf_retrans;
+       peer->pathmaxrxt  = net_params->max_retrans_path;
+       peer->pf_retrans  = net_params->pf_retrans;
 
        INIT_LIST_HEAD(&peer->transmitted);
        INIT_LIST_HEAD(&peer->send_ready);
@@ -109,7 +112,8 @@ static struct sctp_transport *sctp_transport_init(struct 
sctp_transport *peer,
 }
 
 /* Allocate and initialize a new transport.  */
-struct sctp_transport *sctp_transport_new(const union sctp_addr *addr,
+struct sctp_transport *sctp_transport_new(struct net *net,
+                                         const union sctp_addr *addr,
                                          gfp_t gfp)
 {
        struct sctp_transport *transport;
@@ -118,7 +122,7 @@ struct sctp_transport *sctp_transport_new(const union 
sctp_addr *addr,
        if (!transport)
                goto fail;
 
-       if (!sctp_transport_init(transport, addr, gfp))
+       if (!sctp_transport_init(net, transport, addr, gfp))
                goto fail_init;
 
        transport->malloced = 1;
@@ -310,8 +314,10 @@ void sctp_transport_put(struct sctp_transport *transport)
 }
 
 /* Update transport's RTO based on the newly calculated RTT. */
-void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
+void sctp_transport_update_rto(struct net *net, struct sctp_transport *tp,
+                               __u32 rtt)
 {
+       struct sctp_net_params *net_params = sctp_get_params(net);
        /* Check for valid transport.  */
        SCTP_ASSERT(tp, "NULL transport", return);
 
@@ -330,10 +336,10 @@ void sctp_transport_update_rto(struct sctp_transport *tp, 
__u32 rtt)
                 * For example, assuming the default value of RTO.Alpha of
                 * 1/8, rto_alpha would be expressed as 3.
                 */
-               tp->rttvar = tp->rttvar - (tp->rttvar >> sctp_rto_beta)
-                       + ((abs(tp->srtt - rtt)) >> sctp_rto_beta);
-               tp->srtt = tp->srtt - (tp->srtt >> sctp_rto_alpha)
-                       + (rtt >> sctp_rto_alpha);
+               tp->rttvar = tp->rttvar - (tp->rttvar >> net_params->rto_beta)
+                       + ((abs(tp->srtt - rtt)) >> net_params->rto_beta);
+               tp->srtt = tp->srtt - (tp->srtt >> net_params->rto_alpha)
+                       + (rtt >> net_params->rto_alpha);
        } else {
                /* 6.3.1 C2) When the first RTT measurement R is made, set
                 * SRTT <- R, RTTVAR <- R/2.
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to