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.
This commit is contained in:
parent
18e5ceed6b
commit
80c79bbe7a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=225635
@ -496,6 +496,7 @@ struct sctp_error_unrecognized_chunk {
|
||||
/*
|
||||
* PCB Features (in sctp_features bitmask)
|
||||
*/
|
||||
#define SCTP_PCB_FLAGS_DO_NOT_PMTUD 0x00000001
|
||||
#define SCTP_PCB_FLAGS_EXT_RCVINFO 0x00000002 /* deprecated */
|
||||
#define SCTP_PCB_FLAGS_DONOT_HEARTBEAT 0x00000004
|
||||
#define SCTP_PCB_FLAGS_FRAG_INTERLEAVE 0x00000008
|
||||
|
@ -508,6 +508,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
/* SCTP reachability state for each address */
|
||||
#define SCTP_ADDR_REACHABLE 0x001
|
||||
#define SCTP_ADDR_NO_PMTUD 0x002
|
||||
#define SCTP_ADDR_NOHB 0x004
|
||||
#define SCTP_ADDR_BEING_DELETED 0x008
|
||||
#define SCTP_ADDR_NOT_IN_ASSOC 0x010
|
||||
|
@ -4030,11 +4030,16 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr,
|
||||
#ifdef INET6
|
||||
net->flowlabel = stcb->asoc.default_flowlabel;
|
||||
#endif
|
||||
if (sctp_is_feature_on(stcb->sctp_ep, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
|
||||
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) {
|
||||
net->dest_state |= SCTP_ADDR_NOHB;
|
||||
} else {
|
||||
net->dest_state &= ~SCTP_ADDR_NOHB;
|
||||
}
|
||||
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD)) {
|
||||
net->dest_state |= SCTP_ADDR_NO_PMTUD;
|
||||
} else {
|
||||
net->dest_state &= ~SCTP_ADDR_NO_PMTUD;
|
||||
}
|
||||
net->heart_beat_delay = stcb->asoc.heart_beat_delay;
|
||||
/* Init the timer structure */
|
||||
SCTP_OS_TIMER_INIT(&net->rxt_timer.timer);
|
||||
|
@ -2423,12 +2423,13 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
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 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
* 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 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
}
|
||||
#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 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize,
|
||||
/* 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;
|
||||
|
@ -2052,6 +2052,9 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
if (net == NULL) {
|
||||
return;
|
||||
}
|
||||
if (net->dest_state & SCTP_ADDR_NO_PMTUD) {
|
||||
return;
|
||||
}
|
||||
to_ticks = inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_PMTU];
|
||||
tmr = &net->pmtu_timer;
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user