13ee17bc7SMat Martineau /* SPDX-License-Identifier: GPL-2.0 */ 23ee17bc7SMat Martineau /* 33ee17bc7SMat Martineau * Multipath TCP 43ee17bc7SMat Martineau * 53ee17bc7SMat Martineau * Copyright (c) 2017 - 2019, Intel Corporation. 63ee17bc7SMat Martineau */ 73ee17bc7SMat Martineau 83ee17bc7SMat Martineau #ifndef __NET_MPTCP_H 93ee17bc7SMat Martineau #define __NET_MPTCP_H 103ee17bc7SMat Martineau 1185712484SMat Martineau #include <linux/skbuff.h> 12eda7acddSPeter Krystad #include <linux/tcp.h> 133ee17bc7SMat Martineau #include <linux/types.h> 143ee17bc7SMat Martineau 15fc518953SFlorian Westphal struct seq_file; 16fc518953SFlorian Westphal 173ee17bc7SMat Martineau /* MPTCP sk_buff extension data */ 183ee17bc7SMat Martineau struct mptcp_ext { 19a0c1d0eaSChristoph Paasch union { 203ee17bc7SMat Martineau u64 data_ack; 21a0c1d0eaSChristoph Paasch u32 data_ack32; 22a0c1d0eaSChristoph Paasch }; 233ee17bc7SMat Martineau u64 data_seq; 243ee17bc7SMat Martineau u32 subflow_seq; 253ee17bc7SMat Martineau u16 data_len; 263ee17bc7SMat Martineau u8 use_map:1, 273ee17bc7SMat Martineau dsn64:1, 283ee17bc7SMat Martineau data_fin:1, 293ee17bc7SMat Martineau use_ack:1, 303ee17bc7SMat Martineau ack64:1, 31cc7972eaSChristoph Paasch mpc_map:1, 32cc7972eaSChristoph Paasch __unused:2; 333ee17bc7SMat Martineau /* one byte hole */ 343ee17bc7SMat Martineau }; 353ee17bc7SMat Martineau 36eda7acddSPeter Krystad struct mptcp_out_options { 37eda7acddSPeter Krystad #if IS_ENABLED(CONFIG_MPTCP) 38eda7acddSPeter Krystad u16 suboptions; 39eda7acddSPeter Krystad u64 sndr_key; 40eda7acddSPeter Krystad u64 rcvr_key; 413df523abSPeter Krystad union { 423df523abSPeter Krystad struct in_addr addr; 433df523abSPeter Krystad #if IS_ENABLED(CONFIG_MPTCP_IPV6) 443df523abSPeter Krystad struct in6_addr addr6; 453df523abSPeter Krystad #endif 463df523abSPeter Krystad }; 473df523abSPeter Krystad u8 addr_id; 483df523abSPeter Krystad u64 ahmac; 493df523abSPeter Krystad u8 rm_id; 50f296234cSPeter Krystad u8 join_id; 51f296234cSPeter Krystad u8 backup; 52f296234cSPeter Krystad u32 nonce; 53f296234cSPeter Krystad u64 thmac; 54ec3edaa7SPeter Krystad u32 token; 55ec3edaa7SPeter Krystad u8 hmac[20]; 566d0060f6SMat Martineau struct mptcp_ext ext_copy; 57eda7acddSPeter Krystad #endif 58eda7acddSPeter Krystad }; 59eda7acddSPeter Krystad 6085712484SMat Martineau #ifdef CONFIG_MPTCP 6108b8d080SFlorian Westphal extern struct request_sock_ops mptcp_subflow_request_sock_ops; 6285712484SMat Martineau 63f870fa0bSMat Martineau void mptcp_init(void); 64f870fa0bSMat Martineau 65cec37a6eSPeter Krystad static inline bool sk_is_mptcp(const struct sock *sk) 66cec37a6eSPeter Krystad { 67cec37a6eSPeter Krystad return tcp_sk(sk)->is_mptcp; 68cec37a6eSPeter Krystad } 69cec37a6eSPeter Krystad 70cec37a6eSPeter Krystad static inline bool rsk_is_mptcp(const struct request_sock *req) 71cec37a6eSPeter Krystad { 72cec37a6eSPeter Krystad return tcp_rsk(req)->is_mptcp; 73cec37a6eSPeter Krystad } 74cec37a6eSPeter Krystad 7590bf4513SPaolo Abeni static inline bool rsk_drop_req(const struct request_sock *req) 7690bf4513SPaolo Abeni { 7790bf4513SPaolo Abeni return tcp_rsk(req)->is_mptcp && tcp_rsk(req)->drop_req; 7890bf4513SPaolo Abeni } 7990bf4513SPaolo Abeni 80071c8ed6SFlorian Westphal void mptcp_space(const struct sock *ssk, int *space, int *full_space); 81cc7972eaSChristoph Paasch bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, 82cc7972eaSChristoph Paasch unsigned int *size, struct mptcp_out_options *opts); 83cec37a6eSPeter Krystad bool mptcp_synack_options(const struct request_sock *req, unsigned int *size, 84cec37a6eSPeter Krystad struct mptcp_out_options *opts); 85cec37a6eSPeter Krystad bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, 86cec37a6eSPeter Krystad unsigned int *size, unsigned int remaining, 87cec37a6eSPeter Krystad struct mptcp_out_options *opts); 88648ef4b8SMat Martineau void mptcp_incoming_options(struct sock *sk, struct sk_buff *skb, 89648ef4b8SMat Martineau struct tcp_options_received *opt_rx); 90cec37a6eSPeter Krystad 91eda7acddSPeter Krystad void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts); 92eda7acddSPeter Krystad 9385712484SMat Martineau /* move the skb extension owership, with the assumption that 'to' is 9485712484SMat Martineau * newly allocated 9585712484SMat Martineau */ 9685712484SMat Martineau static inline void mptcp_skb_ext_move(struct sk_buff *to, 9785712484SMat Martineau struct sk_buff *from) 9885712484SMat Martineau { 9985712484SMat Martineau if (!skb_ext_exist(from, SKB_EXT_MPTCP)) 10085712484SMat Martineau return; 10185712484SMat Martineau 10285712484SMat Martineau if (WARN_ON_ONCE(to->active_extensions)) 10385712484SMat Martineau skb_ext_put(to); 10485712484SMat Martineau 10585712484SMat Martineau to->active_extensions = from->active_extensions; 10685712484SMat Martineau to->extensions = from->extensions; 10785712484SMat Martineau from->active_extensions = 0; 10885712484SMat Martineau } 10985712484SMat Martineau 11085712484SMat Martineau static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext, 11185712484SMat Martineau const struct mptcp_ext *from_ext) 11285712484SMat Martineau { 11385712484SMat Martineau /* MPTCP always clears the ext when adding it to the skb, so 11485712484SMat Martineau * holes do not bother us here 11585712484SMat Martineau */ 11685712484SMat Martineau return !from_ext || 11785712484SMat Martineau (to_ext && from_ext && 11885712484SMat Martineau !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext))); 11985712484SMat Martineau } 12085712484SMat Martineau 12185712484SMat Martineau /* check if skbs can be collapsed. 12285712484SMat Martineau * MPTCP collapse is allowed if neither @to or @from carry an mptcp data 12385712484SMat Martineau * mapping, or if the extension of @to is the same as @from. 12485712484SMat Martineau * Collapsing is not possible if @to lacks an extension, but @from carries one. 12585712484SMat Martineau */ 12685712484SMat Martineau static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 12785712484SMat Martineau const struct sk_buff *from) 12885712484SMat Martineau { 12985712484SMat Martineau return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP), 13085712484SMat Martineau skb_ext_find(from, SKB_EXT_MPTCP)); 13185712484SMat Martineau } 13285712484SMat Martineau 133fc518953SFlorian Westphal void mptcp_seq_show(struct seq_file *seq); 134*c83a47e5SFlorian Westphal int mptcp_subflow_init_cookie_req(struct request_sock *req, 135*c83a47e5SFlorian Westphal const struct sock *sk_listener, 136*c83a47e5SFlorian Westphal struct sk_buff *skb); 13785712484SMat Martineau #else 13885712484SMat Martineau 139f870fa0bSMat Martineau static inline void mptcp_init(void) 140f870fa0bSMat Martineau { 141f870fa0bSMat Martineau } 142f870fa0bSMat Martineau 143cec37a6eSPeter Krystad static inline bool sk_is_mptcp(const struct sock *sk) 144cec37a6eSPeter Krystad { 145cec37a6eSPeter Krystad return false; 146cec37a6eSPeter Krystad } 147cec37a6eSPeter Krystad 148cec37a6eSPeter Krystad static inline bool rsk_is_mptcp(const struct request_sock *req) 149cec37a6eSPeter Krystad { 150cec37a6eSPeter Krystad return false; 151cec37a6eSPeter Krystad } 152cec37a6eSPeter Krystad 15390bf4513SPaolo Abeni static inline bool rsk_drop_req(const struct request_sock *req) 15490bf4513SPaolo Abeni { 15590bf4513SPaolo Abeni return false; 15690bf4513SPaolo Abeni } 15790bf4513SPaolo Abeni 158cc7972eaSChristoph Paasch static inline void mptcp_parse_option(const struct sk_buff *skb, 159cc7972eaSChristoph Paasch const unsigned char *ptr, int opsize, 160eda7acddSPeter Krystad struct tcp_options_received *opt_rx) 161eda7acddSPeter Krystad { 162eda7acddSPeter Krystad } 163eda7acddSPeter Krystad 164cc7972eaSChristoph Paasch static inline bool mptcp_syn_options(struct sock *sk, const struct sk_buff *skb, 165cc7972eaSChristoph Paasch unsigned int *size, 166cec37a6eSPeter Krystad struct mptcp_out_options *opts) 167cec37a6eSPeter Krystad { 168cec37a6eSPeter Krystad return false; 169cec37a6eSPeter Krystad } 170cec37a6eSPeter Krystad 171cec37a6eSPeter Krystad static inline bool mptcp_synack_options(const struct request_sock *req, 172cec37a6eSPeter Krystad unsigned int *size, 173cec37a6eSPeter Krystad struct mptcp_out_options *opts) 174cec37a6eSPeter Krystad { 175cec37a6eSPeter Krystad return false; 176cec37a6eSPeter Krystad } 177cec37a6eSPeter Krystad 178cec37a6eSPeter Krystad static inline bool mptcp_established_options(struct sock *sk, 179cec37a6eSPeter Krystad struct sk_buff *skb, 180cec37a6eSPeter Krystad unsigned int *size, 181cec37a6eSPeter Krystad unsigned int remaining, 182cec37a6eSPeter Krystad struct mptcp_out_options *opts) 183cec37a6eSPeter Krystad { 184cec37a6eSPeter Krystad return false; 185cec37a6eSPeter Krystad } 186cec37a6eSPeter Krystad 187648ef4b8SMat Martineau static inline void mptcp_incoming_options(struct sock *sk, 188648ef4b8SMat Martineau struct sk_buff *skb, 189648ef4b8SMat Martineau struct tcp_options_received *opt_rx) 190648ef4b8SMat Martineau { 191648ef4b8SMat Martineau } 192648ef4b8SMat Martineau 19385712484SMat Martineau static inline void mptcp_skb_ext_move(struct sk_buff *to, 19485712484SMat Martineau const struct sk_buff *from) 19585712484SMat Martineau { 19685712484SMat Martineau } 19785712484SMat Martineau 19885712484SMat Martineau static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 19985712484SMat Martineau const struct sk_buff *from) 20085712484SMat Martineau { 20185712484SMat Martineau return true; 20285712484SMat Martineau } 20385712484SMat Martineau 204071c8ed6SFlorian Westphal static inline void mptcp_space(const struct sock *ssk, int *s, int *fs) { } 205fc518953SFlorian Westphal static inline void mptcp_seq_show(struct seq_file *seq) { } 206*c83a47e5SFlorian Westphal 207*c83a47e5SFlorian Westphal static inline int mptcp_subflow_init_cookie_req(struct request_sock *req, 208*c83a47e5SFlorian Westphal const struct sock *sk_listener, 209*c83a47e5SFlorian Westphal struct sk_buff *skb) 210*c83a47e5SFlorian Westphal { 211*c83a47e5SFlorian Westphal return 0; /* TCP fallback */ 212*c83a47e5SFlorian Westphal } 21385712484SMat Martineau #endif /* CONFIG_MPTCP */ 214f870fa0bSMat Martineau 215f870fa0bSMat Martineau #if IS_ENABLED(CONFIG_MPTCP_IPV6) 216f870fa0bSMat Martineau int mptcpv6_init(void); 21731484d56SGeert Uytterhoeven void mptcpv6_handle_mapped(struct sock *sk, bool mapped); 218f870fa0bSMat Martineau #elif IS_ENABLED(CONFIG_IPV6) 21931484d56SGeert Uytterhoeven static inline int mptcpv6_init(void) { return 0; } 22031484d56SGeert Uytterhoeven static inline void mptcpv6_handle_mapped(struct sock *sk, bool mapped) { } 221f870fa0bSMat Martineau #endif 222f870fa0bSMat Martineau 2233ee17bc7SMat Martineau #endif /* __NET_MPTCP_H */ 224