xref: /openbmc/linux/net/handshake/handshake.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
13b3009eaSChuck Lever /* SPDX-License-Identifier: GPL-2.0-only */
23b3009eaSChuck Lever /*
33b3009eaSChuck Lever  * Generic netlink handshake service
43b3009eaSChuck Lever  *
53b3009eaSChuck Lever  * Author: Chuck Lever <chuck.lever@oracle.com>
63b3009eaSChuck Lever  *
73b3009eaSChuck Lever  * Copyright (c) 2023, Oracle and/or its affiliates.
83b3009eaSChuck Lever  */
93b3009eaSChuck Lever 
103b3009eaSChuck Lever #ifndef _INTERNAL_HANDSHAKE_H
113b3009eaSChuck Lever #define _INTERNAL_HANDSHAKE_H
123b3009eaSChuck Lever 
133b3009eaSChuck Lever /* Per-net namespace context */
143b3009eaSChuck Lever struct handshake_net {
153b3009eaSChuck Lever 	spinlock_t		hn_lock;	/* protects next 3 fields */
163b3009eaSChuck Lever 	int			hn_pending;
173b3009eaSChuck Lever 	int			hn_pending_max;
183b3009eaSChuck Lever 	struct list_head	hn_requests;
193b3009eaSChuck Lever 
203b3009eaSChuck Lever 	unsigned long		hn_flags;
213b3009eaSChuck Lever };
223b3009eaSChuck Lever 
233b3009eaSChuck Lever enum hn_flags_bits {
243b3009eaSChuck Lever 	HANDSHAKE_F_NET_DRAINING,
253b3009eaSChuck Lever };
263b3009eaSChuck Lever 
273b3009eaSChuck Lever struct handshake_proto;
283b3009eaSChuck Lever 
293b3009eaSChuck Lever /* One handshake request */
303b3009eaSChuck Lever struct handshake_req {
313b3009eaSChuck Lever 	struct list_head		hr_list;
323b3009eaSChuck Lever 	struct rhash_head		hr_rhash;
333b3009eaSChuck Lever 	unsigned long			hr_flags;
343b3009eaSChuck Lever 	const struct handshake_proto	*hr_proto;
353b3009eaSChuck Lever 	struct sock			*hr_sk;
363b3009eaSChuck Lever 	void				(*hr_odestruct)(struct sock *sk);
373b3009eaSChuck Lever 
383b3009eaSChuck Lever 	/* Always the last field */
393b3009eaSChuck Lever 	char				hr_priv[];
403b3009eaSChuck Lever };
413b3009eaSChuck Lever 
423b3009eaSChuck Lever enum hr_flags_bits {
433b3009eaSChuck Lever 	HANDSHAKE_F_REQ_COMPLETED,
44*35b1b538SChuck Lever 	HANDSHAKE_F_REQ_SESSION,
453b3009eaSChuck Lever };
463b3009eaSChuck Lever 
47*35b1b538SChuck Lever struct genl_info;
48*35b1b538SChuck Lever 
493b3009eaSChuck Lever /* Invariants for all handshake requests for one transport layer
503b3009eaSChuck Lever  * security protocol
513b3009eaSChuck Lever  */
523b3009eaSChuck Lever struct handshake_proto {
533b3009eaSChuck Lever 	int			hp_handler_class;
543b3009eaSChuck Lever 	size_t			hp_privsize;
5588232ec1SChuck Lever 	unsigned long		hp_flags;
563b3009eaSChuck Lever 
573b3009eaSChuck Lever 	int			(*hp_accept)(struct handshake_req *req,
583b3009eaSChuck Lever 					     struct genl_info *info, int fd);
593b3009eaSChuck Lever 	void			(*hp_done)(struct handshake_req *req,
603b3009eaSChuck Lever 					   unsigned int status,
613b3009eaSChuck Lever 					   struct genl_info *info);
623b3009eaSChuck Lever 	void			(*hp_destroy)(struct handshake_req *req);
633b3009eaSChuck Lever };
643b3009eaSChuck Lever 
6588232ec1SChuck Lever enum hp_flags_bits {
6688232ec1SChuck Lever 	HANDSHAKE_F_PROTO_NOTIFY,
6788232ec1SChuck Lever };
6888232ec1SChuck Lever 
69*35b1b538SChuck Lever /* alert.c */
70*35b1b538SChuck Lever int tls_alert_send(struct socket *sock, u8 level, u8 description);
71*35b1b538SChuck Lever 
723b3009eaSChuck Lever /* netlink.c */
733b3009eaSChuck Lever int handshake_genl_notify(struct net *net, const struct handshake_proto *proto,
743b3009eaSChuck Lever 			  gfp_t flags);
753b3009eaSChuck Lever struct nlmsghdr *handshake_genl_put(struct sk_buff *msg,
763b3009eaSChuck Lever 				    struct genl_info *info);
773b3009eaSChuck Lever struct handshake_net *handshake_pernet(struct net *net);
783b3009eaSChuck Lever 
793b3009eaSChuck Lever /* request.c */
803b3009eaSChuck Lever struct handshake_req *handshake_req_alloc(const struct handshake_proto *proto,
813b3009eaSChuck Lever 					  gfp_t flags);
823b3009eaSChuck Lever int handshake_req_hash_init(void);
833b3009eaSChuck Lever void handshake_req_hash_destroy(void);
843b3009eaSChuck Lever void *handshake_req_private(struct handshake_req *req);
853b3009eaSChuck Lever struct handshake_req *handshake_req_hash_lookup(struct sock *sk);
863b3009eaSChuck Lever struct handshake_req *handshake_req_next(struct handshake_net *hn, int class);
873b3009eaSChuck Lever int handshake_req_submit(struct socket *sock, struct handshake_req *req,
883b3009eaSChuck Lever 			 gfp_t flags);
893b3009eaSChuck Lever void handshake_complete(struct handshake_req *req, unsigned int status,
903b3009eaSChuck Lever 			struct genl_info *info);
913b3009eaSChuck Lever bool handshake_req_cancel(struct sock *sk);
923b3009eaSChuck Lever 
933b3009eaSChuck Lever #endif /* _INTERNAL_HANDSHAKE_H */
94