Hello, people.
I've discovered and fixed nasty bug that did not allow to route IPX
packets among media with different-sized link-layer headers (between
Arcnet and Ethernet in my case).
This bug was present in any 2.2.X kernel (as I found, this bug is not
present in 2.0.36 and 2.1.27 kernels, but appears at least in 2.2.5. I
do not have any other kernels between 2.0.36 and 2.2.5)
My current kernel is 2.2.12-20 in RedHat 6.1 (Cartman) Linux system.
Comparing this kernel with patches to 2.2.13 I have found that some
files already identical to files from kernel 2.2.13 (net/ipx/af_ipx.c
is too).
My system is IP and IPX router between four ethernet and one arcnet
segment (and also PPP server). For IPX routing I use ipxd 0.7 and it
works fine for all ethernet segments and modem. But any IPX
connections from arcnet to ethernet fails (TCP/IP works). I had to fix
it.
Some preciuos experiments allow to decide that kernel has only
failed to route between arcnet ant ethernet, but not to talk via
arcnet. So now let's consider net/ipx/af_ipx.c file from kernel 2.2.13
(also, as I know, this file has no change in 2.2.14).
In lines 582-606 there is a routine that adjusts skb (socket buffer)
if necessary (when outgoing media packets has longer link layer
headers than incoming packets). Here is it. It is called from
ipxitf_send routine (lines 608-704, invocation is in line 691).
<----- cut from net/ipx/af_ipx.c, lines 582-606 (kernel 2.2.13)
static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb)
{
struct sk_buff *skb2;
int in_offset = skb->h.raw - skb->head;
int out_offset = intrfc->if_ipx_offset;
int len;
/* Hopefully, most cases */
if(in_offset >= out_offset)
return (skb);
/* Need new SKB */
len = skb->len + out_offset;
skb2 = alloc_skb(len, GFP_ATOMIC);
if(skb2 != NULL)
{
skb_reserve(skb2, out_offset);
skb2->nh.raw =
skb2->h.raw = skb_put(skb2,skb->len);
memcpy(skb2->h.raw, skb->h.raw, skb->len);
}
kfree_skb(NULL);
return (NULL);
}
<----- end cut
Arcnet packet has only six bytes in its header, but ethernet one has
more (fourteen).
Now. If we transmit packet from one ethernet segment to other
ethernet segment, the routine ipxitf_adjust_skbuff terminates normally
in line 591 (return (skb)). If any packet is xmited from ethernet to
arcnet, termination also followed in line 591 (14 is greater than 6).
But if we xmit from arcnet to ethernet, we had to execute the next
statements.
And therefore, since line 602 contains UNCONDITIONALLY returned
failure, it is a BUG.
This bug
a) is memory leaky (skb2 never will freed)
b) does not allow to route any IPX packets between some physical media
(in this case the ipxitf_send routine ALWAYS get failure).
The appropriate patch shown here:
<---- patch
diff -u af_ipx.c af_ipx.c.orig
--- af_ipx.c Fri Apr 21 17:17:34 2000
+++ af_ipx.c.orig Mon Sep 27 00:00:00 1999
@@ -602,7 +602,7 @@
}
kfree_skb(skb);
- return (skb2);
+ return (NULL);
}
static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
<---- end patch
After patching my system is now have full IPX routing capabilities.
Please try this out and report. Feel free to mail me.
So I claim that linux now MIGHT HAVE FULL IPX ROUTING and
NOW HAS POSSIBILITY TO BEAT NOVELL NETWARE IN ROUTING IPX PACKETS.
---
Best regards,
Alexandr S. Agranovsky mailto:[EMAIL PROTECTED]
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to [EMAIL PROTECTED]