patch-2.0.31 linux/drivers/net/eql.c
Next file: linux/drivers/net/eth16i.c
Previous file: linux/drivers/net/eepro100.c
Back to the patch index
Back to the overall index
- Lines: 119
- Date:
Tue Aug 12 14:15:56 1997
- Orig file:
v2.0.30/linux/drivers/net/eql.c
- Orig date:
Sun Sep 22 11:17:08 1996
diff -u --recursive --new-file v2.0.30/linux/drivers/net/eql.c linux/drivers/net/eql.c
@@ -17,7 +17,7 @@
*/
static const char *version =
- "Equalizer1996: $Revision: 1.2.1 $ $Date: 1996/09/22 13:52:00 $ Simon Janes (simon@ncm.com)\n";
+ "Equalizer1996: $Revision: 1.9 $ $Date: 1996/10/12 11:14:37 $ Simon Janes (simon@ncm.com)\n";
/*
* Sources:
@@ -31,6 +31,9 @@
/*
* $Log: eql.c,v $
+ * Revision 1.9 1996/10/12 11:14:37 davem
+ * Quick merge to 2.0.20
+ *
* Revision 1.2 1996/04/11 17:51:52 guru
* Added one-line eql_remove_slave patch.
*
@@ -262,6 +265,7 @@
dev->hard_header = eql_header;
dev->rebuild_header = eql_rebuild_header;
+ dev->hard_header_len = MAX_HEADER; /* enough space for any slave */
/*
* Now we undo some of the things that eth_setup does
@@ -371,10 +375,19 @@
equalizer_t *eql = (equalizer_t *) dev->priv;
struct device *slave_dev = 0;
slave_t *slave;
+ struct sk_buff *skb2;
if (skb == NULL)
return 0;
+#if 0
+ /* Make a copy we can free so we don't mess up the skb->dev pointer */
+ skb2 = skb_clone(skb, GFP_ATOMIC);
+
+ if (skb2 == NULL)
+ return 1;
+#endif
+
eql_schedule_slaves (eql->queue);
slave_dev = eql_best_slave_dev (eql->queue);
@@ -388,20 +401,48 @@
dev->name, eql_number_slaves (eql->queue), skb->len,
slave_dev->name);
#endif
- dev_queue_xmit (skb, slave_dev, 1);
- eql->stats->tx_packets++;
- slave->bytes_queued += skb->len;
- }
- else
- {
- /*
- * The alternative for this is the return 1 and have
- * dev_queue_xmit just queue it up on the eql's queue.
+
+ /* Rip off the fake header */
+ skb_pull(skb,MAX_HEADER);
+
+ /* The original code had no hard header constructed.
+ * If a frame is fragmented on EQL and then passed to PPP,
+ * or ISDN, the result will be a panic.
+ * The solution is to call the hard_header constructor
+ * for the device we point to just before we send the packet.
+ * If this fails we drop the packet.
+ * We don't know any special parameters for the hard_header
+ * constructor at this point, so we pass in made up values
+ * that will cause the constructor to fail on every device
+ * except those that we are allowed to use EQL on:
+ * PPP, SLIP and ISDN (in some cases!).
+ * The worst thing that happens is if some fool
+ * configures EQL to enslave something that needs
+ * these parameters it throws out packets.
+ * This is not an issue for the things EQL is intended for
+ * anyway, and probably would have crashed the kernel
+ * or sent garbage down the wire previously.
*/
- eql->stats->tx_dropped++;
- dev_kfree_skb(skb, FREE_WRITE);
- }
+ if (slave_dev->hard_header == NULL
+ || slave_dev->hard_header(skb,slave_dev,
+ ETH_P_IP,NULL,NULL,skb->len) >= 0) {
+ dev_queue_xmit (skb, slave_dev, 1);
+ eql->stats->tx_packets++;
+ slave->bytes_queued += skb->len;
+ /* dev_kfree_skb(skb, FREE_WRITE); */
+ return 0;
+ }
+ }
+
+ /*
+ * The alternative for this is the return 1 and have
+ * dev_queue_xmit just queue it up on the eql's queue.
+ */
+
+ eql->stats->tx_dropped++;
+ /* dev_kfree_skb(skb2, FREE_WRITE); */
+ dev_kfree_skb(skb, FREE_WRITE);
return 0;
}
@@ -417,7 +458,9 @@
unsigned short type, void *daddr, void *saddr,
unsigned len)
{
- return 0;
+ /* Fake header to keep space during buggy IP fragmentation. */
+ skb_push(skb,MAX_HEADER);
+ return MAX_HEADER;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov