51 #define VERSION "0.409"
53 #include <asm/uaccess.h>
54 #include <linux/bitops.h>
55 #include <linux/types.h>
56 #include <linux/kernel.h>
58 #include <linux/string.h>
59 #include <linux/socket.h>
61 #include <linux/errno.h>
65 #include <linux/netdevice.h>
66 #include <linux/if_arp.h>
70 #include <linux/netlink.h>
72 #include <linux/list.h>
73 #include <linux/slab.h>
74 #include <linux/prefetch.h>
75 #include <linux/export.h>
85 #define MAX_STAT_DEPTH 32
87 #define KEYLENGTH (8*sizeof(t_key))
93 #define NODE_TYPE_MASK 0x1UL
94 #define NODE_TYPE(node) ((node)->parent & NODE_TYPE_MASK)
96 #define IS_TNODE(n) (!(n->parent & T_LEAF))
97 #define IS_LEAF(n) (n->parent & T_LEAF)
134 #ifdef CONFIG_IP_FIB_TRIE_STATS
135 struct trie_use_stats {
137 unsigned int backtrack;
138 unsigned int semantic_match_passed;
139 unsigned int semantic_match_miss;
140 unsigned int null_node_hit;
141 unsigned int resize_node_skipped;
157 #ifdef CONFIG_IP_FIB_TRIE_STATS
158 struct trie_use_stats
stats;
168 static struct tnode *tnode_free_head;
169 static size_t tnode_free_size;
176 static const int sync_pages = 128;
201 lockdep_rtnl_is_held());
218 static inline struct rt_trie_node *tnode_get_child(
const struct tnode *tn,
unsigned int i)
228 static inline struct rt_trie_node *tnode_get_child_rcu(
const struct tnode *tn,
unsigned int i)
235 static inline int tnode_child_length(
const struct tnode *tn)
237 return 1 << tn->
bits;
258 static inline int tkey_sub_equals(
t_key a,
int offset,
int bits,
t_key b)
266 static inline int tkey_mismatch(
t_key a,
int offset,
t_key b)
273 while ((diff << i) >> (
KEYLENGTH-1) == 0)
341 static inline void check_tnode(
const struct tnode *tn)
346 static const int halve_threshold = 25;
347 static const int inflate_threshold = 50;
348 static const int halve_threshold_root = 15;
349 static const int inflate_threshold_root = 30;
357 static inline void alias_free_mem_rcu(
struct fib_alias *
fa)
368 static inline void free_leaf(
struct leaf *l)
378 static struct tnode *tnode_alloc(
size_t size)
395 size_t size =
sizeof(
struct tnode) +
409 free_leaf((
struct leaf *) tn);
414 static void tnode_free_safe(
struct tnode *tn)
418 tnode_free_head = tn;
419 tnode_free_size +=
sizeof(
struct tnode) +
423 static void tnode_free_flush(
void)
427 while ((tn = tnode_free_head)) {
433 if (tnode_free_size >=
PAGE_SIZE * sync_pages) {
439 static struct leaf *leaf_new(
void)
455 INIT_LIST_HEAD(&li->
falh);
463 struct tnode *tn = tnode_alloc(sz);
492 static inline void put_child(
struct tnode *tn,
int i,
495 tnode_put_child_reorg(tn, i, n, -1);
503 static void tnode_put_child_reorg(
struct tnode *tn,
int i,
struct rt_trie_node *n,
519 wasfull = tnode_full(tn, chi);
521 isfull = tnode_full(tn, n);
522 if (wasfull && !isfull)
524 else if (!wasfull && isfull)
528 node_set_parent(n, tn);
537 struct tnode *old_tn;
538 int inflate_threshold_use;
539 int halve_threshold_use;
545 pr_debug(
"In tnode_resize %p inflate_threshold=%d threshold=%d\n",
546 tn, inflate_threshold, halve_threshold);
625 inflate_threshold_use = inflate_threshold_root;
626 halve_threshold_use = halve_threshold_root;
628 inflate_threshold_use = inflate_threshold;
629 halve_threshold_use = halve_threshold;
636 >= inflate_threshold_use * tnode_child_length(tn))) {
643 #ifdef CONFIG_IP_FIB_TRIE_STATS
644 t->stats.resize_node_skipped++;
662 while (tn->
bits > 1 && max_work-- &&
664 halve_threshold_use * tnode_child_length(tn)) {
670 #ifdef CONFIG_IP_FIB_TRIE_STATS
671 t->stats.resize_node_skipped++;
681 for (i = 0; i < tnode_child_length(tn); i++) {
690 node_set_parent(n,
NULL);
699 static void tnode_clean_free(
struct tnode *tn)
702 struct tnode *tofree;
704 for (i = 0; i < tnode_child_length(tn); i++) {
714 struct tnode *oldtnode = tn;
715 int olen = tnode_child_length(tn);
720 tn = tnode_new(oldtnode->
key, oldtnode->
pos, oldtnode->
bits + 1);
732 for (i = 0; i < olen; i++) {
735 inode = (
struct tnode *) tnode_get_child(oldtnode, i);
738 inode->
pos == oldtnode->
pos + oldtnode->
bits &&
743 left = tnode_new(inode->
key&(~m), inode->
pos + 1,
748 right = tnode_new(inode->
key|m, inode->
pos + 1,
761 for (i = 0; i < olen; i++) {
763 struct rt_trie_node *node = tnode_get_child(oldtnode, i);
775 if (tkey_extract_bits(node->
key,
776 oldtnode->
pos + oldtnode->
bits,
778 put_child(tn, 2*i, node);
780 put_child(tn, 2*i+1, node);
785 inode = (
struct tnode *) node;
787 if (inode->
bits == 1) {
791 tnode_free_safe(inode);
818 left = (
struct tnode *) tnode_get_child(tn, 2*i);
819 put_child(tn, 2*i,
NULL);
823 right = (
struct tnode *) tnode_get_child(tn, 2*i+1);
824 put_child(tn, 2*i+1,
NULL);
828 size = tnode_child_length(left);
829 for (j = 0; j <
size; j++) {
833 put_child(tn, 2*i, resize(t, left));
834 put_child(tn, 2*i+1, resize(t, right));
836 tnode_free_safe(inode);
838 tnode_free_safe(oldtnode);
841 tnode_clean_free(tn);
847 struct tnode *oldtnode = tn;
850 int olen = tnode_child_length(tn);
854 tn = tnode_new(oldtnode->
key, oldtnode->
pos, oldtnode->
bits - 1);
866 for (i = 0; i < olen; i += 2) {
867 left = tnode_get_child(oldtnode, i);
868 right = tnode_get_child(oldtnode, i+1);
874 newn = tnode_new(left->
key, tn->
pos + tn->
bits, 1);
884 for (i = 0; i < olen; i += 2) {
885 struct tnode *newBinNode;
887 left = tnode_get_child(oldtnode, i);
888 right = tnode_get_child(oldtnode, i+1);
894 put_child(tn, i/2, right);
899 put_child(tn, i/2, left);
904 newBinNode = (
struct tnode *) tnode_get_child(tn, i/2);
905 put_child(tn, i/2,
NULL);
906 put_child(newBinNode, 0, left);
907 put_child(newBinNode, 1, right);
908 put_child(tn, i/2, resize(t, newBinNode));
910 tnode_free_safe(oldtnode);
913 tnode_clean_free(tn);
920 static struct leaf_info *find_leaf_info(
struct leaf *l,
int plen)
926 hlist_for_each_entry_rcu(li, node, head,
hlist)
927 if (li->plen == plen)
935 struct leaf_info *li = find_leaf_info(l, plen);
948 if (hlist_empty(head)) {
949 hlist_add_head_rcu(&new->hlist, head);
952 if (new->plen > li->
plen)
958 hlist_add_after_rcu(&last->hlist, &new->hlist);
960 hlist_add_before_rcu(&new->hlist, &li->
hlist);
967 fib_find_node(
struct trie *t,
u32 key)
977 tn = (
struct tnode *) n;
981 if (tkey_sub_equals(tn->
key, pos, tn->
pos-pos, key)) {
983 n = tnode_get_child_rcu(tn,
984 tkey_extract_bits(key,
992 if (n != NULL &&
IS_LEAF(n) && tkey_equals(key, n->
key))
993 return (
struct leaf *)
n;
998 static void trie_rebalance(
struct trie *t,
struct tnode *tn)
1006 while (tn != NULL && (tp = node_parent((
struct rt_trie_node *)tn)) != NULL) {
1007 cindex = tkey_extract_bits(key, tp->
pos, tp->
bits);
1008 wasfull = tnode_full(tp, tnode_get_child(tp, cindex));
1009 tn = (
struct tnode *)resize(t, tn);
1011 tnode_put_child_reorg(tp, cindex,
1026 tn = (
struct tnode *)resize(t, tn);
1034 static struct list_head *fib_insert_node(
struct trie *t,
u32 key,
int plen)
1067 tn = (
struct tnode *) n;
1071 if (tkey_sub_equals(tn->key, pos, tn->pos-pos, key)) {
1073 pos = tn->
pos + tn->bits;
1074 n = tnode_get_child(tn,
1075 tkey_extract_bits(key,
1079 BUG_ON(n && node_parent(n) != tn);
1094 if (n != NULL &&
IS_LEAF(n) && tkey_equals(key, n->
key)) {
1095 l = (
struct leaf *) n;
1096 li = leaf_info_new(plen);
1101 fa_head = &li->
falh;
1102 insert_leaf_info(&l->
list, li);
1111 li = leaf_info_new(plen);
1118 fa_head = &li->
falh;
1119 insert_leaf_info(&l->
list, li);
1121 if (t->
trie && n == NULL) {
1126 cindex = tkey_extract_bits(key, tp->
pos, tp->
bits);
1141 newpos = tkey_mismatch(key, pos, n->
key);
1142 tn = tnode_new(n->
key, newpos, 1);
1145 tn = tnode_new(key, newpos, 1);
1156 missbit = tkey_extract_bits(key, newpos, 1);
1158 put_child(tn, 1-missbit, n);
1161 cindex = tkey_extract_bits(key, tp->
pos, tp->
bits);
1169 if (tp && tp->
pos + tp->
bits > 32)
1170 pr_warn(
"fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",
1171 tp, tp->
pos, tp->
bits, key, plen);
1175 trie_rebalance(t, tp);
1200 pr_debug(
"Insert table=%u %08x/%d\n", tb->
tb_id, key, plen);
1215 l = fib_find_node(t, key);
1219 fa_head = get_fa_head(l, plen);
1234 if (fa && fa->
fa_tos == tos &&
1235 fa->
fa_info->fib_priority == fi->fib_priority) {
1253 if (fa->
fa_info->fib_priority != fi->fib_priority)
1278 new_fa->fa_tos = fa->
fa_tos;
1279 new_fa->fa_info = fi;
1280 new_fa->fa_type = cfg->
fc_type;
1284 list_replace_rcu(&fa->
fa_list, &new_fa->fa_list);
1285 alias_free_mem_rcu(fa);
1314 new_fa->fa_info = fi;
1315 new_fa->fa_tos = tos;
1316 new_fa->fa_type = cfg->
fc_type;
1317 new_fa->fa_state = 0;
1323 fa_head = fib_insert_node(t, key, plen);
1326 goto out_free_new_fa;
1333 list_add_tail_rcu(&new_fa->fa_list,
1334 (fa ? &fa->
fa_list : fa_head));
1359 hlist_for_each_entry_rcu(li, node, hhead,
hlist) {
1373 if (fa->
fa_info->fib_scope < flp->flowi4_scope)
1375 fib_alias_accessed(fa);
1378 #ifdef CONFIG_IP_FIB_TRIE_STATS
1379 t->stats.semantic_match_passed++;
1385 for (nhsel = 0; nhsel < fi->
fib_nhs; nhsel++) {
1390 if (flp->flowi4_oif && flp->flowi4_oif != nh->
nh_oif)
1393 #ifdef CONFIG_IP_FIB_TRIE_STATS
1394 t->stats.semantic_match_passed++;
1409 #ifdef CONFIG_IP_FIB_TRIE_STATS
1410 t->stats.semantic_match_miss++;
1424 unsigned int pos, bits;
1426 unsigned int chopped_off;
1428 unsigned int current_prefix_length =
KEYLENGTH;
1430 t_key pref_mismatch;
1438 #ifdef CONFIG_IP_FIB_TRIE_STATS
1456 cindex = tkey_extract_bits(mask_pfx(key, current_prefix_length),
1459 n = tnode_get_child_rcu(
pn, cindex);
1462 #ifdef CONFIG_IP_FIB_TRIE_STATS
1463 t->stats.null_node_hit++;
1475 cn = (
struct tnode *)n;
1506 if (current_prefix_length < pos+bits) {
1507 if (tkey_extract_bits(cn->
key, current_prefix_length,
1508 cn->
pos - current_prefix_length)
1545 pref_mismatch = mask_pfx(cn->
key ^ key, cn->
pos);
1552 if (pref_mismatch) {
1556 if (tkey_extract_bits(cn->
key, mp, cn->
pos - mp) != 0)
1559 if (current_prefix_length >= cn->
pos)
1560 current_prefix_length =
mp;
1571 while ((chopped_off <= pn->bits)
1572 && !(cindex & (1<<(chopped_off-1))))
1576 if (current_prefix_length >
pn->pos +
pn->bits - chopped_off)
1577 current_prefix_length =
pn->pos +
pn->bits
1585 if (chopped_off <= pn->bits) {
1586 cindex &= ~(1 << (chopped_off-1));
1593 cindex = tkey_extract_bits(
pn->key, parent->
pos, parent->
bits);
1597 #ifdef CONFIG_IP_FIB_TRIE_STATS
1598 t->stats.backtrack++;
1614 static void trie_leaf_remove(
struct trie *t,
struct leaf *l)
1618 pr_debug(
"entering trie_leaf_remove(%p)\n", l);
1622 put_child(tp, cindex, NULL);
1623 trie_rebalance(t, tp);
1654 l = fib_find_node(t, key);
1659 li = find_leaf_info(l, plen);
1664 fa_head = &li->
falh;
1670 pr_debug(
"Deleting %08x/%d tos=%d t=%p\n", key, plen, tos, t);
1672 fa_to_delete =
NULL;
1705 if (list_empty(fa_head)) {
1706 hlist_del_rcu(&li->
hlist);
1710 if (hlist_empty(&l->
list))
1711 trie_leaf_remove(t, l);
1717 alias_free_mem_rcu(fa);
1721 static int trie_flush_list(
struct list_head *head)
1732 alias_free_mem_rcu(fa);
1739 static int trie_flush_leaf(
struct leaf *l)
1747 found += trie_flush_list(&li->
falh);
1749 if (list_empty(&li->
falh)) {
1750 hlist_del_rcu(&li->
hlist);
1767 idx = tkey_extract_bits(c->
key, p->
pos, p->
bits) + 1;
1771 while (idx < 1
u << p->
bits) {
1772 c = tnode_get_child_rcu(p, idx++);
1778 return (
struct leaf *)
c;
1782 p = (
struct tnode *) c;
1788 }
while ((p = node_parent_rcu(c)) != NULL);
1793 static struct leaf *trie_firstleaf(
struct trie *t)
1801 return (
struct leaf *)
n;
1803 return leaf_walk_rcu(n, NULL);
1806 static struct leaf *trie_nextleaf(
struct leaf *l)
1809 struct tnode *p = node_parent_rcu(c);
1814 return leaf_walk_rcu(p, c);
1817 static struct leaf *trie_leafindex(
struct trie *t,
int index)
1819 struct leaf *l = trie_firstleaf(t);
1821 while (l && index-- > 0)
1822 l = trie_nextleaf(l);
1834 struct leaf *l, *ll = NULL;
1837 for (l = trie_firstleaf(t);
l; l = trie_nextleaf(l)) {
1838 found += trie_flush_leaf(l);
1840 if (ll && hlist_empty(&ll->list))
1841 trie_leaf_remove(t, ll);
1845 if (ll && hlist_empty(&ll->list))
1846 trie_leaf_remove(t, ll);
1848 pr_debug(
"trie_flush found=%d\n", found);
1857 static int fn_trie_dump_fa(
t_key key,
int plen,
struct list_head *fah,
1870 list_for_each_entry_rcu(fa, fah,
fa_list) {
1894 static int fn_trie_dump_leaf(
struct leaf *l,
struct fib_table *tb,
1905 hlist_for_each_entry_rcu(li, node, &l->
list,
hlist) {
1914 if (list_empty(&li->
falh))
1917 if (fn_trie_dump_fa(l->
key, li->
plen, &li->
falh, tb, skb, cb) < 0) {
1941 l = trie_firstleaf(t);
1946 l = fib_find_node(t, key);
1948 l = trie_leafindex(t,
count);
1953 if (fn_trie_dump_leaf(l, tb, skb, cb) < 0) {
1960 l = trie_nextleaf(l);
1962 sizeof(cb->
args) - 4*
sizeof(cb->
args[0]));
1998 memset(t, 0,
sizeof(*t));
2003 #ifdef CONFIG_PROC_FS
2005 struct fib_trie_iter {
2013 static struct rt_trie_node *fib_trie_get_next(
struct fib_trie_iter *iter)
2015 struct tnode *tn = iter->tnode;
2016 unsigned int cindex = iter->index;
2023 pr_debug(
"get_next iter={node=%p index=%d depth=%d}\n",
2024 iter->tnode, iter->index, iter->depth);
2026 while (cindex < (1<<tn->
bits)) {
2027 struct rt_trie_node *n = tnode_get_child_rcu(tn, cindex);
2032 iter->index = cindex + 1;
2035 iter->tnode = (
struct tnode *) n;
2048 cindex = tkey_extract_bits(tn->
key, p->
pos, p->
bits)+1;
2058 static struct rt_trie_node *fib_trie_get_first(
struct fib_trie_iter *iter,
2071 iter->tnode = (
struct tnode *) n;
2083 static void trie_collect_stats(
struct trie *t,
struct trie_stat *
s)
2086 struct fib_trie_iter iter;
2088 memset(s, 0,
sizeof(*s));
2091 for (n = fib_trie_get_first(&iter, t);
n; n = fib_trie_get_next(&iter)) {
2102 hlist_for_each_entry_rcu(li, tmp, &l->
list,
hlist)
2105 const struct tnode *tn = (
const struct tnode *) n;
2112 for (i = 0; i < (1<<tn->
bits); i++)
2125 unsigned int i,
max, pointers,
bytes, avdepth;
2133 avdepth / 100, avdepth % 100);
2146 while (max > 0 && stat->
nodesizes[max-1] == 0)
2150 for (i = 1; i <=
max; i++)
2156 seq_printf(seq,
"\tPointers: %u\n", pointers);
2160 seq_printf(seq,
"Total size: %u kB\n", (bytes + 1023) / 1024);
2163 #ifdef CONFIG_IP_FIB_TRIE_STATS
2164 static void trie_show_usage(
struct seq_file *seq,
2165 const struct trie_use_stats *
stats)
2169 seq_printf(seq,
"backtracks = %u\n", stats->backtrack);
2170 seq_printf(seq,
"semantic match passed = %u\n",
2171 stats->semantic_match_passed);
2172 seq_printf(seq,
"semantic match miss = %u\n",
2173 stats->semantic_match_miss);
2174 seq_printf(seq,
"null node hit= %u\n", stats->null_node_hit);
2175 seq_printf(seq,
"skipped node resize = %u\n\n",
2176 stats->resize_node_skipped);
2191 static int fib_triestat_seq_show(
struct seq_file *seq,
void *
v)
2197 "Basic info: size of leaf:"
2198 " %Zd bytes, size of tnode: %Zd bytes.\n",
2199 sizeof(
struct leaf),
sizeof(
struct tnode));
2206 hlist_for_each_entry_rcu(tb, node, head,
tb_hlist) {
2213 fib_table_print(seq, tb);
2215 trie_collect_stats(t, &stat);
2216 trie_show_stats(seq, &stat);
2217 #ifdef CONFIG_IP_FIB_TRIE_STATS
2218 trie_show_usage(seq, &t->stats);
2226 static int fib_triestat_seq_open(
struct inode *inode,
struct file *
file)
2233 .open = fib_triestat_seq_open,
2241 struct fib_trie_iter *iter = seq->
private;
2242 struct net *net = seq_file_net(seq);
2251 hlist_for_each_entry_rcu(tb, node, head,
tb_hlist) {
2254 for (n = fib_trie_get_first(iter,
2256 n; n = fib_trie_get_next(iter))
2267 static void *fib_trie_seq_start(
struct seq_file *seq, loff_t *pos)
2271 return fib_trie_get_idx(seq, *pos);
2274 static void *fib_trie_seq_next(
struct seq_file *seq,
void *v, loff_t *pos)
2276 struct fib_trie_iter *iter = seq->
private;
2277 struct net *net = seq_file_net(seq);
2285 n = fib_trie_get_next(iter);
2290 h = tb->
tb_id & (FIB_TABLE_HASHSZ - 1);
2293 n = fib_trie_get_first(iter, (
struct trie *) tb->
tb_data);
2299 while (++h < FIB_TABLE_HASHSZ) {
2301 hlist_for_each_entry_rcu(tb, tb_node, head, tb_hlist) {
2302 n = fib_trie_get_first(iter, (
struct trie *) tb->
tb_data);
2314 static void fib_trie_seq_stop(
struct seq_file *seq,
void *v)
2320 static void seq_indent(
struct seq_file *seq,
int n)
2326 static inline const char *rtn_scope(
char *
buf,
size_t len,
enum rt_scope_t s)
2340 static const char *
const rtn_type_names[
__RTN_MAX] = {
2355 static inline const char *rtn_type(
char *buf,
size_t len,
unsigned int t)
2358 return rtn_type_names[
t];
2364 static int fib_trie_seq_show(
struct seq_file *seq,
void *v)
2366 const struct fib_trie_iter *iter = seq->
private;
2369 if (!node_parent_rcu(n))
2370 fib_table_print(seq, iter->tb);
2376 seq_indent(seq, iter->depth-1);
2382 struct leaf *l = (
struct leaf *) n;
2387 seq_indent(seq, iter->depth);
2390 hlist_for_each_entry_rcu(li, node, &l->
list,
hlist) {
2394 char buf1[32], buf2[32];
2396 seq_indent(seq, iter->depth+1);
2398 rtn_scope(buf1,
sizeof(buf1),
2400 rtn_type(buf2,
sizeof(buf2),
2413 .
start = fib_trie_seq_start,
2414 .next = fib_trie_seq_next,
2415 .stop = fib_trie_seq_stop,
2416 .show = fib_trie_seq_show,
2419 static int fib_trie_seq_open(
struct inode *inode,
struct file *
file)
2422 sizeof(
struct fib_trie_iter));
2427 .open = fib_trie_seq_open,
2433 struct fib_route_iter {
2435 struct trie *main_trie;
2440 static struct leaf *fib_route_get_idx(
struct fib_route_iter *iter, loff_t pos)
2443 struct trie *t = iter->main_trie;
2446 if (iter->pos > 0 && pos >= iter->pos && (l = fib_find_node(t, iter->key)))
2450 l = trie_firstleaf(t);
2453 while (l && pos-- > 0) {
2455 l = trie_nextleaf(l);
2466 static void *fib_route_seq_start(
struct seq_file *seq, loff_t *pos)
2469 struct fib_route_iter *iter = seq->
private;
2481 return fib_route_get_idx(iter, *pos - 1);
2484 static void *fib_route_seq_next(
struct seq_file *seq,
void *v, loff_t *pos)
2486 struct fib_route_iter *iter = seq->
private;
2492 l = trie_firstleaf(iter->main_trie);
2495 l = trie_nextleaf(l);
2505 static void fib_route_seq_stop(
struct seq_file *seq,
void *v)
2513 unsigned int flags = 0;
2517 if (fi && fi->
fib_nh->nh_gw)
2519 if (mask ==
htonl(0xFFFFFFFF))
2531 static int fib_route_seq_show(
struct seq_file *seq,
void *v)
2538 seq_printf(seq,
"%-127s\n",
"Iface\tDestination\tGateway "
2539 "\tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU"
2544 hlist_for_each_entry_rcu(li, node, &l->
list,
hlist) {
2548 mask = inet_make_mask(li->
plen);
2553 unsigned int flags = fib_flag_trans(fa->
fa_type, mask, fi);
2562 "%s\t%08X\t%08X\t%04X\t%d\t%u\t"
2563 "%d\t%08X\t%d\t%u\t%u%n",
2564 fi->fib_dev ? fi->fib_dev->name :
"*",
2566 fi->
fib_nh->nh_gw, flags, 0, 0,
2570 fi->fib_advmss + 40 : 0),
2572 fi->fib_rtt >> 3, &len);
2575 "*\t%08X\t%08X\t%04X\t%d\t%u\t"
2576 "%d\t%08X\t%d\t%u\t%u%n",
2577 prefix, 0, flags, 0, 0, 0,
2578 mask, 0, 0, 0, &len);
2588 .
start = fib_route_seq_start,
2589 .next = fib_route_seq_next,
2590 .stop = fib_route_seq_stop,
2591 .show = fib_route_seq_show,
2594 static int fib_route_seq_open(
struct inode *inode,
struct file *file)
2597 sizeof(
struct fib_route_iter));
2602 .open = fib_route_seq_open,
2608 int __net_init fib_proc_init(
struct net *net)
2614 &fib_triestat_fops))
2630 void __net_exit fib_proc_exit(
struct net *net)