Commit 100ad4e2 authored by Ariel Levkovich's avatar Ariel Levkovich Committed by Saeed Mahameed

net/mlx5e: Offload internal port as encap route device

When pefroming encap action, a route lookup is performed
to find the routing device the packet should be forwarded
to after the encapsulation. This is the device that has the
local tunnel ip address.

This change adds support to offload an encap rule where the
route device ends up being an ovs internal port.
In such case, the driver will add a HW rule that will encapsulate
the packet with the tunnel header and will overwrite the vport
metadata in reg_c0 to the internal port metadata value.
Finally, the packet will be forwarded to the root table to be
processed again with the indication that it came from an internal
port.
Signed-off-by: default avatarAriel Levkovich <lariel@nvidia.com>
Reviewed-by: default avatarVlad Buslov <vladbu@nvidia.com>
Reviewed-by: default avatarRoi Dayan <roid@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 27484f71
...@@ -83,7 +83,8 @@ static int get_route_and_out_devs(struct mlx5e_priv *priv, ...@@ -83,7 +83,8 @@ static int get_route_and_out_devs(struct mlx5e_priv *priv,
*/ */
*route_dev = dev; *route_dev = dev;
if (!netdev_port_same_parent_id(priv->netdev, real_dev) || if (!netdev_port_same_parent_id(priv->netdev, real_dev) ||
dst_is_lag_dev || is_vlan_dev(*route_dev)) dst_is_lag_dev || is_vlan_dev(*route_dev) ||
netif_is_ovs_master(*route_dev))
*out_dev = uplink_dev; *out_dev = uplink_dev;
else if (mlx5e_eswitch_rep(dev) && else if (mlx5e_eswitch_rep(dev) &&
mlx5e_is_valid_eswitch_fwd_dev(priv, dev)) mlx5e_is_valid_eswitch_fwd_dev(priv, dev))
......
...@@ -13,6 +13,30 @@ enum { ...@@ -13,6 +13,30 @@ enum {
MLX5E_ROUTE_ENTRY_VALID = BIT(0), MLX5E_ROUTE_ENTRY_VALID = BIT(0),
}; };
static int mlx5e_set_int_port_tunnel(struct mlx5e_priv *priv,
struct mlx5_flow_attr *attr,
struct mlx5e_encap_entry *e,
int out_index)
{
struct net_device *route_dev;
int err = 0;
route_dev = dev_get_by_index(dev_net(e->out_dev), e->route_dev_ifindex);
if (!route_dev || !netif_is_ovs_master(route_dev))
goto out;
err = mlx5e_set_fwd_to_int_port_actions(priv, attr, e->route_dev_ifindex,
MLX5E_TC_INT_PORT_EGRESS,
&attr->action, out_index);
out:
if (route_dev)
dev_put(route_dev);
return err;
}
struct mlx5e_route_key { struct mlx5e_route_key {
int ip_version; int ip_version;
union { union {
...@@ -809,6 +833,17 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -809,6 +833,17 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv,
if (err) if (err)
goto out_err; goto out_err;
err = mlx5e_set_int_port_tunnel(priv, attr, e, out_index);
if (err == -EOPNOTSUPP) {
/* If device doesn't support int port offload,
* redirect to uplink vport.
*/
mlx5_core_dbg(priv->mdev, "attaching int port as encap dev not supported, using uplink\n");
err = 0;
} else if (err) {
goto out_err;
}
flow->encaps[out_index].e = e; flow->encaps[out_index].e = e;
list_add(&flow->encaps[out_index].list, &e->flows); list_add(&flow->encaps[out_index].list, &e->flows);
flow->encaps[out_index].index = out_index; flow->encaps[out_index].index = out_index;
......
...@@ -1458,7 +1458,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv, ...@@ -1458,7 +1458,8 @@ mlx5e_tc_add_fdb_flow(struct mlx5e_priv *priv,
goto err_out; goto err_out;
if (esw_attr->dests[out_index].flags & if (esw_attr->dests[out_index].flags &
MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE) MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE &&
!esw_attr->dest_int_port)
vf_tun = true; vf_tun = true;
out_priv = netdev_priv(encap_dev); out_priv = netdev_priv(encap_dev);
rpriv = out_priv->ppriv; rpriv = out_priv->ppriv;
...@@ -1566,7 +1567,8 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, ...@@ -1566,7 +1567,8 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) { for (out_index = 0; out_index < MLX5_MAX_FLOW_FWD_VPORTS; out_index++) {
if (esw_attr->dests[out_index].flags & if (esw_attr->dests[out_index].flags &
MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE) MLX5_ESW_DEST_CHAIN_WITH_SRC_PORT_CHANGE &&
!esw_attr->dest_int_port)
vf_tun = true; vf_tun = true;
if (esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) { if (esw_attr->dests[out_index].flags & MLX5_ESW_DEST_ENCAP) {
mlx5e_detach_encap(priv, flow, out_index); mlx5e_detach_encap(priv, flow, out_index);
......
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