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