in case of a icmp-unreach condition the tcp-keepalive-entrys

will be dropped from the internal double-link-list (only abc-extension).
send icmp unreach only if the skb->protocol == ETH_P_IP
speedup abc-no-dchan  redial
This commit is contained in:
Detlef Wengorz 1998-05-22 10:01:20 +00:00
parent 98ab998efc
commit 7e3201df58
2 changed files with 57 additions and 16 deletions

View File

@ -31,6 +31,10 @@
*
*
* $Log$
* Revision 1.8 1998/05/07 19:58:48 detabc
* bugfix in abc_delayed_hangup
* optimize keepalive-tests for abc_rawip
*
* Revision 1.7 1998/05/06 08:35:00 detabc
* fixed a wrong response-message in udp-control-packets
*
@ -116,7 +120,7 @@ struct TCP_CONMERK {
u_short tm_dstport; /* destination portnummer */
u_short tm_window;
u_short tm_hashnr;
struct device *tm_dev; /* device for clear-entry wich unreach */
};
#define HASH_MAX 256
@ -526,6 +530,7 @@ int abc_first_senden(struct device *ndev,isdn_net_local *lp)
printk(KERN_DEBUG "abc_send_first no space for new skb\n");
return(-1);
}
skb->protocol = htons(ETH_P_IP);
skb_reserve(skb,dev->abc_max_hdrlen);
skb->pkt_type = PACKET_HOST;
p = skb_put(skb,len);
@ -862,6 +867,7 @@ struct sk_buff *abc_get_keep_skb()
return NULL;
}
skb->protocol = htons(ETH_P_IP);
skb_reserve(skb,dev->abc_max_hdrlen);
buf = skb_put(skb,2);
skb->pkt_type = PACKET_HOST;
@ -918,6 +924,8 @@ struct sk_buff *abc_snd_data(struct device *ndev,struct sk_buff *skb)
} else skb_reserve(ns,dev->abc_max_hdrlen);
ns->protocol = skb->protocol;
if( skb->len > 10 &&
(nlen = abcgmbh_pack((u_char *)skb->data,ns->data,skb->len)) > 0 &&
nlen < skb->len) {
@ -1590,7 +1598,7 @@ static int free_all_tm(void)
static void tcp_merk_police(void)
static void tcp_merk_police(struct device *ndev)
{
struct TCP_CONMERK *nb = tcp_c_first;
@ -1601,7 +1609,8 @@ static void tcp_merk_police(void)
nb = nb->tm_snext;
if(b->tm_time > jiffies ||
((jiffies - b->tm_time) > (HZ * 3600 * 12))) {
((jiffies - b->tm_time) > (HZ * 3600 * 12)) ||
(ndev != NULL && ndev == b->tm_dev)) {
free_used_tm(b);
}
@ -1799,8 +1808,16 @@ int abcgmbh_tcp_test(struct device *ndev,struct sk_buff *sp)
**
*/
if(sp == NULL)
if(sp == NULL) {
if(!test_and_set_bit(0,(void *)&tcp_inuse)) {
tcp_merk_police(ndev);
tcp_inuse = 0;
}
return(0);
}
if(ntohs(sp->protocol) != ETH_P_IP) {
@ -1867,7 +1884,7 @@ int abcgmbh_tcp_test(struct device *ndev,struct sk_buff *sp)
tcp_merk_disable_to = 0;
if(tcp_next_police < jiffies || tcp_last_police > jiffies)
tcp_merk_police();
tcp_merk_police(NULL);
/*
** tcp protkoll

View File

@ -21,6 +21,10 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log$
* Revision 1.64 1998/05/07 19:58:39 detabc
* bugfix in abc_delayed_hangup
* optimize keepalive-tests for abc_rawip
*
* Revision 1.63 1998/05/05 23:23:36 detabc
* change ICMP_HOST_UNREACH to ICMP_NET_UNREACH (only abc-ext.)
* set dev->tbusy to zero in isdn_net_unreachable() (only abc-ext.)
@ -311,15 +315,20 @@ isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason)
if(skb) {
printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP\n",
dev->name,
(reason != NULL) ? reason : "unknown");
u_short proto = ntohs(skb->protocol);
printk(KERN_DEBUG "isdn_net: %s: %s, send ICMP %s\n",
dev->name,
(reason != NULL) ? reason : "unknown",
(proto != ETH_P_IP) ? "Protcol != ETH_P_IP" : "");
if(proto == ETH_P_IP) {
#ifdef CONFIG_ISDN_WITH_ABC
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0);
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN, 0);
#else
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
#endif
}
}
#ifdef CONFIG_ISDN_WITH_ABC
@ -328,6 +337,7 @@ isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason)
isdn_net_local *lp = (isdn_net_local *) dev->priv;
lp->abc_unreached_jiffies = jiffies + lp->dialwait;
lp->abc_max_unreached_jiffies = jiffies + lp->dialwait * 6;
abcgmbh_tcp_test(dev,NULL);
abc_clear_tx_que(lp);
clear_bit(0, (void *) &(dev->tbusy));
}
@ -339,7 +349,8 @@ isdn_net_unreachable(struct device *dev, struct sk_buff *skb, char *reason)
struct sk_buff *skb;
while((skb = skb_dequeue(&dev->buffs[i]))) {
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
if(ntohs(skb->protocol) == ETH_P_IP)
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
dev_kfree_skb(skb);
}
}
@ -1004,6 +1015,8 @@ isdn_net_dial(void)
/* Nothing to do for this interface */
#ifdef CONFIG_ISDN_WITH_ABC
abc_nodchan_redial:;
if(lp->abc_flags & ABC_NODCHAN) {
int chi = -1;
@ -1027,9 +1040,9 @@ isdn_net_dial(void)
lp->pre_device,
lp->pre_channel)) < 0) {
printk(KERN_DEBUG
"ABC_REDIAL: No channel for %s\n",
lp->name);
isdn_net_unreachable(&p->dev,
lp->first_skb,
"ABC_REDIAL: No free channel");
} else {
@ -1215,9 +1228,16 @@ isdn_net_dial(void)
lp->first_skb = skb;
restore_flags(flags);
lp->abc_call_disabled = 0;
lp->dialwait_timer = 0;
lp->abc_flags |= ABC_NODCHAN;
anymore = 1;
/*
** try once more with a new channel (redial)
*/
goto abc_nodchan_redial;
} else isdn_net_hangup(&p->dev);
#endif
break;
}
@ -1845,9 +1865,13 @@ isdn_net_start_xmit(struct sk_buff *skb, struct device *ndev)
lp->abc_max_unreached_jiffies > jiffies) {
abc_clear_tx_que(lp);
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0);
if(ntohs(skb->protocol) == ETH_P_IP)
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN, 0);
dev_kfree_skb(skb);
lp->abc_unreached_jiffies = jiffies + lp->dialwait;
abcgmbh_tcp_test(ndev,NULL);
ndev->tbusy = 0;
if(dev->net_verbose > 6)