syncookies.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/skbuff.h>
  3. #include "protocol.h"
  4. /* Syncookies do not work for JOIN requests.
  5. *
  6. * Unlike MP_CAPABLE, where the ACK cookie contains the needed MPTCP
  7. * options to reconstruct the initial syn state, MP_JOIN does not contain
  8. * the token to obtain the mptcp socket nor the server-generated nonce
  9. * that was used in the cookie SYN/ACK response.
  10. *
  11. * Keep a small best effort state table to store the syn/synack data,
  12. * indexed by skb hash.
  13. *
  14. * A MP_JOIN SYN packet handled by syn cookies is only stored if the 32bit
  15. * token matches a known mptcp connection that can still accept more subflows.
  16. *
  17. * There is no timeout handling -- state is only re-constructed
  18. * when the TCP ACK passed the cookie validation check.
  19. */
  20. struct join_entry {
  21. u32 token;
  22. u32 remote_nonce;
  23. u32 local_nonce;
  24. u8 join_id;
  25. u8 local_id;
  26. u8 backup;
  27. u8 valid;
  28. };
  29. #define COOKIE_JOIN_SLOTS 1024
  30. static struct join_entry join_entries[COOKIE_JOIN_SLOTS] __cacheline_aligned_in_smp;
  31. static spinlock_t join_entry_locks[COOKIE_JOIN_SLOTS] __cacheline_aligned_in_smp;
  32. static u32 mptcp_join_entry_hash(struct sk_buff *skb, struct net *net)
  33. {
  34. static u32 mptcp_join_hash_secret __read_mostly;
  35. struct tcphdr *th = tcp_hdr(skb);
  36. u32 seq, i;
  37. net_get_random_once(&mptcp_join_hash_secret,
  38. sizeof(mptcp_join_hash_secret));
  39. if (th->syn)
  40. seq = TCP_SKB_CB(skb)->seq;
  41. else
  42. seq = TCP_SKB_CB(skb)->seq - 1;
  43. i = jhash_3words(seq, net_hash_mix(net),
  44. (__force __u32)th->source << 16 | (__force __u32)th->dest,
  45. mptcp_join_hash_secret);
  46. return i % ARRAY_SIZE(join_entries);
  47. }
  48. static void mptcp_join_store_state(struct join_entry *entry,
  49. const struct mptcp_subflow_request_sock *subflow_req)
  50. {
  51. entry->token = subflow_req->token;
  52. entry->remote_nonce = subflow_req->remote_nonce;
  53. entry->local_nonce = subflow_req->local_nonce;
  54. entry->backup = subflow_req->backup;
  55. entry->join_id = subflow_req->remote_id;
  56. entry->local_id = subflow_req->local_id;
  57. entry->valid = 1;
  58. }
  59. void subflow_init_req_cookie_join_save(const struct mptcp_subflow_request_sock *subflow_req,
  60. struct sk_buff *skb)
  61. {
  62. struct net *net = read_pnet(&subflow_req->sk.req.ireq_net);
  63. u32 i = mptcp_join_entry_hash(skb, net);
  64. /* No use in waiting if other cpu is already using this slot --
  65. * would overwrite the data that got stored.
  66. */
  67. spin_lock_bh(&join_entry_locks[i]);
  68. mptcp_join_store_state(&join_entries[i], subflow_req);
  69. spin_unlock_bh(&join_entry_locks[i]);
  70. }
  71. /* Called for a cookie-ack with MP_JOIN option present.
  72. * Look up the saved state based on skb hash & check token matches msk
  73. * in same netns.
  74. *
  75. * Caller will check msk can still accept another subflow. The hmac
  76. * present in the cookie ACK mptcp option space will be checked later.
  77. */
  78. bool mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_req,
  79. struct sk_buff *skb)
  80. {
  81. struct net *net = read_pnet(&subflow_req->sk.req.ireq_net);
  82. u32 i = mptcp_join_entry_hash(skb, net);
  83. struct mptcp_sock *msk;
  84. struct join_entry *e;
  85. e = &join_entries[i];
  86. spin_lock_bh(&join_entry_locks[i]);
  87. if (e->valid == 0) {
  88. spin_unlock_bh(&join_entry_locks[i]);
  89. return false;
  90. }
  91. e->valid = 0;
  92. msk = mptcp_token_get_sock(net, e->token);
  93. if (!msk) {
  94. spin_unlock_bh(&join_entry_locks[i]);
  95. return false;
  96. }
  97. subflow_req->remote_nonce = e->remote_nonce;
  98. subflow_req->local_nonce = e->local_nonce;
  99. subflow_req->backup = e->backup;
  100. subflow_req->remote_id = e->join_id;
  101. subflow_req->token = e->token;
  102. subflow_req->msk = msk;
  103. spin_unlock_bh(&join_entry_locks[i]);
  104. return true;
  105. }
  106. void __init mptcp_join_cookie_init(void)
  107. {
  108. int i;
  109. for (i = 0; i < COOKIE_JOIN_SLOTS; i++)
  110. spin_lock_init(&join_entry_locks[i]);
  111. }