diff options
author | Michael Brown | 2006-08-09 03:24:32 +0200 |
---|---|---|
committer | Michael Brown | 2006-08-09 03:24:32 +0200 |
commit | a3d508b648906fb742e5205bcd4b97fbf88ea653 (patch) | |
tree | f5783a075a4d73d014949412a2323637bace4a09 /src/net/netdevice.c | |
parent | Note to self: learn to count. (diff) | |
download | ipxe-a3d508b648906fb742e5205bcd4b97fbf88ea653.tar.gz ipxe-a3d508b648906fb742e5205bcd4b97fbf88ea653.tar.xz ipxe-a3d508b648906fb742e5205bcd4b97fbf88ea653.zip |
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.
Diffstat (limited to 'src/net/netdevice.c')
-rw-r--r-- | src/net/netdevice.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/net/netdevice.c b/src/net/netdevice.c index 825613cc..634977f7 100644 --- a/src/net/netdevice.c +++ b/src/net/netdevice.c @@ -97,8 +97,9 @@ int net_tx ( struct pk_buff *pkb, struct net_device *netdev, * @v netdev Network device * @v net_proto Network-layer protocol, in network-byte order * @v ll_source Source link-layer address + * @ret rc Return status code */ -void net_rx ( struct pk_buff *pkb, struct net_device *netdev, +int net_rx ( struct pk_buff *pkb, struct net_device *netdev, uint16_t net_proto, const void *ll_source ) { struct net_protocol *net_protocol; @@ -106,10 +107,11 @@ void net_rx ( struct pk_buff *pkb, struct net_device *netdev, for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ; net_protocol++ ) { if ( net_protocol->net_proto == net_proto ) { - net_protocol->rx ( pkb, netdev, ll_source ); - break; + return net_protocol->rx ( pkb, netdev, ll_source ); } } + free_pkb ( pkb ); + return 0; } /** |