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