diff -ru linux-2.4.26-pre1.orig/include/net/ip_vs.h linux-2.4.26-pre1/include/net/ip_vs.h --- linux-2.4.26-pre1.orig/include/net/ip_vs.h 2003-11-29 03:26:21.000000000 +0900 +++ linux-2.4.26-pre1/include/net/ip_vs.h 2004-03-01 15:27:19.000000000 +0900 @@ -19,6 +19,9 @@ */ #define IP_VS_SVC_F_PERSISTENT 0x0001 /* persistent port */ #define IP_VS_SVC_F_HASHED 0x0002 /* hashed entry */ +#define IP_VS_SVC_F_UNCONN_UDP 0x1000 /* connectionless udp, also + * IP_VS_CONN_F_UNCONN_UDP */ + /* * Destination Server Flags @@ -82,6 +85,8 @@ #define IP_VS_CONN_F_IN_SEQ 0x0400 /* must do input seq adjust */ #define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */ #define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */ +#define IP_VS_CONN_F_UNCONN_UDP IP_VS_SVC_F_UNCONN_UDP /* 0x1000 */ + /* connectionless udp */ /* Move it to better place one day, for now keep it unique */ #define NFC_IPVS_PROPERTY 0x10000 @@ -317,6 +322,7 @@ NET_IPV4_VS_EXPIRE_NODEST_CONN=23, NET_IPV4_VS_SYNC_THRESHOLD=24, NET_IPV4_VS_NAT_ICMP_SEND=25, + NET_IPV4_VS_TO_UDP_UNCONN=26, NET_IPV4_VS_LAST }; @@ -338,6 +344,7 @@ IP_VS_S_SYNACK, IP_VS_S_UDP, IP_VS_S_ICMP, + IP_VS_S_UDP_UNCONN, IP_VS_S_LAST }; diff -ru linux-2.4.26-pre1.orig/net/ipv4/ipvs/ip_vs_conn.c linux-2.4.26-pre1/net/ipv4/ipvs/ip_vs_conn.c --- linux-2.4.26-pre1.orig/net/ipv4/ipvs/ip_vs_conn.c 2003-11-29 03:26:21.000000000 +0900 +++ linux-2.4.26-pre1/net/ipv4/ipvs/ip_vs_conn.c 2004-03-01 15:27:19.000000000 +0900 @@ -322,6 +322,7 @@ [IP_VS_S_SYNACK] = 120*HZ, [IP_VS_S_UDP] = 5*60*HZ, [IP_VS_S_ICMP] = 1*60*HZ, + [IP_VS_S_UDP_UNCONN] = 0, [IP_VS_S_LAST] = 2*HZ, }, /* timeout */ }; @@ -344,6 +345,7 @@ [IP_VS_S_SYNACK] = 100*HZ, [IP_VS_S_UDP] = 3*60*HZ, [IP_VS_S_ICMP] = 1*60*HZ, + [IP_VS_S_UDP_UNCONN] = 0, [IP_VS_S_LAST] = 2*HZ, }, /* timeout */ }; @@ -371,6 +373,7 @@ [IP_VS_S_SYNACK] = "SYNACK", [IP_VS_S_UDP] = "UDP", [IP_VS_S_ICMP] = "ICMP", + [IP_VS_S_UDP_UNCONN] = "UDP_UNCONN", [IP_VS_S_LAST] = "BUG!", }; @@ -574,7 +577,10 @@ ret = vs_tcp_state(cp, state_off, tp); break; case IPPROTO_UDP: - ret = vs_set_state_timeout(cp, IP_VS_S_UDP); + if (unlikely(cp->flags & IP_VS_SVC_F_UNCONN_UDP)) + ret = vs_set_state_timeout(cp, IP_VS_S_UDP_UNCONN); + else + ret = vs_set_state_timeout(cp, IP_VS_S_UDP); break; case IPPROTO_ICMP: ret = vs_set_state_timeout(cp, IP_VS_S_ICMP); diff -ru linux-2.4.26-pre1.orig/net/ipv4/ipvs/ip_vs_core.c linux-2.4.26-pre1/net/ipv4/ipvs/ip_vs_core.c --- linux-2.4.26-pre1.orig/net/ipv4/ipvs/ip_vs_core.c 2003-11-29 03:26:21.000000000 +0900 +++ linux-2.4.26-pre1/net/ipv4/ipvs/ip_vs_core.c 2004-03-01 15:27:19.000000000 +0900 @@ -297,7 +297,7 @@ iph->saddr, portp[0], iph->daddr, portp[1], dest->addr, dport, - 0, + svc->flags & IP_VS_SVC_F_UNCONN_UDP, dest); if (cp == NULL) { ip_vs_conn_put(ct); @@ -364,7 +364,7 @@ iph->saddr, portp[0], iph->daddr, portp[1], dest->addr, dest->port?dest->port:portp[1], - 0, + svc->flags & IP_VS_SVC_F_UNCONN_UDP, dest); if (cp == NULL) return NULL; diff -ru linux-2.4.26-pre1.orig/net/ipv4/ipvs/ip_vs_ctl.c linux-2.4.26-pre1/net/ipv4/ipvs/ip_vs_ctl.c --- linux-2.4.26-pre1.orig/net/ipv4/ipvs/ip_vs_ctl.c 2003-11-29 03:26:21.000000000 +0900 +++ linux-2.4.26-pre1/net/ipv4/ipvs/ip_vs_ctl.c 2004-03-01 15:29:58.000000000 +0900 @@ -1424,6 +1424,9 @@ {NET_IPV4_VS_TO_ICMP, "timeout_icmp", &vs_timeout_table_dos.timeout[IP_VS_S_ICMP], sizeof(int), 0644, NULL, &proc_dointvec_jiffies}, + {NET_IPV4_VS_TO_UDP_UNCONN, "timeout_udp_unconn", + &vs_timeout_table_dos.timeout[IP_VS_S_UDP_UNCONN], + sizeof(int), 0644, NULL, &proc_dointvec_jiffies}, {NET_IPV4_VS_CACHE_BYPASS, "cache_bypass", &sysctl_ip_vs_cache_bypass, sizeof(int), 0644, NULL, &proc_dointvec}, @@ -1507,17 +1510,19 @@ pos += 64; if (pos > offset) { if (svc->flags & IP_VS_SVC_F_PERSISTENT) - sprintf(temp2, "persistent %d %08X", + sprintf(temp2, "persitent %d %08X", svc->timeout, ntohl(svc->netmask)); else temp2[0] = '\0'; - sprintf(temp, "%s %08X:%04X %s %s", + sprintf(temp, "%s %08X:%04X %s %s %s", ip_vs_proto_name(svc->protocol), ntohl(svc->addr), ntohs(svc->port), - svc->scheduler->name, temp2); + svc->scheduler->name, temp2, + svc->flags & IP_VS_SVC_F_UNCONN_UDP ? + "unconn_udp" : ""); len += sprintf(buf+len, "%-63s\n", temp); if (len >= length) goto done; @@ -1558,9 +1563,11 @@ else temp2[0] = '\0'; - sprintf(temp, "FWM %08X %s %s", + sprintf(temp, "FWM %08X %s %s %s", svc->fwmark, - svc->scheduler->name, temp2); + svc->scheduler->name, temp2, + svc->flags & IP_VS_SVC_F_UNCONN_UDP ? + "unconn_udp" : ""); len += sprintf(buf+len, "%-63s\n", temp); if (len >= length) goto done; @@ -1748,6 +1755,19 @@ } /* + * IP_VS_SVC_F_UNCONN_UDP is not valid for a IPPROTO_TCP service + */ + if (urule->protocol==IPPROTO_TCP && + urule->vs_flags&IP_VS_SVC_F_UNCONN_UDP) { + IP_VS_INFO("vs_ctl: IP_VS_SVC_F_UNCONN_UDP used with " + "IPPROTO_TCP: %d %d.%d.%d.%d:%d %s\n", + urule->protocol, NIPQUAD(urule->vaddr), + ntohs(urule->vport), urule->sched_name); + ret = -EFAULT; + goto out_unlock; + } + + /* * Lookup the exact service by or fwmark */ if (urule->vfwmark == 0)