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