Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f835e471 authored by Robert Olsson's avatar Robert Olsson Committed by David S. Miller
Browse files

[IPV4]: Broken memory allocation in fib_trie



This should help up the insertion... but the resize is more crucial.
and complex and needs some thinking. 

Signed-off-by: default avatarRobert Olsson <robert.olsson@its.uu.se>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2f85a429
Loading
Loading
Loading
Loading
+39 −17
Original line number Original line Diff line number Diff line
@@ -43,7 +43,7 @@
 *		2 of the License, or (at your option) any later version.
 *		2 of the License, or (at your option) any later version.
 */
 */


#define VERSION "0.323"
#define VERSION "0.324"


#include <linux/config.h>
#include <linux/config.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
@@ -341,8 +341,10 @@ static struct leaf *leaf_new(void)
static struct leaf_info *leaf_info_new(int plen)
static struct leaf_info *leaf_info_new(int plen)
{
{
	struct leaf_info *li = kmalloc(sizeof(struct leaf_info),  GFP_KERNEL);
	struct leaf_info *li = kmalloc(sizeof(struct leaf_info),  GFP_KERNEL);
	if(li) {
		li->plen = plen;
		li->plen = plen;
		INIT_LIST_HEAD(&li->falh);
		INIT_LIST_HEAD(&li->falh);
	}
	return li;
	return li;
}
}


@@ -880,7 +882,7 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
}
}


static  struct list_head *
static  struct list_head *
fib_insert_node(struct trie *t, u32 key, int plen)
fib_insert_node(struct trie *t, int *err, u32 key, int plen)
{
{
	int pos, newpos;
	int pos, newpos;
	struct tnode *tp = NULL, *tn = NULL;
	struct tnode *tp = NULL, *tn = NULL;
@@ -940,7 +942,6 @@ fib_insert_node(struct trie *t, u32 key, int plen)
	if(tp && IS_LEAF(tp))
	if(tp && IS_LEAF(tp))
		BUG();
		BUG();


	t->revision++;


	/* Case 1: n is a leaf. Compare prefixes */
	/* Case 1: n is a leaf. Compare prefixes */


@@ -949,8 +950,10 @@ fib_insert_node(struct trie *t, u32 key, int plen)
		
		
		li = leaf_info_new(plen);
		li = leaf_info_new(plen);
		
		
		if(! li) 
		if(! li) {
			BUG();
			*err = -ENOMEM;
			goto err;
		}


		fa_head = &li->falh;
		fa_head = &li->falh;
		insert_leaf_info(&l->list, li);
		insert_leaf_info(&l->list, li);
@@ -959,14 +962,19 @@ fib_insert_node(struct trie *t, u32 key, int plen)
	t->size++;
	t->size++;
	l = leaf_new();
	l = leaf_new();


	if(! l) 
	if(! l) {
		BUG();
		*err = -ENOMEM;
		goto err;
	}


	l->key = key;
	l->key = key;
	li = leaf_info_new(plen);
	li = leaf_info_new(plen);


	if(! li) 
	if(! li) {
		BUG();
		tnode_free((struct tnode *) l);
		*err = -ENOMEM;
		goto err;
	}


	fa_head = &li->falh;
	fa_head = &li->falh;
	insert_leaf_info(&l->list, li);
	insert_leaf_info(&l->list, li);
@@ -1003,8 +1011,13 @@ fib_insert_node(struct trie *t, u32 key, int plen)
			newpos = 0;
			newpos = 0;
			tn = tnode_new(key, newpos, 1); /* First tnode */ 
			tn = tnode_new(key, newpos, 1); /* First tnode */ 
		}
		}
		if(!tn) 

			trie_bug("tnode_pfx_new failed");
		if(!tn) {
			free_leaf_info(li);
			tnode_free((struct tnode *) l);
			*err = -ENOMEM;
			goto err;
		}			
			
			
		NODE_SET_PARENT(tn, tp);
		NODE_SET_PARENT(tn, tp);


@@ -1027,7 +1040,9 @@ fib_insert_node(struct trie *t, u32 key, int plen)
	}
	}
	/* Rebalance the trie */
	/* Rebalance the trie */
	t->trie = trie_rebalance(t, tp);
	t->trie = trie_rebalance(t, tp);
done:;
done:
	t->revision++;
err:;
	return fa_head;
	return fa_head;
}
}


@@ -1156,8 +1171,12 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
	 * Insert new entry to the list.
	 * Insert new entry to the list.
	 */
	 */


	if(!fa_head)
	if(!fa_head) {
		fa_head = fib_insert_node(t, key, plen);
		fa_head = fib_insert_node(t, &err, key, plen);
		err = 0;
		if(err) 
			goto out_free_new_fa;
	}


	write_lock_bh(&fib_lock);
	write_lock_bh(&fib_lock);


@@ -1170,6 +1189,9 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta,
	rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req);
	rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req);
succeeded:
succeeded:
	return 0;
	return 0;

out_free_new_fa:
	kmem_cache_free(fn_alias_kmem, new_fa);
out:
out:
	fib_release_info(fi);
	fib_release_info(fi);
err:;	
err:;