1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Multipath TCP 4 * 5 * Copyright (c) 2017 - 2019, Intel Corporation. 6 */ 7 8 #ifndef __NET_MPTCP_H 9 #define __NET_MPTCP_H 10 11 #include <linux/skbuff.h> 12 #include <linux/tcp.h> 13 #include <linux/types.h> 14 15 struct seq_file; 16 17 /* MPTCP sk_buff extension data */ 18 struct mptcp_ext { 19 union { 20 u64 data_ack; 21 u32 data_ack32; 22 }; 23 u64 data_seq; 24 u32 subflow_seq; 25 u16 data_len; 26 __sum16 csum; 27 u8 use_map:1, 28 dsn64:1, 29 data_fin:1, 30 use_ack:1, 31 ack64:1, 32 mpc_map:1, 33 frozen:1, 34 reset_transient:1; 35 u8 reset_reason:4, 36 csum_reqd:1; 37 }; 38 39 #define MPTCP_RM_IDS_MAX 8 40 41 struct mptcp_rm_list { 42 u8 ids[MPTCP_RM_IDS_MAX]; 43 u8 nr; 44 }; 45 46 struct mptcp_addr_info { 47 u8 id; 48 sa_family_t family; 49 __be16 port; 50 union { 51 struct in_addr addr; 52 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 53 struct in6_addr addr6; 54 #endif 55 }; 56 }; 57 58 struct mptcp_out_options { 59 #if IS_ENABLED(CONFIG_MPTCP) 60 u16 suboptions; 61 u64 sndr_key; 62 u64 rcvr_key; 63 u64 ahmac; 64 struct mptcp_addr_info addr; 65 struct mptcp_rm_list rm_list; 66 u8 join_id; 67 u8 backup; 68 u8 reset_reason:4, 69 reset_transient:1, 70 csum_reqd:1, 71 allow_join_id0:1; 72 u32 nonce; 73 u64 thmac; 74 u32 token; 75 u8 hmac[20]; 76 struct mptcp_ext ext_copy; 77 #endif 78 }; 79 80 #ifdef CONFIG_MPTCP 81 extern struct request_sock_ops mptcp_subflow_request_sock_ops; 82 83 void mptcp_init(void); 84 85 static inline bool sk_is_mptcp(const struct sock *sk) 86 { 87 return tcp_sk(sk)->is_mptcp; 88 } 89 90 static inline bool rsk_is_mptcp(const struct request_sock *req) 91 { 92 return tcp_rsk(req)->is_mptcp; 93 } 94 95 static inline bool rsk_drop_req(const struct request_sock *req) 96 { 97 return tcp_rsk(req)->is_mptcp && tcp_rsk(req)->drop_req; 98 } 99 100 void mptcp_space(const struct sock *ssk, int *space, int *full_space); 101 bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, 102 unsigned int *size, struct mptcp_out_options *opts); 103 bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, 104 struct mptcp_out_options *opts); 105 bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, 106 unsigned int *size, unsigned int remaining, 107 struct mptcp_out_options *opts); 108 void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb); 109 110 void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, 111 struct mptcp_out_options *opts); 112 113 /* move the skb extension owership, with the assumption that 'to' is 114 * newly allocated 115 */ 116 static inline void mptcp_skb_ext_move(struct sk_buff *to, 117 struct sk_buff *from) 118 { 119 if (!skb_ext_exist(from, SKB_EXT_MPTCP)) 120 return; 121 122 if (WARN_ON_ONCE(to->active_extensions)) 123 skb_ext_put(to); 124 125 to->active_extensions = from->active_extensions; 126 to->extensions = from->extensions; 127 from->active_extensions = 0; 128 } 129 130 static inline void mptcp_skb_ext_copy(struct sk_buff *to, 131 struct sk_buff *from) 132 { 133 struct mptcp_ext *from_ext; 134 135 from_ext = skb_ext_find(from, SKB_EXT_MPTCP); 136 if (!from_ext) 137 return; 138 139 from_ext->frozen = 1; 140 skb_ext_copy(to, from); 141 } 142 143 static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext, 144 const struct mptcp_ext *from_ext) 145 { 146 /* MPTCP always clears the ext when adding it to the skb, so 147 * holes do not bother us here 148 */ 149 return !from_ext || 150 (to_ext && from_ext && 151 !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext))); 152 } 153 154 /* check if skbs can be collapsed. 155 * MPTCP collapse is allowed if neither @to or @from carry an mptcp data 156 * mapping, or if the extension of @to is the same as @from. 157 * Collapsing is not possible if @to lacks an extension, but @from carries one. 158 */ 159 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 160 const struct sk_buff *from) 161 { 162 return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP), 163 skb_ext_find(from, SKB_EXT_MPTCP)); 164 } 165 166 void mptcp_seq_show(struct seq_file *seq); 167 int mptcp_subflow_init_cookie_req(struct request_sock *req, 168 const struct sock *sk_listener, 169 struct sk_buff *skb); 170 171 __be32 mptcp_get_reset_option(const struct sk_buff *skb); 172 173 static inline __be32 mptcp_reset_option(const struct sk_buff *skb) 174 { 175 if (skb_ext_exist(skb, SKB_EXT_MPTCP)) 176 return mptcp_get_reset_option(skb); 177 178 return htonl(0u); 179 } 180 #else 181 182 static inline void mptcp_init(void) 183 { 184 } 185 186 static inline bool sk_is_mptcp(const struct sock *sk) 187 { 188 return false; 189 } 190 191 static inline bool rsk_is_mptcp(const struct request_sock *req) 192 { 193 return false; 194 } 195 196 static inline bool rsk_drop_req(const struct request_sock *req) 197 { 198 return false; 199 } 200 201 static inline void mptcp_parse_option(const struct sk_buff *skb, 202 const unsigned char *ptr, int opsize, 203 struct tcp_options_received *opt_rx) 204 { 205 } 206 207 static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, 208 unsigned int *size, 209 struct mptcp_out_options *opts) 210 { 211 return false; 212 } 213 214 static inline bool mptcp_synack_options(const struct request_sock *req, 215 unsigned int *size, 216 struct mptcp_out_options *opts) 217 { 218 return false; 219 } 220 221 static inline bool mptcp_established_options(struct sock *sk, 222 struct sk_buff *skb, 223 unsigned int *size, 224 unsigned int remaining, 225 struct mptcp_out_options *opts) 226 { 227 return false; 228 } 229 230 static inline void mptcp_incoming_options(struct sock *sk, 231 struct sk_buff *skb) 232 { 233 } 234 235 static inline void mptcp_skb_ext_move(struct sk_buff *to, 236 const struct sk_buff *from) 237 { 238 } 239 240 static inline void mptcp_skb_ext_copy(struct sk_buff *to, 241 struct sk_buff *from) 242 { 243 } 244 245 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 246 const struct sk_buff *from) 247 { 248 return true; 249 } 250 251 static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { } 252 static inline void mptcp_seq_show(struct seq_file *seq) { } 253 254 static inline int mptcp_subflow_init_cookie_req(struct request_sock *req, 255 const struct sock *sk_listener, 256 struct sk_buff *skb) 257 { 258 return 0; /* TCP fallback */ 259 } 260 261 static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); } 262 #endif /* CONFIG_MPTCP */ 263 264 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 265 int mptcpv6_init(void); 266 void mptcpv6_handle_mapped(struct sock *sk, bool mapped); 267 #elif IS_ENABLED(CONFIG_IPV6) 268 static inline int mptcpv6_init(void) { return 0; } 269 static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { } 270 #endif 271 272 #endif /* __NET_MPTCP_H */ 273