net/socketcan: move rx filter down to can_input;

rx filter from recvmsg down to can_input, before packet delivery;

Signed-off-by: wangjinjing1 <wangjinjing1@xiaomi.com>
This commit is contained in:
wangjinjing1
2025-04-16 20:36:25 +08:00
committed by Xiang Xiao
parent 1d91a15820
commit a22f2a6123
3 changed files with 73 additions and 73 deletions
+64
View File
@@ -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;
}
}
+7
View File
@@ -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)
+2 -73
View File
@@ -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))