xref: /openbmc/linux/include/net/mptcp.h (revision eda7acddf8080bb2d022a8d4b8b2345eb80c63ec)
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 #endif
36 };
37 
38 #ifdef CONFIG_MPTCP
39 
40 void mptcp_init(void);
41 
42 void mptcp_parse_option(const unsigned char *ptr, int opsize,
43 			struct tcp_options_received *opt_rx);
44 void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
45 
46 /* move the skb extension owership, with the assumption that 'to' is
47  * newly allocated
48  */
49 static inline void mptcp_skb_ext_move(struct sk_buff *to,
50 				      struct sk_buff *from)
51 {
52 	if (!skb_ext_exist(from, SKB_EXT_MPTCP))
53 		return;
54 
55 	if (WARN_ON_ONCE(to->active_extensions))
56 		skb_ext_put(to);
57 
58 	to->active_extensions = from->active_extensions;
59 	to->extensions = from->extensions;
60 	from->active_extensions = 0;
61 }
62 
63 static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext,
64 				     const struct mptcp_ext *from_ext)
65 {
66 	/* MPTCP always clears the ext when adding it to the skb, so
67 	 * holes do not bother us here
68 	 */
69 	return !from_ext ||
70 	       (to_ext && from_ext &&
71 	        !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext)));
72 }
73 
74 /* check if skbs can be collapsed.
75  * MPTCP collapse is allowed if neither @to or @from carry an mptcp data
76  * mapping, or if the extension of @to is the same as @from.
77  * Collapsing is not possible if @to lacks an extension, but @from carries one.
78  */
79 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
80 					  const struct sk_buff *from)
81 {
82 	return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP),
83 				 skb_ext_find(from, SKB_EXT_MPTCP));
84 }
85 
86 #else
87 
88 static inline void mptcp_init(void)
89 {
90 }
91 
92 static inline void mptcp_parse_option(const unsigned char *ptr, int opsize,
93 				      struct tcp_options_received *opt_rx)
94 {
95 }
96 
97 static inline void mptcp_skb_ext_move(struct sk_buff *to,
98 				      const struct sk_buff *from)
99 {
100 }
101 
102 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to,
103 					  const struct sk_buff *from)
104 {
105 	return true;
106 }
107 
108 #endif /* CONFIG_MPTCP */
109 
110 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
111 int mptcpv6_init(void);
112 #elif IS_ENABLED(CONFIG_IPV6)
113 static inline int mptcpv6_init(void)
114 {
115 	return 0;
116 }
117 #endif
118 
119 #endif /* __NET_MPTCP_H */
120