summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/user.h15
-rw-r--r--net/sctp/socket.c54
2 files changed, 52 insertions, 17 deletions
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index 4ed752119bb..80b7afea17f 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -513,16 +513,17 @@ struct sctp_setadaptation {
* address's parameters:
*/
enum sctp_spp_flags {
- SPP_HB_ENABLE = 1, /*Enable heartbeats*/
- SPP_HB_DISABLE = 2, /*Disable heartbeats*/
+ SPP_HB_ENABLE = 1<<0, /*Enable heartbeats*/
+ SPP_HB_DISABLE = 1<<1, /*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_HB_DEMAND = 1<<2, /*Send heartbeat immediately*/
+ SPP_PMTUD_ENABLE = 1<<3, /*Enable PMTU discovery*/
+ SPP_PMTUD_DISABLE = 1<<4, /*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_ENABLE = 1<<5, /*Enable SACK*/
+ SPP_SACKDELAY_DISABLE = 1<<6, /*Disable SACK*/
SPP_SACKDELAY = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE,
+ SPP_HB_TIME_IS_ZERO = 1<<7, /* Set HB delay to 0 */
};
struct sctp_paddrparams {
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 1e787a2d0b5..dda2f6700f5 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2039,6 +2039,10 @@ static int sctp_setsockopt_autoclose(struct sock *sk, char __user *optval,
* SPP_HB_DEMAND - Request a user initiated heartbeat
* to be made immediately.
*
+ * SPP_HB_TIME_IS_ZERO - Specify's that the time for
+ * heartbeat delayis to be set to the value of 0
+ * milliseconds.
+ *
* SPP_PMTUD_ENABLE - This field will enable PMTU
* discovery upon the specified address. Note that
* if the address feild is empty then all addresses
@@ -2081,13 +2085,30 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
return error;
}
- if (params->spp_hbinterval) {
- if (trans) {
- trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
- } else if (asoc) {
- asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval);
- } else {
- sp->hbinterval = params->spp_hbinterval;
+ /* Note that unless the spp_flag is set to SPP_HB_ENABLE the value of
+ * this field is ignored. Note also that a value of zero indicates
+ * the current setting should be left unchanged.
+ */
+ if (params->spp_flags & SPP_HB_ENABLE) {
+
+ /* Re-zero the interval if the SPP_HB_TIME_IS_ZERO is
+ * set. This lets us use 0 value when this flag
+ * is set.
+ */
+ if (params->spp_flags & SPP_HB_TIME_IS_ZERO)
+ params->spp_hbinterval = 0;
+
+ if (params->spp_hbinterval ||
+ (params->spp_flags & SPP_HB_TIME_IS_ZERO)) {
+ if (trans) {
+ trans->hbinterval =
+ msecs_to_jiffies(params->spp_hbinterval);
+ } else if (asoc) {
+ asoc->hbinterval =
+ msecs_to_jiffies(params->spp_hbinterval);
+ } else {
+ sp->hbinterval = params->spp_hbinterval;
+ }
}
}
@@ -2104,7 +2125,12 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
}
}
- if (params->spp_pathmtu) {
+ /* When Path MTU discovery is disabled the value specified here will
+ * be the "fixed" path mtu (i.e. the value of the spp_flags field must
+ * include the flag SPP_PMTUD_DISABLE for this field to have any
+ * effect).
+ */
+ if ((params->spp_flags & SPP_PMTUD_DISABLE) && params->spp_pathmtu) {
if (trans) {
trans->pathmtu = params->spp_pathmtu;
sctp_assoc_sync_pmtu(asoc);
@@ -2135,7 +2161,11 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
}
}
- if (params->spp_sackdelay) {
+ /* Note that unless the spp_flag is set to SPP_SACKDELAY_ENABLE the
+ * value of this field is ignored. Note also that a value of zero
+ * indicates the current setting should be left unchanged.
+ */
+ if ((params->spp_flags & SPP_SACKDELAY_ENABLE) && params->spp_sackdelay) {
if (trans) {
trans->sackdelay =
msecs_to_jiffies(params->spp_sackdelay);
@@ -2163,7 +2193,11 @@ static int sctp_apply_peer_addr_params(struct sctp_paddrparams *params,
}
}
- if (params->spp_pathmaxrxt) {
+ /* Note that unless the spp_flag is set to SPP_PMTUD_ENABLE the value
+ * of this field is ignored. Note also that a value of zero
+ * indicates the current setting should be left unchanged.
+ */
+ if ((params->spp_flags & SPP_PMTUD_ENABLE) && params->spp_pathmaxrxt) {
if (trans) {
trans->pathmaxrxt = params->spp_pathmaxrxt;
} else if (asoc) {