Date: Fri, 3 Nov 2017 20:46:12 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r325370 - in head/sys: netinet netinet6 Message-ID: <201711032046.vA3KkCBb046117@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Fri Nov 3 20:46:12 2017 New Revision: 325370 URL: https://svnweb.freebsd.org/changeset/base/325370 Log: Allow the setting of the MTU for future paths using an SCTP socket option. This functionality was missing. MFC after: 1 week Modified: head/sys/netinet/sctp_output.c head/sys/netinet/sctp_pcb.c head/sys/netinet/sctp_pcb.h head/sys/netinet/sctp_structs.h head/sys/netinet/sctp_usrreq.c head/sys/netinet/sctputil.c head/sys/netinet6/sctp6_usrreq.c Modified: head/sys/netinet/sctp_output.c ============================================================================== --- head/sys/netinet/sctp_output.c Fri Nov 3 19:32:10 2017 (r325369) +++ head/sys/netinet/sctp_output.c Fri Nov 3 20:46:12 2017 (r325370) @@ -4273,12 +4273,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, /* free tempy routes */ RO_RTFREE(ro); } else { - /* - * PMTU check versus smallest asoc MTU goes - * here - */ - if ((ro->ro_rt != NULL) && - (net->ro._s_addr)) { + if ((ro->ro_rt != NULL) && (net->ro._s_addr) && + ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0)) { uint32_t mtu; mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt); @@ -4635,8 +4631,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, } net->src_addr_selected = 0; } - if ((ro->ro_rt != NULL) && - (net->ro._s_addr)) { + if ((ro->ro_rt != NULL) && (net->ro._s_addr) && + ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0)) { uint32_t mtu; mtu = SCTP_GATHER_MTU_FROM_ROUTE(net->ro._s_addr, &net->ro._l_addr.sa, ro->ro_rt); Modified: head/sys/netinet/sctp_pcb.c ============================================================================== --- head/sys/netinet/sctp_pcb.c Fri Nov 3 19:32:10 2017 (r325369) +++ head/sys/netinet/sctp_pcb.c Fri Nov 3 20:46:12 2017 (r325370) @@ -2577,6 +2577,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) /* number of streams to pre-open on a association */ m->pre_open_stream_count = SCTP_BASE_SYSCTL(sctp_nr_outgoing_streams_default); + m->default_mtu = 0; /* Add adaptation cookie */ m->adaptation_layer_indicator = 0; m->adaptation_layer_indicator_provided = 0; @@ -3942,7 +3943,28 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct soc net, 0, stcb->asoc.vrf_id); - if (net->ro._s_addr != NULL) { + if (stcb->asoc.default_mtu > 0) { + net->mtu = stcb->asoc.default_mtu; + switch (net->ro._l_addr.sa.sa_family) { +#ifdef INET + case AF_INET: + net->mtu += SCTP_MIN_V4_OVERHEAD; + break; +#endif +#ifdef INET6 + case AF_INET6: + net->mtu += SCTP_MIN_OVERHEAD; + break; +#endif + default: + break; + } +#if defined(INET) || defined(INET6) + if (net->port) { + net->mtu += (uint32_t)sizeof(struct udphdr); + } +#endif + } else if (net->ro._s_addr != NULL) { uint32_t imtu, rmtu, hcmtu; net->src_addr_selected = 1; @@ -3966,19 +3988,42 @@ sctp_add_remote_addr(struct sctp_tcb *stcb, struct soc } } if (net->mtu == 0) { - switch (newaddr->sa_family) { + if (stcb->asoc.default_mtu > 0) { + net->mtu = stcb->asoc.default_mtu; + switch (net->ro._l_addr.sa.sa_family) { #ifdef INET - case AF_INET: - net->mtu = SCTP_DEFAULT_MTU; - break; + case AF_INET: + net->mtu += SCTP_MIN_V4_OVERHEAD; + break; #endif #ifdef INET6 - case AF_INET6: - net->mtu = 1280; - break; + case AF_INET6: + net->mtu += SCTP_MIN_OVERHEAD; + break; #endif - default: - break; + default: + break; + } +#if defined(INET) || defined(INET6) + if (net->port) { + net->mtu += (uint32_t)sizeof(struct udphdr); + } +#endif + } else { + switch (newaddr->sa_family) { +#ifdef INET + case AF_INET: + net->mtu = SCTP_DEFAULT_MTU; + break; +#endif +#ifdef INET6 + case AF_INET6: + net->mtu = 1280; + break; +#endif + default: + break; + } } } #if defined(INET) || defined(INET6) Modified: head/sys/netinet/sctp_pcb.h ============================================================================== --- head/sys/netinet/sctp_pcb.h Fri Nov 3 19:32:10 2017 (r325369) +++ head/sys/netinet/sctp_pcb.h Fri Nov 3 20:46:12 2017 (r325370) @@ -287,6 +287,7 @@ struct sctp_pcb { sctp_auth_chklist_t *local_auth_chunks; sctp_hmaclist_t *local_hmacs; uint16_t default_keyid; + uint32_t default_mtu; /* various thresholds */ /* Max times I will init at a guy */ Modified: head/sys/netinet/sctp_structs.h ============================================================================== --- head/sys/netinet/sctp_structs.h Fri Nov 3 19:32:10 2017 (r325369) +++ head/sys/netinet/sctp_structs.h Fri Nov 3 20:46:12 2017 (r325370) @@ -1098,6 +1098,7 @@ struct sctp_association { uint32_t chunks_on_out_queue; /* total chunks floating around, * locked by send socket buffer */ uint32_t peers_adaptation; + uint32_t default_mtu; uint16_t peer_hmac_id; /* peer HMAC id to send */ /* Modified: head/sys/netinet/sctp_usrreq.c ============================================================================== --- head/sys/netinet/sctp_usrreq.c Fri Nov 3 19:32:10 2017 (r325369) +++ head/sys/netinet/sctp_usrreq.c Fri Nov 3 20:46:12 2017 (r325370) @@ -202,6 +202,10 @@ sctp_notify(struct sctp_inpcb *inp, #endif /* no need to unlock here, since the TCB is gone */ } else if (icmp_code == ICMP_UNREACH_NEEDFRAG) { + if ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0) { + SCTP_TCB_UNLOCK(stcb); + return; + } /* Find the next (smaller) MTU */ if (next_mtu == 0) { /* @@ -2447,7 +2451,7 @@ flags_out: * value */ paddrp->spp_pathmaxrxt = stcb->asoc.def_net_failure; - paddrp->spp_pathmtu = 0; + paddrp->spp_pathmtu = stcb->asoc.default_mtu; if (stcb->asoc.default_dscp & 0x01) { paddrp->spp_dscp = stcb->asoc.default_dscp & 0xfc; paddrp->spp_flags |= SPP_DSCP; @@ -2494,8 +2498,7 @@ flags_out: paddrp->spp_flags |= SPP_IPV6_FLOWLABEL; } #endif - /* can't return this */ - paddrp->spp_pathmtu = 0; + paddrp->spp_pathmtu = inp->sctp_ep.default_mtu; if (sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT)) { paddrp->spp_flags |= SPP_HB_ENABLE; @@ -5479,6 +5482,7 @@ sctp_setopt(struct socket *so, int optname, void *optv sctp_pathmtu_adjustment(stcb, net->mtu); } } + stcb->asoc.default_mtu = paddrp->spp_pathmtu; sctp_stcb_feature_on(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { @@ -5488,6 +5492,7 @@ sctp_setopt(struct socket *so, int optname, void *optv } net->dest_state &= ~SCTP_ADDR_NO_PMTUD; } + stcb->asoc.default_mtu = 0; sctp_stcb_feature_off(inp, stcb, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } if (paddrp->spp_flags & SPP_DSCP) { @@ -5544,8 +5549,12 @@ sctp_setopt(struct socket *so, int optname, void *optv sctp_feature_on(inp, SCTP_PCB_FLAGS_DONOT_HEARTBEAT); } if (paddrp->spp_flags & SPP_PMTUD_ENABLE) { + inp->sctp_ep.default_mtu = 0; sctp_feature_off(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } else if (paddrp->spp_flags & SPP_PMTUD_DISABLE) { + if (paddrp->spp_pathmtu >= SCTP_SMALLEST_PMTU) { + inp->sctp_ep.default_mtu = paddrp->spp_pathmtu; + } sctp_feature_on(inp, SCTP_PCB_FLAGS_DO_NOT_PMTUD); } if (paddrp->spp_flags & SPP_DSCP) { Modified: head/sys/netinet/sctputil.c ============================================================================== --- head/sys/netinet/sctputil.c Fri Nov 3 19:32:10 2017 (r325369) +++ head/sys/netinet/sctputil.c Fri Nov 3 20:46:12 2017 (r325370) @@ -1042,6 +1042,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb asoc->initial_init_rto_max = inp->sctp_ep.initial_init_rto_max; asoc->initial_rto = inp->sctp_ep.initial_rto; + asoc->default_mtu = inp->sctp_ep.default_mtu; asoc->max_init_times = inp->sctp_ep.max_init_times; asoc->max_send_times = inp->sctp_ep.max_send_times; asoc->def_net_failure = inp->sctp_ep.def_net_failure; Modified: head/sys/netinet6/sctp6_usrreq.c ============================================================================== --- head/sys/netinet6/sctp6_usrreq.c Fri Nov 3 19:32:10 2017 (r325369) +++ head/sys/netinet6/sctp6_usrreq.c Fri Nov 3 20:46:12 2017 (r325370) @@ -229,6 +229,10 @@ sctp6_notify(struct sctp_inpcb *inp, } break; case ICMP6_PACKET_TOO_BIG: + if ((net->dest_state & SCTP_ADDR_NO_PMTUD) == 0) { + SCTP_TCB_UNLOCK(stcb); + break; + } if (SCTP_OS_TIMER_PENDING(&net->pmtu_timer.timer)) { timer_stopped = 1; sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201711032046.vA3KkCBb046117>