2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  INET 		An  implementation  of  the  TCP / IP  protocol  suite  for  the  LINUX 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 		operating  system .   INET  is  implemented  using  the   BSD  Socket 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 		interface  as  the  means  of  communication  with  the  user  level . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 		Routing  netlink  socket  interface :  protocol  independent  part . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Authors : 	Alexey  Kuznetsov ,  < kuznet @ ms2 . inr . ac . ru > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 		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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	Fixes : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 	Vitaly  E .  Lavrov 		RTA_OK  arithmetics  was  wrong . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/errno.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/module.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/types.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/socket.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/kernel.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/timer.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/string.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/sockios.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/net.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/fcntl.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/mm.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/slab.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/interrupt.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/capability.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/skbuff.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/init.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/security.h> 
  
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/mutex.h> 
  
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:04:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/if_addr.h> 
  
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/if_bridge.h> 
  
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/pci.h> 
  
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <linux/etherdevice.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <asm/uaccess.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/inet.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <linux/netdevice.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/ip.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/protocol.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/arp.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/route.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/udp.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/sock.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <net/pkt_sched.h> 
  
						 
					
						
							
								
									
										
										
										
											2006-08-04 03:38:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <net/fib_rules.h> 
  
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <net/rtnetlink.h> 
  
						 
					
						
							
								
									
										
										
										
											2009-07-10 09:51:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <net/net_namespace.h> 
  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  rtnl_link  {  
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_doit_func 		doit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_dumpit_func 	dumpit ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_calcit_func  	calcit ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  DEFINE_MUTEX ( rtnl_mutex ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  rtnl_lock ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mutex_lock ( & rtnl_mutex ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_lock ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  __rtnl_unlock ( void )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									mutex_unlock ( & rtnl_mutex ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  rtnl_unlock ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-10-07 15:50:03 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* This fellow will unlock it for us. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									netdev_run_todo ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_unlock ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  rtnl_trylock ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  mutex_trylock ( & rtnl_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_trylock ) ;  
						 
					
						
							
								
									
										
										
										
											2006-03-20 22:23:58 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-23 22:10:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  rtnl_is_locked ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  mutex_is_locked ( & rtnl_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_is_locked ) ;  
						 
					
						
							
								
									
										
										
										
											2008-04-23 22:10:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-22 17:04:49 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_PROVE_LOCKING 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  lockdep_rtnl_is_held ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  lockdep_is_held ( & rtnl_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( lockdep_rtnl_is_held ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif  /* #ifdef CONFIG_PROVE_LOCKING */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 16:02:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  rtnl_link  * rtnl_msg_handlers [ RTNL_FAMILY_MAX  +  1 ] ;  
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  int  rtm_msgindex ( int  msgtype )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  msgindex  =  msgtype  -  RTM_BASE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  msgindex  <  0  implies  someone  tried  to  register  a  netlink 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  control  code .  msgindex  > =  RTM_NR_MSGTYPES  may  indicate  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  the  message  type  has  not  been  added  to  linux / rtnetlink . h 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BUG_ON ( msgindex  <  0  | |  msgindex  > =  RTM_NR_MSGTYPES ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  msgindex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  rtnl_doit_func  rtnl_get_doit ( int  protocol ,  int  msgindex )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtnl_link  * tab ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 16:02:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( protocol  < =  RTNL_FAMILY_MAX ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-13 05:03:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tab  =  rtnl_msg_handlers [ protocol ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 21:41:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tab  = =  NULL  | |  tab [ msgindex ] . doit  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tab  =  rtnl_msg_handlers [ PF_UNSPEC ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-22 22:21:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  tab [ msgindex ] . doit ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  rtnl_dumpit_func  rtnl_get_dumpit ( int  protocol ,  int  msgindex )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtnl_link  * tab ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 16:02:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( protocol  < =  RTNL_FAMILY_MAX ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-13 05:03:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tab  =  rtnl_msg_handlers [ protocol ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 21:41:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tab  = =  NULL  | |  tab [ msgindex ] . dumpit  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tab  =  rtnl_msg_handlers [ PF_UNSPEC ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-22 22:21:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  tab [ msgindex ] . dumpit ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  rtnl_calcit_func  rtnl_get_calcit ( int  protocol ,  int  msgindex )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtnl_link  * tab ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( protocol  < =  RTNL_FAMILY_MAX ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab  =  rtnl_msg_handlers [ protocol ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tab  = =  NULL  | |  tab [ msgindex ] . calcit  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab  =  rtnl_msg_handlers [ PF_UNSPEC ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-22 22:21:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  tab [ msgindex ] . calcit ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  __rtnl_register  -  Register  a  rtnetlink  message  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ protocol :  Protocol  family  or  PF_UNSPEC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ msgtype :  rtnetlink  message  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ doit :  Function  pointer  called  for  each  request  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ dumpit :  Function  pointer  called  for  each  dump  request  ( NLM_F_DUMP )  message 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ calcit :  Function  pointer  to  calc  size  of  dump  message 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Registers  the  specified  function  pointers  ( at  least  one  of  them  has 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  to  be  non - NULL )  to  be  called  whenever  a  request  message  for  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  specified  protocol  family  and  message  type  is  received . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  special  protocol  family  PF_UNSPEC  may  be  used  to  define  fallback 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  function  pointers  for  the  case  when  no  entry  for  the  specific  protocol 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  family  exists . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  on  success  or  a  negative  error  code . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  __rtnl_register ( int  protocol ,  int  msgtype ,  
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    rtnl_doit_func  doit ,  rtnl_dumpit_func  dumpit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    rtnl_calcit_func  calcit ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtnl_link  * tab ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  msgindex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 16:02:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( protocol  <  0  | |  protocol  >  RTNL_FAMILY_MAX ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									msgindex  =  rtm_msgindex ( msgtype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tab  =  rtnl_msg_handlers [ protocol ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tab  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab  =  kcalloc ( RTM_NR_MSGTYPES ,  sizeof ( * tab ) ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tab  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - ENOBUFS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtnl_msg_handlers [ protocol ]  =  tab ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( doit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab [ msgindex ] . doit  =  doit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dumpit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab [ msgindex ] . dumpit  =  dumpit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( calcit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tab [ msgindex ] . calcit  =  calcit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( __rtnl_register ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  rtnl_register  -  Register  a  rtnetlink  message  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Identical  to  __rtnl_register ( )  but  panics  on  failure .  This  is  useful 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  as  failure  of  this  function  is  very  unlikely ,  it  can  only  happen  due 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  to  lack  of  memory  when  allocating  the  chain  to  store  all  message 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  handlers  for  a  protocol .  Meant  for  use  in  init  functions  where  lack 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-30 22:57:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  of  memory  implies  no  sense  in  continuing . 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  rtnl_register ( int  protocol ,  int  msgtype ,  
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										   rtnl_doit_func  doit ,  rtnl_dumpit_func  dumpit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   rtnl_calcit_func  calcit ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( __rtnl_register ( protocol ,  msgtype ,  doit ,  dumpit ,  calcit )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										panic ( " Unable to register rtnetlink message handler,  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      " protocol = %d, message type = %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      protocol ,  msgtype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_register ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  rtnl_unregister  -  Unregister  a  rtnetlink  message  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ protocol :  Protocol  family  or  PF_UNSPEC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ msgtype :  rtnetlink  message  type 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  on  success  or  a  negative  error  code . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  rtnl_unregister ( int  protocol ,  int  msgtype )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  msgindex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 16:02:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( protocol  <  0  | |  protocol  >  RTNL_FAMILY_MAX ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									msgindex  =  rtm_msgindex ( msgtype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtnl_msg_handlers [ protocol ]  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENOENT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_msg_handlers [ protocol ] [ msgindex ] . doit  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_msg_handlers [ protocol ] [ msgindex ] . dumpit  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_unregister ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  rtnl_unregister_all  -  Unregister  all  rtnetlink  message  type  of  a  protocol 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ protocol  :  Protocol  family  or  PF_UNSPEC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Identical  to  calling  rtnl_unregster ( )  for  all  registered  message  types 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  of  a  certain  protocol  family . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  rtnl_unregister_all ( int  protocol )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-04-26 16:02:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BUG_ON ( protocol  <  0  | |  protocol  >  RTNL_FAMILY_MAX ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									kfree ( rtnl_msg_handlers [ protocol ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_msg_handlers [ protocol ]  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_unregister_all ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  LIST_HEAD ( link_ops ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-13 11:38:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  rtnl_link_ops  * rtnl_link_ops_get ( const  char  * kind )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry ( ops ,  & link_ops ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( ops - > kind ,  kind ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  __rtnl_link_register  -  Register  rtnl_link_ops  with  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_link_ops  *  to  register 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  caller  must  hold  the  rtnl_mutex .  This  function  should  be  used 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  by  drivers  that  create  devices  during  module  initialization .  It 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  must  be  called  before  registering  the  devices . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  on  success  or  a  negative  error  code . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  __rtnl_link_register ( struct  rtnl_link_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2011-12-13 11:38:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( rtnl_link_ops_get ( ops - > kind ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EEXIST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-11 19:42:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ops - > dellink ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-27 07:06:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ops - > dellink  =  unregister_netdevice_queue ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-11 19:42:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_add_tail ( & ops - > list ,  & link_ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( __rtnl_link_register ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  rtnl_link_register  -  Register  rtnl_link_ops  with  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_link_ops  *  to  register 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  on  success  or  a  negative  error  code . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  rtnl_link_register ( struct  rtnl_link_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  __rtnl_link_register ( ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_link_register ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-16 00:46:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __rtnl_kill_links ( struct  net  * net ,  struct  rtnl_link_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-27 07:06:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									LIST_HEAD ( list_kill ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-16 00:46:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for_each_netdev ( net ,  dev )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-27 07:06:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( dev - > rtnl_link_ops  = =  ops ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ops - > dellink ( dev ,  & list_kill ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-16 00:46:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-27 07:06:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unregister_netdevice_many ( & list_kill ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-16 00:46:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  __rtnl_link_unregister  -  Unregister  rtnl_link_ops  from  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_link_ops  *  to  unregister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-11 19:42:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  The  caller  must  hold  the  rtnl_mutex . 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  __rtnl_link_unregister ( struct  rtnl_link_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-09-17 11:56:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-11 19:42:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 11:56:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for_each_net ( net )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-16 00:46:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										__rtnl_kill_links ( net ,  ops ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-11 19:42:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_del ( & ops - > list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( __rtnl_link_unregister ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  rtnl_link_unregister  -  Unregister  rtnl_link_ops  from  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_link_ops  *  to  unregister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  rtnl_link_unregister ( struct  rtnl_link_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__rtnl_link_unregister ( ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_link_unregister ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  size_t  rtnl_link_get_size ( const  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops  =  dev - > rtnl_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ops ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-11 15:47:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									size  =  nla_total_size ( sizeof ( struct  nlattr ) )  +  /* IFLA_LINKINFO */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       nla_total_size ( strlen ( ops - > kind )  +  1 ) ;   /* IFLA_INFO_KIND */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ops - > get_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* IFLA_INFO_DATA + nested data */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-11 15:47:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										size  + =  nla_total_size ( sizeof ( struct  nlattr ) )  + 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ops - > get_size ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ops - > get_xstats_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-11 15:47:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* IFLA_INFO_XSTATS */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										size  + =  nla_total_size ( ops - > get_xstats_size ( dev ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  LIST_HEAD ( rtnl_af_ops ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  struct  rtnl_af_ops  * rtnl_af_lookup ( const  int  family )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  rtnl_af_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry ( ops ,  & rtnl_af_ops ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ops - > family  = =  family ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  __rtnl_af_register  -  Register  rtnl_af_ops  with  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_af_ops  *  to  register 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  caller  must  hold  the  rtnl_mutex . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  on  success  or  a  negative  error  code . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  __rtnl_af_register ( struct  rtnl_af_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_add_tail ( & ops - > list ,  & rtnl_af_ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( __rtnl_af_register ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  rtnl_af_register  -  Register  rtnl_af_ops  with  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_af_ops  *  to  register 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  on  success  or  a  negative  error  code . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  rtnl_af_register ( struct  rtnl_af_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  __rtnl_af_register ( ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_af_register ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  __rtnl_af_unregister  -  Unregister  rtnl_af_ops  from  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_af_ops  *  to  unregister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  caller  must  hold  the  rtnl_mutex . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  __rtnl_af_unregister ( struct  rtnl_af_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_del ( & ops - > list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( __rtnl_af_unregister ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  rtnl_af_unregister  -  Unregister  rtnl_af_ops  from  rtnetlink . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ ops :  struct  rtnl_af_ops  *  to  unregister 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  rtnl_af_unregister ( struct  rtnl_af_ops  * ops )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__rtnl_af_unregister ( ops ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_af_unregister ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  size_t  rtnl_link_get_af_size ( const  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtnl_af_ops  * af_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* IFLA_AF_SPEC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size  =  nla_total_size ( sizeof ( struct  nlattr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry ( af_ops ,  & rtnl_af_ops ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( af_ops - > get_link_af_size )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* AF_* + nested data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											size  + =  nla_total_size ( sizeof ( struct  nlattr ) )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												af_ops - > get_link_af_size ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_link_fill ( struct  sk_buff  * skb ,  const  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops  =  dev - > rtnl_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * linkinfo ,  * data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									linkinfo  =  nla_nest_start ( skb ,  IFLA_LINKINFO ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( linkinfo  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nla_put_string ( skb ,  IFLA_INFO_KIND ,  ops - > kind )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err_cancel_link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ops - > fill_xstats )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  ops - > fill_xstats ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  err_cancel_link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ops - > fill_info )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										data  =  nla_nest_start ( skb ,  IFLA_INFO_DATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( data  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  err_cancel_link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  ops - > fill_info ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  err_cancel_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_nest_end ( skb ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_end ( skb ,  linkinfo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								err_cancel_data :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_cancel ( skb ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								err_cancel_link :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_cancel ( skb ,  linkinfo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-05-03 14:29:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  int  rtm_min [ RTM_NR_FAMILIES ]  =  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-05-03 14:29:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWLINK ) ]       =  NLMSG_LENGTH ( sizeof ( struct  ifinfomsg ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWADDR ) ]       =  NLMSG_LENGTH ( sizeof ( struct  ifaddrmsg ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWROUTE ) ]      =  NLMSG_LENGTH ( sizeof ( struct  rtmsg ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 03:38:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWRULE ) ]       =  NLMSG_LENGTH ( sizeof ( struct  fib_rule_hdr ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-03 14:29:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWQDISC ) ]      =  NLMSG_LENGTH ( sizeof ( struct  tcmsg ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWTCLASS ) ]     =  NLMSG_LENGTH ( sizeof ( struct  tcmsg ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWTFILTER ) ]    =  NLMSG_LENGTH ( sizeof ( struct  tcmsg ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWACTION ) ]     =  NLMSG_LENGTH ( sizeof ( struct  tcamsg ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_GETMULTICAST ) ]  =  NLMSG_LENGTH ( sizeof ( struct  rtgenmsg ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_GETANYCAST ) ]    =  NLMSG_LENGTH ( sizeof ( struct  rtgenmsg ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-05-03 14:29:39 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  int  rta_max [ RTM_NR_FAMILIES ]  =  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-05-03 14:29:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWLINK ) ]       =  IFLA_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWADDR ) ]       =  IFA_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWROUTE ) ]      =  RTA_MAX , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 03:38:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWRULE ) ]       =  FRA_MAX , 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-03 14:29:00 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWQDISC ) ]      =  TCA_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWTCLASS ) ]     =  TCA_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWTFILTER ) ]    =  TCA_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ RTM_FAM ( RTM_NEWACTION ) ]     =  TCAA_MAX , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 05:58:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  rtnetlink_send ( struct  sk_buff  * skb ,  struct  net  * net ,  u32  pid ,  unsigned  int  group ,  int  echo )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sock  * rtnl  =  net - > rtnl ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  err  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-14 19:29:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									NETLINK_CB ( skb ) . dst_group  =  group ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( echo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										atomic_inc ( & skb - > users ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netlink_broadcast ( rtnl ,  skb ,  pid ,  group ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( echo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  netlink_unicast ( rtnl ,  skb ,  pid ,  MSG_DONTWAIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  rtnl_unicast ( struct  sk_buff  * skb ,  struct  net  * net ,  u32  pid )  
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:30:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sock  * rtnl  =  net - > rtnl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:30:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nlmsg_unicast ( rtnl ,  skb ,  pid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_unicast ) ;  
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:30:25 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 23:18:28 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  rtnl_notify ( struct  sk_buff  * skb ,  struct  net  * net ,  u32  pid ,  u32  group ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 struct  nlmsghdr  * nlh ,  gfp_t  flags ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:31:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sock  * rtnl  =  net - > rtnl ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:31:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  report  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										report  =  nlmsg_report ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 23:18:28 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nlmsg_notify ( rtnl ,  skb ,  pid ,  group ,  report ,  flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:31:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_notify ) ;  
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:31:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  rtnl_set_sk_err ( struct  net  * net ,  u32  group ,  int  error )  
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:31:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sock  * rtnl  =  net - > rtnl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:31:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netlink_set_err ( rtnl ,  0 ,  group ,  error ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_set_sk_err ) ;  
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:31:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								int  rtnetlink_put_metrics ( struct  sk_buff  * skb ,  u32  * metrics )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-08-22 00:01:27 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  nlattr  * mx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ,  valid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mx  =  nla_nest_start ( skb ,  RTA_METRICS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( mx  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENOBUFS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  RTAX_MAX ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( metrics [ i ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											valid + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( nla_put_u32 ( skb ,  i + 1 ,  metrics [ i ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-22 00:01:27 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-22 22:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! valid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_nest_cancel ( skb ,  mx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-22 00:01:27 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nla_nest_end ( skb ,  mx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								nla_put_failure :  
						 
					
						
							
								
									
										
										
										
											2008-06-03 16:36:54 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nla_nest_cancel ( skb ,  mx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - EMSGSIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnetlink_put_metrics ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-11-27 09:27:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  rtnl_put_cacheinfo ( struct  sk_buff  * skb ,  struct  dst_entry  * dst ,  u32  id ,  
						 
					
						
							
								
									
										
										
										
											2012-07-10 05:06:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       long  expires ,  u32  error ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-27 09:27:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rta_cacheinfo  ci  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 21:13:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										. rta_lastuse  =  jiffies_delta_to_clock_t ( jiffies  -  dst - > lastuse ) , 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-27 09:27:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										. rta_used  =  dst - > __use , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. rta_clntref  =  atomic_read ( & ( dst - > __refcnt ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. rta_error  =  error , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. rta_id  =   id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-29 16:01:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( expires )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unsigned  long  clock ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-27 09:27:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-29 16:01:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										clock  =  jiffies_to_clock_t ( abs ( expires ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										clock  =  min_t ( unsigned  long ,  clock ,  INT_MAX ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ci . rta_expires  =  ( expires  >  0 )  ?  clock  :  - clock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-27 09:27:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nla_put ( skb ,  RTA_CACHEINFO ,  sizeof ( ci ) ,  & ci ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL_GPL ( rtnl_put_cacheinfo ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-17 18:35:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  set_operstate ( struct  net_device  * dev ,  unsigned  char  transition )  
						 
					
						
							
								
									
										
										
										
											2006-03-20 17:09:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  operstate  =  dev - > operstate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  ( transition )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 17:09:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  IF_OPER_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( operstate  = =  IF_OPER_DORMANT  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     operstate  = =  IF_OPER_UNKNOWN )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ! netif_dormant ( dev ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											operstate  =  IF_OPER_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  IF_OPER_DORMANT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( operstate  = =  IF_OPER_UP  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    operstate  = =  IF_OPER_UNKNOWN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											operstate  =  IF_OPER_DORMANT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-20 17:09:22 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 17:09:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev - > operstate  ! =  operstate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_lock_bh ( & dev_base_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev - > operstate  =  operstate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_unlock_bh ( & dev_base_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-17 18:35:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										netdev_state_change ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 17:09:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-27 02:58:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  unsigned  int  rtnl_dev_get_flags ( const  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( dev - > flags  &  ~ ( IFF_PROMISC  |  IFF_ALLMULTI ) )  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       ( dev - > gflags  &  ( IFF_PROMISC  |  IFF_ALLMULTI ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: support specifying device flags on device creation
commit e8469ed959c373c2ff9e6f488aa5a14971aebe1f
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Feb 23 20:41:30 2010 +0100
Support specifying the initial device flags when creating a device though
rtnl_link. Devices allocated by rtnl_create_link() are marked as INITIALIZING
in order to surpress netlink registration notifications. To complete setup,
rtnl_configure_link() must be called, which performs the device flag changes
and invokes the deferred notifiers if everything went well.
Two examples:
# add macvlan to eth0
#
$ ip link add link eth0 up allmulticast on type macvlan
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 26:f8:84:02:f9:2a brd ff:ff:ff:ff:ff:ff
[ROUTE]ff00::/8 dev macvlan0  table local  metric 256  mtu 1500 advmss 1440 hoplimit 0
[ROUTE]fe80::/64 dev macvlan0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 0
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500
    link/ether 26:f8:84:02:f9:2a
[ADDR]11: macvlan0    inet6 fe80::24f8:84ff:fe02:f92a/64 scope link
       valid_lft forever preferred_lft forever
[ROUTE]local fe80::24f8:84ff:fe02:f92a via :: dev lo  table local  proto none  metric 0  mtu 16436 advmss 16376 hoplimit 0
[ROUTE]default via fe80::215:e9ff:fef0:10f8 dev macvlan0  proto kernel  metric 1024  mtu 1500 advmss 1440 hoplimit 0
[NEIGH]fe80::215:e9ff:fef0:10f8 dev macvlan0 lladdr 00:15:e9:f0:10:f8 router STALE
[ROUTE]2001:6f8:974::/64 dev macvlan0  proto kernel  metric 256  expires 0sec mtu 1500 advmss 1440 hoplimit 0
[PREFIX]prefix 2001:6f8:974::/64 dev macvlan0 onlink autoconf valid 14400 preferred 131084
[ADDR]11: macvlan0    inet6 2001:6f8:974:0:24f8:84ff:fe02:f92a/64 scope global dynamic
       valid_lft 86399sec preferred_lft 14399sec
# add VLAN to eth1, eth1 is down
#
$ ip link add link eth1 up type vlan id 1000
RTNETLINK answers: Network is down
<no events>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-02-26 06:34:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  unsigned  int  rtnl_dev_combine_flags ( const  struct  net_device  * dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   const  struct  ifinfomsg  * ifm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  flags  =  ifm - > ifi_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* bugwards compatibility: ifi_change == 0 is treated as ~0 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifm - > ifi_change ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										flags  =  ( flags  &  ifm - > ifi_change )  | 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-27 02:58:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											( rtnl_dev_get_flags ( dev )  &  ~ ifm - > ifi_change ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: support specifying device flags on device creation
commit e8469ed959c373c2ff9e6f488aa5a14971aebe1f
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Feb 23 20:41:30 2010 +0100
Support specifying the initial device flags when creating a device though
rtnl_link. Devices allocated by rtnl_create_link() are marked as INITIALIZING
in order to surpress netlink registration notifications. To complete setup,
rtnl_configure_link() must be called, which performs the device flag changes
and invokes the deferred notifiers if everything went well.
Two examples:
# add macvlan to eth0
#
$ ip link add link eth0 up allmulticast on type macvlan
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 26:f8:84:02:f9:2a brd ff:ff:ff:ff:ff:ff
[ROUTE]ff00::/8 dev macvlan0  table local  metric 256  mtu 1500 advmss 1440 hoplimit 0
[ROUTE]fe80::/64 dev macvlan0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 0
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500
    link/ether 26:f8:84:02:f9:2a
[ADDR]11: macvlan0    inet6 fe80::24f8:84ff:fe02:f92a/64 scope link
       valid_lft forever preferred_lft forever
[ROUTE]local fe80::24f8:84ff:fe02:f92a via :: dev lo  table local  proto none  metric 0  mtu 16436 advmss 16376 hoplimit 0
[ROUTE]default via fe80::215:e9ff:fef0:10f8 dev macvlan0  proto kernel  metric 1024  mtu 1500 advmss 1440 hoplimit 0
[NEIGH]fe80::215:e9ff:fef0:10f8 dev macvlan0 lladdr 00:15:e9:f0:10:f8 router STALE
[ROUTE]2001:6f8:974::/64 dev macvlan0  proto kernel  metric 256  expires 0sec mtu 1500 advmss 1440 hoplimit 0
[PREFIX]prefix 2001:6f8:974::/64 dev macvlan0 onlink autoconf valid 14400 preferred 131084
[ADDR]11: macvlan0    inet6 2001:6f8:974:0:24f8:84ff:fe02:f92a/64 scope global dynamic
       valid_lft 86399sec preferred_lft 14399sec
# add VLAN to eth1, eth1 is down
#
$ ip link add link eth1 up type vlan id 1000
RTNETLINK answers: Network is down
<no events>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-02-26 06:34:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  copy_rtnl_link_stats ( struct  rtnl_link_stats  * a ,  
						 
					
						
							
								
									
										
										
										
											2010-06-08 07:19:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 const  struct  rtnl_link_stats64  * b ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									a - > rx_packets  =  b - > rx_packets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_packets  =  b - > tx_packets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_bytes  =  b - > rx_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_bytes  =  b - > tx_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_errors  =  b - > rx_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_errors  =  b - > tx_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_dropped  =  b - > rx_dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_dropped  =  b - > tx_dropped ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > multicast  =  b - > multicast ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > collisions  =  b - > collisions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_length_errors  =  b - > rx_length_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_over_errors  =  b - > rx_over_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_crc_errors  =  b - > rx_crc_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_frame_errors  =  b - > rx_frame_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_fifo_errors  =  b - > rx_fifo_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_missed_errors  =  b - > rx_missed_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_aborted_errors  =  b - > tx_aborted_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_carrier_errors  =  b - > tx_carrier_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_fifo_errors  =  b - > tx_fifo_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_heartbeat_errors  =  b - > tx_heartbeat_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_window_errors  =  b - > tx_window_errors ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > rx_compressed  =  b - > rx_compressed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a - > tx_compressed  =  b - > tx_compressed ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-11 09:57:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-08 07:19:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  copy_rtnl_link_stats64 ( void  * v ,  const  struct  rtnl_link_stats64  * b )  
						 
					
						
							
								
									
										
										
										
											2010-03-11 09:57:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-08-23 07:14:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memcpy ( v ,  b ,  sizeof ( * b ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-11 09:57:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* All VF info */  
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  int  rtnl_vfinfo_size ( const  struct  net_device  * dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   u32  ext_filter_mask ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev - > dev . parent  & &  dev_is_pci ( dev - > dev . parent )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( ext_filter_mask  &  RTEXT_FILTER_VF ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  num_vfs  =  dev_num_vf ( dev - > dev . parent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-28 03:42:43 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										size_t  size  =  nla_total_size ( sizeof ( struct  nlattr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										size  + =  nla_total_size ( num_vfs  *  sizeof ( struct  nlattr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										size  + =  num_vfs  * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											( nla_total_size ( sizeof ( struct  ifla_vf_mac ) )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 nla_total_size ( sizeof ( struct  ifla_vf_vlan ) )  + 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-08 03:05:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 nla_total_size ( sizeof ( struct  ifla_vf_tx_rate ) )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 nla_total_size ( sizeof ( struct  ifla_vf_spoofchk ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  size_t  rtnl_port_size ( const  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  port_size  =  nla_total_size ( 4 ) 		/* PORT_VF */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( PORT_PROFILE_MAX ) 	/* PORT_PROFILE */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( struct  ifla_port_vsi ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															/* PORT_VSI_TYPE */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( PORT_UUID_MAX ) 		/* PORT_INSTANCE_UUID */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( PORT_UUID_MAX ) 		/* PORT_HOST_UUID */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( 1 ) 			/* PROT_VDP_REQUEST */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( 2 ) ; 			/* PORT_VDP_RESPONSE */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  vf_ports_size  =  nla_total_size ( sizeof ( struct  nlattr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  vf_port_size  =  nla_total_size ( sizeof ( struct  nlattr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  port_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  port_self_size  =  nla_total_size ( sizeof ( struct  nlattr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  port_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dev - > netdev_ops - > ndo_get_vf_port  | |  ! dev - > dev . parent ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev_num_vf ( dev - > dev . parent ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  port_self_size  +  vf_ports_size  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vf_port_size  *  dev_num_vf ( dev - > dev . parent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  port_self_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  noinline  size_t  if_nlmsg_size ( const  struct  net_device  * dev ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												     u32  ext_filter_mask ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-10 14:10:15 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NLMSG_ALIGN ( sizeof ( struct  ifinfomsg ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( IFNAMSIZ )  /* IFLA_IFNAME */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-22 21:28:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( IFALIASZ )  /* IFLA_IFALIAS */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-10 14:10:15 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( IFNAMSIZ )  /* IFLA_QDISC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( sizeof ( struct  rtnl_link_ifmap ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( sizeof ( struct  rtnl_link_stats ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-27 17:15:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( sizeof ( struct  rtnl_link_stats64 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-10 14:10:15 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( MAX_ADDR_LEN )  /* IFLA_ADDRESS */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( MAX_ADDR_LEN )  /* IFLA_BROADCAST */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_TXQLEN */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_WEIGHT */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_MTU */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_LINK */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_MASTER */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-27 23:49:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( 1 )  /* IFLA_CARRIER */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-29 12:51:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_PROMISCUITY */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_NUM_TX_QUEUES */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( 4 )  /* IFLA_NUM_RX_QUEUES */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-10 14:10:15 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( 1 )  /* IFLA_OPERSTATE */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( 1 )  /* IFLA_LINKMODE */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  nla_total_size ( ext_filter_mask 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											        &  RTEXT_FILTER_VF  ?  4  :  0 )  /* IFLA_NUM_VF */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  rtnl_vfinfo_size ( dev ,  ext_filter_mask )  /* IFLA_VFINFO_LIST */ 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  rtnl_port_size ( dev )  /* IFLA_VF_PORTS + IFLA_PORT_SELF */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  rtnl_link_get_size ( dev )  /* IFLA_LINKINFO */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  rtnl_link_get_af_size ( dev ) ;  /* IFLA_AF_SPEC */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-10 14:10:15 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_vf_ports_fill ( struct  sk_buff  * skb ,  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * vf_ports ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * vf_port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  vf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									vf_ports  =  nla_nest_start ( skb ,  IFLA_VF_PORTS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! vf_ports ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( vf  =  0 ;  vf  <  dev_num_vf ( dev - > dev . parent ) ;  vf + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										vf_port  =  nla_nest_start ( skb ,  IFLA_VF_PORT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-28 03:42:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! vf_port ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( nla_put_u32 ( skb ,  IFLA_PORT_VF ,  vf ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev - > netdev_ops - > ndo_get_vf_port ( dev ,  vf ,  skb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-28 03:42:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  = =  - EMSGSIZE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nla_nest_cancel ( skb ,  vf_port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_nest_end ( skb ,  vf_port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_end ( skb ,  vf_ports ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-28 03:42:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								nla_put_failure :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_cancel ( skb ,  vf_ports ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - EMSGSIZE ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnl_port_self_fill ( struct  sk_buff  * skb ,  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * port_self ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									port_self  =  nla_nest_start ( skb ,  IFLA_PORT_SELF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! port_self ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  dev - > netdev_ops - > ndo_get_vf_port ( dev ,  PORT_SELF_VF ,  skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_nest_cancel ( skb ,  port_self ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-28 03:42:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  ( err  = =  - EMSGSIZE )  ?  err  :  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_end ( skb ,  port_self ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnl_port_fill ( struct  sk_buff  * skb ,  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dev - > netdev_ops - > ndo_get_vf_port  | |  ! dev - > dev . parent ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  rtnl_port_self_fill ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev_num_vf ( dev - > dev . parent ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  rtnl_vf_ports_fill ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_fill_ifinfo ( struct  sk_buff  * skb ,  struct  net_device  * dev ,  
						 
					
						
							
								
									
										
										
										
											2007-05-22 17:00:49 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											    int  type ,  u32  pid ,  u32  seq ,  u32  change , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											    unsigned  int  flags ,  u32  ext_filter_mask ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlmsghdr  * nlh ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-07 14:58:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  rtnl_link_stats64  temp ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-08 07:19:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  rtnl_link_stats64  * stats ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  nlattr  * attr ,  * af_spec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtnl_af_ops  * af_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * upper_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 07:34:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ASSERT_RTNL ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nlh  =  nlmsg_put ( skb ,  pid ,  seq ,  type ,  sizeof ( * ifm ) ,  flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlh  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-31 23:16:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_family  =  AF_UNSPEC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > __ifi_pad  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_type  =  dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_index  =  dev - > ifindex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_flags  =  dev_get_flags ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_change  =  change ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nla_put_string ( skb ,  IFLA_IFNAME ,  dev - > name )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_TXQLEN ,  dev - > tx_queue_len )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u8 ( skb ,  IFLA_OPERSTATE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										       netif_running ( dev )  ?  dev - > operstate  :  IF_OPER_DOWN )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u8 ( skb ,  IFLA_LINKMODE ,  dev - > link_mode )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_MTU ,  dev - > mtu )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_GROUP ,  dev - > group )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-29 12:51:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_PROMISCUITY ,  dev - > promiscuity )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_NUM_TX_QUEUES ,  dev - > num_tx_queues )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 13:35:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_RPS 
  
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_NUM_RX_QUEUES ,  dev - > num_rx_queues )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 13:35:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( dev - > ifindex  ! =  dev - > iflink  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     nla_put_u32 ( skb ,  IFLA_LINK ,  dev - > iflink ) )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( upper_dev  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     nla_put_u32 ( skb ,  IFLA_MASTER ,  upper_dev - > ifindex ) )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-27 23:49:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    nla_put_u8 ( skb ,  IFLA_CARRIER ,  netif_carrier_ok ( dev ) )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( dev - > qdisc  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     nla_put_string ( skb ,  IFLA_QDISC ,  dev - > qdisc - > ops - > id ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( dev - > ifalias  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     nla_put_string ( skb ,  IFLA_IFALIAS ,  dev - > ifalias ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-22 21:28:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  rtnl_link_ifmap  map  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. mem_start    =  dev - > mem_start , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. mem_end      =  dev - > mem_end , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. base_addr    =  dev - > base_addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. irq          =  dev - > irq , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. dma          =  dev - > dma , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. port         =  dev - > if_port , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( nla_put ( skb ,  IFLA_MAP ,  sizeof ( map ) ,  & map ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev - > addr_len )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( nla_put ( skb ,  IFLA_ADDRESS ,  dev - > addr_len ,  dev - > dev_addr )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    nla_put ( skb ,  IFLA_BROADCAST ,  dev - > addr_len ,  dev - > broadcast ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-21 14:12:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									attr  =  nla_reserve ( skb ,  IFLA_STATS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sizeof ( struct  rtnl_link_stats ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( attr  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-07 14:58:56 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stats  =  dev_get_stats ( dev ,  & temp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-21 14:12:46 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									copy_rtnl_link_stats ( nla_data ( attr ) ,  stats ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-11 09:57:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									attr  =  nla_reserve ( skb ,  IFLA_STATS64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sizeof ( struct  rtnl_link_stats64 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( attr  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									copy_rtnl_link_stats64 ( nla_data ( attr ) ,  stats ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev - > dev . parent  & &  ( ext_filter_mask  &  RTEXT_FILTER_VF )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_NUM_VF ,  dev_num_vf ( dev - > dev . parent ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev - > netdev_ops - > ndo_get_vf_config  & &  dev - > dev . parent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    & &  ( ext_filter_mask  &  RTEXT_FILTER_VF ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  nlattr  * vfinfo ,  * vf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  num_vfs  =  dev_num_vf ( dev - > dev . parent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										vfinfo  =  nla_nest_start ( skb ,  IFLA_VFINFO_LIST ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! vfinfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  0 ;  i  <  num_vfs ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_info  ivi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_mac  vf_mac ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_vlan  vf_vlan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_tx_rate  vf_tx_rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-08 03:05:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  ifla_vf_spoofchk  vf_spoofchk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  Not  all  SR - IOV  capable  drivers  support  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  spoofcheck  query .   Preset  to  - 1  so  the  user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  space  tool  can  detect  that  the  driver  didn ' t 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  report  anything . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ivi . spoofchk  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-09 05:52:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											memset ( ivi . mac ,  0 ,  sizeof ( ivi . mac ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( dev - > netdev_ops - > ndo_get_vf_config ( dev ,  i ,  & ivi ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-08 03:05:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vf_mac . vf  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vf_vlan . vf  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vf_tx_rate . vf  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vf_spoofchk . vf  =  ivi . vf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											memcpy ( vf_mac . mac ,  ivi . mac ,  sizeof ( ivi . mac ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vf_vlan . vlan  =  ivi . vlan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vf_vlan . qos  =  ivi . qos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vf_tx_rate . rate  =  ivi . tx_rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-08 03:05:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vf_spoofchk . setting  =  ivi . spoofchk ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vf  =  nla_nest_start ( skb ,  IFLA_VF_INFO ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! vf )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nla_nest_cancel ( skb ,  vfinfo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( nla_put ( skb ,  IFLA_VF_MAC ,  sizeof ( vf_mac ) ,  & vf_mac )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    nla_put ( skb ,  IFLA_VF_VLAN ,  sizeof ( vf_vlan ) ,  & vf_vlan )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    nla_put ( skb ,  IFLA_VF_TX_RATE ,  sizeof ( vf_tx_rate ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    & vf_tx_rate )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    nla_put ( skb ,  IFLA_VF_SPOOFCHK ,  sizeof ( vf_spoofchk ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    & vf_spoofchk ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  nla_put_failure ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											nla_nest_end ( skb ,  vf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										nla_nest_end ( skb ,  vfinfo ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtnl_port_fill ( skb ,  dev ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev - > rtnl_link_ops )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtnl_link_fill ( skb ,  dev )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( af_spec  =  nla_nest_start ( skb ,  IFLA_AF_SPEC ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry ( af_ops ,  & rtnl_af_ops ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( af_ops - > fill_link_af )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  nlattr  * af ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( af  =  nla_nest_start ( skb ,  af_ops - > family ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  af_ops - > fill_link_af ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  Caller  may  return  ENODATA  to  indicate  that  there 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  was  no  data  to  be  dumped .  This  is  not  an  error ,  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  means  we  should  trim  the  attribute  header  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  continue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( err  = =  - ENODATA ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nla_nest_cancel ( skb ,  af ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else  if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nla_nest_end ( skb ,  af ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_end ( skb ,  af_spec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nlmsg_end ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								nla_put_failure :  
						 
					
						
							
								
									
										
										
										
											2007-01-31 23:16:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nlmsg_cancel ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - EMSGSIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_dump_ifinfo ( struct  sk_buff  * skb ,  struct  netlink_callback  * cb )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-26 02:26:21 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  h ,  s_h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  idx  =  0 ,  s_idx ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  hlist_head  * head ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  nlattr  * tb [ IFLA_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u32  ext_filter_mask  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s_h  =  cb - > args [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									s_idx  =  cb - > args [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-27 22:56:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rcu_read_lock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-21 03:11:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cb - > seq  =  net - > dev_base_seq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-04 12:32:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nlmsg_parse ( cb - > nlh ,  sizeof ( struct  rtgenmsg ) ,  tb ,  IFLA_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ifla_policy )  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-04 12:32:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( tb [ IFLA_EXT_MASK ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ext_filter_mask  =  nla_get_u32 ( tb [ IFLA_EXT_MASK ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( h  =  s_h ;  h  <  NETDEV_HASHENTRIES ;  h + + ,  s_idx  =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										idx  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										head  =  & net - > dev_index_head [ h ] ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
        list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
        hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
 - Fix up the actual hlist iterators in linux/list.h
 - Fix up the declaration of other iterators based on the hlist ones.
 - A very small amount of places were using the 'node' parameter, this
 was modified to use 'obj->member' instead.
 - Coccinelle didn't handle the hlist_for_each_entry_safe iterator
 properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
    <+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
    ...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
											 
										 
										
											2013-02-27 17:06:00 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hlist_for_each_entry_rcu ( dev ,  head ,  index_hlist )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( idx  <  s_idx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  cont ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtnl_fill_ifinfo ( skb ,  dev ,  RTM_NEWLINK , 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-07 20:12:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													     NETLINK_CB ( cb - > skb ) . portid , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													     cb - > nlh - > nlmsg_seq ,  0 , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													     NLM_F_MULTI , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													     ext_filter_mask )  < =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-21 03:11:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nl_dump_check_consistent ( cb ,  nlmsg_hdr ( skb ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-03 15:13:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								cont :  
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											idx + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
									
										
										
										
											2011-04-27 22:56:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rcu_read_unlock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-24 06:13:17 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cb - > args [ 1 ]  =  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cb - > args [ 0 ]  =  h ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  skb - > len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  struct  nla_policy  ifla_policy [ IFLA_MAX + 1 ]  =  {  
						 
					
						
							
								
									
										
										
										
											2006-08-26 20:13:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_IFNAME ] 		=  {  . type  =  NLA_STRING ,  . len  =  IFNAMSIZ - 1  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_ADDRESS ] 		=  {  . type  =  NLA_BINARY ,  . len  =  MAX_ADDR_LEN  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_BROADCAST ] 	=  {  . type  =  NLA_BINARY ,  . len  =  MAX_ADDR_LEN  } , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-26 20:13:18 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_MAP ] 		=  {  . len  =  sizeof ( struct  rtnl_link_ifmap )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_MTU ] 		=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-19 16:12:08 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_LINK ] 		=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_MASTER ] 		=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-12-27 23:49:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_CARRIER ] 		=  {  . type  =  NLA_U8  } , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_TXQLEN ] 		=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_WEIGHT ] 		=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_OPERSTATE ] 	=  {  . type  =  NLA_U8  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_LINKMODE ] 		=  {  . type  =  NLA_U8  } , 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-19 16:12:08 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_LINKINFO ] 		=  {  . type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-12 13:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_NET_NS_PID ] 	=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-04 17:51:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_NET_NS_FD ] 	=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-22 21:28:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_IFALIAS ] 	        =  {  . type  =  NLA_STRING ,  . len  =  IFALIASZ - 1  } , 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_VFINFO_LIST ] 	=  { .  type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_VF_PORTS ] 		=  {  . type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_SELF ] 	=  {  . type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_AF_SPEC ] 		=  {  . type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_EXT_MASK ] 		=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-29 12:51:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_PROMISCUITY ] 	=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_NUM_TX_QUEUES ] 	=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_NUM_RX_QUEUES ] 	=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( ifla_policy ) ;  
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  nla_policy  ifla_info_policy [ IFLA_INFO_MAX + 1 ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_INFO_KIND ] 	=  {  . type  =  NLA_STRING  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_INFO_DATA ] 	=  {  . type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  nla_policy  ifla_vfinfo_policy [ IFLA_VF_INFO_MAX + 1 ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_VF_INFO ] 		=  {  . type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  struct  nla_policy  ifla_vf_policy [ IFLA_VF_MAX + 1 ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_VF_MAC ] 		=  {  . type  =  NLA_BINARY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    . len  =  sizeof ( struct  ifla_vf_mac )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_VF_VLAN ] 		=  {  . type  =  NLA_BINARY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    . len  =  sizeof ( struct  ifla_vf_vlan )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_VF_TX_RATE ] 	=  {  . type  =  NLA_BINARY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    . len  =  sizeof ( struct  ifla_vf_tx_rate )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-08 00:45:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_VF_SPOOFCHK ] 	=  {  . type  =  NLA_BINARY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    . len  =  sizeof ( struct  ifla_vf_spoofchk )  } , 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  nla_policy  ifla_port_policy [ IFLA_PORT_MAX + 1 ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_VF ] 		=  {  . type  =  NLA_U32  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_PROFILE ] 	=  {  . type  =  NLA_STRING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    . len  =  PORT_PROFILE_MAX  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_VSI_TYPE ] 	=  {  . type  =  NLA_BINARY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    . len  =  sizeof ( struct  ifla_port_vsi ) } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_INSTANCE_UUID ]  =  {  . type  =  NLA_BINARY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												      . len  =  PORT_UUID_MAX  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_HOST_UUID ] 	=  {  . type  =  NLA_STRING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    . len  =  PORT_UUID_MAX  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_REQUEST ] 	=  {  . type  =  NLA_U8 ,  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_PORT_RESPONSE ] 	=  {  . type  =  NLA_U16 ,  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  net  * rtnl_link_get_net ( struct  net  * src_net ,  struct  nlattr  * tb [ ] )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Examine the link attributes and figure out which
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  network  namespace  we  are  talking  about . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_NET_NS_PID ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										net  =  get_net_ns_by_pid ( nla_get_u32 ( tb [ IFLA_NET_NS_PID ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-04 17:51:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( tb [ IFLA_NET_NS_FD ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										net  =  get_net_ns_by_fd ( nla_get_u32 ( tb [ IFLA_NET_NS_FD ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										net  =  get_net ( src_net ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  net ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_link_get_net ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-23 19:54:36 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  validate_linkmsg ( struct  net_device  * dev ,  struct  nlattr  * tb [ ] )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tb [ IFLA_ADDRESS ]  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    nla_len ( tb [ IFLA_ADDRESS ] )  <  dev - > addr_len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tb [ IFLA_BROADCAST ]  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    nla_len ( tb [ IFLA_BROADCAST ] )  <  dev - > addr_len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 01:31:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_AF_SPEC ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * af ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  rem ,  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_for_each_nested ( af ,  tb [ IFLA_AF_SPEC ] ,  rem )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  struct  rtnl_af_ops  * af_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( af_ops  =  rtnl_af_lookup ( nla_type ( af ) ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - EAFNOSUPPORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! af_ops - > set_link_af ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( af_ops - > validate_link_af )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-26 04:55:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												err  =  af_ops - > validate_link_af ( dev ,  af ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 01:31:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-23 19:54:36 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  do_setvfinfo ( struct  net_device  * dev ,  struct  nlattr  * attr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rem ,  err  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * vf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  net_device_ops  * ops  =  dev - > netdev_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_for_each_nested ( vf ,  attr ,  rem )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( nla_type ( vf ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  IFLA_VF_MAC :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_mac  * ivm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ivm  =  nla_data ( vf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > ndo_set_vf_mac ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  ops - > ndo_set_vf_mac ( dev ,  ivm - > vf , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															  ivm - > mac ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  IFLA_VF_VLAN :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_vlan  * ivv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ivv  =  nla_data ( vf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > ndo_set_vf_vlan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  ops - > ndo_set_vf_vlan ( dev ,  ivv - > vf , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															   ivv - > vlan , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															   ivv - > qos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  IFLA_VF_TX_RATE :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_tx_rate  * ivt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ivt  =  nla_data ( vf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > ndo_set_vf_tx_rate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  ops - > ndo_set_vf_tx_rate ( dev ,  ivt - > vf , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															      ivt - > rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-08 03:05:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  IFLA_VF_SPOOFCHK :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_spoofchk  * ivs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ivs  =  nla_data ( vf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > ndo_set_vf_spoofchk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  ops - > ndo_set_vf_spoofchk ( dev ,  ivs - > vf , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															       ivs - > setting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  do_set_master ( struct  net_device  * dev ,  int  ifindex )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * upper_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  net_device_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( upper_dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( upper_dev - > ifindex  = =  ifindex ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ops  =  upper_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ops - > ndo_del_slave )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  ops - > ndo_del_slave ( upper_dev ,  dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifindex )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										upper_dev  =  __dev_get_by_index ( dev_net ( dev ) ,  ifindex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! upper_dev ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - EINVAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ops  =  upper_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ops - > ndo_add_slave )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  ops - > ndo_add_slave ( upper_dev ,  dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  do_setlink ( struct  net_device  * dev ,  struct  ifinfomsg  * ifm ,  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										      struct  nlattr  * * tb ,  char  * ifname ,  int  modified ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:32:24 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  net_device_ops  * ops  =  dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-04 17:51:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_NET_NS_PID ]  | |  tb [ IFLA_NET_NS_FD ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  net  * net  =  rtnl_link_get_net ( dev_net ( dev ) ,  tb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-12 13:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( IS_ERR ( net ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  PTR_ERR ( net ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-16 03:03:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ns_capable ( net - > user_ns ,  CAP_NET_ADMIN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EPERM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-12 13:57:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev_change_net_namespace ( dev ,  net ,  ifname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										put_net ( net ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_MAP ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										struct  rtnl_link_ifmap  * u_map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ifmap  k_map ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:32:24 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ops - > ndo_set_config )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! netif_device_present ( dev ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - ENODEV ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										u_map  =  nla_data ( tb [ IFLA_MAP ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										k_map . mem_start  =  ( unsigned  long )  u_map - > mem_start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										k_map . mem_end  =  ( unsigned  long )  u_map - > mem_end ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										k_map . base_addr  =  ( unsigned  short )  u_map - > base_addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										k_map . irq  =  ( unsigned  char )  u_map - > irq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										k_map . dma  =  ( unsigned  char )  u_map - > dma ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										k_map . port  =  ( unsigned  char )  u_map - > port ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-19 21:32:24 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  ops - > ndo_set_config ( dev ,  & k_map ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_ADDRESS ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-08 16:47:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  sockaddr  * sa ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										len  =  sizeof ( sa_family_t )  +  dev - > addr_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sa  =  kmalloc ( len ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! sa )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-08 16:47:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sa - > sa_family  =  dev - > type ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memcpy ( sa - > sa_data ,  nla_data ( tb [ IFLA_ADDRESS ] ) , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-08 16:47:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										       dev - > addr_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-01 03:30:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev_set_mac_address ( dev ,  sa ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-08 16:47:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										kfree ( sa ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_MTU ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  dev_set_mtu ( dev ,  nla_get_u32 ( tb [ IFLA_MTU ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 23:38:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_GROUP ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_set_group ( dev ,  nla_get_u32 ( tb [ IFLA_GROUP ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Interface  selected  by  interface  index  but  interface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  name  provided  implies  that  a  name  change  has  been 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  requested . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-05 12:40:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ifm - > ifi_index  >  0  & &  ifname [ 0 ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev_change_name ( dev ,  ifname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-09-22 21:28:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_IFALIAS ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  dev_set_alias ( dev ,  nla_data ( tb [ IFLA_IFALIAS ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    nla_len ( tb [ IFLA_IFALIAS ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_BROADCAST ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_memcpy ( dev - > broadcast ,  tb [ IFLA_BROADCAST ] ,  dev - > addr_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-01 03:30:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										call_netdevice_notifiers ( NETDEV_CHANGEADDR ,  dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-22 17:00:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ifm - > ifi_flags  | |  ifm - > ifi_change )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: support specifying device flags on device creation
commit e8469ed959c373c2ff9e6f488aa5a14971aebe1f
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Feb 23 20:41:30 2010 +0100
Support specifying the initial device flags when creating a device though
rtnl_link. Devices allocated by rtnl_create_link() are marked as INITIALIZING
in order to surpress netlink registration notifications. To complete setup,
rtnl_configure_link() must be called, which performs the device flag changes
and invokes the deferred notifiers if everything went well.
Two examples:
# add macvlan to eth0
#
$ ip link add link eth0 up allmulticast on type macvlan
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 26:f8:84:02:f9:2a brd ff:ff:ff:ff:ff:ff
[ROUTE]ff00::/8 dev macvlan0  table local  metric 256  mtu 1500 advmss 1440 hoplimit 0
[ROUTE]fe80::/64 dev macvlan0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 0
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500
    link/ether 26:f8:84:02:f9:2a
[ADDR]11: macvlan0    inet6 fe80::24f8:84ff:fe02:f92a/64 scope link
       valid_lft forever preferred_lft forever
[ROUTE]local fe80::24f8:84ff:fe02:f92a via :: dev lo  table local  proto none  metric 0  mtu 16436 advmss 16376 hoplimit 0
[ROUTE]default via fe80::215:e9ff:fef0:10f8 dev macvlan0  proto kernel  metric 1024  mtu 1500 advmss 1440 hoplimit 0
[NEIGH]fe80::215:e9ff:fef0:10f8 dev macvlan0 lladdr 00:15:e9:f0:10:f8 router STALE
[ROUTE]2001:6f8:974::/64 dev macvlan0  proto kernel  metric 256  expires 0sec mtu 1500 advmss 1440 hoplimit 0
[PREFIX]prefix 2001:6f8:974::/64 dev macvlan0 onlink autoconf valid 14400 preferred 131084
[ADDR]11: macvlan0    inet6 2001:6f8:974:0:24f8:84ff:fe02:f92a/64 scope global dynamic
       valid_lft 86399sec preferred_lft 14399sec
# add VLAN to eth1, eth1 is down
#
$ ip link add link eth1 up type vlan id 1000
RTNETLINK answers: Network is down
<no events>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-02-26 06:34:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev_change_flags ( dev ,  rtnl_dev_combine_flags ( dev ,  ifm ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-16 23:20:31 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-22 17:00:01 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-13 10:15:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_MASTER ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  do_set_master ( dev ,  nla_get_u32 ( tb [ IFLA_MASTER ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-12-27 23:49:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_CARRIER ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  dev_change_carrier ( dev ,  nla_get_u8 ( tb [ IFLA_CARRIER ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-17 18:35:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_TXQLEN ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev - > tx_queue_len  =  nla_get_u32 ( tb [ IFLA_TXQLEN ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 17:09:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_OPERSTATE ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-17 18:35:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										set_operstate ( dev ,  nla_get_u8 ( tb [ IFLA_OPERSTATE ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 17:09:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_LINKMODE ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-17 18:35:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										write_lock_bh ( & dev_base_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev - > link_mode  =  nla_get_u8 ( tb [ IFLA_LINKMODE ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										write_unlock_bh ( & dev_base_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-20 17:09:11 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_VFINFO_LIST ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * attr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  rem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_for_each_nested ( attr ,  tb [ IFLA_VFINFO_LIST ] ,  rem )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 02:25:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( nla_type ( attr )  ! =  IFLA_VF_INFO )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  - EINVAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 02:25:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-16 01:05:45 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  do_setvfinfo ( dev ,  attr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-10 01:44:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									err  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_VF_PORTS ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * port [ IFLA_PORT_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * attr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  vf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  rem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ops - > ndo_set_vf_port ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_for_each_nested ( attr ,  tb [ IFLA_VF_PORTS ] ,  rem )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( nla_type ( attr )  ! =  IFLA_VF_PORT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  nla_parse_nested ( port ,  IFLA_PORT_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												attr ,  ifla_port_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! port [ IFLA_PORT_VF ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											vf  =  nla_get_u32 ( port [ IFLA_PORT_VF ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  ops - > ndo_set_vf_port ( dev ,  vf ,  port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_PORT_SELF ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * port [ IFLA_PORT_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  nla_parse_nested ( port ,  IFLA_PORT_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tb [ IFLA_PORT_SELF ] ,  ifla_port_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ops - > ndo_set_vf_port ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  ops - > ndo_set_vf_port ( dev ,  PORT_SELF_VF ,  port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_AF_SPEC ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * af ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  rem ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_for_each_nested ( af ,  tb [ IFLA_AF_SPEC ] ,  rem )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  struct  rtnl_af_ops  * af_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( af_ops  =  rtnl_af_lookup ( nla_type ( af ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 01:31:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												BUG ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 01:31:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  af_ops - > set_link_af ( dev ,  af ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												net: Add netlink support for virtual port management (was iovnl)
Add new netdev ops ndo_{set|get}_vf_port to allow setting of
port-profile on a netdev interface.  Extends netlink socket RTM_SETLINK/
RTM_GETLINK with two new sub msgs called IFLA_VF_PORTS and IFLA_PORT_SELF
(added to end of IFLA_cmd list).  These are both nested atrtibutes
using this layout:
              [IFLA_NUM_VF]
              [IFLA_VF_PORTS]
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      [IFLA_VF_PORT]
                              [IFLA_PORT_*], ...
                      ...
              [IFLA_PORT_SELF]
                      [IFLA_PORT_*], ...
These attributes are design to be set and get symmetrically.  VF_PORTS
is a list of VF_PORTs, one for each VF, when dealing with an SR-IOV
device.  PORT_SELF is for the PF of the SR-IOV device, in case it wants
to also have a port-profile, or for the case where the VF==PF, like in
enic patch 2/2 of this patch set.
A port-profile is used to configure/enable the external switch virtual port
backing the netdev interface, not to configure the host-facing side of the
netdev.  A port-profile is an identifier known to the switch.  How port-
profiles are installed on the switch or how available port-profiles are
made know to the host is outside the scope of this patch.
There are two types of port-profiles specs in the netlink msg.  The first spec
is for 802.1Qbg (pre-)standard, VDP protocol.  The second spec is for devices
that run a similar protocol as VDP but in firmware, thus hiding the protocol
details.  In either case, the specs have much in common and makes sense to
define the netlink msg as the union of the two specs.  For example, both specs
have a notition of associating/deassociating a port-profile.  And both specs
require some information from the hypervisor manager, such as client port
instance ID.
The general flow is the port-profile is applied to a host netdev interface
using RTM_SETLINK, the receiver of the RTM_SETLINK msg communicates with the
switch, and the switch virtual port backing the host netdev interface is
configured/enabled based on the settings defined by the port-profile.  What
those settings comprise, and how those settings are managed is again
outside the scope of this patch, since this patch only deals with the
first step in the flow.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-05-17 22:49:55 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								errout :  
						 
					
						
							
								
									
										
										
										
											2012-05-13 21:56:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( err  <  0  & &  modified ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										net_warn_ratelimited ( " A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												     dev - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_setlink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-26 02:26:21 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * tb [ IFLA_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  ifname [ IFNAMSIZ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  nlmsg_parse ( nlh ,  sizeof ( * ifm ) ,  tb ,  IFLA_MAX ,  ifla_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_IFNAME ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_strlcpy ( ifname ,  tb [ IFLA_IFNAME ] ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ifname [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifm - > ifi_index  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev  =  __dev_get_by_index ( net ,  ifm - > ifi_index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( tb [ IFLA_IFNAME ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev  =  __dev_get_by_name ( net ,  ifname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  validate_linkmsg ( dev ,  tb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  do_setlink ( dev ,  ifm ,  tb ,  ifname ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-10 21:17:37 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								errout :  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_dellink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-26 02:26:21 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  ifname [ IFNAMSIZ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * tb [ IFLA_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-08 23:17:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									LIST_HEAD ( list_kill ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  nlmsg_parse ( nlh ,  sizeof ( * ifm ) ,  tb ,  IFLA_MAX ,  ifla_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_IFNAME ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_strlcpy ( ifname ,  tb [ IFLA_IFNAME ] ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifm - > ifi_index  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 11:56:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev  =  __dev_get_by_index ( net ,  ifm - > ifi_index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( tb [ IFLA_IFNAME ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 11:56:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev  =  __dev_get_by_name ( net ,  ifname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ops  =  dev - > rtnl_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ops ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-08 23:17:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ops - > dellink ( dev ,  & list_kill ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unregister_netdevice_many ( & list_kill ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_del ( & list_kill ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: support specifying device flags on device creation
commit e8469ed959c373c2ff9e6f488aa5a14971aebe1f
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Feb 23 20:41:30 2010 +0100
Support specifying the initial device flags when creating a device though
rtnl_link. Devices allocated by rtnl_create_link() are marked as INITIALIZING
in order to surpress netlink registration notifications. To complete setup,
rtnl_configure_link() must be called, which performs the device flag changes
and invokes the deferred notifiers if everything went well.
Two examples:
# add macvlan to eth0
#
$ ip link add link eth0 up allmulticast on type macvlan
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 26:f8:84:02:f9:2a brd ff:ff:ff:ff:ff:ff
[ROUTE]ff00::/8 dev macvlan0  table local  metric 256  mtu 1500 advmss 1440 hoplimit 0
[ROUTE]fe80::/64 dev macvlan0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 0
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500
    link/ether 26:f8:84:02:f9:2a
[ADDR]11: macvlan0    inet6 fe80::24f8:84ff:fe02:f92a/64 scope link
       valid_lft forever preferred_lft forever
[ROUTE]local fe80::24f8:84ff:fe02:f92a via :: dev lo  table local  proto none  metric 0  mtu 16436 advmss 16376 hoplimit 0
[ROUTE]default via fe80::215:e9ff:fef0:10f8 dev macvlan0  proto kernel  metric 1024  mtu 1500 advmss 1440 hoplimit 0
[NEIGH]fe80::215:e9ff:fef0:10f8 dev macvlan0 lladdr 00:15:e9:f0:10:f8 router STALE
[ROUTE]2001:6f8:974::/64 dev macvlan0  proto kernel  metric 256  expires 0sec mtu 1500 advmss 1440 hoplimit 0
[PREFIX]prefix 2001:6f8:974::/64 dev macvlan0 onlink autoconf valid 14400 preferred 131084
[ADDR]11: macvlan0    inet6 2001:6f8:974:0:24f8:84ff:fe02:f92a/64 scope global dynamic
       valid_lft 86399sec preferred_lft 14399sec
# add VLAN to eth1, eth1 is down
#
$ ip link add link eth1 up type vlan id 1000
RTNETLINK answers: Network is down
<no events>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-02-26 06:34:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  rtnl_configure_link ( struct  net_device  * dev ,  const  struct  ifinfomsg  * ifm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  old_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									old_flags  =  dev - > flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifm  & &  ( ifm - > ifi_flags  | |  ifm - > ifi_change ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  __dev_change_flags ( dev ,  rtnl_dev_combine_flags ( dev ,  ifm ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev - > rtnl_link_state  =  RTNL_LINK_INITIALIZED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtmsg_ifinfo ( RTM_NEWLINK ,  dev ,  ~ 0U ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__dev_notify_flags ( dev ,  old_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_configure_link ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-30 01:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  net_device  * rtnl_create_link ( struct  net  * net ,  
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * ifname ,  const  struct  rtnl_link_ops  * ops ,  struct  nlattr  * tb [ ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  num_tx_queues  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  num_rx_queues  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_NUM_TX_QUEUES ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										num_tx_queues  =  nla_get_u32 ( tb [ IFLA_NUM_TX_QUEUES ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( ops - > get_num_tx_queues ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										num_tx_queues  =  ops - > get_num_tx_queues ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_NUM_RX_QUEUES ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										num_rx_queues  =  nla_get_u32 ( tb [ IFLA_NUM_RX_QUEUES ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( ops - > get_num_rx_queues ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										num_rx_queues  =  ops - > get_num_rx_queues ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-10 18:34:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  - ENOMEM ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 02:28:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dev  =  alloc_netdev_mqs ( ops - > priv_size ,  ifname ,  ops - > setup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       num_tx_queues ,  num_rx_queues ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dev_net_set ( dev ,  net ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev - > rtnl_link_ops  =  ops ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: support specifying device flags on device creation
commit e8469ed959c373c2ff9e6f488aa5a14971aebe1f
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Feb 23 20:41:30 2010 +0100
Support specifying the initial device flags when creating a device though
rtnl_link. Devices allocated by rtnl_create_link() are marked as INITIALIZING
in order to surpress netlink registration notifications. To complete setup,
rtnl_configure_link() must be called, which performs the device flag changes
and invokes the deferred notifiers if everything went well.
Two examples:
# add macvlan to eth0
#
$ ip link add link eth0 up allmulticast on type macvlan
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 26:f8:84:02:f9:2a brd ff:ff:ff:ff:ff:ff
[ROUTE]ff00::/8 dev macvlan0  table local  metric 256  mtu 1500 advmss 1440 hoplimit 0
[ROUTE]fe80::/64 dev macvlan0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 0
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500
    link/ether 26:f8:84:02:f9:2a
[ADDR]11: macvlan0    inet6 fe80::24f8:84ff:fe02:f92a/64 scope link
       valid_lft forever preferred_lft forever
[ROUTE]local fe80::24f8:84ff:fe02:f92a via :: dev lo  table local  proto none  metric 0  mtu 16436 advmss 16376 hoplimit 0
[ROUTE]default via fe80::215:e9ff:fef0:10f8 dev macvlan0  proto kernel  metric 1024  mtu 1500 advmss 1440 hoplimit 0
[NEIGH]fe80::215:e9ff:fef0:10f8 dev macvlan0 lladdr 00:15:e9:f0:10:f8 router STALE
[ROUTE]2001:6f8:974::/64 dev macvlan0  proto kernel  metric 256  expires 0sec mtu 1500 advmss 1440 hoplimit 0
[PREFIX]prefix 2001:6f8:974::/64 dev macvlan0 onlink autoconf valid 14400 preferred 131084
[ADDR]11: macvlan0    inet6 2001:6f8:974:0:24f8:84ff:fe02:f92a/64 scope global dynamic
       valid_lft 86399sec preferred_lft 14399sec
# add VLAN to eth1, eth1 is down
#
$ ip link add link eth1 up type vlan id 1000
RTNETLINK answers: Network is down
<no events>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-02-26 06:34:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dev - > rtnl_link_state  =  RTNL_LINK_INITIALIZING ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_MTU ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev - > mtu  =  nla_get_u32 ( tb [ IFLA_MTU ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-06 12:41:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_ADDRESS ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memcpy ( dev - > dev_addr ,  nla_data ( tb [ IFLA_ADDRESS ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nla_len ( tb [ IFLA_ADDRESS ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-06 12:41:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev - > addr_assign_type  =  NET_ADDR_SET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_BROADCAST ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( dev - > broadcast ,  nla_data ( tb [ IFLA_BROADCAST ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nla_len ( tb [ IFLA_BROADCAST ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_TXQLEN ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev - > tx_queue_len  =  nla_get_u32 ( tb [ IFLA_TXQLEN ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_OPERSTATE ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-17 18:35:07 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										set_operstate ( dev ,  nla_get_u8 ( tb [ IFLA_OPERSTATE ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_LINKMODE ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev - > link_mode  =  nla_get_u8 ( tb [ IFLA_LINKMODE ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-20 03:00:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_GROUP ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev_set_group ( dev ,  nla_get_u32 ( tb [ IFLA_GROUP ] ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								err :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ERR_PTR ( err ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtnl_create_link ) ;  
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 23:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_group_changelink ( struct  net  * net ,  int  group ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ifinfomsg  * ifm , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * * tb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for_each_netdev ( net ,  dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dev - > group  = =  group )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  do_setlink ( dev ,  ifm ,  tb ,  NULL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_newlink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-26 02:26:21 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  kind [ MODULE_NAME_LEN ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  ifname [ IFNAMSIZ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * tb [ IFLA_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * linkinfo [ IFLA_INFO_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-16 15:24:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_MODULES 
  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								replay :  
						 
					
						
							
								
									
										
										
										
											2007-07-31 14:13:50 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  nlmsg_parse ( nlh ,  sizeof ( * ifm ) ,  tb ,  IFLA_MAX ,  ifla_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tb [ IFLA_IFNAME ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_strlcpy ( ifname ,  tb [ IFLA_IFNAME ] ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ifname [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifm - > ifi_index  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 11:56:21 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev  =  __dev_get_by_index ( net ,  ifm - > ifi_index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-13 23:38:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ifname [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dev  =  __dev_get_by_name ( net ,  ifname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  validate_linkmsg ( dev ,  tb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-23 19:54:36 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_LINKINFO ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  nla_parse_nested ( linkinfo ,  IFLA_INFO_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												       tb [ IFLA_LINKINFO ] ,  ifla_info_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memset ( linkinfo ,  0 ,  sizeof ( linkinfo ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( linkinfo [ IFLA_INFO_KIND ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_strlcpy ( kind ,  linkinfo [ IFLA_INFO_KIND ] ,  sizeof ( kind ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ops  =  rtnl_link_ops_get ( kind ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kind [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ops  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * attr [ ops  ?  ops - > maxtype  +  1  :  0 ] ,  * * data  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  net  * dest_net ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ops )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > maxtype  & &  linkinfo [ IFLA_INFO_DATA ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  nla_parse_nested ( attr ,  ops - > maxtype , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														       linkinfo [ IFLA_INFO_DATA ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														       ops - > policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												data  =  attr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > validate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  ops - > validate ( tb ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  modified  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( nlh - > nlmsg_flags  &  NLM_F_EXCL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - EEXIST ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( nlh - > nlmsg_flags  &  NLM_F_REPLACE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( linkinfo [ IFLA_INFO_DATA ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! ops  | |  ops  ! =  dev - > rtnl_link_ops  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    ! ops - > changelink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  ops - > changelink ( dev ,  tb ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  do_setlink ( dev ,  ifm ,  tb ,  ifname ,  modified ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-20 03:00:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ( nlh - > nlmsg_flags  &  NLM_F_CREATE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ifm - > ifi_index  = =  0  & &  tb [ IFLA_GROUP ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  rtnl_group_changelink ( net , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														nla_get_u32 ( tb [ IFLA_GROUP ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ifm ,  tb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - ENODEV ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-20 03:00:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-11 19:42:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( tb [ IFLA_MAP ]  | |  tb [ IFLA_MASTER ]  | |  tb [ IFLA_PROTINFO ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ops )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-16 15:24:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef CONFIG_MODULES 
  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( kind [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												__rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												request_module ( " rtnl-link-%s " ,  kind ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ops  =  rtnl_link_ops_get ( kind ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ops ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  replay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ifname [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( ifname ,  IFNAMSIZ ,  " %s%%d " ,  ops - > kind ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dest_net  =  rtnl_link_get_net ( net ,  tb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-29 14:57:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( IS_ERR ( dest_net ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  PTR_ERR ( dest_net ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-30 01:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dev  =  rtnl_create_link ( dest_net ,  ifname ,  ops ,  tb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 21:52:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( IS_ERR ( dev ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 22:16:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  PTR_ERR ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 21:52:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev - > ifindex  =  ifm - > ifi_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ops - > newlink ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  ops - > newlink ( net ,  dev ,  tb ,  data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-11 19:42:13 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  register_netdevice ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-21 23:53:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0  & &  ! IS_ERR ( dev ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											free_netdev ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-21 23:53:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: support specifying device flags on device creation
commit e8469ed959c373c2ff9e6f488aa5a14971aebe1f
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Feb 23 20:41:30 2010 +0100
Support specifying the initial device flags when creating a device though
rtnl_link. Devices allocated by rtnl_create_link() are marked as INITIALIZING
in order to surpress netlink registration notifications. To complete setup,
rtnl_configure_link() must be called, which performs the device flag changes
and invokes the deferred notifiers if everything went well.
Two examples:
# add macvlan to eth0
#
$ ip link add link eth0 up allmulticast on type macvlan
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 26:f8:84:02:f9:2a brd ff:ff:ff:ff:ff:ff
[ROUTE]ff00::/8 dev macvlan0  table local  metric 256  mtu 1500 advmss 1440 hoplimit 0
[ROUTE]fe80::/64 dev macvlan0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 0
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500
    link/ether 26:f8:84:02:f9:2a
[ADDR]11: macvlan0    inet6 fe80::24f8:84ff:fe02:f92a/64 scope link
       valid_lft forever preferred_lft forever
[ROUTE]local fe80::24f8:84ff:fe02:f92a via :: dev lo  table local  proto none  metric 0  mtu 16436 advmss 16376 hoplimit 0
[ROUTE]default via fe80::215:e9ff:fef0:10f8 dev macvlan0  proto kernel  metric 1024  mtu 1500 advmss 1440 hoplimit 0
[NEIGH]fe80::215:e9ff:fef0:10f8 dev macvlan0 lladdr 00:15:e9:f0:10:f8 router STALE
[ROUTE]2001:6f8:974::/64 dev macvlan0  proto kernel  metric 256  expires 0sec mtu 1500 advmss 1440 hoplimit 0
[PREFIX]prefix 2001:6f8:974::/64 dev macvlan0 onlink autoconf valid 14400 preferred 131084
[ADDR]11: macvlan0    inet6 2001:6f8:974:0:24f8:84ff:fe02:f92a/64 scope global dynamic
       valid_lft 86399sec preferred_lft 14399sec
# add VLAN to eth1, eth1 is down
#
$ ip link add link eth1 up type vlan id 1000
RTNETLINK answers: Network is down
<no events>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-02-26 06:34:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: support specifying device flags on device creation
commit e8469ed959c373c2ff9e6f488aa5a14971aebe1f
Author: Patrick McHardy <kaber@trash.net>
Date:   Tue Feb 23 20:41:30 2010 +0100
Support specifying the initial device flags when creating a device though
rtnl_link. Devices allocated by rtnl_create_link() are marked as INITIALIZING
in order to surpress netlink registration notifications. To complete setup,
rtnl_configure_link() must be called, which performs the device flag changes
and invokes the deferred notifiers if everything went well.
Two examples:
# add macvlan to eth0
#
$ ip link add link eth0 up allmulticast on type macvlan
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether 26:f8:84:02:f9:2a brd ff:ff:ff:ff:ff:ff
[ROUTE]ff00::/8 dev macvlan0  table local  metric 256  mtu 1500 advmss 1440 hoplimit 0
[ROUTE]fe80::/64 dev macvlan0  proto kernel  metric 256  mtu 1500 advmss 1440 hoplimit 0
[LINK]11: macvlan0@eth0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500
    link/ether 26:f8:84:02:f9:2a
[ADDR]11: macvlan0    inet6 fe80::24f8:84ff:fe02:f92a/64 scope link
       valid_lft forever preferred_lft forever
[ROUTE]local fe80::24f8:84ff:fe02:f92a via :: dev lo  table local  proto none  metric 0  mtu 16436 advmss 16376 hoplimit 0
[ROUTE]default via fe80::215:e9ff:fef0:10f8 dev macvlan0  proto kernel  metric 1024  mtu 1500 advmss 1440 hoplimit 0
[NEIGH]fe80::215:e9ff:fef0:10f8 dev macvlan0 lladdr 00:15:e9:f0:10:f8 router STALE
[ROUTE]2001:6f8:974::/64 dev macvlan0  proto kernel  metric 256  expires 0sec mtu 1500 advmss 1440 hoplimit 0
[PREFIX]prefix 2001:6f8:974::/64 dev macvlan0 onlink autoconf valid 14400 preferred 131084
[ADDR]11: macvlan0    inet6 2001:6f8:974:0:24f8:84ff:fe02:f92a/64 scope global dynamic
       valid_lft 86399sec preferred_lft 14399sec
# add VLAN to eth1, eth1 is down
#
$ ip link add link eth1 up type vlan id 1000
RTNETLINK answers: Network is down
<no events>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2010-02-26 06:34:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  rtnl_configure_link ( dev ,  ifm ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unregister_netdevice ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
									
										
										
										
											2009-11-08 00:53:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										put_net ( dest_net ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_getlink ( struct  sk_buff  * skb ,  struct  nlmsghdr *  nlh ,  void  * arg )  
						 
					
						
							
								
									
										
										
										
											2006-02-22 15:10:56 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-26 02:26:21 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  ifname [ IFNAMSIZ ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  nlattr  * tb [ IFLA_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sk_buff  * nskb ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-10 14:10:15 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									u32  ext_filter_mask  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-22 15:10:56 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  nlmsg_parse ( nlh ,  sizeof ( * ifm ) ,  tb ,  IFLA_MAX ,  ifla_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-26 23:26:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_IFNAME ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_strlcpy ( ifname ,  tb [ IFLA_IFNAME ] ,  IFNAMSIZ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( tb [ IFLA_EXT_MASK ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ext_filter_mask  =  nla_get_u32 ( tb [ IFLA_EXT_MASK ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ifm - > ifi_index  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev  =  __dev_get_by_index ( net ,  ifm - > ifi_index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( tb [ IFLA_IFNAME ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dev  =  __dev_get_by_name ( net ,  ifname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-22 15:10:56 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nskb  =  nlmsg_new ( if_nlmsg_size ( dev ,  ext_filter_mask ) ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nskb  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENOBUFS ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-07 20:12:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  rtnl_fill_ifinfo ( nskb ,  dev ,  RTM_NEWLINK ,  NETLINK_CB ( skb ) . portid , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											       nlh - > nlmsg_seq ,  0 ,  0 ,  ext_filter_mask ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-31 23:16:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( err  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* -EMSGSIZE implies BUG in if_nlmsg_size */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WARN_ON ( err  = =  - EMSGSIZE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kfree_skb ( nskb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 10:59:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-07 20:12:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  rtnl_unicast ( nskb ,  net ,  NETLINK_CB ( skb ) . portid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-22 15:10:56 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-04 23:05:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-22 15:10:56 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  u16  rtnl_calcit ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * tb [ IFLA_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u32  ext_filter_mask  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u16  min_ifinfo_dump_size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-03-04 12:32:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nlmsg_parse ( nlh ,  sizeof ( struct  rtgenmsg ) ,  tb ,  IFLA_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ifla_policy )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tb [ IFLA_EXT_MASK ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ext_filter_mask  =  nla_get_u32 ( tb [ IFLA_EXT_MASK ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ext_filter_mask ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NLMSG_GOODSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  traverse  the  list  of  net  devices  and  compute  the  minimum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  buffer  size  based  upon  the  filter  mask . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry ( dev ,  & net - > dev_base_head ,  dev_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										min_ifinfo_dump_size  =  max_t ( u16 ,  min_ifinfo_dump_size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													     if_nlmsg_size ( dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														           ext_filter_mask ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  min_ifinfo_dump_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-04-26 00:57:41 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_dump_all ( struct  sk_buff  * skb ,  struct  netlink_callback  * cb )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  s_idx  =  cb - > family ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( s_idx  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s_idx  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 16:02:05 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( idx  =  1 ;  idx  < =  RTNL_FAMILY_MAX ;  idx + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										int  type  =  cb - > nlh - > nlmsg_type - RTM_BASE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( idx  <  s_idx  | |  idx  = =  PF_PACKET ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( rtnl_msg_handlers [ idx ]  = =  NULL  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    rtnl_msg_handlers [ idx ] [ type ] . dumpit  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( idx  >  s_idx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memset ( & cb - > args [ 0 ] ,  0 ,  sizeof ( cb - > args ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( rtnl_msg_handlers [ idx ] [ type ] . dumpit ( skb ,  cb ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cb - > family  =  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  skb - > len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 05:58:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  rtmsg_ifinfo ( int  type ,  struct  net_device  * dev ,  unsigned  int  change )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-25 21:47:49 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  dev_net ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  sk_buff  * skb ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:37:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  err  =  - ENOBUFS ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									size_t  if_info_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									skb  =  nlmsg_new ( ( if_info_size  =  if_nlmsg_size ( dev ,  0 ) ) ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:37:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( skb  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  rtnl_fill_ifinfo ( skb ,  dev ,  type ,  0 ,  0 ,  change ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-31 23:16:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( err  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* -EMSGSIZE implies BUG in if_nlmsg_size() */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WARN_ON ( err  = =  - EMSGSIZE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 23:18:28 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_notify ( skb ,  net ,  0 ,  RTNLGRP_LINK ,  NULL ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 00:37:09 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								errout :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:27:40 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtnl_set_sk_err ( net ,  RTNLGRP_LINK ,  err ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:49:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( rtmsg_ifinfo ) ;  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  nlmsg_populate_fdb_fill ( struct  sk_buff  * skb ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   struct  net_device  * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   u8  * addr ,  u32  pid ,  u32  seq , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   int  type ,  unsigned  int  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlmsghdr  * nlh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ndmsg  * ndm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nlh  =  nlmsg_put ( skb ,  pid ,  seq ,  type ,  sizeof ( * ndm ) ,  NLM_F_MULTI ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! nlh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm - > ndm_family   =  AF_BRIDGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm - > ndm_pad1 	 =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm - > ndm_pad2     =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm - > ndm_flags 	 =  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm - > ndm_type 	 =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm - > ndm_ifindex  =  dev - > ifindex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm - > ndm_state    =  NUD_PERMANENT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nla_put ( skb ,  NDA_LLADDR ,  ETH_ALEN ,  addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nlmsg_end ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								nla_put_failure :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nlmsg_cancel ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  size_t  rtnl_fdb_nlmsg_size ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NLMSG_ALIGN ( sizeof ( struct  ndmsg ) )  +  nla_total_size ( ETH_ALEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  rtnl_fdb_notify ( struct  net_device  * dev ,  u8  * addr ,  int  type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  dev_net ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sk_buff  * skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  - ENOBUFS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									skb  =  nlmsg_new ( rtnl_fdb_nlmsg_size ( ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! skb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  nlmsg_populate_fdb_fill ( skb ,  dev ,  addr ,  0 ,  0 ,  type ,  NTF_SELF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_notify ( skb ,  net ,  0 ,  RTNLGRP_NEIGH ,  NULL ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								errout :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_set_sk_err ( net ,  RTNLGRP_NEIGH ,  err ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_fdb_add ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ndmsg  * ndm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * tb [ NDA_MAX + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u8  * addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  nlmsg_parse ( nlh ,  sizeof ( * ndm ) ,  tb ,  NDA_MAX ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ndm - > ndm_ifindex  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_NEWNEIGH with invalid ifindex \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev  =  __dev_get_by_index ( net ,  ndm - > ndm_ifindex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_NEWNEIGH with unknown ifindex \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! tb [ NDA_LLADDR ]  | |  nla_len ( tb [ NDA_LLADDR ] )  ! =  ETH_ALEN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_NEWNEIGH with invalid address \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr  =  nla_data ( tb [ NDA_LLADDR ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! is_valid_ether_addr ( addr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_NEWNEIGH with invalid ether address \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Support fdb on master device the net/bridge default case */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ! ndm - > ndm_flags  | |  ndm - > ndm_flags  &  NTF_MASTER )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( dev - > priv_flags  &  IFF_BRIDGE_PORT ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  net_device  * br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  struct  net_device_ops  * ops  =  br_dev - > netdev_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  ops - > ndo_fdb_add ( ndm ,  tb ,  dev ,  addr ,  nlh - > nlmsg_flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ndm - > ndm_flags  & =  ~ NTF_MASTER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Embedded bridge, macvlan, and any other device support */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ndm - > ndm_flags  &  NTF_SELF )  & &  dev - > netdev_ops - > ndo_fdb_add )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-01 12:32:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev - > netdev_ops - > ndo_fdb_add ( ndm ,  tb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   dev ,  addr , 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														   nlh - > nlmsg_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtnl_fdb_notify ( dev ,  addr ,  RTM_NEWNEIGH ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ndm - > ndm_flags  & =  ~ NTF_SELF ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnl_fdb_del ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh ,  void  * arg )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ndmsg  * ndm ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  nlattr  * tb [ NDA_MAX + 1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									__u8  * addr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! capable ( CAP_NET_ADMIN ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EPERM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  nlmsg_parse ( nlh ,  sizeof ( * ndm ) ,  tb ,  NDA_MAX ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ndm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ndm - > ndm_ifindex  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_DELNEIGH with invalid ifindex \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev  =  __dev_get_by_index ( net ,  ndm - > ndm_ifindex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dev  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_DELNEIGH with unknown ifindex \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! tb [ NDA_LLADDR ]  | |  nla_len ( tb [ NDA_LLADDR ] )  ! =  ETH_ALEN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_DELNEIGH with invalid address \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									addr  =  nla_data ( tb [ NDA_LLADDR ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! is_valid_ether_addr ( addr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_DELNEIGH with invalid ether address \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Support fdb on master device the net/bridge default case */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ! ndm - > ndm_flags  | |  ndm - > ndm_flags  &  NTF_MASTER )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( dev - > priv_flags  &  IFF_BRIDGE_PORT ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  net_device  * br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  struct  net_device_ops  * ops  =  br_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ops - > ndo_fdb_del ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  ops - > ndo_fdb_del ( ndm ,  tb ,  dev ,  addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ndm - > ndm_flags  & =  ~ NTF_MASTER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Embedded bridge, macvlan, and any other device support */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ndm - > ndm_flags  &  NTF_SELF )  & &  dev - > netdev_ops - > ndo_fdb_del )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev - > netdev_ops - > ndo_fdb_del ( ndm ,  tb ,  dev ,  addr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtnl_fdb_notify ( dev ,  addr ,  RTM_DELNEIGH ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ndm - > ndm_flags  & =  ~ NTF_SELF ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  nlmsg_populate_fdb ( struct  sk_buff  * skb ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											      struct  netlink_callback  * cb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											      struct  net_device  * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											      int  * idx , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											      struct  netdev_hw_addr_list  * list ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  netdev_hw_addr  * ha ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-07 20:12:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									u32  portid ,  seq ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-07 20:12:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									portid  =  NETLINK_CB ( cb - > skb ) . portid ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									seq  =  cb - > nlh - > nlmsg_seq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									list_for_each_entry ( ha ,  & list - > list ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( * idx  <  cb - > args [ 0 ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  skip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  nlmsg_populate_fdb_fill ( skb ,  dev ,  ha - > addr , 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-01 16:23:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													      portid ,  seq , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      RTM_NEWNEIGH ,  NTF_SELF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								skip :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* idx  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
									
										
										
										
											2012-07-10 10:55:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  ndo_dflt_fdb_dump  -  default  netdevice  operation  to  dump  an  FDB  table . 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  @ nlh :  netlink  message  header 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  @ dev :  netdevice 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Default  netdevice  operation  to  dump  the  existing  unicast  address  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  zero  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  ndo_dflt_fdb_dump ( struct  sk_buff  * skb ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      struct  netlink_callback  * cb , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      struct  net_device  * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      int  idx ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netif_addr_lock_bh ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  nlmsg_populate_fdb ( skb ,  cb ,  dev ,  & idx ,  & dev - > uc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nlmsg_populate_fdb ( skb ,  cb ,  dev ,  & idx ,  & dev - > mc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netif_addr_unlock_bh ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( ndo_dflt_fdb_dump ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_fdb_dump ( struct  sk_buff  * skb ,  struct  netlink_callback  * cb )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  idx  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for_each_netdev_rcu ( net ,  dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dev - > priv_flags  &  IFF_BRIDGE_PORT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  net_device  * br_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  struct  net_device_ops  * ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ops  =  br_dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ops - > ndo_fdb_dump ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												idx  =  ops - > ndo_fdb_dump ( skb ,  cb ,  dev ,  idx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dev - > netdev_ops - > ndo_fdb_dump ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											idx  =  dev - > netdev_ops - > ndo_fdb_dump ( skb ,  cb ,  dev ,  idx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cb - > args [ 0 ]  =  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  skb - > len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  ndo_dflt_bridge_getlink ( struct  sk_buff  * skb ,  u32  pid ,  u32  seq ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    struct  net_device  * dev ,  u16  mode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlmsghdr  * nlh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * br_afspec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u8  operstate  =  netif_running ( dev )  ?  dev - > operstate  :  IF_OPER_DOWN ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nlh  =  nlmsg_put ( skb ,  pid ,  seq ,  RTM_NEWLINK ,  sizeof ( * ifm ) ,  NLM_F_MULTI ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlh  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_family  =  AF_BRIDGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > __ifi_pad  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_type  =  dev - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_index  =  dev - > ifindex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_flags  =  dev_get_flags ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm - > ifi_change  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nla_put_string ( skb ,  IFLA_IFNAME ,  dev - > name )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u32 ( skb ,  IFLA_MTU ,  dev - > mtu )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u8 ( skb ,  IFLA_OPERSTATE ,  operstate )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( br_dev  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     nla_put_u32 ( skb ,  IFLA_MASTER ,  br_dev - > ifindex ) )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    ( dev - > addr_len  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     nla_put ( skb ,  IFLA_ADDRESS ,  dev - > addr_len ,  dev - > dev_addr ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( dev - > ifindex  ! =  dev - > iflink  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									     nla_put_u32 ( skb ,  IFLA_LINK ,  dev - > iflink ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									br_afspec  =  nla_nest_start ( skb ,  IFLA_AF_SPEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! br_afspec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nla_put_u16 ( skb ,  IFLA_BRIDGE_FLAGS ,  BRIDGE_FLAGS_SELF )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    nla_put_u16 ( skb ,  IFLA_BRIDGE_MODE ,  mode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_nest_cancel ( skb ,  br_afspec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_end ( skb ,  br_afspec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nlmsg_end ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								nla_put_failure :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nlmsg_cancel ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( ndo_dflt_bridge_getlink ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_bridge_getlink ( struct  sk_buff  * skb ,  struct  netlink_callback  * cb )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  idx  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u32  portid  =  NETLINK_CB ( cb - > skb ) . portid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u32  seq  =  cb - > nlh - > nlmsg_seq ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  nlattr  * extfilt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u32  filter_mask  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									extfilt  =  nlmsg_find_attr ( cb - > nlh ,  sizeof ( struct  rtgenmsg ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												  IFLA_EXT_MASK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( extfilt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										filter_mask  =  nla_get_u32 ( extfilt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for_each_netdev_rcu ( net ,  dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  struct  net_device_ops  * ops  =  dev - > netdev_ops ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  net_device  * br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( br_dev  & &  br_dev - > netdev_ops - > ndo_bridge_getlink )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 12:56:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( idx  > =  cb - > args [ 0 ]  & & 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											    br_dev - > netdev_ops - > ndo_bridge_getlink ( 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    skb ,  portid ,  seq ,  dev ,  filter_mask )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 12:56:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											idx + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ops - > ndo_bridge_getlink )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 12:56:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( idx  > =  cb - > args [ 0 ]  & & 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											    ops - > ndo_bridge_getlink ( skb ,  portid ,  seq ,  dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														    filter_mask )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 12:56:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											idx + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rcu_read_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cb - > args [ 0 ]  =  idx ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  skb - > len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  inline  size_t  bridge_nlmsg_size ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NLMSG_ALIGN ( sizeof ( struct  ifinfomsg ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( IFNAMSIZ ) 	/* IFLA_IFNAME */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( MAX_ADDR_LEN ) 	/* IFLA_ADDRESS */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( u32 ) ) 	/* IFLA_MASTER */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( u32 ) ) 	/* IFLA_MTU */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( u32 ) ) 	/* IFLA_LINK */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( u32 ) ) 	/* IFLA_OPERSTATE */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( u8 ) ) 	/* IFLA_PROTINFO */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( struct  nlattr ) ) 	/* IFLA_AF_SPEC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( u16 ) ) 	/* IFLA_BRIDGE_FLAGS */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+  nla_total_size ( sizeof ( u16 ) ) ; 	/* IFLA_BRIDGE_MODE */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnl_bridge_notify ( struct  net_device  * dev ,  u16  flags )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  dev_net ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sk_buff  * skb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									skb  =  nlmsg_new ( bridge_nlmsg_size ( ) ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! skb )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( ! flags  | |  ( flags  &  BRIDGE_FLAGS_MASTER ) )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									    br_dev  & &  br_dev - > netdev_ops - > ndo_bridge_getlink )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  br_dev - > netdev_ops - > ndo_bridge_getlink ( skb ,  0 ,  0 ,  dev ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( flags  &  BRIDGE_FLAGS_SELF )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    dev - > netdev_ops - > ndo_bridge_getlink )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  dev - > netdev_ops - > ndo_bridge_getlink ( skb ,  0 ,  0 ,  dev ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  errout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_notify ( skb ,  net ,  0 ,  RTNLGRP_LINK ,  NULL ,  GFP_ATOMIC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								errout :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WARN_ON ( err  = =  - EMSGSIZE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									kfree_skb ( skb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_set_sk_err ( net ,  RTNLGRP_LINK ,  err ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_bridge_setlink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       void  * arg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  nlattr  * br_spec ,  * attr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rem ,  err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									u16  oflags ,  flags  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  have_flags  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlmsg_len ( nlh )  <  sizeof ( * ifm ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifm - > ifi_family  ! =  AF_BRIDGE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EPFNOSUPPORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev  =  __dev_get_by_index ( net ,  ifm - > ifi_index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_SETLINK with unknown ifindex \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									br_spec  =  nlmsg_find_attr ( nlh ,  sizeof ( struct  ifinfomsg ) ,  IFLA_AF_SPEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( br_spec )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_for_each_nested ( attr ,  br_spec ,  rem )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( nla_type ( attr )  = =  IFLA_BRIDGE_FLAGS )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												have_flags  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												flags  =  nla_get_u16 ( attr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									oflags  =  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! flags  | |  ( flags  &  BRIDGE_FLAGS_MASTER ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  net_device  * br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! br_dev  | |  ! br_dev - > netdev_ops - > ndo_bridge_setlink )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-01-03 22:48:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  br_dev - > netdev_ops - > ndo_bridge_setlink ( dev ,  nlh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										flags  & =  ~ BRIDGE_FLAGS_MASTER ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( flags  &  BRIDGE_FLAGS_SELF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! dev - > netdev_ops - > ndo_bridge_setlink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  dev - > netdev_ops - > ndo_bridge_setlink ( dev ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											flags  & =  ~ BRIDGE_FLAGS_SELF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( have_flags ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:13:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memcpy ( nla_data ( attr ) ,  & flags ,  sizeof ( flags ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Generate event to notify upper layer of bridge change */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! err ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-02 16:32:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  rtnl_bridge_notify ( dev ,  oflags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_bridge_dellink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       void  * arg ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ifinfomsg  * ifm ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * br_spec ,  * attr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rem ,  err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u16  oflags ,  flags  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  have_flags  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlmsg_len ( nlh )  <  sizeof ( * ifm ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ifm  =  nlmsg_data ( nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ifm - > ifi_family  ! =  AF_BRIDGE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EPFNOSUPPORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dev  =  __dev_get_by_index ( net ,  ifm - > ifi_index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " PF_BRIDGE: RTM_SETLINK with unknown ifindex \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENODEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									br_spec  =  nlmsg_find_attr ( nlh ,  sizeof ( struct  ifinfomsg ) ,  IFLA_AF_SPEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( br_spec )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_for_each_nested ( attr ,  br_spec ,  rem )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( nla_type ( attr )  = =  IFLA_BRIDGE_FLAGS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												have_flags  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												flags  =  nla_get_u16 ( attr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									oflags  =  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! flags  | |  ( flags  &  BRIDGE_FLAGS_MASTER ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  net_device  * br_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! br_dev  | |  ! br_dev - > netdev_ops - > ndo_bridge_dellink )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  br_dev - > netdev_ops - > ndo_bridge_dellink ( dev ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										flags  & =  ~ BRIDGE_FLAGS_MASTER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( flags  &  BRIDGE_FLAGS_SELF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! dev - > netdev_ops - > ndo_bridge_dellink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  dev - > netdev_ops - > ndo_bridge_dellink ( dev ,  nlh ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											flags  & =  ~ BRIDGE_FLAGS_SELF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( have_flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( nla_data ( attr ) ,  & flags ,  sizeof ( flags ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Generate event to notify upper layer of bridge change */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  rtnl_bridge_notify ( dev ,  oflags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/* Protected by RTNL sempahore.  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  rtattr  * * rta_buf ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtattr_max ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Process one rtnetlink message. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 23:30:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnetlink_rcv_msg ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-26 02:26:21 +09:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net  * net  =  sock_net ( skb - > sk ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_doit_func  doit ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  sz_idx ,  kind ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  min_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  family ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  type ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 07:34:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  =  nlh - > nlmsg_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( type  >  RTM_MAX ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-05 14:35:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									type  - =  RTM_BASE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* All the messages must have at least 1 byte length */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlh - > nlmsg_len  <  NLMSG_LENGTH ( sizeof ( struct  rtgenmsg ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									family  =  ( ( struct  rtgenmsg  * ) NLMSG_DATA ( nlh ) ) - > rtgen_family ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									sz_idx  =  type > > 2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									kind  =  type & 3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-11-16 03:03:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( kind  ! =  2  & &  ! ns_capable ( net - > user_ns ,  CAP_NET_ADMIN ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 23:30:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EPERM ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-18 12:40:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( kind  = =  2  & &  nlh - > nlmsg_flags & NLM_F_DUMP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  sock  * rtnl ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtnl_dumpit_func  dumpit ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtnl_calcit_func  calcit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										u16  min_dump_alloc  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dumpit  =  rtnl_get_dumpit ( family ,  type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dumpit  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-05 14:35:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										calcit  =  rtnl_get_calcit ( family ,  type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( calcit ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-21 16:54:48 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											min_dump_alloc  =  calcit ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-10 02:25:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 07:34:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										__rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtnl  =  net - > rtnl ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-24 14:30:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  netlink_dump_control  c  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												. dump 		=  dumpit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												. min_dump_alloc 	=  min_dump_alloc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  netlink_dump_start ( rtnl ,  skb ,  nlh ,  & c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 07:34:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( rta_buf ,  0 ,  ( rtattr_max  *  sizeof ( struct  rtattr  * ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									min_len  =  rtm_min [ sz_idx ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlh - > nlmsg_len  <  min_len ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 23:30:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nlh - > nlmsg_len  >  min_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  attrlen  =  nlh - > nlmsg_len  -  NLMSG_ALIGN ( min_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-07 01:26:17 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  rtattr  * attr  =  ( void  * ) nlh  +  NLMSG_ALIGN ( min_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( RTA_OK ( attr ,  attrlen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 05:58:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											unsigned  int  flavor  =  attr - > rta_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( flavor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( flavor  >  rta_max [ sz_idx ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 23:30:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  - EINVAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												rta_buf [ flavor - 1 ]  =  attr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											attr  =  RTA_NEXT ( attr ,  attrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:48:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									doit  =  rtnl_get_doit ( family ,  type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( doit  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-05 14:35:52 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 23:30:12 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  doit ( skb ,  nlh ,  ( void  * ) & rta_buf [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-10 21:15:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  rtnetlink_rcv ( struct  sk_buff  * skb )  
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-10-10 21:15:29 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									netlink_rcv_skb ( skb ,  & rtnetlink_rcv_msg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnetlink_event ( struct  notifier_block  * this ,  unsigned  long  event ,  void  * ptr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * dev  =  ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-12 13:02:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  ( event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_DOWN : 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-26 06:34:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  NETDEV_PRE_UP : 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-12 22:11:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  NETDEV_POST_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_REGISTER : 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  NETDEV_CHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-19 04:42:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  NETDEV_PRE_TYPE_CHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  NETDEV_GOING_DOWN : 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-26 06:34:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  NETDEV_UNREGISTER : 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-22 17:19:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  NETDEV_UNREGISTER_FINAL : 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-19 23:06:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  NETDEV_RELEASE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NETDEV_JOIN : 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtmsg_ifinfo ( RTM_NEWLINK ,  dev ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NOTIFY_DONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  notifier_block  rtnetlink_dev_notifier  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. notifier_call 	=  rtnetlink_event , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  __net_init  rtnetlink_net_init ( struct  net  * net )  
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sock  * sk ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-29 06:15:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  netlink_kernel_cfg  cfg  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. groups 		=  RTNLGRP_MAX , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. input 		=  rtnetlink_rcv , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. cb_mutex 	=  & rtnl_mutex , 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 02:53:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										. flags 		=  NL_CFG_F_NONROOT_RECV , 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-29 06:15:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-09-08 02:53:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sk  =  netlink_kernel_create ( net ,  NETLINK_ROUTE ,  & cfg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! sk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - ENOMEM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									net - > rtnl  =  sk ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-17 03:35:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  __net_exit  rtnetlink_net_exit ( struct  net  * net )  
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-01-18 23:55:19 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									netlink_kernel_release ( net - > rtnl ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									net - > rtnl  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  pernet_operations  rtnetlink_net_ops  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. init  =  rtnetlink_net_init , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. exit  =  rtnetlink_net_exit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  __init  rtnetlink_init ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtattr_max  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  ARRAY_SIZE ( rta_max ) ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rta_max [ i ]  >  rtattr_max ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtattr_max  =  rta_max [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rta_buf  =  kmalloc ( rtattr_max  *  sizeof ( struct  rtattr  * ) ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rta_buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										panic ( " rtnetlink_init: cannot allocate rta_buf \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( register_pernet_subsys ( & rtnetlink_net_ops ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										panic ( " rtnetlink_init: cannot initialize rtnetlink \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-19 22:26:51 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									register_netdevice_notifier ( & rtnetlink_dev_notifier ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:49:22 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_register ( PF_UNSPEC ,  RTM_GETLINK ,  rtnl_getlink , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      rtnl_dump_ifinfo ,  rtnl_calcit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_UNSPEC ,  RTM_SETLINK ,  rtnl_setlink ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_UNSPEC ,  RTM_NEWLINK ,  rtnl_newlink ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_UNSPEC ,  RTM_DELLINK ,  rtnl_dellink ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-22 11:59:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-10 01:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_register ( PF_UNSPEC ,  RTM_GETADDR ,  NULL ,  rtnl_dump_all ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_UNSPEC ,  RTM_GETROUTE ,  NULL ,  rtnl_dump_all ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_BRIDGE ,  RTM_NEWNEIGH ,  rtnl_fdb_add ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_BRIDGE ,  RTM_DELNEIGH ,  rtnl_fdb_del ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_BRIDGE ,  RTM_GETNEIGH ,  NULL ,  rtnl_fdb_dump ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_register ( PF_BRIDGE ,  RTM_GETLINK ,  NULL ,  rtnl_bridge_getlink ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_register ( PF_BRIDGE ,  RTM_DELLINK ,  rtnl_bridge_dellink ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_register ( PF_BRIDGE ,  RTM_SETLINK ,  rtnl_bridge_setlink ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}