lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lwip-users] LLDP Implementation for lwIP


From: Amit Ashara
Subject: Re: [lwip-users] LLDP Implementation for lwIP
Date: Fri, 12 Aug 2016 11:00:11 -0500

Hello Sergio, Simon,

I finally got the LLDP basic frame to work. I am able to send the LLDP frame out of my device and see the same correctly on the wire-shark.

However, do be able to make a proper source code out of it, I would need advise. The fields of the LLDP are static and not expected to change dynamically. Also it is up to the user to decide what is required in the fields and some of the field size may be configured at compile time. How do I do this within the framework of lwIP

As an example, following is the "hack-patch" code.

#if !LWIP_AUTOIP
static
#endif /* LWIP_AUTOIP */
err_t
lldp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr)
{
#if 1
      struct pbuf *p;
      err_t result = ERR_OK;
      struct eth_hdr *ethhdr;
      struct lldp_hdr *lldptlv;

      LWIP_ASSERT("netif != NULL", netif != NULL);

      /* allocate a pbuf for the outgoing ARP request packet */
      p = pbuf_alloc(PBUF_RAW, SIZEOF_LLDP_PACKET, PBUF_RAM);
      /* could allocate a pbuf for an ARP request? */
      if (p == NULL) {
        LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
          ("etharp_raw: could not allocate pbuf for ARP request.\n"));
        ETHARP_STATS_INC(etharp.memerr);
        return ERR_MEM;
      }
      LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr",
                  (p->len >= SIZEOF_LLDP_PACKET));

      ethhdr = (struct eth_hdr *)p->payload;
      lldptlv = (struct lldp_hdr *)((u8_t*)ethhdr + SIZEOF_ETH_HDR);
      LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n"));

      lldptlv->chassisid.tlvtype    = 0x02;
      lldptlv->chassisid.tlvlen     = 0x07;
      lldptlv->chassisid.tlvsubtype = 0x04;
      ETHADDR16_COPY(&lldptlv->chassisid.tlvvalue,ethsrc_addr);

      lldptlv->portid.tlvtype  = 0x04;
      lldptlv->portid.tlvlen   = 0x07;
      lldptlv->portid.tlvsubtype = 0x03;
      ETHADDR16_COPY(&lldptlv->portid.tlvvalue,ethsrc_addr);

      lldptlv->ttl.tlvtype  = 0x06;
      lldptlv->ttl.tlvlen   = 0x07;
      lldptlv->ttl.tlvsubtype = 0x00;
      lldptlv->ttl.tlvvalue[0] = 0x10;
      lldptlv->ttl.tlvvalue[1] = 0x00;
      lldptlv->ttl.tlvvalue[2] = 0x00;
      lldptlv->ttl.tlvvalue[3] = 0x00;
      lldptlv->ttl.tlvvalue[4] = 0x00;
      lldptlv->ttl.tlvvalue[5] = 0x00;


      LWIP_ASSERT("netif->hwaddr_len must be the same as ETHARP_HWADDR_LEN for etharp!",
                  (netif->hwaddr_len == ETHARP_HWADDR_LEN));
      /* Write the Ethernet MAC-Addresses */
      ETHADDR16_COPY(&ethhdr->dest, &ethlldpdestmac0);
      ETHADDR16_COPY(&ethhdr->src, ethsrc_addr);
      ethhdr->type = PP_HTONS(ETHTYPE_LLDP);

      /* send ARP query */
      result = netif->linkoutput(netif, p);
      //ETHARP_STATS_INC(etharp.xmit);
      /* free ARP query packet */
      pbuf_free(p);
      p = NULL;
      /* could not allocate pbuf for ARP request */

      return result;
#endif
}


Regards
Amit

On Thu, Aug 4, 2016 at 1:07 PM, Amit Ashara <address@hidden> wrote:
Hello Sergio

LLDP is a multicast information only packet. It has the be sent at fixed time intervals. The second approach to have a separate driver and calling it in a timer function seems to be the approach. Again the receive packet is easy to process. The transmit needs to be thought and inserted . Let me run some experiments and run into issues rather than sending emails on phantom issues.

Regards
Amit Ashara

On Aug 4, 2016, at 9:31 AM, Sergio R. Caprile <address@hidden> wrote:

>> psNetif->linkoutput = tivaif_transmit;
>
>> If i check the tivaif_transmit function, "tivaif_transmit(struct
>> netif *psNetif, struct pbuf *p)" it maps the pbuf to the MAC
>> controller for transmission. It is this buffer that needs to be
>> modified for LLDP frame.
>
> Not exactly. You need to allocate a pbuf, fill it with your data, give
> it to tivaif_transmit(), and free it when it is done. Unless there is
> some retransmission mechanism inside LLDP (which I don't know), then it
> is done when the controller has it in its memory. Unless it is a
> zero-copy driver (looks so, DMA perhaps?), in which "the controller
> memory and the pbuf memory is the same space", so you need to know when
> it has been transmitted to free it. I have no expertise in this area,
> but there is this:
> http://lwip.wikia.com/wiki/Writing_a_device_driver#Notes_on_Zero-Copy_Network_interface_drivers
>
>> However the call stack is always from TCP or DHCP (even when ARP is
>> called which is a link layer packet).
>
> That is because you said you just needed the output phase ;^)
> The stack is answering because it is receiving the datagrams.
> Now you need to check your input to see why. You can go two paths, and I
> suggest you take both, not necessarily in this order.
>
> (1) Go back to my first mail, where I've shown you code that explains this
>
> (2) Read this:
>    http://lwip.wikia.com/wiki/Writing_a_device_driver
>
> ARP is link layer but is part of the IP suite, so the stack supports ARP
> and the link level driver has been configured to deliver ARP to lwIP
> input function.
>
>
>
> _______________________________________________
> lwip-users mailing list
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/lwip-users


reply via email to

[Prev in Thread] Current Thread [Next in Thread]