Index: ip_vs_conn.c =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ip_vs_conn.c,v retrieving revision 1.13 diff -u -r1.13 ip_vs_conn.c --- ip_vs_conn.c 2001/03/22 12:57:46 1.13 +++ ip_vs_conn.c 2001/04/01 11:46:31 @@ -69,11 +69,14 @@ static inline void __ip_vs_set_expire(struct ip_vs_conn *cp, unsigned long tout) { - if (tout) { - cp->timer.expires = jiffies+tout; - add_sltimer(&cp->timer); - } else { - del_sltimer(&cp->timer); + /* add/del timer when it is only referred by the conn table */ + if (atomic_read(&cp->refcnt) == 1) { + if (tout) { + cp->timer.expires = jiffies+tout; + add_sltimer(&cp->timer); + } else { + del_sltimer(&cp->timer); + } } } @@ -226,8 +229,8 @@ d_port==cp->vport && d_addr==cp->vaddr && protocol==cp->protocol) { /* HIT */ - atomic_inc(&cp->refcnt); __ip_vs_set_expire(cp, 0); + atomic_inc(&cp->refcnt); ct_read_unlock(hash); return cp; } @@ -241,19 +244,19 @@ struct ip_vs_conn *ip_vs_conn_in_get (int protocol, __u32 s_addr, __u16 s_port, __u32 d_addr, __u16 d_port) { - struct ip_vs_conn *ret; + struct ip_vs_conn *cp; - ret = __ip_vs_conn_in_get(protocol, s_addr, s_port, d_addr, d_port); - if (!ret && atomic_read(&ip_vs_conn_no_cport_cnt)) - ret = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port); + cp = __ip_vs_conn_in_get(protocol, s_addr, s_port, d_addr, d_port); + if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) + cp = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port); IP_VS_DBG(7, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", ip_vs_proto_name(protocol), NIPQUAD(s_addr), ntohs(s_port), NIPQUAD(d_addr), ntohs(d_port), - ret?"hit":"not hit"); + cp?"hit":"not hit"); - return ret; + return cp; } @@ -285,8 +288,8 @@ s_port == cp->dport && s_addr == cp->daddr && protocol == cp->protocol) { /* HIT */ - atomic_inc(&cp->refcnt); __ip_vs_set_expire(cp, 0); + atomic_inc(&cp->refcnt); ret = cp; break; } @@ -312,16 +315,9 @@ __ip_vs_conn_put(cp); /* - * if refcnt==1 (only referenced by the conn table + * Set expiration */ - if (atomic_read(&cp->refcnt) == 1) { - __ip_vs_set_expire(cp, cp->timeout); - } else { - IP_VS_DBG(0, "did not set timer with refcnt=%d, " - "called from %p\n", - atomic_read(&cp->refcnt), - __builtin_return_address(0)); - } + __ip_vs_set_expire(cp, cp->timeout); } Index: ip_vs_core.c =================================================================== RCS file: /home/wensong/cvsroot/ipvs/ip_vs_core.c,v retrieving revision 1.16 diff -u -r1.16 ip_vs_core.c --- ip_vs_core.c 2001/03/22 12:57:46 1.16 +++ ip_vs_core.c 2001/04/01 11:46:31 @@ -24,10 +24,6 @@ * */ -#ifdef MODULE -#define EXPORT_SYMTAB -#endif - #include #include #include @@ -531,15 +527,15 @@ /* bind the bypass_xmit */ ip_vs_bind_bypass_xmit(cp); + /* statistics */ + ip_vs_in_stats(cp, skb); + /* set state */ ip_vs_set_state(cp, VS_STATE_INPUT, iph, portp); /* transmit the first SYN packet */ ret = cp->packet_xmit(skb, cp); - /* statistics */ - ip_vs_in_stats(cp, skb); - ip_vs_conn_put(cp); return ret; } @@ -679,13 +675,14 @@ /* the TCP/UDP dest port - cannot redo check */ pptr[1] = cp->vport; - ip_vs_out_stats(cp, skb); - __ip_vs_conn_put(cp); - /* And finally the ICMP checksum */ icmph->checksum = 0; icmph->checksum = ip_compute_csum((unsigned char *) icmph, len); + /* do the statistics and put it back */ + ip_vs_out_stats(cp, skb); + ip_vs_conn_put(cp); + IP_VS_DBG(11, "Forwarding correct outgoing ICMP to " "%u.%u.%u.%u:%d -> %u.%u.%u.%u:%d\n", NIPQUAD(ciph->saddr), ntohs(pptr[0]), @@ -789,6 +786,7 @@ case CHECKSUM_HW: if (csum_tcpudp_magic(iph->saddr, iph->daddr, size, iph->protocol, skb->csum)) { + ip_vs_conn_put(cp); IP_VS_DBG(0, "Outgoing failed %s checksum " "from %d.%d.%d.%d (size=%d)!\n", ip_vs_proto_name(iph->protocol), @@ -997,7 +995,7 @@ /* The ICMP packet for VS/NAT must be written to correct addresses before being forwarded to the right server */ if ((skb=vs_skb_cow(skb_p, &iph, (unsigned char**)&icmph)) == NULL) { - __ip_vs_conn_put(cp); + ip_vs_conn_put(cp); return NF_DROP; } @@ -1015,7 +1013,6 @@ /* the TCP/UDP source port - cannot redo check */ pptr[0] = cp->dport; - __ip_vs_conn_put(cp); /* And finally the ICMP checksum */ icmph->checksum = 0; @@ -1063,12 +1060,14 @@ skb->nf_debug = 1 << NF_IP_LOCAL_OUT; #endif /* CONFIG_NETFILTER_DEBUG */ ip_send(skb); + ip_vs_conn_put(cp); return NF_STOLEN; tx_error_icmp: dst_link_failure(skb); tx_error: dev_kfree_skb(skb); + ip_vs_conn_put(cp); return NF_STOLEN; } @@ -1145,8 +1144,9 @@ * If the dest is not avaiable, don't restart the timer * of the packet, but silently drop it. */ - add_sltimer(&cp->timer); __ip_vs_conn_put(cp); + if (atomic_read(&cp->refcnt) == 1) + add_sltimer(&cp->timer); return NF_DROP; }