diff options
author | Sathya Perla <sathya.perla@broadcom.com> | 2017-12-01 03:13:04 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-12-02 21:25:38 -0500 |
commit | e9ecc731a87912d209d6e9b4ed20ed70451c08cb (patch) | |
tree | 2e851ba75f0a91ce7525427a63875e93217be960 | |
parent | c8fb7b8259c67b86cd93a71c85e78b34d2c96fdc (diff) |
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: 8c95f773b4a3 ("bnxt_en: add support for Flower based vxlan encap/decap offload")
Signed-off-by: Sathya Perla <sathya.perla@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index 96bff48af971..3d201d7324bd 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c | |||
@@ -56,7 +56,6 @@ static int bnxt_tc_parse_redir(struct bnxt *bp, | |||
56 | { | 56 | { |
57 | int ifindex = tcf_mirred_ifindex(tc_act); | 57 | int ifindex = tcf_mirred_ifindex(tc_act); |
58 | struct net_device *dev; | 58 | struct net_device *dev; |
59 | u16 dst_fid; | ||
60 | 59 | ||
61 | dev = __dev_get_by_index(dev_net(bp->dev), ifindex); | 60 | dev = __dev_get_by_index(dev_net(bp->dev), ifindex); |
62 | if (!dev) { | 61 | if (!dev) { |
@@ -64,15 +63,7 @@ static int bnxt_tc_parse_redir(struct bnxt *bp, | |||
64 | return -EINVAL; | 63 | return -EINVAL; |
65 | } | 64 | } |
66 | 65 | ||
67 | /* find the FID from dev */ | ||
68 | dst_fid = bnxt_flow_get_dst_fid(bp, dev); | ||
69 | if (dst_fid == BNXT_FID_INVALID) { | ||
70 | netdev_info(bp->dev, "can't get fid for ifindex=%d", ifindex); | ||
71 | return -EINVAL; | ||
72 | } | ||
73 | |||
74 | actions->flags |= BNXT_TC_ACTION_FLAG_FWD; | 66 | actions->flags |= BNXT_TC_ACTION_FLAG_FWD; |
75 | actions->dst_fid = dst_fid; | ||
76 | actions->dst_dev = dev; | 67 | actions->dst_dev = dev; |
77 | return 0; | 68 | return 0; |
78 | } | 69 | } |
@@ -160,13 +151,17 @@ static int bnxt_tc_parse_actions(struct bnxt *bp, | |||
160 | if (rc) | 151 | if (rc) |
161 | return rc; | 152 | return rc; |
162 | 153 | ||
163 | /* Tunnel encap/decap action must be accompanied by a redirect action */ | 154 | if (actions->flags & BNXT_TC_ACTION_FLAG_FWD) { |
164 | if ((actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP || | 155 | if (actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_ENCAP) { |
165 | actions->flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) && | 156 | /* dst_fid is PF's fid */ |
166 | !(actions->flags & BNXT_TC_ACTION_FLAG_FWD)) { | 157 | actions->dst_fid = bp->pf.fw_fid; |
167 | netdev_info(bp->dev, | 158 | } else { |
168 | "error: no redir action along with encap/decap"); | 159 | /* find the FID from dst_dev */ |
169 | return -EINVAL; | 160 | actions->dst_fid = |
161 | bnxt_flow_get_dst_fid(bp, actions->dst_dev); | ||
162 | if (actions->dst_fid == BNXT_FID_INVALID) | ||
163 | return -EINVAL; | ||
164 | } | ||
170 | } | 165 | } |
171 | 166 | ||
172 | return rc; | 167 | return rc; |
@@ -899,10 +894,10 @@ static void bnxt_tc_put_decap_handle(struct bnxt *bp, | |||
899 | 894 | ||
900 | static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, | 895 | static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, |
901 | struct ip_tunnel_key *tun_key, | 896 | struct ip_tunnel_key *tun_key, |
902 | struct bnxt_tc_l2_key *l2_info, | 897 | struct bnxt_tc_l2_key *l2_info) |
903 | struct net_device *real_dst_dev) | ||
904 | { | 898 | { |
905 | #ifdef CONFIG_INET | 899 | #ifdef CONFIG_INET |
900 | struct net_device *real_dst_dev = bp->dev; | ||
906 | struct flowi4 flow = { {0} }; | 901 | struct flowi4 flow = { {0} }; |
907 | struct net_device *dst_dev; | 902 | struct net_device *dst_dev; |
908 | struct neighbour *nbr; | 903 | struct neighbour *nbr; |
@@ -1006,7 +1001,7 @@ static int bnxt_tc_get_decap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, | |||
1006 | */ | 1001 | */ |
1007 | tun_key.u.ipv4.dst = flow->tun_key.u.ipv4.src; | 1002 | tun_key.u.ipv4.dst = flow->tun_key.u.ipv4.src; |
1008 | tun_key.tp_dst = flow->tun_key.tp_dst; | 1003 | tun_key.tp_dst = flow->tun_key.tp_dst; |
1009 | rc = bnxt_tc_resolve_tunnel_hdrs(bp, &tun_key, &l2_info, bp->dev); | 1004 | rc = bnxt_tc_resolve_tunnel_hdrs(bp, &tun_key, &l2_info); |
1010 | if (rc) | 1005 | if (rc) |
1011 | goto put_decap; | 1006 | goto put_decap; |
1012 | 1007 | ||
@@ -1092,8 +1087,7 @@ static int bnxt_tc_get_encap_handle(struct bnxt *bp, struct bnxt_tc_flow *flow, | |||
1092 | if (encap_node->tunnel_handle != INVALID_TUNNEL_HANDLE) | 1087 | if (encap_node->tunnel_handle != INVALID_TUNNEL_HANDLE) |
1093 | goto done; | 1088 | goto done; |
1094 | 1089 | ||
1095 | rc = bnxt_tc_resolve_tunnel_hdrs(bp, encap_key, &encap_node->l2_info, | 1090 | rc = bnxt_tc_resolve_tunnel_hdrs(bp, encap_key, &encap_node->l2_info); |
1096 | flow->actions.dst_dev); | ||
1097 | if (rc) | 1091 | if (rc) |
1098 | goto put_encap; | 1092 | goto put_encap; |
1099 | 1093 | ||
@@ -1166,6 +1160,15 @@ static int __bnxt_tc_del_flow(struct bnxt *bp, | |||
1166 | return 0; | 1160 | return 0; |
1167 | } | 1161 | } |
1168 | 1162 | ||
1163 | static void bnxt_tc_set_src_fid(struct bnxt *bp, struct bnxt_tc_flow *flow, | ||
1164 | u16 src_fid) | ||
1165 | { | ||
1166 | if (flow->actions.flags & BNXT_TC_ACTION_FLAG_TUNNEL_DECAP) | ||
1167 | flow->src_fid = bp->pf.fw_fid; | ||
1168 | else | ||
1169 | flow->src_fid = src_fid; | ||
1170 | } | ||
1171 | |||
1169 | /* Add a new flow or replace an existing flow. | 1172 | /* Add a new flow or replace an existing flow. |
1170 | * Notes on locking: | 1173 | * Notes on locking: |
1171 | * There are essentially two critical sections here. | 1174 | * There are essentially two critical sections here. |
@@ -1201,7 +1204,8 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, | |||
1201 | rc = bnxt_tc_parse_flow(bp, tc_flow_cmd, flow); | 1204 | rc = bnxt_tc_parse_flow(bp, tc_flow_cmd, flow); |
1202 | if (rc) | 1205 | if (rc) |
1203 | goto free_node; | 1206 | goto free_node; |
1204 | flow->src_fid = src_fid; | 1207 | |
1208 | bnxt_tc_set_src_fid(bp, flow, src_fid); | ||
1205 | 1209 | ||
1206 | if (!bnxt_tc_can_offload(bp, flow)) { | 1210 | if (!bnxt_tc_can_offload(bp, flow)) { |
1207 | rc = -ENOSPC; | 1211 | rc = -ENOSPC; |