Skip to content

Commit

Permalink
[SCTP]: Update SCTP_PEER_ADDR_PARAMS socket option to the latest api …
Browse files Browse the repository at this point in the history
…draft.

This patch adds support to set/get heartbeat interval, maximum number of
retransmissions, pathmtu, sackdelay time for a particular transport/
association/socket as per the latest SCTP sockets api draft11.

Signed-off-by: Frank Filz <ffilz@us.ibm.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Frank Filz authored and David S. Miller committed Jan 3, 2006
1 parent fd96625 commit 52ccb8e
Show file tree
Hide file tree
Showing 9 changed files with 595 additions and 220 deletions.
76 changes: 56 additions & 20 deletions include/net/sctp/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,24 @@ struct sctp_sock {
__u32 default_context;
__u32 default_timetolive;

/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
* the destination address every heartbeat interval. This value
* will be inherited by all new associations.
*/
__u32 hbinterval;

/* This is the max_retrans value for new associations. */
__u16 pathmaxrxt;

/* The initial Path MTU to use for new associations. */
__u32 pathmtu;

/* The default SACK delay timeout for new associations. */
__u32 sackdelay;

/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
__u32 param_flags;

struct sctp_initmsg initmsg;
struct sctp_rtoinfo rtoinfo;
struct sctp_paddrparams paddrparam;
Expand Down Expand Up @@ -845,9 +863,6 @@ struct sctp_transport {
/* Data that has been sent, but not acknowledged. */
__u32 flight_size;

/* PMTU : The current known path MTU. */
__u32 pmtu;

/* Destination */
struct dst_entry *dst;
/* Source address. */
Expand All @@ -862,7 +877,22 @@ struct sctp_transport {
/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
* the destination address every heartbeat interval.
*/
int hb_interval;
__u32 hbinterval;

/* This is the max_retrans value for the transport and will
* be initialized from the assocs value. This can be changed
* using SCTP_SET_PEER_ADDR_PARAMS socket option.
*/
__u16 pathmaxrxt;

/* PMTU : The current known path MTU. */
__u32 pathmtu;

/* SACK delay timeout */
__u32 sackdelay;

/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
__u32 param_flags;

/* When was the last time (in jiffies) that we heard from this
* transport? We use this to pick new active and retran paths.
Expand All @@ -882,22 +912,11 @@ struct sctp_transport {
*/
int state;

/* hb_allowed : The current heartbeat state of this destination,
* : i.e. ALLOW-HB, NO-HEARTBEAT, etc.
*/
int hb_allowed;

/* These are the error stats for this destination. */

/* Error count : The current error count for this destination. */
unsigned short error_count;

/* This is the max_retrans value for the transport and will
* be initialized to proto.max_retrans.path. This can be changed
* using SCTP_SET_PEER_ADDR_PARAMS socket option.
*/
int max_retrans;

/* Per : A timer used by each destination.
* Destination :
* Timer :
Expand Down Expand Up @@ -1502,6 +1521,28 @@ struct sctp_association {
/* The largest timeout or RTO value to use in attempting an INIT */
__u16 max_init_timeo;

/* Heartbeat interval: The endpoint sends out a Heartbeat chunk to
* the destination address every heartbeat interval. This value
* will be inherited by all new transports.
*/
__u32 hbinterval;

/* This is the max_retrans value for new transports in the
* association.
*/
__u16 pathmaxrxt;

/* Association : The smallest PMTU discovered for all of the
* PMTU : peer's transport addresses.
*/
__u32 pathmtu;

/* SACK delay timeout */
__u32 sackdelay;

/* Flags controling Heartbeat, SACK delay, and Path MTU Discovery. */
__u32 param_flags;

int timeouts[SCTP_NUM_TIMEOUT_TYPES];
struct timer_list timers[SCTP_NUM_TIMEOUT_TYPES];

Expand Down Expand Up @@ -1571,11 +1612,6 @@ struct sctp_association {
*/
wait_queue_head_t wait;

/* Association : The smallest PMTU discovered for all of the
* PMTU : peer's transport addresses.
*/
__u32 pmtu;

/* The message size at which SCTP fragmentation will occur. */
__u32 frag_point;

Expand Down
16 changes: 16 additions & 0 deletions include/net/sctp/user.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,11 +503,27 @@ struct sctp_setadaption {
* unreachable. The following structure is used to access and modify an
* address's parameters:
*/
enum sctp_spp_flags {
SPP_HB_ENABLE = 1, /*Enable heartbeats*/
SPP_HB_DISABLE = 2, /*Disable heartbeats*/
SPP_HB = SPP_HB_ENABLE | SPP_HB_DISABLE,
SPP_HB_DEMAND = 4, /*Send heartbeat immediately*/
SPP_PMTUD_ENABLE = 8, /*Enable PMTU discovery*/
SPP_PMTUD_DISABLE = 16, /*Disable PMTU discovery*/
SPP_PMTUD = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE,
SPP_SACKDELAY_ENABLE = 32, /*Enable SACK*/
SPP_SACKDELAY_DISABLE = 64, /*Disable SACK*/
SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE,
};

struct sctp_paddrparams {
sctp_assoc_t spp_assoc_id;
struct sockaddr_storage spp_address;
__u32 spp_hbinterval;
__u16 spp_pathmaxrxt;
__u32 spp_pathmtu;
__u32 spp_sackdelay;
__u32 spp_flags;
} __attribute__((packed, aligned(4)));

/*
Expand Down
81 changes: 55 additions & 26 deletions net/sctp/associola.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
asoc->cookie_life.tv_sec = sp->assocparams.sasoc_cookie_life / 1000;
asoc->cookie_life.tv_usec = (sp->assocparams.sasoc_cookie_life % 1000)
* 1000;
asoc->pmtu = 0;
asoc->frag_point = 0;

/* Set the association max_retrans and RTO values from the
Expand All @@ -123,6 +122,25 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a

asoc->overall_error_count = 0;

/* Initialize the association's heartbeat interval based on the
* sock configured value.
*/
asoc->hbinterval = msecs_to_jiffies(sp->hbinterval);

/* Initialize path max retrans value. */
asoc->pathmaxrxt = sp->pathmaxrxt;

/* Initialize default path MTU. */
asoc->pathmtu = sp->pathmtu;

/* Set association default SACK delay */
asoc->sackdelay = msecs_to_jiffies(sp->sackdelay);

/* Set the association default flags controlling
* Heartbeat, SACK delay, and Path MTU Discovery.
*/
asoc->param_flags = sp->param_flags;

/* Initialize the maximum mumber of new data packets that can be sent
* in a burst.
*/
Expand All @@ -144,8 +162,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
= 5 * asoc->rto_max;

asoc->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0;
asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] =
SCTP_DEFAULT_TIMEOUT_SACK;
asoc->timeouts[SCTP_EVENT_TIMEOUT_SACK] = asoc->sackdelay;
asoc->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] =
sp->autoclose * HZ;

Expand Down Expand Up @@ -540,23 +557,46 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,

sctp_transport_set_owner(peer, asoc);

/* Initialize the peer's heartbeat interval based on the
* association configured value.
*/
peer->hbinterval = asoc->hbinterval;

/* Set the path max_retrans. */
peer->pathmaxrxt = asoc->pathmaxrxt;

/* Initialize the peer's SACK delay timeout based on the
* association configured value.
*/
peer->sackdelay = asoc->sackdelay;

/* Enable/disable heartbeat, SACK delay, and path MTU discovery
* based on association setting.
*/
peer->param_flags = asoc->param_flags;

/* Initialize the pmtu of the transport. */
sctp_transport_pmtu(peer);
if (peer->param_flags & SPP_PMTUD_ENABLE)
sctp_transport_pmtu(peer);
else if (asoc->pathmtu)
peer->pathmtu = asoc->pathmtu;
else
peer->pathmtu = SCTP_DEFAULT_MAXSEGMENT;

/* If this is the first transport addr on this association,
* initialize the association PMTU to the peer's PMTU.
* If not and the current association PMTU is higher than the new
* peer's PMTU, reset the association PMTU to the new peer's PMTU.
*/
if (asoc->pmtu)
asoc->pmtu = min_t(int, peer->pmtu, asoc->pmtu);
if (asoc->pathmtu)
asoc->pathmtu = min_t(int, peer->pathmtu, asoc->pathmtu);
else
asoc->pmtu = peer->pmtu;
asoc->pathmtu = peer->pathmtu;

SCTP_DEBUG_PRINTK("sctp_assoc_add_peer:association %p PMTU set to "
"%d\n", asoc, asoc->pmtu);
"%d\n", asoc, asoc->pathmtu);

asoc->frag_point = sctp_frag_point(sp, asoc->pmtu);
asoc->frag_point = sctp_frag_point(sp, asoc->pathmtu);

/* The asoc->peer.port might not be meaningful yet, but
* initialize the packet structure anyway.
Expand All @@ -574,7 +614,7 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
* (for example, implementations MAY use the size of the
* receiver advertised window).
*/
peer->cwnd = min(4*asoc->pmtu, max_t(__u32, 2*asoc->pmtu, 4380));
peer->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));

/* At this point, we may not have the receiver's advertised window,
* so initialize ssthresh to the default value and it will be set
Expand All @@ -585,17 +625,6 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
peer->partial_bytes_acked = 0;
peer->flight_size = 0;

/* By default, enable heartbeat for peer address. */
peer->hb_allowed = 1;

/* Initialize the peer's heartbeat interval based on the
* sock configured value.
*/
peer->hb_interval = msecs_to_jiffies(sp->paddrparam.spp_hbinterval);

/* Set the path max_retrans. */
peer->max_retrans = sp->paddrparam.spp_pathmaxrxt;

/* Set the transport's RTO.initial value */
peer->rto = asoc->rto_initial;

Expand Down Expand Up @@ -1155,18 +1184,18 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
/* Get the lowest pmtu of all the transports. */
list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, struct sctp_transport, transports);
if (!pmtu || (t->pmtu < pmtu))
pmtu = t->pmtu;
if (!pmtu || (t->pathmtu < pmtu))
pmtu = t->pathmtu;
}

if (pmtu) {
struct sctp_sock *sp = sctp_sk(asoc->base.sk);
asoc->pmtu = pmtu;
asoc->pathmtu = pmtu;
asoc->frag_point = sctp_frag_point(sp, pmtu);
}

SCTP_DEBUG_PRINTK("%s: asoc:%p, pmtu:%d, frag_point:%d\n",
__FUNCTION__, asoc, asoc->pmtu, asoc->frag_point);
__FUNCTION__, asoc, asoc->pathmtu, asoc->frag_point);
}

/* Should we send a SACK to update our peer? */
Expand All @@ -1179,7 +1208,7 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
case SCTP_STATE_SHUTDOWN_SENT:
if ((asoc->rwnd > asoc->a_rwnd) &&
((asoc->rwnd - asoc->a_rwnd) >=
min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pmtu)))
min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu)))
return 1;
break;
default:
Expand Down
36 changes: 27 additions & 9 deletions net/sctp/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -305,18 +305,36 @@ int sctp_backlog_rcv(struct sock *sk, struct sk_buff *skb)
void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
struct sctp_transport *t, __u32 pmtu)
{
if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
printk(KERN_WARNING "%s: Reported pmtu %d too low, "
"using default minimum of %d\n", __FUNCTION__, pmtu,
SCTP_DEFAULT_MINSEGMENT);
pmtu = SCTP_DEFAULT_MINSEGMENT;
}
if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu))
return;

if (!sock_owned_by_user(sk) && t && (t->pmtu != pmtu)) {
t->pmtu = pmtu;
if (t->param_flags & SPP_PMTUD_ENABLE) {
if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
printk(KERN_WARNING "%s: Reported pmtu %d too low, "
"using default minimum of %d\n",
__FUNCTION__, pmtu,
SCTP_DEFAULT_MINSEGMENT);
/* Use default minimum segment size and disable
* pmtu discovery on this transport.
*/
t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
t->param_flags = (t->param_flags & ~SPP_HB) |
SPP_PMTUD_DISABLE;
} else {
t->pathmtu = pmtu;
}

/* Update association pmtu. */
sctp_assoc_sync_pmtu(asoc);
sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
}

/* Retransmit with the new pmtu setting.
* Normally, if PMTU discovery is disabled, an ICMP Fragmentation
* Needed will never be sent, but if a message was sent before
* PMTU discovery was disabled that was larger than the PMTU, it
* would not be fragmented, so it must be re-transmitted fragmented.
*/
sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD);
}

/*
Expand Down
Loading

0 comments on commit 52ccb8e

Please sign in to comment.