hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/infiniband/sw/rxe/rxe_recv.c
....@@ -1,34 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
12 /*
23 * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved.
34 * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved.
4
- *
5
- * This software is available to you under a choice of one of two
6
- * licenses. You may choose to be licensed under the terms of the GNU
7
- * General Public License (GPL) Version 2, available from the file
8
- * COPYING in the main directory of this source tree, or the
9
- * OpenIB.org BSD license below:
10
- *
11
- * Redistribution and use in source and binary forms, with or
12
- * without modification, are permitted provided that the following
13
- * conditions are met:
14
- *
15
- * - Redistributions of source code must retain the above
16
- * copyright notice, this list of conditions and the following
17
- * disclaimer.
18
- *
19
- * - Redistributions in binary form must reproduce the above
20
- * copyright notice, this list of conditions and the following
21
- * disclaimer in the documentation and/or other materials
22
- * provided with the distribution.
23
- *
24
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
- * SOFTWARE.
325 */
336
347 #include <linux/skbuff.h>
....@@ -106,40 +79,19 @@
10679 static int check_keys(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
10780 u32 qpn, struct rxe_qp *qp)
10881 {
109
- int i;
110
- int found_pkey = 0;
11182 struct rxe_port *port = &rxe->port;
11283 u16 pkey = bth_pkey(pkt);
11384
11485 pkt->pkey_index = 0;
11586
116
- if (qpn == 1) {
117
- for (i = 0; i < port->attr.pkey_tbl_len; i++) {
118
- if (pkey_match(pkey, port->pkey_tbl[i])) {
119
- pkt->pkey_index = i;
120
- found_pkey = 1;
121
- break;
122
- }
123
- }
124
-
125
- if (!found_pkey) {
126
- pr_warn_ratelimited("bad pkey = 0x%x\n", pkey);
127
- set_bad_pkey_cntr(port);
128
- goto err1;
129
- }
130
- } else if (qpn != 0) {
131
- if (unlikely(!pkey_match(pkey,
132
- port->pkey_tbl[qp->attr.pkey_index]
133
- ))) {
134
- pr_warn_ratelimited("bad pkey = 0x%0x\n", pkey);
135
- set_bad_pkey_cntr(port);
136
- goto err1;
137
- }
138
- pkt->pkey_index = qp->attr.pkey_index;
87
+ if (!pkey_match(pkey, IB_DEFAULT_PKEY_FULL)) {
88
+ pr_warn_ratelimited("bad pkey = 0x%x\n", pkey);
89
+ set_bad_pkey_cntr(port);
90
+ goto err1;
13991 }
14092
14193 if ((qp_type(qp) == IB_QPT_UD || qp_type(qp) == IB_QPT_GSI) &&
142
- qpn != 0 && pkt->mask) {
94
+ pkt->mask) {
14395 u32 qkey = (qpn == 1) ? GSI_QKEY : qp->attr.qkey;
14496
14597 if (unlikely(deth_qkey(pkt) != qkey)) {
....@@ -271,14 +223,12 @@
271223 return -EINVAL;
272224 }
273225
274
-static inline void rxe_rcv_pkt(struct rxe_dev *rxe,
275
- struct rxe_pkt_info *pkt,
276
- struct sk_buff *skb)
226
+static inline void rxe_rcv_pkt(struct rxe_pkt_info *pkt, struct sk_buff *skb)
277227 {
278228 if (pkt->mask & RXE_REQ_MASK)
279
- rxe_resp_queue_pkt(rxe, pkt->qp, skb);
229
+ rxe_resp_queue_pkt(pkt->qp, skb);
280230 else
281
- rxe_comp_queue_pkt(rxe, pkt->qp, skb);
231
+ rxe_comp_queue_pkt(pkt->qp, skb);
282232 }
283233
284234 static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
....@@ -288,6 +238,8 @@
288238 struct rxe_mc_elem *mce;
289239 struct rxe_qp *qp;
290240 union ib_gid dgid;
241
+ struct sk_buff *per_qp_skb;
242
+ struct rxe_pkt_info *per_qp_pkt;
291243 int err;
292244
293245 if (skb->protocol == htons(ETH_P_IP))
....@@ -305,7 +257,6 @@
305257
306258 list_for_each_entry(mce, &mcg->qp_list, qp_list) {
307259 qp = mce->qp;
308
- pkt = SKB_TO_PKT(skb);
309260
310261 /* validate qp for incoming packet */
311262 err = check_type_state(rxe, pkt, qp);
....@@ -316,15 +267,27 @@
316267 if (err)
317268 continue;
318269
319
- /* if *not* the last qp in the list
320
- * increase the users of the skb then post to the next qp
270
+ /* for all but the last qp create a new clone of the
271
+ * skb and pass to the qp. If an error occurs in the
272
+ * checks for the last qp in the list we need to
273
+ * free the skb since it hasn't been passed on to
274
+ * rxe_rcv_pkt() which would free it later.
321275 */
322
- if (mce->qp_list.next != &mcg->qp_list)
323
- skb_get(skb);
276
+ if (mce->qp_list.next != &mcg->qp_list) {
277
+ per_qp_skb = skb_clone(skb, GFP_ATOMIC);
278
+ } else {
279
+ per_qp_skb = skb;
280
+ /* show we have consumed the skb */
281
+ skb = NULL;
282
+ }
324283
325
- pkt->qp = qp;
284
+ if (unlikely(!per_qp_skb))
285
+ continue;
286
+
287
+ per_qp_pkt = SKB_TO_PKT(per_qp_skb);
288
+ per_qp_pkt->qp = qp;
326289 rxe_add_ref(qp);
327
- rxe_rcv_pkt(rxe, pkt, skb);
290
+ rxe_rcv_pkt(per_qp_pkt, per_qp_skb);
328291 }
329292
330293 spin_unlock_bh(&mcg->mcg_lock);
....@@ -332,10 +295,21 @@
332295 rxe_drop_ref(mcg); /* drop ref from rxe_pool_get_key. */
333296
334297 err1:
298
+ /* free skb if not consumed */
335299 kfree_skb(skb);
336300 }
337301
338
-static int rxe_match_dgid(struct rxe_dev *rxe, struct sk_buff *skb)
302
+/**
303
+ * rxe_chk_dgid - validate destination IP address
304
+ * @rxe: rxe device that received packet
305
+ * @skb: the received packet buffer
306
+ *
307
+ * Accept any loopback packets
308
+ * Extract IP address from packet and
309
+ * Accept if multicast packet
310
+ * Accept if matches an SGID table entry
311
+ */
312
+static int rxe_chk_dgid(struct rxe_dev *rxe, struct sk_buff *skb)
339313 {
340314 struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);
341315 const struct ib_gid_attr *gid_attr;
....@@ -352,6 +326,9 @@
352326 } else {
353327 pdgid = (union ib_gid *)&ipv6_hdr(skb)->daddr;
354328 }
329
+
330
+ if (rdma_is_multicast_addr((struct in6_addr *)pdgid))
331
+ return 0;
355332
356333 gid_attr = rdma_find_gid_by_port(&rxe->ib_dev, pdgid,
357334 IB_GID_TYPE_ROCE_UDP_ENCAP,
....@@ -377,8 +354,8 @@
377354 if (unlikely(skb->len < pkt->offset + RXE_BTH_BYTES))
378355 goto drop;
379356
380
- if (rxe_match_dgid(rxe, skb) < 0) {
381
- pr_warn_ratelimited("failed matching dgid\n");
357
+ if (rxe_chk_dgid(rxe, skb) < 0) {
358
+ pr_warn_ratelimited("failed checking dgid\n");
382359 goto drop;
383360 }
384361
....@@ -420,7 +397,7 @@
420397 if (unlikely(bth_qpn(pkt) == IB_MULTICAST_QPN))
421398 rxe_rcv_mcast_pkt(rxe, skb);
422399 else
423
- rxe_rcv_pkt(rxe, pkt, skb);
400
+ rxe_rcv_pkt(pkt, skb);
424401
425402 return;
426403