2019-07-23 15:17:55 +02:00
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
2019-07-24 14:16:29 +02:00
/* af_can.c - Protocol family CAN core module
2007-11-16 15:52:17 -08:00
* ( used by different CAN protocol modules )
*
2017-04-25 08:19:41 +02:00
* Copyright ( c ) 2002 - 2017 Volkswagen Group Electronic Research
2007-11-16 15:52:17 -08:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. Neither the name of Volkswagen nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* Alternatively , provided that this notice is retained in full , this
* software may be distributed under the terms of the GNU General
* Public License ( " GPL " ) version 2 , in which case the provisions of the
* GPL apply INSTEAD OF those given above .
*
* The provided data structures and external interfaces from this code
* are not restricted to be used by modules with a GPL compatible license .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT
* LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL ,
* SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT
* LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE .
*
*/
# include <linux/module.h>
2012-06-13 20:04:33 +02:00
# include <linux/stddef.h>
2007-11-16 15:52:17 -08:00
# include <linux/init.h>
# include <linux/kmod.h>
# include <linux/slab.h>
# include <linux/list.h>
# include <linux/spinlock.h>
# include <linux/rcupdate.h>
# include <linux/uaccess.h>
# include <linux/net.h>
# include <linux/netdevice.h>
# include <linux/socket.h>
# include <linux/if_ether.h>
# include <linux/if_arp.h>
# include <linux/skbuff.h>
# include <linux/can.h>
# include <linux/can/core.h>
2014-01-30 10:11:28 +01:00
# include <linux/can/skb.h>
2018-10-08 09:02:38 +02:00
# include <linux/can/can-ml.h>
2011-06-16 02:08:01 +00:00
# include <linux/ratelimit.h>
2007-11-16 15:52:17 -08:00
# include <net/net_namespace.h>
# include <net/sock.h>
# include "af_can.h"
MODULE_DESCRIPTION ( " Controller Area Network PF_CAN core " ) ;
MODULE_LICENSE ( " Dual BSD/GPL " ) ;
MODULE_AUTHOR ( " Urs Thuermann <urs.thuermann@volkswagen.de>, "
" Oliver Hartkopp <oliver.hartkopp@volkswagen.de> " ) ;
MODULE_ALIAS_NETPROTO ( PF_CAN ) ;
static int stats_timer __read_mostly = 1 ;
2018-03-23 15:54:38 -07:00
module_param ( stats_timer , int , 0444 ) ;
2007-11-16 15:52:17 -08:00
MODULE_PARM_DESC ( stats_timer , " enable timer for statistics (default:on) " ) ;
static struct kmem_cache * rcv_cache __read_mostly ;
/* table of registered CAN protocols */
2017-10-17 07:18:35 +02:00
static const struct can_proto __rcu * proto_tab [ CAN_NPROTO ] __read_mostly ;
2011-04-05 08:01:16 +00:00
static DEFINE_MUTEX ( proto_tab_lock ) ;
2007-11-16 15:52:17 -08:00
2015-06-26 11:58:19 +02:00
static atomic_t skbcounter = ATOMIC_INIT ( 0 ) ;
2019-07-24 14:16:29 +02:00
/* af_can socket functions */
2007-11-16 15:52:17 -08:00
2019-11-07 11:55:42 +01:00
void can_sock_destruct ( struct sock * sk )
2007-11-16 15:52:17 -08:00
{
skb_queue_purge ( & sk - > sk_receive_queue ) ;
2019-06-07 16:46:07 -04:00
skb_queue_purge ( & sk - > sk_error_queue ) ;
2007-11-16 15:52:17 -08:00
}
2019-11-07 11:55:42 +01:00
EXPORT_SYMBOL ( can_sock_destruct ) ;
2007-11-16 15:52:17 -08:00
2011-05-03 18:42:04 +00:00
static const struct can_proto * can_get_proto ( int protocol )
2011-04-05 08:01:16 +00:00
{
2011-05-03 18:40:57 +00:00
const struct can_proto * cp ;
2011-04-05 08:01:16 +00:00
rcu_read_lock ( ) ;
cp = rcu_dereference ( proto_tab [ protocol ] ) ;
if ( cp & & ! try_module_get ( cp - > prot - > owner ) )
cp = NULL ;
rcu_read_unlock ( ) ;
return cp ;
}
2011-05-03 18:42:04 +00:00
static inline void can_put_proto ( const struct can_proto * cp )
{
module_put ( cp - > prot - > owner ) ;
}
2009-11-05 22:18:14 -08:00
static int can_create ( struct net * net , struct socket * sock , int protocol ,
int kern )
2007-11-16 15:52:17 -08:00
{
struct sock * sk ;
2011-05-03 18:40:57 +00:00
const struct can_proto * cp ;
2007-11-16 15:52:17 -08:00
int err = 0 ;
sock - > state = SS_UNCONNECTED ;
if ( protocol < 0 | | protocol > = CAN_NPROTO )
return - EINVAL ;
2011-05-03 18:42:04 +00:00
cp = can_get_proto ( protocol ) ;
2011-04-05 08:01:16 +00:00
2008-10-16 15:24:51 -07:00
# ifdef CONFIG_MODULES
2011-04-05 08:01:16 +00:00
if ( ! cp ) {
/* try to load protocol module if kernel is modular */
2008-02-07 18:04:21 -08:00
err = request_module ( " can-proto-%d " , protocol ) ;
2007-11-16 15:52:17 -08:00
2019-07-24 14:16:29 +02:00
/* In case of error we only print a message but don't
2007-11-16 15:52:17 -08:00
* return the error code immediately . Below we will
* return - EPROTONOSUPPORT
*/
2011-06-16 02:08:01 +00:00
if ( err )
2019-08-13 09:29:10 +02:00
pr_err_ratelimited ( " can: request_module (can-proto-%d) failed. \n " ,
protocol ) ;
2011-04-05 08:01:16 +00:00
2011-05-03 18:42:04 +00:00
cp = can_get_proto ( protocol ) ;
2007-11-16 15:52:17 -08:00
}
2008-02-07 18:04:21 -08:00
# endif
2007-11-16 15:52:17 -08:00
/* check for available protocol and correct usage */
if ( ! cp )
return - EPROTONOSUPPORT ;
if ( cp - > type ! = sock - > type ) {
2011-04-05 08:01:16 +00:00
err = - EPROTOTYPE ;
2007-11-16 15:52:17 -08:00
goto errout ;
}
sock - > ops = cp - > ops ;
2015-05-08 21:09:13 -05:00
sk = sk_alloc ( net , PF_CAN , GFP_KERNEL , cp - > prot , kern ) ;
2007-11-16 15:52:17 -08:00
if ( ! sk ) {
err = - ENOMEM ;
goto errout ;
}
sock_init_data ( sock , sk ) ;
sk - > sk_destruct = can_sock_destruct ;
if ( sk - > sk_prot - > init )
err = sk - > sk_prot - > init ( sk ) ;
if ( err ) {
/* release sk on errors */
sock_orphan ( sk ) ;
sock_put ( sk ) ;
}
errout :
2011-05-03 18:42:04 +00:00
can_put_proto ( cp ) ;
2007-11-16 15:52:17 -08:00
return err ;
}
2019-07-24 14:16:29 +02:00
/* af_can tx path */
2007-11-16 15:52:17 -08:00
/**
* can_send - transmit a CAN frame ( optional with local loopback )
* @ skb : pointer to socket buffer with CAN frame in data section
* @ loop : loopback for listeners on local CAN sockets ( recommended default ! )
*
2009-09-15 01:31:34 -07:00
* Due to the loopback this routine must not be called from hardirq context .
*
2007-11-16 15:52:17 -08:00
* Return :
* 0 on success
* - ENETDOWN when the selected interface is down
* - ENOBUFS on full driver queue ( see net_xmit_errno ( ) )
* - ENOMEM when local loopback failed at calling skb_clone ( )
* - EPERM when trying to send on a non - CAN interface
2012-06-13 20:33:02 +02:00
* - EMSGSIZE CAN frame size is bigger than CAN interface MTU
2008-07-05 23:38:43 -07:00
* - EINVAL when the skb - > data does not contain a valid CAN frame
2007-11-16 15:52:17 -08:00
*/
int can_send ( struct sk_buff * skb , int loop )
{
2008-05-08 02:49:55 -07:00
struct sk_buff * newskb = NULL ;
2012-06-13 20:33:02 +02:00
struct canfd_frame * cfd = ( struct canfd_frame * ) skb - > data ;
2018-10-08 09:02:28 +02:00
struct can_pkg_stats * pkg_stats = dev_net ( skb - > dev ) - > can . pkg_stats ;
2012-06-13 20:33:02 +02:00
int err = - EINVAL ;
if ( skb - > len = = CAN_MTU ) {
skb - > protocol = htons ( ETH_P_CAN ) ;
if ( unlikely ( cfd - > len > CAN_MAX_DLEN ) )
goto inval_skb ;
} else if ( skb - > len = = CANFD_MTU ) {
skb - > protocol = htons ( ETH_P_CANFD ) ;
if ( unlikely ( cfd - > len > CANFD_MAX_DLEN ) )
goto inval_skb ;
2019-08-13 09:03:55 +02:00
} else {
2012-06-13 20:33:02 +02:00
goto inval_skb ;
2019-08-13 09:03:55 +02:00
}
2007-11-16 15:52:17 -08:00
2019-07-24 14:16:29 +02:00
/* Make sure the CAN frame can pass the selected CAN netdevice.
2012-06-13 20:33:02 +02:00
* As structs can_frame and canfd_frame are similar , we can provide
* CAN FD frames to legacy CAN drivers as long as the length is < = 8
*/
if ( unlikely ( skb - > len > skb - > dev - > mtu & & cfd - > len > CAN_MAX_DLEN ) ) {
err = - EMSGSIZE ;
goto inval_skb ;
2008-07-05 23:38:43 -07:00
}
2012-06-13 20:33:02 +02:00
if ( unlikely ( skb - > dev - > type ! = ARPHRD_CAN ) ) {
err = - EPERM ;
goto inval_skb ;
2007-11-16 15:52:17 -08:00
}
2012-06-13 20:33:02 +02:00
if ( unlikely ( ! ( skb - > dev - > flags & IFF_UP ) ) ) {
err = - ENETDOWN ;
goto inval_skb ;
2007-11-16 15:52:17 -08:00
}
2015-02-23 20:37:54 +01:00
skb - > ip_summed = CHECKSUM_UNNECESSARY ;
skb_reset_mac_header ( skb ) ;
2007-11-16 15:52:17 -08:00
skb_reset_network_header ( skb ) ;
skb_reset_transport_header ( skb ) ;
if ( loop ) {
/* local loopback of sent CAN frames */
/* indication for the CAN driver: do loopback */
skb - > pkt_type = PACKET_LOOPBACK ;
2019-07-24 14:16:29 +02:00
/* The reference to the originating sock may be required
2007-11-16 15:52:17 -08:00
* by the receiving socket to check whether the frame is
* its own . Example : can_raw sockopt CAN_RAW_RECV_OWN_MSGS
* Therefore we have to ensure that skb - > sk remains the
* reference to the originating sock by restoring skb - > sk
* after each skb_clone ( ) or skb_orphan ( ) usage .
*/
if ( ! ( skb - > dev - > flags & IFF_ECHO ) ) {
2019-07-24 14:16:29 +02:00
/* If the interface is not capable to do loopback
2007-11-16 15:52:17 -08:00
* itself , we do it here .
*/
2008-05-08 02:49:55 -07:00
newskb = skb_clone ( skb , GFP_ATOMIC ) ;
2007-11-16 15:52:17 -08:00
if ( ! newskb ) {
kfree_skb ( skb ) ;
return - ENOMEM ;
}
2014-01-30 10:11:28 +01:00
can_skb_set_owner ( newskb , skb - > sk ) ;
2007-11-16 15:52:17 -08:00
newskb - > ip_summed = CHECKSUM_UNNECESSARY ;
newskb - > pkt_type = PACKET_BROADCAST ;
}
} else {
/* indication for the CAN driver: no loopback required */
skb - > pkt_type = PACKET_HOST ;
}
/* send to netdevice */
err = dev_queue_xmit ( skb ) ;
if ( err > 0 )
err = net_xmit_errno ( err ) ;
2008-05-08 02:49:55 -07:00
if ( err ) {
2009-02-25 00:35:44 +00:00
kfree_skb ( newskb ) ;
2008-05-08 02:49:55 -07:00
return err ;
}
2015-06-26 11:58:19 +02:00
if ( newskb )
2009-09-15 01:31:34 -07:00
netif_rx_ni ( newskb ) ;
2008-05-08 02:49:55 -07:00
2007-11-16 15:52:17 -08:00
/* update statistics */
2018-10-08 09:02:28 +02:00
pkg_stats - > tx_frames + + ;
pkg_stats - > tx_frames_delta + + ;
2007-11-16 15:52:17 -08:00
2008-05-08 02:49:55 -07:00
return 0 ;
2012-06-13 20:33:02 +02:00
inval_skb :
kfree_skb ( skb ) ;
return err ;
2007-11-16 15:52:17 -08:00
}
EXPORT_SYMBOL ( can_send ) ;
2019-07-24 14:16:29 +02:00
/* af_can rx path */
2007-11-16 15:52:17 -08:00
2018-10-08 09:02:34 +02:00
static struct can_dev_rcv_lists * can_dev_rcv_lists_find ( struct net * net ,
struct net_device * dev )
2007-11-16 15:52:17 -08:00
{
2018-10-08 09:02:39 +02:00
if ( dev ) {
struct can_ml_priv * ml_priv = dev - > ml_priv ;
return & ml_priv - > dev_rcv_lists ;
} else {
2018-10-08 09:02:30 +02:00
return net - > can . rx_alldev_list ;
2018-10-08 09:02:39 +02:00
}
2007-11-16 15:52:17 -08:00
}
2014-04-02 20:25:26 +02:00
/**
* effhash - hash function for 29 bit CAN identifier reduction
* @ can_id : 29 bit CAN identifier
*
* Description :
* To reduce the linear traversal in one linked list of _single_ EFF CAN
* frame subscriptions the 29 bit identifier is mapped to 10 bits .
* ( see CAN_EFF_RCV_HASH_BITS definition )
*
* Return :
* Hash value from 0x000 - 0x3FF ( enforced by CAN_EFF_RCV_HASH_BITS mask )
*/
static unsigned int effhash ( canid_t can_id )
{
unsigned int hash ;
hash = can_id ;
hash ^ = can_id > > CAN_EFF_RCV_HASH_BITS ;
hash ^ = can_id > > ( 2 * CAN_EFF_RCV_HASH_BITS ) ;
return hash & ( ( 1 < < CAN_EFF_RCV_HASH_BITS ) - 1 ) ;
}
2008-12-03 15:52:35 -08:00
/**
2018-10-08 09:02:33 +02:00
* can_rcv_list_find - determine optimal filterlist inside device filter struct
2008-12-03 15:52:35 -08:00
* @ can_id : pointer to CAN identifier of a given can_filter
* @ mask : pointer to CAN mask of a given can_filter
* @ d : pointer to the device filter struct
*
* Description :
* Returns the optimal filterlist to reduce the filter handling in the
* receive path . This function is called by service functions that need
* to register or unregister a can_filter in the filter lists .
*
* A filter matches in general , when
*
* < received_can_id > & mask = = can_id & mask
*
* so every bit set in the mask ( even CAN_EFF_FLAG , CAN_RTR_FLAG ) describe
* relevant bits for the filter .
*
* The filter can be inverted ( CAN_INV_FILTER bit set in can_id ) or it can
2012-05-08 22:20:33 +02:00
* filter for error messages ( CAN_ERR_FLAG bit set in mask ) . For error msg
* frames there is a special filterlist and a special rx path filter handling .
2008-12-03 15:52:35 -08:00
*
* Return :
* Pointer to optimal filterlist for the given can_id / mask pair .
* Constistency checked mask .
* Reduced can_id to have a preprocessed filter compare value .
*/
2018-10-08 09:02:33 +02:00
static struct hlist_head * can_rcv_list_find ( canid_t * can_id , canid_t * mask ,
struct can_dev_rcv_lists * dev_rcv_lists )
2007-11-16 15:52:17 -08:00
{
canid_t inv = * can_id & CAN_INV_FILTER ; /* save flag before masking */
2012-05-08 22:20:33 +02:00
/* filter for error message frames in extra filterlist */
2007-11-16 15:52:17 -08:00
if ( * mask & CAN_ERR_FLAG ) {
2008-12-03 15:52:35 -08:00
/* clear CAN_ERR_FLAG in filter entry */
2007-11-16 15:52:17 -08:00
* mask & = CAN_ERR_MASK ;
2018-10-08 09:02:31 +02:00
return & dev_rcv_lists - > rx [ RX_ERR ] ;
2007-11-16 15:52:17 -08:00
}
2008-12-03 15:52:35 -08:00
/* with cleared CAN_ERR_FLAG we have a simple mask/value filterpair */
# define CAN_EFF_RTR_FLAGS (CAN_EFF_FLAG | CAN_RTR_FLAG)
/* ensure valid values in can_mask for 'SFF only' frame filtering */
if ( ( * mask & CAN_EFF_FLAG ) & & ! ( * can_id & CAN_EFF_FLAG ) )
* mask & = ( CAN_SFF_MASK | CAN_EFF_RTR_FLAGS ) ;
2007-11-16 15:52:17 -08:00
/* reduce condition testing at receive time */
* can_id & = * mask ;
/* inverse can_id/can_mask filter */
if ( inv )
2018-10-08 09:02:31 +02:00
return & dev_rcv_lists - > rx [ RX_INV ] ;
2007-11-16 15:52:17 -08:00
/* mask == 0 => no condition testing at receive time */
if ( ! ( * mask ) )
2018-10-08 09:02:31 +02:00
return & dev_rcv_lists - > rx [ RX_ALL ] ;
2007-11-16 15:52:17 -08:00
2008-12-03 15:52:35 -08:00
/* extra filterlists for the subscription of a single non-RTR can_id */
2009-11-29 16:55:45 -08:00
if ( ( ( * mask & CAN_EFF_RTR_FLAGS ) = = CAN_EFF_RTR_FLAGS ) & &
! ( * can_id & CAN_RTR_FLAG ) ) {
2008-12-03 15:52:35 -08:00
if ( * can_id & CAN_EFF_FLAG ) {
2014-04-02 20:25:26 +02:00
if ( * mask = = ( CAN_EFF_MASK | CAN_EFF_RTR_FLAGS ) )
2018-10-08 09:02:31 +02:00
return & dev_rcv_lists - > rx_eff [ effhash ( * can_id ) ] ;
2008-12-03 15:52:35 -08:00
} else {
if ( * mask = = ( CAN_SFF_MASK | CAN_EFF_RTR_FLAGS ) )
2018-10-08 09:02:31 +02:00
return & dev_rcv_lists - > rx_sff [ * can_id ] ;
2007-11-16 15:52:17 -08:00
}
}
/* default: filter via can_id/can_mask */
2018-10-08 09:02:31 +02:00
return & dev_rcv_lists - > rx [ RX_FIL ] ;
2007-11-16 15:52:17 -08:00
}
/**
* can_rx_register - subscribe CAN frames from a specific interface
* @ dev : pointer to netdevice ( NULL = > subcribe from ' all ' CAN devices list )
* @ can_id : CAN identifier ( see description )
* @ mask : CAN mask ( see description )
* @ func : callback function on filter match
* @ data : returned parameter for callback function
2013-10-12 01:29:46 +02:00
* @ ident : string for calling module identification
2017-01-27 08:11:44 -08:00
* @ sk : socket pointer ( might be NULL )
2007-11-16 15:52:17 -08:00
*
* Description :
* Invokes the callback function with the received sk_buff and the given
* parameter ' data ' on a matching receive filter . A filter matches , when
*
* < received_can_id > & mask = = can_id & mask
*
* The filter can be inverted ( CAN_INV_FILTER bit set in can_id ) or it can
2012-05-08 22:20:33 +02:00
* filter for error message frames ( CAN_ERR_FLAG bit set in mask ) .
2007-11-16 15:52:17 -08:00
*
2009-01-06 11:07:54 -08:00
* The provided pointer to the sk_buff is guaranteed to be valid as long as
* the callback function is running . The callback function must * not * free
* the given sk_buff while processing it ' s task . When the given sk_buff is
* needed after the end of the callback function it must be cloned inside
* the callback function with skb_clone ( ) .
*
2007-11-16 15:52:17 -08:00
* Return :
* 0 on success
* - ENOMEM on missing cache mem to create subscription entry
* - ENODEV unknown device
*/
2017-02-21 12:19:47 +01:00
int can_rx_register ( struct net * net , struct net_device * dev , canid_t can_id ,
canid_t mask , void ( * func ) ( struct sk_buff * , void * ) ,
void * data , char * ident , struct sock * sk )
2007-11-16 15:52:17 -08:00
{
2018-10-08 09:02:35 +02:00
struct receiver * rcv ;
struct hlist_head * rcv_list ;
2018-10-08 09:02:31 +02:00
struct can_dev_rcv_lists * dev_rcv_lists ;
2018-10-08 09:02:28 +02:00
struct can_rcv_lists_stats * rcv_lists_stats = net - > can . rcv_lists_stats ;
2007-11-16 15:52:17 -08:00
int err = 0 ;
/* insert new receiver (dev,canid,mask) -> (func,data) */
2010-02-02 07:21:34 -08:00
if ( dev & & dev - > type ! = ARPHRD_CAN )
return - ENODEV ;
2017-02-21 12:19:47 +01:00
if ( dev & & ! net_eq ( net , dev_net ( dev ) ) )
return - ENODEV ;
2018-10-08 09:02:35 +02:00
rcv = kmem_cache_alloc ( rcv_cache , GFP_KERNEL ) ;
if ( ! rcv )
2007-11-16 15:52:17 -08:00
return - ENOMEM ;
2018-10-30 09:00:34 +01:00
spin_lock_bh ( & net - > can . rcvlists_lock ) ;
2007-11-16 15:52:17 -08:00
2018-10-08 09:02:34 +02:00
dev_rcv_lists = can_dev_rcv_lists_find ( net , dev ) ;
2018-10-08 09:02:40 +02:00
rcv_list = can_rcv_list_find ( & can_id , & mask , dev_rcv_lists ) ;
rcv - > can_id = can_id ;
rcv - > mask = mask ;
rcv - > matches = 0 ;
rcv - > func = func ;
rcv - > data = data ;
rcv - > ident = ident ;
rcv - > sk = sk ;
2007-11-16 15:52:17 -08:00
2018-10-08 09:02:40 +02:00
hlist_add_head_rcu ( & rcv - > list , rcv_list ) ;
dev_rcv_lists - > entries + + ;
rcv_lists_stats - > rcv_entries + + ;
rcv_lists_stats - > rcv_entries_max = max ( rcv_lists_stats - > rcv_entries_max ,
rcv_lists_stats - > rcv_entries ) ;
2018-10-30 09:00:34 +01:00
spin_unlock_bh ( & net - > can . rcvlists_lock ) ;
2007-11-16 15:52:17 -08:00
return err ;
}
EXPORT_SYMBOL ( can_rx_register ) ;
2019-07-24 14:16:29 +02:00
/* can_rx_delete_receiver - rcu callback for single receiver entry removal */
2007-11-16 15:52:17 -08:00
static void can_rx_delete_receiver ( struct rcu_head * rp )
{
2018-10-08 09:02:35 +02:00
struct receiver * rcv = container_of ( rp , struct receiver , rcu ) ;
struct sock * sk = rcv - > sk ;
2007-11-16 15:52:17 -08:00
2018-10-08 09:02:35 +02:00
kmem_cache_free ( rcv_cache , rcv ) ;
2017-01-27 08:11:44 -08:00
if ( sk )
sock_put ( sk ) ;
2007-11-16 15:52:17 -08:00
}
/**
* can_rx_unregister - unsubscribe CAN frames from a specific interface
2014-12-05 09:54:38 -08:00
* @ dev : pointer to netdevice ( NULL = > unsubscribe from ' all ' CAN devices list )
2007-11-16 15:52:17 -08:00
* @ can_id : CAN identifier
* @ mask : CAN mask
* @ func : callback function on filter match
* @ data : returned parameter for callback function
*
* Description :
* Removes subscription entry depending on given ( subscription ) values .
*/
2017-02-21 12:19:47 +01:00
void can_rx_unregister ( struct net * net , struct net_device * dev , canid_t can_id ,
canid_t mask , void ( * func ) ( struct sk_buff * , void * ) ,
void * data )
2007-11-16 15:52:17 -08:00
{
2018-10-08 09:02:35 +02:00
struct receiver * rcv = NULL ;
struct hlist_head * rcv_list ;
2018-10-08 09:02:28 +02:00
struct can_rcv_lists_stats * rcv_lists_stats = net - > can . rcv_lists_stats ;
2018-10-08 09:02:31 +02:00
struct can_dev_rcv_lists * dev_rcv_lists ;
2007-11-16 15:52:17 -08:00
2010-02-02 07:21:34 -08:00
if ( dev & & dev - > type ! = ARPHRD_CAN )
return ;
2017-02-21 12:19:47 +01:00
if ( dev & & ! net_eq ( net , dev_net ( dev ) ) )
return ;
2007-11-16 15:52:17 -08:00
2018-10-30 09:00:34 +01:00
spin_lock_bh ( & net - > can . rcvlists_lock ) ;
2017-02-21 12:19:47 +01:00
2018-10-08 09:02:34 +02:00
dev_rcv_lists = can_dev_rcv_lists_find ( net , dev ) ;
2018-10-08 09:02:35 +02:00
rcv_list = can_rcv_list_find ( & can_id , & mask , dev_rcv_lists ) ;
2007-11-16 15:52:17 -08:00
2019-07-24 14:16:29 +02:00
/* Search the receiver list for the item to delete. This should
2007-11-16 15:52:17 -08:00
* exist , since no receiver may be unregistered that hasn ' t
* been registered before .
*/
2018-10-08 09:02:35 +02:00
hlist_for_each_entry_rcu ( rcv , rcv_list , list ) {
if ( rcv - > can_id = = can_id & & rcv - > mask = = mask & &
rcv - > func = = func & & rcv - > data = = data )
2007-11-16 15:52:17 -08:00
break ;
}
2019-07-24 14:16:29 +02:00
/* Check for bugs in CAN protocol implementations using af_can.c:
2018-10-08 09:02:35 +02:00
* ' rcv ' will be NULL if no matching list item was found for removal .
2007-11-16 15:52:17 -08:00
*/
2018-10-08 09:02:35 +02:00
if ( ! rcv ) {
2019-08-13 09:29:10 +02:00
WARN ( 1 , " BUG: receive list entry not found for dev %s, id %03X, mask %03X \n " ,
DNAME ( dev ) , can_id , mask ) ;
2007-11-16 15:52:17 -08:00
goto out ;
}
2018-10-08 09:02:35 +02:00
hlist_del_rcu ( & rcv - > list ) ;
2018-10-08 09:02:31 +02:00
dev_rcv_lists - > entries - - ;
2007-11-16 15:52:17 -08:00
2018-10-08 09:02:28 +02:00
if ( rcv_lists_stats - > rcv_entries > 0 )
rcv_lists_stats - > rcv_entries - - ;
2007-11-16 15:52:17 -08:00
out :
2018-10-30 09:00:34 +01:00
spin_unlock_bh ( & net - > can . rcvlists_lock ) ;
2007-11-16 15:52:17 -08:00
/* schedule the receiver item for deletion */
2018-10-08 09:02:35 +02:00
if ( rcv ) {
if ( rcv - > sk )
sock_hold ( rcv - > sk ) ;
call_rcu ( & rcv - > rcu , can_rx_delete_receiver ) ;
2017-01-27 08:11:44 -08:00
}
2007-11-16 15:52:17 -08:00
}
EXPORT_SYMBOL ( can_rx_unregister ) ;
2018-10-08 09:02:35 +02:00
static inline void deliver ( struct sk_buff * skb , struct receiver * rcv )
2007-11-16 15:52:17 -08:00
{
2018-10-08 09:02:35 +02:00
rcv - > func ( skb , rcv - > data ) ;
rcv - > matches + + ;
2007-11-16 15:52:17 -08:00
}
2018-10-08 09:02:31 +02:00
static int can_rcv_filter ( struct can_dev_rcv_lists * dev_rcv_lists , struct sk_buff * skb )
2007-11-16 15:52:17 -08:00
{
2018-10-08 09:02:35 +02:00
struct receiver * rcv ;
2007-11-16 15:52:17 -08:00
int matches = 0 ;
struct can_frame * cf = ( struct can_frame * ) skb - > data ;
canid_t can_id = cf - > can_id ;
2018-10-08 09:02:31 +02:00
if ( dev_rcv_lists - > entries = = 0 )
2007-11-16 15:52:17 -08:00
return 0 ;
if ( can_id & CAN_ERR_FLAG ) {
2012-05-08 22:20:33 +02:00
/* check for error message frame entries only */
2018-10-08 09:02:35 +02:00
hlist_for_each_entry_rcu ( rcv , & dev_rcv_lists - > rx [ RX_ERR ] , list ) {
if ( can_id & rcv - > mask ) {
deliver ( skb , rcv ) ;
2007-11-16 15:52:17 -08:00
matches + + ;
}
}
return matches ;
}
/* check for unfiltered entries */
2018-10-08 09:02:35 +02:00
hlist_for_each_entry_rcu ( rcv , & dev_rcv_lists - > rx [ RX_ALL ] , list ) {
deliver ( skb , rcv ) ;
2007-11-16 15:52:17 -08:00
matches + + ;
}
/* check for can_id/mask entries */
2018-10-08 09:02:35 +02:00
hlist_for_each_entry_rcu ( rcv , & dev_rcv_lists - > rx [ RX_FIL ] , list ) {
if ( ( can_id & rcv - > mask ) = = rcv - > can_id ) {
deliver ( skb , rcv ) ;
2007-11-16 15:52:17 -08:00
matches + + ;
}
}
/* check for inverted can_id/mask entries */
2018-10-08 09:02:35 +02:00
hlist_for_each_entry_rcu ( rcv , & dev_rcv_lists - > rx [ RX_INV ] , list ) {
if ( ( can_id & rcv - > mask ) ! = rcv - > can_id ) {
deliver ( skb , rcv ) ;
2007-11-16 15:52:17 -08:00
matches + + ;
}
}
2008-12-04 15:01:08 -08:00
/* check filterlists for single non-RTR can_ids */
if ( can_id & CAN_RTR_FLAG )
return matches ;
2007-11-16 15:52:17 -08:00
if ( can_id & CAN_EFF_FLAG ) {
2018-10-08 09:02:35 +02:00
hlist_for_each_entry_rcu ( rcv , & dev_rcv_lists - > rx_eff [ effhash ( can_id ) ] , list ) {
if ( rcv - > can_id = = can_id ) {
deliver ( skb , rcv ) ;
2007-11-16 15:52:17 -08:00
matches + + ;
}
}
} else {
can_id & = CAN_SFF_MASK ;
2018-10-08 09:02:35 +02:00
hlist_for_each_entry_rcu ( rcv , & dev_rcv_lists - > rx_sff [ can_id ] , list ) {
deliver ( skb , rcv ) ;
2007-11-16 15:52:17 -08:00
matches + + ;
}
}
return matches ;
}
2012-06-13 20:33:02 +02:00
static void can_receive ( struct sk_buff * skb , struct net_device * dev )
2007-11-16 15:52:17 -08:00
{
2018-10-08 09:02:31 +02:00
struct can_dev_rcv_lists * dev_rcv_lists ;
2017-04-25 08:19:41 +02:00
struct net * net = dev_net ( dev ) ;
2018-10-08 09:02:28 +02:00
struct can_pkg_stats * pkg_stats = net - > can . pkg_stats ;
2007-11-16 15:52:17 -08:00
int matches ;
/* update statistics */
2018-10-08 09:02:28 +02:00
pkg_stats - > rx_frames + + ;
pkg_stats - > rx_frames_delta + + ;
2007-11-16 15:52:17 -08:00
2015-06-26 11:58:19 +02:00
/* create non-zero unique skb identifier together with *skb */
while ( ! ( can_skb_prv ( skb ) - > skbcnt ) )
can_skb_prv ( skb ) - > skbcnt = atomic_inc_return ( & skbcounter ) ;
2007-11-16 15:52:17 -08:00
rcu_read_lock ( ) ;
/* deliver the packet to sockets listening on all devices */
2018-10-08 09:02:30 +02:00
matches = can_rcv_filter ( net - > can . rx_alldev_list , skb ) ;
2007-11-16 15:52:17 -08:00
/* find receive list for this device */
2018-10-08 09:02:34 +02:00
dev_rcv_lists = can_dev_rcv_lists_find ( net , dev ) ;
2018-10-08 09:02:40 +02:00
matches + = can_rcv_filter ( dev_rcv_lists , skb ) ;
2007-11-16 15:52:17 -08:00
rcu_read_unlock ( ) ;
2009-04-17 01:38:46 -07:00
/* consume the skbuff allocated by the netdevice driver */
consume_skb ( skb ) ;
2007-11-16 15:52:17 -08:00
if ( matches > 0 ) {
2018-10-08 09:02:28 +02:00
pkg_stats - > matches + + ;
pkg_stats - > matches_delta + + ;
2007-11-16 15:52:17 -08:00
}
2012-06-13 20:33:02 +02:00
}
static int can_rcv ( struct sk_buff * skb , struct net_device * dev ,
struct packet_type * pt , struct net_device * orig_dev )
{
struct canfd_frame * cfd = ( struct canfd_frame * ) skb - > data ;
2007-11-16 15:52:17 -08:00
2018-01-16 19:30:14 +01:00
if ( unlikely ( dev - > type ! = ARPHRD_CAN | | skb - > len ! = CAN_MTU | |
cfd - > len > CAN_MAX_DLEN ) ) {
pr_warn_once ( " PF_CAN: dropped non conform CAN skbuf: dev type %d, len %d, datalen %d \n " ,
dev - > type , skb - > len , cfd - > len ) ;
kfree_skb ( skb ) ;
return NET_RX_DROP ;
}
2012-06-13 20:33:02 +02:00
can_receive ( skb , dev ) ;
return NET_RX_SUCCESS ;
}
static int canfd_rcv ( struct sk_buff * skb , struct net_device * dev ,
2019-08-13 09:06:17 +02:00
struct packet_type * pt , struct net_device * orig_dev )
2012-06-13 20:33:02 +02:00
{
struct canfd_frame * cfd = ( struct canfd_frame * ) skb - > data ;
2018-01-16 19:30:14 +01:00
if ( unlikely ( dev - > type ! = ARPHRD_CAN | | skb - > len ! = CANFD_MTU | |
cfd - > len > CANFD_MAX_DLEN ) ) {
pr_warn_once ( " PF_CAN: dropped non conform CAN FD skbuf: dev type %d, len %d, datalen %d \n " ,
dev - > type , skb - > len , cfd - > len ) ;
kfree_skb ( skb ) ;
return NET_RX_DROP ;
}
2012-06-13 20:33:02 +02:00
can_receive ( skb , dev ) ;
2009-08-29 06:45:09 +00:00
return NET_RX_SUCCESS ;
2007-11-16 15:52:17 -08:00
}
2019-07-24 14:16:29 +02:00
/* af_can protocol functions */
2007-11-16 15:52:17 -08:00
/**
* can_proto_register - register CAN transport protocol
* @ cp : pointer to CAN protocol structure
*
* Return :
* 0 on success
* - EINVAL invalid ( out of range ) protocol number
* - EBUSY protocol already in use
* - ENOBUF if proto_register ( ) fails
*/
2011-05-03 18:40:57 +00:00
int can_proto_register ( const struct can_proto * cp )
2007-11-16 15:52:17 -08:00
{
int proto = cp - > protocol ;
int err = 0 ;
if ( proto < 0 | | proto > = CAN_NPROTO ) {
2013-03-10 11:15:13 +00:00
pr_err ( " can: protocol number %d out of range \n " , proto ) ;
2007-11-16 15:52:17 -08:00
return - EINVAL ;
}
2008-02-07 18:04:45 -08:00
err = proto_register ( cp - > prot , 0 ) ;
if ( err < 0 )
return err ;
2011-04-05 08:01:16 +00:00
mutex_lock ( & proto_tab_lock ) ;
2017-10-17 07:18:35 +02:00
if ( rcu_access_pointer ( proto_tab [ proto ] ) ) {
2013-03-10 11:15:13 +00:00
pr_err ( " can: protocol %d already registered \n " , proto ) ;
2007-11-16 15:52:17 -08:00
err = - EBUSY ;
2019-08-13 09:03:55 +02:00
} else {
2011-08-01 16:19:00 +00:00
RCU_INIT_POINTER ( proto_tab [ proto ] , cp ) ;
2019-08-13 09:03:55 +02:00
}
2008-02-07 18:04:45 -08:00
2011-04-05 08:01:16 +00:00
mutex_unlock ( & proto_tab_lock ) ;
2007-11-16 15:52:17 -08:00
if ( err < 0 )
2008-02-07 18:04:45 -08:00
proto_unregister ( cp - > prot ) ;
2007-11-16 15:52:17 -08:00
return err ;
}
EXPORT_SYMBOL ( can_proto_register ) ;
/**
* can_proto_unregister - unregister CAN transport protocol
* @ cp : pointer to CAN protocol structure
*/
2011-05-03 18:40:57 +00:00
void can_proto_unregister ( const struct can_proto * cp )
2007-11-16 15:52:17 -08:00
{
int proto = cp - > protocol ;
2011-04-05 08:01:16 +00:00
mutex_lock ( & proto_tab_lock ) ;
2017-10-17 07:18:35 +02:00
BUG_ON ( rcu_access_pointer ( proto_tab [ proto ] ) ! = cp ) ;
2011-08-01 16:19:00 +00:00
RCU_INIT_POINTER ( proto_tab [ proto ] , NULL ) ;
2011-04-05 08:01:16 +00:00
mutex_unlock ( & proto_tab_lock ) ;
synchronize_rcu ( ) ;
2008-02-07 18:04:45 -08:00
proto_unregister ( cp - > prot ) ;
2007-11-16 15:52:17 -08:00
}
EXPORT_SYMBOL ( can_proto_unregister ) ;
2019-07-24 14:16:29 +02:00
/* af_can notifier to create/remove CAN netdevice specific structs */
2007-11-16 15:52:17 -08:00
static int can_notifier ( struct notifier_block * nb , unsigned long msg ,
2013-05-28 01:30:21 +00:00
void * ptr )
2007-11-16 15:52:17 -08:00
{
2013-05-28 01:30:21 +00:00
struct net_device * dev = netdev_notifier_info_to_dev ( ptr ) ;
2007-11-16 15:52:17 -08:00
if ( dev - > type ! = ARPHRD_CAN )
return NOTIFY_DONE ;
switch ( msg ) {
case NETDEV_REGISTER :
2018-10-08 09:02:39 +02:00
WARN ( ! dev - > ml_priv ,
" No CAN mid layer private allocated, please fix your driver and use alloc_candev()! \n " ) ;
2007-11-16 15:52:17 -08:00
break ;
}
return NOTIFY_DONE ;
}
2017-02-21 12:19:47 +01:00
static int can_pernet_init ( struct net * net )
{
2018-10-08 09:02:30 +02:00
spin_lock_init ( & net - > can . rcvlists_lock ) ;
net - > can . rx_alldev_list =
kzalloc ( sizeof ( * net - > can . rx_alldev_list ) , GFP_KERNEL ) ;
if ( ! net - > can . rx_alldev_list )
2017-07-29 11:51:01 +02:00
goto out ;
2018-10-08 09:02:27 +02:00
net - > can . pkg_stats = kzalloc ( sizeof ( * net - > can . pkg_stats ) , GFP_KERNEL ) ;
if ( ! net - > can . pkg_stats )
goto out_free_rx_alldev_list ;
net - > can . rcv_lists_stats = kzalloc ( sizeof ( * net - > can . rcv_lists_stats ) , GFP_KERNEL ) ;
if ( ! net - > can . rcv_lists_stats )
goto out_free_pkg_stats ;
2017-04-25 08:19:41 +02:00
if ( IS_ENABLED ( CONFIG_PROC_FS ) ) {
/* the statistics are updated every second (timer triggered) */
if ( stats_timer ) {
2018-10-08 09:02:30 +02:00
timer_setup ( & net - > can . stattimer , can_stat_update ,
2017-10-16 17:29:06 -07:00
0 ) ;
2018-10-08 09:02:30 +02:00
mod_timer ( & net - > can . stattimer ,
2017-04-25 08:19:41 +02:00
round_jiffies ( jiffies + HZ ) ) ;
}
2018-10-08 09:02:27 +02:00
net - > can . pkg_stats - > jiffies_init = jiffies ;
2017-02-21 12:19:47 +01:00
can_init_proc ( net ) ;
2017-04-25 08:19:41 +02:00
}
2017-02-21 12:19:47 +01:00
return 0 ;
2017-07-29 11:51:01 +02:00
2018-10-08 09:02:27 +02:00
out_free_pkg_stats :
kfree ( net - > can . pkg_stats ) ;
out_free_rx_alldev_list :
2018-10-08 09:02:30 +02:00
kfree ( net - > can . rx_alldev_list ) ;
2017-07-29 11:51:01 +02:00
out :
return - ENOMEM ;
2017-02-21 12:19:47 +01:00
}
static void can_pernet_exit ( struct net * net )
{
2017-04-25 08:19:41 +02:00
if ( IS_ENABLED ( CONFIG_PROC_FS ) ) {
2017-02-21 12:19:47 +01:00
can_remove_proc ( net ) ;
2017-04-25 08:19:41 +02:00
if ( stats_timer )
2018-10-08 09:02:30 +02:00
del_timer_sync ( & net - > can . stattimer ) ;
2017-04-25 08:19:41 +02:00
}
2017-02-21 12:19:47 +01:00
2018-10-08 09:02:30 +02:00
kfree ( net - > can . rx_alldev_list ) ;
2018-10-08 09:02:27 +02:00
kfree ( net - > can . pkg_stats ) ;
kfree ( net - > can . rcv_lists_stats ) ;
2017-02-21 12:19:47 +01:00
}
2019-07-24 14:16:29 +02:00
/* af_can module init/exit functions */
2007-11-16 15:52:17 -08:00
static struct packet_type can_packet __read_mostly = {
2009-02-01 00:45:17 -08:00
. type = cpu_to_be16 ( ETH_P_CAN ) ,
2007-11-16 15:52:17 -08:00
. func = can_rcv ,
} ;
2012-06-13 20:33:02 +02:00
static struct packet_type canfd_packet __read_mostly = {
. type = cpu_to_be16 ( ETH_P_CANFD ) ,
. func = canfd_rcv ,
} ;
2009-10-05 05:58:39 +00:00
static const struct net_proto_family can_family_ops = {
2007-11-16 15:52:17 -08:00
. family = PF_CAN ,
. create = can_create ,
. owner = THIS_MODULE ,
} ;
/* notifier block for netdevice event */
static struct notifier_block can_netdev_notifier __read_mostly = {
. notifier_call = can_notifier ,
} ;
2017-02-21 12:19:47 +01:00
static struct pernet_operations can_pernet_ops __read_mostly = {
. init = can_pernet_init ,
. exit = can_pernet_exit ,
} ;
2007-11-16 15:52:17 -08:00
static __init int can_init ( void )
{
2019-05-16 22:36:26 +08:00
int err ;
2012-06-13 20:04:33 +02:00
/* check for correct padding to be able to use the structs similarly */
BUILD_BUG_ON ( offsetof ( struct can_frame , can_dlc ) ! =
offsetof ( struct canfd_frame , len ) | |
offsetof ( struct can_frame , data ) ! =
offsetof ( struct canfd_frame , data ) ) ;
2014-11-21 23:42:35 -08:00
pr_info ( " can: controller area network core ( " CAN_VERSION_STRING " ) \n " ) ;
2007-11-16 15:52:17 -08:00
rcv_cache = kmem_cache_create ( " can_receiver " , sizeof ( struct receiver ) ,
0 , 0 , NULL ) ;
if ( ! rcv_cache )
return - ENOMEM ;
2019-05-16 22:36:26 +08:00
err = register_pernet_subsys ( & can_pernet_ops ) ;
if ( err )
goto out_pernet ;
2017-02-21 12:19:47 +01:00
2007-11-16 15:52:17 -08:00
/* protocol register */
2019-05-16 22:36:26 +08:00
err = sock_register ( & can_family_ops ) ;
if ( err )
goto out_sock ;
err = register_netdevice_notifier ( & can_netdev_notifier ) ;
if ( err )
goto out_notifier ;
2007-11-16 15:52:17 -08:00
dev_add_pack ( & can_packet ) ;
2012-06-13 20:33:02 +02:00
dev_add_pack ( & canfd_packet ) ;
2007-11-16 15:52:17 -08:00
return 0 ;
2019-05-16 22:36:26 +08:00
out_notifier :
sock_unregister ( PF_CAN ) ;
out_sock :
unregister_pernet_subsys ( & can_pernet_ops ) ;
out_pernet :
kmem_cache_destroy ( rcv_cache ) ;
return err ;
2007-11-16 15:52:17 -08:00
}
static __exit void can_exit ( void )
{
/* protocol unregister */
2012-06-13 20:33:02 +02:00
dev_remove_pack ( & canfd_packet ) ;
2007-11-16 15:52:17 -08:00
dev_remove_pack ( & can_packet ) ;
unregister_netdevice_notifier ( & can_netdev_notifier ) ;
sock_unregister ( PF_CAN ) ;
2017-02-21 12:19:47 +01:00
unregister_pernet_subsys ( & can_pernet_ops ) ;
2007-11-16 15:52:17 -08:00
2009-06-08 03:11:38 +00:00
rcu_barrier ( ) ; /* Wait for completion of call_rcu()'s */
2007-11-16 15:52:17 -08:00
kmem_cache_destroy ( rcv_cache ) ;
}
module_init ( can_init ) ;
module_exit ( can_exit ) ;