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 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  size_t  rtnl_link_get_slave_info_data_size ( const  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * master_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									master_dev  =  netdev_master_upper_dev_get ( ( struct  net_device  * )  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! master_dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ops  =  master_dev - > rtnl_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ops - > get_slave_size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* IFLA_INFO_SLAVE_DATA + nested data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nla_total_size ( sizeof ( struct  nlattr ) )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       ops - > get_slave_size ( master_dev ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									size  + =  rtnl_link_get_slave_info_data_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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Returns  0  on  success  or  a  negative  error  code . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-30 10:41:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  rtnl_af_register ( struct  rtnl_af_ops  * ops )  
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtnl_lock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-30 10:41:32 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									list_add_tail ( & ops - > list ,  & rtnl_af_ops ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 04:30:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  bool  rtnl_have_link_slave_info ( const  struct  net_device  * dev )  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * master_dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									master_dev  =  netdev_master_upper_dev_get ( ( struct  net_device  * )  dev ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-23 19:19:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( master_dev  & &  master_dev - > rtnl_link_ops ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnl_link_slave_info_fill ( struct  sk_buff  * skb ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												     const  struct  net_device  * dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  net_device  * master_dev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * slave_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									master_dev  =  netdev_master_upper_dev_get ( ( struct  net_device  * )  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! master_dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ops  =  master_dev - > rtnl_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ops ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nla_put_string ( skb ,  IFLA_INFO_SLAVE_KIND ,  ops - > kind )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ops - > fill_slave_info )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										slave_data  =  nla_nest_start ( skb ,  IFLA_INFO_SLAVE_DATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! slave_data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  ops - > fill_slave_info ( skb ,  master_dev ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  err_cancel_slave_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_nest_end ( skb ,  slave_data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								err_cancel_slave_data :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_cancel ( skb ,  slave_data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnl_link_info_fill ( struct  sk_buff  * skb ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											       const  struct  net_device  * dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * ops  =  dev - > rtnl_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ops ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nla_put_string ( skb ,  IFLA_INFO_KIND ,  ops - > kind )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ops - > fill_xstats )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  ops - > fill_xstats ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ops - > fill_info )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										data  =  nla_nest_start ( skb ,  IFLA_INFO_DATA ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( data  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - EMSGSIZE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  ops - > fill_info ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  err_cancel_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nla_nest_end ( skb ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								err_cancel_data :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_cancel ( skb ,  data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtnl_link_fill ( struct  sk_buff  * skb ,  const  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  nlattr  * linkinfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									linkinfo  =  nla_nest_start ( skb ,  IFLA_LINKINFO ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( linkinfo  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  rtnl_link_info_fill ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err_cancel_link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  rtnl_link_slave_info_fill ( skb ,  dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  err_cancel_link ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_end ( skb ,  linkinfo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								err_cancel_link :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									nla_nest_cancel ( skb ,  linkinfo ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								out :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-29 18:16:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									       +  rtnl_link_get_af_size ( dev )  /* IFLA_AF_SPEC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									       +  nla_total_size ( MAX_PHYS_PORT_ID_LEN ) ;  /* IFLA_PHYS_PORT_ID */ 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-29 18:16:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_phys_port_id_fill ( struct  sk_buff  * skb ,  struct  net_device  * dev )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  netdev_phys_port_id  ppid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  dev_get_phys_port_id ( dev ,  & ppid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( err  = =  - EOPNOTSUPP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( nla_put ( skb ,  IFLA_PHYS_PORT_ID ,  ppid . id_len ,  ppid . id ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EMSGSIZE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-29 18:16:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( rtnl_phys_port_id_fill ( skb ,  dev ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  nla_put_failure ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-13 13:19:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  ifla_vf_link_state  vf_linkstate ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-08 03:05:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  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 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-13 13:19:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* The default value for VF link state is "auto"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  IFLA_VF_LINK_STATE_AUTO  which  equals  zero 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ivi . linkstate  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											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  = 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-13 13:19:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												vf_spoofchk . vf  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												vf_linkstate . vf  =  ivi . vf ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-08 03:05:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-13 13:19:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											vf_linkstate . link_state  =  ivi . linkstate ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-13 13:19:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												    & vf_spoofchk )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    nla_put ( skb ,  IFLA_VF_LINK_STATE ,  sizeof ( vf_linkstate ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    & vf_linkstate ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-01 20:12:00 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev - > rtnl_link_ops  | |  rtnl_have_link_slave_info ( dev ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-08 05:45:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nlmsg_parse ( cb - > nlh ,  sizeof ( struct  ifinfomsg ) ,  tb ,  IFLA_MAX , 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-04 12:32:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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  } , 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-29 18:16:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_PHYS_PORT_ID ] 	=  {  . type  =  NLA_BINARY ,  . len  =  MAX_PHYS_PORT_ID_LEN  } , 
							 
						 
					
						
							
								
									
										
										
										
											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  } , 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									[ IFLA_INFO_SLAVE_KIND ] 	=  {  . type  =  NLA_STRING  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									[ IFLA_INFO_SLAVE_DATA ] 	=  {  . type  =  NLA_NESTED  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-13 13:19:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  IFLA_VF_LINK_STATE :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ifla_vf_link_state  * ivl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ivl  =  nla_data ( vf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ops - > ndo_set_vf_link_state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  ops - > ndo_set_vf_link_state ( dev ,  ivl - > vf , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 ivl - > link_state ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_setlink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:36 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_dellink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-09-25 12:02:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									__dev_notify_flags ( dev ,  old_flags ,  ~ 0U ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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  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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_newlink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  struct  rtnl_link_ops  * m_ops  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * dev ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * master_dev  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										master_dev  =  netdev_master_upper_dev_get ( dev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( master_dev ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											m_ops  =  master_dev - > rtnl_link_ops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  nlattr  * attr [ ops  ?  ops - > maxtype  +  1  :  0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * slave_attr [ m_ops  ?  m_ops - > slave_maxtype  +  1  :  0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * * data  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  nlattr  * * slave_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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( m_ops )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( m_ops - > slave_maxtype  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    linkinfo [ IFLA_INFO_SLAVE_DATA ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  nla_parse_nested ( slave_attr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														       m_ops - > slave_maxtype , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														       linkinfo [ IFLA_INFO_SLAVE_DATA ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														       m_ops - > slave_policy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												slave_data  =  slave_attr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( m_ops - > slave_validate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  m_ops - > slave_validate ( tb ,  slave_data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-01-22 09:05:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( linkinfo [ IFLA_INFO_SLAVE_DATA ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! m_ops  | |  ! m_ops - > slave_changelink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  m_ops - > slave_changelink ( master_dev ,  dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															      tb ,  slave_data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( err  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												modified  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-08-14 12:35:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( err  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-13 12:03:51 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											free_netdev ( dev ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-14 12:35:42 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_getlink ( struct  sk_buff  * skb ,  struct  nlmsghdr *  nlh )  
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-04-08 05:45:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nlmsg_parse ( nlh ,  sizeof ( struct  ifinfomsg ) ,  tb ,  IFLA_MAX , 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-04 12:32:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-22 06:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( idx  >  s_idx )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											memset ( & cb - > args [ 0 ] ,  0 ,  sizeof ( cb - > args ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-22 06:28:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cb - > prev_seq  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											cb - > seq  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-10-23 16:02:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  rtmsg_ifinfo ( int  type ,  struct  net_device  * dev ,  unsigned  int  change ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										  gfp_t  flags ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-10-23 16:02:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									skb  =  nlmsg_new ( ( if_info_size  =  if_nlmsg_size ( dev ,  0 ) ) ,  flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-23 16:02:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtnl_notify ( skb ,  net ,  0 ,  RTNLGRP_LINK ,  NULL ,  flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-24 23:18:28 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-06 15:39:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  ndo_dflt_fdb_add  -  default  netdevice  operation  to  add  an  FDB  entry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  ndo_dflt_fdb_add ( struct  ndmsg  * ndm ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     struct  nlattr  * tb [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     struct  net_device  * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     const  unsigned  char  * addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     u16  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If aging addresses are supported device will need to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  implement  its  own  handler  for  this . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ndm - > ndm_state  & &  ! ( ndm - > ndm_state  &  NUD_PERMANENT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pr_info ( " %s: FDB only supports static addresses \n " ,  dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_unicast_ether_addr ( addr )  | |  is_link_local_ether_addr ( addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  dev_uc_add_excl ( dev ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( is_multicast_ether_addr ( addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  dev_mc_add_excl ( dev ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Only return duplicate errors if NLM_F_EXCL is set */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( err  = =  - EEXIST  & &  ! ( flags  &  NLM_F_EXCL ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( ndo_dflt_fdb_add ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_fdb_add ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-06 15:39:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( ndm - > ndm_flags  &  NTF_SELF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dev - > netdev_ops - > ndo_fdb_add ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  dev - > netdev_ops - > ndo_fdb_add ( ndm ,  tb ,  dev ,  addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															   nlh - > nlmsg_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  ndo_dflt_fdb_add ( ndm ,  tb ,  dev ,  addr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													       nlh - > nlmsg_flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-06 15:39:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/**
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  ndo_dflt_fdb_del  -  default  netdevice  operation  to  delete  an  FDB  entry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  ndo_dflt_fdb_del ( struct  ndmsg  * ndm ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     struct  nlattr  * tb [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     struct  net_device  * dev , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     const  unsigned  char  * addr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  err  =  - EOPNOTSUPP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If aging addresses are supported device will need to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  implement  its  own  handler  for  this . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-08 15:19:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( ndm - > ndm_state  &  NUD_PERMANENT ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-06 15:39:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pr_info ( " %s: FDB only supports static addresses \n " ,  dev - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_unicast_ether_addr ( addr )  | |  is_link_local_ether_addr ( addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  dev_uc_del ( dev ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( is_multicast_ether_addr ( addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  dev_mc_del ( dev ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										err  =  - EINVAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  err ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								EXPORT_SYMBOL ( ndo_dflt_fdb_del ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_fdb_del ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-06 15:39:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ndm - > ndm_flags  &  NTF_SELF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dev - > netdev_ops - > ndo_fdb_del ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  dev - > netdev_ops - > ndo_fdb_del ( ndm ,  tb ,  dev ,  addr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  ndo_dflt_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 . 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-29 08:18:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Returns  number  of  addresses  from  list  put  in  skb . 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:44:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-06 15:39:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-29 08:18:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											idx  =  ndo_dflt_fdb_dump ( skb ,  cb ,  dev ,  idx ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-04-15 06:43:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												rtnetlink: rtnl_bridge_getlink: Call nlmsg_find_attr() with ifinfomsg header
Fix the iproute2 command `bridge vlan show`, after switching from
rtgenmsg to ifinfomsg.
Let's start with a little history:
Feb 20:   Vlad Yasevich got his VLAN-aware bridge patchset included in
          the 3.9 merge window.
          In the kernel commit 6cbdceeb, he added attribute support to
          bridge GETLINK requests sent with rtgenmsg.
Mar 6th:  Vlad got this iproute2 reference implementation of the bridge
          vlan netlink interface accepted (iproute2 9eff0e5c)
Apr 25th: iproute2 switched from using rtgenmsg to ifinfomsg (63338dca)
          http://patchwork.ozlabs.org/patch/239602/
          http://marc.info/?t=136680900700007
Apr 28th: Linus released 3.9
Apr 30th: Stephen released iproute2 3.9.0
The `bridge vlan show` command haven't been working since the switch to
ifinfomsg, or in a released version of iproute2. Since the kernel side
only supports rtgenmsg, which iproute2 switched away from just prior to
the iproute2 3.9.0 release.
I haven't been able to find any documentation, about neither rtgenmsg
nor ifinfomsg, and in which situation to use which, but kernel commit
88c5b5ce seams to suggest that ifinfomsg should be used.
Fixing this in kernel will break compatibility, but I doubt that anybody
have been using it due to this bug in the user space reference
implementation, at least not without noticing this bug. That said the
functionality is still fully functional in 3.9, when reversing iproute2
commit 63338dca.
This could also be fixed in iproute2, but thats an ugly patch that would
reintroduce rtgenmsg in iproute2, and from searching in netdev it seams
like rtgenmsg usage is discouraged. I'm assuming that the only reason
that Vlad implemented the kernel side to use rtgenmsg, was because
iproute2 was using it at the time.
Signed-off-by: Asbjoern Sloth Toennesen <ast@fiberby.net>
Reviewed-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
											 
										 
										
											2013-08-12 16:30:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									extfilt  =  nlmsg_find_attr ( cb - > nlh ,  sizeof ( struct  ifinfomsg ) , 
							 
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												  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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_bridge_setlink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2012-10-24 08:12:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtnl_bridge_dellink ( struct  sk_buff  * skb ,  struct  nlmsghdr  * nlh )  
						 
					
						
							
								
									
										
										
										
											2013-02-13 12:00:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/* 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  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 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-03-27 06:47:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( nlmsg_len ( nlh )  <  sizeof ( struct  rtgenmsg ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-27 06:47:04 +00: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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-03-21 07:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  doit ( skb ,  nlh ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2013-05-28 01:30:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  net_device  * dev  =  netdev_notifier_info_to_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 : 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-23 16:02:42 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtmsg_ifinfo ( RTM_NEWLINK ,  dev ,  0 ,  GFP_KERNEL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-16 15:20:36 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										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 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}