#ifndef AX25_KERNEL_H
#define AX25_KERNEL_H
-#define PF_AX25 AF_AX25
#define AX25_MTU 256
#define AX25_MAX_DIGIS 6 /* This is wrong, should be 8 */
#ifndef NETROM_KERNEL_H
#define NETROM_KERNEL_H
-#define PF_NETROM AF_NETROM
#define NETROM_MTU 236
#define NETROM_T1 1
* Alan Cox : Support for TCP parameters.
* Alexey Kuznetsov: Major changes for new routing code.
* Elliot Poger : Added support for SO_BINDTODEVICE.
+ * Wolfgang Walter,
+ * Daniel Ryde,
+ * Ingo Molinar : fixed bug in ip_rt_put introduced
+ * by SO_BINDTODEVICE support causing
+ * a memory leak
*
* FIXME:
* Make atomic ops more generic and hide them in asm/...
extern atomic_t ip_rt_lock;
extern unsigned ip_rt_bh_mask;
extern struct rtable *ip_rt_hash_table[RT_HASH_DIVISOR];
+extern void rt_free(struct rtable * rt);
extern __inline__ void ip_rt_fast_lock(void)
{
{
if (rt)
atomic_dec(&rt->rt_refcnt);
+
+ /* If this rtable entry is not in the cache, we'd better free it once the
+ * refcnt goes to zero, because nobody else will... */
+ if ( rt && (rt->rt_flags & RTF_NOTCACHED) && (!rt->rt_refcnt) )
+ rt_free(rt);
}
#else
;
* use output device for accounting.
* Jos Vos : Call forward firewall after routing
* (always use output device).
+ * Philip Gladstone: Add some missing ip_rt_put()
*/
#include <linux/config.h>
struct device *dev2; /* Output device */
struct iphdr *iph; /* Our header */
struct sk_buff *skb2; /* Output packet */
- struct rtable *rt; /* Route we use */
+ struct rtable *rt = NULL; /* Route we use */
unsigned char *ptr; /* Data pointer */
unsigned long raddr; /* Router IP address */
struct options * opt = (struct options*)skb->proto_priv;
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
/* fall thru */
default:
+ if (rt)
+ ip_rt_put(rt);
return -1;
}
icmp_send(skb2, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
if (skb != skb2)
kfree_skb(skb2,FREE_WRITE);
+ if (rt)
+ ip_rt_put(rt);
return -1;
}
#endif
* Elliot Poger : Added support for SO_BINDTODEVICE.
* Andi Kleen : Don't send multicast addresses to
* kerneld.
+ * Wolfgang Walter : make rt_free() non-static
*
* Juan Jose Ciarlante : Added ip_rt_dev
* This program is free software; you can redistribute it and/or
}
-static void rt_free(struct rtable * rt)
+void rt_free(struct rtable * rt)
{
unsigned long flags;
* Elliot Poger : Added support for SO_BINDTODEVICE.
* Willy Konynenberg : Transparent proxy adapted to new
* socket hash code.
+ * Philip Gladstone: Added missing ip_rt_put
*
*
* This program is free software; you can redistribute it and/or
sk->daddr = usin->sin_addr.s_addr;
sk->dummy_th.dest = usin->sin_port;
sk->state = TCP_ESTABLISHED;
+ if (sk->ip_route_cache)
+ ip_rt_put(sk->ip_route_cache);
sk->ip_route_cache = rt;
return(0);
}
* Copyright (C) Barak A. Pearlmutter.
* Released under the GPL version 2 or later.
*
+ * 12/3/97 -- Flood
+ * Internal stack is only allocated one page. On systems with NR_FILE
+ * > 1024, this makes it quite easy for a user-space program to open
+ * a large number of AF_UNIX domain sockets, causing the garbage
+ * collection routines to run up against the wall (and panic).
+ * Changed the MAX_STACK to be associated to the system-wide open file
+ * maximum, and use vmalloc() instead of get_free_page() [as more than
+ * one page may be necessary]. As noted below, this should ideally be
+ * done with a linked list.
+ *
* Chopped about by Alan Cox 22/3/96 to make it fit the AF_UNIX socket problem.
* If it doesn't work blame me, it worked when Barak sent it.
*
/* Internal data structures and random procedures: */
-#define MAX_STACK 1000 /* Maximum depth of tree (about 1 page) */
static unix_socket **stack; /* stack of objects to mark */
static int in_stack = 0; /* first free entry in stack */
-
+static int max_stack; /* Calculated in unix_gc() */
extern inline unix_socket *unix_get_socket(struct file *filp)
{
extern inline void push_stack(unix_socket *x)
{
- if (in_stack == MAX_STACK)
+ if (in_stack == max_stack)
panic("can't push onto full stack");
stack[in_stack++] = x;
}
if(in_unix_gc)
return;
in_unix_gc=1;
-
- stack=(unix_socket **)get_free_page(GFP_KERNEL);
+
+ max_stack = max_files;
+
+ stack=(unix_socket **)vmalloc(max_stack * sizeof(unix_socket **));
+ if (!stack) {
+ in_unix_gc=0;
+ return;
+ }
/*
* Assume everything is now unmarked
in_unix_gc=0;
- free_page((long)stack);
+ vfree(stack);
}