| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ | 
|---|
| 2 | /* | 
|---|
| 3 | * 	connector.h | 
|---|
| 4 | * | 
|---|
| 5 | * 2004-2005 Copyright (c) Evgeniy Polyakov <zbr@ioremap.net> | 
|---|
| 6 | * All rights reserved. | 
|---|
| 7 | */ | 
|---|
| 8 | #ifndef __CONNECTOR_H | 
|---|
| 9 | #define __CONNECTOR_H | 
|---|
| 10 |  | 
|---|
| 11 |  | 
|---|
| 12 | #include <linux/refcount.h> | 
|---|
| 13 |  | 
|---|
| 14 | #include <linux/list.h> | 
|---|
| 15 | #include <linux/workqueue.h> | 
|---|
| 16 |  | 
|---|
| 17 | #include <net/sock.h> | 
|---|
| 18 | #include <uapi/linux/connector.h> | 
|---|
| 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 |  | 
|---|
| 26 | struct list_head queue_list; | 
|---|
| 27 | spinlock_t queue_lock; | 
|---|
| 28 |  | 
|---|
| 29 | struct sock *nls; | 
|---|
| 30 | }; | 
|---|
| 31 |  | 
|---|
| 32 | struct cn_callback_id { | 
|---|
| 33 | unsigned char name[CN_CBQ_NAMELEN]; | 
|---|
| 34 | struct cb_id id; | 
|---|
| 35 | }; | 
|---|
| 36 |  | 
|---|
| 37 | struct cn_callback_entry { | 
|---|
| 38 | struct list_head callback_entry; | 
|---|
| 39 | refcount_t refcnt; | 
|---|
| 40 | struct cn_queue_dev *pdev; | 
|---|
| 41 |  | 
|---|
| 42 | struct cn_callback_id id; | 
|---|
| 43 | void (*callback) (struct cn_msg *, struct netlink_skb_parms *); | 
|---|
| 44 |  | 
|---|
| 45 | u32 seq, group; | 
|---|
| 46 | }; | 
|---|
| 47 |  | 
|---|
| 48 | struct cn_dev { | 
|---|
| 49 | struct cb_id id; | 
|---|
| 50 |  | 
|---|
| 51 | u32 seq, groups; | 
|---|
| 52 | struct sock *nls; | 
|---|
| 53 |  | 
|---|
| 54 | struct cn_queue_dev *cbdev; | 
|---|
| 55 | }; | 
|---|
| 56 |  | 
|---|
| 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 | */ | 
|---|
| 67 | int cn_add_callback(const struct cb_id *id, const char *name, | 
|---|
| 68 | void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); | 
|---|
| 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(const 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 | * @filter:     Filter function to be used at netlink layer. | 
|---|
| 94 | * @filter_data:Filter data to be supplied to the filter function | 
|---|
| 95 | * | 
|---|
| 96 | * It can be safely called from softirq context, but may silently | 
|---|
| 97 | * fail under strong memory pressure. | 
|---|
| 98 | * | 
|---|
| 99 | * If there are no listeners for given group %-ESRCH can be returned. | 
|---|
| 100 | */ | 
|---|
| 101 | int cn_netlink_send_mult(struct cn_msg *msg, u16 len, u32 portid, | 
|---|
| 102 | u32 group, gfp_t gfp_mask, | 
|---|
| 103 | netlink_filter_fn filter, | 
|---|
| 104 | void *filter_data); | 
|---|
| 105 |  | 
|---|
| 106 | /** | 
|---|
| 107 | * cn_netlink_send - Sends message to the specified groups. | 
|---|
| 108 | * | 
|---|
| 109 | * @msg:	message header(with attached data). | 
|---|
| 110 | * @portid:	destination port. | 
|---|
| 111 | *		If non-zero the message will be sent to the given port, | 
|---|
| 112 | *		which should be set to the original sender. | 
|---|
| 113 | * @group:	destination group. | 
|---|
| 114 | * 		If @portid and @group is zero, then appropriate group will | 
|---|
| 115 | *		be searched through all registered connector users, and | 
|---|
| 116 | *		message will be delivered to the group which was created | 
|---|
| 117 | *		for user with the same ID as in @msg. | 
|---|
| 118 | *		If @group is not zero, then message will be delivered | 
|---|
| 119 | *		to the specified group. | 
|---|
| 120 | * @gfp_mask:	GFP mask. | 
|---|
| 121 | * | 
|---|
| 122 | * It can be safely called from softirq context, but may silently | 
|---|
| 123 | * fail under strong memory pressure. | 
|---|
| 124 | * | 
|---|
| 125 | * If there are no listeners for given group %-ESRCH can be returned. | 
|---|
| 126 | */ | 
|---|
| 127 | int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask); | 
|---|
| 128 |  | 
|---|
| 129 | int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, | 
|---|
| 130 | const struct cb_id *id, | 
|---|
| 131 | void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); | 
|---|
| 132 | void cn_queue_del_callback(struct cn_queue_dev *dev, const struct cb_id *id); | 
|---|
| 133 | void cn_queue_release_callback(struct cn_callback_entry *); | 
|---|
| 134 |  | 
|---|
| 135 | struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *); | 
|---|
| 136 | void cn_queue_free_dev(struct cn_queue_dev *dev); | 
|---|
| 137 |  | 
|---|
| 138 | int cn_cb_equal(const struct cb_id *, const struct cb_id *); | 
|---|
| 139 |  | 
|---|
| 140 | #endif				/* __CONNECTOR_H */ | 
|---|
| 141 |  | 
|---|