Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 18 Jun 2020 22:08:30 +0200
From:      Andreas Longwitz <longwitz@incore.de>
To:        freebsd-net@freebsd.org
Subject:   Re: pxeboot is very slow on servers sending gratuitous ARP probably caused by commit r317887
Message-ID:  <5EEBC9BE.6020206@incore.de>
In-Reply-To: <5EE28A7D.7090406@incore.de>
References:  <5EE28A7D.7090406@incore.de>

next in thread | previous in thread | raw e-mail | index | archive | help
In the meantime I did some more research. Now I am sure that after
commit r317887 pxeboot is not robust when ARP packets come in. Before
this commit pxe.c had a function readudp() which used PXENV_UDP_READ to
get data from the NFS server and so never an ARP packet was coming in.
Now pxe.c reads data from the NFS server in function pxe_netif_receive()
using the API PXENV_UNDI_ISR. In my network a lot of ARP packets are
coming in and can be seen in arp.c when ARP_DEBUG is enabled. I have
sneaking suspicion incoming gratuitous ARPs send from many of my servers
on the network are not handled correct in pxe_netif_receive() and that
is the cause of the slowness.

At home on a small network without gratuitous ARPs the actual pxeboot
has normal speed.

The following patch for r360998 disables all broadcast ARPs and pxeboot
again runs with normal speed on all of my networks:

--- pxe.c.orig  2019-01-13 08:25:55.000000000 +0100
+++ pxe.c       2020-06-15 21:30:19.000000000 +0200
@@ -424,7 +424,7 @@
        if (undi_open_p == NULL)
                return;
        bzero(undi_open_p, sizeof(*undi_open_p));
-       undi_open_p->PktFilter = FLTR_DIRECTED | FLTR_BRDCST;
+       undi_open_p->PktFilter = FLTR_DIRECTED;
        pxe_call(PXENV_UNDI_OPEN, undi_open_p);
        if (undi_open_p->Status != 0)
                printf("undi open failed: %x\n", undi_open_p->Status);

Using ARP_DEBUG in libsa/arp.c needs the following small patch:

--- arp.c.orig  2018-12-17 16:13:58.000000000 +0100
+++ arp.c       2020-06-18 21:51:37.920045000 +0200
@@ -178,7 +178,7 @@
        if (n == -1 || n < sizeof(struct ether_arp)) {
 #ifdef ARP_DEBUG
                if (debug)
-                       printf("bad len=%d\n", n);
+                       printf("bad len=%zd\n", n);
 #endif
                free(ptr);
                return (-1);

I could not figure out why and in which way ARPs are handled not always
correct. I do not understand the API of PXENV_UNDI_ISR used in
pxe_netif_receive(). The well known PXE documentation pxespec.pdf has a
description for this but only for the case when the program handles the
interrupt of the PIC. But we do not have assembler coding for doing
this. It would be fine if somebody can point me to a documentation of
the PXENV_UNDI_ISR API used in pxe_netif_receive().

Andreas Longwitz





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5EEBC9BE.6020206>