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