@@ -26,6 +26,126 @@ static enum mlx5e_traffic_types fs_accel2tt(enum accel_fs_tcp_type i)
2626 }
2727}
2828
29+ static void accel_fs_tcp_set_ipv4_flow (struct mlx5_flow_spec * spec , struct sock * sk )
30+ {
31+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , outer_headers .ip_protocol );
32+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .ip_protocol , IPPROTO_TCP );
33+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , outer_headers .ip_version );
34+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .ip_version , 4 );
35+ memcpy (MLX5_ADDR_OF (fte_match_param , spec -> match_value ,
36+ outer_headers .src_ipv4_src_ipv6 .ipv4_layout .ipv4 ),
37+ & inet_sk (sk )-> inet_daddr , 4 );
38+ memcpy (MLX5_ADDR_OF (fte_match_param , spec -> match_value ,
39+ outer_headers .dst_ipv4_dst_ipv6 .ipv4_layout .ipv4 ),
40+ & inet_sk (sk )-> inet_rcv_saddr , 4 );
41+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
42+ outer_headers .src_ipv4_src_ipv6 .ipv4_layout .ipv4 );
43+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
44+ outer_headers .dst_ipv4_dst_ipv6 .ipv4_layout .ipv4 );
45+ }
46+
47+ static void accel_fs_tcp_set_ipv6_flow (struct mlx5_flow_spec * spec , struct sock * sk )
48+ {
49+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , outer_headers .ip_protocol );
50+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .ip_protocol , IPPROTO_TCP );
51+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , outer_headers .ip_version );
52+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .ip_version , 6 );
53+ memcpy (MLX5_ADDR_OF (fte_match_param , spec -> match_value ,
54+ outer_headers .src_ipv4_src_ipv6 .ipv6_layout .ipv6 ),
55+ & sk -> sk_v6_daddr , 16 );
56+ memcpy (MLX5_ADDR_OF (fte_match_param , spec -> match_value ,
57+ outer_headers .dst_ipv4_dst_ipv6 .ipv6_layout .ipv6 ),
58+ & inet6_sk (sk )-> saddr , 16 );
59+ memset (MLX5_ADDR_OF (fte_match_param , spec -> match_criteria ,
60+ outer_headers .src_ipv4_src_ipv6 .ipv6_layout .ipv6 ),
61+ 0xff , 16 );
62+ memset (MLX5_ADDR_OF (fte_match_param , spec -> match_criteria ,
63+ outer_headers .dst_ipv4_dst_ipv6 .ipv6_layout .ipv6 ),
64+ 0xff , 16 );
65+ }
66+
67+ void mlx5e_accel_fs_del_sk (struct mlx5_flow_handle * rule )
68+ {
69+ mlx5_del_flow_rules (rule );
70+ }
71+
72+ struct mlx5_flow_handle * mlx5e_accel_fs_add_sk (struct mlx5e_priv * priv ,
73+ struct sock * sk , u32 tirn ,
74+ uint32_t flow_tag )
75+ {
76+ struct mlx5_flow_destination dest = {};
77+ struct mlx5e_flow_table * ft = NULL ;
78+ struct mlx5e_accel_fs_tcp * fs_tcp ;
79+ MLX5_DECLARE_FLOW_ACT (flow_act );
80+ struct mlx5_flow_handle * flow ;
81+ struct mlx5_flow_spec * spec ;
82+
83+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
84+ if (!spec )
85+ return ERR_PTR (- ENOMEM );
86+
87+ fs_tcp = priv -> fs .accel_tcp ;
88+
89+ spec -> match_criteria_enable = MLX5_MATCH_OUTER_HEADERS ;
90+
91+ switch (sk -> sk_family ) {
92+ case AF_INET :
93+ accel_fs_tcp_set_ipv4_flow (spec , sk );
94+ ft = & fs_tcp -> tables [ACCEL_FS_IPV4_TCP ];
95+ mlx5e_dbg (HW , priv , "%s flow is %pI4:%d -> %pI4:%d\n" , __func__ ,
96+ & inet_sk (sk )-> inet_rcv_saddr ,
97+ inet_sk (sk )-> inet_sport ,
98+ & inet_sk (sk )-> inet_daddr ,
99+ inet_sk (sk )-> inet_dport );
100+ break ;
101+ #if IS_ENABLED (CONFIG_IPV6 )
102+ case AF_INET6 :
103+ if (!sk -> sk_ipv6only &&
104+ ipv6_addr_type (& sk -> sk_v6_daddr ) == IPV6_ADDR_MAPPED ) {
105+ accel_fs_tcp_set_ipv4_flow (spec , sk );
106+ ft = & fs_tcp -> tables [ACCEL_FS_IPV4_TCP ];
107+ } else {
108+ accel_fs_tcp_set_ipv6_flow (spec , sk );
109+ ft = & fs_tcp -> tables [ACCEL_FS_IPV6_TCP ];
110+ }
111+ break ;
112+ #endif
113+ default :
114+ break ;
115+ }
116+
117+ if (!ft ) {
118+ flow = ERR_PTR (- EINVAL );
119+ goto out ;
120+ }
121+
122+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
123+ outer_headers .tcp_dport );
124+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
125+ outer_headers .tcp_sport );
126+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .tcp_dport ,
127+ ntohs (inet_sk (sk )-> inet_sport ));
128+ MLX5_SET (fte_match_param , spec -> match_value , outer_headers .tcp_sport ,
129+ ntohs (inet_sk (sk )-> inet_dport ));
130+
131+ dest .type = MLX5_FLOW_DESTINATION_TYPE_TIR ;
132+ dest .tir_num = tirn ;
133+ if (flow_tag != MLX5_FS_DEFAULT_FLOW_TAG ) {
134+ spec -> flow_context .flow_tag = flow_tag ;
135+ spec -> flow_context .flags = FLOW_CONTEXT_HAS_TAG ;
136+ }
137+
138+ flow = mlx5_add_flow_rules (ft -> t , spec , & flow_act , & dest , 1 );
139+
140+ if (IS_ERR (flow ))
141+ netdev_err (priv -> netdev , "mlx5_add_flow_rules() failed, flow is %ld\n" ,
142+ PTR_ERR (flow ));
143+
144+ out :
145+ kvfree (spec );
146+ return flow ;
147+ }
148+
29149static int accel_fs_tcp_add_default_rule (struct mlx5e_priv * priv ,
30150 enum accel_fs_tcp_type type )
31151{
0 commit comments