diff mbox series

[net-next] net: ncsi: check for netlink-driven responses before requiring a handler

Message ID 20241028-ncsi-arb-opcode-v1-1-9d65080908b9@codeconstruct.com.au (mailing list archive)
State New
Delegated to: Netdev Maintainers
Headers show
Series [net-next] net: ncsi: check for netlink-driven responses before requiring a handler | expand

Commit Message

Jeremy Kerr Oct. 28, 2024, 7:08 a.m. UTC
Currently, the NCSI response path will look up an opcode-specific
handler for all incoming response messages. However, we may be receiving
a response from a netlink-generated request, which may not have a
corresponding in-kernel handler for that request opcode. In that case,
we'll drop the response because we didn't find a opcode-specific
handler.

Perform the lookup for the pending request (and hence for
NETLINK_DRIVEN) before requiring an in-kernel handler, and defer the
requirement for a corresponding kernel request until we know it's a
kernel-driven command.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
 net/ncsi/ncsi-rsp.c | 61 ++++++++++++++++++++++++-----------------------------
 1 file changed, 27 insertions(+), 34 deletions(-)


---
base-commit: 03fc07a24735e0be8646563913abf5f5cb71ad19
change-id: 20241028-ncsi-arb-opcode-a346ddb88862

Best regards,
diff mbox series

Patch

diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index e28be33bdf2c487c0fbfe3a1b4de6f52c8f923cc..882767c138895eba5bd7e413b7edb6480d5807bf 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -1205,12 +1205,6 @@  int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
 		}
 	}
 
-	if (!nrh) {
-		netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
-			   hdr->type);
-		return -ENOENT;
-	}
-
 	/* Associate with the request */
 	spin_lock_irqsave(&ndp->lock, flags);
 	nr = &ndp->requests[hdr->id];
@@ -1228,43 +1222,42 @@  int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
 
 	/* Validate the packet */
 	spin_unlock_irqrestore(&ndp->lock, flags);
-	payload = nrh->payload;
+	payload = nrh ? nrh->payload : -1;
 	if (payload < 0)
 		payload = ntohs(hdr->length);
+
 	ret = ncsi_validate_rsp_pkt(nr, payload);
-	if (ret) {
+	if (ret)
 		netdev_warn(ndp->ndev.dev,
 			    "NCSI: 'bad' packet ignored for type 0x%x\n",
 			    hdr->type);
 
-		if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
-			if (ret == -EPERM)
-				goto out_netlink;
-			else
-				ncsi_send_netlink_err(ndp->ndev.dev,
-						      nr->snd_seq,
-						      nr->snd_portid,
-						      &nr->nlhdr,
-						      ret);
-		}
-		goto out;
-	}
-
-	/* Process the packet */
-	ret = nrh->handler(nr);
-	if (ret)
-		netdev_err(ndp->ndev.dev,
-			   "NCSI: Handler for packet type 0x%x returned %d\n",
-			   hdr->type, ret);
-
-out_netlink:
 	if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
-		ret = ncsi_rsp_handler_netlink(nr);
-		if (ret) {
-			netdev_err(ndp->ndev.dev,
-				   "NCSI: Netlink handler for packet type 0x%x returned %d\n",
-				   hdr->type, ret);
+		/* netlink driven: forward response to netlink socket */
+		if (!ret || ret == -EPERM)
+			ncsi_rsp_handler_netlink(nr);
+		else
+			ncsi_send_netlink_err(ndp->ndev.dev,
+					      nr->snd_seq,
+					      nr->snd_portid,
+					      &nr->nlhdr,
+					      ret);
+	} else if (nrh) {
+		/* not netlink driven: process the packet in the kernel. We
+		 * need to have a handler for this
+		 */
+		if (!ret) {
+			ret = nrh->handler(nr);
+			if (ret)
+				netdev_err(ndp->ndev.dev,
+					   "NCSI: Handler for packet type 0x%x returned %d\n",
+					   hdr->type, ret);
 		}
+
+	} else {
+		netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
+			   hdr->type);
+		ret = -ENOENT;
 	}
 
 out: