162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#ifndef _RDMA_NETLINK_H
462306a36Sopenharmony_ci#define _RDMA_NETLINK_H
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/netlink.h>
762306a36Sopenharmony_ci#include <uapi/rdma/rdma_netlink.h>
862306a36Sopenharmony_ci
962306a36Sopenharmony_cienum {
1062306a36Sopenharmony_ci	RDMA_NLDEV_ATTR_EMPTY_STRING = 1,
1162306a36Sopenharmony_ci	RDMA_NLDEV_ATTR_ENTRY_STRLEN = 16,
1262306a36Sopenharmony_ci	RDMA_NLDEV_ATTR_CHARDEV_TYPE_SIZE = 32,
1362306a36Sopenharmony_ci};
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cistruct rdma_nl_cbs {
1662306a36Sopenharmony_ci	int (*doit)(struct sk_buff *skb, struct nlmsghdr *nlh,
1762306a36Sopenharmony_ci		    struct netlink_ext_ack *extack);
1862306a36Sopenharmony_ci	int (*dump)(struct sk_buff *skb, struct netlink_callback *nlcb);
1962306a36Sopenharmony_ci	u8 flags;
2062306a36Sopenharmony_ci};
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cienum rdma_nl_flags {
2362306a36Sopenharmony_ci	/* Require CAP_NET_ADMIN */
2462306a36Sopenharmony_ci	RDMA_NL_ADMIN_PERM	= 1 << 0,
2562306a36Sopenharmony_ci};
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* Define this module as providing netlink services for NETLINK_RDMA, with
2862306a36Sopenharmony_ci * index _index.  Since the client indexes were setup in a uapi header as an
2962306a36Sopenharmony_ci * enum and we do no want to change that, the user must supply the expanded
3062306a36Sopenharmony_ci * constant as well and the compiler checks they are the same.
3162306a36Sopenharmony_ci */
3262306a36Sopenharmony_ci#define MODULE_ALIAS_RDMA_NETLINK(_index, _val)                                \
3362306a36Sopenharmony_ci	static inline void __maybe_unused __chk_##_index(void)                 \
3462306a36Sopenharmony_ci	{                                                                      \
3562306a36Sopenharmony_ci		BUILD_BUG_ON(_index != _val);                                  \
3662306a36Sopenharmony_ci	}                                                                      \
3762306a36Sopenharmony_ci	MODULE_ALIAS("rdma-netlink-subsys-" __stringify(_val))
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/**
4062306a36Sopenharmony_ci * Register client in RDMA netlink.
4162306a36Sopenharmony_ci * @index: Index of the added client
4262306a36Sopenharmony_ci * @cb_table: A table for op->callback
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_civoid rdma_nl_register(unsigned int index,
4562306a36Sopenharmony_ci		      const struct rdma_nl_cbs cb_table[]);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/**
4862306a36Sopenharmony_ci * Remove a client from IB netlink.
4962306a36Sopenharmony_ci * @index: Index of the removed IB client.
5062306a36Sopenharmony_ci */
5162306a36Sopenharmony_civoid rdma_nl_unregister(unsigned int index);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/**
5462306a36Sopenharmony_ci * Put a new message in a supplied skb.
5562306a36Sopenharmony_ci * @skb: The netlink skb.
5662306a36Sopenharmony_ci * @nlh: Pointer to put the header of the new netlink message.
5762306a36Sopenharmony_ci * @seq: The message sequence number.
5862306a36Sopenharmony_ci * @len: The requested message length to allocate.
5962306a36Sopenharmony_ci * @client: Calling IB netlink client.
6062306a36Sopenharmony_ci * @op: message content op.
6162306a36Sopenharmony_ci * Returns the allocated buffer on success and NULL on failure.
6262306a36Sopenharmony_ci */
6362306a36Sopenharmony_civoid *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq,
6462306a36Sopenharmony_ci		   int len, int client, int op, int flags);
6562306a36Sopenharmony_ci/**
6662306a36Sopenharmony_ci * Put a new attribute in a supplied skb.
6762306a36Sopenharmony_ci * @skb: The netlink skb.
6862306a36Sopenharmony_ci * @nlh: Header of the netlink message to append the attribute to.
6962306a36Sopenharmony_ci * @len: The length of the attribute data.
7062306a36Sopenharmony_ci * @data: The attribute data to put.
7162306a36Sopenharmony_ci * @type: The attribute type.
7262306a36Sopenharmony_ci * Returns the 0 and a negative error code on failure.
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_ciint ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh,
7562306a36Sopenharmony_ci		  int len, void *data, int type);
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci/**
7862306a36Sopenharmony_ci * Send the supplied skb to a specific userspace PID.
7962306a36Sopenharmony_ci * @net: Net namespace in which to send the skb
8062306a36Sopenharmony_ci * @skb: The netlink skb
8162306a36Sopenharmony_ci * @pid: Userspace netlink process ID
8262306a36Sopenharmony_ci * Returns 0 on success or a negative error code.
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_ciint rdma_nl_unicast(struct net *net, struct sk_buff *skb, u32 pid);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/**
8762306a36Sopenharmony_ci * Send, with wait/1 retry, the supplied skb to a specific userspace PID.
8862306a36Sopenharmony_ci * @net: Net namespace in which to send the skb
8962306a36Sopenharmony_ci * @skb: The netlink skb
9062306a36Sopenharmony_ci * @pid: Userspace netlink process ID
9162306a36Sopenharmony_ci * Returns 0 on success or a negative error code.
9262306a36Sopenharmony_ci */
9362306a36Sopenharmony_ciint rdma_nl_unicast_wait(struct net *net, struct sk_buff *skb, __u32 pid);
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci/**
9662306a36Sopenharmony_ci * Send the supplied skb to a netlink group.
9762306a36Sopenharmony_ci * @net: Net namespace in which to send the skb
9862306a36Sopenharmony_ci * @skb: The netlink skb
9962306a36Sopenharmony_ci * @group: Netlink group ID
10062306a36Sopenharmony_ci * @flags: allocation flags
10162306a36Sopenharmony_ci * Returns 0 on success or a negative error code.
10262306a36Sopenharmony_ci */
10362306a36Sopenharmony_ciint rdma_nl_multicast(struct net *net, struct sk_buff *skb,
10462306a36Sopenharmony_ci		      unsigned int group, gfp_t flags);
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/**
10762306a36Sopenharmony_ci * Check if there are any listeners to the netlink group
10862306a36Sopenharmony_ci * @group: the netlink group ID
10962306a36Sopenharmony_ci * Returns true on success or false if no listeners.
11062306a36Sopenharmony_ci */
11162306a36Sopenharmony_cibool rdma_nl_chk_listeners(unsigned int group);
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_cistruct rdma_link_ops {
11462306a36Sopenharmony_ci	struct list_head list;
11562306a36Sopenharmony_ci	const char *type;
11662306a36Sopenharmony_ci	int (*newlink)(const char *ibdev_name, struct net_device *ndev);
11762306a36Sopenharmony_ci};
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_civoid rdma_link_register(struct rdma_link_ops *ops);
12062306a36Sopenharmony_civoid rdma_link_unregister(struct rdma_link_ops *ops);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci#define MODULE_ALIAS_RDMA_LINK(type) MODULE_ALIAS("rdma-link-" type)
12362306a36Sopenharmony_ci#define MODULE_ALIAS_RDMA_CLIENT(type) MODULE_ALIAS("rdma-client-" type)
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci#endif /* _RDMA_NETLINK_H */
126