2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 6 * Pseudo-driver for the loopback interface. 8 * Version: @(#)loopback.c 1.0.4b 08/16/93 10 * Authors: Ross Biro, <bir7@leland.Stanford.Edu> 11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 12 * Donald Becker, <becker@cesdis.gsfc.nasa.gov> 14 * Alan Cox : Fixed oddments for NET3.014 15 * Alan Cox : Rejig for NET3.029 snap #3 16 * Alan Cox : Fixed NET3.029 bugs and sped up 17 * Larry McVoy : Tiny tweak to double performance 18 * Alan Cox : Backed out LMV's tweak - the linux mm 20 * Michael Griffith: Don't bother computing the checksums 21 * on packets received on the loopback 23 * Alexey Kuznetsov: Potential hang under some extreme 26 * This program is free software; you can redistribute it and/or 27 * modify it under the terms of the GNU General Public License 28 * as published by the Free Software Foundation; either version 29 * 2 of the License, or (at your option) any later version. 31 #include <linux/config.h> 32 #include <linux/kernel.h> 33 #include <linux/sched.h> 34 #include <linux/interrupt.h> 36 #include <linux/types.h> 37 #include <linux/string.h> 38 #include <linux/socket.h> 39 #include <linux/errno.h> 40 #include <linux/fcntl.h> 43 #include <asm/system.h> 44 #include <asm/uaccess.h> 47 #include <linux/inet.h> 48 #include <linux/netdevice.h> 49 #include <linux/etherdevice.h> 50 #include <linux/skbuff.h> 52 #include <linux/if_ether.h>/* For the statistics structure. */ 53 #include <linux/if_arp.h>/* For ARPHRD_ETHER */ 55 #define LOOPBACK_MTU (PAGE_SIZE*7/8) 58 * The higher levels take care of making this non-reentrant (it's 59 * called with bh's disabled). 61 static intloopback_xmit(struct sk_buff
*skb
,struct device
*dev
) 63 struct enet_statistics
*stats
= (struct enet_statistics
*)dev
->priv
; 65 if(skb
== NULL
|| dev
== NULL
) 69 * Optimise so buffers with skb->free=1 are not copied but 70 * instead are lobbed from tx queue to rx queue 75 struct sk_buff
*skb2
=skb
; 76 skb
=skb_clone(skb
, GFP_ATOMIC
);/* Clone the buffer */ 78 kfree_skb(skb2
, FREE_WRITE
); 81 kfree_skb(skb2
, FREE_WRITE
); 86 skb
->protocol
=eth_type_trans(skb
,dev
); 88 #ifndef LOOPBACK_MUST_CHECKSUM 89 skb
->ip_summed
= CHECKSUM_UNNECESSARY
; 99 static struct enet_statistics
*get_stats(struct device
*dev
) 101 return(struct enet_statistics
*)dev
->priv
; 104 static intloopback_open(struct device
*dev
) 106 dev
->flags
|=IFF_LOOPBACK
; 110 /* Initialize the rest of the LOOPBACK device. */ 111 intloopback_init(struct device
*dev
) 115 dev
->mtu
= LOOPBACK_MTU
; 117 dev
->hard_start_xmit
= loopback_xmit
; 118 dev
->hard_header
= eth_header
; 119 dev
->hard_header_cache
= eth_header_cache
; 120 dev
->header_cache_update
= eth_header_cache_update
; 121 dev
->hard_header_len
= ETH_HLEN
;/* 14 */ 122 dev
->addr_len
= ETH_ALEN
;/* 6 */ 123 dev
->tx_queue_len
=0; 124 dev
->type
= ARPHRD_LOOPBACK
;/* 0x0001 */ 125 dev
->rebuild_header
= eth_rebuild_header
; 126 dev
->open
= loopback_open
; 127 dev
->flags
= IFF_LOOPBACK
|IFF_BROADCAST
; 128 dev
->family
= AF_INET
; 130 dev
->pa_addr
=in_aton("127.0.0.1"); 131 dev
->pa_brdaddr
=in_aton("127.255.255.255"); 132 dev
->pa_mask
=in_aton("255.0.0.0"); 135 dev
->priv
=kmalloc(sizeof(struct enet_statistics
), GFP_KERNEL
); 136 if(dev
->priv
== NULL
) 138 memset(dev
->priv
,0,sizeof(struct enet_statistics
)); 139 dev
->get_stats
= get_stats
; 142 * Fill in the generic fields of the device structure. 145 for(i
=0; i
< DEV_NUMBUFFS
; i
++) 146 skb_queue_head_init(&dev
->buffs
[i
]);