[733] in linux-net channel archive
Fix forwarding, SNMP and maybe broken ring
daemon@ATHENA.MIT.EDU (A.Cox)
Thu Jul 20 01:11:43 1995
Date: Tue, 18 Jul 95 23:04 BST
From: anarchy@thunder.swansea.linux.org.uk (A.Cox)
To: linux-net3@www.linux.org.uk, linux-net@vger.rutgers.edu,
torvalds@cs.helsinki.fi
*
* Fix IP forwarding.
* Fix SNMP counts up.
* Remove masquerading compile warn.
* Possibly fix token ring (I dont have a broken ring to check).
*
--- include/linux/trdevice.h.old Wed Jul 19 00:40:55 1995
+++ include/linux/trdevice.h Wed Jul 19 00:41:09 1995
@@ -28,9 +28,9 @@
#include <linux/if_tr.h>
#ifdef __KERNEL__
-extern int tr_header(unsigned char *buff, struct device *dev,
+extern int tr_header(struct sk_buff *skb, struct device *dev,
unsigned short type, void *daddr,
- void *saddr, unsigned len, struct sk_buff *skb);
+ void *saddr, unsigned len);
extern int tr_rebuild_header(void *buff, struct device *dev,
unsigned long raddr, struct sk_buff *skb);
extern unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev);
--- net/802/tr.c.old Wed Jul 19 00:40:26 1995
+++ net/802/tr.c Wed Jul 19 00:40:26 1995
@@ -38,11 +38,12 @@
#define RIF_CHECK_INTERVAL 60*HZ
static struct timer_list rif_timer={ NULL,NULL,RIF_CHECK_INTERVAL,0L,rif_check_expire };
-int tr_header(unsigned char *buff, struct device *dev, unsigned short type,
- void *daddr, void *saddr, unsigned len, struct sk_buff *skb) {
+int tr_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+ void *daddr, void *saddr, unsigned len)
+{
struct trh_hdr *trh=(struct trh_hdr *)skb_push(skb,dev->hard_header_len);
- struct trllc *trllc=(struct trllc *)(buff+sizeof(struct trh_hdr));
+ struct trllc *trllc=(struct trllc *)(trh+1);
trh->ac=AC;
trh->fc=LLC_FRAME;
@@ -91,6 +92,8 @@
struct trh_hdr *trh=(struct trh_hdr *)skb->data;
struct trllc *trllc=(struct trllc *)(skb->data+sizeof(struct trh_hdr));
+
+ skb->mac.raw = skb->data;
skb_pull(skb,dev->hard_header_len);
--- net/core/dev.c.old Tue Jul 18 22:48:10 1995
+++ net/core/dev.c Tue Jul 18 22:48:10 1995
@@ -172,6 +172,7 @@
return;
}
}
+ printk("dev_remove_pack: %p not found.\n", pt);
}
/*****************************************************************************************
--- net/ipv4/ip.c.old Wed Jul 19 00:11:49 1995
+++ net/ipv4/ip.c Wed Jul 19 00:32:05 1995
@@ -85,6 +85,8 @@
* Dave Bonn,Alan Cox : Faster IP forwarding whenever possible.
* Alan Cox : Memory leaks, tramples, misc debugging.
* Alan Cox : Fixed multicast (by popular demand 8))
+ * Alan Cox : Fixed forwarding (by even more popular demand 8))
+ * Alan Cox : Fixed SNMP statistics [I think]
*
*
*
@@ -1139,7 +1141,7 @@
*/
dev2 = rt->rt_dev;
-
+
/*
* In IP you never have to forward a frame on the interface that it
* arrived upon. We now generate an ICMP HOST REDIRECT giving the route
@@ -1165,33 +1167,35 @@
if (!(is_frag&4) && fw_res==2)
ip_fw_masquerade(&skb, dev2);
#endif
+ IS_SKB(skb);
if(skb_headroom(skb)<dev2->hard_header_len)
+ {
skb2 = alloc_skb(dev2->hard_header_len + skb->len + 15, GFP_ATOMIC);
- else skb2=skb;
+ IS_SKB(skb2);
- /*
- * This is rare and since IP is tolerant of network failures
- * quite harmless.
- */
+ /*
+ * This is rare and since IP is tolerant of network failures
+ * quite harmless.
+ */
- if (skb2 == NULL)
- {
- NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
- return -1;
- }
+ if (skb2 == NULL)
+ {
+ NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
+ return -1;
+ }
+ /*
+ * Add the physical headers.
+ */
- /* Now build the MAC header. */
- (void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);
+ ip_send(skb2,raddr,skb->len,dev2,dev2->pa_addr);
- /*
- * We have to copy the bytes over as the new header wouldn't fit
- * the old buffer. This should be very rare.
- */
-
- if(skb2!=skb)
- {
+ /*
+ * We have to copy the bytes over as the new header wouldn't fit
+ * the old buffer. This should be very rare.
+ */
+
ptr = skb_put(skb2,skb->len);
skb2->free = 1;
skb2->h.raw = ptr;
@@ -1201,9 +1205,22 @@
*/
memcpy(ptr, skb->h.raw, skb->len);
}
+ else
+ {
+ /*
+ * Build a new MAC header.
+ */
- ip_statistics.IpForwDatagrams++;
-
+ skb2 = skb;
+ skb2->dev=dev2;
+ skb->arp=1;
+ if(dev->hard_header)
+ {
+ if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)
+ skb->arp=0;
+ }
+ ip_statistics.IpForwDatagrams++;
+ }
/*
* See if it needs fragmenting. Note in ip_rcv we tagged
* the fragment type. This must be right so that
@@ -2347,6 +2364,7 @@
struct iphdr *iph;
int local=0;
struct device *dev;
+ int nfrags=0;
ip_statistics.IpOutRequests++;
@@ -2437,7 +2455,10 @@
int error;
struct sk_buff *skb=sock_alloc_send_skb(sk, length+20+15+dev->hard_header_len,0,&error);
if(skb==NULL)
+ {
+ ip_statistics.IpOutDiscards++;
return error;
+ }
skb->dev=dev;
skb->free=1;
skb->when=jiffies;
@@ -2555,8 +2576,13 @@
skb = sock_alloc_send_skb(sk, fraglen+15, 0, &error);
if (skb == NULL)
+ {
+ ip_statistics.IpOutDiscards++;
+ if(nfrags>1)
+ ip_statistics.IpFragCreates++;
return(error);
-
+ }
+
/*
* Fill in the control structures
*/
@@ -2689,6 +2715,9 @@
kfree_skb(skb, FREE_READ);
}
#endif
+
+ nfrags++;
+
/*
* BSD loops broadcasts
*/
@@ -2715,12 +2744,15 @@
*/
ip_statistics.IpOutDiscards++;
+ if(nfrags>1)
+ ip_statistics.IpFragCreates+=nfrags;
kfree_skb(skb, FREE_WRITE);
return(0); /* lose rest of fragments */
}
}
while (offset >= 0);
-
+ if(nfrags>1)
+ ip_statistics.IpFragCreates+=nfrags;
return(0);
}
--- net/ipv4/ip_fw.c~ Tue Jul 18 22:24:06 1995
+++ net/ipv4/ip_fw.c Tue Jul 18 22:24:06 1995
@@ -1483,7 +1483,7 @@
int timer_active = del_timer(&ms->timer);
if (!timer_active)
ms->timer.expires = 0;
- len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08lX %5d %lu\n",
+ len+=sprintf(buffer+len,"%s %08lX:%04X %08lX:%04X %04X %08X %5d %lu\n",
strProt[ms->protocol==IPPROTO_TCP],
ntohl(ms->src),ntohs(ms->sport),
ntohl(ms->dst),ntohs(ms->dport),
--- net/ipv4/ip.c~ Wed Jul 19 00:54:27 1995
+++ net/ipv4/ip.c Wed Jul 19 00:54:27 1995
@@ -1214,6 +1214,7 @@
skb2 = skb;
skb2->dev=dev2;
skb->arp=1;
+ skb->raddr=raddr;
if(dev->hard_header)
{
if(dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, skb->len)<0)