OSDN Git Service

net/mlx5e: Take SW parser code to a separate function
authorMoshe Shemesh <moshe@mellanox.com>
Thu, 21 Mar 2019 22:51:37 +0000 (15:51 -0700)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 22 Mar 2019 19:09:31 +0000 (12:09 -0700)
Refactor mlx5e_ipsec_set_swp() code, split the part which sets the eseg
software parser (SWP) offsets and flags, so it can be used in a
downstream patch by other mlx5e functionality which needs to set eseg
SWP.
The new function mlx5e_set_eseg_swp() is useful for setting swp for both
outer and inner headers. It also handles the special ipsec case of xfrm
mode transfer.

Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_rxtx.c

index 5c2e327..16a6448 100644 (file)
@@ -884,6 +884,47 @@ static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
                MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ft_field_support.inner_ip_version));
 }
 
+struct mlx5e_swp_spec {
+       __be16 l3_proto;
+       u8 l4_proto;
+       u8 is_tun;
+       __be16 tun_l3_proto;
+       u8 tun_l4_proto;
+};
+
+static inline void
+mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,
+                  struct mlx5e_swp_spec *swp_spec)
+{
+       /* SWP offsets are in 2-bytes words */
+       eseg->swp_outer_l3_offset = skb_network_offset(skb) / 2;
+       if (swp_spec->l3_proto == htons(ETH_P_IPV6))
+               eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L3_IPV6;
+       if (swp_spec->l4_proto) {
+               eseg->swp_outer_l4_offset = skb_transport_offset(skb) / 2;
+               if (swp_spec->l4_proto == IPPROTO_UDP)
+                       eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L4_UDP;
+       }
+
+       if (swp_spec->is_tun) {
+               eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
+               if (swp_spec->tun_l3_proto == htons(ETH_P_IPV6))
+                       eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
+       } else { /* typically for ipsec when xfrm mode != XFRM_MODE_TUNNEL */
+               eseg->swp_inner_l3_offset = skb_network_offset(skb) / 2;
+               if (swp_spec->l3_proto == htons(ETH_P_IPV6))
+                       eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
+       }
+       switch (swp_spec->tun_l4_proto) {
+       case IPPROTO_UDP:
+               eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
+               /* fall through */
+       case IPPROTO_TCP:
+               eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
+               break;
+       }
+}
+
 static inline void mlx5e_sq_fetch_wqe(struct mlx5e_txqsq *sq,
                                      struct mlx5e_tx_wqe **wqe,
                                      u16 *pi)
index 53608af..0dd1751 100644 (file)
@@ -136,7 +136,7 @@ static void mlx5e_ipsec_set_swp(struct sk_buff *skb,
                                struct mlx5_wqe_eth_seg *eseg, u8 mode,
                                struct xfrm_offload *xo)
 {
-       u8 proto;
+       struct mlx5e_swp_spec swp_spec = {};
 
        /* Tunnel Mode:
         * SWP:      OutL3       InL3  InL4
@@ -146,35 +146,23 @@ static void mlx5e_ipsec_set_swp(struct sk_buff *skb,
         * SWP:      OutL3       InL4
         *           InL3
         * Pkt: MAC  IP     ESP  L4
-        *
-        * Offsets are in 2-byte words, counting from start of frame
         */
-       eseg->swp_outer_l3_offset = skb_network_offset(skb) / 2;
-       if (skb->protocol == htons(ETH_P_IPV6))
-               eseg->swp_flags |= MLX5_ETH_WQE_SWP_OUTER_L3_IPV6;
-
-       if (mode == XFRM_MODE_TUNNEL) {
-               eseg->swp_inner_l3_offset = skb_inner_network_offset(skb) / 2;
+       swp_spec.l3_proto = skb->protocol;
+       swp_spec.is_tun = mode == XFRM_MODE_TUNNEL;
+       if (swp_spec.is_tun) {
                if (xo->proto == IPPROTO_IPV6) {
-                       eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
-                       proto = inner_ipv6_hdr(skb)->nexthdr;
+                       swp_spec.tun_l3_proto = htons(ETH_P_IPV6);
+                       swp_spec.tun_l4_proto = inner_ipv6_hdr(skb)->nexthdr;
                } else {
-                       proto = inner_ip_hdr(skb)->protocol;
+                       swp_spec.tun_l3_proto = htons(ETH_P_IP);
+                       swp_spec.tun_l4_proto = inner_ip_hdr(skb)->protocol;
                }
        } else {
-               eseg->swp_inner_l3_offset = skb_network_offset(skb) / 2;
-               if (skb->protocol == htons(ETH_P_IPV6))
-                       eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L3_IPV6;
-               proto = xo->proto;
-       }
-       switch (proto) {
-       case IPPROTO_UDP:
-               eseg->swp_flags |= MLX5_ETH_WQE_SWP_INNER_L4_UDP;
-               /* Fall through */
-       case IPPROTO_TCP:
-               eseg->swp_inner_l4_offset = skb_inner_transport_offset(skb) / 2;
-               break;
+               swp_spec.tun_l3_proto = skb->protocol;
+               swp_spec.tun_l4_proto = xo->proto;
        }
+
+       mlx5e_set_eseg_swp(skb, eseg, &swp_spec);
 }
 
 void mlx5e_ipsec_set_iv_esn(struct sk_buff *skb, struct xfrm_state *x,