Skip to content

Commit df2ef3b

Browse files
ozshlomoSaeed Mahameed
authored andcommitted
net/mlx5e: Add GRE protocol offloading
Add HW offloading support for TC flower filters configured on gretap/ip6gretap net devices. Signed-off-by: Oz Shlomo <[email protected]> Reviewed-by: Eli Britstein <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 0621e6f commit df2ef3b

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/* Copyright (c) 2018 Mellanox Technologies. */
33

44
#include <net/vxlan.h>
5+
#include <net/gre.h>
56
#include "lib/vxlan.h"
67
#include "en/tc_tun.h"
78

@@ -109,6 +110,30 @@ static int mlx5e_gen_vxlan_header(char buf[], struct ip_tunnel_key *tun_key)
109110
return 0;
110111
}
111112

113+
static int mlx5e_gen_gre_header(char buf[], struct ip_tunnel_key *tun_key)
114+
{
115+
__be32 tun_id = tunnel_id_to_key32(tun_key->tun_id);
116+
int hdr_len;
117+
struct gre_base_hdr *greh = (struct gre_base_hdr *)(buf);
118+
119+
/* the HW does not calculate GRE csum or sequences */
120+
if (tun_key->tun_flags & (TUNNEL_CSUM | TUNNEL_SEQ))
121+
return -EOPNOTSUPP;
122+
123+
greh->protocol = htons(ETH_P_TEB);
124+
125+
/* GRE key */
126+
hdr_len = gre_calc_hlen(tun_key->tun_flags);
127+
greh->flags = gre_tnl_flags_to_gre_flags(tun_key->tun_flags);
128+
if (tun_key->tun_flags & TUNNEL_KEY) {
129+
__be32 *ptr = (__be32 *)(((u8 *)greh) + hdr_len - 4);
130+
131+
*ptr = tun_id;
132+
}
133+
134+
return 0;
135+
}
136+
112137
static int mlx5e_gen_ip_tunnel_header(char buf[], __u8 *ip_proto,
113138
struct mlx5e_encap_entry *e)
114139
{
@@ -118,6 +143,9 @@ static int mlx5e_gen_ip_tunnel_header(char buf[], __u8 *ip_proto,
118143
if (e->tunnel_type == MLX5E_TC_TUNNEL_TYPE_VXLAN) {
119144
*ip_proto = IPPROTO_UDP;
120145
err = mlx5e_gen_vxlan_header(buf, key);
146+
} else if (e->tunnel_type == MLX5E_TC_TUNNEL_TYPE_GRETAP) {
147+
*ip_proto = IPPROTO_GRE;
148+
err = mlx5e_gen_gre_header(buf, key);
121149
} else {
122150
pr_warn("mlx5: Cannot generate tunnel header for tunnel type (%d)\n"
123151
, e->tunnel_type);
@@ -358,6 +386,9 @@ int mlx5e_tc_tun_get_type(struct net_device *tunnel_dev)
358386
{
359387
if (netif_is_vxlan(tunnel_dev))
360388
return MLX5E_TC_TUNNEL_TYPE_VXLAN;
389+
else if (netif_is_gretap(tunnel_dev) ||
390+
netif_is_ip6gretap(tunnel_dev))
391+
return MLX5E_TC_TUNNEL_TYPE_GRETAP;
361392
else
362393
return MLX5E_TC_TUNNEL_TYPE_UNKNOWN;
363394
}
@@ -370,6 +401,9 @@ bool mlx5e_tc_tun_device_to_offload(struct mlx5e_priv *priv,
370401
if (tunnel_type == MLX5E_TC_TUNNEL_TYPE_VXLAN &&
371402
MLX5_CAP_ESW(priv->mdev, vxlan_encap_decap))
372403
return true;
404+
else if (tunnel_type == MLX5E_TC_TUNNEL_TYPE_GRETAP &&
405+
MLX5_CAP_ESW(priv->mdev, nvgre_encap_decap))
406+
return true;
373407
else
374408
return false;
375409
}
@@ -394,6 +428,9 @@ int mlx5e_tc_tun_init_encap_attr(struct net_device *tunnel_dev,
394428
}
395429
e->reformat_type = MLX5_REFORMAT_TYPE_L2_TO_VXLAN;
396430
e->tunnel_hlen = VXLAN_HLEN;
431+
} else if (e->tunnel_type == MLX5E_TC_TUNNEL_TYPE_GRETAP) {
432+
e->reformat_type = MLX5_REFORMAT_TYPE_L2_TO_NVGRE;
433+
e->tunnel_hlen = gre_calc_hlen(e->tun_info.key.tun_flags);
397434
} else {
398435
e->reformat_type = -1;
399436
e->tunnel_hlen = -1;
@@ -472,6 +509,53 @@ static int mlx5e_tc_tun_parse_vxlan(struct mlx5e_priv *priv,
472509
return 0;
473510
}
474511

512+
static int mlx5e_tc_tun_parse_gretap(struct mlx5e_priv *priv,
513+
struct mlx5_flow_spec *spec,
514+
struct tc_cls_flower_offload *f,
515+
void *outer_headers_c,
516+
void *outer_headers_v)
517+
{
518+
void *misc_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
519+
misc_parameters);
520+
void *misc_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
521+
misc_parameters);
522+
523+
if (!MLX5_CAP_ESW(priv->mdev, nvgre_encap_decap)) {
524+
NL_SET_ERR_MSG_MOD(f->common.extack,
525+
"GRE HW offloading is not supported");
526+
netdev_warn(priv->netdev, "GRE HW offloading is not supported\n");
527+
return -EOPNOTSUPP;
528+
}
529+
530+
MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol);
531+
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v,
532+
ip_protocol, IPPROTO_GRE);
533+
534+
/* gre protocol*/
535+
MLX5_SET_TO_ONES(fte_match_set_misc, misc_c, gre_protocol);
536+
MLX5_SET(fte_match_set_misc, misc_v, gre_protocol, ETH_P_TEB);
537+
538+
/* gre key */
539+
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_ENC_KEYID)) {
540+
struct flow_dissector_key_keyid *mask = NULL;
541+
struct flow_dissector_key_keyid *key = NULL;
542+
543+
mask = skb_flow_dissector_target(f->dissector,
544+
FLOW_DISSECTOR_KEY_ENC_KEYID,
545+
f->mask);
546+
MLX5_SET(fte_match_set_misc, misc_c,
547+
gre_key.key, be32_to_cpu(mask->keyid));
548+
549+
key = skb_flow_dissector_target(f->dissector,
550+
FLOW_DISSECTOR_KEY_ENC_KEYID,
551+
f->key);
552+
MLX5_SET(fte_match_set_misc, misc_v,
553+
gre_key.key, be32_to_cpu(key->keyid));
554+
}
555+
556+
return 0;
557+
}
558+
475559
int mlx5e_tc_tun_parse(struct net_device *filter_dev,
476560
struct mlx5e_priv *priv,
477561
struct mlx5_flow_spec *spec,
@@ -486,6 +570,9 @@ int mlx5e_tc_tun_parse(struct net_device *filter_dev,
486570
if (tunnel_type == MLX5E_TC_TUNNEL_TYPE_VXLAN) {
487571
err = mlx5e_tc_tun_parse_vxlan(priv, spec, f,
488572
headers_c, headers_v);
573+
} else if (tunnel_type == MLX5E_TC_TUNNEL_TYPE_GRETAP) {
574+
err = mlx5e_tc_tun_parse_gretap(priv, spec, f,
575+
headers_c, headers_v);
489576
} else {
490577
netdev_warn(priv->netdev,
491578
"decapsulation offload is not supported for %s net device (%d)\n",

drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
enum {
1515
MLX5E_TC_TUNNEL_TYPE_UNKNOWN,
16-
MLX5E_TC_TUNNEL_TYPE_VXLAN
16+
MLX5E_TC_TUNNEL_TYPE_VXLAN,
17+
MLX5E_TC_TUNNEL_TYPE_GRETAP
1718
};
1819

1920
int mlx5e_tc_tun_init_encap_attr(struct net_device *tunnel_dev,

0 commit comments

Comments
 (0)