| /* 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 |