92244fd59df47ec31343c5e8d96b818a7d2dc3bf
[gpxe.git] / src / include / gpxe / pkbuff.h
1 #ifndef _GPXE_PKBUFF_H
2 #define _GPXE_PKBUFF_H
3
4 /** @file
5  *
6  * Packet buffers
7  *
8  * Packet buffers are used to contain network packets.  Methods are
9  * provided for appending, prepending, etc. data.
10  *
11  */
12
13 #include <stdint.h>
14 #include <assert.h>
15 #include <gpxe/list.h>
16
17 struct net_protocol;
18 struct ll_protocol;
19
20 /**
21  * Packet buffer alignment
22  *
23  * Packet buffers allocated via alloc_pkb() are guaranteed to be
24  * physically aligned to this boundary.  Some cards cannot DMA across
25  * a 4kB boundary.  With a standard Ethernet MTU, aligning to a 2kB
26  * boundary is sufficient to guarantee no 4kB boundary crossings.  For
27  * a jumbo Ethernet MTU, a packet may be larger than 4kB anyway.
28  */
29 #define PKBUFF_ALIGN 2048
30
31 /** A packet buffer
32  *
33  * This structure is used to represent a network packet within gPXE.
34  */
35 struct pk_buff {
36         /** Start of the buffer */
37         void *head;
38         /** Start of data */
39         void *data;
40         /** End of data */
41         void *tail;
42         /** End of the buffer */
43         void *end;
44
45         /** List of which this buffer is a member */
46         struct list_head list;
47
48         /** The network-layer protocol */
49         struct net_protocol *net_protocol;
50         /** The link-layer protocol */
51         struct ll_protocol *ll_protocol;
52 };
53
54 /**
55  * Reserve space at start of packet buffer
56  *
57  * @v pkb       Packet buffer
58  * @v len       Length to reserve
59  * @ret data    Pointer to new start of buffer
60  */
61 static inline void * pkb_reserve ( struct pk_buff *pkb, size_t len ) {
62         pkb->data += len;
63         pkb->tail += len;
64         assert ( pkb->tail <= pkb->end );
65         return pkb->data;
66 }
67
68 /**
69  * Add data to start of packet buffer
70  *
71  * @v pkb       Packet buffer
72  * @v len       Length to add
73  * @ret data    Pointer to new start of buffer
74  */
75 static inline void * pkb_push ( struct pk_buff *pkb, size_t len ) {
76         pkb->data -= len;
77         assert ( pkb->data >= pkb->head );
78         return pkb->data;
79 }
80
81 /**
82  * Remove data from start of packet buffer
83  *
84  * @v pkb       Packet buffer
85  * @v len       Length to remove
86  * @ret data    Pointer to new start of buffer
87  */
88 static inline void * pkb_pull ( struct pk_buff *pkb, size_t len ) {
89         pkb->data += len;
90         assert ( pkb->data <= pkb->tail );
91         return pkb->data;
92 }
93
94 /**
95  * Add data to end of packet buffer
96  *
97  * @v pkb       Packet buffer
98  * @v len       Length to add
99  * @ret data    Pointer to newly added space
100  */
101 static inline void * pkb_put ( struct pk_buff *pkb, size_t len ) {
102         void *old_tail = pkb->tail;
103         pkb->tail += len;
104         assert ( pkb->tail <= pkb->end );
105         return old_tail;
106 }
107
108 /**
109  * Remove data from end of packet buffer
110  *
111  * @v pkb       Packet buffer
112  * @v len       Length to remove
113  */
114 static inline void pkb_unput ( struct pk_buff *pkb, size_t len ) {
115         pkb->tail -= len;
116         assert ( pkb->tail >= pkb->data );
117 }
118
119 /**
120  * Empty a packet buffer
121  *
122  * @v pkb       Packet buffer
123  */
124 static inline void pkb_empty ( struct pk_buff *pkb ) {
125         pkb->tail = pkb->data;
126 }
127
128 /**
129  * Calculate length of data in a packet buffer
130  *
131  * @v pkb       Packet buffer
132  * @ret len     Length of data in buffer
133  */
134 static inline size_t pkb_len ( struct pk_buff *pkb ) {
135         return ( pkb->tail - pkb->data );
136 }
137
138 extern struct pk_buff * alloc_pkb ( size_t len );
139 extern void free_pkb ( struct pk_buff *pkb );
140
141 #endif /* _GPXE_PKBUFF_H */