I’m having an issue with network buffers getting hung up, so I’ve built monitoring in the cli, which I’ll attach to show how I’m doing this.
What I’m trying to understand is the flow of release, why do some buffers show as not free when in fact they are not accepted? In this example dump here
MON:[01](IPV4)581122D6230D->FCC23D0B6A84 192.168.0.120 -> 192.168.0.77(TCP) 9491 -> 80
MON:[02](IPV4)581122D6230D->FCC23D0B6A84 192.168.0.120 -> 192.168.0.77(TCP) 9293 -> 80
MON:[04](IPV4)FCC23D0B6A84->581122D6230D 192.168.0.77 -> 192.168.0.120(TCP) 80 -> 9291
MON:[06](IPV4)FCC23D0B6A84->581122D6230D 192.168.0.77 -> 192.168.0.120(TCP) 80 -> 9491
MON:[07](0x0069)245A4C8B7DFF->0180C2000000 4242 -> ...
MON:[12]( ARP)FCC23D0B6A84->FFFFFFFFFFFF 192.168.0.77 -> 192.168.0.77
MON:[16](IPV4)FCC23D0B6A84->581122D6230D 192.168.0.77 -> 192.168.0.120(TCP) 80 -> 9291
MON:[22](IPV4)FCC23D0B6A84->581122D6230D 192.168.0.77 -> 192.168.0.120(TCP) 80 -> 9491
MON[07] is a Spanning Tree Protocol packet, which gets rejected in prvNetworkInterfaceInput at
if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
{
/* Not an Ethernet frame-type or a checksum error. */
xAccepted = pdFALSE;
}
So why do these show up at all as non free as they never were really allocated? Or is the current descriptor ready to capture the next rx always listed as non free? If so, why would I ever get multiples, like this dump at startup?
MON:[00](0x88CC)245A4C8B7DFF->0180C200000E 0207 -> ...
MON:[01](0x0069)245A4C8B7DFF->0180C2000000 4242 -> ...
MON:[02](0x0069)245A4C8B7DFF->0180C2000000 4242 -> ...
MON:[03](IPV4)FCC23D0B6A84->581122D6230D 192.168.0.77 -> 192.168.0.120(TCP) 80 -> 9293
MON:[04](IPV4)FCC23D0B6A84->581122D6230D 192.168.0.77 -> 192.168.0.120(TCP) 80 -> 9293
MON:[05](IPV4)FCC23D0B6A84->581122D6230D 192.168.0.77 -> 192.168.0.120(TCP) 80 -> 9491
MON:[06](IPV4)581122D6230D->FCC23D0B6A84 192.168.0.120 -> 192.168.0.77(TCP) 9713 -> 80
MON:[07](IPV4)581122D6230D->FCC23D0B6A84 192.168.0.120 -> 192.168.0.77(TCP) 9491 -> 80
Corresponding code:
#if ENABLE_NET_BUF_VIEW == 1
static BaseType_t viewNetBuffers(char *pcWriteBuffer, size_t xWriteBufferLen,
const char *pcCommandString,
CLI_CmdState *state) {
int i, len;
int count = 0;
char *buf = x_malloc(128, XMEM_HEAP_SLOW);
char *ipSrc = x_malloc(32, XMEM_HEAP_SLOW);
char *ipDst = x_malloc(32, XMEM_HEAP_SLOW);
char *frameType = x_malloc(32, XMEM_HEAP_SLOW);
char *out = pcWriteBuffer;
// typedef struct xIP_PACKET *IPPacket;
IPPacket_t *IPPacket;
TCPPacket_t *TCPPacket;
UDPPacket_t *UDPPacket;
ICMPPacket_t *ICMPPacket;
ARPPacket_t * ARPPacket;
NetworkBufferDescriptor_t *bd = debug_xNetworkBuffers();
for (i = 0; i < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; i++) {
if (!isBufferFree(&bd[i])) {
count++;
vTaskSuspendAll();
IPPacket = (IPPacket_t *)bd[i].pucEthernetBuffer;
ARPPacket = (ARPPacket_t *)bd[i].pucEthernetBuffer;
switch (IPPacket->xEthernetHeader.usFrameType) {
case ipARP_FRAME_TYPE:
sprintf(frameType, " ARP");
sprintf(ipSrc, "%i.%i.%i.%i",
ARPPacket->xARPHeader.ucSenderProtocolAddress[0],
ARPPacket->xARPHeader.ucSenderProtocolAddress[1],
ARPPacket->xARPHeader.ucSenderProtocolAddress[2],
ARPPacket->xARPHeader.ucSenderProtocolAddress[3]);
FreeRTOS_inet_ntoa(ARPPacket->xARPHeader.ulTargetProtocolAddress,
ipDst);
break;
case ipIPv4_FRAME_TYPE:
sprintf(frameType, "IPV4");
FreeRTOS_inet_ntoa(IPPacket->xIPHeader.ulSourceIPAddress,
(char *)ipSrc);
FreeRTOS_inet_ntoa(IPPacket->xIPHeader.ulDestinationIPAddress,
(char *)ipDst);
break;
case ipIPv6_FRAME_TYPE:
sprintf(frameType, "IPV6");
sprintf(ipSrc, "...");
sprintf(ipDst, "...");
break;
default:
sprintf(frameType, "0x%02X%02X",
IPPacket->xEthernetHeader.usFrameType & 0xFF,
IPPacket->xEthernetHeader.usFrameType >> 8);
sprintf(ipSrc, "%02X%02X", IPPacket->xIPHeader.ucVersionHeaderLength,
IPPacket->xIPHeader.ucDifferentiatedServicesCode);
sprintf(ipDst, "...");
break;
}
len = sprintf(
buf,
"MON:[%02i](%s)%02X%02X%02X%02X%02X%02X->%02X%02X%02X%02X%02X%"
"02X %s -> %s",
i, frameType, IPPacket->xEthernetHeader.xSourceAddress.ucBytes[0],
IPPacket->xEthernetHeader.xSourceAddress.ucBytes[1],
IPPacket->xEthernetHeader.xSourceAddress.ucBytes[2],
IPPacket->xEthernetHeader.xSourceAddress.ucBytes[3],
IPPacket->xEthernetHeader.xSourceAddress.ucBytes[4],
IPPacket->xEthernetHeader.xSourceAddress.ucBytes[5],
IPPacket->xEthernetHeader.xDestinationAddress.ucBytes[0],
IPPacket->xEthernetHeader.xDestinationAddress.ucBytes[1],
IPPacket->xEthernetHeader.xDestinationAddress.ucBytes[2],
IPPacket->xEthernetHeader.xDestinationAddress.ucBytes[3],
IPPacket->xEthernetHeader.xDestinationAddress.ucBytes[4],
IPPacket->xEthernetHeader.xDestinationAddress.ucBytes[5], ipSrc,
ipDst);
if (IPPacket->xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE) {
switch (IPPacket->xIPHeader.ucProtocol) {
case FREERTOS_IPPROTO_TCP:
TCPPacket = (TCPPacket_t *)IPPacket;
len +=
sprintf(&buf[len], "(TCP) %i -> %i\r\n",
FreeRTOS_htons(TCPPacket->xTCPHeader.usSourcePort),
FreeRTOS_htons(TCPPacket->xTCPHeader.usDestinationPort));
break;
case FREERTOS_IPPROTO_UDP:
UDPPacket = (UDPPacket_t *)IPPacket;
len +=
sprintf(&buf[len], "(UDP) %i -> %i\r\n",
FreeRTOS_htons(UDPPacket->xUDPHeader.usSourcePort),
FreeRTOS_htons(UDPPacket->xUDPHeader.usDestinationPort));
break;
case FREERTOS_SOCK_STREAM: // ICMP
ICMPPacket = (ICMPPacket_t *)IPPacket;
len += sprintf(&buf[len], "(ICMP) msg=%i type=%i\r\n",
ICMPPacket->xICMPHeader.ucTypeOfMessage,
ICMPPacket->xICMPHeader.ucTypeOfService);
break;
default:
len += sprintf(&buf[len], "(%i)\r\n", IPPacket->xIPHeader.ucProtocol);
break;
}
} else {
len += sprintf(&buf[len], "\r\n");
}
xTaskResumeAll();
out += cliSafePrint(out, &xWriteBufferLen, buf);
}
}
if (count == 0) {
out += cliSafePrint(out, &xWriteBufferLen, "No used buffers\r\n");
}
*out = 0;
x_free(buf);
x_free(ipSrc);
x_free(ipDst);
x_free(frameType);
return pdFALSE;
}
#endif