xref: /linux/include/uapi/linux/if_packet.h (revision 68a360e82e55c9b35097e7be7f7991d8f401032f)
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
57607ca46eSDavid Howells 
58607ca46eSDavid Howells #define PACKET_FANOUT_HASH		0
59607ca46eSDavid Howells #define PACKET_FANOUT_LB		1
60607ca46eSDavid Howells #define PACKET_FANOUT_CPU		2
6177f65ebdSWillem de Bruijn #define PACKET_FANOUT_ROLLOVER		3
625df0ddfbSDaniel Borkmann #define PACKET_FANOUT_RND		4
632d36097dSNeil Horman #define PACKET_FANOUT_QM		5
6477f65ebdSWillem de Bruijn #define PACKET_FANOUT_FLAG_ROLLOVER	0x1000
65607ca46eSDavid Howells #define PACKET_FANOUT_FLAG_DEFRAG	0x8000
66607ca46eSDavid Howells 
67607ca46eSDavid Howells struct tpacket_stats {
68607ca46eSDavid Howells 	unsigned int	tp_packets;
69607ca46eSDavid Howells 	unsigned int	tp_drops;
70607ca46eSDavid Howells };
71607ca46eSDavid Howells 
72607ca46eSDavid Howells struct tpacket_stats_v3 {
73607ca46eSDavid Howells 	unsigned int	tp_packets;
74607ca46eSDavid Howells 	unsigned int	tp_drops;
75607ca46eSDavid Howells 	unsigned int	tp_freeze_q_cnt;
76607ca46eSDavid Howells };
77607ca46eSDavid Howells 
78607ca46eSDavid Howells union tpacket_stats_u {
79607ca46eSDavid Howells 	struct tpacket_stats stats1;
80607ca46eSDavid Howells 	struct tpacket_stats_v3 stats3;
81607ca46eSDavid Howells };
82607ca46eSDavid Howells 
83607ca46eSDavid Howells struct tpacket_auxdata {
84607ca46eSDavid Howells 	__u32		tp_status;
85607ca46eSDavid Howells 	__u32		tp_len;
86607ca46eSDavid Howells 	__u32		tp_snaplen;
87607ca46eSDavid Howells 	__u16		tp_mac;
88607ca46eSDavid Howells 	__u16		tp_net;
89607ca46eSDavid Howells 	__u16		tp_vlan_tci;
90a0cdfcf3SAtzm Watanabe 	__u16		tp_vlan_tpid;
91607ca46eSDavid Howells };
92607ca46eSDavid Howells 
93607ca46eSDavid Howells /* Rx ring - header status */
947276d5d7SDaniel Borkmann #define TP_STATUS_KERNEL		      0
957276d5d7SDaniel Borkmann #define TP_STATUS_USER			(1 << 0)
967276d5d7SDaniel Borkmann #define TP_STATUS_COPY			(1 << 1)
977276d5d7SDaniel Borkmann #define TP_STATUS_LOSING		(1 << 2)
987276d5d7SDaniel Borkmann #define TP_STATUS_CSUMNOTREADY		(1 << 3)
997276d5d7SDaniel Borkmann #define TP_STATUS_VLAN_VALID		(1 << 4) /* auxdata has valid tp_vlan_tci */
1007276d5d7SDaniel Borkmann #define TP_STATUS_BLK_TMO		(1 << 5)
101a0cdfcf3SAtzm Watanabe #define TP_STATUS_VLAN_TPID_VALID	(1 << 6) /* auxdata has valid tp_vlan_tpid */
102607ca46eSDavid Howells 
103607ca46eSDavid Howells /* Tx ring - header status */
1047276d5d7SDaniel Borkmann #define TP_STATUS_AVAILABLE	      0
1057276d5d7SDaniel Borkmann #define TP_STATUS_SEND_REQUEST	(1 << 0)
1067276d5d7SDaniel Borkmann #define TP_STATUS_SENDING	(1 << 1)
1077276d5d7SDaniel Borkmann #define TP_STATUS_WRONG_FORMAT	(1 << 2)
108607ca46eSDavid Howells 
109b9c32fb2SDaniel Borkmann /* Rx and Tx ring - header status */
110b9c32fb2SDaniel Borkmann #define TP_STATUS_TS_SOFTWARE		(1 << 29)
111*68a360e8SWillem de Bruijn #define TP_STATUS_TS_SYS_HARDWARE	(1 << 30) /* deprecated, never set */
112b9c32fb2SDaniel Borkmann #define TP_STATUS_TS_RAW_HARDWARE	(1 << 31)
113b9c32fb2SDaniel Borkmann 
114607ca46eSDavid Howells /* Rx ring - feature request bits */
115607ca46eSDavid Howells #define TP_FT_REQ_FILL_RXHASH	0x1
116607ca46eSDavid Howells 
117607ca46eSDavid Howells struct tpacket_hdr {
118607ca46eSDavid Howells 	unsigned long	tp_status;
119607ca46eSDavid Howells 	unsigned int	tp_len;
120607ca46eSDavid Howells 	unsigned int	tp_snaplen;
121607ca46eSDavid Howells 	unsigned short	tp_mac;
122607ca46eSDavid Howells 	unsigned short	tp_net;
123607ca46eSDavid Howells 	unsigned int	tp_sec;
124607ca46eSDavid Howells 	unsigned int	tp_usec;
125607ca46eSDavid Howells };
126607ca46eSDavid Howells 
127607ca46eSDavid Howells #define TPACKET_ALIGNMENT	16
128607ca46eSDavid Howells #define TPACKET_ALIGN(x)	(((x)+TPACKET_ALIGNMENT-1)&~(TPACKET_ALIGNMENT-1))
129607ca46eSDavid Howells #define TPACKET_HDRLEN		(TPACKET_ALIGN(sizeof(struct tpacket_hdr)) + sizeof(struct sockaddr_ll))
130607ca46eSDavid Howells 
131607ca46eSDavid Howells struct tpacket2_hdr {
132607ca46eSDavid Howells 	__u32		tp_status;
133607ca46eSDavid Howells 	__u32		tp_len;
134607ca46eSDavid Howells 	__u32		tp_snaplen;
135607ca46eSDavid Howells 	__u16		tp_mac;
136607ca46eSDavid Howells 	__u16		tp_net;
137607ca46eSDavid Howells 	__u32		tp_sec;
138607ca46eSDavid Howells 	__u32		tp_nsec;
139607ca46eSDavid Howells 	__u16		tp_vlan_tci;
140a0cdfcf3SAtzm Watanabe 	__u16		tp_vlan_tpid;
141a0cdfcf3SAtzm Watanabe 	__u8		tp_padding[4];
142607ca46eSDavid Howells };
143607ca46eSDavid Howells 
144607ca46eSDavid Howells struct tpacket_hdr_variant1 {
145607ca46eSDavid Howells 	__u32	tp_rxhash;
146607ca46eSDavid Howells 	__u32	tp_vlan_tci;
147a0cdfcf3SAtzm Watanabe 	__u16	tp_vlan_tpid;
148a0cdfcf3SAtzm Watanabe 	__u16	tp_padding;
149607ca46eSDavid Howells };
150607ca46eSDavid Howells 
151607ca46eSDavid Howells struct tpacket3_hdr {
152607ca46eSDavid Howells 	__u32		tp_next_offset;
153607ca46eSDavid Howells 	__u32		tp_sec;
154607ca46eSDavid Howells 	__u32		tp_nsec;
155607ca46eSDavid Howells 	__u32		tp_snaplen;
156607ca46eSDavid Howells 	__u32		tp_len;
157607ca46eSDavid Howells 	__u32		tp_status;
158607ca46eSDavid Howells 	__u16		tp_mac;
159607ca46eSDavid Howells 	__u16		tp_net;
160607ca46eSDavid Howells 	/* pkt_hdr variants */
161607ca46eSDavid Howells 	union {
162607ca46eSDavid Howells 		struct tpacket_hdr_variant1 hv1;
163607ca46eSDavid Howells 	};
164a0cdfcf3SAtzm Watanabe 	__u8		tp_padding[8];
165607ca46eSDavid Howells };
166607ca46eSDavid Howells 
167607ca46eSDavid Howells struct tpacket_bd_ts {
168607ca46eSDavid Howells 	unsigned int ts_sec;
169607ca46eSDavid Howells 	union {
170607ca46eSDavid Howells 		unsigned int ts_usec;
171607ca46eSDavid Howells 		unsigned int ts_nsec;
172607ca46eSDavid Howells 	};
173607ca46eSDavid Howells };
174607ca46eSDavid Howells 
175607ca46eSDavid Howells struct tpacket_hdr_v1 {
176607ca46eSDavid Howells 	__u32	block_status;
177607ca46eSDavid Howells 	__u32	num_pkts;
178607ca46eSDavid Howells 	__u32	offset_to_first_pkt;
179607ca46eSDavid Howells 
180607ca46eSDavid Howells 	/* Number of valid bytes (including padding)
181607ca46eSDavid Howells 	 * blk_len <= tp_block_size
182607ca46eSDavid Howells 	 */
183607ca46eSDavid Howells 	__u32	blk_len;
184607ca46eSDavid Howells 
185607ca46eSDavid Howells 	/*
186607ca46eSDavid Howells 	 * Quite a few uses of sequence number:
187607ca46eSDavid Howells 	 * 1. Make sure cache flush etc worked.
188607ca46eSDavid Howells 	 *    Well, one can argue - why not use the increasing ts below?
189607ca46eSDavid Howells 	 *    But look at 2. below first.
190607ca46eSDavid Howells 	 * 2. When you pass around blocks to other user space decoders,
191607ca46eSDavid Howells 	 *    you can see which blk[s] is[are] outstanding etc.
192607ca46eSDavid Howells 	 * 3. Validate kernel code.
193607ca46eSDavid Howells 	 */
194607ca46eSDavid Howells 	__aligned_u64	seq_num;
195607ca46eSDavid Howells 
196607ca46eSDavid Howells 	/*
197607ca46eSDavid Howells 	 * ts_last_pkt:
198607ca46eSDavid Howells 	 *
199607ca46eSDavid Howells 	 * Case 1.	Block has 'N'(N >=1) packets and TMO'd(timed out)
200607ca46eSDavid Howells 	 *		ts_last_pkt == 'time-stamp of last packet' and NOT the
201607ca46eSDavid Howells 	 *		time when the timer fired and the block was closed.
202607ca46eSDavid Howells 	 *		By providing the ts of the last packet we can absolutely
203607ca46eSDavid Howells 	 *		guarantee that time-stamp wise, the first packet in the
204607ca46eSDavid Howells 	 *		next block will never precede the last packet of the
205607ca46eSDavid Howells 	 *		previous block.
206607ca46eSDavid Howells 	 * Case 2.	Block has zero packets and TMO'd
207607ca46eSDavid Howells 	 *		ts_last_pkt = time when the timer fired and the block
208607ca46eSDavid Howells 	 *		was closed.
209607ca46eSDavid Howells 	 * Case 3.	Block has 'N' packets and NO TMO.
210607ca46eSDavid Howells 	 *		ts_last_pkt = time-stamp of the last pkt in the block.
211607ca46eSDavid Howells 	 *
212607ca46eSDavid Howells 	 * ts_first_pkt:
213607ca46eSDavid Howells 	 *		Is always the time-stamp when the block was opened.
214607ca46eSDavid Howells 	 *		Case a)	ZERO packets
215607ca46eSDavid Howells 	 *			No packets to deal with but atleast you know the
216607ca46eSDavid Howells 	 *			time-interval of this block.
217607ca46eSDavid Howells 	 *		Case b) Non-zero packets
218607ca46eSDavid Howells 	 *			Use the ts of the first packet in the block.
219607ca46eSDavid Howells 	 *
220607ca46eSDavid Howells 	 */
221607ca46eSDavid Howells 	struct tpacket_bd_ts	ts_first_pkt, ts_last_pkt;
222607ca46eSDavid Howells };
223607ca46eSDavid Howells 
224607ca46eSDavid Howells union tpacket_bd_header_u {
225607ca46eSDavid Howells 	struct tpacket_hdr_v1 bh1;
226607ca46eSDavid Howells };
227607ca46eSDavid Howells 
228607ca46eSDavid Howells struct tpacket_block_desc {
229607ca46eSDavid Howells 	__u32 version;
230607ca46eSDavid Howells 	__u32 offset_to_priv;
231607ca46eSDavid Howells 	union tpacket_bd_header_u hdr;
232607ca46eSDavid Howells };
233607ca46eSDavid Howells 
234607ca46eSDavid Howells #define TPACKET2_HDRLEN		(TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) + sizeof(struct sockaddr_ll))
235607ca46eSDavid Howells #define TPACKET3_HDRLEN		(TPACKET_ALIGN(sizeof(struct tpacket3_hdr)) + sizeof(struct sockaddr_ll))
236607ca46eSDavid Howells 
237607ca46eSDavid Howells enum tpacket_versions {
238607ca46eSDavid Howells 	TPACKET_V1,
239607ca46eSDavid Howells 	TPACKET_V2,
240607ca46eSDavid Howells 	TPACKET_V3
241607ca46eSDavid Howells };
242607ca46eSDavid Howells 
243607ca46eSDavid Howells /*
244607ca46eSDavid Howells    Frame structure:
245607ca46eSDavid Howells 
246607ca46eSDavid Howells    - Start. Frame must be aligned to TPACKET_ALIGNMENT=16
247607ca46eSDavid Howells    - struct tpacket_hdr
248607ca46eSDavid Howells    - pad to TPACKET_ALIGNMENT=16
249607ca46eSDavid Howells    - struct sockaddr_ll
250607ca46eSDavid Howells    - Gap, chosen so that packet data (Start+tp_net) alignes to TPACKET_ALIGNMENT=16
251607ca46eSDavid Howells    - Start+tp_mac: [ Optional MAC header ]
252607ca46eSDavid Howells    - Start+tp_net: Packet data, aligned to TPACKET_ALIGNMENT=16.
253607ca46eSDavid Howells    - Pad to align to TPACKET_ALIGNMENT=16
254607ca46eSDavid Howells  */
255607ca46eSDavid Howells 
256607ca46eSDavid Howells struct tpacket_req {
257607ca46eSDavid Howells 	unsigned int	tp_block_size;	/* Minimal size of contiguous block */
258607ca46eSDavid Howells 	unsigned int	tp_block_nr;	/* Number of blocks */
259607ca46eSDavid Howells 	unsigned int	tp_frame_size;	/* Size of frame */
260607ca46eSDavid Howells 	unsigned int	tp_frame_nr;	/* Total number of frames */
261607ca46eSDavid Howells };
262607ca46eSDavid Howells 
263607ca46eSDavid Howells struct tpacket_req3 {
264607ca46eSDavid Howells 	unsigned int	tp_block_size;	/* Minimal size of contiguous block */
265607ca46eSDavid Howells 	unsigned int	tp_block_nr;	/* Number of blocks */
266607ca46eSDavid Howells 	unsigned int	tp_frame_size;	/* Size of frame */
267607ca46eSDavid Howells 	unsigned int	tp_frame_nr;	/* Total number of frames */
268607ca46eSDavid Howells 	unsigned int	tp_retire_blk_tov; /* timeout in msecs */
269607ca46eSDavid Howells 	unsigned int	tp_sizeof_priv; /* offset to private data area */
270607ca46eSDavid Howells 	unsigned int	tp_feature_req_word;
271607ca46eSDavid Howells };
272607ca46eSDavid Howells 
273607ca46eSDavid Howells union tpacket_req_u {
274607ca46eSDavid Howells 	struct tpacket_req	req;
275607ca46eSDavid Howells 	struct tpacket_req3	req3;
276607ca46eSDavid Howells };
277607ca46eSDavid Howells 
278607ca46eSDavid Howells struct packet_mreq {
279607ca46eSDavid Howells 	int		mr_ifindex;
280607ca46eSDavid Howells 	unsigned short	mr_type;
281607ca46eSDavid Howells 	unsigned short	mr_alen;
282607ca46eSDavid Howells 	unsigned char	mr_address[8];
283607ca46eSDavid Howells };
284607ca46eSDavid Howells 
285607ca46eSDavid Howells #define PACKET_MR_MULTICAST	0
286607ca46eSDavid Howells #define PACKET_MR_PROMISC	1
287607ca46eSDavid Howells #define PACKET_MR_ALLMULTI	2
288607ca46eSDavid Howells #define PACKET_MR_UNICAST	3
289607ca46eSDavid Howells 
290607ca46eSDavid Howells #endif
291