Fix for hanging ip_masq_ftp

Miquel van Smoorenburg (miquels@q.cistron.nl)
19 Jun 1996 13:24:27 +0200


After a night of hacking, I found the source of the "hanging in DIR" problem
that has plagued the users of ip_masq_ftp for some time. It turned out this
problem only shows up when using PPP, since the sbk->protocol field isn't
set properly when an skb is resized. This causes the PPP driver to discard the
packet. Here is the fix:

--- linux-2.0.0.orig/net/ipv4/ip_masq_app.c Sun Jun 2 08:36:53 1996
+++ linux-2.0.0/net/ipv4/ip_masq_app.c Wed Jun 19 12:09:40 1996
@@ -2,7 +2,7 @@
* IP_MASQ_APP application masquerading module
*
*
- * Version: @(#)ip_masq_app.c 0.03 03/96
+ * Version: @(#)ip_masq_app.c 0.04 96/06/17
*
* Author: Juan Jose Ciarlante, <jjciarla@raiz.uncu.edu.ar>
*
@@ -13,7 +13,8 @@
* 2 of the License, or (at your option) any later version.
*
* Fixes:
- * JJC : Implemented also input pkt hook
+ * JJC : Implemented also input pkt hook
+ * Miquel van Smoorenburg : Copy more stuff when resizing skb
*
*
* FIXME:
@@ -502,6 +503,7 @@
{
int maxsize, diff, o_offset;
struct sk_buff *n_skb;
+ int offset;

maxsize = skb->truesize - sizeof(struct sk_buff);

@@ -521,7 +523,9 @@
skb->end = skb->head+n_len;
} else {
/*
- * Sizes differ, make a copy
+ * Sizes differ, make a copy.
+ *
+ * FIXME: move this to core/sbuff.c:skb_grow()
*/

n_skb = alloc_skb(MAX_HEADER + skb->len + diff, pri);
@@ -534,8 +538,22 @@
n_skb->free = skb->free;
skb_reserve(n_skb, MAX_HEADER);
skb_put(n_skb, skb->len + diff);
- n_skb->h.raw = n_skb->data + (skb->h.raw - skb->data);
-
+
+ /*
+ * Copy as much data from the old skb as possible. Even
+ * though we're only forwarding packets, we need stuff
+ * like skb->protocol (PPP driver wants it).
+ */
+ offset = n_skb->data - skb->data;
+ n_skb->h.raw = skb->h.raw + offset;
+ n_skb->when = skb->when;
+ n_skb->dev = skb->dev;
+ n_skb->mac.raw = skb->mac.raw + offset;
+ n_skb->ip_hdr = (struct iphdr *)(((char *)skb->ip_hdr)+offset);
+ n_skb->pkt_type = skb->pkt_type;
+ n_skb->protocol = skb->protocol;
+ n_skb->ip_summed = skb->ip_summed;
+
/*
* Copy pkt in new buffer
*/
=============================================================================

Mike.

-- 
  Miquel van    | Cistron Internet Services   --    Alphen aan den Rijn.
  Smoorenburg,  | mailto:info@cistron.nl          http://www.cistron.nl/
miquels@het.net | Tel: +31-172-419445 (Voice) 430979 (Fax) 442580 (Data)