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 /* MPTCP sk_buff extension data */ 16 struct mptcp_ext { 17 u64 data_ack; 18 u64 data_seq; 19 u32 subflow_seq; 20 u16 data_len; 21 u8 use_map:1, 22 dsn64:1, 23 data_fin:1, 24 use_ack:1, 25 ack64:1, 26 mpc_map:1, 27 __unused:2; 28 /* one byte hole */ 29 }; 30 31 struct mptcp_out_options { 32 #if IS_ENABLED(CONFIG_MPTCP) 33 u16 suboptions; 34 u64 sndr_key; 35 u64 rcvr_key; 36 union { 37 struct in_addr addr; 38 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 39 struct in6_addr addr6; 40 #endif 41 }; 42 u8 addr_id; 43 u64 ahmac; 44 u8 rm_id; 45 u8 join_id; 46 u8 backup; 47 u32 nonce; 48 u64 thmac; 49 u32 token; 50 u8 hmac[20]; 51 struct mptcp_ext ext_copy; 52 #endif 53 }; 54 55 #ifdef CONFIG_MPTCP 56 57 void mptcp_init(void); 58 59 static inline bool sk_is_mptcp(const struct sock *sk) 60 { 61 return tcp_sk(sk)->is_mptcp; 62 } 63 64 static inline bool rsk_is_mptcp(const struct request_sock *req) 65 { 66 return tcp_rsk(req)->is_mptcp; 67 } 68 69 void mptcp_parse_option(const struct sk_buff *skb, const unsigned char *ptr, 70 int opsize, struct tcp_options_received *opt_rx); 71 bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, 72 unsigned int *size, struct mptcp_out_options *opts); 73 void mptcp_rcv_synsent(struct sock *sk); 74 bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, 75 struct mptcp_out_options *opts); 76 bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, 77 unsigned int *size, unsigned int remaining, 78 struct mptcp_out_options *opts); 79 void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, 80 struct tcp_options_received *opt_rx); 81 82 void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts); 83 84 /* move the skb extension owership, with the assumption that 'to' is 85 * newly allocated 86 */ 87 static inline void mptcp_skb_ext_move(struct sk_buff *to, 88 struct sk_buff *from) 89 { 90 if (!skb_ext_exist(from, SKB_EXT_MPTCP)) 91 return; 92 93 if (WARN_ON_ONCE(to->active_extensions)) 94 skb_ext_put(to); 95 96 to->active_extensions = from->active_extensions; 97 to->extensions = from->extensions; 98 from->active_extensions = 0; 99 } 100 101 static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext, 102 const struct mptcp_ext *from_ext) 103 { 104 /* MPTCP always clears the ext when adding it to the skb, so 105 * holes do not bother us here 106 */ 107 return !from_ext || 108 (to_ext && from_ext && 109 !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext))); 110 } 111 112 /* check if skbs can be collapsed. 113 * MPTCP collapse is allowed if neither @to or @from carry an mptcp data 114 * mapping, or if the extension of @to is the same as @from. 115 * Collapsing is not possible if @to lacks an extension, but @from carries one. 116 */ 117 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 118 const struct sk_buff *from) 119 { 120 return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP), 121 skb_ext_find(from, SKB_EXT_MPTCP)); 122 } 123 124 bool mptcp_sk_is_subflow(const struct sock *sk); 125 126 #else 127 128 static inline void mptcp_init(void) 129 { 130 } 131 132 static inline bool sk_is_mptcp(const struct sock *sk) 133 { 134 return false; 135 } 136 137 static inline bool rsk_is_mptcp(const struct request_sock *req) 138 { 139 return false; 140 } 141 142 static inline void mptcp_parse_option(const struct sk_buff *skb, 143 const unsigned char *ptr, int opsize, 144 struct tcp_options_received *opt_rx) 145 { 146 } 147 148 static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, 149 unsigned int *size, 150 struct mptcp_out_options *opts) 151 { 152 return false; 153 } 154 155 static inline void mptcp_rcv_synsent(struct sock *sk) 156 { 157 } 158 159 static inline bool mptcp_synack_options(const struct request_sock *req, 160 unsigned int *size, 161 struct mptcp_out_options *opts) 162 { 163 return false; 164 } 165 166 static inline bool mptcp_established_options(struct sock *sk, 167 struct sk_buff *skb, 168 unsigned int *size, 169 unsigned int remaining, 170 struct mptcp_out_options *opts) 171 { 172 return false; 173 } 174 175 static inline void mptcp_incoming_options(struct sock *sk, 176 struct sk_buff *skb, 177 struct tcp_options_received *opt_rx) 178 { 179 } 180 181 static inline void mptcp_skb_ext_move(struct sk_buff *to, 182 const struct sk_buff *from) 183 { 184 } 185 186 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 187 const struct sk_buff *from) 188 { 189 return true; 190 } 191 192 static inline bool mptcp_sk_is_subflow(const struct sock *sk) 193 { 194 return false; 195 } 196 197 #endif /* CONFIG_MPTCP */ 198 199 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 200 int mptcpv6_init(void); 201 void mptcpv6_handle_mapped(struct sock *sk, bool mapped); 202 #elif IS_ENABLED(CONFIG_IPV6) 203 static inline int mptcpv6_init(void) { return 0; } 204 static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { } 205 #endif 206 207 #endif /* __NET_MPTCP_H */ 208