ip6_fib.c (05668381140309088443bf5dc53add4104610fbb) | ip6_fib.c (c71099acce933455123ee505cc75964610a209ad) |
---|---|
1/* 2 * Linux INET6 implementation 3 * Forwarding Information Database 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $ --- 12 unchanged lines hidden (view full) --- 21 */ 22#include <linux/errno.h> 23#include <linux/types.h> 24#include <linux/net.h> 25#include <linux/route.h> 26#include <linux/netdevice.h> 27#include <linux/in6.h> 28#include <linux/init.h> | 1/* 2 * Linux INET6 implementation 3 * Forwarding Information Database 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * $Id: ip6_fib.c,v 1.25 2001/10/31 21:55:55 davem Exp $ --- 12 unchanged lines hidden (view full) --- 21 */ 22#include <linux/errno.h> 23#include <linux/types.h> 24#include <linux/net.h> 25#include <linux/route.h> 26#include <linux/netdevice.h> 27#include <linux/in6.h> 28#include <linux/init.h> |
29#include <linux/list.h> |
|
29 30#ifdef CONFIG_PROC_FS 31#include <linux/proc_fs.h> 32#endif 33 34#include <net/ipv6.h> 35#include <net/ndisc.h> 36#include <net/addrconf.h> --- 105 unchanged lines hidden (view full) --- 142} 143 144static __inline__ void rt6_release(struct rt6_info *rt) 145{ 146 if (atomic_dec_and_test(&rt->rt6i_ref)) 147 dst_free(&rt->u.dst); 148} 149 | 30 31#ifdef CONFIG_PROC_FS 32#include <linux/proc_fs.h> 33#endif 34 35#include <net/ipv6.h> 36#include <net/ndisc.h> 37#include <net/addrconf.h> --- 105 unchanged lines hidden (view full) --- 143} 144 145static __inline__ void rt6_release(struct rt6_info *rt) 146{ 147 if (atomic_dec_and_test(&rt->rt6i_ref)) 148 dst_free(&rt->u.dst); 149} 150 |
151static struct fib6_table fib6_main_tbl = { 152 .tb6_id = RT6_TABLE_MAIN, 153 .tb6_lock = RW_LOCK_UNLOCKED, 154 .tb6_root = { 155 .leaf = &ip6_null_entry, 156 .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, 157 }, 158}; |
|
150 | 159 |
160#ifdef CONFIG_IPV6_MULTIPLE_TABLES 161 162#define FIB_TABLE_HASHSZ 256 163static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ]; 164 165static struct fib6_table *fib6_alloc_table(u32 id) 166{ 167 struct fib6_table *table; 168 169 table = kzalloc(sizeof(*table), GFP_ATOMIC); 170 if (table != NULL) { 171 table->tb6_id = id; 172 table->tb6_lock = RW_LOCK_UNLOCKED; 173 table->tb6_root.leaf = &ip6_null_entry; 174 table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; 175 } 176 177 return table; 178} 179 180static void fib6_link_table(struct fib6_table *tb) 181{ 182 unsigned int h; 183 184 h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); 185 186 /* 187 * No protection necessary, this is the only list mutatation 188 * operation, tables never disappear once they exist. 189 */ 190 hlist_add_head_rcu(&tb->tb6_hlist, &fib_table_hash[h]); 191} 192 193struct fib6_table *fib6_new_table(u32 id) 194{ 195 struct fib6_table *tb; 196 197 if (id == 0) 198 id = RT6_TABLE_MAIN; 199 tb = fib6_get_table(id); 200 if (tb) 201 return tb; 202 203 tb = fib6_alloc_table(id); 204 if (tb != NULL) 205 fib6_link_table(tb); 206 207 return tb; 208} 209 210struct fib6_table *fib6_get_table(u32 id) 211{ 212 struct fib6_table *tb; 213 struct hlist_node *node; 214 unsigned int h; 215 216 if (id == 0) 217 id = RT6_TABLE_MAIN; 218 h = id & (FIB_TABLE_HASHSZ - 1); 219 rcu_read_lock(); 220 hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb6_hlist) { 221 if (tb->tb6_id == id) { 222 rcu_read_unlock(); 223 return tb; 224 } 225 } 226 rcu_read_unlock(); 227 228 return NULL; 229} 230 231struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, 232 pol_lookup_t lookup) 233{ 234 /* 235 * TODO: Add rule lookup 236 */ 237 struct fib6_table *table = fib6_get_table(RT6_TABLE_MAIN); 238 239 return (struct dst_entry *) lookup(table, fl, flags); 240} 241 242static void __init fib6_tables_init(void) 243{ 244 fib6_link_table(&fib6_main_tbl); 245} 246 247#else 248 249struct fib6_table *fib6_new_table(u32 id) 250{ 251 return fib6_get_table(id); 252} 253 254struct fib6_table *fib6_get_table(u32 id) 255{ 256 return &fib6_main_tbl; 257} 258 259struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags, 260 pol_lookup_t lookup) 261{ 262 return (struct dst_entry *) lookup(&fib6_main_tbl, fl, flags); 263} 264 265static void __init fib6_tables_init(void) 266{ 267} 268 269#endif 270 271 |
|
151/* 152 * Routing Table 153 * 154 * return the appropriate node for a routing tree "add" operation 155 * by either creating and inserting or by returning an existing 156 * node. 157 */ 158 --- 900 unchanged lines hidden (view full) --- 1059 c.w.func = fib6_clean_node; 1060 c.w.prune = prune; 1061 c.func = func; 1062 c.arg = arg; 1063 1064 fib6_walk(&c.w); 1065} 1066 | 272/* 273 * Routing Table 274 * 275 * return the appropriate node for a routing tree "add" operation 276 * by either creating and inserting or by returning an existing 277 * node. 278 */ 279 --- 900 unchanged lines hidden (view full) --- 1180 c.w.func = fib6_clean_node; 1181 c.w.prune = prune; 1182 c.func = func; 1183 c.arg = arg; 1184 1185 fib6_walk(&c.w); 1186} 1187 |
1188void fib6_clean_all(int (*func)(struct rt6_info *, void *arg), 1189 int prune, void *arg) 1190{ 1191 int i; 1192 struct fib6_table *table; 1193 1194 for (i = FIB6_TABLE_MIN; i <= FIB6_TABLE_MAX; i++) { 1195 table = fib6_get_table(i); 1196 if (table != NULL) { 1197 write_lock_bh(&table->tb6_lock); 1198 fib6_clean_tree(&table->tb6_root, func, prune, arg); 1199 write_unlock_bh(&table->tb6_lock); 1200 } 1201 } 1202} 1203 |
|
1067static int fib6_prune_clone(struct rt6_info *rt, void *arg) 1068{ 1069 if (rt->rt6i_flags & RTF_CACHE) { 1070 RT6_TRACE("pruning clone %p\n", rt); 1071 return -1; 1072 } 1073 1074 return 0; --- 62 unchanged lines hidden (view full) --- 1137 mod_timer(&ip6_fib_timer, jiffies + HZ); 1138 local_bh_enable(); 1139 return; 1140 } 1141 gc_args.timeout = ip6_rt_gc_interval; 1142 } 1143 gc_args.more = 0; 1144 | 1204static int fib6_prune_clone(struct rt6_info *rt, void *arg) 1205{ 1206 if (rt->rt6i_flags & RTF_CACHE) { 1207 RT6_TRACE("pruning clone %p\n", rt); 1208 return -1; 1209 } 1210 1211 return 0; --- 62 unchanged lines hidden (view full) --- 1274 mod_timer(&ip6_fib_timer, jiffies + HZ); 1275 local_bh_enable(); 1276 return; 1277 } 1278 gc_args.timeout = ip6_rt_gc_interval; 1279 } 1280 gc_args.more = 0; 1281 |
1145 1146 write_lock_bh(&rt6_lock); | |
1147 ndisc_dst_gc(&gc_args.more); | 1282 ndisc_dst_gc(&gc_args.more); |
1148 fib6_clean_tree(&ip6_routing_table, fib6_age, 0, NULL); 1149 write_unlock_bh(&rt6_lock); | 1283 fib6_clean_all(fib6_age, 0, NULL); |
1150 1151 if (gc_args.more) 1152 mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); 1153 else { 1154 del_timer(&ip6_fib_timer); 1155 ip6_fib_timer.expires = 0; 1156 } 1157 spin_unlock_bh(&fib6_gc_lock); 1158} 1159 1160void __init fib6_init(void) 1161{ 1162 fib6_node_kmem = kmem_cache_create("fib6_nodes", 1163 sizeof(struct fib6_node), 1164 0, SLAB_HWCACHE_ALIGN, 1165 NULL, NULL); 1166 if (!fib6_node_kmem) 1167 panic("cannot create fib6_nodes cache"); | 1284 1285 if (gc_args.more) 1286 mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval); 1287 else { 1288 del_timer(&ip6_fib_timer); 1289 ip6_fib_timer.expires = 0; 1290 } 1291 spin_unlock_bh(&fib6_gc_lock); 1292} 1293 1294void __init fib6_init(void) 1295{ 1296 fib6_node_kmem = kmem_cache_create("fib6_nodes", 1297 sizeof(struct fib6_node), 1298 0, SLAB_HWCACHE_ALIGN, 1299 NULL, NULL); 1300 if (!fib6_node_kmem) 1301 panic("cannot create fib6_nodes cache"); |
1302 1303 fib6_tables_init(); |
|
1168} 1169 1170void fib6_gc_cleanup(void) 1171{ 1172 del_timer(&ip6_fib_timer); 1173 kmem_cache_destroy(fib6_node_kmem); 1174} | 1304} 1305 1306void fib6_gc_cleanup(void) 1307{ 1308 del_timer(&ip6_fib_timer); 1309 kmem_cache_destroy(fib6_node_kmem); 1310} |