root/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_vxlan.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlx5e_tc_tun_can_offload_vxlan
  2. mlx5e_tc_tun_calc_hlen_vxlan
  3. mlx5e_tc_tun_check_udp_dport_vxlan
  4. mlx5e_tc_tun_parse_udp_ports_vxlan
  5. mlx5e_tc_tun_init_encap_attr_vxlan
  6. mlx5e_gen_ip_tunnel_header_vxlan
  7. mlx5e_tc_tun_parse_vxlan

   1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
   2 /* Copyright (c) 2018 Mellanox Technologies. */
   3 
   4 #include <net/vxlan.h>
   5 #include "lib/vxlan.h"
   6 #include "en/tc_tun.h"
   7 
   8 static bool mlx5e_tc_tun_can_offload_vxlan(struct mlx5e_priv *priv)
   9 {
  10         return !!MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap);
  11 }
  12 
  13 static int mlx5e_tc_tun_calc_hlen_vxlan(struct mlx5e_encap_entry *e)
  14 {
  15         return VXLAN_HLEN;
  16 }
  17 
  18 static int mlx5e_tc_tun_check_udp_dport_vxlan(struct mlx5e_priv *priv,
  19                                               struct flow_cls_offload *f)
  20 {
  21         struct flow_rule *rule = flow_cls_offload_flow_rule(f);
  22         struct netlink_ext_ack *extack = f->common.extack;
  23         struct flow_match_ports enc_ports;
  24 
  25         if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_PORTS))
  26                 return -EOPNOTSUPP;
  27 
  28         flow_rule_match_enc_ports(rule, &enc_ports);
  29 
  30         /* check the UDP destination port validity */
  31 
  32         if (!mlx5_vxlan_lookup_port(priv->mdev->vxlan,
  33                                     be16_to_cpu(enc_ports.key->dst))) {
  34                 NL_SET_ERR_MSG_MOD(extack,
  35                                    "Matched UDP dst port is not registered as a VXLAN port");
  36                 netdev_warn(priv->netdev,
  37                             "UDP port %d is not registered as a VXLAN port\n",
  38                             be16_to_cpu(enc_ports.key->dst));
  39                 return -EOPNOTSUPP;
  40         }
  41 
  42         return 0;
  43 }
  44 
  45 static int mlx5e_tc_tun_parse_udp_ports_vxlan(struct mlx5e_priv *priv,
  46                                               struct mlx5_flow_spec *spec,
  47                                               struct flow_cls_offload *f,
  48                                               void *headers_c,
  49                                               void *headers_v)
  50 {
  51         int err = 0;
  52 
  53         err = mlx5e_tc_tun_parse_udp_ports(priv, spec, f, headers_c, headers_v);
  54         if (err)
  55                 return err;
  56 
  57         return mlx5e_tc_tun_check_udp_dport_vxlan(priv, f);
  58 }
  59 
  60 static int mlx5e_tc_tun_init_encap_attr_vxlan(struct net_device *tunnel_dev,
  61                                               struct mlx5e_priv *priv,
  62                                               struct mlx5e_encap_entry *e,
  63                                               struct netlink_ext_ack *extack)
  64 {
  65         int dst_port = be16_to_cpu(e->tun_info->key.tp_dst);
  66 
  67         e->tunnel = &vxlan_tunnel;
  68 
  69         if (!mlx5_vxlan_lookup_port(priv->mdev->vxlan, dst_port)) {
  70                 NL_SET_ERR_MSG_MOD(extack,
  71                                    "vxlan udp dport was not registered with the HW");
  72                 netdev_warn(priv->netdev,
  73                             "%d isn't an offloaded vxlan udp dport\n",
  74                             dst_port);
  75                 return -EOPNOTSUPP;
  76         }
  77 
  78         e->reformat_type = MLX5_REFORMAT_TYPE_L2_TO_VXLAN;
  79         return 0;
  80 }
  81 
  82 static int mlx5e_gen_ip_tunnel_header_vxlan(char buf[],
  83                                             __u8 *ip_proto,
  84                                             struct mlx5e_encap_entry *e)
  85 {
  86         const struct ip_tunnel_key *tun_key = &e->tun_info->key;
  87         __be32 tun_id = tunnel_id_to_key32(tun_key->tun_id);
  88         struct udphdr *udp = (struct udphdr *)(buf);
  89         struct vxlanhdr *vxh;
  90 
  91         vxh = (struct vxlanhdr *)((char *)udp + sizeof(struct udphdr));
  92         *ip_proto = IPPROTO_UDP;
  93 
  94         udp->dest = tun_key->tp_dst;
  95         vxh->vx_flags = VXLAN_HF_VNI;
  96         vxh->vx_vni = vxlan_vni_field(tun_id);
  97 
  98         return 0;
  99 }
 100 
 101 static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
 102                                     struct mlx5_flow_spec *spec,
 103                                     struct flow_cls_offload *f,
 104                                     void *headers_c,
 105                                     void *headers_v)
 106 {
 107         struct flow_rule *rule = flow_cls_offload_flow_rule(f);
 108         struct netlink_ext_ack *extack = f->common.extack;
 109         struct flow_match_enc_keyid enc_keyid;
 110         void *misc_c, *misc_v;
 111 
 112         misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, misc_parameters);
 113         misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value, misc_parameters);
 114 
 115         if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID))
 116                 return 0;
 117 
 118         flow_rule_match_enc_keyid(rule, &enc_keyid);
 119 
 120         if (!enc_keyid.mask->keyid)
 121                 return 0;
 122 
 123         /* match on VNI is required */
 124 
 125         if (!MLX5_CAP_ESW_FLOWTABLE_FDB(priv->mdev,
 126                                         ft_field_support.outer_vxlan_vni)) {
 127                 NL_SET_ERR_MSG_MOD(extack,
 128                                    "Matching on VXLAN VNI is not supported");
 129                 netdev_warn(priv->netdev,
 130                             "Matching on VXLAN VNI is not supported\n");
 131                 return -EOPNOTSUPP;
 132         }
 133 
 134         MLX5_SET(fte_match_set_misc, misc_c, vxlan_vni,
 135                  be32_to_cpu(enc_keyid.mask->keyid));
 136         MLX5_SET(fte_match_set_misc, misc_v, vxlan_vni,
 137                  be32_to_cpu(enc_keyid.key->keyid));
 138 
 139         return 0;
 140 }
 141 
 142 struct mlx5e_tc_tunnel vxlan_tunnel = {
 143         .tunnel_type          = MLX5E_TC_TUNNEL_TYPE_VXLAN,
 144         .match_level          = MLX5_MATCH_L4,
 145         .can_offload          = mlx5e_tc_tun_can_offload_vxlan,
 146         .calc_hlen            = mlx5e_tc_tun_calc_hlen_vxlan,
 147         .init_encap_attr      = mlx5e_tc_tun_init_encap_attr_vxlan,
 148         .generate_ip_tun_hdr  = mlx5e_gen_ip_tunnel_header_vxlan,
 149         .parse_udp_ports      = mlx5e_tc_tun_parse_udp_ports_vxlan,
 150         .parse_tunnel         = mlx5e_tc_tun_parse_vxlan,
 151 };

/* [<][>][^][v][top][bottom][index][help] */