diff -Nru linux-2.4.20/net/ipv4/netfilter/ipt_REJECT.c linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_REJECT.c
--- linux-2.4.20/net/ipv4/netfilter/ipt_REJECT.c	2003-05-02 12:59:23.000000000 -0500
+++ linux-2.4.20-pom2patch/net/ipv4/netfilter/ipt_REJECT.c	2003-05-02 13:00:17.000000000 -0500
@@ -44,6 +44,7 @@
 	u_int16_t tmp_port;
 	u_int32_t tmp_addr;
 	int needs_ack;
+	int hh_len;
 
 	/* IP header checks: fragment, too short. */
 	if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
@@ -63,13 +64,28 @@
 			 csum_partial((char *)otcph, otcplen, 0)) != 0)
 		return;
 
+	/* Routing: if not headed for us, route won't like source */
+	if (ip_route_output(&rt, oldskb->nh.iph->daddr,
+			    local ? oldskb->nh.iph->saddr : 0,
+			    RT_TOS(oldskb->nh.iph->tos) | RTO_CONN,
+			    0) != 0)
+		return;
+
+	hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
+
+
 	/* Copy skb (even if skb is about to be dropped, we can't just
            clone it because there may be other things, such as tcpdump,
-           interested in it) */
-	nskb = skb_copy(oldskb, GFP_ATOMIC);
+           interested in it). We also need to expand headroom in case
+	   hh_len of incoming interface < hh_len of outgoing interface */
+	nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
+			       GFP_ATOMIC);
 	if (!nskb)
 		return;
 
+	dst_release(nskb->dst);
+	nskb->dst = &rt->u.dst;
+
 	/* This packet will not be the same as the other: clear nf fields */
 	nf_conntrack_put(nskb->nfct);
 	nskb->nfct = NULL;
@@ -132,16 +148,6 @@
 	nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, 
 					   nskb->nh.iph->ihl);
 
-	/* Routing: if not headed for us, route won't like source */
-	if (ip_route_output(&rt, nskb->nh.iph->daddr,
-			    local ? nskb->nh.iph->saddr : 0,
-			    RT_TOS(nskb->nh.iph->tos) | RTO_CONN,
-			    0) != 0)
-		goto free_nskb;
-
-	dst_release(nskb->dst);
-	nskb->dst = &rt->u.dst;
-
 	/* "Never happens" */
 	if (nskb->len > nskb->dst->pmtu)
 		goto free_nskb;
