LCOV - code coverage report
Current view: top level - home/net-next/net/quic - path.h (source / functions) Hit Total Coverage
Test: quic.info Lines: 18 18 100.0 %
Date: 2025-07-04 13:24:45 Functions: 2 2 100.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             : #define QUIC_PATH_MIN_PMTU      1200U
      12             : #define QUIC_PATH_MAX_PMTU      65536U
      13             : 
      14             : #define QUIC_MIN_UDP_PAYLOAD    1200
      15             : #define QUIC_MAX_UDP_PAYLOAD    65527
      16             : 
      17             : #define QUIC_PATH_ENTROPY_LEN   8
      18             : 
      19             : /* Connection Migration State Machine:
      20             :  *
      21             :  * +--------+      recv non-probing, free old path    +----------+
      22             :  * |  NONE  | <-------------------------------------- | SWAPPED  |
      23             :  * +--------+                                         +----------+
      24             :  *      |   ^ \                                            ^
      25             :  *      |    \ \                                           |
      26             :  *      |     \ \   new path detected,                     | recv
      27             :  *      |      \ \  has another DCID,                      | Path
      28             :  *      |       \ \ snd Path Challenge                     | Response
      29             :  *      |        \ -------------------------------         |
      30             :  *      |         ------------------------------- \        |
      31             :  *      | new path detected,            Path     \ \       |
      32             :  *      | has no other DCID,            Challenge \ \      |
      33             :  *      | request a new DCID            failed     \ \     |
      34             :  *      v                                           \ v    |
      35             :  * +----------+                                       +----------+
      36             :  * | PENDING  | ------------------------------------> | PROBING  |
      37             :  * +----------+  recv a new DCID, snd Path Challenge  +----------+
      38             :  */
      39             : enum {
      40             :         QUIC_PATH_ALT_NONE,     /* No alternate path (migration complete or aborted) */
      41             :         QUIC_PATH_ALT_PENDING,  /* Waiting for a new destination CID for migration */
      42             :         QUIC_PATH_ALT_PROBING,  /* Validating the alternate path (PATH_CHALLENGE) */
      43             :         QUIC_PATH_ALT_SWAPPED,  /* Alternate path is now active; roles swapped */
      44             : };
      45             : 
      46             : struct quic_udp_sock {
      47             :         struct work_struct work;        /* Workqueue to destroy UDP tunnel socket */
      48             :         struct hlist_node node;         /* Entry in address-based UDP socket hash table */
      49             :         union quic_addr addr;
      50             :         refcount_t refcnt;
      51             :         struct sock *sk;                /* Underlying UDP tunnel socket */
      52             : };
      53             : 
      54             : struct quic_path {
      55             :         union quic_addr daddr;          /* Destination address */
      56             :         union quic_addr saddr;          /* Source address */
      57             :         struct quic_udp_sock *udp_sk;   /* Wrapped UDP socket used to receive QUIC packets */
      58             : };
      59             : 
      60             : struct quic_path_group {
      61             :         /* Connection ID validation during handshake (rfc9000#section-7.3) */
      62             :         struct quic_conn_id retry_dcid;         /* Source CID from Retry packet */
      63             :         struct quic_conn_id orig_dcid;          /* Destination CID from first Initial */
      64             : 
      65             :         /* Path validation (rfc9000#section-8.2) */
      66             :         u8 entropy[QUIC_PATH_ENTROPY_LEN];      /* Entropy for PATH_CHALLENGE */
      67             :         struct quic_path path[2];               /* Active path (0) and alternate path (1) */
      68             :         struct flowi fl;                        /* Flow info from routing decisions */
      69             : 
      70             :         /* Anti-amplification limit (rfc9000#section-8) */
      71             :         u16 ampl_sndlen;        /* Bytes sent before address is validated */
      72             :         u16 ampl_rcvlen;        /* Bytes received to lift amplification limit */
      73             : 
      74             :         /* MTU discovery handling */
      75             :         u32 mtu_info;           /* PMTU value from received ICMP, pending apply */
      76             :         struct {                /* PLPMTUD probing (rfc8899) */
      77             :                 s64 number;     /* Packet number used for current probe */
      78             :                 u16 pmtu;       /* Confirmed path MTU */
      79             : 
      80             :                 u16 probe_size; /* Current probe packet size */
      81             :                 u16 probe_high; /* Highest failed probe size */
      82             :                 u8 probe_count; /* Retry count for current probe_size */
      83             :                 u8 state;       /* Probe state machine (rfc8899#section-5.2) */
      84             :         } pl;
      85             : 
      86             :         /* Connection Migration (rfc9000#section-9) */
      87             :         u8 disable_saddr_alt:1; /* Remote disable_active_migration (rfc9000#section-18.2) */
      88             :         u8 disable_daddr_alt:1; /* Local disable_active_migration (rfc9000#section-18.2) */
      89             :         u8 pref_addr:1;         /* Preferred address offered (rfc9000#section-18.2) */
      90             :         u8 alt_probes;          /* Number of PATH_CHALLENGE probes sent */
      91             :         u8 alt_state;           /* State for alternate path migration logic (see above) */
      92             : 
      93             :         u8 ecn_probes;          /* ECN probe counter */
      94             :         u8 validated:1;         /* Path validated with PATH_RESPONSE */
      95             :         u8 blocked:1;           /* Blocked by anti-amplification limit */
      96             :         u8 retry:1;             /* Retry used in initial packet */
      97             :         u8 serv:1;              /* Indicates server side */
      98             : };
      99             : 
     100    17595984 : static inline union quic_addr *quic_path_saddr(struct quic_path_group *paths, u8 path)
     101             : {
     102    17593058 :         return &paths->path[path].saddr;
     103             : }
     104             : 
     105         609 : static inline void quic_path_set_saddr(struct quic_path_group *paths, u8 path,
     106             :                                        union quic_addr *addr)
     107             : {
     108         609 :         memcpy(quic_path_saddr(paths, path), addr, sizeof(*addr));
     109         609 : }
     110             : 
     111    24151142 : static inline union quic_addr *quic_path_daddr(struct quic_path_group *paths, u8 path)
     112             : {
     113    24147725 :         return &paths->path[path].daddr;
     114             : }
     115             : 
     116        1100 : static inline void quic_path_set_daddr(struct quic_path_group *paths, u8 path,
     117             :                                        union quic_addr *addr)
     118             : {
     119        1100 :         memcpy(quic_path_daddr(paths, path), addr, sizeof(*addr));
     120        1100 : }
     121             : 
     122          35 : static inline union quic_addr *quic_path_uaddr(struct quic_path_group *paths, u8 path)
     123             : {
     124          35 :         return &paths->path[path].udp_sk->addr;
     125             : }
     126             : 
     127    13072018 : static inline bool quic_path_alt_state(struct quic_path_group *paths, u8 state)
     128             : {
     129    13072018 :         return paths->alt_state == state;
     130             : }
     131             : 
     132          99 : static inline void quic_path_set_alt_state(struct quic_path_group *paths, u8 state)
     133             : {
     134          99 :         paths->alt_state = state;
     135             : }
     136             : 
     137             : /* Returns the destination Connection ID (DCID) used for identifying the connection.
     138             :  * Per rfc9000#section-7.3, handshake packets are considered part of the same connection
     139             :  * if their DCID matches the one returned here.
     140             :  */
     141         340 : static inline struct quic_conn_id *quic_path_orig_dcid(struct quic_path_group *paths)
     142             : {
     143         340 :         return paths->retry ? &paths->retry_dcid : &paths->orig_dcid;
     144             : }
     145             : 
     146             : int quic_path_detect_alt(struct quic_path_group *paths, union quic_addr *sa, union quic_addr *da,
     147             :                          struct sock *sk);
     148             : int quic_path_bind(struct sock *sk, struct quic_path_group *paths, u8 path);
     149             : void quic_path_free(struct sock *sk, struct quic_path_group *paths, u8 path);
     150             : void quic_path_swap(struct quic_path_group *paths);
     151             : 
     152             : u32 quic_path_pl_recv(struct quic_path_group *paths, bool *raise_timer, bool *complete);
     153             : u32 quic_path_pl_toobig(struct quic_path_group *paths, u32 pmtu, bool *reset_timer);
     154             : u32 quic_path_pl_send(struct quic_path_group *paths, s64 number);
     155             : 
     156             : void quic_path_get_param(struct quic_path_group *paths, struct quic_transport_param *p);
     157             : void quic_path_set_param(struct quic_path_group *paths, struct quic_transport_param *p);
     158             : bool quic_path_pl_confirm(struct quic_path_group *paths, s64 largest, s64 smallest);
     159             : void quic_path_pl_reset(struct quic_path_group *paths);
     160             : 
     161             : int quic_path_init(int (*rcv)(struct sk_buff *skb, u8 err));
     162             : void quic_path_destroy(void);

Generated by: LCOV version 1.14