From a3d508b648906fb742e5205bcd4b97fbf88ea653 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 9 Aug 2006 01:24:32 +0000 Subject: Clarified packet ownership transfer between a few functions. Added a large number of missing calls to free_pkb(). In the case of UDP, no received packets were ever freed, which lead to memory exhaustion remarkably quickly once pxelinux started up. In general, any function with _rx() in its name which accepts a pk_buff *must* either call free_pkb() or pass the pkb to another _rx() function (e.g. the next layer up the stack). Since the UDP (and TCP) layers don't pass packet buffers up to the higher-layer protocols (the "applications"), they must free the packet buffer after calling the application's newdata() method. --- src/net/ethernet.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/net/ethernet.c') diff --git a/src/net/ethernet.c b/src/net/ethernet.c index 13b3c2dbc..c4b526f51 100644 --- a/src/net/ethernet.c +++ b/src/net/ethernet.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -68,21 +69,22 @@ static int eth_tx ( struct pk_buff *pkb, struct net_device *netdev, * Strips off the Ethernet link-layer header and passes up to the * network-layer protocol. */ -static void eth_rx ( struct pk_buff *pkb, struct net_device *netdev ) { +static int eth_rx ( struct pk_buff *pkb, struct net_device *netdev ) { struct ethhdr *ethhdr = pkb->data; /* Sanity check */ if ( pkb_len ( pkb ) < sizeof ( *ethhdr ) ) { DBG ( "Ethernet packet too short (%d bytes)\n", pkb_len ( pkb ) ); - return; + free_pkb ( pkb ); + return -EINVAL; } /* Strip off Ethernet header */ pkb_pull ( pkb, sizeof ( *ethhdr ) ); /* Hand off to network-layer protocol */ - net_rx ( pkb, netdev, ethhdr->h_protocol, ethhdr->h_source ); + return net_rx ( pkb, netdev, ethhdr->h_protocol, ethhdr->h_source ); } /** -- cgit v1.2.3-55-g7522