diff -u --new-file --recursive v1.1.4/linux/Makefile linux/Makefile --- v1.1.4/linux/Makefile Fri Apr 15 02:11:37 1994 +++ linux/Makefile Fri Apr 15 01:16:45 1994 @@ -1,6 +1,6 @@ VERSION = 1 PATCHLEVEL = 1 -SUBLEVEL = 4 +SUBLEVEL = 5 all: Version zImage diff -u --new-file --recursive v1.1.4/linux/drivers/net/loopback.c linux/drivers/net/loopback.c --- v1.1.4/linux/drivers/net/loopback.c Fri Apr 15 02:11:43 1994 +++ linux/drivers/net/loopback.c Fri Apr 15 01:28:42 1994 @@ -50,23 +50,17 @@ cli(); if (dev->tbusy != 0) { sti(); - printk("loopback error: called by %08lx\n", - ((unsigned long *)&skb)[-1]); stats->tx_errors++; return(1); } dev->tbusy = 1; sti(); - start_bh_atomic(); done = dev_rint(skb->data, skb->len, 0, dev); if (skb->free) kfree_skb(skb, FREE_WRITE); - end_bh_atomic(); while (done != 1) { - start_bh_atomic(); done = dev_rint(NULL, 0, 0, dev); - end_bh_atomic(); } stats->tx_packets++; diff -u --new-file --recursive v1.1.4/linux/net/inet/arp.c linux/net/inet/arp.c --- v1.1.4/linux/net/inet/arp.c Fri Apr 15 02:11:52 1994 +++ linux/net/inet/arp.c Fri Apr 15 02:23:51 1994 @@ -26,7 +26,7 @@ * Alan Cox : Make ARP add its own protocol entry * */ - + #include #include #include @@ -58,10 +58,10 @@ * This structure defines the ARP mapping cache. As long as we make changes * in this structure, we keep interrupts of. But normally we can copy the * hardware address and the device pointer in a local variable and then make - * any "long calls" to send a packet out. + * any "long calls" to send a packet out. */ - -struct arp_table + +struct arp_table { struct arp_table *next; /* Linked entry list */ unsigned long last_used; /* For expiry */ @@ -73,19 +73,19 @@ struct device *dev; /* Device the entry is tied to */ /* - * The following entries are only used for unresolved hw addresses. + * The following entries are only used for unresolved hw addresses. */ - - struct timer_list timer; /* expire timer */ + + struct timer_list timer; /* expire timer */ int retries; /* remaining retries */ struct sk_buff_head skb; /* list of queued packets */ }; -/* - * This structure defines an ethernet arp header. +/* + * This structure defines an ethernet arp header. */ - -struct arphdr + +struct arphdr { unsigned short ar_hrd; /* format of hardware address */ unsigned short ar_pro; /* format of protocol address */ @@ -108,31 +108,31 @@ /* * Configurable Parameters (don't touch unless you know what you are doing */ - + /* * If an arp request is send, ARP_RES_TIME is the timeout value until the - * next request is send. + * next request is send. */ - + #define ARP_RES_TIME (250*(HZ/10)) /* * The number of times an arp request is send, until the host is - * considered unreachable. + * considered unreachable. */ - + #define ARP_MAX_TRIES 3 /* - * After that time, an unused entry is deleted from the arp table. + * After that time, an unused entry is deleted from the arp table. */ - + #define ARP_TIMEOUT (600*HZ) /* * How often is the function 'arp_check_retries' called. * An entry is invalidated in the time between ARP_TIMEOUT and - * (ARP_TIMEOUT+ARP_CHECK_INTERVAL). + * (ARP_TIMEOUT+ARP_CHECK_INTERVAL). */ #define ARP_CHECK_INTERVAL (60 * HZ) @@ -147,27 +147,27 @@ /* * The size of the hash table. Must be a power of two. * Maybe we should remove hashing in the future for arp and concentrate - * on Patrick Schaaf's Host-Cache-Lookup... + * on Patrick Schaaf's Host-Cache-Lookup... */ #define ARP_TABLE_SIZE 16 -struct arp_table *arp_tables[ARP_TABLE_SIZE] = +struct arp_table *arp_tables[ARP_TABLE_SIZE] = { NULL, }; /* - * The last bits in the IP address are used for the cache lookup. + * The last bits in the IP address are used for the cache lookup. */ - + #define HASH(paddr) (htonl(paddr) & (ARP_TABLE_SIZE - 1)) /* * Number of proxy arp entries. This is normally zero and we use it to do - * some optimizing for normal uses + * some optimizing for normal uses. */ - + static int proxies = 0; @@ -176,9 +176,9 @@ * flag is set, they are always left in the arp cache (permanent entry). * Note: Only fully resolved entries, which don't have any packets in * the queue, can be deleted, since ARP_TIMEOUT is much greater than - * ARP_MAX_TRIES*ARP_RES_TIME. + * ARP_MAX_TRIES*ARP_RES_TIME. */ - + static void arp_check_expire(unsigned long dummy) { int i; @@ -186,43 +186,43 @@ unsigned long flags; save_flags(flags); cli(); - - for (i = 0; i < ARP_TABLE_SIZE; i++) + + for (i = 0; i < ARP_TABLE_SIZE; i++) { struct arp_table *entry; struct arp_table **pentry = &arp_tables[i]; - while ((entry = *pentry) != NULL) + while ((entry = *pentry) != NULL) { if ((now - entry->last_used) > ARP_TIMEOUT - && !(entry->flags & ATF_PERM)) + && !(entry->flags & ATF_PERM)) { *pentry = entry->next; /* remove from list */ if (entry->flags & ATF_PUBL) proxies--; - del_timer(&entry->timer); /* Paranoia */ + del_timer(&entry->timer); /* Paranoia */ kfree_s(entry, sizeof(struct arp_table)); - } - else + } + else pentry = &entry->next; /* go to next entry */ } } restore_flags(flags); /* - * Set the timer again. + * Set the timer again. */ del_timer(&arp_timer); - arp_timer.expires = ARP_CHECK_INTERVAL; + arp_timer.expires = ARP_CHECK_INTERVAL; add_timer(&arp_timer); } /* - * Release all linked skb's and the memory for this entry. + * Release all linked skb's and the memory for this entry. */ - + static void arp_release_entry(struct arp_table *entry) { struct sk_buff *skb; @@ -230,7 +230,7 @@ if (entry->flags & ATF_PUBL) proxies--; /* Release the list of `skb' pointers. */ - while ((skb = skb_dequeue(&entry->skb)) != NULL) + while ((skb = skb_dequeue(&entry->skb)) != NULL) { if (skb->free) kfree_skb(skb, FREE_WRITE); @@ -243,9 +243,9 @@ /* * Create and send an arp packet. If (dest_hw == NULL), we create a broadcast - * message. + * message. */ - + static void arp_send(int type, unsigned long dest_ip, struct device *dev, unsigned long src_ip, unsigned char *dest_hw, unsigned char *src_hw) { @@ -256,17 +256,17 @@ /* * No arp on this interface. */ - + if(dev->flags&IFF_NOARP) return; - + /* * Allocate a buffer */ - + skb = alloc_skb(sizeof(struct arphdr)+ 2*(dev->addr_len+4) + dev->hard_header_len, GFP_ATOMIC); - if (skb == NULL) + if (skb == NULL) { printk("ARP: no memory to send an arp packet\n"); return; @@ -277,7 +277,7 @@ skb->free = 1; /* - * Fill the device header for the ARP frame + * Fill the device header for the ARP frame */ dev->hard_header(skb->data,dev,ETH_P_ARP,dest_hw?dest_hw:dev->broadcast,src_hw?src_hw:NULL,skb->len,skb); @@ -285,17 +285,17 @@ /* Fill out the arp protocol part. */ arp = (struct arphdr *) (skb->data + dev->hard_header_len); arp->ar_hrd = htons(dev->type); -#ifdef CONFIG_AX25 +#ifdef CONFIG_AX25 arp->ar_pro = (dev->type != ARPHRD_AX25)? htons(ETH_P_IP) : htons(AX25_P_IP); #else arp->ar_pro = htons(ETH_P_IP); -#endif +#endif arp->ar_hln = dev->addr_len; arp->ar_pln = 4; arp->ar_op = htons(type); arp_ptr=(unsigned char *)(arp+1); - + memcpy(arp_ptr, src_hw, dev->addr_len); arp_ptr+=dev->addr_len; memcpy(arp_ptr, &src_ip,4); @@ -306,39 +306,39 @@ memset(arp_ptr, 0, dev->addr_len); arp_ptr+=dev->addr_len; memcpy(arp_ptr, &dest_ip, 4); - + dev_queue_xmit(skb, dev, 0); } /* * This function is called, if an entry is not resolved in ARP_RES_TIME. - * Either resend a request, or give it up and free the entry. + * Either resend a request, or give it up and free the entry. */ - + static void arp_expire_request (unsigned long arg) { struct arp_table *entry = (struct arp_table *) arg; struct arp_table **pentry; unsigned long hash; unsigned long flags; - + save_flags(flags); cli(); - + /* * Since all timeouts are handled with interrupts enabled, there is a * small chance, that this entry has just been resolved by an incoming - * packet. This is the only race condition, but it is handled... + * packet. This is the only race condition, but it is handled... */ - - if (entry->flags & ATF_COM) + + if (entry->flags & ATF_COM) { restore_flags(flags); return; } - - if (--entry->retries > 0) + + if (--entry->retries > 0) { unsigned long ip = entry->ip; struct device *dev = entry->dev; @@ -352,19 +352,19 @@ dev->dev_addr); return; } - + /* * Arp request timed out. Delete entry and all waiting packets. * If we give each entry a pointer to itself, we don't have to * loop through everything again. Maybe hash is good enough, but - * I will look at it later. + * I will look at it later. */ - + hash = HASH(entry->ip); pentry = &arp_tables[hash]; - while (*pentry != NULL) + while (*pentry != NULL) { - if (*pentry == entry) + if (*pentry == entry) { *pentry = entry->next; /* delete from linked list */ del_timer(&entry->timer); @@ -377,37 +377,37 @@ restore_flags(flags); printk("Possible ARP queue corruption.\n"); /* - * We should never arrive here. + * We should never arrive here. */ } /* - * This will try to retransmit everything on the queue. + * This will try to retransmit everything on the queue. */ - + static void arp_send_q(struct arp_table *entry, unsigned char *hw_dest) { struct sk_buff *skb; - - + + /* * Empty the entire queue, building its data up ready to send */ - + if(!(entry->flags&ATF_COM)) { printk("arp_send_q: incomplete entry for %s\n", in_ntoa(entry->ip)); return; } - - while((skb = skb_dequeue(&entry->skb)) != NULL) + + while((skb = skb_dequeue(&entry->skb)) != NULL) { IS_SKB(skb); if(!skb->dev->rebuild_header(skb->data,skb->dev,skb->raddr,skb)) { - skb->arp = 1; + skb->arp = 1; if(skb->sk==NULL) dev_queue_xmit(skb, skb->dev, 0); else @@ -426,9 +426,9 @@ /* - * Delete an ARP mapping entry in the cache. + * Delete an ARP mapping entry in the cache. */ - + void arp_destroy(unsigned long ip_addr, int force) { struct arp_table *entry; @@ -437,15 +437,15 @@ cli(); pentry = &arp_tables[hash]; - while ((entry = *pentry) != NULL) + while ((entry = *pentry) != NULL) { - if (entry->ip == ip_addr) + if (entry->ip == ip_addr) { if ((entry->flags & ATF_PERM) && !force) return; *pentry = entry->next; - sti(); del_timer(&entry->timer); + sti(); arp_release_entry(entry); return; } @@ -455,18 +455,18 @@ } -/* +/* * Receive an arp request by the device layer. Maybe I rewrite it, to * use the incoming packet for the reply. The time for the current - * "overhead" isn't that high... + * "overhead" isn't that high... */ - + int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) { /* - * We shouldn't use this type conversion. Check later. + * We shouldn't use this type conversion. Check later. */ - + struct arphdr *arp = (struct arphdr *)skb->h.raw; unsigned char *arp_ptr= (unsigned char *)(arp+1); struct arp_table *entry; @@ -480,22 +480,22 @@ /* * If this test doesn't pass, its not IP, or we should ignore it anyway */ - - if (arp->ar_hln != dev->addr_len || dev->type != ntohs(arp->ar_hrd) || dev->flags&IFF_NOARP) + + if (arp->ar_hln != dev->addr_len || dev->type != ntohs(arp->ar_hrd) || dev->flags&IFF_NOARP) { kfree_skb(skb, FREE_READ); return 0; } /* - * For now we will only deal with IP addresses. + * For now we will only deal with IP addresses. */ if ( -#ifdef CONFIG_AX25 +#ifdef CONFIG_AX25 (arp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) || -#endif +#endif (arp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) - || arp->ar_pln != 4) + || arp->ar_pln != 4) { /* This packet is not for us. Remove it. */ kfree_skb(skb, FREE_READ); @@ -513,21 +513,21 @@ tha=arp_ptr; arp_ptr+=dev->addr_len; memcpy(&tip,arp_ptr,4); - + /* * Process entry */ - + addr_hint = ip_chk_addr(tip); hash = HASH(sip); proxy_entry = NULL; - if (proxies != 0 && addr_hint != IS_MYADDR) + if (proxies != 0 && addr_hint != IS_MYADDR) { unsigned long dest_hash = HASH(tip); cli(); proxy_entry = arp_tables[dest_hash]; - while (proxy_entry != NULL) + while (proxy_entry != NULL) { if (proxy_entry->ip == tip && proxy_entry->htype==arp->ar_hrd) break; @@ -537,15 +537,15 @@ memcpy(ha, proxy_entry->ha, dev->addr_len); else proxy_entry = NULL; - } - else + } + else cli(); for (entry = arp_tables[hash]; entry != NULL; entry = entry->next) - if (entry->ip == sip) + if (entry->ip == sip) break; - - if (entry != NULL) + + if (entry != NULL) { int old_flags = entry->flags; memcpy(entry->ha, sha, arp->ar_hln); @@ -555,28 +555,28 @@ if(entry->htype==0) entry->htype = dev->type; /* Not good but we have no choice */ entry->last_used = jiffies; - if (!(entry->flags & ATF_COM)) + if (!(entry->flags & ATF_COM)) { del_timer(&entry->timer); entry->flags |= ATF_COM; } sti(); - if (!(old_flags & ATF_COM)) + if (!(old_flags & ATF_COM)) { /* Send out waiting packets. We might have problems, if someone is manually removing entries right now. I will fix this one. */ arp_send_q(entry, sha); } - if (addr_hint != IS_MYADDR && proxy_entry == NULL) + if (addr_hint != IS_MYADDR && proxy_entry == NULL) { kfree_skb(skb, FREE_READ); return 0; } - } - else + } + else { - if (addr_hint != IS_MYADDR && proxy_entry == NULL) + if (addr_hint != IS_MYADDR && proxy_entry == NULL) { /* We don't do "smart arp" and cache all possible entries. That just makes us more work. */ @@ -586,7 +586,7 @@ } entry = (struct arp_table *)kmalloc(sizeof(struct arp_table), GFP_ATOMIC); - if (entry == NULL) + if (entry == NULL) { sti(); kfree_skb(skb, FREE_READ); @@ -610,7 +610,7 @@ any more. */ if (arp->ar_op != htons(ARPOP_REQUEST) - || tip == INADDR_LOOPBACK) + || tip == INADDR_LOOPBACK) { /* This wasn't a request, or some bad request for 127.0.0.1 has made its way to the net, so delete it. */ @@ -629,16 +629,16 @@ /* - * Find an arp mapping in the cache. If not found, post a request. + * Find an arp mapping in the cache. If not found, post a request. */ - + int arp_find(unsigned char *haddr, unsigned long paddr, struct device *dev, unsigned long saddr, struct sk_buff *skb) { struct arp_table *entry; unsigned long hash; - switch (ip_chk_addr(paddr)) + switch (ip_chk_addr(paddr)) { case IS_MYADDR: printk("ARP: arp called for own IP address\n"); @@ -653,34 +653,34 @@ hash = HASH(paddr); cli(); - + /* - * Find an entry + * Find an entry */ for (entry = arp_tables[hash]; entry != NULL; entry = entry->next) - if (entry->ip == paddr) + if (entry->ip == paddr) break; - - + + if (entry != NULL) /* It exists */ { - if (!(entry->flags & ATF_COM)) + if (!(entry->flags & ATF_COM)) { - /* + /* * A request was already send, but no reply yet. Thus * queue the packet with the previous attempt */ - + if (skb != NULL) skb_queue_tail(&entry->skb, skb); sti(); return 1; } - + /* * Update the record */ - + entry->last_used = jiffies; memcpy(haddr, entry->ha, dev->addr_len); if (skb) @@ -690,12 +690,12 @@ } /* - * Create a new unresolved entry. + * Create a new unresolved entry. */ - + entry = (struct arp_table *) kmalloc(sizeof(struct arp_table), GFP_ATOMIC); - if (entry != NULL) + if (entry != NULL) { entry->ip = paddr; entry->hlen = dev->addr_len; @@ -714,8 +714,8 @@ skb_queue_head_init(&entry->skb); if (skb != NULL) skb_queue_tail(&entry->skb, skb); - } - else + } + else { if (skb != NULL && skb->free) kfree_skb(skb, FREE_WRITE); @@ -723,21 +723,21 @@ sti(); /* - * If we didn't find an entry, we will try to send an ARP packet. + * If we didn't find an entry, we will try to send an ARP packet. */ - + arp_send(ARPOP_REQUEST, paddr, dev, saddr, NULL, dev->dev_addr); return 1; } -/* - * Write the contents of the ARP cache to a PROCfs file. +/* + * Write the contents of the ARP cache to a PROCfs file. * * Will change soon to ASCII format */ - + int arp_get_info(char *buffer, char **start, off_t offset, int length) { struct arp_table *entry; @@ -749,9 +749,9 @@ cli(); /* Loop over the ARP table and copy structures to the buffer. */ - for (i = 0; i < ARP_TABLE_SIZE; i++) + for (i = 0; i < ARP_TABLE_SIZE; i++) { - for (entry = arp_tables[i]; entry; entry = entry->next) + for (entry = arp_tables[i]; entry; entry = entry->next) { memset(req, 0, sizeof(struct arpreq)); req->arp_pa.sa_family = AF_INET; @@ -783,11 +783,11 @@ } -/* +/* * This will find an entry in the ARP table by looking at the IP address. - * Be careful, interrupts are turned off on exit!!! + * Be careful, interrupts are turned off on exit!!! */ - + static struct arp_table *arp_lookup(unsigned long paddr) { struct arp_table *entry; @@ -801,9 +801,9 @@ /* - * Set (create) an ARP cache entry. + * Set (create) an ARP cache entry. */ - + static int arp_req_set(struct arpreq *req) { struct arpreq r; @@ -824,7 +824,7 @@ * We have to be compatible with BSD UNIX, so we have to * assume that a "not set" value (i.e. 0) means Ethernet. */ - + switch (r.arp_ha.sa_family) { case 0: /* Moan about this. ARP family 0 is NetROM and _will_ be needed */ @@ -833,24 +833,24 @@ htype = ARPHRD_ETHER; hlen = ETH_ALEN; break; -#ifdef CONFIG_AX25 +#ifdef CONFIG_AX25 case ARPHRD_AX25: htype = ARPHRD_AX25; hlen = 7; break; -#endif +#endif default: return -EPFNOSUPPORT; } si = (struct sockaddr_in *) &r.arp_pa; ip = si->sin_addr.s_addr; - if (ip == 0) + if (ip == 0) { printk("ARP: SETARP: requested PA is 0.0.0.0 !\n"); return -EINVAL; } - + /* * Is it reachable directly ? */ @@ -860,28 +860,28 @@ return -ENETUNREACH; /* - * Is there an existing entry for this address? + * Is there an existing entry for this address? */ - + hash = HASH(ip); cli(); - + /* * Find the entry */ for (entry = arp_tables[hash]; entry != NULL; entry = entry->next) - if (entry->ip == ip) + if (entry->ip == ip) break; - + /* * Do we need to create a new entry */ - - if (entry == NULL) + + if (entry == NULL) { entry = (struct arp_table *) kmalloc(sizeof(struct arp_table), GFP_ATOMIC); - if (entry == NULL) + if (entry == NULL) { sti(); return -ENOMEM; @@ -892,14 +892,14 @@ entry->next = arp_tables[hash]; arp_tables[hash] = entry; skb_queue_head_init(&entry->skb); - } - else + } + else if (entry->flags & ATF_PUBL) proxies--; /* - * We now have a pointer to an ARP entry. Update it! + * We now have a pointer to an ARP entry. Update it! */ - + memcpy(&entry->ha, &r.arp_ha.sa_data, hlen); entry->last_used = jiffies; entry->flags = r.arp_flags | ATF_COM; @@ -913,9 +913,9 @@ /* - * Get an ARP cache entry. + * Get an ARP cache entry. */ - + static int arp_req_get(struct arpreq *req) { struct arpreq r; @@ -923,64 +923,64 @@ struct sockaddr_in *si; /* - * We only understand about IP addresses... + * We only understand about IP addresses... */ - - memcpy_fromfs(&r, req, sizeof(r)); - if (r.arp_pa.sa_family != AF_INET) + memcpy_fromfs(&r, req, sizeof(r)); + + if (r.arp_pa.sa_family != AF_INET) return -EPFNOSUPPORT; /* - * Is there an existing entry for this address? + * Is there an existing entry for this address? */ - + si = (struct sockaddr_in *) &r.arp_pa; entry = arp_lookup(si->sin_addr.s_addr); - if (entry == NULL) + if (entry == NULL) { sti(); return -ENXIO; } /* - * We found it; copy into structure. + * We found it; copy into structure. */ - + memcpy(r.arp_ha.sa_data, &entry->ha, entry->hlen); r.arp_ha.sa_family = entry->htype; r.arp_flags = entry->flags; sti(); /* - * Copy the information back + * Copy the information back */ - + memcpy_tofs(req, &r, sizeof(r)); return 0; } /* - * Handle an ARP layer I/O control request. + * Handle an ARP layer I/O control request. */ - + int arp_ioctl(unsigned int cmd, void *arg) { struct arpreq r; struct sockaddr_in *si; int err; - switch(cmd) + switch(cmd) { case DDIOCSDBG: return dbg_ioctl(arg, DBG_ARP); case SIOCDARP: - if (!suser()) + if (!suser()) return -EPERM; err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq)); - if(err) + if(err) return err; memcpy_fromfs(&r, arg, sizeof(r)); if (r.arp_pa.sa_family != AF_INET) @@ -990,14 +990,14 @@ return 0; case SIOCGARP: err = verify_area(VERIFY_WRITE, arg, sizeof(struct arpreq)); - if(err) + if(err) return err; return arp_req_get((struct arpreq *)arg); case SIOCSARP: - if (!suser()) + if (!suser()) return -EPERM; err = verify_area(VERIFY_READ, arg, sizeof(struct arpreq)); - if(err) + if(err) return err; return arp_req_set((struct arpreq *)arg); default: @@ -1009,10 +1009,10 @@ /* - * Called once on startup. + * Called once on startup. */ -static struct packet_type arp_packet_type = +static struct packet_type arp_packet_type = { 0, /* Should be: __constant_htons(ETH_P_ARP) - but this _doesn't_ come out constant! */ 0, /* copy */ @@ -1020,7 +1020,7 @@ NULL, NULL }; - + void arp_init (void) { /* Register the packet type */ diff -u --new-file --recursive v1.1.4/linux/net/inet/dev.c linux/net/inet/dev.c --- v1.1.4/linux/net/inet/dev.c Fri Apr 15 02:11:53 1994 +++ linux/net/inet/dev.c Fri Apr 15 01:16:45 1994 @@ -319,6 +319,7 @@ void dev_queue_xmit(struct sk_buff *skb, struct device *dev, int pri) { + unsigned long flags; int where = 0; /* used to say if the packet should go */ /* at the front or the back of the */ /* queue. */ @@ -335,7 +336,6 @@ IS_SKB(skb); skb->dev = dev; - start_bh_atomic(); /* * This just eliminates some race conditions, but not all... @@ -348,7 +348,6 @@ */ printk("dev_queue_xmit: worked around a missed interrupt\n"); dev->hard_start_xmit(NULL, dev); - end_bh_atomic(); return; } @@ -376,33 +375,27 @@ */ if (!skb->arp && dev->rebuild_header(skb->data, dev, skb->raddr, skb)) { - end_bh_atomic(); return; } - /* - * This is vitally important. We _MUST_ keep packets in order. While tcp/ip - * suffers only a slow down some IPX apps, and all the AX.25 code will break - * if it occurs out of order. - * - * This is commented out while I fix a few 'side effects' - */ + save_flags(flags); + cli(); + if (!where) { + skb_queue_tail(dev->buffs + pri,skb); + skb = skb_dequeue(dev->buffs + pri); + } + restore_flags(flags); - if ((where==1 || skb_peek(&dev->buffs[pri])==NULL) && dev->hard_start_xmit(skb, dev) == 0) - { - end_bh_atomic(); + if (dev->hard_start_xmit(skb, dev) == 0) { return; } /* * Transmission failed, put skb back into a list. */ - - if(where) - skb_queue_head(&dev->buffs[pri],skb); - else - skb_queue_tail(&dev->buffs[pri],skb); - end_bh_atomic(); + cli(); + skb_queue_head(dev->buffs + pri,skb); + restore_flags(flags); } /* diff -u --new-file --recursive v1.1.4/linux/net/inet/icmp.c linux/net/inet/icmp.c --- v1.1.4/linux/net/inet/icmp.c Fri Apr 15 02:11:55 1994 +++ linux/net/inet/icmp.c Fri Apr 15 01:54:45 1994 @@ -28,7 +28,6 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version -#include * 2 of the License, or (at your option) any later version. */ #include @@ -39,6 +38,7 @@ #include #include #include +#include #include "snmp.h" #include "ip.h" #include "route.h" @@ -313,8 +313,10 @@ * Handle ICMP_REDIRECT. */ -static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, struct device *dev) +static void icmp_redirect(struct icmphdr *icmph, struct sk_buff *skb, + struct device *dev, unsigned long source) { + struct rtable *rt; struct iphdr *iph; unsigned long ip; @@ -340,8 +342,16 @@ #endif case ICMP_REDIR_HOST: /* - * Add better route to host + * Add better route to host. + * But first check that the redirect + * comes from the old gateway.. */ + rt = ip_rt_route(ip, NULL, NULL); + if (!rt) + break; + if (rt->rt_gateway != source) + break; + printk("redirect from %08lx\n", source); ip_rt_add((RTF_DYNAMIC | RTF_MODIFIED | RTF_HOST | RTF_GATEWAY), ip, 0, icmph->un.gateway, dev); break; @@ -657,7 +667,7 @@ return(0); case ICMP_REDIRECT: icmp_statistics.IcmpInRedirects++; - icmp_redirect(icmph, skb1, dev); + icmp_redirect(icmph, skb1, dev, saddr); return(0); case ICMP_ECHO: icmp_statistics.IcmpInEchos++;