/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */ #ifndef __MPTCP_BPF_H__ #define __MPTCP_BPF_H__ #include "bpf_experimental.h" /* list helpers from include/linux/list.h */ static inline int list_is_head(const struct list_head *list, const struct list_head *head) { return list == head; } #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) #define list_entry_is_head(pos, head, member) \ list_is_head(&pos->member, (head)) /* small difference: 'can_loop' has been added in the conditions */ #define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ !list_entry_is_head(pos, head, member) && can_loop; \ pos = list_next_entry(pos, member)) /* mptcp helpers from protocol.h */ #define mptcp_for_each_subflow(__msk, __subflow) \ list_for_each_entry(__subflow, &((__msk)->conn_list), node) static __always_inline struct sock * mptcp_subflow_tcp_sock(const struct mptcp_subflow_context *subflow) { return subflow->tcp_sock; } #endif