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 | |