Factor out tcp6_use_min_mtu() to handle IPV6_USE_MIN_MTU by TCP.
Pass control for IP/IP6 level options from generic tcp_ctloutput_set() down to per-stack ctloutput. Call tcp6_use_min_mtu() from tcp stack tcp_default_ctloutput(). Reviewed by: rrs Differential Revision: https://reviews.freebsd.org/D32655
This commit is contained in:
parent
de156263a5
commit
f581a26e46
@ -14253,6 +14253,12 @@ bbr_set_sockopt(struct socket *so, struct sockopt *sopt,
|
|||||||
struct epoch_tracker et;
|
struct epoch_tracker et;
|
||||||
int32_t error = 0, optval;
|
int32_t error = 0, optval;
|
||||||
|
|
||||||
|
switch (sopt->sopt_level) {
|
||||||
|
case IPPROTO_IPV6:
|
||||||
|
case IPPROTO_IP:
|
||||||
|
return (tcp_default_ctloutput(so, sopt, inp, tp));
|
||||||
|
}
|
||||||
|
|
||||||
switch (sopt->sopt_name) {
|
switch (sopt->sopt_name) {
|
||||||
case TCP_RACK_PACE_MAX_SEG:
|
case TCP_RACK_PACE_MAX_SEG:
|
||||||
case TCP_RACK_MIN_TO:
|
case TCP_RACK_MIN_TO:
|
||||||
|
@ -20248,6 +20248,25 @@ rack_set_sockopt(struct socket *so, struct sockopt *sopt,
|
|||||||
uint64_t loptval;
|
uint64_t loptval;
|
||||||
int32_t error = 0, optval;
|
int32_t error = 0, optval;
|
||||||
|
|
||||||
|
switch (sopt->sopt_level) {
|
||||||
|
#ifdef INET6
|
||||||
|
case IPPROTO_IPV6:
|
||||||
|
MPASS(inp->inp_vflag & INP_IPV6PROTO);
|
||||||
|
switch (sopt->sopt_name) {
|
||||||
|
case IPV6_USE_MIN_MTU:
|
||||||
|
tcp6_use_min_mtu(tp);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
}
|
||||||
|
INP_WUNLOCK(inp);
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
#ifdef INET
|
||||||
|
case IPPROTO_IP:
|
||||||
|
INP_WUNLOCK(inp);
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
switch (sopt->sopt_name) {
|
switch (sopt->sopt_name) {
|
||||||
case TCP_RACK_TLP_REDUCE: /* URL:tlp_reduce */
|
case TCP_RACK_TLP_REDUCE: /* URL:tlp_reduce */
|
||||||
/* Pacing related ones */
|
/* Pacing related ones */
|
||||||
|
@ -3559,6 +3559,41 @@ tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap)
|
|||||||
|
|
||||||
return (maxmtu);
|
return (maxmtu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle setsockopt(IPV6_USE_MIN_MTU) by a TCP stack.
|
||||||
|
*
|
||||||
|
* XXXGL: we are updating inpcb here with INC_IPV6MINMTU flag.
|
||||||
|
* The right place to do that is ip6_setpktopt() that has just been
|
||||||
|
* executed. By the way it just filled ip6po_minmtu for us.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tcp6_use_min_mtu(struct tcpcb *tp)
|
||||||
|
{
|
||||||
|
struct inpcb *inp = tp->t_inpcb;
|
||||||
|
|
||||||
|
INP_WLOCK_ASSERT(inp);
|
||||||
|
/*
|
||||||
|
* In case of the IPV6_USE_MIN_MTU socket
|
||||||
|
* option, the INC_IPV6MINMTU flag to announce
|
||||||
|
* a corresponding MSS during the initial
|
||||||
|
* handshake. If the TCP connection is not in
|
||||||
|
* the front states, just reduce the MSS being
|
||||||
|
* used. This avoids the sending of TCP
|
||||||
|
* segments which will be fragmented at the
|
||||||
|
* IPv6 layer.
|
||||||
|
*/
|
||||||
|
inp->inp_inc.inc_flags |= INC_IPV6MINMTU;
|
||||||
|
if ((tp->t_state >= TCPS_SYN_SENT) &&
|
||||||
|
(inp->inp_inc.inc_flags & INC_ISIPV6)) {
|
||||||
|
struct ip6_pktopts *opt;
|
||||||
|
|
||||||
|
opt = inp->in6p_outputopts;
|
||||||
|
if (opt != NULL && opt->ip6po_minmtu == IP6PO_MINMTU_ALL &&
|
||||||
|
tp->t_maxseg > TCP6_MSS)
|
||||||
|
tp->t_maxseg = TCP6_MSS;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1763,43 +1763,8 @@ tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt)
|
|||||||
/* Notify tcp stacks that care (e.g. RACK). */
|
/* Notify tcp stacks that care (e.g. RACK). */
|
||||||
break;
|
break;
|
||||||
case IPV6_USE_MIN_MTU:
|
case IPV6_USE_MIN_MTU:
|
||||||
/*
|
/* Update t_maxseg accordingly. */
|
||||||
* XXXGL: this handling should belong to
|
break;
|
||||||
* stack specific tfb_tcp_ctloutput, we
|
|
||||||
* should just break here.
|
|
||||||
*
|
|
||||||
* In case of the IPV6_USE_MIN_MTU socket
|
|
||||||
* option, the INC_IPV6MINMTU flag to announce
|
|
||||||
* a corresponding MSS during the initial
|
|
||||||
* handshake. If the TCP connection is not in
|
|
||||||
* the front states, just reduce the MSS being
|
|
||||||
* used. This avoids the sending of TCP
|
|
||||||
* segments which will be fragmented at the
|
|
||||||
* IPv6 layer.
|
|
||||||
*/
|
|
||||||
INP_WLOCK(inp);
|
|
||||||
if ((inp->inp_flags &
|
|
||||||
(INP_TIMEWAIT | INP_DROPPED))) {
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
return (ECONNRESET);
|
|
||||||
}
|
|
||||||
inp->inp_inc.inc_flags |= INC_IPV6MINMTU;
|
|
||||||
tp = intotcpcb(inp);
|
|
||||||
if ((tp->t_state >= TCPS_SYN_SENT) &&
|
|
||||||
(inp->inp_inc.inc_flags & INC_ISIPV6)) {
|
|
||||||
struct ip6_pktopts *opt;
|
|
||||||
|
|
||||||
opt = inp->in6p_outputopts;
|
|
||||||
if ((opt != NULL) &&
|
|
||||||
(opt->ip6po_minmtu ==
|
|
||||||
IP6PO_MINMTU_ALL)) {
|
|
||||||
if (tp->t_maxseg > TCP6_MSS) {
|
|
||||||
tp->t_maxseg = TCP6_MSS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
INP_WUNLOCK(inp);
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
default:
|
default:
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
@ -2058,6 +2023,27 @@ tcp_default_ctloutput(struct socket *so, struct sockopt *sopt, struct inpcb *inp
|
|||||||
#endif
|
#endif
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
INP_WLOCK_ASSERT(inp);
|
||||||
|
|
||||||
|
switch (sopt->sopt_level) {
|
||||||
|
#ifdef INET6
|
||||||
|
case IPPROTO_IPV6:
|
||||||
|
MPASS(inp->inp_vflag & INP_IPV6PROTO);
|
||||||
|
switch (sopt->sopt_name) {
|
||||||
|
case IPV6_USE_MIN_MTU:
|
||||||
|
tcp6_use_min_mtu(tp);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
}
|
||||||
|
INP_WUNLOCK(inp);
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
#ifdef INET
|
||||||
|
case IPPROTO_IP:
|
||||||
|
INP_WUNLOCK(inp);
|
||||||
|
return (0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For TCP_CCALGOOPT forward the control to CC module, for both
|
* For TCP_CCALGOOPT forward the control to CC module, for both
|
||||||
* SOPT_SET and SOPT_GET.
|
* SOPT_SET and SOPT_GET.
|
||||||
|
@ -1053,6 +1053,7 @@ extern uint32_t tcp_ack_war_cnt;
|
|||||||
|
|
||||||
uint32_t tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *);
|
uint32_t tcp_maxmtu(struct in_conninfo *, struct tcp_ifcap *);
|
||||||
uint32_t tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
|
uint32_t tcp_maxmtu6(struct in_conninfo *, struct tcp_ifcap *);
|
||||||
|
void tcp6_use_min_mtu(struct tcpcb *);
|
||||||
u_int tcp_maxseg(const struct tcpcb *);
|
u_int tcp_maxseg(const struct tcpcb *);
|
||||||
u_int tcp_fixed_maxseg(const struct tcpcb *);
|
u_int tcp_fixed_maxseg(const struct tcpcb *);
|
||||||
void tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *,
|
void tcp_mss_update(struct tcpcb *, int, int, struct hc_metrics_lite *,
|
||||||
|
Loading…
Reference in New Issue
Block a user