@@ -950,7 +950,7 @@ index 89163ef8c..49ad1ddc9 100644
950
950
union {
951
951
struct ip_options_rcu __rcu *ireq_opt;
952
952
diff --git a/include/net/sock.h b/include/net/sock.h
953
- index 261195598..b277c7efb 100644
953
+ index 261195598..f03d8b999 100644
954
954
--- a/include/net/sock.h
955
955
+++ b/include/net/sock.h
956
956
@@ -506,6 +506,30 @@ struct sock {
@@ -984,18 +984,24 @@ index 261195598..b277c7efb 100644
984
984
void (*sk_error_report)(struct sock *sk);
985
985
int (*sk_backlog_rcv)(struct sock *sk,
986
986
struct sk_buff *skb);
987
- @@ -861,6 +885,10 @@ enum sock_flags {
987
+ @@ -861,6 +885,16 @@ enum sock_flags {
988
988
SOCK_TXTIME,
989
989
SOCK_XDP, /* XDP is attached */
990
990
SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */
991
991
+ #ifdef CONFIG_SECURITY_TEMPESTA
992
992
+ SOCK_TEMPESTA, /* The socket is managed by Tempesta FW */
993
- + SOCK_TEMPESTA_HAS_DATA /* The socket has data in Tempesta FW write queue */
993
+ + SOCK_TEMPESTA_HAS_DATA, /* The socket has data in Tempesta FW
994
+ + * write queue.
995
+ + */
996
+ + SOCK_TEMPESTA_IS_CLOSING, /* The socket is closing by Tempesta FW
997
+ + * from `ss_do_close`. `tcp_done` should
998
+ + * not be called from the kernel code.
999
+ + */
994
1000
+ #endif
995
1001
};
996
1002
997
1003
#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
998
- @@ -1081,6 +1109 ,16 @@ static inline void sock_rps_reset_rxhash(struct sock *sk)
1004
+ @@ -1081,6 +1115 ,16 @@ static inline void sock_rps_reset_rxhash(struct sock *sk)
999
1005
__rc; \
1000
1006
})
1001
1007
@@ -1012,7 +1018,7 @@ index 261195598..b277c7efb 100644
1012
1018
int sk_stream_wait_connect(struct sock *sk, long *timeo_p);
1013
1019
int sk_stream_wait_memory(struct sock *sk, long *timeo_p);
1014
1020
void sk_stream_wait_close(struct sock *sk, long timeo_p);
1015
- @@ -1915,8 +1953 ,7 @@ static inline bool sk_rethink_txhash(struct sock *sk)
1021
+ @@ -1915,8 +1959 ,7 @@ static inline bool sk_rethink_txhash(struct sock *sk)
1016
1022
static inline struct dst_entry *
1017
1023
__sk_dst_get(struct sock *sk)
1018
1024
{
@@ -1023,7 +1029,7 @@ index 261195598..b277c7efb 100644
1023
1029
1024
1030
static inline struct dst_entry *
1025
1031
diff --git a/include/net/tcp.h b/include/net/tcp.h
1026
- index 7d66c61d2..440938820 100644
1032
+ index 7d66c61d2..f85ea9a2b 100644
1027
1033
--- a/include/net/tcp.h
1028
1034
+++ b/include/net/tcp.h
1029
1035
@@ -307,6 +307,7 @@ bool tcp_check_oom(struct sock *sk, int shift);
@@ -1075,15 +1081,15 @@ index 7d66c61d2..440938820 100644
1075
1081
+ sk->sk_err = error;
1076
1082
+ sk->sk_error_report(sk);
1077
1083
+ tcp_write_queue_purge(sk);
1078
- +
1079
1084
+ /*
1080
- + * If this function is called when error occurs during sending
1081
- + * TCP FIN from `ss_do_close` or `tcp_shutdown`, we should not
1082
- + * call `tcp_done` just set state to TCP_CLOSE and clear timers
1083
- + * to prevent extra call of `inet_csk_destroy_sock`.
1085
+ + * SOCK_TEMPESTA_IS_CLOSING is set from `ss_do_close`
1086
+ + * or `ss_do_shutdown` function from Tempesta FW code.
1087
+ + * We should not call `tcp_done` if error occurs during
1088
+ + * one of this function, just set socket state to TCP_CLOSE,
1089
+ + * clear timers and socket write queue. Socket will be
1090
+ + * closed in one of this function.
1084
1091
+ */
1085
- + if (unlikely(sk->sk_state == TCP_FIN_WAIT1
1086
- + || sk->sk_state == TCP_LAST_ACK)) {
1092
+ + if (unlikely(sock_flag(sk, SOCK_TEMPESTA_IS_CLOSING))) {
1087
1093
+ tcp_set_state(sk, TCP_CLOSE);
1088
1094
+ tcp_clear_xmit_timers(sk);
1089
1095
+ } else {
@@ -2544,7 +2550,7 @@ index f0f67b25c..58fbfb071 100644
2544
2550
return NULL;
2545
2551
}
2546
2552
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
2547
- index f99494637..879836861 100644
2553
+ index f99494637..042f9e38d 100644
2548
2554
--- a/net/ipv4/tcp_output.c
2549
2555
+++ b/net/ipv4/tcp_output.c
2550
2556
@@ -39,6 +39,9 @@
@@ -2753,7 +2759,7 @@ index f99494637..879836861 100644
2753
2759
2754
2760
len -= skb->len;
2755
2761
}
2756
- @@ -2310,6 +2364,75 @@ static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
2762
+ @@ -2310,6 +2364,76 @@ static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
2757
2763
return true;
2758
2764
}
2759
2765
@@ -2776,16 +2782,17 @@ index f99494637..879836861 100644
2776
2782
+ int result;
2777
2783
+
2778
2784
+ /*
2779
- + * If skb has tls type, but sk->sk_write_xmit is equal to zero
2780
- + * it means that connection was already dropped. In this case
2781
- + * there should not be any skbs with tls type in socket write
2782
- + * queue, because we always recalculate sequence numbers of skb
2783
- + * in `sk_write_xmit`, and if we don't call it skb will have
2784
- + * incorrect sequence numbers, that leads to unclear warning
2785
- + * later.
2785
+ + * If skb has tls type, but `sk->sk_write_xmit` is equal to zero
2786
+ + * it means that connection was already dropped. This skb is
2787
+ + * not valid, because we should recalculate sequence numbers of
2788
+ + * for this skb in `sk_write_xmit`, and if we don't call it skb
2789
+ + * will have incorrect sequence numbers. So we should return
2790
+ + * error code here and close socket using `tcp_tfw_handle_error`.
2786
2791
+ */
2787
- + if (!skb_tfw_tls_type(skb) || WARN_ON_ONCE(!sk->sk_write_xmit) )
2792
+ + if (!skb_tfw_tls_type(skb))
2788
2793
+ return 0;
2794
+ + else if (!sk->sk_write_xmit)
2795
+ + return -EPIPE;
2789
2796
+
2790
2797
+ /* Should be checked early. */
2791
2798
+ BUG_ON(after(TCP_SKB_CB(skb)->seq, tcp_wnd_end(tp)));
@@ -2829,7 +2836,7 @@ index f99494637..879836861 100644
2829
2836
/* Create a new MTU probe if we are ready.
2830
2837
* MTU probe is regularly attempting to increase the path MTU by
2831
2838
* deliberately sending larger packets. This discovers routing
2832
- @@ -2330,6 +2453 ,9 @@ static int tcp_mtu_probe(struct sock *sk)
2839
+ @@ -2330,6 +2454 ,9 @@ static int tcp_mtu_probe(struct sock *sk)
2833
2840
int copy, len;
2834
2841
int mss_now;
2835
2842
int interval;
@@ -2839,15 +2846,15 @@ index f99494637..879836861 100644
2839
2846
2840
2847
/* Not currently probing/verifying,
2841
2848
* not in recovery,
2842
- @@ -2382,6 +2508 ,7 @@ static int tcp_mtu_probe(struct sock *sk)
2849
+ @@ -2382,6 +2509 ,7 @@ static int tcp_mtu_probe(struct sock *sk)
2843
2850
return 0;
2844
2851
}
2845
2852
2846
2853
+ TFW_ADJUST_TLS_OVERHEAD(probe_size);
2847
2854
if (!tcp_can_coalesce_send_queue_head(sk, probe_size))
2848
2855
return -1;
2849
2856
2850
- @@ -2402,6 +2529 ,10 @@ static int tcp_mtu_probe(struct sock *sk)
2857
+ @@ -2402,6 +2530 ,10 @@ static int tcp_mtu_probe(struct sock *sk)
2851
2858
nskb->csum = 0;
2852
2859
nskb->ip_summed = CHECKSUM_PARTIAL;
2853
2860
@@ -2858,13 +2865,17 @@ index f99494637..879836861 100644
2858
2865
tcp_insert_write_queue_before(nskb, skb, sk);
2859
2866
tcp_highest_sack_replace(sk, skb, nskb);
2860
2867
2861
- @@ -2440,6 +2571,20 @@ static int tcp_mtu_probe(struct sock *sk)
2868
+ @@ -2440,6 +2572,24 @@ static int tcp_mtu_probe(struct sock *sk)
2862
2869
}
2863
2870
tcp_init_tso_segs(nskb, nskb->len);
2864
2871
2865
2872
+ #ifdef CONFIG_SECURITY_TEMPESTA
2866
- + if (!skb_tfw_tls_type(nskb) || WARN_ON_ONCE(!sk->sk_write_xmit) )
2873
+ + if (!skb_tfw_tls_type(nskb))
2867
2874
+ goto transmit;
2875
+ + else if (!sk->sk_write_xmit) {
2876
+ + tcp_tfw_handle_error(sk, -EPIPE);
2877
+ + return 0;
2878
+ + }
2868
2879
+
2869
2880
+ result = sk->sk_write_xmit(sk, nskb, probe_size, probe_size);
2870
2881
+ if (unlikely(result)) {
@@ -2879,7 +2890,7 @@ index f99494637..879836861 100644
2879
2890
/* We're ready to send. If this fails, the probe will
2880
2891
* be resegmented into mss-sized pieces by tcp_write_xmit().
2881
2892
*/
2882
- @@ -2666,7 +2811 ,17 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
2893
+ @@ -2666,7 +2816 ,17 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
2883
2894
cwnd_quota,
2884
2895
max_segs),
2885
2896
nonagle);
@@ -2898,7 +2909,7 @@ index f99494637..879836861 100644
2898
2909
if (skb->len > limit &&
2899
2910
unlikely(tso_fragment(sk, skb, limit, mss_now, gfp)))
2900
2911
break;
2901
- @@ -2681,7 +2836 ,13 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
2912
+ @@ -2681,7 +2841 ,13 @@ static bool tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle,
2902
2913
*/
2903
2914
if (TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq)
2904
2915
break;
@@ -2913,15 +2924,15 @@ index f99494637..879836861 100644
2913
2924
if (unlikely(tcp_transmit_skb(sk, skb, 1, gfp)))
2914
2925
break;
2915
2926
2916
- @@ -2866,6 +3027 ,7 @@ void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
2927
+ @@ -2866,6 +3032 ,7 @@ void __tcp_push_pending_frames(struct sock *sk, unsigned int cur_mss,
2917
2928
sk_gfp_mask(sk, GFP_ATOMIC)))
2918
2929
tcp_check_probe_timer(sk);
2919
2930
}
2920
2931
+ EXPORT_SYMBOL(__tcp_push_pending_frames);
2921
2932
2922
2933
/* Send _single_ skb sitting at the send head. This function requires
2923
2934
* true push pending frames to setup probe timer etc.
2924
- @@ -3183,7 +3345 ,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
2935
+ @@ -3183,7 +3350 ,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
2925
2936
cur_mss, GFP_ATOMIC))
2926
2937
return -ENOMEM; /* We'll try again later. */
2927
2938
} else {
@@ -2930,31 +2941,31 @@ index f99494637..879836861 100644
2930
2941
return -ENOMEM;
2931
2942
2932
2943
diff = tcp_skb_pcount(skb);
2933
- @@ -3374,6 +3536 ,7 @@ void sk_forced_mem_schedule(struct sock *sk, int size)
2944
+ @@ -3374,6 +3541 ,7 @@ void sk_forced_mem_schedule(struct sock *sk, int size)
2934
2945
if (mem_cgroup_sockets_enabled && sk->sk_memcg)
2935
2946
mem_cgroup_charge_skmem(sk->sk_memcg, amt);
2936
2947
}
2937
2948
+ EXPORT_SYMBOL(sk_forced_mem_schedule);
2938
2949
2939
2950
/* Send a FIN. The caller locks the socket for us.
2940
2951
* We should try to send a FIN packet really hard, but eventually give up.
2941
- @@ -3421,6 +3584 ,7 @@ void tcp_send_fin(struct sock *sk)
2952
+ @@ -3421,6 +3589 ,7 @@ void tcp_send_fin(struct sock *sk)
2942
2953
}
2943
2954
__tcp_push_pending_frames(sk, tcp_current_mss(sk), TCP_NAGLE_OFF);
2944
2955
}
2945
2956
+ EXPORT_SYMBOL(tcp_send_fin);
2946
2957
2947
2958
/* We get here when a process closes a file descriptor (either due to
2948
2959
* an explicit close() or as a byproduct of exit()'ing) and there
2949
- @@ -3454,6 +3618 ,7 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
2960
+ @@ -3454,6 +3623 ,7 @@ void tcp_send_active_reset(struct sock *sk, gfp_t priority)
2950
2961
*/
2951
2962
trace_tcp_send_reset(sk, NULL);
2952
2963
}
2953
2964
+ EXPORT_SYMBOL(tcp_send_active_reset);
2954
2965
2955
2966
/* Send a crossed SYN-ACK during socket establishment.
2956
2967
* WARNING: This routine must only be called when we have already sent
2957
- @@ -4044,6 +4209 ,17 @@ int tcp_write_wakeup(struct sock *sk, int mib)
2968
+ @@ -4044,6 +4214 ,17 @@ int tcp_write_wakeup(struct sock *sk, int mib)
2958
2969
if (seg_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq ||
2959
2970
skb->len > mss) {
2960
2971
seg_size = min(seg_size, mss);
@@ -2972,7 +2983,7 @@ index f99494637..879836861 100644
2972
2983
TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
2973
2984
if (tcp_fragment(sk, TCP_FRAG_IN_WRITE_QUEUE,
2974
2985
skb, seg_size, mss, GFP_ATOMIC))
2975
- @@ -4052,6 +4228 ,15 @@ int tcp_write_wakeup(struct sock *sk, int mib)
2986
+ @@ -4052,6 +4233 ,15 @@ int tcp_write_wakeup(struct sock *sk, int mib)
2976
2987
tcp_set_skb_tso_segs(skb, mss);
2977
2988
2978
2989
TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_PSH;
0 commit comments