[HELP] <title>add 802.1Q header
Description
Hello, I need to add priority ethernet messaging. My LAN9370 supports 802.1Q with VLAN. Think I can use SOCK_RAW for the priority msg's, but can't figure out where the packets are put together to add the extra 32 bits to the frame. Can anyone point me to the correct area of the code? thanks Ken
Verification
- [x] I have verified before submitting the report.
@wengzhe could you please help here?
@xiaoxiang781216 any idea?
Hi All. I've made some progress, but have an issue I hope someone can help with.
A quick summary of how it works is here: https://nuttx.apache.org/docs/latest/components/net/pkt.html Another helpful example here: https://github.com/microchip-ung/lan937x_linux/blob/main/src/Atmel_SOC_SAMA5D3/buildroot_external_lan937x/package/lan937x_tc/src/pkt_io.c#L603
My problem is when I call read(socket, buffer, sizeof(buffer)) the read function is blocking. Does not return until there is data to read. Also seems like non-raw traffic is blocked. Ping is fine outside this, but didn't work while 'read' is waiting. Does this sound right? Is there a better way to do this?
thanks Ken
@matiamic since you are working with low level Ethernet 10BASE-T1x, could you please take a look here?
@wengzhe @raiden00pl for visibility
Hi @ken-hutchinson, this seems like the default behavior to me: https://man7.org/linux/man-pages/man2/recv.2.html
If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is nonblocking
You should be able to go nonblocking by passing the MSG_DONTWAIT flag to the recv.
I am not sure about the blocking of the rest of the network. The behavior is defined here I believe.
The net_lock() is being called, but the lock should be released by the net_sem_wait during waiting. But it seems from your description that the netlock might still be locked or there is some other mechanism blocking your ping...
Thanks for your reply @matiamic
The blocking call is probably fine.
I have the receiver doing 'read' in a loop with 1m-sec sleep between calls. The sender can send a ping, or raw frames (with 802.1q tag). If I ping first, they go fine. The raw frame is fine. The first 'ping' after a raw frame always fails. If I ping again, it works. Does this mean anything to you?
Could also be a problem with the vlan config on the LAN9370. On the failed pings, I can see in the LAN9370 stats the data enters the RGMII MAC port, but doesn't make it to the outgoing port. Don't know why that would happen.
thanks
Ken
Sounds like expected behavior of arp_out.
This should happen only after reset (or when arp cache is dropped maybe). The incoming ICMP echo request is processed by the net stack and the ICMP echo reply is then saved into the output buffer. Before sending, the arp_out is called. No arp cache entry is found for the given IP, the contents of the output buffer are replaced with the ARP request, the ICMP reply is lost forever.
Hi @ken-hutchinson, is it possible to you share your code? This way more people could analyze and help to test. I see that NuttX has some support to 802.1Q, but there is no documentation about it. Probably someone used, got it working on their board and never submitted it to mainline.
I tried to find some development board with LAN9370 to test, but I didn't find any. Do you know some chip that could be used to test it?
I wanted to post a follow up, as a thank you for your help. It's pretty easy to create a RAW_SOCK message, using the netpkt example, and easy to add the 802.1q tag. But I couldn't get it to work well. The raw msg's themselves go through, but I had another pthread sending UDP msg's and they would only go through when the raw msg's stopped. I don't know if this was due to nuttx or the LAN937x, but I suspect the switch. It would also lose it's connection after the raw msgs. A ping would fail and a TCP msg would take 6 seconds to return. My solution was to use 802.1p on UDP msgs using this for the socket where you need priority: int dscp = 0xfc; // priority tag using DSCP bits [5:3] (must be configured on the switch) setsockopt(udpSocket, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)); Much easier to configure and seems to work. I get HI_PRIO packets in the switch. Difficult to actually prove and quantify how much it helps. Thanks all