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