This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit a22f2a61239a789312b6de4497bb61a23dc46a82
Author: wangjinjing1 <[email protected]>
AuthorDate: Wed Apr 16 20:36:25 2025 +0800

    net/socketcan: move rx filter down to can_input;
    
    rx filter from recvmsg down to can_input, before packet delivery;
    
    Signed-off-by: wangjinjing1 <[email protected]>
---
 net/can/can_conn.c    | 64 +++++++++++++++++++++++++++++++++++++++++++
 net/can/can_input.c   |  7 +++++
 net/can/can_recvmsg.c | 75 ++-------------------------------------------------
 3 files changed, 73 insertions(+), 73 deletions(-)

diff --git a/net/can/can_conn.c b/net/can/can_conn.c
index 36e8b241802..8daa2e2b740 100644
--- a/net/can/can_conn.c
+++ b/net/can/can_conn.c
@@ -167,6 +167,59 @@ void can_free(FAR struct can_conn_s *conn)
   NET_BUFPOOL_UNLOCK(g_can_connections);
 }
 
+/****************************************************************************
+ * Name: can_recv_filter
+ *
+ * Description:
+ *   filter incoming packet
+ *
+ * Input Parameters:
+ *   conn - A pointer to the CAN connection structure
+ *   id   - The CAN identifier
+ *
+ * Returned Value: 0 - Filter not passed, 1 - Filter passed
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+static int can_recv_filter(FAR struct can_conn_s *conn, canid_t id)
+{
+  uint32_t i;
+
+#ifdef CONFIG_NET_CAN_ERRORS
+  /* error message frame */
+
+  if ((id & CAN_ERR_FLAG) != 0)
+    {
+      return id & conn->err_mask ? 1 : 0;
+    }
+#endif
+
+  for (i = 0; i < conn->filter_count; i++)
+    {
+      if (conn->filters[i].can_id & CAN_INV_FILTER)
+        {
+          if ((id & conn->filters[i].can_mask) !=
+                ((conn->filters[i].can_id & ~CAN_INV_FILTER) &
+                 conn->filters[i].can_mask))
+            {
+              return 1;
+            }
+        }
+      else
+        {
+          if ((id & conn->filters[i].can_mask) ==
+                (conn->filters[i].can_id & conn->filters[i].can_mask))
+            {
+              return 1;
+            }
+        }
+    }
+
+  return 0;
+}
+#endif
+
 /****************************************************************************
  * Name: can_nextconn()
  *
@@ -209,11 +262,22 @@ FAR struct can_conn_s *can_nextconn(FAR struct can_conn_s 
*conn)
 FAR struct can_conn_s *can_active(FAR struct net_driver_s *dev,
                                   FAR struct can_conn_s *conn)
 {
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+  canid_t can_id;
+  memcpy(&can_id, NETLLBUF, sizeof(canid_t));
+#endif
+
   while ((conn = can_nextconn(conn)) != NULL)
     {
       if ((conn->dev == NULL && _SS_ISBOUND(conn->sconn.s_flags)) ||
           conn->dev == dev)
         {
+#ifdef CONFIG_NET_CANPROTO_OPTIONS
+          if (can_recv_filter(conn, can_id) == 0)
+            {
+              continue;
+            }
+#endif
           break;
         }
     }
diff --git a/net/can/can_input.c b/net/can/can_input.c
index ea4639aefa2..7a30fc3febd 100644
--- a/net/can/can_input.c
+++ b/net/can/can_input.c
@@ -219,6 +219,13 @@ static int can_in(FAR struct net_driver_s *dev)
   FAR struct can_conn_s *conn = can_active(dev, NULL);
   FAR struct can_conn_s *nextconn;
 
+  if (conn == NULL)
+    {
+      /* There is no listener on the dev.  Just drop the packet. */
+
+      return OK;
+    }
+
   /* Do we have second connection that can hold this packet? */
 
   while ((nextconn = can_active(dev, conn)) != NULL)
diff --git a/net/can/can_recvmsg.c b/net/can/can_recvmsg.c
index 0ef861fd43f..a0965e80f08 100644
--- a/net/can/can_recvmsg.c
+++ b/net/can/can_recvmsg.c
@@ -75,10 +75,6 @@ struct can_recvfrom_s
  * Private Functions
  ****************************************************************************/
 
-#ifdef CONFIG_NET_CANPROTO_OPTIONS
-static int can_recv_filter(FAR struct can_conn_s *conn, canid_t id);
-#endif
-
 /****************************************************************************
  * Name: can_add_recvlen
  *
@@ -248,21 +244,6 @@ static inline int can_readahead(struct can_recvfrom_s 
*pstate)
     {
       DEBUGASSERT(iob->io_pktlen > 0);
 
-#ifdef CONFIG_NET_CANPROTO_OPTIONS
-      /* Check receive filters */
-
-      canid_t can_id;
-      iob_copyout((uint8_t *)&can_id, iob, sizeof(canid_t), 0);
-
-      if (can_recv_filter(conn, can_id) == 0)
-        {
-          /* Free the I/O buffer chain */
-
-          iob_free_chain(iob);
-          return 0;
-        }
-#endif
-
 #ifdef CONFIG_NET_TIMESTAMP
       if (_SO_GETOPT(conn->sconn.s_options, SO_TIMESTAMP) &&
           pstate->pr_msglen == sizeof(struct timeval))
@@ -306,45 +287,6 @@ static inline int can_readahead(struct can_recvfrom_s 
*pstate)
   return 0;
 }
 
-#ifdef CONFIG_NET_CANPROTO_OPTIONS
-static int can_recv_filter(FAR struct can_conn_s *conn, canid_t id)
-{
-  uint32_t i;
-
-#ifdef CONFIG_NET_CAN_ERRORS
-  /* error message frame */
-
-  if ((id & CAN_ERR_FLAG) != 0)
-    {
-      return id & conn->err_mask ? 1 : 0;
-    }
-#endif
-
-  for (i = 0; i < conn->filter_count; i++)
-    {
-      if (conn->filters[i].can_id & CAN_INV_FILTER)
-        {
-          if ((id & conn->filters[i].can_mask) !=
-                ((conn->filters[i].can_id & ~CAN_INV_FILTER) &
-                 conn->filters[i].can_mask))
-            {
-              return 1;
-            }
-        }
-      else
-        {
-          if ((id & conn->filters[i].can_mask) ==
-                (conn->filters[i].can_id & conn->filters[i].can_mask))
-            {
-              return 1;
-            }
-        }
-    }
-
-  return 0;
-}
-#endif
-
 static uint16_t can_recvfrom_eventhandler(FAR struct net_driver_s *dev,
                                           FAR void *pvpriv, uint16_t flags)
 {
@@ -354,26 +296,13 @@ static uint16_t can_recvfrom_eventhandler(FAR struct 
net_driver_s *dev,
 
   if (pstate)
     {
-#if defined(CONFIG_NET_CANPROTO_OPTIONS) || defined(CONFIG_NET_TIMESTAMP)
+#if (defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)) \
+     || defined(CONFIG_NET_TIMESTAMP)
       struct can_conn_s *conn = pstate->pr_conn;
 #endif
 
       if ((flags & CAN_NEWDATA) != 0)
         {
-          /* If a new packet is available, check receive filters
-           * when is valid then complete the read action.
-           */
-#ifdef CONFIG_NET_CANPROTO_OPTIONS
-          canid_t can_id;
-          memcpy(&can_id, dev->d_appdata, sizeof(canid_t));
-
-          if (can_recv_filter(conn, can_id) == 0)
-            {
-              flags &= ~CAN_NEWDATA;
-              return flags;
-            }
-#endif
-
           /* do not pass frames with DLC > 8 to a legacy socket */
 #if defined(CONFIG_NET_CANPROTO_OPTIONS) && defined(CONFIG_NET_CAN_CANFD)
           if (!_SO_GETOPT(conn->sconn.s_options, CAN_RAW_FD_FRAMES))

Reply via email to