* Determine a reasonable value for maxseg size. * If the route is known, check route for mtu. * If none, use an mss that can be handled on the outgoing interface * without forcing IP to fragment. If no route is found, route has no mtu, * or the destination isn't local, use a default, hopefully conservative * size (usually 512 or the default IP max size, but no more than the mtu * of the int
| 3656 | * settings are handled in tcp_mssopt(). |
| 3657 | */ |
| 3658 | void |
| 3659 | tcp_mss_update(struct tcpcb *tp, int offer, int mtuoffer, |
| 3660 | struct hc_metrics_lite *metricptr, struct tcp_ifcap *cap) |
| 3661 | { |
| 3662 | int mss = 0; |
| 3663 | uint32_t maxmtu = 0; |
| 3664 | struct inpcb *inp = tp->t_inpcb; |
| 3665 | struct hc_metrics_lite metrics; |
| 3666 | #ifdef INET6 |
| 3667 | int isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; |
| 3668 | size_t min_protoh = isipv6 ? |
| 3669 | sizeof (struct ip6_hdr) + sizeof (struct tcphdr) : |
| 3670 | sizeof (struct tcpiphdr); |
| 3671 | #else |
| 3672 | const size_t min_protoh = sizeof(struct tcpiphdr); |
| 3673 | #endif |
| 3674 | |
| 3675 | INP_WLOCK_ASSERT(tp->t_inpcb); |
| 3676 | |
| 3677 | if (mtuoffer != -1) { |
| 3678 | KASSERT(offer == -1, ("%s: conflict", __func__)); |
| 3679 | offer = mtuoffer - min_protoh; |
| 3680 | } |
| 3681 | |
| 3682 | /* Initialize. */ |
| 3683 | #ifdef INET6 |
| 3684 | if (isipv6) { |
| 3685 | maxmtu = tcp_maxmtu6(&inp->inp_inc, cap); |
| 3686 | tp->t_maxseg = V_tcp_v6mssdflt; |
| 3687 | } |
| 3688 | #endif |
| 3689 | #if defined(INET) && defined(INET6) |
| 3690 | else |
| 3691 | #endif |
| 3692 | #ifdef INET |
| 3693 | { |
| 3694 | maxmtu = tcp_maxmtu(&inp->inp_inc, cap); |
| 3695 | tp->t_maxseg = V_tcp_mssdflt; |
| 3696 | } |
| 3697 | #endif |
| 3698 | |
| 3699 | /* |
| 3700 | * No route to sender, stay with default mss and return. |
| 3701 | */ |
| 3702 | if (maxmtu == 0) { |
| 3703 | /* |
| 3704 | * In case we return early we need to initialize metrics |
| 3705 | * to a defined state as tcp_hc_get() would do for us |
| 3706 | * if there was no cache hit. |
| 3707 | */ |
| 3708 | if (metricptr != NULL) |
| 3709 | bzero(metricptr, sizeof(struct hc_metrics_lite)); |
| 3710 | return; |
| 3711 | } |
| 3712 | |
| 3713 | /* What have we got? */ |
| 3714 | switch (offer) { |
| 3715 | case 0: |
no test coverage detected