LCOV - code coverage report
Current view: top level - home/net-next/net/quic - common.h (source / functions) Hit Total Coverage
Test: quic.info Lines: 27 31 87.1 %
Date: 2025-07-04 13:24:45 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0-or-later */
       2             : /* QUIC kernel implementation
       3             :  * (C) Copyright Red Hat Corp. 2023
       4             :  *
       5             :  * This file is part of the QUIC kernel implementation
       6             :  *
       7             :  * Written or modified by:
       8             :  *    Xin Long <lucien.xin@gmail.com>
       9             :  */
      10             : 
      11             : #include <net/netns/hash.h>
      12             : #include <linux/jhash.h>
      13             : 
      14             : #define QUIC_HT_SIZE            64
      15             : 
      16             : #define QUIC_MAX_ACK_DELAY      (16384 * 1000)
      17             : #define QUIC_DEF_ACK_DELAY      25000
      18             : 
      19             : #define QUIC_STREAM_BIT_FIN     0x01
      20             : #define QUIC_STREAM_BIT_LEN     0x02
      21             : #define QUIC_STREAM_BIT_OFF     0x04
      22             : #define QUIC_STREAM_BIT_MASK    0x08
      23             : 
      24             : #define QUIC_CONN_ID_MAX_LEN    20
      25             : #define QUIC_CONN_ID_DEF_LEN    8
      26             : 
      27             : struct quic_conn_id {
      28             :         u8 data[QUIC_CONN_ID_MAX_LEN];
      29             :         u8 len;
      30             : };
      31             : 
      32       17293 : static inline void quic_conn_id_update(struct quic_conn_id *conn_id, u8 *data, u32 len)
      33             : {
      34       34586 :         memcpy(conn_id->data, data, len);
      35       17293 :         conn_id->len = (u8)len;
      36       17293 : }
      37             : 
      38             : struct quic_skb_cb {
      39             :         /* Callback when encryption/decryption completes in async mode */
      40             :         void (*crypto_done)(struct sk_buff *skb, int err);
      41             :         union {
      42             :                 struct sk_buff *last;           /* Last packet in TX bundle */
      43             :                 s64 seqno;                      /* Dest connection ID number on RX */
      44             :         };
      45             :         s64 number_max;         /* Largest packet number seen before parsing this one */
      46             :         s64 number;             /* Parsed packet number */
      47             :         u16 errcode;            /* Error code if encryption/decryption fails */
      48             :         u16 length;             /* Payload length + packet number length */
      49             :         u32 time;               /* Arrival time in UDP tunnel */
      50             : 
      51             :         u16 number_offset;      /* Offset of packet number field */
      52             :         u16 udph_offset;        /* Offset of UDP header */
      53             :         u8 number_len;          /* Length of the packet number field */
      54             :         u8 level;               /* Encryption level: Initial, Handshake, App, or Early */
      55             : 
      56             :         u8 key_update:1;        /* Key update triggered by this packet */
      57             :         u8 key_phase:1;         /* Key phase used (0 or 1) */
      58             :         u8 resume:1;            /* Crypto already processed (encrypted or decrypted) */
      59             :         u8 path:1;              /* Packet arrived from a new or migrating path */
      60             :         u8 ecn:2;               /* ECN marking used on TX */
      61             : };
      62             : 
      63             : #define QUIC_SKB_CB(skb)        ((struct quic_skb_cb *)&((skb)->cb[0]))
      64             : 
      65     6577299 : static inline struct udphdr *quic_udphdr(const struct sk_buff *skb)
      66             : {
      67     6577299 :         return (struct udphdr *)(skb->head + QUIC_SKB_CB(skb)->udph_offset);
      68             : }
      69             : 
      70             : struct quichdr {
      71             : #if defined(__LITTLE_ENDIAN_BITFIELD)
      72             :         __u8 pnl:2,
      73             :              key:1,
      74             :              reserved:2,
      75             :              spin:1,
      76             :              fixed:1,
      77             :              form:1;
      78             : #elif defined(__BIG_ENDIAN_BITFIELD)
      79             :         __u8 form:1,
      80             :              fixed:1,
      81             :              spin:1,
      82             :              reserved:2,
      83             :              key:1,
      84             :              pnl:2;
      85             : #endif
      86             : };
      87             : 
      88    49456072 : static inline struct quichdr *quic_hdr(struct sk_buff *skb)
      89             : {
      90    49456267 :         return (struct quichdr *)skb_transport_header(skb);
      91             : }
      92             : 
      93             : struct quichshdr {
      94             : #if defined(__LITTLE_ENDIAN_BITFIELD)
      95             :         __u8 pnl:2,
      96             :              reserved:2,
      97             :              type:2,
      98             :              fixed:1,
      99             :              form:1;
     100             : #elif defined(__BIG_ENDIAN_BITFIELD)
     101             :         __u8 form:1,
     102             :              fixed:1,
     103             :              type:2,
     104             :              reserved:2,
     105             :              pnl:2;
     106             : #endif
     107             : };
     108             : 
     109       15945 : static inline struct quichshdr *quic_hshdr(struct sk_buff *skb)
     110             : {
     111       15945 :         return (struct quichshdr *)skb_transport_header(skb);
     112             : }
     113             : 
     114             : union quic_addr {
     115             :         struct sockaddr_in6 v6;
     116             :         struct sockaddr_in v4;
     117             :         struct sockaddr sa;
     118             : };
     119             : 
     120             : static inline union quic_addr *quic_addr(const void *addr)
     121             : {
     122             :         return (union quic_addr *)addr;
     123             : }
     124             : 
     125             : struct quic_hash_head {
     126             :         struct hlist_head       head;
     127             :         union {
     128             :                 spinlock_t      s_lock; /* Protects 'head' in atomic context */
     129             :                 struct mutex    m_lock; /* Protects 'head' in process context */
     130             :         };
     131             : };
     132             : 
     133             : struct quic_hash_table {
     134             :         struct quic_hash_head *hash;
     135             :         int size;
     136             : };
     137             : 
     138             : enum  {
     139             :         QUIC_HT_SOCK,           /* Hash table for QUIC sockets */
     140             :         QUIC_HT_UDP_SOCK,       /* Hash table for UDP tunnel sockets */
     141             :         QUIC_HT_LISTEN_SOCK,    /* Hash table for QUIC listening sockets */
     142             :         QUIC_HT_CONNECTION_ID,  /* Hash table for source connection IDs */
     143             :         QUIC_HT_MAX_TABLES,
     144             : };
     145             : 
     146           0 : static inline u32 quic_shash(const struct net *net, const union quic_addr *a)
     147             : {
     148           0 :         u32 addr = (a->sa.sa_family == AF_INET6) ? jhash(&a->v6.sin6_addr, 16, 0)
     149           0 :                                                  : (__force u32)a->v4.sin_addr.s_addr;
     150             : 
     151           0 :         return  jhash_3words(addr, (__force u32)a->v4.sin_port, net_hash_mix(net), 0);
     152             : }
     153             : 
     154        6362 : static inline u32 quic_ahash(const struct net *net, const union quic_addr *s,
     155             :                              const union quic_addr *d)
     156             : {
     157        6362 :         u32 ports = ((__force u32)s->v4.sin_port) << 16 | (__force u32)d->v4.sin_port;
     158        3028 :         u32 saddr = (s->sa.sa_family == AF_INET6) ? jhash(&s->v6.sin6_addr, 16, 0)
     159        6362 :                                                   : (__force u32)s->v4.sin_addr.s_addr;
     160        3028 :         u32 daddr = (d->sa.sa_family == AF_INET6) ? jhash(&d->v6.sin6_addr, 16, 0)
     161        6362 :                                                   : (__force u32)d->v4.sin_addr.s_addr;
     162             : 
     163        6362 :         return  jhash_3words(saddr, ports, net_hash_mix(net), daddr);
     164             : }
     165             : 
     166             : struct quic_data {
     167             :         u8 *data;
     168             :         u32 len;
     169             : };
     170             : 
     171       36840 : static inline struct quic_data *quic_data(struct quic_data *d, u8 *data, u32 len)
     172             : {
     173       36856 :         d->data = data;
     174       36470 :         d->len  = len;
     175       29545 :         return d;
     176             : }
     177             : 
     178         386 : static inline int quic_data_cmp(struct quic_data *d1, struct quic_data *d2)
     179             : {
     180         748 :         return d1->len != d2->len || memcmp(d1->data, d2->data, d1->len);
     181             : }
     182             : 
     183        5340 : static inline void quic_data_free(struct quic_data *d)
     184             : {
     185        2111 :         kfree(d->data);
     186        5340 :         d->data = NULL;
     187        2111 :         d->len = 0;
     188             : }
     189             : 
     190             : struct quic_hash_head *quic_sock_head(struct net *net, union quic_addr *s, union quic_addr *d);
     191             : struct quic_hash_head *quic_listen_sock_head(struct net *net, u16 port);
     192             : struct quic_hash_head *quic_stream_head(struct quic_hash_table *ht, s64 stream_id);
     193             : struct quic_hash_head *quic_source_conn_id_head(struct net *net, u8 *scid);
     194             : struct quic_hash_head *quic_udp_sock_head(struct net *net, u16 port);
     195             : 
     196             : struct quic_hash_head *quic_sock_hash(u32 hash);
     197             : void quic_hash_tables_destroy(void);
     198             : int quic_hash_tables_init(void);
     199             : 
     200             : u32 quic_get_data(u8 **pp, u32 *plen, u8 *data, u32 len);
     201             : u32 quic_get_int(u8 **pp, u32 *plen, u64 *val, u32 len);
     202             : s64 quic_get_num(s64 max_pkt_num, s64 pkt_num, u32 n);
     203             : u8 quic_get_param(u64 *pdest, u8 **pp, u32 *plen);
     204             : u8 quic_get_var(u8 **pp, u32 *plen, u64 *val);
     205             : u8 quic_var_len(u64 n);
     206             : 
     207             : u8 *quic_put_param(u8 *p, u16 id, u64 value);
     208             : u8 *quic_put_data(u8 *p, u8 *data, u32 len);
     209             : u8 *quic_put_varint(u8 *p, u64 num, u8 len);
     210             : u8 *quic_put_int(u8 *p, u64 num, u8 len);
     211             : u8 *quic_put_var(u8 *p, u64 num);
     212             : 
     213             : void quic_data_from_string(struct quic_data *to, u8 *from, u32 len);
     214             : void quic_data_to_string(u8 *to, u32 *plen, struct quic_data *from);
     215             : 
     216             : int quic_data_match(struct quic_data *d1, struct quic_data *d2);
     217             : int quic_data_append(struct quic_data *to, u8 *data, u32 len);
     218             : int quic_data_has(struct quic_data *d1, struct quic_data *d2);
     219             : int quic_data_dup(struct quic_data *to, u8 *data, u32 len);

Generated by: LCOV version 1.14