lkml.org 
[lkml]   [1996]   [Sep]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectYet Another Networking Diff
*
* Yet another block of diffs.
*
* o Documentation notes 3c59x problems a few people have and points
* to new driver for 3c59x/3c9xx
* o On a network where active hosts >> arp cache size we got noisy
* and our cache tended to cycle
* o Bridge had a memory leak
* o bind() on a SOCK_PACKET with ETH_P_ALL behaves.
* o Tom May's even faster checksum routines for ix86. Worth
* another few K a second. Can anyone else do better ?
*
* [This one is an experiment, Linus don't apply the tcp changes to the
* 2.0.xx kernel just yet ;)]
*
* o Diffs to tcp.c tcp.h tcp_input.c to include a simple SYN
* attack filter for people not faking addresses, and some
* limited protection for the generic case. This is mostly
* there as a hook folks can add stuff onto. The simple case
* it covers is useful as it will stop both a malfunctioning
* host, and an attack via a provider with more than half a
* brain.
* People wanting to experiment further should look at
* tcp_syn_filter() and add appropriately.
*
*
diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/Documentation/Configure.help linux/Documentation/Configure.help
--- linux.vanilla/Documentation/Configure.help Sun Sep 15 16:07:07 1996
+++ linux/Documentation/Configure.help Sun Sep 15 14:45:17 1996
@@ -2148,10 +2148,14 @@
the Ethernet-HOWTO, available via ftp (user: anonymous) in
sunsite.unc.edu:/pub/Linux/docs/HOWTO. More specific information is
in Documentation/networking/vortex.txt and in the comments at the
- beginning of drivers/net/3c59x.c. If you want to compile this
- as a module ( = code which can be inserted in and removed from the
- running kernel whenever you want), say M here and read
- Documentation/modules.txt as well as
+ beginning of drivers/net/3c59x.c.
+ Some people have reported a few problems with the 3c590 card and this
+ driver. A newer EXPERIMENTAL driver for this card and the newest 3c9xx
+ series boards can be found at:
+ ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/v2.0/boomerang.c
+ If you want to compile this as a module ( = code which can be inserted
+ in and removed from the running kernel whenever you want), say M here
+ and read Documentation/modules.txt as well as
Documentation/networking/net-modules.txt. If you plan to use more
than one network card under linux, read the
Multiple-Ethernet-mini-HOWTO, available from
diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/arch/i386/lib/checksum.c linux/arch/i386/lib/checksum.c
--- linux.vanilla/arch/i386/lib/checksum.c Sun Jul 28 13:34:32 1996
+++ linux/arch/i386/lib/checksum.c Sun Sep 15 14:31:16 1996
@@ -70,8 +70,7 @@
2: movl %%edx, %%ecx
andl $0x1c, %%edx
je 4f
- shrl $2, %%edx
- testl %%esi, %%esi
+ shrl $2, %%edx # This clears CF
3: adcl (%%esi), %%eax
lea 4(%%esi), %%esi
dec %%edx
@@ -159,10 +158,9 @@
jne 1b
adcl $0, %%eax
2: movl %%edx, %%ecx
- andl $28, %%edx
+ andl $0x1c, %%edx
je 4f
- shrl $2, %%edx
- testl %%esi, %%esi
+ shrl $2, %%edx # This clears CF
3: movl %%fs:(%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, (%%edi)
@@ -212,52 +210,48 @@
addw %%bx, %%ax
adcl $0, %%eax
2:
- movl %%ecx, %%edx
+ pushl %%ecx
shrl $5, %%ecx
jz 2f
testl %%esi, %%esi
1: movl (%%esi), %%ebx
+ movl 4(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, (%%edi)
-
- movl 4(%%esi), %%ebx
- adcl %%ebx, %%eax
- movl %%ebx, 4(%%edi)
+ adcl %%edx, %%eax
+ movl %%edx, 4(%%edi)

movl 8(%%esi), %%ebx
+ movl 12(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, 8(%%edi)
-
- movl 12(%%esi), %%ebx
- adcl %%ebx, %%eax
- movl %%ebx, 12(%%edi)
+ adcl %%edx, %%eax
+ movl %%edx, 12(%%edi)

movl 16(%%esi), %%ebx
+ movl 20(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, 16(%%edi)
-
- movl 20(%%esi), %%ebx
- adcl %%ebx, %%eax
- movl %%ebx, 20(%%edi)
+ adcl %%edx, %%eax
+ movl %%edx, 20(%%edi)

movl 24(%%esi), %%ebx
+ movl 28(%%esi), %%edx
adcl %%ebx, %%eax
movl %%ebx, 24(%%edi)
-
- movl 28(%%esi), %%ebx
- adcl %%ebx, %%eax
- movl %%ebx, 28(%%edi)
+ adcl %%edx, %%eax
+ movl %%edx, 28(%%edi)

lea 32(%%esi), %%esi
lea 32(%%edi), %%edi
dec %%ecx
jne 1b
adcl $0, %%eax
-2: movl %%edx, %%ecx
- andl $28, %%edx
+2: popl %%edx
+ movl %%edx, %%ecx
+ andl $0x1c, %%edx
je 4f
- shrl $2, %%edx
- testl %%esi, %%esi
+ shrl $2, %%edx # This clears CF
3: movl (%%esi), %%ebx
adcl %%ebx, %%eax
movl %%ebx, (%%edi)
diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/include/linux/if_arp.h linux/include/linux/if_arp.h
--- linux.vanilla/include/linux/if_arp.h Sun Jul 28 13:32:54 1996
+++ linux/include/linux/if_arp.h Sun Sep 15 15:43:03 1996
@@ -52,6 +52,8 @@
#define ARPHRD_SKIP 771 /* SKIP vif */
#define ARPHRD_LOOPBACK 772 /* Loopback device */
#define ARPHRD_LOCALTLK 773 /* Localtalk device */
+#define ARPHRD_FDDI 774 /* FDDI interface (really uses 802 on wire)
+ */

/* ARP protocol opcodes. */
#define ARPOP_REQUEST 1 /* ARP request */
diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/include/net/tcp.h linux/include/net/tcp.h
--- linux.vanilla/include/net/tcp.h Tue Sep 3 22:07:30 1996
+++ linux/include/net/tcp.h Sun Sep 15 11:59:02 1996
@@ -70,7 +70,8 @@
#define TCP_PROBEWAIT_LEN (1*HZ)/* time to wait between probes when
* I've got something to write and
* there is no window */
-
+#define TCP_CONNECT_TIMEOUT (75*HZ) /* 75 second default - more needed
+ for an amateur radio site! */
#define TCP_NO_CHECK 0 /* turn to one if you want the default
* to be no checksum */

diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/bridge/br.c linux/net/bridge/br.c
--- linux.vanilla/net/bridge/br.c Sun Jul 28 13:33:23 1996
+++ linux/net/bridge/br.c Sun Sep 15 13:45:02 1996
@@ -19,6 +19,9 @@
* Put the path costs in the port info and devices.
* Put the bridge port number in the device structure for speed.
* Bridge SNMP stats.
+ *
+ * Fixes:
+ * Michael Leodolter : Bridge memory leak fix
*
*/

@@ -1052,7 +1055,7 @@
int br_receive_frame(struct sk_buff *skb) /* 3.5 */
{
int port;
- int i;
+/* int i;*/

if (br_stats.flags & BR_DEBUG)
printk("br_receive_frame: ");
@@ -1137,7 +1140,7 @@
/* happen in net_bh() in dev.c) */
}
/* ok, forward this frame... */
- skb_device_lock(skb);
+ /*skb_device_lock(skb);*/
return(br_forward(skb, port));
default:
printk(KERN_DEBUG "br_receive_frame: port [%i] unknown state [%i]\n",
diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/core/dev.c linux/net/core/dev.c
--- linux.vanilla/net/core/dev.c Sat Aug 17 18:08:39 1996
+++ linux/net/core/dev.c Sun Sep 15 14:33:03 1996
@@ -654,13 +654,17 @@
pt_prev = NULL;
for (ptype = ptype_all; ptype!=NULL; ptype=ptype->next)
{
- if(pt_prev)
+ /* Make sure we only pass on packets for the right device */
+ if (!ptype->dev || ptype->dev==skb->dev)
{
- struct sk_buff *skb2=skb_clone(skb, GFP_ATOMIC);
- if(skb2)
- pt_prev->func(skb2,skb->dev, pt_prev);
- }
- pt_prev=ptype;
+ if(pt_prev)
+ {
+ struct sk_buff *skb2=skb_clone(skb, GFP_ATOMIC);
+ if(skb2)
+ pt_prev->func(skb2,skb->dev, pt_prev);
+ }
+ pt_prev=ptype;
+ }
}

for (ptype = ptype_base[ntohs(type)&15]; ptype != NULL; ptype = ptype->next)
diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/ipv4/arp.c linux/net/ipv4/arp.c
--- linux.vanilla/net/ipv4/arp.c Sat Aug 17 18:08:39 1996
+++ linux/net/ipv4/arp.c Sun Sep 15 14:57:29 1996
@@ -60,6 +60,8 @@
* Mike Shaver : /proc/sys/net/ipv4/arp_* support
* Stuart Cheshire : Metricom and grat arp fixes
* *** FOR 2.1 clean this up ***
+ * Alan Cox : Cyclic ARP flushing bug fixed when
+ * run on big networks.
*/

/* RFC1122 Status:
@@ -279,7 +281,7 @@
static void arp_run_bh(void);
static void arp_check_expire (unsigned long);
static int arp_update (u32 sip, char *sha, struct device * dev,
- unsigned long updated, struct arp_table *ientry, int grat);
+ unsigned long updated, struct arp_table *ientry, int grat, int force);

static struct timer_list arp_timer =
{ NULL, NULL, ARP_CHECK_INTERVAL, 0L, &arp_check_expire };
@@ -697,7 +699,7 @@
else
{
arp_fast_lock();
- arp_update(retreq->ip, retreq->ha, dev, retreq->updated, NULL, 0);
+ arp_update(retreq->ip, retreq->ha, dev, retreq->updated, NULL, 0, 1);
arp_unlock();
}

@@ -1024,13 +1026,17 @@
* arp_alloc_entry() should only be called with the cache locked too!
*/

-static struct arp_table * arp_alloc_entry(void)
+static struct arp_table * arp_alloc_entry(int force)
{
struct arp_table * entry;


if (arp_size >= ARP_MAXSIZE)
+ {
+ if(!force)
+ return NULL;
arp_force_expire();
+ }

entry = (struct arp_table *)
kmalloc(sizeof(struct arp_table),GFP_ATOMIC);
@@ -1146,7 +1152,7 @@

static int
arp_update (u32 sip, char *sha, struct device * dev,
- unsigned long updated, struct arp_table *ientry, int grat)
+ unsigned long updated, struct arp_table *ientry, int grat, int force)
{
struct arp_table * entry;
unsigned long hash;
@@ -1211,7 +1217,7 @@

if (!entry)
{
- entry = arp_alloc_entry();
+ entry = arp_alloc_entry(force);
if (!entry)
return 0;

@@ -1323,7 +1329,7 @@
{
struct arp_table *entry;

- entry = arp_alloc_entry();
+ entry = arp_alloc_entry(1);

if (entry != NULL)
{
@@ -1567,7 +1573,7 @@
while ((entry = arp_dequeue(&arp_backlog)) != NULL)
{
restore_flags(flags);
- if (arp_update(entry->ip, entry->ha, entry->dev, 0, entry, 0))
+ if (arp_update(entry->ip, entry->ha, entry->dev, 0, entry, 0, 1))
arp_free_entry(entry);
cli();
}
@@ -1751,7 +1757,7 @@
unsigned char *arp_ptr= (unsigned char *)(arp+1);
unsigned char *sha,*tha;
u32 sip,tip;
-
+
/*
* The hardware length of the packet should match the hardware length
* of the device. Similarly, the hardware types should match. The
@@ -1937,7 +1943,17 @@
}

arp_fast_lock();
- arp_update(sip, sha, dev, 0, NULL, ip_chk_addr(tip) != IS_MYADDR && dev->type != ARPHRD_METRICOM);
+ /*
+ * This is a bit subtle. We pass 0 for force, meaning an update
+ * here will not force an entry out of cache. This is correct
+ * because:
+ * An entry we here off the wire but don't need should
+ * not kick out an entry.
+ * An entry we are waiting to resolve or using exists
+ * and the force flag is not used. (Its used
+ * when we create the pending request).
+ */
+ arp_update(sip, sha, dev, 0, NULL, ip_chk_addr(tip) != IS_MYADDR && dev->type != ARPHRD_METRICOM, 0);
arp_unlock();
kfree_skb(skb, FREE_READ);
return 0;
@@ -2032,7 +2048,7 @@
entryp = &entry->next;
}

- entry = arp_alloc_entry();
+ entry = arp_alloc_entry(1);
if (entry == NULL)
{
arp_unlock();
diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/ipv4/tcp.c linux/net/ipv4/tcp.c
--- linux.vanilla/net/ipv4/tcp.c Sun Sep 8 14:15:30 1996
+++ linux/net/ipv4/tcp.c Sun Sep 15 13:43:15 1996
@@ -438,7 +438,7 @@
unsigned long seq_offset;
struct tcp_mib tcp_statistics;

-static void tcp_close(struct sock *sk, unsigned long timeout);
+extern void tcp_close(struct sock *sk, unsigned long timeout);

/*
* Find someone to 'accept'. Must be called with
@@ -1734,7 +1734,7 @@
}


-static void tcp_close(struct sock *sk, unsigned long timeout)
+void tcp_close(struct sock *sk, unsigned long timeout)
{
struct sk_buff *skb;

diff --unified --new-file --recursive --exclude-from exclude linux.vanilla/net/ipv4/tcp_input.c linux/net/ipv4/tcp_input.c
--- linux.vanilla/net/ipv4/tcp_input.c Tue Sep 3 22:07:31 1996
+++ linux/net/ipv4/tcp_input.c Sun Sep 15 13:41:55 1996
@@ -341,6 +341,82 @@
#endif
}

+/*
+ * TCP filter for SYN frames. We disallow more than 30% queue
+ * occupancy by the same class C network range. This is designed
+ * to stop runaway hosts and attacks being made via a competent
+ * provider who has proper address filter rules. It doesn't stop
+ * spoofed source address attacks via a provider too stupid to
+ * have proper source address filters. For those cases you'll
+ * have to rely on dumps, provider co-operation and the law.
+ *
+ * Feel free to invent smarter filters and hook them here.
+ */
+
+int tcp_syn_filter(struct sock *sk, struct sk_buff *skb, __u32 saddr)
+{
+ extern void tcp_close(struct sock *sk, unsigned long timeout);
+
+ int ct=0;
+ struct sk_buff *tmp;
+ unsigned long flags;
+ /* If we have < 33% queue occupancy we don't care */
+ if(3*sk->ack_backlog<=sk->max_ack_backlog)
+ return 0;
+
+ /*
+ * We are potentially going to be losing things due to
+ * slow connects.. See if they've passed the trash timer
+ * as we do the count
+ */
+
+ /* Now count */
+ saddr&=htonl(0xFFFFFF00);
+
+ save_flags(flags);
+ cli();
+
+ tmp=skb_peek(&sk->receive_queue);
+ while(tmp && tmp!=(struct sk_buff *)&sk->receive_queue)
+ {
+ /*
+ * The next pointer could change if tcp_close does
+ * delete the socket.
+ */
+
+ struct sk_buff *tnext=tmp->next;
+
+ /*
+ * Fits mask ?
+ */
+
+ if((tmp->sk->saddr&htonl(0xFFFFFF00))==saddr)
+ ct++;
+
+ /*
+ * Timed out ?
+ */
+ if(tmp->when - jiffies > TCP_CONNECT_TIMEOUT)
+ {
+ /*
+ * You can modify this to send a reset and
+ * go straight to closed. If you do then you
+ * in theory risk data errors (see RFC1337)
+ */
+ tcp_close(tmp->sk,0);
+ }
+ tmp=tnext;
+ }
+ restore_flags(flags);
+
+ /*
+ * Report whether to accept
+ */
+
+ if(3*ct>sk->max_ack_backlog)
+ return 1;
+ return 0;
+}

/*
* This routine handles a connection request.
@@ -382,13 +458,13 @@
* set backlog as a fudge factor. That's just too gross.
*/

- if (sk->ack_backlog >= sk->max_ack_backlog)
+ if (sk->ack_backlog >= sk->max_ack_backlog || tcp_syn_filter(sk,skb,saddr))
{
tcp_statistics.TcpAttemptFails++;
kfree_skb(skb, FREE_READ);
return;
}
-
+
/*
* We need to build a new sock struct.
* It is sort of bad to have a socket without an inode attached
@@ -428,6 +504,8 @@
return;
}
}
+
+ skb->when = jiffies; /* For timeout */
skb_queue_head_init(&newsk->write_queue);
skb_queue_head_init(&newsk->receive_queue);
newsk->send_head = NULL;
\
 
 \ /
  Last update: 2005-03-22 13:38    [W:0.042 / U:0.056 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site