aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSathya Perla <sathya.perla@broadcom.com>2017-12-01 03:13:04 -0500
committerDavid S. Miller <davem@davemloft.net>2017-12-02 21:25:38 -0500
commite9ecc731a87912d209d6e9b4ed20ed70451c08cb (patch)
tree2e851ba75f0a91ce7525427a63875e93217be960
parentc8fb7b8259c67b86cd93a71c85e78b34d2c96fdc (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.c48
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
900static int bnxt_tc_resolve_tunnel_hdrs(struct bnxt *bp, 895static 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
1163static 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;