162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __PACKET_INTERNAL_H__
362306a36Sopenharmony_ci#define __PACKET_INTERNAL_H__
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/refcount.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_cistruct packet_mclist {
862306a36Sopenharmony_ci	struct packet_mclist	*next;
962306a36Sopenharmony_ci	int			ifindex;
1062306a36Sopenharmony_ci	int			count;
1162306a36Sopenharmony_ci	unsigned short		type;
1262306a36Sopenharmony_ci	unsigned short		alen;
1362306a36Sopenharmony_ci	unsigned char		addr[MAX_ADDR_LEN];
1462306a36Sopenharmony_ci};
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/* kbdq - kernel block descriptor queue */
1762306a36Sopenharmony_cistruct tpacket_kbdq_core {
1862306a36Sopenharmony_ci	struct pgv	*pkbdq;
1962306a36Sopenharmony_ci	unsigned int	feature_req_word;
2062306a36Sopenharmony_ci	unsigned int	hdrlen;
2162306a36Sopenharmony_ci	unsigned char	reset_pending_on_curr_blk;
2262306a36Sopenharmony_ci	unsigned char   delete_blk_timer;
2362306a36Sopenharmony_ci	unsigned short	kactive_blk_num;
2462306a36Sopenharmony_ci	unsigned short	blk_sizeof_priv;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	/* last_kactive_blk_num:
2762306a36Sopenharmony_ci	 * trick to see if user-space has caught up
2862306a36Sopenharmony_ci	 * in order to avoid refreshing timer when every single pkt arrives.
2962306a36Sopenharmony_ci	 */
3062306a36Sopenharmony_ci	unsigned short	last_kactive_blk_num;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	char		*pkblk_start;
3362306a36Sopenharmony_ci	char		*pkblk_end;
3462306a36Sopenharmony_ci	int		kblk_size;
3562306a36Sopenharmony_ci	unsigned int	max_frame_len;
3662306a36Sopenharmony_ci	unsigned int	knum_blocks;
3762306a36Sopenharmony_ci	uint64_t	knxt_seq_num;
3862306a36Sopenharmony_ci	char		*prev;
3962306a36Sopenharmony_ci	char		*nxt_offset;
4062306a36Sopenharmony_ci	struct sk_buff	*skb;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	rwlock_t	blk_fill_in_prog_lock;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	/* Default is set to 8ms */
4562306a36Sopenharmony_ci#define DEFAULT_PRB_RETIRE_TOV	(8)
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	unsigned short  retire_blk_tov;
4862306a36Sopenharmony_ci	unsigned short  version;
4962306a36Sopenharmony_ci	unsigned long	tov_in_jiffies;
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	/* timer to retire an outstanding block */
5262306a36Sopenharmony_ci	struct timer_list retire_blk_timer;
5362306a36Sopenharmony_ci};
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistruct pgv {
5662306a36Sopenharmony_ci	char *buffer;
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistruct packet_ring_buffer {
6062306a36Sopenharmony_ci	struct pgv		*pg_vec;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	unsigned int		head;
6362306a36Sopenharmony_ci	unsigned int		frames_per_block;
6462306a36Sopenharmony_ci	unsigned int		frame_size;
6562306a36Sopenharmony_ci	unsigned int		frame_max;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	unsigned int		pg_vec_order;
6862306a36Sopenharmony_ci	unsigned int		pg_vec_pages;
6962306a36Sopenharmony_ci	unsigned int		pg_vec_len;
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	unsigned int __percpu	*pending_refcnt;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	union {
7462306a36Sopenharmony_ci		unsigned long			*rx_owner_map;
7562306a36Sopenharmony_ci		struct tpacket_kbdq_core	prb_bdqc;
7662306a36Sopenharmony_ci	};
7762306a36Sopenharmony_ci};
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ciextern struct mutex fanout_mutex;
8062306a36Sopenharmony_ci#define PACKET_FANOUT_MAX	(1 << 16)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct packet_fanout {
8362306a36Sopenharmony_ci	possible_net_t		net;
8462306a36Sopenharmony_ci	unsigned int		num_members;
8562306a36Sopenharmony_ci	u32			max_num_members;
8662306a36Sopenharmony_ci	u16			id;
8762306a36Sopenharmony_ci	u8			type;
8862306a36Sopenharmony_ci	u8			flags;
8962306a36Sopenharmony_ci	union {
9062306a36Sopenharmony_ci		atomic_t		rr_cur;
9162306a36Sopenharmony_ci		struct bpf_prog __rcu	*bpf_prog;
9262306a36Sopenharmony_ci	};
9362306a36Sopenharmony_ci	struct list_head	list;
9462306a36Sopenharmony_ci	spinlock_t		lock;
9562306a36Sopenharmony_ci	refcount_t		sk_ref;
9662306a36Sopenharmony_ci	struct packet_type	prot_hook ____cacheline_aligned_in_smp;
9762306a36Sopenharmony_ci	struct sock	__rcu	*arr[];
9862306a36Sopenharmony_ci};
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistruct packet_rollover {
10162306a36Sopenharmony_ci	int			sock;
10262306a36Sopenharmony_ci	atomic_long_t		num;
10362306a36Sopenharmony_ci	atomic_long_t		num_huge;
10462306a36Sopenharmony_ci	atomic_long_t		num_failed;
10562306a36Sopenharmony_ci#define ROLLOVER_HLEN	(L1_CACHE_BYTES / sizeof(u32))
10662306a36Sopenharmony_ci	u32			history[ROLLOVER_HLEN] ____cacheline_aligned;
10762306a36Sopenharmony_ci} ____cacheline_aligned_in_smp;
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistruct packet_sock {
11062306a36Sopenharmony_ci	/* struct sock has to be the first member of packet_sock */
11162306a36Sopenharmony_ci	struct sock		sk;
11262306a36Sopenharmony_ci	struct packet_fanout	*fanout;
11362306a36Sopenharmony_ci	union  tpacket_stats_u	stats;
11462306a36Sopenharmony_ci	struct packet_ring_buffer	rx_ring;
11562306a36Sopenharmony_ci	struct packet_ring_buffer	tx_ring;
11662306a36Sopenharmony_ci	int			copy_thresh;
11762306a36Sopenharmony_ci	spinlock_t		bind_lock;
11862306a36Sopenharmony_ci	struct mutex		pg_vec_lock;
11962306a36Sopenharmony_ci	unsigned long		flags;
12062306a36Sopenharmony_ci	int			ifindex;	/* bound device		*/
12162306a36Sopenharmony_ci	u8			vnet_hdr_sz;
12262306a36Sopenharmony_ci	__be16			num;
12362306a36Sopenharmony_ci	struct packet_rollover	*rollover;
12462306a36Sopenharmony_ci	struct packet_mclist	*mclist;
12562306a36Sopenharmony_ci	atomic_long_t		mapped;
12662306a36Sopenharmony_ci	enum tpacket_versions	tp_version;
12762306a36Sopenharmony_ci	unsigned int		tp_hdrlen;
12862306a36Sopenharmony_ci	unsigned int		tp_reserve;
12962306a36Sopenharmony_ci	unsigned int		tp_tstamp;
13062306a36Sopenharmony_ci	struct completion	skb_completion;
13162306a36Sopenharmony_ci	struct net_device __rcu	*cached_dev;
13262306a36Sopenharmony_ci	struct packet_type	prot_hook ____cacheline_aligned_in_smp;
13362306a36Sopenharmony_ci	atomic_t		tp_drops ____cacheline_aligned_in_smp;
13462306a36Sopenharmony_ci};
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci#define pkt_sk(ptr) container_of_const(ptr, struct packet_sock, sk)
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_cienum packet_sock_flags {
13962306a36Sopenharmony_ci	PACKET_SOCK_ORIGDEV,
14062306a36Sopenharmony_ci	PACKET_SOCK_AUXDATA,
14162306a36Sopenharmony_ci	PACKET_SOCK_TX_HAS_OFF,
14262306a36Sopenharmony_ci	PACKET_SOCK_TP_LOSS,
14362306a36Sopenharmony_ci	PACKET_SOCK_RUNNING,
14462306a36Sopenharmony_ci	PACKET_SOCK_PRESSURE,
14562306a36Sopenharmony_ci	PACKET_SOCK_QDISC_BYPASS,
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_cistatic inline void packet_sock_flag_set(struct packet_sock *po,
14962306a36Sopenharmony_ci					enum packet_sock_flags flag,
15062306a36Sopenharmony_ci					bool val)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	if (val)
15362306a36Sopenharmony_ci		set_bit(flag, &po->flags);
15462306a36Sopenharmony_ci	else
15562306a36Sopenharmony_ci		clear_bit(flag, &po->flags);
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic inline bool packet_sock_flag(const struct packet_sock *po,
15962306a36Sopenharmony_ci				    enum packet_sock_flags flag)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	return test_bit(flag, &po->flags);
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#endif
165