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