|
1 | 1 | // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
|
2 | 2 | /* Copyright (c) 2020 Mellanox Technologies. */
|
3 | 3 |
|
4 |
| -#include <net/dst_metadata.h> |
5 | 4 | #include <linux/netdevice.h>
|
6 | 5 | #include <linux/if_macvlan.h>
|
7 | 6 | #include <linux/list.h>
|
@@ -665,230 +664,54 @@ void mlx5e_rep_tc_netdevice_event_unregister(struct mlx5e_rep_priv *rpriv)
|
665 | 664 | mlx5e_rep_indr_block_unbind);
|
666 | 665 | }
|
667 | 666 |
|
668 |
| -static bool mlx5e_restore_tunnel(struct mlx5e_priv *priv, struct sk_buff *skb, |
669 |
| - struct mlx5e_tc_update_priv *tc_priv, |
670 |
| - u32 tunnel_id) |
671 |
| -{ |
672 |
| - struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; |
673 |
| - struct tunnel_match_enc_opts enc_opts = {}; |
674 |
| - struct mlx5_rep_uplink_priv *uplink_priv; |
675 |
| - struct mlx5e_rep_priv *uplink_rpriv; |
676 |
| - struct metadata_dst *tun_dst; |
677 |
| - struct tunnel_match_key key; |
678 |
| - u32 tun_id, enc_opts_id; |
679 |
| - struct net_device *dev; |
680 |
| - int err; |
681 |
| - |
682 |
| - enc_opts_id = tunnel_id & ENC_OPTS_BITS_MASK; |
683 |
| - tun_id = tunnel_id >> ENC_OPTS_BITS; |
684 |
| - |
685 |
| - if (!tun_id) |
686 |
| - return true; |
687 |
| - |
688 |
| - uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); |
689 |
| - uplink_priv = &uplink_rpriv->uplink_priv; |
690 |
| - |
691 |
| - err = mapping_find(uplink_priv->tunnel_mapping, tun_id, &key); |
692 |
| - if (err) { |
693 |
| - netdev_dbg(priv->netdev, |
694 |
| - "Couldn't find tunnel for tun_id: %d, err: %d\n", |
695 |
| - tun_id, err); |
696 |
| - return false; |
697 |
| - } |
698 |
| - |
699 |
| - if (enc_opts_id) { |
700 |
| - err = mapping_find(uplink_priv->tunnel_enc_opts_mapping, |
701 |
| - enc_opts_id, &enc_opts); |
702 |
| - if (err) { |
703 |
| - netdev_dbg(priv->netdev, |
704 |
| - "Couldn't find tunnel (opts) for tun_id: %d, err: %d\n", |
705 |
| - enc_opts_id, err); |
706 |
| - return false; |
707 |
| - } |
708 |
| - } |
709 |
| - |
710 |
| - if (key.enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS) { |
711 |
| - tun_dst = __ip_tun_set_dst(key.enc_ipv4.src, key.enc_ipv4.dst, |
712 |
| - key.enc_ip.tos, key.enc_ip.ttl, |
713 |
| - key.enc_tp.dst, TUNNEL_KEY, |
714 |
| - key32_to_tunnel_id(key.enc_key_id.keyid), |
715 |
| - enc_opts.key.len); |
716 |
| - } else if (key.enc_control.addr_type == FLOW_DISSECTOR_KEY_IPV6_ADDRS) { |
717 |
| - tun_dst = __ipv6_tun_set_dst(&key.enc_ipv6.src, &key.enc_ipv6.dst, |
718 |
| - key.enc_ip.tos, key.enc_ip.ttl, |
719 |
| - key.enc_tp.dst, 0, TUNNEL_KEY, |
720 |
| - key32_to_tunnel_id(key.enc_key_id.keyid), |
721 |
| - enc_opts.key.len); |
722 |
| - } else { |
723 |
| - netdev_dbg(priv->netdev, |
724 |
| - "Couldn't restore tunnel, unsupported addr_type: %d\n", |
725 |
| - key.enc_control.addr_type); |
726 |
| - return false; |
727 |
| - } |
728 |
| - |
729 |
| - if (!tun_dst) { |
730 |
| - netdev_dbg(priv->netdev, "Couldn't restore tunnel, no tun_dst\n"); |
731 |
| - return false; |
732 |
| - } |
733 |
| - |
734 |
| - tun_dst->u.tun_info.key.tp_src = key.enc_tp.src; |
735 |
| - |
736 |
| - if (enc_opts.key.len) |
737 |
| - ip_tunnel_info_opts_set(&tun_dst->u.tun_info, |
738 |
| - enc_opts.key.data, |
739 |
| - enc_opts.key.len, |
740 |
| - enc_opts.key.dst_opt_type); |
741 |
| - |
742 |
| - skb_dst_set(skb, (struct dst_entry *)tun_dst); |
743 |
| - dev = dev_get_by_index(&init_net, key.filter_ifindex); |
744 |
| - if (!dev) { |
745 |
| - netdev_dbg(priv->netdev, |
746 |
| - "Couldn't find tunnel device with ifindex: %d\n", |
747 |
| - key.filter_ifindex); |
748 |
| - return false; |
749 |
| - } |
750 |
| - |
751 |
| - /* Set fwd_dev so we do dev_put() after datapath */ |
752 |
| - tc_priv->fwd_dev = dev; |
753 |
| - |
754 |
| - skb->dev = dev; |
755 |
| - |
756 |
| - return true; |
757 |
| -} |
758 |
| - |
759 |
| -static bool mlx5e_restore_skb_chain(struct sk_buff *skb, u32 chain, u32 reg_c1, |
760 |
| - struct mlx5e_tc_update_priv *tc_priv) |
761 |
| -{ |
762 |
| - struct mlx5e_priv *priv = netdev_priv(skb->dev); |
763 |
| - u32 tunnel_id = (reg_c1 >> ESW_TUN_OFFSET) & TUNNEL_ID_MASK; |
764 |
| - |
765 |
| - if (chain) { |
766 |
| - struct mlx5_rep_uplink_priv *uplink_priv; |
767 |
| - struct mlx5e_rep_priv *uplink_rpriv; |
768 |
| - struct tc_skb_ext *tc_skb_ext; |
769 |
| - struct mlx5_eswitch *esw; |
770 |
| - u32 zone_restore_id; |
771 |
| - |
772 |
| - tc_skb_ext = tc_skb_ext_alloc(skb); |
773 |
| - if (!tc_skb_ext) { |
774 |
| - WARN_ON(1); |
775 |
| - return false; |
776 |
| - } |
777 |
| - tc_skb_ext->chain = chain; |
778 |
| - zone_restore_id = reg_c1 & ESW_ZONE_ID_MASK; |
779 |
| - esw = priv->mdev->priv.eswitch; |
780 |
| - uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); |
781 |
| - uplink_priv = &uplink_rpriv->uplink_priv; |
782 |
| - if (!mlx5e_tc_ct_restore_flow(uplink_priv->ct_priv, skb, |
783 |
| - zone_restore_id)) |
784 |
| - return false; |
785 |
| - } |
786 |
| - |
787 |
| - return mlx5e_restore_tunnel(priv, skb, tc_priv, tunnel_id); |
788 |
| -} |
789 |
| - |
790 |
| -static void mlx5_rep_tc_post_napi_receive(struct mlx5e_tc_update_priv *tc_priv) |
791 |
| -{ |
792 |
| - if (tc_priv->fwd_dev) |
793 |
| - dev_put(tc_priv->fwd_dev); |
794 |
| -} |
795 |
| - |
796 |
| -static void mlx5e_restore_skb_sample(struct mlx5e_priv *priv, struct sk_buff *skb, |
797 |
| - struct mlx5_mapped_obj *mapped_obj, |
798 |
| - struct mlx5e_tc_update_priv *tc_priv) |
799 |
| -{ |
800 |
| - if (!mlx5e_restore_tunnel(priv, skb, tc_priv, mapped_obj->sample.tunnel_id)) { |
801 |
| - netdev_dbg(priv->netdev, |
802 |
| - "Failed to restore tunnel info for sampled packet\n"); |
803 |
| - return; |
804 |
| - } |
805 |
| - mlx5e_tc_sample_skb(skb, mapped_obj); |
806 |
| - mlx5_rep_tc_post_napi_receive(tc_priv); |
807 |
| -} |
808 |
| - |
809 |
| -static bool mlx5e_restore_skb_int_port(struct mlx5e_priv *priv, struct sk_buff *skb, |
810 |
| - struct mlx5_mapped_obj *mapped_obj, |
811 |
| - struct mlx5e_tc_update_priv *tc_priv, |
812 |
| - bool *forward_tx, |
813 |
| - u32 reg_c1) |
814 |
| -{ |
815 |
| - u32 tunnel_id = (reg_c1 >> ESW_TUN_OFFSET) & TUNNEL_ID_MASK; |
816 |
| - struct mlx5_eswitch *esw = priv->mdev->priv.eswitch; |
817 |
| - struct mlx5_rep_uplink_priv *uplink_priv; |
818 |
| - struct mlx5e_rep_priv *uplink_rpriv; |
819 |
| - |
820 |
| - /* Tunnel restore takes precedence over int port restore */ |
821 |
| - if (tunnel_id) |
822 |
| - return mlx5e_restore_tunnel(priv, skb, tc_priv, tunnel_id); |
823 |
| - |
824 |
| - uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); |
825 |
| - uplink_priv = &uplink_rpriv->uplink_priv; |
826 |
| - |
827 |
| - if (mlx5e_tc_int_port_dev_fwd(uplink_priv->int_port_priv, skb, |
828 |
| - mapped_obj->int_port_metadata, forward_tx)) { |
829 |
| - /* Set fwd_dev for future dev_put */ |
830 |
| - tc_priv->fwd_dev = skb->dev; |
831 |
| - |
832 |
| - return true; |
833 |
| - } |
834 |
| - |
835 |
| - return false; |
836 |
| -} |
837 |
| - |
838 | 667 | void mlx5e_rep_tc_receive(struct mlx5_cqe64 *cqe, struct mlx5e_rq *rq,
|
839 | 668 | struct sk_buff *skb)
|
840 | 669 | {
|
841 |
| - u32 reg_c1 = be32_to_cpu(cqe->ft_metadata); |
| 670 | + u32 reg_c0, reg_c1, zone_restore_id, tunnel_id; |
842 | 671 | struct mlx5e_tc_update_priv tc_priv = {};
|
843 |
| - struct mlx5_mapped_obj mapped_obj; |
| 672 | + struct mlx5_rep_uplink_priv *uplink_priv; |
| 673 | + struct mlx5e_rep_priv *uplink_rpriv; |
| 674 | + struct mlx5_tc_ct_priv *ct_priv; |
| 675 | + struct mapping_ctx *mapping_ctx; |
844 | 676 | struct mlx5_eswitch *esw;
|
845 |
| - bool forward_tx = false; |
846 | 677 | struct mlx5e_priv *priv;
|
847 |
| - u32 reg_c0; |
848 |
| - int err; |
849 | 678 |
|
850 | 679 | reg_c0 = (be32_to_cpu(cqe->sop_drop_qpn) & MLX5E_TC_FLOW_ID_MASK);
|
851 | 680 | if (!reg_c0 || reg_c0 == MLX5_FS_DEFAULT_FLOW_TAG)
|
852 | 681 | goto forward;
|
853 | 682 |
|
854 |
| - /* If reg_c0 is not equal to the default flow tag then skb->mark |
| 683 | + /* If mapped_obj_id is not equal to the default flow tag then skb->mark |
855 | 684 | * is not supported and must be reset back to 0.
|
856 | 685 | */
|
857 | 686 | skb->mark = 0;
|
858 | 687 |
|
859 | 688 | priv = netdev_priv(skb->dev);
|
860 | 689 | esw = priv->mdev->priv.eswitch;
|
861 |
| - err = mapping_find(esw->offloads.reg_c0_obj_pool, reg_c0, &mapped_obj); |
862 |
| - if (err) { |
863 |
| - netdev_dbg(priv->netdev, |
864 |
| - "Couldn't find mapped object for reg_c0: %d, err: %d\n", |
865 |
| - reg_c0, err); |
866 |
| - goto free_skb; |
867 |
| - } |
| 690 | + mapping_ctx = esw->offloads.reg_c0_obj_pool; |
| 691 | + reg_c1 = be32_to_cpu(cqe->ft_metadata); |
| 692 | + zone_restore_id = reg_c1 & ESW_ZONE_ID_MASK; |
| 693 | + tunnel_id = (reg_c1 >> ESW_TUN_OFFSET) & TUNNEL_ID_MASK; |
868 | 694 |
|
869 |
| - if (mapped_obj.type == MLX5_MAPPED_OBJ_CHAIN) { |
870 |
| - if (!mlx5e_restore_skb_chain(skb, mapped_obj.chain, reg_c1, &tc_priv) && |
871 |
| - !mlx5_ipsec_is_rx_flow(cqe)) |
872 |
| - goto free_skb; |
873 |
| - } else if (mapped_obj.type == MLX5_MAPPED_OBJ_SAMPLE) { |
874 |
| - mlx5e_restore_skb_sample(priv, skb, &mapped_obj, &tc_priv); |
875 |
| - goto free_skb; |
876 |
| - } else if (mapped_obj.type == MLX5_MAPPED_OBJ_INT_PORT_METADATA) { |
877 |
| - if (!mlx5e_restore_skb_int_port(priv, skb, &mapped_obj, &tc_priv, |
878 |
| - &forward_tx, reg_c1)) |
879 |
| - goto free_skb; |
880 |
| - } else { |
881 |
| - netdev_dbg(priv->netdev, "Invalid mapped object type: %d\n", mapped_obj.type); |
| 695 | + uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH); |
| 696 | + uplink_priv = &uplink_rpriv->uplink_priv; |
| 697 | + ct_priv = uplink_priv->ct_priv; |
| 698 | + |
| 699 | + if (!mlx5_ipsec_is_rx_flow(cqe) && |
| 700 | + !mlx5e_tc_update_skb(cqe, skb, mapping_ctx, reg_c0, ct_priv, zone_restore_id, tunnel_id, |
| 701 | + &tc_priv)) |
882 | 702 | goto free_skb;
|
883 |
| - } |
884 | 703 |
|
885 | 704 | forward:
|
886 |
| - if (forward_tx) |
| 705 | + if (tc_priv.skb_done) |
| 706 | + goto free_skb; |
| 707 | + |
| 708 | + if (tc_priv.forward_tx) |
887 | 709 | dev_queue_xmit(skb);
|
888 | 710 | else
|
889 | 711 | napi_gro_receive(rq->cq.napi, skb);
|
890 | 712 |
|
891 |
| - mlx5_rep_tc_post_napi_receive(&tc_priv); |
| 713 | + if (tc_priv.fwd_dev) |
| 714 | + dev_put(tc_priv.fwd_dev); |
892 | 715 |
|
893 | 716 | return;
|
894 | 717 |
|
|
0 commit comments