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/types.h> 13 14 /* MPTCP sk_buff extension data */ 15 struct mptcp_ext { 16 u64 data_ack; 17 u64 data_seq; 18 u32 subflow_seq; 19 u16 data_len; 20 u8 use_map:1, 21 dsn64:1, 22 data_fin:1, 23 use_ack:1, 24 ack64:1, 25 __unused:3; 26 /* one byte hole */ 27 }; 28 29 #ifdef CONFIG_MPTCP 30 31 void mptcp_init(void); 32 33 /* move the skb extension owership, with the assumption that 'to' is 34 * newly allocated 35 */ 36 static inline void mptcp_skb_ext_move(struct sk_buff *to, 37 struct sk_buff *from) 38 { 39 if (!skb_ext_exist(from, SKB_EXT_MPTCP)) 40 return; 41 42 if (WARN_ON_ONCE(to->active_extensions)) 43 skb_ext_put(to); 44 45 to->active_extensions = from->active_extensions; 46 to->extensions = from->extensions; 47 from->active_extensions = 0; 48 } 49 50 static inline bool mptcp_ext_matches(const struct mptcp_ext *to_ext, 51 const struct mptcp_ext *from_ext) 52 { 53 /* MPTCP always clears the ext when adding it to the skb, so 54 * holes do not bother us here 55 */ 56 return !from_ext || 57 (to_ext && from_ext && 58 !memcmp(from_ext, to_ext, sizeof(struct mptcp_ext))); 59 } 60 61 /* check if skbs can be collapsed. 62 * MPTCP collapse is allowed if neither @to or @from carry an mptcp data 63 * mapping, or if the extension of @to is the same as @from. 64 * Collapsing is not possible if @to lacks an extension, but @from carries one. 65 */ 66 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 67 const struct sk_buff *from) 68 { 69 return mptcp_ext_matches(skb_ext_find(to, SKB_EXT_MPTCP), 70 skb_ext_find(from, SKB_EXT_MPTCP)); 71 } 72 73 #else 74 75 static inline void mptcp_init(void) 76 { 77 } 78 79 static inline void mptcp_skb_ext_move(struct sk_buff *to, 80 const struct sk_buff *from) 81 { 82 } 83 84 static inline bool mptcp_skb_can_collapse(const struct sk_buff *to, 85 const struct sk_buff *from) 86 { 87 return true; 88 } 89 90 #endif /* CONFIG_MPTCP */ 91 92 #if IS_ENABLED(CONFIG_MPTCP_IPV6) 93 int mptcpv6_init(void); 94 #elif IS_ENABLED(CONFIG_IPV6) 95 static inline int mptcpv6_init(void) 96 { 97 return 0; 98 } 99 #endif 100 101 #endif /* __NET_MPTCP_H */ 102