inet-framework / inet

INET Framework for the OMNeT++ discrete event simulator
https://inet.omnetpp.org
Other
429 stars 482 forks source link

Unknown Protocol: dropping Packet for UDP Packet over TSN when reaching Wireless host #905

Closed Abh4git closed 11 months ago

Abh4git commented 1 year ago

Platform

Describe the bug I am having a TSN device (ES2)-> connected to a TSN Switch(SW2) which is then connected to access point (AP1) in turn associated to a wireless host (ES4). I am sending from ES2-> UDPSourceApp message sized 500B over 250us intervals named "video" to ES4. (Port 1004). WARN: Unknown Protocol, dropping packet
To Reproduce Help the development team to reproduce the issue. Provide step-by-step instructions, code examples, etc. ---ned file---


package tsnschedwifi;

import inet.linklayer.ieee8021as.GptpMaster;
import inet.networklayer.configurator.ipv4.Ipv4NetworkConfigurator;
import inet.node.inet.WirelessHost;
import inet.node.tsn.TsnDevice;
import inet.node.tsn.TsnSwitch;
import inet.linklayer.configurator.gatescheduling.contract.IGateScheduleConfigurator;
//import inet.node.wireless.AccessPoint;
import inet.node.ethernet.Eth100M;
import inet.node.contract.IEthernetNetworkNode;
import inet.networks.base.TsnNetworkBase;
import inet.node.wireless.AccessPoint;
import inet.physicallayer.wireless.ieee80211.packetlevel.Ieee80211ScalarRadioMedium;
import inet.visualizer.common.PacketDropVisualizer;
import tdma.scheduler.TdmaScheduler;

@license(LGPL);
//
// TODO documentation
//
network Network3 extends TsnNetworkBase
{
    parameters:
        *.eth[*].bitrate = default(100Mbps);
        @display("bgb=879.65625,529.9263");
    submodules:
        ES1: <default("TsnDevice")> like IEthernetNetworkNode {
            @display("p=176,128");
        }
        ES2: <default("TsnDevice")> like IEthernetNetworkNode {
            @display("p=176,293");
        }
        ES3: <default("TsnDevice")> like IEthernetNetworkNode {
            @display("p=590.7025,186.59375");
        }
        SW1: <default("TsnSwitch")> like IEthernetNetworkNode {
            @display("p=394,146");
        }
        SW2: <default("TsnSwitch")> like IEthernetNetworkNode {
            @display("p=394,282");
        }
        ES4: WirelessHost {
            @display("p=768.20996,399.5575");
        }
        radioMedium: Ieee80211ScalarRadioMedium {
            @display("p=219.6475,469.15002");
        }
        accessPoint: AccessPoint {
            @display("p=716.52,297.48376");
        }
        scheduler: TdmaScheduler {
            parameters:
                @display("p=493.37625,71.74375;is=s");
        }
        packetDropVisualizer: PacketDropVisualizer {
            @display("p=507.72498,429.35873");
        }
    connections:
        ES1.ethg++ <--> Eth100M <--> SW1.ethg++;
        SW1.ethg++ <--> Eth100M <--> ES3.ethg++;
        ES2.ethg++ <--> Eth100M <--> SW2.ethg++;
        SW2.ethg++ <--> Eth100M <--> ES3.ethg++;
        SW1.ethg++ <--> Eth100M <--> SW2.ethg++;
        SW2.ethg++ <--> Eth100M <--> accessPoint.ethg++;

}

-----ini file---

[tsnwifi]
network = Network3
description = "tsn gate scheduling"
sim-time-limit = 0.2s
#record-eventlog = true

#Computed for 

**.crcMode = "computed"
**.fcsMode = "computed"

# Routing settings
*.*.ipv4.arp.typename = "GlobalArp"
*.*.ipv4.routingTable.netmaskRoutes = ""

*.accessPoint.wlan[0].mgmt.typename = "Ieee80211MgmtAp"
*.ES4.wlan[0].mgmt.typename = "Ieee80211MgmtStaSimplified"

*.ES4.numWlanInterfaces = 1
*.accessPoint.numWlanInterfaces = 1
*.accessPoint.wlan[0].radio.bandName = "5 GHz"
*.accessPoint.wlan[0].radio.channelNumber = 0

*.accessPoint.wlan[0].address = "10:00:00:00:00:00"
*.accessPoint.mgmt.accessPointAddress = "10:00:00:00:00:00"
*.ES4.accessPointAddress = "10:00:00:00:00:00"

*.accessPoint.bridging.typename = "MacRelayUnit"
#**.arp.typename = "GlobalArp"

**.wlan[*].mac.dcf.channelAccess.cwMin = 7

**.wlan[*].radio.transmitter.power = 100mW
**.wlan[*].radio.transmitter.headerLength = 96b
**.wlan[*].radio.transmitter.centerFrequency = 2.4GHz
**.wlan[*].radio.receiver.sensitivity = -85dBm
**.wlan[*].radio.receiver.snirThreshold = 4dB

*.*.wlan[*].bitrate = 54Mbps
#*.accessPoint.wlan[0].mgmt.ssid = "area1"
*.accessPoint[*].eth[*].typename = "LayeredEthernetInterface"

*.ES4.wlan[0].radio.channelNumber = 0
#*.ES4.wlan[0].agent.defaultSsid = "area1"
*.*.wlan[0].agent.typename = ""
*.ES4.wlan[0].mgmt.accessPointAddress = "10:00:00:00:00:00"
*.ES4.wlan[0].radio.bandName= "5 GHz"
#**.wlan[*].macType = "Ieee80211Mac"
*.SW1.typename = "TsnSwitch1"
*.SW2.typename = "TsnSwitch2"

# client applications
*.ES1.numApps = 2
*.ES1.app[*].typename = "UdpSourceApp"
*.ES1.app[0].display-name = "best effort"
*.ES1.app[1].display-name = "video"
*.ES1.app[0].io.destAddress = "ES3"
*.ES1.app[1].io.destAddress = "ES3"
*.ES1.app[0].io.destPort = 1000
*.ES1.app[1].io.destPort = 1002

*.ES2.numApps = 3
*.ES2.app[0..1].typename = "UdpSourceApp"
*.ES2.app[0].display-name = "best effort"
*.ES2.app[1].display-name = "video"
*.ES2.app[0].io.destAddress = "ES3"
*.ES2.app[1].io.destAddress = "ES3"
*.ES2.app[0].io.destPort = 1001
*.ES2.app[1].io.destPort = 1003

# WIRED TO WIRELESS with IO
*.ES2.app[2].typename = "UdpSourceApp"
*.ES2.app[2].display-name = "video-app2"
*.ES2.app[2].io.destAddress = "ES4"
*.ES2.app[2].io.destPort = 1004
*.ES2.app[2].source.packetLength = 500B
*.ES2.app[2].source.productionInterval = 250us # ~16Mbps

# WIRED TO WIRELESS without IO
#*.ES2.app[2].typename = "UdpBasicApp"
#*.ES2.app[2].display-name = "video-app2"
#*.ES2.app[2].destAddress = "ES4"
#*.ES2.app[2].destPort = 1004
#*.ES2.app[2].source.packetLength = 500B
#*.ES2.app[2].source.productionInterval = 250us # ~16Mbps

#*.ES2.app[2].messageLength = 500B
#*.ES2.app[0].sendInterval = 250us

*.ES1.app[*].source.packetNameFormat = "%M-%m-%c"
*.ES1.app[0].source.packetLength = 1000B
*.ES1.app[1].source.packetLength = 500B
*.ES1.app[0].source.productionInterval = 500us # ~16Mbps
*.ES1.app[1].source.productionInterval = 250us # ~16Mbps

*.ES2.app[*].source.packetNameFormat = "%M-%m-%c"
*.ES2.app[0].source.packetLength = 1000B
*.ES2.app[1].source.packetLength = 500B
*.ES2.app[0].source.productionInterval = 500us # ~16Mbps
*.ES2.app[1].source.productionInterval = 250us # ~16Mbps

# server applications
*.ES3.numApps = 4
*.ES3.app[*].typename = "UdpSinkApp"
*.ES3.app[0..1].display-name = "best effort"
*.ES3.app[2..3].display-name = "video"
*.ES3.app[0].io.localPort = 1000
*.ES3.app[1].io.localPort = 1001
*.ES3.app[2].io.localPort = 1002
*.ES3.app[3].io.localPort = 1003

*.ES4.numApps = 1
*.ES4.app[*].typename = "UdpSinkApp"
*.ES4.app[0].display-name = "video-app2"
*.ES4.app[0].io.localPort = 1004
#*.ES4.app[0].localPort = 1004 

# enable outgoing streams
*.ES1.hasOutgoingStreams = true
*.ES2.hasOutgoingStreams = true

# client stream identification
*.ES1.bridging.streamIdentifier.identifier.mapping = [{stream: "best effort", packetFilter: expr(has(udp) && udp.destPort == 1000)},
                                                          {stream: "video", packetFilter: expr(has(udp) && udp.destPort == 1002)}]
*.ES2.bridging.streamIdentifier.identifier.mapping = [{stream: "best effort", packetFilter: expr(has(udp) && udp.destPort == 1001)},
                                                          {stream: "video", packetFilter: expr(has(udp) && (udp.destPort == 1003 || udp.destPort == 1004 ) )}]

# client stream encoding
*.ES1.bridging.streamCoder.encoder.mapping = [{stream: "best effort", pcp: 0},
                                                  {stream: "video", pcp: 4}]
# client stream encoding
*.ES2.bridging.streamCoder.encoder.mapping = [{stream: "best effort", pcp: 0},
                                                  {stream: "video", pcp: 4}]
# enable streams
*.SW*.hasIncomingStreams = true
*.SW*.hasOutgoingStreams = true

*.SW*.bridging.streamCoder.decoder.mapping = [{pcp: 0, stream: "best effort"},
                                                  {pcp: 4, stream: "video"}]

*.SW*.bridging.streamCoder.encoder.mapping = [{stream: "best effort", pcp: 0},
                                                  {stream: "video", pcp: 4}]
*.accessPoint.bridging.streamCoder.encoder.mapping = [{stream: "best effort", pcp: 0},
                                                  {stream: "video", pcp: 4}]
# enable incoming streams
*.ES3.hasIncomingStreams = true
*.ES4.hasIncomingStreams = true

# enable egress traffic shaping
*.SW*.hasEgressTrafficShaping = true

# time-aware traffic shaping with 2 queues
*.SW*.eth[*].macLayer.queue.numTrafficClasses = 2
*.SW*.eth[*].macLayer.queue.queue[0].display-name = "best effort"
*.SW*.eth[*].macLayer.queue.queue[1].display-name = "video"

#PCAP recording

*.accessPoint.numPcapRecorders = 1
*.accessPoint.pcapRecorder[*].pcapFile = "results/ap1.pcap"

*.ES4.numPcapRecorders = 1
*.ES4.pcapRecorder[*].pcapFile = "results/es4.pcap"

**.pcapRecorder[*].alwaysFlush = true

# automatic gate scheduling
*.gateScheduleConfigurator.typename = "TSNschedGateScheduleConfigurator"
*.gateScheduleConfigurator.gateCycleDuration = 1ms
# 58B = 8B (UDP) + 20B (IP) + 4B (802.1 Q-TAG) + 14B (ETH MAC) + 4B (ETH FCS) + 8B (ETH PHY)
*.gateScheduleConfigurator.configuration =
   [{pcp: 0, gateIndex: 0, application: "app[0]", source: "ES1", destination: "ES3", packetLength: 1000B + 58B, packetInterval: 500us, maxLatency: 500us},
    {pcp: 4, gateIndex: 1, application: "app[1]", source: "ES1", destination: "ES3", packetLength: 500B + 58B, packetInterval: 250us, maxLatency: 500us},
    {pcp: 0, gateIndex: 0, application: "app[0]", source: "ES2", destination: "ES3", packetLength: 1000B + 58B, packetInterval: 500us, maxLatency: 500us},
    {pcp: 4, gateIndex: 1, application: "app[1]", source: "ES2", destination: "ES3", packetLength: 500B + 58B, packetInterval: 250us, maxLatency: 500us}]

# gate scheduling visualization
*.visualizer.gateScheduleVisualizer.displayGateSchedules = true
*.visualizer.gateScheduleVisualizer.displayDuration = 100us
*.visualizer.gateScheduleVisualizer.gateFilter = "*.SW1.eth[2].** or *.SW2.eth[0].**.transmissionGate[0] or *.SW2.eth[1].**.transmissionGate[1] or *.SW2.eth[3].**.transmissionGate[0]" 
*.visualizer.gateScheduleVisualizer.height = 16

*.visualizer.packetDropVisualizer.displayPacketDrops = true
*.visualizer.packetDropVisualizer.labelFormat = "%n/reason: %r"
*.visualizer.packetDropVisualizer.fadeOutTime = 3s

*.visualizer.interfaceTableVisualizer.displayInterfaceTables = true

------------Stack Trace --------

Thread #1 [tsnwiredwireles] 7964 [core: 11] (Suspended : Breakpoint)    
    inet::ieee80211::Ieee80211LlcLpd::getProtocol() at Ieee80211LlcLpd.cc:18 0x7ffff614534f 
    inet::ieee80211::Ieee80211Mac::decapsulate() at Ieee80211Mac.cc:274 0x7ffff614f423  
    inet::ieee80211::Ieee80211Mac::sendUpFrame() at Ieee80211Mac.cc:352 0x7ffff6150f71  
    inet::ieee80211::Dcf::sendUp() at Dcf.cc:233 0x7ffff61d43df 
    inet::ieee80211::Dcf::recipientProcessReceivedFrame() at Dcf.cc:220 0x7ffff61d3d82  
    inet::ieee80211::Dcf::processLowerFrame() at Dcf.cc:165 0x7ffff61d2067  
    inet::ieee80211::Ieee80211Mac::processLowerFrame() at Ieee80211Mac.cc:396 0x7ffff6151ce6    
    inet::ieee80211::Ieee80211Mac::handleLowerPacket() at Ieee80211Mac.cc:187 0x7ffff614cef8    
    inet::LayeredProtocolBase::handleLowerMessage() at LayeredProtocolBase.cc:42 0x7ffff5e1c46d 
    inet::LayeredProtocolBase::handleMessageWhenUp() at LayeredProtocolBase.cc:21 0x7ffff5e1c276    
    <...more frames...> 

I checked the data at wirelesshost using pcap recorder and it is a UDP Packet, But looks like UDP Data. Looks like this kind of data, TSN UDP Packet doesn't seem to be handled in the getProtocol (or not yet handled) . Would be great if this change is included in INET. If you can give some pointers I can do the modification and contribute. Thank you for the time and effort!

Thanks Regards Abhilash

Abh4git commented 1 year ago

I worked on this further and figured out that the 4Bytes added for Ieee802.1Q Tag just shifts the ipv4 header. Therefore in Wireless mac it detects as Ieee802.1Qtag as protocol (instead of ipv4). How can this be well handled in wireless case. I tried changing the protocol type to ipv4 but that seems more short term solution in Ieee8022Llc.cc void Ieee8022Llc::decapsulate(Packet *frame) { const auto& llcHeader = frame->popAtFront();

auto sapInd = frame->addTagIfAbsent<Ieee802SapInd>();
sapInd->setSsap(llcHeader->getSsap());
sapInd->setDsap(llcHeader->getDsap());
// TODO control?

if (llcHeader->getSsap() == 0xAA && llcHeader->getDsap() == 0xAA && llcHeader->getControl() == 0x03) {
    const auto& snapHeader = dynamicPtrCast<const Ieee8022LlcSnapHeader>(llcHeader);
    if (snapHeader == nullptr)
        throw cRuntimeError("LLC header indicates SNAP header, but SNAP header is missing");
}
//frame->peekAll(PF_ALLOW_REINTERPRETATION);

// llcHeader->peek(&iter, length, flags)(PF_ALLOW_REINTERPRETATION); auto payloadProtocol = getProtocol(llcHeader); if (payloadProtocol->getId()==inet::Protocol::ieee8021qCTag.getId()) { //auto vlanReq = frame->removeTagIfPresent(); const auto& llcHeaderQTag = frame->popAtFront(); frame->peekData(32); payloadProtocol = &Protocol::ipv4; } if (payloadProtocol) { frame->addTagIfAbsent()->setProtocol(payloadProtocol); frame->addTagIfAbsent()->setProtocol(payloadProtocol); } else { frame->removeTagIfPresent(); frame->removeTagIfPresent(); } } I am using peek with PF_ALLOW_REINTERPRETATION (32) . This I guess is a workaround which allows 802Qtagged packets to go up. Can you suggest a more long term/correct approach?

Abh4git commented 11 months ago

I worked further on this and realized I need to add a Ieee8211qTagHeader removal in place at wireless end. Adding this and it worked fine. Can be closed. I will try to summarize and contribute to community soon.