drivers/net/loopback.c
changeset 2 d1f6d8b6f81c
parent 0 aa628870c1d3
equal deleted inserted replaced
1:0056487c491e 2:d1f6d8b6f81c
    74 
    74 
    75 	skb_orphan(skb);
    75 	skb_orphan(skb);
    76 
    76 
    77 	skb->protocol = eth_type_trans(skb,dev);
    77 	skb->protocol = eth_type_trans(skb,dev);
    78 
    78 
    79 	dev->last_rx = jiffies;
       
    80 
       
    81 	/* it's OK to use per_cpu_ptr() because BHs are off */
    79 	/* it's OK to use per_cpu_ptr() because BHs are off */
    82 	pcpu_lstats = dev->ml_priv;
    80 	pcpu_lstats = dev->ml_priv;
    83 	lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
    81 	lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
    84 	lb_stats->bytes += skb->len;
    82 	lb_stats->bytes += skb->len;
    85 	lb_stats->packets++;
    83 	lb_stats->packets++;
    87 	netif_rx(skb);
    85 	netif_rx(skb);
    88 
    86 
    89 	return 0;
    87 	return 0;
    90 }
    88 }
    91 
    89 
    92 static struct net_device_stats *get_stats(struct net_device *dev)
    90 static struct net_device_stats *loopback_get_stats(struct net_device *dev)
    93 {
    91 {
    94 	const struct pcpu_lstats *pcpu_lstats;
    92 	const struct pcpu_lstats *pcpu_lstats;
    95 	struct net_device_stats *stats = &dev->stats;
    93 	struct net_device_stats *stats = &dev->stats;
    96 	unsigned long bytes = 0;
    94 	unsigned long bytes = 0;
    97 	unsigned long packets = 0;
    95 	unsigned long packets = 0;
   143 
   141 
   144 	free_percpu(lstats);
   142 	free_percpu(lstats);
   145 	free_netdev(dev);
   143 	free_netdev(dev);
   146 }
   144 }
   147 
   145 
       
   146 static const struct net_device_ops loopback_ops = {
       
   147 	.ndo_init      = loopback_dev_init,
       
   148 	.ndo_start_xmit= loopback_xmit,
       
   149 	.ndo_get_stats = loopback_get_stats,
       
   150 };
       
   151 
   148 /*
   152 /*
   149  * The loopback device is special. There is only one instance
   153  * The loopback device is special. There is only one instance
   150  * per network namespace.
   154  * per network namespace.
   151  */
   155  */
   152 static void loopback_setup(struct net_device *dev)
   156 static void loopback_setup(struct net_device *dev)
   153 {
   157 {
   154 	dev->get_stats		= &get_stats;
       
   155 	dev->mtu		= (16 * 1024) + 20 + 20 + 12;
   158 	dev->mtu		= (16 * 1024) + 20 + 20 + 12;
   156 	dev->hard_start_xmit	= loopback_xmit;
       
   157 	dev->hard_header_len	= ETH_HLEN;	/* 14	*/
   159 	dev->hard_header_len	= ETH_HLEN;	/* 14	*/
   158 	dev->addr_len		= ETH_ALEN;	/* 6	*/
   160 	dev->addr_len		= ETH_ALEN;	/* 6	*/
   159 	dev->tx_queue_len	= 0;
   161 	dev->tx_queue_len	= 0;
   160 	dev->type		= ARPHRD_LOOPBACK;	/* 0x0001*/
   162 	dev->type		= ARPHRD_LOOPBACK;	/* 0x0001*/
   161 	dev->flags		= IFF_LOOPBACK;
   163 	dev->flags		= IFF_LOOPBACK;
   165 		| NETIF_F_HIGHDMA
   167 		| NETIF_F_HIGHDMA
   166 		| NETIF_F_LLTX
   168 		| NETIF_F_LLTX
   167 		| NETIF_F_NETNS_LOCAL;
   169 		| NETIF_F_NETNS_LOCAL;
   168 	dev->ethtool_ops	= &loopback_ethtool_ops;
   170 	dev->ethtool_ops	= &loopback_ethtool_ops;
   169 	dev->header_ops		= &eth_header_ops;
   171 	dev->header_ops		= &eth_header_ops;
   170 	dev->init = loopback_dev_init;
   172 	dev->netdev_ops		= &loopback_ops;
   171 	dev->destructor = loopback_dev_free;
   173 	dev->destructor		= loopback_dev_free;
   172 }
   174 }
   173 
   175 
   174 /* Setup and register the loopback device. */
   176 /* Setup and register the loopback device. */
   175 static __net_init int loopback_net_init(struct net *net)
   177 static __net_init int loopback_net_init(struct net *net)
   176 {
   178 {
   204 	struct net_device *dev = net->loopback_dev;
   206 	struct net_device *dev = net->loopback_dev;
   205 
   207 
   206 	unregister_netdev(dev);
   208 	unregister_netdev(dev);
   207 }
   209 }
   208 
   210 
   209 static struct pernet_operations __net_initdata loopback_net_ops = {
   211 /* Registered in net/core/dev.c */
       
   212 struct pernet_operations __net_initdata loopback_net_ops = {
   210        .init = loopback_net_init,
   213        .init = loopback_net_init,
   211        .exit = loopback_net_exit,
   214        .exit = loopback_net_exit,
   212 };
   215 };
   213 
       
   214 static int __init loopback_init(void)
       
   215 {
       
   216 	return register_pernet_device(&loopback_net_ops);
       
   217 }
       
   218 
       
   219 /* Loopback is special. It should be initialized before any other network
       
   220  * device and network subsystem.
       
   221  */
       
   222 fs_initcall(loopback_init);