Commit 9ec7e58c authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.17

parent c2700b1f
VERSION = 1
PATCHLEVEL = 1
SUBLEVEL = 16
SUBLEVEL = 17
all: Version zImage
......
......@@ -73,6 +73,7 @@ if [ "$CONFIG_NETDEVICES" = "n" ]; then
comment 'Skipping ethercard configuration options...'
else
bool 'Dummy net driver support' CONFIG_DUMMY y
bool 'SLIP (serial line) support' CONFIG_SLIP n
if [ "$CONFIG_SLIP" = "y" ]; then
bool ' CSLIP compressed headers' SL_COMPRESSED y
......@@ -98,7 +99,7 @@ bool 'DEPCA support' CONFIG_DEPCA n
#bool 'NI52EE support' CONFIG_NI52 n
#bool 'NI65EE support' CONFIG_NI65 n
#bool 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
#bool 'Cabletron E21xx support (not recommended)' CONFIG_E21 n
#bool 'Cabletron E21xx support (not recommended)' CONFIG_E2100 n
bool 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
fi
......
......@@ -82,6 +82,12 @@ ifdef CONFIG_3C589
NETDRV_OBJS := $(NETDRV_OBJS) net.a(3c589.o)
endif
ifdef CONFIG_DUMMY
NETDRV_OBJS := $(NETDRV_OBJS) net.a(dummy.o)
dummy.o: dummy.c CONFIG
$(CC) $(CPPFLAGS) $(CFLAGS) -c $<
endif
ifdef CONFIG_DE600
NETDRV_OBJS := $(NETDRV_OBJS) net.a(de600.o)
endif
......
/* dummy.c: a dummy net driver
The purpose of this driver is to provide a device to point a
route through, but not to actually transmit packets.
Why? If you have a machine whose only connection is an occasional
PPP/SLIP/PLIP link, you can only connect to your own hostname
when the link is up. Otherwise you have to use localhost.
This isn't very consistent.
One solution is to set up a dummy link using PPP/SLIP/PLIP,
but this seems (to me) too much overhead for too little gain.
This driver provides a small alternative. Thus you can do
[when not running slip]
ifconfig dummy slip.addr.ess.here up
[to go to slip]
ifconfig dummy down
dip whatever
This was written by looking at Donald Becker's skeleton driver
and the loopback driver. I then threw away anything that didn't
apply! Thanks to Alan Cox for the key clue on what to do with
misguided packets.
Nick Holloway, 27th May 1994
[I tweaked this explanation a little but thats all]
Alan Cox, 30th May 1994
*/
/* To have statistics (just packets sent) define this */
#undef DUMMY_STATS
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/malloc.h>
#include <linux/string.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
static int dummy_xmit(struct sk_buff *skb, struct device *dev);
#ifdef DUMMY_STATS
static struct enet_statistics *dummy_get_stats(struct device *dev);
#endif
int
dummy_init(struct device *dev)
{
/* I commented this out as bootup is noisy enough anyway and this driver
seems pretty reliable 8) 8) 8) */
/* printk ( KERN_INFO "Dummy net driver (94/05/27 v1.0)\n" ); */
/* Initialize the device structure. */
dev->hard_start_xmit = dummy_xmit;
#if DUMMY_STATS
dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
memset(dev->priv, 0, sizeof(struct enet_statistics));
dev->get_stats = dummy_get_stats;
#endif
/* Fill in the fields of the device structure with ethernet-generic values. */
ether_setup(dev);
return 0;
}
static int
dummy_xmit(struct sk_buff *skb, struct device *dev)
{
#if DUMMY_STATS
struct enet_statistics *stats;
#endif
if (skb == NULL || dev == NULL)
return 0;
if (skb->free)
kfree_skb(skb, FREE_WRITE);
#if DUMMY_STATS
stats = (struct enet_statistics *)dev->priv;
stats->tx_packets++;
#endif
return 0;
}
#if DUMMY_STATS
static struct enet_statistics *
dummy_get_stats(struct device *dev)
{
struct enet_statistics *stats = (struct enet_statistics*) dev->priv;
return stats;
}
#endif
......@@ -15,7 +15,9 @@
A secondary advantage is that the dangerous NE*000 netcards can reserve
their I/O port region before the SCSI probes start.
register_netdev()/unregister_netdev() by Bjorn Ekwall <bj0rn@blox.se>
Modifications/additions by Bjorn Ekwall <bj0rn@blox.se>:
ethdev_index[MAX_ETH_CARDS]
register_netdev() / unregister_netdev()
*/
#include <linux/config.h>
......@@ -45,8 +47,9 @@
by magic we get them, but otherwise they are un-needed and a space waste]
*/
/* The next device number/name to assign: "eth0", "eth1", etc. */
static int next_ethdev_number = 0;
/* The list of used and available "eth" slots (for "eth0", "eth1", etc.) */
#define MAX_ETH_CARDS 16 /* same as the number if irq's in irq2dev[] */
static struct device *ethdev_index[MAX_ETH_CARDS];
unsigned long lance_init(unsigned long mem_start, unsigned long mem_end);
......@@ -78,11 +81,11 @@ unsigned long net_dev_init (unsigned long mem_start, unsigned long mem_end)
long.
*/
struct device *init_etherdev(struct device *dev, int sizeof_private,
unsigned long *mem_startp)
struct device *
init_etherdev(struct device *dev, int sizeof_private, unsigned long *mem_startp)
{
int i;
int new_device = 0;
int i;
if (dev == NULL) {
int alloc_size = sizeof(struct device) + sizeof("eth%d ")
......@@ -99,31 +102,17 @@ struct device *init_etherdev(struct device *dev, int sizeof_private,
new_device = 1;
}
if (dev->name && dev->name[0] == '\0')
sprintf(dev->name, "eth%d", next_ethdev_number++);
for (i = 0; i < DEV_NUMBUFFS; i++)
skb_queue_head_init(&dev->buffs[i]);
dev->hard_header = eth_header;
dev->rebuild_header = eth_rebuild_header;
dev->type_trans = eth_type_trans;
dev->type = ARPHRD_ETHER;
dev->hard_header_len = ETH_HLEN;
dev->mtu = 1500; /* eth_mtu */
dev->addr_len = ETH_ALEN;
for (i = 0; i < ETH_ALEN; i++) {
dev->broadcast[i]=0xff;
if (dev->name &&
((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
for (i = 0; i < MAX_ETH_CARDS; ++i)
if (ethdev_index[i] == NULL) {
sprintf(dev->name, "eth%d", i);
ethdev_index[i] = dev;
break;
}
}
/* New-style flags. */
dev->flags = IFF_BROADCAST;
dev->family = AF_INET;
dev->pa_addr = 0;
dev->pa_brdaddr = 0;
dev->pa_mask = 0;
dev->pa_alen = sizeof(unsigned long);
ether_setup(dev); /* should this be called here? */
if (new_device) {
/* Append the device to the device queue. */
......@@ -144,6 +133,19 @@ void ether_setup(struct device *dev)
for (i = 0; i < DEV_NUMBUFFS; i++)
skb_queue_head_init(&dev->buffs[i]);
/* register boot-defined "eth" devices */
if (dev->name && (strncmp(dev->name, "eth", 3) == 0)) {
i = simple_strtoul(dev->name + 3, NULL, 0);
if (ethdev_index[i] == NULL) {
ethdev_index[i] = dev;
}
else if (dev != ethdev_index[i]) {
/* Really shouldn't happen! */
printk("ether_setup: Ouch! Someone else took %s\n",
dev->name);
}
}
dev->hard_header = eth_header;
dev->rebuild_header = eth_rebuild_header;
dev->type_trans = eth_type_trans;
......@@ -186,24 +188,30 @@ int register_netdev(struct device *dev)
{
struct device *d = dev_base;
unsigned long flags;
int i;
save_flags(flags);
cli();
if (dev && dev->init)
{
if (dev->init(dev) != 0)
{
if (dev && dev->init) {
if (dev->init(dev) != 0) {
restore_flags(flags);
return -EIO;
}
if (dev->name && dev->name[0] == '\0')
sprintf(dev->name, "eth%d", next_ethdev_number++);
if (dev->name &&
((dev->name[0] == '\0') || (dev->name[0] == ' '))) {
for (i = 0; i < MAX_ETH_CARDS; ++i)
if (ethdev_index[i] == NULL) {
sprintf(dev->name, "eth%d", i);
printk("device '%s' loaded\n", dev->name);
ethdev_index[i] = dev;
break;
}
}
/* Add device to end of chain */
if (dev_base)
{
if (dev_base) {
while (d->next)
d = d->next;
d->next = dev;
......@@ -220,36 +228,49 @@ void unregister_netdev(struct device *dev)
{
struct device *d = dev_base;
unsigned long flags;
int i;
save_flags(flags);
cli();
printk("unregister_netdev: device ");
if (dev) {
if (dev->start)
printk("'%s' busy", dev->name);
if (dev == NULL) {
printk("was NULL\n");
restore_flags(flags);
return;
}
/* else */
if (dev->start)
printk("'%s' busy\n", dev->name);
else {
if (dev_base == dev)
dev_base = dev->next;
else {
if (dev_base == dev)
dev_base = dev->next;
else {
while (d && (d->next != dev))
d = d->next;
while (d && (d->next != dev))
d = d->next;
if (d && (d->next == dev)) {
d->next = dev->next;
printk("'%s' unlinked", dev->name);
}
else
printk("'%s' not found", dev->name);
if (d && (d->next == dev)) {
d->next = dev->next;
printk("'%s' unlinked\n", dev->name);
}
else {
printk("'%s' not found\n", dev->name);
restore_flags(flags);
return;
}
}
for (i = 0; i < MAX_ETH_CARDS; ++i) {
if (ethdev_index[i] == dev) {
ethdev_index[i] = NULL;
break;
}
}
}
else
printk("was NULL");
printk("\n");
restore_flags(flags);
}
/*
* Local variables:
......
......@@ -45,6 +45,12 @@
*
***** So we can all compare loads of different PLIP drivers for a bit I've modularised this beastie too.
***** In addition a seperate bidirectional plip module can be done.
*
* WARNING: The PRE 1.1.16 plip will NOT work with this PLIP driver. We
* can't avoid this due to an error in the old plip module. If you must
* mix PLIP's you'll need to fix the _OLD_ one to use 0xFC 0xFC as its
* MAC header not 0xFD.
*
*/
static char *version =
......@@ -703,7 +709,7 @@ plip_set_physicaladdr(struct device *dev, unsigned long ipaddr)
{
/*
* set physical address to
* 0xfd.0xfd.ipaddr
* 0xfc.0xfc.ipaddr
*/
unsigned char *addr = dev->dev_addr;
......
This is snapshot 014
Fixes added for 1.1.17
o Charles Hedrick's fixes broken fragmentation totally. Mended.
o Contributed 'dummy' device added. Apparently some slip people want it.
o Tried to kill the memory problems with fragments by setting things
up more carefully and guarding them.
o Module fixes by Bj0rn.
o PLIP fix by Tanabe.
Fixes added for 1.1.16
o Charles Hedricks fixes to TCP.
o Small fixes all over the place.
Fixes added for 1.1.15
o Modular PLIP and 3c501 drivers. Now you -can- have multiple 3c501's
(sort of).
......
......@@ -722,17 +722,6 @@ int arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev,
{
struct arp_table *entry;
unsigned long hash;
/* SHOULD BE FIXED NOW */
if(paddr==0)
{
printk("ADDRESS BOTCH 0\n");
if(skb)
{
printk("skb(saddr=%lx, daddr=%lx, raddr=%lx)\n",
skb->saddr,skb->daddr,skb->raddr);
}
}
/* ------------- */
switch (ip_chk_addr(paddr))
{
case IS_MYADDR:
......
......@@ -171,7 +171,7 @@ static int ip_send(struct sk_buff *skb, unsigned long daddr, int len, struct dev
{
mac = -mac;
skb->arp = 0;
skb->raddr = daddr; /* next routing address */
skb->raddr = daddr; /* next routing address */
}
}
return mac;
......@@ -226,7 +226,7 @@ int ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long dadd
* If the frame is from us and going off machine it MUST MUST MUST
* have the output device ip address and never the loopback
*/
if (saddr == 0x0100007FL && daddr != 0x0100007FL)
if (saddr == htonl(0x7F000001L) && daddr != htonl(0x7F000001L))
saddr = src;/*rt->rt_dev->pa_addr;*/
raddr = rt->rt_gateway;
......@@ -665,7 +665,6 @@ static void ip_free(struct ipq *qp)
/* Finally, release the queue descriptor itself. */
kfree_s(qp, sizeof(struct ipq));
/* printk("ip_free:done\n");*/
sti();
}
......@@ -716,7 +715,7 @@ static struct ipq *ip_create(struct sk_buff *skb, struct iphdr *iph, struct devi
{
printk("IP: create: no memory left !\n");
return(NULL);
skb->dev = qp->dev;
skb->dev = qp->dev;
}
memset(qp, 0, sizeof(struct ipq));
......@@ -949,7 +948,7 @@ static struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct
ihl = (iph->ihl * sizeof(unsigned long));
end = offset + ntohs(iph->tot_len) - ihl;
/*
* Point into the IP datagram 'data' part.
*/
......@@ -1088,6 +1087,7 @@ static struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct
struct sk_buff *skb2;
int left, mtu, hlen, len;
int offset;
unsigned long flags;
/*
* Point into the IP datagram header.
......@@ -1180,19 +1180,27 @@ static struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct
* Set up data on packet
*/
skb2->arp = 0;/*skb->arp;*/
skb2->free = skb->free;
skb2->arp = skb->arp;
if(skb->free==0)
printk("IP fragmenter: BUG free!=1 in fragmenter\n");
skb2->free = 1;
skb2->len = len + hlen;
skb2->h.raw=(char *) skb2->data;
skb2->raddr = skb->raddr; /* For rebuild_header */
/*
* Charge the memory for the fragment to any owner
* it might posess
*/
save_flags(flags);
if (sk)
{
cli();
sk->wmem_alloc += skb2->mem_len;
skb2->sk=sk;
}
restore_flags(flags);
skb2->raddr = skb->raddr; /* For rebuild_header - must be here */
/*
* Copy the packet header into the new buffer.
*/
......@@ -1227,7 +1235,7 @@ static struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct
ip_statistics.IpFragCreates++;
ip_queue_xmit(sk, dev, skb2, 1);
ip_queue_xmit(sk, dev, skb2, 2);
}
ip_statistics.IpFragOKs++;
}
......@@ -1236,7 +1244,7 @@ static struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct
#ifdef CONFIG_IP_FORWARD
/*
/*
* Forward an IP datagram to its next destination.
*/
......@@ -1627,7 +1635,8 @@ int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
/*
* Queues a packet to be sent, and starts the transmitter
* if necessary. if free = 1 then we free the block after
* transmit, otherwise we don't.
* transmit, otherwise we don't. If free==2 we not only
* free the block but also dont assign a new ip seq number.
* This routine also needs to put in the total length,
* and compute the checksum
*/
......@@ -1655,7 +1664,7 @@ void ip_queue_xmit(struct sock *sk, struct device *dev,
* Do some book-keeping in the packet for later
*/
skb->free = free;
skb->dev = dev;
skb->when = jiffies;
......@@ -1672,7 +1681,17 @@ void ip_queue_xmit(struct sock *sk, struct device *dev,
iph = (struct iphdr *)ptr;
skb->ip_hdr = iph;
iph->tot_len = ntohs(skb->len-dev->hard_header_len);
iph->id = htons(ip_id_count++);
/*
* No reassigning numbers to fragments...
*/
if(free!=2)
iph->id = htons(ip_id_count++);
else
free=1;
skb->free = free;
/*
* Do we need to fragment. Again this is inefficient.
......
......@@ -71,6 +71,7 @@
* Matthew Dillon : Reworked TCP machine states as per RFC
* Gerhard Koerting: PC/TCP workarounds
* Adam Caldwell : Assorted timer/timing errors
* Matthew Dillon : Fixed another RST bug
*
*
* To Fix:
......@@ -78,7 +79,6 @@
* it causes a select. Linux can - given the official select semantics I
* feel that _really_ its the BSD network programs that are bust (notably
* inetd, which hangs occasionally because of this).
* Protocol closedown badly messed up.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -2044,7 +2044,9 @@ static void tcp_close(struct sock *sk, int timeout)
printk("Clean rcv queue\n");
while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
{
if(skb->len > 0 && after(skb->h.th->seq + skb->len + 1 , sk->copied_seq))
/* The +1 is not needed because the FIN takes up sequence space and
is not read!!! */
if(skb->len > 0 && after(skb->h.th->seq + skb->len/* + 1 */ , sk->copied_seq))
need_reset = 1;
kfree_skb(skb, FREE_READ);
}
......
......@@ -118,6 +118,15 @@ void udp_err(int err, unsigned char *header, unsigned long daddr,
return;
}
/*
* Various people wanted BSD UDP semantics. Well they've come
* back out because they slow down response to stuff like dead
* or unreachable name servers and they screw term users something
* chronic. Oh and it violates RFC1122. So basically fix your
* client code people.
*/
#ifdef CONFIG_I_AM_A_BROKEN_BSD_WEENIE
/*
* It's only fatal if we have connected to them. I'm not happy
* with this code. Some BSD comparisons need doing.
......@@ -126,10 +135,15 @@ void udp_err(int err, unsigned char *header, unsigned long daddr,
if (icmp_err_convert[err & 0xff].fatal && sk->state == TCP_ESTABLISHED)
{
sk->err = icmp_err_convert[err & 0xff].errno;
/* sk->err=ECONNREFUSED;*/
sk->error_report(sk);
}
sk->error_report(sk);
#else
if (icmp_err_convert[err & 0xff].fatal)
{
sk->err = icmp_err_convert[err & 0xff].errno;
sk->error_report(sk);
}
#endif
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment