patch-1.3.82 linux/net/ax25/af_ax25.c
Next file: linux/net/ax25/ax25_in.c
Previous file: linux/net/ax25/Makefile
Back to the patch index
Back to the overall index
- Lines: 239
- Date:
Mon Apr 1 10:46:30 1996
- Orig file:
v1.3.81/linux/net/ax25/af_ax25.c
- Orig date:
Mon Mar 25 08:58:24 1996
diff -u --recursive --new-file v1.3.81/linux/net/ax25/af_ax25.c linux/net/ax25/af_ax25.c
@@ -72,12 +72,15 @@
* Joerg(DL1BKE) Added DAMA support, fixed (?) digipeating, fixed buffer locking
* for "virtual connect" mode... Result: Probably the
* "Most Buggiest Code You've Ever Seen" (TM)
- * HaJo(DD8NE) implementation of a T5 (idle) timer
- * Joerg(DL1BKE) renamed T5 to IDLE and changed behaviour:
+ * HaJo(DD8NE) Implementation of a T5 (idle) timer
+ * Joerg(DL1BKE) Renamed T5 to IDLE and changed behaviour:
* the timer gets reloaded on every received or transmited
* I frame for IP or NETROM. The idle timer is not active
* on "vanilla AX.25" connections. Furthermore added PACLEN
* to provide AX.25-layer based fragmentation (like WAMPES)
+ * AX.25 032 Joerg(DL1BKE) Fixed DAMA timeout error.
+ * ax25_send_frame() limits the number of enqueued
+ * datagrams per socket.
*
* To do:
* Restructure the ax25_rcv code to be cleaner/faster and
@@ -634,6 +637,12 @@
printk("ax25_ctl_ioctl(): Warning --- huge paclen %d", (int) ax25_ctl.arg);
ax25->paclen = ax25_ctl.arg;
break;
+ case AX25_IPMAXQUEUE:
+ if (ax25_ctl.arg < 1)
+ return -EINVAL;
+
+ ax25->maxqueue = ax25_ctl.arg;
+ break;
default:
return -EINVAL;
}
@@ -667,6 +676,7 @@
ax25->t3 = AX25_DEF_T3 * PR_SLOWHZ;
ax25->n2 = AX25_DEF_N2;
ax25->paclen = AX25_DEF_PACLEN;
+ ax25->maxqueue= AX25_DEF_IPMAXQUEUE;
ax25->idle = 0;
ax25->modulus = AX25_DEF_AXDEFMODE;
@@ -729,14 +739,15 @@
*/
static void ax25_fillin_cb(ax25_cb *ax25, struct device *dev)
{
- ax25->device = dev;
+ ax25->device = dev;
- ax25->rtt = ax25_dev_get_value(dev, AX25_VALUES_T1);
- ax25->t1 = ax25_dev_get_value(dev, AX25_VALUES_T1);
- ax25->t2 = ax25_dev_get_value(dev, AX25_VALUES_T2);
- ax25->t3 = ax25_dev_get_value(dev, AX25_VALUES_T3);
- ax25->n2 = ax25_dev_get_value(dev, AX25_VALUES_N2);
- ax25->paclen = ax25_dev_get_value(dev, AX25_VALUES_PACLEN);
+ ax25->rtt = ax25_dev_get_value(dev, AX25_VALUES_T1);
+ ax25->t1 = ax25_dev_get_value(dev, AX25_VALUES_T1);
+ ax25->t2 = ax25_dev_get_value(dev, AX25_VALUES_T2);
+ ax25->t3 = ax25_dev_get_value(dev, AX25_VALUES_T3);
+ ax25->n2 = ax25_dev_get_value(dev, AX25_VALUES_N2);
+ ax25->paclen = ax25_dev_get_value(dev, AX25_VALUES_PACLEN);
+ ax25->maxqueue = ax25_dev_get_value(dev, AX25_VALUES_IPMAXQUEUE);
ax25->dama_slave = 0;
ax25->idle = 0;
@@ -768,7 +779,11 @@
continue;
if (ax25cmp(&ax25->source_addr, src) == 0 && ax25cmp(&ax25->dest_addr, dest) == 0 && ax25->device == dev) {
- ax25_output(ax25, skb);
+ if (ax25_queue_length(ax25, skb) > ax25->maxqueue * ax25->window) {
+ kfree_skb(skb, FREE_WRITE);
+ } else {
+ ax25_output(ax25, skb);
+ }
ax25->idletimer = ax25->idle; /* dl1bke 960228 */
return 1; /* It already existed */
}
@@ -1075,11 +1090,11 @@
return -ESOCKTNOSUPPORT;
}
- if ((sk = (struct sock *)kmalloc(sizeof(*sk), GFP_ATOMIC)) == NULL)
+ if ((sk = sk_alloc(GFP_ATOMIC)) == NULL)
return -ENOMEM;
if ((ax25 = ax25_create_cb()) == NULL) {
- kfree_s(sk, sizeof(*sk));
+ sk_free(sk);
return -ENOMEM;
}
@@ -1133,11 +1148,11 @@
struct sock *sk;
ax25_cb *ax25;
- if ((sk = (struct sock *)kmalloc(sizeof(*sk), GFP_ATOMIC)) == NULL)
+ if ((sk = sk_alloc(GFP_ATOMIC)) == NULL)
return NULL;
if ((ax25 = ax25_create_cb()) == NULL) {
- kfree_s(sk, sizeof(*sk));
+ sk_free(sk);
return NULL;
}
@@ -1152,7 +1167,7 @@
case SOCK_SEQPACKET:
break;
default:
- kfree_s((void *)sk, sizeof(*sk));
+ sk_free(sk);
kfree_s((void *)ax25, sizeof(*ax25));
return NULL;
}
@@ -1206,7 +1221,7 @@
if (osk->ax25->digipeat != NULL) {
if ((ax25->digipeat = (ax25_digi *)kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
- kfree_s(sk, sizeof(*sk));
+ sk_free(sk);
kfree_s(ax25, sizeof(*ax25));
return NULL;
}
@@ -1268,9 +1283,12 @@
case AX25_STATE_4:
ax25_clear_queues(sk->ax25);
sk->ax25->n2count = 0;
- if (!sk->ax25->dama_slave)
+ if (!sk->ax25->dama_slave) {
ax25_send_control(sk->ax25, DISC, POLLON, C_COMMAND);
- sk->ax25->t3timer = 0;
+ sk->ax25->t3timer = 0;
+ } else {
+ sk->ax25->t3timer = sk->ax25->t3; /* DAMA slave timeout */
+ }
sk->ax25->t1timer = sk->ax25->t1 = ax25_calculate_t1(sk->ax25);
sk->ax25->state = AX25_STATE_2;
sk->state = TCP_CLOSE;
@@ -1501,7 +1519,7 @@
struct sk_buff *skb;
if (newsock->data)
- kfree_s(newsock->data, sizeof(struct sock));
+ sk_free(newsock->data);
newsock->data = NULL;
@@ -2441,11 +2459,10 @@
void ax25_queue_xmit(struct sk_buff *skb, struct device *dev, int pri)
{
unsigned char *ptr;
- int was_locked;
#ifdef CONFIG_FIREWALL
if (call_out_firewall(PF_AX25, skb, skb->data) != FW_ACCEPT) {
- kfree_skb(skb, FREE_WRITE);
+ dev_kfree_skb(skb, FREE_WRITE);
return;
}
#endif
@@ -2459,8 +2476,7 @@
if(skb_headroom(skb) < AX25_BPQ_HEADER_LEN) {
printk("ax25_queue_xmit: not enough space to add BPQ Ether header\n");
- skb->free = 1;
- kfree_skb(skb, FREE_WRITE);
+ dev_kfree_skb(skb, FREE_WRITE);
return;
}
@@ -2472,32 +2488,14 @@
*ptr++ = (size + 5) / 256;
dev->hard_header(skb, dev, ETH_P_BPQ, bcast_addr, NULL, 0);
-
- /* dl1bke 960201: see below. Note that the device driver should
- * copy the data into its own buffers, or strange
- * things will happen again.
- */
-
- was_locked = skb_device_locked(skb);
dev_queue_xmit(skb, dev, pri);
- if (was_locked) skb_device_unlock(skb);
-
return;
}
#endif
ptr = skb_push(skb, 1);
*ptr++ = 0; /* KISS */
-
-/* dl1bke 960201: dev_queue_xmit() will free the skb if it's not locked, so
- * we need an additional variable to store its status.
- * sl_xmit() copies the data before returning, we can
- * remove the lock savely.
- */
-
- was_locked = skb_device_locked(skb);
dev_queue_xmit(skb, dev, pri);
- if (was_locked) skb_device_unlock(skb);
}
/*
@@ -2584,9 +2582,17 @@
* freeing it).
*/
struct sk_buff *ourskb=skb_clone(skb, GFP_ATOMIC);
+
+ if(ourskb==NULL) {
+ dev_kfree_skb(skb, FREE_WRITE);
+ return 1;
+ }
+
+ ourskb->sk = skb->sk;
+ if (ourskb->sk != NULL)
+ atomic_add(ourskb->truesize, &ourskb->sk->wmem_alloc);
+
dev_kfree_skb(skb, FREE_WRITE);
- if(ourskb==NULL)
- return 1;
skb_pull(ourskb, AX25_HEADER_LEN - 1); /* Keep PID */
ax25_send_frame(ourskb, (ax25_address *)(bp + 8), (ax25_address *)(bp + 1), NULL, dev);
return 1;
@@ -2600,10 +2606,16 @@
bp[14] &= ~LAPB_C;
bp[14] |= LAPB_E;
bp[14] |= SSSID_SPARE;
+
+ /*
+ * dl1bke 960317: we use ax25_queue_xmit here to allow mode datagram
+ * over ethernet. I don't know if this is valid, though.
+ */
ax25_dg_build_path(skb, (ax25_address *)(bp + 1), dev);
+ ax25_queue_xmit(skb, dev, SOPRI_NORMAL);
- return 0;
+ return 1;
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this