| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 
|---|
| 2 | /* | 
|---|
| 3 | * Generic netlink handshake service | 
|---|
| 4 | * | 
|---|
| 5 | * Author: Chuck Lever <chuck.lever@oracle.com> | 
|---|
| 6 | * | 
|---|
| 7 | * Copyright (c) 2023, Oracle and/or its affiliates. | 
|---|
| 8 | */ | 
|---|
| 9 |  | 
|---|
| 10 | #ifndef _INTERNAL_HANDSHAKE_H | 
|---|
| 11 | #define _INTERNAL_HANDSHAKE_H | 
|---|
| 12 |  | 
|---|
| 13 | /* Per-net namespace context */ | 
|---|
| 14 | struct handshake_net { | 
|---|
| 15 | spinlock_t		hn_lock;	/* protects next 3 fields */ | 
|---|
| 16 | int			hn_pending; | 
|---|
| 17 | int			hn_pending_max; | 
|---|
| 18 | struct list_head	hn_requests; | 
|---|
| 19 |  | 
|---|
| 20 | unsigned long		hn_flags; | 
|---|
| 21 | }; | 
|---|
| 22 |  | 
|---|
| 23 | enum hn_flags_bits { | 
|---|
| 24 | HANDSHAKE_F_NET_DRAINING, | 
|---|
| 25 | }; | 
|---|
| 26 |  | 
|---|
| 27 | struct handshake_proto; | 
|---|
| 28 |  | 
|---|
| 29 | /* One handshake request */ | 
|---|
| 30 | struct handshake_req { | 
|---|
| 31 | struct list_head		hr_list; | 
|---|
| 32 | struct rhash_head		hr_rhash; | 
|---|
| 33 | unsigned long			hr_flags; | 
|---|
| 34 | const struct handshake_proto	*hr_proto; | 
|---|
| 35 | struct sock			*hr_sk; | 
|---|
| 36 | void				(*hr_odestruct)(struct sock *sk); | 
|---|
| 37 |  | 
|---|
| 38 | /* Always the last field */ | 
|---|
| 39 | char				hr_priv[]; | 
|---|
| 40 | }; | 
|---|
| 41 |  | 
|---|
| 42 | enum hr_flags_bits { | 
|---|
| 43 | HANDSHAKE_F_REQ_COMPLETED, | 
|---|
| 44 | HANDSHAKE_F_REQ_SESSION, | 
|---|
| 45 | }; | 
|---|
| 46 |  | 
|---|
| 47 | struct genl_info; | 
|---|
| 48 |  | 
|---|
| 49 | /* Invariants for all handshake requests for one transport layer | 
|---|
| 50 | * security protocol | 
|---|
| 51 | */ | 
|---|
| 52 | struct handshake_proto { | 
|---|
| 53 | int			hp_handler_class; | 
|---|
| 54 | size_t			hp_privsize; | 
|---|
| 55 | unsigned long		hp_flags; | 
|---|
| 56 |  | 
|---|
| 57 | int			(*hp_accept)(struct handshake_req *req, | 
|---|
| 58 | struct genl_info *info, int fd); | 
|---|
| 59 | void			(*hp_done)(struct handshake_req *req, | 
|---|
| 60 | unsigned int status, | 
|---|
| 61 | struct genl_info *info); | 
|---|
| 62 | void			(*hp_destroy)(struct handshake_req *req); | 
|---|
| 63 | }; | 
|---|
| 64 |  | 
|---|
| 65 | enum hp_flags_bits { | 
|---|
| 66 | HANDSHAKE_F_PROTO_NOTIFY, | 
|---|
| 67 | }; | 
|---|
| 68 |  | 
|---|
| 69 | /* alert.c */ | 
|---|
| 70 | int tls_alert_send(struct socket *sock, u8 level, u8 description); | 
|---|
| 71 |  | 
|---|
| 72 | /* netlink.c */ | 
|---|
| 73 | int handshake_genl_notify(struct net *net, const struct handshake_proto *proto, | 
|---|
| 74 | gfp_t flags); | 
|---|
| 75 | struct nlmsghdr *handshake_genl_put(struct sk_buff *msg, | 
|---|
| 76 | struct genl_info *info); | 
|---|
| 77 | struct handshake_net *handshake_pernet(struct net *net); | 
|---|
| 78 |  | 
|---|
| 79 | /* request.c */ | 
|---|
| 80 | struct handshake_req *handshake_req_alloc(const struct handshake_proto *proto, | 
|---|
| 81 | gfp_t flags); | 
|---|
| 82 | int handshake_req_hash_init(void); | 
|---|
| 83 | void handshake_req_hash_destroy(void); | 
|---|
| 84 | void *handshake_req_private(struct handshake_req *req); | 
|---|
| 85 | struct handshake_req *handshake_req_hash_lookup(struct sock *sk); | 
|---|
| 86 | struct handshake_req *handshake_req_next(struct handshake_net *hn, int class); | 
|---|
| 87 | int handshake_req_submit(struct socket *sock, struct handshake_req *req, | 
|---|
| 88 | gfp_t flags); | 
|---|
| 89 | void handshake_complete(struct handshake_req *req, unsigned int status, | 
|---|
| 90 | struct genl_info *info); | 
|---|
| 91 | bool handshake_req_cancel(struct sock *sk); | 
|---|
| 92 |  | 
|---|
| 93 | #endif /* _INTERNAL_HANDSHAKE_H */ | 
|---|
| 94 |  | 
|---|