[718] in linux-net channel archive
More bug fixes
daemon@ATHENA.MIT.EDU (A.Cox)
Tue Jul 18 19:32:14 1995
Date: Mon, 17 Jul 95 22:06 BST
From: anarchy@thunder.swansea.linux.org.uk (A.Cox)
To: linux-net3@www.linux.org.uk, linux-net@vger.rutgers.edu,
torvalds@linux.helsinki.fi
*
* Fix the AX.25 crashes when running digipeated VC sessions
* Allow TCP to cope with route changes.
* [Linus, it should be safe to merge the infinite SLIP channel patch now]
* Clean up header lengths
* Ought to fix masquerade of ftp crashes (untested).
*
*
* Known bugs outstanding that need fixing before the next stage of code
* merging.
*
* Token ring is broken
* One odd crash while forwarding with skb_put panic - cause
* still a mystery
* IPX bug reports
* TCP syn not resetting close_wait connections
*
--- drivers/net/slip.c.old Mon Jul 17 21:49:32 1995
+++ drivers/net/slip.c Mon Jul 17 21:50:28 1995
@@ -36,6 +36,7 @@
* statistics. Include CSLIP code only
* if it really needed.
* Alan Cox : Free slhc buffers in the right place.
+ * Alan Cox : Allow for digipeated IP over AX.25
*
*
*
@@ -1014,7 +1015,7 @@
#else
if ((tmp & SL_MODE_AX25) || (tmp & SL_MODE_AX25VC)) {
sl->dev->addr_len=AX25_ADDR_LEN; /* sizeof an AX.25 addr */
- sl->dev->hard_header_len=AX25_HEADER_LEN; /* We don't do digipeaters */
+ sl->dev->hard_header_len=73; /* We don't do digipeaters */
} else {
sl->dev->addr_len=0; /* No mac addr in slip mode */
sl->dev->hard_header_len=0;
--- drivers/net/pi2.c.old Mon Jul 17 21:49:15 1995
+++ drivers/net/pi2.c Mon Jul 17 21:49:15 1995
@@ -49,6 +49,7 @@
April 23, 1995 (dp) Fixed ioctl so it works properly with piconfig program
when changing the baud rate or clock mode.
version 0.8 ALPHA
+ July 17, 1995 (ac) Finally polishing of AX25.030+ support
*/
@@ -59,7 +60,7 @@
of each transmitted packet. If this causes you to lose sleep, #undefine it.
*/
-#define STUFF2 1
+/*#define STUFF2 1*/
/* The default configuration */
#define PI_DMA 3
@@ -1429,10 +1430,10 @@
dev->rebuild_header = pi_rebuild_header;
dev->set_mac_address = pi_set_mac_address;
- dev->type = ARPHRD_AX25; /* AF_AX25 device */
- dev->hard_header_len = 17; /* We don't do digipeaters */
- dev->mtu = 1500; /* eth_mtu is the default */
- dev->addr_len = 7; /* sizeof an ax.25 address */
+ dev->type = ARPHRD_AX25; /* AF_AX25 device */
+ dev->hard_header_len = 73; /* We do digipeaters now */
+ dev->mtu = 1500; /* eth_mtu is the default */
+ dev->addr_len = 7; /* sizeof an ax.25 address */
memcpy(dev->broadcast, ax25_bcast, 7);
memcpy(dev->dev_addr, ax25_test, 7);
--- tcp.c.old Wed Jul 12 22:16:06 1995
+++ tcp.c Mon Jul 17 21:41:10 1995
@@ -145,6 +145,9 @@
* sk->retransmits misupdating fixed.
* Fixed tcp_write_timeout: stuck close,
* and TCP syn retries gets used now.
+ * Alan Cox : Look up device on a retransmit - routes may
+ * change. Doesn't yet cope with MSS shrink right
+ * but its a start!
*
*
* To Fix:
@@ -439,6 +442,7 @@
struct proto *prot;
struct device *dev;
int ct=0;
+ struct rtable *rt;
prot = sk->prot;
skb = sk->send_head;
@@ -454,6 +458,12 @@
skb->when = jiffies;
/*
+ * Discard the surplus MAC header
+ */
+
+ skb_pull(skb,((unsigned char *)skb->ip_hdr)-skb->data);
+
+ /*
* In general it's OK just to use the old packet. However we
* need to use the current ack and window fields. Urg and
* urg_ptr could possibly stand to be updated as well, but we
@@ -462,60 +472,89 @@
* changing the packet, we have to issue a new IP identifier.
*/
- iph = (struct iphdr *)(skb->data + dev->hard_header_len);
+ iph = (struct iphdr *)skb->data;
th = (struct tcphdr *)(((char *)iph) + (iph->ihl << 2));
- size = skb->len - (((unsigned char *) th) - skb->data);
+ size = ntohs(iph->tot_len) - (iph->ihl<<2);
/*
* Note: We ought to check for window limits here but
* currently this is done (less efficiently) elsewhere.
- * We do need to check for a route change but can't handle
- * that until we have the new 1.3.x buffers in.
- *
*/
iph->id = htons(ip_id_count++);
ip_send_check(iph);
-
- /*
- * This is not the right way to handle this. We have to
- * issue an up to date window and ack report with this
- * retransmit to keep the odd buggy tcp that relies on
- * the fact BSD does this happy.
- * We don't however need to recalculate the entire
- * checksum, so someone wanting a small problem to play
- * with might like to implement RFC1141/RFC1624 and speed
- * this up by avoiding a full checksum.
- */
-
- th->ack_seq = ntohl(sk->acked_seq);
- th->window = ntohs(tcp_select_window(sk));
- tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
/*
- * If the interface is (still) up and running, kick it.
+ * Put a MAC header back on (may cause ARPing)
*/
-
- if (dev->flags & IFF_UP)
+
+ if(skb->localroute)
+ rt=ip_rt_local(iph->daddr,NULL,NULL);
+ else
+ rt=ip_rt_route(iph->daddr,NULL,NULL);
+
+ if(rt==NULL) /* Deep poo */
{
+ if(skb->sk)
+ {
+ skb->sk->err=ENETUNREACH;
+ skb->sk->error_report(skb->sk);
+ }
+ }
+ else
+ {
+ dev=rt->rt_dev;
+ skb->raddr=rt->rt_gateway;
+ if(skb->raddr==0)
+ skb->raddr=iph->daddr;
+ skb->dev=dev;
+ skb->arp=1;
+ if(dev->hard_header)
+ {
+ if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)
+ skb->arp=0;
+ }
+
/*
- * If the packet is still being sent by the device/protocol
- * below then don't retransmit. This is both needed, and good -
- * especially with connected mode AX.25 where it stops resends
- * occurring of an as yet unsent anyway frame!
- * We still add up the counts as the round trip time wants
- * adjusting.
+ * This is not the right way to handle this. We have to
+ * issue an up to date window and ack report with this
+ * retransmit to keep the odd buggy tcp that relies on
+ * the fact BSD does this happy.
+ * We don't however need to recalculate the entire
+ * checksum, so someone wanting a small problem to play
+ * with might like to implement RFC1141/RFC1624 and speed
+ * this up by avoiding a full checksum.
*/
- if (sk && !skb_device_locked(skb))
+
+ th->ack_seq = ntohl(sk->acked_seq);
+ th->window = ntohs(tcp_select_window(sk));
+ tcp_send_check(th, sk->saddr, sk->daddr, size, sk);
+
+ /*
+ * If the interface is (still) up and running, kick it.
+ */
+
+ if (dev->flags & IFF_UP)
{
- /* Remove it from any existing driver queue first! */
- skb_unlink(skb);
- /* Now queue it */
- ip_statistics.IpOutRequests++;
- dev_queue_xmit(skb, dev, sk->priority);
+ /*
+ * If the packet is still being sent by the device/protocol
+ * below then don't retransmit. This is both needed, and good -
+ * especially with connected mode AX.25 where it stops resends
+ * occurring of an as yet unsent anyway frame!
+ * We still add up the counts as the round trip time wants
+ * adjusting.
+ */
+ if (sk && !skb_device_locked(skb))
+ {
+ /* Remove it from any existing driver queue first! */
+ skb_unlink(skb);
+ /* Now queue it */
+ ip_statistics.IpOutRequests++;
+ dev_queue_xmit(skb, dev, sk->priority);
+ }
}
}
-
+
/*
* Count retransmissions
*/
@@ -3034,8 +3073,7 @@
* Ack and window will in general have changed since this packet was put
* on the write queue.
*/
- iph = (struct iphdr *)(skb->data +
- skb->dev->hard_header_len);
+ iph = skb->ip_hdr;
th = (struct tcphdr *)(((char *)iph) +(iph->ihl << 2));
size = skb->len - (((unsigned char *) th) - skb->data);
--- include/linux/netdevice.h.old Mon Jul 17 21:54:03 1995
+++ include/linux/netdevice.h Mon Jul 17 21:54:03 1995
@@ -31,7 +31,11 @@
/* for future expansion when we will have different priorities. */
#define DEV_NUMBUFFS 3
#define MAX_ADDR_LEN 7
-#define MAX_HEADER 38
+#ifndef CONFIG_AX25
+#define MAX_HEADER 32 /* We really need about 18 worst case .. so 32 is aligned */
+#else
+#define MAX_HEADER 96 /* AX.25 + NetROM */
+#endif
#define IS_MYADDR 1 /* address is (one of) our own */
#define IS_LOOPBACK 2 /* address is for LOOPBACK */
--- ip_fw.c~ Mon Jul 17 23:52:47 1995
+++ ip_fw.c Mon Jul 17 23:52:47 1995
@@ -733,7 +733,7 @@
if (portptr[1]==htons(21))
{
skb = revamp(*skb_ptr, dev, ms);
- skb = *skb_ptr;
+ *skb_ptr = skb;
iph = skb->h.iph;
portptr = (unsigned short *)&(((char *)iph)[iph->ihl*4]);
}
--- ip.c.ook Tue Jul 18 00:15:32 1995
+++ ip.c Tue Jul 18 00:15:32 1995
@@ -201,6 +201,26 @@
return mac;
}
+static int ip_send_room(struct sk_buff *skb, unsigned long daddr, int len, struct device *dev, unsigned long saddr)
+{
+ int mac = 0;
+
+ skb->dev = dev;
+ skb->arp = 1;
+ if (dev->hard_header)
+ {
+ skb_reserve(skb,MAX_HEADER);
+ mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
+ if (mac < 0)
+ {
+ mac = -mac;
+ skb->arp = 0;
+ skb->raddr = daddr; /* next routing address */
+ }
+ }
+ return mac;
+}
+
int ip_id_count = 0;
/*
@@ -283,7 +303,10 @@
* Now build the MAC header.
*/
- tmp = ip_send(skb, raddr, len, *dev, saddr);
+ if(type==IPPROTO_TCP)
+ tmp = ip_send_room(skb, raddr, len, *dev, saddr);
+ else
+ tmp = ip_send(skb, raddr, len, *dev, saddr);
/*
* Book keeping
--- route.c.old Tue Jul 18 00:09:23 1995
+++ route.c Tue Jul 18 00:10:43 1995
@@ -30,6 +30,7 @@
* Alan Cox : TCP irtt support.
* Jonathan Naylor : Added Metric support.
* Miquel van Smoorenburg : BSD API fixes.
+ * Alan Cox : Disallow route add xxx dev yyy when yyy is down
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -396,6 +397,8 @@
putname(devname);
if (!dev)
return -EINVAL;
+ if(!(dev->flags&IFF_UP))
+ return -ENXIO;
}
/*