Thomas Gleixner | 1a59d1b8 | 2019-05-27 08:55:05 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 2 | /* |
| 3 | * connector.h |
| 4 | * |
Evgeniy Polyakov | a801876 | 2011-08-25 15:59:06 -0700 | [diff] [blame] | 5 | * 2004-2005 Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 6 | * All rights reserved. |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 7 | */ |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 8 | #ifndef __CONNECTOR_H |
| 9 | #define __CONNECTOR_H |
| 10 | |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 11 | |
Elena Reshetova | e65f7ee | 2017-10-20 10:23:49 +0300 | [diff] [blame] | 12 | #include <linux/refcount.h> |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 13 | |
| 14 | #include <linux/list.h> |
| 15 | #include <linux/workqueue.h> |
| 16 | |
| 17 | #include <net/sock.h> |
David Howells | 607ca46 | 2012-10-13 10:46:48 +0100 | [diff] [blame] | 18 | #include <uapi/linux/connector.h> |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 19 | |
| 20 | #define CN_CBQ_NAMELEN 32 |
| 21 | |
| 22 | struct cn_queue_dev { |
| 23 | atomic_t refcnt; |
| 24 | unsigned char name[CN_CBQ_NAMELEN]; |
| 25 | |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 26 | struct list_head queue_list; |
| 27 | spinlock_t queue_lock; |
| 28 | |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 29 | struct sock *nls; |
| 30 | }; |
| 31 | |
Evgeniy Polyakov | acd042b | 2005-09-26 15:06:50 -0700 | [diff] [blame] | 32 | struct cn_callback_id { |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 33 | unsigned char name[CN_CBQ_NAMELEN]; |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 34 | struct cb_id id; |
Evgeniy Polyakov | acd042b | 2005-09-26 15:06:50 -0700 | [diff] [blame] | 35 | }; |
| 36 | |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 37 | struct cn_callback_entry { |
| 38 | struct list_head callback_entry; |
Elena Reshetova | e65f7ee | 2017-10-20 10:23:49 +0300 | [diff] [blame] | 39 | refcount_t refcnt; |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 40 | struct cn_queue_dev *pdev; |
| 41 | |
Evgeniy Polyakov | acd042b | 2005-09-26 15:06:50 -0700 | [diff] [blame] | 42 | struct cn_callback_id id; |
Patrick McHardy | 04f482f | 2011-03-28 08:39:36 +0000 | [diff] [blame] | 43 | void (*callback) (struct cn_msg *, struct netlink_skb_parms *); |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 44 | |
Li Zefan | 6e32814 | 2008-01-04 01:59:42 -0800 | [diff] [blame] | 45 | u32 seq, group; |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 46 | }; |
| 47 | |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 48 | struct cn_dev { |
| 49 | struct cb_id id; |
| 50 | |
| 51 | u32 seq, groups; |
| 52 | struct sock *nls; |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 53 | |
| 54 | struct cn_queue_dev *cbdev; |
| 55 | }; |
| 56 | |
Mauro Carvalho Chehab | 720594f | 2019-04-13 22:54:53 -0300 | [diff] [blame] | 57 | /** |
| 58 | * cn_add_callback() - Registers new callback with connector core. |
| 59 | * |
| 60 | * @id: unique connector's user identifier. |
| 61 | * It must be registered in connector.h for legal |
| 62 | * in-kernel users. |
| 63 | * @name: connector's callback symbolic name. |
| 64 | * @callback: connector's callback. |
| 65 | * parameters are %cn_msg and the sender's credentials |
| 66 | */ |
Joe Perches | 008536e | 2011-02-19 15:45:29 -0800 | [diff] [blame] | 67 | int cn_add_callback(struct cb_id *id, const char *name, |
| 68 | void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); |
Mauro Carvalho Chehab | 720594f | 2019-04-13 22:54:53 -0300 | [diff] [blame] | 69 | /** |
| 70 | * cn_del_callback() - Unregisters new callback with connector core. |
| 71 | * |
| 72 | * @id: unique connector's user identifier. |
| 73 | */ |
| 74 | void cn_del_callback(struct cb_id *id); |
| 75 | |
| 76 | |
| 77 | /** |
| 78 | * cn_netlink_send_mult - Sends message to the specified groups. |
| 79 | * |
| 80 | * @msg: message header(with attached data). |
| 81 | * @len: Number of @msg to be sent. |
| 82 | * @portid: destination port. |
| 83 | * If non-zero the message will be sent to the given port, |
| 84 | * which should be set to the original sender. |
| 85 | * @group: destination group. |
| 86 | * If @portid and @group is zero, then appropriate group will |
| 87 | * be searched through all registered connector users, and |
| 88 | * message will be delivered to the group which was created |
| 89 | * for user with the same ID as in @msg. |
| 90 | * If @group is not zero, then message will be delivered |
| 91 | * to the specified group. |
| 92 | * @gfp_mask: GFP mask. |
| 93 | * |
| 94 | * It can be safely called from softirq context, but may silently |
| 95 | * fail under strong memory pressure. |
| 96 | * |
| 97 | * If there are no listeners for given group %-ESRCH can be returned. |
| 98 | */ |
David Fries | 34470e0 | 2014-04-08 22:37:08 -0500 | [diff] [blame] | 99 | int cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, u32 group, gfp_t gfp_mask); |
Mauro Carvalho Chehab | 720594f | 2019-04-13 22:54:53 -0300 | [diff] [blame] | 100 | |
| 101 | /** |
| 102 | * cn_netlink_send_mult - Sends message to the specified groups. |
| 103 | * |
| 104 | * @msg: message header(with attached data). |
| 105 | * @portid: destination port. |
| 106 | * If non-zero the message will be sent to the given port, |
| 107 | * which should be set to the original sender. |
| 108 | * @group: destination group. |
| 109 | * If @portid and @group is zero, then appropriate group will |
| 110 | * be searched through all registered connector users, and |
| 111 | * message will be delivered to the group which was created |
| 112 | * for user with the same ID as in @msg. |
| 113 | * If @group is not zero, then message will be delivered |
| 114 | * to the specified group. |
| 115 | * @gfp_mask: GFP mask. |
| 116 | * |
| 117 | * It can be safely called from softirq context, but may silently |
| 118 | * fail under strong memory pressure. |
| 119 | * |
| 120 | * If there are no listeners for given group %-ESRCH can be returned. |
| 121 | */ |
David Fries | ac8f733 | 2014-01-15 22:29:19 -0600 | [diff] [blame] | 122 | int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask); |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 123 | |
Joe Perches | 008536e | 2011-02-19 15:45:29 -0800 | [diff] [blame] | 124 | int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, |
| 125 | struct cb_id *id, |
| 126 | void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 127 | void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id); |
Patrick McHardy | 04f482f | 2011-03-28 08:39:36 +0000 | [diff] [blame] | 128 | void cn_queue_release_callback(struct cn_callback_entry *); |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 129 | |
Joe Perches | 008536e | 2011-02-19 15:45:29 -0800 | [diff] [blame] | 130 | struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *); |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 131 | void cn_queue_free_dev(struct cn_queue_dev *dev); |
| 132 | |
| 133 | int cn_cb_equal(struct cb_id *, struct cb_id *); |
| 134 | |
Evgeniy Polyakov | 7672d0b | 2005-09-11 19:15:07 -0700 | [diff] [blame] | 135 | #endif /* __CONNECTOR_H */ |