In the frag_buffer timer expiry function, there was comment "Free the
fragment buffer" but no attempt to free it was actually done.
Signed-off-by: Michal Kubecek <mku...@su...>
---
src/include/gpxe/ip.h | 3 +++
src/net/ipv4.c | 26 ++++++++++++++++++++++++--
2 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/src/include/gpxe/ip.h b/src/include/gpxe/ip.h
index 4342a0c..29def10 100644
--- a/src/include/gpxe/ip.h
+++ b/src/include/gpxe/ip.h
@@ -34,6 +34,7 @@ struct net_protocol;
#define IP_FRAG_IOB_SIZE 1500
#define IP_FRAG_TIMEOUT 50
+#define IP_FRAG_EXPIRED 0x0001
/** An IPv4 packet header */
struct iphdr {
@@ -86,6 +87,8 @@ struct frag_buffer {
struct io_buffer *frag_iob;
/* Reassembly timer */
struct retry_timer frag_timer;
+ /* Flags */
+ uint16_t frag_flags;
/* List of fragment reassembly buffers */
struct list_head list;
};
diff --git a/src/net/ipv4.c b/src/net/ipv4.c
index d698318..f20762f 100644
--- a/src/net/ipv4.c
+++ b/src/net/ipv4.c
@@ -139,11 +139,14 @@ static struct ipv4_miniroute * ipv4_route ( struct in_addr *dest ) {
* @v timer Retry timer
* @v over If asserted, the timer is greater than @c MAX_TIMEOUT
*/
-static void ipv4_frag_expired ( struct retry_timer *timer __unused,
+static void ipv4_frag_expired ( struct retry_timer *timer,
int over ) {
if ( over ) {
+ struct frag_buffer *fragbuf;
DBG ( "Fragment reassembly timeout" );
- /* Free the fragment buffer */
+ /* Mark the fragment buffer for cleanup */
+ fragbuf = container_of(timer, struct frag_buffer, frag_timer);
+ fragbuf->frag_flags |= IP_FRAG_EXPIRED;
}
}
@@ -161,6 +164,21 @@ static void free_fragbuf ( struct frag_buffer *fragbuf ) {
}
/**
+ * Remove all expired fragment buffers
+ *
+ */
+static void ipv4_frag_cleanup ()
+{
+ struct frag_buffer *fragbuf;
+ struct frag_buffer *fragtmp;
+
+ list_for_each_entry_safe ( fragbuf, fragtmp, &frag_buffers, list ) {
+ if ( fragbuf->frag_flags & IP_FRAG_EXPIRED )
+ free_fragbuf ( fragbuf );
+ }
+}
+
+/**
* Fragment reassembler
*
* @v iobuf I/O buffer, fragment of the datagram
@@ -172,6 +190,9 @@ static struct io_buffer * ipv4_reassemble ( struct io_buffer * iobuf ) {
struct frag_buffer *fragbuf;
struct frag_buffer *fragtmp;
+ /* Remove expired fragment buffers */
+ ipv4_frag_cleanup();
+
/**
* Check if the fragment belongs to any fragment series
*/
@@ -228,6 +249,7 @@ static struct io_buffer * ipv4_reassemble ( struct io_buffer * iobuf ) {
/** Create a new fragment buffer */
fragbuf = ( struct frag_buffer* ) malloc ( sizeof( *fragbuf ) );
+ fragbuf->frag_flags = 0;
fragbuf->ident = iphdr->ident;
fragbuf->src = iphdr->src;
--
1.7.7
|