tcp_subr.c (9ca874cf740ee68c5742df8b5f9e20910085c011) tcp_subr.c (01d74fe1ffc32dc7f42dc0fb0c4861276a6b2bd2)
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 2777 unchanged lines hidden (view full) ---

2786
2787SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred,
2788 CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_NEEDGIANT,
2789 0, 0, tcp6_getcred, "S,xucred",
2790 "Get the xucred of a TCP6 connection");
2791#endif /* INET6 */
2792
2793#ifdef INET
1/*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions

--- 2777 unchanged lines hidden (view full) ---

2786
2787SYSCTL_PROC(_net_inet6_tcp6, OID_AUTO, getcred,
2788 CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_PRISON | CTLFLAG_NEEDGIANT,
2789 0, 0, tcp6_getcred, "S,xucred",
2790 "Get the xucred of a TCP6 connection");
2791#endif /* INET6 */
2792
2793#ifdef INET
2794/* Path MTU to try next when a fragmentation-needed message is received. */
2795static inline int
2796tcp_next_pmtu(const struct icmp *icp, const struct ip *ip)
2797{
2798 int mtu = ntohs(icp->icmp_nextmtu);
2799
2800 /* If no alternative MTU was proposed, try the next smaller one. */
2801 if (!mtu)
2802 mtu = ip_next_mtu(ntohs(ip->ip_len), 1);
2803 if (mtu < V_tcp_minmss + sizeof(struct tcpiphdr))
2804 mtu = V_tcp_minmss + sizeof(struct tcpiphdr);
2805
2806 return (mtu);
2807}
2808
2794static void
2795tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
2796{
2797 struct ip *ip = vip;
2798 struct tcphdr *th;
2799 struct in_addr faddr;
2800 struct inpcb *inp;
2801 struct tcpcb *tp;

--- 39 unchanged lines hidden (view full) ---

2841 goto out;
2842 }
2843 icmp_tcp_seq = th->th_seq;
2844 if (inp != NULL) {
2845 if (!(inp->inp_flags & INP_TIMEWAIT) &&
2846 !(inp->inp_flags & INP_DROPPED) &&
2847 !(inp->inp_socket == NULL)) {
2848 tp = intotcpcb(inp);
2809static void
2810tcp_ctlinput_with_port(int cmd, struct sockaddr *sa, void *vip, uint16_t port)
2811{
2812 struct ip *ip = vip;
2813 struct tcphdr *th;
2814 struct in_addr faddr;
2815 struct inpcb *inp;
2816 struct tcpcb *tp;

--- 39 unchanged lines hidden (view full) ---

2856 goto out;
2857 }
2858 icmp_tcp_seq = th->th_seq;
2859 if (inp != NULL) {
2860 if (!(inp->inp_flags & INP_TIMEWAIT) &&
2861 !(inp->inp_flags & INP_DROPPED) &&
2862 !(inp->inp_socket == NULL)) {
2863 tp = intotcpcb(inp);
2864#ifdef TCP_OFFLOAD
2865 if (tp->t_flags & TF_TOE && cmd == PRC_MSGSIZE) {
2866 /*
2867 * MTU discovery for offloaded connections. Let
2868 * the TOE driver verify seq# and process it.
2869 */
2870 mtu = tcp_next_pmtu(icp, ip);
2871 tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu);
2872 goto out;
2873 }
2874#endif
2849 if (tp->t_port != port) {
2850 goto out;
2851 }
2852 if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) &&
2853 SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) {
2854 if (cmd == PRC_MSGSIZE) {
2855 /*
2875 if (tp->t_port != port) {
2876 goto out;
2877 }
2878 if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) &&
2879 SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) {
2880 if (cmd == PRC_MSGSIZE) {
2881 /*
2856 * MTU discovery:
2857 * If we got a needfrag set the MTU
2858 * in the route to the suggested new
2859 * value (if given) and then notify.
2882 * MTU discovery: we got a needfrag and
2883 * will potentially try a lower MTU.
2860 */
2884 */
2861 mtu = ntohs(icp->icmp_nextmtu);
2885 mtu = tcp_next_pmtu(icp, ip);
2886
2862 /*
2887 /*
2863 * If no alternative MTU was
2864 * proposed, try the next smaller
2865 * one.
2866 */
2867 if (!mtu)
2868 mtu = ip_next_mtu(
2869 ntohs(ip->ip_len), 1);
2870 if (mtu < V_tcp_minmss +
2871 sizeof(struct tcpiphdr))
2872 mtu = V_tcp_minmss +
2873 sizeof(struct tcpiphdr);
2874 /*
2875 * Only process the offered MTU if it
2876 * is smaller than the current one.
2877 */
2878 if (mtu < tp->t_maxseg +
2879 sizeof(struct tcpiphdr)) {
2880 bzero(&inc, sizeof(inc));
2881 inc.inc_faddr = faddr;
2882 inc.inc_fibnum =

--- 60 unchanged lines hidden (view full) ---

2943 o_len -= sizeof(struct udphdr);
2944 outer_ip->ip_len = htons(o_len);
2945 /* Now call in to the normal handling code */
2946 tcp_ctlinput_with_port(cmd, sa, vip, port);
2947}
2948#endif /* INET */
2949
2950#ifdef INET6
2888 * Only process the offered MTU if it
2889 * is smaller than the current one.
2890 */
2891 if (mtu < tp->t_maxseg +
2892 sizeof(struct tcpiphdr)) {
2893 bzero(&inc, sizeof(inc));
2894 inc.inc_faddr = faddr;
2895 inc.inc_fibnum =

--- 60 unchanged lines hidden (view full) ---

2956 o_len -= sizeof(struct udphdr);
2957 outer_ip->ip_len = htons(o_len);
2958 /* Now call in to the normal handling code */
2959 tcp_ctlinput_with_port(cmd, sa, vip, port);
2960}
2961#endif /* INET */
2962
2963#ifdef INET6
2964static inline int
2965tcp6_next_pmtu(const struct icmp6_hdr *icmp6)
2966{
2967 int mtu = ntohl(icmp6->icmp6_mtu);
2968
2969 /*
2970 * If no alternative MTU was proposed, or the proposed MTU was too
2971 * small, set to the min.
2972 */
2973 if (mtu < IPV6_MMTU)
2974 mtu = IPV6_MMTU - 8; /* XXXNP: what is the adjustment for? */
2975 return (mtu);
2976}
2977
2951static void
2952tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
2953{
2954 struct in6_addr *dst;
2955 struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
2956 struct ip6_hdr *ip6;
2957 struct mbuf *m;
2958 struct inpcb *inp;

--- 75 unchanged lines hidden (view full) ---

3034 goto out;
3035 }
3036 m_copydata(m, off, sizeof(tcp_seq), (caddr_t)&icmp_tcp_seq);
3037 if (inp != NULL) {
3038 if (!(inp->inp_flags & INP_TIMEWAIT) &&
3039 !(inp->inp_flags & INP_DROPPED) &&
3040 !(inp->inp_socket == NULL)) {
3041 tp = intotcpcb(inp);
2978static void
2979tcp6_ctlinput_with_port(int cmd, struct sockaddr *sa, void *d, uint16_t port)
2980{
2981 struct in6_addr *dst;
2982 struct inpcb *(*notify)(struct inpcb *, int) = tcp_notify;
2983 struct ip6_hdr *ip6;
2984 struct mbuf *m;
2985 struct inpcb *inp;

--- 75 unchanged lines hidden (view full) ---

3061 goto out;
3062 }
3063 m_copydata(m, off, sizeof(tcp_seq), (caddr_t)&icmp_tcp_seq);
3064 if (inp != NULL) {
3065 if (!(inp->inp_flags & INP_TIMEWAIT) &&
3066 !(inp->inp_flags & INP_DROPPED) &&
3067 !(inp->inp_socket == NULL)) {
3068 tp = intotcpcb(inp);
3069#ifdef TCP_OFFLOAD
3070 if (tp->t_flags & TF_TOE && cmd == PRC_MSGSIZE) {
3071 /* MTU discovery for offloaded connections. */
3072 mtu = tcp6_next_pmtu(icmp6);
3073 tcp_offload_pmtu_update(tp, icmp_tcp_seq, mtu);
3074 goto out;
3075 }
3076#endif
3042 if (tp->t_port != port) {
3043 goto out;
3044 }
3045 if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) &&
3046 SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) {
3047 if (cmd == PRC_MSGSIZE) {
3048 /*
3049 * MTU discovery:
3050 * If we got a needfrag set the MTU
3051 * in the route to the suggested new
3052 * value (if given) and then notify.
3053 */
3077 if (tp->t_port != port) {
3078 goto out;
3079 }
3080 if (SEQ_GEQ(ntohl(icmp_tcp_seq), tp->snd_una) &&
3081 SEQ_LT(ntohl(icmp_tcp_seq), tp->snd_max)) {
3082 if (cmd == PRC_MSGSIZE) {
3083 /*
3084 * MTU discovery:
3085 * If we got a needfrag set the MTU
3086 * in the route to the suggested new
3087 * value (if given) and then notify.
3088 */
3054 mtu = ntohl(icmp6->icmp6_mtu);
3055 /*
3056 * If no alternative MTU was
3057 * proposed, or the proposed
3058 * MTU was too small, set to
3059 * the min.
3060 */
3061 if (mtu < IPV6_MMTU)
3062 mtu = IPV6_MMTU - 8;
3089 mtu = tcp6_next_pmtu(icmp6);
3090
3063 bzero(&inc, sizeof(inc));
3064 inc.inc_fibnum = M_GETFIB(m);
3065 inc.inc_flags |= INC_ISIPV6;
3066 inc.inc6_faddr = *dst;
3067 if (in6_setscope(&inc.inc6_faddr,
3068 m->m_pkthdr.rcvif, NULL))
3069 goto out;
3070 /*

--- 876 unchanged lines hidden ---
3091 bzero(&inc, sizeof(inc));
3092 inc.inc_fibnum = M_GETFIB(m);
3093 inc.inc_flags |= INC_ISIPV6;
3094 inc.inc6_faddr = *dst;
3095 if (in6_setscope(&inc.inc6_faddr,
3096 m->m_pkthdr.rcvif, NULL))
3097 goto out;
3098 /*

--- 876 unchanged lines hidden ---