Skip to content

Conversation

@Dimi1010
Copy link
Collaborator

@Dimi1010 Dimi1010 commented Oct 24, 2025

Summary

This PR intended to improve the encapsulation and clarity of Layer field data. As per the C++ core guidelines protected data fields are generally undesired as they represent difficulty in maintaining base class invariants across derived classes.

The main object of this PR is the introduction of a new helper struct LayerAllocationInfo in the internal namespace, to hold allocation information for Layer objects and provide behavior helper methods. The helper structure replaces is contained as a field in a Layer to represent its current allocation state.

LayerAllocationInfo and chosen fields.

The information structure contains 2 members:

  • Packet* attachedPacket, replacing m_Packet pointer inside Layer.
  • bool managedByPacket, replacing m_isAllocatedInPacket flag inside Layer.

The replacements were chosen due to their relevancy to the allocation behaviour of Layer and little else. Those fields were previously intermixed with other fields in the Layer object causing confusion when determining their use and scope.

  • attachedPacket (previously m_Packet) is exclusively used for indication if the layer's data is owned by a packet and to forward requests for structural data changes to the underlying packet buffer, if available. The new name was chosen to better represent that use.
  • managedByPacket (previously m_IsAllocatedInPacket) is exclusively used as flag to determine if the Layer object's lifecycle is managed by the Packet instance it is attached to. The field intricately tied to the state of attachedPacket and as such is included to the helper structure.

The new fields include extensive documentation regarding their use, improving the maintainability of the code. ( Think about the you in 5 months reading it 🙂 )

Behaviour methods instead of direct field mutation

The new helper structure adds two behavior methods:

  • attachPacket(Packet* packet, bool managed, bool force = false): This method encapsulates the behavior of attaching a layer to a Packet instance. It allows a Packet instance attaching a Layer to itself to update the information in one step instead of manually having to directly update private fields to the Layer instance. The method also provides integrated sanity checks if a Layer is being attached to a Packet instance twice.
  • detach(): Encapsulates the behaviour of detaching a Layer from Packet. It allows a Packet instance detaching a Layer to inform it of its new state in one step.

Protected data accessors and private fields

The new LayerAllocationInfo structure is held as a private field inside Layer. The change improves data integrity as the allocation information (packet or managed flag) is unavailable for accidental modification by derived classes.

To keep existing behaviour of a Layer instance forwarding its attachment to any other instance it constructs during parsing, a new protected accessor getAttachedPacket() has been added and instances of direct use of m_Packet are replaced by it.

Bug Fixes

  • Fixed bug due to lack of zeroing of m_IsAllocatedInPacket flag when detaching a layer. If said layer is attached to a new packet instance, the old implementation disregarded the ownership flag and considered the layer instance as owned by the packet, due to the layer flag being set from the previous packet.

Comment on lines +29 to 31
// Should this really always delete m_Data? What if the layer is attached to a packet?
if (m_Data != nullptr)
delete[] m_Data;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment? This would cause an error if called on a Layer that does not own its data span.

else
{
layer->m_Packet = nullptr;
layer->m_AllocationInfo.detach();
Copy link
Collaborator Author

@Dimi1010 Dimi1010 Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line in particular created a subtle bug in the old implementation.

If a layer is originally owned by the packet instance, and detached, the m_IsAllocatedInPacket flag was not zeroed. If the layer has then been attached to another Packet. The attached layer was considered as if managed by the new packet even if attached with addLayer(layer, false) which should not transfer ownership of the layer object.

@Dimi1010 Dimi1010 added the bug label Oct 24, 2025
///
/// If 'false', the Layer object is considered unmanaged and the user is responsible for freeing it.
/// This is commonly the case for layers created on the stack and attached to a Packet.
bool managedByPacket = false;
Copy link
Collaborator Author

@Dimi1010 Dimi1010 Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe ownedByPacket is a more descriptive name? 🤔

Comment on lines +330 to +332
PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanEthLayer, true));
PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanIP4Layer, true));
PTF_ASSERT_TRUE(packetWithoutTunnel.addLayer(vxlanIcmpLayer, true));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or should we keep the test as is, but correctly delete the layers afterwards?

@codecov
Copy link

codecov bot commented Oct 24, 2025

Codecov Report

❌ Patch coverage is 63.48684% with 111 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.45%. Comparing base (0132d27) to head (3d64f18).

Files with missing lines Patch % Lines
Packet++/src/Sll2Layer.cpp 6.25% 13 Missing and 2 partials ⚠️
Packet++/src/IPv6Layer.cpp 40.90% 13 Missing ⚠️
Packet++/src/SllLayer.cpp 18.75% 12 Missing and 1 partial ⚠️
Packet++/src/GreLayer.cpp 29.41% 10 Missing and 2 partials ⚠️
Packet++/src/IPSecLayer.cpp 27.27% 7 Missing and 1 partial ⚠️
Packet++/src/NullLoopbackLayer.cpp 42.85% 7 Missing and 1 partial ⚠️
Packet++/src/VlanLayer.cpp 52.94% 7 Missing and 1 partial ⚠️
Packet++/src/IPv4Layer.cpp 72.00% 7 Missing ⚠️
Packet++/src/TcpLayer.cpp 76.00% 6 Missing ⚠️
Packet++/src/NflogLayer.cpp 20.00% 3 Missing and 1 partial ⚠️
... and 10 more
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #2004      +/-   ##
==========================================
+ Coverage   83.41%   83.45%   +0.03%     
==========================================
  Files         311      311              
  Lines       55019    54576     -443     
  Branches    11816    11806      -10     
==========================================
- Hits        45892    45544     -348     
- Misses       7852     8199     +347     
+ Partials     1275      833     -442     
Flag Coverage Δ
alpine320 75.89% <57.99%> (+<0.01%) ⬆️
fedora42 75.44% <58.36%> (-0.39%) ⬇️
macos-14 81.57% <60.13%> (+0.06%) ⬆️
macos-15 81.55% <60.13%> (+0.04%) ⬆️
mingw32 69.95% <47.52%> (-0.58%) ⬇️
mingw64 69.91% <47.52%> (-0.49%) ⬇️
npcap ?
rhel94 75.45% <58.20%> (-0.42%) ⬇️
ubuntu2004 59.48% <57.50%> (-0.65%) ⬇️
ubuntu2004-zstd 59.56% <57.50%> (-0.67%) ⬇️
ubuntu2204 75.41% <58.20%> (-0.39%) ⬇️
ubuntu2204-icpx 57.82% <34.47%> (-2.73%) ⬇️
ubuntu2404 75.51% <57.83%> (-0.38%) ⬇️
ubuntu2404-arm64 75.56% <57.83%> (-0.01%) ⬇️
unittest 83.45% <63.48%> (+0.03%) ⬆️
windows-2022 85.42% <74.11%> (+0.17%) ⬆️
windows-2025 85.45% <74.11%> (+0.11%) ⬆️
winpcap 85.45% <74.11%> (-0.09%) ⬇️
xdp 53.02% <55.97%> (-0.52%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Dimi1010 Dimi1010 marked this pull request as ready for review October 24, 2025 22:53
@Dimi1010 Dimi1010 requested a review from seladb as a code owner October 24, 2025 22:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant