@@ -18,6 +18,11 @@ struct mlx5_ipsec_rx_roce {
1818 struct mlx5_flow_table * ft ;
1919 struct mlx5_flow_handle * rule ;
2020 struct mlx5_ipsec_miss roce_miss ;
21+ struct mlx5_flow_table * nic_master_ft ;
22+ struct mlx5_flow_group * nic_master_group ;
23+ struct mlx5_flow_handle * nic_master_rule ;
24+ struct mlx5_flow_table * goto_alias_ft ;
25+ u32 alias_id ;
2126
2227 struct mlx5_flow_table * ft_rdma ;
2328 struct mlx5_flow_namespace * ns_rdma ;
@@ -119,6 +124,7 @@ ipsec_fs_roce_rx_rule_setup(struct mlx5_core_dev *mdev,
119124 struct mlx5_flow_destination * default_dst ,
120125 struct mlx5_ipsec_rx_roce * roce )
121126{
127+ bool is_mpv_slave = mlx5_core_is_mp_slave (mdev );
122128 struct mlx5_flow_destination dst = {};
123129 MLX5_DECLARE_FLOW_ACT (flow_act );
124130 struct mlx5_flow_handle * rule ;
@@ -132,14 +138,19 @@ ipsec_fs_roce_rx_rule_setup(struct mlx5_core_dev *mdev,
132138 ipsec_fs_roce_setup_udp_dport (spec , ROCE_V2_UDP_DPORT );
133139
134140 flow_act .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
135- dst .type = MLX5_FLOW_DESTINATION_TYPE_TABLE_TYPE ;
136- dst .ft = roce -> ft_rdma ;
141+ if (is_mpv_slave ) {
142+ dst .type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE ;
143+ dst .ft = roce -> goto_alias_ft ;
144+ } else {
145+ dst .type = MLX5_FLOW_DESTINATION_TYPE_TABLE_TYPE ;
146+ dst .ft = roce -> ft_rdma ;
147+ }
137148 rule = mlx5_add_flow_rules (roce -> ft , spec , & flow_act , & dst , 1 );
138149 if (IS_ERR (rule )) {
139150 err = PTR_ERR (rule );
140151 mlx5_core_err (mdev , "Fail to add RX RoCE IPsec rule err=%d\n" ,
141152 err );
142- goto fail_add_rule ;
153+ goto out ;
143154 }
144155
145156 roce -> rule = rule ;
@@ -155,12 +166,30 @@ ipsec_fs_roce_rx_rule_setup(struct mlx5_core_dev *mdev,
155166
156167 roce -> roce_miss .rule = rule ;
157168
169+ if (!is_mpv_slave )
170+ goto out ;
171+
172+ flow_act .action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST ;
173+ dst .type = MLX5_FLOW_DESTINATION_TYPE_TABLE_TYPE ;
174+ dst .ft = roce -> ft_rdma ;
175+ rule = mlx5_add_flow_rules (roce -> nic_master_ft , NULL , & flow_act , & dst ,
176+ 1 );
177+ if (IS_ERR (rule )) {
178+ err = PTR_ERR (rule );
179+ mlx5_core_err (mdev , "Fail to add RX RoCE IPsec rule for alias err=%d\n" ,
180+ err );
181+ goto fail_add_nic_master_rule ;
182+ }
183+ roce -> nic_master_rule = rule ;
184+
158185 kvfree (spec );
159186 return 0 ;
160187
188+ fail_add_nic_master_rule :
189+ mlx5_del_flow_rules (roce -> roce_miss .rule );
161190fail_add_default_rule :
162191 mlx5_del_flow_rules (roce -> rule );
163- fail_add_rule :
192+ out :
164193 kvfree (spec );
165194 return err ;
166195}
@@ -379,6 +408,141 @@ static int ipsec_fs_roce_tx_mpv_create(struct mlx5_core_dev *mdev,
379408 return err ;
380409}
381410
411+ static void roce_rx_mpv_destroy_tables (struct mlx5_core_dev * mdev , struct mlx5_ipsec_rx_roce * roce )
412+ {
413+ mlx5_destroy_flow_table (roce -> goto_alias_ft );
414+ mlx5_cmd_alias_obj_destroy (mdev , roce -> alias_id ,
415+ MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS );
416+ mlx5_destroy_flow_group (roce -> nic_master_group );
417+ mlx5_destroy_flow_table (roce -> nic_master_ft );
418+ }
419+
420+ #define MLX5_RX_ROCE_GROUP_SIZE BIT(0)
421+ #define MLX5_IPSEC_RX_IPV4_FT_LEVEL 3
422+ #define MLX5_IPSEC_RX_IPV6_FT_LEVEL 2
423+
424+ static int ipsec_fs_roce_rx_mpv_create (struct mlx5_core_dev * mdev ,
425+ struct mlx5_ipsec_fs * ipsec_roce ,
426+ struct mlx5_flow_namespace * ns ,
427+ u32 family , u32 level , u32 prio )
428+ {
429+ struct mlx5_flow_namespace * roce_ns , * nic_ns ;
430+ struct mlx5_flow_table_attr ft_attr = {};
431+ struct mlx5_devcom_comp_dev * tmp = NULL ;
432+ struct mlx5_ipsec_rx_roce * roce ;
433+ struct mlx5_flow_table next_ft ;
434+ struct mlx5_flow_table * ft ;
435+ struct mlx5_flow_group * g ;
436+ struct mlx5e_priv * peer_priv ;
437+ int ix = 0 ;
438+ u32 * in ;
439+ int err ;
440+
441+ roce = (family == AF_INET ) ? & ipsec_roce -> ipv4_rx :
442+ & ipsec_roce -> ipv6_rx ;
443+
444+ if (!mlx5_devcom_for_each_peer_begin (* ipsec_roce -> devcom ))
445+ return - EOPNOTSUPP ;
446+
447+ peer_priv = mlx5_devcom_get_next_peer_data (* ipsec_roce -> devcom , & tmp );
448+ if (!peer_priv ) {
449+ err = - EOPNOTSUPP ;
450+ goto release_peer ;
451+ }
452+
453+ roce_ns = mlx5_get_flow_namespace (peer_priv -> mdev , MLX5_FLOW_NAMESPACE_RDMA_RX_IPSEC );
454+ if (!roce_ns ) {
455+ err = - EOPNOTSUPP ;
456+ goto release_peer ;
457+ }
458+
459+ nic_ns = mlx5_get_flow_namespace (peer_priv -> mdev , MLX5_FLOW_NAMESPACE_KERNEL );
460+ if (!nic_ns ) {
461+ err = - EOPNOTSUPP ;
462+ goto release_peer ;
463+ }
464+
465+ in = kvzalloc (MLX5_ST_SZ_BYTES (create_flow_group_in ), GFP_KERNEL );
466+ if (!in ) {
467+ err = - ENOMEM ;
468+ goto release_peer ;
469+ }
470+
471+ ft_attr .level = (family == AF_INET ) ? MLX5_IPSEC_RX_IPV4_FT_LEVEL :
472+ MLX5_IPSEC_RX_IPV6_FT_LEVEL ;
473+ ft_attr .max_fte = 1 ;
474+ ft = mlx5_create_flow_table (roce_ns , & ft_attr );
475+ if (IS_ERR (ft )) {
476+ err = PTR_ERR (ft );
477+ mlx5_core_err (mdev , "Fail to create RoCE IPsec rx ft at rdma master err=%d\n" , err );
478+ goto free_in ;
479+ }
480+
481+ roce -> ft_rdma = ft ;
482+
483+ ft_attr .max_fte = 1 ;
484+ ft_attr .prio = prio ;
485+ ft_attr .level = level + 2 ;
486+ ft = mlx5_create_flow_table (nic_ns , & ft_attr );
487+ if (IS_ERR (ft )) {
488+ err = PTR_ERR (ft );
489+ mlx5_core_err (mdev , "Fail to create RoCE IPsec rx ft at NIC master err=%d\n" , err );
490+ goto destroy_ft_rdma ;
491+ }
492+ roce -> nic_master_ft = ft ;
493+
494+ MLX5_SET_CFG (in , start_flow_index , ix );
495+ ix += 1 ;
496+ MLX5_SET_CFG (in , end_flow_index , ix - 1 );
497+ g = mlx5_create_flow_group (roce -> nic_master_ft , in );
498+ if (IS_ERR (g )) {
499+ err = PTR_ERR (g );
500+ mlx5_core_err (mdev , "Fail to create RoCE IPsec rx group aliased err=%d\n" , err );
501+ goto destroy_nic_master_ft ;
502+ }
503+ roce -> nic_master_group = g ;
504+
505+ err = ipsec_fs_create_aliased_ft (peer_priv -> mdev , mdev , roce -> nic_master_ft ,
506+ & roce -> alias_id );
507+ if (err ) {
508+ mlx5_core_err (mdev , "Fail to create RoCE IPsec rx alias FT err=%d\n" , err );
509+ goto destroy_group ;
510+ }
511+
512+ next_ft .id = roce -> alias_id ;
513+ ft_attr .max_fte = 1 ;
514+ ft_attr .prio = prio ;
515+ ft_attr .level = roce -> ft -> level + 1 ;
516+ ft_attr .flags = MLX5_FLOW_TABLE_UNMANAGED ;
517+ ft_attr .next_ft = & next_ft ;
518+ ft = mlx5_create_flow_table (ns , & ft_attr );
519+ if (IS_ERR (ft )) {
520+ err = PTR_ERR (ft );
521+ mlx5_core_err (mdev , "Fail to create RoCE IPsec rx ft at NIC slave err=%d\n" , err );
522+ goto destroy_alias ;
523+ }
524+ roce -> goto_alias_ft = ft ;
525+
526+ kvfree (in );
527+ mlx5_devcom_for_each_peer_end (* ipsec_roce -> devcom );
528+ return 0 ;
529+
530+ destroy_alias :
531+ mlx5_cmd_alias_obj_destroy (mdev , roce -> alias_id ,
532+ MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS );
533+ destroy_group :
534+ mlx5_destroy_flow_group (roce -> nic_master_group );
535+ destroy_nic_master_ft :
536+ mlx5_destroy_flow_table (roce -> nic_master_ft );
537+ destroy_ft_rdma :
538+ mlx5_destroy_flow_table (roce -> ft_rdma );
539+ free_in :
540+ kvfree (in );
541+ release_peer :
542+ mlx5_devcom_for_each_peer_end (* ipsec_roce -> devcom );
543+ return err ;
544+ }
545+
382546void mlx5_ipsec_fs_roce_tx_destroy (struct mlx5_ipsec_fs * ipsec_roce ,
383547 struct mlx5_core_dev * mdev )
384548{
@@ -493,8 +657,10 @@ struct mlx5_flow_table *mlx5_ipsec_fs_roce_ft_get(struct mlx5_ipsec_fs *ipsec_ro
493657 return rx_roce -> ft ;
494658}
495659
496- void mlx5_ipsec_fs_roce_rx_destroy (struct mlx5_ipsec_fs * ipsec_roce , u32 family )
660+ void mlx5_ipsec_fs_roce_rx_destroy (struct mlx5_ipsec_fs * ipsec_roce , u32 family ,
661+ struct mlx5_core_dev * mdev )
497662{
663+ bool is_mpv_slave = mlx5_core_is_mp_slave (mdev );
498664 struct mlx5_ipsec_rx_roce * rx_roce ;
499665
500666 if (!ipsec_roce )
@@ -503,22 +669,25 @@ void mlx5_ipsec_fs_roce_rx_destroy(struct mlx5_ipsec_fs *ipsec_roce, u32 family)
503669 rx_roce = (family == AF_INET ) ? & ipsec_roce -> ipv4_rx :
504670 & ipsec_roce -> ipv6_rx ;
505671
672+ if (is_mpv_slave )
673+ mlx5_del_flow_rules (rx_roce -> nic_master_rule );
506674 mlx5_del_flow_rules (rx_roce -> roce_miss .rule );
507675 mlx5_del_flow_rules (rx_roce -> rule );
676+ if (is_mpv_slave )
677+ roce_rx_mpv_destroy_tables (mdev , rx_roce );
508678 mlx5_destroy_flow_table (rx_roce -> ft_rdma );
509679 mlx5_destroy_flow_group (rx_roce -> roce_miss .group );
510680 mlx5_destroy_flow_group (rx_roce -> g );
511681 mlx5_destroy_flow_table (rx_roce -> ft );
512682}
513683
514- #define MLX5_RX_ROCE_GROUP_SIZE BIT(0)
515-
516684int mlx5_ipsec_fs_roce_rx_create (struct mlx5_core_dev * mdev ,
517685 struct mlx5_ipsec_fs * ipsec_roce ,
518686 struct mlx5_flow_namespace * ns ,
519687 struct mlx5_flow_destination * default_dst ,
520688 u32 family , u32 level , u32 prio )
521689{
690+ bool is_mpv_slave = mlx5_core_is_mp_slave (mdev );
522691 struct mlx5_flow_table_attr ft_attr = {};
523692 struct mlx5_ipsec_rx_roce * roce ;
524693 struct mlx5_flow_table * ft ;
@@ -582,18 +751,28 @@ int mlx5_ipsec_fs_roce_rx_create(struct mlx5_core_dev *mdev,
582751 }
583752 roce -> roce_miss .group = g ;
584753
585- memset (& ft_attr , 0 , sizeof (ft_attr ));
586- if (family == AF_INET )
587- ft_attr .level = 1 ;
588- ft = mlx5_create_flow_table (roce -> ns_rdma , & ft_attr );
589- if (IS_ERR (ft )) {
590- err = PTR_ERR (ft );
591- mlx5_core_err (mdev , "Fail to create RoCE IPsec rx ft at rdma err=%d\n" , err );
592- goto fail_rdma_table ;
754+ if (is_mpv_slave ) {
755+ err = ipsec_fs_roce_rx_mpv_create (mdev , ipsec_roce , ns , family , level , prio );
756+ if (err ) {
757+ mlx5_core_err (mdev , "Fail to create RoCE IPsec rx alias err=%d\n" , err );
758+ goto fail_mpv_create ;
759+ }
760+ } else {
761+ memset (& ft_attr , 0 , sizeof (ft_attr ));
762+ if (family == AF_INET )
763+ ft_attr .level = 1 ;
764+ ft_attr .max_fte = 1 ;
765+ ft = mlx5_create_flow_table (roce -> ns_rdma , & ft_attr );
766+ if (IS_ERR (ft )) {
767+ err = PTR_ERR (ft );
768+ mlx5_core_err (mdev ,
769+ "Fail to create RoCE IPsec rx ft at rdma err=%d\n" , err );
770+ goto fail_rdma_table ;
771+ }
772+
773+ roce -> ft_rdma = ft ;
593774 }
594775
595- roce -> ft_rdma = ft ;
596-
597776 err = ipsec_fs_roce_rx_rule_setup (mdev , default_dst , roce );
598777 if (err ) {
599778 mlx5_core_err (mdev , "Fail to create RoCE IPsec rx rules err=%d\n" , err );
@@ -604,7 +783,10 @@ int mlx5_ipsec_fs_roce_rx_create(struct mlx5_core_dev *mdev,
604783 return 0 ;
605784
606785fail_setup_rule :
786+ if (is_mpv_slave )
787+ roce_rx_mpv_destroy_tables (mdev , roce );
607788 mlx5_destroy_flow_table (roce -> ft_rdma );
789+ fail_mpv_create :
608790fail_rdma_table :
609791 mlx5_destroy_flow_group (roce -> roce_miss .group );
610792fail_mgroup :
0 commit comments