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);