Hello,
This is the user space part for the threshold limitation backport to the
2.4.x kernel. Among the implementation I've once again addressed some
minor nits which IMNSHO should finally be applied. Guys, the code does
nothing magic and should not be considered holy:
o added support for threshold limitation in 2.4.x kernels
o string_to_number() should use unsigned int
o POPT_ARGFLAG_OPTIONAL is unfortunately still not available on
all Linux systems, so drop it.
- Actually either drop it or rewrite the stuff without the popt
dependency, which would also make it easier to extend
- Or rewrite the stuff from scatch with netlink support (also needs
kernel part support for netlink, as discussed with Horms)
o Change 65535 to UINT16_MAX
o Add support for LDFLAGS passing so I can link the thing statically
Please discuss and consider merging selected pieces of the patch.
Actually consider (once again) merging all the ipvsadm versions.
Cheers,
Roberto Nibali, ratz
--
-------------------------------------------------------------
addr://Kasinostrasse 30, CH-5001 Aarau tel://++41 62 823 9355
http://www.terreactive.com fax://++41 62 823 9356
-------------------------------------------------------------
terreActive AG Wir sichern Ihren Erfolg
-------------------------------------------------------------
diff -Nur ipvsadm-1.21-11/ipvsadm.c ipvsadm-1.21-11-ratz/ipvsadm.c
--- ipvsadm-1.21-11/ipvsadm.c 2005-01-22 05:07:42.000000000 +0100
+++ ipvsadm-1.21-11-ratz/ipvsadm.c 2005-10-17 14:59:22.000000000 +0200
@@ -54,6 +54,7 @@
* processing options.
* Horms : added to load ip_vs_ftp for VS/NAT at port 21
* Alexandre Cassen : added SyncID support
+ * Roberto Nibali, ratz: added support for threshold limitation
*
*
* ippfvsadm - Port Fowarding & Virtual Server ADMinistration program
@@ -168,7 +169,10 @@
#define OPT_RATE 0x02000
#define OPT_SORT 0x04000
#define OPT_SYNCID 0x08000
-#define NUMBER_OF_OPT 16
+#define OPT_UTHRESHOLD 0x10000
+#define OPT_LTHRESHOLD 0x20000
+#define OPT_THRESHOLDS 0x40000
+#define NUMBER_OF_OPT 19
static const char* optnames[] = {
"numeric",
@@ -187,6 +191,9 @@
"rate",
"sort",
"syncid",
+ "u_threshold",
+ "l_threshold",
+ "thresholds",
};
/*
@@ -199,22 +206,22 @@
*/
static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
{
- /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st
-rt srt sid */
-/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x', ' '},
-/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', '
', ' ', ' ', 'x'},
-/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x',
'x', 'x', 'x', ' '},
-/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', ' '},
-/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
-/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+ /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st
-rt srt sid -x -y thr */
+/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x', ' ', 'x', 'x', 'x'},
+/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', '
', ' ', ' ', 'x', 'x', 'x', ' '},
+/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x', ' ', ' ', 'x'},
+/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x', ' ', ' ', 'x'},
+/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x',
'x', 'x', 'x', ' ', 'x', 'x', 'x'},
+/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', ' ', 'x', 'x', 'x'},
+/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
+/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x', 'x', 'x', 'x'},
};
/* printing format flags */
@@ -224,6 +231,7 @@
#define FMT_STATS 0x0004
#define FMT_RATE 0x0008
#define FMT_SORT 0x0010
+#define FMT_THRESHOLDS 0x0020
#define SERVICE_NONE 0x0
#define SERVICE_ADDR 0x1
@@ -246,7 +254,7 @@
/* various parsing helpers & parsing functions */
static int str_is_digit(const char *str);
-static int string_to_number(const char *s, int min, int max);
+static int string_to_number(const char *s, unsigned int min, unsigned int max);
static int host_to_addr(const char *name, struct in_addr *addr);
static char * addr_to_host(struct in_addr *addr);
static char * addr_to_anyname(struct in_addr *addr);
@@ -346,8 +354,7 @@
{"udp-service", 'u', POPT_ARG_STRING, &optarg, 'u'},
{"fwmark-service", 'f', POPT_ARG_STRING, &optarg, 'f'},
{"scheduler", 's', POPT_ARG_STRING, &optarg, 's'},
- {"persistent", 'p', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL,
- &optarg, 'p'},
+ {"persistent", 'p', POPT_ARG_STRING, &optarg, 'p'},
{"netmask", 'M', POPT_ARG_STRING, &optarg, 'M'},
{"real-server", 'r', POPT_ARG_STRING, &optarg, 'r'},
{"masquerading", 'm', POPT_ARG_NONE, NULL, 'm'},
@@ -363,6 +370,9 @@
{"stats", '\0', POPT_ARG_NONE, NULL, '7'},
{"rate", '\0', POPT_ARG_NONE, NULL, '8'},
{"sort", '\0', POPT_ARG_NONE, NULL, '9'},
+ {"u_threshold", 'x', POPT_ARG_STRING, &optarg, 'x'},
+ {"l-threshold", 'y', POPT_ARG_STRING, &optarg, 'y'},
+ {"thresholds", '\0', POPT_ARG_NONE, NULL, '0'},
{NULL, 0, 0, NULL, 0}
};
@@ -503,9 +513,24 @@
case 'w':
set_option(options, OPT_WEIGHT);
if ((ur->weight =
- string_to_number(optarg, 0, 65535)) == -1)
+ string_to_number(optarg, 0, UINT16_MAX)) == -1)
fail(2, "illegal weight specified");
break;
+ case 'x':
+ set_option(options, OPT_UTHRESHOLD);
+ if ((ur->u_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal u_threshold specified");
+ break;
+ case 'y':
+ set_option(options, OPT_LTHRESHOLD);
+ if ((ur->l_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal l_threshold specified");
+ if (ur->l_threshold > ur->u_threshold) {
+ fail(2, "l_threshold must be smaller than
u_threshold");
+ }
+ break;
case 'c':
set_option(options, OPT_CONNECTION);
break;
@@ -541,6 +566,10 @@
set_option(options, OPT_SORT);
*format |= FMT_SORT;
break;
+ case '0':
+ set_option(options, OPT_THRESHOLDS);
+ *format |= FMT_THRESHOLDS;
+ break;
default:
fail(2, "invalid option");
}
@@ -586,7 +615,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:x:y:gmicn";
const struct option long_options[] = {
{"add-service", 0, 0, 'A'},
{"edit-service", 0, 0, 'E'},
@@ -624,6 +653,9 @@
{"stats", 0, 0, '7'},
{"rate", 0, 0, '8'},
{"sort", 0, 0, '9'},
+ {"u-threshold", 1, 0, 'x'},
+ {"l-threshold", 1, 0, 'y'},
+ {"thresholds", 0, 0, '0'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
@@ -787,9 +819,24 @@
case 'w':
set_option(options, OPT_WEIGHT);
if ((ur->weight =
- string_to_number(optarg, 0, 65535)) == -1)
+ string_to_number(optarg, 0, UINT16_MAX)) == -1)
fail(2, "illegal weight specified");
break;
+ case 'x':
+ set_option(options, OPT_UTHRESHOLD);
+ if ((ur->u_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal u_threshold specified");
+ break;
+ case 'y':
+ set_option(options, OPT_LTHRESHOLD);
+ if ((ur->l_threshold =
+ string_to_number(optarg, 0, UINT32_MAX)) == -1)
+ fail(2, "illegal l_threshold specified");
+ if (ur->l_threshold > ur->u_threshold) {
+ fail(2, "l_threshold must be smaller than
u_threshold");
+ }
+ break;
case 'c':
set_option(options, OPT_CONNECTION);
break;
@@ -825,6 +872,10 @@
set_option(options, OPT_SORT);
*format |= FMT_SORT;
break;
+ case '0':
+ set_option(options, OPT_THRESHOLDS);
+ *format |= FMT_THRESHOLDS;
+ break;
default:
fail(2, "invalid option");
}
@@ -884,7 +935,8 @@
if ((options & OPT_CONNECTION
|| options & OPT_TIMEOUT
|| options & OPT_DAEMON)
- && (options & OPT_STATS || options & OPT_RATE))
+ && (options & OPT_STATS || options & OPT_RATE
+ || options & OPT_THRESHOLDS))
fail(2, "options conflicts in the list command");
if (options & OPT_CONNECTION)
@@ -955,13 +1007,13 @@
}
-static int string_to_number(const char *s, int min, int max)
+static int string_to_number(const char *s, unsigned int min, unsigned int max)
{
- long number;
+ unsigned long number;
char *end;
errno = 0;
- number = strtol(s, &end, 10);
+ number = strtoul(s, &end, 10);
if (*end == '\0' && end != s) {
/* We parsed a number, let's see if we want this. */
if (errno != ERANGE && min <= number && number <= max)
@@ -1064,9 +1116,9 @@
if (portp != NULL){
result |= SERVICE_PORT;
- if ((portn=string_to_number(portp+1, 0, 65535)) != -1)
+ if ((portn=string_to_number(portp + 1, 0, UINT16_MAX)) != -1)
*port = htons(portn);
- else if ((portn=service_to_port(portp+1, proto)) != -1)
+ else if ((portn=service_to_port(portp + 1, proto)) != -1)
*port = htons(portn);
else
return SERVICE_NONE;
@@ -1207,6 +1259,8 @@
" --ipip -i ipip encapsulation
(tunneling)\n"
" --masquerading -m masquerading (NAT)\n"
" --weight -w weight capacity of real
server\n"
+ " --u-threshold -x uthreshold upper threshold for
amount of connections per RS\n"
+ " --l-threshold -y lthreshold lower threshold for
amount of connections per RS\n"
" --mcast-interface interface multicast interface for
connection sync\n"
" --syncid sid syncid for connection
sync (default=255)\n"
" --connection -c output of current IPVS
connections\n"
@@ -1214,6 +1268,7 @@
" --daemon output of daemon
information\n"
" --stats output of statistics
information\n"
" --rate output of rate
information\n"
+ " --thresholds information on threshold
settings\n"
" --sort sorting output of
service/server entries\n"
" --numeric -n numeric output of
addresses and ports\n",
DEF_SCHED);
@@ -1453,6 +1508,11 @@
" -> RemoteAddress:Port\n",
"Prot LocalAddress:Port",
"CPS", "InPPS", "OutPPS", "InBPS", "OutBPS");
+ else if (format & FMT_THRESHOLDS)
+ printf("%-33s %-10s %-10s %-10s %-10s\n"
+ " -> RemoteAddress:Port\n",
+ "Prot LocalAddress:Port",
+ "Uthreshold", "Lthreshold", "ActiveConn", "InActConn");
else if (!(format & FMT_RULE))
printf("Prot LocalAddress:Port Scheduler Flags\n"
" -> RemoteAddress:Port Forward Weight
ActiveConn InActConn\n");
@@ -1569,6 +1629,10 @@
print_largenum(e->stats.inbps);
print_largenum(e->stats.outbps);
printf("\n");
+ } else if (format & FMT_THRESHOLDS) {
+ printf(" -> %-28s %-10u %-10u %-10u %-10u\n", dname,
+ e->u_threshold, e->l_threshold,
+ e->activeconns, e->inactconns);
} else
printf(" -> %-28s %-7s %-6d %-10u %-10u\n",
dname, fwd_name(e->flags),
diff -Nur ipvsadm-1.21-11/Makefile ipvsadm-1.21-11-ratz/Makefile
--- ipvsadm-1.21-11/Makefile 2005-01-22 05:07:42.000000000 +0100
+++ ipvsadm-1.21-11-ratz/Makefile 2005-10-17 13:46:08.000000000 +0200
@@ -38,6 +38,7 @@
else
CFLAGS = -Wall -Wunused -Wstrict-prototypes -g -O2
endif
+LDFLAGS =
SBIN = $(BUILD_ROOT)/sbin
MANDIR = usr/man
MAN = $(BUILD_ROOT)/$(MANDIR)/man8
@@ -87,7 +88,7 @@
all: ipvsadm
ipvsadm: $(OBJS) $(STATIC_LIBS)
- $(CC) $(CFLAGS) -o $@ $^ $(LIBS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LIBS) $(LDFLAGS)
install: ipvsadm
if [ ! -d $(SBIN) ]; then $(MKDIR) -p $(SBIN); fi
|