aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOr Gerlitz <ogerlitz@mellanox.com>2017-04-06 12:28:30 -0400
committerSaeed Mahameed <saeedm@mellanox.com>2017-04-22 14:52:37 -0400
commit225aabaffe9ab42b2dd8770359442f019083275e (patch)
treecb2920318f319edde99e7dfc17853867b35782a5
parent32f3671f6951836cfe9d84e1a6554908b85c61d7 (diff)
net/mlx5e: Make sure the FW max encap size is enough for ipv6 tunnels
Otherwise the code that fills the ipv6 encapsulation headers could be writing beyond the allocated headers buffer. Fixes: ce99f6b97fcd ('net/mlx5e: Support SRIOV TC encapsulation offloads for IPv6 tunnels') Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com> Reviewed-by: Roi Dayan <roid@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_tc.c42
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index fc7c1d30461c..5436866798f4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -819,16 +819,15 @@ static void gen_vxlan_header_ipv4(struct net_device *out_dev,
819 vxh->vx_vni = vxlan_vni_field(vx_vni); 819 vxh->vx_vni = vxlan_vni_field(vx_vni);
820} 820}
821 821
822static int gen_vxlan_header_ipv6(struct net_device *out_dev, 822static void gen_vxlan_header_ipv6(struct net_device *out_dev,
823 char buf[], 823 char buf[], int encap_size,
824 unsigned char h_dest[ETH_ALEN], 824 unsigned char h_dest[ETH_ALEN],
825 int ttl, 825 int ttl,
826 struct in6_addr *daddr, 826 struct in6_addr *daddr,
827 struct in6_addr *saddr, 827 struct in6_addr *saddr,
828 __be16 udp_dst_port, 828 __be16 udp_dst_port,
829 __be32 vx_vni) 829 __be32 vx_vni)
830{ 830{
831 int encap_size = VXLAN_HLEN + sizeof(struct ipv6hdr) + ETH_HLEN;
832 struct ethhdr *eth = (struct ethhdr *)buf; 831 struct ethhdr *eth = (struct ethhdr *)buf;
833 struct ipv6hdr *ip6h = (struct ipv6hdr *)((char *)eth + sizeof(struct ethhdr)); 832 struct ipv6hdr *ip6h = (struct ipv6hdr *)((char *)eth + sizeof(struct ethhdr));
834 struct udphdr *udp = (struct udphdr *)((char *)ip6h + sizeof(struct ipv6hdr)); 833 struct udphdr *udp = (struct udphdr *)((char *)ip6h + sizeof(struct ipv6hdr));
@@ -850,8 +849,6 @@ static int gen_vxlan_header_ipv6(struct net_device *out_dev,
850 udp->dest = udp_dst_port; 849 udp->dest = udp_dst_port;
851 vxh->vx_flags = VXLAN_HF_VNI; 850 vxh->vx_flags = VXLAN_HF_VNI;
852 vxh->vx_vni = vxlan_vni_field(vx_vni); 851 vxh->vx_vni = vxlan_vni_field(vx_vni);
853
854 return encap_size;
855} 852}
856 853
857static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv, 854static int mlx5e_create_encap_header_ipv4(struct mlx5e_priv *priv,
@@ -935,13 +932,20 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
935 932
936{ 933{
937 int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size); 934 int max_encap_size = MLX5_CAP_ESW(priv->mdev, max_encap_header_size);
935 int ipv6_encap_size = ETH_HLEN + sizeof(struct ipv6hdr) + VXLAN_HLEN;
938 struct ip_tunnel_key *tun_key = &e->tun_info.key; 936 struct ip_tunnel_key *tun_key = &e->tun_info.key;
939 int encap_size, err, ttl = 0;
940 struct neighbour *n = NULL; 937 struct neighbour *n = NULL;
941 struct flowi6 fl6 = {}; 938 struct flowi6 fl6 = {};
942 char *encap_header; 939 char *encap_header;
940 int err, ttl = 0;
943 941
944 encap_header = kzalloc(max_encap_size, GFP_KERNEL); 942 if (max_encap_size < ipv6_encap_size) {
943 mlx5_core_warn(priv->mdev, "encap size %d too big, max supported is %d\n",
944 ipv6_encap_size, max_encap_size);
945 return -EOPNOTSUPP;
946 }
947
948 encap_header = kzalloc(ipv6_encap_size, GFP_KERNEL);
945 if (!encap_header) 949 if (!encap_header)
946 return -ENOMEM; 950 return -ENOMEM;
947 951
@@ -977,11 +981,11 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
977 981
978 switch (e->tunnel_type) { 982 switch (e->tunnel_type) {
979 case MLX5_HEADER_TYPE_VXLAN: 983 case MLX5_HEADER_TYPE_VXLAN:
980 encap_size = gen_vxlan_header_ipv6(*out_dev, encap_header, 984 gen_vxlan_header_ipv6(*out_dev, encap_header,
981 e->h_dest, ttl, 985 ipv6_encap_size, e->h_dest, ttl,
982 &fl6.daddr, 986 &fl6.daddr,
983 &fl6.saddr, tun_key->tp_dst, 987 &fl6.saddr, tun_key->tp_dst,
984 tunnel_id_to_key32(tun_key->tun_id)); 988 tunnel_id_to_key32(tun_key->tun_id));
985 break; 989 break;
986 default: 990 default:
987 err = -EOPNOTSUPP; 991 err = -EOPNOTSUPP;
@@ -989,7 +993,7 @@ static int mlx5e_create_encap_header_ipv6(struct mlx5e_priv *priv,
989 } 993 }
990 994
991 err = mlx5_encap_alloc(priv->mdev, e->tunnel_type, 995 err = mlx5_encap_alloc(priv->mdev, e->tunnel_type,
992 encap_size, encap_header, &e->encap_id); 996 ipv6_encap_size, encap_header, &e->encap_id);
993out: 997out:
994 if (err && n) 998 if (err && n)
995 neigh_release(n); 999 neigh_release(n);