@@ -7388,6 +7388,124 @@ static const struct bpf_func_proto bpf_sock_ops_reserve_hdr_opt_proto = {
73887388 .arg3_type = ARG_ANYTHING ,
73897389};
73907390
7391+ BPF_CALL_3 (bpf_tcp_raw_gen_syncookie_ipv4 , struct iphdr * , iph ,
7392+ struct tcphdr * , th , u32 , th_len )
7393+ {
7394+ #ifdef CONFIG_SYN_COOKIES
7395+ u32 cookie ;
7396+ u16 mss ;
7397+
7398+ if (unlikely (th_len < sizeof (* th ) || th_len != th -> doff * 4 ))
7399+ return - EINVAL ;
7400+
7401+ mss = tcp_parse_mss_option (th , 0 ) ?: TCP_MSS_DEFAULT ;
7402+ cookie = __cookie_v4_init_sequence (iph , th , & mss );
7403+
7404+ return cookie | ((u64 )mss << 32 );
7405+ #else
7406+ return - EOPNOTSUPP ;
7407+ #endif /* CONFIG_SYN_COOKIES */
7408+ }
7409+
7410+ static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv4_proto = {
7411+ .func = bpf_tcp_raw_gen_syncookie_ipv4 ,
7412+ .gpl_only = true, /* __cookie_v4_init_sequence() is GPL */
7413+ .pkt_access = true,
7414+ .ret_type = RET_INTEGER ,
7415+ .arg1_type = ARG_PTR_TO_MEM ,
7416+ .arg1_size = sizeof (struct iphdr ),
7417+ .arg2_type = ARG_PTR_TO_MEM ,
7418+ .arg3_type = ARG_CONST_SIZE ,
7419+ };
7420+
7421+ BPF_CALL_3 (bpf_tcp_raw_gen_syncookie_ipv6 , struct ipv6hdr * , iph ,
7422+ struct tcphdr * , th , u32 , th_len )
7423+ {
7424+ #ifndef CONFIG_SYN_COOKIES
7425+ return - EOPNOTSUPP ;
7426+ #elif !IS_BUILTIN (CONFIG_IPV6 )
7427+ return - EPROTONOSUPPORT ;
7428+ #else
7429+ const u16 mss_clamp = IPV6_MIN_MTU - sizeof (struct tcphdr ) -
7430+ sizeof (struct ipv6hdr );
7431+ u32 cookie ;
7432+ u16 mss ;
7433+
7434+ if (unlikely (th_len < sizeof (* th ) || th_len != th -> doff * 4 ))
7435+ return - EINVAL ;
7436+
7437+ mss = tcp_parse_mss_option (th , 0 ) ?: mss_clamp ;
7438+ cookie = __cookie_v6_init_sequence (iph , th , & mss );
7439+
7440+ return cookie | ((u64 )mss << 32 );
7441+ #endif
7442+ }
7443+
7444+ static const struct bpf_func_proto bpf_tcp_raw_gen_syncookie_ipv6_proto = {
7445+ .func = bpf_tcp_raw_gen_syncookie_ipv6 ,
7446+ .gpl_only = true, /* __cookie_v6_init_sequence() is GPL */
7447+ .pkt_access = true,
7448+ .ret_type = RET_INTEGER ,
7449+ .arg1_type = ARG_PTR_TO_MEM ,
7450+ .arg1_size = sizeof (struct ipv6hdr ),
7451+ .arg2_type = ARG_PTR_TO_MEM ,
7452+ .arg3_type = ARG_CONST_SIZE ,
7453+ };
7454+
7455+ BPF_CALL_2 (bpf_tcp_raw_check_syncookie_ipv4 , struct iphdr * , iph ,
7456+ struct tcphdr * , th )
7457+ {
7458+ #ifdef CONFIG_SYN_COOKIES
7459+ u32 cookie = ntohl (th -> ack_seq ) - 1 ;
7460+
7461+ if (__cookie_v4_check (iph , th , cookie ) > 0 )
7462+ return 0 ;
7463+
7464+ return - EACCES ;
7465+ #else
7466+ return - EOPNOTSUPP ;
7467+ #endif
7468+ }
7469+
7470+ static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv4_proto = {
7471+ .func = bpf_tcp_raw_check_syncookie_ipv4 ,
7472+ .gpl_only = true, /* __cookie_v4_check is GPL */
7473+ .pkt_access = true,
7474+ .ret_type = RET_INTEGER ,
7475+ .arg1_type = ARG_PTR_TO_MEM ,
7476+ .arg1_size = sizeof (struct iphdr ),
7477+ .arg2_type = ARG_PTR_TO_MEM ,
7478+ .arg2_size = sizeof (struct tcphdr ),
7479+ };
7480+
7481+ BPF_CALL_2 (bpf_tcp_raw_check_syncookie_ipv6 , struct ipv6hdr * , iph ,
7482+ struct tcphdr * , th )
7483+ {
7484+ #ifndef CONFIG_SYN_COOKIES
7485+ return - EOPNOTSUPP ;
7486+ #elif !IS_BUILTIN (CONFIG_IPV6 )
7487+ return - EPROTONOSUPPORT ;
7488+ #else
7489+ u32 cookie = ntohl (th -> ack_seq ) - 1 ;
7490+
7491+ if (__cookie_v6_check (iph , th , cookie ) > 0 )
7492+ return 0 ;
7493+
7494+ return - EACCES ;
7495+ #endif
7496+ }
7497+
7498+ static const struct bpf_func_proto bpf_tcp_raw_check_syncookie_ipv6_proto = {
7499+ .func = bpf_tcp_raw_check_syncookie_ipv6 ,
7500+ .gpl_only = true, /* __cookie_v6_check is GPL */
7501+ .pkt_access = true,
7502+ .ret_type = RET_INTEGER ,
7503+ .arg1_type = ARG_PTR_TO_MEM ,
7504+ .arg1_size = sizeof (struct ipv6hdr ),
7505+ .arg2_type = ARG_PTR_TO_MEM ,
7506+ .arg2_size = sizeof (struct tcphdr ),
7507+ };
7508+
73917509#endif /* CONFIG_INET */
73927510
73937511bool bpf_helper_changes_pkt_data (void * func )
@@ -7798,6 +7916,14 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
77987916 return & bpf_tcp_check_syncookie_proto ;
77997917 case BPF_FUNC_tcp_gen_syncookie :
78007918 return & bpf_tcp_gen_syncookie_proto ;
7919+ case BPF_FUNC_tcp_raw_gen_syncookie_ipv4 :
7920+ return & bpf_tcp_raw_gen_syncookie_ipv4_proto ;
7921+ case BPF_FUNC_tcp_raw_gen_syncookie_ipv6 :
7922+ return & bpf_tcp_raw_gen_syncookie_ipv6_proto ;
7923+ case BPF_FUNC_tcp_raw_check_syncookie_ipv4 :
7924+ return & bpf_tcp_raw_check_syncookie_ipv4_proto ;
7925+ case BPF_FUNC_tcp_raw_check_syncookie_ipv6 :
7926+ return & bpf_tcp_raw_check_syncookie_ipv6_proto ;
78017927#endif
78027928 default :
78037929 return bpf_sk_base_func_proto (func_id );
0 commit comments