* 2 of the License, or (at your option) any later version.
*/
-#define VERSION "0.323"
+#define VERSION "0.324"
#include <linux/config.h>
#include <asm/uaccess.h>
static struct leaf_info *leaf_info_new(int plen)
{
struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL);
- li->plen = plen;
- INIT_LIST_HEAD(&li->falh);
+ if(li) {
+ li->plen = plen;
+ INIT_LIST_HEAD(&li->falh);
+ }
return li;
}
return (struct node*) tn;
}
-static struct list_head *
-fib_insert_node(struct trie *t, u32 key, int plen)
+static struct list_head *
+fib_insert_node(struct trie *t, int *err, u32 key, int plen)
{
int pos, newpos;
struct tnode *tp = NULL, *tn = NULL;
if(tp && IS_LEAF(tp))
BUG();
- t->revision++;
/* Case 1: n is a leaf. Compare prefixes */
li = leaf_info_new(plen);
- if(! li)
- BUG();
+ if(! li) {
+ *err = -ENOMEM;
+ goto err;
+ }
fa_head = &li->falh;
insert_leaf_info(&l->list, li);
t->size++;
l = leaf_new();
- if(! l)
- BUG();
+ if(! l) {
+ *err = -ENOMEM;
+ goto err;
+ }
l->key = key;
li = leaf_info_new(plen);
- if(! li)
- BUG();
+ if(! li) {
+ tnode_free((struct tnode *) l);
+ *err = -ENOMEM;
+ goto err;
+ }
fa_head = &li->falh;
insert_leaf_info(&l->list, li);
newpos = 0;
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);
missbit=tkey_extract_bits(key, newpos, 1);
}
/* Rebalance the trie */
t->trie = trie_rebalance(t, tp);
-done:;
+done:
+ t->revision++;
+err:;
return fa_head;
}
* Insert new entry to the list.
*/
- if(!fa_head)
- fa_head = fib_insert_node(t, key, plen);
+ if(!fa_head) {
+ fa_head = fib_insert_node(t, &err, key, plen);
+ err = 0;
+ if(err)
+ goto out_free_new_fa;
+ }
write_lock_bh(&fib_lock);
rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req);
succeeded:
return 0;
+
+out_free_new_fa:
+ kmem_cache_free(fn_alias_kmem, new_fa);
out:
fib_release_info(fi);
err:;