Commit e9ecc731 authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

bnxt_en: fix dst/src fid for vxlan encap/decap actions

For flows that involve a vxlan encap action, the vxlan sock
interface may be specified as the outgoing interface. The driver
must resolve the outgoing PF interface used by this socket and
use the dst_fid of the PF in the hwrm_cfa_encap_record_alloc cmd.

Similarily for flows that have a vxlan decap action, the
fid of the incoming PF interface must be used as the src_fid in
the hwrm_cfa_decap_filter_alloc cmd.

Fixes: 8c95f773 ("bnxt_en: add support for Flower based vxlan encap/decap offload")
Signed-off-by: default avatarSathya Perla <sathya.perla@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c8fb7b82
...@@ -56,7 +56,6 @@ static int bnxt_tc_parse_redir(struct bnxt *bp, ...@@ -56,7 +56,6 @@ static int bnxt_tc_parse_redir(struct bnxt *bp,
{ {
int ifindex = tcf_mirred_ifindex(tc_act); int ifindex = tcf_mirred_ifindex(tc_act);
struct net_device *dev; struct net_device *dev;
u16 dst_fid;
dev = __dev_get_by_index(dev_net(bp->dev), ifindex); dev = __dev_get_by_index(dev_net(bp->dev), ifindex);
if (!dev) { if (!dev) {
...@@ -64,15 +63,7 @@ static int bnxt_tc_parse_redir(struct bnxt *bp, ...@@ -64,15 +63,7 @@ static int bnxt_tc_parse_redir(struct bnxt *bp,
return -EINVAL; return -EINVAL;
} }
/* find the FID from dev */
dst_fid = bnxt_flow_get_dst_fid(bp, dev);
if (dst_fid == BNXT_FID_INVALID) {
netdev_info(bp->dev, "can't get fid for ifindex=%d", ifindex);
return -EINVAL;
}
actions->flags |= BNXT_TC_ACTION_FLAG_FWD; actions->flags |= BNXT_TC_ACTION_FLAG_FWD;
actions->dst_fid = dst_fid;
actions->dst_dev = dev; actions->dst_dev = dev;
return 0; return 0;
} }
...@@ -160,14 +151,18 @@ static int bnxt_tc_parse_actions(struct bnxt *bp, ...@@ -160,14 +151,18 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
if (rc) if (rc)
return rc; return rc;
/* Tunnel encap/decap action must be accompanied by a redirect action */ if (actions->flags & BNXT_TC_ACTION_FLAG_FWD) {
if ((actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP || if (actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) {
actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) && /* dst_fid is PF's fid */
!(actions->flags & BNXT_TC_ACTION_FLAG_FWD)) { actions->dst_fid = bp->pf.fw_fid;
netdev_info(bp->dev, } else {
"error: no redir action along with encap/decap"); /* find the FID from dst_dev */
actions->dst_fid =
bnxt_flow_get_dst_fid(bp, actions->dst_dev);
if (actions->dst_fid == BNXT_FID_INVALID)
return -EINVAL; return -EINVAL;
} }
}
return rc; return rc;
} }
...@@ -899,10 +894,10 @@ static void bnxt_tc_put_decap_handle(struct bnxt *bp, ...@@ -899,10 +894,10 @@ static void bnxt_tc_put_decap_handle(struct bnxt *bp,
static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp,
struct ip_tunnel_key *tun_key, struct ip_tunnel_key *tun_key,
struct bnxt_tc_l2_key *l2_info, struct bnxt_tc_l2_key *l2_info)
struct net_device *real_dst_dev)
{ {
#ifdef CONFIG_INET #ifdef CONFIG_INET
struct net_device *real_dst_dev = bp->dev;
struct flowi4 flow = { {0} }; struct flowi4 flow = { {0} };
struct net_device *dst_dev; struct net_device *dst_dev;
struct neighbour *nbr; struct neighbour *nbr;
...@@ -1006,7 +1001,7 @@ static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, ...@@ -1006,7 +1001,7 @@ static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow,
*/ */
tun_key.u.ipv4.dst = flow->tun_key.u.ipv4.src; tun_key.u.ipv4.dst = flow->tun_key.u.ipv4.src;
tun_key.tp_dst = flow->tun_key.tp_dst; tun_key.tp_dst = flow->tun_key.tp_dst;
rc = bnxt_tc_resolve_tunnel_hdrs(bp, &tun_key, &l2_info, bp->dev); rc = bnxt_tc_resolve_tunnel_hdrs(bp, &tun_key, &l2_info);
if (rc) if (rc)
goto put_decap; goto put_decap;
...@@ -1092,8 +1087,7 @@ static int bnxt_tc_get_encap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, ...@@ -1092,8 +1087,7 @@ static int bnxt_tc_get_encap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow,
if (encap_node->tunnel_handle != INVALID_TUNNEL_HANDLE) if (encap_node->tunnel_handle != INVALID_TUNNEL_HANDLE)
goto done; goto done;
rc = bnxt_tc_resolve_tunnel_hdrs(bp, encap_key, &encap_node->l2_info, rc = bnxt_tc_resolve_tunnel_hdrs(bp, encap_key, &encap_node->l2_info);
flow->actions.dst_dev);
if (rc) if (rc)
goto put_encap; goto put_encap;
...@@ -1166,6 +1160,15 @@ static int __bnxt_tc_del_flow(struct bnxt *bp, ...@@ -1166,6 +1160,15 @@ static int __bnxt_tc_del_flow(struct bnxt *bp,
return 0; return 0;
} }
static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow,
u16 src_fid)
{
if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP)
flow->src_fid = bp->pf.fw_fid;
else
flow->src_fid = src_fid;
}
/* Add a new flow or replace an existing flow. /* Add a new flow or replace an existing flow.
* Notes on locking: * Notes on locking:
* There are essentially two critical sections here. * There are essentially two critical sections here.
...@@ -1201,7 +1204,8 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, ...@@ -1201,7 +1204,8 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid,
rc = bnxt_tc_parse_flow(bp, tc_flow_cmd, flow); rc = bnxt_tc_parse_flow(bp, tc_flow_cmd, flow);
if (rc) if (rc)
goto free_node; goto free_node;
flow->src_fid = src_fid;
bnxt_tc_set_src_fid(bp, flow, src_fid);
if (!bnxt_tc_can_offload(bp, flow)) { if (!bnxt_tc_can_offload(bp, flow)) {
rc = -ENOSPC; rc = -ENOSPC;
......
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