Commit c63741b4 authored by Maor Dickman's avatar Maor Dickman Committed by Saeed Mahameed

net/mlx5e: Fix MPLSoUDP encap to use MPLS action information

Currently the MPLSoUDP encap builds the MPLS header using encap action
information (tunnel id, ttl and tos) instead of the MPLS action
information (label, ttl, tc and bos) which is wrong.

Fix by storing the MPLS action information during the flow action
parse and later using it to create the encap MPLS header.

Fixes: f828ca6a ("net/mlx5e: Add support for hw encapsulation of MPLS over UDP")
Signed-off-by: default avatarMaor Dickman <maord@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 7fac0529
...@@ -22,6 +22,7 @@ struct mlx5e_tc_act_parse_state { ...@@ -22,6 +22,7 @@ struct mlx5e_tc_act_parse_state {
bool mpls_push; bool mpls_push;
bool ptype_host; bool ptype_host;
const struct ip_tunnel_info *tun_info; const struct ip_tunnel_info *tun_info;
struct mlx5e_mpls_info mpls_info;
struct pedit_headers_action hdrs[__PEDIT_CMD_MAX]; struct pedit_headers_action hdrs[__PEDIT_CMD_MAX];
int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS]; int ifindexes[MLX5_MAX_FLOW_FWD_VPORTS];
int if_count; int if_count;
......
...@@ -177,6 +177,12 @@ parse_mirred_encap(struct mlx5e_tc_act_parse_state *parse_state, ...@@ -177,6 +177,12 @@ parse_mirred_encap(struct mlx5e_tc_act_parse_state *parse_state,
return -ENOMEM; return -ENOMEM;
parse_state->encap = false; parse_state->encap = false;
if (parse_state->mpls_push) {
memcpy(&parse_attr->mpls_info[esw_attr->out_count],
&parse_state->mpls_info, sizeof(parse_state->mpls_info));
parse_state->mpls_push = false;
}
esw_attr->dests[esw_attr->out_count].flags |= MLX5_ESW_DEST_ENCAP; esw_attr->dests[esw_attr->out_count].flags |= MLX5_ESW_DEST_ENCAP;
esw_attr->out_count++; esw_attr->out_count++;
/* attr->dests[].rep is resolved when we handle encap */ /* attr->dests[].rep is resolved when we handle encap */
......
...@@ -22,6 +22,16 @@ tc_act_can_offload_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, ...@@ -22,6 +22,16 @@ tc_act_can_offload_mpls_push(struct mlx5e_tc_act_parse_state *parse_state,
return true; return true;
} }
static void
copy_mpls_info(struct mlx5e_mpls_info *mpls_info,
const struct flow_action_entry *act)
{
mpls_info->label = act->mpls_push.label;
mpls_info->tc = act->mpls_push.tc;
mpls_info->bos = act->mpls_push.bos;
mpls_info->ttl = act->mpls_push.ttl;
}
static int static int
tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state,
const struct flow_action_entry *act, const struct flow_action_entry *act,
...@@ -29,6 +39,7 @@ tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state, ...@@ -29,6 +39,7 @@ tc_act_parse_mpls_push(struct mlx5e_tc_act_parse_state *parse_state,
struct mlx5_flow_attr *attr) struct mlx5_flow_attr *attr)
{ {
parse_state->mpls_push = true; parse_state->mpls_push = true;
copy_mpls_info(&parse_state->mpls_info, act);
return 0; return 0;
} }
......
...@@ -35,6 +35,7 @@ enum { ...@@ -35,6 +35,7 @@ enum {
struct mlx5e_tc_flow_parse_attr { struct mlx5e_tc_flow_parse_attr {
const struct ip_tunnel_info *tun_info[MLX5_MAX_FLOW_FWD_VPORTS]; const struct ip_tunnel_info *tun_info[MLX5_MAX_FLOW_FWD_VPORTS];
struct mlx5e_mpls_info mpls_info[MLX5_MAX_FLOW_FWD_VPORTS];
struct net_device *filter_dev; struct net_device *filter_dev;
struct mlx5_flow_spec spec; struct mlx5_flow_spec spec;
struct mlx5e_tc_mod_hdr_acts mod_hdr_acts; struct mlx5e_tc_mod_hdr_acts mod_hdr_acts;
......
...@@ -750,6 +750,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -750,6 +750,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
struct mlx5e_tc_flow_parse_attr *parse_attr; struct mlx5e_tc_flow_parse_attr *parse_attr;
struct mlx5_flow_attr *attr = flow->attr; struct mlx5_flow_attr *attr = flow->attr;
const struct ip_tunnel_info *tun_info; const struct ip_tunnel_info *tun_info;
const struct mlx5e_mpls_info *mpls_info;
unsigned long tbl_time_before = 0; unsigned long tbl_time_before = 0;
struct mlx5e_encap_entry *e; struct mlx5e_encap_entry *e;
struct mlx5e_encap_key key; struct mlx5e_encap_key key;
...@@ -760,6 +761,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -760,6 +761,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
parse_attr = attr->parse_attr; parse_attr = attr->parse_attr;
tun_info = parse_attr->tun_info[out_index]; tun_info = parse_attr->tun_info[out_index];
mpls_info = &parse_attr->mpls_info[out_index];
family = ip_tunnel_info_af(tun_info); family = ip_tunnel_info_af(tun_info);
key.ip_tun_key = &tun_info->key; key.ip_tun_key = &tun_info->key;
key.tc_tunnel = mlx5e_get_tc_tun(mirred_dev); key.tc_tunnel = mlx5e_get_tc_tun(mirred_dev);
...@@ -810,6 +812,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -810,6 +812,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
goto out_err_init; goto out_err_init;
} }
e->tun_info = tun_info; e->tun_info = tun_info;
memcpy(&e->mpls_info, mpls_info, sizeof(*mpls_info));
err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack); err = mlx5e_tc_tun_init_encap_attr(mirred_dev, priv, e, extack);
if (err) if (err)
goto out_err_init; goto out_err_init;
......
...@@ -30,16 +30,15 @@ static int generate_ip_tun_hdr(char buf[], ...@@ -30,16 +30,15 @@ static int generate_ip_tun_hdr(char buf[],
struct mlx5e_encap_entry *r) struct mlx5e_encap_entry *r)
{ {
const struct ip_tunnel_key *tun_key = &r->tun_info->key; const struct ip_tunnel_key *tun_key = &r->tun_info->key;
const struct mlx5e_mpls_info *mpls_info = &r->mpls_info;
struct udphdr *udp = (struct udphdr *)(buf); struct udphdr *udp = (struct udphdr *)(buf);
struct mpls_shim_hdr *mpls; struct mpls_shim_hdr *mpls;
u32 tun_id;
tun_id = be32_to_cpu(tunnel_id_to_key32(tun_key->tun_id));
mpls = (struct mpls_shim_hdr *)(udp + 1); mpls = (struct mpls_shim_hdr *)(udp + 1);
*ip_proto = IPPROTO_UDP; *ip_proto = IPPROTO_UDP;
udp->dest = tun_key->tp_dst; udp->dest = tun_key->tp_dst;
*mpls = mpls_entry_encode(tun_id, tun_key->ttl, tun_key->tos, true); *mpls = mpls_entry_encode(mpls_info->label, mpls_info->ttl, mpls_info->tc, mpls_info->bos);
return 0; return 0;
} }
......
...@@ -183,6 +183,13 @@ struct mlx5e_decap_entry { ...@@ -183,6 +183,13 @@ struct mlx5e_decap_entry {
struct rcu_head rcu; struct rcu_head rcu;
}; };
struct mlx5e_mpls_info {
u32 label;
u8 tc;
u8 bos;
u8 ttl;
};
struct mlx5e_encap_entry { struct mlx5e_encap_entry {
/* attached neigh hash entry */ /* attached neigh hash entry */
struct mlx5e_neigh_hash_entry *nhe; struct mlx5e_neigh_hash_entry *nhe;
...@@ -196,6 +203,7 @@ struct mlx5e_encap_entry { ...@@ -196,6 +203,7 @@ struct mlx5e_encap_entry {
struct list_head route_list; struct list_head route_list;
struct mlx5_pkt_reformat *pkt_reformat; struct mlx5_pkt_reformat *pkt_reformat;
const struct ip_tunnel_info *tun_info; const struct ip_tunnel_info *tun_info;
struct mlx5e_mpls_info mpls_info;
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
struct net_device *out_dev; struct net_device *out_dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment