Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TSN mcrc calculation wrong #1020

Open
HannHank opened this issue Feb 18, 2025 · 1 comment
Open

TSN mcrc calculation wrong #1020

HannHank opened this issue Feb 18, 2025 · 1 comment
Assignees
Labels
Milestone

Comments

@HannHank
Copy link

I am enhancing and developing simulations with Frame Preemption and noticed that Wireshark flags mismatched checksums for SMD-C values that are not the final fragment of the packet.

You can reproduce this by adding a third application to the Frame Preemption showcase in the omnetpp.ini file and setting the initialProductionOffset to delay the frames in a way that causes a packet to be split into more than two fragments.

example:

# host1
*.host1.numApps = 3
*.host1.app[*].typename = "UdpSourceApp"
*.host1.app[0].source.packetNameFormat = "background-%c"
*.host1.app[1].source.packetNameFormat = "ts-%c"
*.host1.app[*].tagger.typename = "PacketTagger"
*.host1.app[0].tagger.vlanId = 1
*.host1.app[1].tagger.vlanId = 0
*.host1.app[2].tagger.vlanId = 0
*.host1.app[*].io.destAddress = "host2"
*.host1.app[0].io.destPort = 1000
*.host1.app[1].io.destPort = 1001
*.host1.app[2].io.destPort = 1001


*.host1.app[0].source.packetLength = 1200B
*.host1.app[0].source.productionInterval = 1ms

*.host1.app[2].source.packetLength = 1200B
*.host1.app[2].source.productionInterval = 1ms 
*.host1.app[2].source.initialProductionOffset = 180us


*.host1.app[1].source.packetLength = 1200B
*.host1.app[1].source.productionInterval = 1ms 
*.host1.app[1].source.initialProductionOffset = 50us

Analyzing the pcap file of the host2, will show wrong mcrc of the first continuation fragment.

Looking at the implementation of EthernetFragmentFcsInserter, it correctly calculates the mcrc for the current fragment. However, the mcrc added to intermediate fragments only reflects the checksum of that individual fragment. This means that mcrc is computed solely for the current fragment and does not incorporate previously transmitted data, as specified by IEEE 802.1br 99.3.6.

This may have been necessary in older INET versions, where the packet included the entire payload, including fragments already transmitted. However, in INET 4.5.4, I would recommend returning currentFragmentFcs instead.

uint32_t EthernetFragmentFcsInserter::computeComputedFcs(const Packet *packet) const
{
    auto data = packet->peekDataAsBytes();
    auto bytes = data->getBytes();
    auto fragmentTag = packet->getTag<FragmentTag>();
    currentFragmentCompleteFcs = ethernetCRC(bytes.data(), packet->getByteLength(), fragmentTag->getFirstFragment() ? 0 : lastFragmentCompleteFcs);
    if (fragmentTag->getLastFragment())
        return currentFragmentCompleteFcs;
    else
        return currentFragmentCompleteFcs ^ 0xFFFF0000;
}

which would also require to change the EthernetFragmentFcsChecker

bool EthernetFragmentFcsChecker::checkComputedFcs(const Packet *packet, uint32_t receivedFcs) const
{
    auto data = packet->peekDataAsBytes();
    auto bytes = data->getBytes();
    auto& fragmentTag = packet->getTag<FragmentTag>();
    currentFragmentCompleteFcs = ethernetCRC(bytes.data(), packet->getByteLength() - 4, fragmentTag->getFirstFragment() ? 0 : lastFragmentCompleteFcs);

	/** In effect, the function is accepting the frame if either:
        → The received FCS matches the computed FCS (last fragment)
        →It matches the computed FCS after being XORed (non‐last fragment).
    */
	return (receivedFcs == currentFragmentCompleteFcs) ||
       (receivedFcs == (currentFragmentCompleteFcs ^ 0xFFFF0000));
}

With these changes, the mcrc appears correct in Wireshark, and the packets are no longer dropped. However, I have not yet tested this with corrupted checksums.

If I am mistaken and the current implementation is correct, I do be happy to be corrected.

@levy levy self-assigned this Feb 18, 2025
@levy levy added the Bug label Feb 18, 2025
@levy levy added this to the INET 4.6.0 milestone Feb 18, 2025
@levy
Copy link
Contributor

levy commented Feb 18, 2025

Thanks for the detailed description! We will make sure that this fix goes into the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants