name='generator' content='cgit v1.2.2'/>
aboutsummaryrefslogblamecommitdiffstats
path: root/net/ipv6/ip6_fib.c
blob: b6a585909d3560d0f9c0396fe8ed4b136c0ef5f6 (plain) (tree)
1
2
3
4
5
6
7
  
                                  


                                       
                                                   
  










                                                                     
                                                       
   






                            
                       
                       



















                                            
                                                        














                               
                        



                                                  
                                       


                           

                      

      

                                                                    

                                                                                 

                                                       









                                                                            

                                                

                                                                
 


                                                            
                                        





                                                              
                         

                                           










                                                            
                                                                





                         




                                           
 
                                                              
 
                             






                                                            

                                                                               

 



                                                     
                                                           











                                                       
                                   

 
                                                                   


                       





                                                                         
                                                 




                                                                    
                                                                         
 
 
                                  
 
                                                                   





                                                    
                                                                





                                                                               
                                                          




                                    
                                     


                          
                                       
                       
                                         



                  
                                                          

                              
                                




                                    
                                         
                        

                                                             









                                          
                                                        
 

                                                       
 

     
                                                          
 
                                       

 
                                                          
 
                                         

 

                                                                     
 
                                                                                    

 
                                                        
 
                                                      



      




                                                  
                                                       





                                                            
                                  









                                                      



                                              






















                                                                         


                             


                                                 
                              
                                        

                                                         
                








                                                                   


                                                 


                                              
                 
         
 


                   
                                                                           
 
                                            





                                     
                                

























                                                     
                      

                       
                                                            
                      

                                                                 

















                                                           
















                                                                        
                        
















                                                                     
 


                                     
 





                                                               
 
                                               
 





                                               
 
















                                                      
 












                               
                                                               









                                                                
                                                                        

                                                                  
 
                                                          
 

                                          





                                                  
 







                                               

                                         



































                                                                    
                  














                                                   
 



















                                                                      
                                                 





                                     
                                                              


























                                                                         
                                          

         



                                                   



                           
                                


                                  
                                                
                                                       

                                               
                                                                





                                           
                                                                          
 
                                                       
                                                       
                                                   
                                                                         

 
                                         
 

                                                     
                                                                         







                                                    
                                                                               
 
                                         







                                                                                

                





















                                                             

                                                                                 




















                                                                                   








                                                                                   



                                                  



                        
                                             

                       
                                                
                                                
                                                                


         





                                                                         



                                                  
                                                                            
                                                                      

                                        
                                                          
                                                                             




                                                        
                                   
         







                                                           
                                                   
                           

















                                                                          
                   
 


                                        




















                                                           
                   
                                                                    




                                                                  







                                                                                   

                 


                                            








                                                                              
                             




                                                                      
                           



                                                                      
      



                                                      
 
                                                          





















































                                                                                
                                       

                                                                       















                                                                                
                                                                               

                                  
                                                







                                               
                                      








                                                                         

                                                                










                                                                              


                                                    





                                                                
                                                     




                                                                   
                                                             

                                             
                                                   
                                                                    







                                                        
                                             
                                                            
                                                

                                       
                                                         



                                                                  

                                           






































                                                                                                                
                                                                








                                                                       
                                                


                                   
                                       



                                      
                                
                             

                                                    
 



                                                   




                                                                         
                                                   





                                                 
                                
 


                                                               
                                                       
                                               










                                                                               
                                                                     





                                                                    
                                                        

         
                                                


                        
                                                       
 
                                       



                                             
                                 
                                    


                               
                                                         

                               
                                              
 









                                                                      
                                                        
         




                                                         
                                                                  
                                 
                                                      












                                                                               
                                                       















                                                                   
                                                      















                                                                  

                                                           


                                         
      
















                                                                 







                                                         

                                                   

                                           








                                          
                                                     
                                                                    













                                                        
                                   




                 
                                             
















                                                   
                                                                             


                                 
 
                                                       


                                          
                                                  







                                                                                                                            
                                  






                                           
  







                                                               
                                                                    

                                                                      





                                   

                      

                      
                    



                        
                                                                               

                                         
                                 
                                
                                
                       
 
                        
                                                 
                                                    
                                                                        
                                                        

                                                              


                                                          
                          

 









                                                           

                                                                    
 
                                                          


























                                                               



                                                

                                                                            















                                                                                  
                                                        
 
                              
                                            

                                                            
                
                                                      
                                                                          

                               
                                                                      
         
 
                                      
 
                                               

                         


                                                                                

                                                    


                                      




                                               
                                                    
 
                                                                                    
 



                                                                                
                                                             

                                                                             
                                      
                                   
 


                                                                           

                                        
                                                         
                                                                          

                                                    

                                  


                                                                             
                                       
                                                           
                                                                           

                                                     
      
                              
 
                 
 
                                  
                  
                                       
      
                   
                                        

                                   
          
                       



                                          
                              

                                                 




                                        
                                   









                                                
 








                                                                    
                                           








                                                                            


                                           



                          
                                                

                                           
/*
 *	Linux INET6 implementation
 *	Forwarding Information Database
 *
 *	Authors:
 *	Pedro Roque		<roque@di.fc.ul.pt>
 *
 *	This program is free software; you can redistribute it and/or
 *      modify it under the terms of the GNU General Public License
 *      as published by the Free Software Foundation; either version
 *      2 of the License, or (at your option) any later version.
 */

/*
 * 	Changes:
 * 	Yuji SEKIYA @USAGI:	Support default route on router node;
 * 				remove ip6_null_entry from the top of
 * 				routing table.
 * 	Ville Nuorvala:		Fixed routing subtrees.
 */
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/net.h>
#include <linux/route.h>
#include <linux/netdevice.h>
#include <linux/in6.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/slab.h>

#ifdef 	CONFIG_PROC_FS
#include <linux/proc_fs.h>
#endif

#include <net/ipv6.h>
#include <net/ndisc.h>
#include <net/addrconf.h>

#include <net/ip6_fib.h>
#include <net/ip6_route.h>

#define RT6_DEBUG 2

#if RT6_DEBUG >= 3
#define RT6_TRACE(x...) printk(KERN_DEBUG x)
#else
#define RT6_TRACE(x...) do { ; } while (0)
#endif

static struct kmem_cache * fib6_node_kmem __read_mostly;

enum fib_walk_state_t
{
#ifdef CONFIG_IPV6_SUBTREES
	FWS_S,
#endif
	FWS_L,
	FWS_R,
	FWS_C,
	FWS_U
};

struct fib6_cleaner_t
{
	struct fib6_walker_t w;
	struct net *net;
	int (*func)(struct rt6_info *, void *arg);
	void *arg;
};

static DEFINE_RWLOCK(fib6_walker_lock);

#ifdef CONFIG_IPV6_SUBTREES
#define FWS_INIT FWS_S
#else
#define FWS_INIT FWS_L
#endif

static void fib6_prune_clones(struct net *net, struct fib6_node *fn,
			      struct rt6_info *rt);
static struct rt6_info *fib6_find_prefix(struct net *net, struct fib6_node *fn);
static struct fib6_node *fib6_repair_tree(struct net *net, struct fib6_node *fn);
static int fib6_walk(struct fib6_walker_t *w);
static int fib6_walk_continue(struct fib6_walker_t *w);

/*
 *	A routing update causes an increase of the serial number on the
 *	affected subtree. This allows for cached routes to be asynchronously
 *	tested when modifications are made to the destination cache as a
 *	result of redirects, path MTU changes, etc.
 */

static __u32 rt_sernum;

static void fib6_gc_timer_cb(unsigned long arg);

static LIST_HEAD(fib6_walkers);
#define FOR_WALKERS(w) list_for_each_entry(w, &fib6_walkers, lh)

static inline void fib6_walker_link(struct fib6_walker_t *w)
{
	write_lock_bh(&fib6_walker_lock);
	list_add(&w->lh, &fib6_walkers);
	write_unlock_bh(&fib6_walker_lock);
}

static inline void fib6_walker_unlink(struct fib6_walker_t *w)
{
	write_lock_bh(&fib6_walker_lock);
	list_del(&w->lh);
	write_unlock_bh(&fib6_walker_lock);
}
static __inline__ u32 fib6_new_sernum(void)
{
	u32 n = ++rt_sernum;
	if ((__s32)n <= 0)
		rt_sernum = n = 1;
	return n;
}

/*
 *	Auxiliary address test functions for the radix tree.
 *
 *	These assume a 32bit processor (although it will work on
 *	64bit processors)
 */

/*
 *	test bit
 */
#if defined(__LITTLE_ENDIAN)
# define BITOP_BE32_SWIZZLE	(0x1F & ~7)
#else
# define BITOP_BE32_SWIZZLE	0
#endif

static __inline__ __be32 addr_bit_set(void *token, int fn_bit)
{
	__be32 *addr = token;
	/*
	 * Here,
	 * 	1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)
	 * is optimized version of
	 *	htonl(1 << ((~fn_bit)&0x1F))
	 * See include/asm-generic/bitops/le.h.
	 */
	return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) &
	       addr[fn_bit >> 5];
}

static __inline__ struct fib6_node * node_alloc(void)
{
	struct fib6_node *fn;

	fn = kmem_cache_zalloc(fib6_node_kmem, GFP_ATOMIC);

	return fn;
}

static __inline__ void node_free(struct fib6_node * fn)
{
	kmem_cache_free(fib6_node_kmem, fn);
}

static __inline__ void rt6_release(struct rt6_info *rt)
{
	if (atomic_dec_and_test(&rt->rt6i_ref))
		dst_free(&rt->dst);
}

static void fib6_link_table(struct net *net, struct fib6_table *tb)
{
	unsigned int h;

	/*
	 * Initialize table lock at a single place to give lockdep a key,
	 * tables aren't visible prior to being linked to the list.
	 */
	rwlock_init(&tb->tb6_lock);

	h = tb->tb6_id & (FIB6_TABLE_HASHSZ - 1);

	/*
	 * No protection necessary, this is the only list mutatation
	 * operation, tables never disappear once they exist.
	 */
	hlist_add_head_rcu(&tb->tb6_hlist, &net->ipv6.fib_table_hash[h]);
}

#ifdef CONFIG_IPV6_MULTIPLE_TABLES

static struct fib6_table *fib6_alloc_table(struct net *net, u32 id)
{
	struct fib6_table *table;

	table = kzalloc(sizeof(*table), GFP_ATOMIC);
	if (table != NULL) {
		table->tb6_id = id;
		table->tb6_root.leaf = net->ipv6.ip6_null_entry;
		table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO;
	}

	return table;
}

struct fib6_table *fib6_new_table(struct net *net, u32 id)
{
	struct fib6_table *tb;

	if (id == 0)
		id = RT6_TABLE_MAIN;
	tb = fib6_get_table(net, id);
	if (tb)
		return tb;

	tb = fib6_alloc_table(net, id);
	if (tb != NULL)
		fib6_link_table(net, tb);

	return tb;
}

struct fib6_table *fib6_get_table(struct net *net, u32 id)
{