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-sctp" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html