This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS/PROCESSOR-SDK-AM437X: Raw Ethernet support for VLAN device patch

Part Number: PROCESSOR-SDK-AM437X

Tool/software: TI-RTOS

While working on our app we found a small bug in NDK 3.40.01.01 which prevents use Raw sockets with VLAN (original SDK always looks for the VLAN frame ID instead of L2 frame ID). Can someone apply it to official source tree?

diff -ru ndk_3_40_01_01/packages/ti/ndk/stack/raweth/raweth.c ndk_3_40_01_01.vlan/packages/ti/ndk/stack/raweth/raweth.c
--- ndk_3_40_01_01/packages/ti/ndk/stack/raweth/raweth.c	2018-08-31 19:18:35.000000000 +0300
+++ ndk_3_40_01_01.vlan/packages/ti/ndk/stack/raweth/raweth.c	2019-05-06 17:32:02.752635600 +0300
@@ -197,7 +197,6 @@
 {
 
     PBM_Pkt*        ptr_pkt = (PBM_Pkt *)hPkt;
-    uint32_t        Type;
     int32_t         len;
     ETHHDR*         ptr_eth_header;
     SOCKRAWETH      *hRawEthSock;
@@ -215,15 +214,10 @@
     ptr_pkt->ValidLen   += ptr_pkt->L2HdrLen;
     ptr_pkt->DataOffset -= ptr_pkt->L2HdrLen;
 
-    /* Get the pointer to the Ethernet Header. */
-    ptr_eth_header = (ETHHDR *) (ptr_pkt->pDataBuffer + ptr_pkt->DataOffset);
-
     /* Use the type field to determine if we have a matching
      * raw ethernet channel open
      */
-    Type = NDK_ntohs (ptr_eth_header->Type);
-
-    hRawEthSock = RawEthSockPcbFind (Type, ptr_pkt->hIFRx);
+    hRawEthSock = RawEthSockPcbFind (ptr_pkt->EtherType, ptr_pkt->hIFRx);
 
     if (!hRawEthSock)
     {

  • Hi Alexander,

    We have an engineer looking into this and will get back to you.

    Todd
  • Hi Alexander,

    Thanks for pointing this out. Can you share a bit more info on the issue you're seeing? What is the exact problem you're encountering while trying to use raw sockets with a VLAN? Is the Type always equal to 0x8100 within RawEthRxPacket()?

    Thanks,
    Brandon
  • Hi Brandon,

    The problem is that you can only subscribe to all VLAN packets instead of enclosed type. I.e. if you need to receive frames with type say 0xbbaa and they encapsulated in VLAN you have to subscribe to 0x8100 at app level. With this patch you can subscribe to 0xbbaa.
  • Brandon has been out of the office for a couple days and will response shortly.
  • I removed unused variable ptr_eth_header from the patch above.

    I made one more VLAN related patch: according to IEEE 802.1Q, VLAN with tag 0 should not be considered as VLAN tagged packet but rather the regular packet which have priority, so second patch allows to receive VLAN 0 frames without creating VLAN device for the VLAN 0. I.e. the socket on raw device will receive both regular frames and VLAN 0 tagged frames, VLAN packets with tag different from 0 will still be send to the corresponding VLAN devices.

    ndk-vlan-0-raweth.diff
    diff -ruP ndk_3_40_01_01/packages/ti/ndk/stack/raweth/raweth.c ndk_3_40_01_01.vlan/packages/ti/ndk/stack/raweth/raweth.c
    --- ndk_3_40_01_01/packages/ti/ndk/stack/raweth/raweth.c	2018-08-31 19:18:35.000000000 +0300
    +++ ndk_3_40_01_01.vlan/packages/ti/ndk/stack/raweth/raweth.c	2019-05-16 19:29:47.625761100 +0300
    @@ -195,11 +195,8 @@
      */
     int RawEthRxPacket (PBM_Handle hPkt)
     {
    -
         PBM_Pkt*        ptr_pkt = (PBM_Pkt *)hPkt;
    -    uint32_t        Type;
         int32_t         len;
    -    ETHHDR*         ptr_eth_header;
         SOCKRAWETH      *hRawEthSock;
         void            *hSBRx;
     
    @@ -215,15 +212,10 @@
         ptr_pkt->ValidLen   += ptr_pkt->L2HdrLen;
         ptr_pkt->DataOffset -= ptr_pkt->L2HdrLen;
     
    -    /* Get the pointer to the Ethernet Header. */
    -    ptr_eth_header = (ETHHDR *) (ptr_pkt->pDataBuffer + ptr_pkt->DataOffset);
    -
         /* Use the type field to determine if we have a matching
          * raw ethernet channel open
          */
    -    Type = NDK_ntohs (ptr_eth_header->Type);
    -
    -    hRawEthSock = RawEthSockPcbFind (Type, ptr_pkt->hIFRx);
    +    hRawEthSock = RawEthSockPcbFind (ptr_pkt->EtherType, ptr_pkt->hIFRx);
     
         if (!hRawEthSock)
         {
    @@ -238,8 +230,8 @@
         /* If we are here, we found a valid socket */
         len = (int)ptr_pkt->ValidLen;
     
    -	/* Get the receiver buffer handle */
    -	hSBRx = RawEthSockGetRx(hRawEthSock);
    +    /* Get the receiver buffer handle */
    +    hSBRx = RawEthSockGetRx(hRawEthSock);
     
         /* Enqueue the data to the Socket buffer. */
         if( len && (SBGetSpace(hSBRx) >= len) )
    diff -ruP ndk_3_40_01_01/packages/ti/ndk/stack/vlan/vlan.c ndk_3_40_01_01.vlan/packages/ti/ndk/stack/vlan/vlan.c
    --- ndk_3_40_01_01/packages/ti/ndk/stack/vlan/vlan.c	2018-08-31 19:18:35.000000000 +0300
    +++ ndk_3_40_01_01.vlan/packages/ti/ndk/stack/vlan/vlan.c	2019-05-16 19:17:48.215837700 +0300
    @@ -140,31 +140,39 @@
         if (ptr_src_device == NULL)
             return encap_protocol;
     
    -    /* Get the VLAN Source Interface: If none exists then this interface is not
    -     * capable of receiving VLAN frames. */
    -    ptr_src = VLANFindSourceInterface (ptr_src_device->index);
    -    if (ptr_src == NULL)
    -        return encap_protocol;
    -
         /* Get the pointer to the VLAN Header */
         ptr_vlanhdr = (VLANHDR *) (ptr_pkt->pDataBuffer + ptr_pkt->DataOffset);
     
         /* Extract the VLAN Identifier. */
         vlan_id = NDK_ntohs(ptr_vlanhdr->TCI) & MAX_VLAN_ID;
     
    -    /* Get the VLAN Node matching the VLAN ID: If none exists then it indicates there
    -     * is no VLAN node; hence no NIMU network interface object capable of handling the
    -     * VLAN Identifier.  */
    -    ptr_node = VLANFindNode (vlan_id, ptr_src);
    -    if (ptr_node == NULL)
    -        return encap_protocol;
    +    /* The null VLAN ID. Indicates that the tag header contains only priority information;
    +     * no VLAN identifier is present in the frame.
    +     */
    +    if (vlan_id != 0)
    +    {
    +        /* Get the VLAN Source Interface: If none exists then this interface is not
    +         * capable of receiving VLAN frames. */
    +        ptr_src = VLANFindSourceInterface (ptr_src_device->index);
    +        if (ptr_src == NULL)
    +            return encap_protocol;
    +
    +        /* Get the VLAN Node matching the VLAN ID: If none exists then it indicates there
    +         * is no VLAN node; hence no NIMU network interface object capable of handling the
    +         * VLAN Identifier.  */
    +        ptr_node = VLANFindNode (vlan_id, ptr_src);
    +        if (ptr_node == NULL)
    +            return encap_protocol;
    +
    +        /* Associate packet with the right vlan device. */
    +        ptr_pkt->hIFRx = (void *)ptr_node->ptr_vlan_device;
    +    }
     
         /* We can proceed with the packet. Modify the fields in the packet appropriately. */
         ptr_pkt->ValidLen   -= VLANHDR_SIZE;
         ptr_pkt->DataOffset += VLANHDR_SIZE;
         ptr_pkt->EtherType   = NDK_ntohs(ptr_vlanhdr->EncapProtocol);
         ptr_pkt->L2HdrLen   += VLANHDR_SIZE;
    -    ptr_pkt->hIFRx       = (void *)ptr_node->ptr_vlan_device;
     
         /* Return the encapsulated protocol in host order. */
         return ptr_pkt->EtherType;
    

  • Hi Alexander,

    Thank you again both for pointing this out and providing a patch! We will review it and decide what to do from there.

    The following JIRA has been filed to track this issue: NDK-403

    Best,
    Brandon