[PATCH 09/13] SCTP: Make transmitted packets use per-namespace parameters.

From: Jan Ariyasu
Date: Sat Aug 04 2012 - 17:34:00 EST


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.ariyasu@xxxxxx>
---
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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/