mirror of
https://github.com/apache/nuttx.git
synced 2026-05-22 13:52:22 +08:00
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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user