1f870fa0bSMat Martineau /* SPDX-License-Identifier: GPL-2.0 */ 2f870fa0bSMat Martineau /* Multipath TCP 3f870fa0bSMat Martineau * 4f870fa0bSMat Martineau * Copyright (c) 2017 - 2019, Intel Corporation. 5f870fa0bSMat Martineau */ 6f870fa0bSMat Martineau 7f870fa0bSMat Martineau #ifndef __MPTCP_PROTOCOL_H 8f870fa0bSMat Martineau #define __MPTCP_PROTOCOL_H 9f870fa0bSMat Martineau 1079c0949eSPeter Krystad #include <linux/random.h> 1179c0949eSPeter Krystad #include <net/tcp.h> 1279c0949eSPeter Krystad #include <net/inet_connection_sock.h> 1379c0949eSPeter Krystad 14cc7972eaSChristoph Paasch #define MPTCP_SUPPORTED_VERSION 1 15eda7acddSPeter Krystad 16eda7acddSPeter Krystad /* MPTCP option bits */ 17eda7acddSPeter Krystad #define OPTION_MPTCP_MPC_SYN BIT(0) 18eda7acddSPeter Krystad #define OPTION_MPTCP_MPC_SYNACK BIT(1) 19eda7acddSPeter Krystad #define OPTION_MPTCP_MPC_ACK BIT(2) 20f296234cSPeter Krystad #define OPTION_MPTCP_MPJ_SYN BIT(3) 21f296234cSPeter Krystad #define OPTION_MPTCP_MPJ_SYNACK BIT(4) 22f296234cSPeter Krystad #define OPTION_MPTCP_MPJ_ACK BIT(5) 233df523abSPeter Krystad #define OPTION_MPTCP_ADD_ADDR BIT(6) 243df523abSPeter Krystad #define OPTION_MPTCP_ADD_ADDR6 BIT(7) 253df523abSPeter Krystad #define OPTION_MPTCP_RM_ADDR BIT(8) 26eda7acddSPeter Krystad 27eda7acddSPeter Krystad /* MPTCP option subtypes */ 28eda7acddSPeter Krystad #define MPTCPOPT_MP_CAPABLE 0 29eda7acddSPeter Krystad #define MPTCPOPT_MP_JOIN 1 30eda7acddSPeter Krystad #define MPTCPOPT_DSS 2 31eda7acddSPeter Krystad #define MPTCPOPT_ADD_ADDR 3 32eda7acddSPeter Krystad #define MPTCPOPT_RM_ADDR 4 33eda7acddSPeter Krystad #define MPTCPOPT_MP_PRIO 5 34eda7acddSPeter Krystad #define MPTCPOPT_MP_FAIL 6 35eda7acddSPeter Krystad #define MPTCPOPT_MP_FASTCLOSE 7 36eda7acddSPeter Krystad 37eda7acddSPeter Krystad /* MPTCP suboption lengths */ 38cc7972eaSChristoph Paasch #define TCPOLEN_MPTCP_MPC_SYN 4 39eda7acddSPeter Krystad #define TCPOLEN_MPTCP_MPC_SYNACK 12 40eda7acddSPeter Krystad #define TCPOLEN_MPTCP_MPC_ACK 20 41cc7972eaSChristoph Paasch #define TCPOLEN_MPTCP_MPC_ACK_DATA 22 42f296234cSPeter Krystad #define TCPOLEN_MPTCP_MPJ_SYN 12 43f296234cSPeter Krystad #define TCPOLEN_MPTCP_MPJ_SYNACK 16 44f296234cSPeter Krystad #define TCPOLEN_MPTCP_MPJ_ACK 24 456d0060f6SMat Martineau #define TCPOLEN_MPTCP_DSS_BASE 4 46648ef4b8SMat Martineau #define TCPOLEN_MPTCP_DSS_ACK32 4 476d0060f6SMat Martineau #define TCPOLEN_MPTCP_DSS_ACK64 8 48648ef4b8SMat Martineau #define TCPOLEN_MPTCP_DSS_MAP32 10 496d0060f6SMat Martineau #define TCPOLEN_MPTCP_DSS_MAP64 14 506d0060f6SMat Martineau #define TCPOLEN_MPTCP_DSS_CHECKSUM 2 513df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR 16 523df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR_PORT 18 533df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR_BASE 8 543df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR_BASE_PORT 10 553df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR6 28 563df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR6_PORT 30 573df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR6_BASE 20 583df523abSPeter Krystad #define TCPOLEN_MPTCP_ADD_ADDR6_BASE_PORT 22 593df523abSPeter Krystad #define TCPOLEN_MPTCP_PORT_LEN 2 603df523abSPeter Krystad #define TCPOLEN_MPTCP_RM_ADDR_BASE 4 61eda7acddSPeter Krystad 62*ec3edaa7SPeter Krystad /* MPTCP MP_JOIN flags */ 63f296234cSPeter Krystad #define MPTCPOPT_BACKUP BIT(0) 64f296234cSPeter Krystad #define MPTCPOPT_HMAC_LEN 20 65*ec3edaa7SPeter Krystad #define MPTCPOPT_THMAC_LEN 8 66f296234cSPeter Krystad 67eda7acddSPeter Krystad /* MPTCP MP_CAPABLE flags */ 68eda7acddSPeter Krystad #define MPTCP_VERSION_MASK (0x0F) 69eda7acddSPeter Krystad #define MPTCP_CAP_CHECKSUM_REQD BIT(7) 70eda7acddSPeter Krystad #define MPTCP_CAP_EXTENSIBILITY BIT(6) 7165492c5aSPaolo Abeni #define MPTCP_CAP_HMAC_SHA256 BIT(0) 72eda7acddSPeter Krystad #define MPTCP_CAP_FLAG_MASK (0x3F) 73eda7acddSPeter Krystad 746d0060f6SMat Martineau /* MPTCP DSS flags */ 756d0060f6SMat Martineau #define MPTCP_DSS_DATA_FIN BIT(4) 766d0060f6SMat Martineau #define MPTCP_DSS_DSN64 BIT(3) 776d0060f6SMat Martineau #define MPTCP_DSS_HAS_MAP BIT(2) 786d0060f6SMat Martineau #define MPTCP_DSS_ACK64 BIT(1) 796d0060f6SMat Martineau #define MPTCP_DSS_HAS_ACK BIT(0) 80648ef4b8SMat Martineau #define MPTCP_DSS_FLAG_MASK (0x1F) 81648ef4b8SMat Martineau 823df523abSPeter Krystad /* MPTCP ADD_ADDR flags */ 833df523abSPeter Krystad #define MPTCP_ADDR_ECHO BIT(0) 843df523abSPeter Krystad #define MPTCP_ADDR_HMAC_LEN 20 853df523abSPeter Krystad #define MPTCP_ADDR_IPVERSION_4 4 863df523abSPeter Krystad #define MPTCP_ADDR_IPVERSION_6 6 873df523abSPeter Krystad 88648ef4b8SMat Martineau /* MPTCP socket flags */ 89d99bfed5SFlorian Westphal #define MPTCP_DATA_READY 0 90d99bfed5SFlorian Westphal #define MPTCP_SEND_SPACE 1 916d0060f6SMat Martineau 923df523abSPeter Krystad static inline __be32 mptcp_option(u8 subopt, u8 len, u8 nib, u8 field) 933df523abSPeter Krystad { 943df523abSPeter Krystad return htonl((TCPOPT_MPTCP << 24) | (len << 16) | (subopt << 12) | 953df523abSPeter Krystad ((nib & 0xF) << 8) | field); 963df523abSPeter Krystad } 973df523abSPeter Krystad 981b1c7a0eSPeter Krystad #define MPTCP_PM_MAX_ADDR 4 991b1c7a0eSPeter Krystad 1001b1c7a0eSPeter Krystad struct mptcp_addr_info { 1011b1c7a0eSPeter Krystad sa_family_t family; 1021b1c7a0eSPeter Krystad __be16 port; 1031b1c7a0eSPeter Krystad u8 id; 1041b1c7a0eSPeter Krystad union { 1051b1c7a0eSPeter Krystad struct in_addr addr; 1061b1c7a0eSPeter Krystad #if IS_ENABLED(CONFIG_MPTCP_IPV6) 1071b1c7a0eSPeter Krystad struct in6_addr addr6; 1081b1c7a0eSPeter Krystad #endif 1091b1c7a0eSPeter Krystad }; 1101b1c7a0eSPeter Krystad }; 1111b1c7a0eSPeter Krystad 1121b1c7a0eSPeter Krystad enum mptcp_pm_status { 1131b1c7a0eSPeter Krystad MPTCP_PM_ADD_ADDR_RECEIVED, 1141b1c7a0eSPeter Krystad MPTCP_PM_ESTABLISHED, 1151b1c7a0eSPeter Krystad MPTCP_PM_SUBFLOW_ESTABLISHED, 1161b1c7a0eSPeter Krystad }; 1171b1c7a0eSPeter Krystad 1181b1c7a0eSPeter Krystad struct mptcp_pm_data { 1191b1c7a0eSPeter Krystad struct mptcp_addr_info local; 1201b1c7a0eSPeter Krystad struct mptcp_addr_info remote; 1211b1c7a0eSPeter Krystad 1221b1c7a0eSPeter Krystad spinlock_t lock; /*protects the whole PM data */ 1231b1c7a0eSPeter Krystad 1241b1c7a0eSPeter Krystad bool addr_signal; 1251b1c7a0eSPeter Krystad bool server_side; 1261b1c7a0eSPeter Krystad bool work_pending; 1271b1c7a0eSPeter Krystad bool accept_addr; 1281b1c7a0eSPeter Krystad bool accept_subflow; 1291b1c7a0eSPeter Krystad u8 add_addr_signaled; 1301b1c7a0eSPeter Krystad u8 add_addr_accepted; 1311b1c7a0eSPeter Krystad u8 local_addr_used; 1321b1c7a0eSPeter Krystad u8 subflows; 1331b1c7a0eSPeter Krystad u8 add_addr_signal_max; 1341b1c7a0eSPeter Krystad u8 add_addr_accept_max; 1351b1c7a0eSPeter Krystad u8 local_addr_max; 1361b1c7a0eSPeter Krystad u8 subflows_max; 1371b1c7a0eSPeter Krystad u8 status; 1381b1c7a0eSPeter Krystad 1391b1c7a0eSPeter Krystad struct work_struct work; 1401b1c7a0eSPeter Krystad }; 1411b1c7a0eSPeter Krystad 142f870fa0bSMat Martineau /* MPTCP connection sock */ 143f870fa0bSMat Martineau struct mptcp_sock { 144f870fa0bSMat Martineau /* inet_connection_sock must be the first member */ 145f870fa0bSMat Martineau struct inet_connection_sock sk; 146cec37a6eSPeter Krystad u64 local_key; 147cec37a6eSPeter Krystad u64 remote_key; 1486d0060f6SMat Martineau u64 write_seq; 1496d0060f6SMat Martineau u64 ack_seq; 15079c0949eSPeter Krystad u32 token; 151648ef4b8SMat Martineau unsigned long flags; 152d22f4988SChristoph Paasch bool can_ack; 153*ec3edaa7SPeter Krystad spinlock_t join_list_lock; 15480992017SPaolo Abeni struct work_struct work; 155cec37a6eSPeter Krystad struct list_head conn_list; 156*ec3edaa7SPeter Krystad struct list_head join_list; 1576d0060f6SMat Martineau struct skb_ext *cached_ext; /* for the next sendmsg */ 158f870fa0bSMat Martineau struct socket *subflow; /* outgoing connect/listener/!mp_capable */ 1598ab183deSPaolo Abeni struct sock *first; 1601b1c7a0eSPeter Krystad struct mptcp_pm_data pm; 161f870fa0bSMat Martineau }; 162f870fa0bSMat Martineau 163cec37a6eSPeter Krystad #define mptcp_for_each_subflow(__msk, __subflow) \ 164cec37a6eSPeter Krystad list_for_each_entry(__subflow, &((__msk)->conn_list), node) 165cec37a6eSPeter Krystad 166f870fa0bSMat Martineau static inline struct mptcp_sock *mptcp_sk(const struct sock *sk) 167f870fa0bSMat Martineau { 168f870fa0bSMat Martineau return (struct mptcp_sock *)sk; 169f870fa0bSMat Martineau } 170f870fa0bSMat Martineau 171cec37a6eSPeter Krystad struct mptcp_subflow_request_sock { 172cec37a6eSPeter Krystad struct tcp_request_sock sk; 173d22f4988SChristoph Paasch u16 mp_capable : 1, 174cec37a6eSPeter Krystad mp_join : 1, 175d22f4988SChristoph Paasch backup : 1, 176d22f4988SChristoph Paasch remote_key_valid : 1; 1771b1c7a0eSPeter Krystad u8 local_id; 178f296234cSPeter Krystad u8 remote_id; 179cec37a6eSPeter Krystad u64 local_key; 180cec37a6eSPeter Krystad u64 remote_key; 18179c0949eSPeter Krystad u64 idsn; 18279c0949eSPeter Krystad u32 token; 183648ef4b8SMat Martineau u32 ssn_offset; 184f296234cSPeter Krystad u64 thmac; 185f296234cSPeter Krystad u32 local_nonce; 186f296234cSPeter Krystad u32 remote_nonce; 187cec37a6eSPeter Krystad }; 188cec37a6eSPeter Krystad 189cec37a6eSPeter Krystad static inline struct mptcp_subflow_request_sock * 190cec37a6eSPeter Krystad mptcp_subflow_rsk(const struct request_sock *rsk) 191cec37a6eSPeter Krystad { 192cec37a6eSPeter Krystad return (struct mptcp_subflow_request_sock *)rsk; 193cec37a6eSPeter Krystad } 194cec37a6eSPeter Krystad 1952303f994SPeter Krystad /* MPTCP subflow context */ 1962303f994SPeter Krystad struct mptcp_subflow_context { 197cec37a6eSPeter Krystad struct list_head node;/* conn_list of subflows */ 198cec37a6eSPeter Krystad u64 local_key; 199cec37a6eSPeter Krystad u64 remote_key; 20079c0949eSPeter Krystad u64 idsn; 201648ef4b8SMat Martineau u64 map_seq; 202cc7972eaSChristoph Paasch u32 snd_isn; 20379c0949eSPeter Krystad u32 token; 2046d0060f6SMat Martineau u32 rel_write_seq; 205648ef4b8SMat Martineau u32 map_subflow_seq; 206648ef4b8SMat Martineau u32 ssn_offset; 207648ef4b8SMat Martineau u32 map_data_len; 208cec37a6eSPeter Krystad u32 request_mptcp : 1, /* send MP_CAPABLE */ 209*ec3edaa7SPeter Krystad request_join : 1, /* send MP_JOIN */ 210*ec3edaa7SPeter Krystad request_bkup : 1, 211cec37a6eSPeter Krystad mp_capable : 1, /* remote is MPTCP capable */ 212f296234cSPeter Krystad mp_join : 1, /* remote is JOINing */ 2130be534f5SPaolo Abeni fully_established : 1, /* path validated */ 214f296234cSPeter Krystad pm_notified : 1, /* PM hook called for established status */ 215648ef4b8SMat Martineau conn_finished : 1, 216648ef4b8SMat Martineau map_valid : 1, 217d22f4988SChristoph Paasch mpc_map : 1, 218f296234cSPeter Krystad backup : 1, 219648ef4b8SMat Martineau data_avail : 1, 220d22f4988SChristoph Paasch rx_eof : 1, 22176c42a29SMat Martineau data_fin_tx_enable : 1, 222d22f4988SChristoph Paasch can_ack : 1; /* only after processing the remote a key */ 22376c42a29SMat Martineau u64 data_fin_tx_seq; 224f296234cSPeter Krystad u32 remote_nonce; 225f296234cSPeter Krystad u64 thmac; 226f296234cSPeter Krystad u32 local_nonce; 227*ec3edaa7SPeter Krystad u32 remote_token; 228*ec3edaa7SPeter Krystad u8 hmac[MPTCPOPT_HMAC_LEN]; 229f296234cSPeter Krystad u8 local_id; 230f296234cSPeter Krystad u8 remote_id; 231648ef4b8SMat Martineau 2322303f994SPeter Krystad struct sock *tcp_sock; /* tcp sk backpointer */ 2332303f994SPeter Krystad struct sock *conn; /* parent mptcp_sock */ 234cec37a6eSPeter Krystad const struct inet_connection_sock_af_ops *icsk_af_ops; 235648ef4b8SMat Martineau void (*tcp_data_ready)(struct sock *sk); 236648ef4b8SMat Martineau void (*tcp_state_change)(struct sock *sk); 237648ef4b8SMat Martineau void (*tcp_write_space)(struct sock *sk); 238648ef4b8SMat Martineau 2392303f994SPeter Krystad struct rcu_head rcu; 2402303f994SPeter Krystad }; 2412303f994SPeter Krystad 2422303f994SPeter Krystad static inline struct mptcp_subflow_context * 2432303f994SPeter Krystad mptcp_subflow_ctx(const struct sock *sk) 2442303f994SPeter Krystad { 2452303f994SPeter Krystad struct inet_connection_sock *icsk = inet_csk(sk); 2462303f994SPeter Krystad 2472303f994SPeter Krystad /* Use RCU on icsk_ulp_data only for sock diag code */ 2482303f994SPeter Krystad return (__force struct mptcp_subflow_context *)icsk->icsk_ulp_data; 2492303f994SPeter Krystad } 2502303f994SPeter Krystad 2512303f994SPeter Krystad static inline struct sock * 2522303f994SPeter Krystad mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow) 2532303f994SPeter Krystad { 2542303f994SPeter Krystad return subflow->tcp_sock; 2552303f994SPeter Krystad } 2562303f994SPeter Krystad 257648ef4b8SMat Martineau static inline u64 258648ef4b8SMat Martineau mptcp_subflow_get_map_offset(const struct mptcp_subflow_context *subflow) 259648ef4b8SMat Martineau { 260648ef4b8SMat Martineau return tcp_sk(mptcp_subflow_tcp_sock(subflow))->copied_seq - 261648ef4b8SMat Martineau subflow->ssn_offset - 262648ef4b8SMat Martineau subflow->map_subflow_seq; 263648ef4b8SMat Martineau } 264648ef4b8SMat Martineau 265648ef4b8SMat Martineau static inline u64 266648ef4b8SMat Martineau mptcp_subflow_get_mapped_dsn(const struct mptcp_subflow_context *subflow) 267648ef4b8SMat Martineau { 268648ef4b8SMat Martineau return subflow->map_seq + mptcp_subflow_get_map_offset(subflow); 269648ef4b8SMat Martineau } 270648ef4b8SMat Martineau 271648ef4b8SMat Martineau int mptcp_is_enabled(struct net *net); 272648ef4b8SMat Martineau bool mptcp_subflow_data_available(struct sock *sk); 2732303f994SPeter Krystad void mptcp_subflow_init(void); 274*ec3edaa7SPeter Krystad 275*ec3edaa7SPeter Krystad /* called with sk socket lock held */ 276*ec3edaa7SPeter Krystad int __mptcp_subflow_connect(struct sock *sk, int ifindex, 277*ec3edaa7SPeter Krystad const struct mptcp_addr_info *loc, 278*ec3edaa7SPeter Krystad const struct mptcp_addr_info *remote); 2792303f994SPeter Krystad int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock); 2802303f994SPeter Krystad 281648ef4b8SMat Martineau static inline void mptcp_subflow_tcp_fallback(struct sock *sk, 282648ef4b8SMat Martineau struct mptcp_subflow_context *ctx) 283648ef4b8SMat Martineau { 284648ef4b8SMat Martineau sk->sk_data_ready = ctx->tcp_data_ready; 285648ef4b8SMat Martineau sk->sk_state_change = ctx->tcp_state_change; 286648ef4b8SMat Martineau sk->sk_write_space = ctx->tcp_write_space; 287648ef4b8SMat Martineau 288648ef4b8SMat Martineau inet_csk(sk)->icsk_af_ops = ctx->icsk_af_ops; 289648ef4b8SMat Martineau } 290648ef4b8SMat Martineau 291cec37a6eSPeter Krystad extern const struct inet_connection_sock_af_ops ipv4_specific; 292cec37a6eSPeter Krystad #if IS_ENABLED(CONFIG_MPTCP_IPV6) 293cec37a6eSPeter Krystad extern const struct inet_connection_sock_af_ops ipv6_specific; 294cec37a6eSPeter Krystad #endif 295cec37a6eSPeter Krystad 296648ef4b8SMat Martineau void mptcp_proto_init(void); 297784325e9SMatthieu Baerts #if IS_ENABLED(CONFIG_MPTCP_IPV6) 298784325e9SMatthieu Baerts int mptcp_proto_v6_init(void); 299784325e9SMatthieu Baerts #endif 300648ef4b8SMat Martineau 30158b09919SPaolo Abeni struct sock *mptcp_sk_clone(const struct sock *sk, struct request_sock *req); 302cec37a6eSPeter Krystad void mptcp_get_options(const struct sk_buff *skb, 303cec37a6eSPeter Krystad struct tcp_options_received *opt_rx); 304cec37a6eSPeter Krystad 305cec37a6eSPeter Krystad void mptcp_finish_connect(struct sock *sk); 3062e52213cSFlorian Westphal void mptcp_data_ready(struct sock *sk, struct sock *ssk); 307f296234cSPeter Krystad bool mptcp_finish_join(struct sock *sk); 308cec37a6eSPeter Krystad 30979c0949eSPeter Krystad int mptcp_token_new_request(struct request_sock *req); 31079c0949eSPeter Krystad void mptcp_token_destroy_request(u32 token); 31179c0949eSPeter Krystad int mptcp_token_new_connect(struct sock *sk); 31258b09919SPaolo Abeni int mptcp_token_new_accept(u32 token, struct sock *conn); 313f296234cSPeter Krystad struct mptcp_sock *mptcp_token_get_sock(u32 token); 31479c0949eSPeter Krystad void mptcp_token_destroy(u32 token); 31579c0949eSPeter Krystad 31679c0949eSPeter Krystad void mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn); 31779c0949eSPeter Krystad static inline void mptcp_crypto_key_gen_sha(u64 *key, u32 *token, u64 *idsn) 31879c0949eSPeter Krystad { 31979c0949eSPeter Krystad /* we might consider a faster version that computes the key as a 32079c0949eSPeter Krystad * hash of some information available in the MPTCP socket. Use 32179c0949eSPeter Krystad * random data at the moment, as it's probably the safest option 32279c0949eSPeter Krystad * in case multiple sockets are opened in different namespaces at 32379c0949eSPeter Krystad * the same time. 32479c0949eSPeter Krystad */ 32579c0949eSPeter Krystad get_random_bytes(key, sizeof(u64)); 32679c0949eSPeter Krystad mptcp_crypto_key_sha(*key, token, idsn); 32779c0949eSPeter Krystad } 32879c0949eSPeter Krystad 3293df523abSPeter Krystad void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac); 33079c0949eSPeter Krystad 3311b1c7a0eSPeter Krystad void mptcp_pm_init(void); 3321b1c7a0eSPeter Krystad void mptcp_pm_data_init(struct mptcp_sock *msk); 3331b1c7a0eSPeter Krystad void mptcp_pm_new_connection(struct mptcp_sock *msk, int server_side); 3341b1c7a0eSPeter Krystad void mptcp_pm_fully_established(struct mptcp_sock *msk); 3351b1c7a0eSPeter Krystad bool mptcp_pm_allow_new_subflow(struct mptcp_sock *msk); 3361b1c7a0eSPeter Krystad void mptcp_pm_connection_closed(struct mptcp_sock *msk); 3371b1c7a0eSPeter Krystad void mptcp_pm_subflow_established(struct mptcp_sock *msk, 3381b1c7a0eSPeter Krystad struct mptcp_subflow_context *subflow); 3391b1c7a0eSPeter Krystad void mptcp_pm_subflow_closed(struct mptcp_sock *msk, u8 id); 3401b1c7a0eSPeter Krystad void mptcp_pm_add_addr_received(struct mptcp_sock *msk, 3411b1c7a0eSPeter Krystad const struct mptcp_addr_info *addr); 3421b1c7a0eSPeter Krystad 3431b1c7a0eSPeter Krystad int mptcp_pm_announce_addr(struct mptcp_sock *msk, 3441b1c7a0eSPeter Krystad const struct mptcp_addr_info *addr); 3451b1c7a0eSPeter Krystad int mptcp_pm_remove_addr(struct mptcp_sock *msk, u8 local_id); 3461b1c7a0eSPeter Krystad int mptcp_pm_remove_subflow(struct mptcp_sock *msk, u8 remote_id); 3471b1c7a0eSPeter Krystad 3481b1c7a0eSPeter Krystad static inline bool mptcp_pm_should_signal(struct mptcp_sock *msk) 3491b1c7a0eSPeter Krystad { 3501b1c7a0eSPeter Krystad return READ_ONCE(msk->pm.addr_signal); 3511b1c7a0eSPeter Krystad } 3521b1c7a0eSPeter Krystad 3531b1c7a0eSPeter Krystad static inline unsigned int mptcp_add_addr_len(int family) 3541b1c7a0eSPeter Krystad { 3551b1c7a0eSPeter Krystad if (family == AF_INET) 3561b1c7a0eSPeter Krystad return TCPOLEN_MPTCP_ADD_ADDR; 3571b1c7a0eSPeter Krystad return TCPOLEN_MPTCP_ADD_ADDR6; 3581b1c7a0eSPeter Krystad } 3591b1c7a0eSPeter Krystad 3601b1c7a0eSPeter Krystad bool mptcp_pm_addr_signal(struct mptcp_sock *msk, unsigned int remaining, 3611b1c7a0eSPeter Krystad struct mptcp_addr_info *saddr); 3621b1c7a0eSPeter Krystad int mptcp_pm_get_local_id(struct mptcp_sock *msk, struct sock_common *skc); 3631b1c7a0eSPeter Krystad 3646d0060f6SMat Martineau static inline struct mptcp_ext *mptcp_get_ext(struct sk_buff *skb) 3656d0060f6SMat Martineau { 3666d0060f6SMat Martineau return (struct mptcp_ext *)skb_ext_find(skb, SKB_EXT_MPTCP); 3676d0060f6SMat Martineau } 3686d0060f6SMat Martineau 369648ef4b8SMat Martineau static inline bool before64(__u64 seq1, __u64 seq2) 370648ef4b8SMat Martineau { 371648ef4b8SMat Martineau return (__s64)(seq1 - seq2) < 0; 372648ef4b8SMat Martineau } 373648ef4b8SMat Martineau 374648ef4b8SMat Martineau #define after64(seq2, seq1) before64(seq1, seq2) 375648ef4b8SMat Martineau 376f870fa0bSMat Martineau #endif /* __MPTCP_PROTOCOL_H */ 377