net/tcp: Prevent TCP-MD5 with TCP-AO being set
[linux-2.6-block.git] / include / net / tcp_ao.h
CommitLineData
c845f5f3
DS
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2#ifndef _TCP_AO_H
3#define _TCP_AO_H
4
5#define TCP_AO_KEY_ALIGN 1
6#define __tcp_ao_key_align __aligned(TCP_AO_KEY_ALIGN)
7
8union tcp_ao_addr {
9 struct in_addr a4;
10#if IS_ENABLED(CONFIG_IPV6)
11 struct in6_addr a6;
12#endif
13};
14
15struct tcp_ao_hdr {
16 u8 kind;
17 u8 length;
18 u8 keyid;
19 u8 rnext_keyid;
20};
21
22struct tcp_ao_key {
23 struct hlist_node node;
24 union tcp_ao_addr addr;
25 u8 key[TCP_AO_MAXKEYLEN] __tcp_ao_key_align;
26 unsigned int tcp_sigpool_id;
27 unsigned int digest_size;
28 u8 prefixlen;
29 u8 family;
30 u8 keylen;
31 u8 keyflags;
32 u8 sndid;
33 u8 rcvid;
34 u8 maclen;
35 struct rcu_head rcu;
36 u8 traffic_keys[];
37};
38
39static inline u8 *rcv_other_key(struct tcp_ao_key *key)
40{
41 return key->traffic_keys;
42}
43
44static inline u8 *snd_other_key(struct tcp_ao_key *key)
45{
46 return key->traffic_keys + key->digest_size;
47}
48
49static inline int tcp_ao_maclen(const struct tcp_ao_key *key)
50{
51 return key->maclen;
52}
53
54static inline int tcp_ao_len(const struct tcp_ao_key *key)
55{
56 return tcp_ao_maclen(key) + sizeof(struct tcp_ao_hdr);
57}
58
59static inline unsigned int tcp_ao_digest_size(struct tcp_ao_key *key)
60{
61 return key->digest_size;
62}
63
64static inline int tcp_ao_sizeof_key(const struct tcp_ao_key *key)
65{
66 return sizeof(struct tcp_ao_key) + (key->digest_size << 1);
67}
68
69struct tcp_ao_info {
70 /* List of tcp_ao_key's */
71 struct hlist_head head;
72 /* current_key and rnext_key aren't maintained on listen sockets.
73 * Their purpose is to cache keys on established connections,
74 * saving needless lookups. Never dereference any of them from
75 * listen sockets.
76 * ::current_key may change in RX to the key that was requested by
77 * the peer, please use READ_ONCE()/WRITE_ONCE() in order to avoid
78 * load/store tearing.
79 * Do the same for ::rnext_key, if you don't hold socket lock
80 * (it's changed only by userspace request in setsockopt()).
81 */
82 struct tcp_ao_key *current_key;
83 struct tcp_ao_key *rnext_key;
4954f17d
DS
84 u32 ao_required :1,
85 __unused :31;
c845f5f3
DS
86 __be32 lisn;
87 __be32 risn;
88 struct rcu_head rcu;
89};
90
4954f17d
DS
91#ifdef CONFIG_TCP_AO
92int tcp_parse_ao(struct sock *sk, int cmd, unsigned short int family,
93 sockptr_t optval, int optlen);
94void tcp_ao_destroy_sock(struct sock *sk);
0aadc739
DS
95struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk,
96 const union tcp_ao_addr *addr,
97 int family, int sndid, int rcvid);
4954f17d
DS
98/* ipv4 specific functions */
99int tcp_v4_parse_ao(struct sock *sk, int cmd, sockptr_t optval, int optlen);
0aadc739
DS
100struct tcp_ao_key *tcp_v4_ao_lookup(const struct sock *sk, struct sock *addr_sk,
101 int sndid, int rcvid);
4954f17d
DS
102/* ipv6 specific functions */
103int tcp_v6_parse_ao(struct sock *sk, int cmd, sockptr_t optval, int optlen);
0aadc739
DS
104struct tcp_ao_key *tcp_v6_ao_lookup(const struct sock *sk,
105 struct sock *addr_sk, int sndid, int rcvid);
4954f17d 106#else
0aadc739
DS
107static inline struct tcp_ao_key *tcp_ao_do_lookup(const struct sock *sk,
108 const union tcp_ao_addr *addr, int family, int sndid, int rcvid)
109{
110 return NULL;
111}
112
4954f17d
DS
113static inline void tcp_ao_destroy_sock(struct sock *sk)
114{
115}
116#endif
117
c845f5f3 118#endif /* _TCP_AO_H */