LCOV - code coverage report
Current view: top level - mptcp/token.c (source / functions) Coverage Total Hit
Test: export-net Lines: 86.8 % 204 177
Test Date: 2026-10-20 11:32:20 Functions: 100.0 % 13 13
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 58.7 % 104 61

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: GPL-2.0
       2                 :             : /* Multipath TCP token management
       3                 :             :  * Copyright (c) 2017 - 2019, Intel Corporation.
       4                 :             :  *
       5                 :             :  * Note: This code is based on mptcp_ctrl.c from multipath-tcp.org,
       6                 :             :  *       authored by:
       7                 :             :  *
       8                 :             :  *       Sébastien Barré <sebastien.barre@uclouvain.be>
       9                 :             :  *       Christoph Paasch <christoph.paasch@uclouvain.be>
      10                 :             :  *       Jaakko Korkeaniemi <jaakko.korkeaniemi@aalto.fi>
      11                 :             :  *       Gregory Detal <gregory.detal@uclouvain.be>
      12                 :             :  *       Fabien Duchêne <fabien.duchene@uclouvain.be>
      13                 :             :  *       Andreas Seelinger <Andreas.Seelinger@rwth-aachen.de>
      14                 :             :  *       Lavkesh Lahngir <lavkesh51@gmail.com>
      15                 :             :  *       Andreas Ripke <ripke@neclab.eu>
      16                 :             :  *       Vlad Dogaru <vlad.dogaru@intel.com>
      17                 :             :  *       Octavian Purdila <octavian.purdila@intel.com>
      18                 :             :  *       John Ronan <jronan@tssg.org>
      19                 :             :  *       Catalin Nicutar <catalin.nicutar@gmail.com>
      20                 :             :  *       Brandon Heller <brandonh@stanford.edu>
      21                 :             :  */
      22                 :             : 
      23                 :             : #define pr_fmt(fmt) "MPTCP: " fmt
      24                 :             : 
      25                 :             : #include <linux/kernel.h>
      26                 :             : #include <linux/module.h>
      27                 :             : #include <linux/memblock.h>
      28                 :             : #include <linux/ip.h>
      29                 :             : #include <linux/tcp.h>
      30                 :             : #include <net/sock.h>
      31                 :             : #include <net/inet_common.h>
      32                 :             : #include <net/protocol.h>
      33                 :             : #include <net/mptcp.h>
      34                 :             : #include "protocol.h"
      35                 :             : 
      36                 :             : #define TOKEN_MAX_CHAIN_LEN     4
      37                 :             : 
      38                 :             : struct token_bucket {
      39                 :             :         spinlock_t              lock;
      40                 :             :         int                     chain_len;
      41                 :             :         struct hlist_nulls_head req_chain;
      42                 :             :         struct hlist_nulls_head msk_chain;
      43                 :             : };
      44                 :             : 
      45                 :             : static struct token_bucket *token_hash __read_mostly;
      46                 :             : static unsigned int token_mask __read_mostly;
      47                 :             : 
      48                 :           0 : static struct token_bucket *token_bucket(u32 token)
      49                 :             : {
      50                 :        7096 :         return &token_hash[token & token_mask];
      51                 :             : }
      52                 :             : 
      53                 :             : /* called with bucket lock held */
      54                 :             : static struct mptcp_subflow_request_sock *
      55                 :           0 : __token_lookup_req(struct token_bucket *t, u32 token)
      56                 :             : {
      57                 :        4139 :         struct mptcp_subflow_request_sock *req;
      58                 :        4139 :         struct hlist_nulls_node *pos;
      59                 :             : 
      60   [ -  -  -  + ]:        5095 :         hlist_nulls_for_each_entry_rcu(req, pos, &t->req_chain, token_node)
      61   [ -  -  -  - ]:        1684 :                 if (req->token == token)
      62                 :             :                         return req;
      63                 :             :         return NULL;
      64                 :             : }
      65                 :             : 
      66                 :             : /* called with bucket lock held */
      67                 :             : static struct mptcp_sock *
      68                 :        6724 : __token_lookup_msk(struct token_bucket *t, u32 token)
      69                 :             : {
      70                 :        6724 :         struct hlist_nulls_node *pos;
      71                 :        6724 :         struct sock *sk;
      72                 :             : 
      73            [ + ]:        6747 :         sk_nulls_for_each_rcu(sk, pos, &t->msk_chain)
      74      [ +  -  + ]:        3336 :                 if (mptcp_sk(sk)->token == token)
      75            [ + ]:        3313 :                         return mptcp_sk(sk);
      76                 :             :         return NULL;
      77                 :             : }
      78                 :             : 
      79                 :        3411 : static bool __token_bucket_busy(struct token_bucket *t, u32 token)
      80                 :             : {
      81    [ +  - ][ + ]:        6756 :         return !token || t->chain_len >= TOKEN_MAX_CHAIN_LEN ||
      82         [ -  - ]:        6822 :                __token_lookup_req(t, token) || __token_lookup_msk(t, token);
              [ -  -  - ]
      83                 :             : }
      84                 :             : 
      85                 :        1733 : static void mptcp_crypto_key_gen_sha(u64 *key, u32 *token, u64 *idsn)
      86                 :             : {
      87                 :             :         /* we might consider a faster version that computes the key as a
      88                 :             :          * hash of some information available in the MPTCP socket. Use
      89                 :             :          * random data at the moment, as it's probably the safest option
      90                 :             :          * in case multiple sockets are opened in different namespaces at
      91                 :             :          * the same time.
      92                 :             :          */
      93                 :        1733 :         get_random_bytes(key, sizeof(u64));
      94                 :        1733 :         mptcp_crypto_key_sha(*key, token, idsn);
      95                 :        1733 : }
      96                 :             : 
      97                 :             : /**
      98                 :             :  * mptcp_token_new_request - create new key/idsn/token for subflow_request
      99                 :             :  * @req: the request socket
     100                 :             :  *
     101                 :             :  * This function is called when a new mptcp connection is coming in.
     102                 :             :  *
     103                 :             :  * It creates a unique token to identify the new mptcp connection,
     104                 :             :  * a secret local key and the initial data sequence number (idsn).
     105                 :             :  *
     106                 :             :  * Return: 0 on success.
     107                 :             :  */
     108                 :        1678 : int mptcp_token_new_request(struct request_sock *req)
     109                 :             : {
     110                 :        1678 :         struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
     111                 :        1678 :         struct token_bucket *bucket;
     112                 :        1678 :         u32 token;
     113                 :             : 
     114                 :        1678 :         mptcp_crypto_key_sha(subflow_req->local_key,
     115                 :             :                              &subflow_req->token,
     116                 :             :                              &subflow_req->idsn);
     117         [ -  - ]:        1678 :         pr_debug("req=%p local_key=%llu, token=%u, idsn=%llu\n",
     118                 :             :                  req, subflow_req->local_key, subflow_req->token,
     119                 :             :                  subflow_req->idsn);
     120                 :             : 
     121                 :        1678 :         token = subflow_req->token;
     122                 :        1678 :         bucket = token_bucket(token);
     123                 :        1678 :         spin_lock_bh(&bucket->lock);
     124            [ + ]:        1678 :         if (__token_bucket_busy(bucket, token)) {
     125                 :           0 :                 spin_unlock_bh(&bucket->lock);
     126                 :           0 :                 return -EBUSY;
     127                 :             :         }
     128                 :             : 
     129                 :        1678 :         hlist_nulls_add_head_rcu(&subflow_req->token_node, &bucket->req_chain);
     130                 :        1678 :         bucket->chain_len++;
     131                 :        1678 :         spin_unlock_bh(&bucket->lock);
     132                 :        1678 :         return 0;
     133                 :             : }
     134                 :             : 
     135                 :             : /**
     136                 :             :  * mptcp_token_new_connect - create new key/idsn/token for subflow
     137                 :             :  * @ssk: the socket that will initiate a connection
     138                 :             :  *
     139                 :             :  * This function is called when a new outgoing mptcp connection is
     140                 :             :  * initiated.
     141                 :             :  *
     142                 :             :  * It creates a unique token to identify the new mptcp connection,
     143                 :             :  * a secret local key and the initial data sequence number (idsn).
     144                 :             :  *
     145                 :             :  * On success, the mptcp connection can be found again using
     146                 :             :  * the computed token at a later time, this is needed to process
     147                 :             :  * join requests.
     148                 :             :  *
     149                 :             :  * Return: 0 on success.
     150                 :             :  */
     151                 :        1733 : int mptcp_token_new_connect(struct sock *ssk)
     152                 :             : {
     153            [ + ]:        1733 :         struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
     154            [ + ]:        1733 :         struct mptcp_sock *msk = mptcp_sk(subflow->conn);
     155                 :          30 :         int retries = MPTCP_TOKEN_MAX_RETRIES;
     156                 :             :         struct sock *sk = subflow->conn;
     157                 :          30 :         struct token_bucket *bucket;
     158                 :             : 
     159                 :        1733 : again:
     160                 :        1733 :         mptcp_crypto_key_gen_sha(&subflow->local_key, &subflow->token,
     161                 :             :                                  &subflow->idsn);
     162                 :             : 
     163                 :        1733 :         bucket = token_bucket(subflow->token);
     164                 :        1733 :         spin_lock_bh(&bucket->lock);
     165            [ + ]:        1733 :         if (__token_bucket_busy(bucket, subflow->token)) {
     166                 :           0 :                 spin_unlock_bh(&bucket->lock);
     167       [ # ][ # ]:           0 :                 if (!--retries)
     168                 :             :                         return -EBUSY;
     169                 :           0 :                 goto again;
     170                 :             :         }
     171                 :             : 
     172         [ -  - ]:        1733 :         pr_debug("ssk=%p, local_key=%llu, token=%u, idsn=%llu\n",
     173                 :             :                  ssk, subflow->local_key, subflow->token, subflow->idsn);
     174                 :             : 
     175                 :        1733 :         WRITE_ONCE(msk->token, subflow->token);
     176                 :        1733 :         __sk_nulls_add_node_rcu((struct sock *)msk, &bucket->msk_chain);
     177                 :        1733 :         bucket->chain_len++;
     178                 :        1733 :         spin_unlock_bh(&bucket->lock);
     179                 :        1733 :         sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
     180                 :        1733 :         return 0;
     181                 :             : }
     182                 :             : 
     183                 :             : /**
     184                 :             :  * mptcp_token_move_request - move request token ownership to a clone
     185                 :             :  * @req: original request socket
     186                 :             :  * @new_req: cloned request socket
     187                 :             :  *
     188                 :             :  * Move the token hash entry from the original request to its clone.
     189                 :             :  */
     190                 :          12 : void mptcp_token_move_request(struct request_sock *req,
     191                 :             :                               struct request_sock *new_req)
     192                 :             : {
     193                 :          12 :         struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
     194                 :          12 :         struct mptcp_subflow_request_sock *new_subflow_req;
     195                 :          12 :         struct mptcp_subflow_request_sock *pos;
     196                 :          12 :         struct token_bucket *bucket;
     197                 :             : 
     198                 :          12 :         new_subflow_req = mptcp_subflow_rsk(new_req);
     199                 :             : 
     200            [ + ]:          12 :         if (hlist_nulls_unhashed_lockless(&subflow_req->token_node)) {
     201                 :           6 :                 mptcp_token_init_request(new_req);
     202                 :           6 :                 return;
     203                 :             :         }
     204                 :             : 
     205                 :           6 :         bucket = token_bucket(subflow_req->token);
     206                 :           6 :         spin_lock_bh(&bucket->lock);
     207            [ + ]:           6 :         if (hlist_nulls_unhashed(&subflow_req->token_node)) {
     208                 :           0 :                 mptcp_token_init_request(new_req);
     209                 :             :         } else {
     210                 :           6 :                 pos = __token_lookup_req(bucket, subflow_req->token);
     211            [ - ]:           6 :                 if (pos == subflow_req)
     212                 :           6 :                         hlist_nulls_replace_init_rcu(&subflow_req->token_node,
     213                 :             :                                                      &new_subflow_req->token_node);
     214                 :             :                 else
     215                 :           0 :                         mptcp_token_init_request(new_req);
     216                 :             :         }
     217                 :           6 :         spin_unlock_bh(&bucket->lock);
     218                 :             : }
     219                 :             : 
     220                 :             : /**
     221                 :             :  * mptcp_token_accept - replace a req sk with full sock in token hash
     222                 :             :  * @req: the request socket to be removed
     223                 :             :  * @msk: the just cloned socket linked to the new connection
     224                 :             :  *
     225                 :             :  * Called when a SYN packet creates a new logical connection, i.e.
     226                 :             :  * is not a join request.
     227                 :             :  *
     228                 :             :  * Return: true on success.
     229                 :             :  */
     230                 :        1646 : bool mptcp_token_accept(struct mptcp_subflow_request_sock *req,
     231                 :             :                         struct mptcp_sock *msk)
     232                 :             : {
     233                 :        1646 :         struct mptcp_subflow_request_sock *pos;
     234                 :        1646 :         struct sock *sk = (struct sock *)msk;
     235                 :        1646 :         struct token_bucket *bucket;
     236                 :        1646 :         bool ret = false;
     237                 :             : 
     238                 :        1646 :         bucket = token_bucket(req->token);
     239                 :        1646 :         spin_lock_bh(&bucket->lock);
     240            [ + ]:        1646 :         if (hlist_nulls_unhashed(&req->token_node))
     241                 :           0 :                 goto unlock;
     242                 :             : 
     243                 :        1646 :         pos = __token_lookup_req(bucket, req->token);
     244            [ + ]:        1646 :         if (pos != req)
     245                 :           0 :                 goto unlock;
     246                 :             : 
     247                 :        1646 :         hlist_nulls_del_init_rcu(&req->token_node);
     248                 :        1646 :         __sk_nulls_add_node_rcu((struct sock *)msk, &bucket->msk_chain);
     249                 :             :         ret = true;
     250                 :             : 
     251                 :        1646 : unlock:
     252                 :        1646 :         spin_unlock_bh(&bucket->lock);
     253       [ - ][ - ]:        1646 :         if (ret)
     254                 :        1646 :                 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
     255                 :             : 
     256                 :        1646 :         return ret;
     257                 :             : }
     258                 :             : 
     259                 :          52 : bool mptcp_token_exists(u32 token)
     260                 :             : {
     261                 :          52 :         struct hlist_nulls_node *pos;
     262                 :          52 :         struct token_bucket *bucket;
     263                 :          52 :         struct mptcp_sock *msk;
     264                 :          52 :         struct sock *sk;
     265                 :             : 
     266                 :          52 :         rcu_read_lock();
     267                 :          52 :         bucket = token_bucket(token);
     268                 :             : 
     269                 :          52 : again:
     270       [ + ][ + ]:          52 :         sk_nulls_for_each_rcu(sk, pos, &bucket->msk_chain) {
     271 [ #  # ][ #  # ]:           0 :                 msk = mptcp_sk(sk);
     272       [ # ][ # ]:           0 :                 if (READ_ONCE(msk->token) == token)
     273                 :           0 :                         goto found;
     274                 :             :         }
     275       [ + ][ + ]:          52 :         if (get_nulls_value(pos) != (token & token_mask))
     276                 :           0 :                 goto again;
     277                 :             : 
     278                 :          52 :         rcu_read_unlock();
     279                 :          52 :         return false;
     280                 :           0 : found:
     281                 :           0 :         rcu_read_unlock();
     282                 :           0 :         return true;
     283                 :             : }
     284                 :             : 
     285                 :             : /**
     286                 :             :  * mptcp_token_get_sock - retrieve mptcp connection sock using its token
     287                 :             :  * @net: restrict to this namespace
     288                 :             :  * @token: token of the mptcp connection to retrieve
     289                 :             :  *
     290                 :             :  * This function returns the mptcp connection structure with the given token.
     291                 :             :  * A reference count on the mptcp socket returned is taken.
     292                 :             :  *
     293                 :             :  * Return: NULL if no connection with the given token value exists.
     294                 :             :  */
     295                 :         814 : struct mptcp_sock *mptcp_token_get_sock(struct net *net, u32 token)
     296                 :             : {
     297                 :         814 :         struct hlist_nulls_node *pos;
     298                 :         814 :         struct token_bucket *bucket;
     299                 :         814 :         struct mptcp_sock *msk;
     300                 :         814 :         struct sock *sk;
     301                 :             : 
     302                 :         814 :         rcu_read_lock();
     303                 :         814 :         bucket = token_bucket(token);
     304                 :             : 
     305                 :             : again:
     306       [ + ][ + ]:         814 :         sk_nulls_for_each_rcu(sk, pos, &bucket->msk_chain) {
     307 [ -  + ][ -  + ]:         800 :                 msk = mptcp_sk(sk);
     308 [ -  + ][ -  + ]:        1197 :                 if (READ_ONCE(msk->token) != token ||
               [ - ][ - ]
     309       [ + ][ + ]:           6 :                     !net_eq(sock_net(sk), net))
     310                 :           0 :                         continue;
     311                 :             : 
     312       [ + ][ + ]:         800 :                 if (!refcount_inc_not_zero(&sk->sk_refcnt))
     313                 :           2 :                         goto not_found;
     314                 :             : 
     315 [ -  + ][ -  + ]:        1194 :                 if (READ_ONCE(msk->token) != token ||
               [ - ][ - ]
     316       [ + ][ + ]:           6 :                     !net_eq(sock_net(sk), net)) {
     317                 :           0 :                         sock_put(sk);
     318                 :           0 :                         goto again;
     319                 :             :                 }
     320                 :         798 :                 goto found;
     321                 :             :         }
     322       [ + ][ + ]:          14 :         if (get_nulls_value(pos) != (token & token_mask))
     323                 :           0 :                 goto again;
     324                 :             : 
     325                 :          14 : not_found:
     326                 :             :         msk = NULL;
     327                 :             : 
     328                 :         814 : found:
     329                 :         814 :         rcu_read_unlock();
     330                 :         814 :         return msk;
     331                 :             : }
     332                 :             : EXPORT_SYMBOL_GPL(mptcp_token_get_sock);
     333                 :             : 
     334                 :             : /**
     335                 :             :  * mptcp_token_iter_next - iterate over the token container from given pos
     336                 :             :  * @net: namespace to be iterated
     337                 :             :  * @s_slot: start slot number
     338                 :             :  * @s_num: start number inside the given lock
     339                 :             :  *
     340                 :             :  * Description:
     341                 :             :  *   On successful iteration, the iterator is moved to the next position and a
     342                 :             :  *   reference to the returned socket is acquired.
     343                 :             :  *
     344                 :             :  * Return:
     345                 :             :  *   The first mptcp connection structure found inside the token container
     346                 :             :  *   starting from the specified position, or NULL.
     347                 :             :  */
     348                 :        5964 : struct mptcp_sock *mptcp_token_iter_next(const struct net *net, long *s_slot,
     349                 :             :                                          long *s_num)
     350                 :             : {
     351                 :        5964 :         struct mptcp_sock *ret = NULL;
     352                 :        5964 :         struct hlist_nulls_node *pos;
     353                 :        5964 :         int slot, num = 0;
     354                 :             : 
     355       [ + ][ + ]:    18839372 :         for (slot = *s_slot; slot <= token_mask; *s_num = 0, slot++) {
     356                 :    18836757 :                 struct token_bucket *bucket = &token_hash[slot];
     357                 :    18836757 :                 struct sock *sk;
     358                 :             : 
     359                 :    18836757 :                 num = 0;
     360                 :             : 
     361            [ + ]:    18836757 :                 if (hlist_nulls_empty(&bucket->msk_chain))
     362                 :    18825326 :                         continue;
     363                 :             : 
     364                 :       11431 :                 rcu_read_lock();
     365       [ + ][ + ]:       19667 :                 sk_nulls_for_each_rcu(sk, pos, &bucket->msk_chain) {
     366                 :       11585 :                         ++num;
     367 [ +  + ][ +  + ]:       11585 :                         if (!net_eq(sock_net(sk), net))
     368                 :        4837 :                                 continue;
     369                 :             : 
     370       [ + ][ + ]:        6748 :                         if (num <= *s_num)
     371                 :        3399 :                                 continue;
     372                 :             : 
     373       [ + ][ + ]:        3349 :                         if (!refcount_inc_not_zero(&sk->sk_refcnt))
     374                 :           0 :                                 continue;
     375                 :             : 
     376       [ + ][ + ]:        3349 :                         if (!net_eq(sock_net(sk), net)) {
     377                 :           0 :                                 sock_put(sk);
     378                 :           0 :                                 continue;
     379                 :             :                         }
     380                 :             : 
     381       [ + ][ + ]:        3349 :                         ret = mptcp_sk(sk);
     382                 :        3349 :                         rcu_read_unlock();
     383                 :        3349 :                         goto out;
     384                 :             :                 }
     385                 :        8082 :                 rcu_read_unlock();
     386                 :             :         }
     387                 :             : 
     388                 :        2615 : out:
     389                 :        5964 :         *s_slot = slot;
     390                 :        5964 :         *s_num = num;
     391                 :        5964 :         return ret;
     392                 :             : }
     393                 :             : EXPORT_SYMBOL_GPL(mptcp_token_iter_next);
     394                 :             : 
     395                 :             : /**
     396                 :             :  * mptcp_token_destroy_request - remove mptcp connection/token
     397                 :             :  * @req: mptcp request socket dropping the token
     398                 :             :  *
     399                 :             :  * Remove the token associated to @req.
     400                 :             :  */
     401                 :        2556 : void mptcp_token_destroy_request(struct request_sock *req)
     402                 :             : {
     403                 :        2556 :         struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
     404                 :        2556 :         struct mptcp_subflow_request_sock *pos;
     405                 :        2556 :         struct token_bucket *bucket;
     406                 :             : 
     407            [ + ]:        2556 :         if (hlist_nulls_unhashed_lockless(&subflow_req->token_node))
     408                 :             :                 return;
     409                 :             : 
     410                 :          32 :         bucket = token_bucket(subflow_req->token);
     411                 :          32 :         spin_lock_bh(&bucket->lock);
     412            [ + ]:          32 :         if (hlist_nulls_unhashed(&subflow_req->token_node))
     413                 :           0 :                 goto unlock;
     414                 :             : 
     415                 :          32 :         pos = __token_lookup_req(bucket, subflow_req->token);
     416            [ + ]:          32 :         if (pos == subflow_req) {
     417                 :          32 :                 hlist_nulls_del_init_rcu(&pos->token_node);
     418                 :          32 :                 bucket->chain_len--;
     419                 :             :         }
     420                 :             : 
     421                 :           0 : unlock:
     422                 :          32 :         spin_unlock_bh(&bucket->lock);
     423                 :             : }
     424                 :             : 
     425                 :             : /**
     426                 :             :  * mptcp_token_destroy - remove mptcp connection/token
     427                 :             :  * @msk: mptcp connection dropping the token
     428                 :             :  *
     429                 :             :  * Remove the token associated to @msk
     430                 :             :  */
     431                 :        5412 : void mptcp_token_destroy(struct mptcp_sock *msk)
     432                 :             : {
     433                 :        5412 :         struct sock *sk = (struct sock *)msk;
     434                 :        5412 :         struct token_bucket *bucket;
     435                 :        5412 :         struct mptcp_sock *pos;
     436                 :             : 
     437       [ + ][ + ]:        5412 :         if (sk_unhashed((struct sock *)msk))
     438                 :             :                 return;
     439                 :             : 
     440                 :        3313 :         sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
     441                 :        3313 :         bucket = token_bucket(msk->token);
     442                 :        3313 :         spin_lock_bh(&bucket->lock);
     443                 :        3313 :         pos = __token_lookup_msk(bucket, msk->token);
     444 [ +  - ][ +  - ]:        3313 :         if (!WARN_ON_ONCE(pos != msk)) {
     445       [ - ][ - ]:        3313 :                 __sk_nulls_del_node_init_rcu((struct sock *)pos);
     446                 :        3313 :                 bucket->chain_len--;
     447                 :             :         }
     448                 :        3313 :         spin_unlock_bh(&bucket->lock);
     449                 :        3313 :         WRITE_ONCE(msk->token, 0);
     450                 :             : }
     451                 :             : 
     452                 :           6 : void __init mptcp_token_init(void)
     453                 :             : {
     454                 :           6 :         int i;
     455                 :             : 
     456                 :           6 :         token_hash = alloc_large_system_hash("MPTCP token",
     457                 :             :                                              sizeof(struct token_bucket),
     458                 :             :                                              0,
     459                 :             :                                              20,/* one slot per 1MB of memory */
     460                 :             :                                              HASH_ZERO,
     461                 :             :                                              NULL,
     462                 :             :                                              &token_mask,
     463                 :             :                                              0,
     464                 :             :                                              64 * 1024);
     465       [ + ][ + ]:       49158 :         for (i = 0; i < token_mask + 1; ++i) {
     466                 :       49152 :                 INIT_HLIST_NULLS_HEAD(&token_hash[i].req_chain, i);
     467                 :       49152 :                 INIT_HLIST_NULLS_HEAD(&token_hash[i].msk_chain, i);
     468                 :       49152 :                 spin_lock_init(&token_hash[i].lock);
     469                 :             :         }
     470                 :           6 : }
     471                 :             : 
     472                 :             : #if IS_MODULE(CONFIG_MPTCP_KUNIT_TEST)
     473                 :             : EXPORT_SYMBOL_GPL(mptcp_token_new_request);
     474                 :             : EXPORT_SYMBOL_GPL(mptcp_token_new_connect);
     475                 :             : EXPORT_SYMBOL_GPL(mptcp_token_accept);
     476                 :             : EXPORT_SYMBOL_GPL(mptcp_token_destroy_request);
     477                 :             : EXPORT_SYMBOL_GPL(mptcp_token_destroy);
     478                 :             : #endif
        

Generated by: LCOV version 2.3.1-1