diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2012-01-31 00:18:33 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-01-31 12:14:00 -0500 |
commit | a915da9b69273815527ccb3789421cb7027b545b (patch) | |
tree | 79b266da33febc50bc54adc033ac9e38a1750bcf /include/net/tcp.h | |
parent | a2d91241a80ec9bbc5ab24b9a2c4d730b3fa5730 (diff) |
tcp: md5: rcu conversion
In order to be able to support proper RST messages for TCP MD5 flows, we
need to allow access to MD5 keys without locking listener socket.
This conversion is a nice cleanup, and shrinks size of timewait sockets
by 80 bytes.
IPv6 code reuses generic code found in IPv4 instead of duplicating it.
Control path uses GFP_KERNEL allocations instead of GFP_ATOMIC.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Shawn Lu <shawn.lu@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/tcp.h')
-rw-r--r-- | include/net/tcp.h | 61 |
1 files changed, 29 insertions, 32 deletions
diff --git a/include/net/tcp.h b/include/net/tcp.h index 3c903462adf5..10ae4c7b6b4f 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -1130,35 +1130,26 @@ static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp) | |||
1130 | /* MD5 Signature */ | 1130 | /* MD5 Signature */ |
1131 | struct crypto_hash; | 1131 | struct crypto_hash; |
1132 | 1132 | ||
1133 | union tcp_md5_addr { | ||
1134 | struct in_addr a4; | ||
1135 | #if IS_ENABLED(CONFIG_IPV6) | ||
1136 | struct in6_addr a6; | ||
1137 | #endif | ||
1138 | }; | ||
1139 | |||
1133 | /* - key database */ | 1140 | /* - key database */ |
1134 | struct tcp_md5sig_key { | 1141 | struct tcp_md5sig_key { |
1135 | u8 *key; | 1142 | struct hlist_node node; |
1136 | u8 keylen; | 1143 | u8 keylen; |
1137 | }; | 1144 | u8 family; /* AF_INET or AF_INET6 */ |
1138 | 1145 | union tcp_md5_addr addr; | |
1139 | struct tcp4_md5sig_key { | 1146 | u8 key[TCP_MD5SIG_MAXKEYLEN]; |
1140 | struct tcp_md5sig_key base; | 1147 | struct rcu_head rcu; |
1141 | __be32 addr; | ||
1142 | }; | ||
1143 | |||
1144 | struct tcp6_md5sig_key { | ||
1145 | struct tcp_md5sig_key base; | ||
1146 | #if 0 | ||
1147 | u32 scope_id; /* XXX */ | ||
1148 | #endif | ||
1149 | struct in6_addr addr; | ||
1150 | }; | 1148 | }; |
1151 | 1149 | ||
1152 | /* - sock block */ | 1150 | /* - sock block */ |
1153 | struct tcp_md5sig_info { | 1151 | struct tcp_md5sig_info { |
1154 | struct tcp4_md5sig_key *keys4; | 1152 | struct hlist_head head; |
1155 | #if IS_ENABLED(CONFIG_IPV6) | ||
1156 | struct tcp6_md5sig_key *keys6; | ||
1157 | u32 entries6; | ||
1158 | u32 alloced6; | ||
1159 | #endif | ||
1160 | u32 entries4; | ||
1161 | u32 alloced4; | ||
1162 | }; | 1153 | }; |
1163 | 1154 | ||
1164 | /* - pseudo header */ | 1155 | /* - pseudo header */ |
@@ -1195,19 +1186,25 @@ extern int tcp_v4_md5_hash_skb(char *md5_hash, struct tcp_md5sig_key *key, | |||
1195 | const struct sock *sk, | 1186 | const struct sock *sk, |
1196 | const struct request_sock *req, | 1187 | const struct request_sock *req, |
1197 | const struct sk_buff *skb); | 1188 | const struct sk_buff *skb); |
1198 | extern struct tcp_md5sig_key * tcp_v4_md5_lookup(struct sock *sk, | 1189 | extern int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, |
1199 | struct sock *addr_sk); | 1190 | int family, const u8 *newkey, |
1200 | extern int tcp_v4_md5_do_add(struct sock *sk, __be32 addr, u8 *newkey, | 1191 | u8 newkeylen, gfp_t gfp); |
1201 | u8 newkeylen); | 1192 | extern int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, |
1202 | extern int tcp_v4_md5_do_del(struct sock *sk, __be32 addr); | 1193 | int family); |
1194 | extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, | ||
1195 | struct sock *addr_sk); | ||
1203 | 1196 | ||
1204 | #ifdef CONFIG_TCP_MD5SIG | 1197 | #ifdef CONFIG_TCP_MD5SIG |
1205 | #define tcp_twsk_md5_key(twsk) ((twsk)->tw_md5_keylen ? \ | 1198 | extern struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk, |
1206 | &(struct tcp_md5sig_key) { \ | 1199 | const union tcp_md5_addr *addr, int family); |
1207 | .key = (twsk)->tw_md5_key, \ | 1200 | #define tcp_twsk_md5_key(twsk) ((twsk)->tw_md5_key) |
1208 | .keylen = (twsk)->tw_md5_keylen, \ | ||
1209 | } : NULL) | ||
1210 | #else | 1201 | #else |
1202 | static inline struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk, | ||
1203 | const union tcp_md5_addr *addr, | ||
1204 | int family) | ||
1205 | { | ||
1206 | return NULL; | ||
1207 | } | ||
1211 | #define tcp_twsk_md5_key(twsk) NULL | 1208 | #define tcp_twsk_md5_key(twsk) NULL |
1212 | #endif | 1209 | #endif |
1213 | 1210 | ||