xref: /linux/include/uapi/linux/if_packet.h (revision 4a69a864209e9ab436d4a58e8028ac96cc873d15)
1607ca46eSDavid Howells #ifndef __LINUX_IF_PACKET_H
2607ca46eSDavid Howells #define __LINUX_IF_PACKET_H
3607ca46eSDavid Howells 
4607ca46eSDavid Howells #include <linux/types.h>
5607ca46eSDavid Howells 
6607ca46eSDavid Howells struct sockaddr_pkt {
7607ca46eSDavid Howells 	unsigned short spkt_family;
8607ca46eSDavid Howells 	unsigned char spkt_device[14];
9607ca46eSDavid Howells 	__be16 spkt_protocol;
10607ca46eSDavid Howells };
11607ca46eSDavid Howells 
12607ca46eSDavid Howells struct sockaddr_ll {
13607ca46eSDavid Howells 	unsigned short	sll_family;
14607ca46eSDavid Howells 	__be16		sll_protocol;
15607ca46eSDavid Howells 	int		sll_ifindex;
16607ca46eSDavid Howells 	unsigned short	sll_hatype;
17607ca46eSDavid Howells 	unsigned char	sll_pkttype;
18607ca46eSDavid Howells 	unsigned char	sll_halen;
19607ca46eSDavid Howells 	unsigned char	sll_addr[8];
20607ca46eSDavid Howells };
21607ca46eSDavid Howells 
22607ca46eSDavid Howells /* Packet types */
23607ca46eSDavid Howells 
24607ca46eSDavid Howells #define PACKET_HOST		0		/* To us		*/
25607ca46eSDavid Howells #define PACKET_BROADCAST	1		/* To all		*/
26607ca46eSDavid Howells #define PACKET_MULTICAST	2		/* To group		*/
27607ca46eSDavid Howells #define PACKET_OTHERHOST	3		/* To someone else 	*/
28607ca46eSDavid Howells #define PACKET_OUTGOING		4		/* Outgoing of any type */
29607ca46eSDavid Howells #define PACKET_LOOPBACK		5		/* MC/BRD frame looped back */
30604d13c9SDaniel Borkmann #define PACKET_USER		6		/* To user space	*/
31604d13c9SDaniel Borkmann #define PACKET_KERNEL		7		/* To kernel space	*/
32604d13c9SDaniel Borkmann /* Unused, PACKET_FASTROUTE and PACKET_LOOPBACK are invisible to user space */
33607ca46eSDavid Howells #define PACKET_FASTROUTE	6		/* Fastrouted frame	*/
34607ca46eSDavid Howells 
35607ca46eSDavid Howells /* Packet socket options */
36607ca46eSDavid Howells 
37607ca46eSDavid Howells #define PACKET_ADD_MEMBERSHIP		1
38607ca46eSDavid Howells #define PACKET_DROP_MEMBERSHIP		2
39607ca46eSDavid Howells #define PACKET_RECV_OUTPUT		3
40607ca46eSDavid Howells /* Value 4 is still used by obsolete turbo-packet. */
41607ca46eSDavid Howells #define PACKET_RX_RING			5
42607ca46eSDavid Howells #define PACKET_STATISTICS		6
43607ca46eSDavid Howells #define PACKET_COPY_THRESH		7
44607ca46eSDavid Howells #define PACKET_AUXDATA			8
45607ca46eSDavid Howells #define PACKET_ORIGDEV			9
46607ca46eSDavid Howells #define PACKET_VERSION			10
47607ca46eSDavid Howells #define PACKET_HDRLEN			11
48607ca46eSDavid Howells #define PACKET_RESERVE			12
49607ca46eSDavid Howells #define PACKET_TX_RING			13
50607ca46eSDavid Howells #define PACKET_LOSS			14
51607ca46eSDavid Howells #define PACKET_VNET_HDR			15
52607ca46eSDavid Howells #define PACKET_TX_TIMESTAMP		16
53607ca46eSDavid Howells #define PACKET_TIMESTAMP		17
54607ca46eSDavid Howells #define PACKET_FANOUT			18
555920cd3aSPaul Chavent #define PACKET_TX_HAS_OFF		19
56d346a3faSDaniel Borkmann #define PACKET_QDISC_BYPASS		20
57a9b63918SWillem de Bruijn #define PACKET_ROLLOVER_STATS		21
5847dceb8eSWillem de Bruijn #define PACKET_FANOUT_DATA		22
59607ca46eSDavid Howells 
60607ca46eSDavid Howells #define PACKET_FANOUT_HASH		0
61607ca46eSDavid Howells #define PACKET_FANOUT_LB		1
62607ca46eSDavid Howells #define PACKET_FANOUT_CPU		2
6377f65ebdSWillem de Bruijn #define PACKET_FANOUT_ROLLOVER		3
645df0ddfbSDaniel Borkmann #define PACKET_FANOUT_RND		4
652d36097dSNeil Horman #define PACKET_FANOUT_QM		5
6647dceb8eSWillem de Bruijn #define PACKET_FANOUT_CBPF		6
67f2e52095SWillem de Bruijn #define PACKET_FANOUT_EBPF		7
6877f65ebdSWillem de Bruijn #define PACKET_FANOUT_FLAG_ROLLOVER	0x1000
69*4a69a864SMike Maloney #define PACKET_FANOUT_FLAG_UNIQUEID	0x2000
70607ca46eSDavid Howells #define PACKET_FANOUT_FLAG_DEFRAG	0x8000
71607ca46eSDavid Howells 
72607ca46eSDavid Howells struct tpacket_stats {
73607ca46eSDavid Howells 	unsigned int	tp_packets;
74607ca46eSDavid Howells 	unsigned int	tp_drops;
75607ca46eSDavid Howells };
76607ca46eSDavid Howells 
77607ca46eSDavid Howells struct tpacket_stats_v3 {
78607ca46eSDavid Howells 	unsigned int	tp_packets;
79607ca46eSDavid Howells 	unsigned int	tp_drops;
80607ca46eSDavid Howells 	unsigned int	tp_freeze_q_cnt;
81607ca46eSDavid Howells };
82607ca46eSDavid Howells 
83a9b63918SWillem de Bruijn struct tpacket_rollover_stats {
84a9b63918SWillem de Bruijn 	__aligned_u64	tp_all;
85a9b63918SWillem de Bruijn 	__aligned_u64	tp_huge;
86a9b63918SWillem de Bruijn 	__aligned_u64	tp_failed;
87a9b63918SWillem de Bruijn };
88a9b63918SWillem de Bruijn 
89607ca46eSDavid Howells union tpacket_stats_u {
90607ca46eSDavid Howells 	struct tpacket_stats stats1;
91607ca46eSDavid Howells 	struct tpacket_stats_v3 stats3;
92607ca46eSDavid Howells };
93607ca46eSDavid Howells 
94607ca46eSDavid Howells struct tpacket_auxdata {
95607ca46eSDavid Howells 	__u32		tp_status;
96607ca46eSDavid Howells 	__u32		tp_len;
97607ca46eSDavid Howells 	__u32		tp_snaplen;
98607ca46eSDavid Howells 	__u16		tp_mac;
99607ca46eSDavid Howells 	__u16		tp_net;
100607ca46eSDavid Howells 	__u16		tp_vlan_tci;
101a0cdfcf3SAtzm Watanabe 	__u16		tp_vlan_tpid;
102607ca46eSDavid Howells };
103607ca46eSDavid Howells 
104607ca46eSDavid Howells /* Rx ring - header status */
1057276d5d7SDaniel Borkmann #define TP_STATUS_KERNEL		      0
1067276d5d7SDaniel Borkmann #define TP_STATUS_USER			(1 << 0)
1077276d5d7SDaniel Borkmann #define TP_STATUS_COPY			(1 << 1)
1087276d5d7SDaniel Borkmann #define TP_STATUS_LOSING		(1 << 2)
1097276d5d7SDaniel Borkmann #define TP_STATUS_CSUMNOTREADY		(1 << 3)
1107276d5d7SDaniel Borkmann #define TP_STATUS_VLAN_VALID		(1 << 4) /* auxdata has valid tp_vlan_tci */
1117276d5d7SDaniel Borkmann #define TP_STATUS_BLK_TMO		(1 << 5)
112a0cdfcf3SAtzm Watanabe #define TP_STATUS_VLAN_TPID_VALID	(1 << 6) /* auxdata has valid tp_vlan_tpid */
113682f048bSAlexander Drozdov #define TP_STATUS_CSUM_VALID		(1 << 7)
114607ca46eSDavid Howells 
115607ca46eSDavid Howells /* Tx ring - header status */
1167276d5d7SDaniel Borkmann #define TP_STATUS_AVAILABLE	      0
1177276d5d7SDaniel Borkmann #define TP_STATUS_SEND_REQUEST	(1 << 0)
1187276d5d7SDaniel Borkmann #define TP_STATUS_SENDING	(1 << 1)
1197276d5d7SDaniel Borkmann #define TP_STATUS_WRONG_FORMAT	(1 << 2)
120607ca46eSDavid Howells 
121b9c32fb2SDaniel Borkmann /* Rx and Tx ring - header status */
122b9c32fb2SDaniel Borkmann #define TP_STATUS_TS_SOFTWARE		(1 << 29)
12368a360e8SWillem de Bruijn #define TP_STATUS_TS_SYS_HARDWARE	(1 << 30) /* deprecated, never set */
124b9c32fb2SDaniel Borkmann #define TP_STATUS_TS_RAW_HARDWARE	(1 << 31)
125b9c32fb2SDaniel Borkmann 
126607ca46eSDavid Howells /* Rx ring - feature request bits */
127607ca46eSDavid Howells #define TP_FT_REQ_FILL_RXHASH	0x1
128607ca46eSDavid Howells 
129607ca46eSDavid Howells struct tpacket_hdr {
130607ca46eSDavid Howells 	unsigned long	tp_status;
131607ca46eSDavid Howells 	unsigned int	tp_len;
132607ca46eSDavid Howells 	unsigned int	tp_snaplen;
133607ca46eSDavid Howells 	unsigned short	tp_mac;
134607ca46eSDavid Howells 	unsigned short	tp_net;
135607ca46eSDavid Howells 	unsigned int	tp_sec;
136607ca46eSDavid Howells 	unsigned int	tp_usec;
137607ca46eSDavid Howells };
138607ca46eSDavid Howells 
139607ca46eSDavid Howells #define TPACKET_ALIGNMENT	16
140607ca46eSDavid Howells #define TPACKET_ALIGN(x)	(((x)+TPACKET_ALIGNMENT-1)&~(TPACKET_ALIGNMENT-1))
141607ca46eSDavid Howells #define TPACKET_HDRLEN		(TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + sizeof(struct sockaddr_ll))
142607ca46eSDavid Howells 
143607ca46eSDavid Howells struct tpacket2_hdr {
144607ca46eSDavid Howells 	__u32		tp_status;
145607ca46eSDavid Howells 	__u32		tp_len;
146607ca46eSDavid Howells 	__u32		tp_snaplen;
147607ca46eSDavid Howells 	__u16		tp_mac;
148607ca46eSDavid Howells 	__u16		tp_net;
149607ca46eSDavid Howells 	__u32		tp_sec;
150607ca46eSDavid Howells 	__u32		tp_nsec;
151607ca46eSDavid Howells 	__u16		tp_vlan_tci;
152a0cdfcf3SAtzm Watanabe 	__u16		tp_vlan_tpid;
153a0cdfcf3SAtzm Watanabe 	__u8		tp_padding[4];
154607ca46eSDavid Howells };
155607ca46eSDavid Howells 
156607ca46eSDavid Howells struct tpacket_hdr_variant1 {
157607ca46eSDavid Howells 	__u32	tp_rxhash;
158607ca46eSDavid Howells 	__u32	tp_vlan_tci;
159a0cdfcf3SAtzm Watanabe 	__u16	tp_vlan_tpid;
160a0cdfcf3SAtzm Watanabe 	__u16	tp_padding;
161607ca46eSDavid Howells };
162607ca46eSDavid Howells 
163607ca46eSDavid Howells struct tpacket3_hdr {
164607ca46eSDavid Howells 	__u32		tp_next_offset;
165607ca46eSDavid Howells 	__u32		tp_sec;
166607ca46eSDavid Howells 	__u32		tp_nsec;
167607ca46eSDavid Howells 	__u32		tp_snaplen;
168607ca46eSDavid Howells 	__u32		tp_len;
169607ca46eSDavid Howells 	__u32		tp_status;
170607ca46eSDavid Howells 	__u16		tp_mac;
171607ca46eSDavid Howells 	__u16		tp_net;
172607ca46eSDavid Howells 	/* pkt_hdr variants */
173607ca46eSDavid Howells 	union {
174607ca46eSDavid Howells 		struct tpacket_hdr_variant1 hv1;
175607ca46eSDavid Howells 	};
176a0cdfcf3SAtzm Watanabe 	__u8		tp_padding[8];
177607ca46eSDavid Howells };
178607ca46eSDavid Howells 
179607ca46eSDavid Howells struct tpacket_bd_ts {
180607ca46eSDavid Howells 	unsigned int ts_sec;
181607ca46eSDavid Howells 	union {
182607ca46eSDavid Howells 		unsigned int ts_usec;
183607ca46eSDavid Howells 		unsigned int ts_nsec;
184607ca46eSDavid Howells 	};
185607ca46eSDavid Howells };
186607ca46eSDavid Howells 
187607ca46eSDavid Howells struct tpacket_hdr_v1 {
188607ca46eSDavid Howells 	__u32	block_status;
189607ca46eSDavid Howells 	__u32	num_pkts;
190607ca46eSDavid Howells 	__u32	offset_to_first_pkt;
191607ca46eSDavid Howells 
192607ca46eSDavid Howells 	/* Number of valid bytes (including padding)
193607ca46eSDavid Howells 	 * blk_len <= tp_block_size
194607ca46eSDavid Howells 	 */
195607ca46eSDavid Howells 	__u32	blk_len;
196607ca46eSDavid Howells 
197607ca46eSDavid Howells 	/*
198607ca46eSDavid Howells 	 * Quite a few uses of sequence number:
199607ca46eSDavid Howells 	 * 1. Make sure cache flush etc worked.
200607ca46eSDavid Howells 	 *    Well, one can argue - why not use the increasing ts below?
201607ca46eSDavid Howells 	 *    But look at 2. below first.
202607ca46eSDavid Howells 	 * 2. When you pass around blocks to other user space decoders,
203607ca46eSDavid Howells 	 *    you can see which blk[s] is[are] outstanding etc.
204607ca46eSDavid Howells 	 * 3. Validate kernel code.
205607ca46eSDavid Howells 	 */
206607ca46eSDavid Howells 	__aligned_u64	seq_num;
207607ca46eSDavid Howells 
208607ca46eSDavid Howells 	/*
209607ca46eSDavid Howells 	 * ts_last_pkt:
210607ca46eSDavid Howells 	 *
211607ca46eSDavid Howells 	 * Case 1.	Block has 'N'(N >=1) packets and TMO'd(timed out)
212607ca46eSDavid Howells 	 *		ts_last_pkt == 'time-stamp of last packet' and NOT the
213607ca46eSDavid Howells 	 *		time when the timer fired and the block was closed.
214607ca46eSDavid Howells 	 *		By providing the ts of the last packet we can absolutely
215607ca46eSDavid Howells 	 *		guarantee that time-stamp wise, the first packet in the
216607ca46eSDavid Howells 	 *		next block will never precede the last packet of the
217607ca46eSDavid Howells 	 *		previous block.
218607ca46eSDavid Howells 	 * Case 2.	Block has zero packets and TMO'd
219607ca46eSDavid Howells 	 *		ts_last_pkt = time when the timer fired and the block
220607ca46eSDavid Howells 	 *		was closed.
221607ca46eSDavid Howells 	 * Case 3.	Block has 'N' packets and NO TMO.
222607ca46eSDavid Howells 	 *		ts_last_pkt = time-stamp of the last pkt in the block.
223607ca46eSDavid Howells 	 *
224607ca46eSDavid Howells 	 * ts_first_pkt:
225607ca46eSDavid Howells 	 *		Is always the time-stamp when the block was opened.
226607ca46eSDavid Howells 	 *		Case a)	ZERO packets
227607ca46eSDavid Howells 	 *			No packets to deal with but atleast you know the
228607ca46eSDavid Howells 	 *			time-interval of this block.
229607ca46eSDavid Howells 	 *		Case b) Non-zero packets
230607ca46eSDavid Howells 	 *			Use the ts of the first packet in the block.
231607ca46eSDavid Howells 	 *
232607ca46eSDavid Howells 	 */
233607ca46eSDavid Howells 	struct tpacket_bd_ts	ts_first_pkt, ts_last_pkt;
234607ca46eSDavid Howells };
235607ca46eSDavid Howells 
236607ca46eSDavid Howells union tpacket_bd_header_u {
237607ca46eSDavid Howells 	struct tpacket_hdr_v1 bh1;
238607ca46eSDavid Howells };
239607ca46eSDavid Howells 
240607ca46eSDavid Howells struct tpacket_block_desc {
241607ca46eSDavid Howells 	__u32 version;
242607ca46eSDavid Howells 	__u32 offset_to_priv;
243607ca46eSDavid Howells 	union tpacket_bd_header_u hdr;
244607ca46eSDavid Howells };
245607ca46eSDavid Howells 
246607ca46eSDavid Howells #define TPACKET2_HDRLEN		(TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
247607ca46eSDavid Howells #define TPACKET3_HDRLEN		(TPACKET_ALIGN(sizeof(struct tpacket3_hdr)) + sizeof(struct sockaddr_ll))
248607ca46eSDavid Howells 
249607ca46eSDavid Howells enum tpacket_versions {
250607ca46eSDavid Howells 	TPACKET_V1,
251607ca46eSDavid Howells 	TPACKET_V2,
252607ca46eSDavid Howells 	TPACKET_V3
253607ca46eSDavid Howells };
254607ca46eSDavid Howells 
255607ca46eSDavid Howells /*
256607ca46eSDavid Howells    Frame structure:
257607ca46eSDavid Howells 
258607ca46eSDavid Howells    - Start. Frame must be aligned to TPACKET_ALIGNMENT=16
259607ca46eSDavid Howells    - struct tpacket_hdr
260607ca46eSDavid Howells    - pad to TPACKET_ALIGNMENT=16
261607ca46eSDavid Howells    - struct sockaddr_ll
262607ca46eSDavid Howells    - Gap, chosen so that packet data (Start+tp_net) alignes to TPACKET_ALIGNMENT=16
263607ca46eSDavid Howells    - Start+tp_mac: [ Optional MAC header ]
264607ca46eSDavid Howells    - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
265607ca46eSDavid Howells    - Pad to align to TPACKET_ALIGNMENT=16
266607ca46eSDavid Howells  */
267607ca46eSDavid Howells 
268607ca46eSDavid Howells struct tpacket_req {
269607ca46eSDavid Howells 	unsigned int	tp_block_size;	/* Minimal size of contiguous block */
270607ca46eSDavid Howells 	unsigned int	tp_block_nr;	/* Number of blocks */
271607ca46eSDavid Howells 	unsigned int	tp_frame_size;	/* Size of frame */
272607ca46eSDavid Howells 	unsigned int	tp_frame_nr;	/* Total number of frames */
273607ca46eSDavid Howells };
274607ca46eSDavid Howells 
275607ca46eSDavid Howells struct tpacket_req3 {
276607ca46eSDavid Howells 	unsigned int	tp_block_size;	/* Minimal size of contiguous block */
277607ca46eSDavid Howells 	unsigned int	tp_block_nr;	/* Number of blocks */
278607ca46eSDavid Howells 	unsigned int	tp_frame_size;	/* Size of frame */
279607ca46eSDavid Howells 	unsigned int	tp_frame_nr;	/* Total number of frames */
280607ca46eSDavid Howells 	unsigned int	tp_retire_blk_tov; /* timeout in msecs */
281607ca46eSDavid Howells 	unsigned int	tp_sizeof_priv; /* offset to private data area */
282607ca46eSDavid Howells 	unsigned int	tp_feature_req_word;
283607ca46eSDavid Howells };
284607ca46eSDavid Howells 
285607ca46eSDavid Howells union tpacket_req_u {
286607ca46eSDavid Howells 	struct tpacket_req	req;
287607ca46eSDavid Howells 	struct tpacket_req3	req3;
288607ca46eSDavid Howells };
289607ca46eSDavid Howells 
290607ca46eSDavid Howells struct packet_mreq {
291607ca46eSDavid Howells 	int		mr_ifindex;
292607ca46eSDavid Howells 	unsigned short	mr_type;
293607ca46eSDavid Howells 	unsigned short	mr_alen;
294607ca46eSDavid Howells 	unsigned char	mr_address[8];
295607ca46eSDavid Howells };
296607ca46eSDavid Howells 
297607ca46eSDavid Howells #define PACKET_MR_MULTICAST	0
298607ca46eSDavid Howells #define PACKET_MR_PROMISC	1
299607ca46eSDavid Howells #define PACKET_MR_ALLMULTI	2
300607ca46eSDavid Howells #define PACKET_MR_UNICAST	3
301607ca46eSDavid Howells 
302607ca46eSDavid Howells #endif
303