Skip to content

Commit 75b55e0

Browse files
Florian Grandelcarlescufi
authored andcommitted
net: pkt: optimize net_pkt packing
This change removes unnecessary padding from the net_pkt struct in preparation for restructuring it in a later commit. Depending on the number of activated Kconfig options, this saves between 4 and 8 bytes per packet. The change also removes anonymous unions inside of bitfields: * The assumption, that anonymous unions inside bitfields save space is wrong. They rather enforce an additional byte aligment boundary with padding before or after on most compilers (try -Wpadded to prove it). Removing the unions therefore counter-intuitively removes padding. * Some of the fields inside the union may actually not be orthogonal if several extensions are enabled at the same time. They may overwrite each other when activated at the same time. The change therefore not only improves packing of net_pkt but also makes net_pkt easier to understand and maintain by removing potentially non-orthogonal uses of bits within bitfields. The union of RX/TX-only attributes has been maintained, though, as it DOES save space and is easy to maintain. Maintainability has further been improved by introducing additional inline comments and anonymous structs that make the orthogonality of RX- and TX-attributes even more obvious. Signed-off-by: Florian Grandel <[email protected]>
1 parent 0b94947 commit 75b55e0

File tree

1 file changed

+75
-79
lines changed

1 file changed

+75
-79
lines changed

include/zephyr/net/net_pkt.h

Lines changed: 75 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ struct net_pkt {
8383

8484
/** @cond ignore */
8585

86+
#if defined(CONFIG_NET_TCP)
87+
/** Allow placing the packet into sys_slist_t */
88+
sys_snode_t next;
89+
#endif
8690
#if defined(CONFIG_NET_ROUTING) || defined(CONFIG_NET_ETHERNET_BRIDGE)
8791
struct net_if *orig_iface; /* Original network interface */
8892
#endif
@@ -126,77 +130,66 @@ struct net_pkt {
126130
struct net_linkaddr lladdr_dst;
127131
uint16_t ll_proto_type;
128132

129-
#if defined(CONFIG_NET_TCP)
130-
/** Allow placing the packet into sys_slist_t */
131-
sys_snode_t next;
132-
#endif
133-
134133
#if defined(CONFIG_NET_IP)
135134
uint8_t ip_hdr_len; /* pre-filled in order to avoid func call */
136135
#endif
137136

138-
uint8_t overwrite : 1; /* Is packet content being overwritten? */
139-
140-
uint8_t sent_or_eof: 1; /* For outgoing packet: is this sent or not
141-
* For incoming packet of a socket: last
142-
* packet before EOF
143-
* Used only if defined(CONFIG_NET_TCP)
144-
*/
145-
union {
146-
uint8_t pkt_queued: 1; /* For outgoing packet: is this packet
147-
* queued to be sent but has not reached
148-
* the driver yet.
149-
* Used only if defined(CONFIG_NET_TCP)
150-
*/
151-
uint8_t ptp_pkt: 1; /* For outgoing packet: is this packet
152-
* a L2 PTP packet.
153-
* Used only if defined (CONFIG_NET_L2_PTP)
154-
*/
155-
};
156-
157-
uint8_t forwarding : 1; /* Are we forwarding this pkt
158-
* Used only if defined(CONFIG_NET_ROUTE)
159-
*/
160-
uint8_t family : 3; /* Address family, see net_ip.h */
137+
uint8_t overwrite : 1; /* Is packet content being overwritten? */
138+
uint8_t sent_or_eof : 1; /* For outgoing packet: is this sent or not
139+
* For incoming packet of a socket: last
140+
* packet before EOF
141+
* Used only if defined(CONFIG_NET_TCP)
142+
*/
143+
uint8_t pkt_queued : 1; /* For outgoing packet: is this packet
144+
* queued to be sent but has not reached
145+
* the driver yet.
146+
* Used only if defined(CONFIG_NET_TCP)
147+
*/
148+
uint8_t ptp_pkt : 1; /* For outgoing packet: is this packet
149+
* a L2 PTP packet.
150+
* Used only if defined (CONFIG_NET_L2_PTP)
151+
*/
152+
uint8_t forwarding : 1; /* Are we forwarding this pkt
153+
* Used only if defined(CONFIG_NET_ROUTE)
154+
*/
155+
uint8_t family : 3; /* Address family, see net_ip.h */
156+
157+
/* bitfield byte alignment boundary */
161158

162-
union {
163159
#if defined(CONFIG_NET_IPV4_AUTO)
164-
uint8_t ipv4_auto_arp_msg : 1; /* Is this pkt IPv4 autoconf ARP
165-
* message.
166-
* Note: family needs to be
167-
* AF_INET.
168-
*/
160+
uint8_t ipv4_auto_arp_msg : 1; /* Is this pkt IPv4 autoconf ARP
161+
* message.
162+
* Note: family needs to be
163+
* AF_INET.
164+
*/
169165
#endif
170166
#if defined(CONFIG_NET_LLDP)
171-
uint8_t lldp_pkt : 1; /* Is this pkt an LLDP message.
172-
* Note: family needs to be
173-
* AF_UNSPEC.
174-
*/
167+
uint8_t lldp_pkt : 1; /* Is this pkt an LLDP message.
168+
* Note: family needs to be
169+
* AF_UNSPEC.
170+
*/
175171
#endif
176-
uint8_t ppp_msg : 1; /* This is a PPP message */
177-
};
178-
172+
uint8_t ppp_msg : 1; /* This is a PPP message */
179173
#if defined(CONFIG_NET_TCP)
180-
uint8_t tcp_first_msg : 1; /* Is this the first time this pkt is
181-
* sent, or is this a resend of a TCP
182-
* segment.
183-
*/
174+
uint8_t tcp_first_msg : 1; /* Is this the first time this pkt is
175+
* sent, or is this a resend of a TCP
176+
* segment.
177+
*/
184178
#endif
185-
186-
uint8_t captured : 1; /* Set to 1 if this packet is already being
187-
* captured
188-
*/
189-
190-
uint8_t l2_bridged : 1; /* set to 1 if this packet comes from a bridge
191-
* and already contains its L2 header to be
192-
* preserved. Useful only if
193-
* defined(CONFIG_NET_ETHERNET_BRIDGE).
194-
*/
195-
179+
uint8_t captured : 1; /* Set to 1 if this packet is already being
180+
* captured
181+
*/
182+
uint8_t l2_bridged : 1; /* set to 1 if this packet comes from a bridge
183+
* and already contains its L2 header to be
184+
* preserved. Useful only if
185+
* defined(CONFIG_NET_ETHERNET_BRIDGE).
186+
*/
196187
uint8_t l2_processed : 1; /* Set to 1 if this packet has already been
197188
* processed by the L2
198189
*/
199190

191+
/* bitfield byte alignment boundary */
192+
200193
#if defined(CONFIG_NET_IP)
201194
union {
202195
/* IPv6 hop limit or IPv4 ttl for this network packet.
@@ -212,28 +205,12 @@ struct net_pkt {
212205

213206
union {
214207
#if defined(CONFIG_NET_IPV4)
215-
uint8_t ipv4_opts_len; /* Length if IPv4 Header Options */
208+
uint8_t ipv4_opts_len; /* length of IPv4 header options */
216209
#endif
217210
#if defined(CONFIG_NET_IPV6)
218211
uint16_t ipv6_ext_len; /* length of extension headers */
219212
#endif
220213
};
221-
#endif /* CONFIG_NET_IP */
222-
223-
/** Network packet priority, can be left out in which case packet
224-
* is not prioritised.
225-
*/
226-
uint8_t priority;
227-
228-
#if defined(CONFIG_NET_VLAN)
229-
/* VLAN TCI (Tag Control Information). This contains the Priority
230-
* Code Point (PCP), Drop Eligible Indicator (DEI) and VLAN
231-
* Identifier (VID, called more commonly VLAN tag). This value is
232-
* kept in host byte order.
233-
*/
234-
uint16_t vlan_tci;
235-
#endif /* CONFIG_NET_VLAN */
236-
237214
#if defined(CONFIG_NET_IPV6)
238215
/* Where is the start of the last header before payload data
239216
* in IPv6 packet. This is offset value from start of the IPv6
@@ -251,20 +228,33 @@ struct net_pkt {
251228
uint8_t ipv6_ext_opt_len; /* IPv6 ND option length */
252229
uint8_t ipv6_next_hdr; /* What is the very first next header */
253230
#endif /* CONFIG_NET_IPV6 */
231+
#endif /* CONFIG_NET_IP */
232+
233+
#if defined(CONFIG_NET_VLAN)
234+
/* VLAN TCI (Tag Control Information). This contains the Priority
235+
* Code Point (PCP), Drop Eligible Indicator (DEI) and VLAN
236+
* Identifier (VID, called more commonly VLAN tag). This value is
237+
* kept in host byte order.
238+
*/
239+
uint16_t vlan_tci;
240+
#endif /* CONFIG_NET_VLAN */
254241

255242
#if defined(CONFIG_IEEE802154)
256243
#if defined(CONFIG_IEEE802154_2015)
257244
uint32_t ieee802154_ack_fc; /* Frame counter set in the ACK */
258245
uint8_t ieee802154_ack_keyid; /* Key index set in the ACK */
259246
#endif
260-
uint8_t ieee802154_lqi; /* Link Quality Indicator */
261247
union {
262-
uint8_t ieee802154_rssi; /* Received Signal Strength Indication */
248+
/* RX packets */
249+
struct {
250+
uint8_t lqi; /* Link Quality Indicator */
251+
uint8_t rssi; /* Received Signal Strength Indication */
252+
};
263253
#if defined(CONFIG_IEEE802154_SELECTIVE_TXPOWER)
264-
int8_t ieee802154_txpwr; /* TX power in dBm. It should be clear from
265-
* the context which field of the union
266-
* is valid at the moment.
267-
*/
254+
/* TX packets */
255+
struct {
256+
int8_t txpwr; /* TX power in dBm. */
257+
};
268258
#endif /* CONFIG_IEEE802154_SELECTIVE_TXPOWER */
269259
};
270260
#if defined(CONFIG_IEEE802154_2015)
@@ -283,6 +273,12 @@ struct net_pkt {
283273
* e.g. Frame Counter injection.
284274
*/
285275
#endif
276+
277+
/** Network packet priority, can be left out in which case packet
278+
* is not prioritised.
279+
*/
280+
uint8_t priority;
281+
286282
/* @endcond */
287283
};
288284

0 commit comments

Comments
 (0)