|
@@ -445,6 +445,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
|
|
|
* @func: callback function on filter match
|
|
|
* @data: returned parameter for callback function
|
|
|
* @ident: string for calling module identification
|
|
|
+ * @sk: socket pointer (might be NULL)
|
|
|
*
|
|
|
* Description:
|
|
|
* Invokes the callback function with the received sk_buff and the given
|
|
@@ -468,7 +469,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
|
|
|
*/
|
|
|
int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
|
|
|
void (*func)(struct sk_buff *, void *), void *data,
|
|
|
- char *ident)
|
|
|
+ char *ident, struct sock *sk)
|
|
|
{
|
|
|
struct receiver *r;
|
|
|
struct hlist_head *rl;
|
|
@@ -496,6 +497,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
|
|
|
r->func = func;
|
|
|
r->data = data;
|
|
|
r->ident = ident;
|
|
|
+ r->sk = sk;
|
|
|
|
|
|
hlist_add_head_rcu(&r->list, rl);
|
|
|
d->entries++;
|
|
@@ -520,8 +522,11 @@ EXPORT_SYMBOL(can_rx_register);
|
|
|
static void can_rx_delete_receiver(struct rcu_head *rp)
|
|
|
{
|
|
|
struct receiver *r = container_of(rp, struct receiver, rcu);
|
|
|
+ struct sock *sk = r->sk;
|
|
|
|
|
|
kmem_cache_free(rcv_cache, r);
|
|
|
+ if (sk)
|
|
|
+ sock_put(sk);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -596,8 +601,11 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
|
|
|
spin_unlock(&can_rcvlists_lock);
|
|
|
|
|
|
/* schedule the receiver item for deletion */
|
|
|
- if (r)
|
|
|
+ if (r) {
|
|
|
+ if (r->sk)
|
|
|
+ sock_hold(r->sk);
|
|
|
call_rcu(&r->rcu, can_rx_delete_receiver);
|
|
|
+ }
|
|
|
}
|
|
|
EXPORT_SYMBOL(can_rx_unregister);
|
|
|
|