119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson/*
219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *   This program is free software; you can redistribute it and/or
319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *   modify it under the terms of the GNU General Public License
419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *   as published by the Free Software Foundation; either version
519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *   2 of the License, or (at your option) any later version.
619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *   Robert Olsson <robert.olsson@its.uu.se> Uppsala Universitet
819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *     & Swedish University of Agricultural Sciences.
919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
10e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki *   Jens Laas <jens.laas@data.slu.se> Swedish University of
1119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *     Agricultural Sciences.
12e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki *
1319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *   Hans Liss <hans.liss@its.uu.se>  Uppsala Universitet
1419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
1525985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * This work is based on the LPC-trie which is originally described in:
16e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki *
1719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * An experimental study of compression methods for dynamic tries
1819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * Stefan Nilsson and Matti Tikkanen. Algorithmica, 33(1):19-33, 2002.
19631dd1a885b6d7e9f6f51b4e5b311c2bb04c323cJustin P. Mattock * http://www.csc.kth.se/~snilsson/software/dyntrie2/
2019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
2119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
2219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * IP-address lookup using LC-tries. Stefan Nilsson and Gunnar Karlsson
2319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * IEEE Journal on Selected Areas in Communications, 17(6):1083-1092, June 1999
2419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
2519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
2619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * Code from fib_hash has been reused which includes the following header:
2719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
2819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
2919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * INET		An implementation of the TCP/IP protocol suite for the LINUX
3019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *		operating system.  INET is implemented using the  BSD Socket
3119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *		interface as the means of communication with the user level.
3219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
3319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *		IPv4 FIB: lookup engine and maintenance routines.
3419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
3519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
3619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
3719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *
3819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *		This program is free software; you can redistribute it and/or
3919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *		modify it under the terms of the GNU General Public License
4019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *		as published by the Free Software Foundation; either version
4119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson *		2 of the License, or (at your option) any later version.
42fd9662555cc35f8bf9242cd7bba8b44ae168a68bRobert Olsson *
43fd9662555cc35f8bf9242cd7bba8b44ae168a68bRobert Olsson * Substantial contributions to this work comes from:
44fd9662555cc35f8bf9242cd7bba8b44ae168a68bRobert Olsson *
45fd9662555cc35f8bf9242cd7bba8b44ae168a68bRobert Olsson *		David S. Miller, <davem@davemloft.net>
46fd9662555cc35f8bf9242cd7bba8b44ae168a68bRobert Olsson *		Stephen Hemminger <shemminger@osdl.org>
47fd9662555cc35f8bf9242cd7bba8b44ae168a68bRobert Olsson *		Paul E. McKenney <paulmck@us.ibm.com>
48fd9662555cc35f8bf9242cd7bba8b44ae168a68bRobert Olsson *		Patrick McHardy <kaber@trash.net>
4919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson */
5019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
5180b71b80df14d885f7e50e115c1348398f418759Jens Låås#define VERSION "0.409"
5219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
5319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <asm/uaccess.h>
541977f032722c27ee3730284582fd3991ad9ac81bJiri Slaby#include <linux/bitops.h>
5519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/types.h>
5619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/kernel.h>
5719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/mm.h>
5819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/string.h>
5919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/socket.h>
6019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/sockios.h>
6119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/errno.h>
6219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/in.h>
6319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/inet.h>
64cd8787ab04d23f925f440b712b43a6fd5cb31eceStephen Hemminger#include <linux/inetdevice.h>
6519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/netdevice.h>
6619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/if_arp.h>
6719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/proc_fs.h>
682373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson#include <linux/rcupdate.h>
6919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/skbuff.h>
7019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/netlink.h>
7119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/init.h>
7219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <linux/list.h>
735a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
74bc3b2d7fb9b014d75ebb79ba371a763dbab5e8cfPaul Gortmaker#include <linux/export.h>
75457c4cbc5a3dde259d2a1f15d5f9785290397267Eric W. Biederman#include <net/net_namespace.h>
7619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <net/ip.h>
7719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <net/protocol.h>
7819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <net/route.h>
7919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <net/tcp.h>
8019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <net/sock.h>
8119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include <net/ip_fib.h>
8219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#include "fib_lookup.h"
8319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
8406ef921d60bbf6f765d1b9492fb4fc88ac7814bdRobert Olsson#define MAX_STAT_DEPTH 32
8519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
8619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#define KEYLENGTH (8*sizeof(t_key))
8719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
8819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssontypedef unsigned int t_key;
8919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
9019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#define T_TNODE 0
9119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#define T_LEAF  1
9219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#define NODE_TYPE_MASK	0x1UL
932373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson#define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK)
942373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
9591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson#define IS_TNODE(n) (!(n->parent & T_LEAF))
9691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson#define IS_LEAF(n) (n->parent & T_LEAF)
9719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
98b299e4f001cfa16205f9121f4630970049652268David S. Millerstruct rt_trie_node {
9991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	unsigned long parent;
1008d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazet	t_key key;
10119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
10219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
10319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstruct leaf {
10491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	unsigned long parent;
1058d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazet	t_key key;
10619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct hlist_head list;
1072373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	struct rcu_head rcu;
10819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
10919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
11019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstruct leaf_info {
11119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct hlist_node hlist;
11219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int plen;
1135c74501f76360ce6f410730b9b5e5976f38e8504Eric Dumazet	u32 mask_plen; /* ntohl(inet_make_mask(plen)) */
11419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct list_head falh;
1155c74501f76360ce6f410730b9b5e5976f38e8504Eric Dumazet	struct rcu_head rcu;
11619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
11719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
11819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstruct tnode {
11991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	unsigned long parent;
1208d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazet	t_key key;
121112d8cfcbf4f5ef0cf669cb5864f1206972076d6Eric Dumazet	unsigned char pos;		/* 2log(KEYLENGTH) bits needed */
122112d8cfcbf4f5ef0cf669cb5864f1206972076d6Eric Dumazet	unsigned char bits;		/* 2log(KEYLENGTH) bits needed */
1238d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazet	unsigned int full_children;	/* KEYLENGTH bits needed */
1248d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazet	unsigned int empty_children;	/* KEYLENGTH bits needed */
12515be75cdb5db442d0e33d37b20832b88f3ccd383Stephen Hemminger	union {
12615be75cdb5db442d0e33d37b20832b88f3ccd383Stephen Hemminger		struct rcu_head rcu;
127e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski		struct tnode *tnode_free;
12815be75cdb5db442d0e33d37b20832b88f3ccd383Stephen Hemminger	};
1290a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	struct rt_trie_node __rcu *child[0];
13019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
13119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
13219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
13319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstruct trie_use_stats {
13419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int gets;
13519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int backtrack;
13619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int semantic_match_passed;
13719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int semantic_match_miss;
13819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int null_node_hit;
1392f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	unsigned int resize_node_skipped;
14019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
14119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#endif
14219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
14319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstruct trie_stat {
14419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int totdepth;
14519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int maxdepth;
14619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int tnodes;
14719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int leaves;
14819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	unsigned int nullpointers;
149936722922f6d2366378de606a40c14f96915474dStephen Hemminger	unsigned int prefixes;
15006ef921d60bbf6f765d1b9492fb4fc88ac7814bdRobert Olsson	unsigned int nodesizes[MAX_STAT_DEPTH];
151c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger};
15219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
15319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstruct trie {
1540a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	struct rt_trie_node __rcu *trie;
15519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
15619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct trie_use_stats stats;
15719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#endif
15819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
15919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
160b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n,
161a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger				  int wasfull);
162b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic struct rt_trie_node *resize(struct trie *t, struct tnode *tn);
1632f80b3c8262d0d646812f776db024d88d569a0c1Robert Olssonstatic struct tnode *inflate(struct trie *t, struct tnode *tn);
1642f80b3c8262d0d646812f776db024d88d569a0c1Robert Olssonstatic struct tnode *halve(struct trie *t, struct tnode *tn);
165e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski/* tnodes to free after resize(); protected by RTNL */
166e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawskistatic struct tnode *tnode_free_head;
167c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawskistatic size_t tnode_free_size;
168c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski
169c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski/*
170c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski * synchronize_rcu after call_rcu for that many pages; it should be especially
171c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski * useful before resizing the root node with PREEMPT_NONE configs; the value was
172c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski * obtained experimentally, aiming to avoid visible slowdown.
173c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski */
174c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawskistatic const int sync_pages = 128;
17519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
176e18b890bb0881bbab6f4f1a6cd20d9c60d66b003Christoph Lameterstatic struct kmem_cache *fn_alias_kmem __read_mostly;
177bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemmingerstatic struct kmem_cache *trie_leaf_kmem __read_mostly;
17819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1790a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet/*
1800a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet * caller must hold RTNL
1810a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet */
1820a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazetstatic inline struct tnode *node_parent(const struct rt_trie_node *node)
1830680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger{
1840a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	unsigned long parent;
1850a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet
1860a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	parent = rcu_dereference_index_check(node->parent, lockdep_rtnl_is_held());
1870a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet
1880a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	return (struct tnode *)(parent & ~NODE_TYPE_MASK);
189b59cfbf77dc8368c2c90b012c79553613f4d70c3Eric Dumazet}
190b59cfbf77dc8368c2c90b012c79553613f4d70c3Eric Dumazet
1910a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet/*
1920a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet * caller must hold RCU read lock or RTNL
1930a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet */
1940a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazetstatic inline struct tnode *node_parent_rcu(const struct rt_trie_node *node)
195b59cfbf77dc8368c2c90b012c79553613f4d70c3Eric Dumazet{
1960a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	unsigned long parent;
1970a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet
1980a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	parent = rcu_dereference_index_check(node->parent, rcu_read_lock_held() ||
1990a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet							   lockdep_rtnl_is_held());
2000680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger
2010a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	return (struct tnode *)(parent & ~NODE_TYPE_MASK);
2020680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger}
2030680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger
204cf778b00e96df6d64f8e21b8395d1f8a859ecdc7Eric Dumazet/* Same as rcu_assign_pointer
2056440cc9e0f48ade57af7be28008cbfa6a991f287Stephen Hemminger * but that macro() assumes that value is a pointer.
2066440cc9e0f48ade57af7be28008cbfa6a991f287Stephen Hemminger */
207b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic inline void node_set_parent(struct rt_trie_node *node, struct tnode *ptr)
2080680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger{
2096440cc9e0f48ade57af7be28008cbfa6a991f287Stephen Hemminger	smp_wmb();
2106440cc9e0f48ade57af7be28008cbfa6a991f287Stephen Hemminger	node->parent = (unsigned long)ptr | NODE_TYPE(node);
2110680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger}
2122373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
2130a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet/*
2140a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet * caller must hold RTNL
2150a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet */
2160a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazetstatic inline struct rt_trie_node *tnode_get_child(const struct tnode *tn, unsigned int i)
217b59cfbf77dc8368c2c90b012c79553613f4d70c3Eric Dumazet{
218b59cfbf77dc8368c2c90b012c79553613f4d70c3Eric Dumazet	BUG_ON(i >= 1U << tn->bits);
2192373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
2200a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	return rtnl_dereference(tn->child[i]);
221b59cfbf77dc8368c2c90b012c79553613f4d70c3Eric Dumazet}
222b59cfbf77dc8368c2c90b012c79553613f4d70c3Eric Dumazet
2230a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet/*
2240a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet * caller must hold RCU read lock or RTNL
2250a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet */
2260a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazetstatic inline struct rt_trie_node *tnode_get_child_rcu(const struct tnode *tn, unsigned int i)
22719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2280a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	BUG_ON(i >= 1U << tn->bits);
22919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2300a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	return rcu_dereference_rtnl(tn->child[i]);
23119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
23219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
233bb435b8d816582064ee0ddb1e2a6fbca67f34108Stephen Hemmingerstatic inline int tnode_child_length(const struct tnode *tn)
23419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
23591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	return 1 << tn->bits;
23619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
23719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2383b004569d86d02786ebae496e75dc0b625be3e9aDavid S. Millerstatic inline t_key mask_pfx(t_key k, unsigned int l)
239ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger{
240ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger	return (l == 0) ? 0 : k >> (KEYLENGTH-l) << (KEYLENGTH-l);
241ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger}
242ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger
2433b004569d86d02786ebae496e75dc0b625be3e9aDavid S. Millerstatic inline t_key tkey_extract_bits(t_key a, unsigned int offset, unsigned int bits)
24419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
24591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (offset < KEYLENGTH)
24619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return ((t_key)(a << offset)) >> (KEYLENGTH - bits);
24791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	else
24819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return 0;
24919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
25019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
25119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstatic inline int tkey_equals(t_key a, t_key b)
25219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
253c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	return a == b;
25419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
25519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
25619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstatic inline int tkey_sub_equals(t_key a, int offset, int bits, t_key b)
25719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
258c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (bits == 0 || offset >= KEYLENGTH)
259c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		return 1;
26091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	bits = bits > KEYLENGTH ? KEYLENGTH : bits;
26191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	return ((a ^ b) << offset) >> (KEYLENGTH - bits) == 0;
262c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger}
26319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
26419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstatic inline int tkey_mismatch(t_key a, int offset, t_key b)
26519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
26619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	t_key diff = a ^ b;
26719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int i = offset;
26819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
269c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (!diff)
270c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		return 0;
271c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	while ((diff << i) >> (KEYLENGTH-1) == 0)
27219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		i++;
27319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return i;
27419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
27519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
27619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson/*
277e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  To understand this stuff, an understanding of keys and all their bits is
278e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  necessary. Every node in the trie has a key associated with it, but not
27919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  all of the bits in that key are significant.
28019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
28119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  Consider a node 'n' and its parent 'tp'.
28219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
283e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  If n is a leaf, every bit in its key is significant. Its presence is
284e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  necessitated by path compression, since during a tree traversal (when
285e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  searching for a leaf - unless we are doing an insertion) we will completely
286e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  ignore all skipped bits we encounter. Thus we need to verify, at the end of
287e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  a potentially successful search, that we have indeed been walking the
28819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  correct key path.
28919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
290e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  Note that we can never "miss" the correct key in the tree if present by
291e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  following the wrong path. Path compression ensures that segments of the key
292e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  that are the same for all keys with a given prefix are skipped, but the
293e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  skipped part *is* identical for each node in the subtrie below the skipped
294e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  bit! trie_insert() in this implementation takes care of that - note the
29519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  call to tkey_sub_equals() in trie_insert().
29619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
297e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  if n is an internal node - a 'tnode' here, the various parts of its key
29819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  have many different meanings.
29919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
300e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  Example:
30119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  _________________________________________________________________
30219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  | i | i | i | i | i | i | i | N | N | N | S | S | S | S | S | C |
30319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  -----------------------------------------------------------------
304e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15
30519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
30619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  _________________________________________________________________
30719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  | C | C | C | u | u | u | u | u | u | u | u | u | u | u | u | u |
30819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  -----------------------------------------------------------------
30919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson   16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31
31019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
31119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  tp->pos = 7
31219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  tp->bits = 3
31319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  n->pos = 15
31491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson  n->bits = 4
31519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
316e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  First, let's just ignore the bits that come before the parent tp, that is
317e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  the bits from 0 to (tp->pos-1). They are *known* but at this point we do
31819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  not use them for anything.
31919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
32019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  The bits from (tp->pos) to (tp->pos + tp->bits - 1) - "N", above - are the
321e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  index into the parent's child array. That is, they will be used to find
32219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  'n' among tp's children.
32319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
32419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  The bits from (tp->pos + tp->bits) to (n->pos - 1) - "S" - are skipped bits
32519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  for the node n.
32619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
327e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  All the bits we have seen so far are significant to the node n. The rest
32819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  of the bits are really not needed or indeed known in n->key.
32919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
330e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki  The bits from (n->pos) to (n->pos + n->bits - 1) - "C" - are the index into
33119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  n's child array, and will of course be different for each child.
332e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki
333c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
33419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  The rest of the bits, from (n->pos + n->bits) onward, are completely unknown
33519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  at this point.
33619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
33719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson*/
33819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
3390c7770c740156c8802c23d24fc094d06967d997dStephen Hemmingerstatic inline void check_tnode(const struct tnode *tn)
34019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
3410c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	WARN_ON(tn && tn->pos+tn->bits > 32);
34219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
34319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
344f5026fabda54e5ab5d469d8cfac5f46b4d321ce9Denis V. Lunevstatic const int halve_threshold = 25;
345f5026fabda54e5ab5d469d8cfac5f46b4d321ce9Denis V. Lunevstatic const int inflate_threshold = 50;
346345aa031207d02d7438c1aa96ed9315911ecd745Jarek Poplawskistatic const int halve_threshold_root = 15;
34780b71b80df14d885f7e50e115c1348398f418759Jens Lååsstatic const int inflate_threshold_root = 30;
3482373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
3492373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic void __alias_free_mem(struct rcu_head *head)
35019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
3512373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	struct fib_alias *fa = container_of(head, struct fib_alias, rcu);
3522373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	kmem_cache_free(fn_alias_kmem, fa);
35319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
35419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
3552373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic inline void alias_free_mem_rcu(struct fib_alias *fa)
35619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
3572373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	call_rcu(&fa->rcu, __alias_free_mem);
3582373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson}
35991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
3602373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic void __leaf_free_rcu(struct rcu_head *head)
3612373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson{
362bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger	struct leaf *l = container_of(head, struct leaf, rcu);
363bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger	kmem_cache_free(trie_leaf_kmem, l);
3642373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson}
36591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
366387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemmingerstatic inline void free_leaf(struct leaf *l)
367387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger{
3680c03eca3d995e73d691edea8c787e25929ec156dEric Dumazet	call_rcu(&l->rcu, __leaf_free_rcu);
369387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger}
370387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger
3712373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic inline void free_leaf_info(struct leaf_info *leaf)
37219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
373bceb0f4512d448763fe98c9f37504c98bbebbed6Lai Jiangshan	kfree_rcu(leaf, rcu);
37419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
37519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
3768d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazetstatic struct tnode *tnode_alloc(size_t size)
377f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy{
3782373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	if (size <= PAGE_SIZE)
3798d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazet		return kzalloc(size, GFP_KERNEL);
38015be75cdb5db442d0e33d37b20832b88f3ccd383Stephen Hemminger	else
3817a1c8e5ab120a5f352e78bbc1fa5bb64e6f23639Eric Dumazet		return vzalloc(size);
38215be75cdb5db442d0e33d37b20832b88f3ccd383Stephen Hemminger}
3832373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
3842373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic void __tnode_free_rcu(struct rcu_head *head)
385f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy{
3862373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	struct tnode *tn = container_of(head, struct tnode, rcu);
3878d96544475b236a0f319e492f4828aa8c0801c7fEric Dumazet	size_t size = sizeof(struct tnode) +
388b299e4f001cfa16205f9121f4630970049652268David S. Miller		      (sizeof(struct rt_trie_node *) << tn->bits);
389f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy
390f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy	if (size <= PAGE_SIZE)
391f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy		kfree(tn);
3920020356355192cbaf6d315515e6c95bd09618c3bAl Viro	else
3930020356355192cbaf6d315515e6c95bd09618c3bAl Viro		vfree(tn);
394f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy}
395f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy
3962373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic inline void tnode_free(struct tnode *tn)
3972373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson{
398387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger	if (IS_LEAF(tn))
399387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger		free_leaf((struct leaf *) tn);
400387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger	else
401550e29bc96e6f1ced2bca82dace197b009434367Robert Olsson		call_rcu(&tn->rcu, __tnode_free_rcu);
4022373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson}
4032373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
404e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawskistatic void tnode_free_safe(struct tnode *tn)
405e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski{
406e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski	BUG_ON(IS_LEAF(tn));
4077b85576d15bf2574b0a451108f59f9ad4170dd3fJarek Poplawski	tn->tnode_free = tnode_free_head;
4087b85576d15bf2574b0a451108f59f9ad4170dd3fJarek Poplawski	tnode_free_head = tn;
409c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski	tnode_free_size += sizeof(struct tnode) +
410b299e4f001cfa16205f9121f4630970049652268David S. Miller			   (sizeof(struct rt_trie_node *) << tn->bits);
411e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski}
412e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski
413e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawskistatic void tnode_free_flush(void)
414e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski{
415e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski	struct tnode *tn;
416e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski
417e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski	while ((tn = tnode_free_head)) {
418e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski		tnode_free_head = tn->tnode_free;
419e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski		tn->tnode_free = NULL;
420e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski		tnode_free(tn);
421e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski	}
422c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski
423c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski	if (tnode_free_size >= PAGE_SIZE * sync_pages) {
424c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski		tnode_free_size = 0;
425c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski		synchronize_rcu();
426c3059477fce2d956a0bb3e04357324780c5d8eebJarek Poplawski	}
427e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski}
428e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski
4292373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic struct leaf *leaf_new(void)
4302373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson{
431bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger	struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL);
4322373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	if (l) {
4332373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson		l->parent = T_LEAF;
4342373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson		INIT_HLIST_HEAD(&l->list);
4352373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	}
4362373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	return l;
4372373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson}
4382373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
4392373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olssonstatic struct leaf_info *leaf_info_new(int plen)
4402373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson{
4412373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	struct leaf_info *li = kmalloc(sizeof(struct leaf_info),  GFP_KERNEL);
4422373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	if (li) {
4432373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson		li->plen = plen;
4445c74501f76360ce6f410730b9b5e5976f38e8504Eric Dumazet		li->mask_plen = ntohl(inet_make_mask(plen));
4452373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson		INIT_LIST_HEAD(&li->falh);
4462373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	}
4472373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	return li;
4482373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson}
4492373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
450a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemmingerstatic struct tnode *tnode_new(t_key key, int pos, int bits)
45119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
452b299e4f001cfa16205f9121f4630970049652268David S. Miller	size_t sz = sizeof(struct tnode) + (sizeof(struct rt_trie_node *) << bits);
453f0e36f8cee8101604378085171c980d9cc71d779Patrick McHardy	struct tnode *tn = tnode_alloc(sz);
45419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
45591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (tn) {
4562373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson		tn->parent = T_TNODE;
45719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->pos = pos;
45819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->bits = bits;
45919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->key = key;
46019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->full_children = 0;
46119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->empty_children = 1<<bits;
46219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
463c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
464a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	pr_debug("AT %p s=%zu %zu\n", tn, sizeof(struct tnode),
4654ea4bf7ebcbacee2f4736d261efb0693e87a34c9Lin Ming		 sizeof(struct rt_trie_node *) << bits);
46619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return tn;
46719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
46819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
46919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson/*
47019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * Check whether a tnode 'n' is "full", i.e. it is an internal node
47119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson * and no bits are skipped. See discussion in dyntree paper p. 6
47219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson */
47319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
474b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic inline int tnode_full(const struct tnode *tn, const struct rt_trie_node *n)
47519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
476c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (n == NULL || IS_LEAF(n))
47719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return 0;
47819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
47919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return ((struct tnode *) n)->pos == tn->pos + tn->bits;
48019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
48119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
48261648d91fc278fd1d500da8061d17e6920cd3500Lin Mingstatic inline void put_child(struct tnode *tn, int i,
483b299e4f001cfa16205f9121f4630970049652268David S. Miller			     struct rt_trie_node *n)
48419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
48519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	tnode_put_child_reorg(tn, i, n, -1);
48619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
48719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
488c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger /*
48919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  * Add a child at position i overwriting the old value.
49019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  * Update the value of full_children and empty_children.
49119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson  */
49219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
493b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic void tnode_put_child_reorg(struct tnode *tn, int i, struct rt_trie_node *n,
494a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger				  int wasfull)
49519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
4960a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	struct rt_trie_node *chi = rtnl_dereference(tn->child[i]);
49719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int isfull;
49819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
4990c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	BUG_ON(i >= 1<<tn->bits);
5000c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger
50119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* update emptyChildren */
50219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (n == NULL && chi != NULL)
50319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->empty_children++;
50419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	else if (n != NULL && chi == NULL)
50519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->empty_children--;
506c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
50719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* update fullChildren */
50891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (wasfull == -1)
50919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		wasfull = tnode_full(tn, chi);
51019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
51119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	isfull = tnode_full(tn, n);
512c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (wasfull && !isfull)
51319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->full_children--;
514c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	else if (!wasfull && isfull)
51519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn->full_children++;
51691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
517c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (n)
5180680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger		node_set_parent(n, tn);
51919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
520cf778b00e96df6d64f8e21b8395d1f8a859ecdc7Eric Dumazet	rcu_assign_pointer(tn->child[i], n);
52119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
52219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
52380b71b80df14d885f7e50e115c1348398f418759Jens Låås#define MAX_WORK 10
524b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic struct rt_trie_node *resize(struct trie *t, struct tnode *tn)
52519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
52619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int i;
5272f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson	struct tnode *old_tn;
528e6308be85afee685347fa3440bed10faaa5d6c1aRobert Olsson	int inflate_threshold_use;
529e6308be85afee685347fa3440bed10faaa5d6c1aRobert Olsson	int halve_threshold_use;
53080b71b80df14d885f7e50e115c1348398f418759Jens Låås	int max_work;
53119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
532e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	if (!tn)
53319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return NULL;
53419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
5350c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	pr_debug("In tnode_resize %p inflate_threshold=%d threshold=%d\n",
5360c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger		 tn, inflate_threshold, halve_threshold);
53719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
53819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* No children */
53919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (tn->empty_children == tnode_child_length(tn)) {
540e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski		tnode_free_safe(tn);
54119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return NULL;
54219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
54319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* One child */
54419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (tn->empty_children == tnode_child_length(tn) - 1)
54580b71b80df14d885f7e50e115c1348398f418759Jens Låås		goto one_child;
546c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	/*
54719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * Double as long as the resulting node has a number of
54819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * nonempty nodes that are above the threshold.
54919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 */
55019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
55119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/*
552c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * From "Implementing a dynamic compressed trie" by Stefan Nilsson of
553c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * the Helsinki University of Technology and Matti Tikkanen of Nokia
55419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * Telecommunications, page 6:
555c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * "A node is doubled if the ratio of non-empty children to all
55619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * children in the *doubled* node is at least 'high'."
55719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
558c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * 'high' in this instance is the variable 'inflate_threshold'. It
559c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * is expressed as a percentage, so we multiply it with
560c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * tnode_child_length() and instead of multiplying by 2 (since the
561c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * child array will be doubled by inflate()) and multiplying
562c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * the left-hand side by 100 (to handle the percentage thing) we
56319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * multiply the left-hand side by 50.
564c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
565c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * The left-hand side may look a bit weird: tnode_child_length(tn)
566c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * - tn->empty_children is of course the number of non-null children
567c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * in the current node. tn->full_children is the number of "full"
56819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * children, that is non-null tnodes with a skip value of 0.
569c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * All of those will be doubled in the resulting inflated tnode, so
57019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * we just count them one extra time here.
571c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
57219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * A clearer way to write this would be:
573c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
57419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * to_be_doubled = tn->full_children;
575c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * not_to_be_doubled = tnode_child_length(tn) - tn->empty_children -
57619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *     tn->full_children;
57719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
57819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * new_child_length = tnode_child_length(tn) * 2;
57919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
580c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * new_fill_factor = 100 * (not_to_be_doubled + 2*to_be_doubled) /
58119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *      new_child_length;
58219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * if (new_fill_factor >= inflate_threshold)
583c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
584c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * ...and so on, tho it would mess up the while () loop.
585c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
58619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * anyway,
58719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * 100 * (not_to_be_doubled + 2*to_be_doubled) / new_child_length >=
58819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *      inflate_threshold
589c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
59019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * avoid a division:
59119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * 100 * (not_to_be_doubled + 2*to_be_doubled) >=
59219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *      inflate_threshold * new_child_length
593c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
59419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * expand not_to_be_doubled and to_be_doubled, and shorten:
595c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * 100 * (tnode_child_length(tn) - tn->empty_children +
59691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	 *    tn->full_children) >= inflate_threshold * new_child_length
597c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
59819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * expand new_child_length:
599c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * 100 * (tnode_child_length(tn) - tn->empty_children +
60091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	 *    tn->full_children) >=
60119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *      inflate_threshold * tnode_child_length(tn) * 2
602c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
60319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * shorten again:
604c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * 50 * (tn->full_children + tnode_child_length(tn) -
60591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	 *    tn->empty_children) >= inflate_threshold *
60619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *    tnode_child_length(tn)
607c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 *
60819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 */
60919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
61019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	check_tnode(tn);
611c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
612e6308be85afee685347fa3440bed10faaa5d6c1aRobert Olsson	/* Keep root node larger  */
613e6308be85afee685347fa3440bed10faaa5d6c1aRobert Olsson
614b299e4f001cfa16205f9121f4630970049652268David S. Miller	if (!node_parent((struct rt_trie_node *)tn)) {
61580b71b80df14d885f7e50e115c1348398f418759Jens Låås		inflate_threshold_use = inflate_threshold_root;
61680b71b80df14d885f7e50e115c1348398f418759Jens Låås		halve_threshold_use = halve_threshold_root;
617a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	} else {
618e6308be85afee685347fa3440bed10faaa5d6c1aRobert Olsson		inflate_threshold_use = inflate_threshold;
61980b71b80df14d885f7e50e115c1348398f418759Jens Låås		halve_threshold_use = halve_threshold;
62080b71b80df14d885f7e50e115c1348398f418759Jens Låås	}
621e6308be85afee685347fa3440bed10faaa5d6c1aRobert Olsson
62280b71b80df14d885f7e50e115c1348398f418759Jens Låås	max_work = MAX_WORK;
62380b71b80df14d885f7e50e115c1348398f418759Jens Låås	while ((tn->full_children > 0 &&  max_work-- &&
624a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		50 * (tn->full_children + tnode_child_length(tn)
625a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		      - tn->empty_children)
626a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		>= inflate_threshold_use * tnode_child_length(tn))) {
62719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
6282f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		old_tn = tn;
6292f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		tn = inflate(t, tn);
630a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
6312f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		if (IS_ERR(tn)) {
6322f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson			tn = old_tn;
6332f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
6342f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson			t->stats.resize_node_skipped++;
6352f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson#endif
6362f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson			break;
6372f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		}
63819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
63919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
64019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	check_tnode(tn);
64119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
64280b71b80df14d885f7e50e115c1348398f418759Jens Låås	/* Return if at least one inflate is run */
643a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	if (max_work != MAX_WORK)
644b299e4f001cfa16205f9121f4630970049652268David S. Miller		return (struct rt_trie_node *) tn;
64580b71b80df14d885f7e50e115c1348398f418759Jens Låås
64619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/*
64719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * Halve as long as the number of empty children in this
64819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * node is above threshold.
64919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 */
6502f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
65180b71b80df14d885f7e50e115c1348398f418759Jens Låås	max_work = MAX_WORK;
65280b71b80df14d885f7e50e115c1348398f418759Jens Låås	while (tn->bits > 1 &&  max_work-- &&
65319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	       100 * (tnode_child_length(tn) - tn->empty_children) <
654e6308be85afee685347fa3440bed10faaa5d6c1aRobert Olsson	       halve_threshold_use * tnode_child_length(tn)) {
6552f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
6562f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		old_tn = tn;
6572f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		tn = halve(t, tn);
6582f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		if (IS_ERR(tn)) {
6592f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson			tn = old_tn;
6602f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
6612f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson			t->stats.resize_node_skipped++;
6622f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson#endif
6632f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson			break;
6642f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		}
6652f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	}
66619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
667c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
66819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* Only one child remains */
66980b71b80df14d885f7e50e115c1348398f418759Jens Låås	if (tn->empty_children == tnode_child_length(tn) - 1) {
67080b71b80df14d885f7e50e115c1348398f418759Jens Lååsone_child:
67119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		for (i = 0; i < tnode_child_length(tn); i++) {
672b299e4f001cfa16205f9121f4630970049652268David S. Miller			struct rt_trie_node *n;
67319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
6740a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet			n = rtnl_dereference(tn->child[i]);
6752373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			if (!n)
67691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson				continue;
67791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
67891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			/* compress one level */
67991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
6800680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger			node_set_parent(n, NULL);
681e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski			tnode_free_safe(tn);
68291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			return n;
68319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
68480b71b80df14d885f7e50e115c1348398f418759Jens Låås	}
685b299e4f001cfa16205f9121f4630970049652268David S. Miller	return (struct rt_trie_node *) tn;
68619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
68719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
6880a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet
6890a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazetstatic void tnode_clean_free(struct tnode *tn)
6900a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet{
6910a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	int i;
6920a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	struct tnode *tofree;
6930a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet
6940a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	for (i = 0; i < tnode_child_length(tn); i++) {
6950a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet		tofree = (struct tnode *)rtnl_dereference(tn->child[i]);
6960a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet		if (tofree)
6970a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet			tnode_free(tofree);
6980a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	}
6990a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	tnode_free(tn);
7000a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet}
7010a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet
7022f80b3c8262d0d646812f776db024d88d569a0c1Robert Olssonstatic struct tnode *inflate(struct trie *t, struct tnode *tn)
70319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
70419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct tnode *oldtnode = tn;
70519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int olen = tnode_child_length(tn);
70619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int i;
70719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
7080c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	pr_debug("In inflate\n");
70919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
71019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1);
71119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
7120c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	if (!tn)
7132f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		return ERR_PTR(-ENOMEM);
7142f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
7152f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	/*
716c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * Preallocate and store tnodes before the actual work so we
717c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * don't get into an inconsistent state if memory allocation
718c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * fails. In case of failure we return the oldnode and  inflate
7192f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	 * of tnode is ignored.
7202f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	 */
72191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
72291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	for (i = 0; i < olen; i++) {
723a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		struct tnode *inode;
7242f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
725a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		inode = (struct tnode *) tnode_get_child(oldtnode, i);
7262f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		if (inode &&
7272f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		    IS_TNODE(inode) &&
7282f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		    inode->pos == oldtnode->pos + oldtnode->bits &&
7292f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		    inode->bits > 1) {
7302f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson			struct tnode *left, *right;
731ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger			t_key m = ~0U << (KEYLENGTH - 1) >> inode->pos;
732c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
7332f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson			left = tnode_new(inode->key&(~m), inode->pos + 1,
7342f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson					 inode->bits - 1);
7352f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson			if (!left)
7362f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson				goto nomem;
73791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
7382f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson			right = tnode_new(inode->key|m, inode->pos + 1,
7392f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson					  inode->bits - 1);
7402f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
741e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki			if (!right) {
7422f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson				tnode_free(left);
7432f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson				goto nomem;
744e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki			}
7452f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
74661648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tn, 2*i, (struct rt_trie_node *) left);
74761648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tn, 2*i+1, (struct rt_trie_node *) right);
7482f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		}
7492f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	}
7502f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
75191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	for (i = 0; i < olen; i++) {
752c95aaf9af5a1f6dee56d1f2ab4915cd722d608daStephen Hemminger		struct tnode *inode;
753b299e4f001cfa16205f9121f4630970049652268David S. Miller		struct rt_trie_node *node = tnode_get_child(oldtnode, i);
75491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		struct tnode *left, *right;
75591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		int size, j;
756c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
75719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* An empty child */
75819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (node == NULL)
75919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			continue;
76019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
76119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* A leaf or an internal node with skipped bits */
76219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
763c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (IS_LEAF(node) || ((struct tnode *) node)->pos >
76419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		   tn->pos + tn->bits - 1) {
765bbe34cf8a1a2cc174e6516fc230b91b531da7ddfbaker.zhang			put_child(tn,
766bbe34cf8a1a2cc174e6516fc230b91b531da7ddfbaker.zhang				tkey_extract_bits(node->key, oldtnode->pos, oldtnode->bits + 1),
767bbe34cf8a1a2cc174e6516fc230b91b531da7ddfbaker.zhang				node);
76819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			continue;
76919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
77019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
77119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* An internal node with two children */
77219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		inode = (struct tnode *) node;
77319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
77419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (inode->bits == 1) {
77561648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tn, 2*i, rtnl_dereference(inode->child[0]));
77661648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tn, 2*i+1, rtnl_dereference(inode->child[1]));
77719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
778e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski			tnode_free_safe(inode);
77991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			continue;
78019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
78119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
78291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/* An internal node with more than two children */
78391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
78491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/* We will replace this node 'inode' with two new
78591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * ones, 'left' and 'right', each with half of the
78691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * original children. The two new nodes will have
78791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * a position one bit further down the key and this
78891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * means that the "significant" part of their keys
78991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * (see the discussion near the top of this file)
79091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * will differ by one bit, which will be "0" in
79191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * left's key and "1" in right's key. Since we are
79291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * moving the key position by one step, the bit that
79391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * we are moving away from - the bit at position
79491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * (inode->pos) - is the one that will differ between
79591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * left and right. So... we synthesize that bit in the
79691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * two  new keys.
79791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * The mask 'm' below will be a single "one" bit at
79891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * the position (inode->pos)
79991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
80019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
80191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/* Use the old key, but set the new significant
80291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 *   bit to zero.
80391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
8042f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
80591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		left = (struct tnode *) tnode_get_child(tn, 2*i);
80661648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, 2*i, NULL);
8072f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
80891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		BUG_ON(!left);
8092f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
81091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		right = (struct tnode *) tnode_get_child(tn, 2*i+1);
81161648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, 2*i+1, NULL);
81219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
81391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		BUG_ON(!right);
81419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
81591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		size = tnode_child_length(left);
81691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		for (j = 0; j < size; j++) {
81761648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(left, j, rtnl_dereference(inode->child[j]));
81861648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(right, j, rtnl_dereference(inode->child[j + size]));
81919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
82061648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, 2*i, resize(t, left));
82161648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, 2*i+1, resize(t, right));
82291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
823e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski		tnode_free_safe(inode);
82419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
825e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski	tnode_free_safe(oldtnode);
82619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return tn;
8272f80b3c8262d0d646812f776db024d88d569a0c1Robert Olssonnomem:
8280a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	tnode_clean_free(tn);
8290a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	return ERR_PTR(-ENOMEM);
83019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
83119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
8322f80b3c8262d0d646812f776db024d88d569a0c1Robert Olssonstatic struct tnode *halve(struct trie *t, struct tnode *tn)
83319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
83419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct tnode *oldtnode = tn;
835b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *left, *right;
83619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int i;
83719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int olen = tnode_child_length(tn);
83819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
8390c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	pr_debug("In halve\n");
840c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
841c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1);
84219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
8432f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson	if (!tn)
8442f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson		return ERR_PTR(-ENOMEM);
8452f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
8462f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	/*
847c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * Preallocate and store tnodes before the actual work so we
848c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * don't get into an inconsistent state if memory allocation
849c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * fails. In case of failure we return the oldnode and halve
8502f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	 * of tnode is ignored.
8512f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	 */
8522f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
85391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	for (i = 0; i < olen; i += 2) {
8542f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		left = tnode_get_child(oldtnode, i);
8552f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		right = tnode_get_child(oldtnode, i+1);
856c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
8572f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		/* Two nonempty children */
8580c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger		if (left && right) {
8592f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson			struct tnode *newn;
8600c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger
8612f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson			newn = tnode_new(left->key, tn->pos + tn->bits, 1);
8620c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger
8630c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger			if (!newn)
8642f80b3c8262d0d646812f776db024d88d569a0c1Robert Olsson				goto nomem;
8650c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger
86661648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tn, i/2, (struct rt_trie_node *)newn);
8672f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson		}
8682f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson
8692f36895aa774cf4d1c3d68921e0209e796b66600Robert Olsson	}
87019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
87191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	for (i = 0; i < olen; i += 2) {
87291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		struct tnode *newBinNode;
87391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
87419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		left = tnode_get_child(oldtnode, i);
87519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		right = tnode_get_child(oldtnode, i+1);
876c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
87719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* At least one of the children is empty */
87819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (left == NULL) {
87919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			if (right == NULL)    /* Both are empty */
88019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				continue;
88161648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tn, i/2, right);
88291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			continue;
8830c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger		}
88491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
88591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		if (right == NULL) {
88661648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tn, i/2, left);
88791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			continue;
88891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		}
889c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
89019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* Two nonempty children */
89191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		newBinNode = (struct tnode *) tnode_get_child(tn, i/2);
89261648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, i/2, NULL);
89361648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(newBinNode, 0, left);
89461648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(newBinNode, 1, right);
89561648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, i/2, resize(t, newBinNode));
89619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
897e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski	tnode_free_safe(oldtnode);
89819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return tn;
8992f80b3c8262d0d646812f776db024d88d569a0c1Robert Olssonnomem:
9000a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	tnode_clean_free(tn);
9010a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	return ERR_PTR(-ENOMEM);
90219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
90319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
904772cb712b1373d335ef2874ea357ec681edc754bRobert Olsson/* readside must use rcu_read_lock currently dump routines
9052373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson via get_fa_head and dump */
9062373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
907772cb712b1373d335ef2874ea357ec681edc754bRobert Olssonstatic struct leaf_info *find_leaf_info(struct leaf *l, int plen)
90819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
909772cb712b1373d335ef2874ea357ec681edc754bRobert Olsson	struct hlist_head *head = &l->list;
91019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct leaf_info *li;
91119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
912b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin	hlist_for_each_entry_rcu(li, head, hlist)
913c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (li->plen == plen)
91419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			return li;
91591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
91619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return NULL;
91719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
91819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
919a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemmingerstatic inline struct list_head *get_fa_head(struct leaf *l, int plen)
92019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
921772cb712b1373d335ef2874ea357ec681edc754bRobert Olsson	struct leaf_info *li = find_leaf_info(l, plen);
922c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
92391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (!li)
92491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		return NULL;
925c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
92691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	return &li->falh;
92719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
92819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
92919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstatic void insert_leaf_info(struct hlist_head *head, struct leaf_info *new)
93019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
931e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	struct leaf_info *li = NULL, *last = NULL;
932e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki
933e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	if (hlist_empty(head)) {
934e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		hlist_add_head_rcu(&new->hlist, head);
935e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	} else {
936b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin		hlist_for_each_entry(li, head, hlist) {
937e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki			if (new->plen > li->plen)
938e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki				break;
939e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki
940e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki			last = li;
941e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		}
942e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		if (last)
9431d023284c31a4e40a94d5bbcb7dbb7a35ee0bcbcKen Helias			hlist_add_behind_rcu(&new->hlist, &last->hlist);
944e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki		else
945e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki			hlist_add_before_rcu(&new->hlist, &li->hlist);
946e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki	}
94719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
94819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
9492373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson/* rcu_read_lock needs to be hold by caller from readside */
9502373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
95119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonstatic struct leaf *
95219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonfib_find_node(struct trie *t, u32 key)
95319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
95419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int pos;
95519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct tnode *tn;
956b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *n;
95719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
95819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	pos = 0;
959a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	n = rcu_dereference_rtnl(t->trie);
96019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
96119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	while (n != NULL &&  NODE_TYPE(n) == T_TNODE) {
96219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn = (struct tnode *) n;
96391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
96419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		check_tnode(tn);
96591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
966c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
96791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			pos = tn->pos + tn->bits;
968a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger			n = tnode_get_child_rcu(tn,
969a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger						tkey_extract_bits(key,
970a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger								  tn->pos,
971a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger								  tn->bits));
97291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		} else
97319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			break;
97419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
97519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* Case we have found a leaf. Compare prefixes */
97619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
97791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key))
97891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		return (struct leaf *)n;
97991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
98019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return NULL;
98119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
98219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
9837b85576d15bf2574b0a451108f59f9ad4170dd3fJarek Poplawskistatic void trie_rebalance(struct trie *t, struct tnode *tn)
98419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
98519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int wasfull;
9863ed18d76d959e5cbfa5d70c8f7ba95476582a556Robert Olsson	t_key cindex, key;
9870680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger	struct tnode *tp;
98819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
9893ed18d76d959e5cbfa5d70c8f7ba95476582a556Robert Olsson	key = tn->key;
9903ed18d76d959e5cbfa5d70c8f7ba95476582a556Robert Olsson
991b299e4f001cfa16205f9121f4630970049652268David S. Miller	while (tn != NULL && (tp = node_parent((struct rt_trie_node *)tn)) != NULL) {
99219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		cindex = tkey_extract_bits(key, tp->pos, tp->bits);
99319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
994e3192690a3c889767d1161b228374f4926d92af0Joe Perches		tn = (struct tnode *)resize(t, tn);
995a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
996e3192690a3c889767d1161b228374f4926d92af0Joe Perches		tnode_put_child_reorg(tp, cindex,
997b299e4f001cfa16205f9121f4630970049652268David S. Miller				      (struct rt_trie_node *)tn, wasfull);
99891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
999b299e4f001cfa16205f9121f4630970049652268David S. Miller		tp = node_parent((struct rt_trie_node *) tn);
1000008440e3ad4b72f5048d1b1f6f5ed894fdc5ad08Jarek Poplawski		if (!tp)
1001cf778b00e96df6d64f8e21b8395d1f8a859ecdc7Eric Dumazet			rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
1002008440e3ad4b72f5048d1b1f6f5ed894fdc5ad08Jarek Poplawski
1003e0f7cb8c8cc6cccce28d2ce39ad8c60d23c3799fJarek Poplawski		tnode_free_flush();
10040680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger		if (!tp)
100519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			break;
10060680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger		tn = tp;
100719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
10080680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger
100919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* Handle last (top) tnode */
10107b85576d15bf2574b0a451108f59f9ad4170dd3fJarek Poplawski	if (IS_TNODE(tn))
1011e3192690a3c889767d1161b228374f4926d92af0Joe Perches		tn = (struct tnode *)resize(t, tn);
101219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1013cf778b00e96df6d64f8e21b8395d1f8a859ecdc7Eric Dumazet	rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
10147b85576d15bf2574b0a451108f59f9ad4170dd3fJarek Poplawski	tnode_free_flush();
101519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
101619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
10172373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson/* only used from updater-side */
10182373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
1019fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemmingerstatic struct list_head *fib_insert_node(struct trie *t, u32 key, int plen)
102019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
102119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int pos, newpos;
102219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct tnode *tp = NULL, *tn = NULL;
1023b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *n;
102419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct leaf *l;
102519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int missbit;
1026c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	struct list_head *fa_head = NULL;
102719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct leaf_info *li;
102819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	t_key cindex;
102919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
103019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	pos = 0;
10310a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	n = rtnl_dereference(t->trie);
103219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1033c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	/* If we point to NULL, stop. Either the tree is empty and we should
1034c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * just put a new leaf in if, or we have reached an empty child slot,
103519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * and we should just put our new leaf in that.
1036c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * If we point to a T_TNODE, check if it matches our key. Note that
1037c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * a T_TNODE might be skipping any number of bits - its 'pos' need
103819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * not be the parent's 'pos'+'bits'!
103919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
1040c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * If it does match the current key, get pos/bits from it, extract
104119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * the index from our key, push the T_TNODE and walk the tree.
104219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
104319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * If it doesn't, we have to replace it with a new T_TNODE.
104419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
1045c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * If we point to a T_LEAF, it might or might not have the same key
1046c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * as we do. If it does, just change the value, update the T_LEAF's
1047c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * value, and return it.
104819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * If it doesn't, we need to replace it with a T_TNODE.
104919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 */
105019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
105119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	while (n != NULL &&  NODE_TYPE(n) == T_TNODE) {
105219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		tn = (struct tnode *) n;
105391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1054c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		check_tnode(tn);
105591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1056c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
105719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			tp = tn;
105891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			pos = tn->pos + tn->bits;
1059a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger			n = tnode_get_child(tn,
1060a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger					    tkey_extract_bits(key,
1061a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger							      tn->pos,
1062a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger							      tn->bits));
106319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
10640680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger			BUG_ON(n && node_parent(n) != tn);
106591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		} else
106619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			break;
106719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
106819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
106919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/*
107019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * n  ----> NULL, LEAF or TNODE
107119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
1072c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	 * tp is n's (parent) ----> NULL or TNODE
107319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 */
107419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
107591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	BUG_ON(tp && IS_LEAF(tp));
107619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
107719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* Case 1: n is a leaf. Compare prefixes */
107819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1079c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (n != NULL && IS_LEAF(n) && tkey_equals(key, n->key)) {
1080c95aaf9af5a1f6dee56d1f2ab4915cd722d608daStephen Hemminger		l = (struct leaf *) n;
108119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		li = leaf_info_new(plen);
108291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1083fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger		if (!li)
1084fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger			return NULL;
108519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
108619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		fa_head = &li->falh;
108719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		insert_leaf_info(&l->list, li);
108819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		goto done;
108919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
109019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	l = leaf_new();
109119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1092fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger	if (!l)
1093fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger		return NULL;
109419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
109519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	l->key = key;
109619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	li = leaf_info_new(plen);
109719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1098c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (!li) {
1099387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger		free_leaf(l);
1100fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger		return NULL;
1101f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olsson	}
110219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
110319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	fa_head = &li->falh;
110419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	insert_leaf_info(&l->list, li);
110519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
110619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (t->trie && n == NULL) {
110791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/* Case 2: n is NULL, and will just insert a new leaf */
110819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1109b299e4f001cfa16205f9121f4630970049652268David S. Miller		node_set_parent((struct rt_trie_node *)l, tp);
111019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
111191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		cindex = tkey_extract_bits(key, tp->pos, tp->bits);
111261648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tp, cindex, (struct rt_trie_node *)l);
111391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	} else {
111491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/* Case 3: n is a LEAF or a TNODE and the key doesn't match. */
1115c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		/*
1116c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		 *  Add a new tnode here
111719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		 *  first tnode need some special handling
111819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		 */
111919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1120c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (n) {
11214c60f1d67fae632743df9324301e3cb2682f54d4baker.zhang			pos = tp ? tp->pos+tp->bits : 0;
112219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			newpos = tkey_mismatch(key, pos, n->key);
112319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			tn = tnode_new(n->key, newpos, 1);
112491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		} else {
112519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			newpos = 0;
1126c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger			tn = tnode_new(key, newpos, 1); /* First tnode */
112719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
112819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1129c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (!tn) {
1130f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olsson			free_leaf_info(li);
1131387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger			free_leaf(l);
1132fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger			return NULL;
113391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		}
113491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1135b299e4f001cfa16205f9121f4630970049652268David S. Miller		node_set_parent((struct rt_trie_node *)tn, tp);
113619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
113791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		missbit = tkey_extract_bits(key, newpos, 1);
113861648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, missbit, (struct rt_trie_node *)l);
113961648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tn, 1-missbit, n);
114019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1141c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (tp) {
114219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			cindex = tkey_extract_bits(key, tp->pos, tp->bits);
114361648d91fc278fd1d500da8061d17e6920cd3500Lin Ming			put_child(tp, cindex, (struct rt_trie_node *)tn);
114491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		} else {
1145cf778b00e96df6d64f8e21b8395d1f8a859ecdc7Eric Dumazet			rcu_assign_pointer(t->trie, (struct rt_trie_node *)tn);
114619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			tp = tn;
114719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
114819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
114991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
115091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (tp && tp->pos + tp->bits > 32)
1151058bd4d2a4ff0aaa4a5381c67e776729d840c785Joe Perches		pr_warn("fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
1152058bd4d2a4ff0aaa4a5381c67e776729d840c785Joe Perches			tp, tp->pos, tp->bits, key, plen);
115391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
115419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* Rebalance the trie */
11552373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
11567b85576d15bf2574b0a451108f59f9ad4170dd3fJarek Poplawski	trie_rebalance(t, tp);
1157f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olssondone:
115819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return fa_head;
115919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
116019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1161d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson/*
1162d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson * Caller must hold RTNL.
1163d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson */
116416c6cf8bb471392fd09b48b7c27e7d83a446b4bcStephen Hemmingerint fib_table_insert(struct fib_table *tb, struct fib_config *cfg)
116519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
116619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct trie *t = (struct trie *) tb->tb_data;
116719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct fib_alias *fa, *new_fa;
1168c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	struct list_head *fa_head = NULL;
116919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct fib_info *fi;
11704e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	int plen = cfg->fc_dst_len;
11714e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	u8 tos = cfg->fc_tos;
117219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	u32 key, mask;
117319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int err;
117419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct leaf *l;
117519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
117619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (plen > 32)
117719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return -EINVAL;
117819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
11794e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	key = ntohl(cfg->fc_dst);
118019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
11812dfe55b47e3d66ded5a84caf71e0da5710edf48bPatrick McHardy	pr_debug("Insert table=%u %08x/%d\n", tb->tb_id, key, plen);
118219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
118391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	mask = ntohl(inet_make_mask(plen));
118419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1185c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (key & ~mask)
118619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return -EINVAL;
118719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
118819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	key = key & mask;
118919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
11904e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	fi = fib_create_info(cfg);
11914e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	if (IS_ERR(fi)) {
11924e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		err = PTR_ERR(fi);
119319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		goto err;
11944e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	}
119519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
119619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	l = fib_find_node(t, key);
1197c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	fa = NULL;
119819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1199c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (l) {
120019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		fa_head = get_fa_head(l, plen);
120119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		fa = fib_find_alias(fa_head, tos, fi->fib_priority);
120219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
120319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
120419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* Now fa, if non-NULL, points to the first fib alias
120519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * with the same keys [prefix,tos,priority], if such key already
120619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * exists or to the node before which we will insert new one.
120719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
120819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * If fa is NULL, we will need to allocate a new one and
120919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * insert to the head of f.
121019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 *
121119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * If f is NULL, no fib node matched the destination key
121219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * and we need to allocate a new one of those as well.
121319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 */
121419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1215936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov	if (fa && fa->fa_tos == tos &&
1216936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov	    fa->fa_info->fib_priority == fi->fib_priority) {
1217936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		struct fib_alias *fa_first, *fa_match;
121819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
121919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		err = -EEXIST;
12204e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		if (cfg->fc_nlflags & NLM_F_EXCL)
122119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			goto out;
122219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1223936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		/* We have 2 goals:
1224936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		 * 1. Find exact match for type, scope, fib_info to avoid
1225936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		 * duplicate routes
1226936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		 * 2. Find next 'fa' (or head), NLM_F_APPEND inserts before it
1227936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		 */
1228936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		fa_match = NULL;
1229936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		fa_first = fa;
1230936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
1231936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		list_for_each_entry_continue(fa, fa_head, fa_list) {
1232936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			if (fa->fa_tos != tos)
1233936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov				break;
1234936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			if (fa->fa_info->fib_priority != fi->fib_priority)
1235936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov				break;
1236936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			if (fa->fa_type == cfg->fc_type &&
1237936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			    fa->fa_info == fi) {
1238936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov				fa_match = fa;
1239936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov				break;
1240936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			}
1241936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		}
1242936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov
12434e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		if (cfg->fc_nlflags & NLM_F_REPLACE) {
124419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			struct fib_info *fi_drop;
124519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			u8 state;
124619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1247936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			fa = fa_first;
1248936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			if (fa_match) {
1249936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov				if (fa == fa_match)
1250936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov					err = 0;
12516725033fa27c8f49e1221d2badbaaaf1ef459519Joonwoo Park				goto out;
1252936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			}
12532373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			err = -ENOBUFS;
1254e94b1766097d53e6f3ccfb36c8baa562ffeda3fcChristoph Lameter			new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
12552373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			if (new_fa == NULL)
12562373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson				goto out;
125719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
125819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			fi_drop = fa->fa_info;
12592373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			new_fa->fa_tos = fa->fa_tos;
12602373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			new_fa->fa_info = fi;
12614e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf			new_fa->fa_type = cfg->fc_type;
126219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			state = fa->fa_state;
1263936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			new_fa->fa_state = state & ~FA_S_ACCESSED;
126419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
12652373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			list_replace_rcu(&fa->fa_list, &new_fa->fa_list);
12662373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			alias_free_mem_rcu(fa);
126719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
126819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			fib_release_info(fi_drop);
126919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			if (state & FA_S_ACCESSED)
12704ccfe6d4109252dfadcd6885f33ed600ee03dbf8Nicolas Dichtel				rt_cache_flush(cfg->fc_nlinfo.nl_net);
1271b8f558313506b5bc435f2e031f3bec4b1725098eMilan Kocian			rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen,
1272b8f558313506b5bc435f2e031f3bec4b1725098eMilan Kocian				tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE);
127319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
127491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			goto succeeded;
127519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
127619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* Error if we find a perfect match which
127719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		 * uses the same scope, type, and nexthop
127819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		 * information.
127919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		 */
1280936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov		if (fa_match)
1281936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			goto out;
1282a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
12834e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		if (!(cfg->fc_nlflags & NLM_F_APPEND))
1284936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov			fa = fa_first;
128519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
128619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	err = -ENOENT;
12874e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	if (!(cfg->fc_nlflags & NLM_F_CREATE))
128819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		goto out;
128919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
129019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	err = -ENOBUFS;
1291e94b1766097d53e6f3ccfb36c8baa562ffeda3fcChristoph Lameter	new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
129219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (new_fa == NULL)
129319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		goto out;
129419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
129519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	new_fa->fa_info = fi;
129619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	new_fa->fa_tos = tos;
12974e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	new_fa->fa_type = cfg->fc_type;
129819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	new_fa->fa_state = 0;
129919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/*
130019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 * Insert new entry to the list.
130119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	 */
130219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1303c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (!fa_head) {
1304fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger		fa_head = fib_insert_node(t, key, plen);
1305fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger		if (unlikely(!fa_head)) {
1306fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger			err = -ENOMEM;
1307f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olsson			goto out_free_new_fa;
1308fea86ad8123df0d49188cbc1dd2f48da6ae49d65Stephen Hemminger		}
1309f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olsson	}
131019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
131121d8c49e01a0c1c6eb6c750cd04110db4a539284David S. Miller	if (!plen)
131221d8c49e01a0c1c6eb6c750cd04110db4a539284David S. Miller		tb->tb_num_default++;
131321d8c49e01a0c1c6eb6c750cd04110db4a539284David S. Miller
13142373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	list_add_tail_rcu(&new_fa->fa_list,
13152373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			  (fa ? &fa->fa_list : fa_head));
131619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
13174ccfe6d4109252dfadcd6885f33ed600ee03dbf8Nicolas Dichtel	rt_cache_flush(cfg->fc_nlinfo.nl_net);
13184e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id,
1319b8f558313506b5bc435f2e031f3bec4b1725098eMilan Kocian		  &cfg->fc_nlinfo, 0);
132019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonsucceeded:
132119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return 0;
1322f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olsson
1323f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olssonout_free_new_fa:
1324f835e471b557c45d2e5701ea5215f6e739b4eb39Robert Olsson	kmem_cache_free(fn_alias_kmem, new_fa);
132519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonout:
132619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	fib_release_info(fi);
132791b9a277fc4d207249e459a455abf804ebb5499dOlof Johanssonerr:
132819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return err;
132919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
133019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1331772cb712b1373d335ef2874ea357ec681edc754bRobert Olsson/* should be called with rcu_read_lock */
13325b4704419cbd0b7597a91c19f9e8e8b17c1af071David S. Millerstatic int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
133322bd5b9b13f2931ac80949f8bfbc40e8cab05be7David S. Miller		      t_key key,  const struct flowi4 *flp,
1334ebc0ffae5dfb4447e0a431ffe7fe1d467c48bbb9Eric Dumazet		      struct fib_result *res, int fib_flags)
133519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
133619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct leaf_info *li;
133719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct hlist_head *hhead = &l->list;
1338c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
1339b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin	hlist_for_each_entry_rcu(li, hhead, hlist) {
13403be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller		struct fib_alias *fa;
1341a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
13425c74501f76360ce6f410730b9b5e5976f38e8504Eric Dumazet		if (l->key != (key & li->mask_plen))
134319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			continue;
134419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
13453be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller		list_for_each_entry_rcu(fa, &li->falh, fa_list) {
13463be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			struct fib_info *fi = fa->fa_info;
13473be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			int nhsel, err;
1348a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
134922bd5b9b13f2931ac80949f8bfbc40e8cab05be7David S. Miller			if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)
13503be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				continue;
1351dccd9ecc374462e5d6a5b8f8110415a86c2213d8David S. Miller			if (fi->fib_dead)
1352dccd9ecc374462e5d6a5b8f8110415a86c2213d8David S. Miller				continue;
135337e826c513883099c298317bad1b3b677b2905fbDavid S. Miller			if (fa->fa_info->fib_scope < flp->flowi4_scope)
13543be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				continue;
13553be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			fib_alias_accessed(fa);
13563be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			err = fib_props[fa->fa_type].error;
13573be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			if (err) {
135819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
13591fbc78439291627642517f15b9b91f3125588143Julian Anastasov				t->stats.semantic_match_passed++;
13603be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller#endif
13611fbc78439291627642517f15b9b91f3125588143Julian Anastasov				return err;
13623be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			}
13633be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			if (fi->fib_flags & RTNH_F_DEAD)
13643be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				continue;
13653be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
13663be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				const struct fib_nh *nh = &fi->fib_nh[nhsel];
13673be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller
13683be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				if (nh->nh_flags & RTNH_F_DEAD)
13693be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller					continue;
137022bd5b9b13f2931ac80949f8bfbc40e8cab05be7David S. Miller				if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif)
13713be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller					continue;
13723be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller
13733be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller#ifdef CONFIG_IP_FIB_TRIE_STATS
13743be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				t->stats.semantic_match_passed++;
13753be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller#endif
13765c74501f76360ce6f410730b9b5e5976f38e8504Eric Dumazet				res->prefixlen = li->plen;
13773be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				res->nh_sel = nhsel;
13783be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				res->type = fa->fa_type;
137937e826c513883099c298317bad1b3b677b2905fbDavid S. Miller				res->scope = fa->fa_info->fib_scope;
13803be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				res->fi = fi;
13813be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				res->table = tb;
13823be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				res->fa_head = &li->falh;
13833be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				if (!(fib_flags & FIB_LOOKUP_NOREF))
13845c74501f76360ce6f410730b9b5e5976f38e8504Eric Dumazet					atomic_inc(&fi->fib_clntref);
13853be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller				return 0;
13863be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller			}
13873be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller		}
13883be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller
13893be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller#ifdef CONFIG_IP_FIB_TRIE_STATS
13903be0686b6e2f953afe83626e871b4a7b0ceae49bDavid S. Miller		t->stats.semantic_match_miss++;
139119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#endif
139219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
1393a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
13942e655571c618434c24ac2ca989374fdd84470d6dBen Hutchings	return 1;
139519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
139619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
139722bd5b9b13f2931ac80949f8bfbc40e8cab05be7David S. Millerint fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
1398ebc0ffae5dfb4447e0a431ffe7fe1d467c48bbb9Eric Dumazet		     struct fib_result *res, int fib_flags)
139919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
140019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct trie *t = (struct trie *) tb->tb_data;
14012e655571c618434c24ac2ca989374fdd84470d6dBen Hutchings	int ret;
1402b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *n;
140319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct tnode *pn;
14043b004569d86d02786ebae496e75dc0b625be3e9aDavid S. Miller	unsigned int pos, bits;
140522bd5b9b13f2931ac80949f8bfbc40e8cab05be7David S. Miller	t_key key = ntohl(flp->daddr);
14063b004569d86d02786ebae496e75dc0b625be3e9aDavid S. Miller	unsigned int chopped_off;
140719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	t_key cindex = 0;
14083b004569d86d02786ebae496e75dc0b625be3e9aDavid S. Miller	unsigned int current_prefix_length = KEYLENGTH;
140991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	struct tnode *cn;
1410874ffa8f72444d6253d2669fed304875c128f86bEric Dumazet	t_key pref_mismatch;
141191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
14122373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	rcu_read_lock();
141391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
14142373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	n = rcu_dereference(t->trie);
1415c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (!n)
141619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		goto failed;
141719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
141819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
141919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	t->stats.gets++;
142019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#endif
142119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
142219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	/* Just a leaf? */
142319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (IS_LEAF(n)) {
14245b4704419cbd0b7597a91c19f9e8e8b17c1af071David S. Miller		ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags);
1425a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		goto found;
142619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
1427a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
142819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	pn = (struct tnode *) n;
142919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	chopped_off = 0;
1430c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
143191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	while (pn) {
143219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		pos = pn->pos;
143319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		bits = pn->bits;
143419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1435c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (!chopped_off)
1436ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger			cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length),
1437ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger						   pos, bits);
143819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1439b902e5735272b6a79fe2853180b2ad6658aa9678Jarek Poplawski		n = tnode_get_child_rcu(pn, cindex);
144019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
144119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (n == NULL) {
144219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
144319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			t->stats.null_node_hit++;
144419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#endif
144519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			goto backtrace;
144619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
144719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
144891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		if (IS_LEAF(n)) {
14495b4704419cbd0b7597a91c19f9e8e8b17c1af071David S. Miller			ret = check_leaf(tb, t, (struct leaf *)n, key, flp, res, fib_flags);
14502e655571c618434c24ac2ca989374fdd84470d6dBen Hutchings			if (ret > 0)
145191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson				goto backtrace;
1452a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger			goto found;
145391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		}
145491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
145591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		cn = (struct tnode *)n;
145619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
145791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/*
145891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * It's a tnode, and we can do some extra checks here if we
145991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * like, to avoid descending into a dead-end branch.
146091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * This tnode is in the parent's child array at index
146191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * key[p_pos..p_pos+p_bits] but potentially with some bits
146291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * chopped off, so in reality the index may be just a
146391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * subprefix, padded with zero at the end.
146491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * We can also take a look at any skipped bits in this
146591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * tnode - everything up to p_pos is supposed to be ok,
146691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * and the non-chopped bits of the index (se previous
146791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * paragraph) are also guaranteed ok, but the rest is
146891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * considered unknown.
146991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 *
147091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * The skipped bits are key[pos+bits..cn->pos].
147191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
147219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
147391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/* If current_prefix_length < pos+bits, we are already doing
147491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * actual prefix  matching, which means everything from
147591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * pos+(bits-chopped_off) onward must be zero along some
147691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * branch of this subtree - otherwise there is *no* valid
147791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * prefix present. Here we can only check the skipped
147891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * bits. Remember, since we have already indexed into the
147991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * parent's child array, we know that the bits we chopped of
148091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * *are* zero.
148191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
148219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1483a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		/* NOTA BENE: Checking only skipped bits
1484a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		   for the new node here */
148519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
148691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		if (current_prefix_length < pos+bits) {
148791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			if (tkey_extract_bits(cn->key, current_prefix_length,
1488a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger						cn->pos - current_prefix_length)
1489a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger			    || !(cn->child[0]))
149091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson				goto backtrace;
149191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		}
149219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
149391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/*
149491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * If chopped_off=0, the index is fully validated and we
149591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * only need to look at the skipped bits for this, the new,
149691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * tnode. What we actually want to do is to find out if
149791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * these skipped bits match our key perfectly, or if we will
149891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * have to count on finding a matching prefix further down,
149991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * because if we do, we would like to have some way of
150091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * verifying the existence of such a prefix at this point.
150191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
150219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
150391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		/* The only thing we can do at this point is to verify that
150491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * any such matching prefix can indeed be a prefix to our
150591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * key, and if the bits in the node we are inspecting that
150691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * do not match our key are not ZERO, this cannot be true.
150791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * Thus, find out where there is a mismatch (before cn->pos)
150891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * and verify that all the mismatching bits are zero in the
150991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 * new tnode's key.
151091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
151119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1512a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		/*
1513a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * Note: We aren't very concerned about the piece of
1514a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * the key that precede pn->pos+pn->bits, since these
1515a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * have already been checked. The bits after cn->pos
1516a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * aren't checked since these are by definition
1517a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * "unknown" at this point. Thus, what we want to see
1518a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * is if we are about to enter the "prefix matching"
1519a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * state, and in that case verify that the skipped
1520a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * bits that will prevail throughout this subtree are
1521a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * zero, as they have to be if we are to find a
1522a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * matching prefix.
152391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
152491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1525874ffa8f72444d6253d2669fed304875c128f86bEric Dumazet		pref_mismatch = mask_pfx(cn->key ^ key, cn->pos);
152691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1527a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		/*
1528a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * In short: If skipped bits in this node do not match
1529a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * the search key, enter the "prefix matching"
1530a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		 * state.directly.
153191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		 */
153291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		if (pref_mismatch) {
153379cda75a107da0d49732b5cb642b456264dd7e0eEric Dumazet			/* fls(x) = __fls(x) + 1 */
153479cda75a107da0d49732b5cb642b456264dd7e0eEric Dumazet			int mp = KEYLENGTH - __fls(pref_mismatch) - 1;
153591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1536874ffa8f72444d6253d2669fed304875c128f86bEric Dumazet			if (tkey_extract_bits(cn->key, mp, cn->pos - mp) != 0)
153791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson				goto backtrace;
153891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
153991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson			if (current_prefix_length >= cn->pos)
154091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson				current_prefix_length = mp;
1541c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		}
1542a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger
154391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		pn = (struct tnode *)n; /* Descend */
154491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		chopped_off = 0;
154591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		continue;
154691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
154719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonbacktrace:
154819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		chopped_off++;
154919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
155019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* As zero don't change the child key (cindex) */
1551a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		while ((chopped_off <= pn->bits)
1552a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		       && !(cindex & (1<<(chopped_off-1))))
155319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			chopped_off++;
155419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
155519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/* Decrease current_... with bits chopped off */
155619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (current_prefix_length > pn->pos + pn->bits - chopped_off)
1557a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger			current_prefix_length = pn->pos + pn->bits
1558a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger				- chopped_off;
155991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
156019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		/*
1561c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		 * Either we do the actual chop off according or if we have
156219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		 * chopped off all bits in this tnode walk up to our parent.
156319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		 */
156419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
156591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		if (chopped_off <= pn->bits) {
156619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			cindex &= ~(1 << (chopped_off-1));
156791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		} else {
1568b299e4f001cfa16205f9121f4630970049652268David S. Miller			struct tnode *parent = node_parent_rcu((struct rt_trie_node *) pn);
15690680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger			if (!parent)
157019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				goto failed;
157191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
157219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			/* Get Child's index */
15730680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger			cindex = tkey_extract_bits(pn->key, parent->pos, parent->bits);
15740680191642c27c81c9be4557d9c6aa3487c15f69Stephen Hemminger			pn = parent;
157519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			chopped_off = 0;
157619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
157719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#ifdef CONFIG_IP_FIB_TRIE_STATS
157819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			t->stats.backtrack++;
157919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#endif
158019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			goto backtrace;
1581c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		}
158219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
158319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonfailed:
1584c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	ret = 1;
158519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olssonfound:
15862373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	rcu_read_unlock();
158719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return ret;
158819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
15896fc01438a94702bd160cb1b89203d9b97ae68cedFlorian WestphalEXPORT_SYMBOL_GPL(fib_table_lookup);
159019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
15919195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger/*
15929195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger * Remove the leaf and return parent.
15939195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger */
15949195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemmingerstatic void trie_leaf_remove(struct trie *t, struct leaf *l)
159519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
1596b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct tnode *tp = node_parent((struct rt_trie_node *) l);
1597c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
15989195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger	pr_debug("entering trie_leaf_remove(%p)\n", l);
159919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1600c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (tp) {
16019195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger		t_key cindex = tkey_extract_bits(l->key, tp->pos, tp->bits);
160261648d91fc278fd1d500da8061d17e6920cd3500Lin Ming		put_child(tp, cindex, NULL);
16037b85576d15bf2574b0a451108f59f9ad4170dd3fJarek Poplawski		trie_rebalance(t, tp);
160491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	} else
1605a9b3cd7f323b2e57593e7215362a7b02fc933e3aStephen Hemminger		RCU_INIT_POINTER(t->trie, NULL);
160619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1607387a5487f5a1f8bfc3b2c5818e50dfd19eeb4f3fStephen Hemminger	free_leaf(l);
160819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
160919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1610d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson/*
1611d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson * Caller must hold RTNL.
1612d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson */
161316c6cf8bb471392fd09b48b7c27e7d83a446b4bcStephen Hemmingerint fib_table_delete(struct fib_table *tb, struct fib_config *cfg)
161419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
161519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct trie *t = (struct trie *) tb->tb_data;
161619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	u32 key, mask;
16174e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	int plen = cfg->fc_dst_len;
16184e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	u8 tos = cfg->fc_tos;
161919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct fib_alias *fa, *fa_to_delete;
162019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct list_head *fa_head;
162119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct leaf *l;
162291b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	struct leaf_info *li;
162391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1624c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (plen > 32)
162519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return -EINVAL;
162619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
16274e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	key = ntohl(cfg->fc_dst);
162891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	mask = ntohl(inet_make_mask(plen));
162919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1630c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (key & ~mask)
163119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return -EINVAL;
163219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
163319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	key = key & mask;
163419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	l = fib_find_node(t, key);
163519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1636c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger	if (!l)
163719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return -ESRCH;
163819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1639ad5b310228da567e35a2ea5dcb2fd62e3a36654eIgor Maravic	li = find_leaf_info(l, plen);
1640ad5b310228da567e35a2ea5dcb2fd62e3a36654eIgor Maravic
1641ad5b310228da567e35a2ea5dcb2fd62e3a36654eIgor Maravic	if (!li)
1642ad5b310228da567e35a2ea5dcb2fd62e3a36654eIgor Maravic		return -ESRCH;
1643ad5b310228da567e35a2ea5dcb2fd62e3a36654eIgor Maravic
1644ad5b310228da567e35a2ea5dcb2fd62e3a36654eIgor Maravic	fa_head = &li->falh;
164519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	fa = fib_find_alias(fa_head, tos, 0);
164619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
164719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (!fa)
164819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return -ESRCH;
164919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
16500c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	pr_debug("Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
165119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
165219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	fa_to_delete = NULL;
1653936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov	fa = list_entry(fa->fa_list.prev, struct fib_alias, fa_list);
1654936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6Julian Anastasov	list_for_each_entry_continue(fa, fa_head, fa_list) {
165519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		struct fib_info *fi = fa->fa_info;
165619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
165719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (fa->fa_tos != tos)
165819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			break;
165919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
16604e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) &&
16614e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		    (cfg->fc_scope == RT_SCOPE_NOWHERE ||
166237e826c513883099c298317bad1b3b677b2905fbDavid S. Miller		     fa->fa_info->fib_scope == cfg->fc_scope) &&
166374cb3c108bc0f599a4eb40980db8580cfba725c9Julian Anastasov		    (!cfg->fc_prefsrc ||
166474cb3c108bc0f599a4eb40980db8580cfba725c9Julian Anastasov		     fi->fib_prefsrc == cfg->fc_prefsrc) &&
16654e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		    (!cfg->fc_protocol ||
16664e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		     fi->fib_protocol == cfg->fc_protocol) &&
16674e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf		    fib_nh_match(cfg, fi) == 0) {
166819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			fa_to_delete = fa;
166919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			break;
167019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
167119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
167219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
167391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (!fa_to_delete)
167491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		return -ESRCH;
167519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
167691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	fa = fa_to_delete;
16774e902c57417c4c285b98ba2722468d1c3ed83d1bThomas Graf	rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id,
1678b8f558313506b5bc435f2e031f3bec4b1725098eMilan Kocian		  &cfg->fc_nlinfo, 0);
167991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
16802373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	list_del_rcu(&fa->fa_list);
168119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
168221d8c49e01a0c1c6eb6c750cd04110db4a539284David S. Miller	if (!plen)
168321d8c49e01a0c1c6eb6c750cd04110db4a539284David S. Miller		tb->tb_num_default--;
168421d8c49e01a0c1c6eb6c750cd04110db4a539284David S. Miller
168591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (list_empty(fa_head)) {
16862373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson		hlist_del_rcu(&li->hlist);
168791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		free_leaf_info(li);
16882373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	}
168919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
169091b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (hlist_empty(&l->list))
16919195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger		trie_leaf_remove(t, l);
169219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
169391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	if (fa->fa_state & FA_S_ACCESSED)
16944ccfe6d4109252dfadcd6885f33ed600ee03dbf8Nicolas Dichtel		rt_cache_flush(cfg->fc_nlinfo.nl_net);
169519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
16962373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	fib_release_info(fa->fa_info);
16972373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	alias_free_mem_rcu(fa);
169891b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	return 0;
169919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
170019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1701ef3660ce0649fa10265455f539b72607cff53d02Stephen Hemmingerstatic int trie_flush_list(struct list_head *head)
170219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
170319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct fib_alias *fa, *fa_node;
170419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int found = 0;
170519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
170619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	list_for_each_entry_safe(fa, fa_node, head, fa_list) {
170719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		struct fib_info *fi = fa->fa_info;
170819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
17092373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson		if (fi && (fi->fib_flags & RTNH_F_DEAD)) {
17102373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			list_del_rcu(&fa->fa_list);
17112373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			fib_release_info(fa->fa_info);
17122373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			alias_free_mem_rcu(fa);
171319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			found++;
171419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
171519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
171619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return found;
171719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
171819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1719ef3660ce0649fa10265455f539b72607cff53d02Stephen Hemmingerstatic int trie_flush_leaf(struct leaf *l)
172019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
172119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int found = 0;
172219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct hlist_head *lih = &l->list;
1723b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin	struct hlist_node *tmp;
172419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct leaf_info *li = NULL;
172519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1726b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin	hlist_for_each_entry_safe(li, tmp, lih, hlist) {
1727ef3660ce0649fa10265455f539b72607cff53d02Stephen Hemminger		found += trie_flush_list(&li->falh);
172819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
172919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (list_empty(&li->falh)) {
17302373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			hlist_del_rcu(&li->hlist);
173119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			free_leaf_info(li);
173219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
173319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
173419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return found;
173519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
173619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
173782cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger/*
173882cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger * Scan for the next right leaf starting at node p->child[idx]
173982cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger * Since we have back pointer, no recursion necessary.
174082cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger */
1741b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic struct leaf *leaf_walk_rcu(struct tnode *p, struct rt_trie_node *c)
174219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
174382cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	do {
174482cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger		t_key idx;
1745c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
1746c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		if (c)
174782cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger			idx = tkey_extract_bits(c->key, p->pos, p->bits) + 1;
1748c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger		else
174982cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger			idx = 0;
17502373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
175182cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger		while (idx < 1u << p->bits) {
175282cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger			c = tnode_get_child_rcu(p, idx++);
17532373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson			if (!c)
175491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson				continue;
175591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1756aab515d7c32a34300312416c50314e755ea6f765Eric Dumazet			if (IS_LEAF(c))
175782cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger				return (struct leaf *) c;
175882cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
175982cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger			/* Rescan start scanning in new node */
176082cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger			p = (struct tnode *) c;
176182cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger			idx = 0;
176219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
176382cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
176482cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger		/* Node empty, walk back up to parent */
1765b299e4f001cfa16205f9121f4630970049652268David S. Miller		c = (struct rt_trie_node *) p;
1766a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	} while ((p = node_parent_rcu(c)) != NULL);
176782cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
176882cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	return NULL; /* Root of trie */
176982cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger}
177082cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
177182cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemmingerstatic struct leaf *trie_firstleaf(struct trie *t)
177282cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger{
1773a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	struct tnode *n = (struct tnode *)rcu_dereference_rtnl(t->trie);
177482cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
177582cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	if (!n)
177682cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger		return NULL;
177782cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
177882cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	if (IS_LEAF(n))          /* trie is just a leaf */
177982cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger		return (struct leaf *) n;
178082cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
178182cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	return leaf_walk_rcu(n, NULL);
178282cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger}
178382cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
178482cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemmingerstatic struct leaf *trie_nextleaf(struct leaf *l)
178582cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger{
1786b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *c = (struct rt_trie_node *) l;
1787b902e5735272b6a79fe2853180b2ad6658aa9678Jarek Poplawski	struct tnode *p = node_parent_rcu(c);
178882cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
178982cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	if (!p)
179082cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger		return NULL;	/* trie with just one leaf */
179182cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger
179282cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	return leaf_walk_rcu(p, c);
179319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
179419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
179571d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemmingerstatic struct leaf *trie_leafindex(struct trie *t, int index)
179671d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger{
179771d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	struct leaf *l = trie_firstleaf(t);
179871d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger
1799ec28cf738d899e9d0652108e1986101771aacb2eStephen Hemminger	while (l && index-- > 0)
180071d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		l = trie_nextleaf(l);
1801ec28cf738d899e9d0652108e1986101771aacb2eStephen Hemminger
180271d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	return l;
180371d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger}
180471d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger
180571d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger
1806d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson/*
1807d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson * Caller must hold RTNL.
1808d562f1f8a92035d5d4681c178fccb991ce57f33aRobert Olsson */
180916c6cf8bb471392fd09b48b7c27e7d83a446b4bcStephen Hemmingerint fib_table_flush(struct fib_table *tb)
181019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
181119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct trie *t = (struct trie *) tb->tb_data;
18129195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger	struct leaf *l, *ll = NULL;
181382cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	int found = 0;
181419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
181582cfbb008572b1a953091ef78f767aa3ca213092Stephen Hemminger	for (l = trie_firstleaf(t); l; l = trie_nextleaf(l)) {
1816ef3660ce0649fa10265455f539b72607cff53d02Stephen Hemminger		found += trie_flush_leaf(l);
181719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
181819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (ll && hlist_empty(&ll->list))
18199195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger			trie_leaf_remove(t, ll);
182019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		ll = l;
182119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
182219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
182319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (ll && hlist_empty(&ll->list))
18249195bef7fb0ba0a91d5ffa566bcf8e007e3c7172Stephen Hemminger		trie_leaf_remove(t, ll);
182519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
18260c7770c740156c8802c23d24fc094d06967d997dStephen Hemminger	pr_debug("trie_flush found=%d\n", found);
182719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return found;
182819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
182919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
18304aa2c466a7733af093a526e9d1cdd0b3b90d47e9Pavel Emelyanovvoid fib_free_table(struct fib_table *tb)
18314aa2c466a7733af093a526e9d1cdd0b3b90d47e9Pavel Emelyanov{
18324aa2c466a7733af093a526e9d1cdd0b3b90d47e9Pavel Emelyanov	kfree(tb);
18334aa2c466a7733af093a526e9d1cdd0b3b90d47e9Pavel Emelyanov}
18344aa2c466a7733af093a526e9d1cdd0b3b90d47e9Pavel Emelyanov
1835a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemmingerstatic int fn_trie_dump_fa(t_key key, int plen, struct list_head *fah,
1836a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger			   struct fib_table *tb,
183719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			   struct sk_buff *skb, struct netlink_callback *cb)
183819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
183919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	int i, s_i;
184019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct fib_alias *fa;
184132ab5f80334fc067386c4c56c434010c01cff6b9Al Viro	__be32 xkey = htonl(key);
184219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
184371d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	s_i = cb->args[5];
184419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	i = 0;
184519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
18462373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	/* rcu_read_lock is hold by caller */
18472373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
18482373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	list_for_each_entry_rcu(fa, fah, fa_list) {
184919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		if (i < s_i) {
185019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			i++;
185119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			continue;
185219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
185319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
185415e473046cb6e5d18a4d0057e61d76315230382bEric W. Biederman		if (fib_dump_info(skb, NETLINK_CB(cb->skb).portid,
185519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				  cb->nlh->nlmsg_seq,
185619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				  RTM_NEWROUTE,
185719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				  tb->tb_id,
185819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				  fa->fa_type,
1859be403ea1856f1428b5912b42184acbba808c41d6Thomas Graf				  xkey,
186019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				  plen,
186119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson				  fa->fa_tos,
186264347f786d13349d6a6f812f3a83c269e26c0136Stephen Hemminger				  fa->fa_info, NLM_F_MULTI) < 0) {
186371d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger			cb->args[5] = i;
186419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			return -1;
186591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson		}
186619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		i++;
186719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
186871d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	cb->args[5] = i;
186919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return skb->len;
187019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
187119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1872a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemmingerstatic int fn_trie_dump_leaf(struct leaf *l, struct fib_table *tb,
1873a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger			struct sk_buff *skb, struct netlink_callback *cb)
187419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
1875a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger	struct leaf_info *li;
1876a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger	int i, s_i;
187719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
187871d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	s_i = cb->args[4];
1879a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger	i = 0;
188019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1881a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger	/* rcu_read_lock is hold by caller */
1882b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin	hlist_for_each_entry_rcu(li, &l->list, hlist) {
1883a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger		if (i < s_i) {
1884a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger			i++;
188519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			continue;
1886a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger		}
188791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
1888a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger		if (i > s_i)
188971d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger			cb->args[5] = 0;
189019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1891a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger		if (list_empty(&li->falh))
189219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			continue;
189319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1894a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger		if (fn_trie_dump_fa(l->key, li->plen, &li->falh, tb, skb, cb) < 0) {
189571d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger			cb->args[4] = i;
189619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson			return -1;
189719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
1898a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger		i++;
189919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
1900a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger
190171d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	cb->args[4] = i;
190219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return skb->len;
190319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
190419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
190516c6cf8bb471392fd09b48b7c27e7d83a446b4bcStephen Hemmingerint fib_table_dump(struct fib_table *tb, struct sk_buff *skb,
190616c6cf8bb471392fd09b48b7c27e7d83a446b4bcStephen Hemminger		   struct netlink_callback *cb)
190719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
1908a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger	struct leaf *l;
190919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct trie *t = (struct trie *) tb->tb_data;
1910d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger	t_key key = cb->args[2];
191171d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	int count = cb->args[3];
191219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
19132373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	rcu_read_lock();
1914d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger	/* Dump starting at last key.
1915d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger	 * Note: 0.0.0.0/0 (ie default) is first key.
1916d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger	 */
191771d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	if (count == 0)
1918d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger		l = trie_firstleaf(t);
1919d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger	else {
192071d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		/* Normally, continue from last key, but if that is missing
192171d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		 * fallback to using slow rescan
192271d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		 */
1923d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger		l = fib_find_node(t, key);
192471d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		if (!l)
192571d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger			l = trie_leafindex(t, count);
1926d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger	}
1927a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger
1928d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger	while (l) {
1929d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger		cb->args[2] = l->key;
1930a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger		if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
193171d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger			cb->args[3] = count;
1932a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger			rcu_read_unlock();
1933a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger			return -1;
193419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
1935d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger
193671d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		++count;
1937d5ce8a0e97073169b5fe0b7c52bd020cdb017dfaStephen Hemminger		l = trie_nextleaf(l);
193871d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		memset(&cb->args[4], 0,
193971d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger		       sizeof(cb->args) - 4*sizeof(cb->args[0]));
194019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
194171d67e666e73e3b7e9ef124745ee2e454ac04be8Stephen Hemminger	cb->args[3] = count;
19422373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	rcu_read_unlock();
1943a88ee229253b31e3a844b30525ff77fbfe3111d3Stephen Hemminger
194419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return skb->len;
194519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
194619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
19475348ba85a02ffe80a8af33a524b6610966760d3dDavid S. Millervoid __init fib_trie_init(void)
19487f9b80529b8a2ad8b3273b15fb444a0e34b760a9Stephen Hemminger{
1949a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	fn_alias_kmem = kmem_cache_create("ip_fib_alias",
1950a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger					  sizeof(struct fib_alias),
1951bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger					  0, SLAB_PANIC, NULL);
1952bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger
1953bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger	trie_leaf_kmem = kmem_cache_create("ip_fib_trie",
1954bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger					   max(sizeof(struct leaf),
1955bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger					       sizeof(struct leaf_info)),
1956bc3c8c1e02ae89668239742fd592f21e1998fa46Stephen Hemminger					   0, SLAB_PANIC, NULL);
19577f9b80529b8a2ad8b3273b15fb444a0e34b760a9Stephen Hemminger}
195819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
19597f9b80529b8a2ad8b3273b15fb444a0e34b760a9Stephen Hemminger
19605348ba85a02ffe80a8af33a524b6610966760d3dDavid S. Millerstruct fib_table *fib_trie_table(u32 id)
196119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
196219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct fib_table *tb;
196319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	struct trie *t;
196419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
196519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	tb = kmalloc(sizeof(struct fib_table) + sizeof(struct trie),
196619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		     GFP_KERNEL);
196719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	if (tb == NULL)
196819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		return NULL;
196919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
197019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	tb->tb_id = id;
1971971b893e79db0f7dccfcea15dbdebca3ca64a84dDenis V. Lunev	tb->tb_default = -1;
197221d8c49e01a0c1c6eb6c750cd04110db4a539284David S. Miller	tb->tb_num_default = 0;
197319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
197419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	t = (struct trie *) tb->tb_data;
1975c28a1cf448e59019fa681741963c3acaeaeb6d27Stephen Hemminger	memset(t, 0, sizeof(*t));
197619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
197719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return tb;
197819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
197919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1980cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger#ifdef CONFIG_PROC_FS
1981cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger/* Depth first Trie walk iterator */
1982cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstruct fib_trie_iter {
19831c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev	struct seq_net_private p;
19843d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	struct fib_table *tb;
1985cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	struct tnode *tnode;
1986a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	unsigned int index;
1987a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	unsigned int depth;
1988cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger};
198919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
1990b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic struct rt_trie_node *fib_trie_get_next(struct fib_trie_iter *iter)
199119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
1992cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	struct tnode *tn = iter->tnode;
1993a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	unsigned int cindex = iter->index;
1994cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	struct tnode *p;
199519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
19966640e69731b42fd5e3d2b26201c8b34fc897a0eeEric W. Biederman	/* A single entry routing table */
19976640e69731b42fd5e3d2b26201c8b34fc897a0eeEric W. Biederman	if (!tn)
19986640e69731b42fd5e3d2b26201c8b34fc897a0eeEric W. Biederman		return NULL;
19996640e69731b42fd5e3d2b26201c8b34fc897a0eeEric W. Biederman
2000cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	pr_debug("get_next iter={node=%p index=%d depth=%d}\n",
2001cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		 iter->tnode, iter->index, iter->depth);
2002cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerrescan:
2003cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	while (cindex < (1<<tn->bits)) {
2004b299e4f001cfa16205f9121f4630970049652268David S. Miller		struct rt_trie_node *n = tnode_get_child_rcu(tn, cindex);
200519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2006cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		if (n) {
2007cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			if (IS_LEAF(n)) {
2008cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				iter->tnode = tn;
2009cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				iter->index = cindex + 1;
2010cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			} else {
2011cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				/* push down one level */
2012cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				iter->tnode = (struct tnode *) n;
2013cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				iter->index = 0;
2014cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				++iter->depth;
2015cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			}
2016cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			return n;
2017cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		}
201819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2019cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		++cindex;
2020cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	}
202191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2022cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	/* Current node exhausted, pop back up */
2023b299e4f001cfa16205f9121f4630970049652268David S. Miller	p = node_parent_rcu((struct rt_trie_node *)tn);
2024cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	if (p) {
2025cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		cindex = tkey_extract_bits(tn->key, p->pos, p->bits)+1;
2026cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		tn = p;
2027cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		--iter->depth;
2028cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		goto rescan;
202919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
2030cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2031cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	/* got root? */
2032cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	return NULL;
203319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
203419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2035b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic struct rt_trie_node *fib_trie_get_first(struct fib_trie_iter *iter,
2036cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				       struct trie *t)
203719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2038b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *n;
20395ddf0eb2bfd613e941dd8748870c71da2e5ad409Robert Olsson
2040132adf54639cf7dd9315e8df89c2faa59f6e46d9Stephen Hemminger	if (!t)
20415ddf0eb2bfd613e941dd8748870c71da2e5ad409Robert Olsson		return NULL;
20425ddf0eb2bfd613e941dd8748870c71da2e5ad409Robert Olsson
20435ddf0eb2bfd613e941dd8748870c71da2e5ad409Robert Olsson	n = rcu_dereference(t->trie);
20443d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	if (!n)
20455ddf0eb2bfd613e941dd8748870c71da2e5ad409Robert Olsson		return NULL;
204619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
20473d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	if (IS_TNODE(n)) {
20483d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		iter->tnode = (struct tnode *) n;
20493d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		iter->index = 0;
20503d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		iter->depth = 1;
20513d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	} else {
20523d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		iter->tnode = NULL;
20533d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		iter->index = 0;
20543d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		iter->depth = 0;
205591b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson	}
20563d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
20573d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	return n;
2058cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger}
205991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2060cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic void trie_collect_stats(struct trie *t, struct trie_stat *s)
2061cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger{
2062b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *n;
2063cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	struct fib_trie_iter iter;
206491b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2065cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	memset(s, 0, sizeof(*s));
206691b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2067cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	rcu_read_lock();
20683d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	for (n = fib_trie_get_first(&iter, t); n; n = fib_trie_get_next(&iter)) {
2069cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		if (IS_LEAF(n)) {
2070936722922f6d2366378de606a40c14f96915474dStephen Hemminger			struct leaf *l = (struct leaf *)n;
2071936722922f6d2366378de606a40c14f96915474dStephen Hemminger			struct leaf_info *li;
2072936722922f6d2366378de606a40c14f96915474dStephen Hemminger
2073cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			s->leaves++;
2074cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			s->totdepth += iter.depth;
2075cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			if (iter.depth > s->maxdepth)
2076cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				s->maxdepth = iter.depth;
2077936722922f6d2366378de606a40c14f96915474dStephen Hemminger
2078b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin			hlist_for_each_entry_rcu(li, &l->list, hlist)
2079936722922f6d2366378de606a40c14f96915474dStephen Hemminger				++s->prefixes;
2080cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		} else {
2081cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			const struct tnode *tn = (const struct tnode *) n;
2082cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			int i;
2083cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2084cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			s->tnodes++;
2085132adf54639cf7dd9315e8df89c2faa59f6e46d9Stephen Hemminger			if (tn->bits < MAX_STAT_DEPTH)
208606ef921d60bbf6f765d1b9492fb4fc88ac7814bdRobert Olsson				s->nodesizes[tn->bits]++;
208706ef921d60bbf6f765d1b9492fb4fc88ac7814bdRobert Olsson
2088cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			for (i = 0; i < (1<<tn->bits); i++)
2089cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				if (!tn->child[i])
2090cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					s->nullpointers++;
209119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson		}
209219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
20932373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson	rcu_read_unlock();
209419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
209519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2096cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger/*
2097cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger *	This outputs /proc/net/fib_triestats
2098cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger */
2099cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic void trie_show_stats(struct seq_file *seq, struct trie_stat *stat)
210019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2101a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	unsigned int i, max, pointers, bytes, avdepth;
2102c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
2103cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	if (stat->leaves)
2104cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		avdepth = stat->totdepth*100 / stat->leaves;
2105cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	else
2106cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		avdepth = 0;
210791b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2108a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	seq_printf(seq, "\tAver depth:     %u.%02d\n",
2109a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		   avdepth / 100, avdepth % 100);
2110cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	seq_printf(seq, "\tMax depth:      %u\n", stat->maxdepth);
211191b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2112cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	seq_printf(seq, "\tLeaves:         %u\n", stat->leaves);
2113cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	bytes = sizeof(struct leaf) * stat->leaves;
2114936722922f6d2366378de606a40c14f96915474dStephen Hemminger
2115936722922f6d2366378de606a40c14f96915474dStephen Hemminger	seq_printf(seq, "\tPrefixes:       %u\n", stat->prefixes);
2116936722922f6d2366378de606a40c14f96915474dStephen Hemminger	bytes += sizeof(struct leaf_info) * stat->prefixes;
2117936722922f6d2366378de606a40c14f96915474dStephen Hemminger
2118187b5188a78694fa6608fa1252d5197a7b3ab076Stephen Hemminger	seq_printf(seq, "\tInternal nodes: %u\n\t", stat->tnodes);
2119cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	bytes += sizeof(struct tnode) * stat->tnodes;
212019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
212106ef921d60bbf6f765d1b9492fb4fc88ac7814bdRobert Olsson	max = MAX_STAT_DEPTH;
212206ef921d60bbf6f765d1b9492fb4fc88ac7814bdRobert Olsson	while (max > 0 && stat->nodesizes[max-1] == 0)
2123cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		max--;
212419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2125cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	pointers = 0;
2126f585a991e1d1612265f0d4e812f77e40dd54975bJerry Snitselaar	for (i = 1; i < max; i++)
2127cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		if (stat->nodesizes[i] != 0) {
2128187b5188a78694fa6608fa1252d5197a7b3ab076Stephen Hemminger			seq_printf(seq, "  %u: %u",  i, stat->nodesizes[i]);
2129cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			pointers += (1<<i) * stat->nodesizes[i];
2130cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		}
2131cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	seq_putc(seq, '\n');
2132187b5188a78694fa6608fa1252d5197a7b3ab076Stephen Hemminger	seq_printf(seq, "\tPointers: %u\n", pointers);
21332373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
2134b299e4f001cfa16205f9121f4630970049652268David S. Miller	bytes += sizeof(struct rt_trie_node *) * pointers;
2135187b5188a78694fa6608fa1252d5197a7b3ab076Stephen Hemminger	seq_printf(seq, "Null ptrs: %u\n", stat->nullpointers);
2136187b5188a78694fa6608fa1252d5197a7b3ab076Stephen Hemminger	seq_printf(seq, "Total size: %u  kB\n", (bytes + 1023) / 1024);
213766a2f7fd2fddee1ddc5d1d286cd832e50a97258eStephen Hemminger}
21382373ce1ca04dd46bf2b8b0f9a799eb2a90da92fbRobert Olsson
2139cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger#ifdef CONFIG_IP_FIB_TRIE_STATS
214066a2f7fd2fddee1ddc5d1d286cd832e50a97258eStephen Hemmingerstatic void trie_show_usage(struct seq_file *seq,
214166a2f7fd2fddee1ddc5d1d286cd832e50a97258eStephen Hemminger			    const struct trie_use_stats *stats)
214266a2f7fd2fddee1ddc5d1d286cd832e50a97258eStephen Hemminger{
214366a2f7fd2fddee1ddc5d1d286cd832e50a97258eStephen Hemminger	seq_printf(seq, "\nCounters:\n---------\n");
2144a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	seq_printf(seq, "gets = %u\n", stats->gets);
2145a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	seq_printf(seq, "backtracks = %u\n", stats->backtrack);
2146a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	seq_printf(seq, "semantic match passed = %u\n",
2147a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		   stats->semantic_match_passed);
2148a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	seq_printf(seq, "semantic match miss = %u\n",
2149a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		   stats->semantic_match_miss);
2150a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	seq_printf(seq, "null node hit= %u\n", stats->null_node_hit);
2151a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger	seq_printf(seq, "skipped node resize = %u\n\n",
2152a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		   stats->resize_node_skipped);
2153cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger}
215466a2f7fd2fddee1ddc5d1d286cd832e50a97258eStephen Hemminger#endif /*  CONFIG_IP_FIB_TRIE_STATS */
215566a2f7fd2fddee1ddc5d1d286cd832e50a97258eStephen Hemminger
21563d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemmingerstatic void fib_table_print(struct seq_file *seq, struct fib_table *tb)
2157d717a9a62049a03e85c3c2dd3399416eeb34a8beStephen Hemminger{
21583d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	if (tb->tb_id == RT_TABLE_LOCAL)
21593d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		seq_puts(seq, "Local:\n");
21603d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	else if (tb->tb_id == RT_TABLE_MAIN)
21613d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		seq_puts(seq, "Main:\n");
21623d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	else
21633d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		seq_printf(seq, "Id %d:\n", tb->tb_id);
2164d717a9a62049a03e85c3c2dd3399416eeb34a8beStephen Hemminger}
216519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
21663d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
2167cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic int fib_triestat_seq_show(struct seq_file *seq, void *v)
2168cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger{
21691c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev	struct net *net = (struct net *)seq->private;
21703d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	unsigned int h;
2171877a9bff3889512d7326d6bf0ba6ed3ddda6d772Eric W. Biederman
2172d717a9a62049a03e85c3c2dd3399416eeb34a8beStephen Hemminger	seq_printf(seq,
2173a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		   "Basic info: size of leaf:"
2174a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger		   " %Zd bytes, size of tnode: %Zd bytes.\n",
2175d717a9a62049a03e85c3c2dd3399416eeb34a8beStephen Hemminger		   sizeof(struct leaf), sizeof(struct tnode));
2176d717a9a62049a03e85c3c2dd3399416eeb34a8beStephen Hemminger
21773d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
21783d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		struct hlist_head *head = &net->ipv4.fib_table_hash[h];
21793d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		struct fib_table *tb;
21803d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
2181b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin		hlist_for_each_entry_rcu(tb, head, tb_hlist) {
21823d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			struct trie *t = (struct trie *) tb->tb_data;
21833d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			struct trie_stat stat;
2184877a9bff3889512d7326d6bf0ba6ed3ddda6d772Eric W. Biederman
21853d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			if (!t)
21863d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger				continue;
21873d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
21883d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			fib_table_print(seq, tb);
21893d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
21903d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			trie_collect_stats(t, &stat);
21913d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			trie_show_stats(seq, &stat);
21923d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger#ifdef CONFIG_IP_FIB_TRIE_STATS
21933d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			trie_show_usage(seq, &t->stats);
21943d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger#endif
21953d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		}
21963d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	}
219719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2198cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	return 0;
219919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
220019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2201cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic int fib_triestat_seq_open(struct inode *inode, struct file *file)
220219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2203de05c557b24c7dffc6d392e3db120cf11c9f6ae7Pavel Emelyanov	return single_open_net(inode, file, fib_triestat_seq_show);
22041c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev}
22051c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev
22069a32144e9d7b4e21341174b1a83b82a82353be86Arjan van de Venstatic const struct file_operations fib_triestat_fops = {
2207cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.owner	= THIS_MODULE,
2208cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.open	= fib_triestat_seq_open,
2209cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.read	= seq_read,
2210cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.llseek	= seq_lseek,
2211b6fcbdb4f283f7ba67cec3cda6be23da8e959031Pavel Emelyanov	.release = single_release_net,
2212cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger};
2213cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2214b299e4f001cfa16205f9121f4630970049652268David S. Millerstatic struct rt_trie_node *fib_trie_get_idx(struct seq_file *seq, loff_t pos)
221519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
22161218854afa6f659be90b748cf1bc7badee954a35YOSHIFUJI Hideaki	struct fib_trie_iter *iter = seq->private;
22171218854afa6f659be90b748cf1bc7badee954a35YOSHIFUJI Hideaki	struct net *net = seq_file_net(seq);
2218cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	loff_t idx = 0;
22193d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	unsigned int h;
2220cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
22213d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
22223d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		struct hlist_head *head = &net->ipv4.fib_table_hash[h];
22233d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		struct fib_table *tb;
2224cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2225b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin		hlist_for_each_entry_rcu(tb, head, tb_hlist) {
2226b299e4f001cfa16205f9121f4630970049652268David S. Miller			struct rt_trie_node *n;
22273d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
22283d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			for (n = fib_trie_get_first(iter,
22293d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger						    (struct trie *) tb->tb_data);
22303d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			     n; n = fib_trie_get_next(iter))
22313d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger				if (pos == idx++) {
22323d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger					iter->tb = tb;
22333d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger					return n;
22343d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger				}
22353d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		}
2236cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	}
22373d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
223819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return NULL;
223919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
224019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2241cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic void *fib_trie_seq_start(struct seq_file *seq, loff_t *pos)
2242c95aaf9af5a1f6dee56d1f2ab4915cd722d608daStephen Hemminger	__acquires(RCU)
224319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2244cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	rcu_read_lock();
22451218854afa6f659be90b748cf1bc7badee954a35YOSHIFUJI Hideaki	return fib_trie_get_idx(seq, *pos);
224619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
224719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2248cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic void *fib_trie_seq_next(struct seq_file *seq, void *v, loff_t *pos)
224919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2250cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	struct fib_trie_iter *iter = seq->private;
22511218854afa6f659be90b748cf1bc7badee954a35YOSHIFUJI Hideaki	struct net *net = seq_file_net(seq);
22523d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	struct fib_table *tb = iter->tb;
22533d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	struct hlist_node *tb_node;
22543d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	unsigned int h;
2255b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *n;
2256cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
225719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	++*pos;
22583d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	/* next node in same table */
22593d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	n = fib_trie_get_next(iter);
22603d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	if (n)
22613d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		return n;
226219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
22633d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	/* walk rest of this hash chain */
22643d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	h = tb->tb_id & (FIB_TABLE_HASHSZ - 1);
22650a5c047507aaaf00519921336d19c0f8f5f9f363Eric Dumazet	while ((tb_node = rcu_dereference(hlist_next_rcu(&tb->tb_hlist)))) {
22663d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		tb = hlist_entry(tb_node, struct fib_table, tb_hlist);
22673d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		n = fib_trie_get_first(iter, (struct trie *) tb->tb_data);
22683d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		if (n)
22693d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			goto found;
22703d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	}
227119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
22723d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	/* new hash chain */
22733d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	while (++h < FIB_TABLE_HASHSZ) {
22743d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		struct hlist_head *head = &net->ipv4.fib_table_hash[h];
2275b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin		hlist_for_each_entry_rcu(tb, head, tb_hlist) {
22763d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			n = fib_trie_get_first(iter, (struct trie *) tb->tb_data);
22773d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger			if (n)
22783d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger				goto found;
22793d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		}
22803d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	}
2281cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	return NULL;
22823d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger
22833d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemmingerfound:
22843d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	iter->tb = tb;
22853d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	return n;
2286cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger}
228719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2288cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic void fib_trie_seq_stop(struct seq_file *seq, void *v)
2289c95aaf9af5a1f6dee56d1f2ab4915cd722d608daStephen Hemminger	__releases(RCU)
229019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2291cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	rcu_read_unlock();
2292cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger}
229391b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2294cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic void seq_indent(struct seq_file *seq, int n)
2295cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger{
2296a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	while (n-- > 0)
2297a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet		seq_puts(seq, "   ");
2298cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger}
229919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
230028d36e3702fcbed73c38e877bcf2a8f8946b7f3dEric Dumazetstatic inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s)
2301cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger{
2302132adf54639cf7dd9315e8df89c2faa59f6e46d9Stephen Hemminger	switch (s) {
2303cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	case RT_SCOPE_UNIVERSE: return "universe";
2304cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	case RT_SCOPE_SITE:	return "site";
2305cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	case RT_SCOPE_LINK:	return "link";
2306cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	case RT_SCOPE_HOST:	return "host";
2307cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	case RT_SCOPE_NOWHERE:	return "nowhere";
2308cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	default:
230928d36e3702fcbed73c38e877bcf2a8f8946b7f3dEric Dumazet		snprintf(buf, len, "scope=%d", s);
2310cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		return buf;
2311cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	}
2312cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger}
231319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
231436cbd3dcc10384f813ec0814255f576c84f2bcd4Jan Engelhardtstatic const char *const rtn_type_names[__RTN_MAX] = {
2315cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_UNSPEC] = "UNSPEC",
2316cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_UNICAST] = "UNICAST",
2317cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_LOCAL] = "LOCAL",
2318cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_BROADCAST] = "BROADCAST",
2319cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_ANYCAST] = "ANYCAST",
2320cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_MULTICAST] = "MULTICAST",
2321cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_BLACKHOLE] = "BLACKHOLE",
2322cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_UNREACHABLE] = "UNREACHABLE",
2323cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_PROHIBIT] = "PROHIBIT",
2324cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_THROW] = "THROW",
2325cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_NAT] = "NAT",
2326cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	[RTN_XRESOLVE] = "XRESOLVE",
2327cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger};
232819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2329a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazetstatic inline const char *rtn_type(char *buf, size_t len, unsigned int t)
2330cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger{
2331cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	if (t < __RTN_MAX && rtn_type_names[t])
2332cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		return rtn_type_names[t];
233328d36e3702fcbed73c38e877bcf2a8f8946b7f3dEric Dumazet	snprintf(buf, len, "type %u", t);
2334cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	return buf;
233519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
233619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2337cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger/* Pretty print the trie */
2338cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic int fib_trie_seq_show(struct seq_file *seq, void *v)
233919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2340cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	const struct fib_trie_iter *iter = seq->private;
2341b299e4f001cfa16205f9121f4630970049652268David S. Miller	struct rt_trie_node *n = v;
2342c877efb207bf4629cfa97ac13412f7392a873485Stephen Hemminger
23433d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger	if (!node_parent_rcu(n))
23443d3b2d25a4debaff05a9e6f5c55a0d31e4334234Stephen Hemminger		fib_table_print(seq, iter->tb);
2345095b8501e4168ae5a879fcb9420ac48cbd43f95aRobert Olsson
2346cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	if (IS_TNODE(n)) {
2347cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		struct tnode *tn = (struct tnode *) n;
2348ab66b4a7a3969077f6e2a18a0d2d849d3b84a337Stephen Hemminger		__be32 prf = htonl(mask_pfx(tn->key, tn->pos));
234991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
23501d25cd6cc2528e4af12ab18e84fe95ed78f3f21aRobert Olsson		seq_indent(seq, iter->depth-1);
2351673d57e72398edfedc93fb50ff58048077c9d587Harvey Harrison		seq_printf(seq, "  +-- %pI4/%d %d %d %d\n",
2352673d57e72398edfedc93fb50ff58048077c9d587Harvey Harrison			   &prf, tn->pos, tn->bits, tn->full_children,
23531d25cd6cc2528e4af12ab18e84fe95ed78f3f21aRobert Olsson			   tn->empty_children);
2354e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki
2355cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	} else {
2356cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		struct leaf *l = (struct leaf *) n;
23571328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger		struct leaf_info *li;
235832ab5f80334fc067386c4c56c434010c01cff6b9Al Viro		__be32 val = htonl(l->key);
2359cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2360cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		seq_indent(seq, iter->depth);
2361673d57e72398edfedc93fb50ff58048077c9d587Harvey Harrison		seq_printf(seq, "  |-- %pI4\n", &val);
23621328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger
2363b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin		hlist_for_each_entry_rcu(li, &l->list, hlist) {
23641328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger			struct fib_alias *fa;
23651328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger
23661328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger			list_for_each_entry_rcu(fa, &li->falh, fa_list) {
23671328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger				char buf1[32], buf2[32];
23681328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger
23691328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger				seq_indent(seq, iter->depth+1);
23701328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger				seq_printf(seq, "  /%d %s %s", li->plen,
23711328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger					   rtn_scope(buf1, sizeof(buf1),
237237e826c513883099c298317bad1b3b677b2905fbDavid S. Miller						     fa->fa_info->fib_scope),
23731328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger					   rtn_type(buf2, sizeof(buf2),
23741328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger						    fa->fa_type));
23751328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger				if (fa->fa_tos)
2376b9c4d82a853713d49ac53b507964d7cf30ee408dDenis V. Lunev					seq_printf(seq, " tos=%d", fa->fa_tos);
23771328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger				seq_putc(seq, '\n');
2378cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			}
2379cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		}
238019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
2381cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
238219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return 0;
238319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
238419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2385f690808e17925fc45217eb22e8670902ecee5c1bStephen Hemmingerstatic const struct seq_operations fib_trie_seq_ops = {
2386cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.start  = fib_trie_seq_start,
2387cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.next   = fib_trie_seq_next,
2388cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.stop   = fib_trie_seq_stop,
2389cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.show   = fib_trie_seq_show,
239019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
239119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2392cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic int fib_trie_seq_open(struct inode *inode, struct file *file)
239319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
23941c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev	return seq_open_net(inode, file, &fib_trie_seq_ops,
23951c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev			    sizeof(struct fib_trie_iter));
239619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
239719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
23989a32144e9d7b4e21341174b1a83b82a82353be86Arjan van de Venstatic const struct file_operations fib_trie_fops = {
2399cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.owner  = THIS_MODULE,
2400cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.open   = fib_trie_seq_open,
2401cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.read   = seq_read,
2402cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.llseek = seq_lseek,
24031c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev	.release = seq_release_net,
240419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
240519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
24068315f5d80a90247bf92232f92ca49933ac49327bStephen Hemmingerstruct fib_route_iter {
24078315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct seq_net_private p;
24088315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct trie *main_trie;
24098315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	loff_t	pos;
24108315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	t_key	key;
24118315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger};
24128315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24138315f5d80a90247bf92232f92ca49933ac49327bStephen Hemmingerstatic struct leaf *fib_route_get_idx(struct fib_route_iter *iter, loff_t pos)
24148315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger{
24158315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct leaf *l = NULL;
24168315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct trie *t = iter->main_trie;
24178315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24188315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	/* use cache location of last found key */
24198315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	if (iter->pos > 0 && pos >= iter->pos && (l = fib_find_node(t, iter->key)))
24208315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		pos -= iter->pos;
24218315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	else {
24228315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->pos = 0;
24238315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		l = trie_firstleaf(t);
24248315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	}
24258315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24268315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	while (l && pos-- > 0) {
24278315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->pos++;
24288315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		l = trie_nextleaf(l);
24298315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	}
24308315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24318315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	if (l)
24328315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->key = pos;	/* remember it */
24338315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	else
24348315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->pos = 0;		/* forget it */
24358315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24368315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	return l;
24378315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger}
24388315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24398315f5d80a90247bf92232f92ca49933ac49327bStephen Hemmingerstatic void *fib_route_seq_start(struct seq_file *seq, loff_t *pos)
24408315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	__acquires(RCU)
24418315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger{
24428315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct fib_route_iter *iter = seq->private;
24438315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct fib_table *tb;
24448315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24458315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	rcu_read_lock();
24461218854afa6f659be90b748cf1bc7badee954a35YOSHIFUJI Hideaki	tb = fib_get_table(seq_file_net(seq), RT_TABLE_MAIN);
24478315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	if (!tb)
24488315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		return NULL;
24498315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24508315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	iter->main_trie = (struct trie *) tb->tb_data;
24518315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	if (*pos == 0)
24528315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		return SEQ_START_TOKEN;
24538315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	else
24548315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		return fib_route_get_idx(iter, *pos - 1);
24558315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger}
24568315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24578315f5d80a90247bf92232f92ca49933ac49327bStephen Hemmingerstatic void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
24588315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger{
24598315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct fib_route_iter *iter = seq->private;
24608315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	struct leaf *l = v;
24618315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24628315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	++*pos;
24638315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	if (v == SEQ_START_TOKEN) {
24648315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->pos = 0;
24658315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		l = trie_firstleaf(iter->main_trie);
24668315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	} else {
24678315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->pos++;
24688315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		l = trie_nextleaf(l);
24698315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	}
24708315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24718315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	if (l)
24728315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->key = l->key;
24738315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	else
24748315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger		iter->pos = 0;
24758315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	return l;
24768315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger}
24778315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
24788315f5d80a90247bf92232f92ca49933ac49327bStephen Hemmingerstatic void fib_route_seq_stop(struct seq_file *seq, void *v)
24798315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	__releases(RCU)
24808315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger{
24818315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	rcu_read_unlock();
24828315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger}
24838315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger
2484a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazetstatic unsigned int fib_flag_trans(int type, __be32 mask, const struct fib_info *fi)
248519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2486a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	unsigned int flags = 0;
248719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2488a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet	if (type == RTN_UNREACHABLE || type == RTN_PROHIBIT)
2489a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet		flags = RTF_REJECT;
2490cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	if (fi && fi->fib_nh->nh_gw)
2491cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		flags |= RTF_GATEWAY;
249232ab5f80334fc067386c4c56c434010c01cff6b9Al Viro	if (mask == htonl(0xFFFFFFFF))
2493cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		flags |= RTF_HOST;
2494cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	flags |= RTF_UP;
2495cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	return flags;
249619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
249719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2498cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger/*
2499cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger *	This outputs /proc/net/route.
2500cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger *	The format of the file is not supposed to be changed
2501a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet *	and needs to be same as fib_hash output to avoid breaking
2502cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger *	legacy utilities
2503cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger */
2504cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic int fib_route_seq_show(struct seq_file *seq, void *v)
250519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2506cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	struct leaf *l = v;
25071328042e268c936189f15eba5bd9a5a4605a8581Stephen Hemminger	struct leaf_info *li;
250819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2509cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	if (v == SEQ_START_TOKEN) {
2510cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		seq_printf(seq, "%-127s\n", "Iface\tDestination\tGateway "
2511cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			   "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
2512cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			   "\tWindow\tIRTT");
2513cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		return 0;
2514cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	}
251519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2516b67bfe0d42cac56c512dd5da4b1b347a23f4b70aSasha Levin	hlist_for_each_entry_rcu(li, &l->list, hlist) {
2517cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		struct fib_alias *fa;
251832ab5f80334fc067386c4c56c434010c01cff6b9Al Viro		__be32 mask, prefix;
251991b9a277fc4d207249e459a455abf804ebb5499dOlof Johansson
2520cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		mask = inet_make_mask(li->plen);
2521cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		prefix = htonl(l->key);
252219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2523cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		list_for_each_entry_rcu(fa, &li->falh, fa_list) {
25241371e37da299d4df6267ad0ddf010435782c28e9Herbert Xu			const struct fib_info *fi = fa->fa_info;
2525a034ee3cca5726b14107f281f4bed1c0fd44472aEric Dumazet			unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi);
252619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2527cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			if (fa->fa_type == RTN_BROADCAST
2528cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			    || fa->fa_type == RTN_MULTICAST)
2529cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger				continue;
253019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2531652586df95e5d76b37d07a11839126dcfede1621Tetsuo Handa			seq_setwidth(seq, 127);
2532652586df95e5d76b37d07a11839126dcfede1621Tetsuo Handa
2533cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			if (fi)
25345e659e4cb0eedacdc1f621a61e400a4611ddef8aPavel Emelyanov				seq_printf(seq,
25355e659e4cb0eedacdc1f621a61e400a4611ddef8aPavel Emelyanov					 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
2536652586df95e5d76b37d07a11839126dcfede1621Tetsuo Handa					 "%d\t%08X\t%d\t%u\t%u",
2537cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					 fi->fib_dev ? fi->fib_dev->name : "*",
2538cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					 prefix,
2539cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					 fi->fib_nh->nh_gw, flags, 0, 0,
2540cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					 fi->fib_priority,
2541cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					 mask,
2542a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger					 (fi->fib_advmss ?
2543a07f5f508a4d9728c8e57d7f66294bf5b254ff7fStephen Hemminger					  fi->fib_advmss + 40 : 0),
2544cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					 fi->fib_window,
2545652586df95e5d76b37d07a11839126dcfede1621Tetsuo Handa					 fi->fib_rtt >> 3);
2546cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger			else
25475e659e4cb0eedacdc1f621a61e400a4611ddef8aPavel Emelyanov				seq_printf(seq,
25485e659e4cb0eedacdc1f621a61e400a4611ddef8aPavel Emelyanov					 "*\t%08X\t%08X\t%04X\t%d\t%u\t"
2549652586df95e5d76b37d07a11839126dcfede1621Tetsuo Handa					 "%d\t%08X\t%d\t%u\t%u",
2550cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger					 prefix, 0, flags, 0, 0, 0,
2551652586df95e5d76b37d07a11839126dcfede1621Tetsuo Handa					 mask, 0, 0, 0);
255219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2553652586df95e5d76b37d07a11839126dcfede1621Tetsuo Handa			seq_pad(seq, '\n');
2554cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		}
255519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	}
255619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
255719baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return 0;
255819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
255919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2560f690808e17925fc45217eb22e8670902ecee5c1bStephen Hemmingerstatic const struct seq_operations fib_route_seq_ops = {
25618315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	.start  = fib_route_seq_start,
25628315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	.next   = fib_route_seq_next,
25638315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger	.stop   = fib_route_seq_stop,
2564cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.show   = fib_route_seq_show,
256519baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
256619baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
2567cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerstatic int fib_route_seq_open(struct inode *inode, struct file *file)
256819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
25691c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev	return seq_open_net(inode, file, &fib_route_seq_ops,
25708315f5d80a90247bf92232f92ca49933ac49327bStephen Hemminger			    sizeof(struct fib_route_iter));
257119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
257219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
25739a32144e9d7b4e21341174b1a83b82a82353be86Arjan van de Venstatic const struct file_operations fib_route_fops = {
2574cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.owner  = THIS_MODULE,
2575cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.open   = fib_route_seq_open,
2576cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.read   = seq_read,
2577cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	.llseek = seq_lseek,
25781c340b2fd73880136c438e6e7978288fbec8273fDenis V. Lunev	.release = seq_release_net,
257919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson};
258019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
258161a0265344786a548e8a0b26cb668e78a71f9602Denis V. Lunevint __net_init fib_proc_init(struct net *net)
258219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2583d4beaa66add8aebf83ab16d2fde4e4de8dac36dfGao feng	if (!proc_create("fib_trie", S_IRUGO, net->proc_net, &fib_trie_fops))
2584cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		goto out1;
2585cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2586d4beaa66add8aebf83ab16d2fde4e4de8dac36dfGao feng	if (!proc_create("fib_triestat", S_IRUGO, net->proc_net,
2587d4beaa66add8aebf83ab16d2fde4e4de8dac36dfGao feng			 &fib_triestat_fops))
2588cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		goto out2;
2589cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2590d4beaa66add8aebf83ab16d2fde4e4de8dac36dfGao feng	if (!proc_create("route", S_IRUGO, net->proc_net, &fib_route_fops))
2591cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger		goto out3;
2592cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
259319baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson	return 0;
2594cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger
2595cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerout3:
2596ece31ffd539e8e2b586b1ca5f50bc4f4591e3893Gao feng	remove_proc_entry("fib_triestat", net->proc_net);
2597cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerout2:
2598ece31ffd539e8e2b586b1ca5f50bc4f4591e3893Gao feng	remove_proc_entry("fib_trie", net->proc_net);
2599cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemmingerout1:
2600cb7b593c2c808b32a1ea188599713c434b95f849Stephen Hemminger	return -ENOMEM;
260119baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
260219baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
260361a0265344786a548e8a0b26cb668e78a71f9602Denis V. Lunevvoid __net_exit fib_proc_exit(struct net *net)
260419baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson{
2605ece31ffd539e8e2b586b1ca5f50bc4f4591e3893Gao feng	remove_proc_entry("fib_trie", net->proc_net);
2606ece31ffd539e8e2b586b1ca5f50bc4f4591e3893Gao feng	remove_proc_entry("fib_triestat", net->proc_net);
2607ece31ffd539e8e2b586b1ca5f50bc4f4591e3893Gao feng	remove_proc_entry("route", net->proc_net);
260819baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson}
260919baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson
261019baf839ff4a8daa1f2a7400897094fc18e4f5e9Robert Olsson#endif /* CONFIG_PROC_FS */
2611