summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_usrreq.c
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2011-09-17 08:50:29 +0000
committertuexen <tuexen@FreeBSD.org>2011-09-17 08:50:29 +0000
commit680b9f90a2df45c87f6be8100faa097073b497b7 (patch)
tree1c66f8080b5b5458c7b294565b24b6e003093597 /sys/netinet/sctp_usrreq.c
parenta5586859b8e8bec4079433cd96cd1cef0b10b335 (diff)
downloadFreeBSD-src-680b9f90a2df45c87f6be8100faa097073b497b7.zip
FreeBSD-src-680b9f90a2df45c87f6be8100faa097073b497b7.tar.gz
Fix the enabling/disabling of Heartbeats and path MTU
discovery when using the SCTP_PEER_ADDR_PARAMS socket option. Approved by: re MFC after: 1 month.
Diffstat (limited to 'sys/netinet/sctp_usrreq.c')
-rw-r--r--sys/netinet/sctp_usrreq.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 82a8cba..d49ea38 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -2423,12 +2423,13 @@ flags_out:
paddrp->spp_pathmaxrxt = net->failure_threshold;
paddrp->spp_pathmtu = net->mtu - ovh;
/* get flags for HB */
- if (net->dest_state & SCTP_ADDR_NOHB)
+ if (net->dest_state & SCTP_ADDR_NOHB) {
paddrp->spp_flags |= SPP_HB_DISABLE;
- else
+ } else {
paddrp->spp_flags |= SPP_HB_ENABLE;
+ }
/* get flags for PMTU */
- if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
+ if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
paddrp->spp_flags |= SPP_PMTUD_ENABLE;
} else {
paddrp->spp_flags |= SPP_PMTUD_DISABLE;
@@ -2449,8 +2450,6 @@ flags_out:
* No destination so return default
* value
*/
- int cnt = 0;
-
paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure;
paddrp->spp_pathmtu = sctp_get_frag_point(stcb, &stcb->asoc);
if (stcb->asoc.default_dscp & 0x01) {
@@ -2464,20 +2463,17 @@ flags_out:
}
#endif
/* default settings should be these */
- if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
+ if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
paddrp->spp_flags |= SPP_HB_DISABLE;
} else {
paddrp->spp_flags |= SPP_HB_ENABLE;
}
- paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
- TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
- cnt++;
- }
- }
- if (cnt) {
+ if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
+ paddrp->spp_flags |= SPP_PMTUD_DISABLE;
+ } else {
paddrp->spp_flags |= SPP_PMTUD_ENABLE;
}
+ paddrp->spp_hbinterval = stcb->asoc.heart_beat_delay;
}
paddrp->spp_assoc_id = sctp_get_associd(stcb);
SCTP_TCB_UNLOCK(stcb);
@@ -2505,14 +2501,16 @@ flags_out:
/* can't return this */
paddrp->spp_pathmtu = 0;
- /* default behavior, no stcb */
- paddrp->spp_flags = SPP_PMTUD_ENABLE;
-
if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
paddrp->spp_flags |= SPP_HB_ENABLE;
} else {
paddrp->spp_flags |= SPP_HB_DISABLE;
}
+ if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
+ paddrp->spp_flags |= SPP_PMTUD_ENABLE;
+ } else {
+ paddrp->spp_flags |= SPP_PMTUD_DISABLE;
+ }
SCTP_INP_RUNLOCK(inp);
} else {
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@@ -4651,6 +4649,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
}
+ net->dest_state |= SCTP_ADDR_NO_PMTUD;
if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
net->mtu = paddrp->spp_pathmtu + ovh;
if (net->mtu < stcb->asoc.smallest_mtu) {
@@ -4659,9 +4658,10 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
}
if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
- if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
+ if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
}
+ net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
}
if (paddrp->spp_pathmaxrxt) {
if (net->dest_state & SCTP_ADDR_PF) {
@@ -4754,9 +4754,9 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, inp, stcb, net);
}
+ sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
}
if (paddrp->spp_flags & SPP_HB_DISABLE) {
- /* Turn back on the timer */
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
if (!(net->dest_state & SCTP_ADDR_NOHB)) {
net->dest_state |= SCTP_ADDR_NOHB;
@@ -4765,6 +4765,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
}
}
+ sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
}
if ((paddrp->spp_flags & SPP_PMTUD_DISABLE) && (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU)) {
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
@@ -4772,6 +4773,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
SCTP_FROM_SCTP_USRREQ + SCTP_LOC_10);
}
+ net->dest_state |= SCTP_ADDR_NO_PMTUD;
if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
net->mtu = paddrp->spp_pathmtu + ovh;
if (net->mtu < stcb->asoc.smallest_mtu) {
@@ -4779,13 +4781,16 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
}
}
+ sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
}
if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
- if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
+ if (!SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) {
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
}
+ net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
}
+ sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
}
if (paddrp->spp_flags & SPP_DSCP) {
TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
@@ -4840,6 +4845,11 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
} else if (paddrp->spp_flags & SPP_HB_DISABLE) {
sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT);
}
+ if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
+ sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
+ } else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) {
+ sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD);
+ }
if (paddrp->spp_flags & SPP_DSCP) {
inp->sctp_ep.default_dscp = paddrp->spp_dscp << 2;
inp->sctp_ep.default_dscp |= 0x01;
OpenPOWER on IntegriCloud