FILE
tc_tun_gre.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_gre.c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2/* Copyright (c) 2018 Mellanox Technologies. */ 3 4#include <net/gre.h> 5#include "en/tc_tun.h" 6 7static bool mlx5e_tc_tun_can_offload_gretap(struct mlx5e_priv *priv) 8{ 9 return !!MLX5_CAP_ESW(priv->mdev, nvgre_encap_decap); 10} 11 12static int mlx5e_tc_tun_calc_hlen_gretap(struct mlx5e_encap_entry *e) 13{ 14 return gre_calc_hlen(e->tun_info->key.tun_flags); 15} 16 17static int mlx5e_tc_tun_init_encap_attr_gretap(struct net_device *tunnel_dev, 18 struct mlx5e_priv *priv, 19 struct mlx5e_encap_entry *e, 20 struct netlink_ext_ack *extack) 21{ 22 e->tunnel = &gre_tunnel; 23 e->reformat_type = MLX5_REFORMAT_TYPE_L2_TO_NVGRE; 24 return 0; 25} 26 27static int mlx5e_gen_ip_tunnel_header_gretap(char buf[], 28 __u8 *ip_proto, 29 struct mlx5e_encap_entry *e) 30{ 31 const struct ip_tunnel_key *tun_key = &e->tun_info->key; 32 struct gre_base_hdr *greh = (struct gre_base_hdr *)(buf); 33 __be32 tun_id = tunnel_id_to_key32(tun_key->tun_id); 34 IP_TUNNEL_DECLARE_FLAGS(unsupp) = { }; 35 int hdr_len; 36 37 *ip_proto = IPPROTO_GRE; 38 39 /* the HW does not calculate GRE csum or sequences */ 40 __set_bit(IP_TUNNEL_CSUM_BIT, unsupp); 41 __set_bit(IP_TUNNEL_SEQ_BIT, unsupp); 42 43 if (ip_tunnel_flags_intersect(tun_key->tun_flags, unsupp)) 44 return -EOPNOTSUPP; 45 46 greh->protocol = htons(ETH_P_TEB); 47 48 /* GRE key */ 49 hdr_len = mlx5e_tc_tun_calc_hlen_gretap(e); 50 greh->flags = gre_tnl_flags_to_gre_flags(tun_key->tun_flags); 51 if (test_bit(IP_TUNNEL_KEY_BIT, tun_key->tun_flags)) { 52 __be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4); 53 *ptr = tun_id; 54 } 55 56 return 0; 57} 58 59static int mlx5e_tc_tun_parse_gretap(struct mlx5e_priv *priv, 60 struct mlx5_flow_spec *spec, 61 struct flow_cls_offload *f, 62 void *headers_c, 63 void *headers_v) 64{ 65 void *misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters); 66 void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters); 67 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 68 69 MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, headers_c, ip_protocol); 70 MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol, IPPROTO_GRE); 71 72 /* gre protocol */ 73 MLX5_SET_TO_ONES(fte_match_set_misc, misc_c, gre_protocol); 74 MLX5_SET(fte_match_set_misc, misc_v, gre_protocol, ETH_P_TEB); 75 76 /* gre key */ 77 if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID)) { 78 struct flow_match_enc_keyid enc_keyid; 79 80 flow_rule_match_enc_keyid(rule, &enc_keyid); 81 MLX5_SET(fte_match_set_misc, misc_c, 82 gre_key.key, be32_to_cpu(enc_keyid.mask->keyid)); 83 MLX5_SET(fte_match_set_misc, misc_v, 84 gre_key.key, be32_to_cpu(enc_keyid.key->keyid)); 85 } 86 87 spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS; 88 89 return 0; 90} 91 92struct mlx5e_tc_tunnel gre_tunnel = { 93 .tunnel_type = MLX5E_TC_TUNNEL_TYPE_GRETAP, 94 .match_level = MLX5_MATCH_L3, 95 .can_offload = mlx5e_tc_tun_can_offload_gretap, 96 .calc_hlen = mlx5e_tc_tun_calc_hlen_gretap, 97 .init_encap_attr = mlx5e_tc_tun_init_encap_attr_gretap, 98 .generate_ip_tun_hdr = mlx5e_gen_ip_tunnel_header_gretap, 99 .parse_udp_ports = NULL, 100 .parse_tunnel = mlx5e_tc_tun_parse_gretap, 101 .encap_info_equal = mlx5e_tc_tun_encap_info_equal_generic, 102};
~/
Read-only file preview.