diff -ru ipvsadm-1.21/ipvsadm.8 ipvsadm-1.21.udp_unconn/ipvsadm.8 --- ipvsadm-1.21/ipvsadm.8 2003-07-13 16:40:13.000000000 +0900 +++ ipvsadm-1.21.udp_unconn/ipvsadm.8 2004-03-02 18:38:33.000000000 +0900 @@ -37,7 +37,7 @@ .SH SYNOPSIS .B ipvsadm -A|E -t|u|f \fIservice-address\fP [-s \fIscheduler\fP] .ti 15 -.B [-p [\fItimeout\fP]] [-M \fInetmask\fP] +.B [-p [\fItimeout\fP]] [-M \fInetmask\fP] [--unconnected-udp] .br .B ipvsadm -D -t|u|f \fIservice-address\fP .br @@ -81,7 +81,7 @@ .TP .B ipvsadm \fICOMMAND\fP [\fIprotocol\fP] \fIservice-address\fP .ti 15 -.B [\fIscheduling-method\fP] [\fIpersistence options\fP] +.B [\fIscheduling-method\fP] [\fIoptions\fP] .TP .B ipvsadm \fIcommand\fP [\fIprotocol\fP] \fIservice-address\fP .ti 15 @@ -91,10 +91,11 @@ .PP The first format manipulates a virtual service and the algorithm for assigning service requests to real servers. Optionally, a persistent -timeout and network mask for the granularity of a persistent service -may be specified. The second format manipulates a real server that is -associated with an existing virtual service. When specifying a real -server, the packet-forwarding method and the weight of the real +timeout and network mask for the granularity of a persistent service may be +specified. For non TCP services an option may also be given to treat UDP as +unconnected rather than connected. The second format manipulates a real +server that is associated with an existing virtual service. When specifying +a real server, the packet-forwarding method and the weight of the real server, relative to other real servers for the virtual service, may be specified, otherwise defaults will be used. .SS COMMANDS @@ -279,6 +280,12 @@ granularity is per client host. Less specific netmasks may be used to resolve problems with non-persistent cache clusters on the client side. .TP +.B --unconnected-udp +Treat UDP as unconnected rather than connected. That is no +attempt will be made to send packets with the same source and destination +address and port to the same real server. Persistance may be used +in conjunction with this option. +.TP .B -r, --real-server \fIserver-address\fP Real server that an associated request for service may be assigned to. The \fIserver-address\fP is the \fIhost\fP address of a real server, diff -ru ipvsadm-1.21/ipvsadm.c ipvsadm-1.21.udp_unconn/ipvsadm.c --- ipvsadm-1.21/ipvsadm.c 2004-01-10 18:35:54.000000000 +0900 +++ ipvsadm-1.21.udp_unconn/ipvsadm.c 2004-03-02 18:39:46.000000000 +0900 @@ -166,7 +166,8 @@ #define OPT_STATS 0x01000 #define OPT_RATE 0x02000 #define OPT_SORT 0x04000 -#define NUMBER_OF_OPT 15 +#define OPT_UNCONN_UDP 0x08000 +#define NUMBER_OF_OPT 16 static const char* optnames[] = { "numeric", @@ -345,6 +346,7 @@ {"scheduler", 's', POPT_ARG_STRING, &optarg, 's'}, {"persistent", 'p', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, &optarg, 'p'}, + {"unconnected-udp", '\0', POPT_ARG_NONE, &optarg, 0x80}, {"netmask", 'M', POPT_ARG_STRING, &optarg, 'M'}, {"real-server", 'r', POPT_ARG_STRING, &optarg, 'r'}, {"masquerading", 'm', POPT_ARG_NONE, NULL, 'm'}, @@ -456,9 +458,16 @@ break; case 'p': set_option(options, OPT_PERSISTENT); - ur->vs_flags = IP_VS_SVC_F_PERSISTENT; + ur->vs_flags |= IP_VS_SVC_F_PERSISTENT; ur->timeout = parse_timeout(optarg, 1, MAX_TIMEOUT); break; + case 0x80: + if(ur->protocol==IPPROTO_TCP) + fail(2, "illegal use of unnconncted_udp flag " + "with a TCP service"); + set_option(options, OPT_UNCONN_UDP); + ur->vs_flags |= IP_VS_SVC_F_UNCONN_UDP; + break; case 'M': set_option(options, OPT_NETMASK); parse = parse_netmask(optarg, &ur->netmask); @@ -571,7 +580,7 @@ int *cmd, unsigned int *options, unsigned int *format) { int c, parse; - const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicn"; + const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicn\x80"; const struct option long_options[] = { {"add-service", 0, 0, 'A'}, {"edit-service", 0, 0, 'E'}, @@ -594,6 +603,7 @@ {"fwmark-service", 1, 0, 'f'}, {"scheduler", 1, 0, 's'}, {"persistent", 2, 0, 'p'}, + {"unconnected-udp", 0, 0, 0x80}, {"real-server", 1, 0, 'r'}, {"masquerading", 0, 0, 'm'}, {"netmask", 1, 0, 'M'}, @@ -725,12 +735,19 @@ break; case 'p': set_option(options, OPT_PERSISTENT); - ur->vs_flags = IP_VS_SVC_F_PERSISTENT; + ur->vs_flags |= IP_VS_SVC_F_PERSISTENT; if (!optarg && optind < argc && argv[optind][0] != '-' && argv[optind][0] != '!') optarg = argv[optind++]; ur->timeout = parse_timeout(optarg, 1, MAX_TIMEOUT); break; + case 0x80: + if(ur->protocol==IPPROTO_TCP) + fail(2, "illegal use of unnconncted_udp flag " + "with a TCP service"); + set_option(options, OPT_UNCONN_UDP); + ur->vs_flags |= IP_VS_SVC_F_UNCONN_UDP; + break; case 'M': set_option(options, OPT_NETMASK); parse = parse_netmask(optarg, &ur->netmask); @@ -884,7 +901,7 @@ * Make sure that port zero service is persistent */ if (!urule.vfwmark && !urule.vport && - (urule.vs_flags != IP_VS_SVC_F_PERSISTENT)) + (! (urule.vs_flags & IP_VS_SVC_F_PERSISTENT))) fail(2, "Zero port specified " "for non-persistent service"); @@ -1129,7 +1146,7 @@ version(stream); fprintf(stream, "Usage:\n" - " %s -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]\n" + " %s -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask] [--unconnected-udp]\n" " %s -D -t|u|f service-address\n" " %s -C\n" " %s -R\n" @@ -1175,6 +1192,7 @@ " the default scheduler is %s.\n" " --persistent -p [timeout] persistent service\n" " --netmask -M netmask persistent granularity mask\n" + " --unconnected-udp unconnected UDP (default is connected UDP)\n" " --real-server -r server-address server-address is host (and port)\n" " --gatewaying -g gatewaying (direct routing) (default)\n" " --ipip -i ipip encapsulation (tunneling)\n" @@ -1482,6 +1500,9 @@ printf(" -M %s", inet_ntoa(mask)); } } + if (svc->flags & IP_VS_SVC_F_UNCONN_UDP) { + printf(" --unconnected-udp"); + } } else if (format & FMT_STATS) { printf("%-33s", svc_name); print_largenum(svc->stats.conns); @@ -1506,6 +1527,9 @@ printf(" mask %s", inet_ntoa(mask)); } } + if (svc->flags & IP_VS_SVC_F_UNCONN_UDP) { + printf(" unconnected-udp"); + } } printf("\n");